diff --git a/agent/context/JSAPI.md b/agent/context/JSAPI.md index e724c329..be46f755 100644 --- a/agent/context/JSAPI.md +++ b/agent/context/JSAPI.md @@ -56,6 +56,10 @@ The Context provides several methods for sending messages to the client: | `Merge(message_id, data, path?)` | Merge data into message | - | - | | `Set(message_id, data, path)` | Set a field in message | - | - | | `End(message_id, final_content?)` | Finalize streaming message | ✅ Yes | - | +| `EndBlock(block_id)` | End a message block | - | - | +| `MessageID()` | Generate unique message ID | - | - | +| `BlockID()` | Generate unique block ID | - | - | +| `ThreadID()` | Generate unique thread ID | - | - | > **Note:** `Append`, `Replace`, `Merge`, and `Set` only work with messages started via `SendStream()`. Messages sent via `Send()` are immediately finalized and cannot be updated. @@ -926,7 +930,36 @@ try { ## Trace API -The `ctx.trace` object provides comprehensive tracing capabilities for debugging and monitoring agent execution. +The `ctx.trace` object provides tracing capabilities for: + +1. **User Transparency** - Expose the agent's working and thinking process to users. The frontend will render these trace nodes to show users what the agent is doing. +2. **Developer Debugging** - Help developers debug agent execution by recording detailed steps and data. + +> **Note:** Trace is primarily designed for developers to expose the agent's process to users. The frontend has corresponding UI components to render these trace nodes. + +### Properties + +- `ctx.trace.id`: String - The unique identifier of the trace + +### Methods Summary + +| Method | Description | +| ------------------------- | ------------------------------- | +| `Add(input, option)` | Create a sequential trace node | +| `Parallel(inputs)` | Create parallel trace nodes | +| `Info(message)` | Add info log to current node | +| `Debug(message)` | Add debug log to current node | +| `Warn(message)` | Add warning log to current node | +| `Error(message)` | Add error log to current node | +| `SetOutput(output)` | Set output for current node | +| `SetMetadata(key, value)` | Set metadata for current node | +| `Complete(output?)` | Mark current node as completed | +| `Fail(error)` | Mark current node as failed | +| `MarkComplete()` | Mark entire trace as complete | +| `IsComplete()` | Check if trace is complete | +| `CreateSpace(option)` | Create a visual space container | +| `GetSpace(id)` | Get a trace space by ID | +| `Release()` | Release trace resources | ### Node Operations @@ -943,11 +976,12 @@ Creates a new trace node (sequential step). ```typescript interface TraceNodeOption { - label: string; // Display label - type: string; // Node type identifier - icon: string; // Icon identifier - description: string; // Node description + label: string; // Display label in UI + type?: string; // Node type identifier + icon?: string; // Icon identifier + description?: string; // Node description metadata?: Record; // Additional metadata + autoCompleteParent?: boolean; // Auto-complete parent node(s) when this node is created (default: true) } ``` @@ -1009,45 +1043,123 @@ const parallel_nodes = ctx.trace.Parallel([ ### Logging Methods -Add log entries to the current trace node: +Add log entries to the current trace node. Each method takes a single string message and returns the trace object for chaining. ```javascript // Information logs -ctx.trace.Info("Processing started", { step: 1 }); +ctx.trace.Info("Processing started"); // Debug logs -ctx.trace.Debug("Variable value", { value: 42 }); +ctx.trace.Debug("Variable value: 42"); // Warning logs -ctx.trace.Warn("Deprecated feature used", { feature: "old_api" }); +ctx.trace.Warn("Deprecated feature used"); // Error logs -ctx.trace.Error("Operation failed", { error: "timeout" }); +ctx.trace.Error("Operation failed: timeout"); ``` -### Node Status Operations +### Trace-Level Operations + +These methods operate on the current trace node (managed by the trace manager). + +#### `ctx.trace.SetOutput(output)` + +Sets the output data for the current trace node. + +```javascript +ctx.trace.SetOutput({ result: "success", data: [...] }); +``` + +#### `ctx.trace.SetMetadata(key, value)` + +Sets metadata for the current trace node. + +```javascript +ctx.trace.SetMetadata("duration", 1500); +ctx.trace.SetMetadata("source", "cache"); +``` + +#### `ctx.trace.Complete(output?)` + +Marks the current trace node as completed (optionally with output). + +```javascript +ctx.trace.Complete({ status: "done" }); +``` + +#### `ctx.trace.Fail(error)` + +Marks the current trace node as failed with an error message. + +```javascript +ctx.trace.Fail("Connection timeout"); +``` + +### Node Object + +The `ctx.trace.Add()` and `ctx.trace.Parallel()` methods return Node objects. Each node has the following properties and methods: + +#### Properties + +- `id`: String - The unique identifier of the node + +#### `node.Add(input, option)` + +Creates a child node under this node. + +```javascript +const parent_node = ctx.trace.Add({ step: "process" }, { label: "Process" }); +const child_node = parent_node.Add( + { action: "validate" }, + { label: "Validate Input", type: "validation" } +); +``` + +#### `node.Parallel(inputs)` + +Creates multiple parallel child nodes under this node. + +```javascript +const parent_node = ctx.trace.Add({ step: "fetch" }, { label: "Fetch Data" }); +const child_nodes = parent_node.Parallel([ + { input: { source: "db" }, option: { label: "Database Query" } }, + { input: { source: "api" }, option: { label: "API Call" } }, +]); +``` + +#### `node.Info(message)`, `node.Debug(message)`, `node.Warn(message)`, `node.Error(message)` + +Add log entries to the node. All methods return the node for chaining. + +```javascript +const search_node = ctx.trace.Add({ query: "search" }, { label: "Search" }); +search_node + .Info("Starting search") + .Debug("Query parameters validated") + .Warn("Cache miss, fetching from source"); +``` #### `node.SetOutput(output)` -Sets the output data for a node. +Sets the output data for a node. Returns the node for chaining. ```javascript -const search_node = ctx.trace.Add({ query: "search" }, options); -search_node.SetOutput({ results: [...] }); +const search_node = ctx.trace.Add({ query: "search" }, { label: "Search" }); +search_node.SetOutput({ results: [...], count: 10 }); ``` #### `node.SetMetadata(key, value)` -Sets metadata for a node. +Sets metadata for a node. Returns the node for chaining. ```javascript -search_node.SetMetadata("duration", 1500); -search_node.SetMetadata("cache_hit", true); +search_node.SetMetadata("duration", 1500).SetMetadata("cache_hit", true); ``` #### `node.Complete(output?)` -Marks a node as completed (optionally with output). +Marks a node as completed (optionally with output). Returns the node for chaining. ```javascript search_node.Complete({ status: "success", data: [...] }); @@ -1055,99 +1167,91 @@ search_node.Complete({ status: "success", data: [...] }); #### `node.Fail(error)` -Marks a node as failed with an error. +Marks a node as failed with an error message. Returns the node for chaining. ```javascript try { // Operation } catch (error) { - search_node.Fail(error); + search_node.Fail(error.message); } ``` -### Query Operations +### Trace Lifecycle -#### `ctx.trace.GetRootNode()` +#### `ctx.trace.IsComplete()` -Returns the root node of the trace tree. +Checks if the trace is complete. ```javascript -const root_node = ctx.trace.GetRootNode(); -console.log(root_node.id, root_node.label); +if (ctx.trace.IsComplete()) { + console.log("Trace completed"); +} ``` -#### `ctx.trace.GetNode(id)` +#### `ctx.trace.MarkComplete()` -Retrieves a specific node by ID. +Marks the entire trace as complete. ```javascript -const target_node = ctx.trace.GetNode("node-123"); +ctx.trace.MarkComplete(); ``` -#### `ctx.trace.GetCurrentNodes()` +### Trace Space Operations -Returns the current active nodes (may be multiple if in parallel state). +Trace spaces are visual containers for organizing trace nodes in the frontend UI. They help group related operations together for better presentation to users. -```javascript -const current_nodes = ctx.trace.GetCurrentNodes(); -``` - -### Memory Space Operations +> **Note:** Trace spaces are purely for visual organization and presentation. They do not store data - use `ctx.space` for data storage between hooks. #### `ctx.trace.CreateSpace(option)` -Creates a memory space for storing key-value data. +Creates a visual space container for grouping trace nodes. + +**Option Structure:** + +```typescript +interface TraceSpaceOption { + label: string; // Display label in UI + type?: string; // Space type identifier + icon?: string; // Icon identifier + description?: string; // Space description + ttl?: number; // Time to live in seconds (for display only) + metadata?: Record; // Additional metadata +} +``` + +**Example:** ```javascript -const memory_space = ctx.trace.CreateSpace({ - label: "Context Memory", - type: "context", - icon: "database", - description: "Stores conversation context", +const visual_space = ctx.trace.CreateSpace({ + label: "Search Results", + type: "search", + icon: "search", + description: "Knowledge base search operations", }); ``` #### `ctx.trace.GetSpace(id)` -Retrieves a memory space by ID. +Retrieves a trace space by ID. ```javascript -const context_space = ctx.trace.GetSpace("context"); -``` - -#### `ctx.trace.HasSpace(id)` - -Checks if a memory space exists. - -```javascript -if (ctx.trace.HasSpace("context")) { - // Space exists -} -``` - -#### `ctx.trace.DeleteSpace(id)` - -Deletes a memory space. - -```javascript -ctx.trace.DeleteSpace("temp_storage"); -``` - -#### `ctx.trace.ListSpaces()` - -Lists all memory spaces. - -```javascript -const all_spaces = ctx.trace.ListSpaces(); -all_spaces.forEach((space) => { - console.log(space.id, space.label); -}); +const search_space = ctx.trace.GetSpace("search-space-id"); ``` ## Space API The `ctx.space` object provides a shared data space for passing data between requests and agent calls. This is useful for storing temporary data that needs to be accessed across different hooks or nested agent calls. +### Methods Summary + +| Method | Description | +| ----------------- | ------------------------------------- | +| `Get(key)` | Get a value from the space | +| `Set(key, value)` | Set a value in the space | +| `Delete(key)` | Delete a key from the space | +| `GetDel(key)` | Get a value and immediately delete it | + ### Methods #### `ctx.space.Get(key): any` @@ -1272,101 +1376,180 @@ function Next(ctx, payload) { The `ctx.mcp` object provides access to Model Context Protocol operations for interacting with external tools, resources, and prompts. +### Methods Summary + +| Method | Description | +| ------------------------------------ | -------------------------------- | +| `ListResources(client, cursor?)` | List available resources | +| `ReadResource(client, uri)` | Read a specific resource | +| `ListTools(client, cursor?)` | List available tools | +| `CallTool(client, name, args?)` | Call a single tool | +| `CallTools(client, tools)` | Call multiple tools sequentially | +| `CallToolsParallel(client, tools)` | Call multiple tools in parallel | +| `ListPrompts(client, cursor?)` | List available prompts | +| `GetPrompt(client, name, args?)` | Get a specific prompt | +| `ListSamples(client, type, name)` | List samples for a tool/resource | +| `GetSample(client, type, name, idx)` | Get a specific sample by index | + ### Resource Operations -#### `ctx.mcp.ListResources(client)` +#### `ctx.mcp.ListResources(client, cursor?)` Lists available resources from an MCP client. +**Parameters:** + +- `client`: String - MCP client ID +- `cursor`: String (optional) - Pagination cursor + ```javascript -const fs_resources = ctx.mcp.ListResources("filesystem"); +const resources = ctx.mcp.ListResources("echo", ""); +console.log(resources.resources); // Array of resources ``` #### `ctx.mcp.ReadResource(client, uri)` Reads a specific resource. +**Parameters:** + +- `client`: String - MCP client ID +- `uri`: String - Resource URI + ```javascript -const file_content = ctx.mcp.ReadResource( - "filesystem", - "file:///path/to/file.txt" -); +const info = ctx.mcp.ReadResource("echo", "echo://info"); +console.log(info.contents); // Array of content items ``` ### Tool Operations -#### `ctx.mcp.ListTools(client)` +#### `ctx.mcp.ListTools(client, cursor?)` Lists available tools from an MCP client. +**Parameters:** + +- `client`: String - MCP client ID +- `cursor`: String (optional) - Pagination cursor + ```javascript -const available_tools = ctx.mcp.ListTools("toolkit"); +const tools = ctx.mcp.ListTools("echo", ""); +console.log(tools.tools); // Array of tools ``` -#### `ctx.mcp.CallTool(client, name, args)` +#### `ctx.mcp.CallTool(client, name, arguments?)` Calls a single tool. +**Parameters:** + +- `client`: String - MCP client ID +- `name`: String - Tool name +- `arguments`: Object (optional) - Tool arguments + ```javascript -const calc_result = ctx.mcp.CallTool("calculator", "add", { - a: 10, - b: 32, -}); +const result = ctx.mcp.CallTool("echo", "ping", { count: 3 }); +console.log(result.content); // Tool result content ``` -#### `ctx.mcp.CallTools(client, calls)` +#### `ctx.mcp.CallTools(client, tools)` Calls multiple tools sequentially. +**Parameters:** + +- `client`: String - MCP client ID +- `tools`: Array - Array of tool call objects + ```javascript -const tool_results = ctx.mcp.CallTools("toolkit", [ - { name: "tool1", args: { param: "value1" } }, - { name: "tool2", args: { param: "value2" } }, +const results = ctx.mcp.CallTools("echo", [ + { name: "ping", arguments: { count: 1 } }, + { name: "status", arguments: { verbose: true } }, ]); +console.log(results.results); // Array of results ``` -#### `ctx.mcp.CallToolsParallel(client, calls)` +#### `ctx.mcp.CallToolsParallel(client, tools)` Calls multiple tools in parallel. +**Parameters:** + +- `client`: String - MCP client ID +- `tools`: Array - Array of tool call objects + ```javascript -const parallel_results = ctx.mcp.CallToolsParallel("toolkit", [ - { name: "api1", args: { endpoint: "/users" } }, - { name: "api2", args: { endpoint: "/posts" } }, +const results = ctx.mcp.CallToolsParallel("echo", [ + { name: "ping", arguments: { count: 1 } }, + { name: "status", arguments: { verbose: false } }, ]); +console.log(results.results); // Array of results (order may vary) ``` ### Prompt Operations -#### `ctx.mcp.ListPrompts(client)` +#### `ctx.mcp.ListPrompts(client, cursor?)` Lists available prompts from an MCP client. +**Parameters:** + +- `client`: String - MCP client ID +- `cursor`: String (optional) - Pagination cursor + ```javascript -const available_prompts = ctx.mcp.ListPrompts("prompt_library"); +const prompts = ctx.mcp.ListPrompts("echo", ""); +console.log(prompts.prompts); // Array of prompts ``` -#### `ctx.mcp.GetPrompt(client, name, args?)` +#### `ctx.mcp.GetPrompt(client, name, arguments?)` -Retrieves a specific prompt. +Retrieves a specific prompt with optional arguments. + +**Parameters:** + +- `client`: String - MCP client ID +- `name`: String - Prompt name +- `arguments`: Object (optional) - Prompt arguments ```javascript -const review_prompt = ctx.mcp.GetPrompt("prompt_library", "code_review", { - language: "javascript", +const prompt = ctx.mcp.GetPrompt("echo", "test_connection", { + detailed: "true", }); +console.log(prompt.messages); // Array of prompt messages ``` ### Sample Operations -#### `ctx.mcp.CreateSample(client, uri, sample)` +#### `ctx.mcp.ListSamples(client, type, name)` -Creates a sample for a resource. +Lists available samples for a tool or resource. + +**Parameters:** + +- `client`: String - MCP client ID +- `type`: String - Sample type ("tool" or "resource") +- `name`: String - Tool or resource name ```javascript -ctx.mcp.CreateSample("filesystem", "file:///examples", { - name: "example1", - content: "Sample content", -}); +const samples = ctx.mcp.ListSamples("echo", "tool", "ping"); +console.log(samples.samples); // Array of samples +``` + +#### `ctx.mcp.GetSample(client, type, name, index)` + +Gets a specific sample by index. + +**Parameters:** + +- `client`: String - MCP client ID +- `type`: String - Sample type ("tool" or "resource") +- `name`: String - Tool or resource name +- `index`: Number - Sample index (0-based) + +```javascript +const sample = ctx.mcp.GetSample("echo", "tool", "ping", 0); +console.log(sample.name, sample.input); // Sample name and input data ``` ## Hooks