@pellux/goodvibes-sdk 0.33.38 → 0.34.1
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/dist/contracts/artifacts/operator-contract.json +1383 -4
- package/dist/events/workflows.d.ts +4 -0
- package/dist/events/workflows.d.ts.map +1 -1
- package/dist/platform/agents/message-bus-core.d.ts +11 -0
- package/dist/platform/agents/message-bus-core.d.ts.map +1 -1
- package/dist/platform/agents/message-bus-core.js +28 -21
- package/dist/platform/agents/orchestrator-runner.d.ts.map +1 -1
- package/dist/platform/agents/orchestrator-runner.js +6 -4
- package/dist/platform/agents/wrfc-config.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-config.js +16 -10
- package/dist/platform/agents/wrfc-controller.d.ts +26 -0
- package/dist/platform/agents/wrfc-controller.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-controller.js +134 -138
- package/dist/platform/agents/wrfc-runtime-events.d.ts +1 -0
- package/dist/platform/agents/wrfc-runtime-events.d.ts.map +1 -1
- package/dist/platform/agents/wrfc-runtime-events.js +4 -1
- package/dist/platform/automation/delivery-manager.d.ts.map +1 -1
- package/dist/platform/automation/delivery-manager.js +1 -6
- package/dist/platform/batch/manager.d.ts.map +1 -1
- package/dist/platform/batch/manager.js +1 -3
- package/dist/platform/channels/policy-manager.d.ts.map +1 -1
- package/dist/platform/channels/policy-manager.js +1 -3
- package/dist/platform/channels/reply-pipeline.d.ts.map +1 -1
- package/dist/platform/channels/reply-pipeline.js +4 -0
- package/dist/platform/config/schema-domain-core.d.ts +1 -1
- package/dist/platform/config/schema-domain-core.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-core.js +12 -12
- package/dist/platform/config/schema-domain-runtime.d.ts +1 -1
- package/dist/platform/config/schema-domain-runtime.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-runtime.js +19 -18
- package/dist/platform/config/schema-domain-surfaces.d.ts +1 -1
- package/dist/platform/config/schema-domain-surfaces.d.ts.map +1 -1
- package/dist/platform/config/schema-domain-surfaces.js +4 -3
- package/dist/platform/config/schema-shared.d.ts +6 -0
- package/dist/platform/config/schema-shared.d.ts.map +1 -1
- package/dist/platform/config/schema-shared.js +21 -1
- package/dist/platform/control-plane/approval-broker.d.ts.map +1 -1
- package/dist/platform/control-plane/approval-broker.js +1 -3
- package/dist/platform/control-plane/method-catalog-calendar.d.ts +9 -0
- package/dist/platform/control-plane/method-catalog-calendar.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-calendar.js +117 -0
- package/dist/platform/control-plane/method-catalog-channels.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog-channels.js +174 -0
- package/dist/platform/control-plane/method-catalog-email.d.ts +9 -0
- package/dist/platform/control-plane/method-catalog-email.d.ts.map +1 -0
- package/dist/platform/control-plane/method-catalog-email.js +101 -0
- package/dist/platform/control-plane/method-catalog.d.ts.map +1 -1
- package/dist/platform/control-plane/method-catalog.js +4 -0
- package/dist/platform/control-plane/session-broker-state.d.ts.map +1 -1
- package/dist/platform/control-plane/session-broker-state.js +1 -3
- package/dist/platform/core/compaction-sections.d.ts +5 -1
- package/dist/platform/core/compaction-sections.d.ts.map +1 -1
- package/dist/platform/core/compaction-sections.js +73 -66
- package/dist/platform/core/context-compaction.d.ts.map +1 -1
- package/dist/platform/core/context-compaction.js +9 -16
- package/dist/platform/core/orchestrator-context-runtime.d.ts +2 -2
- package/dist/platform/core/orchestrator-context-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-context-runtime.js +24 -21
- package/dist/platform/core/orchestrator-tool-runtime.d.ts.map +1 -1
- package/dist/platform/core/orchestrator-tool-runtime.js +2 -1
- package/dist/platform/core/session-lineage.d.ts +2 -5
- package/dist/platform/core/session-lineage.d.ts.map +1 -1
- package/dist/platform/core/session-lineage.js +4 -16
- package/dist/platform/core/wrfc-routing.d.ts.map +1 -1
- package/dist/platform/core/wrfc-routing.js +1 -3
- package/dist/platform/daemon/http/mcp-routes.d.ts.map +1 -1
- package/dist/platform/daemon/http/mcp-routes.js +1 -3
- package/dist/platform/daemon/http/openai-compatible-routes.d.ts.map +1 -1
- package/dist/platform/daemon/http/openai-compatible-routes.js +1 -3
- package/dist/platform/daemon/http/runtime-routes.d.ts.map +1 -1
- package/dist/platform/daemon/http/runtime-routes.js +1 -3
- package/dist/platform/hooks/runners/http.d.ts.map +1 -1
- package/dist/platform/hooks/runners/http.js +9 -19
- package/dist/platform/integrations/webhooks.js +2 -11
- package/dist/platform/knowledge/semantic/self-improvement.d.ts.map +1 -1
- package/dist/platform/knowledge/semantic/self-improvement.js +2 -21
- package/dist/platform/mcp/client.d.ts.map +1 -1
- package/dist/platform/mcp/client.js +1 -3
- package/dist/platform/mcp/config.d.ts.map +1 -1
- package/dist/platform/mcp/config.js +1 -3
- package/dist/platform/media/builtin-generation-providers.d.ts.map +1 -1
- package/dist/platform/media/builtin-generation-providers.js +1 -6
- package/dist/platform/providers/anthropic-compat.d.ts.map +1 -1
- package/dist/platform/providers/anthropic-compat.js +11 -131
- package/dist/platform/providers/anthropic-sdk-provider.d.ts.map +1 -1
- package/dist/platform/providers/anthropic-sdk-provider.js +8 -42
- package/dist/platform/providers/anthropic-sse-assembler.d.ts +80 -0
- package/dist/platform/providers/anthropic-sse-assembler.d.ts.map +1 -0
- package/dist/platform/providers/anthropic-sse-assembler.js +146 -0
- package/dist/platform/providers/anthropic-stream.d.ts +30 -0
- package/dist/platform/providers/anthropic-stream.d.ts.map +1 -0
- package/dist/platform/providers/anthropic-stream.js +44 -0
- package/dist/platform/providers/anthropic-vertex.d.ts.map +1 -1
- package/dist/platform/providers/anthropic-vertex.js +1 -3
- package/dist/platform/providers/anthropic.d.ts.map +1 -1
- package/dist/platform/providers/anthropic.js +15 -151
- package/dist/platform/providers/capabilities.d.ts.map +1 -1
- package/dist/platform/providers/capabilities.js +11 -7
- package/dist/platform/providers/context-discovery.d.ts.map +1 -1
- package/dist/platform/providers/context-discovery.js +9 -16
- package/dist/platform/providers/context-window-fallback.d.ts +24 -0
- package/dist/platform/providers/context-window-fallback.d.ts.map +1 -0
- package/dist/platform/providers/context-window-fallback.js +48 -0
- package/dist/platform/providers/gemini.d.ts.map +1 -1
- package/dist/platform/providers/gemini.js +3 -6
- package/dist/platform/providers/json-ttl-cache.d.ts +35 -0
- package/dist/platform/providers/json-ttl-cache.d.ts.map +1 -0
- package/dist/platform/providers/json-ttl-cache.js +52 -0
- package/dist/platform/providers/llama-cpp.d.ts.map +1 -1
- package/dist/platform/providers/llama-cpp.js +2 -23
- package/dist/platform/providers/lm-studio-helpers.d.ts +1 -1
- package/dist/platform/providers/lm-studio-helpers.d.ts.map +1 -1
- package/dist/platform/providers/lm-studio-helpers.js +5 -25
- package/dist/platform/providers/model-benchmarks.d.ts.map +1 -1
- package/dist/platform/providers/model-benchmarks.js +11 -34
- package/dist/platform/providers/model-catalog-cache.d.ts.map +1 -1
- package/dist/platform/providers/model-catalog-cache.js +15 -38
- package/dist/platform/providers/model-catalog-synthetic.d.ts.map +1 -1
- package/dist/platform/providers/model-catalog-synthetic.js +3 -2
- package/dist/platform/providers/model-catalog.d.ts.map +1 -1
- package/dist/platform/providers/model-catalog.js +3 -2
- package/dist/platform/providers/model-limits.d.ts.map +1 -1
- package/dist/platform/providers/model-limits.js +18 -42
- package/dist/platform/providers/ollama.d.ts.map +1 -1
- package/dist/platform/providers/ollama.js +3 -24
- package/dist/platform/providers/openai-codex.d.ts.map +1 -1
- package/dist/platform/providers/openai-codex.js +8 -9
- package/dist/platform/providers/openai-compat.d.ts.map +1 -1
- package/dist/platform/providers/openai-compat.js +13 -40
- package/dist/platform/providers/openai-stream-helpers.d.ts +62 -0
- package/dist/platform/providers/openai-stream-helpers.d.ts.map +1 -0
- package/dist/platform/providers/openai-stream-helpers.js +73 -0
- package/dist/platform/providers/openai.d.ts.map +1 -1
- package/dist/platform/providers/openai.js +13 -41
- package/dist/platform/providers/provider-error.d.ts +17 -0
- package/dist/platform/providers/provider-error.d.ts.map +1 -0
- package/dist/platform/providers/provider-error.js +33 -0
- package/dist/platform/providers/provider-stop-reason.d.ts +15 -0
- package/dist/platform/providers/provider-stop-reason.d.ts.map +1 -0
- package/dist/platform/providers/provider-stop-reason.js +15 -0
- package/dist/platform/providers/sse-line-buffer.d.ts +13 -0
- package/dist/platform/providers/sse-line-buffer.d.ts.map +1 -0
- package/dist/platform/providers/sse-line-buffer.js +23 -0
- package/dist/platform/providers/tool-formats.d.ts +5 -0
- package/dist/platform/providers/tool-formats.d.ts.map +1 -1
- package/dist/platform/providers/tool-formats.js +14 -0
- package/dist/platform/runtime/bootstrap-runtime-events.d.ts.map +1 -1
- package/dist/platform/runtime/bootstrap-runtime-events.js +6 -0
- package/dist/platform/runtime/bootstrap-services.d.ts.map +1 -1
- package/dist/platform/runtime/bootstrap-services.js +4 -5
- package/dist/platform/runtime/emitters/workflows.d.ts +4 -0
- package/dist/platform/runtime/emitters/workflows.d.ts.map +1 -1
- package/dist/platform/runtime/emitters/workflows.js +3 -0
- package/dist/platform/runtime/remote/distributed-runtime-store.d.ts.map +1 -1
- package/dist/platform/runtime/remote/distributed-runtime-store.js +1 -3
- package/dist/platform/runtime/retention/pruner.js +2 -5
- package/dist/platform/runtime/store/helpers/reducers/lifecycle.d.ts.map +1 -1
- package/dist/platform/runtime/store/helpers/reducers/lifecycle.js +15 -14
- package/dist/platform/runtime/store/helpers/reducers/shared.d.ts +6 -0
- package/dist/platform/runtime/store/helpers/reducers/shared.d.ts.map +1 -1
- package/dist/platform/runtime/store/helpers/reducers/shared.js +8 -1
- package/dist/platform/runtime/telemetry/exporters/queue.d.ts.map +1 -1
- package/dist/platform/runtime/telemetry/exporters/queue.js +1 -7
- package/dist/platform/runtime/transports/http-helpers.d.ts +0 -1
- package/dist/platform/runtime/transports/http-helpers.d.ts.map +1 -1
- package/dist/platform/runtime/transports/http-helpers.js +1 -3
- package/dist/platform/runtime/ui-read-model-helpers.d.ts +2 -0
- package/dist/platform/runtime/ui-read-model-helpers.d.ts.map +1 -1
- package/dist/platform/runtime/ui-read-model-helpers.js +8 -0
- package/dist/platform/runtime/ui-read-models-core.d.ts.map +1 -1
- package/dist/platform/runtime/ui-read-models-core.js +3 -5
- package/dist/platform/runtime/ui-read-models-observability-remote.d.ts.map +1 -1
- package/dist/platform/runtime/ui-read-models-observability-remote.js +2 -4
- package/dist/platform/runtime/ui-read-models-operations.d.ts.map +1 -1
- package/dist/platform/runtime/ui-read-models-operations.js +8 -26
- package/dist/platform/scheduler/scheduler.d.ts.map +1 -1
- package/dist/platform/scheduler/scheduler.js +1 -3
- package/dist/platform/tools/exec/runtime.d.ts.map +1 -1
- package/dist/platform/tools/exec/runtime.js +1 -7
- package/dist/platform/tools/fetch/runtime.d.ts.map +1 -1
- package/dist/platform/tools/fetch/runtime.js +9 -20
- package/dist/platform/tools/shared/process-manager.d.ts.map +1 -1
- package/dist/platform/tools/shared/process-manager.js +1 -6
- package/dist/platform/utils/concurrency.d.ts +1 -0
- package/dist/platform/utils/concurrency.d.ts.map +1 -1
- package/dist/platform/utils/concurrency.js +1 -0
- package/dist/platform/utils/error-display.d.ts +9 -0
- package/dist/platform/utils/error-display.d.ts.map +1 -1
- package/dist/platform/utils/error-display.js +11 -0
- package/dist/platform/utils/fetch-with-timeout.d.ts +22 -2
- package/dist/platform/utils/fetch-with-timeout.d.ts.map +1 -1
- package/dist/platform/utils/fetch-with-timeout.js +33 -15
- package/dist/platform/utils/record-coerce.d.ts +5 -0
- package/dist/platform/utils/record-coerce.d.ts.map +1 -1
- package/dist/platform/utils/record-coerce.js +7 -0
- package/dist/platform/utils/retry.d.ts.map +1 -1
- package/dist/platform/utils/retry.js +2 -4
- package/dist/platform/version.js +1 -1
- package/package.json +9 -9
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import OpenAI from 'openai';
|
|
2
2
|
import { ProviderError } from '../types/errors.js';
|
|
3
|
-
import { summarizeError
|
|
3
|
+
import { summarizeError } from '../utils/error-display.js';
|
|
4
|
+
import { getErrorStatus } from './provider-error.js';
|
|
5
|
+
export { normalizeProviderError } from './provider-error.js';
|
|
4
6
|
export function createResponsesClient(baseURL, apiKey, defaultHeaders) {
|
|
5
7
|
const client = new OpenAI({
|
|
6
8
|
apiKey,
|
|
@@ -222,7 +224,7 @@ export function toRecord(value) {
|
|
|
222
224
|
}
|
|
223
225
|
export function shouldFallbackFromNative(err) {
|
|
224
226
|
const status = getErrorStatus(err);
|
|
225
|
-
const message =
|
|
227
|
+
const message = summarizeError(err);
|
|
226
228
|
if (status === 404 || status === 405 || status === 501)
|
|
227
229
|
return true;
|
|
228
230
|
if (status === 400 && /previous_response_id|response_id/i.test(message))
|
|
@@ -231,30 +233,8 @@ export function shouldFallbackFromNative(err) {
|
|
|
231
233
|
}
|
|
232
234
|
export function shouldFallbackFromResponses(err) {
|
|
233
235
|
const status = getErrorStatus(err);
|
|
234
|
-
const message =
|
|
236
|
+
const message = summarizeError(err);
|
|
235
237
|
if (status === 404 || status === 405 || status === 501)
|
|
236
238
|
return true;
|
|
237
239
|
return /not implemented|unsupported|unknown endpoint/i.test(message);
|
|
238
240
|
}
|
|
239
|
-
function getErrorStatus(err) {
|
|
240
|
-
if (err && typeof err === 'object') {
|
|
241
|
-
const record = err;
|
|
242
|
-
if (typeof record.status === 'number')
|
|
243
|
-
return record.status;
|
|
244
|
-
if (typeof record.statusCode === 'number')
|
|
245
|
-
return record.statusCode;
|
|
246
|
-
}
|
|
247
|
-
return undefined;
|
|
248
|
-
}
|
|
249
|
-
function getErrorMessage(err) {
|
|
250
|
-
return summarizeError(err);
|
|
251
|
-
}
|
|
252
|
-
export function normalizeProviderError(err, provider, operation, phase = 'request') {
|
|
253
|
-
const status = getErrorStatus(err);
|
|
254
|
-
return toProviderError(err, {
|
|
255
|
-
...(status !== undefined ? { statusCode: status } : {}),
|
|
256
|
-
provider,
|
|
257
|
-
operation,
|
|
258
|
-
phase,
|
|
259
|
-
});
|
|
260
|
-
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-benchmarks.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-benchmarks.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-benchmarks.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-benchmarks.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,eAAe,CAAC;CAC7B;AAED,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AA8ChD,eAAO,MAAM,gBAAgB,MAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,eAAO,MAAM,gBAAgB,MAAO,CAAC;AAoErC,wBAAgB,cAAc,CAAC,UAAU,EAAE,eAAe,GAAG,MAAM,GAAG,IAAI,CAOzE;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,eAAe,GAAG,WAAW,CAIvE;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,WAAW,CAKlE;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,KAAK,CAAgC;IAC7C,OAAO,CAAC,SAAS,CAA4C;IAC7D,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAyB;gBAE9C,OAAO,EAAE,qBAAqB;IAI1C,YAAY,IAAI,MAAM;IAItB,OAAO,CAAC,UAAU;IAIlB,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI;IAO7C,cAAc,IAAI,IAAI;IAUhB,iBAAiB,IAAI,OAAO,CAAC,IAAI,CAAC;IAmBxC,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS;IAgE5D,uBAAuB,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE;YAW9B,eAAe;IAU7B,OAAO,CAAC,SAAS;IAuBjB,OAAO,CAAC,SAAS;IAUjB,OAAO,CAAC,YAAY;CAGrB"}
|
|
@@ -2,10 +2,10 @@ import { mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { summarizeError } from '../utils/error-display.js';
|
|
5
|
-
import {
|
|
5
|
+
import { TTL_24H_MS, isTtlCacheStale, validateTtlCacheEnvelope } from './json-ttl-cache.js';
|
|
6
|
+
import { instrumentedFetch, fetchWithTimeout } from '../utils/fetch-with-timeout.js';
|
|
6
7
|
const ZEROEVAL_URL = 'https://api.zeroeval.com/leaderboard/models/full?justCanonicals=true';
|
|
7
8
|
const FETCH_TIMEOUT_MS = 20_000;
|
|
8
|
-
const CACHE_TTL_MS = 86_400_000;
|
|
9
9
|
export const S_TIER_THRESHOLD = 0.80;
|
|
10
10
|
export const A_TIER_THRESHOLD = 0.65;
|
|
11
11
|
export const B_TIER_THRESHOLD = 0.50;
|
|
@@ -72,21 +72,7 @@ function buildNameIndex(entries) {
|
|
|
72
72
|
return index;
|
|
73
73
|
}
|
|
74
74
|
function validateBenchmarksCache(value) {
|
|
75
|
-
|
|
76
|
-
return { cache: null, reason: 'root value is not an object' };
|
|
77
|
-
}
|
|
78
|
-
const parsed = value;
|
|
79
|
-
if (parsed.version !== 1)
|
|
80
|
-
return { cache: null, reason: 'unsupported cache version' };
|
|
81
|
-
if (typeof parsed.fetchedAt !== 'number' || !Number.isFinite(parsed.fetchedAt)) {
|
|
82
|
-
return { cache: null, reason: 'fetchedAt must be a finite number' };
|
|
83
|
-
}
|
|
84
|
-
if (typeof parsed.ttlMs !== 'number' || !Number.isFinite(parsed.ttlMs)) {
|
|
85
|
-
return { cache: null, reason: 'ttlMs must be a finite number' };
|
|
86
|
-
}
|
|
87
|
-
if (!Array.isArray(parsed.entries))
|
|
88
|
-
return { cache: null, reason: 'entries must be an array' };
|
|
89
|
-
return { cache: parsed };
|
|
75
|
+
return validateTtlCacheEnvelope(value, 'entries', 'array');
|
|
90
76
|
}
|
|
91
77
|
export function compositeScore(benchmarks) {
|
|
92
78
|
let total = 0;
|
|
@@ -158,7 +144,7 @@ export class BenchmarkStore {
|
|
|
158
144
|
const next = {
|
|
159
145
|
version: 1,
|
|
160
146
|
fetchedAt: Date.now(),
|
|
161
|
-
ttlMs:
|
|
147
|
+
ttlMs: TTL_24H_MS,
|
|
162
148
|
entries,
|
|
163
149
|
};
|
|
164
150
|
this.saveCache(next);
|
|
@@ -236,22 +222,13 @@ export class BenchmarkStore {
|
|
|
236
222
|
.map((entry) => entry.id);
|
|
237
223
|
}
|
|
238
224
|
async fetchBenchmarks() {
|
|
239
|
-
const
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
signal: controller.signal,
|
|
245
|
-
headers: { Accept: 'application/json' },
|
|
246
|
-
});
|
|
247
|
-
if (!response.ok) {
|
|
248
|
-
throw new Error(`ZeroEval API returned ${response.status} ${response.statusText}`);
|
|
249
|
-
}
|
|
250
|
-
return parseEntries(await response.json());
|
|
251
|
-
}
|
|
252
|
-
finally {
|
|
253
|
-
clearTimeout(timer);
|
|
225
|
+
const response = await fetchWithTimeout(ZEROEVAL_URL, {
|
|
226
|
+
headers: { Accept: 'application/json' },
|
|
227
|
+
}, FETCH_TIMEOUT_MS, instrumentedFetch);
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
throw new Error(`ZeroEval API returned ${response.status} ${response.statusText}`);
|
|
254
230
|
}
|
|
231
|
+
return parseEntries(await response.json());
|
|
255
232
|
}
|
|
256
233
|
loadCache() {
|
|
257
234
|
try {
|
|
@@ -288,6 +265,6 @@ export class BenchmarkStore {
|
|
|
288
265
|
}
|
|
289
266
|
}
|
|
290
267
|
isCacheStale(cache) {
|
|
291
|
-
return
|
|
268
|
+
return isTtlCacheStale(cache);
|
|
292
269
|
}
|
|
293
270
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog-cache.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-catalog-cache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"model-catalog-cache.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-catalog-cache.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAkBvD,UAAU,gBAAgB;IACxB,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,YAAY,EAAE,CAAC;CACxB;AA6BD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE1D;AAsHD,iBAAS,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI,CAmBpE;AAED,iBAAS,gBAAgB,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAc1F;AAED,iBAAS,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,OAAO,CAE7D;AAED;;;GAGG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAa5D;AAED,OAAO,EACL,gBAAgB,EAChB,gBAAgB,EAChB,mBAAmB,GACpB,CAAC"}
|
|
@@ -2,10 +2,10 @@ import fs from 'node:fs';
|
|
|
2
2
|
import { dirname, join } from 'node:path';
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { summarizeError } from '../utils/error-display.js';
|
|
5
|
-
import {
|
|
5
|
+
import { TTL_24H_MS, isTtlCacheStale, validateTtlCacheEnvelope } from './json-ttl-cache.js';
|
|
6
|
+
import { instrumentedFetch, fetchWithTimeout } from '../utils/fetch-with-timeout.js';
|
|
6
7
|
const MODELS_DEV_URL = 'https://models.dev/api.json';
|
|
7
8
|
const CATALOG_FETCH_TIMEOUT_MS = 30_000;
|
|
8
|
-
const CATALOG_TTL_MS = 86_400_000; // 24 hours
|
|
9
9
|
export function getCatalogCachePath(cacheDir) {
|
|
10
10
|
return join(cacheDir, 'model-catalog.json');
|
|
11
11
|
}
|
|
@@ -78,7 +78,7 @@ function transformModelsDevResponse(json) {
|
|
|
78
78
|
const supportsReasoning = modelData.reasoning === true;
|
|
79
79
|
const inputCost = typeof cost?.input === 'number' ? cost.input : 0;
|
|
80
80
|
const outputCost = typeof cost?.output === 'number' ? cost.output : 0;
|
|
81
|
-
const contextWindow = typeof limit?.context === 'number' ? limit.context : undefined;
|
|
81
|
+
const contextWindow = typeof limit?.context === 'number' && limit.context > 0 ? limit.context : undefined;
|
|
82
82
|
let tier;
|
|
83
83
|
if (providerCategory === 'subscription') {
|
|
84
84
|
tier = 'subscription';
|
|
@@ -115,21 +115,7 @@ function transformModelsDevResponse(json) {
|
|
|
115
115
|
return models;
|
|
116
116
|
}
|
|
117
117
|
function validateCatalogCache(value) {
|
|
118
|
-
|
|
119
|
-
return { cache: null, reason: 'root value is not an object' };
|
|
120
|
-
}
|
|
121
|
-
const parsed = value;
|
|
122
|
-
if (parsed.version !== 1)
|
|
123
|
-
return { cache: null, reason: 'unsupported cache version' };
|
|
124
|
-
if (typeof parsed.fetchedAt !== 'number' || !Number.isFinite(parsed.fetchedAt)) {
|
|
125
|
-
return { cache: null, reason: 'fetchedAt must be a finite number' };
|
|
126
|
-
}
|
|
127
|
-
if (typeof parsed.ttlMs !== 'number' || !Number.isFinite(parsed.ttlMs)) {
|
|
128
|
-
return { cache: null, reason: 'ttlMs must be a finite number' };
|
|
129
|
-
}
|
|
130
|
-
if (!Array.isArray(parsed.models))
|
|
131
|
-
return { cache: null, reason: 'models must be an array' };
|
|
132
|
-
return { cache: parsed };
|
|
118
|
+
return validateTtlCacheEnvelope(value, 'models', 'array');
|
|
133
119
|
}
|
|
134
120
|
function loadCatalogCache(cachePath) {
|
|
135
121
|
try {
|
|
@@ -159,7 +145,7 @@ function saveCatalogCache(models, cachePath, tmpPath) {
|
|
|
159
145
|
const payload = {
|
|
160
146
|
version: 1,
|
|
161
147
|
fetchedAt: Date.now(),
|
|
162
|
-
ttlMs:
|
|
148
|
+
ttlMs: TTL_24H_MS,
|
|
163
149
|
models,
|
|
164
150
|
};
|
|
165
151
|
fs.writeFileSync(tmpPath, JSON.stringify(payload, null, 2), 'utf-8');
|
|
@@ -170,31 +156,22 @@ function saveCatalogCache(models, cachePath, tmpPath) {
|
|
|
170
156
|
}
|
|
171
157
|
}
|
|
172
158
|
function isCatalogCacheStale(cache) {
|
|
173
|
-
return
|
|
159
|
+
return isTtlCacheStale(cache);
|
|
174
160
|
}
|
|
175
161
|
/**
|
|
176
162
|
* Fetch models.dev/api.json and parse into CatalogModel[].
|
|
177
163
|
* Uses a 30-second timeout.
|
|
178
164
|
*/
|
|
179
165
|
export async function fetchCatalog() {
|
|
180
|
-
const
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
signal: controller.signal,
|
|
186
|
-
headers: { Accept: 'application/json' },
|
|
187
|
-
});
|
|
188
|
-
if (!response.ok) {
|
|
189
|
-
throw new Error(`models.dev API returned ${response.status} ${response.statusText}`);
|
|
190
|
-
}
|
|
191
|
-
const json = await response.json();
|
|
192
|
-
const models = transformModelsDevResponse(json);
|
|
193
|
-
logger.debug('[model-catalog] Fetched models from models.dev', { count: models.length });
|
|
194
|
-
return models;
|
|
195
|
-
}
|
|
196
|
-
finally {
|
|
197
|
-
clearTimeout(timer);
|
|
166
|
+
const response = await fetchWithTimeout(MODELS_DEV_URL, {
|
|
167
|
+
headers: { Accept: 'application/json' },
|
|
168
|
+
}, CATALOG_FETCH_TIMEOUT_MS, instrumentedFetch);
|
|
169
|
+
if (!response.ok) {
|
|
170
|
+
throw new Error(`models.dev API returned ${response.status} ${response.statusText}`);
|
|
198
171
|
}
|
|
172
|
+
const json = await response.json();
|
|
173
|
+
const models = transformModelsDevResponse(json);
|
|
174
|
+
logger.debug('[model-catalog] Fetched models from models.dev', { count: models.length });
|
|
175
|
+
return models;
|
|
199
176
|
}
|
|
200
177
|
export { loadCatalogCache, saveCatalogCache, isCatalogCacheStale, };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog-synthetic.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-catalog-synthetic.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"model-catalog-synthetic.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-catalog-synthetic.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AACnE,OAAO,KAAK,EAAoB,cAAc,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEtF,MAAM,WAAW,sBAAsB;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE;QACZ,WAAW,EAAE,OAAO,CAAC;QACrB,WAAW,EAAE,OAAO,CAAC;QACrB,SAAS,EAAE,OAAO,CAAC;QACnB,UAAU,EAAE,OAAO,CAAC;KACrB,CAAC;IACF,aAAa,EAAE,MAAM,CAAC;IACtB,uBAAuB,CAAC,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC9D,UAAU,EAAE,OAAO,CAAC;IACpB,IAAI,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;IACvD,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;CACxC;AAED,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,IAAI,EAAE,aAAa,CAAC;IACpB,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAID,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/C;AASD,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,GAAG,cAAc,EAAE,CAgF/F;AAED,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,SAAS,cAAc,EAAE,EAC1C,aAAa,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,cAAc,GAAG,SAAS,GAC/D,kBAAkB,GAAG,IAAI,CAoB3B;AAED,wBAAgB,2BAA2B,CAAC,eAAe,EAAE,SAAS,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,CAAC,CAEnG;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,YAAY,EAAE,EAC/B,eAAe,EAAE,SAAS,cAAc,EAAE,GACzC,sBAAsB,EAAE,CAoC1B"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { inferFallbackContextWindow } from './context-window-fallback.js';
|
|
2
3
|
import { compositeScore } from './model-benchmarks.js';
|
|
3
4
|
const MAX_FAMILY_UNIQUE_NAMES = 20;
|
|
4
5
|
export function nameToSlug(name) {
|
|
@@ -127,7 +128,7 @@ export function getSyntheticModelDefinitions(models, canonicalModels) {
|
|
|
127
128
|
const catalogMatch = models.find((model) => canonical.backends.some((backend) => backend.modelId === model.id));
|
|
128
129
|
const displayName = catalogMatch?.name ?? canonical.id;
|
|
129
130
|
const hasReasoning = catalogMatch?.reasoning === true;
|
|
130
|
-
const hasCatalogContextWindow = bestBackend?.contextWindow != null;
|
|
131
|
+
const hasCatalogContextWindow = bestBackend?.contextWindow != null && bestBackend.contextWindow > 0;
|
|
131
132
|
return {
|
|
132
133
|
id: canonical.id,
|
|
133
134
|
provider: 'synthetic',
|
|
@@ -140,7 +141,7 @@ export function getSyntheticModelDefinitions(models, canonicalModels) {
|
|
|
140
141
|
reasoning: hasReasoning,
|
|
141
142
|
multimodal: false,
|
|
142
143
|
},
|
|
143
|
-
contextWindow: hasCatalogContextWindow ? bestBackend.contextWindow :
|
|
144
|
+
contextWindow: hasCatalogContextWindow ? bestBackend.contextWindow : inferFallbackContextWindow('synthetic', canonical.id),
|
|
144
145
|
...(!hasCatalogContextWindow ? { contextWindowProvenance: 'fallback' } : {}),
|
|
145
146
|
selectable: true,
|
|
146
147
|
tier: canonical.tier === 'free' ? 'free' : canonical.tier === 'subscription' ? 'subscription' : 'standard',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-catalog.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACvE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,sBAAsB,EAAsB,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"model-catalog.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-catalog.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { logger } from '../utils/logger.js';
|
|
2
|
+
import { inferFallbackContextWindow } from './context-window-fallback.js';
|
|
2
3
|
export function getCostFromPricingCatalog(modelId, catalog, modelLimitsService, opts = {}) {
|
|
3
4
|
if (modelId.endsWith(':free')) {
|
|
4
5
|
return { input: 0, output: 0 };
|
|
@@ -93,7 +94,7 @@ export function getCatalogModelDefinitionsFrom(models) {
|
|
|
93
94
|
const isAnthropic = providerLower.includes('anthropic');
|
|
94
95
|
const isOpenAI = providerLower.includes('openai');
|
|
95
96
|
const hasReasoning = model.reasoning === true || isAnthropic || isOpenAI || isGoogle;
|
|
96
|
-
const hasCatalogContextWindow = model.contextWindow != null;
|
|
97
|
+
const hasCatalogContextWindow = model.contextWindow != null && model.contextWindow > 0;
|
|
97
98
|
return {
|
|
98
99
|
id: model.id,
|
|
99
100
|
provider: model.providerId,
|
|
@@ -108,7 +109,7 @@ export function getCatalogModelDefinitionsFrom(models) {
|
|
|
108
109
|
},
|
|
109
110
|
contextWindow: hasCatalogContextWindow
|
|
110
111
|
? model.contextWindow
|
|
111
|
-
: (
|
|
112
|
+
: inferFallbackContextWindow(model.provider, model.id),
|
|
112
113
|
...(!hasCatalogContextWindow ? { contextWindowProvenance: 'fallback' } : {}),
|
|
113
114
|
selectable: true,
|
|
114
115
|
tier: model.tier === 'subscription' ? 'subscription' : isFree ? 'free' : model.pricing.input >= 3 ? 'premium' : 'standard',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"model-limits.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-limits.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA6ClE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;
|
|
1
|
+
{"version":3,"file":"model-limits.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/model-limits.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AA6ClE,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAEhE;AA6GD,qBAAa,kBAAkB;IAIjB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAHpC,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,WAAW,CAAiD;gBAEvC,OAAO,EAAE,yBAAyB;IAE/D,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,kBAAkB;IA4B1B,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IAWpG,sBAAsB,CAAC,QAAQ,EAAE,eAAe,GAAG,QAAQ,CAAC,WAAW,CAAC;IAIxE,wBAAwB,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM;IAc3D,6BAA6B,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM;IAK1E,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAiChC,IAAI,IAAI,IAAI;CASb"}
|
|
@@ -2,10 +2,10 @@ import { dirname, join } from 'node:path';
|
|
|
2
2
|
import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
3
3
|
import { logger } from '../utils/logger.js';
|
|
4
4
|
import { summarizeError } from '../utils/error-display.js';
|
|
5
|
-
import {
|
|
5
|
+
import { TTL_24H_MS, isTtlCacheStale, validateTtlCacheEnvelope } from './json-ttl-cache.js';
|
|
6
|
+
import { instrumentedFetch, fetchWithTimeout } from '../utils/fetch-with-timeout.js';
|
|
6
7
|
const OPENROUTER_MODELS_URL = 'https://openrouter.ai/api/v1/models';
|
|
7
8
|
const FETCH_TIMEOUT_MS = 15_000;
|
|
8
|
-
const CACHE_TTL_MS = 86_400_000;
|
|
9
9
|
const DEFAULT_TOKEN_LIMITS = {
|
|
10
10
|
maxOutputTokens: 8192,
|
|
11
11
|
maxToolResultTokens: 50_000,
|
|
@@ -16,22 +16,7 @@ export function getModelLimitsCachePath(cacheDir) {
|
|
|
16
16
|
return join(cacheDir, 'model-limits.json');
|
|
17
17
|
}
|
|
18
18
|
function validateModelLimitsCache(value) {
|
|
19
|
-
|
|
20
|
-
return { cache: null, reason: 'root value is not an object' };
|
|
21
|
-
}
|
|
22
|
-
const parsed = value;
|
|
23
|
-
if (parsed.version !== 1)
|
|
24
|
-
return { cache: null, reason: 'unsupported cache version' };
|
|
25
|
-
if (typeof parsed.fetchedAt !== 'number' || !Number.isFinite(parsed.fetchedAt)) {
|
|
26
|
-
return { cache: null, reason: 'fetchedAt must be a finite number' };
|
|
27
|
-
}
|
|
28
|
-
if (typeof parsed.ttlMs !== 'number' || !Number.isFinite(parsed.ttlMs)) {
|
|
29
|
-
return { cache: null, reason: 'ttlMs must be a finite number' };
|
|
30
|
-
}
|
|
31
|
-
if (!parsed.models || typeof parsed.models !== 'object' || Array.isArray(parsed.models)) {
|
|
32
|
-
return { cache: null, reason: 'models must be an object' };
|
|
33
|
-
}
|
|
34
|
-
return { cache: parsed };
|
|
19
|
+
return validateTtlCacheEnvelope(value, 'models', 'object');
|
|
35
20
|
}
|
|
36
21
|
function loadCachedLimits(cachePath) {
|
|
37
22
|
try {
|
|
@@ -65,34 +50,25 @@ function saveCachedLimits(cache, cachePath) {
|
|
|
65
50
|
}
|
|
66
51
|
}
|
|
67
52
|
function isCacheStale(cache) {
|
|
68
|
-
return
|
|
53
|
+
return isTtlCacheStale(cache);
|
|
69
54
|
}
|
|
70
55
|
async function fetchOpenRouterModels() {
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
const map = new Map();
|
|
84
|
-
if (Array.isArray(json.data)) {
|
|
85
|
-
for (const model of json.data) {
|
|
86
|
-
if (typeof model.id === 'string') {
|
|
87
|
-
map.set(model.id, model);
|
|
88
|
-
}
|
|
56
|
+
const response = await fetchWithTimeout(OPENROUTER_MODELS_URL, {
|
|
57
|
+
headers: { Accept: 'application/json' },
|
|
58
|
+
}, FETCH_TIMEOUT_MS, instrumentedFetch);
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
throw new Error(`OpenRouter API returned ${response.status}`);
|
|
61
|
+
}
|
|
62
|
+
const json = await response.json();
|
|
63
|
+
const map = new Map();
|
|
64
|
+
if (Array.isArray(json.data)) {
|
|
65
|
+
for (const model of json.data) {
|
|
66
|
+
if (typeof model.id === 'string') {
|
|
67
|
+
map.set(model.id, model);
|
|
89
68
|
}
|
|
90
69
|
}
|
|
91
|
-
return map;
|
|
92
|
-
}
|
|
93
|
-
finally {
|
|
94
|
-
clearTimeout(timer);
|
|
95
70
|
}
|
|
71
|
+
return map;
|
|
96
72
|
}
|
|
97
73
|
function getModelStem(modelId) {
|
|
98
74
|
return modelId
|
|
@@ -239,7 +215,7 @@ export class ModelLimitsService {
|
|
|
239
215
|
const newCache = {
|
|
240
216
|
version: 1,
|
|
241
217
|
fetchedAt: Date.now(),
|
|
242
|
-
ttlMs:
|
|
218
|
+
ttlMs: TTL_24H_MS,
|
|
243
219
|
models,
|
|
244
220
|
};
|
|
245
221
|
saveCachedLimits(newCache, this.options.cachePath);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/ollama.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EAEZ,WAAW,EAEX,wBAAwB,EACxB,uBAAuB,EAEvB,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/ollama.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EAEZ,WAAW,EAEX,wBAAwB,EACxB,uBAAuB,EAEvB,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAOpF,KAAK,WAAW,GAAG,CACjB,KAAK,EAAE,WAAW,GAAG,GAAG,EACxB,IAAI,CAAC,EAAE,WAAW,KACf,OAAO,CAAC,QAAQ,CAAC,CAAC;AAqBvB,MAAM,WAAW,qBAAsB,SAAQ,mBAAmB;IAChE,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACtC,cAAc,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;CAC1C;AAED,qBAAa,cAAe,YAAW,WAAW;IAChD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,GAAG,SAAS,CAAC;IAEhE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAS;IACxC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAc;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoB;gBAEvC,IAAI,EAAE,qBAAqB;IAYvC,YAAY,IAAI,OAAO;IAIjB,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAmBhD,KAAK,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAuC1E,eAAe,CAAC,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAAC,uBAAuB,CAAC;YA4C5E,mBAAmB;CAmGlC"}
|
|
@@ -3,7 +3,8 @@ import { instrumentedLlmCall } from '../runtime/llm-observability.js';
|
|
|
3
3
|
import { ProviderError } from '../types/errors.js';
|
|
4
4
|
import { OpenAICompatProvider } from './openai-compat.js';
|
|
5
5
|
import { toOpenAITools } from './tool-formats.js';
|
|
6
|
-
import { summarizeError
|
|
6
|
+
import { summarizeError } from '../utils/error-display.js';
|
|
7
|
+
import { getErrorStatus, normalizeProviderError } from './provider-error.js';
|
|
7
8
|
import { mapOllamaStopReason } from './stop-reason-maps.js';
|
|
8
9
|
import { instrumentedFetch } from '../utils/fetch-with-timeout.js';
|
|
9
10
|
export class OllamaProvider {
|
|
@@ -347,35 +348,13 @@ async function buildHttpError(prefix, response, provider, operation, phase) {
|
|
|
347
348
|
}
|
|
348
349
|
function shouldFallbackFromNative(err) {
|
|
349
350
|
const status = getErrorStatus(err);
|
|
350
|
-
const message =
|
|
351
|
+
const message = summarizeError(err);
|
|
351
352
|
if (status === 404 || status === 405 || status === 501)
|
|
352
353
|
return true;
|
|
353
354
|
if (status === 400 && /tool|messages|unsupported/i.test(message))
|
|
354
355
|
return true;
|
|
355
356
|
return /not implemented|unsupported|unknown endpoint/i.test(message);
|
|
356
357
|
}
|
|
357
|
-
function getErrorStatus(err) {
|
|
358
|
-
if (err && typeof err === 'object') {
|
|
359
|
-
const record = err;
|
|
360
|
-
if (typeof record.status === 'number')
|
|
361
|
-
return record.status;
|
|
362
|
-
if (typeof record.statusCode === 'number')
|
|
363
|
-
return record.statusCode;
|
|
364
|
-
}
|
|
365
|
-
return undefined;
|
|
366
|
-
}
|
|
367
|
-
function getErrorMessage(err) {
|
|
368
|
-
return summarizeError(err);
|
|
369
|
-
}
|
|
370
|
-
function normalizeProviderError(err, provider, operation, phase = 'request') {
|
|
371
|
-
const status = getErrorStatus(err);
|
|
372
|
-
return toProviderError(err, {
|
|
373
|
-
...(status !== undefined ? { statusCode: status } : {}),
|
|
374
|
-
provider,
|
|
375
|
-
operation,
|
|
376
|
-
phase,
|
|
377
|
-
});
|
|
378
|
-
}
|
|
379
358
|
function toRecord(value) {
|
|
380
359
|
return value && typeof value === 'object' ? value : {};
|
|
381
360
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/openai-codex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EAGX,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AAMxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-codex.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/openai-codex.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EAGX,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AAMxB,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AA8ItE,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,YAAY,CAAC,CA2PvB;AAED,qBAAa,mBAAoB,YAAW,WAAW;IAKnD,OAAO,CAAC,QAAQ,CAAC,mBAAmB;IAJtC,QAAQ,CAAC,IAAI,uBAA8B;IAC3C,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,CAAM;gBAGZ,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,EAAE,KAAK,GAAG,kBAAkB,GAAG,oBAAoB,CAAC;IAG9G,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAgBhD,eAAe,CAAC,IAAI,EAAE,2BAA2B,GAAG,OAAO,CAAC,uBAAuB,CAAC;CAgC3F"}
|
|
@@ -7,6 +7,7 @@ import { instrumentedLlmCall } from '../runtime/llm-observability.js';
|
|
|
7
7
|
import { mapCodexStopReason } from './stop-reason-maps.js';
|
|
8
8
|
import { instrumentedFetch } from '../utils/fetch-with-timeout.js';
|
|
9
9
|
import { parseToolCallArguments } from './tool-formats.js';
|
|
10
|
+
import { SseLineBuffer } from './sse-line-buffer.js';
|
|
10
11
|
const OPENAI_CODEX_BASE_URL = 'https://chatgpt.com/backend-api';
|
|
11
12
|
const OPENAI_CODEX_PROVIDER_NAME = 'openai-subscriber';
|
|
12
13
|
function getOpenAICodexUserAgent() {
|
|
@@ -192,8 +193,7 @@ export async function chatWithOpenAICodex(accessToken, params) {
|
|
|
192
193
|
});
|
|
193
194
|
}
|
|
194
195
|
try {
|
|
195
|
-
const
|
|
196
|
-
let buffer = '';
|
|
196
|
+
const sseBuffer = new SseLineBuffer();
|
|
197
197
|
let text = '';
|
|
198
198
|
const toolStarts = new Map();
|
|
199
199
|
const toolItemIds = new Map();
|
|
@@ -346,10 +346,7 @@ export async function chatWithOpenAICodex(accessToken, params) {
|
|
|
346
346
|
break;
|
|
347
347
|
if (!value)
|
|
348
348
|
continue;
|
|
349
|
-
|
|
350
|
-
const lines = buffer.split(/\r?\n/);
|
|
351
|
-
buffer = lines.pop() ?? '';
|
|
352
|
-
for (const rawLine of lines) {
|
|
349
|
+
for (const rawLine of sseBuffer.feed(value)) {
|
|
353
350
|
const line = rawLine.trim();
|
|
354
351
|
if (!line.startsWith('data: '))
|
|
355
352
|
continue;
|
|
@@ -359,9 +356,11 @@ export async function chatWithOpenAICodex(accessToken, params) {
|
|
|
359
356
|
handleDataPayload(data);
|
|
360
357
|
}
|
|
361
358
|
}
|
|
362
|
-
const
|
|
363
|
-
|
|
364
|
-
|
|
359
|
+
for (const rawLine of sseBuffer.flush()) {
|
|
360
|
+
const line = rawLine.trim();
|
|
361
|
+
if (!line.startsWith('data: '))
|
|
362
|
+
continue;
|
|
363
|
+
const data = line.slice(6).trim();
|
|
365
364
|
if (data && data !== '[DONE]') {
|
|
366
365
|
handleDataPayload(data);
|
|
367
366
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/openai-compat.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,YAAY,EAEZ,wBAAwB,EACxB,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC5B,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-compat.d.ts","sourceRoot":"","sources":["../../../src/platform/providers/openai-compat.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,7 +2,9 @@ import OpenAI from 'openai';
|
|
|
2
2
|
import { ProviderError } from '../types/errors.js';
|
|
3
3
|
import { withRetry } from '../utils/retry.js';
|
|
4
4
|
import { instrumentedLlmCall } from '../runtime/llm-observability.js';
|
|
5
|
-
import { toOpenAITools, toOpenAIMessages,
|
|
5
|
+
import { toOpenAITools, toOpenAIMessages, } from './tool-formats.js';
|
|
6
|
+
import { accumOpenAIToolCall, finalizeOpenAIToolCalls, applyOpenAIChunkUsage, resolveOpenAIToolCallsAndFallback } from './openai-stream-helpers.js';
|
|
7
|
+
import { resolveCompletedStopReason, withProviderStopReason } from './provider-stop-reason.js';
|
|
6
8
|
import { getCacheCapability } from './cache-capability.js';
|
|
7
9
|
import { extractOpenAIStreamTextDelta } from './openai-stream-delta.js';
|
|
8
10
|
import { logger } from '../utils/logger.js';
|
|
@@ -324,20 +326,7 @@ export class OpenAICompatProvider {
|
|
|
324
326
|
// Accumulate streaming tool_calls deltas
|
|
325
327
|
if (delta?.tool_calls) {
|
|
326
328
|
for (const tc of delta.tool_calls) {
|
|
327
|
-
|
|
328
|
-
if (!accToolCalls.has(idx)) {
|
|
329
|
-
accToolCalls.set(idx, { id: tc.id ?? '', name: tc.function?.name ?? '', args: '' });
|
|
330
|
-
}
|
|
331
|
-
const entry = accToolCalls.get(idx);
|
|
332
|
-
if (tc.id)
|
|
333
|
-
entry.id = tc.id;
|
|
334
|
-
if (tc.function?.name)
|
|
335
|
-
entry.name = tc.function.name;
|
|
336
|
-
if (tc.function?.arguments)
|
|
337
|
-
entry.args += tc.function.arguments;
|
|
338
|
-
if (onDelta) {
|
|
339
|
-
onDelta({ toolCalls: [{ index: idx, id: tc.id, name: tc.function?.name, arguments: tc.function?.arguments }] });
|
|
340
|
-
}
|
|
329
|
+
accumOpenAIToolCall(accToolCalls, tc, onDelta);
|
|
341
330
|
}
|
|
342
331
|
}
|
|
343
332
|
const finishReason = raw.choices[0]?.finish_reason;
|
|
@@ -345,20 +334,9 @@ export class OpenAICompatProvider {
|
|
|
345
334
|
rawStopReason = finishReason;
|
|
346
335
|
stopReason = mapOpenAIStopReason(finishReason);
|
|
347
336
|
}
|
|
348
|
-
|
|
349
|
-
const rawUsage = raw.usage;
|
|
350
|
-
inputTokens = rawUsage.prompt_tokens ?? 0;
|
|
351
|
-
outputTokens = rawUsage.completion_tokens ?? 0;
|
|
352
|
-
cacheReadTokens = rawUsage.prompt_tokens_details?.cached_tokens ?? cacheReadTokens;
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
for (const [, tc] of [...accToolCalls.entries()].sort(([a], [b]) => a - b)) {
|
|
356
|
-
rawToolCalls.push({
|
|
357
|
-
id: tc.id,
|
|
358
|
-
type: 'function',
|
|
359
|
-
function: { name: tc.name, arguments: tc.args },
|
|
360
|
-
});
|
|
337
|
+
({ inputTokens, outputTokens, cacheReadTokens } = applyOpenAIChunkUsage(raw.usage, { inputTokens, outputTokens, cacheReadTokens }));
|
|
361
338
|
}
|
|
339
|
+
rawToolCalls = finalizeOpenAIToolCalls(accToolCalls);
|
|
362
340
|
}
|
|
363
341
|
catch (err) {
|
|
364
342
|
const diagnostic = extractOpenAICompatErrorDiagnostic(err);
|
|
@@ -393,16 +371,11 @@ export class OpenAICompatProvider {
|
|
|
393
371
|
// Some models (e.g. kimi-k2-thinking via ollama-cloud) emit tool calls as
|
|
394
372
|
// raw text tokens instead of the OpenAI function-calling wire format.
|
|
395
373
|
// Fall back to text extraction when no structured tool calls were found.
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
responseText = extracted.cleanedContent;
|
|
402
|
-
stopReason = 'tool_call';
|
|
403
|
-
rawStopReason = rawStopReason ?? 'tool_calls';
|
|
404
|
-
}
|
|
405
|
-
}
|
|
374
|
+
const resolved = resolveOpenAIToolCallsAndFallback(rawToolCalls, responseText, stopReason, rawStopReason);
|
|
375
|
+
const toolCalls = resolved.toolCalls;
|
|
376
|
+
responseText = resolved.responseText;
|
|
377
|
+
stopReason = resolved.stopReason;
|
|
378
|
+
rawStopReason = resolved.rawStopReason;
|
|
406
379
|
const response = {
|
|
407
380
|
content: responseText,
|
|
408
381
|
toolCalls,
|
|
@@ -411,8 +384,8 @@ export class OpenAICompatProvider {
|
|
|
411
384
|
outputTokens,
|
|
412
385
|
...(cacheReadTokens > 0 ? { cacheReadTokens } : {}),
|
|
413
386
|
},
|
|
414
|
-
stopReason: stopReason
|
|
415
|
-
...(rawStopReason
|
|
387
|
+
stopReason: resolveCompletedStopReason(stopReason, responseText),
|
|
388
|
+
...withProviderStopReason(rawStopReason),
|
|
416
389
|
};
|
|
417
390
|
if (reasoningSummaryText) {
|
|
418
391
|
response.reasoningSummary = reasoningSummaryText;
|