From 21b2c46516458a42705054dc22ae8ad778f8877a Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Sun, 18 Jan 2026 01:52:36 +1000 Subject: [PATCH] fix(hllm): update package configuration and exports --- packages/tools/official/hllm/package.json | 2 +- packages/tools/official/hllm/src/index.ts | 173 ++++++++++++++-------- 2 files changed, 112 insertions(+), 63 deletions(-) diff --git a/packages/tools/official/hllm/package.json b/packages/tools/official/hllm/package.json index 9892e33..b1314e0 100644 --- a/packages/tools/official/hllm/package.json +++ b/packages/tools/official/hllm/package.json @@ -1,6 +1,6 @@ { "name": "@tpmjs/tools-hllm", - "version": "0.1.2", + "version": "0.1.4", "description": "HLLM API client tools for AI agents. Manage topologies, sessions, prompts, files, and more.", "type": "module", "keywords": [ diff --git a/packages/tools/official/hllm/src/index.ts b/packages/tools/official/hllm/src/index.ts index 1fa13aa..552577f 100644 --- a/packages/tools/official/hllm/src/index.ts +++ b/packages/tools/official/hllm/src/index.ts @@ -110,14 +110,14 @@ function handleApiError(status: number, errorText: string): never { // ============================================================================ export interface ExecuteTopologyInput { - topology: TopologyType; - prompt: string; - model?: string; - systemPrompt?: string; - temperature?: number; - maxTokens?: number; - tools?: string[]; + topologyId: TopologyType; + intent: string; + config?: Record; sessionId?: string; + conversationHistory?: Array<{ + role: 'user' | 'assistant' | 'system'; + content: string; + }>; } export interface ExecuteTopologyResult { @@ -139,6 +139,7 @@ export interface ExecuteTopologyResult { /** * Execute a topology with the given configuration. + * Returns streaming SSE response with text chunks and event objects. */ export const executeTopology = tool({ description: @@ -146,58 +147,106 @@ export const executeTopology = tool({ inputSchema: jsonSchema({ type: 'object', properties: { - topology: { + topologyId: { type: 'string', enum: [...TOPOLOGY_TYPES], description: 'Type of topology to execute.', }, - prompt: { + intent: { type: 'string', - description: 'The prompt to send to the topology.', + description: 'The task or prompt for execution (1-50,000 characters).', }, - model: { - type: 'string', - description: 'Model to use (e.g., "gpt-4", "claude-3-opus"). Uses default if not specified.', - }, - systemPrompt: { - type: 'string', - description: 'System prompt to set the context.', - }, - temperature: { - type: 'number', - description: 'Temperature for response randomness (0-2). Default: 0.7', - }, - maxTokens: { - type: 'number', - description: 'Maximum tokens in response.', - }, - tools: { - type: 'array', - items: { type: 'string' }, - description: 'Tool IDs to make available to the topology.', + config: { + type: 'object', + description: 'Topology-specific configuration (e.g., maxIterations for reflection).', + additionalProperties: true, }, sessionId: { type: 'string', - description: 'Session ID to continue a conversation.', + description: 'Associate execution with a chat session.', + }, + conversationHistory: { + type: 'array', + items: { + type: 'object', + properties: { + role: { type: 'string', enum: ['user', 'assistant', 'system'] }, + content: { type: 'string' }, + }, + required: ['role', 'content'], + }, + description: 'Previous messages for context continuity.', }, }, - required: ['topology', 'prompt'], + required: ['topologyId', 'intent'], additionalProperties: false, }), async execute(input: ExecuteTopologyInput): Promise { + const { apiKey, baseUrl } = getApiConfig(); + const body: Record = { - topology: input.topology, - prompt: input.prompt, + topologyId: input.topologyId, + intent: input.intent, }; - if (input.model) body.model = input.model; - if (input.systemPrompt) body.systemPrompt = input.systemPrompt; - if (input.temperature !== undefined) body.temperature = input.temperature; - if (input.maxTokens) body.maxTokens = input.maxTokens; - if (input.tools) body.tools = input.tools; + if (input.config) body.config = input.config; if (input.sessionId) body.sessionId = input.sessionId; + if (input.conversationHistory) body.conversationHistory = input.conversationHistory; - return apiRequest('POST', '/topology/execute', body); + // The /api/execute endpoint returns a streaming SSE response + // We need to collect the full response + const response = await fetch(`${baseUrl}/execute`, { + method: 'POST', + headers: { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify(body), + }); + + if (!response.ok) { + const errorText = await response.text().catch(() => 'Unknown error'); + handleApiError(response.status, errorText); + } + + // Parse streaming response - collect text chunks + const reader = response.body?.getReader(); + if (!reader) { + throw new Error('No response body'); + } + + const decoder = new TextDecoder(); + let fullText = ''; + let lastEvent: Record | null = null; + + while (true) { + const { done, value } = await reader.read(); + if (done) break; + + const chunk = decoder.decode(value, { stream: true }); + const lines = chunk.split('\n'); + + for (const line of lines) { + if (line.startsWith('text:')) { + fullText += line.slice(5); + } else if (line.startsWith('event:')) { + try { + lastEvent = JSON.parse(line.slice(6)); + } catch { + // Ignore parse errors + } + } + } + } + + return { + id: (lastEvent?.id as string) || 'unknown', + status: 'completed', + output: fullText, + tokens: lastEvent?.tokens as ExecuteTopologyResult['tokens'], + duration: lastEvent?.duration as number, + steps: lastEvent?.steps as ExecuteTopologyResult['steps'], + }; }, }); @@ -251,7 +300,7 @@ export const listSessions = tool({ if (input.limit) params.set('limit', input.limit.toString()); if (input.offset) params.set('offset', input.offset.toString()); const query = params.toString() ? `?${params.toString()}` : ''; - return apiRequest('GET', `/sessions${query}`, undefined); + return apiRequest('GET', `/chat/sessions${query}`, undefined); }, }); @@ -280,7 +329,7 @@ export const createSession = tool({ additionalProperties: false, }), async execute(input: CreateSessionInput): Promise { - return apiRequest('POST', '/sessions', input); + return apiRequest('POST', '/chat/sessions', input); }, }); @@ -303,7 +352,7 @@ export const getSession = tool({ async execute(input: { sessionId: string }): Promise { return apiRequest( 'GET', - `/sessions/${encodeURIComponent(input.sessionId)}`, + `/chat/sessions/${encodeURIComponent(input.sessionId)}`, undefined ); }, @@ -343,7 +392,7 @@ export const updateSession = tool({ const { sessionId, ...body } = input; return apiRequest( 'PATCH', - `/sessions/${encodeURIComponent(sessionId)}`, + `/chat/sessions/${encodeURIComponent(sessionId)}`, body ); }, @@ -368,7 +417,7 @@ export const deleteSession = tool({ async execute(input: { sessionId: string }): Promise<{ success: boolean }> { return apiRequest<{ success: boolean }>( 'DELETE', - `/sessions/${encodeURIComponent(input.sessionId)}`, + `/chat/sessions/${encodeURIComponent(input.sessionId)}`, undefined ); }, @@ -420,7 +469,7 @@ export const addMessage = tool({ const { sessionId, ...body } = input; return apiRequest( 'POST', - `/sessions/${encodeURIComponent(sessionId)}/messages`, + `/chat/sessions/${encodeURIComponent(sessionId)}/messages`, body ); }, @@ -445,7 +494,7 @@ export const clearMessages = tool({ async execute(input: { sessionId: string }): Promise<{ success: boolean; clearedCount: number }> { return apiRequest<{ success: boolean; clearedCount: number }>( 'DELETE', - `/sessions/${encodeURIComponent(input.sessionId)}/messages`, + `/chat/sessions/${encodeURIComponent(input.sessionId)}/messages`, undefined ); }, @@ -818,7 +867,7 @@ export const listEnvVars = tool({ additionalProperties: false, }), async execute(): Promise { - return apiRequest('GET', '/env-vars', undefined); + return apiRequest('GET', '/user/tpmjs-env', undefined); }, }); @@ -848,7 +897,7 @@ export const setEnvVar = tool({ additionalProperties: false, }), async execute(input: SetEnvVarInput): Promise { - return apiRequest('PUT', '/env-vars', input); + return apiRequest('PUT', '/user/tpmjs-env', input); }, }); @@ -871,7 +920,7 @@ export const deleteEnvVar = tool({ async execute(input: { key: string }): Promise<{ success: boolean }> { return apiRequest<{ success: boolean }>( 'DELETE', - `/env-vars/${encodeURIComponent(input.key)}`, + `/user/tpmjs-env/${encodeURIComponent(input.key)}`, undefined ); }, @@ -1112,7 +1161,7 @@ export const getAgentMetrics = tool({ }), async execute(input: { period?: 'hour' | 'day' | 'week' | 'month' }): Promise { const query = input.period ? `?period=${input.period}` : ''; - return apiRequest('GET', `/metrics${query}`, undefined); + return apiRequest('GET', `/metrics/agents${query}`, undefined); }, }); @@ -1154,7 +1203,7 @@ export const listTools = tool({ }), async execute(input: { category?: string }): Promise { const query = input.category ? `?category=${encodeURIComponent(input.category)}` : ''; - return apiRequest('GET', `/tools${query}`, undefined); + return apiRequest('GET', `/tpmjs/tools${query}`, undefined); }, }); @@ -1176,9 +1225,9 @@ export const describeTool = tool({ }), async execute(input: { toolId: string }): Promise { return apiRequest( - 'GET', - `/tools/${encodeURIComponent(input.toolId)}`, - undefined + 'POST', + '/tpmjs/describe', + { toolId: input.toolId } ); }, }); @@ -1218,8 +1267,8 @@ export const executeTool = tool({ async execute(input: ExecuteToolInput): Promise { return apiRequest( 'POST', - `/tools/${encodeURIComponent(input.toolId)}/execute`, - { parameters: input.parameters } + '/tpmjs/execute', + { toolId: input.toolId, parameters: input.parameters } ); }, }); @@ -1265,7 +1314,7 @@ export const generatePrompt = tool({ additionalProperties: false, }), async execute(input: GeneratePromptInput): Promise { - return apiRequest('POST', '/prompts/generate', input); + return apiRequest('POST', '/prompt-generate', input); }, }); @@ -1295,7 +1344,7 @@ export const improvePrompt = tool({ additionalProperties: false, }), async execute(input: ImprovePromptInput): Promise { - return apiRequest('POST', '/prompts/improve', input); + return apiRequest('POST', '/prompt-improve', input); }, }); @@ -1455,7 +1504,7 @@ export const listApiKeys = tool({ additionalProperties: false, }), async execute(): Promise { - return apiRequest('GET', '/api-keys', undefined); + return apiRequest('GET', '/user/api-keys', undefined); }, }); @@ -1487,7 +1536,7 @@ export const createApiKey = tool({ additionalProperties: false, }), async execute(input: CreateApiKeyInput): Promise { - return apiRequest('POST', '/api-keys', input); + return apiRequest('POST', '/user/api-keys', input); }, }); @@ -1510,7 +1559,7 @@ export const deleteApiKey = tool({ async execute(input: { keyId: string }): Promise<{ success: boolean }> { return apiRequest<{ success: boolean }>( 'DELETE', - `/api-keys/${encodeURIComponent(input.keyId)}`, + `/user/api-keys/${encodeURIComponent(input.keyId)}`, undefined ); },