feat: Add intelligent auto-router and enhanced integrations
- Add intelligent-router.sh hook for automatic agent routing - Add AUTO-TRIGGER-SUMMARY.md documentation - Add FINAL-INTEGRATION-SUMMARY.md documentation - Complete Prometheus integration (6 commands + 4 tools) - Complete Dexto integration (12 commands + 5 tools) - Enhanced Ralph with access to all agents - Fix /clawd command (removed disable-model-invocation) - Update hooks.json to v5 with intelligent routing - 291 total skills now available - All 21 commands with automatic routing 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
9
dexto/docs/api/sdk/_category_.json
Normal file
9
dexto/docs/api/sdk/_category_.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Dexto SDK",
|
||||
"position": 4,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Dexto SDK API Reference",
|
||||
"description": "Complete technical API reference for the Dexto SDK for TypeScript/JavaScript."
|
||||
}
|
||||
}
|
||||
324
dexto/docs/api/sdk/agent-factory.md
Normal file
324
dexto/docs/api/sdk/agent-factory.md
Normal file
@@ -0,0 +1,324 @@
|
||||
---
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# AgentFactory API
|
||||
|
||||
The `AgentFactory` namespace provides static methods for agent creation, installation, and management. Use these functions to create agents from inline configs, install agents from the bundled registry, install custom agents, and manage installed agents.
|
||||
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## createAgent
|
||||
|
||||
Creates a `DextoAgent` from an inline configuration object. Use this when you have a config from a database, API, or constructed programmatically and don't need a registry file.
|
||||
|
||||
```typescript
|
||||
async function AgentFactory.createAgent(
|
||||
config: AgentConfig,
|
||||
options?: CreateAgentOptions
|
||||
): Promise<DextoAgent>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `config` | `AgentConfig` | Agent configuration object |
|
||||
| `options.agentId` | `string` | (Optional) Override agent ID (affects log/storage paths) |
|
||||
| `options.isInteractiveCli` | `boolean` | (Optional) If true, disables console logging |
|
||||
|
||||
**Returns:** `Promise<DextoAgent>` - Agent instance (not started)
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
|
||||
// Create from inline config
|
||||
const agent = await AgentFactory.createAgent({
|
||||
llm: {
|
||||
provider: 'openai',
|
||||
model: 'gpt-4o',
|
||||
apiKey: process.env.OPENAI_API_KEY
|
||||
},
|
||||
systemPrompt: 'You are a helpful assistant.'
|
||||
});
|
||||
await agent.start();
|
||||
|
||||
// With custom agent ID (affects log/storage paths)
|
||||
const agent = await AgentFactory.createAgent(config, { agentId: 'my-custom-agent' });
|
||||
|
||||
// From database
|
||||
const configFromDb = await db.getAgentConfig(userId);
|
||||
const agent = await AgentFactory.createAgent(configFromDb, { agentId: `user-${userId}` });
|
||||
await agent.start();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## listAgents
|
||||
|
||||
Lists all installed and available agents from the bundled registry.
|
||||
|
||||
```typescript
|
||||
async function AgentFactory.listAgents(): Promise<{
|
||||
installed: AgentInfo[];
|
||||
available: AgentInfo[];
|
||||
}>
|
||||
```
|
||||
|
||||
**Returns:** Object with `installed` and `available` agent arrays
|
||||
|
||||
```typescript
|
||||
interface AgentInfo {
|
||||
id: string; // Unique identifier
|
||||
name: string; // Display name
|
||||
description: string; // What the agent does
|
||||
author: string; // Creator
|
||||
tags: string[]; // Categorization tags
|
||||
type: 'builtin' | 'custom';
|
||||
}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
|
||||
const { installed, available } = await AgentFactory.listAgents();
|
||||
|
||||
console.log('Installed agents:');
|
||||
installed.forEach(agent => {
|
||||
console.log(` - ${agent.name} (${agent.id})`);
|
||||
});
|
||||
|
||||
console.log('\nAvailable to install:');
|
||||
available.forEach(agent => {
|
||||
console.log(` - ${agent.name}: ${agent.description}`);
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## installAgent
|
||||
|
||||
Installs an agent from the bundled registry to the local agents directory (`~/.dexto/agents/`).
|
||||
|
||||
```typescript
|
||||
async function AgentFactory.installAgent(
|
||||
agentId: string,
|
||||
options?: InstallOptions
|
||||
): Promise<string>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `agentId` | `string` | Agent ID from bundled registry |
|
||||
| `options.agentsDir` | `string` | (Optional) Custom agents directory |
|
||||
|
||||
**Returns:** `Promise<string>` - Path to installed agent's main config file
|
||||
|
||||
**Throws:** `DextoRuntimeError` if agent not found or installation fails
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
|
||||
// Install a bundled agent
|
||||
const configPath = await AgentFactory.installAgent('coding-agent');
|
||||
console.log(`Installed to: ${configPath}`);
|
||||
```
|
||||
|
||||
### What Happens During Installation
|
||||
|
||||
1. Agent files are copied from bundled location to `~/.dexto/agents/{agentId}/`
|
||||
2. Agent is added to the user's registry (`~/.dexto/agents/registry.json`)
|
||||
3. User preferences are applied at runtime for the bundled coding-agent only
|
||||
|
||||
---
|
||||
|
||||
## installCustomAgent
|
||||
|
||||
Installs a custom agent from a local file or directory path.
|
||||
|
||||
```typescript
|
||||
async function AgentFactory.installCustomAgent(
|
||||
agentId: string,
|
||||
sourcePath: string,
|
||||
metadata: {
|
||||
name?: string;
|
||||
description: string;
|
||||
author: string;
|
||||
tags: string[];
|
||||
},
|
||||
options?: InstallOptions
|
||||
): Promise<string>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `agentId` | `string` | Unique ID for the custom agent |
|
||||
| `sourcePath` | `string` | Absolute path to agent YAML file or directory |
|
||||
| `metadata.name` | `string` | (Optional) Display name (defaults to agentId) |
|
||||
| `metadata.description` | `string` | Description of what the agent does |
|
||||
| `metadata.author` | `string` | Creator of the agent |
|
||||
| `metadata.tags` | `string[]` | Categorization tags |
|
||||
| `options.agentsDir` | `string` | (Optional) Custom agents directory |
|
||||
|
||||
**Returns:** `Promise<string>` - Path to installed agent's main config file
|
||||
|
||||
**Throws:**
|
||||
- `DextoRuntimeError` if agent ID conflicts with bundled agent
|
||||
- `DextoRuntimeError` if agent ID already exists
|
||||
- `DextoRuntimeError` if source path doesn't exist
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
|
||||
// Install from a single YAML file
|
||||
const configPath = await AgentFactory.installCustomAgent(
|
||||
'my-support-agent',
|
||||
'/path/to/support-agent.yml',
|
||||
{
|
||||
description: 'Custom support agent for our product',
|
||||
author: 'My Team',
|
||||
tags: ['support', 'custom']
|
||||
}
|
||||
);
|
||||
|
||||
// Install from a directory (for agents with multiple files)
|
||||
const configPath = await AgentFactory.installCustomAgent(
|
||||
'my-complex-agent',
|
||||
'/path/to/agent-directory/',
|
||||
{
|
||||
name: 'Complex Agent',
|
||||
description: 'Agent with knowledge files and multiple configs',
|
||||
author: 'My Team',
|
||||
tags: ['complex', 'custom']
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### Directory Structure for Multi-File Agents
|
||||
|
||||
When installing from a directory:
|
||||
|
||||
```
|
||||
my-agent/
|
||||
├── agent.yml # Main config (required, or specify custom name)
|
||||
├── knowledge/
|
||||
│ ├── docs.md
|
||||
│ └── faq.md
|
||||
└── prompts/
|
||||
└── system.txt
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## uninstallAgent
|
||||
|
||||
Removes an installed agent from disk and the user registry.
|
||||
|
||||
```typescript
|
||||
async function AgentFactory.uninstallAgent(agentId: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `agentId` | `string` | Agent ID to uninstall |
|
||||
|
||||
**Throws:** `DextoRuntimeError` if agent is not installed
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
|
||||
// Uninstall an agent
|
||||
await AgentFactory.uninstallAgent('my-custom-agent');
|
||||
console.log('Agent uninstalled');
|
||||
```
|
||||
|
||||
### What Happens During Uninstallation
|
||||
|
||||
1. Agent directory is removed from `~/.dexto/agents/{agentId}/`
|
||||
2. Agent entry is removed from user registry (`~/.dexto/agents/registry.json`)
|
||||
|
||||
:::caution
|
||||
Uninstallation is permanent. All agent files including conversation history (if stored locally) will be deleted.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## InstallOptions
|
||||
|
||||
Options for installation functions:
|
||||
|
||||
```typescript
|
||||
interface InstallOptions {
|
||||
/** Directory where agents are stored (default: ~/.dexto/agents) */
|
||||
agentsDir?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Example
|
||||
|
||||
```typescript
|
||||
import { AgentFactory } from '@dexto/agent-management';
|
||||
import { AgentManager } from '@dexto/agent-management';
|
||||
|
||||
async function setupAgents() {
|
||||
// List what's available
|
||||
const { installed, available } = await AgentFactory.listAgents();
|
||||
console.log(`${installed.length} installed, ${available.length} available`);
|
||||
|
||||
// Install a bundled agent if not already installed
|
||||
if (!installed.some(a => a.id === 'coding-agent')) {
|
||||
await AgentFactory.installAgent('coding-agent');
|
||||
console.log('Installed coding-agent');
|
||||
}
|
||||
|
||||
// Install a custom agent
|
||||
await AgentFactory.installCustomAgent(
|
||||
'team-agent',
|
||||
'./my-agents/team-agent.yml',
|
||||
{
|
||||
description: 'Our team\'s custom agent',
|
||||
author: 'Engineering Team',
|
||||
tags: ['internal', 'custom']
|
||||
}
|
||||
);
|
||||
|
||||
// Now use AgentManager to work with installed agents
|
||||
const manager = new AgentManager('~/.dexto/agents/registry.json');
|
||||
await manager.loadRegistry();
|
||||
|
||||
const agent = await manager.loadAgent('team-agent');
|
||||
await agent.start();
|
||||
|
||||
// ... use the agent ...
|
||||
|
||||
await agent.stop();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## File Locations
|
||||
|
||||
| Resource | Path |
|
||||
| :--- | :--- |
|
||||
| Agents directory | `~/.dexto/agents/` |
|
||||
| User registry | `~/.dexto/agents/registry.json` |
|
||||
| Per-agent configs | `~/.dexto/agents/{agentId}/` |
|
||||
| Bundled registry | Bundled with `@dexto/agent-management` package |
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [AgentManager API](./agent-manager.md) - Registry-based agent lifecycle management
|
||||
- [Config Utilities](./config-utilities.md) - Lower-level config loading functions
|
||||
- [Agent Orchestration Tutorial](/docs/tutorials/sdk/orchestration) - Step-by-step guide
|
||||
263
dexto/docs/api/sdk/agent-manager.md
Normal file
263
dexto/docs/api/sdk/agent-manager.md
Normal file
@@ -0,0 +1,263 @@
|
||||
---
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
# AgentManager API
|
||||
|
||||
The `AgentManager` class provides registry-based agent lifecycle management. It loads agent configurations from a registry file and creates agent instances programmatically.
|
||||
|
||||
```typescript
|
||||
import { AgentManager } from '@dexto/agent-management';
|
||||
```
|
||||
|
||||
:::note When to use AgentManager
|
||||
**`AgentManager`** - Registry-based. Use when you have a `registry.json` with multiple predefined agents.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
## Constructor
|
||||
|
||||
### `constructor`
|
||||
|
||||
Creates a new AgentManager instance pointing to a registry file.
|
||||
|
||||
```typescript
|
||||
constructor(registryPath: string)
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `registryPath` | `string` | Path to registry.json file (absolute or relative) |
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
// Project-local registry
|
||||
const manager = new AgentManager('./agents/registry.json');
|
||||
|
||||
// Absolute path
|
||||
const manager = new AgentManager('/path/to/registry.json');
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Methods
|
||||
|
||||
### `loadRegistry`
|
||||
|
||||
Loads the registry from file. Must be called before using sync methods like `listAgents()` or `hasAgent()`.
|
||||
|
||||
```typescript
|
||||
async loadRegistry(): Promise<Registry>
|
||||
```
|
||||
|
||||
**Returns:** `Promise<Registry>` - The loaded registry object
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const manager = new AgentManager('./registry.json');
|
||||
await manager.loadRegistry();
|
||||
|
||||
// Now sync methods work
|
||||
const agents = manager.listAgents();
|
||||
```
|
||||
|
||||
:::note
|
||||
`loadAgent()` automatically calls `loadRegistry()` if not already loaded.
|
||||
:::
|
||||
|
||||
---
|
||||
|
||||
### `listAgents`
|
||||
|
||||
Returns metadata for all agents in the registry.
|
||||
|
||||
```typescript
|
||||
listAgents(): AgentMetadata[]
|
||||
```
|
||||
|
||||
**Returns:** `AgentMetadata[]` - Array of agent metadata objects
|
||||
|
||||
```typescript
|
||||
interface AgentMetadata {
|
||||
id: string; // Unique identifier
|
||||
name: string; // Display name
|
||||
description: string; // What the agent does
|
||||
author?: string; // Creator
|
||||
tags?: string[]; // Categorization tags
|
||||
}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const manager = new AgentManager('./registry.json');
|
||||
await manager.loadRegistry();
|
||||
|
||||
const agents = manager.listAgents();
|
||||
console.log(agents);
|
||||
// [
|
||||
// { id: 'coding-agent', name: 'Coding Assistant', description: '...', tags: ['coding'] },
|
||||
// { id: 'support-agent', name: 'Support Assistant', description: '...', tags: ['support'] }
|
||||
// ]
|
||||
|
||||
// Filter by tag
|
||||
const codingAgents = agents.filter(a => a.tags?.includes('coding'));
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `hasAgent`
|
||||
|
||||
Checks if an agent exists in the registry.
|
||||
|
||||
```typescript
|
||||
hasAgent(id: string): boolean
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `id` | `string` | Agent ID to check |
|
||||
|
||||
**Returns:** `boolean` - True if agent exists
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const manager = new AgentManager('./registry.json');
|
||||
await manager.loadRegistry();
|
||||
|
||||
if (manager.hasAgent('coding-agent')) {
|
||||
const agent = await manager.loadAgent('coding-agent');
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### `loadAgent`
|
||||
|
||||
Loads a `DextoAgent` instance from the registry. Loads the agent's YAML config, enriches it with runtime paths, and returns an unstarted agent.
|
||||
|
||||
```typescript
|
||||
async loadAgent(id: string): Promise<DextoAgent>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `id` | `string` | Agent ID from registry |
|
||||
|
||||
**Returns:** `Promise<DextoAgent>` - Agent instance (not started)
|
||||
|
||||
**Throws:**
|
||||
- `DextoRuntimeError` if agent not found or config loading fails
|
||||
- `DextoValidationError` if agent config validation fails
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const manager = new AgentManager('./registry.json');
|
||||
const agent = await manager.loadAgent('coding-agent');
|
||||
await agent.start();
|
||||
|
||||
// Use the agent
|
||||
const session = await agent.createSession();
|
||||
const response = await agent.generate('Write a function to reverse a string', session.id);
|
||||
|
||||
console.log(response.content);
|
||||
await agent.stop();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Registry Format
|
||||
|
||||
The registry file is a JSON file that describes available agents:
|
||||
|
||||
```json
|
||||
{
|
||||
"agents": [
|
||||
{
|
||||
"id": "coding-agent",
|
||||
"name": "Coding Assistant",
|
||||
"description": "Expert coding assistant for development tasks",
|
||||
"configPath": "./coding-agent.yml",
|
||||
"author": "Your Team",
|
||||
"tags": ["coding", "development"]
|
||||
},
|
||||
{
|
||||
"id": "support-agent",
|
||||
"name": "Support Assistant",
|
||||
"description": "Friendly customer support agent",
|
||||
"configPath": "./support-agent.yml",
|
||||
"tags": ["support", "customer-service"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
| Field | Type | Required | Description |
|
||||
| :--- | :--- | :--- | :--- |
|
||||
| `id` | `string` | Yes | Unique identifier (used in `loadAgent()`) |
|
||||
| `name` | `string` | Yes | Human-readable display name |
|
||||
| `description` | `string` | Yes | What this agent does |
|
||||
| `configPath` | `string` | Yes | Path to YAML config (relative to registry.json) |
|
||||
| `author` | `string` | No | Creator of the agent |
|
||||
| `tags` | `string[]` | No | Categorization tags |
|
||||
|
||||
---
|
||||
|
||||
## Complete Example
|
||||
|
||||
```typescript
|
||||
import { AgentManager } from '@dexto/agent-management';
|
||||
|
||||
async function main() {
|
||||
// Initialize manager
|
||||
const manager = new AgentManager('./agents/registry.json');
|
||||
await manager.loadRegistry();
|
||||
|
||||
// List available agents
|
||||
console.log('Available agents:');
|
||||
for (const agent of manager.listAgents()) {
|
||||
console.log(` - ${agent.name} (${agent.id}): ${agent.description}`);
|
||||
}
|
||||
|
||||
// Create and use an agent
|
||||
if (manager.hasAgent('coding-agent')) {
|
||||
const agent = await manager.loadAgent('coding-agent');
|
||||
await agent.start();
|
||||
|
||||
const session = await agent.createSession();
|
||||
const response = await agent.generate('Hello!', session.id);
|
||||
console.log(response.content);
|
||||
|
||||
await agent.stop();
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
import { AgentManager } from '@dexto/agent-management';
|
||||
|
||||
try {
|
||||
const manager = new AgentManager('./registry.json');
|
||||
const agent = await manager.loadAgent('non-existent-agent');
|
||||
} catch (error) {
|
||||
if (error.code === 'AGENT_NOT_FOUND') {
|
||||
console.log('Agent not found in registry');
|
||||
} else if (error.name === 'DextoValidationError') {
|
||||
console.log('Agent config validation failed:', error.issues);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [Config Utilities](./config-utilities.md) - Lower-level config loading functions
|
||||
- [AgentFactory API](./agent-factory.md) - Agent installation and management
|
||||
- [Agent Orchestration Tutorial](/docs/tutorials/sdk/orchestration) - Step-by-step guide
|
||||
209
dexto/docs/api/sdk/config-utilities.md
Normal file
209
dexto/docs/api/sdk/config-utilities.md
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# Config Utilities
|
||||
|
||||
Utilities for loading and enriching agent configurations from YAML files. These functions are the building blocks for programmatic agent management.
|
||||
|
||||
```typescript
|
||||
import { loadAgentConfig, enrichAgentConfig } from '@dexto/agent-management';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## loadAgentConfig
|
||||
|
||||
Loads and processes an agent configuration from a YAML file. Handles file reading, YAML parsing, and template variable expansion.
|
||||
|
||||
```typescript
|
||||
async function loadAgentConfig(
|
||||
configPath: string,
|
||||
logger?: IDextoLogger
|
||||
): Promise<AgentConfig>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `configPath` | `string` | Path to the YAML config file (absolute or relative) |
|
||||
| `logger` | `IDextoLogger` | (Optional) Logger instance for debug output |
|
||||
|
||||
**Returns:** `Promise<AgentConfig>` - Parsed configuration object
|
||||
|
||||
**Throws:**
|
||||
- `ConfigError` with `FILE_NOT_FOUND` if file doesn't exist
|
||||
- `ConfigError` with `FILE_READ_ERROR` if file read fails
|
||||
- `ConfigError` with `PARSE_ERROR` if YAML is invalid
|
||||
|
||||
### What It Does
|
||||
|
||||
1. **Reads the YAML file** from disk
|
||||
2. **Parses YAML** into a JavaScript object
|
||||
3. **Expands template variables** like `${{dexto.agent_dir}}`
|
||||
4. **Expands environment variables** like `$OPENAI_API_KEY`
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
import { loadAgentConfig } from '@dexto/agent-management';
|
||||
|
||||
// Load a config file
|
||||
const config = await loadAgentConfig('./agents/my-agent.yml');
|
||||
|
||||
console.log(config.llm.provider); // 'openai'
|
||||
console.log(config.llm.model); // 'gpt-4o'
|
||||
```
|
||||
|
||||
### Template Variables
|
||||
|
||||
Config files can use template variables that are expanded at load time:
|
||||
|
||||
```yaml
|
||||
# my-agent.yml
|
||||
systemPrompt:
|
||||
contributors:
|
||||
- id: knowledge
|
||||
type: file
|
||||
files:
|
||||
- ${{dexto.agent_dir}}/knowledge/docs.md
|
||||
```
|
||||
|
||||
| Variable | Expands To |
|
||||
| :--- | :--- |
|
||||
| `${{dexto.agent_dir}}` | Directory containing the config file |
|
||||
|
||||
### Environment Variables
|
||||
|
||||
Environment variables are expanded during schema validation:
|
||||
|
||||
```yaml
|
||||
llm:
|
||||
provider: openai
|
||||
model: gpt-4o
|
||||
apiKey: $OPENAI_API_KEY # Expanded from environment
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## enrichAgentConfig
|
||||
|
||||
Enriches a loaded configuration with per-agent runtime paths for logs, database, and blob storage. This function should be called after `loadAgentConfig` and before creating a `DextoAgent`.
|
||||
|
||||
```typescript
|
||||
function enrichAgentConfig(
|
||||
config: AgentConfig,
|
||||
configPath?: string,
|
||||
isInteractiveCli?: boolean
|
||||
): AgentConfig
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `config` | `AgentConfig` | Configuration from `loadAgentConfig` |
|
||||
| `configPath` | `string` | (Optional) Path to config file (used for agent ID derivation) |
|
||||
| `isInteractiveCli` | `boolean` | (Optional) If true, disables console logging (default: false) |
|
||||
|
||||
**Returns:** `AgentConfig` - Enriched configuration with explicit paths
|
||||
|
||||
### What It Adds
|
||||
|
||||
Each agent gets isolated paths based on its ID:
|
||||
|
||||
| Resource | Path |
|
||||
| :--- | :--- |
|
||||
| Logs | `~/.dexto/agents/{agentId}/logs/{agentId}.log` |
|
||||
| Database | `~/.dexto/agents/{agentId}/db/{agentId}.db` |
|
||||
| Blob Storage | `~/.dexto/agents/{agentId}/blobs/` |
|
||||
|
||||
### Agent ID Derivation
|
||||
|
||||
The agent ID is derived in priority order:
|
||||
1. `agentCard.name` from config (sanitized)
|
||||
2. Config filename (without extension)
|
||||
3. Fallback: `coding-agent`
|
||||
|
||||
### Example
|
||||
|
||||
```typescript
|
||||
import { loadAgentConfig, enrichAgentConfig } from '@dexto/agent-management';
|
||||
import { DextoAgent } from '@dexto/core';
|
||||
|
||||
// Load raw config
|
||||
const config = await loadAgentConfig('./agents/coding-agent.yml');
|
||||
|
||||
// Enrich with runtime paths
|
||||
const enrichedConfig = enrichAgentConfig(config, './agents/coding-agent.yml');
|
||||
|
||||
// Create agent with enriched config
|
||||
const agent = new DextoAgent(enrichedConfig, './agents/coding-agent.yml');
|
||||
await agent.start();
|
||||
```
|
||||
|
||||
### Default Storage Configuration
|
||||
|
||||
If no storage is specified in the config, enrichment adds:
|
||||
|
||||
```typescript
|
||||
{
|
||||
storage: {
|
||||
cache: { type: 'in-memory' },
|
||||
database: { type: 'sqlite', path: '~/.dexto/agents/{agentId}/db/{agentId}.db' },
|
||||
blob: { type: 'local', storePath: '~/.dexto/agents/{agentId}/blobs/' }
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Complete Usage Pattern
|
||||
|
||||
```typescript
|
||||
import { loadAgentConfig, enrichAgentConfig } from '@dexto/agent-management';
|
||||
import { DextoAgent } from '@dexto/core';
|
||||
|
||||
async function createAgentFromConfig(configPath: string): Promise<DextoAgent> {
|
||||
// 1. Load the YAML config
|
||||
const config = await loadAgentConfig(configPath);
|
||||
|
||||
// 2. Enrich with runtime paths
|
||||
const enrichedConfig = enrichAgentConfig(config, configPath);
|
||||
|
||||
// 3. Create and start the agent
|
||||
const agent = new DextoAgent(enrichedConfig, configPath);
|
||||
await agent.start();
|
||||
|
||||
return agent;
|
||||
}
|
||||
|
||||
// Usage
|
||||
const agent = await createAgentFromConfig('./agents/my-agent.yml');
|
||||
const session = await agent.createSession();
|
||||
const response = await agent.generate('Hello!', session.id);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Error Handling
|
||||
|
||||
```typescript
|
||||
import { loadAgentConfig, enrichAgentConfig } from '@dexto/agent-management';
|
||||
|
||||
try {
|
||||
const config = await loadAgentConfig('./agents/my-agent.yml');
|
||||
const enriched = enrichAgentConfig(config, './agents/my-agent.yml');
|
||||
} catch (error) {
|
||||
if (error.code === 'FILE_NOT_FOUND') {
|
||||
console.error('Config file not found:', error.path);
|
||||
} else if (error.code === 'PARSE_ERROR') {
|
||||
console.error('Invalid YAML:', error.message);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## See Also
|
||||
|
||||
- [AgentManager API](./agent-manager.md) - Higher-level registry-based management
|
||||
- [AgentFactory API](./agent-factory.md) - Agent installation functions
|
||||
- [Loading Agent Configs Tutorial](/docs/tutorials/sdk/config-files) - Step-by-step guide
|
||||
596
dexto/docs/api/sdk/dexto-agent.md
Normal file
596
dexto/docs/api/sdk/dexto-agent.md
Normal file
@@ -0,0 +1,596 @@
|
||||
---
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
# DextoAgent API
|
||||
|
||||
Complete API reference for the main `DextoAgent` class. This is the core interface for the Dexto Agent SDK.
|
||||
|
||||
## Constructor and Lifecycle
|
||||
|
||||
### `constructor`
|
||||
|
||||
Creates a new Dexto agent instance with the provided configuration.
|
||||
|
||||
```typescript
|
||||
constructor(config: AgentConfig)
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `config` | `AgentConfig` | Agent configuration object |
|
||||
|
||||
### `start`
|
||||
|
||||
Initializes and starts the agent with all required services.
|
||||
|
||||
```typescript
|
||||
async start(): Promise<void>
|
||||
```
|
||||
|
||||
**Parameters:** None
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const agent = new DextoAgent(config);
|
||||
await agent.start();
|
||||
```
|
||||
|
||||
### `stop`
|
||||
|
||||
Stops the agent and cleans up all resources.
|
||||
|
||||
```typescript
|
||||
async stop(): Promise<void>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
await agent.stop();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Core Methods
|
||||
|
||||
The Dexto Agent SDK provides three methods for processing messages:
|
||||
- **`generate()`** - Recommended for most use cases. Returns a complete response.
|
||||
- **`stream()`** - For real-time streaming UIs. Yields events as they arrive.
|
||||
- **`run()`** - Lower-level method for direct control.
|
||||
|
||||
### `generate`
|
||||
|
||||
**Recommended method** for processing user input. Waits for complete response.
|
||||
|
||||
```typescript
|
||||
async generate(
|
||||
content: ContentInput,
|
||||
sessionId: string,
|
||||
options?: GenerateOptions
|
||||
): Promise<GenerateResponse>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `content` | `string \| ContentPart[]` | User message (string) or multimodal content (array) |
|
||||
| `sessionId` | `string` | **Required.** Session ID for the conversation |
|
||||
| `options.signal` | `AbortSignal` | (Optional) For cancellation |
|
||||
|
||||
**Content Types:**
|
||||
```typescript
|
||||
// Simple string content
|
||||
type ContentInput = string | ContentPart[];
|
||||
|
||||
// For multimodal content, use ContentPart array:
|
||||
type ContentPart = TextPart | ImagePart | FilePart;
|
||||
|
||||
interface TextPart { type: 'text'; text: string; }
|
||||
interface ImagePart { type: 'image'; image: string; mimeType?: string; }
|
||||
interface FilePart { type: 'file'; data: string; mimeType: string; filename?: string; }
|
||||
```
|
||||
|
||||
**Returns:** `Promise<GenerateResponse>`
|
||||
```typescript
|
||||
interface GenerateResponse {
|
||||
content: string; // The AI's text response
|
||||
reasoning?: string; // Extended thinking (o1/o3 models)
|
||||
usage: TokenUsage; // Token usage statistics
|
||||
toolCalls: AgentToolCall[]; // Tools that were called
|
||||
sessionId: string;
|
||||
messageId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const agent = new DextoAgent(config);
|
||||
await agent.start();
|
||||
|
||||
const session = await agent.createSession();
|
||||
|
||||
// Simple text message
|
||||
const response = await agent.generate('What is 2+2?', session.id);
|
||||
console.log(response.content); // "4"
|
||||
console.log(response.usage.totalTokens); // Token count
|
||||
|
||||
// With image URL (auto-detected)
|
||||
const response = await agent.generate([
|
||||
{ type: 'text', text: 'Describe this image' },
|
||||
{ type: 'image', image: 'https://example.com/photo.jpg' }
|
||||
], session.id);
|
||||
|
||||
// With image base64
|
||||
const response = await agent.generate([
|
||||
{ type: 'text', text: 'Describe this image' },
|
||||
{ type: 'image', image: base64Image, mimeType: 'image/png' }
|
||||
], session.id);
|
||||
|
||||
// With file URL
|
||||
const response = await agent.generate([
|
||||
{ type: 'text', text: 'Summarize this document' },
|
||||
{ type: 'file', data: 'https://example.com/doc.pdf', mimeType: 'application/pdf' }
|
||||
], session.id);
|
||||
|
||||
// With file base64
|
||||
const response = await agent.generate([
|
||||
{ type: 'text', text: 'Summarize this document' },
|
||||
{ type: 'file', data: base64Pdf, mimeType: 'application/pdf', filename: 'doc.pdf' }
|
||||
], session.id);
|
||||
|
||||
// With cancellation support
|
||||
const controller = new AbortController();
|
||||
const response = await agent.generate('Long task...', session.id, { signal: controller.signal });
|
||||
|
||||
await agent.stop();
|
||||
```
|
||||
|
||||
### `stream`
|
||||
|
||||
For real-time streaming UIs. Yields events as they arrive.
|
||||
|
||||
```typescript
|
||||
async stream(
|
||||
content: ContentInput,
|
||||
sessionId: string,
|
||||
options?: StreamOptions
|
||||
): Promise<AsyncIterableIterator<StreamingEvent>>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `content` | `string \| ContentPart[]` | User message (string) or multimodal content (array) |
|
||||
| `sessionId` | `string` | **Required.** Session ID |
|
||||
| `options.signal` | `AbortSignal` | (Optional) For cancellation |
|
||||
|
||||
**Returns:** `Promise<AsyncIterableIterator<StreamingEvent>>`
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const session = await agent.createSession();
|
||||
|
||||
// Simple text streaming
|
||||
for await (const event of await agent.stream('Write a poem', session.id)) {
|
||||
if (event.name === 'llm:chunk') {
|
||||
process.stdout.write(event.content);
|
||||
}
|
||||
if (event.name === 'llm:tool-call') {
|
||||
console.log(`\n[Using ${event.toolName}]\n`);
|
||||
}
|
||||
}
|
||||
|
||||
// Streaming with image
|
||||
for await (const event of await agent.stream([
|
||||
{ type: 'text', text: 'Describe this image' },
|
||||
{ type: 'image', image: base64Image, mimeType: 'image/png' }
|
||||
], session.id)) {
|
||||
if (event.name === 'llm:chunk') {
|
||||
process.stdout.write(event.content);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### `run`
|
||||
|
||||
Lower-level method for direct control. Prefer `generate()` for most use cases.
|
||||
|
||||
```typescript
|
||||
async run(
|
||||
textInput: string,
|
||||
imageDataInput: { image: string; mimeType: string } | undefined,
|
||||
fileDataInput: { data: string; mimeType: string; filename?: string } | undefined,
|
||||
sessionId: string,
|
||||
stream?: boolean
|
||||
): Promise<string>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `textInput` | `string` | User message or query |
|
||||
| `imageDataInput` | `{ image: string; mimeType: string } \| undefined` | Image data or undefined |
|
||||
| `fileDataInput` | `{ data: string; mimeType: string; filename?: string } \| undefined` | File data or undefined |
|
||||
| `sessionId` | `string` | **Required.** Session ID |
|
||||
| `stream` | `boolean` | (Optional) Enable streaming (default: false) |
|
||||
|
||||
**Returns:** `Promise<string>` - AI response text
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const agent = new DextoAgent(config);
|
||||
await agent.start();
|
||||
|
||||
const session = await agent.createSession();
|
||||
|
||||
// Recommended: Use generate() for most use cases
|
||||
const response = await agent.generate(
|
||||
"Explain quantum computing",
|
||||
session.id
|
||||
);
|
||||
console.log(response.content);
|
||||
|
||||
// Lower-level run() method (returns just the text)
|
||||
const responseText = await agent.run(
|
||||
"Explain quantum computing",
|
||||
undefined, // no image
|
||||
undefined, // no file
|
||||
session.id
|
||||
);
|
||||
|
||||
await agent.stop();
|
||||
```
|
||||
|
||||
### `cancel`
|
||||
|
||||
Cancels the currently running turn for a session.
|
||||
|
||||
```typescript
|
||||
async cancel(sessionId: string): Promise<boolean>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | **Required.** Session ID to cancel |
|
||||
|
||||
**Returns:** `Promise<boolean>` - true if a run was in progress and cancelled
|
||||
|
||||
---
|
||||
|
||||
## Session Management
|
||||
|
||||
:::note Architectural Pattern
|
||||
DextoAgent's core is **stateless** and does not track a "current" or "default" session. All session-specific operations require an explicit `sessionId` parameter. Application layers (CLI, WebUI, API servers) are responsible for managing which session is active in their own context.
|
||||
:::
|
||||
|
||||
### `createSession`
|
||||
|
||||
Creates a new conversation session with optional custom ID.
|
||||
|
||||
```typescript
|
||||
async createSession(sessionId?: string): Promise<ChatSession>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | (Optional) Custom session ID |
|
||||
|
||||
**Returns:** `Promise<ChatSession>`
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
// Create a new session (auto-generated ID)
|
||||
const session = await agent.createSession();
|
||||
console.log(`Created session: ${session.id}`);
|
||||
|
||||
// Create a session with custom ID
|
||||
const userSession = await agent.createSession('user-123');
|
||||
|
||||
// Use the session for conversations
|
||||
await agent.generate("Hello!", session.id);
|
||||
```
|
||||
|
||||
### `getSession`
|
||||
|
||||
Retrieves an existing session by its ID.
|
||||
|
||||
```typescript
|
||||
async getSession(sessionId: string): Promise<ChatSession | undefined>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | Session ID to retrieve |
|
||||
|
||||
**Returns:** `Promise<ChatSession | undefined>`
|
||||
|
||||
### `listSessions`
|
||||
|
||||
Returns an array of all active session IDs.
|
||||
|
||||
```typescript
|
||||
async listSessions(): Promise<string[]>
|
||||
```
|
||||
|
||||
**Returns:** `Promise<string[]>` - Array of session IDs
|
||||
|
||||
### `deleteSession`
|
||||
|
||||
Permanently deletes a session and all its conversation history. This action cannot be undone.
|
||||
|
||||
```typescript
|
||||
async deleteSession(sessionId: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | Session ID to delete |
|
||||
|
||||
**Note:** This completely removes the session and all associated conversation data from storage.
|
||||
|
||||
### `resetConversation`
|
||||
|
||||
Clears the conversation history of a session while keeping the session active.
|
||||
|
||||
```typescript
|
||||
async resetConversation(sessionId: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | Session ID to reset |
|
||||
|
||||
### `getSessionMetadata`
|
||||
|
||||
Retrieves metadata for a session including creation time and message count.
|
||||
|
||||
```typescript
|
||||
async getSessionMetadata(sessionId: string): Promise<SessionMetadata | undefined>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | Session ID |
|
||||
|
||||
**Returns:** `Promise<SessionMetadata | undefined>`
|
||||
|
||||
### `getSessionHistory`
|
||||
|
||||
Gets the complete conversation history for a session.
|
||||
|
||||
```typescript
|
||||
async getSessionHistory(sessionId: string): Promise<ConversationHistory>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | Session ID |
|
||||
|
||||
**Returns:** `Promise<ConversationHistory>`
|
||||
|
||||
---
|
||||
|
||||
## Configuration
|
||||
|
||||
### `switchLLM`
|
||||
|
||||
Dynamically changes the LLM configuration for the agent or a specific session.
|
||||
|
||||
```typescript
|
||||
async switchLLM(
|
||||
llmUpdates: LLMUpdates,
|
||||
sessionId?: string
|
||||
): Promise<ValidatedLLMConfig>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `llmUpdates` | `LLMUpdates` | LLM configuration updates (model, provider, apiKey, etc.) |
|
||||
| `sessionId` | `string` | (Optional) Target session ID |
|
||||
|
||||
**Returns:** `Promise<ValidatedLLMConfig>` – the fully validated, effective LLM configuration.
|
||||
|
||||
```typescript
|
||||
const config = await agent.switchLLM({
|
||||
provider: 'anthropic',
|
||||
model: 'claude-sonnet-4-5-20250929'
|
||||
});
|
||||
console.log(config.model);
|
||||
```
|
||||
|
||||
### `getCurrentLLMConfig`
|
||||
|
||||
Returns the base LLM configuration from the agent's initialization config.
|
||||
|
||||
```typescript
|
||||
getCurrentLLMConfig(): LLMConfig
|
||||
```
|
||||
|
||||
**Returns:** `LLMConfig` - The base LLM configuration (does not include session-specific overrides)
|
||||
|
||||
### `getEffectiveConfig`
|
||||
|
||||
Gets the complete effective configuration for a session or the default configuration.
|
||||
|
||||
```typescript
|
||||
getEffectiveConfig(sessionId?: string): Readonly<AgentConfig>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `sessionId` | `string` | (Optional) Session ID |
|
||||
|
||||
**Returns:** `Readonly<AgentConfig>`
|
||||
|
||||
---
|
||||
|
||||
## MCP Server Management
|
||||
|
||||
### `addMcpServer`
|
||||
|
||||
Adds and connects to a new MCP server, making its tools available to the agent.
|
||||
|
||||
```typescript
|
||||
async addMcpServer(name: string, config: McpServerConfig): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `name` | `string` | Server name |
|
||||
| `config` | `McpServerConfig` | Server configuration |
|
||||
|
||||
### `removeMcpServer`
|
||||
|
||||
Disconnects from an MCP server and removes it completely from the agent.
|
||||
|
||||
```typescript
|
||||
async removeMcpServer(name: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `name` | `string` | Server name to remove |
|
||||
|
||||
### `enableMcpServer`
|
||||
|
||||
Enables a disabled MCP server and connects it.
|
||||
|
||||
```typescript
|
||||
async enableMcpServer(name: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `name` | `string` | Server name to enable |
|
||||
|
||||
### `disableMcpServer`
|
||||
|
||||
Disables an MCP server and disconnects it. The server remains registered but inactive.
|
||||
|
||||
```typescript
|
||||
async disableMcpServer(name: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `name` | `string` | Server name to disable |
|
||||
|
||||
### `restartMcpServer`
|
||||
|
||||
Restarts an MCP server by disconnecting and reconnecting with its original configuration.
|
||||
|
||||
```typescript
|
||||
async restartMcpServer(name: string): Promise<void>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `name` | `string` | Server name to restart |
|
||||
|
||||
### `executeTool`
|
||||
|
||||
Executes a tool from any source (MCP servers, custom tools, or internal tools). This is the unified interface for tool execution.
|
||||
|
||||
```typescript
|
||||
async executeTool(toolName: string, args: any): Promise<any>
|
||||
```
|
||||
|
||||
| Parameter | Type | Description |
|
||||
| :--- | :--- | :--- |
|
||||
| `toolName` | `string` | Tool name |
|
||||
| `args` | `any` | Tool arguments |
|
||||
|
||||
**Returns:** `Promise<any>` - Tool execution result
|
||||
|
||||
### `getAllMcpTools`
|
||||
|
||||
Returns a map of all available tools from all connected MCP servers.
|
||||
|
||||
```typescript
|
||||
async getAllMcpTools(): Promise<Record<string, ToolDefinition>>
|
||||
```
|
||||
|
||||
**Returns:** `Promise<Record<string, ToolDefinition>>`
|
||||
|
||||
### `getAllTools`
|
||||
|
||||
Returns a map of all available tools from all sources (MCP servers, custom tools, and internal tools). This is the unified interface for tool discovery.
|
||||
|
||||
```typescript
|
||||
async getAllTools(): Promise<Record<string, ToolDefinition>>
|
||||
```
|
||||
|
||||
**Returns:** `Promise<Record<string, ToolDefinition>>`
|
||||
|
||||
### `getMcpClients`
|
||||
|
||||
Returns a map of all connected MCP client instances.
|
||||
|
||||
```typescript
|
||||
getMcpClients(): Map<string, IMCPClient>
|
||||
```
|
||||
|
||||
**Returns:** `Map<string, IMCPClient>`
|
||||
|
||||
### `getMcpFailedConnections`
|
||||
|
||||
Returns a record of failed MCP server connections and their error messages.
|
||||
|
||||
```typescript
|
||||
getMcpFailedConnections(): Record<string, string>
|
||||
```
|
||||
|
||||
**Returns:** `Record<string, string>` - Failed connection names to error messages
|
||||
|
||||
---
|
||||
|
||||
## Model & Provider Introspection
|
||||
|
||||
### `getSupportedProviders`
|
||||
|
||||
Returns the list of supported LLM providers.
|
||||
|
||||
```typescript
|
||||
getSupportedProviders(): LLMProvider[]
|
||||
```
|
||||
|
||||
### `getSupportedModels`
|
||||
|
||||
Returns supported models grouped by provider, including a flag for the default model per provider.
|
||||
|
||||
```typescript
|
||||
getSupportedModels(): Record<LLMProvider, Array<ModelInfo & { isDefault: boolean }>>
|
||||
```
|
||||
|
||||
### `getSupportedModelsForProvider`
|
||||
|
||||
Returns supported models for a specific provider.
|
||||
|
||||
```typescript
|
||||
getSupportedModelsForProvider(provider: LLMProvider): Array<ModelInfo & { isDefault: boolean }>
|
||||
```
|
||||
|
||||
### `inferProviderFromModel`
|
||||
|
||||
Infers the provider from a model name or returns `null` if unknown.
|
||||
|
||||
```typescript
|
||||
inferProviderFromModel(modelName: string): LLMProvider | null
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Search
|
||||
|
||||
### `searchMessages`
|
||||
|
||||
Search for messages across all sessions or within a specific session.
|
||||
|
||||
```typescript
|
||||
async searchMessages(query: string, options?: SearchOptions): Promise<SearchResponse>
|
||||
```
|
||||
|
||||
### `searchSessions`
|
||||
|
||||
Search for sessions that contain the specified query.
|
||||
|
||||
```typescript
|
||||
async searchSessions(query: string): Promise<SessionSearchResponse>
|
||||
```
|
||||
658
dexto/docs/api/sdk/events.md
Normal file
658
dexto/docs/api/sdk/events.md
Normal file
@@ -0,0 +1,658 @@
|
||||
---
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Events Reference
|
||||
|
||||
Complete event system documentation for monitoring and integrating with Dexto agents.
|
||||
|
||||
## Overview
|
||||
|
||||
The Dexto SDK provides a comprehensive event system through two main event buses:
|
||||
- **AgentEventBus**: Agent-level events that occur across the entire agent instance
|
||||
- **SessionEventBus**: Session-specific events that occur within individual conversation sessions
|
||||
|
||||
### Event Naming Convention
|
||||
|
||||
All events follow the `namespace:kebab-case` format:
|
||||
- **LLM events**: `llm:thinking`, `llm:chunk`, `llm:response`, `llm:tool-call`
|
||||
- **Session events**: `session:created`, `session:reset`, `session:title-updated`
|
||||
- **MCP events**: `mcp:server-connected`, `mcp:resource-updated`
|
||||
- **Approval events**: `approval:request`, `approval:response`
|
||||
- **State events**: `state:changed`, `state:exported`
|
||||
- **Tool events**: `tools:available-updated`
|
||||
|
||||
### Event Visibility Tiers
|
||||
|
||||
Events are organized into three tiers based on their intended audience:
|
||||
|
||||
#### **Tier 1: Streaming Events** (`STREAMING_EVENTS`)
|
||||
Exposed via `DextoAgent.stream()` for real-time chat UIs. These are the most commonly used events for building interactive applications.
|
||||
|
||||
**LLM Events:** `llm:thinking`, `llm:chunk`, `llm:response`, `llm:tool-call`, `llm:tool-result`, `llm:error`, `llm:unsupported-input`
|
||||
|
||||
**Tool Events:** `tool:running`
|
||||
|
||||
**Context Events:** `context:compressed`, `context:pruned`
|
||||
|
||||
**Message Queue Events:** `message:queued`, `message:dequeued`
|
||||
|
||||
**Run Lifecycle Events:** `run:complete`
|
||||
|
||||
**Session Events:** `session:title-updated`
|
||||
|
||||
**Approval Events:** `approval:request`, `approval:response`
|
||||
|
||||
**Use cases:**
|
||||
- Real-time chat interfaces
|
||||
- Progress indicators
|
||||
- Streaming responses
|
||||
- Tool execution tracking
|
||||
- User approval flows
|
||||
|
||||
#### **Tier 2: Integration Events** (`INTEGRATION_EVENTS`)
|
||||
Exposed via webhooks, A2A subscriptions, and monitoring systems. Includes all streaming events plus lifecycle and state management events.
|
||||
|
||||
**Additional events:** `session:created`, `session:reset`, `mcp:server-connected`, `mcp:server-restarted`, `mcp:tools-list-changed`, `mcp:prompts-list-changed`, `tools:available-updated`, `llm:switched`, `state:changed`
|
||||
|
||||
**Use cases:**
|
||||
- External system integrations
|
||||
- Monitoring and observability
|
||||
- Analytics and logging
|
||||
- Multi-agent coordination (A2A)
|
||||
|
||||
#### **Tier 3: Internal Events**
|
||||
Only available via direct `AgentEventBus` access for advanced use cases. These are implementation details that may change between versions.
|
||||
|
||||
**Examples:** `resource:cache-invalidated`, `state:exported`, `state:reset`, `mcp:server-added`, `mcp:server-removed`, `session:override-set`
|
||||
|
||||
---
|
||||
|
||||
## Agent-Level Events
|
||||
|
||||
These events are emitted by the `AgentEventBus` and provide insight into agent-wide operations.
|
||||
|
||||
### Session Events
|
||||
|
||||
#### `session:reset`
|
||||
|
||||
Fired when a conversation history is reset for a session.
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `session:created`
|
||||
|
||||
Fired when a new session is created and should become active.
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
switchTo: boolean; // Whether UI should switch to this session
|
||||
}
|
||||
```
|
||||
|
||||
#### `session:title-updated`
|
||||
|
||||
Fired when a session's human-friendly title is updated.
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
title: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `session:override-set`
|
||||
|
||||
Fired when session-specific configuration is set.
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
override: SessionOverride;
|
||||
}
|
||||
```
|
||||
|
||||
#### `session:override-cleared`
|
||||
|
||||
Fired when session-specific configuration is cleared.
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
### MCP Server Events
|
||||
|
||||
#### `mcp:server-connected`
|
||||
|
||||
Fired when an MCP server connection attempt completes (success or failure).
|
||||
|
||||
```typescript
|
||||
{
|
||||
name: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:server-added`
|
||||
|
||||
Fired when an MCP server is added to the runtime state.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
config: McpServerConfig;
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:server-removed`
|
||||
|
||||
Fired when an MCP server is removed from the runtime state.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:server-updated`
|
||||
|
||||
Fired when an MCP server configuration is updated.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
config: McpServerConfig;
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:server-restarted`
|
||||
|
||||
Fired when an MCP server is restarted.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:resource-updated`
|
||||
|
||||
Fired when an MCP server resource is updated.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
resourceUri: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:prompts-list-changed`
|
||||
|
||||
Fired when available prompts from MCP servers change.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
prompts: string[];
|
||||
}
|
||||
```
|
||||
|
||||
#### `mcp:tools-list-changed`
|
||||
|
||||
Fired when available tools from MCP servers change.
|
||||
|
||||
```typescript
|
||||
{
|
||||
serverName: string;
|
||||
tools: string[];
|
||||
}
|
||||
```
|
||||
|
||||
#### `resource:cache-invalidated`
|
||||
|
||||
Fired when resource cache is invalidated.
|
||||
|
||||
```typescript
|
||||
{
|
||||
resourceUri?: string;
|
||||
serverName: string;
|
||||
action: 'updated' | 'server_connected' | 'server_removed' | 'blob_stored';
|
||||
}
|
||||
```
|
||||
|
||||
#### `tools:available-updated`
|
||||
|
||||
Fired when the available tools list is updated.
|
||||
|
||||
```typescript
|
||||
{
|
||||
tools: string[];
|
||||
source: 'mcp' | 'builtin';
|
||||
}
|
||||
```
|
||||
|
||||
### Configuration Events
|
||||
|
||||
#### `llm:switched`
|
||||
|
||||
Fired when the LLM configuration is changed.
|
||||
|
||||
```typescript
|
||||
{
|
||||
newConfig: LLMConfig;
|
||||
historyRetained?: boolean;
|
||||
sessionIds: string[]; // Array of affected session IDs
|
||||
}
|
||||
```
|
||||
|
||||
#### `state:changed`
|
||||
|
||||
Fired when agent runtime state changes.
|
||||
|
||||
```typescript
|
||||
{
|
||||
field: string; // keyof AgentRuntimeState
|
||||
oldValue: any;
|
||||
newValue: any;
|
||||
sessionId?: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `state:exported`
|
||||
|
||||
Fired when agent state is exported as configuration.
|
||||
|
||||
```typescript
|
||||
{
|
||||
config: AgentConfig;
|
||||
}
|
||||
```
|
||||
|
||||
#### `state:reset`
|
||||
|
||||
Fired when agent state is reset to baseline.
|
||||
|
||||
```typescript
|
||||
{
|
||||
toConfig: AgentConfig;
|
||||
}
|
||||
```
|
||||
|
||||
### User Approval Events
|
||||
|
||||
Dexto's generalized approval system handles various types of user input requests, including tool confirmations and form-based input (elicitation). These events are included in `STREAMING_EVENTS` and are available via `DextoAgent.stream()`.
|
||||
|
||||
:::tip Custom Approval Handlers
|
||||
For direct `DextoAgent` usage without SSE streaming, you can implement a custom approval handler via `agent.setApprovalHandler()` to intercept approval requests programmatically.
|
||||
:::
|
||||
|
||||
#### `approval:request`
|
||||
|
||||
Fired when user approval or input is requested. This event supports multiple approval types through a discriminated union based on the `type` field.
|
||||
|
||||
```typescript
|
||||
{
|
||||
approvalId: string; // Unique identifier for this approval request
|
||||
type: string; // 'tool_confirmation' | 'command_confirmation' | 'elicitation'
|
||||
sessionId?: string; // Optional session scope
|
||||
timeout?: number; // Request timeout in milliseconds
|
||||
timestamp: Date; // When the request was created
|
||||
metadata: Record<string, any>; // Type-specific approval data
|
||||
}
|
||||
```
|
||||
|
||||
**Approval Types:**
|
||||
|
||||
- **`tool_confirmation`**: Binary approval for tool execution
|
||||
- `metadata.toolName`: Name of the tool requiring confirmation
|
||||
- `metadata.args`: Tool arguments
|
||||
- `metadata.description`: Optional tool description
|
||||
|
||||
- **`command_confirmation`**: Binary approval for command execution (e.g., bash commands)
|
||||
- `metadata.command`: Command requiring confirmation
|
||||
- `metadata.args`: Command arguments
|
||||
|
||||
- **`elicitation`**: Schema-based form input (typically from MCP servers or ask_user tool)
|
||||
- `metadata.schema`: JSON Schema defining expected input structure
|
||||
- `metadata.prompt`: Prompt text to display to user
|
||||
- `metadata.serverName`: Name of requesting entity (MCP server or 'Dexto Agent')
|
||||
- `metadata.context`: Optional additional context
|
||||
|
||||
#### `approval:response`
|
||||
|
||||
Fired when a user approval response is received from the UI layer.
|
||||
|
||||
```typescript
|
||||
{
|
||||
approvalId: string; // Must match the request approvalId
|
||||
status: 'approved' | 'denied' | 'cancelled'; // Approval status
|
||||
reason?: DenialReason; // Reason for denial/cancellation
|
||||
message?: string; // Optional user message
|
||||
sessionId?: string; // Session identifier (if scoped)
|
||||
data?: Record<string, any>; // Type-specific response data
|
||||
}
|
||||
```
|
||||
|
||||
**Response Data by Type:**
|
||||
|
||||
- **Tool confirmation**: `{ rememberChoice?: boolean }`
|
||||
- **Command confirmation**: `{ rememberChoice?: boolean }`
|
||||
- **Elicitation**: `{ formData: Record<string, unknown> }`
|
||||
|
||||
**Usage Notes:**
|
||||
|
||||
- Agent-initiated forms use `ask_user` tool → triggers elicitation request
|
||||
- MCP server input requests trigger elicitation automatically
|
||||
- Tool confirmations can be remembered per session via `rememberChoice`
|
||||
- Approval requests timeout based on configuration (default: 2 minutes)
|
||||
- Cancelled status indicates timeout or explicit cancellation
|
||||
|
||||
---
|
||||
|
||||
## Session-Level Events
|
||||
|
||||
These events are emitted by the `SessionEventBus` and provide insight into LLM service operations within sessions. They are automatically forwarded to the `AgentEventBus` with a `sessionId` property.
|
||||
|
||||
### LLM Processing Events
|
||||
|
||||
#### `llm:thinking`
|
||||
|
||||
Fired when the LLM service starts processing a request.
|
||||
|
||||
```typescript
|
||||
{
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `llm:response`
|
||||
|
||||
Fired when the LLM service completes a response.
|
||||
|
||||
```typescript
|
||||
{
|
||||
content: string;
|
||||
reasoning?: string; // Extended thinking output for reasoning models
|
||||
provider?: string;
|
||||
model?: string;
|
||||
tokenUsage?: {
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
reasoningTokens?: number; // Additional tokens used for reasoning
|
||||
totalTokens?: number;
|
||||
};
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The `reasoning` field contains extended thinking output for models that support reasoning (e.g., o1, o3-mini). This is separate from the main `content` response.
|
||||
|
||||
#### `llm:chunk`
|
||||
|
||||
Fired when a streaming response chunk is received.
|
||||
|
||||
```typescript
|
||||
{
|
||||
chunkType: 'text' | 'reasoning'; // Indicates whether chunk is reasoning or main response
|
||||
content: string;
|
||||
isComplete?: boolean;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The `chunkType` field distinguishes between reasoning output (`reasoning`) and the main response text (`text`). For reasoning models, you'll receive reasoning chunks followed by text chunks.
|
||||
|
||||
#### `llm:error`
|
||||
|
||||
Fired when the LLM service encounters an error.
|
||||
|
||||
```typescript
|
||||
{
|
||||
error: Error;
|
||||
context?: string;
|
||||
recoverable?: boolean;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `llm:switched`
|
||||
|
||||
Fired when session LLM configuration is changed.
|
||||
|
||||
```typescript
|
||||
{
|
||||
newConfig: LLMConfig;
|
||||
historyRetained?: boolean;
|
||||
sessionIds: string[]; // Array of affected session IDs
|
||||
}
|
||||
```
|
||||
|
||||
#### `llm:unsupported-input`
|
||||
|
||||
Fired when the LLM service receives unsupported input.
|
||||
|
||||
```typescript
|
||||
{
|
||||
errors: string[];
|
||||
provider: LLMProvider;
|
||||
model?: string;
|
||||
fileType?: string;
|
||||
details?: any;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Tool Execution Events
|
||||
|
||||
#### `llm:tool-call`
|
||||
|
||||
Fired when the LLM service requests a tool execution.
|
||||
|
||||
```typescript
|
||||
{
|
||||
toolName: string;
|
||||
args: Record<string, any>;
|
||||
callId?: string;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `tool:running`
|
||||
|
||||
Fired when a tool actually starts executing (after approval if required). This allows UIs to distinguish between tools pending approval and tools actively running.
|
||||
|
||||
```typescript
|
||||
{
|
||||
toolName: string;
|
||||
toolCallId: string;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `llm:tool-result`
|
||||
|
||||
Fired when a tool execution completes.
|
||||
|
||||
```typescript
|
||||
{
|
||||
toolName: string;
|
||||
sanitized: SanitizedToolResult;
|
||||
rawResult?: unknown; // only present when DEXTO_DEBUG_TOOL_RESULT_RAW=true
|
||||
callId?: string;
|
||||
success: boolean;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Context Management Events
|
||||
|
||||
#### `context:compressed`
|
||||
|
||||
Fired when conversation context is compressed to stay within token limits.
|
||||
|
||||
```typescript
|
||||
{
|
||||
originalTokens: number; // Actual input tokens that triggered compression
|
||||
compressedTokens: number; // Estimated tokens after compression
|
||||
originalMessages: number;
|
||||
compressedMessages: number;
|
||||
strategy: string;
|
||||
reason: 'overflow' | 'token_limit' | 'message_limit';
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `context:pruned`
|
||||
|
||||
Fired when old messages are pruned from context.
|
||||
|
||||
```typescript
|
||||
{
|
||||
prunedCount: number;
|
||||
savedTokens: number;
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Message Queue Events
|
||||
|
||||
These events track the message queue system, which allows users to queue additional messages while the agent is processing.
|
||||
|
||||
#### `message:queued`
|
||||
|
||||
Fired when a user message is queued during agent execution.
|
||||
|
||||
```typescript
|
||||
{
|
||||
position: number; // Position in the queue
|
||||
id: string; // Unique message ID
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
#### `message:dequeued`
|
||||
|
||||
Fired when queued messages are dequeued and injected into context.
|
||||
|
||||
```typescript
|
||||
{
|
||||
count: number; // Number of messages dequeued
|
||||
ids: string[]; // IDs of dequeued messages
|
||||
coalesced: boolean; // Whether messages were combined
|
||||
content: ContentPart[]; // Combined content for UI display
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
### Run Lifecycle Events
|
||||
|
||||
#### `run:complete`
|
||||
|
||||
Fired when an agent run completes, providing summary information about the execution.
|
||||
|
||||
```typescript
|
||||
{
|
||||
finishReason: LLMFinishReason; // How the run ended
|
||||
stepCount: number; // Number of steps executed
|
||||
durationMs: number; // Wall-clock duration in milliseconds
|
||||
error?: Error; // Error if finishReason === 'error'
|
||||
sessionId: string;
|
||||
}
|
||||
```
|
||||
|
||||
**Finish Reasons:**
|
||||
- `stop` - Normal completion
|
||||
- `tool-calls` - Stopped to execute tool calls (more steps coming)
|
||||
- `length` - Hit token/length limit
|
||||
- `content-filter` - Content filter violation
|
||||
- `error` - Error occurred
|
||||
- `cancelled` - User cancelled
|
||||
- `max-steps` - Hit max steps limit
|
||||
|
||||
---
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Listening to Streaming Events
|
||||
|
||||
```typescript
|
||||
import { DextoAgent } from '@dexto/core';
|
||||
|
||||
const agent = new DextoAgent(config);
|
||||
await agent.start();
|
||||
|
||||
// Use the stream() API to get streaming events
|
||||
for await (const event of await agent.stream('Hello!', 'session-1')) {
|
||||
switch (event.name) {
|
||||
case 'llm:thinking':
|
||||
console.log('Agent is thinking...');
|
||||
break;
|
||||
case 'llm:chunk':
|
||||
process.stdout.write(event.content);
|
||||
break;
|
||||
case 'llm:response':
|
||||
console.log('\nFull response:', event.content);
|
||||
console.log('Tokens used:', event.tokenUsage);
|
||||
break;
|
||||
case 'llm:tool-call':
|
||||
console.log(`Calling tool: ${event.toolName}`);
|
||||
break;
|
||||
case 'tool:running':
|
||||
console.log(`Tool ${event.toolName} is now running`);
|
||||
break;
|
||||
case 'run:complete':
|
||||
console.log(`Run completed: ${event.finishReason} (${event.stepCount} steps, ${event.durationMs}ms)`);
|
||||
break;
|
||||
case 'approval:request':
|
||||
console.log(`Approval needed: ${event.type}`);
|
||||
// Handle approval UI...
|
||||
break;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Listening to Integration Events
|
||||
|
||||
```typescript
|
||||
import { DextoAgent, INTEGRATION_EVENTS } from '@dexto/core';
|
||||
|
||||
const agent = new DextoAgent(config);
|
||||
await agent.start();
|
||||
|
||||
// Listen to all integration events via the event bus
|
||||
INTEGRATION_EVENTS.forEach((eventName) => {
|
||||
agent.agentEventBus.on(eventName, (payload) => {
|
||||
console.log(`[${eventName}]`, payload);
|
||||
|
||||
// Send to your monitoring/analytics system
|
||||
sendToMonitoring(eventName, payload);
|
||||
});
|
||||
});
|
||||
```
|
||||
|
||||
### Listening to Internal Events
|
||||
|
||||
```typescript
|
||||
import { DextoAgent } from '@dexto/core';
|
||||
|
||||
const agent = new DextoAgent(config);
|
||||
await agent.start();
|
||||
|
||||
// Listen to internal events for advanced debugging
|
||||
agent.agentEventBus.on('resource:cache-invalidated', (payload) => {
|
||||
console.log('Cache invalidated:', payload);
|
||||
});
|
||||
|
||||
agent.agentEventBus.on('state:exported', (payload) => {
|
||||
console.log('State exported:', payload.config);
|
||||
});
|
||||
```
|
||||
|
||||
415
dexto/docs/api/sdk/mcp-manager.md
Normal file
415
dexto/docs/api/sdk/mcp-manager.md
Normal file
@@ -0,0 +1,415 @@
|
||||
---
|
||||
sidebar_position: 2
|
||||
title: "MCPManager"
|
||||
---
|
||||
|
||||
# MCPManager
|
||||
|
||||
The `MCPManager` is a powerful, standalone utility for managing [Model Context Protocol (MCP)](/docs/mcp/overview) servers. It allows you to connect, manage, and interact with multiple MCP servers in your own applications without needing the full Dexto agent framework.
|
||||
|
||||
This class provides a unified interface for accessing tools, resources, and prompts from all connected servers, making it an essential component for building complex, multi-server workflows.
|
||||
|
||||
## Constructor
|
||||
|
||||
```typescript
|
||||
constructor(confirmationProvider?: ToolConfirmationProvider)
|
||||
```
|
||||
|
||||
Creates a new `MCPManager` instance for managing MCP server connections.
|
||||
|
||||
**Parameters:**
|
||||
- `confirmationProvider` (optional): A custom tool confirmation provider. If not provided, a default CLI-based confirmation is used.
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
import { MCPManager } from '@dexto/core';
|
||||
|
||||
// Basic manager
|
||||
const manager = new MCPManager();
|
||||
|
||||
// With a custom confirmation provider
|
||||
const customProvider = new CustomConfirmationProvider();
|
||||
const managerWithProvider = new MCPManager(customProvider);
|
||||
```
|
||||
|
||||
## Connection Management Methods
|
||||
|
||||
#### `connectServer`
|
||||
|
||||
Connects to a new MCP server.
|
||||
|
||||
```typescript
|
||||
async connectServer(name: string, config: McpServerConfig): Promise<void>
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `name`: Unique identifier for the server connection
|
||||
- `config`: Server configuration object
|
||||
|
||||
**Server Configuration Types:**
|
||||
|
||||
```typescript
|
||||
// stdio server (most common)
|
||||
{
|
||||
type: 'stdio',
|
||||
command: 'npx',
|
||||
args: ['-y', '@modelcontextprotocol/server-filesystem', '.'],
|
||||
env?: { [key: string]: string }
|
||||
}
|
||||
|
||||
// HTTP server (recommended for remote)
|
||||
{
|
||||
type: 'http',
|
||||
url: 'http://localhost:3001/mcp',
|
||||
headers?: { [key: string]: string },
|
||||
timeout?: number,
|
||||
connectionMode?: 'strict' | 'lenient'
|
||||
}
|
||||
|
||||
// SSE (Server-Sent Events) server - DEPRECATED, use http instead
|
||||
{
|
||||
type: 'sse',
|
||||
url: 'http://localhost:3001/sse',
|
||||
headers?: { [key: string]: string },
|
||||
timeout?: number,
|
||||
connectionMode?: 'strict' | 'lenient'
|
||||
}
|
||||
```
|
||||
|
||||
**Examples:**
|
||||
|
||||
```typescript
|
||||
// File system server
|
||||
await manager.connectServer('filesystem', {
|
||||
type: 'stdio',
|
||||
command: 'npx',
|
||||
args: ['-y', '@modelcontextprotocol/server-filesystem', '.']
|
||||
});
|
||||
|
||||
// Web search server with API key
|
||||
await manager.connectServer('tavily-search', {
|
||||
type: 'stdio',
|
||||
command: 'npx',
|
||||
args: ['-y', 'tavily-mcp@0.1.2'],
|
||||
env: {
|
||||
TAVILY_API_KEY: process.env.TAVILY_API_KEY
|
||||
}
|
||||
});
|
||||
|
||||
// HTTP MCP server
|
||||
await manager.connectServer('remote-agent', {
|
||||
type: 'http',
|
||||
baseUrl: 'http://localhost:3001/mcp',
|
||||
timeout: 30000
|
||||
});
|
||||
```
|
||||
|
||||
#### `initializeFromConfig`
|
||||
|
||||
Initialize multiple servers from configuration.
|
||||
|
||||
```typescript
|
||||
async initializeFromConfig(
|
||||
serverConfigs: ServerConfigs,
|
||||
connectionMode: 'strict' | 'lenient' = 'lenient'
|
||||
): Promise<void>
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `serverConfigs`: Object mapping server names to configurations
|
||||
- `connectionMode`:
|
||||
- `'strict'`: All servers must connect successfully
|
||||
- `'lenient'`: At least one server must connect successfully
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const serverConfigs = {
|
||||
filesystem: {
|
||||
type: 'stdio',
|
||||
command: 'npx',
|
||||
args: ['-y', '@modelcontextprotocol/server-filesystem', '.']
|
||||
},
|
||||
search: {
|
||||
type: 'stdio',
|
||||
command: 'npx',
|
||||
args: ['-y', 'tavily-mcp@0.1.2'],
|
||||
env: { TAVILY_API_KEY: process.env.TAVILY_API_KEY }
|
||||
}
|
||||
};
|
||||
|
||||
await manager.initializeFromConfig(serverConfigs, 'lenient');
|
||||
```
|
||||
|
||||
#### `removeClient`
|
||||
|
||||
Disconnects and removes a specific MCP server.
|
||||
|
||||
```typescript
|
||||
async removeClient(name: string): Promise<void>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
await manager.removeClient('filesystem');
|
||||
```
|
||||
|
||||
#### `disconnectAll`
|
||||
|
||||
Disconnect all servers and clear caches.
|
||||
|
||||
```typescript
|
||||
async disconnectAll(): Promise<void>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
await manager.disconnectAll();
|
||||
```
|
||||
|
||||
#### `restartServer`
|
||||
|
||||
Restart a specific MCP server by disconnecting and reconnecting with its original configuration.
|
||||
|
||||
```typescript
|
||||
async restartServer(name: string): Promise<void>
|
||||
```
|
||||
|
||||
**Parameters:**
|
||||
- `name`: The name of the server to restart
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
// Restart a server after it becomes unresponsive
|
||||
await manager.restartServer('filesystem');
|
||||
```
|
||||
|
||||
#### `refresh`
|
||||
|
||||
Refresh all tool, resource, and prompt caches from connected servers.
|
||||
|
||||
```typescript
|
||||
async refresh(): Promise<void>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
// Force refresh all caches after external changes
|
||||
await manager.refresh();
|
||||
```
|
||||
|
||||
## Tool Management Methods
|
||||
|
||||
#### `getAllTools`
|
||||
|
||||
Gets all available tools from connected servers.
|
||||
|
||||
```typescript
|
||||
async getAllTools(): Promise<ToolSet>
|
||||
```
|
||||
|
||||
**Returns:** Object mapping tool names to tool definitions
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const tools = await manager.getAllTools();
|
||||
console.log('Available tools:', Object.keys(tools));
|
||||
|
||||
// Inspect a specific tool
|
||||
const readFileTool = tools.readFile;
|
||||
console.log('Tool schema:', readFileTool.inputSchema);
|
||||
```
|
||||
|
||||
#### `getToolClient`
|
||||
|
||||
Get the client that provides a specific tool.
|
||||
|
||||
```typescript
|
||||
getToolClient(toolName: string): IMCPClient | undefined
|
||||
```
|
||||
|
||||
#### `executeTool`
|
||||
|
||||
Executes a specific tool with arguments.
|
||||
|
||||
```typescript
|
||||
async executeTool(toolName: string, args: any): Promise<any>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
// Read a file
|
||||
const content = await manager.executeTool('readFile', {
|
||||
path: './package.json'
|
||||
});
|
||||
|
||||
// Search the web
|
||||
const searchResults = await manager.executeTool('search', {
|
||||
query: 'latest AI developments',
|
||||
max_results: 5
|
||||
});
|
||||
|
||||
// Write a file
|
||||
await manager.executeTool('writeFile', {
|
||||
path: './output.txt',
|
||||
content: 'Hello from MCP!'
|
||||
});
|
||||
```
|
||||
|
||||
## Resource Management Methods
|
||||
|
||||
#### `listAllResources`
|
||||
|
||||
Gets all cached MCP resources from connected servers.
|
||||
|
||||
```typescript
|
||||
async listAllResources(): Promise<MCPResolvedResource[]>
|
||||
```
|
||||
|
||||
**Returns:** Array of resolved resources with metadata:
|
||||
|
||||
```typescript
|
||||
interface MCPResolvedResource {
|
||||
key: string; // Qualified resource key
|
||||
serverName: string; // Server that provides this resource
|
||||
summary: MCPResourceSummary;
|
||||
}
|
||||
```
|
||||
|
||||
#### `getResource`
|
||||
|
||||
Get cached resource metadata by qualified key.
|
||||
|
||||
```typescript
|
||||
getResource(resourceKey: string): MCPResolvedResource | undefined
|
||||
```
|
||||
|
||||
#### `readResource`
|
||||
|
||||
Reads a specific resource by URI.
|
||||
|
||||
```typescript
|
||||
async readResource(uri: string): Promise<ReadResourceResult>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const resource = await manager.readResource('file:///project/README.md');
|
||||
console.log('Resource content:', resource.contents);
|
||||
```
|
||||
|
||||
## Prompt Management Methods
|
||||
|
||||
#### `listAllPrompts`
|
||||
|
||||
Gets all available prompt names from connected servers.
|
||||
|
||||
```typescript
|
||||
async listAllPrompts(): Promise<string[]>
|
||||
```
|
||||
|
||||
#### `getPromptClient`
|
||||
|
||||
Get the client that provides a specific prompt.
|
||||
|
||||
```typescript
|
||||
getPromptClient(promptName: string): IMCPClient | undefined
|
||||
```
|
||||
|
||||
#### `getPrompt`
|
||||
|
||||
Gets a specific prompt by name.
|
||||
|
||||
```typescript
|
||||
async getPrompt(name: string, args?: any): Promise<GetPromptResult>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const prompt = await manager.getPrompt('code-review', {
|
||||
language: 'typescript',
|
||||
file: 'src/index.ts'
|
||||
});
|
||||
console.log('Prompt:', prompt.messages);
|
||||
```
|
||||
|
||||
#### `getPromptMetadata`
|
||||
|
||||
Get cached metadata for a specific prompt (no network calls).
|
||||
|
||||
```typescript
|
||||
getPromptMetadata(promptName: string): PromptDefinition | undefined
|
||||
```
|
||||
|
||||
#### `getAllPromptMetadata`
|
||||
|
||||
Get all cached prompt metadata (no network calls).
|
||||
|
||||
```typescript
|
||||
getAllPromptMetadata(): Array<{
|
||||
promptName: string;
|
||||
serverName: string;
|
||||
definition: PromptDefinition;
|
||||
}>
|
||||
```
|
||||
|
||||
## Status and Monitoring Methods
|
||||
|
||||
#### `getClients`
|
||||
|
||||
Returns all registered MCP client instances.
|
||||
|
||||
```typescript
|
||||
getClients(): Map<string, IMCPClient>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const clients = manager.getClients();
|
||||
console.log('Connected servers:', Array.from(clients.keys()));
|
||||
|
||||
for (const [name, client] of clients) {
|
||||
console.log(`Server: ${name}, Tools available: ${Object.keys(await client.getTools()).length}`);
|
||||
}
|
||||
```
|
||||
|
||||
#### `getFailedConnections`
|
||||
|
||||
Returns failed connection error messages.
|
||||
|
||||
```typescript
|
||||
getFailedConnections(): Record<string, string>
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```typescript
|
||||
const errors = manager.getFailedConnections();
|
||||
if (Object.keys(errors).length > 0) {
|
||||
console.log('Failed connections:', errors);
|
||||
}
|
||||
```
|
||||
|
||||
### Complete Example
|
||||
|
||||
```typescript
|
||||
import { MCPManager } from '@dexto/core';
|
||||
|
||||
const manager = new MCPManager();
|
||||
|
||||
// Connect to servers
|
||||
await manager.connectServer('filesystem', {
|
||||
type: 'stdio',
|
||||
command: 'npx',
|
||||
args: ['-y', '@modelcontextprotocol/server-filesystem', '.']
|
||||
});
|
||||
|
||||
// Execute tools directly
|
||||
const result = await manager.executeTool('readFile', { path: './README.md' });
|
||||
console.log('Read file result:', result);
|
||||
|
||||
// Get all available tools
|
||||
const tools = await manager.getAllTools();
|
||||
console.log('Available tools:', Object.keys(tools));
|
||||
|
||||
// Clean up
|
||||
await manager.disconnectAll();
|
||||
```
|
||||
685
dexto/docs/api/sdk/types.md
Normal file
685
dexto/docs/api/sdk/types.md
Normal file
@@ -0,0 +1,685 @@
|
||||
---
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
# SDK Types for TypeScript
|
||||
|
||||
Type definitions and interfaces for the Dexto Agent SDK for TypeScript.
|
||||
|
||||
## Core Imports
|
||||
|
||||
```typescript
|
||||
import {
|
||||
// Main classes
|
||||
DextoAgent,
|
||||
|
||||
// Standalone utilities
|
||||
MCPManager,
|
||||
Logger,
|
||||
AgentEventBus,
|
||||
SessionEventBus,
|
||||
createStorageBackends,
|
||||
createAgentServices,
|
||||
|
||||
// Configuration types
|
||||
AgentConfig,
|
||||
LLMConfig,
|
||||
McpServerConfig,
|
||||
StorageConfig,
|
||||
|
||||
// Session types
|
||||
ChatSession,
|
||||
SessionMetadata,
|
||||
ConversationHistory,
|
||||
|
||||
// Result types
|
||||
ValidatedLLMConfig,
|
||||
|
||||
// Event types
|
||||
AgentEventMap,
|
||||
SessionEventMap,
|
||||
|
||||
// Storage types
|
||||
StorageBackends,
|
||||
CacheBackend,
|
||||
DatabaseBackend,
|
||||
|
||||
// Service types
|
||||
AgentServices,
|
||||
} from '@dexto/core';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Configuration Types
|
||||
|
||||
### `AgentConfig`
|
||||
|
||||
Main configuration object for creating Dexto agents.
|
||||
|
||||
```typescript
|
||||
interface AgentConfig {
|
||||
llm: LLMConfig;
|
||||
mcpServers?: Record<string, McpServerConfig>;
|
||||
storage?: StorageConfig;
|
||||
sessions?: SessionConfig;
|
||||
systemPrompt?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### `LLMConfig`
|
||||
|
||||
Configuration for Large Language Model providers.
|
||||
|
||||
```typescript
|
||||
interface LLMConfig {
|
||||
provider: 'openai' | 'anthropic' | 'google' | 'groq' | 'xai' | 'cohere' | 'openai-compatible';
|
||||
model: string;
|
||||
apiKey?: string;
|
||||
baseURL?: string;
|
||||
temperature?: number;
|
||||
maxOutputTokens?: number;
|
||||
maxInputTokens?: number;
|
||||
maxIterations?: number;
|
||||
systemPrompt?: string;
|
||||
}
|
||||
```
|
||||
|
||||
### `McpServerConfig`
|
||||
|
||||
Configuration for Model Context Protocol servers.
|
||||
|
||||
```typescript
|
||||
interface McpServerConfig {
|
||||
type: 'stdio' | 'sse' | 'http';
|
||||
command?: string; // Required for stdio
|
||||
args?: string[]; // For stdio
|
||||
env?: Record<string, string>; // For stdio
|
||||
url?: string; // Required for sse/http
|
||||
headers?: Record<string, string>; // For sse/http
|
||||
timeout?: number; // Default: 30000
|
||||
connectionMode?: 'strict' | 'lenient'; // Default: 'lenient'
|
||||
}
|
||||
```
|
||||
|
||||
### `StorageConfig`
|
||||
|
||||
Configuration for storage backends.
|
||||
|
||||
```typescript
|
||||
interface StorageConfig {
|
||||
cache: CacheBackendConfig;
|
||||
database: DatabaseBackendConfig;
|
||||
}
|
||||
|
||||
interface CacheBackendConfig {
|
||||
type: 'in-memory' | 'redis';
|
||||
url?: string;
|
||||
options?: Record<string, any>;
|
||||
}
|
||||
|
||||
interface DatabaseBackendConfig {
|
||||
type: 'in-memory' | 'sqlite' | 'postgresql';
|
||||
url?: string;
|
||||
options?: Record<string, any>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Session Types
|
||||
|
||||
### `ChatSession`
|
||||
|
||||
Represents an individual conversation session.
|
||||
|
||||
```typescript
|
||||
interface ChatSession {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
lastActivity: Date;
|
||||
|
||||
// Session methods
|
||||
run(userInput: string, imageData?: ImageData): Promise<string>;
|
||||
getHistory(): Promise<ConversationHistory>;
|
||||
reset(): Promise<void>;
|
||||
getLLMService(): VercelLLMService;
|
||||
}
|
||||
```
|
||||
|
||||
### `SessionMetadata`
|
||||
|
||||
Metadata information about a session.
|
||||
|
||||
```typescript
|
||||
interface SessionMetadata {
|
||||
id: string;
|
||||
createdAt: Date;
|
||||
lastActivity: Date;
|
||||
messageCount: number;
|
||||
tokenCount?: number;
|
||||
}
|
||||
```
|
||||
|
||||
### `ConversationHistory`
|
||||
|
||||
Complete conversation history for a session.
|
||||
|
||||
```typescript
|
||||
interface ConversationHistory {
|
||||
sessionId: string;
|
||||
messages: ConversationMessage[];
|
||||
totalTokens?: number;
|
||||
}
|
||||
|
||||
interface ConversationMessage {
|
||||
role: 'user' | 'assistant' | 'system' | 'tool';
|
||||
content: string;
|
||||
timestamp: Date;
|
||||
tokenCount?: number;
|
||||
toolCall?: ToolCall;
|
||||
toolResult?: ToolResult;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Result Types
|
||||
|
||||
### `ValidatedLLMConfig`
|
||||
|
||||
Validated LLM configuration returned by `switchLLM`.
|
||||
|
||||
```typescript
|
||||
type ValidatedLLMConfig = LLMConfig & {
|
||||
maxInputTokens?: number;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Event Types
|
||||
|
||||
:::info Event Naming Convention
|
||||
All events use the `namespace:kebab-case` format. For detailed event documentation and usage examples, see the [Events Reference](./events.md).
|
||||
:::
|
||||
|
||||
### `AgentEventMap`
|
||||
|
||||
Type map for agent-level events. All event names follow the `namespace:kebab-case` convention.
|
||||
|
||||
```typescript
|
||||
interface AgentEventMap {
|
||||
// Session events
|
||||
'session:reset': {
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'session:created': {
|
||||
sessionId: string;
|
||||
switchTo: boolean; // Whether UI should switch to this session
|
||||
};
|
||||
|
||||
'session:title-updated': {
|
||||
sessionId: string;
|
||||
title: string;
|
||||
};
|
||||
|
||||
'session:override-set': {
|
||||
sessionId: string;
|
||||
override: SessionOverride;
|
||||
};
|
||||
|
||||
'session:override-cleared': {
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
// MCP server events
|
||||
'mcp:server-connected': {
|
||||
name: string;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
};
|
||||
|
||||
'mcp:server-added': {
|
||||
serverName: string;
|
||||
config: McpServerConfig;
|
||||
};
|
||||
|
||||
'mcp:server-removed': {
|
||||
serverName: string;
|
||||
};
|
||||
|
||||
'mcp:server-updated': {
|
||||
serverName: string;
|
||||
config: McpServerConfig;
|
||||
};
|
||||
|
||||
'mcp:server-restarted': {
|
||||
serverName: string;
|
||||
};
|
||||
|
||||
'mcp:resource-updated': {
|
||||
serverName: string;
|
||||
resourceUri: string;
|
||||
};
|
||||
|
||||
'mcp:prompts-list-changed': {
|
||||
serverName: string;
|
||||
prompts: string[];
|
||||
};
|
||||
|
||||
'mcp:tools-list-changed': {
|
||||
serverName: string;
|
||||
tools: string[];
|
||||
};
|
||||
|
||||
'resource:cache-invalidated': {
|
||||
resourceUri?: string;
|
||||
serverName: string;
|
||||
action: 'updated' | 'server_connected' | 'server_removed' | 'blob_stored';
|
||||
};
|
||||
|
||||
'tools:available-updated': {
|
||||
tools: string[];
|
||||
source: 'mcp' | 'builtin';
|
||||
};
|
||||
|
||||
// Configuration events
|
||||
'llm:switched': {
|
||||
newConfig: ValidatedLLMConfig;
|
||||
historyRetained?: boolean;
|
||||
sessionIds: string[]; // Array of affected session IDs
|
||||
};
|
||||
|
||||
'state:changed': {
|
||||
field: string;
|
||||
oldValue: any;
|
||||
newValue: any;
|
||||
sessionId?: string;
|
||||
};
|
||||
|
||||
'state:exported': {
|
||||
config: AgentConfig;
|
||||
};
|
||||
|
||||
'state:reset': {
|
||||
toConfig: AgentConfig;
|
||||
};
|
||||
|
||||
// Approval events
|
||||
'approval:request': {
|
||||
approvalId: string;
|
||||
approvalType: 'tool_confirmation' | 'elicitation' | 'custom';
|
||||
sessionId?: string;
|
||||
timeout?: number;
|
||||
timestamp: Date;
|
||||
metadata: Record<string, any>;
|
||||
};
|
||||
|
||||
'approval:response': {
|
||||
approvalId: string;
|
||||
status: 'approved' | 'denied' | 'cancelled';
|
||||
reason?: DenialReason;
|
||||
message?: string;
|
||||
sessionId?: string;
|
||||
data?: Record<string, any>;
|
||||
};
|
||||
|
||||
// LLM service events (forwarded from sessions with sessionId)
|
||||
'llm:thinking': {
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'llm:response': {
|
||||
content: string;
|
||||
reasoning?: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
tokenUsage?: {
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
reasoningTokens?: number;
|
||||
totalTokens?: number;
|
||||
};
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'llm:chunk': {
|
||||
chunkType: 'text' | 'reasoning'; // Note: renamed from 'type' to avoid conflicts
|
||||
content: string;
|
||||
isComplete?: boolean;
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'llm:tool-call': {
|
||||
toolName: string;
|
||||
args: Record<string, any>;
|
||||
callId?: string;
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'llm:tool-result': {
|
||||
toolName: string;
|
||||
sanitized: SanitizedToolResult;
|
||||
rawResult?: unknown;
|
||||
callId?: string;
|
||||
success: boolean;
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'llm:error': {
|
||||
error: Error;
|
||||
context?: string;
|
||||
recoverable?: boolean;
|
||||
sessionId: string;
|
||||
};
|
||||
|
||||
'llm:unsupported-input': {
|
||||
errors: string[];
|
||||
provider: LLMProvider;
|
||||
model?: string;
|
||||
fileType?: string;
|
||||
details?: any;
|
||||
sessionId: string;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### `SessionEventMap`
|
||||
|
||||
Type map for session-level events. These events are emitted within individual chat sessions and are automatically forwarded to the `AgentEventBus` with a `sessionId` property.
|
||||
|
||||
```typescript
|
||||
interface SessionEventMap {
|
||||
'llm:thinking': void;
|
||||
|
||||
'llm:response': {
|
||||
content: string;
|
||||
reasoning?: string;
|
||||
provider?: string;
|
||||
model?: string;
|
||||
tokenUsage?: {
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
reasoningTokens?: number;
|
||||
totalTokens?: number;
|
||||
};
|
||||
};
|
||||
|
||||
'llm:chunk': {
|
||||
chunkType: 'text' | 'reasoning';
|
||||
content: string;
|
||||
isComplete?: boolean;
|
||||
};
|
||||
|
||||
'llm:tool-call': {
|
||||
toolName: string;
|
||||
args: Record<string, any>;
|
||||
callId?: string;
|
||||
};
|
||||
|
||||
'llm:tool-result': {
|
||||
toolName: string;
|
||||
sanitized: SanitizedToolResult;
|
||||
rawResult?: unknown;
|
||||
callId?: string;
|
||||
success: boolean;
|
||||
};
|
||||
|
||||
'llm:error': {
|
||||
error: Error;
|
||||
context?: string;
|
||||
recoverable?: boolean;
|
||||
};
|
||||
|
||||
'llm:switched': {
|
||||
newConfig: ValidatedLLMConfig;
|
||||
historyRetained?: boolean;
|
||||
sessionIds: string[];
|
||||
};
|
||||
|
||||
'llm:unsupported-input': {
|
||||
errors: string[];
|
||||
provider: LLMProvider;
|
||||
model?: string;
|
||||
fileType?: string;
|
||||
details?: any;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Event Tier Types
|
||||
|
||||
```typescript
|
||||
// Tier 1: Events exposed via DextoAgent.stream()
|
||||
export type StreamingEventName =
|
||||
| 'llm:thinking'
|
||||
| 'llm:chunk'
|
||||
| 'llm:response'
|
||||
| 'llm:tool-call'
|
||||
| 'llm:tool-result'
|
||||
| 'llm:error'
|
||||
| 'llm:unsupported-input'
|
||||
| 'approval:request'
|
||||
| 'approval:response'
|
||||
| 'session:title-updated';
|
||||
|
||||
// Tier 2: Events exposed via webhooks, A2A, and monitoring
|
||||
export type IntegrationEventName = StreamingEventName
|
||||
| 'session:created'
|
||||
| 'session:reset'
|
||||
| 'mcp:server-connected'
|
||||
| 'mcp:server-restarted'
|
||||
| 'mcp:tools-list-changed'
|
||||
| 'mcp:prompts-list-changed'
|
||||
| 'tools:available-updated'
|
||||
| 'llm:switched'
|
||||
| 'state:changed';
|
||||
|
||||
// Union types with payloads
|
||||
// Note: Uses 'name' (not 'type') to avoid collision with ApprovalRequest.type payload field
|
||||
export type StreamingEvent = {
|
||||
[K in StreamingEventName]: { name: K } & AgentEventMap[K];
|
||||
}[StreamingEventName];
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Storage Types
|
||||
|
||||
### `StorageBackends`
|
||||
|
||||
Container for storage backend instances.
|
||||
|
||||
```typescript
|
||||
interface StorageBackends {
|
||||
cache: CacheBackend;
|
||||
database: DatabaseBackend;
|
||||
}
|
||||
```
|
||||
|
||||
### `CacheBackend`
|
||||
|
||||
Interface for cache storage operations.
|
||||
|
||||
```typescript
|
||||
interface CacheBackend {
|
||||
get(key: string): Promise<any>;
|
||||
set(key: string, value: any, ttl?: number): Promise<void>;
|
||||
delete(key: string): Promise<void>;
|
||||
clear(): Promise<void>;
|
||||
disconnect?(): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
### `DatabaseBackend`
|
||||
|
||||
Interface for database storage operations.
|
||||
|
||||
```typescript
|
||||
interface DatabaseBackend {
|
||||
get(key: string): Promise<any>;
|
||||
set(key: string, value: any): Promise<void>;
|
||||
delete(key: string): Promise<void>;
|
||||
append(key: string, value: any): Promise<void>;
|
||||
getRange(key: string, start: number, end: number): Promise<any[]>;
|
||||
disconnect?(): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Service Types
|
||||
|
||||
### `AgentServices`
|
||||
|
||||
Container for all agent service instances.
|
||||
|
||||
```typescript
|
||||
interface AgentServices {
|
||||
mcpManager: MCPManager;
|
||||
systemPromptManager: SystemPromptManager;
|
||||
agentEventBus: AgentEventBus;
|
||||
stateManager: AgentStateManager;
|
||||
sessionManager: SessionManager;
|
||||
storage: StorageBackends;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Tool Types
|
||||
|
||||
### `ToolSet`
|
||||
|
||||
Map of tool names to tool definitions.
|
||||
|
||||
```typescript
|
||||
type ToolSet = Record<string, ToolDefinition>;
|
||||
|
||||
interface ToolDefinition {
|
||||
name: string;
|
||||
description: string;
|
||||
inputSchema: {
|
||||
type: 'object';
|
||||
properties: Record<string, any>;
|
||||
required?: string[];
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### `ToolCall`
|
||||
|
||||
Represents a tool execution request.
|
||||
|
||||
```typescript
|
||||
interface ToolCall {
|
||||
id: string;
|
||||
name: string;
|
||||
arguments: Record<string, any>;
|
||||
}
|
||||
```
|
||||
|
||||
### `ToolResult`
|
||||
|
||||
Represents a tool execution result.
|
||||
|
||||
```typescript
|
||||
interface ToolResult {
|
||||
callId: string;
|
||||
toolName: string;
|
||||
result: any;
|
||||
success: boolean;
|
||||
error?: string;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Utility Types
|
||||
|
||||
### `ImageData`
|
||||
|
||||
Type for image data in conversations.
|
||||
|
||||
```typescript
|
||||
interface ImageData {
|
||||
base64: string; // Base64 encoded image
|
||||
mimeType: string; // e.g., 'image/jpeg', 'image/png'
|
||||
}
|
||||
```
|
||||
|
||||
### `FileData`
|
||||
|
||||
Type for file data in conversations.
|
||||
|
||||
```typescript
|
||||
interface FileData {
|
||||
base64: string; // Base64 encoded file data
|
||||
mimeType: string; // e.g., 'application/pdf', 'audio/wav'
|
||||
filename?: string; // Optional filename
|
||||
}
|
||||
```
|
||||
|
||||
**Supported File Types:**
|
||||
- **PDF files** (`application/pdf`) - Most widely supported
|
||||
- **Audio files** (`audio/mp3`, `audio/wav`) - With OpenAI `gpt-4o-audio-preview` and Google Gemini models
|
||||
|
||||
**Unsupported File Types:**
|
||||
- Text files (`.txt`, `.md`)
|
||||
- CSV files (`.csv`)
|
||||
- Word documents (`.doc`, `.docx`)
|
||||
- Excel files (`.xls`, `.xlsx`)
|
||||
- PowerPoint files (`.ppt`, `.pptx`)
|
||||
- JSON files (`.json`)
|
||||
- XML files (`.xml`)
|
||||
- HTML files (`.html`)
|
||||
|
||||
For unsupported file types, consider:
|
||||
1. Converting to text and sending as regular messages
|
||||
2. Using specialized MCP servers for file processing
|
||||
3. Using dedicated file processing tools
|
||||
|
||||
### `LoggerOptions`
|
||||
|
||||
Configuration options for the Logger class.
|
||||
|
||||
```typescript
|
||||
interface LoggerOptions {
|
||||
level?: 'error' | 'warn' | 'info' | 'http' | 'verbose' | 'debug' | 'silly';
|
||||
silent?: boolean;
|
||||
}
|
||||
```
|
||||
|
||||
### `ChalkColor`
|
||||
|
||||
Available colors for logger output.
|
||||
|
||||
```typescript
|
||||
type ChalkColor =
|
||||
| 'black' | 'red' | 'green' | 'yellow' | 'blue' | 'magenta' | 'cyan' | 'white'
|
||||
| 'gray' | 'grey' | 'blackBright' | 'redBright' | 'greenBright' | 'yellowBright'
|
||||
| 'blueBright' | 'magentaBright' | 'cyanBright' | 'whiteBright';
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Generic Types
|
||||
|
||||
### `EventListener`
|
||||
|
||||
Generic event listener function type.
|
||||
|
||||
```typescript
|
||||
type EventListener<T> = (data: T) => void;
|
||||
```
|
||||
|
||||
### `EventEmitterOptions`
|
||||
|
||||
Options for event emitter methods.
|
||||
|
||||
```typescript
|
||||
interface EventEmitterOptions {
|
||||
signal?: AbortSignal;
|
||||
}
|
||||
Reference in New Issue
Block a user