From 0fa4374d9e439a39e503df2c08ac69e04346b744 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Sat, 17 Jan 2026 08:35:27 +1000 Subject: [PATCH] feat(tools): add @tpmjs/tools-hllm package Add HLLM API client tools for AI agents with 36 tools: - Topology execution (executeTopology) - Chat sessions (list, create, get, update, delete) - Session messages (add, clear) - Prompt library (CRUD + usage tracking) - User profile and stats - Environment variables - File management - Models listing - Execution logs and agent metrics - TPMJS tools (list, describe, execute) - Prompt generation and improvement - Data export/import - Health check and public stats - API keys management Published as @tpmjs/tools-hllm@0.1.0 --- packages/tools/official/blocks.yml | 916 +++++++++++ packages/tools/official/hllm/block.ts | 121 ++ packages/tools/official/hllm/index.ts | 6 + packages/tools/official/hllm/package.json | 207 +++ packages/tools/official/hllm/src/index.ts | 1577 +++++++++++++++++++ packages/tools/official/hllm/tsconfig.json | 11 + packages/tools/official/hllm/tsup.config.ts | 10 + pnpm-lock.yaml | 16 + 8 files changed, 2864 insertions(+) create mode 100644 packages/tools/official/hllm/block.ts create mode 100644 packages/tools/official/hllm/index.ts create mode 100644 packages/tools/official/hllm/package.json create mode 100644 packages/tools/official/hllm/src/index.ts create mode 100644 packages/tools/official/hllm/tsconfig.json create mode 100644 packages/tools/official/hllm/tsup.config.ts diff --git a/packages/tools/official/blocks.yml b/packages/tools/official/blocks.yml index 40d5343..0848113 100644 --- a/packages/tools/official/blocks.yml +++ b/packages/tools/official/blocks.yml @@ -421,6 +421,61 @@ domain: fields: [stdout, stderr, exitCode] description: "Result of executing a command on an exe.dev VM" + # ------------------------------------------------------------------------- + # HLLM entities + # ------------------------------------------------------------------------- + hllm_topology_result: + fields: [id, status, output, tokens, duration, steps] + description: "Result of executing an HLLM topology" + + hllm_session: + fields: [id, title, createdAt, updatedAt, messageCount] + description: "An HLLM chat session" + + hllm_message: + fields: [id, role, content, createdAt] + description: "A message in an HLLM chat session" + + hllm_prompt: + fields: [id, name, content, description, category, tags, usageCount] + description: "A prompt in the HLLM prompt library" + + hllm_user_profile: + fields: [id, email, name, avatar, preferences] + description: "HLLM user profile information" + + hllm_user_stats: + fields: [totalExecutions, totalTokens, totalSessions, totalPrompts, topologyBreakdown] + description: "HLLM user usage statistics" + + hllm_env_var: + fields: [key, value, createdAt, updatedAt] + description: "A TPMJS environment variable in HLLM" + + hllm_file: + fields: [id, name, size, mimeType, url, createdAt] + description: "An uploaded file in HLLM" + + hllm_model: + fields: [id, name, provider, contextWindow, inputPricing, outputPricing, capabilities] + description: "An available AI model in HLLM" + + hllm_execution_log: + fields: [id, topologyType, status, inputTokens, outputTokens, duration, error] + description: "An execution log entry in HLLM" + + hllm_agent_metrics: + fields: [totalRequests, successRate, averageLatency, tokenUsage, topologyBreakdown] + description: "HLLM agent performance metrics" + + hllm_tool_info: + fields: [id, name, description, package, parameters] + description: "Information about a TPMJS tool in HLLM" + + hllm_api_key: + fields: [id, name, keyHint, createdAt, lastUsedAt] + description: "An HLLM API key" + # ------------------------------------------------------------------------- # Agent & workflow entities # ------------------------------------------------------------------------- @@ -6593,6 +6648,867 @@ blocks: description: "Whether Shelley was successfully installed/upgraded" measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + # --------------------------------------------------------------------------- + # N) HLLM - Topology & Agent Tools + # --------------------------------------------------------------------------- + hllm.executeTopology: + type: utility + description: "Execute a topology with streaming SSE response. Supports topology types: single, sequential, parallel, map-reduce, scatter, debate, reflection, consensus, brainstorm, decomposition, rhetorical-triangle, tree-of-thoughts, react." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /topology/execute endpoint" + - id: topology_types + description: "Must support all topology types: single, sequential, parallel, map-reduce, scatter, debate, reflection, consensus, brainstorm, decomposition, rhetorical-triangle, tree-of-thoughts, react" + inputs: + - name: topology + type: string + description: "Type of topology to execute" + - name: prompt + type: string + description: "The prompt to send to the topology" + - name: model + type: string + optional: true + description: "Model to use (e.g., 'gpt-4', 'claude-3-opus')" + - name: systemPrompt + type: string + optional: true + description: "System prompt to set the context" + - name: temperature + type: number + optional: true + description: "Temperature for response randomness (0-2)" + - name: maxTokens + type: number + optional: true + description: "Maximum tokens in response" + - name: tools + type: string[] + optional: true + description: "Tool IDs to make available to the topology" + - name: sessionId + type: string + optional: true + description: "Session ID to continue a conversation" + outputs: + - name: id + type: string + description: "Execution ID" + - name: status + type: string + description: "Execution status" + - name: output + type: string + description: "Generated output" + - name: tokens + type: object + description: "Token usage (input, output, total)" + - name: duration + type: number + description: "Execution duration in ms" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.listSessions: + type: utility + description: "List all chat sessions for the authenticated user." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /sessions endpoint" + inputs: + - name: limit + type: number + optional: true + description: "Maximum number of sessions to return" + - name: offset + type: number + optional: true + description: "Number of sessions to skip" + outputs: + - name: sessions + type: hllm_session[] + description: "Array of chat sessions" + - name: total + type: number + description: "Total number of sessions" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.createSession: + type: utility + description: "Create a new chat session with optional initial configuration." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /sessions endpoint" + inputs: + - name: title + type: string + optional: true + description: "Title for the session" + - name: systemPrompt + type: string + optional: true + description: "System prompt for the session" + outputs: + - name: session + type: hllm_session + description: "The created session" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getSession: + type: utility + description: "Get details of a specific chat session including messages." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /sessions/{id} endpoint" + inputs: + - name: sessionId + type: string + description: "The session ID" + outputs: + - name: session + type: hllm_session + description: "Session details" + - name: messages + type: hllm_message[] + description: "Messages in the session" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.updateSession: + type: utility + description: "Update session properties like title or configuration." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API PATCH /sessions/{id} endpoint" + inputs: + - name: sessionId + type: string + description: "The session ID" + - name: title + type: string + optional: true + description: "New title for the session" + - name: systemPrompt + type: string + optional: true + description: "New system prompt" + outputs: + - name: session + type: hllm_session + description: "Updated session" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.deleteSession: + type: utility + description: "Delete a chat session and all its messages." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API DELETE /sessions/{id} endpoint" + inputs: + - name: sessionId + type: string + description: "The session ID to delete" + outputs: + - name: success + type: boolean + description: "Whether deletion was successful" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.addMessage: + type: utility + description: "Add a message to a chat session." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /sessions/{id}/messages endpoint" + inputs: + - name: sessionId + type: string + description: "The session ID" + - name: role + type: string + description: "Message role: user, assistant, or system" + - name: content + type: string + description: "Message content" + outputs: + - name: message + type: hllm_message + description: "The created message" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.clearMessages: + type: utility + description: "Clear all messages from a chat session." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API DELETE /sessions/{id}/messages endpoint" + inputs: + - name: sessionId + type: string + description: "The session ID" + outputs: + - name: success + type: boolean + description: "Whether clearing was successful" + - name: clearedCount + type: number + description: "Number of messages cleared" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.listPrompts: + type: utility + description: "List all prompts in the prompt library with optional filtering." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /prompts endpoint" + inputs: + - name: category + type: string + optional: true + description: "Filter by category" + - name: search + type: string + optional: true + description: "Search in name and content" + - name: limit + type: number + optional: true + description: "Maximum number of prompts to return" + - name: offset + type: number + optional: true + description: "Number of prompts to skip" + outputs: + - name: prompts + type: hllm_prompt[] + description: "Array of prompts" + - name: total + type: number + description: "Total number of prompts" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.createPrompt: + type: utility + description: "Create a new prompt in the library." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /prompts endpoint" + inputs: + - name: name + type: string + description: "Name of the prompt" + - name: content + type: string + description: "The prompt content/template" + - name: description + type: string + optional: true + description: "Description of what the prompt does" + - name: category + type: string + optional: true + description: "Category for organization" + - name: tags + type: string[] + optional: true + description: "Tags for filtering" + outputs: + - name: prompt + type: hllm_prompt + description: "The created prompt" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getPrompt: + type: utility + description: "Get details of a specific prompt." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /prompts/{id} endpoint" + inputs: + - name: promptId + type: string + description: "The prompt ID" + outputs: + - name: prompt + type: hllm_prompt + description: "Prompt details" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.updatePrompt: + type: utility + description: "Update an existing prompt." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API PATCH /prompts/{id} endpoint" + inputs: + - name: promptId + type: string + description: "The prompt ID" + - name: name + type: string + optional: true + description: "New name" + - name: content + type: string + optional: true + description: "New content" + - name: description + type: string + optional: true + description: "New description" + - name: category + type: string + optional: true + description: "New category" + - name: tags + type: string[] + optional: true + description: "New tags" + outputs: + - name: prompt + type: hllm_prompt + description: "Updated prompt" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.deletePrompt: + type: utility + description: "Delete a prompt from the library." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API DELETE /prompts/{id} endpoint" + inputs: + - name: promptId + type: string + description: "The prompt ID to delete" + outputs: + - name: success + type: boolean + description: "Whether deletion was successful" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.incrementPromptUsage: + type: utility + description: "Increment the usage count for a prompt." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /prompts/{id}/usage endpoint" + inputs: + - name: promptId + type: string + description: "The prompt ID" + outputs: + - name: usageCount + type: number + description: "New usage count" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getUserProfile: + type: utility + description: "Get the current user's profile information." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /user/profile endpoint" + inputs: [] + outputs: + - name: profile + type: hllm_user_profile + description: "User profile information" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.updateUserProfile: + type: utility + description: "Update the current user's profile." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API PATCH /user/profile endpoint" + inputs: + - name: name + type: string + optional: true + description: "Display name" + - name: avatar + type: string + optional: true + description: "Avatar URL" + - name: preferences + type: object + optional: true + description: "User preferences" + outputs: + - name: profile + type: hllm_user_profile + description: "Updated profile" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getUserStats: + type: utility + description: "Get usage statistics for the current user." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /user/stats endpoint" + inputs: + - name: period + type: string + optional: true + description: "Time period: day, week, month, or all" + outputs: + - name: stats + type: hllm_user_stats + description: "User statistics" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.listEnvVars: + type: utility + description: "List all TPMJS environment variables." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /env-vars endpoint" + inputs: [] + outputs: + - name: envVars + type: hllm_env_var[] + description: "Array of environment variables" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.setEnvVar: + type: utility + description: "Set or update a TPMJS environment variable." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API PUT /env-vars endpoint" + inputs: + - name: key + type: string + description: "Variable name" + - name: value + type: string + description: "Variable value" + outputs: + - name: envVar + type: hllm_env_var + description: "The created/updated variable" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.deleteEnvVar: + type: utility + description: "Delete a TPMJS environment variable." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API DELETE /env-vars/{key} endpoint" + inputs: + - name: key + type: string + description: "Variable name to delete" + outputs: + - name: success + type: boolean + description: "Whether deletion was successful" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.uploadFile: + type: utility + description: "Upload a file for use in topologies." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /files endpoint" + inputs: + - name: name + type: string + description: "File name" + - name: content + type: string + description: "Base64-encoded file content" + - name: mimeType + type: string + optional: true + description: "MIME type of the file" + outputs: + - name: file + type: hllm_file + description: "Uploaded file information" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getFile: + type: utility + description: "Get file metadata and download URL." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /files/{id} endpoint" + inputs: + - name: fileId + type: string + description: "The file ID" + outputs: + - name: file + type: hllm_file + description: "File information" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.deleteFile: + type: utility + description: "Delete an uploaded file." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API DELETE /files/{id} endpoint" + inputs: + - name: fileId + type: string + description: "The file ID to delete" + outputs: + - name: success + type: boolean + description: "Whether deletion was successful" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.listModels: + type: utility + description: "List all available AI models." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /models endpoint" + inputs: + - name: provider + type: string + optional: true + description: "Filter by provider (openai, anthropic, google, etc.)" + outputs: + - name: models + type: hllm_model[] + description: "Array of available models" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getExecutionLogs: + type: utility + description: "Get execution logs for topology runs." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /logs endpoint" + inputs: + - name: sessionId + type: string + optional: true + description: "Filter logs by session ID" + - name: limit + type: number + optional: true + description: "Maximum number of logs to return" + - name: offset + type: number + optional: true + description: "Number of logs to skip" + outputs: + - name: logs + type: hllm_execution_log[] + description: "Array of execution logs" + - name: total + type: number + description: "Total number of logs" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getAgentMetrics: + type: utility + description: "Get agent performance metrics." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /metrics endpoint" + inputs: + - name: period + type: string + optional: true + description: "Time period: hour, day, week, or month" + outputs: + - name: metrics + type: hllm_agent_metrics + description: "Agent metrics" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.listTools: + type: utility + description: "List all available TPMJS tools." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /tools endpoint" + inputs: + - name: category + type: string + optional: true + description: "Filter by category" + outputs: + - name: tools + type: hllm_tool_info[] + description: "Array of available tools" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.describeTool: + type: utility + description: "Get detailed description of a specific tool." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /tools/{id} endpoint" + inputs: + - name: toolId + type: string + description: "The tool ID" + outputs: + - name: tool + type: hllm_tool_info + description: "Tool information" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.executeTool: + type: utility + description: "Execute a TPMJS tool directly." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /tools/{id}/execute endpoint" + inputs: + - name: toolId + type: string + description: "The tool ID to execute" + - name: parameters + type: object + description: "Tool parameters" + outputs: + - name: success + type: boolean + description: "Whether execution was successful" + - name: result + type: any + description: "Tool execution result" + - name: duration + type: number + description: "Execution duration in ms" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.generatePrompt: + type: utility + description: "Generate a prompt using AI assistance." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /prompts/generate endpoint" + inputs: + - name: task + type: string + description: "Description of what the prompt should accomplish" + - name: context + type: string + optional: true + description: "Additional context for prompt generation" + - name: style + type: string + optional: true + description: "Style: concise, detailed, or creative" + outputs: + - name: prompt + type: string + description: "Generated prompt" + - name: suggestions + type: string[] + optional: true + description: "Alternative suggestions" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.improvePrompt: + type: utility + description: "Improve an existing prompt using AI." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /prompts/improve endpoint" + inputs: + - name: prompt + type: string + description: "The prompt to improve" + - name: goal + type: string + optional: true + description: "What improvement to focus on" + outputs: + - name: prompt + type: string + description: "Improved prompt" + - name: suggestions + type: string[] + optional: true + description: "Alternative suggestions" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.exportData: + type: utility + description: "Export user data including sessions, prompts, and settings." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /export endpoint" + inputs: + - name: include + type: string[] + optional: true + description: "What data to include: sessions, prompts, settings, files" + outputs: + - name: data + type: string + description: "Base64 encoded export data" + - name: format + type: string + description: "Export format" + - name: exportedAt + type: string + description: "Export timestamp" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.importData: + type: utility + description: "Import previously exported data." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /import endpoint" + inputs: + - name: data + type: string + description: "Base64 encoded export data" + - name: overwrite + type: boolean + optional: true + description: "Whether to overwrite existing data" + outputs: + - name: success + type: boolean + description: "Whether import was successful" + - name: imported + type: object + description: "Summary of imported items" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.healthCheck: + type: utility + description: "Check HLLM API health status." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /health endpoint" + inputs: [] + outputs: + - name: status + type: string + description: "Health status" + - name: version + type: string + description: "API version" + - name: uptime + type: number + description: "Uptime in seconds" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.getStats: + type: utility + description: "Get public HLLM statistics." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /stats endpoint" + inputs: [] + outputs: + - name: totalUsers + type: number + description: "Total number of users" + - name: totalExecutions + type: number + description: "Total number of executions" + - name: totalTokens + type: number + description: "Total tokens processed" + - name: uptimePercent + type: number + description: "Uptime percentage" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.listApiKeys: + type: utility + description: "List all API keys for the authenticated user." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API GET /api-keys endpoint" + inputs: [] + outputs: + - name: apiKeys + type: hllm_api_key[] + description: "Array of API keys" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.createApiKey: + type: utility + description: "Create a new API key." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API POST /api-keys endpoint" + inputs: + - name: name + type: string + description: "Name for the API key" + outputs: + - name: id + type: string + description: "Key ID" + - name: name + type: string + description: "Key name" + - name: key + type: string + description: "Full API key (only shown once)" + - name: createdAt + type: string + description: "Creation timestamp" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + + hllm.deleteApiKey: + type: utility + description: "Delete an API key." + path: "hllm" + domain_rules: + - id: api_integration + description: "Must call HLLM API DELETE /api-keys/{id} endpoint" + inputs: + - name: keyId + type: string + description: "The API key ID to delete" + outputs: + - name: success + type: boolean + description: "Whether deletion was successful" + measures: [working_implementation, valid_output_structure, proper_error_handling, ai_sdk_compliance] + # --------------------------------------------------------------------------- # Utility Tools # --------------------------------------------------------------------------- diff --git a/packages/tools/official/hllm/block.ts b/packages/tools/official/hllm/block.ts new file mode 100644 index 0000000..1ef3521 --- /dev/null +++ b/packages/tools/official/hllm/block.ts @@ -0,0 +1,121 @@ +/** + * Block metadata for HLLM tools + * This file provides metadata for the blocks validator + */ +import { + // Topology + executeTopology, + // Sessions + listSessions, + createSession, + getSession, + updateSession, + deleteSession, + // Messages + addMessage, + clearMessages, + // Prompts + listPrompts, + createPrompt, + getPrompt, + updatePrompt, + deletePrompt, + incrementPromptUsage, + // User + getUserProfile, + updateUserProfile, + getUserStats, + // Env Vars + listEnvVars, + setEnvVar, + deleteEnvVar, + // Files + uploadFile, + getFile, + deleteFile, + // Models + listModels, + // Logs + getExecutionLogs, + // Metrics + getAgentMetrics, + // Tools + listTools, + describeTool, + executeTool, + // Prompt Generation + generatePrompt, + improvePrompt, + // Export/Import + exportData, + importData, + // Public + healthCheck, + getStats, + // API Keys + listApiKeys, + createApiKey, + deleteApiKey, +} from './src/index.js'; + +export const block = { + name: 'hllm', + description: 'HLLM API client tools for AI agents. Manage topologies, sessions, prompts, files, and more.', + tools: { + // Topology + executeTopology, + // Sessions + listSessions, + createSession, + getSession, + updateSession, + deleteSession, + // Messages + addMessage, + clearMessages, + // Prompts + listPrompts, + createPrompt, + getPrompt, + updatePrompt, + deletePrompt, + incrementPromptUsage, + // User + getUserProfile, + updateUserProfile, + getUserStats, + // Env Vars + listEnvVars, + setEnvVar, + deleteEnvVar, + // Files + uploadFile, + getFile, + deleteFile, + // Models + listModels, + // Logs + getExecutionLogs, + // Metrics + getAgentMetrics, + // Tools + listTools, + describeTool, + executeTool, + // Prompt Generation + generatePrompt, + improvePrompt, + // Export/Import + exportData, + importData, + // Public + healthCheck, + getStats, + // API Keys + listApiKeys, + createApiKey, + deleteApiKey, + }, +}; + +export default block; diff --git a/packages/tools/official/hllm/index.ts b/packages/tools/official/hllm/index.ts new file mode 100644 index 0000000..9721968 --- /dev/null +++ b/packages/tools/official/hllm/index.ts @@ -0,0 +1,6 @@ +/** + * HLLM API Client Tools for TPMJS + * Re-export all tools from src/index.ts + */ +export * from './src/index.js'; +export { default } from './src/index.js'; diff --git a/packages/tools/official/hllm/package.json b/packages/tools/official/hllm/package.json new file mode 100644 index 0000000..0188cab --- /dev/null +++ b/packages/tools/official/hllm/package.json @@ -0,0 +1,207 @@ +{ + "name": "@tpmjs/tools-hllm", + "version": "0.1.0", + "description": "HLLM API client tools for AI agents. Manage topologies, sessions, prompts, files, and more.", + "type": "module", + "keywords": [ + "tpmjs", + "hllm", + "ai", + "llm", + "topology", + "agent" + ], + "exports": { + ".": { + "types": "./dist/index.d.ts", + "default": "./dist/index.js" + } + }, + "files": [ + "dist" + ], + "scripts": { + "build": "tsup", + "dev": "tsup --watch", + "type-check": "tsc --noEmit", + "clean": "rm -rf dist .turbo" + }, + "devDependencies": { + "@tpmjs/tsconfig": "workspace:*", + "tsup": "^8.5.1", + "typescript": "^5.9.3" + }, + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "https://github.com/tpmjs/tpmjs.git", + "directory": "packages/tools/official/hllm" + }, + "homepage": "https://tpmjs.com", + "license": "MIT", + "tpmjs": { + "category": "agent", + "frameworks": [ + "vercel-ai" + ], + "tools": [ + { + "name": "executeTopology", + "description": "Execute a topology with streaming SSE response. Supports various topology types including single, sequential, parallel, map-reduce, and more." + }, + { + "name": "listSessions", + "description": "List all chat sessions for the authenticated user." + }, + { + "name": "createSession", + "description": "Create a new chat session with optional initial configuration." + }, + { + "name": "getSession", + "description": "Get details of a specific chat session including messages." + }, + { + "name": "updateSession", + "description": "Update session properties like title or configuration." + }, + { + "name": "deleteSession", + "description": "Delete a chat session and all its messages." + }, + { + "name": "addMessage", + "description": "Add a message to a chat session." + }, + { + "name": "clearMessages", + "description": "Clear all messages from a chat session." + }, + { + "name": "listPrompts", + "description": "List all prompts in the prompt library with optional filtering." + }, + { + "name": "createPrompt", + "description": "Create a new prompt in the library." + }, + { + "name": "getPrompt", + "description": "Get details of a specific prompt." + }, + { + "name": "updatePrompt", + "description": "Update an existing prompt." + }, + { + "name": "deletePrompt", + "description": "Delete a prompt from the library." + }, + { + "name": "incrementPromptUsage", + "description": "Increment the usage count for a prompt." + }, + { + "name": "getUserProfile", + "description": "Get the current user's profile information." + }, + { + "name": "updateUserProfile", + "description": "Update the current user's profile." + }, + { + "name": "getUserStats", + "description": "Get usage statistics for the current user." + }, + { + "name": "listEnvVars", + "description": "List all TPMJS environment variables." + }, + { + "name": "setEnvVar", + "description": "Set or update a TPMJS environment variable." + }, + { + "name": "deleteEnvVar", + "description": "Delete a TPMJS environment variable." + }, + { + "name": "uploadFile", + "description": "Upload a file for use in topologies." + }, + { + "name": "getFile", + "description": "Get file metadata and download URL." + }, + { + "name": "deleteFile", + "description": "Delete an uploaded file." + }, + { + "name": "listModels", + "description": "List all available AI models." + }, + { + "name": "getExecutionLogs", + "description": "Get execution logs for topology runs." + }, + { + "name": "getAgentMetrics", + "description": "Get agent performance metrics." + }, + { + "name": "listTools", + "description": "List all available TPMJS tools." + }, + { + "name": "describeTool", + "description": "Get detailed description of a specific tool." + }, + { + "name": "executeTool", + "description": "Execute a TPMJS tool directly." + }, + { + "name": "generatePrompt", + "description": "Generate a prompt using AI assistance." + }, + { + "name": "improvePrompt", + "description": "Improve an existing prompt using AI." + }, + { + "name": "exportData", + "description": "Export user data including sessions, prompts, and settings." + }, + { + "name": "importData", + "description": "Import previously exported data." + }, + { + "name": "healthCheck", + "description": "Check HLLM API health status." + }, + { + "name": "getStats", + "description": "Get public HLLM statistics." + }, + { + "name": "listApiKeys", + "description": "List all API keys for the authenticated user." + }, + { + "name": "createApiKey", + "description": "Create a new API key." + }, + { + "name": "deleteApiKey", + "description": "Delete an API key." + } + ] + }, + "dependencies": { + "ai": "6.0.23" + } +} diff --git a/packages/tools/official/hllm/src/index.ts b/packages/tools/official/hllm/src/index.ts new file mode 100644 index 0000000..582df51 --- /dev/null +++ b/packages/tools/official/hllm/src/index.ts @@ -0,0 +1,1577 @@ +/** + * HLLM API Client Tools for TPMJS + * Manage topologies, sessions, prompts, files, and more. + * + * @requires HLLM_API_KEY environment variable (hllm_xxxx_xxx format) + * @requires HLLM_BASE_URL environment variable (optional, defaults to https://hllm.ai/api) + */ + +import { jsonSchema, tool } from 'ai'; + +const DEFAULT_BASE_URL = 'https://hllm.ai/api'; + +/** + * Topology types supported by HLLM + */ +export const TOPOLOGY_TYPES = [ + 'single', + 'sequential', + 'parallel', + 'map-reduce', + 'scatter', + 'debate', + 'reflection', + 'consensus', + 'brainstorm', + 'decomposition', + 'rhetorical-triangle', + 'tree-of-thoughts', + 'react', +] as const; + +export type TopologyType = (typeof TOPOLOGY_TYPES)[number]; + +/** + * Get API configuration from environment variables + */ +function getApiConfig(): { apiKey: string; baseUrl: string } { + const apiKey = process.env.HLLM_API_KEY; + const baseUrl = process.env.HLLM_BASE_URL || DEFAULT_BASE_URL; + + if (!apiKey) { + throw new Error( + 'HLLM_API_KEY environment variable is required. Get your API key from https://hllm.ai/settings/api-keys' + ); + } + + return { apiKey, baseUrl }; +} + +/** + * Make an authenticated request to the HLLM API + */ +async function apiRequest( + method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', + path: string, + body?: unknown +): Promise { + const { apiKey, baseUrl } = getApiConfig(); + + const headers: Record = { + Authorization: `Bearer ${apiKey}`, + }; + + if (body !== undefined) { + headers['Content-Type'] = 'application/json'; + } + + const response = await fetch(`${baseUrl}${path}`, { + method, + headers, + body: body !== undefined ? JSON.stringify(body) : undefined, + }); + + if (!response.ok) { + const errorText = await response.text().catch(() => 'Unknown error'); + handleApiError(response.status, errorText); + } + + return response.json() as Promise; +} + +/** + * Handle API errors with specific messages for common HTTP status codes + */ +function handleApiError(status: number, errorText: string): never { + switch (status) { + case 400: + throw new Error(`Bad request: ${errorText}`); + case 401: + throw new Error( + 'Authentication failed: Invalid API key. Ensure HLLM_API_KEY is correct.' + ); + case 403: + throw new Error(`Access forbidden: ${errorText}`); + case 404: + throw new Error(`Resource not found: ${errorText}`); + case 429: + throw new Error(`Rate limit exceeded: ${errorText}`); + case 500: + case 502: + case 503: + throw new Error(`HLLM service error (${status}): ${errorText}`); + default: + throw new Error(`HLLM API error: HTTP ${status} - ${errorText}`); + } +} + +// ============================================================================ +// Topology Execution +// ============================================================================ + +export interface ExecuteTopologyInput { + topology: TopologyType; + prompt: string; + model?: string; + systemPrompt?: string; + temperature?: number; + maxTokens?: number; + tools?: string[]; + sessionId?: string; +} + +export interface ExecuteTopologyResult { + id: string; + status: string; + output?: string; + tokens?: { + input: number; + output: number; + total: number; + }; + duration?: number; + steps?: Array<{ + id: string; + role: string; + content: string; + }>; +} + +/** + * Execute a topology with the given configuration. + */ +export const executeTopology = tool({ + description: + 'Execute a topology with streaming SSE response. Supports topology types: single, sequential, parallel, map-reduce, scatter, debate, reflection, consensus, brainstorm, decomposition, rhetorical-triangle, tree-of-thoughts, react.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + topology: { + type: 'string', + enum: [...TOPOLOGY_TYPES], + description: 'Type of topology to execute.', + }, + prompt: { + type: 'string', + description: 'The prompt to send to the topology.', + }, + 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.', + }, + sessionId: { + type: 'string', + description: 'Session ID to continue a conversation.', + }, + }, + required: ['topology', 'prompt'], + additionalProperties: false, + }), + async execute(input: ExecuteTopologyInput): Promise { + const body: Record = { + topology: input.topology, + prompt: input.prompt, + }; + + 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.sessionId) body.sessionId = input.sessionId; + + return apiRequest('POST', '/topology/execute', body); + }, +}); + +// ============================================================================ +// Chat Sessions +// ============================================================================ + +export interface Session { + id: string; + title?: string; + createdAt: string; + updatedAt: string; + messageCount?: number; +} + +export interface SessionWithMessages extends Session { + messages: Array<{ + id: string; + role: 'user' | 'assistant' | 'system'; + content: string; + createdAt: string; + }>; +} + +export interface ListSessionsResult { + sessions: Session[]; + total: number; +} + +/** + * List all chat sessions. + */ +export const listSessions = tool({ + description: 'List all chat sessions for the authenticated user.', + inputSchema: jsonSchema<{ limit?: number; offset?: number }>({ + type: 'object', + properties: { + limit: { + type: 'number', + description: 'Maximum number of sessions to return. Default: 20', + }, + offset: { + type: 'number', + description: 'Number of sessions to skip. Default: 0', + }, + }, + additionalProperties: false, + }), + async execute(input: { limit?: number; offset?: number }): Promise { + const params = new URLSearchParams(); + 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); + }, +}); + +export interface CreateSessionInput { + title?: string; + systemPrompt?: string; +} + +/** + * Create a new chat session. + */ +export const createSession = tool({ + description: 'Create a new chat session with optional initial configuration.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + title: { + type: 'string', + description: 'Title for the session.', + }, + systemPrompt: { + type: 'string', + description: 'System prompt for the session.', + }, + }, + additionalProperties: false, + }), + async execute(input: CreateSessionInput): Promise { + return apiRequest('POST', '/sessions', input); + }, +}); + +/** + * Get session details. + */ +export const getSession = tool({ + description: 'Get details of a specific chat session including messages.', + inputSchema: jsonSchema<{ sessionId: string }>({ + type: 'object', + properties: { + sessionId: { + type: 'string', + description: 'The session ID.', + }, + }, + required: ['sessionId'], + additionalProperties: false, + }), + async execute(input: { sessionId: string }): Promise { + return apiRequest( + 'GET', + `/sessions/${encodeURIComponent(input.sessionId)}`, + undefined + ); + }, +}); + +export interface UpdateSessionInput { + sessionId: string; + title?: string; + systemPrompt?: string; +} + +/** + * Update session properties. + */ +export const updateSession = tool({ + description: 'Update session properties like title or configuration.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + sessionId: { + type: 'string', + description: 'The session ID.', + }, + title: { + type: 'string', + description: 'New title for the session.', + }, + systemPrompt: { + type: 'string', + description: 'New system prompt for the session.', + }, + }, + required: ['sessionId'], + additionalProperties: false, + }), + async execute(input: UpdateSessionInput): Promise { + const { sessionId, ...body } = input; + return apiRequest( + 'PATCH', + `/sessions/${encodeURIComponent(sessionId)}`, + body + ); + }, +}); + +/** + * Delete a chat session. + */ +export const deleteSession = tool({ + description: 'Delete a chat session and all its messages.', + inputSchema: jsonSchema<{ sessionId: string }>({ + type: 'object', + properties: { + sessionId: { + type: 'string', + description: 'The session ID to delete.', + }, + }, + required: ['sessionId'], + additionalProperties: false, + }), + async execute(input: { sessionId: string }): Promise<{ success: boolean }> { + return apiRequest<{ success: boolean }>( + 'DELETE', + `/sessions/${encodeURIComponent(input.sessionId)}`, + undefined + ); + }, +}); + +// ============================================================================ +// Session Messages +// ============================================================================ + +export interface AddMessageInput { + sessionId: string; + role: 'user' | 'assistant' | 'system'; + content: string; +} + +export interface Message { + id: string; + role: 'user' | 'assistant' | 'system'; + content: string; + createdAt: string; +} + +/** + * Add a message to a session. + */ +export const addMessage = tool({ + description: 'Add a message to a chat session.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + sessionId: { + type: 'string', + description: 'The session ID.', + }, + role: { + type: 'string', + enum: ['user', 'assistant', 'system'], + description: 'The role of the message sender.', + }, + content: { + type: 'string', + description: 'The message content.', + }, + }, + required: ['sessionId', 'role', 'content'], + additionalProperties: false, + }), + async execute(input: AddMessageInput): Promise { + const { sessionId, ...body } = input; + return apiRequest( + 'POST', + `/sessions/${encodeURIComponent(sessionId)}/messages`, + body + ); + }, +}); + +/** + * Clear all messages from a session. + */ +export const clearMessages = tool({ + description: 'Clear all messages from a chat session.', + inputSchema: jsonSchema<{ sessionId: string }>({ + type: 'object', + properties: { + sessionId: { + type: 'string', + description: 'The session ID.', + }, + }, + required: ['sessionId'], + additionalProperties: false, + }), + async execute(input: { sessionId: string }): Promise<{ success: boolean; clearedCount: number }> { + return apiRequest<{ success: boolean; clearedCount: number }>( + 'DELETE', + `/sessions/${encodeURIComponent(input.sessionId)}/messages`, + undefined + ); + }, +}); + +// ============================================================================ +// Prompt Library +// ============================================================================ + +export interface Prompt { + id: string; + name: string; + content: string; + description?: string; + category?: string; + tags?: string[]; + usageCount: number; + createdAt: string; + updatedAt: string; +} + +export interface ListPromptsInput { + category?: string; + search?: string; + limit?: number; + offset?: number; +} + +export interface ListPromptsResult { + prompts: Prompt[]; + total: number; +} + +/** + * List prompts in the library. + */ +export const listPrompts = tool({ + description: 'List all prompts in the prompt library with optional filtering.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + category: { + type: 'string', + description: 'Filter by category.', + }, + search: { + type: 'string', + description: 'Search in name and content.', + }, + limit: { + type: 'number', + description: 'Maximum number of prompts to return.', + }, + offset: { + type: 'number', + description: 'Number of prompts to skip.', + }, + }, + additionalProperties: false, + }), + async execute(input: ListPromptsInput): Promise { + const params = new URLSearchParams(); + if (input.category) params.set('category', input.category); + if (input.search) params.set('search', input.search); + 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', `/prompts${query}`, undefined); + }, +}); + +export interface CreatePromptInput { + name: string; + content: string; + description?: string; + category?: string; + tags?: string[]; +} + +/** + * Create a new prompt. + */ +export const createPrompt = tool({ + description: 'Create a new prompt in the library.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + name: { + type: 'string', + description: 'Name of the prompt.', + }, + content: { + type: 'string', + description: 'The prompt content/template.', + }, + description: { + type: 'string', + description: 'Description of what the prompt does.', + }, + category: { + type: 'string', + description: 'Category for organization.', + }, + tags: { + type: 'array', + items: { type: 'string' }, + description: 'Tags for filtering.', + }, + }, + required: ['name', 'content'], + additionalProperties: false, + }), + async execute(input: CreatePromptInput): Promise { + return apiRequest('POST', '/prompts', input); + }, +}); + +/** + * Get prompt details. + */ +export const getPrompt = tool({ + description: 'Get details of a specific prompt.', + inputSchema: jsonSchema<{ promptId: string }>({ + type: 'object', + properties: { + promptId: { + type: 'string', + description: 'The prompt ID.', + }, + }, + required: ['promptId'], + additionalProperties: false, + }), + async execute(input: { promptId: string }): Promise { + return apiRequest( + 'GET', + `/prompts/${encodeURIComponent(input.promptId)}`, + undefined + ); + }, +}); + +export interface UpdatePromptInput { + promptId: string; + name?: string; + content?: string; + description?: string; + category?: string; + tags?: string[]; +} + +/** + * Update a prompt. + */ +export const updatePrompt = tool({ + description: 'Update an existing prompt.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + promptId: { + type: 'string', + description: 'The prompt ID.', + }, + name: { + type: 'string', + description: 'New name for the prompt.', + }, + content: { + type: 'string', + description: 'New content for the prompt.', + }, + description: { + type: 'string', + description: 'New description.', + }, + category: { + type: 'string', + description: 'New category.', + }, + tags: { + type: 'array', + items: { type: 'string' }, + description: 'New tags.', + }, + }, + required: ['promptId'], + additionalProperties: false, + }), + async execute(input: UpdatePromptInput): Promise { + const { promptId, ...body } = input; + return apiRequest( + 'PATCH', + `/prompts/${encodeURIComponent(promptId)}`, + body + ); + }, +}); + +/** + * Delete a prompt. + */ +export const deletePrompt = tool({ + description: 'Delete a prompt from the library.', + inputSchema: jsonSchema<{ promptId: string }>({ + type: 'object', + properties: { + promptId: { + type: 'string', + description: 'The prompt ID to delete.', + }, + }, + required: ['promptId'], + additionalProperties: false, + }), + async execute(input: { promptId: string }): Promise<{ success: boolean }> { + return apiRequest<{ success: boolean }>( + 'DELETE', + `/prompts/${encodeURIComponent(input.promptId)}`, + undefined + ); + }, +}); + +/** + * Increment prompt usage count. + */ +export const incrementPromptUsage = tool({ + description: 'Increment the usage count for a prompt.', + inputSchema: jsonSchema<{ promptId: string }>({ + type: 'object', + properties: { + promptId: { + type: 'string', + description: 'The prompt ID.', + }, + }, + required: ['promptId'], + additionalProperties: false, + }), + async execute(input: { promptId: string }): Promise<{ usageCount: number }> { + return apiRequest<{ usageCount: number }>( + 'POST', + `/prompts/${encodeURIComponent(input.promptId)}/usage`, + {} + ); + }, +}); + +// ============================================================================ +// User Profile & Stats +// ============================================================================ + +export interface UserProfile { + id: string; + email: string; + name?: string; + avatar?: string; + preferences?: Record; + createdAt: string; +} + +/** + * Get user profile. + */ +export const getUserProfile = tool({ + description: "Get the current user's profile information.", + inputSchema: jsonSchema>({ + type: 'object', + properties: {}, + additionalProperties: false, + }), + async execute(): Promise { + return apiRequest('GET', '/user/profile', undefined); + }, +}); + +export interface UpdateUserProfileInput { + name?: string; + avatar?: string; + preferences?: Record; +} + +/** + * Update user profile. + */ +export const updateUserProfile = tool({ + description: "Update the current user's profile.", + inputSchema: jsonSchema({ + type: 'object', + properties: { + name: { + type: 'string', + description: 'Display name.', + }, + avatar: { + type: 'string', + description: 'Avatar URL.', + }, + preferences: { + type: 'object', + description: 'User preferences object.', + additionalProperties: true, + }, + }, + additionalProperties: false, + }), + async execute(input: UpdateUserProfileInput): Promise { + return apiRequest('PATCH', '/user/profile', input); + }, +}); + +export interface UserStats { + totalExecutions: number; + totalTokens: { + input: number; + output: number; + }; + totalSessions: number; + totalPrompts: number; + topologyBreakdown: Record; + periodStart: string; + periodEnd: string; +} + +/** + * Get user stats. + */ +export const getUserStats = tool({ + description: 'Get usage statistics for the current user.', + inputSchema: jsonSchema<{ period?: 'day' | 'week' | 'month' | 'all' }>({ + type: 'object', + properties: { + period: { + type: 'string', + enum: ['day', 'week', 'month', 'all'], + description: 'Time period for stats. Default: month', + }, + }, + additionalProperties: false, + }), + async execute(input: { period?: 'day' | 'week' | 'month' | 'all' }): Promise { + const query = input.period ? `?period=${input.period}` : ''; + return apiRequest('GET', `/user/stats${query}`, undefined); + }, +}); + +// ============================================================================ +// TPMJS Environment Variables +// ============================================================================ + +export interface EnvVar { + key: string; + value: string; + createdAt: string; + updatedAt: string; +} + +export interface ListEnvVarsResult { + envVars: EnvVar[]; +} + +/** + * List environment variables. + */ +export const listEnvVars = tool({ + description: 'List all TPMJS environment variables.', + inputSchema: jsonSchema>({ + type: 'object', + properties: {}, + additionalProperties: false, + }), + async execute(): Promise { + return apiRequest('GET', '/env-vars', undefined); + }, +}); + +export interface SetEnvVarInput { + key: string; + value: string; +} + +/** + * Set environment variable. + */ +export const setEnvVar = tool({ + description: 'Set or update a TPMJS environment variable.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + key: { + type: 'string', + description: 'Variable name.', + }, + value: { + type: 'string', + description: 'Variable value.', + }, + }, + required: ['key', 'value'], + additionalProperties: false, + }), + async execute(input: SetEnvVarInput): Promise { + return apiRequest('PUT', '/env-vars', input); + }, +}); + +/** + * Delete environment variable. + */ +export const deleteEnvVar = tool({ + description: 'Delete a TPMJS environment variable.', + inputSchema: jsonSchema<{ key: string }>({ + type: 'object', + properties: { + key: { + type: 'string', + description: 'Variable name to delete.', + }, + }, + required: ['key'], + additionalProperties: false, + }), + async execute(input: { key: string }): Promise<{ success: boolean }> { + return apiRequest<{ success: boolean }>( + 'DELETE', + `/env-vars/${encodeURIComponent(input.key)}`, + undefined + ); + }, +}); + +// ============================================================================ +// Files +// ============================================================================ + +export interface FileInfo { + id: string; + name: string; + size: number; + mimeType: string; + url: string; + createdAt: string; +} + +export interface UploadFileInput { + name: string; + content: string; // Base64 encoded + mimeType?: string; +} + +/** + * Upload a file. + */ +export const uploadFile = tool({ + description: 'Upload a file for use in topologies.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + name: { + type: 'string', + description: 'File name.', + }, + content: { + type: 'string', + description: 'Base64-encoded file content.', + }, + mimeType: { + type: 'string', + description: 'MIME type of the file.', + }, + }, + required: ['name', 'content'], + additionalProperties: false, + }), + async execute(input: UploadFileInput): Promise { + return apiRequest('POST', '/files', input); + }, +}); + +/** + * Get file metadata. + */ +export const getFile = tool({ + description: 'Get file metadata and download URL.', + inputSchema: jsonSchema<{ fileId: string }>({ + type: 'object', + properties: { + fileId: { + type: 'string', + description: 'The file ID.', + }, + }, + required: ['fileId'], + additionalProperties: false, + }), + async execute(input: { fileId: string }): Promise { + return apiRequest( + 'GET', + `/files/${encodeURIComponent(input.fileId)}`, + undefined + ); + }, +}); + +/** + * Delete a file. + */ +export const deleteFile = tool({ + description: 'Delete an uploaded file.', + inputSchema: jsonSchema<{ fileId: string }>({ + type: 'object', + properties: { + fileId: { + type: 'string', + description: 'The file ID to delete.', + }, + }, + required: ['fileId'], + additionalProperties: false, + }), + async execute(input: { fileId: string }): Promise<{ success: boolean }> { + return apiRequest<{ success: boolean }>( + 'DELETE', + `/files/${encodeURIComponent(input.fileId)}`, + undefined + ); + }, +}); + +// ============================================================================ +// Models +// ============================================================================ + +export interface Model { + id: string; + name: string; + provider: string; + contextWindow: number; + inputPricing: number; + outputPricing: number; + capabilities: string[]; +} + +export interface ListModelsResult { + models: Model[]; +} + +/** + * List available models. + */ +export const listModels = tool({ + description: 'List all available AI models.', + inputSchema: jsonSchema<{ provider?: string }>({ + type: 'object', + properties: { + provider: { + type: 'string', + description: 'Filter by provider (openai, anthropic, google, etc.).', + }, + }, + additionalProperties: false, + }), + async execute(input: { provider?: string }): Promise { + const query = input.provider ? `?provider=${encodeURIComponent(input.provider)}` : ''; + return apiRequest('GET', `/models${query}`, undefined); + }, +}); + +// ============================================================================ +// Execution Logs +// ============================================================================ + +export interface ExecutionLog { + id: string; + topologyType: string; + status: 'success' | 'error' | 'timeout'; + inputTokens: number; + outputTokens: number; + duration: number; + error?: string; + createdAt: string; +} + +export interface GetExecutionLogsInput { + sessionId?: string; + limit?: number; + offset?: number; +} + +export interface GetExecutionLogsResult { + logs: ExecutionLog[]; + total: number; +} + +/** + * Get execution logs. + */ +export const getExecutionLogs = tool({ + description: 'Get execution logs for topology runs.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + sessionId: { + type: 'string', + description: 'Filter logs by session ID.', + }, + limit: { + type: 'number', + description: 'Maximum number of logs to return.', + }, + offset: { + type: 'number', + description: 'Number of logs to skip.', + }, + }, + additionalProperties: false, + }), + async execute(input: GetExecutionLogsInput): Promise { + const params = new URLSearchParams(); + if (input.sessionId) params.set('sessionId', input.sessionId); + 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', `/logs${query}`, undefined); + }, +}); + +// ============================================================================ +// Agent Metrics +// ============================================================================ + +export interface AgentMetrics { + totalRequests: number; + successRate: number; + averageLatency: number; + tokenUsage: { + input: number; + output: number; + }; + topologyBreakdown: Record; + periodStart: string; + periodEnd: string; +} + +/** + * Get agent metrics. + */ +export const getAgentMetrics = tool({ + description: 'Get agent performance metrics.', + inputSchema: jsonSchema<{ period?: 'hour' | 'day' | 'week' | 'month' }>({ + type: 'object', + properties: { + period: { + type: 'string', + enum: ['hour', 'day', 'week', 'month'], + description: 'Time period for metrics. Default: day', + }, + }, + additionalProperties: false, + }), + async execute(input: { period?: 'hour' | 'day' | 'week' | 'month' }): Promise { + const query = input.period ? `?period=${input.period}` : ''; + return apiRequest('GET', `/metrics${query}`, undefined); + }, +}); + +// ============================================================================ +// TPMJS Tools +// ============================================================================ + +export interface ToolInfo { + id: string; + name: string; + description: string; + package: string; + parameters: Array<{ + name: string; + type: string; + description: string; + required: boolean; + }>; +} + +export interface ListToolsResult { + tools: ToolInfo[]; +} + +/** + * List TPMJS tools. + */ +export const listTools = tool({ + description: 'List all available TPMJS tools.', + inputSchema: jsonSchema<{ category?: string }>({ + type: 'object', + properties: { + category: { + type: 'string', + description: 'Filter by category.', + }, + }, + additionalProperties: false, + }), + async execute(input: { category?: string }): Promise { + const query = input.category ? `?category=${encodeURIComponent(input.category)}` : ''; + return apiRequest('GET', `/tools${query}`, undefined); + }, +}); + +/** + * Get tool details. + */ +export const describeTool = tool({ + description: 'Get detailed description of a specific tool.', + inputSchema: jsonSchema<{ toolId: string }>({ + type: 'object', + properties: { + toolId: { + type: 'string', + description: 'The tool ID.', + }, + }, + required: ['toolId'], + additionalProperties: false, + }), + async execute(input: { toolId: string }): Promise { + return apiRequest( + 'GET', + `/tools/${encodeURIComponent(input.toolId)}`, + undefined + ); + }, +}); + +export interface ExecuteToolInput { + toolId: string; + parameters: Record; +} + +export interface ExecuteToolResult { + success: boolean; + result: unknown; + duration: number; +} + +/** + * Execute a TPMJS tool. + */ +export const executeTool = tool({ + description: 'Execute a TPMJS tool directly.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + toolId: { + type: 'string', + description: 'The tool ID to execute.', + }, + parameters: { + type: 'object', + description: 'Tool parameters.', + additionalProperties: true, + }, + }, + required: ['toolId', 'parameters'], + additionalProperties: false, + }), + async execute(input: ExecuteToolInput): Promise { + return apiRequest( + 'POST', + `/tools/${encodeURIComponent(input.toolId)}/execute`, + { parameters: input.parameters } + ); + }, +}); + +// ============================================================================ +// Prompt Generation +// ============================================================================ + +export interface GeneratePromptInput { + task: string; + context?: string; + style?: 'concise' | 'detailed' | 'creative'; +} + +export interface GeneratePromptResult { + prompt: string; + suggestions?: string[]; +} + +/** + * Generate a prompt. + */ +export const generatePrompt = tool({ + description: 'Generate a prompt using AI assistance.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + task: { + type: 'string', + description: 'Description of what the prompt should accomplish.', + }, + context: { + type: 'string', + description: 'Additional context for prompt generation.', + }, + style: { + type: 'string', + enum: ['concise', 'detailed', 'creative'], + description: 'Style of the generated prompt.', + }, + }, + required: ['task'], + additionalProperties: false, + }), + async execute(input: GeneratePromptInput): Promise { + return apiRequest('POST', '/prompts/generate', input); + }, +}); + +export interface ImprovePromptInput { + prompt: string; + goal?: string; +} + +/** + * Improve an existing prompt. + */ +export const improvePrompt = tool({ + description: 'Improve an existing prompt using AI.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + prompt: { + type: 'string', + description: 'The prompt to improve.', + }, + goal: { + type: 'string', + description: 'What improvement to focus on.', + }, + }, + required: ['prompt'], + additionalProperties: false, + }), + async execute(input: ImprovePromptInput): Promise { + return apiRequest('POST', '/prompts/improve', input); + }, +}); + +// ============================================================================ +// Export/Import +// ============================================================================ + +export interface ExportDataInput { + include?: ('sessions' | 'prompts' | 'settings' | 'files')[]; +} + +export interface ExportDataResult { + data: string; // Base64 encoded + format: string; + exportedAt: string; +} + +/** + * Export user data. + */ +export const exportData = tool({ + description: 'Export user data including sessions, prompts, and settings.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + include: { + type: 'array', + items: { + type: 'string', + enum: ['sessions', 'prompts', 'settings', 'files'], + }, + description: 'What data to include. Default: all', + }, + }, + additionalProperties: false, + }), + async execute(input: ExportDataInput): Promise { + return apiRequest('POST', '/export', input); + }, +}); + +export interface ImportDataInput { + data: string; // Base64 encoded + overwrite?: boolean; +} + +export interface ImportDataResult { + success: boolean; + imported: { + sessions?: number; + prompts?: number; + settings?: boolean; + files?: number; + }; +} + +/** + * Import data. + */ +export const importData = tool({ + description: 'Import previously exported data.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + data: { + type: 'string', + description: 'Base64 encoded export data.', + }, + overwrite: { + type: 'boolean', + description: 'Whether to overwrite existing data. Default: false', + }, + }, + required: ['data'], + additionalProperties: false, + }), + async execute(input: ImportDataInput): Promise { + return apiRequest('POST', '/import', input); + }, +}); + +// ============================================================================ +// Public Endpoints +// ============================================================================ + +export interface HealthResult { + status: string; + version: string; + uptime: number; +} + +/** + * Health check. + */ +export const healthCheck = tool({ + description: 'Check HLLM API health status.', + inputSchema: jsonSchema>({ + type: 'object', + properties: {}, + additionalProperties: false, + }), + async execute(): Promise { + const { baseUrl } = getApiConfig(); + const response = await fetch(`${baseUrl}/health`); + return response.json() as Promise; + }, +}); + +export interface PublicStats { + totalUsers: number; + totalExecutions: number; + totalTokens: number; + uptimePercent: number; +} + +/** + * Get public stats. + */ +export const getStats = tool({ + description: 'Get public HLLM statistics.', + inputSchema: jsonSchema>({ + type: 'object', + properties: {}, + additionalProperties: false, + }), + async execute(): Promise { + const { baseUrl } = getApiConfig(); + const response = await fetch(`${baseUrl}/stats`); + return response.json() as Promise; + }, +}); + +// ============================================================================ +// API Keys +// ============================================================================ + +export interface ApiKey { + id: string; + name: string; + keyHint: string; + createdAt: string; + lastUsedAt?: string; +} + +export interface ListApiKeysResult { + apiKeys: ApiKey[]; +} + +/** + * List API keys. + */ +export const listApiKeys = tool({ + description: 'List all API keys for the authenticated user.', + inputSchema: jsonSchema>({ + type: 'object', + properties: {}, + additionalProperties: false, + }), + async execute(): Promise { + return apiRequest('GET', '/api-keys', undefined); + }, +}); + +export interface CreateApiKeyInput { + name: string; +} + +export interface CreateApiKeyResult { + id: string; + name: string; + key: string; // Full key, only shown once + createdAt: string; +} + +/** + * Create API key. + */ +export const createApiKey = tool({ + description: 'Create a new API key.', + inputSchema: jsonSchema({ + type: 'object', + properties: { + name: { + type: 'string', + description: 'Name for the API key.', + }, + }, + required: ['name'], + additionalProperties: false, + }), + async execute(input: CreateApiKeyInput): Promise { + return apiRequest('POST', '/api-keys', input); + }, +}); + +/** + * Delete API key. + */ +export const deleteApiKey = tool({ + description: 'Delete an API key.', + inputSchema: jsonSchema<{ keyId: string }>({ + type: 'object', + properties: { + keyId: { + type: 'string', + description: 'The API key ID to delete.', + }, + }, + required: ['keyId'], + additionalProperties: false, + }), + async execute(input: { keyId: string }): Promise<{ success: boolean }> { + return apiRequest<{ success: boolean }>( + 'DELETE', + `/api-keys/${encodeURIComponent(input.keyId)}`, + undefined + ); + }, +}); + +// ============================================================================ +// Default Export +// ============================================================================ + +export default { + // Topology + executeTopology, + // Sessions + listSessions, + createSession, + getSession, + updateSession, + deleteSession, + // Messages + addMessage, + clearMessages, + // Prompts + listPrompts, + createPrompt, + getPrompt, + updatePrompt, + deletePrompt, + incrementPromptUsage, + // User + getUserProfile, + updateUserProfile, + getUserStats, + // Env Vars + listEnvVars, + setEnvVar, + deleteEnvVar, + // Files + uploadFile, + getFile, + deleteFile, + // Models + listModels, + // Logs + getExecutionLogs, + // Metrics + getAgentMetrics, + // Tools + listTools, + describeTool, + executeTool, + // Prompt Generation + generatePrompt, + improvePrompt, + // Export/Import + exportData, + importData, + // Public + healthCheck, + getStats, + // API Keys + listApiKeys, + createApiKey, + deleteApiKey, +}; diff --git a/packages/tools/official/hllm/tsconfig.json b/packages/tools/official/hllm/tsconfig.json new file mode 100644 index 0000000..6521d56 --- /dev/null +++ b/packages/tools/official/hllm/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "@tpmjs/tsconfig/base.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "incremental": false, + "composite": false + }, + "include": ["src"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/tools/official/hllm/tsup.config.ts b/packages/tools/official/hllm/tsup.config.ts new file mode 100644 index 0000000..a242871 --- /dev/null +++ b/packages/tools/official/hllm/tsup.config.ts @@ -0,0 +1,10 @@ +import { defineConfig } from 'tsup'; + +export default defineConfig({ + entry: ['src/index.ts'], + format: ['esm'], + dts: true, + clean: true, + treeshake: true, + splitting: false, +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5a80620..df1993e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1799,6 +1799,22 @@ importers: specifier: ^5.9.3 version: 5.9.3 + packages/tools/official/hllm: + dependencies: + ai: + specifier: 6.0.23 + version: 6.0.23(zod@4.3.5) + devDependencies: + '@tpmjs/tsconfig': + specifier: workspace:* + version: link:../../../config/tsconfig + tsup: + specifier: ^8.5.1 + version: 8.5.1(jiti@2.6.1)(postcss@8.5.6)(tsx@4.21.0)(typescript@5.9.3)(yaml@2.8.2) + typescript: + specifier: ^5.9.3 + version: 5.9.3 + packages/tools/official/html-sanitize: dependencies: ai: