@downcity/city 0.2.75 → 0.2.76
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/bin/index.d.ts +3 -3
- package/bin/index.d.ts.map +1 -1
- package/bin/index.js +1 -1
- package/bin/index.js.map +1 -1
- package/bin/service/ai/ai-service.d.ts.map +1 -1
- package/bin/service/ai/ai-service.js +2 -70
- package/bin/service/ai/ai-service.js.map +1 -1
- package/bin/service/ai/helpers.d.ts +121 -0
- package/bin/service/ai/helpers.d.ts.map +1 -0
- package/bin/service/ai/helpers.js +368 -0
- package/bin/service/ai/helpers.js.map +1 -0
- package/bin/service/ai/provider.d.ts +100 -26
- package/bin/service/ai/provider.d.ts.map +1 -1
- package/bin/service/ai/provider.js +166 -24
- package/bin/service/ai/provider.js.map +1 -1
- package/bin/service/ai/types.d.ts +35 -1
- package/bin/service/ai/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/bin/service/ai/openai-compatible-provider.d.ts +0 -54
- package/bin/service/ai/openai-compatible-provider.d.ts.map +0 -1
- package/bin/service/ai/openai-compatible-provider.js +0 -175
- package/bin/service/ai/openai-compatible-provider.js.map +0 -1
|
@@ -1,40 +1,182 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* AI Provider 模块。
|
|
3
3
|
*
|
|
4
|
-
* Provider
|
|
5
|
-
*
|
|
4
|
+
* Provider 是第三方 AI 提供商的基类。
|
|
5
|
+
* - 默认提供 OpenAI-compatible 的 text / stream 实现。
|
|
6
|
+
* - 子类通过覆盖 createClient 来绑定不同的 AI SDK provider。
|
|
7
|
+
* - 需要其它模态(image / video / tts / asr)或自定义 openai 透传时,覆盖对应方法。
|
|
8
|
+
*/
|
|
9
|
+
import { convertToModelMessages, generateText, streamText } from "ai";
|
|
10
|
+
import { buildAssistantMessage, buildToolSet, readRequiredEnv, resolveUpstreamModel, } from "./helpers.js";
|
|
11
|
+
// ===========================================================================
|
|
12
|
+
// Provider 基类
|
|
13
|
+
// ===========================================================================
|
|
14
|
+
/**
|
|
15
|
+
* AI Provider 基类。
|
|
6
16
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* - OpenAI 兼容通路:openai — 给 /chat/completions 端点用
|
|
10
|
-
* - 未提供 openai action → AIService 自动透传(需 baseURL + envKey)
|
|
11
|
-
* - 提供了 openai action → 按自定义逻辑处理
|
|
17
|
+
* 子类通过覆盖方法声明 action,model() 会自动收集并生成 ModelConfig。
|
|
18
|
+
* 默认 text / stream 使用 OpenAI-compatible 协议,覆盖 createClient 即可接入不同上游。
|
|
12
19
|
*/
|
|
13
20
|
export class Provider {
|
|
21
|
+
/** Provider 唯一 ID。 */
|
|
14
22
|
id;
|
|
23
|
+
/** 模型所需环境变量说明。 */
|
|
15
24
|
env;
|
|
25
|
+
/** Provider 的 baseURL(用于自动透传)。 */
|
|
16
26
|
baseURL;
|
|
27
|
+
/** Provider 的环境变量 key。 */
|
|
17
28
|
envKey;
|
|
29
|
+
/** 上游 API 实际模型 ID(自动透传时替换 body.model)。 */
|
|
18
30
|
passthroughModel;
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.
|
|
22
|
-
this.
|
|
23
|
-
this.
|
|
24
|
-
this.
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
constructor(options) {
|
|
32
|
+
this.id = options.id;
|
|
33
|
+
this.env = options.env ?? (options.envKey ? { [options.envKey]: `${options.id} API Key` } : undefined);
|
|
34
|
+
this.baseURL = options.baseURL;
|
|
35
|
+
this.envKey = options.envKey;
|
|
36
|
+
this.passthroughModel = options.passthroughModel;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* 创建 OpenAI-compatible chat client。
|
|
40
|
+
*
|
|
41
|
+
* 子类需要支持 text / stream 时必须覆盖。
|
|
42
|
+
* 默认抛出错误。
|
|
43
|
+
*/
|
|
44
|
+
createClient(config) {
|
|
45
|
+
throw new Error(`Provider ${this.id} does not support text/stream`);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* 从输入中提取 prompt 文本。
|
|
49
|
+
*
|
|
50
|
+
* 子类可覆盖以支持多模态 messages 转文本。
|
|
51
|
+
*/
|
|
52
|
+
extractPrompt(input) {
|
|
53
|
+
if (typeof input.prompt === "string")
|
|
54
|
+
return input.prompt;
|
|
55
|
+
return input.messages
|
|
56
|
+
?.find((message) => message.role === "user")
|
|
57
|
+
?.parts?.find((part) => part.type === "text")
|
|
58
|
+
?.text ?? "";
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 从 usage 生成计费行。
|
|
62
|
+
*
|
|
63
|
+
* 默认不返回计费,由 billingService pricing rules 兜底。
|
|
64
|
+
*/
|
|
65
|
+
buildBilling(ctx, usage) {
|
|
66
|
+
return undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* 创建当前请求的 chat model。
|
|
70
|
+
*/
|
|
71
|
+
createChatModel(ctx) {
|
|
72
|
+
if (!this.envKey) {
|
|
73
|
+
throw new Error(`Provider ${this.id} is missing envKey`);
|
|
74
|
+
}
|
|
75
|
+
const api_key = readRequiredEnv(ctx, this.envKey);
|
|
76
|
+
const base_url = this.baseURL ?? "https://api.openai.com/v1";
|
|
77
|
+
const upstream_model = resolveUpstreamModel(ctx, this.passthroughModel ?? "");
|
|
78
|
+
return this.createClient({ apiKey: api_key, baseURL: base_url, name: this.id }).chat(upstream_model);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* 将输入解析成 prompt 或 tools+messages。
|
|
82
|
+
*/
|
|
83
|
+
async resolveActionInput(input) {
|
|
84
|
+
const tools = buildToolSet(input.tools);
|
|
85
|
+
if (!tools) {
|
|
86
|
+
return { prompt: this.extractPrompt(input) };
|
|
87
|
+
}
|
|
88
|
+
return {
|
|
89
|
+
tools,
|
|
90
|
+
messages: await convertToModelMessages(input.messages ?? [], { tools }),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* 文本生成 action(OpenAI-compatible 默认实现)。
|
|
95
|
+
*/
|
|
96
|
+
async text(ctx) {
|
|
97
|
+
const input = ctx.input;
|
|
98
|
+
const resolved_input = await this.resolveActionInput(input);
|
|
99
|
+
const model = this.createChatModel(ctx);
|
|
100
|
+
if ("tools" in resolved_input) {
|
|
101
|
+
const result = await generateText({
|
|
102
|
+
model,
|
|
103
|
+
messages: resolved_input.messages,
|
|
104
|
+
tools: resolved_input.tools,
|
|
105
|
+
});
|
|
106
|
+
return buildAssistantMessage(result.text, ctx, {
|
|
107
|
+
finishReason: result.finishReason,
|
|
108
|
+
usage: result.usage,
|
|
109
|
+
toolCalls: result.toolCalls,
|
|
110
|
+
}, this.buildBilling(ctx, result.usage));
|
|
111
|
+
}
|
|
112
|
+
const result = await generateText({
|
|
113
|
+
model,
|
|
114
|
+
prompt: resolved_input.prompt,
|
|
115
|
+
temperature: 1,
|
|
116
|
+
});
|
|
117
|
+
return buildAssistantMessage(result.text, ctx, {
|
|
118
|
+
finishReason: result.finishReason,
|
|
119
|
+
usage: result.usage,
|
|
120
|
+
}, this.buildBilling(ctx, result.usage));
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* 流式生成 action(OpenAI-compatible 默认实现)。
|
|
124
|
+
*/
|
|
125
|
+
async stream(ctx) {
|
|
126
|
+
const input = ctx.input;
|
|
127
|
+
const resolved_input = await this.resolveActionInput(input);
|
|
128
|
+
const model = this.createChatModel(ctx);
|
|
129
|
+
if ("tools" in resolved_input) {
|
|
130
|
+
const result = streamText({
|
|
131
|
+
model,
|
|
132
|
+
messages: resolved_input.messages,
|
|
133
|
+
tools: resolved_input.tools,
|
|
134
|
+
});
|
|
135
|
+
return {
|
|
136
|
+
response: result.toUIMessageStreamResponse(),
|
|
137
|
+
billing: Promise.resolve(result.totalUsage.then((usage) => this.buildBilling(ctx, usage))),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
const result = streamText({
|
|
141
|
+
model,
|
|
142
|
+
prompt: resolved_input.prompt,
|
|
143
|
+
temperature: 1,
|
|
144
|
+
});
|
|
145
|
+
return {
|
|
146
|
+
response: result.toUIMessageStreamResponse(),
|
|
147
|
+
billing: Promise.resolve(result.totalUsage.then((usage) => this.buildBilling(ctx, usage))),
|
|
35
148
|
};
|
|
36
149
|
}
|
|
150
|
+
/**
|
|
151
|
+
* 生成模型配置。
|
|
152
|
+
*
|
|
153
|
+
* 自动收集当前 Provider 实例上定义的 action 方法。
|
|
154
|
+
*/
|
|
37
155
|
model(spec) {
|
|
156
|
+
const actions = {};
|
|
157
|
+
const all_modalities = [
|
|
158
|
+
"text",
|
|
159
|
+
"stream",
|
|
160
|
+
"image",
|
|
161
|
+
"image_job",
|
|
162
|
+
"video",
|
|
163
|
+
"tts",
|
|
164
|
+
"asr",
|
|
165
|
+
"openai",
|
|
166
|
+
];
|
|
167
|
+
for (const modality of all_modalities) {
|
|
168
|
+
const fn = this[modality];
|
|
169
|
+
if (typeof fn !== "function")
|
|
170
|
+
continue;
|
|
171
|
+
// text / stream 默认由基类实现,只有子类显式覆盖或提供了 createClient 才暴露
|
|
172
|
+
if (modality === "text" || modality === "stream") {
|
|
173
|
+
const is_overridden = fn !== Provider.prototype[modality];
|
|
174
|
+
const has_create_client = this.createClient !== Provider.prototype.createClient;
|
|
175
|
+
if (!is_overridden && !has_create_client)
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
actions[modality] = fn.bind(this);
|
|
179
|
+
}
|
|
38
180
|
return {
|
|
39
181
|
id: spec.id,
|
|
40
182
|
provider_id: this.id,
|
|
@@ -47,7 +189,7 @@ export class Provider {
|
|
|
47
189
|
baseURL: this.baseURL,
|
|
48
190
|
envKey: this.envKey,
|
|
49
191
|
passthroughModel: this.passthroughModel,
|
|
50
|
-
actions
|
|
192
|
+
actions,
|
|
51
193
|
};
|
|
52
194
|
}
|
|
53
195
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/service/ai/provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../src/service/ai/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -5,6 +5,40 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import type { ActionFn } from "../action.js";
|
|
7
7
|
import type { AIBillingBridge } from "./billing.js";
|
|
8
|
+
import type { LanguageModel } from "ai";
|
|
9
|
+
/**
|
|
10
|
+
* Provider 构造选项。
|
|
11
|
+
*/
|
|
12
|
+
export interface ProviderOptions {
|
|
13
|
+
/** Provider 唯一 ID。 */
|
|
14
|
+
id: string;
|
|
15
|
+
/** 模型所需环境变量说明。 */
|
|
16
|
+
env?: Record<string, string>;
|
|
17
|
+
/** Provider 的 baseURL(用于自动透传)。 */
|
|
18
|
+
baseURL?: string;
|
|
19
|
+
/** Provider 的环境变量 key。 */
|
|
20
|
+
envKey?: string;
|
|
21
|
+
/** 上游 API 实际模型 ID(自动透传时替换 body.model)。 */
|
|
22
|
+
passthroughModel?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* OpenAI-compatible client 工厂入参。
|
|
26
|
+
*/
|
|
27
|
+
export interface OpenAICompatibleClientConfig {
|
|
28
|
+
/** 上游 API Key。 */
|
|
29
|
+
apiKey: string;
|
|
30
|
+
/** 上游 OpenAI-compatible baseURL。 */
|
|
31
|
+
baseURL: string;
|
|
32
|
+
/** Provider 展示名称,通常用于底层 SDK 调试和埋点。 */
|
|
33
|
+
name: string;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* OpenAI-compatible chat client 最小能力约束。
|
|
37
|
+
*/
|
|
38
|
+
export interface OpenAICompatibleClient {
|
|
39
|
+
/** 根据模型 ID 创建可传给 AI SDK 的 chat model。 */
|
|
40
|
+
chat(modelId: string): LanguageModel;
|
|
41
|
+
}
|
|
8
42
|
/**
|
|
9
43
|
* 模型 action 映射,key 为通路名称。
|
|
10
44
|
*
|
|
@@ -13,7 +47,7 @@ import type { AIBillingBridge } from "./billing.js";
|
|
|
13
47
|
* - OpenAI 兼容通路:openai — 给 /chat/completions 端点用
|
|
14
48
|
*
|
|
15
49
|
* 每个 action 接收 Context,返回对应通路的结果。
|
|
16
|
-
* Provider
|
|
50
|
+
* Provider 通过方法声明提供 action,通过 model() 方法绑定到模型配置。
|
|
17
51
|
*/
|
|
18
52
|
export interface ModelActions {
|
|
19
53
|
/** 文本生成 action */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/service/ai/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/service/ai/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAI-compatible Provider 构造工具。
|
|
3
|
-
*
|
|
4
|
-
* 负责把 OpenAI 兼容上游包装成 Downcity 的 SDK 通路:
|
|
5
|
-
* - text → 返回 AI SDK `UIMessage`
|
|
6
|
-
* - stream → 返回 AI SDK `UIMessageStreamResponse`
|
|
7
|
-
*
|
|
8
|
-
* 关键说明(中文)
|
|
9
|
-
* - `/chat/completions` 仍由 AIService 的自动透传处理
|
|
10
|
-
* - 这里专门补齐 User City .ai.text() / stream() 所需的 server 侧 action
|
|
11
|
-
* - 不在请求热路径里做动态导入,减少首请求和冷启动额外开销
|
|
12
|
-
*/
|
|
13
|
-
import type { LanguageModel } from "ai";
|
|
14
|
-
import { Provider } from "./provider.js";
|
|
15
|
-
/**
|
|
16
|
-
* OpenAI-compatible Provider 配置。
|
|
17
|
-
*/
|
|
18
|
-
export interface OpenAICompatibleProviderOptions {
|
|
19
|
-
/** Provider 唯一 ID,用于模型注册和日志标识。 */
|
|
20
|
-
id: string;
|
|
21
|
-
/** 运行时 API Key 对应的环境变量 key。 */
|
|
22
|
-
envKey: string;
|
|
23
|
-
/** OpenAI-compatible 上游 baseURL。 */
|
|
24
|
-
baseURL: string;
|
|
25
|
-
/** 该 Provider 默认绑定的上游模型 ID。 */
|
|
26
|
-
defaultModelId: string;
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* OpenAI-compatible client 工厂入参。
|
|
30
|
-
*/
|
|
31
|
-
export interface OpenAICompatibleClientConfig {
|
|
32
|
-
/** 上游 API Key。 */
|
|
33
|
-
apiKey: string;
|
|
34
|
-
/** 上游 OpenAI-compatible baseURL。 */
|
|
35
|
-
baseURL: string;
|
|
36
|
-
/** Provider 展示名称,通常用于底层 SDK 调试和埋点。 */
|
|
37
|
-
name: string;
|
|
38
|
-
}
|
|
39
|
-
/**
|
|
40
|
-
* OpenAI-compatible chat client 最小能力约束。
|
|
41
|
-
*/
|
|
42
|
-
export interface OpenAICompatibleClient {
|
|
43
|
-
/** 根据模型 ID 创建可传给 AI SDK 的 chat model。 */
|
|
44
|
-
chat(modelId: string): LanguageModel;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* OpenAI-compatible client 工厂签名。
|
|
48
|
-
*/
|
|
49
|
-
export type OpenAICompatibleClientFactory = (config: OpenAICompatibleClientConfig) => OpenAICompatibleClient;
|
|
50
|
-
/**
|
|
51
|
-
* 创建 OpenAI-compatible Provider。
|
|
52
|
-
*/
|
|
53
|
-
export declare function createOpenAICompatibleProvider(options: OpenAICompatibleProviderOptions, createClient: OpenAICompatibleClientFactory): Provider;
|
|
54
|
-
//# sourceMappingURL=openai-compatible-provider.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compatible-provider.d.ts","sourceRoot":"","sources":["../../../src/service/ai/openai-compatible-provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAqB,aAAa,EAAsB,MAAM,IAAI,CAAC;AAE/E,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC;;GAEG;AACH,MAAM,WAAW,+BAA+B;IAC9C,kCAAkC;IAClC,EAAE,EAAE,MAAM,CAAC;IACX,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,+BAA+B;IAC/B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,yCAAyC;IACzC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,CAAC;CACtC;AAED;;GAEG;AACH,MAAM,MAAM,6BAA6B,GAAG,CAC1C,MAAM,EAAE,4BAA4B,KACjC,sBAAsB,CAAC;AAoC5B;;GAEG;AACH,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,EACxC,YAAY,EAAE,6BAA6B,GAC1C,QAAQ,CASV"}
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OpenAI-compatible Provider 构造工具。
|
|
3
|
-
*
|
|
4
|
-
* 负责把 OpenAI 兼容上游包装成 Downcity 的 SDK 通路:
|
|
5
|
-
* - text → 返回 AI SDK `UIMessage`
|
|
6
|
-
* - stream → 返回 AI SDK `UIMessageStreamResponse`
|
|
7
|
-
*
|
|
8
|
-
* 关键说明(中文)
|
|
9
|
-
* - `/chat/completions` 仍由 AIService 的自动透传处理
|
|
10
|
-
* - 这里专门补齐 User City .ai.text() / stream() 所需的 server 侧 action
|
|
11
|
-
* - 不在请求热路径里做动态导入,减少首请求和冷启动额外开销
|
|
12
|
-
*/
|
|
13
|
-
import { convertToModelMessages, generateText, jsonSchema, streamText, tool } from "ai";
|
|
14
|
-
import { Provider } from "./provider.js";
|
|
15
|
-
/**
|
|
16
|
-
* 创建 OpenAI-compatible Provider。
|
|
17
|
-
*/
|
|
18
|
-
export function createOpenAICompatibleProvider(options, createClient) {
|
|
19
|
-
return new Provider(options.id, {
|
|
20
|
-
env: { [options.envKey]: `${options.id} API Key` },
|
|
21
|
-
baseURL: options.baseURL,
|
|
22
|
-
envKey: options.envKey,
|
|
23
|
-
passthroughModel: options.defaultModelId,
|
|
24
|
-
text: createTextAction(options, createClient),
|
|
25
|
-
stream: createStreamAction(options, createClient),
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
/**
|
|
29
|
-
* 读取必填 API Key。
|
|
30
|
-
*/
|
|
31
|
-
function readApiKey(ctx, key) {
|
|
32
|
-
const value = ctx.env(key);
|
|
33
|
-
if (!value)
|
|
34
|
-
throw new Error(`${key} is required`);
|
|
35
|
-
return value;
|
|
36
|
-
}
|
|
37
|
-
/**
|
|
38
|
-
* 从 input 中提取 prompt 文本。
|
|
39
|
-
*/
|
|
40
|
-
function extractPrompt(input) {
|
|
41
|
-
if (typeof input.prompt === "string")
|
|
42
|
-
return input.prompt;
|
|
43
|
-
const messages = input.messages;
|
|
44
|
-
return messages
|
|
45
|
-
?.find((message) => message.role === "user")
|
|
46
|
-
?.parts?.find((part) => part.type === "text")
|
|
47
|
-
?.text ?? "";
|
|
48
|
-
}
|
|
49
|
-
/**
|
|
50
|
-
* OpenAI function tools → ai-sdk ToolSet。
|
|
51
|
-
*/
|
|
52
|
-
function buildToolSet(items) {
|
|
53
|
-
if (!items?.length)
|
|
54
|
-
return undefined;
|
|
55
|
-
return Object.fromEntries(items
|
|
56
|
-
.filter((item) => item.type === "function" && typeof item.function?.name === "string")
|
|
57
|
-
.map((item) => [
|
|
58
|
-
item.function.name,
|
|
59
|
-
tool({
|
|
60
|
-
description: item.function.description ?? "",
|
|
61
|
-
inputSchema: jsonSchema(item.function.parameters ?? {}),
|
|
62
|
-
}),
|
|
63
|
-
]));
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* 将输入解析成 prompt 或 tools+messages,供 text / stream 共用。
|
|
67
|
-
*/
|
|
68
|
-
async function resolveActionInput(input) {
|
|
69
|
-
const tools = buildToolSet(input.tools);
|
|
70
|
-
if (!tools) {
|
|
71
|
-
return { prompt: extractPrompt(input) };
|
|
72
|
-
}
|
|
73
|
-
return {
|
|
74
|
-
tools,
|
|
75
|
-
messages: await convertToModelMessages(input.messages ?? [], { tools }),
|
|
76
|
-
};
|
|
77
|
-
}
|
|
78
|
-
/**
|
|
79
|
-
* 创建当前请求的 chat model。
|
|
80
|
-
*
|
|
81
|
-
* 关键说明(中文)
|
|
82
|
-
* - client 工厂本身在模块加载时就已静态绑定
|
|
83
|
-
* - 这里只按当前 env 读取 API Key,避免 key 轮换后继续复用旧值
|
|
84
|
-
*/
|
|
85
|
-
function createChatModel(ctx, options, createClient) {
|
|
86
|
-
return createClient({
|
|
87
|
-
apiKey: readApiKey(ctx, options.envKey),
|
|
88
|
-
baseURL: options.baseURL,
|
|
89
|
-
name: options.id,
|
|
90
|
-
}).chat(options.defaultModelId);
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* generateText 结果 → UIMessage。
|
|
94
|
-
*/
|
|
95
|
-
function buildMessage(text, ctx, result) {
|
|
96
|
-
const parts = [{ type: "text", text }];
|
|
97
|
-
if (result.toolCalls) {
|
|
98
|
-
for (const toolCall of result.toolCalls) {
|
|
99
|
-
const part = {
|
|
100
|
-
type: "dynamic-tool",
|
|
101
|
-
toolCallId: toolCall.toolCallId,
|
|
102
|
-
toolName: toolCall.toolName,
|
|
103
|
-
state: "input-available",
|
|
104
|
-
input: toolCall.input,
|
|
105
|
-
};
|
|
106
|
-
parts.push(part);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return {
|
|
110
|
-
id: `msg_${crypto.randomUUID()}`,
|
|
111
|
-
role: "assistant",
|
|
112
|
-
parts,
|
|
113
|
-
metadata: {
|
|
114
|
-
model: ctx.variant?.id,
|
|
115
|
-
town_id: ctx.town?.town_id,
|
|
116
|
-
user_id: ctx.user?.user_id,
|
|
117
|
-
finishReason: result.finishReason,
|
|
118
|
-
usage: result.usage,
|
|
119
|
-
},
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* 构造 text action。
|
|
124
|
-
*/
|
|
125
|
-
function createTextAction(options, createClient) {
|
|
126
|
-
return async (ctx) => {
|
|
127
|
-
const input = ctx.input;
|
|
128
|
-
const resolvedInput = await resolveActionInput(input);
|
|
129
|
-
const model = createChatModel(ctx, options, createClient);
|
|
130
|
-
if ("tools" in resolvedInput) {
|
|
131
|
-
const result = await generateText({
|
|
132
|
-
model,
|
|
133
|
-
messages: resolvedInput.messages,
|
|
134
|
-
tools: resolvedInput.tools,
|
|
135
|
-
});
|
|
136
|
-
return buildMessage(result.text, ctx, {
|
|
137
|
-
finishReason: result.finishReason,
|
|
138
|
-
usage: result.usage,
|
|
139
|
-
toolCalls: result.toolCalls,
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
const result = await generateText({
|
|
143
|
-
model,
|
|
144
|
-
prompt: resolvedInput.prompt,
|
|
145
|
-
temperature: 1,
|
|
146
|
-
});
|
|
147
|
-
return buildMessage(result.text, ctx, {
|
|
148
|
-
finishReason: result.finishReason,
|
|
149
|
-
usage: result.usage,
|
|
150
|
-
});
|
|
151
|
-
};
|
|
152
|
-
}
|
|
153
|
-
/**
|
|
154
|
-
* 构造 stream action。
|
|
155
|
-
*/
|
|
156
|
-
function createStreamAction(options, createClient) {
|
|
157
|
-
return async (ctx) => {
|
|
158
|
-
const input = ctx.input;
|
|
159
|
-
const resolvedInput = await resolveActionInput(input);
|
|
160
|
-
const model = createChatModel(ctx, options, createClient);
|
|
161
|
-
if ("tools" in resolvedInput) {
|
|
162
|
-
return streamText({
|
|
163
|
-
model,
|
|
164
|
-
messages: resolvedInput.messages,
|
|
165
|
-
tools: resolvedInput.tools,
|
|
166
|
-
}).toUIMessageStreamResponse();
|
|
167
|
-
}
|
|
168
|
-
return streamText({
|
|
169
|
-
model,
|
|
170
|
-
prompt: resolvedInput.prompt,
|
|
171
|
-
temperature: 1,
|
|
172
|
-
}).toUIMessageStreamResponse();
|
|
173
|
-
};
|
|
174
|
-
}
|
|
175
|
-
//# sourceMappingURL=openai-compatible-provider.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compatible-provider.js","sourceRoot":"","sources":["../../../src/service/ai/openai-compatible-provider.ts"],"names":[],"mappings":"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"}
|