@hyav/pi-provider 0.1.8 → 0.2.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 +11 -0
- package/README.md +5 -5
- package/README.zh-CN.md +5 -5
- package/core/adapter-extensions.ts +9 -2
- package/core/adapter-protocol.ts +4 -2
- package/core/catalog-preflight.ts +14 -1
- package/core/host.ts +43 -75
- package/core/model-catalog.ts +13 -1
- package/core/opencode-preflight.ts +6 -0
- package/core/pi-model-metadata.ts +739 -0
- package/core/provider-registration.ts +75 -78
- package/core/public-adapters.ts +9 -1
- package/core/runtime-config.ts +18 -38
- package/core/runtime-entry.ts +11 -6
- package/core/runtime.ts +24 -104
- package/core/status-report.ts +316 -236
- package/core/types.ts +28 -19
- package/index.ts +30 -21
- package/package.json +3 -1
- package/preflight/charm-hyper.ts +6 -2
- package/preflight/deepseek.ts +10 -1
- package/preflight/github-copilot.ts +4 -0
- package/preflight/google.ts +10 -1
- package/preflight/groq.ts +10 -1
- package/preflight/openai-codex.ts +10 -1
- package/preflight/openrouter.ts +11 -2
- package/preflight/vercel-ai-gateway.ts +11 -1
- package/preflight/xai.ts +18 -4
- package/providers/charm-hyper/oauth.ts +17 -11
- package/providers/charm-hyper.ts +26 -12
- package/status/huggingface.ts +2 -1
- package/status/openrouter.ts +8 -2
- package/status/vercel-ai-gateway.ts +1 -1
- package/core/official-pricing.ts +0 -923
package/core/runtime.ts
CHANGED
|
@@ -1,21 +1,14 @@
|
|
|
1
1
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
|
-
import type
|
|
3
|
-
import { validatePiProviderDefinition } from "./definition.ts";
|
|
2
|
+
import { type PiProviderDefinition, validatePiProviderDefinition } from "./definition.ts";
|
|
4
3
|
import { LiveCheckManager, type LiveCheckResult } from "./live-check-manager.ts";
|
|
5
4
|
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
} from "./
|
|
12
|
-
import
|
|
13
|
-
import { PreflightManager } from "./preflight-manager.ts";
|
|
14
|
-
import {
|
|
15
|
-
cancelDeferredProviderRegistrations,
|
|
16
|
-
refreshProviderRegistrations,
|
|
17
|
-
registerProviderAdapter,
|
|
18
|
-
} from "./provider-registration.ts";
|
|
5
|
+
createEmptyCatalogSnapshot,
|
|
6
|
+
loadPiCatalog,
|
|
7
|
+
type PiCatalogSnapshot,
|
|
8
|
+
toPiCatalogSnapshot,
|
|
9
|
+
} from "./pi-model-metadata.ts";
|
|
10
|
+
import { type PreflightContextLike, PreflightManager } from "./preflight-manager.ts";
|
|
11
|
+
import { cancelDeferredProviderRegistrations, registerProviderAdapter } from "./provider-registration.ts";
|
|
19
12
|
import type { PiProviderDependencies, PiProviderLoader } from "./runtime-config.ts";
|
|
20
13
|
import { resolvePiProviderDependencies } from "./runtime-config.ts";
|
|
21
14
|
import type { StatusContextLike } from "./status-manager.ts";
|
|
@@ -30,7 +23,6 @@ import {
|
|
|
30
23
|
} from "./status-report.ts";
|
|
31
24
|
import { applyTunerAdapters, sortTunerAdapters } from "./tuner-manager.ts";
|
|
32
25
|
import type {
|
|
33
|
-
ModelMetadataStatus,
|
|
34
26
|
ProviderAdapter,
|
|
35
27
|
ProviderCost,
|
|
36
28
|
ProviderModelDraft,
|
|
@@ -116,7 +108,9 @@ export function scheduleModelCatalogRefresh(ctx: Pick<ExtensionContext, "modelRe
|
|
|
116
108
|
|
|
117
109
|
export interface PiProviderRuntimeController {
|
|
118
110
|
resetForSession(): void;
|
|
119
|
-
|
|
111
|
+
/** @deprecated Kept for backwards compatibility. */
|
|
112
|
+
updateOfficialPricing?(snapshot: Record<string, unknown>): void;
|
|
113
|
+
updatePiCatalog?(snapshot: PiCatalogSnapshot): void;
|
|
120
114
|
shutdown(): void;
|
|
121
115
|
clearStatusPresentation(ctx: Pick<ExtensionContext, "ui">): void;
|
|
122
116
|
applyTunerPayload(payload: unknown, model: ActiveModel): unknown | undefined | Promise<unknown | undefined>;
|
|
@@ -135,23 +129,6 @@ function cloneProviderCost(cost: ProviderCost): ProviderCost {
|
|
|
135
129
|
};
|
|
136
130
|
}
|
|
137
131
|
|
|
138
|
-
function getOfficialMetadataStatus(
|
|
139
|
-
snapshot: Record<string, OfficialModelMeta>,
|
|
140
|
-
runtime: PiProviderDependencies,
|
|
141
|
-
): ModelMetadataStatus | undefined {
|
|
142
|
-
const source = runtime.officialPricingUrl === OPENROUTER_MODELS_URL ? "AA/OpenRouter" : "Official metadata";
|
|
143
|
-
if (!runtime.enableOfficialPricingFallback && Object.keys(snapshot).length === 0) return undefined;
|
|
144
|
-
if (Object.keys(snapshot).length === 0) return { state: "unavailable", source };
|
|
145
|
-
const now = runtime.now();
|
|
146
|
-
const age = getPricingCacheAge(runtime.officialPricingUrl, now);
|
|
147
|
-
const updatedAt = age === undefined ? now : now - age;
|
|
148
|
-
return {
|
|
149
|
-
state: age !== undefined && age >= runtime.officialPricingCacheTtlMs ? "stale" : "fresh",
|
|
150
|
-
updatedAt,
|
|
151
|
-
source,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
|
|
155
132
|
function hasKnownNativeCost(cost: ProviderCost | undefined): cost is ProviderCost {
|
|
156
133
|
if (!cost) return false;
|
|
157
134
|
return (
|
|
@@ -164,12 +141,7 @@ function hasKnownNativeCost(cost: ProviderCost | undefined): cost is ProviderCos
|
|
|
164
141
|
}
|
|
165
142
|
|
|
166
143
|
/** Build report-only metadata; never merge external fields into Pi's native model. */
|
|
167
|
-
function getNativeModelMetadata(
|
|
168
|
-
model: ActiveModel,
|
|
169
|
-
officialPricing: Record<string, OfficialModelMeta>,
|
|
170
|
-
): ProviderModelMetadata {
|
|
171
|
-
const officialMeta =
|
|
172
|
-
findOfficialMeta(`${model.provider}/${model.id}`, officialPricing) ?? findOfficialMeta(model.id, officialPricing);
|
|
144
|
+
function getNativeModelMetadata(model: ActiveModel): ProviderModelMetadata {
|
|
173
145
|
const knownPrice = hasKnownNativeCost(model.cost);
|
|
174
146
|
return {
|
|
175
147
|
pricing: {
|
|
@@ -187,14 +159,6 @@ function getNativeModelMetadata(
|
|
|
187
159
|
reasoning: "native",
|
|
188
160
|
thinkingLevelMap: model.thinkingLevelMap === undefined ? "default" : "native",
|
|
189
161
|
},
|
|
190
|
-
...(officialMeta?.quality
|
|
191
|
-
? {
|
|
192
|
-
quality: officialMeta.quality.map((score) => ({
|
|
193
|
-
...score,
|
|
194
|
-
...(score.confidenceInterval ? { confidenceInterval: { ...score.confidenceInterval } } : {}),
|
|
195
|
-
})),
|
|
196
|
-
}
|
|
197
|
-
: {}),
|
|
198
162
|
};
|
|
199
163
|
}
|
|
200
164
|
|
|
@@ -202,7 +166,7 @@ export function installPiProviderRuntime(
|
|
|
202
166
|
pi: ExtensionAPI,
|
|
203
167
|
runtime: PiProviderDependencies,
|
|
204
168
|
definition: PiProviderDefinition,
|
|
205
|
-
|
|
169
|
+
piCatalogSnapshot: PiCatalogSnapshot | Record<string, unknown> = {},
|
|
206
170
|
options: {
|
|
207
171
|
registerHandlers?: boolean;
|
|
208
172
|
providerDrafts?: ReadonlyMap<ProviderAdapter, ProviderModelDraft[]>;
|
|
@@ -210,20 +174,20 @@ export function installPiProviderRuntime(
|
|
|
210
174
|
): PiProviderRuntimeController {
|
|
211
175
|
validatePiProviderDefinition(definition);
|
|
212
176
|
const registerHandlers = options.registerHandlers ?? true;
|
|
213
|
-
let
|
|
214
|
-
let currentOfficialMetadataStatus = getOfficialMetadataStatus(officialPricing, runtime);
|
|
177
|
+
let currentPiCatalog: PiCatalogSnapshot = toPiCatalogSnapshot(piCatalogSnapshot) ?? createEmptyCatalogSnapshot();
|
|
215
178
|
const providers = [...definition.providers].sort(compareAdapterIds);
|
|
216
179
|
const statuses = [...(definition.statuses ?? [])].sort(compareAdapterIds);
|
|
217
180
|
const preflights = [...(definition.preflights ?? [])].sort(compareAdapterIds);
|
|
218
181
|
const tuners = sortTunerAdapters(definition.tuners ?? []);
|
|
219
182
|
|
|
220
183
|
for (const adapter of providers) {
|
|
221
|
-
registerProviderAdapter(pi, adapter, runtime,
|
|
184
|
+
registerProviderAdapter(pi, adapter, runtime, currentPiCatalog, options.providerDrafts?.get(adapter));
|
|
222
185
|
}
|
|
223
186
|
|
|
224
187
|
const statusManager = new StatusManager(statuses, runtime.fetch, runtime.now);
|
|
225
188
|
const preflightManager = new PreflightManager(preflights, runtime.fetch, runtime.now);
|
|
226
189
|
const liveCheckManager = new LiveCheckManager(runtime.liveCheckRequestTimeoutMs, runtime.fetch, runtime.now);
|
|
190
|
+
|
|
227
191
|
let lifecycleGeneration = 0;
|
|
228
192
|
let statusPresentationGeneration = 0;
|
|
229
193
|
let statusPresentationVisible = false;
|
|
@@ -239,10 +203,9 @@ export function installPiProviderRuntime(
|
|
|
239
203
|
const native = resolveNativeProvider(createNativeProviderRegistry(ctx.modelRegistry), model.provider);
|
|
240
204
|
return {
|
|
241
205
|
provider,
|
|
242
|
-
metadataStatus: currentOfficialMetadataStatus,
|
|
243
206
|
modelMetadata:
|
|
244
207
|
provider?.registration?.modelMetadata?.[model.id] ??
|
|
245
|
-
(provider === undefined ? getNativeModelMetadata(model
|
|
208
|
+
(provider === undefined ? getNativeModelMetadata(model) : undefined),
|
|
246
209
|
status: statuses.find(({ providerId }) => providerId === model.provider),
|
|
247
210
|
preflight: preflights.find(({ providerId }) => providerId === model.provider),
|
|
248
211
|
nativeProvider: native.provider,
|
|
@@ -283,7 +246,6 @@ export function installPiProviderRuntime(
|
|
|
283
246
|
nativeLookupAvailable,
|
|
284
247
|
nativePreflight,
|
|
285
248
|
auth,
|
|
286
|
-
metadataStatus,
|
|
287
249
|
} = getStatusDetails(model, ctx);
|
|
288
250
|
const diagnostics = status ? statusManager.getDiagnostics(model.provider) : undefined;
|
|
289
251
|
const preflightDiagnostics = preflightManager.getDiagnostics(model.provider, model.id);
|
|
@@ -309,7 +271,6 @@ export function installPiProviderRuntime(
|
|
|
309
271
|
liveCheckDiagnostics?.pending === true ||
|
|
310
272
|
liveCheckDiagnostics?.lastError !== undefined),
|
|
311
273
|
modelMetadata,
|
|
312
|
-
metadataStatus,
|
|
313
274
|
},
|
|
314
275
|
);
|
|
315
276
|
const message = report.report;
|
|
@@ -423,8 +384,10 @@ export function installPiProviderRuntime(
|
|
|
423
384
|
const controller: PiProviderRuntimeController = {
|
|
424
385
|
resetForSession,
|
|
425
386
|
updateOfficialPricing(snapshot) {
|
|
426
|
-
|
|
427
|
-
|
|
387
|
+
currentPiCatalog = toPiCatalogSnapshot(snapshot) ?? createEmptyCatalogSnapshot();
|
|
388
|
+
},
|
|
389
|
+
updatePiCatalog(snapshot) {
|
|
390
|
+
currentPiCatalog = toPiCatalogSnapshot(snapshot) ?? createEmptyCatalogSnapshot();
|
|
428
391
|
},
|
|
429
392
|
shutdown,
|
|
430
393
|
clearStatusPresentation,
|
|
@@ -464,52 +427,9 @@ export function createPiProviderRuntime(
|
|
|
464
427
|
): (pi: ExtensionAPI) => Promise<void> {
|
|
465
428
|
const runtime = resolvePiProviderDependencies(dependencies);
|
|
466
429
|
return async (pi) => {
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
let pricingRefreshController: AbortController | undefined;
|
|
470
|
-
const cachePath =
|
|
471
|
-
runtime.officialPricingUrl === OPENROUTER_MODELS_URL ? runtime.openRouterMetadataCachePath : undefined;
|
|
472
|
-
const fetchMetadata = (options: { allowNetwork?: boolean; signal?: AbortSignal } = {}) =>
|
|
473
|
-
fetchOfficialModelMetadata(
|
|
474
|
-
runtime.fetch,
|
|
475
|
-
runtime.officialPricingUrl,
|
|
476
|
-
runtime.officialPricingTimeoutMs,
|
|
477
|
-
runtime.officialPricingCacheTtlMs,
|
|
478
|
-
runtime.officialPricingMaxStaleMs,
|
|
479
|
-
runtime.now,
|
|
480
|
-
{ cachePath, ...options },
|
|
481
|
-
);
|
|
482
|
-
const officialPricingPromise = runtime.enableOfficialPricingFallback
|
|
483
|
-
? fetchMetadata({ allowNetwork: false })
|
|
484
|
-
: Promise.resolve({});
|
|
485
|
-
const definitionPromise = loadDefinition(runtime);
|
|
486
|
-
const [officialPricing, definition] = await Promise.all([officialPricingPromise, definitionPromise]);
|
|
430
|
+
const piCatalog = await loadPiCatalog({ fetch: runtime.fetch }).catch(() => ({ models: {}, providers: {} }));
|
|
431
|
+
const definition = await loadDefinition(runtime);
|
|
487
432
|
validatePiProviderDefinition(definition);
|
|
488
|
-
|
|
489
|
-
pi.on("session_start", () => {
|
|
490
|
-
pricingRefreshController?.abort();
|
|
491
|
-
pricingRefreshController = undefined;
|
|
492
|
-
if (!runtime.enableOfficialPricingFallback || disposed) {
|
|
493
|
-
return;
|
|
494
|
-
}
|
|
495
|
-
const controller = new AbortController();
|
|
496
|
-
pricingRefreshController = controller;
|
|
497
|
-
void fetchMetadata({ signal: controller.signal })
|
|
498
|
-
.then((snapshot) => {
|
|
499
|
-
if (disposed || controller.signal.aborted) return;
|
|
500
|
-
installedController?.updateOfficialPricing?.(snapshot);
|
|
501
|
-
refreshProviderRegistrations(pi, definition.providers, runtime, snapshot);
|
|
502
|
-
})
|
|
503
|
-
.catch(() => undefined)
|
|
504
|
-
.finally(() => {
|
|
505
|
-
if (pricingRefreshController === controller) pricingRefreshController = undefined;
|
|
506
|
-
});
|
|
507
|
-
});
|
|
508
|
-
pi.on("session_shutdown", () => {
|
|
509
|
-
disposed = true;
|
|
510
|
-
pricingRefreshController?.abort();
|
|
511
|
-
pricingRefreshController = undefined;
|
|
512
|
-
});
|
|
513
|
-
installedController = installPiProviderRuntime(pi, runtime, definition, officialPricing);
|
|
433
|
+
installPiProviderRuntime(pi, runtime, definition, piCatalog);
|
|
514
434
|
};
|
|
515
435
|
}
|