@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 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
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
114
- _executionResult: JSON.stringify(input.toolResult)
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:", {
@@ -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
- // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
112
- _executionResult: JSON.stringify(input.toolResult)
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":";;;AA4DO,IAAM,oBAAN,MAA8C;AAAA,EAC3C,MAAA;AAAA,EACA,KAAA;AAAA,EACA,cAAA,GAAiB,CAAA;AAAA,EACjB,aAAA,GAAgB,KAAA;AAAA,EAChB,aAAA;AAAA,EACA,cAAA;AAAA,EACA,YAAA;AAAA;AAAA,EAGA,kBAA8B,EAAC;AAAA,EAEvC,WAAA,CAAY,MAAA,GAAkC,EAAC,EAAG;AAChD,IAAA,IAAA,CAAK,KAAA,GAAQ,OAAO,KAAA,IAAS,QAAA;AAC7B,IAAA,IAAA,CAAK,gBAAgB,MAAA,CAAO,aAAA;AAC5B,IAAA,IAAA,CAAK,YAAA,GAAe,OAAO,KAAA,IAAS,KAAA;AAIpC,IAAA,IAAA,CAAK,MAAA,GAAS,IAAI,aAAA,CAAc;AAAA,MAC9B,QAAQ,MAAA,CAAO,MAAA;AAAA,MACf,OAAA,EAAS,CAAC,wBAAwB;AAAA,KACnC,CAAA;AAED,IAAA,IAAA,CAAK,IAAI,4BAAA,EAA8B;AAAA,MACrC,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,IAAA,EAAM,MAAA,CAAO,MAAA,GAAS,iBAAA,GAAoB,cAAA;AAAA,MAC1C,SAAA,EAAW,CAAC,CAAC,IAAA,CAAK,aAAA;AAAA,MAClB,iBAAA,EAAmB;AAAA,KACpB,CAAA;AAAA,EACH;AAAA,EAEQ,OAAO,IAAA,EAAmB;AAChC,IAAA,IAAI,KAAK,YAAA,EAAc;AAErB,MAAA,OAAA,CAAQ,GAAA,CAAI,qBAAA,EAAuB,GAAG,IAAI,CAAA;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,IAAA,CAAK,IAAI,sCAAsC,CAAA;AAC/C,MAAA;AAAA,IACF;AAEA,IAAA,IAAA,CAAK,IAAI,4BAA4B,CAAA;AACrC,IAAA,MAAM,IAAA,CAAK,OAAO,KAAA,EAAM;AACxB,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,IAAA,IAAA,CAAK,IAAI,qCAAqC,CAAA;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAM,QAAA,CACJ,QAAA,EACA,KAAA,EACA,SACA,GAAA,EACsB;AACtB,IAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,MAAA,MAAM,KAAK,UAAA,EAAW;AAAA,IACxB;AAGA,IAAA,IAAA,CAAK,cAAA,GAAiB,GAAA;AAGtB,IAAA,IAAA,CAAK,kBAAkB,EAAC;AAExB,IAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAG3B,IAAA,MAAM,YAAY,CAAA,cAAA,EAAiB,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,KAAK,cAAA,EAAgB,CAAA,CAAA;AACtE,IAAA,IAAA,CAAK,GAAA,CAAI,gCAAgC,SAAS,CAAA;AAGlD,IAAA,MAAM,YAAA,GAAe,KAAA,GAAQ,IAAA,CAAK,YAAA,CAAa,KAAK,CAAA,GAAI,MAAA;AAExD,IAAA,MAAM,SAAA,GAAY,cAAc,GAAA,CAAI,CAAC,MAAO,CAAA,CAAU,IAAI,KAAK,EAAC;AAEhE,IAAA,IAAA,CAAK,IAAI,gBAAA,EAAkB;AAAA,MACzB,OAAO,SAAA,CAAU,MAAA;AAAA,MACjB,KAAA,EAAO;AAAA,KACR,CAAA;AAGD,IAAA,MAAM,aAAA,GAAqB;AAAA,MACzB,SAAA;AAAA,MACA,OAAO,IAAA,CAAK,KAAA;AAAA,MACZ,KAAA,EAAO,YAAA;AAAA;AAAA,MAEP,aAAA,EAAe;AAAA,QACb,MAAA;AAAA,QACA,YAAA;AAAA,QACA,WAAA;AAAA,QACA,WAAA;AAAA,QACA,WAAA;AAAA,QACA,OAAA;AAAA,QACA,MAAA;AAAA,QACA,QAAA;AAAA,QACA,MAAA;AAAA,QACA,WAAA;AAAA,QACA,eAAA;AAAA,QACA,WAAA;AAAA,QACA,YAAA;AAAA,QACA,KAAA;AAAA,QACA,YAAA;AAAA,QACA,aAAA;AAAA,QACA,MAAA;AAAA,QACA,MAAA;AAAA,QACA;AAAA,OACF;AAAA;AAAA,MAEA,KAAA,EAAO;AAAA,QACL,aAAA,EAAe,CAAC,KAAA,KAAe;AAG7B,UAAA,IAAI,YAAA;AAEJ,UAAA,IAAI,KAAA,CAAM,cAAc,OAAO,KAAA,CAAM,eAAe,QAAA,IAAY,kBAAA,IAAsB,MAAM,UAAA,EAAY;AAEtG,YAAA,YAAA,GAAe,MAAM,UAAA,CAAW,gBAAA;AAAA,UAClC,CAAA,MAAO;AAEL,YAAA,YAAA,GAAe,OAAO,MAAM,UAAA,KAAe,QAAA,GAAW,MAAM,UAAA,GAAa,IAAA,CAAK,SAAA,CAAU,KAAA,CAAM,UAAU,CAAA;AAAA,UAC1G;AAGA,UAAA,MAAM,QAAA,GAAgB;AAAA,YACpB,EAAA,EAAI,CAAA,KAAA,EAAQ,IAAA,CAAK,GAAA,EAAK,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,EAAO,CAAE,QAAA,CAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAAA;AAAA,YAE7D,MAAM,KAAA,CAAM,QAAA;AAAA;AAAA,YAEZ,WAAW,KAAA,CAAM,QAAA;AAAA,YACjB,gBAAA,EAAkB,IAAA;AAAA;AAAA,YAClB,gBAAA,EAAkB;AAAA;AAAA,WACpB;AAEA,UAAA,IAAA,CAAK,eAAA,CAAgB,KAAK,QAAQ,CAAA;AAElC,UAAA,IAAA,CAAK,IAAI,oBAAA,EAAsB;AAAA;AAAA,YAE7B,MAAM,KAAA,CAAM,QAAA;AAAA,YACZ,UAAA,EAAY,KAAK,eAAA,CAAgB;AAAA,WAClC,CAAA;AAGD,UAAA,OAAO,MAAA;AAAA,QACT;AAAA;AACF,KACF;AAGA,IAAA,MAAM,OAAA,GAAU,MAAM,IAAA,CAAK,MAAA,CAAO,cAAc,aAAa,CAAA;AAC7D,IAAA,IAAA,CAAK,GAAA,CAAI,oBAAoB,SAAS,CAAA;AAEtC,IAAA,IAAI;AAEF,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,gBAAA,CAAiB,QAAQ,CAAA;AAE7C,MAAA,IAAA,CAAK,IAAI,iBAAA,EAAmB;AAAA,QAC1B,cAAc,MAAA,CAAO,MAAA;AAAA,QACrB,WAAW,OAAA,CAAQ,SAAA;AAAA,QACnB,UAAA,EAAY,OAAO,MAAA,IAAU;AAAA,OAC9B,CAAA;AAED,MAAA,IAAI,eAAA,GAAkB,EAAA;AAGtB,MAAA,IAAI;AACF,QAAA,MAAM,SAAS,MAAM,OAAA,CAAQ,YAAY,EAAE,MAAA,IAAU,IAAQ,CAAA;AAE7D,QAAA,IAAI,MAAA,EAAQ;AACV,UAAA,eAAA,GAAkB,MAAA,CAAO,KAAK,OAAA,IAAW,EAAA;AACzC,UAAA,IAAA,CAAK,IAAI,oBAAA,EAAsB;AAAA,YAC7B,QAAQ,eAAA,CAAgB;AAAA,WACzB,CAAA;AAAA,QACH;AAAA,MACF,SAAS,KAAA,EAAY;AAEnB,QAAA,OAAA,CAAQ,KAAA,CAAM,wCAAA,EAA0C,KAAA,CAAM,OAAO,CAAA;AACrE,QAAA,MAAM,KAAA;AAAA,MACR;AAEA,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA;AAC7B,MAAA,IAAA,CAAK,GAAA,CAAI,CAAA,yBAAA,EAA4B,OAAO,CAAA,EAAA,CAAI,CAAA;AAEhD,MAAA,IAAI,IAAA,CAAK,eAAA,CAAgB,MAAA,GAAS,CAAA,EAAG;AACnC,QAAA,IAAA,CAAK,GAAA,CAAI,CAAA,iBAAA,EAAoB,IAAA,CAAK,eAAA,CAAgB,MAAM,CAAA,WAAA,CAAa,CAAA;AAAA,MACvE;AAIA,MAAA,MAAM,QAAA,GAAwB;AAAA,QAC5B,OAAA,EAAS,eAAA;AAAA,QACT,WAAW,IAAA,CAAK,eAAA,CAAgB,MAAA,GAAS,CAAA,GAAI,KAAK,eAAA,GAAkB,KAAA;AAAA,OACtE;AAEA,MAAA,OAAO,QAAA;AAAA,IACT,SAAS,KAAA,EAAO;AAEd,MAAA,MAAM,QAAQ,OAAA,EAAQ;AACtB,MAAA,MAAM,KAAA;AAAA,IACR,CAAA,SAAE;AAEA,MAAA,MAAM,QAAQ,OAAA,EAAQ;AACtB,MAAA,IAAA,CAAK,GAAA,CAAI,sBAAsB,SAAS,CAAA;AAAA,IAC1C;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,aAAa,UAAA,EAAmC;AACtD,IAAA,IAAA,CAAK,IAAI,+CAAA,EAAiD;AAAA,MACxD,OAAO,UAAA,CAAW,MAAA;AAAA,MAClB,OAAO,UAAA,CAAW,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,IAAI;AAAA,KACpC,CAAA;AAED,IAAA,MAAM,SAAA,GAAY,UAAA,CAAW,GAAA,CAAI,CAAC,IAAA,KAAS;AAGzC,MAAA,MAAM,aAAa,IAAA,CAAK,WAAA;AAIxB,MAAA,OAAO,UAAA,CAAW,KAAK,IAAA,EAAM;AAAA,QAC3B,WAAA,EAAa,IAAA,CAAK,WAAA,IAAe,CAAA,MAAA,EAAS,KAAK,IAAI,CAAA,CAAA;AAAA,QACnD,UAAA;AAAA,QACA,OAAA,EAAS,OAAO,IAAA,KAAkB;AAChC,UAAA,IAAA,CAAK,IAAI,iCAAA,EAAmC;AAAA,YAC1C,MAAM,IAAA,CAAK;AAAA,WACZ,CAAA;AAED,UAAA,IAAI;AACF,YAAA,IAAI,CAAC,KAAK,cAAA,EAAgB;AACxB,cAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,YACpE;AAGA,YAAA,MAAM,SAAS,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,EAAM,KAAK,cAAc,CAAA;AAE3D,YAAA,IAAA,CAAK,GAAA,CAAI,4BAAA,EAA8B,IAAA,CAAK,IAAI,CAAA;AAGhD,YAAA,OAAO,OAAO,MAAA,KAAW,QAAA,GAAW,MAAA,GAAS,IAAA,CAAK,UAAU,MAAM,CAAA;AAAA,UACpE,SAAS,KAAA,EAAO;AACd,YAAA,MAAM,WAAW,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK,CAAA;AACtE,YAAA,OAAA,CAAQ,MAAM,4CAAA,EAA8C;AAAA,cAC1D,MAAM,IAAA,CAAK,IAAA;AAAA,cACX,KAAA,EAAO;AAAA,aACR,CAAA;AAGD,YAAA,OAAO,KAAK,SAAA,CAAU;AAAA,cACpB,OAAA,EAAS,KAAA;AAAA,cACT,KAAA,EAAO;AAAA,aACR,CAAA;AAAA,UACH;AAAA,QACF;AAAA,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,IAAI,2BAAA,EAA6B;AAAA,MACpC,gBAAgB,SAAA,CAAU,MAAA;AAAA;AAAA,MAE1B,WAAW,SAAA,CAAU,GAAA,CAAI,CAAC,CAAA,KAAW,CAAA,CAAE,QAAQ,SAAS;AAAA,KACzD,CAAA;AAED,IAAA,OAAO,SAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,iBAAiB,QAAA,EAA6B;AACpD,IAAA,IAAI,MAAA,GAAS,EAAA;AAEb,IAAA,KAAA,MAAW,OAAO,QAAA,EAAU;AAC1B,MAAA,QAAQ,IAAI,IAAA;AAAM,QAChB,KAAK,QAAA;AACH,UAAA,MAAA,IAAU,IAAI,OAAA,GAAU,MAAA;AACxB,UAAA;AAAA,QACF,KAAK,MAAA;AACH,UAAA,MAAA,IAAU,CAAA,MAAA,EAAS,IAAI,OAAO;;AAAA,CAAA;AAC9B,UAAA;AAAA,QACF,KAAK,WAAA;AACH,UAAA,MAAA,IAAU,CAAA,WAAA,EAAc,IAAI,OAAO;;AAAA,CAAA;AACnC,UAAA;AAGA;AACJ,IACF;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAM,OAAA,GAAyB;AAC7B,IAAA,IAAI,CAAC,KAAK,aAAA,EAAe;AACvB,MAAA;AAAA,IACF;AAGA,IAAA,IAAA,CAAK,IAAI,4BAA4B,CAAA;AACrC,IAAA,MAAM,IAAA,CAAK,OAAO,IAAA,EAAK;AACvB,IAAA,IAAA,CAAK,aAAA,GAAgB,KAAA;AACrB,IAAA,IAAA,CAAK,IAAI,wBAAwB,CAAA;AAAA,EACnC;AACF","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.1",
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.1.3-alpha.2",
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.1.3-alpha.2",
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",