UNPKG

@mondaydotcomorg/atp-client

Version:
411 lines (328 loc) 8.78 kB
# @mondaydotcomorg/atp-client Client library for connecting to Agent Tool Protocol servers and executing code. ## Overview The ATP client enables agents to connect to ATP servers, execute TypeScript code with runtime APIs, handle pauses for LLM/approval/embedding callbacks, and manage client-side tool execution. ## Installation ```bash npm install @mondaydotcomorg/atp-client ``` ## Architecture ```mermaid graph TB Client[AgentToolProtocolClient] --> Session[ClientSession] Client --> API[APIOperations] Client --> Exec[ExecutionOperations] Client --> Services[ServiceProviders] Services --> LLM[LLM Handler] Services --> Approval[Approval Handler] Services --> Embedding[Embedding Handler] Services --> Tools[Client Tools] Exec --> Pause[Pause/Resume] Session --> Hooks[Pre-Request Hooks] ``` ## Quick Start ### Basic Client ```typescript import { AgentToolProtocolClient } from '@mondaydotcomorg/atp-client'; const client = new AgentToolProtocolClient({ baseUrl: 'http://localhost:3333', headers: { Authorization: 'Bearer your-api-key', }, }); await client.init(); // Execute code const result = await client.execute({ code: ` const items = ['apple', 'banana', 'cherry']; return items.length; `, }); console.log(result.result); // 3 ``` ### With LLM Support ```typescript import { ChatOpenAI } from '@langchain/openai'; const llm = new ChatOpenAI({ modelName: 'gpt-4' }); const client = new AgentToolProtocolClient({ baseUrl: 'http://localhost:3333', headers: { Authorization: 'Bearer key' }, }); // Provide LLM for atp.llm.* calls client.provideLLM({ call: async (prompt, options) => { const response = await llm.invoke(prompt); return response.content; }, }); await client.init(); // Now code can use atp.llm.call() const result = await client.execute({ code: ` const joke = await atp.llm.call({ prompt: 'Tell me a programming joke', }); return joke; `, }); ``` ### With Embeddings ```typescript import { OpenAIEmbeddings } from '@langchain/openai'; const embeddings = new OpenAIEmbeddings(); client.provideEmbedding({ embed: async (text) => { const vector = await embeddings.embedQuery(text); // Store and return ID return 'embedding-id-123'; }, search: async (query, options) => { const queryVector = await embeddings.embedQuery(query); // Perform similarity search return results; }, }); // Code can now use atp.embedding.* const result = await client.execute({ code: ` const id = await atp.embedding.embed('Important document'); const similar = await atp.embedding.search('document', { topK: 5 }); return similar; `, }); ``` ### With Approval Handler ```typescript client.provideApproval({ request: async (message, context) => { // Prompt user for approval const approved = await askUser(message); return { approved, response: { reason: 'User decision' }, timestamp: Date.now(), }; }, }); // Code can use atp.approval.request() const result = await client.execute({ code: ` const approval = await atp.approval.request( 'Delete all files?', { critical: true } ); if (!approval.approved) { return { cancelled: true }; } return { deleted: true }; `, }); ``` ### Client-Side Tools Register custom tools that execute on the client: ```typescript import { createClientTool } from '@mondaydotcomorg/atp-client'; const fetchTool = createClientTool({ name: 'fetch', description: 'Make HTTP requests from client', inputSchema: { type: 'object', properties: { url: { type: 'string' }, method: { type: 'string', enum: ['GET', 'POST'] }, }, required: ['url'], }, handler: async (input) => { const response = await fetch(input.url, { method: input.method || 'GET', }); return await response.json(); }, }); const client = new AgentToolProtocolClient({ baseUrl: 'http://localhost:3333', headers: { Authorization: 'Bearer key' }, serviceProviders: { tools: [fetchTool], }, }); await client.init(); // Registers tools with server const tools = client.getClientTools(); console.log( 'Available tools:', tools.map((t) => t.name) ); const toolDefs = client.getClientToolDefinitions(); console.log('Tool definitions:', JSON.stringify(toolDefs, null, 2)); const result = await client.execute({ code: ` const data = await atp.tool.fetch({ url: 'https://api.example.com/data', method: 'GET', }); return data; `, }); ``` ### Pre-Request Hooks Intercept and modify requests (e.g., token refresh): ```typescript const client = new AgentToolProtocolClient({ baseUrl: 'http://localhost:3333', hooks: { preRequest: async (context) => { // Refresh token if needed if (tokenExpired()) { const newToken = await refreshToken(); return { headers: { ...context.currentHeaders, Authorization: `Bearer ${newToken}`, }, }; } return {}; }, }, }); ``` ## Core Features ### Execute Code ```typescript const result = await client.execute({ code: 'return 1 + 1', timeout: 30000, pausable: true, }); // Result structure interface ExecutionResult { status: 'success' | 'error' | 'paused' | 'timeout'; result?: unknown; error?: string; pauseReason?: string; executionId?: string; } ``` ### Search APIs ```typescript const results = await client.search({ query: 'user authentication', limit: 10, }); // Search by natural language query const searchResults = await client.searchQuery('how to create a user'); ``` ### Explore APIs ```typescript const schema = await client.explore(); // Returns API structure interface ExploreResult { apis: Array<{ name: string; description: string; functions: Array<{ name: string; description: string; parameters: unknown; }>; }>; } ``` ### Type Definitions ```typescript const types = await client.getTypeDefinitions(); // Returns TypeScript definitions for atp.* APIs ``` ## API Reference ### AgentToolProtocolClient ```typescript class AgentToolProtocolClient { constructor(options: AgentToolProtocolClientOptions); // Initialize session init(clientInfo?: Record<string, unknown>): Promise<{ clientId: string; token: string; expiresAt: number; tokenRotateAt: number; }>; // Execute code execute(config: ExecutionConfig): Promise<ExecutionResult>; // Resume paused execution resume(executionId: string, resumeData: ResumeData): Promise<ExecutionResult>; // Provide services provideLLM(handler: ClientLLMHandler): void; provideApproval(handler: ClientApprovalHandler): void; provideEmbedding(handler: ClientEmbeddingHandler): void; provideTools(tools: ClientTool[]): void; // Get client tools getTools(): ClientTool[]; // Returns tools with handlers getToolDefinitions(): ClientToolDefinition[]; // Returns tools without handlers // API discovery search(options: SearchOptions): Promise<SearchResult[]>; searchQuery(query: string, options?: SearchOptions): Promise<SearchResult[]>; explore(): Promise<ExploreResult>; getTypeDefinitions(): Promise<string>; // Session info getClientId(): string; } ``` ### Options ```typescript interface AgentToolProtocolClientOptions { baseUrl: string; headers?: Record<string, string>; serviceProviders?: { llm?: ClientLLMHandler; approval?: ClientApprovalHandler; embedding?: ClientEmbeddingHandler; tools?: ClientTool[]; }; hooks?: { preRequest?: (context: HookContext) => Promise<HookResult>; }; } ``` ## Flow Diagram ```mermaid sequenceDiagram participant Agent participant Client participant Server participant LLM Agent->>Client: execute(code) Client->>Server: POST /execute Server->>Server: Run code alt Code calls atp.llm.call() Server->>Client: Pause (LLM callback) Client->>Agent: Request LLM Agent->>LLM: API call LLM-->>Agent: Response Agent->>Client: Resume with result Client->>Server: POST /resume Server->>Server: Continue execution end Server-->>Client: Execution result Client-->>Agent: Return result ``` ## Error Handling ```typescript import { ExecutionStatus } from '@mondaydotcomorg/atp-client'; try { const result = await client.execute({ code: '...' }); if (result.status === ExecutionStatus.ERROR) { console.error('Execution failed:', result.error); } else if (result.status === ExecutionStatus.TIMEOUT) { console.error('Execution timed out'); } else if (result.status === ExecutionStatus.PAUSED) { console.log('Execution paused:', result.pauseReason); // Handle pause (resume later) } } catch (error) { console.error('Client error:', error); } ``` ## TypeScript Support Full TypeScript definitions with strict typing for all APIs. ## License MIT