qlogicagent 0.2.1 → 0.3.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 (229) hide show
  1. package/dist/agent.js +1 -0
  2. package/dist/cli.js +9 -0
  3. package/dist/contracts.js +1 -0
  4. package/dist/index.js +5 -15
  5. package/dist/orchestration.js +118 -0
  6. package/package.json +56 -42
  7. package/dist/agent/agent.js +0 -113
  8. package/dist/agent/tool-loop.js +0 -575
  9. package/dist/agent/types.js +0 -14
  10. package/dist/cli/main.js +0 -23
  11. package/dist/cli/stdio-server.js +0 -463
  12. package/dist/config/config.js +0 -21
  13. package/dist/contracts/hooks.js +0 -7
  14. package/dist/contracts/index.js +0 -10
  15. package/dist/contracts/planner.js +0 -2
  16. package/dist/contracts/skill-candidate.js +0 -195
  17. package/dist/contracts/todo.js +0 -9
  18. package/dist/llm/builtin-providers.js +0 -531
  19. package/dist/llm/index.js +0 -14
  20. package/dist/llm/llm-client.js +0 -67
  21. package/dist/llm/model-catalog.js +0 -191
  22. package/dist/llm/provider-def.js +0 -12
  23. package/dist/llm/provider-registry.js +0 -147
  24. package/dist/llm/transport.js +0 -27
  25. package/dist/llm/transports/anthropic-messages.js +0 -293
  26. package/dist/llm/transports/openai-chat.js +0 -165
  27. package/dist/orchestration/agent-registry.js +0 -116
  28. package/dist/orchestration/approval-aware-tool-plan.js +0 -87
  29. package/dist/orchestration/context-compression.js +0 -583
  30. package/dist/orchestration/conversation-repair.js +0 -429
  31. package/dist/orchestration/curator-scheduler.js +0 -135
  32. package/dist/orchestration/embedded-failover-policy.js +0 -168
  33. package/dist/orchestration/error-classification.js +0 -77
  34. package/dist/orchestration/failover-classification.js +0 -381
  35. package/dist/orchestration/failover-error.js +0 -198
  36. package/dist/orchestration/fork-subagent.js +0 -98
  37. package/dist/orchestration/index.js +0 -267
  38. package/dist/orchestration/memory-flush-policy.js +0 -85
  39. package/dist/orchestration/memory-provider.js +0 -2
  40. package/dist/orchestration/parallel-tool-calls.js +0 -59
  41. package/dist/orchestration/prompt-cache-strategy.js +0 -228
  42. package/dist/orchestration/reactive-compact.js +0 -78
  43. package/dist/orchestration/retry-loop.js +0 -24
  44. package/dist/orchestration/skill-candidate.js +0 -141
  45. package/dist/orchestration/skill-consolidation.js +0 -220
  46. package/dist/orchestration/skill-improvement.js +0 -66
  47. package/dist/orchestration/skill-similarity.js +0 -131
  48. package/dist/orchestration/streaming-tool-executor.js +0 -96
  49. package/dist/orchestration/team-orchestration.js +0 -369
  50. package/dist/orchestration/team-tool-loop-wiring.js +0 -147
  51. package/dist/orchestration/tool-choice-policy.js +0 -164
  52. package/dist/orchestration/tool-loop-state.js +0 -133
  53. package/dist/orchestration/tool-schema.js +0 -297
  54. package/dist/orchestration/transcript-repair.js +0 -426
  55. package/dist/orchestration/turn-loop-guard.js +0 -92
  56. package/dist/orchestration/web-browser-policy.js +0 -39
  57. package/dist/runtime/context-compression.js +0 -274
  58. package/dist/runtime/hook-registry.js +0 -53
  59. package/dist/runtime/memory-hooks.js +0 -65
  60. package/dist/runtime/tool-eligibility.js +0 -111
  61. package/dist/skills/index.js +0 -82
  62. package/dist/skills/memory-extractor.js +0 -173
  63. package/dist/skills/memory-query-tool.js +0 -127
  64. package/dist/skills/memory-store.js +0 -228
  65. package/dist/skills/memory-tool.js +0 -192
  66. package/dist/skills/portable-tool.js +0 -14
  67. package/dist/skills/qmemory-adapter.js +0 -165
  68. package/dist/skills/skill-frontmatter.js +0 -344
  69. package/dist/skills/skill-guard.js +0 -229
  70. package/dist/skills/skill-loader.js +0 -303
  71. package/dist/skills/skill-source.js +0 -126
  72. package/dist/skills/skill-types.js +0 -6
  73. package/dist/skills/think-tool.js +0 -59
  74. package/dist/skills/todo-tool.js +0 -114
  75. package/dist/skills/tools/agent-tool.js +0 -142
  76. package/dist/skills/tools/apply-patch-tool.js +0 -184
  77. package/dist/skills/tools/ask-user-tool.js +0 -121
  78. package/dist/skills/tools/brief-tool.js +0 -95
  79. package/dist/skills/tools/browser-tool.js +0 -155
  80. package/dist/skills/tools/checkpoint-tool.js +0 -102
  81. package/dist/skills/tools/config-tool.js +0 -143
  82. package/dist/skills/tools/cron-tool.js +0 -175
  83. package/dist/skills/tools/edit-tool.js +0 -70
  84. package/dist/skills/tools/exec-tool.js +0 -133
  85. package/dist/skills/tools/image-generate-tool.js +0 -67
  86. package/dist/skills/tools/instructions-tool.js +0 -187
  87. package/dist/skills/tools/lsp-tool.js +0 -227
  88. package/dist/skills/tools/mcp-client-types.js +0 -53
  89. package/dist/skills/tools/mcp-tool.js +0 -503
  90. package/dist/skills/tools/memory-tool.js +0 -88
  91. package/dist/skills/tools/monitor-tool.js +0 -131
  92. package/dist/skills/tools/music-generate-tool.js +0 -62
  93. package/dist/skills/tools/notify-tool.js +0 -62
  94. package/dist/skills/tools/patch-tool.js +0 -505
  95. package/dist/skills/tools/pdf-tool.js +0 -88
  96. package/dist/skills/tools/plan-mode-tool.js +0 -122
  97. package/dist/skills/tools/read-tool.js +0 -84
  98. package/dist/skills/tools/repl-tool.js +0 -69
  99. package/dist/skills/tools/search-tool.js +0 -225
  100. package/dist/skills/tools/send-message-tool.js +0 -76
  101. package/dist/skills/tools/skill-list-tool.js +0 -54
  102. package/dist/skills/tools/skill-manage-tool.js +0 -153
  103. package/dist/skills/tools/skill-view-tool.js +0 -72
  104. package/dist/skills/tools/sleep-tool.js +0 -81
  105. package/dist/skills/tools/structured-output-tool.js +0 -176
  106. package/dist/skills/tools/task-tool.js +0 -161
  107. package/dist/skills/tools/team-tool.js +0 -105
  108. package/dist/skills/tools/tool-search-tool.js +0 -110
  109. package/dist/skills/tools/tts-tool.js +0 -45
  110. package/dist/skills/tools/video-edit-tool.js +0 -74
  111. package/dist/skills/tools/video-generate-tool.js +0 -66
  112. package/dist/skills/tools/video-merge-tool.js +0 -92
  113. package/dist/skills/tools/video-upscale-tool.js +0 -52
  114. package/dist/skills/tools/web-fetch-tool.js +0 -92
  115. package/dist/skills/tools/web-search-tool.js +0 -86
  116. package/dist/skills/tools/worktree-tool.js +0 -147
  117. package/dist/skills/tools/write-tool.js +0 -81
  118. /package/dist/{agent → types/agent}/agent.d.ts +0 -0
  119. /package/dist/{agent → types/agent}/tool-loop.d.ts +0 -0
  120. /package/dist/{agent → types/agent}/types.d.ts +0 -0
  121. /package/dist/{cli → types/cli}/main.d.ts +0 -0
  122. /package/dist/{cli → types/cli}/stdio-server.d.ts +0 -0
  123. /package/dist/{config → types/config}/config.d.ts +0 -0
  124. /package/dist/{contracts → types/contracts}/hooks.d.ts +0 -0
  125. /package/dist/{contracts → types/contracts}/index.d.ts +0 -0
  126. /package/dist/{contracts → types/contracts}/planner.d.ts +0 -0
  127. /package/dist/{contracts → types/contracts}/skill-candidate.d.ts +0 -0
  128. /package/dist/{contracts → types/contracts}/todo.d.ts +0 -0
  129. /package/dist/{index.d.ts → types/index.d.ts} +0 -0
  130. /package/dist/{llm → types/llm}/builtin-providers.d.ts +0 -0
  131. /package/dist/{llm → types/llm}/index.d.ts +0 -0
  132. /package/dist/{llm → types/llm}/llm-client.d.ts +0 -0
  133. /package/dist/{llm → types/llm}/model-catalog.d.ts +0 -0
  134. /package/dist/{llm → types/llm}/provider-def.d.ts +0 -0
  135. /package/dist/{llm → types/llm}/provider-registry.d.ts +0 -0
  136. /package/dist/{llm → types/llm}/transport.d.ts +0 -0
  137. /package/dist/{llm → types/llm}/transports/anthropic-messages.d.ts +0 -0
  138. /package/dist/{llm → types/llm}/transports/openai-chat.d.ts +0 -0
  139. /package/dist/{orchestration → types/orchestration}/agent-registry.d.ts +0 -0
  140. /package/dist/{orchestration → types/orchestration}/approval-aware-tool-plan.d.ts +0 -0
  141. /package/dist/{orchestration → types/orchestration}/context-compression.d.ts +0 -0
  142. /package/dist/{orchestration → types/orchestration}/conversation-repair.d.ts +0 -0
  143. /package/dist/{orchestration → types/orchestration}/curator-scheduler.d.ts +0 -0
  144. /package/dist/{orchestration → types/orchestration}/embedded-failover-policy.d.ts +0 -0
  145. /package/dist/{orchestration → types/orchestration}/error-classification.d.ts +0 -0
  146. /package/dist/{orchestration → types/orchestration}/failover-classification.d.ts +0 -0
  147. /package/dist/{orchestration → types/orchestration}/failover-error.d.ts +0 -0
  148. /package/dist/{orchestration → types/orchestration}/fork-subagent.d.ts +0 -0
  149. /package/dist/{orchestration → types/orchestration}/index.d.ts +0 -0
  150. /package/dist/{orchestration → types/orchestration}/memory-flush-policy.d.ts +0 -0
  151. /package/dist/{orchestration → types/orchestration}/memory-provider.d.ts +0 -0
  152. /package/dist/{orchestration → types/orchestration}/parallel-tool-calls.d.ts +0 -0
  153. /package/dist/{orchestration → types/orchestration}/prompt-cache-strategy.d.ts +0 -0
  154. /package/dist/{orchestration → types/orchestration}/reactive-compact.d.ts +0 -0
  155. /package/dist/{orchestration → types/orchestration}/retry-loop.d.ts +0 -0
  156. /package/dist/{orchestration → types/orchestration}/skill-candidate.d.ts +0 -0
  157. /package/dist/{orchestration → types/orchestration}/skill-consolidation.d.ts +0 -0
  158. /package/dist/{orchestration → types/orchestration}/skill-improvement.d.ts +0 -0
  159. /package/dist/{orchestration → types/orchestration}/skill-similarity.d.ts +0 -0
  160. /package/dist/{orchestration → types/orchestration}/streaming-tool-executor.d.ts +0 -0
  161. /package/dist/{orchestration → types/orchestration}/team-orchestration.d.ts +0 -0
  162. /package/dist/{orchestration → types/orchestration}/team-tool-loop-wiring.d.ts +0 -0
  163. /package/dist/{orchestration → types/orchestration}/tool-choice-policy.d.ts +0 -0
  164. /package/dist/{orchestration → types/orchestration}/tool-loop-state.d.ts +0 -0
  165. /package/dist/{orchestration → types/orchestration}/tool-schema.d.ts +0 -0
  166. /package/dist/{orchestration → types/orchestration}/transcript-repair.d.ts +0 -0
  167. /package/dist/{orchestration → types/orchestration}/turn-loop-guard.d.ts +0 -0
  168. /package/dist/{orchestration → types/orchestration}/web-browser-policy.d.ts +0 -0
  169. /package/dist/{runtime → types/runtime}/context-compression.d.ts +0 -0
  170. /package/dist/{runtime → types/runtime}/hook-registry.d.ts +0 -0
  171. /package/dist/{runtime → types/runtime}/memory-hooks.d.ts +0 -0
  172. /package/dist/{runtime → types/runtime}/tool-eligibility.d.ts +0 -0
  173. /package/dist/{skills → types/skills}/index.d.ts +0 -0
  174. /package/dist/{skills → types/skills}/memory-extractor.d.ts +0 -0
  175. /package/dist/{skills → types/skills}/memory-query-tool.d.ts +0 -0
  176. /package/dist/{skills → types/skills}/memory-store.d.ts +0 -0
  177. /package/dist/{skills → types/skills}/memory-tool.d.ts +0 -0
  178. /package/dist/{skills → types/skills}/portable-tool.d.ts +0 -0
  179. /package/dist/{skills → types/skills}/qmemory-adapter.d.ts +0 -0
  180. /package/dist/{skills → types/skills}/skill-frontmatter.d.ts +0 -0
  181. /package/dist/{skills → types/skills}/skill-guard.d.ts +0 -0
  182. /package/dist/{skills → types/skills}/skill-loader.d.ts +0 -0
  183. /package/dist/{skills → types/skills}/skill-source.d.ts +0 -0
  184. /package/dist/{skills → types/skills}/skill-types.d.ts +0 -0
  185. /package/dist/{skills → types/skills}/think-tool.d.ts +0 -0
  186. /package/dist/{skills → types/skills}/todo-tool.d.ts +0 -0
  187. /package/dist/{skills → types/skills}/tools/agent-tool.d.ts +0 -0
  188. /package/dist/{skills → types/skills}/tools/apply-patch-tool.d.ts +0 -0
  189. /package/dist/{skills → types/skills}/tools/ask-user-tool.d.ts +0 -0
  190. /package/dist/{skills → types/skills}/tools/brief-tool.d.ts +0 -0
  191. /package/dist/{skills → types/skills}/tools/browser-tool.d.ts +0 -0
  192. /package/dist/{skills → types/skills}/tools/checkpoint-tool.d.ts +0 -0
  193. /package/dist/{skills → types/skills}/tools/config-tool.d.ts +0 -0
  194. /package/dist/{skills → types/skills}/tools/cron-tool.d.ts +0 -0
  195. /package/dist/{skills → types/skills}/tools/edit-tool.d.ts +0 -0
  196. /package/dist/{skills → types/skills}/tools/exec-tool.d.ts +0 -0
  197. /package/dist/{skills → types/skills}/tools/image-generate-tool.d.ts +0 -0
  198. /package/dist/{skills → types/skills}/tools/instructions-tool.d.ts +0 -0
  199. /package/dist/{skills → types/skills}/tools/lsp-tool.d.ts +0 -0
  200. /package/dist/{skills → types/skills}/tools/mcp-client-types.d.ts +0 -0
  201. /package/dist/{skills → types/skills}/tools/mcp-tool.d.ts +0 -0
  202. /package/dist/{skills → types/skills}/tools/memory-tool.d.ts +0 -0
  203. /package/dist/{skills → types/skills}/tools/monitor-tool.d.ts +0 -0
  204. /package/dist/{skills → types/skills}/tools/music-generate-tool.d.ts +0 -0
  205. /package/dist/{skills → types/skills}/tools/notify-tool.d.ts +0 -0
  206. /package/dist/{skills → types/skills}/tools/patch-tool.d.ts +0 -0
  207. /package/dist/{skills → types/skills}/tools/pdf-tool.d.ts +0 -0
  208. /package/dist/{skills → types/skills}/tools/plan-mode-tool.d.ts +0 -0
  209. /package/dist/{skills → types/skills}/tools/read-tool.d.ts +0 -0
  210. /package/dist/{skills → types/skills}/tools/repl-tool.d.ts +0 -0
  211. /package/dist/{skills → types/skills}/tools/search-tool.d.ts +0 -0
  212. /package/dist/{skills → types/skills}/tools/send-message-tool.d.ts +0 -0
  213. /package/dist/{skills → types/skills}/tools/skill-list-tool.d.ts +0 -0
  214. /package/dist/{skills → types/skills}/tools/skill-manage-tool.d.ts +0 -0
  215. /package/dist/{skills → types/skills}/tools/skill-view-tool.d.ts +0 -0
  216. /package/dist/{skills → types/skills}/tools/sleep-tool.d.ts +0 -0
  217. /package/dist/{skills → types/skills}/tools/structured-output-tool.d.ts +0 -0
  218. /package/dist/{skills → types/skills}/tools/task-tool.d.ts +0 -0
  219. /package/dist/{skills → types/skills}/tools/team-tool.d.ts +0 -0
  220. /package/dist/{skills → types/skills}/tools/tool-search-tool.d.ts +0 -0
  221. /package/dist/{skills → types/skills}/tools/tts-tool.d.ts +0 -0
  222. /package/dist/{skills → types/skills}/tools/video-edit-tool.d.ts +0 -0
  223. /package/dist/{skills → types/skills}/tools/video-generate-tool.d.ts +0 -0
  224. /package/dist/{skills → types/skills}/tools/video-merge-tool.d.ts +0 -0
  225. /package/dist/{skills → types/skills}/tools/video-upscale-tool.d.ts +0 -0
  226. /package/dist/{skills → types/skills}/tools/web-fetch-tool.d.ts +0 -0
  227. /package/dist/{skills → types/skills}/tools/web-search-tool.d.ts +0 -0
  228. /package/dist/{skills → types/skills}/tools/worktree-tool.d.ts +0 -0
  229. /package/dist/{skills → types/skills}/tools/write-tool.d.ts +0 -0
@@ -1,133 +0,0 @@
1
- import { injectDanglingToolCallPlaceholders, repairOpenAiResponsesItems, stripForcedStopAssistantToolMetadata, sanitizeOpenAiChatMessages, } from "./conversation-repair.js";
2
- function collectChatPendingToolCallIds(messages) {
3
- const called = new Set();
4
- const completed = new Set();
5
- for (const message of messages) {
6
- if (message.role === "assistant" && Array.isArray(message.tool_calls)) {
7
- for (const toolCall of message.tool_calls) {
8
- if (typeof toolCall.id === "string" && toolCall.id) {
9
- called.add(toolCall.id);
10
- }
11
- }
12
- }
13
- if (message.role === "tool" && typeof message.tool_call_id === "string" && message.tool_call_id) {
14
- completed.add(message.tool_call_id);
15
- }
16
- }
17
- return [...called].filter((callId) => !completed.has(callId));
18
- }
19
- function collectChatCompletedToolCallIds(messages) {
20
- const completed = new Set();
21
- for (const message of messages) {
22
- if (message.role === "tool" && typeof message.tool_call_id === "string" && message.tool_call_id) {
23
- completed.add(message.tool_call_id);
24
- }
25
- }
26
- return [...completed];
27
- }
28
- function collectResponsesPendingToolCallIds(items) {
29
- const called = new Set();
30
- const completed = new Set();
31
- for (const item of items) {
32
- if (item.type === "function_call") {
33
- const callId = typeof item.call_id === "string" && item.call_id
34
- ? item.call_id
35
- : typeof item.id === "string"
36
- ? item.id
37
- : "";
38
- if (callId) {
39
- called.add(callId);
40
- }
41
- }
42
- if (item.type === "function_call_output" && typeof item.call_id === "string" && item.call_id) {
43
- completed.add(item.call_id);
44
- }
45
- }
46
- return [...called].filter((callId) => !completed.has(callId));
47
- }
48
- function collectResponsesCompletedToolCallIds(items) {
49
- const completed = new Set();
50
- for (const item of items) {
51
- if (item.type === "function_call_output" && typeof item.call_id === "string" && item.call_id) {
52
- completed.add(item.call_id);
53
- }
54
- }
55
- return [...completed];
56
- }
57
- export function createToolLoopState(params) {
58
- return {
59
- round: params.round ?? 0,
60
- maxRounds: params.maxRounds,
61
- pendingToolCallIds: [...(params.pendingToolCallIds ?? [])],
62
- completedToolCallIds: [...(params.completedToolCallIds ?? [])],
63
- lastStopReason: params.lastStopReason,
64
- replayMessages: [...(params.replayMessages ?? [])],
65
- };
66
- }
67
- export function advanceToolLoopState(state, params) {
68
- return {
69
- round: state.round + 1,
70
- maxRounds: state.maxRounds,
71
- pendingToolCallIds: [...(params.pendingToolCallIds ?? state.pendingToolCallIds)],
72
- completedToolCallIds: [...(params.completedToolCallIds ?? state.completedToolCallIds)],
73
- lastStopReason: params.lastStopReason ?? state.lastStopReason,
74
- replayMessages: [...(params.replayMessages ?? state.replayMessages)],
75
- };
76
- }
77
- export function settleToolLoopState(state, params) {
78
- return {
79
- round: state.round,
80
- maxRounds: state.maxRounds,
81
- pendingToolCallIds: [],
82
- completedToolCallIds: [...(params.completedToolCallIds ?? state.completedToolCallIds)],
83
- lastStopReason: params.lastStopReason ?? state.lastStopReason,
84
- replayMessages: [...(params.replayMessages ?? state.replayMessages)],
85
- };
86
- }
87
- export function recoverToolLoopStateFromChatConversation(params) {
88
- const recoveryActions = [];
89
- const sanitizedMessages = sanitizeOpenAiChatMessages(params.replayMessages);
90
- if (sanitizedMessages.length !== params.replayMessages.length) {
91
- recoveryActions.push({ kind: "drop-orphan-tool-result", detail: "Removed orphan tool results or invalid assistant tool calls." });
92
- }
93
- const strippedMessages = stripForcedStopAssistantToolMetadata(sanitizedMessages, params.options);
94
- if (strippedMessages.some((message, index) => message !== sanitizedMessages[index])) {
95
- recoveryActions.push({ kind: "strip-forced-stop-tool-metadata", detail: "Removed assistant tool-call metadata after forced stop." });
96
- }
97
- const repairedMessages = injectDanglingToolCallPlaceholders(strippedMessages, params.options);
98
- if (repairedMessages.length > strippedMessages.length) {
99
- recoveryActions.push({ kind: "inject-placeholder-tool-result", detail: "Injected placeholder tool result for pending tool calls." });
100
- }
101
- return {
102
- state: createToolLoopState({
103
- maxRounds: params.maxRounds,
104
- round: params.round,
105
- lastStopReason: params.lastStopReason,
106
- replayMessages: repairedMessages,
107
- pendingToolCallIds: collectChatPendingToolCallIds(repairedMessages),
108
- completedToolCallIds: collectChatCompletedToolCallIds(repairedMessages),
109
- }),
110
- recoveryActions,
111
- };
112
- }
113
- export function recoverToolLoopStateFromResponsesItems(params) {
114
- const repairedItems = repairOpenAiResponsesItems(params.replayItems, params.options);
115
- const recoveryActions = [];
116
- if (repairedItems.length !== params.replayItems.length) {
117
- recoveryActions.push({ kind: "drop-trailing-reasoning", detail: "Dropped dangling reasoning blocks or injected missing function_call_output items." });
118
- }
119
- if (repairedItems.some((item, index) => item !== params.replayItems[index] && item.type === "function_call")) {
120
- recoveryActions.push({ kind: "rewrite-openai-function-call-pair", detail: "Rewrote OpenAI function_call pairing ids for replay compatibility." });
121
- }
122
- return {
123
- state: createToolLoopState({
124
- maxRounds: params.maxRounds,
125
- round: params.round,
126
- lastStopReason: params.lastStopReason,
127
- replayMessages: repairedItems,
128
- pendingToolCallIds: collectResponsesPendingToolCallIds(repairedItems),
129
- completedToolCallIds: collectResponsesCompletedToolCallIds(repairedItems),
130
- }),
131
- recoveryActions,
132
- };
133
- }
@@ -1,297 +0,0 @@
1
- function extractEnumValues(schema) {
2
- if (!schema || typeof schema !== "object") {
3
- return undefined;
4
- }
5
- const record = schema;
6
- if (Array.isArray(record.enum)) {
7
- return record.enum;
8
- }
9
- if ("const" in record) {
10
- return [record.const];
11
- }
12
- const variants = Array.isArray(record.anyOf)
13
- ? record.anyOf
14
- : Array.isArray(record.oneOf)
15
- ? record.oneOf
16
- : null;
17
- if (!variants) {
18
- return undefined;
19
- }
20
- const values = variants.flatMap((variant) => extractEnumValues(variant) ?? []);
21
- return values.length > 0 ? values : undefined;
22
- }
23
- function mergePropertySchemas(existing, incoming) {
24
- if (!existing)
25
- return incoming;
26
- if (!incoming)
27
- return existing;
28
- const existingEnum = extractEnumValues(existing);
29
- const incomingEnum = extractEnumValues(incoming);
30
- if (!existingEnum && !incomingEnum) {
31
- return existing;
32
- }
33
- const values = Array.from(new Set([...(existingEnum ?? []), ...(incomingEnum ?? [])]));
34
- const merged = {};
35
- for (const source of [existing, incoming]) {
36
- if (!source || typeof source !== "object") {
37
- continue;
38
- }
39
- const record = source;
40
- for (const key of ["title", "description", "default"]) {
41
- if (!(key in merged) && key in record) {
42
- merged[key] = record[key];
43
- }
44
- }
45
- }
46
- const types = new Set(values.map((value) => typeof value));
47
- if (types.size === 1) {
48
- merged.type = Array.from(types)[0];
49
- }
50
- merged.enum = values;
51
- return merged;
52
- }
53
- const GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS = new Set([
54
- "patternProperties",
55
- "additionalProperties",
56
- "$schema",
57
- "$id",
58
- "$ref",
59
- "$defs",
60
- "definitions",
61
- "examples",
62
- "minLength",
63
- "maxLength",
64
- "minimum",
65
- "maximum",
66
- "multipleOf",
67
- "pattern",
68
- "format",
69
- "minItems",
70
- "maxItems",
71
- "uniqueItems",
72
- "minProperties",
73
- "maxProperties",
74
- ]);
75
- const XAI_UNSUPPORTED_SCHEMA_KEYWORDS = new Set([
76
- "minLength",
77
- "maxLength",
78
- "minItems",
79
- "maxItems",
80
- "minContains",
81
- "maxContains",
82
- ]);
83
- function cleanSchemaForGemini(schema) {
84
- if (!schema || typeof schema !== "object") {
85
- return schema;
86
- }
87
- if (Array.isArray(schema)) {
88
- return schema.map((item) => cleanSchemaForGemini(item));
89
- }
90
- const record = schema;
91
- const cleaned = {};
92
- for (const [key, value] of Object.entries(record)) {
93
- if (GEMINI_UNSUPPORTED_SCHEMA_KEYWORDS.has(key)) {
94
- continue;
95
- }
96
- if (key === "properties" && value && typeof value === "object" && !Array.isArray(value)) {
97
- cleaned[key] = Object.fromEntries(Object.entries(value).map(([nestedKey, nestedValue]) => [nestedKey, cleanSchemaForGemini(nestedValue)]));
98
- continue;
99
- }
100
- if ((key === "items" || key === "additionalProperties") && value && typeof value === "object") {
101
- cleaned[key] = Array.isArray(value) ? value.map((item) => cleanSchemaForGemini(item)) : cleanSchemaForGemini(value);
102
- continue;
103
- }
104
- if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) {
105
- cleaned[key] = value.map((item) => cleanSchemaForGemini(item));
106
- continue;
107
- }
108
- cleaned[key] = value;
109
- }
110
- return cleaned;
111
- }
112
- function stripXaiUnsupportedKeywords(schema) {
113
- if (!schema || typeof schema !== "object") {
114
- return schema;
115
- }
116
- if (Array.isArray(schema)) {
117
- return schema.map((item) => stripXaiUnsupportedKeywords(item));
118
- }
119
- const record = schema;
120
- const cleaned = {};
121
- for (const [key, value] of Object.entries(record)) {
122
- if (XAI_UNSUPPORTED_SCHEMA_KEYWORDS.has(key)) {
123
- continue;
124
- }
125
- if (key === "properties" && value && typeof value === "object" && !Array.isArray(value)) {
126
- cleaned[key] = Object.fromEntries(Object.entries(value).map(([nestedKey, nestedValue]) => [nestedKey, stripXaiUnsupportedKeywords(nestedValue)]));
127
- continue;
128
- }
129
- if ((key === "items") && value && typeof value === "object") {
130
- cleaned[key] = Array.isArray(value) ? value.map((item) => stripXaiUnsupportedKeywords(item)) : stripXaiUnsupportedKeywords(value);
131
- continue;
132
- }
133
- if ((key === "anyOf" || key === "oneOf" || key === "allOf") && Array.isArray(value)) {
134
- cleaned[key] = value.map((item) => stripXaiUnsupportedKeywords(item));
135
- continue;
136
- }
137
- cleaned[key] = value;
138
- }
139
- return cleaned;
140
- }
141
- export function isXaiProvider(modelProvider, modelId) {
142
- const provider = modelProvider?.toLowerCase() ?? "";
143
- if (provider.includes("xai") || provider.includes("x-ai")) {
144
- return true;
145
- }
146
- const lowerModelId = modelId?.toLowerCase() ?? "";
147
- if (provider === "openrouter" && lowerModelId.startsWith("x-ai/")) {
148
- return true;
149
- }
150
- if (provider === "venice" && lowerModelId.includes("grok")) {
151
- return true;
152
- }
153
- return false;
154
- }
155
- export function normalizeFunctionToolParameters(parameters, options) {
156
- const schema = parameters && typeof parameters === "object" ? parameters : { type: "object", properties: {}, additionalProperties: true };
157
- const isGeminiProvider = options?.modelProvider?.toLowerCase().includes("google") || options?.modelProvider?.toLowerCase().includes("gemini");
158
- const isAnthropicProvider = options?.modelProvider?.toLowerCase().includes("anthropic");
159
- const isXai = isXaiProvider(options?.modelProvider, options?.modelId);
160
- const applyProviderCleaning = (nextSchema) => {
161
- if (isGeminiProvider && !isAnthropicProvider) {
162
- return cleanSchemaForGemini(nextSchema);
163
- }
164
- if (isXai) {
165
- return stripXaiUnsupportedKeywords(nextSchema);
166
- }
167
- return nextSchema;
168
- };
169
- if ("type" in schema && "properties" in schema && !Array.isArray(schema.anyOf)) {
170
- return applyProviderCleaning(schema);
171
- }
172
- if (!("type" in schema)
173
- && (typeof schema.properties === "object" || Array.isArray(schema.required))
174
- && !Array.isArray(schema.anyOf)
175
- && !Array.isArray(schema.oneOf)) {
176
- return applyProviderCleaning({ ...schema, type: "object" });
177
- }
178
- const variantKey = Array.isArray(schema.anyOf)
179
- ? "anyOf"
180
- : Array.isArray(schema.oneOf)
181
- ? "oneOf"
182
- : null;
183
- if (!variantKey) {
184
- return applyProviderCleaning(schema);
185
- }
186
- const variants = schema[variantKey];
187
- const mergedProperties = {};
188
- const requiredCounts = new Map();
189
- let objectVariants = 0;
190
- for (const entry of variants) {
191
- if (!entry || typeof entry !== "object") {
192
- continue;
193
- }
194
- const props = entry.properties;
195
- if (!props || typeof props !== "object") {
196
- continue;
197
- }
198
- objectVariants += 1;
199
- for (const [key, value] of Object.entries(props)) {
200
- mergedProperties[key] = key in mergedProperties ? mergePropertySchemas(mergedProperties[key], value) : value;
201
- }
202
- const required = Array.isArray(entry.required)
203
- ? entry.required
204
- : [];
205
- for (const key of required) {
206
- if (typeof key === "string") {
207
- requiredCounts.set(key, (requiredCounts.get(key) ?? 0) + 1);
208
- }
209
- }
210
- }
211
- const baseRequired = Array.isArray(schema.required) ? schema.required.filter((key) => typeof key === "string") : undefined;
212
- const mergedRequired = baseRequired && baseRequired.length > 0
213
- ? baseRequired
214
- : objectVariants > 0
215
- ? Array.from(requiredCounts.entries()).filter(([, count]) => count === objectVariants).map(([key]) => key)
216
- : undefined;
217
- return applyProviderCleaning({
218
- type: "object",
219
- ...(typeof schema.title === "string" ? { title: schema.title } : {}),
220
- ...(typeof schema.description === "string" ? { description: schema.description } : {}),
221
- properties: Object.keys(mergedProperties).length > 0 ? mergedProperties : (schema.properties ?? {}),
222
- ...(mergedRequired && mergedRequired.length > 0 ? { required: mergedRequired } : {}),
223
- additionalProperties: "additionalProperties" in schema ? schema.additionalProperties : true,
224
- });
225
- }
226
- export function convertFunctionTools(tools, options) {
227
- return tools.map((tool) => ({
228
- type: "function",
229
- function: {
230
- name: tool.name,
231
- ...(typeof tool.description === "string" ? { description: tool.description } : {}),
232
- parameters: normalizeFunctionToolParameters(tool.parameters, options),
233
- },
234
- }));
235
- }
236
- export function convertCapabilityToolManifestsToFunctionTools(tools) {
237
- return convertFunctionTools(tools.map((tool) => ({
238
- name: tool.name,
239
- description: tool.description,
240
- parameters: {
241
- type: "object",
242
- properties: Object.fromEntries((tool.requiredParameters ?? []).map((name) => [name, { type: "string" }])),
243
- additionalProperties: true,
244
- ...((tool.requiredParameters?.length ?? 0) > 0 ? { required: tool.requiredParameters } : {}),
245
- },
246
- })));
247
- }
248
- export function normalizeMessageTextContent(content) {
249
- if (typeof content === "string") {
250
- return content;
251
- }
252
- if (!Array.isArray(content)) {
253
- return "";
254
- }
255
- return content.map((entry) => {
256
- if (typeof entry === "string") {
257
- return entry;
258
- }
259
- if (entry && typeof entry === "object" && "text" in entry && typeof entry.text === "string") {
260
- return entry.text;
261
- }
262
- return "";
263
- }).filter(Boolean).join("\n");
264
- }
265
- export function parseOpenAiToolCallsFromChatResponse(responseBody) {
266
- try {
267
- const parsed = JSON.parse(responseBody);
268
- const firstChoice = parsed.choices?.[0]?.message;
269
- const toolCalls = Array.isArray(firstChoice?.tool_calls)
270
- ? firstChoice.tool_calls.filter((entry) => entry?.type === "function" && typeof entry.function?.name === "string")
271
- : [];
272
- return {
273
- toolCalls,
274
- responseText: normalizeMessageTextContent(firstChoice?.content),
275
- };
276
- }
277
- catch {
278
- return { toolCalls: [], responseText: "" };
279
- }
280
- }
281
- export function buildAssistantToolCallMessage(toolCalls) {
282
- return {
283
- role: "assistant",
284
- content: "",
285
- tool_calls: toolCalls,
286
- };
287
- }
288
- export function buildToolResultMessage(callId, result) {
289
- return {
290
- role: "tool",
291
- tool_call_id: callId,
292
- content: JSON.stringify(result.ok ? { ok: true, payload: result.payload } : { ok: false, error: result.error ?? "Tool invoke failed" }),
293
- };
294
- }
295
- export function cleanToolSchemaForGemini(schema) {
296
- return cleanSchemaForGemini(schema);
297
- }