@hybridaione/hybridclaw 0.2.2 → 0.2.6

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 (277) hide show
  1. package/.github/workflows/ci.yml +70 -0
  2. package/.husky/pre-commit +1 -0
  3. package/CHANGELOG.md +85 -0
  4. package/CONTRIBUTING.md +33 -0
  5. package/README.md +41 -16
  6. package/SECURITY.md +17 -0
  7. package/biome.json +35 -0
  8. package/config.example.json +71 -8
  9. package/container/package-lock.json +2 -2
  10. package/container/package.json +1 -1
  11. package/container/src/approval-policy.ts +1303 -0
  12. package/container/src/browser-tools.ts +431 -136
  13. package/container/src/extensions.ts +36 -12
  14. package/container/src/hybridai-client.ts +34 -13
  15. package/container/src/index.ts +451 -109
  16. package/container/src/ipc.ts +5 -3
  17. package/container/src/token-usage.ts +20 -10
  18. package/container/src/tools.ts +599 -225
  19. package/container/src/types.ts +32 -2
  20. package/container/src/web-fetch.ts +89 -32
  21. package/dist/agent.d.ts.map +1 -1
  22. package/dist/agent.js +10 -2
  23. package/dist/agent.js.map +1 -1
  24. package/dist/audit-cli.d.ts.map +1 -1
  25. package/dist/audit-cli.js +4 -2
  26. package/dist/audit-cli.js.map +1 -1
  27. package/dist/audit-events.d.ts.map +1 -1
  28. package/dist/audit-events.js +53 -3
  29. package/dist/audit-events.js.map +1 -1
  30. package/dist/audit-trail.d.ts.map +1 -1
  31. package/dist/audit-trail.js +17 -8
  32. package/dist/audit-trail.js.map +1 -1
  33. package/dist/channels/discord/attachments.d.ts.map +1 -1
  34. package/dist/channels/discord/attachments.js +14 -7
  35. package/dist/channels/discord/attachments.js.map +1 -1
  36. package/dist/channels/discord/debounce.d.ts +9 -0
  37. package/dist/channels/discord/debounce.d.ts.map +1 -0
  38. package/dist/channels/discord/debounce.js +20 -0
  39. package/dist/channels/discord/debounce.js.map +1 -0
  40. package/dist/channels/discord/delivery.d.ts +4 -1
  41. package/dist/channels/discord/delivery.d.ts.map +1 -1
  42. package/dist/channels/discord/delivery.js +19 -3
  43. package/dist/channels/discord/delivery.js.map +1 -1
  44. package/dist/channels/discord/human-delay.d.ts +16 -0
  45. package/dist/channels/discord/human-delay.d.ts.map +1 -0
  46. package/dist/channels/discord/human-delay.js +29 -0
  47. package/dist/channels/discord/human-delay.js.map +1 -0
  48. package/dist/channels/discord/inbound.d.ts +4 -0
  49. package/dist/channels/discord/inbound.d.ts.map +1 -1
  50. package/dist/channels/discord/inbound.js +45 -4
  51. package/dist/channels/discord/inbound.js.map +1 -1
  52. package/dist/channels/discord/mentions.d.ts.map +1 -1
  53. package/dist/channels/discord/mentions.js +16 -4
  54. package/dist/channels/discord/mentions.js.map +1 -1
  55. package/dist/channels/discord/presence.d.ts +33 -0
  56. package/dist/channels/discord/presence.d.ts.map +1 -0
  57. package/dist/channels/discord/presence.js +111 -0
  58. package/dist/channels/discord/presence.js.map +1 -0
  59. package/dist/channels/discord/rate-limiter.d.ts +14 -0
  60. package/dist/channels/discord/rate-limiter.d.ts.map +1 -0
  61. package/dist/channels/discord/rate-limiter.js +49 -0
  62. package/dist/channels/discord/rate-limiter.js.map +1 -0
  63. package/dist/channels/discord/reactions.d.ts +38 -0
  64. package/dist/channels/discord/reactions.d.ts.map +1 -0
  65. package/dist/channels/discord/reactions.js +151 -0
  66. package/dist/channels/discord/reactions.js.map +1 -0
  67. package/dist/channels/discord/runtime.d.ts +6 -3
  68. package/dist/channels/discord/runtime.d.ts.map +1 -1
  69. package/dist/channels/discord/runtime.js +621 -125
  70. package/dist/channels/discord/runtime.js.map +1 -1
  71. package/dist/channels/discord/stream.d.ts +4 -1
  72. package/dist/channels/discord/stream.d.ts.map +1 -1
  73. package/dist/channels/discord/stream.js +16 -8
  74. package/dist/channels/discord/stream.js.map +1 -1
  75. package/dist/channels/discord/tool-actions.d.ts.map +1 -1
  76. package/dist/channels/discord/tool-actions.js +24 -12
  77. package/dist/channels/discord/tool-actions.js.map +1 -1
  78. package/dist/channels/discord/typing.d.ts +15 -0
  79. package/dist/channels/discord/typing.d.ts.map +1 -0
  80. package/dist/channels/discord/typing.js +106 -0
  81. package/dist/channels/discord/typing.js.map +1 -0
  82. package/dist/chunk.d.ts.map +1 -1
  83. package/dist/chunk.js +4 -2
  84. package/dist/chunk.js.map +1 -1
  85. package/dist/cli.js +47 -22
  86. package/dist/cli.js.map +1 -1
  87. package/dist/config.d.ts +19 -0
  88. package/dist/config.d.ts.map +1 -1
  89. package/dist/config.js +103 -18
  90. package/dist/config.js.map +1 -1
  91. package/dist/container-runner.d.ts.map +1 -1
  92. package/dist/container-runner.js +58 -26
  93. package/dist/container-runner.js.map +1 -1
  94. package/dist/container-setup.d.ts.map +1 -1
  95. package/dist/container-setup.js +10 -9
  96. package/dist/container-setup.js.map +1 -1
  97. package/dist/conversation.d.ts +2 -2
  98. package/dist/conversation.d.ts.map +1 -1
  99. package/dist/conversation.js +1 -1
  100. package/dist/conversation.js.map +1 -1
  101. package/dist/db.d.ts +118 -2
  102. package/dist/db.d.ts.map +1 -1
  103. package/dist/db.js +1568 -50
  104. package/dist/db.js.map +1 -1
  105. package/dist/delegation-manager.d.ts.map +1 -1
  106. package/dist/delegation-manager.js +3 -2
  107. package/dist/delegation-manager.js.map +1 -1
  108. package/dist/gateway-client.d.ts +2 -2
  109. package/dist/gateway-client.d.ts.map +1 -1
  110. package/dist/gateway-client.js +10 -4
  111. package/dist/gateway-client.js.map +1 -1
  112. package/dist/gateway-service.d.ts +3 -3
  113. package/dist/gateway-service.d.ts.map +1 -1
  114. package/dist/gateway-service.js +563 -73
  115. package/dist/gateway-service.js.map +1 -1
  116. package/dist/gateway-types.d.ts +24 -0
  117. package/dist/gateway-types.d.ts.map +1 -1
  118. package/dist/gateway-types.js.map +1 -1
  119. package/dist/gateway.js +179 -24
  120. package/dist/gateway.js.map +1 -1
  121. package/dist/health.d.ts.map +1 -1
  122. package/dist/health.js +20 -10
  123. package/dist/health.js.map +1 -1
  124. package/dist/heartbeat.d.ts +4 -0
  125. package/dist/heartbeat.d.ts.map +1 -1
  126. package/dist/heartbeat.js +48 -20
  127. package/dist/heartbeat.js.map +1 -1
  128. package/dist/hybridai-bots.d.ts.map +1 -1
  129. package/dist/hybridai-bots.js +4 -2
  130. package/dist/hybridai-bots.js.map +1 -1
  131. package/dist/instruction-approval-audit.d.ts.map +1 -1
  132. package/dist/instruction-approval-audit.js.map +1 -1
  133. package/dist/instruction-integrity.d.ts.map +1 -1
  134. package/dist/instruction-integrity.js +8 -2
  135. package/dist/instruction-integrity.js.map +1 -1
  136. package/dist/ipc.d.ts.map +1 -1
  137. package/dist/ipc.js +6 -1
  138. package/dist/ipc.js.map +1 -1
  139. package/dist/logger.js.map +1 -1
  140. package/dist/memory-consolidation.d.ts +17 -0
  141. package/dist/memory-consolidation.d.ts.map +1 -0
  142. package/dist/memory-consolidation.js +25 -0
  143. package/dist/memory-consolidation.js.map +1 -0
  144. package/dist/memory-service.d.ts +200 -0
  145. package/dist/memory-service.d.ts.map +1 -0
  146. package/dist/memory-service.js +294 -0
  147. package/dist/memory-service.js.map +1 -0
  148. package/dist/mount-security.d.ts.map +1 -1
  149. package/dist/mount-security.js +31 -7
  150. package/dist/mount-security.js.map +1 -1
  151. package/dist/observability-ingest.d.ts.map +1 -1
  152. package/dist/observability-ingest.js +32 -11
  153. package/dist/observability-ingest.js.map +1 -1
  154. package/dist/onboarding.d.ts.map +1 -1
  155. package/dist/onboarding.js +32 -9
  156. package/dist/onboarding.js.map +1 -1
  157. package/dist/proactive-policy.d.ts.map +1 -1
  158. package/dist/proactive-policy.js +2 -1
  159. package/dist/proactive-policy.js.map +1 -1
  160. package/dist/prompt-hooks.d.ts.map +1 -1
  161. package/dist/prompt-hooks.js +9 -7
  162. package/dist/prompt-hooks.js.map +1 -1
  163. package/dist/runtime-config.d.ts +98 -1
  164. package/dist/runtime-config.d.ts.map +1 -1
  165. package/dist/runtime-config.js +477 -23
  166. package/dist/runtime-config.js.map +1 -1
  167. package/dist/scheduled-task-runner.d.ts +1 -0
  168. package/dist/scheduled-task-runner.d.ts.map +1 -1
  169. package/dist/scheduled-task-runner.js +29 -10
  170. package/dist/scheduled-task-runner.js.map +1 -1
  171. package/dist/scheduler.d.ts +43 -4
  172. package/dist/scheduler.d.ts.map +1 -1
  173. package/dist/scheduler.js +530 -56
  174. package/dist/scheduler.js.map +1 -1
  175. package/dist/session-export.d.ts +26 -0
  176. package/dist/session-export.d.ts.map +1 -0
  177. package/dist/session-export.js +149 -0
  178. package/dist/session-export.js.map +1 -0
  179. package/dist/session-maintenance.d.ts.map +1 -1
  180. package/dist/session-maintenance.js +75 -13
  181. package/dist/session-maintenance.js.map +1 -1
  182. package/dist/session-transcripts.d.ts.map +1 -1
  183. package/dist/session-transcripts.js.map +1 -1
  184. package/dist/side-effects.d.ts.map +1 -1
  185. package/dist/side-effects.js +14 -2
  186. package/dist/side-effects.js.map +1 -1
  187. package/dist/skills-guard.d.ts.map +1 -1
  188. package/dist/skills-guard.js +893 -130
  189. package/dist/skills-guard.js.map +1 -1
  190. package/dist/skills.d.ts +5 -0
  191. package/dist/skills.d.ts.map +1 -1
  192. package/dist/skills.js +29 -15
  193. package/dist/skills.js.map +1 -1
  194. package/dist/token-efficiency.d.ts.map +1 -1
  195. package/dist/token-efficiency.js.map +1 -1
  196. package/dist/tui.js +92 -11
  197. package/dist/tui.js.map +1 -1
  198. package/dist/types.d.ts +146 -0
  199. package/dist/types.d.ts.map +1 -1
  200. package/dist/types.js +24 -1
  201. package/dist/types.js.map +1 -1
  202. package/dist/update.d.ts.map +1 -1
  203. package/dist/update.js +42 -14
  204. package/dist/update.js.map +1 -1
  205. package/dist/workspace.d.ts.map +1 -1
  206. package/dist/workspace.js +49 -9
  207. package/dist/workspace.js.map +1 -1
  208. package/docs/chat.html +9 -3
  209. package/docs/index.html +37 -13
  210. package/package.json +8 -2
  211. package/src/agent.ts +16 -3
  212. package/src/audit-cli.ts +44 -16
  213. package/src/audit-events.ts +69 -5
  214. package/src/audit-trail.ts +41 -15
  215. package/src/channels/discord/attachments.ts +81 -27
  216. package/src/channels/discord/debounce.ts +25 -0
  217. package/src/channels/discord/delivery.ts +57 -13
  218. package/src/channels/discord/human-delay.ts +48 -0
  219. package/src/channels/discord/inbound.ts +66 -7
  220. package/src/channels/discord/mentions.ts +42 -18
  221. package/src/channels/discord/presence.ts +148 -0
  222. package/src/channels/discord/rate-limiter.ts +58 -0
  223. package/src/channels/discord/reactions.ts +211 -0
  224. package/src/channels/discord/runtime.ts +1048 -182
  225. package/src/channels/discord/stream.ts +73 -27
  226. package/src/channels/discord/tool-actions.ts +78 -37
  227. package/src/channels/discord/typing.ts +140 -0
  228. package/src/chunk.ts +12 -4
  229. package/src/cli.ts +141 -56
  230. package/src/config.ts +192 -34
  231. package/src/container-runner.ts +132 -42
  232. package/src/container-setup.ts +57 -22
  233. package/src/conversation.ts +9 -7
  234. package/src/db.ts +2217 -84
  235. package/src/delegation-manager.ts +6 -2
  236. package/src/gateway-client.ts +41 -17
  237. package/src/gateway-service.ts +1019 -201
  238. package/src/gateway-types.ts +33 -0
  239. package/src/gateway.ts +321 -48
  240. package/src/health.ts +66 -26
  241. package/src/heartbeat.ts +84 -22
  242. package/src/hybridai-bots.ts +14 -5
  243. package/src/instruction-approval-audit.ts +4 -1
  244. package/src/instruction-integrity.ts +30 -9
  245. package/src/ipc.ts +23 -5
  246. package/src/logger.ts +4 -1
  247. package/src/memory-consolidation.ts +41 -0
  248. package/src/memory-service.ts +606 -0
  249. package/src/mount-security.ts +58 -13
  250. package/src/observability-ingest.ts +134 -35
  251. package/src/onboarding.ts +126 -35
  252. package/src/proactive-policy.ts +3 -1
  253. package/src/prompt-hooks.ts +40 -17
  254. package/src/runtime-config.ts +1114 -99
  255. package/src/scheduled-task-runner.ts +63 -11
  256. package/src/scheduler.ts +683 -60
  257. package/src/session-export.ts +196 -0
  258. package/src/session-maintenance.ts +125 -22
  259. package/src/session-transcripts.ts +12 -3
  260. package/src/side-effects.ts +28 -5
  261. package/src/skills-guard.ts +1067 -219
  262. package/src/skills.ts +163 -65
  263. package/src/token-efficiency.ts +31 -9
  264. package/src/tui.ts +166 -25
  265. package/src/types.ts +195 -2
  266. package/src/update.ts +79 -23
  267. package/src/workspace.ts +63 -11
  268. package/tests/approval-policy.test.ts +224 -0
  269. package/tests/discord.basic.test.ts +82 -2
  270. package/tests/discord.human-presence.test.ts +85 -0
  271. package/tests/gateway-service.media-routing.test.ts +8 -2
  272. package/tests/memory-service.test.ts +1114 -0
  273. package/tests/token-efficiency.basic.test.ts +8 -2
  274. package/vitest.e2e.config.ts +3 -1
  275. package/vitest.integration.config.ts +3 -1
  276. package/vitest.live.config.ts +3 -1
  277. package/vitest.unit.config.ts +9 -0
@@ -16,14 +16,22 @@ interface RuntimeEventPayload {
16
16
  interface RuntimeExtension {
17
17
  name: string;
18
18
  onEvent?: (payload: RuntimeEventPayload) => void | Promise<void>;
19
- onBeforeToolCall?: (toolName: string, args: Record<string, unknown>) => string | null | Promise<string | null>;
20
- onAfterToolCall?: (toolName: string, args: Record<string, unknown>, result: string) => void | Promise<void>;
19
+ onBeforeToolCall?: (
20
+ toolName: string,
21
+ args: Record<string, unknown>,
22
+ ) => string | null | Promise<string | null>;
23
+ onAfterToolCall?: (
24
+ toolName: string,
25
+ args: Record<string, unknown>,
26
+ result: string,
27
+ ) => void | Promise<void>;
21
28
  }
22
29
 
23
30
  const DANGEROUS_FILE_CONTENT_PATTERNS: Array<{ re: RegExp; reason: string }> = [
24
31
  {
25
32
  re: /\brm\s+-rf\s+\/(\s|$)/i,
26
- reason: 'Detected destructive root delete pattern (`rm -rf /`) in file content.',
33
+ reason:
34
+ 'Detected destructive root delete pattern (`rm -rf /`) in file content.',
27
35
  },
28
36
  {
29
37
  re: /:\(\)\s*\{.*\};\s*:/i,
@@ -31,7 +39,8 @@ const DANGEROUS_FILE_CONTENT_PATTERNS: Array<{ re: RegExp; reason: string }> = [
31
39
  },
32
40
  {
33
41
  re: /\bcurl\b[^\n|]*\|\s*(sh|bash|zsh)\b/i,
34
- reason: 'Detected remote shell execution pattern (`curl | sh`) in file content.',
42
+ reason:
43
+ 'Detected remote shell execution pattern (`curl | sh`) in file content.',
35
44
  },
36
45
  ];
37
46
 
@@ -50,9 +59,10 @@ const securityHookExtension: RuntimeExtension = {
50
59
  name: 'security-hook',
51
60
  onBeforeToolCall: (toolName, args) => {
52
61
  if (toolName === 'write' || toolName === 'edit') {
53
- const content = toolName === 'write'
54
- ? String(args.contents || '')
55
- : String(args.new || '');
62
+ const content =
63
+ toolName === 'write'
64
+ ? String(args.contents || '')
65
+ : String(args.new || '');
56
66
  for (const pattern of DANGEROUS_FILE_CONTENT_PATTERNS) {
57
67
  if (pattern.re.test(content)) return pattern.reason;
58
68
  }
@@ -74,14 +84,17 @@ const runtimeExtensions: RuntimeExtension[] = [securityHookExtension];
74
84
  function parseArgs(argsJson: string): Record<string, unknown> {
75
85
  try {
76
86
  const parsed = JSON.parse(argsJson) as unknown;
77
- if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) return {};
87
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed))
88
+ return {};
78
89
  return parsed as Record<string, unknown>;
79
90
  } catch {
80
91
  return {};
81
92
  }
82
93
  }
83
94
 
84
- export async function emitRuntimeEvent(payload: RuntimeEventPayload): Promise<void> {
95
+ export async function emitRuntimeEvent(
96
+ payload: RuntimeEventPayload,
97
+ ): Promise<void> {
85
98
  for (const ext of runtimeExtensions) {
86
99
  if (!ext.onEvent) continue;
87
100
  try {
@@ -92,7 +105,10 @@ export async function emitRuntimeEvent(payload: RuntimeEventPayload): Promise<vo
92
105
  }
93
106
  }
94
107
 
95
- export async function runBeforeToolHooks(toolName: string, argsJson: string): Promise<string | null> {
108
+ export async function runBeforeToolHooks(
109
+ toolName: string,
110
+ argsJson: string,
111
+ ): Promise<string | null> {
96
112
  const args = parseArgs(argsJson);
97
113
  for (const ext of runtimeExtensions) {
98
114
  if (!ext.onBeforeToolCall) continue;
@@ -112,11 +128,19 @@ export async function runBeforeToolHooks(toolName: string, argsJson: string): Pr
112
128
  // ignore broken extensions
113
129
  }
114
130
  }
115
- await emitRuntimeEvent({ event: 'before_tool_call', toolName, blocked: false });
131
+ await emitRuntimeEvent({
132
+ event: 'before_tool_call',
133
+ toolName,
134
+ blocked: false,
135
+ });
116
136
  return null;
117
137
  }
118
138
 
119
- export async function runAfterToolHooks(toolName: string, argsJson: string, result: string): Promise<void> {
139
+ export async function runAfterToolHooks(
140
+ toolName: string,
141
+ argsJson: string,
142
+ result: string,
143
+ ): Promise<void> {
120
144
  const args = parseArgs(argsJson);
121
145
  for (const ext of runtimeExtensions) {
122
146
  if (!ext.onAfterToolCall) continue;
@@ -1,4 +1,9 @@
1
- import type { ChatCompletionResponse, ChatMessage, ToolCall, ToolDefinition } from './types.js';
1
+ import type {
2
+ ChatCompletionResponse,
3
+ ChatMessage,
4
+ ToolCall,
5
+ ToolDefinition,
6
+ } from './types.js';
2
7
 
3
8
  export class HybridAIRequestError extends Error {
4
9
  status: number;
@@ -86,7 +91,10 @@ function ensureToolCall(toolCalls: ToolCall[], index: number): ToolCall {
86
91
  return toolCalls[index];
87
92
  }
88
93
 
89
- function mergeToolCallDelta(target: ToolCall, delta: StreamToolCallDelta): void {
94
+ function mergeToolCallDelta(
95
+ target: ToolCall,
96
+ delta: StreamToolCallDelta,
97
+ ): void {
90
98
  if (typeof delta.id === 'string' && delta.id) {
91
99
  target.id = target.id ? `${target.id}${delta.id}` : delta.id;
92
100
  }
@@ -99,7 +107,10 @@ function mergeToolCallDelta(target: ToolCall, delta: StreamToolCallDelta): void
99
107
  ? `${target.function.name}${delta.function.name}`
100
108
  : delta.function.name;
101
109
  }
102
- if (typeof delta.function.arguments === 'string' && delta.function.arguments) {
110
+ if (
111
+ typeof delta.function.arguments === 'string' &&
112
+ delta.function.arguments
113
+ ) {
103
114
  target.function.arguments += delta.function.arguments;
104
115
  }
105
116
  }
@@ -166,11 +177,13 @@ export async function callHybridAIStream(
166
177
  throw new HybridAIRequestError(response.status, text);
167
178
  }
168
179
 
169
- const contentType = (response.headers.get('content-type') || '').toLowerCase();
180
+ const contentType = (
181
+ response.headers.get('content-type') || ''
182
+ ).toLowerCase();
170
183
  if (
171
- contentType.includes('application/json')
172
- && !contentType.includes('ndjson')
173
- && !contentType.includes('event-stream')
184
+ contentType.includes('application/json') &&
185
+ !contentType.includes('ndjson') &&
186
+ !contentType.includes('event-stream')
174
187
  ) {
175
188
  return (await response.json()) as ChatCompletionResponse;
176
189
  }
@@ -208,10 +221,14 @@ export async function callHybridAIStream(
208
221
 
209
222
  sawPayload = true;
210
223
  if (typeof payload.id === 'string' && payload.id) streamId = payload.id;
211
- if (typeof payload.model === 'string' && payload.model) streamModel = payload.model;
212
- if (payload.usage && typeof payload.usage === 'object') usage = payload.usage;
213
-
214
- const choice = Array.isArray(payload.choices) ? payload.choices[0] : undefined;
224
+ if (typeof payload.model === 'string' && payload.model)
225
+ streamModel = payload.model;
226
+ if (payload.usage && typeof payload.usage === 'object')
227
+ usage = payload.usage;
228
+
229
+ const choice = Array.isArray(payload.choices)
230
+ ? payload.choices[0]
231
+ : undefined;
215
232
  if (!choice) return;
216
233
 
217
234
  if (choice.message) {
@@ -249,7 +266,10 @@ export async function callHybridAIStream(
249
266
  }
250
267
  if (Array.isArray(delta.tool_calls) && delta.tool_calls.length > 0) {
251
268
  for (const callDelta of delta.tool_calls) {
252
- const index = typeof callDelta.index === 'number' && callDelta.index >= 0 ? callDelta.index : 0;
269
+ const index =
270
+ typeof callDelta.index === 'number' && callDelta.index >= 0
271
+ ? callDelta.index
272
+ : 0;
253
273
  const target = ensureToolCall(toolCalls, index);
254
274
  mergeToolCallDelta(target, callDelta);
255
275
  }
@@ -293,7 +313,8 @@ export async function callHybridAIStream(
293
313
  throw new Error('Streaming response ended without payload');
294
314
  }
295
315
 
296
- const finalFinishReason = finishReason || (toolCalls.length > 0 ? 'tool_calls' : 'stop');
316
+ const finalFinishReason =
317
+ finishReason || (toolCalls.length > 0 ? 'tool_calls' : 'stop');
297
318
  return {
298
319
  id: streamId || 'stream',
299
320
  model: streamModel,