skimpyclaw 0.3.14 → 0.4.0

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.
Files changed (222) hide show
  1. package/README.md +47 -37
  2. package/dist/__tests__/adapter-types.test.d.ts +4 -0
  3. package/dist/__tests__/adapter-types.test.js +63 -0
  4. package/dist/__tests__/anthropic-adapter.test.d.ts +4 -0
  5. package/dist/__tests__/anthropic-adapter.test.js +264 -0
  6. package/dist/__tests__/api.test.js +0 -1
  7. package/dist/__tests__/cli.integration.test.js +2 -4
  8. package/dist/__tests__/cli.test.js +0 -1
  9. package/dist/__tests__/code-agents-notifications.test.js +137 -0
  10. package/dist/__tests__/code-agents-parser.test.js +19 -1
  11. package/dist/__tests__/code-agents-preflight.test.js +3 -28
  12. package/dist/__tests__/code-agents-utils.test.js +34 -9
  13. package/dist/__tests__/code-agents-worktrees.test.js +116 -0
  14. package/dist/__tests__/codex-adapter.test.js +184 -0
  15. package/dist/__tests__/codex-auth.test.js +66 -0
  16. package/dist/__tests__/codex-provider-gating.test.js +35 -0
  17. package/dist/__tests__/codex-unified-loop.test.js +111 -0
  18. package/dist/__tests__/config-security.test.js +127 -0
  19. package/dist/__tests__/config.test.js +23 -0
  20. package/dist/__tests__/context-manager.test.js +243 -164
  21. package/dist/__tests__/cron-run.test.js +250 -0
  22. package/dist/__tests__/cron.test.js +12 -38
  23. package/dist/__tests__/digests.test.js +67 -0
  24. package/dist/__tests__/discord-attachments.test.js +211 -0
  25. package/dist/__tests__/discord-docs.test.d.ts +1 -0
  26. package/dist/__tests__/discord-docs.test.js +27 -0
  27. package/dist/__tests__/discord-thread-agents.test.d.ts +1 -0
  28. package/dist/__tests__/discord-thread-agents.test.js +115 -0
  29. package/dist/__tests__/discord-thread-context.test.d.ts +1 -0
  30. package/dist/__tests__/discord-thread-context.test.js +42 -0
  31. package/dist/__tests__/doctor.formatters.test.js +4 -4
  32. package/dist/__tests__/doctor.index.test.js +1 -1
  33. package/dist/__tests__/doctor.runner.test.js +3 -15
  34. package/dist/__tests__/env-sanitizer.test.d.ts +1 -0
  35. package/dist/__tests__/env-sanitizer.test.js +45 -0
  36. package/dist/__tests__/exec-approval.test.js +61 -0
  37. package/dist/__tests__/fetch-tool.test.d.ts +1 -0
  38. package/dist/__tests__/fetch-tool.test.js +85 -0
  39. package/dist/__tests__/gateway-status-auth.test.d.ts +1 -0
  40. package/dist/__tests__/gateway-status-auth.test.js +72 -0
  41. package/dist/__tests__/heartbeat.test.js +3 -3
  42. package/dist/__tests__/interactive-sessions.test.d.ts +1 -0
  43. package/dist/__tests__/interactive-sessions.test.js +96 -0
  44. package/dist/__tests__/langfuse.test.js +6 -18
  45. package/dist/__tests__/model-selection.test.js +3 -4
  46. package/dist/__tests__/providers-init.test.js +2 -8
  47. package/dist/__tests__/providers-routing.test.js +1 -1
  48. package/dist/__tests__/providers-utils.test.js +13 -3
  49. package/dist/__tests__/sessions.test.js +14 -10
  50. package/dist/__tests__/setup.test.js +12 -29
  51. package/dist/__tests__/skills.test.js +10 -7
  52. package/dist/__tests__/stream-formatter.test.d.ts +1 -0
  53. package/dist/__tests__/stream-formatter.test.js +114 -0
  54. package/dist/__tests__/token-efficiency.test.js +131 -15
  55. package/dist/__tests__/tool-loop.test.d.ts +4 -0
  56. package/dist/__tests__/tool-loop.test.js +505 -0
  57. package/dist/__tests__/tools.test.js +101 -276
  58. package/dist/__tests__/utils.test.d.ts +1 -0
  59. package/dist/__tests__/utils.test.js +14 -0
  60. package/dist/__tests__/voice.test.js +21 -0
  61. package/dist/agent.js +35 -4
  62. package/dist/api.js +113 -37
  63. package/dist/channels/discord/attachments.d.ts +50 -0
  64. package/dist/channels/discord/attachments.js +137 -0
  65. package/dist/channels/discord/delegation.d.ts +5 -0
  66. package/dist/channels/discord/delegation.js +136 -0
  67. package/dist/channels/discord/handlers.js +694 -7
  68. package/dist/channels/discord/index.d.ts +16 -1
  69. package/dist/channels/discord/index.js +64 -1
  70. package/dist/channels/discord/thread-agents.d.ts +54 -0
  71. package/dist/channels/discord/thread-agents.js +323 -0
  72. package/dist/channels/discord/threads.d.ts +58 -0
  73. package/dist/channels/discord/threads.js +192 -0
  74. package/dist/channels/discord/types.js +4 -2
  75. package/dist/channels/discord/utils.d.ts +16 -0
  76. package/dist/channels/discord/utils.js +86 -6
  77. package/dist/channels/telegram/index.d.ts +1 -1
  78. package/dist/channels/telegram/types.js +1 -1
  79. package/dist/channels/telegram/utils.js +9 -3
  80. package/dist/channels.d.ts +1 -1
  81. package/dist/cli.js +20 -400
  82. package/dist/code-agents/executor.d.ts +1 -1
  83. package/dist/code-agents/executor.js +101 -45
  84. package/dist/code-agents/index.d.ts +2 -7
  85. package/dist/code-agents/index.js +111 -80
  86. package/dist/code-agents/interactive-resume.d.ts +6 -0
  87. package/dist/code-agents/interactive-resume.js +98 -0
  88. package/dist/code-agents/interactive-sessions.d.ts +20 -0
  89. package/dist/code-agents/interactive-sessions.js +132 -0
  90. package/dist/code-agents/parser.js +5 -1
  91. package/dist/code-agents/registry.d.ts +7 -1
  92. package/dist/code-agents/registry.js +11 -23
  93. package/dist/code-agents/stream-formatter.d.ts +8 -0
  94. package/dist/code-agents/stream-formatter.js +92 -0
  95. package/dist/code-agents/types.d.ts +16 -24
  96. package/dist/code-agents/utils.d.ts +35 -11
  97. package/dist/code-agents/utils.js +349 -95
  98. package/dist/code-agents/worktrees.d.ts +37 -0
  99. package/dist/code-agents/worktrees.js +116 -0
  100. package/dist/config.d.ts +2 -4
  101. package/dist/config.js +123 -23
  102. package/dist/cron.d.ts +1 -6
  103. package/dist/cron.js +175 -82
  104. package/dist/dashboard/assets/index-B345aOO-.js +65 -0
  105. package/dist/dashboard/assets/index-ZWK4dalJ.css +1 -0
  106. package/dist/dashboard/index.html +2 -2
  107. package/dist/digests.d.ts +1 -0
  108. package/dist/digests.js +132 -42
  109. package/dist/doctor/checks.d.ts +0 -3
  110. package/dist/doctor/checks.js +1 -108
  111. package/dist/doctor/runner.js +1 -4
  112. package/dist/env-sanitizer.d.ts +2 -0
  113. package/dist/env-sanitizer.js +61 -0
  114. package/dist/exec-approval.d.ts +11 -1
  115. package/dist/exec-approval.js +17 -4
  116. package/dist/gateway.d.ts +3 -1
  117. package/dist/gateway.js +17 -7
  118. package/dist/heartbeat.js +1 -6
  119. package/dist/langfuse.js +3 -29
  120. package/dist/model-selection.js +3 -1
  121. package/dist/providers/adapter.d.ts +118 -0
  122. package/dist/providers/adapter.js +6 -0
  123. package/dist/providers/adapters/anthropic-adapter.d.ts +22 -0
  124. package/dist/providers/adapters/anthropic-adapter.js +204 -0
  125. package/dist/providers/adapters/codex-adapter.d.ts +26 -0
  126. package/dist/providers/adapters/codex-adapter.js +203 -0
  127. package/dist/providers/anthropic.d.ts +1 -0
  128. package/dist/providers/anthropic.js +10 -272
  129. package/dist/providers/codex.d.ts +21 -0
  130. package/dist/providers/codex.js +149 -330
  131. package/dist/providers/content.d.ts +1 -1
  132. package/dist/providers/content.js +2 -2
  133. package/dist/providers/context-manager.d.ts +18 -6
  134. package/dist/providers/context-manager.js +199 -223
  135. package/dist/providers/index.d.ts +9 -1
  136. package/dist/providers/index.js +73 -64
  137. package/dist/providers/loop-utils.d.ts +20 -0
  138. package/dist/providers/loop-utils.js +30 -0
  139. package/dist/providers/tool-loop.d.ts +12 -0
  140. package/dist/providers/tool-loop.js +251 -0
  141. package/dist/providers/utils.d.ts +19 -3
  142. package/dist/providers/utils.js +100 -29
  143. package/dist/secure-store.d.ts +8 -0
  144. package/dist/secure-store.js +80 -0
  145. package/dist/service.js +3 -28
  146. package/dist/sessions.d.ts +3 -0
  147. package/dist/sessions.js +147 -18
  148. package/dist/setup-templates.js +13 -25
  149. package/dist/setup.d.ts +10 -6
  150. package/dist/setup.js +84 -292
  151. package/dist/skills.js +3 -11
  152. package/dist/tools/agent-delegation.d.ts +19 -0
  153. package/dist/tools/agent-delegation.js +49 -0
  154. package/dist/tools/bash-tool.js +89 -34
  155. package/dist/tools/definitions.d.ts +199 -302
  156. package/dist/tools/definitions.js +70 -123
  157. package/dist/tools/execute-context.d.ts +13 -4
  158. package/dist/tools/fetch-tool.js +109 -13
  159. package/dist/tools/file-tools.js +7 -1
  160. package/dist/tools.d.ts +7 -7
  161. package/dist/tools.js +133 -151
  162. package/dist/types.d.ts +37 -30
  163. package/dist/utils.js +4 -6
  164. package/dist/voice.d.ts +1 -1
  165. package/dist/voice.js +17 -4
  166. package/package.json +33 -23
  167. package/templates/TOOLS.md +0 -27
  168. package/dist/__tests__/audit.test.js +0 -122
  169. package/dist/__tests__/code-agents-orchestrator.test.js +0 -216
  170. package/dist/__tests__/code-agents-sandbox.test.js +0 -163
  171. package/dist/__tests__/orchestrator.test.js +0 -425
  172. package/dist/__tests__/sandbox-bridge.test.js +0 -116
  173. package/dist/__tests__/sandbox-manager.test.js +0 -144
  174. package/dist/__tests__/sandbox-mount-security.test.js +0 -139
  175. package/dist/__tests__/sandbox-runtime.test.js +0 -176
  176. package/dist/__tests__/subagent.test.js +0 -240
  177. package/dist/__tests__/telegram.test.js +0 -42
  178. package/dist/code-agents/orchestrator.d.ts +0 -29
  179. package/dist/code-agents/orchestrator.js +0 -694
  180. package/dist/code-agents/worktree.d.ts +0 -40
  181. package/dist/code-agents/worktree.js +0 -215
  182. package/dist/dashboard/assets/index-BoTHPby4.js +0 -65
  183. package/dist/dashboard/assets/index-D4mufvBg.css +0 -1
  184. package/dist/dashboard.d.ts +0 -8
  185. package/dist/dashboard.js +0 -4071
  186. package/dist/discord.d.ts +0 -8
  187. package/dist/discord.js +0 -792
  188. package/dist/mcp-context-a8c.d.ts +0 -13
  189. package/dist/mcp-context-a8c.js +0 -34
  190. package/dist/orchestrator.d.ts +0 -15
  191. package/dist/orchestrator.js +0 -676
  192. package/dist/providers/openai.d.ts +0 -10
  193. package/dist/providers/openai.js +0 -355
  194. package/dist/sandbox/bridge.d.ts +0 -5
  195. package/dist/sandbox/bridge.js +0 -63
  196. package/dist/sandbox/index.d.ts +0 -5
  197. package/dist/sandbox/index.js +0 -4
  198. package/dist/sandbox/manager.d.ts +0 -7
  199. package/dist/sandbox/manager.js +0 -100
  200. package/dist/sandbox/mount-security.d.ts +0 -12
  201. package/dist/sandbox/mount-security.js +0 -122
  202. package/dist/sandbox/runtime.d.ts +0 -39
  203. package/dist/sandbox/runtime.js +0 -192
  204. package/dist/sandbox-utils.d.ts +0 -6
  205. package/dist/sandbox-utils.js +0 -36
  206. package/dist/subagent.d.ts +0 -19
  207. package/dist/subagent.js +0 -407
  208. package/dist/telegram.d.ts +0 -2
  209. package/dist/telegram.js +0 -11
  210. package/dist/tools/browser-tool.d.ts +0 -3
  211. package/dist/tools/browser-tool.js +0 -266
  212. package/sandbox/Dockerfile +0 -40
  213. /package/dist/__tests__/{audit.test.d.ts → code-agents-notifications.test.d.ts} +0 -0
  214. /package/dist/__tests__/{code-agents-orchestrator.test.d.ts → code-agents-worktrees.test.d.ts} +0 -0
  215. /package/dist/__tests__/{code-agents-sandbox.test.d.ts → codex-adapter.test.d.ts} +0 -0
  216. /package/dist/__tests__/{orchestrator.test.d.ts → codex-auth.test.d.ts} +0 -0
  217. /package/dist/__tests__/{sandbox-bridge.test.d.ts → codex-provider-gating.test.d.ts} +0 -0
  218. /package/dist/__tests__/{sandbox-manager.test.d.ts → codex-unified-loop.test.d.ts} +0 -0
  219. /package/dist/__tests__/{sandbox-mount-security.test.d.ts → config-security.test.d.ts} +0 -0
  220. /package/dist/__tests__/{sandbox-runtime.test.d.ts → cron-run.test.d.ts} +0 -0
  221. /package/dist/__tests__/{subagent.test.d.ts → digests.test.d.ts} +0 -0
  222. /package/dist/__tests__/{telegram.test.d.ts → discord-attachments.test.d.ts} +0 -0
@@ -1,12 +1,5 @@
1
1
  // Anthropic Provider
2
- import { startObservation } from '@langfuse/tracing';
3
- import { buildSystemParam, addToolCacheBreakpoint, contentToText, stripProvider, buildThinkingConfig, truncateToolResult } from './utils.js';
4
- import { compactAnthropicMessages } from './context-manager.js';
5
- import { toAnthropicUsageDetails, toCostDetails } from './observability.js';
6
- import { getToolDefinitions, executeTool } from '../tools.js';
7
- import { ToolCallGuard } from './tool-guard.js';
8
- import { toErrorMessage } from '../utils.js';
9
- import { startTrace, addEvent } from '../audit.js';
2
+ import { toCostDetails } from './observability.js';
10
3
  import { buildUsageRecord, recordUsage } from '../usage.js';
11
4
  let anthropicClient = null;
12
5
  export function setAnthropicClient(client) {
@@ -46,276 +39,21 @@ async function startGenerationObservation(name, attributes) {
46
39
  if (!isLangfuseEnabled())
47
40
  return null;
48
41
  attributes.metadata = { app: LANGFUSE_APP_NAME, ...attributes.metadata };
42
+ const { startObservation } = await import('@langfuse/tracing');
49
43
  return startObservation(name, attributes, { asType: 'generation' });
50
44
  }
45
+ /** @deprecated Use adapter.chat() via the provider registry instead. */
51
46
  export async function chatAnthropic(params) {
52
- if (!anthropicClient) {
53
- throw new Error('Anthropic client not initialized');
54
- }
55
- const { messages, options, config } = params;
56
- const modelId = stripProvider(options.model);
57
- const systemMessage = messages.find(m => m.role === 'system');
58
- const chatMessages = messages
59
- .filter(m => m.role !== 'system')
60
- .map(m => ({
61
- role: m.role,
62
- content: m.content,
63
- }));
64
- // Build request parameters
65
- const cacheEnabled = config.models?.promptCaching !== false;
66
- const anthropicParams = {
67
- model: modelId,
68
- max_tokens: options.maxTokens || 4096,
69
- messages: chatMessages,
70
- };
71
- const systemParam = buildSystemParam(contentToText(systemMessage?.content || ''), cacheEnabled);
72
- if (systemParam) {
73
- anthropicParams.system = systemParam;
74
- }
75
- // Add extended thinking if requested
76
- const thinkingConfig = buildThinkingConfig(options.thinking);
77
- if (thinkingConfig) {
78
- anthropicParams.thinking = {
79
- type: 'enabled',
80
- budget_tokens: thinkingConfig.budget,
81
- };
82
- anthropicParams.max_tokens = Math.max(anthropicParams.max_tokens, thinkingConfig.maxTokens);
83
- }
84
- const genObs = await startGenerationObservation(`anthropic:${modelId}`, {
85
- input: { system: systemMessage?.content, messages: chatMessages },
86
- model: modelId,
87
- modelParameters: {
88
- max_tokens: anthropicParams.max_tokens,
89
- ...(options.thinking && options.thinking !== 'none' ? { thinking: options.thinking } : {}),
90
- },
91
- metadata: { provider: 'anthropic' },
92
- });
93
- try {
94
- const response = await anthropicClient.messages.create(anthropicParams);
95
- const usage = response.usage;
96
- // Log cache metrics
97
- if (usage?.cache_read_input_tokens > 0 || usage?.cache_creation_input_tokens > 0) {
98
- console.log(`[cache] read=${usage.cache_read_input_tokens || 0} created=${usage.cache_creation_input_tokens || 0}`);
99
- }
100
- recordAnthropicUsage({ model: modelId, usage, trigger: 'api' });
101
- // Extract text content
102
- const textContent = response.content.find(c => c.type === 'text');
103
- const text = textContent?.text || '';
104
- genObs?.update({
105
- output: { text },
106
- usageDetails: toAnthropicUsageDetails(usage),
107
- costDetails: toCostDetails(modelId, usage),
108
- });
109
- genObs?.end();
110
- return text;
111
- }
112
- catch (err) {
113
- const errorMessage = toErrorMessage(err);
114
- genObs?.update({ level: 'ERROR', statusMessage: errorMessage, output: { error: errorMessage } });
115
- genObs?.end();
116
- throw err;
117
- }
47
+ const { AnthropicAdapter } = await import('./adapters/anthropic-adapter.js');
48
+ const adapter = new AnthropicAdapter();
49
+ return adapter.chat(params.messages, params.options, params.config);
118
50
  }
119
51
  export async function chatWithToolsAnthropic(params) {
120
52
  if (!anthropicClient) {
121
53
  throw new Error('Anthropic client not initialized');
122
54
  }
123
- const { messages, options, config, toolConfig, toolContext } = params;
124
- const modelId = stripProvider(options.model);
125
- const maxIterations = toolConfig.maxIterations || 20;
126
- // Resolve tools once at start of agent loop
127
- const includeSpawn = !!(toolContext?.fullConfig && (toolContext?.chatId || toolContext?.isCronJob));
128
- const toolDefs = await getToolDefinitions(toolConfig, { includeAgentTools: includeSpawn, projects: toolContext?.fullConfig?.projects });
129
- // Enable prompt caching for system + tools
130
- const cacheEnabled = config.models?.promptCaching !== false;
131
- if (cacheEnabled)
132
- addToolCacheBreakpoint(toolDefs);
133
- // Build system param with OAuth identity guard
134
- const systemMessage = messages.find(m => m.role === 'system');
135
- const systemParam = buildSystemParam(contentToText(systemMessage?.content || ''), cacheEnabled);
136
- // Build initial messages (exclude system)
137
- const apiMessages = messages
138
- .filter(m => m.role !== 'system')
139
- .map(m => ({ role: m.role, content: m.content }));
140
- // Track tool calls for logging
141
- const toolLog = [];
142
- // Guard: spin detection, no-progress detection, token budget
143
- const guard = new ToolCallGuard(toolConfig.maxTurnTokens);
144
- // Start audit trace
145
- const auditTraceId = toolContext?.auditTraceId || startTrace((toolContext?.trigger || 'api'));
146
- for (let i = 0; i < maxIterations; i++) {
147
- // Check abort signal before each iteration
148
- if (toolContext?.abortSignal?.aborted) {
149
- return {
150
- response: `[Cancelled after ${toolLog.length} tool calls]`,
151
- toolCalls: toolLog,
152
- };
153
- }
154
- // Compact old tool results if context is growing large
155
- const compactionResult = await compactAnthropicMessages(apiMessages, toolConfig.contextManagement, i + 1, config);
156
- const messagesForApi = compactionResult.messages;
157
- if (compactionResult.compacted) {
158
- const method = compactionResult.method === 'llm' ? 'LLM summary' : 'truncation';
159
- const detail = `~${Math.round((compactionResult.tokensBefore || 0) / 1000)}k → ~${Math.round((compactionResult.tokensAfter || 0) / 1000)}k tokens`;
160
- toolLog.push(`[context compacted via ${method}: ${detail}]`);
161
- }
162
- const anthropicParams = {
163
- model: modelId,
164
- max_tokens: options.maxTokens || 16384,
165
- messages: messagesForApi,
166
- tools: toolDefs,
167
- };
168
- if (systemParam) {
169
- anthropicParams.system = systemParam;
170
- }
171
- // Add thinking if configured
172
- const thinkingConfig = buildThinkingConfig(options.thinking);
173
- if (thinkingConfig) {
174
- anthropicParams.thinking = { type: 'enabled', budget_tokens: thinkingConfig.budget };
175
- anthropicParams.max_tokens = Math.max(anthropicParams.max_tokens, thinkingConfig.maxTokens);
176
- }
177
- console.log(`[agent:tools] Iteration ${i + 1}/${maxIterations}`);
178
- const genObs = await startGenerationObservation(`anthropic:${modelId}`, {
179
- input: { messages: apiMessages },
180
- model: modelId,
181
- modelParameters: { max_tokens: anthropicParams.max_tokens },
182
- metadata: { provider: 'anthropic', iteration: i + 1 },
183
- });
184
- let response;
185
- try {
186
- response = await anthropicClient.messages.create(anthropicParams);
187
- const usage = response.usage;
188
- // Log cache metrics
189
- if (usage?.cache_read_input_tokens > 0 || usage?.cache_creation_input_tokens > 0) {
190
- console.log(`[cache] read=${usage.cache_read_input_tokens || 0} created=${usage.cache_creation_input_tokens || 0}`);
191
- }
192
- recordAnthropicUsage({
193
- model: modelId,
194
- usage,
195
- trigger: toolContext?.trigger || 'api',
196
- agentId: toolContext?.agentId,
197
- });
198
- genObs?.update({
199
- output: response.content,
200
- usageDetails: toAnthropicUsageDetails(usage),
201
- costDetails: toCostDetails(modelId, usage),
202
- });
203
- genObs?.end();
204
- // Guard: track token usage (stats only, no enforcement)
205
- guard.recordTokens(response.usage?.input_tokens ?? 0, response.usage?.output_tokens ?? 0);
206
- }
207
- catch (err) {
208
- const errorMessage = toErrorMessage(err);
209
- genObs?.update({ level: 'ERROR', statusMessage: errorMessage, output: { error: errorMessage } });
210
- genObs?.end();
211
- throw err;
212
- }
213
- // If no tool use, we're done — extract text
214
- if (response.stop_reason !== 'tool_use') {
215
- const textBlocks = response.content.filter((c) => c.type === 'text');
216
- let responseText = textBlocks.map((b) => b.text).join('\n') || '';
217
- // Fallback when model did tool work but returned no text summary
218
- if (!responseText && toolLog.length > 0) {
219
- responseText = `[Completed with ${toolLog.length} tool calls, no text response]`;
220
- }
221
- const usage = response.usage;
222
- return {
223
- response: responseText,
224
- toolCalls: toolLog,
225
- usage: {
226
- prompt_tokens: usage?.input_tokens ?? 0,
227
- completion_tokens: usage?.output_tokens ?? 0,
228
- total_tokens: (usage?.input_tokens ?? 0) + (usage?.output_tokens ?? 0),
229
- },
230
- cost: toCostDetails(modelId, usage),
231
- };
232
- }
233
- // Add assistant response (full content including tool_use blocks)
234
- apiMessages.push({ role: 'assistant', content: response.content });
235
- // Execute each tool_use block
236
- const toolResults = [];
237
- for (const block of response.content) {
238
- if (block.type !== 'tool_use')
239
- continue;
240
- const inputStr = JSON.stringify(block.input).slice(0, 200);
241
- console.log(`[agent:tools] -> ${block.name}(${inputStr})`);
242
- // Dynamic import to avoid circular dependency
243
- const { isLangfuseEnabled } = await import('../langfuse.js');
244
- const { startObservation } = await import('@langfuse/tracing');
245
- const toolObs = isLangfuseEnabled()
246
- ? startObservation(`tool:${block.name}`, { input: block.input, metadata: { app: LANGFUSE_APP_NAME, tool: block.name } }, { asType: 'tool' })
247
- : null;
248
- // Guard: spin detection
249
- const guardResult = guard.recordCall(block.name, block.input);
250
- if (guardResult.warning)
251
- console.warn(`[agent:tools:guard] ${guardResult.warning}`);
252
- if (guardResult.blocked) {
253
- toolResults.push({
254
- type: 'tool_result',
255
- tool_use_id: block.id,
256
- content: guardResult.warning || 'Blocked: repeated identical call',
257
- is_error: true,
258
- });
259
- toolLog.push(`${block.name} [BLOCKED: spin detected]`);
260
- continue;
261
- }
262
- const toolStart = Date.now();
263
- try {
264
- const result = await executeTool(block.name, block.input, toolConfig, toolContext);
265
- const truncatedResult = truncateToolResult(result);
266
- const resultPreview = result.slice(0, 200) + (result.length > 200 ? '...' : '');
267
- console.log(`[agent:tools] <- ${resultPreview}`);
268
- toolLog.push(`${block.name}(${inputStr}) → ${resultPreview}`);
269
- toolObs?.update({ output: result });
270
- toolObs?.end();
271
- // Record audit event
272
- if (toolContext?.auditTraceId) {
273
- addEvent(toolContext.auditTraceId, {
274
- type: 'tool_use',
275
- summary: `${block.name}(${inputStr})`,
276
- durationMs: Date.now() - toolStart,
277
- });
278
- }
279
- toolResults.push({
280
- type: 'tool_result',
281
- tool_use_id: block.id,
282
- content: truncatedResult,
283
- });
284
- // Guard: no-progress detection
285
- const progressResult = guard.recordResult(result);
286
- if (progressResult.nudge) {
287
- console.warn(`[agent:tools:guard] ${progressResult.nudge}`);
288
- toolResults[toolResults.length - 1].content += `\n\n[System: ${progressResult.nudge}]`;
289
- }
290
- }
291
- catch (err) {
292
- const errorMessage = toErrorMessage(err);
293
- toolObs?.update({ level: 'ERROR', statusMessage: errorMessage, output: { error: errorMessage } });
294
- toolObs?.end();
295
- if (toolContext?.auditTraceId) {
296
- addEvent(toolContext.auditTraceId, {
297
- type: 'tool_error',
298
- summary: `${block.name} error: ${errorMessage.slice(0, 150)}`,
299
- durationMs: Date.now() - toolStart,
300
- });
301
- }
302
- throw err;
303
- }
304
- }
305
- // Send tool results back
306
- apiMessages.push({ role: 'user', content: toolResults });
307
- }
308
- console.warn(`[agent:tools] Max iterations (${maxIterations}) reached`);
309
- return {
310
- response: '[Tool use loop reached maximum iterations]',
311
- toolCalls: toolLog,
312
- };
313
- }
314
- /** Build UsageDetails from Anthropic usage response */
315
- function buildUsageDetails(usage) {
316
- return {
317
- prompt_tokens: usage?.input_tokens ?? 0,
318
- completion_tokens: usage?.output_tokens ?? 0,
319
- total_tokens: (usage?.input_tokens ?? 0) + (usage?.output_tokens ?? 0),
320
- };
55
+ const { runToolLoop } = await import('./tool-loop.js');
56
+ const { AnthropicAdapter } = await import('./adapters/anthropic-adapter.js');
57
+ const adapter = new AnthropicAdapter();
58
+ return runToolLoop(adapter, params.messages, params.options, params.config, params.toolConfig, params.toolContext);
321
59
  }
@@ -8,10 +8,31 @@ interface CodexAuth {
8
8
  accessToken: string;
9
9
  accountId: string;
10
10
  }
11
+ export declare function resolveCodexAuthPath(authPath?: string): string;
11
12
  export declare function loadCodexAuth(authPath?: string): CodexAuth | null;
12
13
  export declare function initCodexAuth(path?: string, baseUrl?: string): boolean;
13
14
  export declare function getCodexAuth(): CodexAuth | null;
14
15
  export declare function isCodexAvailable(): boolean;
16
+ export declare function recordCodexUsage(params: {
17
+ model: string;
18
+ usage: any;
19
+ trigger?: string;
20
+ agentId?: string;
21
+ }): void;
22
+ /**
23
+ * Make a single Codex API call. Returns raw SSE text.
24
+ */
25
+ export declare function codexFetch(body: any, timeoutMs?: number): Promise<string>;
26
+ /**
27
+ * Parse an SSE response from the Codex backend.
28
+ * Extracts function calls from the completed response object.
29
+ */
30
+ export declare function parseCodexSSE(text: string): {
31
+ outputText: string;
32
+ functionCalls: any[];
33
+ response: any | null;
34
+ };
35
+ /** @deprecated Use adapter.chat() via the provider registry instead. */
15
36
  export declare function chatCodex(params: ProviderChatParams): Promise<string>;
16
37
  export declare function chatWithToolsCodex(params: ProviderToolChatParams): Promise<ToolChatResult>;
17
38
  export {};