@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.
- package/CHANGELOG.md +17 -0
- package/README.md +61 -25
- package/dist/capabilities/speech-recognition/bailian/module.js +15 -3
- package/dist/capabilities/speech-recognition/bailian/parse.js +9 -1
- package/dist/capabilities/speech-recognition/bailian/presets.d.ts +3 -1
- package/dist/capabilities/speech-recognition/bailian/presets.js +4 -0
- package/dist/capabilities/speech-recognition/bailian/realtime/presets.d.ts +2 -1
- package/dist/capabilities/speech-recognition/bailian/realtime/presets.js +2 -0
- package/dist/capabilities/speech-recognition/bailian/realtime/protocol.js +8 -0
- package/dist/capabilities/speech-recognition/bailian/realtime/types.d.ts +3 -0
- package/dist/capabilities/speech-recognition/bailian/types.d.ts +4 -0
- package/dist/capabilities/speech-recognition/index.d.ts +2 -0
- package/dist/catalog/index.js +39 -35
- package/dist/catalog/kie/happyhorse-1.1.model.d.ts +2 -0
- package/dist/catalog/kie/happyhorse-1.1.model.js +67 -0
- package/dist/catalog/volcengine/seedream-5.0-flash.model.d.ts +2 -0
- package/dist/catalog/volcengine/seedream-5.0-flash.model.js +7 -0
- package/dist/catalog/volcengine/seedream-5.0-pro.model.d.ts +0 -1
- package/dist/catalog/volcengine/seedream-5.0-pro.model.js +5 -147
- package/dist/catalog/volcengine/seedream-5.0.d.ts +11 -0
- package/dist/catalog/volcengine/seedream-5.0.js +153 -0
- package/dist/llm/bigmodel/profiles.d.ts +2 -0
- package/dist/llm/bigmodel/profiles.js +8 -1
- package/dist/llm/chat.d.ts +3 -1
- package/dist/llm/chat.js +12 -2
- package/dist/llm/chatTypes.d.ts +7 -1
- package/dist/llm/defaults.js +1 -0
- package/dist/llm/groq/module.js +1 -0
- package/dist/llm/groq/preset.js +1 -0
- package/dist/llm/modelCatalog.d.ts +2 -0
- package/dist/llm/modelCatalog.js +1 -0
- package/dist/llm/modelCatalogEntries.js +30 -6
- package/dist/llm/modelStep.d.ts +2 -2
- package/dist/llm/providerPresets.js +4 -3
- package/dist/llm/providerProtocolCore.js +2 -1
- package/dist/llm/providerReasoningRequest.d.ts +2 -1
- package/dist/llm/providerReasoningRequest.js +27 -5
- package/dist/llm/sdk/mimoResponses.d.ts +4 -0
- package/dist/llm/sdk/mimoResponses.js +42 -0
- package/dist/llm/sdk/provider.js +4 -2
- package/dist/llm/streaming/index.d.ts +1 -1
- package/dist/llm/streaming.d.ts +2 -1
- package/dist/llm/streaming.js +100 -14
- package/dist/llm/types.d.ts +19 -0
- package/dist/packs/models/kie/happyhorse-1.1.d.ts +6 -0
- package/dist/packs/models/kie/happyhorse-1.1.js +7 -0
- package/dist/packs/models/volcengine/seedream-5.0-flash.d.ts +6 -0
- package/dist/packs/models/volcengine/seedream-5.0-flash.js +7 -0
- package/dist/packs/provider-packs/kie.d.ts +1 -1
- package/dist/packs/provider-packs/kie.js +22 -21
- package/dist/packs/provider-packs/volcengine.d.ts +1 -1
- package/dist/packs/provider-packs/volcengine.js +4 -3
- package/docs/consumers.md +20 -4
- package/docs/llm-adaptation/README.md +8 -8
- package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/DeepSeek.md +4 -3
- package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206/Kimi.md +3 -2
- package/docs/llm-adaptation//344/276/233/345/272/224/345/225/206//345/260/217/347/261/263MiMo.md +42 -1
- package/docs/model-adaptation/GLM-5.3-Flash/GLM-5.3-Flash_/346/231/272/350/260/261.md +6 -0
- package/docs/model-adaptation/HappyHorse-1.1/HappyHorse-1.1_KIE.md +27 -0
- package/docs/model-adaptation/README.md +11 -3
- 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
- package/docs/model-adaptation//344/276/233/345/272/224/345/225/206//347/231/276/347/202/274.md +19 -0
- package/examples/form-renderer/package.json +1 -1
- package/examples/llm-chat/README.md +8 -2
- package/examples/llm-chat/index.ts +1 -1
- package/examples/llm-chat/package.json +1 -1
- package/examples/minimal-node/package.json +1 -1
- package/package.json +258 -258
|
@@ -32,6 +32,7 @@ function pickEffort(effort, supported) {
|
|
|
32
32
|
return picked;
|
|
33
33
|
}
|
|
34
34
|
const PROVIDER_REASONING_BODY = {
|
|
35
|
+
mimo: reasoning => ({ thinking: { type: reasoning.enabled ? 'enabled' : 'disabled' } }),
|
|
35
36
|
// 硅基流动的思考开关与原厂不同;强度字段只发送给端点文档明确列举的模型。
|
|
36
37
|
siliconflow: (reasoning, body) => ({
|
|
37
38
|
enable_thinking: reasoning.enabled,
|
|
@@ -75,8 +76,6 @@ const PROVIDER_REASONING_BODY = {
|
|
|
75
76
|
include_reasoning: true,
|
|
76
77
|
}
|
|
77
78
|
: { include_reasoning: false }),
|
|
78
|
-
// 小米 MiMo、MiniMax:官方文档只约定了思考内容怎么回传,没有给出请求侧的开关或强度字段,
|
|
79
|
-
// 因此不下发任何字段。等文档补齐再加,不要凭字段名相似猜。
|
|
80
79
|
};
|
|
81
80
|
/**
|
|
82
81
|
* 未登记供应商的兜底:只发 OpenAI 事实标准字段,关闭时什么都不发。
|
|
@@ -101,11 +100,34 @@ function resolveReasoningKey(providerId, adapter) {
|
|
|
101
100
|
export function hasProviderReasoningRule(providerId, adapter) {
|
|
102
101
|
return resolveReasoningKey(providerId, adapter) !== null;
|
|
103
102
|
}
|
|
104
|
-
export function applyProviderReasoningRequestBody(providerId, adapter, body, reasoning) {
|
|
105
|
-
if (!reasoning)
|
|
106
|
-
return body;
|
|
103
|
+
export function applyProviderReasoningRequestBody(providerId, adapter, body, reasoning, protocol = 'openai-compatible') {
|
|
107
104
|
const key = resolveReasoningKey(providerId, adapter);
|
|
105
|
+
if (!reasoning && key !== 'mimo')
|
|
106
|
+
return body;
|
|
107
|
+
reasoning ??= { enabled: true, effort: 'high' };
|
|
108
108
|
const build = key ? PROVIDER_REASONING_BODY[key] : defaultReasoningBody;
|
|
109
|
+
if (key === 'mimo') {
|
|
110
|
+
const { thinking: _thinking, reasoning_effort: _effort, reasoning: _reasoning, ...clean } = body;
|
|
111
|
+
// MiMo 思考时采样参数固定为 1 / 0.95;省略可避免用户采样设置造成 400。
|
|
112
|
+
if (reasoning.enabled) {
|
|
113
|
+
delete clean.temperature;
|
|
114
|
+
delete clean.top_p;
|
|
115
|
+
}
|
|
116
|
+
if (protocol === 'openai-responses' && Array.isArray(clean.input)) {
|
|
117
|
+
clean.input = clean.input.map((item) => {
|
|
118
|
+
if (!item || typeof item !== 'object' || Array.isArray(item))
|
|
119
|
+
return item;
|
|
120
|
+
const value = item;
|
|
121
|
+
if (value.type !== 'reasoning' || !Array.isArray(value.summary))
|
|
122
|
+
return value;
|
|
123
|
+
const { summary, encrypted_content: _encrypted, ...rest } = value;
|
|
124
|
+
return { ...rest, content: summary.map((part) => ({ type: 'reasoning_text', text: part.text })) };
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
return protocol === 'openai-responses'
|
|
128
|
+
? { ...clean, reasoning: { effort: reasoning.enabled ? 'high' : 'none' } }
|
|
129
|
+
: { ...clean, ...build(reasoning, clean) };
|
|
130
|
+
}
|
|
109
131
|
if (key === 'siliconflow') {
|
|
110
132
|
const { thinking: _thinking, reasoning_effort: _effort, ...clean } = body;
|
|
111
133
|
return { ...clean, ...build(reasoning, clean) };
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { EventSourceParserStream } from '@ai-sdk/provider-utils';
|
|
2
|
+
/** MiMo 返回完整 reasoning_text;OpenAI adapter 只识别 summary 事件。
|
|
3
|
+
* 只在 MiMo Responses 边界改写事件名/索引,不丢弃正文、工具或 usage。
|
|
4
|
+
*/
|
|
5
|
+
export function adaptMimoResponses(response) {
|
|
6
|
+
if (!response.ok || !response.body || !response.headers.get('content-type')?.includes('text/event-stream'))
|
|
7
|
+
return response;
|
|
8
|
+
let terminal = false;
|
|
9
|
+
const stream = response.body
|
|
10
|
+
.pipeThrough(new TextDecoderStream())
|
|
11
|
+
.pipeThrough(new EventSourceParserStream())
|
|
12
|
+
.pipeThrough(new TransformStream({
|
|
13
|
+
transform(event, controller) {
|
|
14
|
+
if (!event.data || event.data === '[DONE]')
|
|
15
|
+
return;
|
|
16
|
+
const value = JSON.parse(event.data);
|
|
17
|
+
if (['response.completed', 'response.incomplete', 'response.failed', 'error'].includes(String(value.type)))
|
|
18
|
+
terminal = true;
|
|
19
|
+
if (value.type === 'response.reasoning_text.delta') {
|
|
20
|
+
value.type = 'response.reasoning_summary_text.delta';
|
|
21
|
+
value.summary_index = value.content_index ?? 0;
|
|
22
|
+
}
|
|
23
|
+
else if (value.type === 'response.content_part.added' || value.type === 'response.content_part.done') {
|
|
24
|
+
const part = value.part;
|
|
25
|
+
if (part?.type === 'reasoning_text') {
|
|
26
|
+
value.type = value.type === 'response.content_part.added'
|
|
27
|
+
? 'response.reasoning_summary_part.added' : 'response.reasoning_summary_part.done';
|
|
28
|
+
value.summary_index = value.content_index ?? 0;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
controller.enqueue(new TextEncoder().encode(`data: ${JSON.stringify(value)}\n\n`));
|
|
32
|
+
},
|
|
33
|
+
flush() {
|
|
34
|
+
if (!terminal)
|
|
35
|
+
throw new Error('[provider_response_incomplete] MiMo Responses stream ended before a terminal event');
|
|
36
|
+
},
|
|
37
|
+
}));
|
|
38
|
+
const headers = new Headers(response.headers);
|
|
39
|
+
headers.delete('content-length');
|
|
40
|
+
headers.delete('content-encoding');
|
|
41
|
+
return new Response(stream, { status: response.status, statusText: response.statusText, headers });
|
|
42
|
+
}
|
package/dist/llm/sdk/provider.js
CHANGED
|
@@ -3,6 +3,7 @@ import { createOpenAI } from '@ai-sdk/openai';
|
|
|
3
3
|
import { fetchProvider } from '../../providers/provider-fetch.js';
|
|
4
4
|
import { applyProviderRequestBodyQuirks, resolveProviderExtraAuthHeaders, } from '../providerProtocol.js';
|
|
5
5
|
import { applyProviderReasoningRequestBody } from '../providerReasoningRequest.js';
|
|
6
|
+
import { adaptMimoResponses } from './mimoResponses.js';
|
|
6
7
|
import { resolveOpenAiCompatibleEndpoint, resolvePpioChatEndpoint } from '../streaming.js';
|
|
7
8
|
import { modelStepProviderAdapters, } from './providerAdapter.js';
|
|
8
9
|
import { getLlmEndpointProfileFamily, resolveLlmEndpointIdentity } from '../endpointProfiles.js';
|
|
@@ -92,7 +93,7 @@ function createOpenAiResponsesLanguageModel(input, apiKey, httpTrace, transport)
|
|
|
92
93
|
captureHttp: httpTrace?.captureHttp === true,
|
|
93
94
|
captureDeepSeekUsage: adapter === 'deepseek',
|
|
94
95
|
transformRequestBody: body => applyProviderRequestBodyQuirks(identity.providerFamilyId, input.capabilities.reasoning
|
|
95
|
-
? applyProviderReasoningRequestBody(identity.providerFamilyId, adapter, body, input.reasoning)
|
|
96
|
+
? applyProviderReasoningRequestBody(identity.providerFamilyId, adapter, body, input.reasoning, 'openai-responses')
|
|
96
97
|
: body),
|
|
97
98
|
}),
|
|
98
99
|
});
|
|
@@ -159,7 +160,8 @@ function createModelStepFetch(providerId, trace, transport, options) {
|
|
|
159
160
|
trace.deepSeekUsage = usage;
|
|
160
161
|
}).catch(() => undefined);
|
|
161
162
|
}
|
|
162
|
-
return
|
|
163
|
+
return providerId === 'mimo' && /\/responses(?:\?|$)/.test(request.url)
|
|
164
|
+
? adaptMimoResponses(response) : response;
|
|
163
165
|
}
|
|
164
166
|
catch (error) {
|
|
165
167
|
if (options.captureHttp && trace) {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
export { cancelLlmChatTask, normalizeLlmChatError, resolveLlmTaskId, runLlmChatStream, } from '../chat.js';
|
|
8
8
|
export type { LlmChatCompletedInfo, LlmChatRequestBuiltInfo, LlmChatStreamHooks, LlmChatStreamOutcome, } from '../chat.js';
|
|
9
9
|
export type { JsonObject, JsonValue, LlmChatMessageDto, LlmChatRequestDto, LlmContentPart, LlmRole, LlmStreamEmitter, LlmStreamEventDto, LlmStreamOutput, LlmTraceDto, LlmUsageDto, } from '../chatTypes.js';
|
|
10
|
-
export type { LlmReasoningConfig, LlmReasoningEffort } from '../
|
|
10
|
+
export type { LlmReasoningConfig, LlmReasoningEffort, LlmStructuredOutputConfig, } from '../types.js';
|
|
11
11
|
export { parseModelProviderError, ProviderModelStepError, serializeModelProviderError, } from '../../runtime/provider-error-core.js';
|
|
12
12
|
export type { ModelProviderError, ModelProviderErrorCategory, } from '../../runtime/provider-error-core.js';
|
|
13
13
|
export type { RuntimeContext } from '../../runtime/RuntimeContext.js';
|
package/dist/llm/streaming.d.ts
CHANGED
|
@@ -12,7 +12,8 @@ import type { JsonObject, LlmChatMessageDto, LlmChatRequestDto, LlmStreamEmitter
|
|
|
12
12
|
interface StreamChatOptions {
|
|
13
13
|
endpoint: string;
|
|
14
14
|
apiKey: string;
|
|
15
|
-
|
|
15
|
+
providerId: string;
|
|
16
|
+
payload: JsonObject;
|
|
16
17
|
signal: AbortSignal;
|
|
17
18
|
emit: LlmStreamEmitter;
|
|
18
19
|
transport: Transport;
|
package/dist/llm/streaming.js
CHANGED
|
@@ -25,15 +25,15 @@ export function resolveOpenAiCompatibleEndpoint(request) {
|
|
|
25
25
|
: `${normalized}/v1/chat/completions`;
|
|
26
26
|
}
|
|
27
27
|
export function buildOpenAiCompatiblePayload(request) {
|
|
28
|
-
const policy = request.policy ?? {};
|
|
29
28
|
const payload = {
|
|
30
29
|
model: request.modelId,
|
|
31
30
|
messages: request.messages.map(serializeMessage),
|
|
32
31
|
stream: true,
|
|
33
32
|
stream_options: { include_usage: true },
|
|
34
33
|
};
|
|
35
|
-
const maxTokens =
|
|
36
|
-
|
|
34
|
+
const maxTokens = resolveMaxOutputTokens(request);
|
|
35
|
+
if (maxTokens !== undefined)
|
|
36
|
+
payload.max_tokens = maxTokens;
|
|
37
37
|
if (request.tools !== undefined) {
|
|
38
38
|
payload.tools = request.tools;
|
|
39
39
|
}
|
|
@@ -45,23 +45,23 @@ export function buildOpenAiCompatiblePayload(request) {
|
|
|
45
45
|
* 用模型能力表兜一层,没标"支持思考"的模型仍然一个字段都不发。
|
|
46
46
|
*/
|
|
47
47
|
const identity = resolveLlmEndpointIdentity(request);
|
|
48
|
+
const withStructuredOutput = applyStructuredOutputRequestBody(request, identity.providerFamilyId, payload);
|
|
48
49
|
const reasoningCapable = request.capabilities?.reasoning === true;
|
|
49
50
|
const withReasoning = reasoningCapable
|
|
50
|
-
? applyProviderReasoningRequestBody(identity.providerFamilyId, request.adapter,
|
|
51
|
-
:
|
|
51
|
+
? applyProviderReasoningRequestBody(identity.providerFamilyId, request.adapter, withStructuredOutput, request.reasoning)
|
|
52
|
+
: withStructuredOutput;
|
|
52
53
|
return applyProviderRequestBodyQuirks(identity.providerFamilyId, withReasoning);
|
|
53
54
|
}
|
|
54
55
|
export async function streamOpenAiCompatibleChat(options) {
|
|
55
|
-
const
|
|
56
|
-
const response = await fetchProvider(identity.providerFamilyId, options.endpoint, {
|
|
56
|
+
const response = await fetchProvider(options.providerId, options.endpoint, {
|
|
57
57
|
method: 'POST',
|
|
58
58
|
headers: {
|
|
59
59
|
Accept: 'text/event-stream',
|
|
60
60
|
Authorization: `Bearer ${options.apiKey}`,
|
|
61
|
-
...resolveProviderExtraAuthHeaders(
|
|
61
|
+
...resolveProviderExtraAuthHeaders(options.providerId, options.apiKey),
|
|
62
62
|
'Content-Type': 'application/json',
|
|
63
63
|
},
|
|
64
|
-
body: JSON.stringify(
|
|
64
|
+
body: JSON.stringify(options.payload),
|
|
65
65
|
signal: options.signal,
|
|
66
66
|
}, {
|
|
67
67
|
transport: options.transport,
|
|
@@ -160,7 +160,14 @@ async function readSseStream(body, emit) {
|
|
|
160
160
|
for (const event of parsed.events) {
|
|
161
161
|
const chunk = parseSseData(event);
|
|
162
162
|
if (chunk.done) {
|
|
163
|
-
return {
|
|
163
|
+
return {
|
|
164
|
+
output,
|
|
165
|
+
reasoningOutput,
|
|
166
|
+
usage,
|
|
167
|
+
finishReason,
|
|
168
|
+
truncated: isOutputTruncated(finishReason),
|
|
169
|
+
toolCalls: [...toolCalls.values()],
|
|
170
|
+
};
|
|
164
171
|
}
|
|
165
172
|
usage = chunk.usage ?? usage;
|
|
166
173
|
finishReason = chunk.finishReason ?? finishReason;
|
|
@@ -194,7 +201,89 @@ async function readSseStream(body, emit) {
|
|
|
194
201
|
emit({ type: 'Token', data: chunk.content });
|
|
195
202
|
}
|
|
196
203
|
}
|
|
197
|
-
return {
|
|
204
|
+
return {
|
|
205
|
+
output,
|
|
206
|
+
reasoningOutput,
|
|
207
|
+
usage,
|
|
208
|
+
finishReason,
|
|
209
|
+
truncated: isOutputTruncated(finishReason),
|
|
210
|
+
toolCalls: [...toolCalls.values()],
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
function applyStructuredOutputRequestBody(request, providerId, body) {
|
|
214
|
+
const output = request.structuredOutput;
|
|
215
|
+
if (!output)
|
|
216
|
+
return body;
|
|
217
|
+
if (output.type === 'text') {
|
|
218
|
+
return { ...body, response_format: { type: 'text' } };
|
|
219
|
+
}
|
|
220
|
+
const supportedMode = request.capabilities?.structuredOutputMode ?? 'none';
|
|
221
|
+
if (output.type === 'json_object' && supportedMode === 'none') {
|
|
222
|
+
throw invalidRequest('STRUCTURED_OUTPUT_JSON_OBJECT_UNSUPPORTED', `Model "${request.modelId}" is not declared to support JSON Object output.`);
|
|
223
|
+
}
|
|
224
|
+
if (output.type === 'json_schema' && supportedMode !== 'schema') {
|
|
225
|
+
throw invalidRequest('STRUCTURED_OUTPUT_JSON_SCHEMA_UNSUPPORTED', `Model "${request.modelId}" is not declared to support JSON Schema output.`);
|
|
226
|
+
}
|
|
227
|
+
if (request.reasoning?.enabled === true) {
|
|
228
|
+
if (request.capabilities?.reasoning !== true) {
|
|
229
|
+
throw invalidRequest('REASONING_UNSUPPORTED', `Model "${request.modelId}" is not declared to support reasoning.`);
|
|
230
|
+
}
|
|
231
|
+
const compatibility = request.capabilities.structuredOutputWithReasoning;
|
|
232
|
+
if (compatibility !== true) {
|
|
233
|
+
throw invalidRequest(compatibility === false
|
|
234
|
+
? 'STRUCTURED_OUTPUT_WITH_REASONING_UNSUPPORTED'
|
|
235
|
+
: 'STRUCTURED_OUTPUT_WITH_REASONING_CAPABILITY_REQUIRED', compatibility === false
|
|
236
|
+
? `Model "${request.modelId}" does not support structured output with reasoning enabled.`
|
|
237
|
+
: `Model "${request.modelId}" must explicitly declare structuredOutputWithReasoning before structured output and reasoning can be combined.`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
if (output.type === 'json_object') {
|
|
241
|
+
return { ...body, response_format: { type: 'json_object' } };
|
|
242
|
+
}
|
|
243
|
+
if (providerId.trim().toLowerCase() === 'groq') {
|
|
244
|
+
throw invalidRequest('STRUCTURED_OUTPUT_STREAMING_UNSUPPORTED', 'Groq does not support JSON Schema structured output with streaming.');
|
|
245
|
+
}
|
|
246
|
+
if (!output.name.trim()) {
|
|
247
|
+
throw invalidRequest('INVALID_STRUCTURED_OUTPUT', 'JSON Schema output requires a non-empty name.');
|
|
248
|
+
}
|
|
249
|
+
if (!isRecord(output.schema)) {
|
|
250
|
+
throw invalidRequest('INVALID_STRUCTURED_OUTPUT', 'JSON Schema output requires schema to be an object.');
|
|
251
|
+
}
|
|
252
|
+
if (typeof output.strict !== 'boolean') {
|
|
253
|
+
throw invalidRequest('INVALID_STRUCTURED_OUTPUT', 'JSON Schema output requires an explicit strict boolean.');
|
|
254
|
+
}
|
|
255
|
+
return {
|
|
256
|
+
...body,
|
|
257
|
+
response_format: {
|
|
258
|
+
type: 'json_schema',
|
|
259
|
+
json_schema: {
|
|
260
|
+
name: output.name.trim(),
|
|
261
|
+
schema: output.schema,
|
|
262
|
+
strict: output.strict,
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
function resolveMaxOutputTokens(request) {
|
|
268
|
+
const policy = request.policy ?? {};
|
|
269
|
+
const legacy = policy.max_tokens ?? policy.maxTokens;
|
|
270
|
+
const candidate = request.maxOutputTokens ?? legacy;
|
|
271
|
+
if (candidate === undefined)
|
|
272
|
+
return undefined;
|
|
273
|
+
if (typeof candidate !== 'number' || !Number.isInteger(candidate) || candidate <= 0) {
|
|
274
|
+
throw invalidRequest('INVALID_MAX_OUTPUT_TOKENS', 'maxOutputTokens must be a positive integer.');
|
|
275
|
+
}
|
|
276
|
+
const modelLimit = request.capabilities?.maxOutputTokens;
|
|
277
|
+
if (typeof modelLimit === 'number' && candidate > modelLimit) {
|
|
278
|
+
throw invalidRequest('MAX_OUTPUT_TOKENS_EXCEEDED', `Requested ${candidate} output tokens, but model "${request.modelId}" declares a limit of ${modelLimit}.`);
|
|
279
|
+
}
|
|
280
|
+
return candidate;
|
|
281
|
+
}
|
|
282
|
+
function invalidRequest(code, message) {
|
|
283
|
+
return Object.assign(new Error(message), { code, statusCode: 400 });
|
|
284
|
+
}
|
|
285
|
+
function isOutputTruncated(finishReason) {
|
|
286
|
+
return finishReason === 'length' || finishReason === 'max_tokens' || finishReason === 'max_output_tokens';
|
|
198
287
|
}
|
|
199
288
|
function drainSseEvents(input) {
|
|
200
289
|
const events = [];
|
|
@@ -312,9 +401,6 @@ function readDelta(value) {
|
|
|
312
401
|
function readString(value) {
|
|
313
402
|
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
314
403
|
}
|
|
315
|
-
function readNumber(value) {
|
|
316
|
-
return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
|
|
317
|
-
}
|
|
318
404
|
function readTokenCount(value) {
|
|
319
405
|
return typeof value === 'number' && Number.isFinite(value) && value >= 0 ? value : null;
|
|
320
406
|
}
|
package/dist/llm/types.d.ts
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
import type { LlmApiProtocol } from './providerProtocol.js';
|
|
2
2
|
import type { LlmReasoningConfig } from './reasoning.js';
|
|
3
|
+
import type { JsonObject } from '../types/runtime.js';
|
|
3
4
|
export type { LlmReasoningConfig, LlmReasoningEffort } from './reasoning.js';
|
|
5
|
+
/** Chat Completions 的正式输出格式配置;省略时由供应商使用默认文本格式。 */
|
|
6
|
+
export type LlmStructuredOutputConfig = {
|
|
7
|
+
type: 'text';
|
|
8
|
+
} | {
|
|
9
|
+
type: 'json_object';
|
|
10
|
+
} | {
|
|
11
|
+
type: 'json_schema';
|
|
12
|
+
name: string;
|
|
13
|
+
schema: JsonObject;
|
|
14
|
+
strict: boolean;
|
|
15
|
+
};
|
|
4
16
|
export interface LlmCapabilities {
|
|
5
17
|
text: boolean;
|
|
6
18
|
image: boolean;
|
|
@@ -13,6 +25,11 @@ export interface LlmCapabilities {
|
|
|
13
25
|
parallelTools: boolean;
|
|
14
26
|
jsonOutput: boolean;
|
|
15
27
|
structuredOutputMode: 'none' | 'json' | 'schema';
|
|
28
|
+
/**
|
|
29
|
+
* 结构化输出能否与思考模式同时启用。`null` / 缺省表示尚未核实;
|
|
30
|
+
* 轻量流式入口在调用方明确开启两者时会拒绝未知组合,避免静默丢参数。
|
|
31
|
+
*/
|
|
32
|
+
structuredOutputWithReasoning?: boolean | null;
|
|
16
33
|
reasoning: boolean;
|
|
17
34
|
sampling: boolean;
|
|
18
35
|
contextWindow: number | null;
|
|
@@ -282,6 +299,8 @@ export interface LlmChatRequest {
|
|
|
282
299
|
reasoning?: LlmReasoningConfig;
|
|
283
300
|
messages: LlmChatMessage[];
|
|
284
301
|
capabilities?: Partial<LlmCapabilities>;
|
|
302
|
+
structuredOutput?: LlmStructuredOutputConfig;
|
|
303
|
+
maxOutputTokens?: number;
|
|
285
304
|
tools?: LlmToolSchema[];
|
|
286
305
|
policy?: Partial<LlmPolicy>;
|
|
287
306
|
memory?: LlmMemoryScope;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** 由 scripts/generate-catalog-index.cjs 自动生成;`pack` 是完整执行单元,`model` 仅供低层目录用途。 */
|
|
2
|
+
import model from '../../../catalog/kie/happyhorse-1.1.model.js';
|
|
3
|
+
import type { GenerationClientProviderRegistration, GenerationPack } from '../../../generation/core.js';
|
|
4
|
+
export { model };
|
|
5
|
+
export declare const provider: GenerationClientProviderRegistration;
|
|
6
|
+
export declare const pack: GenerationPack;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** 由 scripts/generate-catalog-index.cjs 自动生成;`pack` 是完整执行单元,`model` 仅供低层目录用途。 */
|
|
2
|
+
import model from '../../../catalog/kie/happyhorse-1.1.model.js';
|
|
3
|
+
import * as adapter from '../../../providers/kie.js';
|
|
4
|
+
import { preprocess } from '../../../upload/provider-preprocessors/kie.js';
|
|
5
|
+
export { model };
|
|
6
|
+
export const provider = { id: 'kie', adapter, preprocess };
|
|
7
|
+
export const pack = { models: [model], providers: [provider] };
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** 由 scripts/generate-catalog-index.cjs 自动生成;`pack` 是完整执行单元,`model` 仅供低层目录用途。 */
|
|
2
|
+
import model from '../../../catalog/volcengine/seedream-5.0-flash.model.js';
|
|
3
|
+
import type { GenerationClientProviderRegistration, GenerationPack } from '../../../generation/core.js';
|
|
4
|
+
export { model };
|
|
5
|
+
export declare const provider: GenerationClientProviderRegistration;
|
|
6
|
+
export declare const pack: GenerationPack;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** 由 scripts/generate-catalog-index.cjs 自动生成;`pack` 是完整执行单元,`model` 仅供低层目录用途。 */
|
|
2
|
+
import model from '../../../catalog/volcengine/seedream-5.0-flash.model.js';
|
|
3
|
+
import * as adapter from '../../../providers/volcengine.js';
|
|
4
|
+
import { preprocess } from '../../../upload/provider-preprocessors/data-uri.js';
|
|
5
|
+
export { model };
|
|
6
|
+
export const provider = { id: 'volcengine', adapter, preprocess };
|
|
7
|
+
export const pack = { models: [model], providers: [provider] };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { GenerationPack } from '../../generation/core.js';
|
|
2
|
-
export declare const models: readonly [import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition];
|
|
2
|
+
export declare const models: readonly [import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition];
|
|
3
3
|
export declare const pack: GenerationPack;
|
|
4
4
|
export default pack;
|
|
@@ -7,27 +7,28 @@ import model5 from '../../catalog/kie/grok-imagine-video.model.js';
|
|
|
7
7
|
import model6 from '../../catalog/kie/grok-imagine.model.js';
|
|
8
8
|
import model7 from '../../catalog/kie/hailuo-02.model.js';
|
|
9
9
|
import model8 from '../../catalog/kie/hailuo-2-3.model.js';
|
|
10
|
-
import model9 from '../../catalog/kie/
|
|
11
|
-
import model10 from '../../catalog/kie/kling-3.0-
|
|
12
|
-
import model11 from '../../catalog/kie/kling-3.0.model.js';
|
|
13
|
-
import model12 from '../../catalog/kie/kling-
|
|
14
|
-
import model13 from '../../catalog/kie/
|
|
15
|
-
import model14 from '../../catalog/kie/
|
|
16
|
-
import model15 from '../../catalog/kie/nano-banana-2.model.js';
|
|
17
|
-
import model16 from '../../catalog/kie/nano-banana-
|
|
18
|
-
import model17 from '../../catalog/kie/
|
|
19
|
-
import model18 from '../../catalog/kie/
|
|
20
|
-
import model19 from '../../catalog/kie/seedance-
|
|
21
|
-
import model20 from '../../catalog/kie/seedance-2.0-
|
|
22
|
-
import model21 from '../../catalog/kie/seedance-2.0.model.js';
|
|
23
|
-
import model22 from '../../catalog/kie/seedance-2.
|
|
24
|
-
import model23 from '../../catalog/kie/seedance-
|
|
25
|
-
import model24 from '../../catalog/kie/
|
|
26
|
-
import model25 from '../../catalog/kie/seedream-4.
|
|
27
|
-
import model26 from '../../catalog/kie/seedream-5.
|
|
28
|
-
import model27 from '../../catalog/kie/seedream-5.0-
|
|
29
|
-
import model28 from '../../catalog/kie/
|
|
10
|
+
import model9 from '../../catalog/kie/happyhorse-1.1.model.js';
|
|
11
|
+
import model10 from '../../catalog/kie/kling-3.0-omni.model.js';
|
|
12
|
+
import model11 from '../../catalog/kie/kling-3.0-turbo.model.js';
|
|
13
|
+
import model12 from '../../catalog/kie/kling-3.0.model.js';
|
|
14
|
+
import model13 from '../../catalog/kie/kling-v2-6.model.js';
|
|
15
|
+
import model14 from '../../catalog/kie/minimax-h3.model.js';
|
|
16
|
+
import model15 from '../../catalog/kie/nano-banana-2-lite.model.js';
|
|
17
|
+
import model16 from '../../catalog/kie/nano-banana-2.model.js';
|
|
18
|
+
import model17 from '../../catalog/kie/nano-banana-pro.model.js';
|
|
19
|
+
import model18 from '../../catalog/kie/qwen-image-3.0.model.js';
|
|
20
|
+
import model19 from '../../catalog/kie/seedance-1.5-pro.model.js';
|
|
21
|
+
import model20 from '../../catalog/kie/seedance-2.0-fast.model.js';
|
|
22
|
+
import model21 from '../../catalog/kie/seedance-2.0-mini.model.js';
|
|
23
|
+
import model22 from '../../catalog/kie/seedance-2.0.model.js';
|
|
24
|
+
import model23 from '../../catalog/kie/seedance-2.5.model.js';
|
|
25
|
+
import model24 from '../../catalog/kie/seedance-v1.model.js';
|
|
26
|
+
import model25 from '../../catalog/kie/seedream-4.0.model.js';
|
|
27
|
+
import model26 from '../../catalog/kie/seedream-4.5.model.js';
|
|
28
|
+
import model27 from '../../catalog/kie/seedream-5.0-lite.model.js';
|
|
29
|
+
import model28 from '../../catalog/kie/seedream-5.0-pro.model.js';
|
|
30
|
+
import model29 from '../../catalog/kie/z-image.model.js';
|
|
30
31
|
import { provider } from '../provider-adapters/kie.js';
|
|
31
|
-
export const models = [model1, model2, model3, model4, model5, model6, model7, model8, model9, model10, model11, model12, model13, model14, model15, model16, model17, model18, model19, model20, model21, model22, model23, model24, model25, model26, model27, model28];
|
|
32
|
+
export const models = [model1, model2, model3, model4, model5, model6, model7, model8, model9, model10, model11, model12, model13, model14, model15, model16, model17, model18, model19, model20, model21, model22, model23, model24, model25, model26, model27, model28, model29];
|
|
32
33
|
export const pack = { models, providers: [provider] };
|
|
33
34
|
export default pack;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { GenerationPack } from '../../generation/core.js';
|
|
2
|
-
export declare const models: readonly [import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition];
|
|
2
|
+
export declare const models: readonly [import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition, import("../../index.js").ModelRuntimeDefinition];
|
|
3
3
|
export declare const pack: GenerationPack;
|
|
4
4
|
export default pack;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/** 由 scripts/generate-catalog-index.cjs 自动生成;只聚合当前供应商的真实模型文件。 */
|
|
2
|
-
import model1 from '../../catalog/volcengine/seedream-5.0-
|
|
3
|
-
import model2 from '../../catalog/volcengine/seedream-5.0-
|
|
2
|
+
import model1 from '../../catalog/volcengine/seedream-5.0-flash.model.js';
|
|
3
|
+
import model2 from '../../catalog/volcengine/seedream-5.0-lite.model.js';
|
|
4
|
+
import model3 from '../../catalog/volcengine/seedream-5.0-pro.model.js';
|
|
4
5
|
import { provider } from '../provider-adapters/volcengine.js';
|
|
5
|
-
export const models = [model1, model2];
|
|
6
|
+
export const models = [model1, model2, model3];
|
|
6
7
|
export const pack = { models, providers: [provider] };
|
|
7
8
|
export default pack;
|
package/docs/consumers.md
CHANGED
|
@@ -3,13 +3,29 @@
|
|
|
3
3
|
本清单是 `@henjicc/ai-sdk` 消费方的唯一维护入口,用于 SDK 发布后的跨仓升级协调。
|
|
4
4
|
绝对路径仅描述当前开发机上的仓库位置,不进入 SDK 运行时代码、发布包或用户配置。
|
|
5
5
|
|
|
6
|
-
最后核对日期:2026-09-
|
|
6
|
+
最后核对日期:2026-09-24
|
|
7
|
+
|
|
8
|
+
`0.6.0` 候选版本:新增 MiMo 2.6、GLM-5.3-FlashX、KIE HappyHorse 1.1、火山 Seedream 5.0 Flash 和百炼 Qwen Audio 3.1 ASR;补齐 MiMo Responses 思考事件与 ASR JSON/说话人解析。SDK 79 个测试文件 / 933 项测试、类型构建、可移植性、49 个公开入口和受限宿主验证通过;痕迹 AI 目录、参数组合、模型发现与旧配置兼容验证通过。MiMo 思考事件、ASR JSON 回退、HappyHorse 图生字段的修复撤销验证均检测到失败,恢复后通过。未执行付费请求。等待发布提交 CI 和 npm 身份恢复,尚未公共发布。
|
|
9
|
+
|
|
10
|
+
本轮消费影响:Henji-AI 自动组合新增 generation pack,无需新增助手工具;三个仓内示例的精确依赖同步到 `0.6.0`,公共发布后的独立安装验证待完成。外部 `say-it` 仍需先完成 `0.5.0` 文件上传桥迁移;当前未引入这批模型,不机械升级。`henji-ai-ps` 本机未定位,不声称已完成外部宿主升级。
|
|
7
11
|
|
|
8
12
|
Henji-AI 安装包的 GPT Image 2.5 高分辨率报错归属:宿主智能比例预处理曾忽略联动过滤,将 `smart` 转成 KIE 仅限 1K 的 `27:16`,SDK 在请求前正确拒绝。修复位于应用公共预处理,按当前分辨率/渠道的合法选项匹配;Flare/Sunburst 的 1K/2K/4K 及 APIMart、Grsai 同类筛选已有定向覆盖。无需放宽 SDK 契约或发布 SDK;安装包需随应用更新才包含修复,现有版本可手动选合法比例规避。
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
当前仓内候选 SDK:`0.6.0`;最近已确认公共 npm SDK:`0.5.2`(2026-09-21 已发布并完成公共匿名回装)。以下为历史发布证据。
|
|
15
|
+
|
|
16
|
+
`0.5.2` 完善轻量 `@henjicc/ai-sdk/llm/streaming`:正式类型支持文本、JSON Object 与 JSON Schema,Chat Completions 的最终请求体写入 `response_format`,OpenAI 输出上限写入 `max_completion_tokens`;结构化输出、思考模式和模型能力的非法组合会在请求前返回结构化错误。流式正文与思考继续分离,保留外部 `AbortSignal`,不设置默认总时限;未显式配置输出上限时不再注入 4096,服务端以 `length` 等原因结束时返回 `truncated: true`。发布前 77 个测试文件 / 909 项测试、可移植性、构建、49 个 Vite 公开入口和受限宿主门禁通过;故意撤销结构化参数、输出上限、OpenAI 字段映射和截断标记后,8 项定向断言失败,恢复后通过。公共索引可读后,已使用隔离 npm 配置和缓存匿名安装精确版本,并从已发布的轻量入口验证最终请求体包含 JSON Schema、思考强度和 24,000 token 上限,SSE 正文/思考事件分离且未截断。
|
|
17
|
+
|
|
18
|
+
- `0.5.2` tarball:https://registry.npmjs.org/@henjicc/ai-sdk/-/ai-sdk-0.5.2.tgz
|
|
19
|
+
- `0.5.2` shasum:`f1c06ae12c9240b203f3ad310c4eec35b755db13`
|
|
20
|
+
- `0.5.2` integrity:`sha512-ljb50njJ0bXWxwNmlgZ1+YDBoBgPiLhoNEDjsbhPbe4pc7aVZGcfvpDLh+zGdx9KsB7g7Xp3mqVM4MLpVQm15g==`
|
|
21
|
+
|
|
22
|
+
`0.5.1` 将 Grsai GPT Image 2.5 未指定变体时的默认值从官方公告仍在维护的 Flare 改为 Standard,并同步默认价格;显式选择 Flare / Sunburst 的调用保持兼容。公共 DTO、请求协议、宿主边界和其余模型未变。发布前 77 个测试文件 / 899 项测试、可移植性、构建、49 个 Vite 公开入口和受限宿主门禁通过;公共索引可读后,已在隔离用户 npm 配置的仓外目录匿名安装并完成 ESM 导入。
|
|
23
|
+
|
|
24
|
+
- `0.5.1` tarball:https://registry.npmjs.org/@henjicc/ai-sdk/-/ai-sdk-0.5.1.tgz
|
|
25
|
+
- `0.5.1` shasum:`40087e680f1b7de63a601d12758acb7280de305f`
|
|
26
|
+
- `0.5.1` integrity:`sha512-+L/mAmFU6zgJ0gdsIwy0T1Z9TDOABaxO3HgLsEvMUNbRQhs9K55golF1472EgSJsIDysScnUulFJfBVg0xsNBg==`
|
|
27
|
+
|
|
28
|
+
`0.5.0` 发布运行时代码提交 `1333422e`,补充边界回归提交 `da37e4bc`;后者必需 CI `35535140722` 全部成功。12组修复撤销验证均检测到失败,恢复后定向测试通过。固定候选包经仓外回装后发布,公共 registry 匿名安装的 shasum/integrity 与候选包一致;Vite公开入口和无TextEncoder/TextDecoder的受限宿主消费通过。npm网页登录与发布二次验证已完成;发布后等待公共索引可读才执行匿名验证,没有重复发布。
|
|
13
29
|
|
|
14
30
|
- tarball:https://registry.npmjs.org/@henjicc/ai-sdk/-/ai-sdk-0.5.0.tgz
|
|
15
31
|
- shasum:`1b66a7c54f4f86a01b73fdca68b1c63e53dcbe10`
|
|
@@ -54,7 +54,7 @@ docs/llm-adaptation/
|
|
|
54
54
|
- 协议不是供应商级一刀切:例如智谱国内只有 `glm-5.3` 默认 Responses,`glm-5.3-flash` / `glm-5v-turbo` 保持 Chat;派欧云聚合网关也不会因为底层模型原厂支持 Responses 就被误切换。
|
|
55
55
|
- 预制供应商的协议控件不在界面显示;自定义未知端点才允许选择 Chat / Responses。Anthropic 没有运行时实现,也不在界面显示,存量伪配置继续归一化成 OpenAI Chat。
|
|
56
56
|
|
|
57
|
-
当前已自动走 Responses 的预制组合:DeepSeek V4 Pro / Flash / Vision、火山引擎目录内三款 Doubao、百炼 Qwen3.8-Max、MiniMax-M3、智谱中国大陆 GLM-5.3。Kimi、
|
|
57
|
+
当前已自动走 Responses 的预制组合:DeepSeek V4 Pro / Flash / Vision、火山引擎目录内三款 Doubao、百炼 Qwen3.8-Max、MiniMax-M3、智谱中国大陆 GLM-5.3。MiMo 2.6 Pro / Flash / Pro-UltraSpeed 也支持并默认走 Responses;Kimi、Groq、派欧云以及未确认的智谱模型继续走 Chat。
|
|
58
58
|
|
|
59
59
|
### 2.3 Responses 事件契约与验证证据
|
|
60
60
|
|
|
@@ -84,7 +84,7 @@ Responses 请求统一下发 `store: false`:助手自己的会话存储仍是
|
|
|
84
84
|
2. **Chat Completions 兜底**。Responses 未确认的供应商/模型继续用它,不阻塞可用性。
|
|
85
85
|
3. **Anthropic Messages API 暂不实现、不显示**。官方支持面只作为未来资料保留,不向用户暴露一个不能工作的选项。
|
|
86
86
|
|
|
87
|
-
每个供应商文件的「摘要」表里都有一行"接入优先级",按这三条给出该供应商的具体落点(例如 Kimi/百炼没有 Anthropic,MiMo
|
|
87
|
+
每个供应商文件的「摘要」表里都有一行"接入优先级",按这三条给出该供应商的具体落点(例如 Kimi/百炼没有 Anthropic,MiMo 已有 Responses API,落点就相应收窄)。
|
|
88
88
|
|
|
89
89
|
## 四、协议矩阵(官方支持面,供路线图参考)
|
|
90
90
|
|
|
@@ -93,15 +93,15 @@ Responses 请求统一下发 `store: false`:助手自己的会话存储仍是
|
|
|
93
93
|
| [火山引擎](供应商/火山引擎.md) | ✅ | ✅ | ❌ 官方未提供 | **仅 Responses API**(Chat API 完全不支持内置工具) |
|
|
94
94
|
| [Kimi](供应商/Kimi.md) | ✅ | ❌ 官方未提供 | ❌ 官方未提供 | Chat Completions(`$web_search`,官方标注"近期不建议用于生产") |
|
|
95
95
|
| [智谱 GLM](供应商/智谱GLM.md) | ✅(`glm-5.3-flash` 目前仅确认此协议) | ✅(仅 `glm-5.3`) | ✅(仅 `glm-5.3`) | Chat Completions 工具 / 独立 Web Search API 均可,GLM-Coding-Plan 订阅账号暂时只能走 Chat Completions |
|
|
96
|
-
| [DeepSeek](供应商/DeepSeek.md) | ✅ | ✅ | ✅ |
|
|
97
|
-
| [小米 MiMo](供应商/小米MiMo.md) | ✅ |
|
|
96
|
+
| [DeepSeek](供应商/DeepSeek.md) | ✅ | ✅ | ✅ | 当前仅 function 工具;内置 web_search 不可据旧资料声明可用 |
|
|
97
|
+
| [小米 MiMo](供应商/小米MiMo.md) | ✅ | ✅(2.6 系列已接入) | ✅ | **仅 Chat Completions**(官方原文:"其他 API 协议暂不支持"),且需先在控制台激活插件 |
|
|
98
98
|
| [百炼 Qwen](供应商/百炼Qwen.md) | ✅ | ✅ | ❌ 官方未提供 | 两条协议都支持,但 Responses 路径能力更全(额外有 `web_extractor`/`code_interpreter`) |
|
|
99
99
|
| [MiniMax](供应商/MiniMax.md) | ✅ | ✅ | ✅(**官方推荐首选**) | Anthropic Messages + Responses API 均支持,纯 Chat Completions 不支持 |
|
|
100
100
|
|
|
101
101
|
**两条对制定路线图有直接影响的结论**:
|
|
102
102
|
|
|
103
|
-
1. **7 家里有 6 家原生支持 Responses API 或与之等价的能力**(火山引擎、GLM-5.3、DeepSeek、百炼、MiniMax 直接支持 Responses API;Kimi
|
|
104
|
-
2. **联网搜索能不能用,很大程度上取决于选了哪个协议**,不是"这家供应商支不支持"
|
|
103
|
+
1. **7 家里有 6 家原生支持 Responses API 或与之等价的能力**(火山引擎、GLM-5.3、DeepSeek、百炼、MiniMax 直接支持 Responses API;MiMo 也直接支持;Kimi 没有 Responses API,只能走 Chat Completions)——这与第三节"Responses API 优先"的既定优先级吻合,先做 Responses API 适配器能覆盖到的供应商数量最多,也是联网搜索等内置工具最主要的解锁路径。
|
|
104
|
+
2. **联网搜索能不能用,很大程度上取决于选了哪个协议**,不是"这家供应商支不支持"这么简单:火山引擎的联网搜索**必须**走 Responses API,DeepSeek 当前文档只确认 function 工具,MiMo 的联网搜索**必须**走 Chat Completions,MiniMax 的联网搜索 Anthropic/Responses 都行但纯 Chat Completions 不行。做 Responses API 适配器时可以顺带核对一下能不能同时把对应供应商的联网搜索也接上,性价比更高。
|
|
105
105
|
3. **4 家(DeepSeek、GLM、MiMo、MiniMax)原生支持 Anthropic Messages API,MiniMax 官方甚至推荐它作为首选**——这是资料记录,供未来"顺手就能接"时参考,**不代表应该优先做**:按第三节的既定优先级,Anthropic 排在 Responses API 和 Chat Completions 之后,不单独立项。
|
|
106
106
|
|
|
107
107
|
## 五、供应商速查表
|
|
@@ -112,7 +112,7 @@ Responses 请求统一下发 `store: false`:助手自己的会话存储仍是
|
|
|
112
112
|
| Kimi | `https://api.moonshot.cn/v1` | `kimi-k3` | 1,048,576 | 20 / 100 |
|
|
113
113
|
| 智谱 GLM | 国内 `https://open.bigmodel.cn/api/paas/v4`;国际 `https://api.z.ai/api/paas/v4` | `glm-5.3` / `glm-5.3-flash`(原生多模态) | 1M | 国内 GLM-5.3:8 / 28;Flash:CNY 0.8 / 2.8、USD 0.15 / 0.50 |
|
|
114
114
|
| DeepSeek | `https://api.deepseek.com` | `deepseek-v4-pro` | 1M | 4.5 / 13.5(闲时) |
|
|
115
|
-
| 小米 MiMo | `https://api.xiaomimimo.com/v1` | `mimo-v2.
|
|
115
|
+
| 小米 MiMo | `https://api.xiaomimimo.com/v1` | `mimo-v2.6-pro` / `mimo-v2.6-flash` | 1M | Pro 3 / 6,Flash 1 / 2 |
|
|
116
116
|
| 百炼 Qwen | `https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/compatible-mode/v1` | `qwen3.8-max` | ~1M | 12 / 36 |
|
|
117
117
|
| MiniMax | `https://api.minimaxi.com/v1` | `MiniMax-M3` | 1,000,000 | 2.10 / 8.40(≤512K,促销价) |
|
|
118
118
|
|
|
@@ -126,7 +126,7 @@ Responses 请求统一下发 `store: false`:助手自己的会话存储仍是
|
|
|
126
126
|
| Kimi | `reasoning_effort` | `low`/`high`/`max` | `max` | **不可以**,K3 始终思考 |
|
|
127
127
|
| 智谱 GLM | `reasoning_effort` + `thinking` | `low`/`high`/`max`(`glm-5.3`、`glm-5.3-flash`) | `max` | GLM-5.3 / Flash 不可以;GLM-5V-Turbo 可以 |
|
|
128
128
|
| DeepSeek | `reasoning_effort` + `thinking.type` | 字符串透传,无固定枚举 | — | 可以 |
|
|
129
|
-
| 小米 MiMo |
|
|
129
|
+
| 小米 MiMo | Chat `thinking.type`;Responses `reasoning.effort` | 开 / 关,无强度分级 | 开启 | 可以;Chat disabled / Responses none |
|
|
130
130
|
| 百炼 Qwen | `enable_thinking`(布尔) | `true`/`false` | 视模型而定 | 可以 |
|
|
131
131
|
| MiniMax | 仅 Anthropic 协议下确认为原生 `thinking` 内容块;Chat/Responses 路径的思考强度字段未在公开文档中找到,接入 Responses API 时需要单独实测确认 | — | — | 视协议而定 |
|
|
132
132
|
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# DeepSeek
|
|
2
2
|
|
|
3
|
-
> 核对时间:2026-09-
|
|
3
|
+
> 核对时间:2026-09-24。以中文官方文档为准,英文页面尚有更新滞后。
|
|
4
4
|
|
|
5
|
-
## 2026-09-11
|
|
5
|
+
## 2026-09-24 复核(含 2026-09-11 更新)(覆盖下方历史资料中的旧模型和能力说明)
|
|
6
6
|
|
|
7
7
|
- 官方默认与预设唯一推荐模型改为 `deepseek-flash`(DeepSeek V4.1 Flash),原生文本、图片输入,1M 上下文、384K 最大输出。Chat Completions 和 Responses 均支持图片;项目继续默认 Responses。
|
|
8
|
-
- 旧 `deepseek-v4-flash`、`deepseek-v4-flash-vision-exp`
|
|
8
|
+
- 旧 `deepseek-v4-flash`、`deepseek-v4-flash-vision-exp` 已由官方转发到新版。2026-09-24 官方价格页重新列出独立的 `deepseek-v4-pro`(V4-Pro-0813,无视觉),不再据旧公告声称其必然转发到 Flash。项目不再推荐这些旧名字,也不把聚合供应商的旧 ID 当作新版别名。
|
|
9
|
+
- Pro-0813 最新人民币/百万 token 闲时 / 高峰:缓存命中 0.15 / 0.30、输入 4.5 / 9、输出 13.5 / 27;高峰不含中国法定节假日。目录保留独立 Pro ID 与无视觉能力,默认推荐仍为 Flash。
|
|
9
10
|
- 新版价格(人民币/百万 token,闲时 / 工作日高峰):缓存命中输入 0.02 / 0.04,未命中输入 1 / 2,输出 4 / 8。高峰为北京时间工作日 09:00–12:00、14:00–18:00。
|
|
10
11
|
- 思考默认开启,默认 high;正式档位 low/high/max,兼容 minimal→low、medium/xhigh→high、ultra→max。Responses 用 reasoning.effort,none 关闭。思考时 temperature 无效,top_p 生效但下限 0.95;非思考 top_p 固定 1。
|
|
11
12
|
- Responses 为无状态 API,必须回传完整历史;text.format 支持 json_schema。当前仅支持 function 工具,内置工具会被忽略,不能再据旧资料宣称 web_search 可用。SDK 本次只更新目录与默认选型,不新增内置工具或协议分支。
|
|
@@ -23,7 +23,7 @@ Kimi 官方文档全文没有出现过 `responses.create`;`platform.kimi.com/d
|
|
|
23
23
|
|---|---|---|---|---|
|
|
24
24
|
| `kimi-k3` | 当前旗舰,2.8 万亿参数,KDA 混合线性注意力,全球首个开源 3 万亿级模型 | 文本、图片、视频 → 文本 | 1,048,576 tokens(1M) | 默认 131,072,最大可设 1,048,576 |
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
价格(2026-09-24 核对,元/百万 tokens):缓存命中 2、缓存未命中 20、输出 100;另计缓存写入,TTL 5 分钟为 20、TTL 1 小时为 40,默认 5 分钟。命中仅按缓存命中单价计费,不重复收取缓存写入费用,命中后有效期续期。当前 SDK 未提供 Kimi 账单计算器,不从总输入 tokens 猜测缓存写入量。
|
|
27
27
|
|
|
28
28
|
K3 是付费解锁模型:**充值后才能调用**,新用户认证赠送的 15 元代金券不能用于 K3。
|
|
29
29
|
|
|
@@ -69,7 +69,8 @@ K3 是付费解锁模型:**充值后才能调用**,新用户认证赠送的
|
|
|
69
69
|
- [推理强度](https://platform.kimi.com/docs/guide/use-reasoning-effort)
|
|
70
70
|
- [使用 Kimi API 的联网搜索功能](https://platform.kimi.com/docs/guide/use-web-search)
|
|
71
71
|
- [如何在 Kimi API 中使用官方工具](https://platform.kimi.com/docs/guide/use-official-tools)
|
|
72
|
-
- [Kimi K3 定价](https://platform.kimi.com/docs/pricing/chat-k3)
|
|
72
|
+
- [Kimi K3 定价](https://platform.kimi.com/docs/pricing/chat-k3)
|
|
73
|
+
- [当前推理与缓存写入定价(2026-09-24)](https://platform.kimi.com/docs/pricing/chat.md)
|
|
73
74
|
- [联网搜索定价](https://platform.kimi.com/docs/pricing/tools)
|
|
74
75
|
- [使用思考模式](https://platform.kimi.com/docs/guide/use-thinking-models)
|
|
75
76
|
- [Kimi 文档全量索引](https://platform.kimi.com/docs/llms.txt)
|