@jskit-ai/assistant-core 0.2.6 → 0.2.8

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 (214) hide show
  1. package/examples/conversation/package.json +5 -5
  2. package/package.json +18 -7
  3. package/src/client/browser.js +21 -0
  4. package/src/client/conversation/AssistantAttachmentQueue.vue +25 -108
  5. package/src/client/conversation/AssistantComposerActions.vue +1 -1
  6. package/src/client/conversation/AssistantConversationElement.vue +14 -52
  7. package/src/client/conversation/AssistantGoalControl.vue +18 -12
  8. package/src/client/conversation/AssistantPromptInput.vue +6 -91
  9. package/src/client/conversation/AssistantTranscript.css +505 -0
  10. package/src/client/conversation/AssistantTranscript.vue +24 -1197
  11. package/src/client/conversation/attachmentFiles.js +158 -0
  12. package/src/client/conversation/attachmentQueueItems.js +121 -0
  13. package/src/client/conversation/attachmentUploadRows.js +265 -0
  14. package/src/client/conversation/conversationDisplay.js +54 -0
  15. package/src/client/conversation/messageDelivery.js +13 -9
  16. package/src/client/conversation/retainedConversation.js +14 -3
  17. package/src/client/conversation/submitText.js +13 -2
  18. package/src/client/conversation/transcriptEntries.js +225 -0
  19. package/src/client/conversation/useAssistantAttachments.js +86 -388
  20. package/src/client/conversation/useAssistantQuestions.js +16 -3
  21. package/src/client/conversation/useAssistantSuggestions.js +16 -2
  22. package/src/client/conversation/useScrollToBottom.js +17 -19
  23. package/src/client/conversation/useTextareaAutoGrow.js +115 -0
  24. package/src/client/conversation/useTranscriptScrollFollow.js +525 -0
  25. package/src/client/lib/assistantApi.js +192 -161
  26. package/src/client/types.js +110 -0
  27. package/src/server/conversation/attachments.js +21 -6
  28. package/src/server/conversation/boundedToolLoop.js +1 -0
  29. package/src/server/conversation/claudeClient.js +71 -20
  30. package/src/server/conversation/claudeCommandRun.js +191 -0
  31. package/src/server/conversation/claudeHistory.js +7 -0
  32. package/src/server/conversation/claudeNativeTurn.js +708 -0
  33. package/src/server/conversation/claudeProcess.js +186 -112
  34. package/src/server/conversation/claudeProcessStart.js +214 -0
  35. package/src/server/conversation/claudePromptDelivery.js +183 -0
  36. package/src/server/conversation/claudeSessionCleanup.js +248 -0
  37. package/src/server/conversation/claudeTools.js +15 -3
  38. package/src/server/conversation/claudeTurn.js +212 -1388
  39. package/src/server/conversation/codexAccountReader.js +168 -0
  40. package/src/server/conversation/codexAuthPreflight.js +5 -4
  41. package/src/server/conversation/codexClient.js +18 -6
  42. package/src/server/conversation/codexConfiguration.js +8 -844
  43. package/src/server/conversation/codexConversationStops.js +377 -0
  44. package/src/server/conversation/codexConversationStore.js +119 -85
  45. package/src/server/conversation/codexConversationTurns.js +378 -0
  46. package/src/server/conversation/codexConversations.js +134 -866
  47. package/src/server/conversation/codexDetachedConversation.js +203 -0
  48. package/src/server/conversation/codexDetachedTurn.js +145 -104
  49. package/src/server/conversation/codexEvents.js +5 -200
  50. package/src/server/conversation/codexGoalCommands.js +14 -4
  51. package/src/server/conversation/codexHelperExecution.js +57 -57
  52. package/src/server/conversation/codexHelperThreadLedger.js +30 -288
  53. package/src/server/conversation/codexHelperThreadRecord.js +304 -0
  54. package/src/server/conversation/codexHelperThreadRecovery.js +54 -76
  55. package/src/server/conversation/codexHelperThreads.js +94 -93
  56. package/src/server/conversation/codexHistoryAdapter.js +13 -8
  57. package/src/server/conversation/codexIsolation.js +672 -0
  58. package/src/server/conversation/codexLiveItems.js +379 -0
  59. package/src/server/conversation/codexMessageCommands.js +68 -286
  60. package/src/server/conversation/codexMessageDelivery.js +46 -37
  61. package/src/server/conversation/codexModelCatalog.js +86 -7
  62. package/src/server/conversation/codexNotificationObserver.js +81 -88
  63. package/src/server/conversation/codexNotificationQueue.js +21 -10
  64. package/src/server/conversation/codexObservationControl.js +105 -89
  65. package/src/server/conversation/codexOutput.js +84 -419
  66. package/src/server/conversation/codexProcess.js +29 -1053
  67. package/src/server/conversation/codexProcessLeader.js +1 -0
  68. package/src/server/conversation/codexPromptDispatch.js +241 -0
  69. package/src/server/conversation/codexProvider.js +147 -1807
  70. package/src/server/conversation/codexProviderAuth.js +348 -0
  71. package/src/server/conversation/codexProviderInvalidation.js +371 -0
  72. package/src/server/conversation/codexProviderInventories.js +437 -0
  73. package/src/server/conversation/codexProviderOwner.js +149 -957
  74. package/src/server/conversation/codexProviderRelease.js +465 -0
  75. package/src/server/conversation/codexProviderSelection.js +26 -15
  76. package/src/server/conversation/codexProviderThreads.js +698 -0
  77. package/src/server/conversation/codexProviderTurns.js +453 -0
  78. package/src/server/conversation/codexReasoning.js +32 -23
  79. package/src/server/conversation/codexRenewalCommands.js +18 -6
  80. package/src/server/conversation/codexRenewalThreads.js +7 -22
  81. package/src/server/conversation/codexResultSettlement.js +70 -88
  82. package/src/server/conversation/codexRunJournal.js +91 -97
  83. package/src/server/conversation/codexRuntime.js +426 -0
  84. package/src/server/conversation/codexRuntimeInventory.js +113 -0
  85. package/src/server/conversation/codexRuntimeLifecycle.js +39 -13
  86. package/src/server/conversation/codexRuntimeStart.js +431 -0
  87. package/src/server/conversation/codexRuntimeStop.js +324 -0
  88. package/src/server/conversation/codexSessionCleanup.js +25 -10
  89. package/src/server/conversation/codexSessionReconciliation.js +21 -7
  90. package/src/server/conversation/codexThreadReadiness.js +49 -52
  91. package/src/server/conversation/codexThreadSnapshot.js +210 -0
  92. package/src/server/conversation/codexThreadStatus.js +48 -62
  93. package/src/server/conversation/codexTurn.js +171 -55
  94. package/src/server/conversation/codexTurnActivity.js +210 -0
  95. package/src/server/conversation/codexTurnControl.js +44 -48
  96. package/src/server/conversation/codexTurnEndings.js +610 -0
  97. package/src/server/conversation/codexTurnRecovery.js +97 -848
  98. package/src/server/conversation/codexTurnState.js +138 -111
  99. package/src/server/conversation/completedResponses.js +227 -0
  100. package/src/server/conversation/configuration.js +2 -2
  101. package/src/server/conversation/continuity.js +43 -6
  102. package/src/server/conversation/conversationDelivery.js +394 -0
  103. package/src/server/conversation/conversationEntries.js +365 -0
  104. package/src/server/conversation/conversationEvents.js +192 -0
  105. package/src/server/conversation/conversationGoals.js +187 -0
  106. package/src/server/conversation/conversationHandles.js +237 -0
  107. package/src/server/conversation/conversationReads.js +206 -0
  108. package/src/server/conversation/conversationRefusals.js +58 -0
  109. package/src/server/conversation/conversationReplacement.js +254 -0
  110. package/src/server/conversation/conversationSending.js +273 -0
  111. package/src/server/conversation/conversationStopping.js +121 -0
  112. package/src/server/conversation/conversationTurnDelivery.js +413 -0
  113. package/src/server/conversation/conversationTurns.js +511 -0
  114. package/src/server/conversation/deliveryTiming.js +25 -3
  115. package/src/server/conversation/fileStorage.js +11 -6
  116. package/src/server/conversation/hookBridge.js +14 -3
  117. package/src/server/conversation/index.js +1 -1
  118. package/src/server/conversation/localExecution.js +82 -625
  119. package/src/server/conversation/nativeCommandCallbacks.js +10 -0
  120. package/src/server/conversation/nativeConversationLifecycle.js +379 -0
  121. package/src/server/conversation/nativeHistoryExport.js +27 -18
  122. package/src/server/conversation/normalize.js +9 -0
  123. package/src/server/conversation/openCodeClient.js +295 -366
  124. package/src/server/conversation/openCodeNativeHistory.js +141 -0
  125. package/src/server/conversation/openCodeNativeSession.js +79 -0
  126. package/src/server/conversation/openCodeProcess.js +109 -53
  127. package/src/server/conversation/openCodeProcessOwner.js +565 -0
  128. package/src/server/conversation/openCodeRuntime.js +111 -1814
  129. package/src/server/conversation/openCodeSessionTurns.js +547 -0
  130. package/src/server/conversation/openCodeTemporaryConversations.js +394 -0
  131. package/src/server/conversation/openCodeTools.js +28 -14
  132. package/src/server/conversation/openCodeTurn.js +80 -74
  133. package/src/server/conversation/openCodeTurnMonitor.js +388 -0
  134. package/src/server/conversation/processIdentity.js +582 -0
  135. package/src/server/conversation/provider.js +21 -6
  136. package/src/server/conversation/providers/api.js +268 -107
  137. package/src/server/conversation/providers/claude.js +29 -6
  138. package/src/server/conversation/providers/claudeDriver.js +325 -250
  139. package/src/server/conversation/providers/codex.js +69 -33
  140. package/src/server/conversation/providers/codexDriver.js +503 -1081
  141. package/src/server/conversation/providers/codexDriverConnection.js +331 -0
  142. package/src/server/conversation/providers/codexDriverTurns.js +464 -0
  143. package/src/server/conversation/providers/opencode.js +30 -4
  144. package/src/server/conversation/providers/opencodeDriver.js +321 -659
  145. package/src/server/conversation/providers/opencodeStandalone.js +475 -0
  146. package/src/server/conversation/providers/scoped.js +64 -19
  147. package/src/server/conversation/runtime.js +171 -2863
  148. package/src/server/conversation/storage.js +91 -50
  149. package/src/server/conversation/streams.js +15 -2
  150. package/src/server/conversation/structuredOutput.js +7 -11
  151. package/src/server/conversation/systemPrompt.js +13 -1
  152. package/src/server/conversation/tools.js +47 -15
  153. package/src/server/conversation/transcript.js +49 -20
  154. package/src/server/hosts/claudeTurn.js +2 -4
  155. package/src/server/hosts/codexConfiguration.js +6 -8
  156. package/src/server/hosts/codexEvents.js +4 -2
  157. package/src/server/hosts/codexProcess.js +1 -1
  158. package/src/server/hosts/codexProvider.js +11 -9
  159. package/src/server/hosts/codexTurn.js +3 -3
  160. package/src/server/hosts/openCodeClient.js +4 -2
  161. package/src/server/index.js +0 -2
  162. package/src/server/lib/aiConnectionClient.js +35 -25
  163. package/src/server/lib/ndjson.js +1 -0
  164. package/src/server/lib/providers/anthropicClient.js +15 -6
  165. package/src/server/lib/providers/common.js +10 -6
  166. package/src/server/lib/providers/openAiCompatibleClient.js +40 -23
  167. package/src/server/lib/serviceToolCatalog.js +29 -283
  168. package/src/server/lib/serviceToolEntries.js +270 -0
  169. package/src/server/types.js +78 -0
  170. package/src/shared/assistantResource.js +0 -23
  171. package/src/shared/conversation/answerChoiceSugar.js +2 -14
  172. package/src/shared/conversation/messageInputSugar.js +18 -0
  173. package/src/shared/conversation/numberedQuestionSugar.js +6 -16
  174. package/src/shared/conversation/pagination.js +1 -1
  175. package/src/shared/conversation/questions.js +1 -0
  176. package/src/shared/conversation/streaming.js +1 -0
  177. package/src/shared/index.js +0 -1
  178. package/src/testing/conversationStorageContract.js +20 -0
  179. package/test/aiConnectionClient.test.js +42 -1
  180. package/test/apiConversationDriver.test.js +217 -38
  181. package/test/assistantBoundedToolLoop.test.js +1 -1
  182. package/test/claudeConversationSession.test.js +15 -11
  183. package/test/claudeInstructionResume.test.js +1 -1
  184. package/test/claudeProcess.test.js +9 -9
  185. package/test/claudeTurn.test.js +21 -8
  186. package/test/codexAccountChange.test.js +5 -3
  187. package/test/codexConversationSession.test.js +22 -21
  188. package/test/codexEvents.test.js +3 -1
  189. package/test/codexHelperDeletion.test.js +3 -7
  190. package/test/codexIsolation.test.js +6 -6
  191. package/test/codexModelCatalog.test.js +6 -7
  192. package/test/codexProcess.test.js +3 -3
  193. package/test/codexThreadSelection.test.js +4 -1
  194. package/test/codexTurn.test.js +29 -20
  195. package/test/conversationApiFacilities.test.js +11 -9
  196. package/test/conversationAttachments.test.js +3 -3
  197. package/test/conversationConfiguration.test.js +4 -4
  198. package/test/conversationNativeStorage.test.js +11 -10
  199. package/test/conversationReplacement.test.js +13 -13
  200. package/test/conversationRuntime.test.js +9 -5
  201. package/test/conversationSession.test.js +78 -22
  202. package/test/conversationTools.test.js +47 -26
  203. package/test/fileConversationStorage.test.js +10 -3
  204. package/test/fixtures/codexHelperThreadLedger.js +3 -3
  205. package/test/frameworkActions.test.js +33 -18
  206. package/test/localConversationExecution.test.js +4 -4
  207. package/test/localExecution.test.js +1 -1
  208. package/test/openCodeConnectionChange.test.js +3 -2
  209. package/test/openCodeRuntime.test.js +8 -7
  210. package/test/openCodeTools.test.js +1 -1
  211. package/test/opencodeConversationSession.test.js +4 -3
  212. package/test/serviceToolCatalog.test.js +3 -8
  213. package/src/server/lib/assistantCompletion.js +0 -190
  214. package/src/server/lib/assistantToolLoop.js +0 -259
@@ -1,259 +0,0 @@
1
- import { normalizeText } from "@jskit-ai/kernel/shared/support/normalize";
2
- import { isAssistantProgressOnlyText } from "../../shared/assistantResponseText.js";
3
- import { sanitizeAssistantMessageText } from "./assistantCompletion.js";
4
-
5
- const MAX_TOOL_ROUNDS = 16;
6
- const MAX_RECOVERY_PASSES = 3;
7
- const MAX_TOOL_RESULT_FALLBACK_CHARS = 4000;
8
- const CURRENT_TIME_PREFLIGHT_INTENT = "current-time";
9
- const COMPLETION_INSTRUCTION = "Do not narrate future work or describe what you are about to do. Either call the required available tool now or provide the completed final answer.";
10
-
11
- function requiresCurrentTime(value = "") {
12
- const text = normalizeText(value);
13
- if (!text) {
14
- return false;
15
- }
16
-
17
- return [
18
- /\b(?:now|today|tomorrow|yesterday|tonight)\b/iu,
19
- /\b(?:current|local)\s+(?:date|day|time|date\s+and\s+time)\b/iu,
20
- /\bwhat(?:'s|\s+is)\s+(?:the\s+)?(?:date|day|time)\b/iu,
21
- /\b(?:this|next|last)\s+(?:day|week|month|year|monday|tuesday|wednesday|thursday|friday|saturday|sunday)\b/iu
22
- ].some((pattern) => pattern.test(text));
23
- }
24
-
25
- function resolvePreflightTools(toolDescriptors = [], input = "") {
26
- if (!requiresCurrentTime(input)) {
27
- return [];
28
- }
29
-
30
- const currentTimeTool = toolDescriptors.find((tool) => {
31
- const intents = Array.isArray(tool?.preflight) ? tool.preflight : [];
32
- const requiredParameters = Array.isArray(tool?.parameters?.required)
33
- ? tool.parameters.required
34
- : [];
35
- return requiredParameters.length < 1 && intents.includes(CURRENT_TIME_PREFLIGHT_INTENT);
36
- });
37
-
38
- return currentTimeTool ? [currentTimeTool] : [];
39
- }
40
-
41
- function buildRecoveryPrompt({ reason = "", toolFailures = [], toolSuccesses = [] } = {}) {
42
- const normalizedReason = normalizeText(reason).toLowerCase();
43
- const failureSummary = (Array.isArray(toolFailures) ? toolFailures : [])
44
- .slice(0, 3)
45
- .map((entry) => {
46
- const toolName = normalizeText(entry?.name) || "unknown_tool";
47
- const errorCode = normalizeText(entry?.error?.code) || "tool_failed";
48
- return `${toolName}:${errorCode}`;
49
- })
50
- .filter(Boolean)
51
- .join(", ");
52
- const successSummary = (Array.isArray(toolSuccesses) ? toolSuccesses : [])
53
- .slice(0, 3)
54
- .map((entry) => normalizeText(entry?.name))
55
- .filter(Boolean)
56
- .join(", ");
57
-
58
- const failureSuffix = failureSummary ? ` Recent tool failures: ${failureSummary}.` : "";
59
- const successSuffix = successSummary ? ` Successful tools: ${successSummary}.` : "";
60
- if (normalizedReason === "tool_failure") {
61
- return `One or more tool calls may fail. Continue with available successful results. Do not output function-call markup. Do not mention failed operations unless explicitly asked. ${COMPLETION_INSTRUCTION}${failureSuffix}${successSuffix}`;
62
- }
63
-
64
- return `Tool-call rounds were exhausted. Provide the best direct answer with available context and successful results only. ${COMPLETION_INSTRUCTION}${failureSuffix}${successSuffix}`;
65
- }
66
-
67
- function buildRecoveryFallbackAnswer({ reason = "", toolFailures = [], toolSuccesses = [] } = {}) {
68
- if (normalizeText(reason).toLowerCase() === "max_tool_rounds") {
69
- return "Limit reached. Start a new conversation.";
70
- }
71
-
72
- return buildToolOutcomeFallbackAnswer({
73
- toolFailures,
74
- toolSuccesses
75
- });
76
- }
77
-
78
- function toSafeToolResultText(value) {
79
- if (value == null) {
80
- return "null";
81
- }
82
- if (typeof value === "string") {
83
- const normalized = normalizeText(value);
84
- return normalized || "\"\"";
85
- }
86
- try {
87
- return JSON.stringify(value, null, 2);
88
- } catch {
89
- return "\"<unserializable>\"";
90
- }
91
- }
92
-
93
- function buildToolOutcomeFallbackAnswer({ toolFailures = [], toolSuccesses = [] } = {}) {
94
- const successfulResults = (Array.isArray(toolSuccesses) ? toolSuccesses : [])
95
- .filter((entry) => normalizeText(entry?.name));
96
- const hasFailures = Array.isArray(toolFailures) && toolFailures.length > 0;
97
-
98
- if (successfulResults.length > 0) {
99
- const latestSuccess = successfulResults.at(-1);
100
- const answer = `Latest successful result from ${normalizeText(latestSuccess.name)}:\n${toSafeToolResultText(latestSuccess.result)}`;
101
- if (answer.length <= MAX_TOOL_RESULT_FALLBACK_CHARS) {
102
- return answer;
103
- }
104
-
105
- const suffix = "\n…[truncated]";
106
- return `${answer.slice(0, MAX_TOOL_RESULT_FALLBACK_CHARS - suffix.length)}${suffix}`;
107
- }
108
-
109
- if (hasFailures) {
110
- return "I could not gather additional information from successful operations.";
111
- }
112
-
113
- return "I could not gather additional information from the available operations.";
114
- }
115
-
116
- function buildAssistantToolCallMessage(toolCalls = []) {
117
- return {
118
- role: "assistant",
119
- content: "",
120
- tool_calls: toolCalls.map((toolCall) => ({
121
- id: toolCall.id,
122
- type: "function",
123
- function: {
124
- name: toolCall.name,
125
- arguments: toolCall.arguments
126
- }
127
- }))
128
- };
129
- }
130
-
131
- /** Existing bounded inference/recovery policy; callers own delivery and tool receipts. */
132
- async function runAssistantToolLoop({ messages, input, toolSet, toToolSchema, complete, executeToolCalls, finish,
133
- preserveWhitespace = false }) {
134
- const answerText = value => preserveWhitespace
135
- ? sanitizeAssistantMessageText(value, { preserveWhitespace: true })
136
- : normalizeText(sanitizeAssistantMessageText(value));
137
-
138
- async function recoverWithoutTools({ reason = "", toolFailures = [], toolSuccesses = [] } = {}) {
139
- for (let pass = 0; pass < MAX_RECOVERY_PASSES; pass += 1) {
140
- const recoveryMessages = [
141
- ...messages,
142
- {
143
- role: "system",
144
- content: buildRecoveryPrompt({
145
- reason,
146
- toolFailures,
147
- toolSuccesses
148
- })
149
- }
150
- ];
151
-
152
- const completion = await complete(recoveryMessages, []);
153
-
154
- const recoveryToolCalls = completion.toolCalls.filter((entry) => entry.name);
155
- if (recoveryToolCalls.length > 0) {
156
- continue;
157
- }
158
-
159
- const assistantMessageText = answerText(completion.assistantText);
160
- if (assistantMessageText && !isAssistantProgressOnlyText(assistantMessageText)) {
161
- return finish(assistantMessageText, {
162
- metadata: {
163
- recoveryReason: reason || "unknown",
164
- toolFailureCount: Array.isArray(toolFailures) ? toolFailures.length : 0
165
- }
166
- });
167
- }
168
- }
169
-
170
- const fallbackText = buildRecoveryFallbackAnswer({
171
- reason,
172
- toolFailures,
173
- toolSuccesses
174
- });
175
- return finish(fallbackText, {
176
- metadata: {
177
- recoveryReason: reason || "unknown",
178
- toolFailureCount: Array.isArray(toolFailures) ? toolFailures.length : 0
179
- }
180
- });
181
- }
182
-
183
- const excludedToolNames = new Set();
184
- const toolFailures = [];
185
- const toolSuccesses = [];
186
-
187
- function excludeFailedTools(failures) {
188
- for (const failure of failures) {
189
- const toolName = normalizeText(failure?.name);
190
- if (toolName && !(failure?.error?.status >= 400 && failure.error.status < 500)) {
191
- excludedToolNames.add(toolName);
192
- }
193
- }
194
- }
195
-
196
- const preflightTools = resolvePreflightTools(toolSet.tools, input);
197
- for (const [index, tool] of preflightTools.entries()) {
198
- const toolCall = {
199
- id: `assistant_preflight_${index + 1}`,
200
- name: tool.name,
201
- arguments: "{}"
202
- };
203
- messages.push(buildAssistantToolCallMessage([toolCall]));
204
- const preflightFailures = await executeToolCalls([toolCall], {
205
- toolFailures,
206
- toolSuccesses
207
- });
208
- excludeFailedTools(preflightFailures);
209
- }
210
-
211
- for (let round = 0; round < MAX_TOOL_ROUNDS; round += 1) {
212
- const roundToolDescriptors = toolSet.tools.filter(
213
- (tool) => !excludedToolNames.has(normalizeText(tool.name))
214
- );
215
- const roundToolSchemas = roundToolDescriptors.map((tool) => toToolSchema(tool));
216
-
217
- const completion = await complete(messages, roundToolSchemas);
218
-
219
- const toolCalls = completion.toolCalls.filter((entry) => entry.name);
220
- if (toolCalls.length < 1) {
221
- const finalMessageText = answerText(completion.assistantText);
222
- if (finalMessageText && !isAssistantProgressOnlyText(finalMessageText)) {
223
- return finish(finalMessageText, {
224
- metadata: toolFailures.length > 0
225
- ? {
226
- recoveryReason: "tool_failure",
227
- toolFailureCount: toolFailures.length
228
- }
229
- : {}
230
- });
231
- }
232
-
233
- messages.push({
234
- role: "system",
235
- content: COMPLETION_INSTRUCTION
236
- });
237
- continue;
238
- }
239
-
240
- messages.push(buildAssistantToolCallMessage(toolCalls));
241
-
242
- const roundFailures = await executeToolCalls(toolCalls, {
243
- toolFailures,
244
- toolSuccesses
245
- });
246
-
247
- if (roundFailures.length > 0) {
248
- excludeFailedTools(roundFailures);
249
- }
250
- }
251
-
252
- return recoverWithoutTools({
253
- reason: toolFailures.length > 0 ? "tool_failure" : "max_tool_rounds",
254
- toolFailures,
255
- toolSuccesses
256
- });
257
- }
258
-
259
- export { runAssistantToolLoop };