@henjicc/ai-sdk 0.5.1 → 0.6.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 (68) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +61 -25
  3. package/dist/capabilities/speech-recognition/bailian/module.js +15 -3
  4. package/dist/capabilities/speech-recognition/bailian/parse.js +9 -1
  5. package/dist/capabilities/speech-recognition/bailian/presets.d.ts +3 -1
  6. package/dist/capabilities/speech-recognition/bailian/presets.js +4 -0
  7. package/dist/capabilities/speech-recognition/bailian/realtime/presets.d.ts +2 -1
  8. package/dist/capabilities/speech-recognition/bailian/realtime/presets.js +2 -0
  9. package/dist/capabilities/speech-recognition/bailian/realtime/protocol.js +8 -0
  10. package/dist/capabilities/speech-recognition/bailian/realtime/types.d.ts +3 -0
  11. package/dist/capabilities/speech-recognition/bailian/types.d.ts +4 -0
  12. package/dist/capabilities/speech-recognition/index.d.ts +2 -0
  13. package/dist/catalog/index.js +39 -35
  14. package/dist/catalog/kie/happyhorse-1.1.model.d.ts +2 -0
  15. package/dist/catalog/kie/happyhorse-1.1.model.js +67 -0
  16. package/dist/catalog/volcengine/seedream-5.0-flash.model.d.ts +2 -0
  17. package/dist/catalog/volcengine/seedream-5.0-flash.model.js +7 -0
  18. package/dist/catalog/volcengine/seedream-5.0-pro.model.d.ts +0 -1
  19. package/dist/catalog/volcengine/seedream-5.0-pro.model.js +5 -147
  20. package/dist/catalog/volcengine/seedream-5.0.d.ts +11 -0
  21. package/dist/catalog/volcengine/seedream-5.0.js +153 -0
  22. package/dist/llm/bigmodel/profiles.d.ts +2 -0
  23. package/dist/llm/bigmodel/profiles.js +8 -1
  24. package/dist/llm/chat.d.ts +3 -1
  25. package/dist/llm/chat.js +12 -2
  26. package/dist/llm/chatTypes.d.ts +7 -1
  27. package/dist/llm/defaults.js +1 -0
  28. package/dist/llm/groq/module.js +1 -0
  29. package/dist/llm/groq/preset.js +1 -0
  30. package/dist/llm/modelCatalog.d.ts +2 -0
  31. package/dist/llm/modelCatalog.js +1 -0
  32. package/dist/llm/modelCatalogEntries.js +30 -6
  33. package/dist/llm/modelStep.d.ts +2 -2
  34. package/dist/llm/providerPresets.js +4 -3
  35. package/dist/llm/providerProtocolCore.js +2 -1
  36. package/dist/llm/providerReasoningRequest.d.ts +2 -1
  37. package/dist/llm/providerReasoningRequest.js +27 -5
  38. package/dist/llm/sdk/mimoResponses.d.ts +4 -0
  39. package/dist/llm/sdk/mimoResponses.js +42 -0
  40. package/dist/llm/sdk/provider.js +4 -2
  41. package/dist/llm/streaming/index.d.ts +1 -1
  42. package/dist/llm/streaming.d.ts +2 -1
  43. package/dist/llm/streaming.js +100 -14
  44. package/dist/llm/types.d.ts +19 -0
  45. package/dist/packs/models/kie/happyhorse-1.1.d.ts +6 -0
  46. package/dist/packs/models/kie/happyhorse-1.1.js +7 -0
  47. package/dist/packs/models/volcengine/seedream-5.0-flash.d.ts +6 -0
  48. package/dist/packs/models/volcengine/seedream-5.0-flash.js +7 -0
  49. package/dist/packs/provider-packs/kie.d.ts +1 -1
  50. package/dist/packs/provider-packs/kie.js +22 -21
  51. package/dist/packs/provider-packs/volcengine.d.ts +1 -1
  52. package/dist/packs/provider-packs/volcengine.js +4 -3
  53. package/docs/consumers.md +20 -4
  54. package/docs/llm-adaptation/README.md +8 -8
  55. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/DeepSeek.md +4 -3
  56. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/Kimi.md +3 -2
  57. package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206//345/260/217/347/261/263MiMo.md +42 -1
  58. package/docs/model-adaptation/GLM-5.3-Flash/GLM-5.3-Flash_/346/231/272/350/260/261.md +6 -0
  59. package/docs/model-adaptation/HappyHorse-1.1/HappyHorse-1.1_KIE.md +27 -0
  60. package/docs/model-adaptation/README.md +11 -3
  61. package/docs/model-adaptation/Seedream-5.0-Flash/Seedream-5.0-Flash_/347/201/253/345/261/261/345/274/225/346/223/216.md +18 -0
  62. package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//347/231/276/347/202/274.md +19 -0
  63. package/examples/form-renderer/package.json +1 -1
  64. package/examples/llm-chat/README.md +8 -2
  65. package/examples/llm-chat/index.ts +1 -1
  66. package/examples/llm-chat/package.json +1 -1
  67. package/examples/minimal-node/package.json +1 -1
  68. package/package.json +258 -258
@@ -1,149 +1,7 @@
1
- /** 火山方舟官方 Seedream 5.0 Pro 图片生成与编辑模型(运行时契约) */
2
- import { defineModel } from '../defineModel.js';
3
- import { parseSeedreamLayerStack } from '../../structured-output/index.js';
4
- import { countUploadedImages } from '../shared/mediaPresence.js';
5
- const ASPECT_RATIOS = ['1:1', '4:3', '3:4', '16:9', '9:16', '3:2', '2:3', '21:9'];
6
- export const volcengineSeedream50ProModel = defineModel({
7
- meta: {
8
- id: 'volcengine-seedream-5.0-pro', canonicalModelId: 'seedream-5.0-pro', seriesId: 'seedream', seriesRank: 5.1,
9
- provider: 'volcengine', type: 'image',
10
- tags: ['text-to-image', 'image-to-image', 'supports-image-editing', 'supports-multi-image', 'supports-layer-decomposition', 'max-images-10', 'provider-volcengine'],
11
- aliases: ['seedream-5-pro-official']
12
- },
13
- inputLimits: {
14
- images: { max: 10 },
15
- videos: { max: 0 },
16
- rules: [
17
- { when: 'volcengineSeedream50ProMode === "layer-decomposition"', images: { min: 1, max: 1 } }
18
- ]
19
- },
20
- requirements: [
21
- {
22
- id: 'volcengine-seedream-5-pro-layer-single-image',
23
- when: 'volcengineSeedream50ProMode === "layer-decomposition"',
24
- require: { images: { exact: 1 } },
25
- message: {
26
- title: '需要一张图片',
27
- message: '图层拆分模式必须且只能输入 1 张图片。',
28
- type: 'warning'
29
- }
30
- }
31
- ],
32
- params: [
33
- {
34
- id: 'volcengineSeedream50ProMode', type: 'dropdown', order: 1,
35
- transferKey: 'layer-decomposition-mode',
36
- default: 'generate',
37
- options: [
38
- { value: 'generate' },
39
- { value: 'layer-decomposition' }
40
- ]
41
- },
42
- {
43
- id: 'volcengineSeedream50ProAspectRatio', type: 'dropdown', order: 2,
44
- default: 'smart',
45
- visible: { condition: 'volcengineSeedream50ProMode !== "layer-decomposition"' },
46
- options: [{ value: 'smart' }, ...ASPECT_RATIOS.map((ratio) => ({ value: ratio }))]
47
- },
48
- {
49
- id: 'volcengineSeedream50ProResolution', type: 'dropdown', order: 3,
50
- default: '2K',
51
- visible: { condition: 'volcengineSeedream50ProMode !== "layer-decomposition"' },
52
- options: ['1K', '1.5K', '2K'].map((value) => ({ value }))
53
- },
54
- {
55
- id: 'volcengineSeedream50ProLayerSize', type: 'dropdown', order: 4,
56
- transferKey: 'layer-output-size',
57
- default: 'auto',
58
- visible: { condition: 'volcengineSeedream50ProMode === "layer-decomposition"' },
59
- options: [
60
- { value: 'auto' },
61
- ...['1K', '1.5K', '2K'].map((value) => ({ value }))
62
- ]
63
- },
64
- {
65
- id: 'volcengineSeedream50ProBackground', type: 'dropdown', order: 5,
66
- default: 'opaque',
67
- visible: { condition: 'volcengineSeedream50ProMode !== "layer-decomposition"' },
68
- options: [
69
- { value: 'opaque' },
70
- { value: 'transparent' }
71
- ]
72
- }
73
- ],
74
- endpoints: '/api/v3/images/generations',
75
- request: {
76
- builder: (params) => {
77
- const filterSources = (value) => Array.isArray(value)
78
- ? value.filter((item) => typeof item === 'string' && item.trim().length > 0) : [];
79
- const uploaded = filterSources(params.uploadedFilePaths);
80
- const images = (uploaded.length > 0 ? uploaded : filterSources(params.images)).slice(0, 10);
81
- if (params.volcengineSeedream50ProMode === 'layer-decomposition') {
82
- if (images.length !== 1)
83
- throw new Error('Seedream 5.0 Pro 图层拆分模式必须且只能输入 1 张图片');
84
- const rawLayerSize = String(params.volcengineSeedream50ProLayerSize || 'auto');
85
- return {
86
- model: 'doubao-seedream-5-0-pro-260628',
87
- prompt: typeof params.prompt === 'string' ? params.prompt : '',
88
- image: images[0],
89
- layer_decomposition: true,
90
- size: ['auto', '1K', '1.5K', '2K'].includes(rawLayerSize) ? rawLayerSize : 'auto',
91
- response_format: 'url',
92
- watermark: false
93
- };
94
- }
95
- const ratios = ['1:1', '4:3', '3:4', '16:9', '9:16', '3:2', '2:3', '21:9'];
96
- const raw = String(params.volcengineSeedream50ProAspectRatio || 'smart');
97
- const hint = typeof params.__firstImageRatio === 'number' && Number.isFinite(params.__firstImageRatio) && params.__firstImageRatio > 0 ? params.__firstImageRatio : 1;
98
- let aspectRatio = ratios.includes(raw) ? raw : '1:1';
99
- if (raw === 'smart' || raw === 'auto') {
100
- let difference = Number.POSITIVE_INFINITY;
101
- for (const candidate of ratios) {
102
- const pair = candidate.split(':').map(Number);
103
- const next = Math.abs(pair[0] / pair[1] - hint);
104
- if (next < difference) {
105
- difference = next;
106
- aspectRatio = candidate;
107
- }
108
- }
109
- }
110
- const pair = aspectRatio.split(':').map(Number);
111
- const ratio = pair[0] / pair[1];
112
- const resolution = String(params.volcengineSeedream50ProResolution || '2K');
113
- const base = resolution === '2K' ? 2048 : (resolution === '1K' ? 1024 : 1536);
114
- const width = Math.round(Math.sqrt(base * base * ratio) / 16) * 16;
115
- const height = Math.round(Math.sqrt(base * base / ratio) / 16) * 16;
116
- const body = {
117
- model: 'doubao-seedream-5-0-pro-260628',
118
- prompt: typeof params.prompt === 'string' ? params.prompt : '',
119
- size: `${width}x${height}`,
120
- background: params.volcengineSeedream50ProBackground === 'transparent' ? 'transparent' : 'opaque',
121
- response_format: 'url', watermark: false
122
- };
123
- if (images.length > 0)
124
- body.image = images;
125
- return body;
126
- }
127
- },
128
- response: {
129
- structuredOutput: ({ metadata, params }) => params.volcengineSeedream50ProMode === 'layer-decomposition'
130
- ? parseSeedreamLayerStack('volcengine', metadata)
131
- : undefined
132
- },
133
- pricing: {
134
- currency: '¥',
135
- calculator: (params) => {
136
- if (params.volcengineSeedream50ProMode === 'layer-decomposition') {
137
- // 输出层数及每层实际像素档位都由模型结果决定,提交前不能给出可靠总价。
138
- return Number.NaN;
139
- }
140
- const output = params.volcengineSeedream50ProResolution === '1K' || params.volcengineSeedream50ProResolution === '1.5K'
141
- ? 0.3
142
- : 0.6;
143
- const inputs = countUploadedImages(params);
144
- return output + Math.max(0, inputs - 1) * 0.02;
145
- },
146
- description: '生成/编辑:1K/1.5K ¥0.30、2K ¥0.60/张,第 2 张起输入图 +¥0.02/张;图层拆分按实际输出图层与像素档位计费,提交前总价暂不可估算(单层 1K/1.5K ¥0.15、2K/自动 ¥0.30)'
147
- }
1
+ import { createSeedream50Model } from './seedream-5.0.js';
2
+ export const volcengineSeedream50ProModel = createSeedream50Model({
3
+ id: 'volcengine-seedream-5.0-pro', canonicalModelId: 'seedream-5.0-pro',
4
+ apiModel: 'doubao-seedream-5-0-pro-260628', paramPrefix: 'volcengineSeedream50Pro',
5
+ aliases: ['seedream-5-pro-official'],
148
6
  });
149
7
  export default volcengineSeedream50ProModel;
@@ -0,0 +1,11 @@
1
+ /** 火山方舟官方 Seedream 5.0 Pro 图片生成与编辑模型(运行时契约) */
2
+ interface Seedream50Config {
3
+ id: string;
4
+ canonicalModelId: string;
5
+ apiModel: string;
6
+ paramPrefix: string;
7
+ aliases: string[];
8
+ flash?: boolean;
9
+ }
10
+ export declare function createSeedream50Model(config: Seedream50Config): import("../../index.js").ModelRuntimeDefinition;
11
+ export {};
@@ -0,0 +1,153 @@
1
+ /** 火山方舟官方 Seedream 5.0 Pro 图片生成与编辑模型(运行时契约) */
2
+ import { defineModel } from '../defineModel.js';
3
+ import { parseSeedreamLayerStack } from '../../structured-output/index.js';
4
+ import { countUploadedImages } from '../shared/mediaPresence.js';
5
+ const ASPECT_RATIOS = ['1:1', '4:3', '3:4', '16:9', '9:16', '3:2', '2:3', '21:9'];
6
+ export function createSeedream50Model(config) {
7
+ const key = (name) => config.paramPrefix + name;
8
+ return defineModel({
9
+ meta: {
10
+ id: config.id, canonicalModelId: config.canonicalModelId, seriesId: 'seedream', seriesRank: 5.1,
11
+ provider: 'volcengine', type: 'image',
12
+ tags: ['text-to-image', 'image-to-image', 'supports-image-editing', 'supports-multi-image', 'supports-layer-decomposition', 'max-images-10', 'provider-volcengine'],
13
+ aliases: config.aliases
14
+ },
15
+ inputLimits: {
16
+ images: { max: 10 },
17
+ videos: { max: 0 },
18
+ rules: [
19
+ { when: `${key('Mode')} === "layer-decomposition"`, images: { min: 1, max: 1 } }
20
+ ]
21
+ },
22
+ requirements: [
23
+ {
24
+ id: `${config.id}-layer-single-image`,
25
+ when: `${key('Mode')} === "layer-decomposition"`,
26
+ require: { images: { exact: 1 } },
27
+ message: {
28
+ title: '需要一张图片',
29
+ message: '图层拆分模式必须且只能输入 1 张图片。',
30
+ type: 'warning'
31
+ }
32
+ }
33
+ ],
34
+ params: [
35
+ {
36
+ id: key('Mode'), type: 'dropdown', order: 1,
37
+ transferKey: 'layer-decomposition-mode',
38
+ default: 'generate',
39
+ options: [
40
+ { value: 'generate' },
41
+ { value: 'layer-decomposition' }
42
+ ]
43
+ },
44
+ {
45
+ id: key('AspectRatio'), type: 'dropdown', order: 2,
46
+ default: 'smart',
47
+ visible: { condition: `${key('Mode')} !== "layer-decomposition"` },
48
+ options: [{ value: 'smart' }, ...ASPECT_RATIOS.map((ratio) => ({ value: ratio }))]
49
+ },
50
+ {
51
+ id: key('Resolution'), type: 'dropdown', order: 3,
52
+ default: '2K',
53
+ visible: { condition: `${key('Mode')} !== "layer-decomposition"` },
54
+ options: ['1K', '1.5K', '2K'].map((value) => ({ value }))
55
+ },
56
+ {
57
+ id: key('LayerSize'), type: 'dropdown', order: 4,
58
+ transferKey: 'layer-output-size',
59
+ default: 'auto',
60
+ visible: { condition: `${key('Mode')} === "layer-decomposition"` },
61
+ options: [
62
+ { value: 'auto' },
63
+ ...['1K', '1.5K', '2K'].map((value) => ({ value }))
64
+ ]
65
+ },
66
+ {
67
+ id: key('Background'), type: 'dropdown', order: 5,
68
+ default: 'opaque',
69
+ visible: { condition: `${key('Mode')} !== "layer-decomposition"` },
70
+ options: [
71
+ { value: 'opaque' },
72
+ { value: 'transparent' }
73
+ ]
74
+ }
75
+ ],
76
+ endpoints: '/api/v3/images/generations',
77
+ request: {
78
+ builder: (params) => {
79
+ const filterSources = (value) => Array.isArray(value)
80
+ ? value.filter((item) => typeof item === 'string' && item.trim().length > 0) : [];
81
+ const uploaded = filterSources(params.uploadedFilePaths);
82
+ const images = uploaded.length > 0 ? uploaded : filterSources(params.images);
83
+ if (images.length > 10)
84
+ throw new Error('Seedream 5.0 最多接受 10 张图片');
85
+ if (params[key('Mode')] === 'layer-decomposition') {
86
+ if (images.length !== 1)
87
+ throw new Error('Seedream 5.0 Pro 图层拆分模式必须且只能输入 1 张图片');
88
+ const rawLayerSize = String(params[key('LayerSize')] || 'auto');
89
+ return {
90
+ model: config.apiModel,
91
+ prompt: typeof params.prompt === 'string' ? params.prompt : '',
92
+ image: images[0],
93
+ layer_decomposition: true,
94
+ size: ['auto', '1K', '1.5K', '2K'].includes(rawLayerSize) ? rawLayerSize : 'auto',
95
+ response_format: 'url',
96
+ watermark: false
97
+ };
98
+ }
99
+ const ratios = ['1:1', '4:3', '3:4', '16:9', '9:16', '3:2', '2:3', '21:9'];
100
+ const raw = String(params[key('AspectRatio')] || 'smart');
101
+ const hint = typeof params.__firstImageRatio === 'number' && Number.isFinite(params.__firstImageRatio) && params.__firstImageRatio > 0 ? params.__firstImageRatio : 1;
102
+ let aspectRatio = ratios.includes(raw) ? raw : '1:1';
103
+ if (raw === 'smart' || raw === 'auto') {
104
+ let difference = Number.POSITIVE_INFINITY;
105
+ for (const candidate of ratios) {
106
+ const pair = candidate.split(':').map(Number);
107
+ const next = Math.abs(pair[0] / pair[1] - hint);
108
+ if (next < difference) {
109
+ difference = next;
110
+ aspectRatio = candidate;
111
+ }
112
+ }
113
+ }
114
+ const pair = aspectRatio.split(':').map(Number);
115
+ const ratio = pair[0] / pair[1];
116
+ const resolution = String(params[key('Resolution')] || '2K');
117
+ const base = resolution === '2K' ? 2048 : (resolution === '1K' ? 1024 : 1536);
118
+ const width = Math.round(Math.sqrt(base * base * ratio) / 16) * 16;
119
+ const height = Math.round(Math.sqrt(base * base / ratio) / 16) * 16;
120
+ const body = {
121
+ model: config.apiModel,
122
+ prompt: typeof params.prompt === 'string' ? params.prompt : '',
123
+ size: `${width}x${height}`,
124
+ background: params[key('Background')] === 'transparent' ? 'transparent' : 'opaque',
125
+ response_format: 'url', watermark: false
126
+ };
127
+ if (images.length > 0)
128
+ body.image = images;
129
+ return body;
130
+ }
131
+ },
132
+ response: {
133
+ structuredOutput: ({ metadata, params }) => params[key('Mode')] === 'layer-decomposition'
134
+ ? parseSeedreamLayerStack('volcengine', metadata)
135
+ : undefined
136
+ },
137
+ pricing: {
138
+ currency: '¥',
139
+ calculator: (params) => {
140
+ if (params[key('Mode')] === 'layer-decomposition') {
141
+ // 输出层数及每层实际像素档位都由模型结果决定,提交前不能给出可靠总价。
142
+ return Number.NaN;
143
+ }
144
+ const output = params[key('Resolution')] === '1K' || params[key('Resolution')] === '1.5K'
145
+ ? 0.3
146
+ : 0.6;
147
+ const inputs = countUploadedImages(params);
148
+ return config.flash ? 0.12 : output + Math.max(0, inputs - 1) * 0.02;
149
+ },
150
+ description: config.flash ? '输入图片免费;输出 ¥0.12/张,图层拆分按实际输出计费,提交前总价暂不可估算' : '生成/编辑:1K/1.5K ¥0.30、2K ¥0.60/张,第 2 张起输入图 +¥0.02/张;图层拆分按实际输出图层与像素档位计费,提交前总价暂不可估算(单层 1K/1.5K ¥0.15、2K/自动 ¥0.30)'
151
+ }
152
+ });
153
+ }
@@ -19,3 +19,5 @@ export interface BigmodelTokenPricing {
19
19
  }
20
20
  export declare const BIGMODEL_ENDPOINT_PROFILE_FAMILY: LlmEndpointProfileFamily;
21
21
  export declare const BIGMODEL_GLM_5_3_FLASH_PRICING: Readonly<Record<'cn' | 'global', BigmodelTokenPricing>>;
22
+ /** 中国大陆常规单价,2026-09-24 核对官方价格页;不把限时免费缓存写入算作永久价格。 */
23
+ export declare const BIGMODEL_GLM_5_3_FLASHX_PRICING: Readonly<BigmodelTokenPricing>;
@@ -21,7 +21,7 @@ export const BIGMODEL_ENDPOINT_PROFILE_FAMILY = {
21
21
  websiteUrl: BIGMODEL_CN_METADATA.websiteUrl,
22
22
  apiKeyUrl: BIGMODEL_CN_METADATA.apiKeyUrl,
23
23
  defaultCredentialId: BIGMODEL_CN_CREDENTIAL_ID,
24
- modelIds: ['glm-5.3', 'glm-5v-turbo', 'glm-5.3-flash'],
24
+ modelIds: ['glm-5.3', 'glm-5v-turbo', 'glm-5.3-flash', 'glm-5.3-flashx'],
25
25
  docs: 'docs/llm-adaptation/供应商/智谱GLM.md',
26
26
  },
27
27
  {
@@ -63,3 +63,10 @@ export const BIGMODEL_GLM_5_3_FLASH_PRICING = {
63
63
  },
64
64
  },
65
65
  };
66
+ /** 中国大陆常规单价,2026-09-24 核对官方价格页;不把限时免费缓存写入算作永久价格。 */
67
+ export const BIGMODEL_GLM_5_3_FLASHX_PRICING = {
68
+ currency: 'CNY',
69
+ inputPerMillionTokens: 2,
70
+ outputPerMillionTokens: 7,
71
+ cacheReadPerMillionTokens: 0.57,
72
+ };
@@ -28,10 +28,11 @@ export interface LlmChatCompletedInfo {
28
28
  reasoningOutput: string;
29
29
  usage: LlmUsageDto | null;
30
30
  finishReason: string | null;
31
+ truncated: boolean;
31
32
  toolCalls?: LlmStreamToolCall[];
32
33
  }
33
34
  export interface LlmChatStreamHooks {
34
- /** 请求体与 endpoint 已经构建好,即将发出网络请求前触发一次。 */
35
+ /** 请求体与 endpoint 已经构建好,即将发出网络请求前触发一次;requestPayload 是只用于观察的快照。 */
35
36
  onRequestBuilt?: (info: LlmChatRequestBuiltInfo) => void;
36
37
  /** 流式响应正常读完(未被取消、未抛错)后触发一次。 */
37
38
  onCompleted?: (info: LlmChatCompletedInfo) => void;
@@ -47,6 +48,7 @@ export interface LlmChatStreamOutcome {
47
48
  reasoningOutput: string;
48
49
  usage: LlmUsageDto | null;
49
50
  finishReason: string | null;
51
+ truncated: boolean;
50
52
  toolCalls?: LlmStreamToolCall[];
51
53
  }
52
54
  export interface LlmChatExecutionOptions {
package/dist/llm/chat.js CHANGED
@@ -53,11 +53,16 @@ export async function runLlmChatStream(request, taskId, emit, runtime, hooks = {
53
53
  ? resolvePpioChatEndpoint(processedRequest.baseUrl)
54
54
  : resolveOpenAiCompatibleEndpoint(processedRequest);
55
55
  const requestPayload = buildOpenAiCompatiblePayload(processedRequest);
56
- hooks.onRequestBuilt?.({ endpoint, requestPayload, processedRequest });
56
+ hooks.onRequestBuilt?.({
57
+ endpoint,
58
+ requestPayload: cloneJsonObject(requestPayload),
59
+ processedRequest,
60
+ });
57
61
  const output = await streamOpenAiCompatibleChat({
58
62
  endpoint,
59
63
  apiKey,
60
- request: processedRequest,
64
+ providerId: identity.providerFamilyId,
65
+ payload: requestPayload,
61
66
  signal: controller.signal,
62
67
  emit,
63
68
  transport: runtime.transport,
@@ -77,6 +82,7 @@ export async function runLlmChatStream(request, taskId, emit, runtime, hooks = {
77
82
  reasoningOutput: output.reasoningOutput,
78
83
  usage: output.usage,
79
84
  finishReason: output.finishReason,
85
+ truncated: output.truncated,
80
86
  toolCalls: output.toolCalls,
81
87
  });
82
88
  span?.end();
@@ -91,6 +97,7 @@ export async function runLlmChatStream(request, taskId, emit, runtime, hooks = {
91
97
  reasoningOutput: output.reasoningOutput,
92
98
  usage: output.usage,
93
99
  finishReason: output.finishReason,
100
+ truncated: output.truncated,
94
101
  toolCalls: output.toolCalls,
95
102
  };
96
103
  }
@@ -142,3 +149,6 @@ function isAbortError(error) {
142
149
  function isJsonObject(value) {
143
150
  return typeof value === 'object' && value !== null && !Array.isArray(value);
144
151
  }
152
+ function cloneJsonObject(value) {
153
+ return JSON.parse(JSON.stringify(value));
154
+ }
@@ -1,5 +1,6 @@
1
1
  import type { JsonObject, JsonValue } from '../types/runtime.js';
2
2
  import type { LlmReasoningConfig } from './reasoning.js';
3
+ import type { LlmCapabilities, LlmStructuredOutputConfig } from './types.js';
3
4
  export type { JsonObject, JsonValue };
4
5
  /**
5
6
  * 原生 SSE 流式聊天路径(`llm:chatStream`)的请求/响应 DTO。
@@ -34,7 +35,10 @@ export interface LlmChatRequestDto {
34
35
  baseUrl?: string;
35
36
  reasoning?: LlmReasoningConfig;
36
37
  messages: LlmChatMessageDto[];
37
- capabilities?: JsonObject;
38
+ capabilities?: Partial<LlmCapabilities>;
39
+ structuredOutput?: LlmStructuredOutputConfig;
40
+ /** 正整数;不设置时不下发限制,由供应商或模型默认值决定。 */
41
+ maxOutputTokens?: number;
38
42
  tools?: JsonValue;
39
43
  policy?: JsonObject;
40
44
  memory?: JsonObject;
@@ -75,6 +79,8 @@ export interface LlmStreamOutput {
75
79
  reasoningOutput: string;
76
80
  usage: LlmUsageDto | null;
77
81
  finishReason: string | null;
82
+ /** 供应商明确因输出 token 上限结束时为 true。 */
83
+ truncated: boolean;
78
84
  toolCalls?: LlmStreamToolCall[];
79
85
  }
80
86
  export interface LlmStreamToolCall {
@@ -28,6 +28,7 @@ export const DEFAULT_LLM_CAPABILITIES = {
28
28
  parallelTools: false,
29
29
  jsonOutput: false,
30
30
  structuredOutputMode: 'none',
31
+ structuredOutputWithReasoning: null,
31
32
  reasoning: false,
32
33
  sampling: true,
33
34
  contextWindow: null,
@@ -39,6 +39,7 @@ export function createGroqLlmModule() {
39
39
  reasoningOutput: outcome.reasoningOutput,
40
40
  usage: outcome.usage,
41
41
  finishReason: outcome.finishReason,
42
+ truncated: outcome.truncated,
42
43
  toolCalls: outcome.toolCalls,
43
44
  };
44
45
  },
@@ -40,6 +40,7 @@ export const GROQ_DEFAULT_MODEL_CONFIG = {
40
40
  parallelTools: false,
41
41
  jsonOutput: true,
42
42
  structuredOutputMode: 'json',
43
+ structuredOutputWithReasoning: true,
43
44
  reasoning: true,
44
45
  sampling: true,
45
46
  contextWindow: 131_072,
@@ -28,6 +28,8 @@ export interface LlmModelCatalogEntry {
28
28
  toolCall: boolean;
29
29
  parallelTools: boolean;
30
30
  structuredOutputMode: LlmCapabilities['structuredOutputMode'];
31
+ /** 结构化输出与思考模式能否同时启用;省略表示官方资料尚未核实。 */
32
+ structuredOutputWithReasoning?: boolean;
31
33
  reasoning: boolean;
32
34
  /** 是否接受 temperature / top_p;官方声明为固定值的模型要记 false */
33
35
  sampling: boolean;
@@ -44,6 +44,7 @@ export function applyLlmModelCatalogEntry(base, entry) {
44
44
  toolCall: entry.toolCall,
45
45
  parallelTools: entry.parallelTools,
46
46
  structuredOutputMode: entry.structuredOutputMode,
47
+ structuredOutputWithReasoning: entry.structuredOutputWithReasoning ?? null,
47
48
  jsonOutput: entry.structuredOutputMode !== 'none',
48
49
  reasoning: entry.reasoning,
49
50
  sampling: entry.sampling,
@@ -37,6 +37,7 @@ export const LLM_MODEL_CATALOG_ENTRIES = [
37
37
  toolCall: true,
38
38
  parallelTools: false,
39
39
  structuredOutputMode: 'json',
40
+ structuredOutputWithReasoning: true,
40
41
  reasoning: true,
41
42
  sampling: true,
42
43
  contextWindow: 131_072,
@@ -117,6 +118,7 @@ export const LLM_MODEL_CATALOG_ENTRIES = [
117
118
  toolCall: true,
118
119
  parallelTools: false,
119
120
  structuredOutputMode: 'schema',
121
+ structuredOutputWithReasoning: true,
120
122
  reasoning: true,
121
123
  // 官方文档把 temperature / top_p 等列为固定值并明确"建议不要显式传入",
122
124
  // sampling=false 会让模型步骤不再下发这两个参数。
@@ -142,21 +144,24 @@ export const LLM_MODEL_CATALOG_ENTRIES = [
142
144
  docs: 'docs/llm-adaptation/供应商/Kimi.md',
143
145
  },
144
146
  // ---------------- 智谱 GLM ----------------
145
- {
146
- id: 'glm-5.3-flash',
147
- displayName: 'GLM-5.3-Flash',
147
+ ...[
148
+ { id: 'glm-5.3-flash', displayName: 'GLM-5.3-Flash' },
149
+ { id: 'glm-5.3-flashx', displayName: 'GLM-5.3-FlashX' },
150
+ ].map(model => ({
151
+ ...model,
148
152
  vendor: '智谱',
149
153
  input: { image: true, video: true, audio: false, file: true },
150
154
  toolCall: true,
151
155
  parallelTools: false,
152
- structuredOutputMode: 'none',
156
+ structuredOutputMode: 'json',
157
+ structuredOutputWithReasoning: true,
153
158
  reasoning: true,
154
159
  sampling: true,
155
160
  contextWindow: 1_000_000,
156
161
  maxOutputTokens: 131_072,
157
- note: '国内与国际端点共用 Chat Completions 协议;文件只接受宿主已持有的 URL/内联内容,不声明上传与 file_id。结构化输出和 tool_stream 未确认,保持关闭。',
162
+ note: '始终开启思考;支持 JSON 输出。文件只接受宿主已持有的 URL/内联内容,不声明上传与 file_id。FlashX 仅核验中国大陆端点。',
158
163
  docs: 'docs/model-adaptation/GLM-5.3-Flash/GLM-5.3-Flash_智谱.md',
159
- },
164
+ })),
160
165
  {
161
166
  id: 'glm-5.3',
162
167
  displayName: 'GLM-5.3',
@@ -237,6 +242,25 @@ export const LLM_MODEL_CATALOG_ENTRIES = [
237
242
  docs: 'docs/llm-adaptation/供应商/火山引擎.md',
238
243
  },
239
244
  // ---------------- 小米 MiMo ----------------
245
+ ...[
246
+ { id: 'mimo-v2.6-pro', displayName: 'MiMo-V2.6-Pro' },
247
+ { id: 'mimo-v2.6-flash', displayName: 'MiMo-V2.6-Flash' },
248
+ { id: 'mimo-v2.6-pro-ultraspeed', displayName: 'MiMo-V2.6-Pro-UltraSpeed' },
249
+ ].map(model => ({
250
+ ...model,
251
+ vendor: '小米',
252
+ input: { image: true, video: true, audio: true },
253
+ toolCall: true,
254
+ parallelTools: false,
255
+ structuredOutputMode: 'json',
256
+ reasoning: true,
257
+ sampling: true,
258
+ contextWindow: 1_000_000,
259
+ maxOutputTokens: 131_072,
260
+ apiProtocols: ['openai-responses', 'openai-compatible'],
261
+ note: '支持 Chat Completions 与 Responses;思考只有开关,无强度分级。UltraSpeed 需要联系供应商开通。',
262
+ docs: 'docs/llm-adaptation/供应商/小米MiMo.md',
263
+ })),
240
264
  {
241
265
  id: 'mimo-v2.5-pro',
242
266
  displayName: 'MiMo-V2.5-Pro',
@@ -55,8 +55,8 @@ export type ModelStepTool = z.infer<typeof modelStepToolSchema>;
55
55
  export declare const modelStepTraceMetadataSchema: z.ZodObject<{
56
56
  kind: z.ZodEnum<{
57
57
  fallback: "fallback";
58
- router: "router";
59
58
  primary: "primary";
59
+ router: "router";
60
60
  summarizer: "summarizer";
61
61
  observer: "observer";
62
62
  other: "other";
@@ -174,8 +174,8 @@ export declare const modelStepInputSchema: z.ZodObject<{
174
174
  trace: z.ZodOptional<z.ZodObject<{
175
175
  kind: z.ZodEnum<{
176
176
  fallback: "fallback";
177
- router: "router";
178
177
  primary: "primary";
178
+ router: "router";
179
179
  summarizer: "summarizer";
180
180
  observer: "observer";
181
181
  other: "other";
@@ -85,7 +85,7 @@ export const LLM_PROVIDER_PRESETS = [
85
85
  baseUrl: 'https://open.bigmodel.cn/api/paas/v4',
86
86
  reasoning: { enabled: true, effort: 'max' },
87
87
  reasoningConfigurable: true,
88
- modelIds: ['glm-5.3', 'glm-5v-turbo', 'glm-5.3-flash'],
88
+ modelIds: ['glm-5.3', 'glm-5v-turbo', 'glm-5.3-flash', 'glm-5.3-flashx'],
89
89
  responsesModelIds: ['glm-5.3'],
90
90
  websiteUrl: providerMetadata('bigmodel').websiteUrl,
91
91
  apiKeyUrl: providerMetadata('bigmodel').apiKeyUrl,
@@ -100,11 +100,12 @@ export const LLM_PROVIDER_PRESETS = [
100
100
  baseUrl: 'https://api.xiaomimimo.com/v1',
101
101
  reasoning: { enabled: true, effort: 'high' },
102
102
  reasoningConfigurable: true,
103
- modelIds: ['mimo-v2.5-pro', 'mimo-v2.5'],
103
+ modelIds: ['mimo-v2.6-pro', 'mimo-v2.6-flash'],
104
+ responsesModelIds: ['mimo-v2.6-pro', 'mimo-v2.6-flash', 'mimo-v2.6-pro-ultraspeed'],
104
105
  websiteUrl: providerMetadata('mimo').websiteUrl,
105
106
  apiKeyUrl: providerMetadata('mimo').apiKeyUrl,
106
107
  docs: 'docs/llm-adaptation/供应商/小米MiMo.md',
107
- note: '认证头与请求体字段有两处自有约定,已在 providerProtocol.ts 里按 providerId 处理,改这里的 id 会让那两条失效。',
108
+ note: '2.5 系列将于北京时间 2026-10-21 10:00 下线;已有模型选择保持不变,请主动迁移到 2.6。UltraSpeed 需要另行开通。',
108
109
  },
109
110
  {
110
111
  providerId: 'minimax',
@@ -7,8 +7,9 @@ export function resolveProviderExtraAuthHeaders(providerId, apiKey) {
7
7
  }
8
8
  export function applyProviderRequestBodyQuirks(providerId, body) {
9
9
  const normalizedProviderId = providerId.trim().toLowerCase();
10
- if (normalizedProviderId === 'mimo')
10
+ if (normalizedProviderId === 'mimo' || normalizedProviderId === 'openai') {
11
11
  return renameMaxCompletionTokens(body);
12
+ }
12
13
  if (normalizedProviderId !== 'groq')
13
14
  return body;
14
15
  const withTokenLimit = renameMaxCompletionTokens(body);
@@ -1,4 +1,5 @@
1
1
  import type { LlmReasoningConfig } from './reasoning.js';
2
+ import type { LlmApiProtocol } from './providerProtocolCore.js';
2
3
  /** 该供应商是否有专门登记的思考参数写法;false 表示走通用兜底。 */
3
4
  export declare function hasProviderReasoningRule(providerId: string, adapter?: string): boolean;
4
- export declare function applyProviderReasoningRequestBody(providerId: string, adapter: string | undefined, body: Record<string, unknown>, reasoning: LlmReasoningConfig | undefined): Record<string, unknown>;
5
+ export declare function applyProviderReasoningRequestBody(providerId: string, adapter: string | undefined, body: Record<string, unknown>, reasoning: LlmReasoningConfig | undefined, protocol?: LlmApiProtocol): Record<string, unknown>;