@springbrand/agent-runtime 0.1.1 → 0.1.2
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/package.json
CHANGED
package/src/kernel/bindings.ts
CHANGED
|
@@ -26,6 +26,9 @@ import {
|
|
|
26
26
|
import {
|
|
27
27
|
openaiProvider,
|
|
28
28
|
} from "@earendil-works/pi-ai/providers/openai";
|
|
29
|
+
import {
|
|
30
|
+
openrouterProvider,
|
|
31
|
+
} from "@earendil-works/pi-ai/providers/openrouter";
|
|
29
32
|
import {
|
|
30
33
|
googleProvider,
|
|
31
34
|
} from "@earendil-works/pi-ai/providers/google";
|
|
@@ -40,6 +43,7 @@ import type {
|
|
|
40
43
|
|
|
41
44
|
const CATALOGS = {
|
|
42
45
|
"openai-chat": openaiProvider().getModels(),
|
|
46
|
+
"openrouter-chat": openrouterProvider().getModels(),
|
|
43
47
|
"anthropic-messages": anthropicProvider().getModels(),
|
|
44
48
|
"google-generative-ai": googleProvider().getModels(),
|
|
45
49
|
"openai-codex-responses": openaiCodexProvider().getModels(),
|
|
@@ -126,6 +130,7 @@ function providerId(endpoint: RuntimeModelEndpoint, index: number): string {
|
|
|
126
130
|
function apiFor(protocol: RuntimeModelProtocol): Api {
|
|
127
131
|
switch (protocol) {
|
|
128
132
|
case "openai-chat":
|
|
133
|
+
case "openrouter-chat":
|
|
129
134
|
return "openai-completions";
|
|
130
135
|
case "anthropic-messages":
|
|
131
136
|
return "anthropic-messages";
|
|
@@ -139,6 +144,7 @@ function apiFor(protocol: RuntimeModelProtocol): Api {
|
|
|
139
144
|
function piApiFor(protocol: RuntimeModelProtocol) {
|
|
140
145
|
switch (protocol) {
|
|
141
146
|
case "openai-chat":
|
|
147
|
+
case "openrouter-chat":
|
|
142
148
|
return openAICompletionsApi();
|
|
143
149
|
case "anthropic-messages":
|
|
144
150
|
return anthropicMessagesApi();
|
|
@@ -165,12 +171,11 @@ function configuredModel(
|
|
|
165
171
|
`Model is not in Pi's built-in catalog for ${endpoint.protocol}: ${modelId}`,
|
|
166
172
|
);
|
|
167
173
|
}
|
|
168
|
-
// 待确认:当前统一丢弃 catalogModel.compat;现有提交历史没有说明这样做对 Anthropic 兼容参数的影响,修改前需先验证 Pi 的流式请求行为。
|
|
169
174
|
const {
|
|
170
175
|
api: _api,
|
|
171
176
|
provider: _provider,
|
|
172
177
|
baseUrl: _baseUrl,
|
|
173
|
-
compat
|
|
178
|
+
compat,
|
|
174
179
|
headers: catalogHeaders,
|
|
175
180
|
...metadata
|
|
176
181
|
} = catalogModel;
|
|
@@ -183,6 +188,9 @@ function configuredModel(
|
|
|
183
188
|
api: apiFor(endpoint.protocol),
|
|
184
189
|
provider: providerId(endpoint, index),
|
|
185
190
|
baseUrl: endpoint.baseURL,
|
|
191
|
+
...(endpoint.protocol === "openrouter-chat" && compat
|
|
192
|
+
? { compat }
|
|
193
|
+
: {}),
|
|
186
194
|
...(Object.keys(headers).length > 0 ? { headers } : {}),
|
|
187
195
|
};
|
|
188
196
|
}
|
|
@@ -228,10 +236,10 @@ export function resolvePiApiKey(
|
|
|
228
236
|
* 用当前部署端点完整重建一个已有的 Pi 模型集合。
|
|
229
237
|
*
|
|
230
238
|
* PiRuntimeAdapter 激活新运行快照时调用它;需要复用 MutableModels 的调用方也可以调用,并继续使用返回的同一实例。
|
|
231
|
-
*
|
|
239
|
+
* 该函数在全部新 provider 校验通过后才清空并替换集合,所以失败时旧集合保持可用。
|
|
232
240
|
*
|
|
233
241
|
* Pi 当前用 provider.id 在 Map 中注册和路由请求,因此每个部署端点都必须同时注册唯一 provider、对应模型、认证解析器和协议实现。
|
|
234
|
-
*
|
|
242
|
+
* 替换时先构建新 provider,确保任一未知 modelId 都不会让旧端点失效;校验通过后再清空旧集合,避免配置更新后旧端点继续可用。
|
|
235
243
|
*
|
|
236
244
|
* @returns 传入并已重建完成的 `models` 实例。
|
|
237
245
|
* @throws 当任一部署模型不在 Pi 内置 OpenAI、Anthropic catalog 中时抛出错误。
|
|
@@ -240,9 +248,8 @@ export function configurePiModels(
|
|
|
240
248
|
models: MutableModels,
|
|
241
249
|
provider: RuntimeProviderPort,
|
|
242
250
|
): MutableModels {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
models.setProvider(createProvider({
|
|
251
|
+
const configuredProviders = provider.endpoints.map((endpoint, index) =>
|
|
252
|
+
createProvider({
|
|
246
253
|
id: providerId(endpoint, index),
|
|
247
254
|
name: endpoint.protocol,
|
|
248
255
|
baseUrl: endpoint.baseURL,
|
|
@@ -259,8 +266,12 @@ export function configurePiModels(
|
|
|
259
266
|
configuredModel(endpoint, index, modelId),
|
|
260
267
|
),
|
|
261
268
|
api: piApiFor(endpoint.protocol),
|
|
262
|
-
})
|
|
263
|
-
|
|
269
|
+
})
|
|
270
|
+
);
|
|
271
|
+
models.clearProviders();
|
|
272
|
+
configuredProviders.forEach((configuredProvider) =>
|
|
273
|
+
models.setProvider(configuredProvider)
|
|
274
|
+
);
|
|
264
275
|
return models;
|
|
265
276
|
}
|
|
266
277
|
|
package/src/pi/tool/base.ts
CHANGED
|
@@ -66,9 +66,9 @@ function candidate<T extends TSchema>(tool: AgentTool<T>): PiToolCandidate {
|
|
|
66
66
|
};
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
-
/** Runtime
|
|
69
|
+
/** Runtime base tools, including native web search when the model supports it. */
|
|
70
70
|
export function basePiToolCandidates(
|
|
71
|
-
webSearch
|
|
71
|
+
webSearch?: WebSearch,
|
|
72
72
|
): PiToolCandidate[] {
|
|
73
73
|
return [
|
|
74
74
|
candidate({
|
|
@@ -105,6 +105,6 @@ export function basePiToolCandidates(
|
|
|
105
105
|
});
|
|
106
106
|
},
|
|
107
107
|
}),
|
|
108
|
-
webSearchPiToolCandidate(webSearch),
|
|
108
|
+
...(webSearch ? [webSearchPiToolCandidate(webSearch)] : []),
|
|
109
109
|
];
|
|
110
110
|
}
|
|
@@ -1106,6 +1106,8 @@ export interface WebSearchOptions {
|
|
|
1106
1106
|
|
|
1107
1107
|
function apiFor(endpoint: RuntimeModelEndpoint): NativeApi {
|
|
1108
1108
|
switch (endpoint.protocol) {
|
|
1109
|
+
case "openrouter-chat":
|
|
1110
|
+
throw new Error("Native web search is unavailable for openrouter-chat");
|
|
1109
1111
|
case "google-generative-ai":
|
|
1110
1112
|
return "google-generative-ai";
|
|
1111
1113
|
case "openai-chat":
|
package/src/plugins.ts
CHANGED
|
@@ -863,12 +863,22 @@ class RuntimeBuilder implements RuntimeContributionContext {
|
|
|
863
863
|
);
|
|
864
864
|
}
|
|
865
865
|
const resolvedModel = resolvePiModel(provider, profile.model);
|
|
866
|
-
const
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
866
|
+
const endpoint = endpoints[0]!;
|
|
867
|
+
const webSearch = endpoint.protocol === "openrouter-chat"
|
|
868
|
+
? undefined
|
|
869
|
+
: createWebSearch({
|
|
870
|
+
endpoint,
|
|
871
|
+
model: profile.model,
|
|
872
|
+
maxTokens: resolvedModel.maxTokens,
|
|
873
|
+
reasoning: resolvedModel.reasoning,
|
|
874
|
+
});
|
|
875
|
+
if (!webSearch) {
|
|
876
|
+
this.reportDegradation({
|
|
877
|
+
capability: "web_search",
|
|
878
|
+
reason: "unavailable",
|
|
879
|
+
detail: "Native web search is unavailable for openrouter-chat",
|
|
880
|
+
});
|
|
881
|
+
}
|
|
872
882
|
for (const candidate of basePiToolCandidates(webSearch)) {
|
|
873
883
|
this.addPiTool(candidate);
|
|
874
884
|
}
|