Merge pull request #1374 from trheyi/main
Refactor context API to standardize property naming conventions
This commit is contained in:
commit
30000cc2da
6 changed files with 352 additions and 169 deletions
|
|
@ -36,8 +36,8 @@ interface Context {
|
||||||
|
|
||||||
// Objects
|
// Objects
|
||||||
space: Space; // Shared data space for passing data between requests
|
space: Space; // Shared data space for passing data between requests
|
||||||
Trace: Trace; // Trace object for debugging and monitoring
|
trace: Trace; // Trace object for debugging and monitoring
|
||||||
MCP: MCP; // MCP object for external tool/resource access
|
mcp: MCP; // MCP object for external tool/resource access
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -56,6 +56,10 @@ The Context provides several methods for sending messages to the client:
|
||||||
| `Merge(message_id, data, path?)` | Merge data into message | - | - |
|
| `Merge(message_id, data, path?)` | Merge data into message | - | - |
|
||||||
| `Set(message_id, data, path)` | Set a field in message | - | - |
|
| `Set(message_id, data, path)` | Set a field in message | - | - |
|
||||||
| `End(message_id, final_content?)` | Finalize streaming message | ✅ Yes | - |
|
| `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.
|
> **Note:** `Append`, `Replace`, `Merge`, and `Set` only work with messages started via `SendStream()`. Messages sent via `Send()` are immediately finalized and cannot be updated.
|
||||||
|
|
||||||
|
|
@ -899,7 +903,7 @@ function Create(ctx, messages) {
|
||||||
|
|
||||||
// MCP tool call block
|
// MCP tool call block
|
||||||
ctx.Send("Fetching data...", mcp_block);
|
ctx.Send("Fetching data...", mcp_block);
|
||||||
const data = ctx.MCP.CallTool("tool", "method", {});
|
const data = ctx.mcp.CallTool("tool", "method", {});
|
||||||
ctx.Send(`Found ${data.length} results`, mcp_block);
|
ctx.Send(`Found ${data.length} results`, mcp_block);
|
||||||
ctx.EndBlock(mcp_block);
|
ctx.EndBlock(mcp_block);
|
||||||
|
|
||||||
|
|
@ -926,11 +930,40 @@ try {
|
||||||
|
|
||||||
## Trace API
|
## 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
|
### Node Operations
|
||||||
|
|
||||||
#### `ctx.Trace.Add(input, options)`
|
#### `ctx.trace.Add(input, options)`
|
||||||
|
|
||||||
Creates a new trace node (sequential step).
|
Creates a new trace node (sequential step).
|
||||||
|
|
||||||
|
|
@ -943,18 +976,19 @@ Creates a new trace node (sequential step).
|
||||||
|
|
||||||
```typescript
|
```typescript
|
||||||
interface TraceNodeOption {
|
interface TraceNodeOption {
|
||||||
label: string; // Display label
|
label: string; // Display label in UI
|
||||||
type: string; // Node type identifier
|
type?: string; // Node type identifier
|
||||||
icon: string; // Icon identifier
|
icon?: string; // Icon identifier
|
||||||
description: string; // Node description
|
description?: string; // Node description
|
||||||
metadata?: Record<string, any>; // Additional metadata
|
metadata?: Record<string, any>; // Additional metadata
|
||||||
|
autoCompleteParent?: boolean; // Auto-complete parent node(s) when this node is created (default: true)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const search_node = ctx.Trace.Add(
|
const search_node = ctx.trace.Add(
|
||||||
{ query: "What is AI?" },
|
{ query: "What is AI?" },
|
||||||
{
|
{
|
||||||
label: "Search Query",
|
label: "Search Query",
|
||||||
|
|
@ -965,7 +999,7 @@ const search_node = ctx.Trace.Add(
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `ctx.Trace.Parallel(inputs)`
|
#### `ctx.trace.Parallel(inputs)`
|
||||||
|
|
||||||
Creates multiple parallel trace nodes for concurrent operations.
|
Creates multiple parallel trace nodes for concurrent operations.
|
||||||
|
|
||||||
|
|
@ -985,7 +1019,7 @@ interface ParallelInput {
|
||||||
**Example:**
|
**Example:**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const parallel_nodes = ctx.Trace.Parallel([
|
const parallel_nodes = ctx.trace.Parallel([
|
||||||
{
|
{
|
||||||
input: { url: "https://api1.com" },
|
input: { url: "https://api1.com" },
|
||||||
option: {
|
option: {
|
||||||
|
|
@ -1009,45 +1043,123 @@ const parallel_nodes = ctx.Trace.Parallel([
|
||||||
|
|
||||||
### Logging Methods
|
### 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
|
```javascript
|
||||||
// Information logs
|
// Information logs
|
||||||
ctx.Trace.Info("Processing started", { step: 1 });
|
ctx.trace.Info("Processing started");
|
||||||
|
|
||||||
// Debug logs
|
// Debug logs
|
||||||
ctx.Trace.Debug("Variable value", { value: 42 });
|
ctx.trace.Debug("Variable value: 42");
|
||||||
|
|
||||||
// Warning logs
|
// Warning logs
|
||||||
ctx.Trace.Warn("Deprecated feature used", { feature: "old_api" });
|
ctx.trace.Warn("Deprecated feature used");
|
||||||
|
|
||||||
// Error logs
|
// 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)`
|
#### `node.SetOutput(output)`
|
||||||
|
|
||||||
Sets the output data for a node.
|
Sets the output data for a node. Returns the node for chaining.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const search_node = ctx.Trace.Add({ query: "search" }, options);
|
const search_node = ctx.trace.Add({ query: "search" }, { label: "Search" });
|
||||||
search_node.SetOutput({ results: [...] });
|
search_node.SetOutput({ results: [...], count: 10 });
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `node.SetMetadata(key, value)`
|
#### `node.SetMetadata(key, value)`
|
||||||
|
|
||||||
Sets metadata for a node.
|
Sets metadata for a node. Returns the node for chaining.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
search_node.SetMetadata("duration", 1500);
|
search_node.SetMetadata("duration", 1500).SetMetadata("cache_hit", true);
|
||||||
search_node.SetMetadata("cache_hit", true);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `node.Complete(output?)`
|
#### `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
|
```javascript
|
||||||
search_node.Complete({ status: "success", data: [...] });
|
search_node.Complete({ status: "success", data: [...] });
|
||||||
|
|
@ -1055,99 +1167,91 @@ search_node.Complete({ status: "success", data: [...] });
|
||||||
|
|
||||||
#### `node.Fail(error)`
|
#### `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
|
```javascript
|
||||||
try {
|
try {
|
||||||
// Operation
|
// Operation
|
||||||
} catch (error) {
|
} 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
|
```javascript
|
||||||
const root_node = ctx.Trace.GetRootNode();
|
if (ctx.trace.IsComplete()) {
|
||||||
console.log(root_node.id, root_node.label);
|
console.log("Trace completed");
|
||||||
```
|
|
||||||
|
|
||||||
#### `ctx.Trace.GetNode(id)`
|
|
||||||
|
|
||||||
Retrieves a specific node by ID.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const target_node = ctx.Trace.GetNode("node-123");
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `ctx.Trace.GetCurrentNodes()`
|
|
||||||
|
|
||||||
Returns the current active nodes (may be multiple if in parallel state).
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const current_nodes = ctx.Trace.GetCurrentNodes();
|
|
||||||
```
|
|
||||||
|
|
||||||
### Memory Space Operations
|
|
||||||
|
|
||||||
#### `ctx.Trace.CreateSpace(option)`
|
|
||||||
|
|
||||||
Creates a memory space for storing key-value data.
|
|
||||||
|
|
||||||
```javascript
|
|
||||||
const memory_space = ctx.Trace.CreateSpace({
|
|
||||||
label: "Context Memory",
|
|
||||||
type: "context",
|
|
||||||
icon: "database",
|
|
||||||
description: "Stores conversation context",
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
#### `ctx.Trace.GetSpace(id)`
|
|
||||||
|
|
||||||
Retrieves a memory 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)`
|
#### `ctx.trace.MarkComplete()`
|
||||||
|
|
||||||
Deletes a memory space.
|
Marks the entire trace as complete.
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
ctx.Trace.DeleteSpace("temp_storage");
|
ctx.trace.MarkComplete();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `ctx.Trace.ListSpaces()`
|
### Trace Space Operations
|
||||||
|
|
||||||
Lists all memory spaces.
|
Trace spaces are visual containers for organizing trace nodes in the frontend UI. They help group related operations together for better presentation to users.
|
||||||
|
|
||||||
|
> **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 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<string, any>; // Additional metadata
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const all_spaces = ctx.Trace.ListSpaces();
|
const visual_space = ctx.trace.CreateSpace({
|
||||||
all_spaces.forEach((space) => {
|
label: "Search Results",
|
||||||
console.log(space.id, space.label);
|
type: "search",
|
||||||
|
icon: "search",
|
||||||
|
description: "Knowledge base search operations",
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### `ctx.trace.GetSpace(id)`
|
||||||
|
|
||||||
|
Retrieves a trace space by ID.
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
const search_space = ctx.trace.GetSpace("search-space-id");
|
||||||
|
```
|
||||||
|
|
||||||
## Space API
|
## 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.
|
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
|
### Methods
|
||||||
|
|
||||||
#### `ctx.space.Get(key): any`
|
#### `ctx.space.Get(key): any`
|
||||||
|
|
@ -1270,103 +1374,182 @@ function Next(ctx, payload) {
|
||||||
|
|
||||||
## MCP API
|
## MCP API
|
||||||
|
|
||||||
The `ctx.MCP` object provides access to Model Context Protocol operations for interacting with external tools, resources, and prompts.
|
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
|
### Resource Operations
|
||||||
|
|
||||||
#### `ctx.MCP.ListResources(client)`
|
#### `ctx.mcp.ListResources(client, cursor?)`
|
||||||
|
|
||||||
Lists available resources from an MCP client.
|
Lists available resources from an MCP client.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `cursor`: String (optional) - Pagination cursor
|
||||||
|
|
||||||
```javascript
|
```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)`
|
#### `ctx.mcp.ReadResource(client, uri)`
|
||||||
|
|
||||||
Reads a specific resource.
|
Reads a specific resource.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `uri`: String - Resource URI
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const file_content = ctx.MCP.ReadResource(
|
const info = ctx.mcp.ReadResource("echo", "echo://info");
|
||||||
"filesystem",
|
console.log(info.contents); // Array of content items
|
||||||
"file:///path/to/file.txt"
|
|
||||||
);
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Tool Operations
|
### Tool Operations
|
||||||
|
|
||||||
#### `ctx.MCP.ListTools(client)`
|
#### `ctx.mcp.ListTools(client, cursor?)`
|
||||||
|
|
||||||
Lists available tools from an MCP client.
|
Lists available tools from an MCP client.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `cursor`: String (optional) - Pagination cursor
|
||||||
|
|
||||||
```javascript
|
```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.
|
Calls a single tool.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `name`: String - Tool name
|
||||||
|
- `arguments`: Object (optional) - Tool arguments
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const calc_result = ctx.MCP.CallTool("calculator", "add", {
|
const result = ctx.mcp.CallTool("echo", "ping", { count: 3 });
|
||||||
a: 10,
|
console.log(result.content); // Tool result content
|
||||||
b: 32,
|
|
||||||
});
|
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `ctx.MCP.CallTools(client, calls)`
|
#### `ctx.mcp.CallTools(client, tools)`
|
||||||
|
|
||||||
Calls multiple tools sequentially.
|
Calls multiple tools sequentially.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `tools`: Array - Array of tool call objects
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const tool_results = ctx.MCP.CallTools("toolkit", [
|
const results = ctx.mcp.CallTools("echo", [
|
||||||
{ name: "tool1", args: { param: "value1" } },
|
{ name: "ping", arguments: { count: 1 } },
|
||||||
{ name: "tool2", args: { param: "value2" } },
|
{ 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.
|
Calls multiple tools in parallel.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `tools`: Array - Array of tool call objects
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const parallel_results = ctx.MCP.CallToolsParallel("toolkit", [
|
const results = ctx.mcp.CallToolsParallel("echo", [
|
||||||
{ name: "api1", args: { endpoint: "/users" } },
|
{ name: "ping", arguments: { count: 1 } },
|
||||||
{ name: "api2", args: { endpoint: "/posts" } },
|
{ name: "status", arguments: { verbose: false } },
|
||||||
]);
|
]);
|
||||||
|
console.log(results.results); // Array of results (order may vary)
|
||||||
```
|
```
|
||||||
|
|
||||||
### Prompt Operations
|
### Prompt Operations
|
||||||
|
|
||||||
#### `ctx.MCP.ListPrompts(client)`
|
#### `ctx.mcp.ListPrompts(client, cursor?)`
|
||||||
|
|
||||||
Lists available prompts from an MCP client.
|
Lists available prompts from an MCP client.
|
||||||
|
|
||||||
|
**Parameters:**
|
||||||
|
|
||||||
|
- `client`: String - MCP client ID
|
||||||
|
- `cursor`: String (optional) - Pagination cursor
|
||||||
|
|
||||||
```javascript
|
```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
|
```javascript
|
||||||
const review_prompt = ctx.MCP.GetPrompt("prompt_library", "code_review", {
|
const prompt = ctx.mcp.GetPrompt("echo", "test_connection", {
|
||||||
language: "javascript",
|
detailed: "true",
|
||||||
});
|
});
|
||||||
|
console.log(prompt.messages); // Array of prompt messages
|
||||||
```
|
```
|
||||||
|
|
||||||
### Sample Operations
|
### 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
|
```javascript
|
||||||
ctx.MCP.CreateSample("filesystem", "file:///examples", {
|
const samples = ctx.mcp.ListSamples("echo", "tool", "ping");
|
||||||
name: "example1",
|
console.log(samples.samples); // Array of samples
|
||||||
content: "Sample content",
|
```
|
||||||
});
|
|
||||||
|
#### `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
|
## Hooks
|
||||||
|
|
@ -1566,7 +1749,7 @@ function Create(ctx, messages) {
|
||||||
ctx.space.Set("original_query", messages[0]?.content || "");
|
ctx.space.Set("original_query", messages[0]?.content || "");
|
||||||
|
|
||||||
// Add trace node
|
// Add trace node
|
||||||
ctx.Trace.Add(
|
ctx.trace.Add(
|
||||||
{ messages },
|
{ messages },
|
||||||
{
|
{
|
||||||
label: "Create Hook",
|
label: "Create Hook",
|
||||||
|
|
@ -1596,7 +1779,7 @@ function Next(ctx, payload) {
|
||||||
const original_query = ctx.space.Get("original_query");
|
const original_query = ctx.space.Get("original_query");
|
||||||
|
|
||||||
// Create trace node for custom processing
|
// Create trace node for custom processing
|
||||||
const process_node = ctx.Trace.Add(
|
const process_node = ctx.trace.Add(
|
||||||
{ completion, tools },
|
{ completion, tools },
|
||||||
{
|
{
|
||||||
label: "Custom Processing",
|
label: "Custom Processing",
|
||||||
|
|
@ -1606,7 +1789,7 @@ function Next(ctx, payload) {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.Trace.Info("Starting custom processing", {
|
ctx.trace.Info("Starting custom processing", {
|
||||||
original_query: original_query,
|
original_query: original_query,
|
||||||
tool_count: tools?.length || 0,
|
tool_count: tools?.length || 0,
|
||||||
});
|
});
|
||||||
|
|
@ -1615,7 +1798,7 @@ function Next(ctx, payload) {
|
||||||
const msg_id = ctx.SendStream("# Search Results\n\n");
|
const msg_id = ctx.SendStream("# Search Results\n\n");
|
||||||
|
|
||||||
// Call MCP tool for additional data
|
// Call MCP tool for additional data
|
||||||
const search_results = ctx.MCP.CallTool("search_engine", "search", {
|
const search_results = ctx.mcp.CallTool("search_engine", "search", {
|
||||||
query: "latest AI news",
|
query: "latest AI news",
|
||||||
limit: 5,
|
limit: 5,
|
||||||
});
|
});
|
||||||
|
|
@ -1640,7 +1823,7 @@ function Next(ctx, payload) {
|
||||||
metadata: { processed: true },
|
metadata: { processed: true },
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ctx.Trace.Error("Processing failed", { error: error.message });
|
ctx.trace.Error("Processing failed", { error: error.message });
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1666,7 +1849,7 @@ All Context methods throw exceptions on failure. Always handle errors appropriat
|
||||||
try {
|
try {
|
||||||
ctx.Send(message);
|
ctx.Send(message);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
ctx.Trace.Error("Failed to send message", { error: error.message });
|
ctx.trace.Error("Failed to send message", { error: error.message });
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -59,8 +59,8 @@ func (ctx *Context) NewObject(v8ctx *v8go.Context) (*v8go.Value, error) {
|
||||||
// Lifecycle methods
|
// Lifecycle methods
|
||||||
jsObject.Set("EndBlock", ctx.endBlockMethod(v8ctx.Isolate()))
|
jsObject.Set("EndBlock", ctx.endBlockMethod(v8ctx.Isolate()))
|
||||||
|
|
||||||
// Set MCP object
|
// Set mcp object
|
||||||
jsObject.Set("MCP", ctx.newMCPObject(v8ctx.Isolate()))
|
jsObject.Set("mcp", ctx.newMCPObject(v8ctx.Isolate()))
|
||||||
|
|
||||||
// Note: Space object will be set after instance creation (requires v8ctx)
|
// Note: Space object will be set after instance creation (requires v8ctx)
|
||||||
|
|
||||||
|
|
@ -86,11 +86,11 @@ func (ctx *Context) NewObject(v8ctx *v8go.Context) (*v8go.Value, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set Trace object (property, not method)
|
// Set trace object (property, not method)
|
||||||
// If trace is not initialized, use no-op object
|
// If trace is not initialized, use no-op object
|
||||||
traceObj := ctx.createTraceObject(v8ctx)
|
traceObj := ctx.createTraceObject(v8ctx)
|
||||||
if traceObj != nil {
|
if traceObj != nil {
|
||||||
obj.Set("Trace", traceObj)
|
obj.Set("trace", traceObj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set complex objects (maps, arrays) after instance creation using bridge
|
// Set complex objects (maps, arrays) after instance creation using bridge
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@ func TestMCPListResources(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// List resources from echo MCP
|
// List resources from echo MCP
|
||||||
const result = ctx.MCP.ListResources("echo", "")
|
const result = ctx.mcp.ListResources("echo", "")
|
||||||
|
|
||||||
if (!result || !result.resources) {
|
if (!result || !result.resources) {
|
||||||
throw new Error("Expected resources")
|
throw new Error("Expected resources")
|
||||||
|
|
@ -75,7 +75,7 @@ func TestMCPReadResource(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Read info resource
|
// Read info resource
|
||||||
const result = ctx.MCP.ReadResource("echo", "echo://info")
|
const result = ctx.mcp.ReadResource("echo", "echo://info")
|
||||||
|
|
||||||
if (!result || !result.contents) {
|
if (!result || !result.contents) {
|
||||||
throw new Error("Expected contents")
|
throw new Error("Expected contents")
|
||||||
|
|
@ -118,7 +118,7 @@ func TestMCPListTools(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// List tools from echo MCP
|
// List tools from echo MCP
|
||||||
const result = ctx.MCP.ListTools("echo", "")
|
const result = ctx.mcp.ListTools("echo", "")
|
||||||
|
|
||||||
if (!result || !result.tools) {
|
if (!result || !result.tools) {
|
||||||
throw new Error("Expected tools")
|
throw new Error("Expected tools")
|
||||||
|
|
@ -165,7 +165,7 @@ func TestMCPCallTool(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Call ping tool
|
// Call ping tool
|
||||||
const result = ctx.MCP.CallTool("echo", "ping", { count: 3, message: "test" })
|
const result = ctx.mcp.CallTool("echo", "ping", { count: 3, message: "test" })
|
||||||
|
|
||||||
if (!result || !result.content) {
|
if (!result || !result.content) {
|
||||||
throw new Error("Expected content")
|
throw new Error("Expected content")
|
||||||
|
|
@ -213,7 +213,7 @@ func TestMCPCallTools(t *testing.T) {
|
||||||
{ name: "status", arguments: { verbose: false } }
|
{ name: "status", arguments: { verbose: false } }
|
||||||
]
|
]
|
||||||
|
|
||||||
const result = ctx.MCP.CallTools("echo", tools)
|
const result = ctx.mcp.CallTools("echo", tools)
|
||||||
|
|
||||||
if (!result || !result.results) {
|
if (!result || !result.results) {
|
||||||
throw new Error("Expected results")
|
throw new Error("Expected results")
|
||||||
|
|
@ -261,7 +261,7 @@ func TestMCPCallToolsParallel(t *testing.T) {
|
||||||
{ name: "status", arguments: { verbose: true } }
|
{ name: "status", arguments: { verbose: true } }
|
||||||
]
|
]
|
||||||
|
|
||||||
const result = ctx.MCP.CallToolsParallel("echo", tools)
|
const result = ctx.mcp.CallToolsParallel("echo", tools)
|
||||||
|
|
||||||
if (!result || !result.results) {
|
if (!result || !result.results) {
|
||||||
throw new Error("Expected results")
|
throw new Error("Expected results")
|
||||||
|
|
@ -304,7 +304,7 @@ func TestMCPListPrompts(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// List prompts from echo MCP
|
// List prompts from echo MCP
|
||||||
const result = ctx.MCP.ListPrompts("echo", "")
|
const result = ctx.mcp.ListPrompts("echo", "")
|
||||||
|
|
||||||
if (!result || !result.prompts) {
|
if (!result || !result.prompts) {
|
||||||
throw new Error("Expected prompts")
|
throw new Error("Expected prompts")
|
||||||
|
|
@ -349,7 +349,7 @@ func TestMCPGetPrompt(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Get test_connection prompt
|
// Get test_connection prompt
|
||||||
const result = ctx.MCP.GetPrompt("echo", "test_connection", { detailed: "true" })
|
const result = ctx.mcp.GetPrompt("echo", "test_connection", { detailed: "true" })
|
||||||
|
|
||||||
if (!result || !result.messages) {
|
if (!result || !result.messages) {
|
||||||
throw new Error("Expected messages")
|
throw new Error("Expected messages")
|
||||||
|
|
@ -392,7 +392,7 @@ func TestMCPListSamples(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// List samples for ping tool
|
// List samples for ping tool
|
||||||
const result = ctx.MCP.ListSamples("echo", "tool", "ping")
|
const result = ctx.mcp.ListSamples("echo", "tool", "ping")
|
||||||
|
|
||||||
if (!result || !result.samples) {
|
if (!result || !result.samples) {
|
||||||
throw new Error("Expected samples")
|
throw new Error("Expected samples")
|
||||||
|
|
@ -435,7 +435,7 @@ func TestMCPGetSample(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Get first sample for ping tool
|
// Get first sample for ping tool
|
||||||
const result = ctx.MCP.GetSample("echo", "tool", "ping", 0)
|
const result = ctx.mcp.GetSample("echo", "tool", "ping", 0)
|
||||||
|
|
||||||
if (!result) {
|
if (!result) {
|
||||||
throw new Error("Expected sample")
|
throw new Error("Expected sample")
|
||||||
|
|
@ -480,10 +480,10 @@ func TestMCPJsApiWithTrace(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Get trace (property, not method call)
|
// Get trace (property, not method call)
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
|
|
||||||
// Call MCP tool - should create trace node
|
// Call MCP tool - should create trace node
|
||||||
const result = ctx.MCP.CallTool("echo", "ping", { count: 5 })
|
const result = ctx.mcp.CallTool("echo", "ping", { count: 5 })
|
||||||
|
|
||||||
// Verify trace and result exist
|
// Verify trace and result exist
|
||||||
return {
|
return {
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ func TestTraceRelease(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Get trace
|
// Get trace
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
|
|
||||||
// Verify trace has Release method
|
// Verify trace has Release method
|
||||||
if (typeof trace.Release !== 'function') {
|
if (typeof trace.Release !== 'function') {
|
||||||
|
|
@ -149,7 +149,7 @@ func TestContextReleaseWithTrace(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Get trace
|
// Get trace
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
|
|
||||||
// Use trace
|
// Use trace
|
||||||
const node = trace.Add({ type: "test" }, { label: "Test Node" })
|
const node = trace.Add({ type: "test" }, { label: "Test Node" })
|
||||||
|
|
@ -197,7 +197,7 @@ func TestTryFinallyPattern(t *testing.T) {
|
||||||
|
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
|
|
||||||
// Try-finally pattern for explicit resource management
|
// Try-finally pattern for explicit resource management
|
||||||
try {
|
try {
|
||||||
|
|
@ -247,7 +247,7 @@ func TestNoOpTraceRelease(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Get trace (should be no-op)
|
// Get trace (should be no-op)
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
|
|
||||||
// Verify trace has Release method even when it's no-op
|
// Verify trace has Release method even when it's no-op
|
||||||
if (typeof trace.Release !== 'function') {
|
if (typeof trace.Release !== 'function') {
|
||||||
|
|
@ -300,7 +300,7 @@ func TestTryFinallyPatternWithError(t *testing.T) {
|
||||||
|
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
|
|
||||||
// Try-finally pattern ensures cleanup even when error occurs
|
// Try-finally pattern ensures cleanup even when error occurs
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ func TestStressContextCreationAndRelease(t *testing.T) {
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Use trace
|
// Use trace
|
||||||
ctx.Trace.Add({ type: "test" }, { label: "Test" })
|
ctx.trace.Add({ type: "test" }, { label: "Test" })
|
||||||
ctx.Trace.Info("Processing")
|
ctx.trace.Info("Processing")
|
||||||
|
|
||||||
// Explicit release
|
// Explicit release
|
||||||
ctx.Release()
|
ctx.Release()
|
||||||
|
|
@ -120,7 +120,7 @@ func TestStressTraceOperations(t *testing.T) {
|
||||||
cxt.Stack = stack
|
cxt.Stack = stack
|
||||||
_, err := v8.Call(v8.CallOptions{}, fmt.Sprintf(`
|
_, err := v8.Call(v8.CallOptions{}, fmt.Sprintf(`
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
const nodes = []
|
const nodes = []
|
||||||
|
|
||||||
// Create multiple nodes
|
// Create multiple nodes
|
||||||
|
|
@ -202,16 +202,16 @@ func TestStressMCPOperations(t *testing.T) {
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// List operations
|
// List operations
|
||||||
const tools = ctx.MCP.ListTools("echo", "")
|
const tools = ctx.mcp.ListTools("echo", "")
|
||||||
const resources = ctx.MCP.ListResources("echo", "")
|
const resources = ctx.mcp.ListResources("echo", "")
|
||||||
const prompts = ctx.MCP.ListPrompts("echo", "")
|
const prompts = ctx.mcp.ListPrompts("echo", "")
|
||||||
|
|
||||||
// Call operations
|
// Call operations
|
||||||
const result1 = ctx.MCP.CallTool("echo", "ping", { count: 1 })
|
const result1 = ctx.mcp.CallTool("echo", "ping", { count: 1 })
|
||||||
const result2 = ctx.MCP.CallTool("echo", "status", { verbose: false })
|
const result2 = ctx.mcp.CallTool("echo", "status", { verbose: false })
|
||||||
|
|
||||||
// Read operations
|
// Read operations
|
||||||
const info = ctx.MCP.ReadResource("echo", "echo://info")
|
const info = ctx.mcp.ReadResource("echo", "echo://info")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
tools: tools.tools.length,
|
tools: tools.tools.length,
|
||||||
|
|
@ -283,12 +283,12 @@ func TestStressConcurrentContexts(t *testing.T) {
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
// Use trace
|
// Use trace
|
||||||
const node = ctx.Trace.Add({ type: "test" }, { label: "Concurrent Test" })
|
const node = ctx.trace.Add({ type: "test" }, { label: "Concurrent Test" })
|
||||||
ctx.Trace.Info("Processing concurrent request")
|
ctx.trace.Info("Processing concurrent request")
|
||||||
node.Complete({ result: "success" })
|
node.Complete({ result: "success" })
|
||||||
|
|
||||||
// Use MCP
|
// Use MCP
|
||||||
const tools = ctx.MCP.ListTools("echo", "")
|
const tools = ctx.mcp.ListTools("echo", "")
|
||||||
|
|
||||||
// Release resources
|
// Release resources
|
||||||
ctx.Release()
|
ctx.Release()
|
||||||
|
|
@ -358,7 +358,7 @@ func TestStressNoOpTracePerformance(t *testing.T) {
|
||||||
for i := 0; i < iterations; i++ {
|
for i := 0; i < iterations; i++ {
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
const trace = ctx.Trace // no-op trace
|
const trace = ctx.trace // no-op trace
|
||||||
|
|
||||||
// All operations should be no-ops and fast
|
// All operations should be no-ops and fast
|
||||||
trace.Info("No-op info")
|
trace.Info("No-op info")
|
||||||
|
|
@ -434,7 +434,7 @@ func TestStressReleasePatterns(t *testing.T) {
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
try {
|
try {
|
||||||
ctx.Trace.Add({ type: "test" }, { label: "Manual Release" })
|
ctx.trace.Add({ type: "test" }, { label: "Manual Release" })
|
||||||
return { success: true }
|
return { success: true }
|
||||||
} finally {
|
} finally {
|
||||||
ctx.Release() // Manual release
|
ctx.Release() // Manual release
|
||||||
|
|
@ -472,7 +472,7 @@ func TestStressReleasePatterns(t *testing.T) {
|
||||||
|
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
ctx.Trace.Add({ type: "test" }, { label: "GC Release" })
|
ctx.trace.Add({ type: "test" }, { label: "GC Release" })
|
||||||
return { success: true }
|
return { success: true }
|
||||||
// No manual release - rely on GC
|
// No manual release - rely on GC
|
||||||
}`, cxt)
|
}`, cxt)
|
||||||
|
|
@ -514,8 +514,8 @@ func TestStressReleasePatterns(t *testing.T) {
|
||||||
_, err := v8.Call(v8.CallOptions{}, `
|
_, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
try {
|
try {
|
||||||
ctx.Trace.Add({ type: "test" }, { label: "Separate Release" })
|
ctx.trace.Add({ type: "test" }, { label: "Separate Release" })
|
||||||
ctx.Trace.Release() // Release trace separately
|
ctx.trace.Release() // Release trace separately
|
||||||
return { success: true }
|
return { success: true }
|
||||||
} finally {
|
} finally {
|
||||||
ctx.Release() // Release context
|
ctx.Release() // Release context
|
||||||
|
|
@ -562,7 +562,7 @@ func TestStressLongRunningTrace(t *testing.T) {
|
||||||
|
|
||||||
_, err := v8.Call(v8.CallOptions{}, fmt.Sprintf(`
|
_, err := v8.Call(v8.CallOptions{}, fmt.Sprintf(`
|
||||||
function test(ctx) {
|
function test(ctx) {
|
||||||
const trace = ctx.Trace
|
const trace = ctx.trace
|
||||||
const allNodes = []
|
const allNodes = []
|
||||||
|
|
||||||
// Create many nested nodes
|
// Create many nested nodes
|
||||||
|
|
|
||||||
|
|
@ -417,7 +417,7 @@ func TestJsValueTrace(t *testing.T) {
|
||||||
res, err := v8.Call(v8.CallOptions{}, `
|
res, err := v8.Call(v8.CallOptions{}, `
|
||||||
function test(cxt) {
|
function test(cxt) {
|
||||||
// Get trace from context (property, not method call)
|
// Get trace from context (property, not method call)
|
||||||
const trace = cxt.Trace
|
const trace = cxt.trace
|
||||||
|
|
||||||
// Verify trace object exists
|
// Verify trace object exists
|
||||||
if (!trace) {
|
if (!trace) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue