agent-world 0.11.1 → 0.12.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 (267) hide show
  1. package/README.md +17 -7
  2. package/dist/cli/commands.d.ts +109 -0
  3. package/dist/cli/commands.js +2024 -0
  4. package/dist/cli/display.d.ts +124 -0
  5. package/dist/cli/display.js +381 -0
  6. package/dist/cli/hitl.d.ts +33 -0
  7. package/dist/cli/hitl.js +81 -0
  8. package/dist/cli/index.d.ts +2 -0
  9. package/dist/cli/stream.d.ts +41 -0
  10. package/dist/cli/stream.js +222 -0
  11. package/dist/core/activity-tracker.d.ts +16 -0
  12. package/dist/core/activity-tracker.d.ts.map +1 -0
  13. package/dist/core/activity-tracker.js +91 -0
  14. package/dist/core/activity-tracker.js.map +1 -0
  15. package/dist/core/ai-commands.d.ts +16 -0
  16. package/dist/core/ai-commands.d.ts.map +1 -0
  17. package/dist/core/ai-commands.js +24 -0
  18. package/dist/core/ai-commands.js.map +1 -0
  19. package/dist/core/ai-sdk-patch.d.ts +24 -0
  20. package/dist/core/ai-sdk-patch.d.ts.map +1 -0
  21. package/dist/core/ai-sdk-patch.js +169 -0
  22. package/dist/core/ai-sdk-patch.js.map +1 -0
  23. package/dist/core/anthropic-direct.d.ts +52 -0
  24. package/dist/core/anthropic-direct.d.ts.map +1 -0
  25. package/dist/core/anthropic-direct.js +301 -0
  26. package/dist/core/anthropic-direct.js.map +1 -0
  27. package/dist/core/approval-cache.d.ts +104 -0
  28. package/dist/core/approval-cache.d.ts.map +1 -0
  29. package/dist/core/approval-cache.js +150 -0
  30. package/dist/core/approval-cache.js.map +1 -0
  31. package/dist/core/chat-constants.d.ts +20 -0
  32. package/dist/core/chat-constants.d.ts.map +1 -0
  33. package/dist/core/chat-constants.js +22 -0
  34. package/dist/core/chat-constants.js.map +1 -0
  35. package/dist/core/create-agent-tool.d.ts +66 -0
  36. package/dist/core/create-agent-tool.d.ts.map +1 -0
  37. package/dist/core/create-agent-tool.js +212 -0
  38. package/dist/core/create-agent-tool.js.map +1 -0
  39. package/dist/core/events/approval-checker.d.ts +61 -0
  40. package/dist/core/events/approval-checker.d.ts.map +1 -0
  41. package/dist/core/events/approval-checker.js +226 -0
  42. package/dist/core/events/approval-checker.js.map +1 -0
  43. package/dist/core/events/index.d.ts +25 -0
  44. package/dist/core/events/index.d.ts.map +1 -0
  45. package/dist/core/events/index.js +30 -0
  46. package/dist/core/events/index.js.map +1 -0
  47. package/dist/core/events/memory-manager.d.ts +73 -0
  48. package/dist/core/events/memory-manager.d.ts.map +1 -0
  49. package/dist/core/events/memory-manager.js +1218 -0
  50. package/dist/core/events/memory-manager.js.map +1 -0
  51. package/dist/core/events/mention-logic.d.ts +39 -0
  52. package/dist/core/events/mention-logic.d.ts.map +1 -0
  53. package/dist/core/events/mention-logic.js +163 -0
  54. package/dist/core/events/mention-logic.js.map +1 -0
  55. package/dist/core/events/orchestrator.d.ts +69 -0
  56. package/dist/core/events/orchestrator.d.ts.map +1 -0
  57. package/dist/core/events/orchestrator.js +883 -0
  58. package/dist/core/events/orchestrator.js.map +1 -0
  59. package/dist/core/events/persistence.d.ts +41 -0
  60. package/dist/core/events/persistence.d.ts.map +1 -0
  61. package/dist/core/events/persistence.js +296 -0
  62. package/dist/core/events/persistence.js.map +1 -0
  63. package/dist/core/events/publishers.d.ts +81 -0
  64. package/dist/core/events/publishers.d.ts.map +1 -0
  65. package/dist/core/events/publishers.js +272 -0
  66. package/dist/core/events/publishers.js.map +1 -0
  67. package/dist/core/events/subscribers.d.ts +45 -0
  68. package/dist/core/events/subscribers.d.ts.map +1 -0
  69. package/dist/core/events/subscribers.js +288 -0
  70. package/dist/core/events/subscribers.js.map +1 -0
  71. package/dist/core/events/tool-bridge-logging.d.ts +28 -0
  72. package/dist/core/events/tool-bridge-logging.d.ts.map +1 -0
  73. package/dist/core/events/tool-bridge-logging.js +94 -0
  74. package/dist/core/events/tool-bridge-logging.js.map +1 -0
  75. package/dist/core/events-metadata.d.ts +72 -0
  76. package/dist/core/events-metadata.d.ts.map +1 -0
  77. package/dist/core/events-metadata.js +167 -0
  78. package/dist/core/events-metadata.js.map +1 -0
  79. package/dist/core/events.d.ts +186 -0
  80. package/dist/core/events.d.ts.map +1 -0
  81. package/dist/core/events.js +1248 -0
  82. package/dist/core/events.js.map +1 -0
  83. package/dist/core/export.d.ts +106 -0
  84. package/dist/core/export.d.ts.map +1 -0
  85. package/dist/core/export.js +705 -0
  86. package/dist/core/export.js.map +1 -0
  87. package/dist/core/file-tools.d.ts +114 -0
  88. package/dist/core/file-tools.d.ts.map +1 -0
  89. package/dist/core/file-tools.js +370 -0
  90. package/dist/core/file-tools.js.map +1 -0
  91. package/dist/core/google-direct.d.ts +58 -0
  92. package/dist/core/google-direct.d.ts.map +1 -0
  93. package/dist/core/google-direct.js +298 -0
  94. package/dist/core/google-direct.js.map +1 -0
  95. package/dist/core/hitl.d.ts +54 -0
  96. package/dist/core/hitl.d.ts.map +1 -0
  97. package/dist/core/hitl.js +153 -0
  98. package/dist/core/hitl.js.map +1 -0
  99. package/dist/core/index.d.ts +59 -0
  100. package/dist/core/index.d.ts.map +1 -0
  101. package/dist/core/index.js +70 -0
  102. package/dist/core/index.js.map +1 -0
  103. package/dist/core/llm-config.d.ts +128 -0
  104. package/dist/core/llm-config.d.ts.map +1 -0
  105. package/dist/core/llm-config.js +164 -0
  106. package/dist/core/llm-config.js.map +1 -0
  107. package/dist/core/llm-manager.d.ts +163 -0
  108. package/dist/core/llm-manager.d.ts.map +1 -0
  109. package/dist/core/llm-manager.js +669 -0
  110. package/dist/core/llm-manager.js.map +1 -0
  111. package/dist/core/load-skill-tool.d.ts +55 -0
  112. package/dist/core/load-skill-tool.d.ts.map +1 -0
  113. package/dist/core/load-skill-tool.js +468 -0
  114. package/dist/core/load-skill-tool.js.map +1 -0
  115. package/dist/core/logger.d.ts +88 -0
  116. package/dist/core/logger.d.ts.map +1 -0
  117. package/dist/core/logger.js +358 -0
  118. package/dist/core/logger.js.map +1 -0
  119. package/dist/core/managers.d.ts +131 -0
  120. package/dist/core/managers.d.ts.map +1 -0
  121. package/dist/core/managers.js +1223 -0
  122. package/dist/core/managers.js.map +1 -0
  123. package/dist/core/mcp-server-registry.d.ts +304 -0
  124. package/dist/core/mcp-server-registry.d.ts.map +1 -0
  125. package/dist/core/mcp-server-registry.js +1769 -0
  126. package/dist/core/mcp-server-registry.js.map +1 -0
  127. package/dist/core/mcp-tools.d.ts +56 -0
  128. package/dist/core/mcp-tools.d.ts.map +1 -0
  129. package/dist/core/mcp-tools.js +186 -0
  130. package/dist/core/mcp-tools.js.map +1 -0
  131. package/dist/core/message-prep.d.ts +81 -0
  132. package/dist/core/message-prep.d.ts.map +1 -0
  133. package/dist/core/message-prep.js +223 -0
  134. package/dist/core/message-prep.js.map +1 -0
  135. package/dist/core/message-processing-control.d.ts +54 -0
  136. package/dist/core/message-processing-control.d.ts.map +1 -0
  137. package/dist/core/message-processing-control.js +139 -0
  138. package/dist/core/message-processing-control.js.map +1 -0
  139. package/dist/core/openai-direct.d.ts +80 -0
  140. package/dist/core/openai-direct.d.ts.map +1 -0
  141. package/dist/core/openai-direct.js +374 -0
  142. package/dist/core/openai-direct.js.map +1 -0
  143. package/dist/core/shell-cmd-tool.d.ts +235 -0
  144. package/dist/core/shell-cmd-tool.d.ts.map +1 -0
  145. package/dist/core/shell-cmd-tool.js +1157 -0
  146. package/dist/core/shell-cmd-tool.js.map +1 -0
  147. package/dist/core/shell-process-registry.d.ts +88 -0
  148. package/dist/core/shell-process-registry.d.ts.map +1 -0
  149. package/dist/core/shell-process-registry.js +309 -0
  150. package/dist/core/shell-process-registry.js.map +1 -0
  151. package/dist/core/skill-registry.d.ts +75 -0
  152. package/dist/core/skill-registry.d.ts.map +1 -0
  153. package/dist/core/skill-registry.js +369 -0
  154. package/dist/core/skill-registry.js.map +1 -0
  155. package/dist/core/skill-script-runner.d.ts +89 -0
  156. package/dist/core/skill-script-runner.d.ts.map +1 -0
  157. package/dist/core/skill-script-runner.js +274 -0
  158. package/dist/core/skill-script-runner.js.map +1 -0
  159. package/dist/core/skill-selector.d.ts +65 -0
  160. package/dist/core/skill-selector.d.ts.map +1 -0
  161. package/dist/core/skill-selector.js +190 -0
  162. package/dist/core/skill-selector.js.map +1 -0
  163. package/dist/core/skill-settings.d.ts +20 -0
  164. package/dist/core/skill-settings.d.ts.map +1 -0
  165. package/dist/core/skill-settings.js +40 -0
  166. package/dist/core/skill-settings.js.map +1 -0
  167. package/dist/core/storage/agent-storage.d.ts +134 -0
  168. package/dist/core/storage/agent-storage.d.ts.map +1 -0
  169. package/dist/core/storage/agent-storage.js +498 -0
  170. package/dist/core/storage/agent-storage.js.map +1 -0
  171. package/dist/core/storage/eventStorage/fileEventStorage.d.ts +100 -0
  172. package/dist/core/storage/eventStorage/fileEventStorage.d.ts.map +1 -0
  173. package/dist/core/storage/eventStorage/fileEventStorage.js +494 -0
  174. package/dist/core/storage/eventStorage/fileEventStorage.js.map +1 -0
  175. package/dist/core/storage/eventStorage/index.d.ts +31 -0
  176. package/dist/core/storage/eventStorage/index.d.ts.map +1 -0
  177. package/dist/core/storage/eventStorage/index.js +31 -0
  178. package/dist/core/storage/eventStorage/index.js.map +1 -0
  179. package/dist/core/storage/eventStorage/memoryEventStorage.d.ts +87 -0
  180. package/dist/core/storage/eventStorage/memoryEventStorage.d.ts.map +1 -0
  181. package/dist/core/storage/eventStorage/memoryEventStorage.js +244 -0
  182. package/dist/core/storage/eventStorage/memoryEventStorage.js.map +1 -0
  183. package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts +45 -0
  184. package/dist/core/storage/eventStorage/sqliteEventStorage.d.ts.map +1 -0
  185. package/dist/core/storage/eventStorage/sqliteEventStorage.js +301 -0
  186. package/dist/core/storage/eventStorage/sqliteEventStorage.js.map +1 -0
  187. package/dist/core/storage/eventStorage/types.d.ts +142 -0
  188. package/dist/core/storage/eventStorage/types.d.ts.map +1 -0
  189. package/dist/core/storage/eventStorage/types.js +43 -0
  190. package/dist/core/storage/eventStorage/types.js.map +1 -0
  191. package/dist/core/storage/eventStorage/validation.d.ts +30 -0
  192. package/dist/core/storage/eventStorage/validation.d.ts.map +1 -0
  193. package/dist/core/storage/eventStorage/validation.js +68 -0
  194. package/dist/core/storage/eventStorage/validation.js.map +1 -0
  195. package/dist/core/storage/legacy-migrations.d.ts +45 -0
  196. package/dist/core/storage/legacy-migrations.d.ts.map +1 -0
  197. package/dist/core/storage/legacy-migrations.js +295 -0
  198. package/dist/core/storage/legacy-migrations.js.map +1 -0
  199. package/dist/core/storage/memory-storage.d.ts +105 -0
  200. package/dist/core/storage/memory-storage.d.ts.map +1 -0
  201. package/dist/core/storage/memory-storage.js +415 -0
  202. package/dist/core/storage/memory-storage.js.map +1 -0
  203. package/dist/core/storage/migration-runner.d.ts +96 -0
  204. package/dist/core/storage/migration-runner.d.ts.map +1 -0
  205. package/dist/core/storage/migration-runner.js +306 -0
  206. package/dist/core/storage/migration-runner.js.map +1 -0
  207. package/dist/core/storage/queue-storage.d.ts +147 -0
  208. package/dist/core/storage/queue-storage.d.ts.map +1 -0
  209. package/dist/core/storage/queue-storage.js +290 -0
  210. package/dist/core/storage/queue-storage.js.map +1 -0
  211. package/dist/core/storage/skill-storage.d.ts +136 -0
  212. package/dist/core/storage/skill-storage.d.ts.map +1 -0
  213. package/dist/core/storage/skill-storage.js +474 -0
  214. package/dist/core/storage/skill-storage.js.map +1 -0
  215. package/dist/core/storage/sqlite-schema.d.ts +95 -0
  216. package/dist/core/storage/sqlite-schema.d.ts.map +1 -0
  217. package/dist/core/storage/sqlite-schema.js +156 -0
  218. package/dist/core/storage/sqlite-schema.js.map +1 -0
  219. package/dist/core/storage/sqlite-storage.d.ts +146 -0
  220. package/dist/core/storage/sqlite-storage.d.ts.map +1 -0
  221. package/dist/core/storage/sqlite-storage.js +709 -0
  222. package/dist/core/storage/sqlite-storage.js.map +1 -0
  223. package/dist/core/storage/storage-factory.d.ts +61 -0
  224. package/dist/core/storage/storage-factory.d.ts.map +1 -0
  225. package/dist/core/storage/storage-factory.js +794 -0
  226. package/dist/core/storage/storage-factory.js.map +1 -0
  227. package/dist/core/storage/validation.d.ts +36 -0
  228. package/dist/core/storage/validation.d.ts.map +1 -0
  229. package/dist/core/storage/validation.js +79 -0
  230. package/dist/core/storage/validation.js.map +1 -0
  231. package/dist/core/storage/world-storage.d.ts +114 -0
  232. package/dist/core/storage/world-storage.d.ts.map +1 -0
  233. package/dist/core/storage/world-storage.js +378 -0
  234. package/dist/core/storage/world-storage.js.map +1 -0
  235. package/dist/core/subscription.d.ts +43 -0
  236. package/dist/core/subscription.d.ts.map +1 -0
  237. package/dist/core/subscription.js +227 -0
  238. package/dist/core/subscription.js.map +1 -0
  239. package/dist/core/tool-utils.d.ts +80 -0
  240. package/dist/core/tool-utils.d.ts.map +1 -0
  241. package/dist/core/tool-utils.js +273 -0
  242. package/dist/core/tool-utils.js.map +1 -0
  243. package/dist/core/types.d.ts +595 -0
  244. package/dist/core/types.d.ts.map +1 -0
  245. package/dist/core/types.js +158 -0
  246. package/dist/core/types.js.map +1 -0
  247. package/dist/core/utils.d.ts +138 -0
  248. package/dist/core/utils.d.ts.map +1 -0
  249. package/dist/core/utils.js +478 -0
  250. package/dist/core/utils.js.map +1 -0
  251. package/dist/core/world-class.d.ts +43 -0
  252. package/dist/core/world-class.d.ts.map +1 -0
  253. package/dist/core/world-class.js +90 -0
  254. package/dist/core/world-class.js.map +1 -0
  255. package/dist/index.d.ts +18 -0
  256. package/dist/public/assets/agent-sprites-DJFgj-zP.png +0 -0
  257. package/dist/public/assets/border-KHK37r8y.svg +83 -0
  258. package/dist/public/assets/index-C9kPXL6G.css +1 -0
  259. package/dist/public/assets/index-DOQEHGWt.js +96 -0
  260. package/dist/public/index.html +21 -0
  261. package/dist/server/api.d.ts +2 -0
  262. package/dist/server/api.js +1124 -0
  263. package/dist/server/index.d.ts +29 -0
  264. package/dist/server/sse-handler.d.ts +62 -0
  265. package/dist/server/sse-handler.js +234 -0
  266. package/package.json +15 -3
  267. package/scripts/launch-electron.js +0 -58
@@ -0,0 +1,222 @@
1
+ /**
2
+ * CLI Streaming Module - Real-time Agent Response Display
3
+ *
4
+ * Manages streaming display for CLI interface with real-time chunk accumulation,
5
+ * visual feedback, and comprehensive event processing.
6
+ *
7
+ * FEATURES:
8
+ * - Real-time streaming with visual feedback and state tracking
9
+ * - Comprehensive event processing (chunk, end, error)
10
+ * - Tool streaming output display for shell_cmd (stdout/stderr)
11
+ * - Color-coded streaming indicators and status messages
12
+ * - Enhanced tool display with Unicode icons and formatted names
13
+ * - Tool output truncation at 50K characters
14
+ * - Modular design for reuse across CLI components
15
+ * - Event-driven display (no timer dependencies)
16
+ * CHANGES:
17
+ * - 2026-02-11: Enhanced tool display with icons, formatted names, stderr prefix, 50K truncation
18
+ * - 2026-02-08: Added tool streaming support for shell_cmd real-time output display
19
+ * - 2025-02-06: Track last streamed message to prevent duplicate MESSAGE events after streaming output
20
+ */
21
+ import { formatToolName, getToolIcon, formatElapsed, } from './display.js';
22
+ // Color helpers
23
+ const gray = (text) => `\x1b[90m${text}\x1b[0m`;
24
+ const boldGreen = (text) => `\x1b[1m\x1b[32m${text}\x1b[0m`;
25
+ const cyan = (text) => `\x1b[36m${text}\x1b[0m`;
26
+ const yellow = (text) => `\x1b[33m${text}\x1b[0m`;
27
+ const green = (text) => `\x1b[32m${text}\x1b[0m`;
28
+ const red = (text) => `\x1b[31m${text}\x1b[0m`;
29
+ const error = (text) => `\x1b[1m\x1b[31m✗\x1b[0m ${text}`;
30
+ export function createStreamingState() {
31
+ return {
32
+ isActive: false,
33
+ content: '',
34
+ sender: undefined,
35
+ messageId: undefined,
36
+ lastStreamedMessageId: undefined,
37
+ lastStreamedContent: undefined,
38
+ lastStreamedSender: undefined,
39
+ lastStreamedAt: undefined
40
+ };
41
+ }
42
+ // Streaming event handlers
43
+ export function handleStreamingEvents(eventData, streaming, statusLine) {
44
+ // Handle tool streaming events first
45
+ if (eventData.type === 'tool-stream') {
46
+ handleToolStreamEvents(eventData);
47
+ return;
48
+ }
49
+ // Handle chunk events
50
+ if (eventData.type === 'chunk' && eventData.content) {
51
+ if (!streaming.isActive) {
52
+ streaming.isActive = true;
53
+ streaming.content = '';
54
+ streaming.sender = eventData.agentName || eventData.sender;
55
+ streaming.messageId = eventData.messageId; // Set new messageId for this stream
56
+ // Stop spinner — streaming content replaces the spinner
57
+ statusLine?.setSpinner(null);
58
+ statusLine?.pause();
59
+ process.stdout.write(`\n${boldGreen(`● ${streaming.sender}`)} ${gray('is responding...')}`);
60
+ }
61
+ if (streaming.messageId === eventData.messageId) {
62
+ // Clear the "is responding..." line on first content
63
+ if (streaming.content === '') {
64
+ // Move cursor to beginning of line and clear it
65
+ process.stdout.write('\r\x1b[K');
66
+ process.stdout.write(`${boldGreen(`● ${streaming.sender}:`)} `);
67
+ }
68
+ streaming.content += eventData.content;
69
+ process.stdout.write(eventData.content);
70
+ }
71
+ return;
72
+ }
73
+ // Handle end events - finish streaming but keep messageId to prevent duplicate display
74
+ if (eventData.type === 'end') {
75
+ if (streaming.isActive && streaming.messageId === eventData.messageId) {
76
+ streaming.lastStreamedMessageId = streaming.messageId;
77
+ streaming.lastStreamedContent = streaming.content;
78
+ streaming.lastStreamedSender = streaming.sender;
79
+ streaming.lastStreamedAt = Date.now();
80
+ process.stdout.write('\n\n'); // End the streaming line with extra newline for spacing
81
+ streaming.isActive = false;
82
+ streaming.content = '';
83
+ streaming.sender = undefined;
84
+ // Keep messageId temporarily to prevent duplicate display of the final message event
85
+ // Resume status line after streaming ends
86
+ statusLine?.resume();
87
+ }
88
+ return;
89
+ }
90
+ // Handle error events
91
+ if (eventData.type === 'error') {
92
+ if (streaming.isActive && streaming.messageId === eventData.messageId) {
93
+ const errorMsg = eventData.error || 'Unknown error';
94
+ process.stdout.write(`\n${error(`Error: ${errorMsg}`)}\n`);
95
+ streaming.isActive = false;
96
+ streaming.content = '';
97
+ streaming.sender = undefined;
98
+ // Keep messageId temporarily to prevent duplicate display
99
+ // Resume status line after error
100
+ statusLine?.resume();
101
+ }
102
+ return;
103
+ }
104
+ }
105
+ // PHASE 2.2 ENHANCEMENT: Handle tool execution events (from world channel)
106
+ export function handleToolEvents(eventData) {
107
+ if (eventData.type === 'tool-start' && eventData.toolExecution) {
108
+ // Tool start events are now implicit — status line handles the indicator
109
+ resetToolStreamTracking();
110
+ return;
111
+ }
112
+ if (eventData.type === 'tool-progress' && eventData.toolExecution) {
113
+ const toolName = eventData.toolExecution.toolName;
114
+ const icon = getToolIcon(toolName);
115
+ const displayName = formatToolName(toolName);
116
+ const agentName = eventData.agentName || eventData.sender || 'agent';
117
+ console.log(`${cyan(agentName)} ${gray('continuing tool')} ${icon} ${yellow(displayName)} ${gray('...')}`);
118
+ return;
119
+ }
120
+ if (eventData.type === 'tool-result' && eventData.toolExecution) {
121
+ const { toolName, duration, resultSize } = eventData.toolExecution;
122
+ const icon = getToolIcon(toolName);
123
+ const displayName = formatToolName(toolName);
124
+ const durationText = duration ? formatElapsed(duration) : 'done';
125
+ const sizeText = resultSize ? `, ${resultSize} chars` : '';
126
+ const agentName = eventData.agentName || eventData.sender || 'agent';
127
+ console.log(`${cyan(agentName)} ${green('\u2713')} ${icon} ${yellow(displayName)} ${gray(`(${durationText}${sizeText})`)}`);
128
+ return;
129
+ }
130
+ if (eventData.type === 'tool-error' && eventData.toolExecution) {
131
+ const { toolName, error: toolError } = eventData.toolExecution;
132
+ const icon = getToolIcon(toolName);
133
+ const displayName = formatToolName(toolName);
134
+ const agentName = eventData.agentName || eventData.sender || 'agent';
135
+ console.log(`${error(`${agentName} ${icon} ${displayName} failed: ${toolError}`)}`);
136
+ return;
137
+ }
138
+ }
139
+ // Handle tool streaming events (real-time stdout/stderr from shell_cmd)
140
+ // Note: Module-level counters track a single tool execution at a time.
141
+ // resetToolStreamTracking() is called on each tool-start, so overlapping
142
+ // concurrent tool streams share (and potentially reset) the same counter.
143
+ const TOOL_STREAM_MAX_CHARS = 50_000;
144
+ let toolStreamCharCount = 0;
145
+ let toolStreamTruncated = false;
146
+ export function handleToolStreamEvents(eventData) {
147
+ if (eventData.type === 'tool-stream' && eventData.toolName === 'shell_cmd') {
148
+ const stream = eventData.stream === 'stderr' ? 'stderr' : 'stdout';
149
+ const prefix = stream === 'stderr' ? red('[stderr] ') : gray('[stdout] ');
150
+ const content = eventData.content;
151
+ // Track cumulative output and truncate if over limit
152
+ if (toolStreamTruncated)
153
+ return;
154
+ toolStreamCharCount += content.length;
155
+ if (toolStreamCharCount > TOOL_STREAM_MAX_CHARS) {
156
+ toolStreamTruncated = true;
157
+ process.stdout.write(`\n${yellow('[output truncated at 50K characters]')}\n`);
158
+ return;
159
+ }
160
+ process.stdout.write(`${prefix}${content}`);
161
+ return;
162
+ }
163
+ }
164
+ /** Reset tool stream tracking (call on tool-start or new tool execution). */
165
+ export function resetToolStreamTracking() {
166
+ toolStreamCharCount = 0;
167
+ toolStreamTruncated = false;
168
+ }
169
+ // Handle world activity events (processing/idle states)
170
+ // Note: In interactive mode with status line, these are largely replaced by
171
+ // the status line manager. This function is kept for pipeline/debug scenarios.
172
+ export function handleActivityEvents(eventData) {
173
+ // Check for valid event types
174
+ if (!eventData || (eventData.type !== 'response-start' && eventData.type !== 'response-end' && eventData.type !== 'idle')) {
175
+ return;
176
+ }
177
+ const source = eventData.source || '';
178
+ const pending = eventData.pendingOperations || 0;
179
+ const activityId = eventData.activityId || 0;
180
+ const activeSources = eventData.activeSources || [];
181
+ const sourceName = source.startsWith('agent:') ? source.slice('agent:'.length) : source;
182
+ // Debug-level activity logging — only outputs in debug/verbose scenarios.
183
+ // In interactive mode, the status line manager handles all visual feedback.
184
+ if (eventData.type === 'response-start') {
185
+ const message = sourceName ? `${sourceName} started` : 'started';
186
+ // Use stderr to avoid corrupting piped output in pipeline mode
187
+ process.stderr.write(`${gray('[World]')} ${message} ${gray(`| pending: ${pending} | id: ${activityId}`)}\n`);
188
+ }
189
+ else if (eventData.type === 'idle' && pending === 0) {
190
+ process.stderr.write(`${gray('[World]')} All complete ${gray(`| id: ${activityId}`)}\n`);
191
+ }
192
+ else if (eventData.type === 'response-end' && pending > 0 && activeSources.length > 0) {
193
+ const activeList = activeSources.map((s) => s.startsWith('agent:') ? s.slice('agent:'.length) : s).join(', ');
194
+ process.stderr.write(`${gray('[World]')} Active: ${activeList} ${gray(`(${pending} pending)`)}\n`);
195
+ }
196
+ }
197
+ export function handleWorldEventWithStreaming(eventType, eventData, streaming, statusLine) {
198
+ // Skip user messages to prevent echo
199
+ if (eventData.sender && (eventData.sender === 'human' || eventData.sender.startsWith('user'))) {
200
+ return false;
201
+ }
202
+ // Handle streaming events
203
+ if (eventType === 'sse') {
204
+ handleStreamingEvents(eventData, streaming, statusLine);
205
+ return true;
206
+ }
207
+ return false;
208
+ }
209
+ // Utility functions
210
+ export function resetStreamingState(streaming) {
211
+ streaming.isActive = false;
212
+ streaming.content = '';
213
+ streaming.sender = undefined;
214
+ streaming.messageId = undefined;
215
+ streaming.lastStreamedMessageId = undefined;
216
+ streaming.lastStreamedContent = undefined;
217
+ streaming.lastStreamedSender = undefined;
218
+ streaming.lastStreamedAt = undefined;
219
+ }
220
+ export function isStreamingActive(streaming) {
221
+ return streaming.isActive;
222
+ }
@@ -0,0 +1,16 @@
1
+ import { World } from './types.js';
2
+ import { getLLMQueueStatus } from './llm-manager.js';
3
+ export type WorldActivityEventType = 'response-start' | 'response-end' | 'idle';
4
+ export interface WorldActivityEventPayload {
5
+ type: WorldActivityEventType;
6
+ pendingOperations: number;
7
+ activityId: number;
8
+ timestamp: string;
9
+ source?: string;
10
+ activeSources: string[];
11
+ queue: ReturnType<typeof getLLMQueueStatus>;
12
+ messageId: string;
13
+ }
14
+ export declare function beginWorldActivity(world: World, source?: string): () => void;
15
+ export declare function trackWorldActivity<T>(world: World, operation: () => Promise<T>, source?: string): Promise<T>;
16
+ //# sourceMappingURL=activity-tracker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-tracker.d.ts","sourceRoot":"","sources":["../../core/activity-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AASrD,MAAM,MAAM,sBAAsB,GAAG,gBAAgB,GAAG,cAAc,GAAG,MAAM,CAAC;AAEhF,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,UAAU,CAAC,OAAO,iBAAiB,CAAC,CAAC;IAC5C,SAAS,EAAE,MAAM,CAAC;CACnB;AA8CD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,IAAI,CA0C5E;AAED,wBAAsB,kBAAkB,CAAC,CAAC,EACxC,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,CAAC,CAcZ"}
@@ -0,0 +1,91 @@
1
+ import { createCategoryLogger } from './logger.js';
2
+ import { getLLMQueueStatus } from './llm-manager.js';
3
+ import { nanoid } from 'nanoid';
4
+ const logger = createCategoryLogger('world.activity');
5
+ const stateKey = Symbol('worldActivityState');
6
+ function getActivityState(world) {
7
+ const existing = world[stateKey];
8
+ if (existing) {
9
+ return existing;
10
+ }
11
+ const initial = {
12
+ pendingOperations: 0,
13
+ lastActivityId: 0,
14
+ activeSources: new Map()
15
+ };
16
+ world[stateKey] = initial;
17
+ return initial;
18
+ }
19
+ function emitActivityEvent(world, type, pendingOperations, activityId, source) {
20
+ const payload = {
21
+ type,
22
+ pendingOperations,
23
+ activityId,
24
+ timestamp: new Date().toISOString(),
25
+ source,
26
+ activeSources: Array.from(getActivityState(world).activeSources.keys()),
27
+ queue: getLLMQueueStatus(),
28
+ messageId: nanoid(10) // Generate unique ID for event persistence
29
+ };
30
+ // Set isProcessing flag: true for response-start/response-end, false only on idle
31
+ world.isProcessing = type !== 'idle';
32
+ // Dual emission pattern: generic 'world' channel + type-specific channel
33
+ world.eventEmitter.emit('world', payload);
34
+ world.eventEmitter.emit(type, payload);
35
+ }
36
+ export function beginWorldActivity(world, source) {
37
+ const activityState = getActivityState(world);
38
+ activityState.pendingOperations += 1;
39
+ if (source) {
40
+ activityState.activeSources.set(source, (activityState.activeSources.get(source) ?? 0) + 1);
41
+ }
42
+ // Increment activityId when starting first operation
43
+ if (activityState.pendingOperations === 1) {
44
+ activityState.lastActivityId += 1;
45
+ }
46
+ // Emit response-start for all operation starts
47
+ emitActivityEvent(world, 'response-start', activityState.pendingOperations, activityState.lastActivityId, source);
48
+ let finished = false;
49
+ const currentActivityId = activityState.lastActivityId;
50
+ return () => {
51
+ if (finished)
52
+ return;
53
+ finished = true;
54
+ const state = getActivityState(world);
55
+ state.pendingOperations = Math.max(0, state.pendingOperations - 1);
56
+ if (source) {
57
+ const currentCount = state.activeSources.get(source) ?? 0;
58
+ if (currentCount <= 1) {
59
+ state.activeSources.delete(source);
60
+ }
61
+ else {
62
+ state.activeSources.set(source, currentCount - 1);
63
+ }
64
+ }
65
+ // Emit idle when all operations complete, otherwise response-end
66
+ if (state.pendingOperations === 0) {
67
+ emitActivityEvent(world, 'idle', 0, currentActivityId, source);
68
+ }
69
+ else {
70
+ emitActivityEvent(world, 'response-end', state.pendingOperations, state.lastActivityId, source);
71
+ }
72
+ };
73
+ }
74
+ export async function trackWorldActivity(world, operation, source) {
75
+ const end = beginWorldActivity(world, source);
76
+ try {
77
+ return await operation();
78
+ }
79
+ catch (error) {
80
+ logger.error('World activity operation failed', {
81
+ worldId: world.id,
82
+ source,
83
+ error: error instanceof Error ? error.message : error
84
+ });
85
+ throw error;
86
+ }
87
+ finally {
88
+ end();
89
+ }
90
+ }
91
+ //# sourceMappingURL=activity-tracker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"activity-tracker.js","sourceRoot":"","sources":["../../core/activity-tracker.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * AI Commands Module
3
+ *
4
+ * This module defines a list of special AI commands that require custom handling.
5
+ * Instead of sending their results back to the LLM, the output is saved
6
+ * directly to agent memory as an assistant message.
7
+ */
8
+ /**
9
+ * Check if a command is a special AI command.
10
+ *
11
+ * @param command - The command string to check (e.g., "gemini", "codex exec 'query'", "ls").
12
+ * Can include arguments - only the first word is checked.
13
+ * @returns True if the command is an AI command, false otherwise.
14
+ */
15
+ export declare function isAICommand(command: string): boolean;
16
+ //# sourceMappingURL=ai-commands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-commands.d.ts","sourceRoot":"","sources":["../../core/ai-commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAMpD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * AI Commands Module
3
+ *
4
+ * This module defines a list of special AI commands that require custom handling.
5
+ * Instead of sending their results back to the LLM, the output is saved
6
+ * directly to agent memory as an assistant message.
7
+ */
8
+ // Hardcoded list of AI commands
9
+ const AI_COMMANDS = new Set(['gemini', 'copilot', 'codex']);
10
+ /**
11
+ * Check if a command is a special AI command.
12
+ *
13
+ * @param command - The command string to check (e.g., "gemini", "codex exec 'query'", "ls").
14
+ * Can include arguments - only the first word is checked.
15
+ * @returns True if the command is an AI command, false otherwise.
16
+ */
17
+ export function isAICommand(command) {
18
+ if (!command)
19
+ return false;
20
+ // Extract first word from command (handles "codex exec 'query'" -> "codex")
21
+ const firstWord = command.trim().split(/\s+/)[0].toLowerCase();
22
+ return AI_COMMANDS.has(firstWord);
23
+ }
24
+ //# sourceMappingURL=ai-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-commands.js","sourceRoot":"","sources":["../../core/ai-commands.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,gCAAgC;AAChC,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,OAAe;IACzC,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAE3B,4EAA4E;IAC5E,MAAM,SAAS,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IAC/D,OAAO,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * AI SDK Runtime Patch - Azure OpenAI Focus
3
+ *
4
+ * This module patches the AI SDK's prepareChatTools function to fix the schema corruption bug
5
+ * where "type": "object" gets corrupted to "type": "None" before reaching Azure OpenAI.
6
+ *
7
+ * Bug Location: @ai-sdk/openai/dist/internal/index.js - prepareChatTools function line 471
8
+ * Issue: parameters: tool.inputSchema directly passes corrupted schemas
9
+ * Azure Usage: Azure imports from '@ai-sdk/openai/internal' and uses prepareChatTools
10
+ *
11
+ * This patch intercepts and fixes the schemas before they reach Azure.
12
+ */
13
+ /**
14
+ * Apply the runtime patch to the AI SDK
15
+ */
16
+ export declare function patchAISDK(): void;
17
+ /**
18
+ * Alternative patching approach - patch at the module level
19
+ */
20
+ export declare function patchAISDKModuleLvel(): void;
21
+ /**
22
+ * Initialize AI SDK patching - try multiple approaches for Azure OpenAI
23
+ */
24
+ export declare function initializeAISDKPatch(): void;
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk-patch.d.ts","sourceRoot":"","sources":["../../core/ai-sdk-patch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AA8HH;;GAEG;AACH,wBAAgB,UAAU,IAAI,IAAI,CAwCjC;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CA6B3C;AAED;;GAEG;AACH,wBAAgB,oBAAoB,IAAI,IAAI,CAU3C"}
@@ -0,0 +1,169 @@
1
+ /**
2
+ * AI SDK Runtime Patch - Azure OpenAI Focus
3
+ *
4
+ * This module patches the AI SDK's prepareChatTools function to fix the schema corruption bug
5
+ * where "type": "object" gets corrupted to "type": "None" before reaching Azure OpenAI.
6
+ *
7
+ * Bug Location: @ai-sdk/openai/dist/internal/index.js - prepareChatTools function line 471
8
+ * Issue: parameters: tool.inputSchema directly passes corrupted schemas
9
+ * Azure Usage: Azure imports from '@ai-sdk/openai/internal' and uses prepareChatTools
10
+ *
11
+ * This patch intercepts and fixes the schemas before they reach Azure.
12
+ */
13
+ import { logger } from './logger.js';
14
+ /**
15
+ * Fix corrupted tool schemas
16
+ */
17
+ function fixToolSchema(schema) {
18
+ if (!schema || typeof schema !== 'object') {
19
+ return schema;
20
+ }
21
+ // Deep clone to avoid mutating original
22
+ const fixed = JSON.parse(JSON.stringify(schema));
23
+ // Fix the primary bug: "type": "None" -> "type": "object"
24
+ if (fixed.type === 'None' || fixed.type === undefined || fixed.type === null) {
25
+ fixed.type = 'object';
26
+ logger.warn('🔧 AI SDK Patch: Fixed corrupted schema type', {
27
+ original: schema.type,
28
+ fixed: 'object'
29
+ });
30
+ }
31
+ // Ensure object schemas have proper structure
32
+ if (fixed.type === 'object') {
33
+ if (!fixed.properties) {
34
+ fixed.properties = {};
35
+ }
36
+ if (fixed.additionalProperties === undefined) {
37
+ fixed.additionalProperties = false;
38
+ }
39
+ }
40
+ // Recursively fix nested schemas
41
+ if (fixed.properties) {
42
+ Object.keys(fixed.properties).forEach(key => {
43
+ fixed.properties[key] = fixToolSchema(fixed.properties[key]);
44
+ });
45
+ }
46
+ if (fixed.items) {
47
+ fixed.items = fixToolSchema(fixed.items);
48
+ }
49
+ if (Array.isArray(fixed.anyOf)) {
50
+ fixed.anyOf = fixed.anyOf.map(fixToolSchema);
51
+ }
52
+ if (Array.isArray(fixed.allOf)) {
53
+ fixed.allOf = fixed.allOf.map(fixToolSchema);
54
+ }
55
+ return fixed;
56
+ }
57
+ /**
58
+ * Patched version of prepareChatTools that fixes schema corruption
59
+ */
60
+ function patchedPrepareChatTools(originalFunction) {
61
+ return function (...args) {
62
+ // Call the original function first
63
+ const result = originalFunction.apply(this, args);
64
+ // Fix any corrupted schemas in the result
65
+ if (result?.tools && Array.isArray(result.tools)) {
66
+ let patchCount = 0;
67
+ result.tools = result.tools.map((tool) => {
68
+ if (tool.type === 'function' && tool.function?.parameters) {
69
+ const originalSchema = tool.function.parameters;
70
+ const fixedSchema = fixToolSchema(originalSchema);
71
+ // Check if we actually fixed something
72
+ if (JSON.stringify(originalSchema) !== JSON.stringify(fixedSchema)) {
73
+ patchCount++;
74
+ logger.info('🔧 AI SDK Patch: Fixed tool schema', {
75
+ toolName: tool.function.name,
76
+ originalType: originalSchema.type,
77
+ fixedType: fixedSchema.type
78
+ });
79
+ }
80
+ return {
81
+ ...tool,
82
+ function: {
83
+ ...tool.function,
84
+ parameters: fixedSchema
85
+ }
86
+ };
87
+ }
88
+ return tool;
89
+ });
90
+ if (patchCount > 0) {
91
+ logger.info(`🔧 AI SDK Patch: Fixed ${patchCount} corrupted tool schemas`);
92
+ }
93
+ }
94
+ return result;
95
+ };
96
+ }
97
+ /**
98
+ * Apply the runtime patch to the AI SDK
99
+ */
100
+ export function patchAISDK() {
101
+ try {
102
+ logger.info('🔧 AI SDK Patch: Attempting to patch @ai-sdk/openai/internal...');
103
+ // Patch the OpenAI internal module that Azure uses
104
+ const openaiInternalModule = require('@ai-sdk/openai/internal');
105
+ logger.info('🔧 AI SDK Patch: OpenAI internal module loaded', {
106
+ hasPrepareChatTools: !!openaiInternalModule?.prepareChatTools
107
+ });
108
+ if (openaiInternalModule && openaiInternalModule.prepareChatTools) {
109
+ const originalFunction = openaiInternalModule.prepareChatTools;
110
+ openaiInternalModule.prepareChatTools = patchedPrepareChatTools(originalFunction);
111
+ logger.info('✅ AI SDK Patch: Successfully patched OpenAI internal prepareChatTools function (used by Azure)');
112
+ return;
113
+ }
114
+ logger.warn('⚠️ AI SDK Patch: OpenAI internal module found but no prepareChatTools function');
115
+ // Fallback: try to patch through the main AI SDK
116
+ logger.info('🔧 AI SDK Patch: Trying fallback approach through main ai module...');
117
+ const aiModule = require('ai');
118
+ // Look for internal OpenAI functions
119
+ if (aiModule?.internal?.openai?.prepareChatTools) {
120
+ const originalFunction = aiModule.internal.openai.prepareChatTools;
121
+ aiModule.internal.openai.prepareChatTools = patchedPrepareChatTools(originalFunction);
122
+ logger.info('✅ AI SDK Patch: Successfully patched prepareChatTools via ai module');
123
+ return;
124
+ }
125
+ logger.warn('⚠️ AI SDK Patch: Could not locate prepareChatTools function to patch');
126
+ }
127
+ catch (error) {
128
+ logger.warn('⚠️ AI SDK Patch: Failed to apply runtime patch', {
129
+ error: error instanceof Error ? error.message : String(error)
130
+ });
131
+ }
132
+ }
133
+ /**
134
+ * Alternative patching approach - patch at the module level
135
+ */
136
+ export function patchAISDKModuleLvel() {
137
+ try {
138
+ // Get the module cache
139
+ const moduleCache = require.cache;
140
+ // Find the OpenAI internal prepareChatTools module that Azure uses
141
+ const openaiInternalPath = Object.keys(moduleCache).find(path => path.includes('@ai-sdk/openai') && (path.includes('internal') || path.includes('prepare-tools')));
142
+ if (openaiInternalPath && moduleCache[openaiInternalPath]) {
143
+ const module = moduleCache[openaiInternalPath];
144
+ if (module.exports && module.exports.prepareChatTools) {
145
+ const originalFunction = module.exports.prepareChatTools;
146
+ module.exports.prepareChatTools = patchedPrepareChatTools(originalFunction);
147
+ logger.info('✅ AI SDK Patch: Successfully patched at module cache level (OpenAI internal for Azure)');
148
+ return;
149
+ }
150
+ }
151
+ logger.warn('⚠️ AI SDK Patch: Could not locate OpenAI internal module in cache for patching');
152
+ }
153
+ catch (error) {
154
+ logger.warn('⚠️ AI SDK Patch: Module-level patching failed', {
155
+ error: error instanceof Error ? error.message : String(error)
156
+ });
157
+ }
158
+ }
159
+ /**
160
+ * Initialize AI SDK patching - try multiple approaches for Azure OpenAI
161
+ */
162
+ export function initializeAISDKPatch() {
163
+ logger.info('🔧 AI SDK Patch: Initializing runtime schema corruption fix for Azure OpenAI...');
164
+ // Try direct function patching first
165
+ patchAISDK();
166
+ // Try module-level patching as fallback
167
+ patchAISDKModuleLvel();
168
+ logger.info('🔧 AI SDK Patch: Initialization complete (Azure OpenAI ready)');
169
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-sdk-patch.js","sourceRoot":"","sources":["../../core/ai-sdk-patch.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Anthropic Direct Integration Module - Pure Client (LLM Provider Refactoring Phase 3)
3
+ *
4
+ * Features:
5
+ * - Direct Anthropic API integration bypassing AI SDK tool calling issues
6
+ * - Streaming and non-streaming responses returning LLMResponse
7
+ * - Function/tool calling detection (NO execution)
8
+ * - Proper error handling and retry logic
9
+ * - Browser-safe configuration injection
10
+ * - Pure client: only calls APIs and returns structured data
11
+ *
12
+ * Implementation Details:
13
+ * - Uses official @anthropic-ai/sdk package for reliable API access
14
+ * - Converts AI SDK message format to Anthropic format
15
+ * - Returns LLMResponse with type='text' or type='tool_calls'
16
+ * - Streaming support with chunk-by-chunk processing via onChunk callback
17
+ * - Error handling with descriptive messages
18
+ * - Configuration injection from llm-config module
19
+ * - NO event emission, NO storage, NO tool execution
20
+ *
21
+ * Recent Changes:
22
+ * - 2026-02-13: Added abort-signal support for streaming and non-streaming calls to enable chat stop cancellation.
23
+ * - 2025-11-09: Phase 3 - Removed ALL tool execution logic (~200 lines)
24
+ * - Provider is now a pure client - only API calls and data transformation
25
+ * - Returns LLMResponse interface with type discriminator
26
+ * - Filters invalid tool calls (empty/missing names) and logs warnings
27
+ * - Includes usage tracking (input_tokens, output_tokens) for non-streaming
28
+ * - 2025-11-08: Removed ALL event emission from provider
29
+ * - Streaming uses onChunk callback instead of direct SSE emission
30
+ */
31
+ import Anthropic from '@anthropic-ai/sdk';
32
+ import { World, Agent, ChatMessage, LLMResponse } from './types.js';
33
+ import { AnthropicConfig } from './llm-config.js';
34
+ /**
35
+ * Anthropic client factory
36
+ */
37
+ export declare function createAnthropicClient(config: AnthropicConfig): Anthropic;
38
+ /**
39
+ * Streaming Anthropic response handler - Pure client (no tool execution)
40
+ * Returns LLMResponse with type='text' or type='tool_calls'
41
+ */
42
+ export declare function streamAnthropicResponse(client: Anthropic, model: string, messages: ChatMessage[], agent: Agent, mcpTools: Record<string, any>, world: World, onChunk: (content: string) => void, messageId: string, abortSignal?: AbortSignal): Promise<LLMResponse>;
43
+ /**
44
+ * Non-streaming Anthropic response handler - Pure client (no tool execution)
45
+ * Returns LLMResponse with type='text' or type='tool_calls'
46
+ */
47
+ export declare function generateAnthropicResponse(client: Anthropic, model: string, messages: ChatMessage[], agent: Agent, mcpTools: Record<string, any>, world: World, abortSignal?: AbortSignal): Promise<LLMResponse>;
48
+ /**
49
+ * Factory function to create Anthropic client for agent
50
+ */
51
+ export declare function createAnthropicClientForAgent(agent: Agent): Anthropic;
52
+ //# sourceMappingURL=anthropic-direct.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-direct.d.ts","sourceRoot":"","sources":["../../core/anthropic-direct.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAwB,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAMxE;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,eAAe,GAAG,SAAS,CAIxE;AAyED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,KAAK,EAAE,KAAK,EACZ,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,EAClC,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,WAAW,CAAC,CAqGtB;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAC7C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,WAAW,EAAE,EACvB,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7B,KAAK,EAAE,KAAK,EACZ,WAAW,CAAC,EAAE,WAAW,GACxB,OAAO,CAAC,WAAW,CAAC,CAmGtB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,KAAK,GAAG,SAAS,CAGrE"}