@jsonstudio/llms 0.6.0 → 0.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/conversion/hub/pipeline/stages/req_inbound/req_inbound_stage3_context_capture/index.js +13 -0
  2. package/dist/conversion/hub/process/chat-process.js +12 -6
  3. package/dist/conversion/hub/response/response-mappers.d.ts +1 -1
  4. package/dist/conversion/hub/response/response-mappers.js +12 -2
  5. package/dist/conversion/hub/semantic-mappers/anthropic-mapper.js +20 -0
  6. package/dist/conversion/hub/semantic-mappers/chat-mapper.js +6 -27
  7. package/dist/conversion/hub/semantic-mappers/gemini-mapper.js +5 -20
  8. package/dist/conversion/hub/standardized-bridge.js +6 -9
  9. package/dist/conversion/responses/responses-openai-bridge.js +0 -4
  10. package/dist/conversion/shared/anthropic-message-utils.js +80 -12
  11. package/dist/conversion/shared/bridge-actions.js +0 -55
  12. package/dist/conversion/shared/bridge-policies.js +4 -10
  13. package/dist/conversion/shared/chat-request-filters.js +1 -3
  14. package/dist/conversion/shared/protocol-state.d.ts +4 -0
  15. package/dist/conversion/shared/protocol-state.js +23 -0
  16. package/dist/conversion/shared/responses-conversation-store.d.ts +35 -0
  17. package/dist/conversion/shared/responses-conversation-store.js +64 -19
  18. package/dist/conversion/shared/responses-output-builder.js +43 -22
  19. package/dist/conversion/shared/responses-response-utils.js +47 -1
  20. package/dist/conversion/shared/text-markup-normalizer.js +2 -2
  21. package/dist/conversion/shared/tool-canonicalizer.js +118 -16
  22. package/dist/conversion/shared/tool-filter-pipeline.js +1 -2
  23. package/dist/conversion/shared/tool-mapping.js +30 -0
  24. package/dist/filters/index.d.ts +18 -0
  25. package/dist/filters/index.js +0 -1
  26. package/dist/filters/special/request-streaming-to-nonstreaming.d.ts +13 -0
  27. package/dist/filters/special/request-streaming-to-nonstreaming.js +13 -1
  28. package/dist/sse/sse-to-json/builders/response-builder.d.ts +2 -0
  29. package/dist/sse/sse-to-json/builders/response-builder.js +76 -12
  30. package/dist/sse/types/responses-types.d.ts +2 -0
  31. package/package.json +3 -3
@@ -395,6 +395,36 @@ export class ResponsesResponseBuilder {
395
395
  outputItemState.arguments = '';
396
396
  outputItemState.lastEventTime = event.timestamp;
397
397
  }
398
+ coerceArgumentsChunk(raw) {
399
+ if (typeof raw === 'string') {
400
+ return raw;
401
+ }
402
+ if (raw && typeof raw === 'object') {
403
+ try {
404
+ return JSON.stringify(raw);
405
+ }
406
+ catch {
407
+ return String(raw);
408
+ }
409
+ }
410
+ return undefined;
411
+ }
412
+ shouldOverrideArguments(current, incoming) {
413
+ if (!incoming) {
414
+ return false;
415
+ }
416
+ const trimmed = incoming.trim();
417
+ if (!current || !current.length) {
418
+ return trimmed.length > 0;
419
+ }
420
+ if (!trimmed.length) {
421
+ return false;
422
+ }
423
+ if (trimmed === '{}' || trimmed.toLowerCase() === 'null') {
424
+ return false;
425
+ }
426
+ return true;
427
+ }
398
428
  /**
399
429
  * 处理function_call.delta事件
400
430
  */
@@ -404,10 +434,10 @@ export class ResponsesResponseBuilder {
404
434
  if (!outputItemState) {
405
435
  throw new Error(`Output item not found: ${data.item_id}`);
406
436
  }
407
- const chunk = (data && data.delta && typeof data.delta === 'object' && typeof data.delta.arguments === 'string')
408
- ? String(data.delta.arguments)
409
- : (typeof (data?.delta) === 'string' ? String(data.delta) : (typeof data?.arguments === 'string' ? String(data.arguments) : undefined));
410
- if (typeof chunk === 'string') {
437
+ const chunk = this.coerceArgumentsChunk(data?.delta?.arguments) ??
438
+ this.coerceArgumentsChunk(data?.delta) ??
439
+ this.coerceArgumentsChunk(data?.arguments);
440
+ if (chunk) {
411
441
  outputItemState.arguments = (outputItemState.arguments || '') + chunk;
412
442
  }
413
443
  outputItemState.lastEventTime = event.timestamp;
@@ -445,8 +475,16 @@ export class ResponsesResponseBuilder {
445
475
  outputItemState.name = data.name;
446
476
  if (typeof data.call_id === 'string' && data.call_id)
447
477
  outputItemState.callId = data.call_id;
448
- if (typeof data.arguments === 'string' && data.arguments)
449
- outputItemState.arguments = data.arguments;
478
+ const finalChunk = this.coerceArgumentsChunk(data?.arguments) ??
479
+ this.coerceArgumentsChunk(data?.delta?.arguments) ??
480
+ this.coerceArgumentsChunk(data?.delta);
481
+ if (this.shouldOverrideArguments(outputItemState.arguments, finalChunk)) {
482
+ outputItemState.arguments = finalChunk;
483
+ }
484
+ else if (!outputItemState.arguments && finalChunk) {
485
+ // 没有任何累计增量时,保底写入 done 事件里的值
486
+ outputItemState.arguments = finalChunk;
487
+ }
450
488
  }
451
489
  catch { /* ignore */ }
452
490
  outputItemState.status = 'completed';
@@ -574,7 +612,30 @@ export class ResponsesResponseBuilder {
574
612
  * 处理required_action事件
575
613
  */
576
614
  handleRequiredAction(event) {
577
- // TODO: 实现required_action处理
615
+ const payload = event.data ?? {};
616
+ const responsePayload = payload.response ?? payload;
617
+ const requiredAction = responsePayload.required_action ??
618
+ payload.required_action ??
619
+ undefined;
620
+ const usage = responsePayload.usage ??
621
+ payload.usage ??
622
+ this.response.usage;
623
+ const nextResponse = {
624
+ ...this.response,
625
+ object: 'response',
626
+ id: responsePayload.id ?? this.response.id,
627
+ status: responsePayload.status ?? 'requires_action',
628
+ output: Array.isArray(responsePayload.output) && responsePayload.output.length
629
+ ? responsePayload.output
630
+ : this.buildOutputItems(),
631
+ required_action: requiredAction ?? this.response.required_action,
632
+ usage
633
+ };
634
+ if (responsePayload.metadata) {
635
+ nextResponse.metadata = responsePayload.metadata;
636
+ }
637
+ this.response = nextResponse;
638
+ this.state = 'completed';
578
639
  }
579
640
  /**
580
641
  * 处理response.done事件
@@ -607,14 +668,17 @@ export class ResponsesResponseBuilder {
607
668
  this.state = 'error';
608
669
  }
609
670
  handleResponseCompleted(event) {
610
- const data = event.data;
611
- if (data?.usage) {
612
- this.response.usage = data.usage;
671
+ const payload = event.data?.response ?? event.data;
672
+ const usage = (payload && payload.usage)
673
+ ? payload.usage
674
+ : event.data?.usage;
675
+ if (usage) {
676
+ this.response.usage = usage;
613
677
  }
614
678
  // 标准化完成态:部分上游的 response.completed 不包含 status 字段
615
679
  // 若未提供明确的完成状态,统一标记为 'completed',而不是沿用之前的 in_progress。
616
- this.response.status = (data && data.status != null)
617
- ? data.status
680
+ this.response.status = (payload && payload.status != null)
681
+ ? payload.status
618
682
  : 'completed';
619
683
  // 将已聚合的输出写回并标记完成(若为空数组也重建)
620
684
  try {
@@ -3,6 +3,7 @@
3
3
  * 支持OpenAI Responses API的JSON↔SSE双向转换
4
4
  */
5
5
  import { BaseSseEvent, StreamDirection, type JsonObject, type JsonValue } from './core-interfaces.js';
6
+ import type { RequiredAction } from './sse-events.js';
6
7
  export * from './sse-events.js';
7
8
  export type ResponsesSseEventType = 'response.created' | 'response.in_progress' | 'response.completed' | 'response.required_action' | 'response.done' | 'response.output_item.added' | 'response.output_item.done' | 'response.content_part.added' | 'response.content_part.done' | 'response.output_text.delta' | 'response.output_text.done' | 'response.reasoning_text.delta' | 'response.reasoning_text.done' | 'response.reasoning_signature.delta' | 'response.reasoning_image.delta' | 'response.reasoning_summary_part.added' | 'response.reasoning_summary_part.done' | 'response.reasoning_summary_text.delta' | 'response.reasoning_summary_text.done' | 'response.function_call_arguments.delta' | 'response.function_call_arguments.done' | 'response.error' | 'response.cancelled' | 'response.start' | 'content_part.delta' | 'reasoning.delta' | 'function_call.start' | 'function_call.delta' | 'function_call.done' | 'output_item.start' | 'content_part.start' | 'content_part.done' | 'output_item.done' | 'reasoning.start' | 'reasoning.done' | 'required_action' | 'error';
8
9
  export interface ResponsesSseEvent extends BaseSseEvent {
@@ -118,6 +119,7 @@ export interface ResponsesResponse {
118
119
  output: ResponsesOutputItem[];
119
120
  previous_response_id?: string;
120
121
  usage?: ResponsesUsage;
122
+ required_action?: RequiredAction;
121
123
  temperature?: number;
122
124
  top_p?: number;
123
125
  max_output_tokens?: number;
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@jsonstudio/llms",
3
- "version": "0.6.0",
3
+ "version": "0.6.006",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
7
7
  "types": "dist/index.d.ts",
8
8
  "scripts": {
9
- "build": "tsc -p tsconfig.json",
10
- "build:dev": "tsc -p tsconfig.json",
9
+ "build": "node scripts/bump-version.mjs && tsc -p tsconfig.json",
10
+ "build:dev": "node scripts/bump-version.mjs && tsc -p tsconfig.json",
11
11
  "lint": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --no-cache",
12
12
  "lint:fix": "eslint --no-eslintrc -c .eslintrc.json src --ext .ts --no-cache --fix",
13
13
  "postbuild": "node scripts/tests/run-matrix-ci.mjs",