@limo-labs/deity-adapter-copilot 0.1.0-alpha.1 → 0.1.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +8 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +8 -3
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -102,6 +102,12 @@ var CopilotSDKAdapter = class {
|
|
|
102
102
|
// Add hooks to track tool calls for Deity compatibility
|
|
103
103
|
hooks: {
|
|
104
104
|
onPostToolUse: (input) => {
|
|
105
|
+
let resultString;
|
|
106
|
+
if (input.toolResult && typeof input.toolResult === "object" && "textResultForLlm" in input.toolResult) {
|
|
107
|
+
resultString = input.toolResult.textResultForLlm;
|
|
108
|
+
} else {
|
|
109
|
+
resultString = typeof input.toolResult === "string" ? input.toolResult : JSON.stringify(input.toolResult);
|
|
110
|
+
}
|
|
105
111
|
const toolCall = {
|
|
106
112
|
id: `call_${Date.now()}_${Math.random().toString(36).slice(2)}`,
|
|
107
113
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
@@ -110,9 +116,8 @@ var CopilotSDKAdapter = class {
|
|
|
110
116
|
arguments: input.toolArgs,
|
|
111
117
|
_alreadyExecuted: true,
|
|
112
118
|
// Mark as already executed by SDK
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
// Store result for reference
|
|
119
|
+
_executionResult: resultString
|
|
120
|
+
// Store raw result string (already JSON stringified by tool handler)
|
|
116
121
|
};
|
|
117
122
|
this.toolCallHistory.push(toolCall);
|
|
118
123
|
this.log("Tool call tracked:", {
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapter.ts"],"names":["CopilotClient","defineTool"],"mappings":"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","file":"index.cjs","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\n/**\n * Copilot SDK Adapter for Deity Framework\n *\n * Uses Copilot SDK's native tool support for reliable tool calling.\n *\n * Architecture:\n * - Deity passes tools to generate()\n * - Adapter converts Deity tools to Copilot SDK tools\n * - Copilot SDK handles tool calling loop automatically\n * - Adapter returns final response with tool call information\n *\n * Session Management:\n * - Uses disposable session pattern (create → use → destroy)\n * - Each generate() call creates a fresh session\n * - Sessions are destroyed in finally block to ensure cleanup\n * - This pattern is optimized for Deity's stateless design\n */\n\nimport { CopilotClient, defineTool, type Tool as CopilotTool } from '@github/copilot-sdk';\nimport type {\n LLMAdapter,\n LLMResponse,\n Message,\n Tool,\n GenerationConfig,\n ExecutionContext,\n ToolCall,\n} from '@limo-labs/deity';\n\nexport interface CopilotSDKAdapterConfig {\n /**\n * Model to use (default: 'gpt-4o')\n * Options: 'gpt-4o', 'claude-opus-4.6', 'o1', 'o1-mini', etc.\n */\n model?: string;\n\n /**\n * Custom Copilot CLI URL (optional)\n * If not provided, SDK will auto-manage the CLI\n */\n cliUrl?: string;\n\n /**\n * Callback for streaming response chunks (optional)\n */\n onStreamChunk?: (chunk: string) => void;\n\n /**\n * Callback for reasoning/thinking chunks (optional)\n */\n onReasoningChunk?: (chunk: string) => void;\n\n /**\n * Enable debug logging (default: false)\n */\n debug?: boolean;\n}\n\nexport class CopilotSDKAdapter implements LLMAdapter {\n private client: CopilotClient;\n private model: string;\n private sessionCounter = 0;\n private isInitialized = false;\n private onStreamChunk?: (chunk: string) => void;\n private currentContext?: ExecutionContext;\n private debugEnabled: boolean;\n\n // Track tool calls for Deity compatibility\n private toolCallHistory: ToolCall[] = [];\n\n constructor(config: CopilotSDKAdapterConfig = {}) {\n this.model = config.model || 'gpt-4o';\n this.onStreamChunk = config.onStreamChunk;\n this.debugEnabled = config.debug || false;\n\n // CRITICAL FIX: Disable built-in GitHub MCP server\n // GitHub MCP server auto-activates in git repos and overrides SDK tools\n this.client = new CopilotClient({\n cliUrl: config.cliUrl,\n cliArgs: ['--disable-builtin-mcps'],\n });\n\n this.log('CopilotSDKAdapter created:', {\n model: this.model,\n mode: config.cliUrl ? 'external-server' : 'auto-managed',\n streaming: !!this.onStreamChunk,\n nativeToolSupport: true,\n });\n }\n\n private log(...args: any[]): void {\n if (this.debugEnabled) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n console.log('[CopilotSDKAdapter]', ...args);\n }\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('Client already initialized, skipping');\n return;\n }\n\n this.log('Starting Copilot client...');\n await this.client.start();\n this.isInitialized = true;\n this.log('Copilot client started successfully');\n }\n\n /**\n * Generate LLM response using Copilot SDK's native tool support\n *\n * Copilot SDK handles:\n * - Tool definition injection\n * - Tool call generation\n * - Tool execution via handlers\n * - Multi-turn tool calling loop\n *\n * Architecture notes:\n * - Creates a disposable session for each call\n * - Session is destroyed after use (in finally block)\n * - Tool calls are tracked via onPostToolUse hook\n * - Returns toolCalls array marked as already executed\n */\n async generate(\n messages: Message[],\n tools?: Tool[],\n _config?: GenerationConfig,\n ctx?: ExecutionContext\n ): Promise<LLMResponse> {\n if (!this.isInitialized) {\n await this.initialize();\n }\n\n // Store context for tool handlers\n this.currentContext = ctx;\n\n // Reset tool call history for this generation\n this.toolCallHistory = [];\n\n const startTime = Date.now();\n\n // Disposable session pattern: create new session for each call\n const sessionId = `deity-session-${Date.now()}-${this.sessionCounter++}`;\n this.log('Creating disposable session:', sessionId);\n\n // Convert Deity tools to Copilot SDK tools\n const copilotTools = tools ? this.convertTools(tools) : undefined;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n const toolNames = copilotTools?.map((t) => (t as any).name) || [];\n\n this.log('Session tools:', {\n count: toolNames.length,\n names: toolNames,\n });\n\n // Create session with hooks to track tool calls\n const sessionConfig: any = {\n sessionId,\n model: this.model,\n tools: copilotTools,\n // Exclude ALL environment tools to ensure only registered tools are used\n excludedTools: [\n 'bash',\n 'write_bash',\n 'read_bash',\n 'stop_bash',\n 'list_bash',\n 'shell',\n 'view',\n 'create',\n 'edit',\n 'web_fetch',\n 'report_intent',\n 'read_file',\n 'write_file',\n 'sql',\n 'read_agent',\n 'list_agents',\n 'grep',\n 'glob',\n 'task',\n ],\n // Add hooks to track tool calls for Deity compatibility\n hooks: {\n onPostToolUse: (input: any) => {\n // Record tool call in history with execution metadata\n const toolCall: any = {\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2)}`,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n arguments: input.toolArgs,\n _alreadyExecuted: true, // Mark as already executed by SDK\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n _executionResult: JSON.stringify(input.toolResult), // Store result for reference\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.toolCallHistory.push(toolCall);\n\n this.log('Tool call tracked:', {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n totalCalls: this.toolCallHistory.length,\n });\n\n // Don't modify anything, just track\n return undefined;\n },\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const session = await this.client.createSession(sessionConfig);\n this.log('Session created:', sessionId);\n\n try {\n // Convert ALL messages to prompt (including system messages)\n const prompt = this.messagesToPrompt(messages);\n\n this.log('Sending prompt:', {\n promptLength: prompt.length,\n sessionId: session.sessionId,\n toolsCount: tools?.length || 0,\n });\n\n let responseContent = '';\n\n // Use sendAndWait() to get the response\n try {\n const result = await session.sendAndWait({ prompt }, 12000000); // 12000s timeout\n\n if (result) {\n responseContent = result.data.content || '';\n this.log('Response received:', {\n length: responseContent.length,\n });\n }\n } catch (error: any) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n console.error('[CopilotSDKAdapter] sendAndWait error:', error.message);\n throw error;\n }\n\n const elapsed = Date.now() - startTime;\n this.log(`API response received in ${elapsed}ms`);\n\n if (this.toolCallHistory.length > 0) {\n this.log(`Session executed ${this.toolCallHistory.length} tool calls`);\n }\n\n // Return result with toolCalls marked as already executed\n // Deity llm-loop will check _alreadyExecuted flag and skip re-execution\n const response: LLMResponse = {\n content: responseContent,\n toolCalls: this.toolCallHistory.length > 0 ? this.toolCallHistory : undefined,\n };\n\n return response;\n } catch (error) {\n // Clean up session on error\n await session.destroy();\n throw error;\n } finally {\n // Always destroy disposable session\n await session.destroy();\n this.log('Session destroyed:', sessionId);\n }\n }\n\n /**\n * Convert Deity Tool to Copilot SDK Tool using defineTool\n *\n * Uses SDK's defineTool() function which properly registers tools.\n * Zod schemas are passed directly - Zod v4 has native toJSONSchema() method.\n */\n private convertTools(deityTools: Tool[]): CopilotTool[] {\n this.log('Converting Deity tools to Copilot SDK format:', {\n count: deityTools.length,\n names: deityTools.map((t) => t.name),\n });\n\n const converted = deityTools.map((tool) => {\n // Pass Zod schema directly - Zod v4 has native toJSONSchema() method\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const parameters = tool.inputSchema as any;\n\n // Use SDK's defineTool function (critical for proper registration)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return\n return defineTool(tool.name, {\n description: tool.description || `Tool: ${tool.name}`,\n parameters,\n handler: async (args: unknown) => {\n this.log('Executing tool via SDK handler:', {\n name: tool.name,\n });\n\n try {\n if (!this.currentContext) {\n throw new Error('Execution context not available for tool handler');\n }\n\n // Execute Deity tool\n const result = await tool.execute(args, this.currentContext);\n\n this.log('Tool execution successful:', tool.name);\n\n // Return result in format expected by Copilot SDK\n return typeof result === 'string' ? result : JSON.stringify(result);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error('[CopilotSDKAdapter] Tool execution failed:', {\n tool: tool.name,\n error: errorMsg,\n });\n\n // Return error result\n return JSON.stringify({\n success: false,\n error: errorMsg,\n });\n }\n },\n });\n });\n\n this.log('Tool conversion complete:', {\n convertedCount: converted.length,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n toolNames: converted.map((t: any) => t.name || 'unknown'),\n });\n\n return converted;\n }\n\n /**\n * Convert Deity messages to Copilot prompt format\n *\n * Note: Copilot SDK uses a simple string prompt format.\n * All message types are concatenated into a single prompt.\n */\n private messagesToPrompt(messages: Message[]): string {\n let prompt = '';\n\n for (const msg of messages) {\n switch (msg.role) {\n case 'system':\n prompt += msg.content + '\\n\\n';\n break;\n case 'user':\n prompt += `User: ${msg.content}\\n\\n`;\n break;\n case 'assistant':\n prompt += `Assistant: ${msg.content}\\n\\n`;\n break;\n case 'tool':\n // Skip tool messages - SDK handles them internally\n break;\n }\n }\n\n return prompt;\n }\n\n async cleanup(): Promise<void> {\n if (!this.isInitialized) {\n return;\n }\n\n // No sessions to clean up (disposable session pattern)\n this.log('Stopping Copilot client...');\n await this.client.stop();\n this.isInitialized = false;\n this.log('Copilot client stopped');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapter.ts"],"names":["CopilotClient","defineTool"],"mappings":"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","file":"index.cjs","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\n/**\n * Copilot SDK Adapter for Deity Framework\n *\n * Uses Copilot SDK's native tool support for reliable tool calling.\n *\n * Architecture:\n * - Deity passes tools to generate()\n * - Adapter converts Deity tools to Copilot SDK tools\n * - Copilot SDK handles tool calling loop automatically\n * - Adapter returns final response with tool call information\n *\n * Session Management:\n * - Uses disposable session pattern (create → use → destroy)\n * - Each generate() call creates a fresh session\n * - Sessions are destroyed in finally block to ensure cleanup\n * - This pattern is optimized for Deity's stateless design\n */\n\nimport { CopilotClient, defineTool, type Tool as CopilotTool } from '@github/copilot-sdk';\nimport type {\n LLMAdapter,\n LLMResponse,\n Message,\n Tool,\n GenerationConfig,\n ExecutionContext,\n ToolCall,\n} from '@limo-labs/deity';\n\nexport interface CopilotSDKAdapterConfig {\n /**\n * Model to use (default: 'gpt-4o')\n * Options: 'gpt-4o', 'claude-opus-4.6', 'o1', 'o1-mini', etc.\n */\n model?: string;\n\n /**\n * Custom Copilot CLI URL (optional)\n * If not provided, SDK will auto-manage the CLI\n */\n cliUrl?: string;\n\n /**\n * Callback for streaming response chunks (optional)\n */\n onStreamChunk?: (chunk: string) => void;\n\n /**\n * Callback for reasoning/thinking chunks (optional)\n */\n onReasoningChunk?: (chunk: string) => void;\n\n /**\n * Enable debug logging (default: false)\n */\n debug?: boolean;\n}\n\nexport class CopilotSDKAdapter implements LLMAdapter {\n private client: CopilotClient;\n private model: string;\n private sessionCounter = 0;\n private isInitialized = false;\n private onStreamChunk?: (chunk: string) => void;\n private currentContext?: ExecutionContext;\n private debugEnabled: boolean;\n\n // Track tool calls for Deity compatibility\n private toolCallHistory: ToolCall[] = [];\n\n constructor(config: CopilotSDKAdapterConfig = {}) {\n this.model = config.model || 'gpt-4o';\n this.onStreamChunk = config.onStreamChunk;\n this.debugEnabled = config.debug || false;\n\n // CRITICAL FIX: Disable built-in GitHub MCP server\n // GitHub MCP server auto-activates in git repos and overrides SDK tools\n this.client = new CopilotClient({\n cliUrl: config.cliUrl,\n cliArgs: ['--disable-builtin-mcps'],\n });\n\n this.log('CopilotSDKAdapter created:', {\n model: this.model,\n mode: config.cliUrl ? 'external-server' : 'auto-managed',\n streaming: !!this.onStreamChunk,\n nativeToolSupport: true,\n });\n }\n\n private log(...args: any[]): void {\n if (this.debugEnabled) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n console.log('[CopilotSDKAdapter]', ...args);\n }\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('Client already initialized, skipping');\n return;\n }\n\n this.log('Starting Copilot client...');\n await this.client.start();\n this.isInitialized = true;\n this.log('Copilot client started successfully');\n }\n\n /**\n * Generate LLM response using Copilot SDK's native tool support\n *\n * Copilot SDK handles:\n * - Tool definition injection\n * - Tool call generation\n * - Tool execution via handlers\n * - Multi-turn tool calling loop\n *\n * Architecture notes:\n * - Creates a disposable session for each call\n * - Session is destroyed after use (in finally block)\n * - Tool calls are tracked via onPostToolUse hook\n * - Returns toolCalls array marked as already executed\n */\n async generate(\n messages: Message[],\n tools?: Tool[],\n _config?: GenerationConfig,\n ctx?: ExecutionContext\n ): Promise<LLMResponse> {\n if (!this.isInitialized) {\n await this.initialize();\n }\n\n // Store context for tool handlers\n this.currentContext = ctx;\n\n // Reset tool call history for this generation\n this.toolCallHistory = [];\n\n const startTime = Date.now();\n\n // Disposable session pattern: create new session for each call\n const sessionId = `deity-session-${Date.now()}-${this.sessionCounter++}`;\n this.log('Creating disposable session:', sessionId);\n\n // Convert Deity tools to Copilot SDK tools\n const copilotTools = tools ? this.convertTools(tools) : undefined;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n const toolNames = copilotTools?.map((t) => (t as any).name) || [];\n\n this.log('Session tools:', {\n count: toolNames.length,\n names: toolNames,\n });\n\n // Create session with hooks to track tool calls\n const sessionConfig: any = {\n sessionId,\n model: this.model,\n tools: copilotTools,\n // Exclude ALL environment tools to ensure only registered tools are used\n excludedTools: [\n 'bash',\n 'write_bash',\n 'read_bash',\n 'stop_bash',\n 'list_bash',\n 'shell',\n 'view',\n 'create',\n 'edit',\n 'web_fetch',\n 'report_intent',\n 'read_file',\n 'write_file',\n 'sql',\n 'read_agent',\n 'list_agents',\n 'grep',\n 'glob',\n 'task',\n ],\n // Add hooks to track tool calls for Deity compatibility\n hooks: {\n onPostToolUse: (input: any) => {\n // Extract actual result from Copilot SDK's toolResult format\n // SDK may return { textResultForLlm: \"...\" } or raw string\n let resultString: string;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (input.toolResult && typeof input.toolResult === 'object' && 'textResultForLlm' in input.toolResult) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n resultString = input.toolResult.textResultForLlm;\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument\n resultString = typeof input.toolResult === 'string' ? input.toolResult : JSON.stringify(input.toolResult);\n }\n\n // Record tool call in history with execution metadata\n const toolCall: any = {\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2)}`,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n arguments: input.toolArgs,\n _alreadyExecuted: true, // Mark as already executed by SDK\n _executionResult: resultString, // Store raw result string (already JSON stringified by tool handler)\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.toolCallHistory.push(toolCall);\n\n this.log('Tool call tracked:', {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n totalCalls: this.toolCallHistory.length,\n });\n\n // Don't modify anything, just track\n return undefined;\n },\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const session = await this.client.createSession(sessionConfig);\n this.log('Session created:', sessionId);\n\n try {\n // Convert ALL messages to prompt (including system messages)\n const prompt = this.messagesToPrompt(messages);\n\n this.log('Sending prompt:', {\n promptLength: prompt.length,\n sessionId: session.sessionId,\n toolsCount: tools?.length || 0,\n });\n\n let responseContent = '';\n\n // Use sendAndWait() to get the response\n try {\n const result = await session.sendAndWait({ prompt }, 12000000); // 12000s timeout\n\n if (result) {\n responseContent = result.data.content || '';\n this.log('Response received:', {\n length: responseContent.length,\n });\n }\n } catch (error: any) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n console.error('[CopilotSDKAdapter] sendAndWait error:', error.message);\n throw error;\n }\n\n const elapsed = Date.now() - startTime;\n this.log(`API response received in ${elapsed}ms`);\n\n if (this.toolCallHistory.length > 0) {\n this.log(`Session executed ${this.toolCallHistory.length} tool calls`);\n }\n\n // Return result with toolCalls marked as already executed\n // Deity llm-loop will check _alreadyExecuted flag and skip re-execution\n const response: LLMResponse = {\n content: responseContent,\n toolCalls: this.toolCallHistory.length > 0 ? this.toolCallHistory : undefined,\n };\n\n return response;\n } catch (error) {\n // Clean up session on error\n await session.destroy();\n throw error;\n } finally {\n // Always destroy disposable session\n await session.destroy();\n this.log('Session destroyed:', sessionId);\n }\n }\n\n /**\n * Convert Deity Tool to Copilot SDK Tool using defineTool\n *\n * Uses SDK's defineTool() function which properly registers tools.\n * Zod schemas are passed directly - Zod v4 has native toJSONSchema() method.\n */\n private convertTools(deityTools: Tool[]): CopilotTool[] {\n this.log('Converting Deity tools to Copilot SDK format:', {\n count: deityTools.length,\n names: deityTools.map((t) => t.name),\n });\n\n const converted = deityTools.map((tool) => {\n // Pass Zod schema directly - Zod v4 has native toJSONSchema() method\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const parameters = tool.inputSchema as any;\n\n // Use SDK's defineTool function (critical for proper registration)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return\n return defineTool(tool.name, {\n description: tool.description || `Tool: ${tool.name}`,\n parameters,\n handler: async (args: unknown) => {\n this.log('Executing tool via SDK handler:', {\n name: tool.name,\n });\n\n try {\n if (!this.currentContext) {\n throw new Error('Execution context not available for tool handler');\n }\n\n // Execute Deity tool\n const result = await tool.execute(args, this.currentContext);\n\n this.log('Tool execution successful:', tool.name);\n\n // Return result in format expected by Copilot SDK\n return typeof result === 'string' ? result : JSON.stringify(result);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error('[CopilotSDKAdapter] Tool execution failed:', {\n tool: tool.name,\n error: errorMsg,\n });\n\n // Return error result\n return JSON.stringify({\n success: false,\n error: errorMsg,\n });\n }\n },\n });\n });\n\n this.log('Tool conversion complete:', {\n convertedCount: converted.length,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n toolNames: converted.map((t: any) => t.name || 'unknown'),\n });\n\n return converted;\n }\n\n /**\n * Convert Deity messages to Copilot prompt format\n *\n * Note: Copilot SDK uses a simple string prompt format.\n * All message types are concatenated into a single prompt.\n */\n private messagesToPrompt(messages: Message[]): string {\n let prompt = '';\n\n for (const msg of messages) {\n switch (msg.role) {\n case 'system':\n prompt += msg.content + '\\n\\n';\n break;\n case 'user':\n prompt += `User: ${msg.content}\\n\\n`;\n break;\n case 'assistant':\n prompt += `Assistant: ${msg.content}\\n\\n`;\n break;\n case 'tool':\n // Skip tool messages - SDK handles them internally\n break;\n }\n }\n\n return prompt;\n }\n\n async cleanup(): Promise<void> {\n if (!this.isInitialized) {\n return;\n }\n\n // No sessions to clean up (disposable session pattern)\n this.log('Stopping Copilot client...');\n await this.client.stop();\n this.isInitialized = false;\n this.log('Copilot client stopped');\n }\n}\n"]}
|
package/dist/index.js
CHANGED
|
@@ -100,6 +100,12 @@ var CopilotSDKAdapter = class {
|
|
|
100
100
|
// Add hooks to track tool calls for Deity compatibility
|
|
101
101
|
hooks: {
|
|
102
102
|
onPostToolUse: (input) => {
|
|
103
|
+
let resultString;
|
|
104
|
+
if (input.toolResult && typeof input.toolResult === "object" && "textResultForLlm" in input.toolResult) {
|
|
105
|
+
resultString = input.toolResult.textResultForLlm;
|
|
106
|
+
} else {
|
|
107
|
+
resultString = typeof input.toolResult === "string" ? input.toolResult : JSON.stringify(input.toolResult);
|
|
108
|
+
}
|
|
103
109
|
const toolCall = {
|
|
104
110
|
id: `call_${Date.now()}_${Math.random().toString(36).slice(2)}`,
|
|
105
111
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
|
|
@@ -108,9 +114,8 @@ var CopilotSDKAdapter = class {
|
|
|
108
114
|
arguments: input.toolArgs,
|
|
109
115
|
_alreadyExecuted: true,
|
|
110
116
|
// Mark as already executed by SDK
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
// Store result for reference
|
|
117
|
+
_executionResult: resultString
|
|
118
|
+
// Store raw result string (already JSON stringified by tool handler)
|
|
114
119
|
};
|
|
115
120
|
this.toolCallHistory.push(toolCall);
|
|
116
121
|
this.log("Tool call tracked:", {
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/adapter.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\n/**\n * Copilot SDK Adapter for Deity Framework\n *\n * Uses Copilot SDK's native tool support for reliable tool calling.\n *\n * Architecture:\n * - Deity passes tools to generate()\n * - Adapter converts Deity tools to Copilot SDK tools\n * - Copilot SDK handles tool calling loop automatically\n * - Adapter returns final response with tool call information\n *\n * Session Management:\n * - Uses disposable session pattern (create → use → destroy)\n * - Each generate() call creates a fresh session\n * - Sessions are destroyed in finally block to ensure cleanup\n * - This pattern is optimized for Deity's stateless design\n */\n\nimport { CopilotClient, defineTool, type Tool as CopilotTool } from '@github/copilot-sdk';\nimport type {\n LLMAdapter,\n LLMResponse,\n Message,\n Tool,\n GenerationConfig,\n ExecutionContext,\n ToolCall,\n} from '@limo-labs/deity';\n\nexport interface CopilotSDKAdapterConfig {\n /**\n * Model to use (default: 'gpt-4o')\n * Options: 'gpt-4o', 'claude-opus-4.6', 'o1', 'o1-mini', etc.\n */\n model?: string;\n\n /**\n * Custom Copilot CLI URL (optional)\n * If not provided, SDK will auto-manage the CLI\n */\n cliUrl?: string;\n\n /**\n * Callback for streaming response chunks (optional)\n */\n onStreamChunk?: (chunk: string) => void;\n\n /**\n * Callback for reasoning/thinking chunks (optional)\n */\n onReasoningChunk?: (chunk: string) => void;\n\n /**\n * Enable debug logging (default: false)\n */\n debug?: boolean;\n}\n\nexport class CopilotSDKAdapter implements LLMAdapter {\n private client: CopilotClient;\n private model: string;\n private sessionCounter = 0;\n private isInitialized = false;\n private onStreamChunk?: (chunk: string) => void;\n private currentContext?: ExecutionContext;\n private debugEnabled: boolean;\n\n // Track tool calls for Deity compatibility\n private toolCallHistory: ToolCall[] = [];\n\n constructor(config: CopilotSDKAdapterConfig = {}) {\n this.model = config.model || 'gpt-4o';\n this.onStreamChunk = config.onStreamChunk;\n this.debugEnabled = config.debug || false;\n\n // CRITICAL FIX: Disable built-in GitHub MCP server\n // GitHub MCP server auto-activates in git repos and overrides SDK tools\n this.client = new CopilotClient({\n cliUrl: config.cliUrl,\n cliArgs: ['--disable-builtin-mcps'],\n });\n\n this.log('CopilotSDKAdapter created:', {\n model: this.model,\n mode: config.cliUrl ? 'external-server' : 'auto-managed',\n streaming: !!this.onStreamChunk,\n nativeToolSupport: true,\n });\n }\n\n private log(...args: any[]): void {\n if (this.debugEnabled) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n console.log('[CopilotSDKAdapter]', ...args);\n }\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('Client already initialized, skipping');\n return;\n }\n\n this.log('Starting Copilot client...');\n await this.client.start();\n this.isInitialized = true;\n this.log('Copilot client started successfully');\n }\n\n /**\n * Generate LLM response using Copilot SDK's native tool support\n *\n * Copilot SDK handles:\n * - Tool definition injection\n * - Tool call generation\n * - Tool execution via handlers\n * - Multi-turn tool calling loop\n *\n * Architecture notes:\n * - Creates a disposable session for each call\n * - Session is destroyed after use (in finally block)\n * - Tool calls are tracked via onPostToolUse hook\n * - Returns toolCalls array marked as already executed\n */\n async generate(\n messages: Message[],\n tools?: Tool[],\n _config?: GenerationConfig,\n ctx?: ExecutionContext\n ): Promise<LLMResponse> {\n if (!this.isInitialized) {\n await this.initialize();\n }\n\n // Store context for tool handlers\n this.currentContext = ctx;\n\n // Reset tool call history for this generation\n this.toolCallHistory = [];\n\n const startTime = Date.now();\n\n // Disposable session pattern: create new session for each call\n const sessionId = `deity-session-${Date.now()}-${this.sessionCounter++}`;\n this.log('Creating disposable session:', sessionId);\n\n // Convert Deity tools to Copilot SDK tools\n const copilotTools = tools ? this.convertTools(tools) : undefined;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n const toolNames = copilotTools?.map((t) => (t as any).name) || [];\n\n this.log('Session tools:', {\n count: toolNames.length,\n names: toolNames,\n });\n\n // Create session with hooks to track tool calls\n const sessionConfig: any = {\n sessionId,\n model: this.model,\n tools: copilotTools,\n // Exclude ALL environment tools to ensure only registered tools are used\n excludedTools: [\n 'bash',\n 'write_bash',\n 'read_bash',\n 'stop_bash',\n 'list_bash',\n 'shell',\n 'view',\n 'create',\n 'edit',\n 'web_fetch',\n 'report_intent',\n 'read_file',\n 'write_file',\n 'sql',\n 'read_agent',\n 'list_agents',\n 'grep',\n 'glob',\n 'task',\n ],\n // Add hooks to track tool calls for Deity compatibility\n hooks: {\n onPostToolUse: (input: any) => {\n // Record tool call in history with execution metadata\n const toolCall: any = {\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2)}`,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n arguments: input.toolArgs,\n _alreadyExecuted: true, // Mark as already executed by SDK\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n _executionResult: JSON.stringify(input.toolResult), // Store result for reference\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.toolCallHistory.push(toolCall);\n\n this.log('Tool call tracked:', {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n totalCalls: this.toolCallHistory.length,\n });\n\n // Don't modify anything, just track\n return undefined;\n },\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const session = await this.client.createSession(sessionConfig);\n this.log('Session created:', sessionId);\n\n try {\n // Convert ALL messages to prompt (including system messages)\n const prompt = this.messagesToPrompt(messages);\n\n this.log('Sending prompt:', {\n promptLength: prompt.length,\n sessionId: session.sessionId,\n toolsCount: tools?.length || 0,\n });\n\n let responseContent = '';\n\n // Use sendAndWait() to get the response\n try {\n const result = await session.sendAndWait({ prompt }, 12000000); // 12000s timeout\n\n if (result) {\n responseContent = result.data.content || '';\n this.log('Response received:', {\n length: responseContent.length,\n });\n }\n } catch (error: any) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n console.error('[CopilotSDKAdapter] sendAndWait error:', error.message);\n throw error;\n }\n\n const elapsed = Date.now() - startTime;\n this.log(`API response received in ${elapsed}ms`);\n\n if (this.toolCallHistory.length > 0) {\n this.log(`Session executed ${this.toolCallHistory.length} tool calls`);\n }\n\n // Return result with toolCalls marked as already executed\n // Deity llm-loop will check _alreadyExecuted flag and skip re-execution\n const response: LLMResponse = {\n content: responseContent,\n toolCalls: this.toolCallHistory.length > 0 ? this.toolCallHistory : undefined,\n };\n\n return response;\n } catch (error) {\n // Clean up session on error\n await session.destroy();\n throw error;\n } finally {\n // Always destroy disposable session\n await session.destroy();\n this.log('Session destroyed:', sessionId);\n }\n }\n\n /**\n * Convert Deity Tool to Copilot SDK Tool using defineTool\n *\n * Uses SDK's defineTool() function which properly registers tools.\n * Zod schemas are passed directly - Zod v4 has native toJSONSchema() method.\n */\n private convertTools(deityTools: Tool[]): CopilotTool[] {\n this.log('Converting Deity tools to Copilot SDK format:', {\n count: deityTools.length,\n names: deityTools.map((t) => t.name),\n });\n\n const converted = deityTools.map((tool) => {\n // Pass Zod schema directly - Zod v4 has native toJSONSchema() method\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const parameters = tool.inputSchema as any;\n\n // Use SDK's defineTool function (critical for proper registration)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return\n return defineTool(tool.name, {\n description: tool.description || `Tool: ${tool.name}`,\n parameters,\n handler: async (args: unknown) => {\n this.log('Executing tool via SDK handler:', {\n name: tool.name,\n });\n\n try {\n if (!this.currentContext) {\n throw new Error('Execution context not available for tool handler');\n }\n\n // Execute Deity tool\n const result = await tool.execute(args, this.currentContext);\n\n this.log('Tool execution successful:', tool.name);\n\n // Return result in format expected by Copilot SDK\n return typeof result === 'string' ? result : JSON.stringify(result);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error('[CopilotSDKAdapter] Tool execution failed:', {\n tool: tool.name,\n error: errorMsg,\n });\n\n // Return error result\n return JSON.stringify({\n success: false,\n error: errorMsg,\n });\n }\n },\n });\n });\n\n this.log('Tool conversion complete:', {\n convertedCount: converted.length,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n toolNames: converted.map((t: any) => t.name || 'unknown'),\n });\n\n return converted;\n }\n\n /**\n * Convert Deity messages to Copilot prompt format\n *\n * Note: Copilot SDK uses a simple string prompt format.\n * All message types are concatenated into a single prompt.\n */\n private messagesToPrompt(messages: Message[]): string {\n let prompt = '';\n\n for (const msg of messages) {\n switch (msg.role) {\n case 'system':\n prompt += msg.content + '\\n\\n';\n break;\n case 'user':\n prompt += `User: ${msg.content}\\n\\n`;\n break;\n case 'assistant':\n prompt += `Assistant: ${msg.content}\\n\\n`;\n break;\n case 'tool':\n // Skip tool messages - SDK handles them internally\n break;\n }\n }\n\n return prompt;\n }\n\n async cleanup(): Promise<void> {\n if (!this.isInitialized) {\n return;\n }\n\n // No sessions to clean up (disposable session pattern)\n this.log('Stopping Copilot client...');\n await this.client.stop();\n this.isInitialized = false;\n this.log('Copilot client stopped');\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/adapter.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-assignment */\n\n/**\n * Copilot SDK Adapter for Deity Framework\n *\n * Uses Copilot SDK's native tool support for reliable tool calling.\n *\n * Architecture:\n * - Deity passes tools to generate()\n * - Adapter converts Deity tools to Copilot SDK tools\n * - Copilot SDK handles tool calling loop automatically\n * - Adapter returns final response with tool call information\n *\n * Session Management:\n * - Uses disposable session pattern (create → use → destroy)\n * - Each generate() call creates a fresh session\n * - Sessions are destroyed in finally block to ensure cleanup\n * - This pattern is optimized for Deity's stateless design\n */\n\nimport { CopilotClient, defineTool, type Tool as CopilotTool } from '@github/copilot-sdk';\nimport type {\n LLMAdapter,\n LLMResponse,\n Message,\n Tool,\n GenerationConfig,\n ExecutionContext,\n ToolCall,\n} from '@limo-labs/deity';\n\nexport interface CopilotSDKAdapterConfig {\n /**\n * Model to use (default: 'gpt-4o')\n * Options: 'gpt-4o', 'claude-opus-4.6', 'o1', 'o1-mini', etc.\n */\n model?: string;\n\n /**\n * Custom Copilot CLI URL (optional)\n * If not provided, SDK will auto-manage the CLI\n */\n cliUrl?: string;\n\n /**\n * Callback for streaming response chunks (optional)\n */\n onStreamChunk?: (chunk: string) => void;\n\n /**\n * Callback for reasoning/thinking chunks (optional)\n */\n onReasoningChunk?: (chunk: string) => void;\n\n /**\n * Enable debug logging (default: false)\n */\n debug?: boolean;\n}\n\nexport class CopilotSDKAdapter implements LLMAdapter {\n private client: CopilotClient;\n private model: string;\n private sessionCounter = 0;\n private isInitialized = false;\n private onStreamChunk?: (chunk: string) => void;\n private currentContext?: ExecutionContext;\n private debugEnabled: boolean;\n\n // Track tool calls for Deity compatibility\n private toolCallHistory: ToolCall[] = [];\n\n constructor(config: CopilotSDKAdapterConfig = {}) {\n this.model = config.model || 'gpt-4o';\n this.onStreamChunk = config.onStreamChunk;\n this.debugEnabled = config.debug || false;\n\n // CRITICAL FIX: Disable built-in GitHub MCP server\n // GitHub MCP server auto-activates in git repos and overrides SDK tools\n this.client = new CopilotClient({\n cliUrl: config.cliUrl,\n cliArgs: ['--disable-builtin-mcps'],\n });\n\n this.log('CopilotSDKAdapter created:', {\n model: this.model,\n mode: config.cliUrl ? 'external-server' : 'auto-managed',\n streaming: !!this.onStreamChunk,\n nativeToolSupport: true,\n });\n }\n\n private log(...args: any[]): void {\n if (this.debugEnabled) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n console.log('[CopilotSDKAdapter]', ...args);\n }\n }\n\n async initialize(): Promise<void> {\n if (this.isInitialized) {\n this.log('Client already initialized, skipping');\n return;\n }\n\n this.log('Starting Copilot client...');\n await this.client.start();\n this.isInitialized = true;\n this.log('Copilot client started successfully');\n }\n\n /**\n * Generate LLM response using Copilot SDK's native tool support\n *\n * Copilot SDK handles:\n * - Tool definition injection\n * - Tool call generation\n * - Tool execution via handlers\n * - Multi-turn tool calling loop\n *\n * Architecture notes:\n * - Creates a disposable session for each call\n * - Session is destroyed after use (in finally block)\n * - Tool calls are tracked via onPostToolUse hook\n * - Returns toolCalls array marked as already executed\n */\n async generate(\n messages: Message[],\n tools?: Tool[],\n _config?: GenerationConfig,\n ctx?: ExecutionContext\n ): Promise<LLMResponse> {\n if (!this.isInitialized) {\n await this.initialize();\n }\n\n // Store context for tool handlers\n this.currentContext = ctx;\n\n // Reset tool call history for this generation\n this.toolCallHistory = [];\n\n const startTime = Date.now();\n\n // Disposable session pattern: create new session for each call\n const sessionId = `deity-session-${Date.now()}-${this.sessionCounter++}`;\n this.log('Creating disposable session:', sessionId);\n\n // Convert Deity tools to Copilot SDK tools\n const copilotTools = tools ? this.convertTools(tools) : undefined;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n const toolNames = copilotTools?.map((t) => (t as any).name) || [];\n\n this.log('Session tools:', {\n count: toolNames.length,\n names: toolNames,\n });\n\n // Create session with hooks to track tool calls\n const sessionConfig: any = {\n sessionId,\n model: this.model,\n tools: copilotTools,\n // Exclude ALL environment tools to ensure only registered tools are used\n excludedTools: [\n 'bash',\n 'write_bash',\n 'read_bash',\n 'stop_bash',\n 'list_bash',\n 'shell',\n 'view',\n 'create',\n 'edit',\n 'web_fetch',\n 'report_intent',\n 'read_file',\n 'write_file',\n 'sql',\n 'read_agent',\n 'list_agents',\n 'grep',\n 'glob',\n 'task',\n ],\n // Add hooks to track tool calls for Deity compatibility\n hooks: {\n onPostToolUse: (input: any) => {\n // Extract actual result from Copilot SDK's toolResult format\n // SDK may return { textResultForLlm: \"...\" } or raw string\n let resultString: string;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n if (input.toolResult && typeof input.toolResult === 'object' && 'textResultForLlm' in input.toolResult) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n resultString = input.toolResult.textResultForLlm;\n } else {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument\n resultString = typeof input.toolResult === 'string' ? input.toolResult : JSON.stringify(input.toolResult);\n }\n\n // Record tool call in history with execution metadata\n const toolCall: any = {\n id: `call_${Date.now()}_${Math.random().toString(36).slice(2)}`,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n arguments: input.toolArgs,\n _alreadyExecuted: true, // Mark as already executed by SDK\n _executionResult: resultString, // Store raw result string (already JSON stringified by tool handler)\n };\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n this.toolCallHistory.push(toolCall);\n\n this.log('Tool call tracked:', {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access\n name: input.toolName,\n totalCalls: this.toolCallHistory.length,\n });\n\n // Don't modify anything, just track\n return undefined;\n },\n },\n };\n\n // eslint-disable-next-line @typescript-eslint/no-unsafe-argument\n const session = await this.client.createSession(sessionConfig);\n this.log('Session created:', sessionId);\n\n try {\n // Convert ALL messages to prompt (including system messages)\n const prompt = this.messagesToPrompt(messages);\n\n this.log('Sending prompt:', {\n promptLength: prompt.length,\n sessionId: session.sessionId,\n toolsCount: tools?.length || 0,\n });\n\n let responseContent = '';\n\n // Use sendAndWait() to get the response\n try {\n const result = await session.sendAndWait({ prompt }, 12000000); // 12000s timeout\n\n if (result) {\n responseContent = result.data.content || '';\n this.log('Response received:', {\n length: responseContent.length,\n });\n }\n } catch (error: any) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n console.error('[CopilotSDKAdapter] sendAndWait error:', error.message);\n throw error;\n }\n\n const elapsed = Date.now() - startTime;\n this.log(`API response received in ${elapsed}ms`);\n\n if (this.toolCallHistory.length > 0) {\n this.log(`Session executed ${this.toolCallHistory.length} tool calls`);\n }\n\n // Return result with toolCalls marked as already executed\n // Deity llm-loop will check _alreadyExecuted flag and skip re-execution\n const response: LLMResponse = {\n content: responseContent,\n toolCalls: this.toolCallHistory.length > 0 ? this.toolCallHistory : undefined,\n };\n\n return response;\n } catch (error) {\n // Clean up session on error\n await session.destroy();\n throw error;\n } finally {\n // Always destroy disposable session\n await session.destroy();\n this.log('Session destroyed:', sessionId);\n }\n }\n\n /**\n * Convert Deity Tool to Copilot SDK Tool using defineTool\n *\n * Uses SDK's defineTool() function which properly registers tools.\n * Zod schemas are passed directly - Zod v4 has native toJSONSchema() method.\n */\n private convertTools(deityTools: Tool[]): CopilotTool[] {\n this.log('Converting Deity tools to Copilot SDK format:', {\n count: deityTools.length,\n names: deityTools.map((t) => t.name),\n });\n\n const converted = deityTools.map((tool) => {\n // Pass Zod schema directly - Zod v4 has native toJSONSchema() method\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment\n const parameters = tool.inputSchema as any;\n\n // Use SDK's defineTool function (critical for proper registration)\n // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-return\n return defineTool(tool.name, {\n description: tool.description || `Tool: ${tool.name}`,\n parameters,\n handler: async (args: unknown) => {\n this.log('Executing tool via SDK handler:', {\n name: tool.name,\n });\n\n try {\n if (!this.currentContext) {\n throw new Error('Execution context not available for tool handler');\n }\n\n // Execute Deity tool\n const result = await tool.execute(args, this.currentContext);\n\n this.log('Tool execution successful:', tool.name);\n\n // Return result in format expected by Copilot SDK\n return typeof result === 'string' ? result : JSON.stringify(result);\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n console.error('[CopilotSDKAdapter] Tool execution failed:', {\n tool: tool.name,\n error: errorMsg,\n });\n\n // Return error result\n return JSON.stringify({\n success: false,\n error: errorMsg,\n });\n }\n },\n });\n });\n\n this.log('Tool conversion complete:', {\n convertedCount: converted.length,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-member-access\n toolNames: converted.map((t: any) => t.name || 'unknown'),\n });\n\n return converted;\n }\n\n /**\n * Convert Deity messages to Copilot prompt format\n *\n * Note: Copilot SDK uses a simple string prompt format.\n * All message types are concatenated into a single prompt.\n */\n private messagesToPrompt(messages: Message[]): string {\n let prompt = '';\n\n for (const msg of messages) {\n switch (msg.role) {\n case 'system':\n prompt += msg.content + '\\n\\n';\n break;\n case 'user':\n prompt += `User: ${msg.content}\\n\\n`;\n break;\n case 'assistant':\n prompt += `Assistant: ${msg.content}\\n\\n`;\n break;\n case 'tool':\n // Skip tool messages - SDK handles them internally\n break;\n }\n }\n\n return prompt;\n }\n\n async cleanup(): Promise<void> {\n if (!this.isInitialized) {\n return;\n }\n\n // No sessions to clean up (disposable session pattern)\n this.log('Stopping Copilot client...');\n await this.client.stop();\n this.isInitialized = false;\n this.log('Copilot client stopped');\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@limo-labs/deity-adapter-copilot",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.2",
|
|
4
4
|
"description": "GitHub Copilot SDK adapter for Deity framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"author": "Limo Labs",
|
|
58
58
|
"license": "MIT",
|
|
59
59
|
"peerDependencies": {
|
|
60
|
-
"@limo-labs/deity": "^0.
|
|
60
|
+
"@limo-labs/deity": "^0.2.0-alpha.0",
|
|
61
61
|
"@github/copilot-sdk": "^0.1.25"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"@limo-labs/deity": "^0.
|
|
64
|
+
"@limo-labs/deity": "^0.2.0-alpha.0",
|
|
65
65
|
"@github/copilot-sdk": "^0.1.25",
|
|
66
66
|
"@types/node": "^20.11.0",
|
|
67
67
|
"@typescript-eslint/eslint-plugin": "^6.19.0",
|