@jsonstudio/llms 0.6.2979 → 0.6.3238

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 (246) hide show
  1. package/dist/conversion/args-mapping.js +8 -0
  2. package/dist/conversion/{shared/bridge-actions.js → bridge-actions.js} +2 -1
  3. package/dist/conversion/{shared/bridge-id-utils.js → bridge-id-utils.js} +1 -1
  4. package/dist/conversion/{shared/bridge-instructions.js → bridge-instructions.js} +1 -1
  5. package/dist/conversion/{shared/bridge-message-utils.d.ts → bridge-message-utils.d.ts} +1 -1
  6. package/dist/conversion/{shared/bridge-message-utils.js → bridge-message-utils.js} +5 -149
  7. package/dist/conversion/{shared/bridge-metadata.js → bridge-metadata.js} +1 -1
  8. package/dist/conversion/{shared/bridge-policies.js → bridge-policies.js} +1 -1
  9. package/dist/conversion/codecs/gemini-openai-codec.js +27 -8
  10. package/dist/conversion/codecs/responses-openai-codec.js +1 -1
  11. package/dist/conversion/{shared/compaction-detect.d.ts → compaction-detect.d.ts} +1 -1
  12. package/dist/conversion/compaction-detect.js +4 -0
  13. package/dist/conversion/compat/actions/apply-patch-fixer.js +2 -2
  14. package/dist/conversion/compat/actions/deepseek-web-response.d.ts +0 -1
  15. package/dist/conversion/compat/actions/deepseek-web-response.js +15 -405
  16. package/dist/conversion/compat/actions/harvest-tool-calls-from-text.js +1 -1
  17. package/dist/conversion/compat/actions/lmstudio-responses-fc-ids.js +1 -1
  18. package/dist/conversion/compat/actions/qwen-transform.js +74 -2
  19. package/dist/conversion/compat/actions/snapshot.js +1 -1
  20. package/dist/conversion/compat/antigravity-session-signature.js +36 -0
  21. package/dist/conversion/compat/profiles/chat-deepseek-web.json +0 -22
  22. package/dist/conversion/compat/profiles/chat-glm.json +251 -72
  23. package/dist/conversion/compat/profiles/chat-iflow.json +174 -39
  24. package/dist/conversion/compat/profiles/chat-lmstudio.json +43 -14
  25. package/dist/conversion/hub/operation-table/operation-table-runner.js +2 -2
  26. package/dist/conversion/hub/operation-table/semantic-mappers/anthropic-mapper.js +1 -1
  27. package/dist/conversion/hub/operation-table/semantic-mappers/archive/chat-mapper.archive.d.ts +8 -0
  28. package/dist/conversion/hub/operation-table/semantic-mappers/archive/chat-mapper.archive.js +404 -0
  29. package/dist/conversion/hub/operation-table/semantic-mappers/chat-mapper.js +5 -381
  30. package/dist/conversion/hub/operation-table/semantic-mappers/gemini-mapper.js +2 -2
  31. package/dist/conversion/hub/operation-table/semantic-mappers/responses-mapper.js +2 -8
  32. package/dist/conversion/hub/pipeline/hub-pipeline.d.ts +1 -0
  33. package/dist/conversion/hub/pipeline/hub-pipeline.js +50 -3
  34. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.d.ts +1 -1
  35. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage2_semantic_map/index.js +62 -0
  36. package/dist/conversion/hub/pipeline/stages/req_process/req_process_stage2_route_select/index.js +3 -1
  37. package/dist/conversion/hub/pipeline/stages/resp_inbound/resp_inbound_stage1_sse_decode/index.js +1 -1
  38. package/dist/conversion/hub/pipeline/stages/resp_outbound/resp_outbound_stage1_client_remap/chat-process-semantics-bridge.d.ts +1 -1
  39. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage1_tool_governance/index.js +42 -29
  40. package/dist/conversion/hub/pipeline/stages/resp_process/resp_process_stage2_finalize/index.js +12 -0
  41. package/dist/conversion/hub/policy/protocol-spec.js +1 -1
  42. package/dist/conversion/hub/process/chat-process-clock-reminders.js +1 -1
  43. package/dist/conversion/hub/process/chat-process-clock-tools.js +1 -1
  44. package/dist/conversion/hub/process/chat-process-continue-execution.js +1 -1
  45. package/dist/conversion/hub/process/chat-process-servertool-orchestration.js +1 -1
  46. package/dist/conversion/hub/process/chat-process-web-search.js +1 -1
  47. package/dist/conversion/hub/response/provider-response.js +14 -5
  48. package/dist/conversion/hub/response/response-mappers.js +23 -1
  49. package/dist/conversion/hub/response/response-runtime.js +28 -5
  50. package/dist/conversion/hub/snapshot-recorder.js +3 -92
  51. package/dist/conversion/hub/tool-governance/engine.d.ts +8 -0
  52. package/dist/conversion/hub/tool-governance/engine.js +40 -193
  53. package/dist/conversion/hub/tool-governance/rules.js +73 -69
  54. package/dist/conversion/hub/tool-surface/tool-surface-engine.js +1 -1
  55. package/dist/conversion/index.d.ts +1 -2
  56. package/dist/conversion/index.js +1 -2
  57. package/dist/conversion/{shared/jsonish.js → jsonish.js} +1 -1
  58. package/dist/conversion/{shared/mcp-injection.js → mcp-injection.js} +1 -1
  59. package/dist/conversion/media.js +4 -0
  60. package/dist/conversion/{shared/metadata-passthrough.d.ts → metadata-passthrough.d.ts} +1 -1
  61. package/dist/conversion/{shared/metadata-passthrough.js → metadata-passthrough.js} +2 -2
  62. package/dist/conversion/payload-budget.js +47 -0
  63. package/dist/conversion/protocol-field-allowlists.d.ts +7 -0
  64. package/dist/conversion/protocol-field-allowlists.js +9 -0
  65. package/dist/conversion/{shared/protocol-state.d.ts → protocol-state.d.ts} +2 -2
  66. package/dist/conversion/{shared/protocol-state.js → protocol-state.js} +2 -2
  67. package/dist/conversion/{shared/errors.d.ts → provider-protocol-error.d.ts} +0 -3
  68. package/dist/conversion/provider-protocol-error.js +25 -0
  69. package/dist/conversion/responses/responses-openai-bridge/response-payload.js +8 -5
  70. package/dist/conversion/responses/responses-openai-bridge/types.d.ts +1 -1
  71. package/dist/conversion/responses/responses-openai-bridge.d.ts +1 -1
  72. package/dist/conversion/responses/responses-openai-bridge.js +43 -10
  73. package/dist/conversion/{shared/runtime-metadata.d.ts → runtime-metadata.d.ts} +1 -1
  74. package/dist/conversion/{shared/runtime-metadata.js → runtime-metadata.js} +2 -2
  75. package/dist/conversion/shared/anthropic-message-utils.js +19 -8
  76. package/dist/conversion/shared/chat-request-filters.d.ts +3 -4
  77. package/dist/conversion/shared/chat-request-filters.js +22 -78
  78. package/dist/conversion/shared/gemini-tool-utils.d.ts +1 -1
  79. package/dist/conversion/shared/openai-finalizer.js +1 -0
  80. package/dist/conversion/shared/openai-message-normalize.js +2 -2
  81. package/dist/conversion/shared/reasoning-normalizer.js +6 -0
  82. package/dist/conversion/shared/reasoning-utils.js +5 -2
  83. package/dist/conversion/shared/responses-conversation-store.js +1 -1
  84. package/dist/conversion/shared/responses-output-builder.js +55 -11
  85. package/dist/conversion/shared/responses-reasoning-registry.d.ts +14 -2
  86. package/dist/conversion/shared/responses-reasoning-registry.js +34 -6
  87. package/dist/conversion/shared/responses-response-utils.js +99 -9
  88. package/dist/conversion/shared/responses-tool-utils.js +1 -1
  89. package/dist/conversion/shared/text-markup-normalizer/normalize.d.ts +1 -1
  90. package/dist/conversion/shared/text-markup-normalizer.d.ts +2 -2
  91. package/dist/conversion/shared/text-markup-normalizer.js +1 -1
  92. package/dist/conversion/shared/tool-filter-pipeline.js +1 -1
  93. package/dist/conversion/shared/tool-governor.js +3 -3
  94. package/dist/conversion/shared/tool-mapping.d.ts +1 -1
  95. package/dist/conversion/{shared/snapshot-utils.d.ts → snapshot-utils.d.ts} +11 -0
  96. package/dist/conversion/{shared/snapshot-utils.js → snapshot-utils.js} +14 -23
  97. package/dist/conversion/types/text-markup-normalizer.d.ts +13 -0
  98. package/dist/conversion/types/text-markup-normalizer.js +1 -0
  99. package/dist/filters/special/request-tools-normalize.js +1 -1
  100. package/dist/filters/special/response-tool-text-canonicalize.js +2 -2
  101. package/dist/native/router_hotpath_napi.node +0 -0
  102. package/dist/quota/quota-manager.js +31 -59
  103. package/dist/quota/quota-state.js +14 -7
  104. package/dist/router/virtual-router/bootstrap/profile-builder.d.ts +1 -0
  105. package/dist/router/virtual-router/bootstrap/profile-builder.js +13 -0
  106. package/dist/router/virtual-router/bootstrap/provider-normalization.d.ts +2 -0
  107. package/dist/router/virtual-router/bootstrap/provider-normalization.js +4 -1
  108. package/dist/router/virtual-router/bootstrap/streaming-helpers.d.ts +7 -0
  109. package/dist/router/virtual-router/bootstrap/streaming-helpers.js +44 -0
  110. package/dist/router/virtual-router/bootstrap.js +2 -0
  111. package/dist/router/virtual-router/engine/routing-state/store.d.ts +1 -2
  112. package/dist/router/virtual-router/engine/routing-state/store.js +2 -2
  113. package/dist/router/virtual-router/engine-legacy/config.d.ts +11 -0
  114. package/dist/router/virtual-router/engine-legacy/config.js +108 -0
  115. package/dist/router/virtual-router/engine-legacy/direct-model.d.ts +10 -0
  116. package/dist/router/virtual-router/engine-legacy/direct-model.js +38 -0
  117. package/dist/router/virtual-router/engine-legacy/health.d.ts +13 -0
  118. package/dist/router/virtual-router/engine-legacy/health.js +104 -0
  119. package/dist/router/virtual-router/engine-legacy/helpers.d.ts +16 -0
  120. package/dist/router/virtual-router/engine-legacy/helpers.js +226 -0
  121. package/dist/router/virtual-router/engine-legacy/route-finalize.d.ts +9 -0
  122. package/dist/router/virtual-router/engine-legacy/route-finalize.js +84 -0
  123. package/dist/router/virtual-router/engine-legacy/route-selection.d.ts +17 -0
  124. package/dist/router/virtual-router/engine-legacy/route-selection.js +205 -0
  125. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.d.ts +3 -0
  126. package/dist/router/virtual-router/engine-legacy/route-state-allowlist.js +36 -0
  127. package/dist/router/virtual-router/engine-legacy/route-state.d.ts +12 -0
  128. package/dist/router/virtual-router/engine-legacy/route-state.js +386 -0
  129. package/dist/router/virtual-router/engine-legacy/route-utils.d.ts +19 -0
  130. package/dist/router/virtual-router/engine-legacy/route-utils.js +212 -0
  131. package/dist/router/virtual-router/engine-legacy/routing.d.ts +8 -0
  132. package/dist/router/virtual-router/engine-legacy/routing.js +8 -0
  133. package/dist/router/virtual-router/engine-legacy/selection-core.d.ts +28 -0
  134. package/dist/router/virtual-router/engine-legacy/selection-core.js +112 -0
  135. package/dist/router/virtual-router/engine-legacy/selection-state.d.ts +16 -0
  136. package/dist/router/virtual-router/engine-legacy/selection-state.js +187 -0
  137. package/dist/router/virtual-router/engine-legacy/state-accessors.d.ts +21 -0
  138. package/dist/router/virtual-router/engine-legacy/state-accessors.js +118 -0
  139. package/dist/router/virtual-router/engine-legacy.d.ts +123 -0
  140. package/dist/router/virtual-router/engine-legacy.js +194 -0
  141. package/dist/router/virtual-router/engine-logging.d.ts +2 -0
  142. package/dist/router/virtual-router/engine-logging.js +7 -2
  143. package/dist/router/virtual-router/engine-selection/key-parsing.js +0 -3
  144. package/dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.d.ts +1 -0
  145. package/dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.js +54 -0
  146. package/dist/router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.d.ts +10 -0
  147. package/dist/router/virtual-router/engine-selection/native-hub-bridge-policy-semantics.js +67 -0
  148. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.d.ts +30 -0
  149. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-governance-semantics.js +202 -0
  150. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-semantic-mappers.d.ts +2 -0
  151. package/dist/router/virtual-router/engine-selection/native-hub-pipeline-semantic-mappers.js +83 -0
  152. package/dist/router/virtual-router/engine-selection/native-router-hotpath-loader.js +43 -2
  153. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.d.ts +75 -0
  154. package/dist/router/virtual-router/engine-selection/native-shared-conversion-semantics.js +205 -0
  155. package/dist/router/virtual-router/engine-selection/native-snapshot-hooks.d.ts +3 -0
  156. package/dist/router/virtual-router/engine-selection/native-snapshot-hooks.js +109 -0
  157. package/dist/router/virtual-router/engine-selection/native-virtual-router-engine-proxy.d.ts +16 -0
  158. package/dist/router/virtual-router/engine-selection/native-virtual-router-engine-proxy.js +14 -0
  159. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.d.ts +2 -0
  160. package/dist/router/virtual-router/engine-selection/native-virtual-router-routing-instructions-semantics.js +86 -0
  161. package/dist/router/virtual-router/engine-selection/tier-selection-quota-integration.js +100 -0
  162. package/dist/router/virtual-router/engine-selection/tier-selection-select.js +99 -0
  163. package/dist/router/virtual-router/engine.d.ts +22 -105
  164. package/dist/router/virtual-router/engine.js +274 -1641
  165. package/dist/router/virtual-router/load-balancer.d.ts +8 -0
  166. package/dist/router/virtual-router/load-balancer.js +65 -2
  167. package/dist/router/virtual-router/provider-registry.js +2 -0
  168. package/dist/router/virtual-router/routing-instructions/clean.d.ts +3 -0
  169. package/dist/router/virtual-router/routing-instructions/clean.js +34 -0
  170. package/dist/router/virtual-router/routing-instructions/parse.d.ts +18 -0
  171. package/dist/router/virtual-router/routing-instructions/parse.js +377 -0
  172. package/dist/router/virtual-router/routing-instructions/state.d.ts +4 -0
  173. package/dist/router/virtual-router/routing-instructions/state.js +245 -0
  174. package/dist/router/virtual-router/routing-instructions/types.d.ts +70 -0
  175. package/dist/router/virtual-router/routing-instructions/types.js +2 -0
  176. package/dist/router/virtual-router/routing-instructions.d.ts +5 -89
  177. package/dist/router/virtual-router/routing-instructions.js +4 -655
  178. package/dist/router/virtual-router/sticky-session-store.d.ts +4 -0
  179. package/dist/router/virtual-router/sticky-session-store.js +19 -81
  180. package/dist/router/virtual-router/tool-signals.js +21 -3
  181. package/dist/router/virtual-router/types.d.ts +4 -0
  182. package/dist/servertool/clock/session-scope.js +32 -1
  183. package/dist/servertool/engine.js +79 -8
  184. package/dist/servertool/handlers/antigravity-thought-signature-bootstrap.js +1 -1
  185. package/dist/servertool/handlers/clock-auto.js +1 -1
  186. package/dist/servertool/handlers/clock.js +1 -1
  187. package/dist/servertool/handlers/compaction-detect.d.ts +1 -1
  188. package/dist/servertool/handlers/compaction-detect.js +1 -1
  189. package/dist/servertool/handlers/gemini-empty-reply-continue.js +1 -1
  190. package/dist/servertool/handlers/iflow-model-error-retry.js +1 -1
  191. package/dist/servertool/handlers/recursive-detection-guard.js +1 -1
  192. package/dist/servertool/handlers/review.js +1 -1
  193. package/dist/servertool/handlers/stop-message-auto/iflow-followup.js +1 -1
  194. package/dist/servertool/handlers/stop-message-auto/runtime-utils.js +1 -1
  195. package/dist/servertool/handlers/stop-message-auto.js +1 -1
  196. package/dist/servertool/handlers/vision.js +1 -1
  197. package/dist/servertool/handlers/web-search.js +1 -1
  198. package/dist/servertool/reenter-backend.js +1 -1
  199. package/dist/servertool/server-side-tools.js +2 -2
  200. package/dist/servertool/stop-gateway-context.js +1 -1
  201. package/dist/servertool/stop-message-compare-context.js +1 -1
  202. package/dist/sse/json-to-sse/event-generators/responses.d.ts +4 -0
  203. package/dist/sse/json-to-sse/event-generators/responses.js +95 -1
  204. package/dist/sse/json-to-sse/sequencers/responses-sequencer.js +6 -4
  205. package/dist/sse/sse-to-json/builders/response-builder.d.ts +8 -0
  206. package/dist/sse/sse-to-json/builders/response-builder.js +162 -4
  207. package/dist/sse/sse-to-json/responses-sse-to-json-converter.js +2 -0
  208. package/dist/sse/types/responses-types.d.ts +6 -2
  209. package/dist/tools/apply-patch/structured/coercion.js +5 -0
  210. package/dist/tools/args-json.js +29 -0
  211. package/package.json +8 -5
  212. package/dist/conversion/shared/args-mapping.js +0 -77
  213. package/dist/conversion/shared/compaction-detect.js +0 -4
  214. package/dist/conversion/shared/errors.js +0 -31
  215. package/dist/conversion/shared/media.js +0 -4
  216. package/dist/conversion/shared/payload-budget.js +0 -165
  217. package/dist/conversion/shared/protocol-field-allowlists.d.ts +0 -7
  218. package/dist/conversion/shared/protocol-field-allowlists.js +0 -149
  219. package/dist/conversion/shared/snapshot-hooks.d.ts +0 -11
  220. package/dist/conversion/shared/snapshot-hooks.js +0 -503
  221. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.d.ts +0 -2
  222. package/dist/conversion/shared/text-markup-normalizer/extractors-apply-patch.js +0 -129
  223. package/dist/conversion/shared/text-markup-normalizer/extractors-json.d.ts +0 -4
  224. package/dist/conversion/shared/text-markup-normalizer/extractors-json.js +0 -637
  225. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.d.ts +0 -21
  226. package/dist/conversion/shared/text-markup-normalizer/extractors-shared.js +0 -177
  227. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.d.ts +0 -5
  228. package/dist/conversion/shared/text-markup-normalizer/extractors-transcript.js +0 -385
  229. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.d.ts +0 -10
  230. package/dist/conversion/shared/text-markup-normalizer/extractors-xml.js +0 -602
  231. package/dist/conversion/shared/text-markup-normalizer/extractors.d.ts +0 -5
  232. package/dist/conversion/shared/text-markup-normalizer/extractors.js +0 -4
  233. package/dist/conversion/shared/tool-canonicalizer.d.ts +0 -2
  234. package/dist/conversion/shared/tool-canonicalizer.js +0 -38
  235. /package/dist/conversion/{shared/args-mapping.d.ts → args-mapping.d.ts} +0 -0
  236. /package/dist/conversion/{shared/bridge-actions.d.ts → bridge-actions.d.ts} +0 -0
  237. /package/dist/conversion/{shared/bridge-id-utils.d.ts → bridge-id-utils.d.ts} +0 -0
  238. /package/dist/conversion/{shared/bridge-instructions.d.ts → bridge-instructions.d.ts} +0 -0
  239. /package/dist/conversion/{shared/bridge-metadata.d.ts → bridge-metadata.d.ts} +0 -0
  240. /package/dist/conversion/{shared/bridge-policies.d.ts → bridge-policies.d.ts} +0 -0
  241. /package/dist/conversion/{shared/jsonish.d.ts → jsonish.d.ts} +0 -0
  242. /package/dist/conversion/{shared/mcp-injection.d.ts → mcp-injection.d.ts} +0 -0
  243. /package/dist/conversion/{shared/media.d.ts → media.d.ts} +0 -0
  244. /package/dist/conversion/{shared/payload-budget.d.ts → payload-budget.d.ts} +0 -0
  245. /package/dist/conversion/{shared → types}/bridge-message-types.d.ts +0 -0
  246. /package/dist/conversion/{shared → types}/bridge-message-types.js +0 -0
@@ -29,6 +29,24 @@ function chunkText(text, config) {
29
29
  return [text];
30
30
  }
31
31
  }
32
+ function normalizeReasoningSummaryEntries(summary) {
33
+ if (!Array.isArray(summary))
34
+ return [];
35
+ const entries = [];
36
+ for (const entry of summary) {
37
+ if (typeof entry === 'string') {
38
+ if (entry.length)
39
+ entries.push(entry);
40
+ continue;
41
+ }
42
+ if (entry && typeof entry === 'object') {
43
+ const text = typeof entry.text === 'string' ? entry.text : '';
44
+ if (text.length)
45
+ entries.push(text);
46
+ }
47
+ }
48
+ return entries;
49
+ }
32
50
  function createResponsePayload(response, overrides = {}) {
33
51
  const raw = response;
34
52
  const usage = normalizeUsage(response.usage);
@@ -213,6 +231,9 @@ export function buildOutputItemStartEvent(outputItem, context, config = DEFAULT_
213
231
  if (reasoning.summary) {
214
232
  itemDescriptor.summary = reasoning.summary;
215
233
  }
234
+ if (typeof reasoning.encrypted_content === 'string' && reasoning.encrypted_content.length) {
235
+ itemDescriptor.encrypted_content = reasoning.encrypted_content;
236
+ }
216
237
  }
217
238
  return {
218
239
  type: 'response.output_item.added',
@@ -441,7 +462,8 @@ export function buildReasoningStartEvent(reasoning, context, config = DEFAULT_RE
441
462
  * 映射:reasoning.delta → response.reasoning_text.delta
442
463
  */
443
464
  export function* buildReasoningDeltas(reasoning, context, config = DEFAULT_RESPONSES_EVENT_GENERATOR_CONFIG) {
444
- for (const content of reasoning.content) {
465
+ const contents = Array.isArray(reasoning.content) ? reasoning.content : [];
466
+ for (const content of contents) {
445
467
  if (content.type === 'reasoning_text') {
446
468
  if (!content.text)
447
469
  continue;
@@ -491,6 +513,78 @@ export function* buildReasoningDeltas(reasoning, context, config = DEFAULT_RESPO
491
513
  }
492
514
  }
493
515
  }
516
+ /**
517
+ * 构建response.reasoning_summary_*事件流
518
+ */
519
+ export function* buildReasoningSummaryEvents(reasoning, context, config = DEFAULT_RESPONSES_EVENT_GENERATOR_CONFIG) {
520
+ const summaries = normalizeReasoningSummaryEntries(reasoning.summary);
521
+ for (let summaryIndex = 0; summaryIndex < summaries.length; summaryIndex++) {
522
+ const text = summaries[summaryIndex];
523
+ if (!text)
524
+ continue;
525
+ const partAddedBase = createBaseEvent(context, config);
526
+ yield {
527
+ type: 'response.reasoning_summary_part.added',
528
+ timestamp: partAddedBase.timestamp,
529
+ protocol: partAddedBase.protocol,
530
+ direction: partAddedBase.direction,
531
+ data: {
532
+ output_index: context.outputIndexCounter,
533
+ item_id: reasoning.id,
534
+ summary_index: summaryIndex,
535
+ part: { type: 'summary_text', text: '' }
536
+ },
537
+ sequenceNumber: partAddedBase.sequenceNumber
538
+ };
539
+ const chunks = chunkText(text, config);
540
+ for (const chunk of chunks) {
541
+ if (!chunk)
542
+ continue;
543
+ const deltaBase = createBaseEvent(context, config);
544
+ yield {
545
+ type: 'response.reasoning_summary_text.delta',
546
+ timestamp: deltaBase.timestamp,
547
+ protocol: deltaBase.protocol,
548
+ direction: deltaBase.direction,
549
+ data: {
550
+ output_index: context.outputIndexCounter,
551
+ item_id: reasoning.id,
552
+ summary_index: summaryIndex,
553
+ delta: chunk
554
+ },
555
+ sequenceNumber: deltaBase.sequenceNumber
556
+ };
557
+ }
558
+ const textDoneBase = createBaseEvent(context, config);
559
+ yield {
560
+ type: 'response.reasoning_summary_text.done',
561
+ timestamp: textDoneBase.timestamp,
562
+ protocol: textDoneBase.protocol,
563
+ direction: textDoneBase.direction,
564
+ data: {
565
+ output_index: context.outputIndexCounter,
566
+ item_id: reasoning.id,
567
+ summary_index: summaryIndex,
568
+ text
569
+ },
570
+ sequenceNumber: textDoneBase.sequenceNumber
571
+ };
572
+ const partDoneBase = createBaseEvent(context, config);
573
+ yield {
574
+ type: 'response.reasoning_summary_part.done',
575
+ timestamp: partDoneBase.timestamp,
576
+ protocol: partDoneBase.protocol,
577
+ direction: partDoneBase.direction,
578
+ data: {
579
+ output_index: context.outputIndexCounter,
580
+ item_id: reasoning.id,
581
+ summary_index: summaryIndex,
582
+ part: { type: 'summary_text', text }
583
+ },
584
+ sequenceNumber: partDoneBase.sequenceNumber
585
+ };
586
+ }
587
+ }
494
588
  /**
495
589
  * 构建reasoning.done事件
496
590
  */
@@ -2,7 +2,7 @@
2
2
  * Responses协议事件编排器
3
3
  * 负责将Responses响应数据转换为有序的SSE事件流
4
4
  */
5
- import { buildResponseStartEvents, buildResponseDoneEvent, buildOutputItemStartEvent, buildOutputItemDoneEvent, buildContentPartStartEvent, buildContentPartDeltas, buildContentPartDoneEvent, buildOutputTextDoneEvent, buildFunctionCallArgsDeltas, buildFunctionCallDoneEvent, buildReasoningStartEvent, buildReasoningDeltas, buildReasoningDoneEvent, buildRequiredActionEvent, buildResponseCompletedEvent, buildErrorEvent, DEFAULT_RESPONSES_EVENT_GENERATOR_CONFIG, createDefaultResponsesContext } from '../event-generators/responses.js';
5
+ import { buildResponseStartEvents, buildResponseDoneEvent, buildOutputItemStartEvent, buildOutputItemDoneEvent, buildContentPartStartEvent, buildContentPartDeltas, buildContentPartDoneEvent, buildOutputTextDoneEvent, buildFunctionCallArgsDeltas, buildFunctionCallDoneEvent, buildReasoningStartEvent, buildReasoningSummaryEvents, buildReasoningDeltas, buildReasoningDoneEvent, buildRequiredActionEvent, buildResponseCompletedEvent, buildErrorEvent, DEFAULT_RESPONSES_EVENT_GENERATOR_CONFIG, createDefaultResponsesContext } from '../event-generators/responses.js';
6
6
  import { expandResponsesMessageItem } from '../../shared/responses-output-normalizer.js';
7
7
  // 默认配置
8
8
  export const DEFAULT_RESPONSES_SEQUENCER_CONFIG = {
@@ -120,11 +120,13 @@ async function* sequenceReasoningItem(item, context, config) {
120
120
  yield buildOutputItemStartEvent(item, context, config);
121
121
  // 2. 发送reasoning.start事件
122
122
  yield buildReasoningStartEvent(item, context, config);
123
- // 3. 发送reasoning.delta事件流
123
+ // 3. 发送reasoning_summary事件流
124
+ yield* withDelay(buildReasoningSummaryEvents(item, context, config), config);
125
+ // 4. 发送reasoning.delta事件流
124
126
  yield* withDelay(buildReasoningDeltas(item, context, config), config);
125
- // 4. 发送reasoning.done事件
127
+ // 5. 发送reasoning.done事件
126
128
  yield buildReasoningDoneEvent(item, context, config);
127
- // 5. 发送output_item.done事件
129
+ // 6. 发送output_item.done事件
128
130
  yield buildOutputItemDoneEvent(item, context, config);
129
131
  }
130
132
  /**
@@ -18,12 +18,15 @@ export interface OutputItemState {
18
18
  contentParts: any[];
19
19
  currentContentIndex: number;
20
20
  accumulatedContent: any[];
21
+ summaryByIndex: Map<number, string>;
22
+ currentSummaryIndex: number;
21
23
  hasContentPartAdded: boolean;
22
24
  isTextInProgress: boolean;
23
25
  callId?: string;
24
26
  name?: string;
25
27
  arguments?: string;
26
28
  role?: string;
29
+ encryptedContent?: string;
27
30
  startTime: number;
28
31
  lastEventTime: number;
29
32
  }
@@ -58,6 +61,7 @@ export declare class ResponsesResponseBuilder {
58
61
  */
59
62
  private handleOutputItemStart;
60
63
  private mapOutputItemAdded;
64
+ private mapOutputItemDone;
61
65
  /**
62
66
  * 处理content_part.start事件
63
67
  */
@@ -97,6 +101,10 @@ export declare class ResponsesResponseBuilder {
97
101
  * 处理reasoning.delta事件
98
102
  */
99
103
  private handleReasoningDelta;
104
+ private handleReasoningSummaryDelta;
105
+ private handleReasoningSummaryDone;
106
+ private handleReasoningSummaryPartAdded;
107
+ private handleReasoningSummaryPartDone;
100
108
  private mapReasoningDelta;
101
109
  private mapReasoningDone;
102
110
  /**
@@ -49,6 +49,9 @@ export class ResponsesResponseBuilder {
49
49
  case 'response.output_item.added':
50
50
  this.handleOutputItemStart(this.mapOutputItemAdded(event));
51
51
  break;
52
+ case 'response.output_item.done':
53
+ this.handleOutputItemDone(this.mapOutputItemDone(event));
54
+ break;
52
55
  case 'response.content_part.added':
53
56
  this.handleContentPartStart(this.mapContentPartAdded(event));
54
57
  break;
@@ -69,6 +72,18 @@ export class ResponsesResponseBuilder {
69
72
  case 'response.reasoning_image.delta':
70
73
  this.handleReasoningDelta(this.mapReasoningDelta(event));
71
74
  break;
75
+ case 'response.reasoning_summary_text.delta':
76
+ this.handleReasoningSummaryDelta(event);
77
+ break;
78
+ case 'response.reasoning_summary_text.done':
79
+ this.handleReasoningSummaryDone(event);
80
+ break;
81
+ case 'response.reasoning_summary_part.added':
82
+ this.handleReasoningSummaryPartAdded(event);
83
+ break;
84
+ case 'response.reasoning_summary_part.done':
85
+ this.handleReasoningSummaryPartDone(event);
86
+ break;
72
87
  case 'response.reasoning_text.done':
73
88
  this.handleReasoningDone(this.mapReasoningDone(event));
74
89
  break;
@@ -198,11 +213,14 @@ export class ResponsesResponseBuilder {
198
213
  contentParts: data.content_index !== undefined ? [] : [],
199
214
  currentContentIndex: 0,
200
215
  accumulatedContent: [],
216
+ summaryByIndex: new Map(),
217
+ currentSummaryIndex: 0,
201
218
  hasContentPartAdded: false,
202
219
  isTextInProgress: false,
203
220
  role: data.role,
204
221
  callId: data.call_id,
205
222
  name: data.name,
223
+ encryptedContent: typeof data.encrypted_content === 'string' ? data.encrypted_content : undefined,
206
224
  startTime: event.timestamp,
207
225
  lastEventTime: event.timestamp
208
226
  };
@@ -228,7 +246,20 @@ export class ResponsesResponseBuilder {
228
246
  status: data.status ?? item.status ?? 'in_progress',
229
247
  role: data.role ?? item.role,
230
248
  call_id: data.call_id ?? item.call_id,
231
- name: data.name ?? item.name
249
+ name: data.name ?? item.name,
250
+ encrypted_content: typeof item.encrypted_content === 'string' ? item.encrypted_content : undefined
251
+ }
252
+ };
253
+ }
254
+ mapOutputItemDone(event) {
255
+ const data = event.data;
256
+ const item = data.item || {};
257
+ return {
258
+ ...event,
259
+ type: 'output_item.done',
260
+ data: {
261
+ item_id: data.item_id ?? item.id,
262
+ item
232
263
  }
233
264
  };
234
265
  }
@@ -515,7 +546,18 @@ export class ResponsesResponseBuilder {
515
546
  if (!outputItemState) {
516
547
  throw new Error(`Output item not found: ${data.item_id}`);
517
548
  }
518
- outputItemState.accumulatedContent = data.summary || [];
549
+ outputItemState.accumulatedContent = [];
550
+ if (Array.isArray(data.summary)) {
551
+ data.summary.forEach((entry, index) => {
552
+ if (typeof entry === 'string') {
553
+ outputItemState.summaryByIndex.set(index, entry);
554
+ return;
555
+ }
556
+ if (entry && typeof entry === 'object' && typeof entry.text === 'string') {
557
+ outputItemState.summaryByIndex.set(index, entry.text);
558
+ }
559
+ });
560
+ }
519
561
  outputItemState.lastEventTime = event.timestamp;
520
562
  }
521
563
  /**
@@ -530,6 +572,86 @@ export class ResponsesResponseBuilder {
530
572
  outputItemState.accumulatedContent.push(data.delta);
531
573
  outputItemState.lastEventTime = event.timestamp;
532
574
  }
575
+ handleReasoningSummaryDelta(event) {
576
+ const data = event.data;
577
+ const outputItemState = this.outputItemBuilders.get(data.item_id);
578
+ if (!outputItemState) {
579
+ throw new Error(`Output item not found: ${data.item_id}`);
580
+ }
581
+ const index = typeof data.summary_index === 'number'
582
+ ? data.summary_index
583
+ : outputItemState.currentSummaryIndex;
584
+ const delta = typeof data.delta === 'string' ? data.delta : '';
585
+ if (!delta) {
586
+ return;
587
+ }
588
+ const previous = outputItemState.summaryByIndex.get(index) ?? '';
589
+ outputItemState.summaryByIndex.set(index, `${previous}${delta}`);
590
+ outputItemState.currentSummaryIndex = index;
591
+ outputItemState.lastEventTime = event.timestamp;
592
+ }
593
+ handleReasoningSummaryDone(event) {
594
+ const data = event.data;
595
+ const outputItemState = this.outputItemBuilders.get(data.item_id);
596
+ if (!outputItemState) {
597
+ throw new Error(`Output item not found: ${data.item_id}`);
598
+ }
599
+ const index = typeof data.summary_index === 'number'
600
+ ? data.summary_index
601
+ : outputItemState.currentSummaryIndex;
602
+ const text = typeof data.text === 'string' ? data.text : '';
603
+ if (!text) {
604
+ return;
605
+ }
606
+ outputItemState.summaryByIndex.set(index, text);
607
+ outputItemState.currentSummaryIndex = index;
608
+ outputItemState.lastEventTime = event.timestamp;
609
+ }
610
+ handleReasoningSummaryPartAdded(event) {
611
+ const data = event.data;
612
+ const outputItemState = this.outputItemBuilders.get(data.item_id);
613
+ if (!outputItemState) {
614
+ throw new Error(`Output item not found: ${data.item_id}`);
615
+ }
616
+ let index;
617
+ if (typeof data.summary_index === 'number') {
618
+ index = data.summary_index;
619
+ }
620
+ else if (outputItemState.summaryByIndex.size) {
621
+ let maxIndex = -1;
622
+ for (const key of outputItemState.summaryByIndex.keys()) {
623
+ if (key > maxIndex)
624
+ maxIndex = key;
625
+ }
626
+ index = maxIndex + 1;
627
+ }
628
+ else {
629
+ index = 0;
630
+ }
631
+ if (!outputItemState.summaryByIndex.has(index)) {
632
+ outputItemState.summaryByIndex.set(index, '');
633
+ }
634
+ outputItemState.currentSummaryIndex = index;
635
+ outputItemState.lastEventTime = event.timestamp;
636
+ }
637
+ handleReasoningSummaryPartDone(event) {
638
+ const data = event.data;
639
+ const outputItemState = this.outputItemBuilders.get(data.item_id);
640
+ if (!outputItemState) {
641
+ throw new Error(`Output item not found: ${data.item_id}`);
642
+ }
643
+ const index = typeof data.summary_index === 'number'
644
+ ? data.summary_index
645
+ : outputItemState.currentSummaryIndex;
646
+ const part = data.part && typeof data.part === 'object' ? data.part : undefined;
647
+ const text = part && typeof part.text === 'string' ? part.text : '';
648
+ if (!text) {
649
+ return;
650
+ }
651
+ outputItemState.summaryByIndex.set(index, text);
652
+ outputItemState.currentSummaryIndex = index;
653
+ outputItemState.lastEventTime = event.timestamp;
654
+ }
533
655
  mapReasoningDelta(event) {
534
656
  const data = event.data;
535
657
  return {
@@ -565,6 +687,10 @@ export class ResponsesResponseBuilder {
565
687
  if (!outputItemState) {
566
688
  throw new Error(`Output item not found: ${data.item_id}`);
567
689
  }
690
+ const text = typeof data.text === 'string' ? data.text : '';
691
+ if (text && outputItemState.accumulatedContent.length === 0) {
692
+ outputItemState.accumulatedContent.push({ type: 'reasoning_text', text });
693
+ }
568
694
  outputItemState.status = 'completed';
569
695
  outputItemState.lastEventTime = event.timestamp;
570
696
  }
@@ -580,6 +706,23 @@ export class ResponsesResponseBuilder {
580
706
  // 若为 custom_tool_call 变体(已在 start 阶段重命名为 function_call),尝试提取 name/arguments
581
707
  try {
582
708
  const item = data.item || {};
709
+ if (outputItemState.type === 'reasoning' && item && typeof item === 'object') {
710
+ if (!outputItemState.encryptedContent && typeof item.encrypted_content === 'string') {
711
+ outputItemState.encryptedContent = item.encrypted_content;
712
+ }
713
+ const summary = Array.isArray(item.summary) ? item.summary : [];
714
+ if (summary.length && outputItemState.summaryByIndex.size === 0) {
715
+ summary.forEach((entry, index) => {
716
+ if (typeof entry === 'string') {
717
+ outputItemState.summaryByIndex.set(index, entry);
718
+ return;
719
+ }
720
+ if (entry && typeof entry === 'object' && typeof entry.text === 'string') {
721
+ outputItemState.summaryByIndex.set(index, entry.text);
722
+ }
723
+ });
724
+ }
725
+ }
583
726
  if (outputItemState.type === 'function_call') {
584
727
  if (!outputItemState.name && typeof item.name === 'string')
585
728
  outputItemState.name = item.name;
@@ -775,12 +918,27 @@ export class ResponsesResponseBuilder {
775
918
  * 构建推理项
776
919
  */
777
920
  buildReasoningItem(state) {
778
- return {
921
+ const summaryEntries = state.summaryByIndex.size > 0
922
+ ? Array.from(state.summaryByIndex.entries())
923
+ .sort((a, b) => a[0] - b[0])
924
+ .map(([, text]) => text)
925
+ .filter(item => typeof item === 'string')
926
+ : (Array.isArray(state.accumulatedContent)
927
+ ? state.accumulatedContent.filter(item => typeof item === 'string')
928
+ : []);
929
+ const summaryParts = summaryEntries
930
+ .map((text) => typeof text === 'string' && text.length ? ({ type: 'summary_text', text }) : null)
931
+ .filter((entry) => Boolean(entry));
932
+ const item = {
779
933
  id: state.id,
780
934
  type: 'reasoning',
781
- summary: Array.isArray(state.accumulatedContent) ? state.accumulatedContent.filter(item => typeof item === 'string') : [],
935
+ summary: summaryParts,
782
936
  content: state.accumulatedContent.filter(item => typeof item === 'object')
783
937
  };
938
+ if (typeof state.encryptedContent === 'string' && state.encryptedContent.length) {
939
+ item.encrypted_content = state.encryptedContent;
940
+ }
941
+ return item;
784
942
  }
785
943
  /**
786
944
  * 获取构建结果
@@ -231,6 +231,8 @@ export class ResponsesSseToJsonConverterRefactored {
231
231
  break;
232
232
  case 'response.reasoning_text.delta':
233
233
  case 'response.reasoning_text.done':
234
+ case 'response.reasoning_summary_text.delta':
235
+ case 'response.reasoning_summary_text.done':
234
236
  context.eventStats.reasoningEventsCount++;
235
237
  break;
236
238
  case 'response.function_call_arguments.delta':
@@ -141,8 +141,12 @@ export interface ResponsesMessageItem {
141
141
  export interface ResponsesReasoningItem {
142
142
  id: string;
143
143
  type: 'reasoning';
144
- summary?: string[];
145
- content: ResponsesReasoningContent[];
144
+ summary?: Array<string | {
145
+ type: 'summary_text';
146
+ text: string;
147
+ }>;
148
+ content?: ResponsesReasoningContent[];
149
+ encrypted_content?: string;
146
150
  }
147
151
  export type ResponsesReasoningContent = {
148
152
  type: 'reasoning_text';
@@ -8,6 +8,11 @@ const resolveTopLevelFile = (record) => {
8
8
  asString(record.filename);
9
9
  if (direct)
10
10
  return direct;
11
+ // Shape fix: treat top-level target as file path when changes exist.
12
+ const target = asString(record.target);
13
+ if (target && Array.isArray(record.changes) && record.changes.length > 0) {
14
+ return target;
15
+ }
11
16
  return undefined;
12
17
  };
13
18
  const buildSingleChangePayload = (record) => {
@@ -21,6 +21,22 @@ const stripArgKeyArtifacts = (input) => {
21
21
  return input;
22
22
  }
23
23
  };
24
+ const repairArgKeyArtifactsInRawJson = (input) => {
25
+ try {
26
+ let out = String(input || '');
27
+ if (!out.includes('<arg_key') && !out.includes('<arg_value') && !out.includes('</arg_key') && !out.includes('</arg_value')) {
28
+ return out;
29
+ }
30
+ // Repair patterns like: "file</arg_key><arg_value>a.ts" -> "file":"a.ts"
31
+ out = out.replace(/"([^"]+?)\s*<\/?\s*arg_key\s*>\s*<\/?\s*arg_value\s*>([^"]*?)"/gi, '"$1":"$2"');
32
+ // Strip remaining tag artifacts after pair repair.
33
+ out = stripArgKeyArtifacts(out);
34
+ return out;
35
+ }
36
+ catch {
37
+ return input;
38
+ }
39
+ };
24
40
  const normalizeObjectKey = (rawKey) => {
25
41
  const cleaned = stripXmlLikeTags(stripArgKeyArtifacts(rawKey)).trim();
26
42
  if (!cleaned)
@@ -143,6 +159,19 @@ export function parseToolArgsJson(input) {
143
159
  return parsed;
144
160
  }
145
161
  catch {
162
+ // attempt raw string repair for arg_key/arg_value artifacts
163
+ try {
164
+ const repairedRaw = repairArgKeyArtifactsInRawJson(raw).trim();
165
+ if (repairedRaw && repairedRaw !== raw) {
166
+ const parsed = JSON.parse(repairedRaw);
167
+ repairArgKeyArtifactsInKeys(parsed);
168
+ repairArgKeyArtifactsInObject(parsed);
169
+ return parsed;
170
+ }
171
+ }
172
+ catch {
173
+ // continue
174
+ }
146
175
  // try stripping common tool-call markup artifacts and parsing again
147
176
  try {
148
177
  const stripped = stripArgKeyArtifacts(raw).trim();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonstudio/llms",
3
- "version": "0.6.2979",
3
+ "version": "0.6.3238",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -139,7 +139,9 @@
139
139
  "verify:shadow-gate:hub-resp-inbound-format-parse": "npm run test:coverage:hub-resp-inbound-format-parse && node scripts/check-shadow-coverage-gate.mjs --summary coverage/module-hub-resp-inbound-format-parse/coverage-summary.json --module hub.resp-inbound.format-parse && node scripts/promote-shadow-module.mjs --module hub.resp-inbound.format-parse",
140
140
  "verify:shadow-gate:hub-resp-inbound-semantic-map": "npm run test:coverage:hub-resp-inbound-semantic-map && node scripts/check-shadow-coverage-gate.mjs --summary coverage/module-hub-resp-inbound-semantic-map/coverage-summary.json --module hub.resp-inbound.semantic-map && node scripts/promote-shadow-module.mjs --module hub.resp-inbound.semantic-map",
141
141
  "verify:shadow-gate:hub-resp-outbound-sse-stream": "npm run test:coverage:hub-resp-outbound-sse-stream && node scripts/check-shadow-coverage-gate.mjs --summary coverage/module-hub-resp-outbound-sse-stream/coverage-summary.json --module hub.resp-outbound.sse-stream && node scripts/promote-shadow-module.mjs --module hub.resp-outbound.sse-stream",
142
- "verify:shadow-gate:hub-native-batch": "npm run test:coverage:hub-native-batch && node scripts/check-shadow-coverage-gate.mjs --summary coverage/module-hub-native-batch/coverage-summary.json --module hub.native-batch.adapters-snapshot-governance && node scripts/promote-shadow-module.mjs --module hub.native-batch.adapters-snapshot-governance"
142
+ "verify:shadow-gate:hub-native-batch": "npm run test:coverage:hub-native-batch && node scripts/check-shadow-coverage-gate.mjs --summary coverage/module-hub-native-batch/coverage-summary.json --module hub.native-batch.adapters-snapshot-governance && node scripts/promote-shadow-module.mjs --module hub.native-batch.adapters-snapshot-governance",
143
+ "test:coverage:hub-chat-request-filters": "npm run build:ci && node ./node_modules/c8/bin/c8.js --reporter=json-summary --reporter=text --report-dir=coverage/module-hub-chat-request-filters --include=dist/conversion/shared/chat-request-filters.js --include=dist/router/virtual-router/engine-selection/native-chat-request-filter-semantics.js --exclude=scripts/** node scripts/tests/coverage-chat-request-filters.mjs",
144
+ "verify:shadow-gate:hub-chat-request-filters": "npm run test:coverage:hub-chat-request-filters && node scripts/check-shadow-coverage-gate.mjs --summary coverage/module-hub-chat-request-filters/coverage-summary.json --module hub.shared.chat-request-filters && node scripts/promote-shadow-module.mjs --module hub.shared.chat-request-filters"
143
145
  },
144
146
  "dependencies": {
145
147
  "ajv": "^8.17.1",
@@ -166,10 +168,11 @@
166
168
  },
167
169
  "devDependencies": {
168
170
  "@types/node": "^20.11.25",
169
- "@typescript-eslint/eslint-plugin": "^6.7.4",
170
- "@typescript-eslint/parser": "^6.7.4",
171
- "c8": "^10.1.3",
171
+ "@typescript-eslint/eslint-plugin": "^8.56.1",
172
+ "@typescript-eslint/parser": "^8.56.1",
173
+ "c8": "^11.0.0",
172
174
  "eslint": "^8.50.0",
175
+ "tsx": "^4.21.0",
173
176
  "typescript": "^5.4.0"
174
177
  },
175
178
  "files": [
@@ -1,77 +0,0 @@
1
- import { buildShellDescription, hasApplyPatchToolDeclared, isShellToolName } from '../../tools/tool-description-utils.js';
2
- import { normalizeArgsBySchemaWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
3
- function isObject(v) {
4
- return !!v && typeof v === 'object' && !Array.isArray(v);
5
- }
6
- export function normalizeArgsBySchema(input, schema) {
7
- return normalizeArgsBySchemaWithNative(input, schema);
8
- }
9
- // Tools normalizer (OpenAI-like)
10
- export function normalizeTools(tools) {
11
- if (!Array.isArray(tools))
12
- return [];
13
- const out = [];
14
- const applyPatchAvailable = hasApplyPatchToolDeclared(tools);
15
- for (const t of tools) {
16
- if (!t || typeof t !== 'object')
17
- continue;
18
- const fn = t.function || {};
19
- const topName = typeof t.name === 'string' ? t.name : undefined;
20
- const topDesc = typeof t.description === 'string' ? t.description : undefined;
21
- const topParams = t.parameters;
22
- const name = typeof fn?.name === 'string' ? fn.name : topName;
23
- const desc = typeof fn?.description === 'string' ? fn.description : topDesc;
24
- let params = (fn?.parameters !== undefined ? fn.parameters : topParams);
25
- if (typeof params === 'string') {
26
- try {
27
- params = JSON.parse(params);
28
- }
29
- catch {
30
- params = {};
31
- }
32
- }
33
- // Enforce schema for known tools with minimal, compatible constraints
34
- let finalParams;
35
- if (isShellToolName(name)) {
36
- // Do NOT downgrade an existing schema; prefer string command, allow argv array as fallback
37
- const base = isObject(params) ? params : {};
38
- const props = isObject(base.properties) ? base.properties : {};
39
- const existing = props.command;
40
- const commandSchema = {
41
- description: existing?.description ||
42
- 'Shell command. Prefer a single string; an array of argv tokens is also accepted.',
43
- oneOf: [
44
- { type: 'string' },
45
- { type: 'array', items: { type: 'string' } }
46
- ]
47
- };
48
- props.command = commandSchema;
49
- base.type = 'object';
50
- base.properties = props;
51
- const req = Array.isArray(base.required) ? base.required : [];
52
- if (!req.includes('command'))
53
- req.push('command');
54
- base.required = req;
55
- if (typeof base.additionalProperties !== 'boolean')
56
- base.additionalProperties = false;
57
- finalParams = base;
58
- }
59
- else if (isObject(params)) {
60
- finalParams = params;
61
- }
62
- else {
63
- finalParams = { type: 'object', properties: {}, additionalProperties: true };
64
- }
65
- const functionNode = { name, ...(desc ? { description: desc } : {}), parameters: finalParams };
66
- if (isShellToolName(name)) {
67
- const display = (typeof name === 'string' && name.trim().length > 0)
68
- ? name.trim()
69
- : ((typeof topName === 'string' && topName.trim().length > 0) ? topName.trim() : 'shell');
70
- functionNode.description = buildShellDescription(display, applyPatchAvailable);
71
- }
72
- const norm = { type: 'function', function: functionNode };
73
- if (norm.function?.name)
74
- out.push(norm);
75
- }
76
- return out;
77
- }
@@ -1,4 +0,0 @@
1
- import { isCompactionRequestWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
- export function isCompactionRequest(payload) {
3
- return isCompactionRequestWithNative(payload);
4
- }
@@ -1,31 +0,0 @@
1
- function inferCategoryFromCode(code) {
2
- switch (code) {
3
- case 'TOOL_PROTOCOL_ERROR':
4
- return 'TOOL_ERROR';
5
- case 'SERVERTOOL_TIMEOUT':
6
- case 'SERVERTOOL_HANDLER_FAILED':
7
- return 'INTERNAL_ERROR';
8
- case 'SSE_DECODE_ERROR':
9
- case 'MALFORMED_RESPONSE':
10
- case 'MALFORMED_REQUEST':
11
- default:
12
- // 默认视为外部协议/载荷问题;真正的内部错误由上层使用 INTERNAL_ERROR 显式标记。
13
- return 'EXTERNAL_ERROR';
14
- }
15
- }
16
- export class ProviderProtocolError extends Error {
17
- code;
18
- protocol;
19
- providerType;
20
- category;
21
- details;
22
- constructor(message, options) {
23
- super(message);
24
- this.name = 'ProviderProtocolError';
25
- this.code = options.code;
26
- this.protocol = options.protocol;
27
- this.providerType = options.providerType;
28
- this.category = options.category ?? inferCategoryFromCode(options.code);
29
- this.details = options.details;
30
- }
31
- }
@@ -1,4 +0,0 @@
1
- import { isImagePathWithNative } from '../../router/virtual-router/engine-selection/native-shared-conversion-semantics.js';
2
- export function isImagePath(p) {
3
- return isImagePathWithNative(p);
4
- }