pi2dsh 0.14.0 → 0.15.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/dist/{analyzer-DPZ8LzSt.mjs → analyzer-er3QPDc0.mjs} +2 -2
- package/dist/{analyzer-DPZ8LzSt.mjs.map → analyzer-er3QPDc0.mjs.map} +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/{compatibility-CP2tpyhg.mjs → compatibility-DH_Gi96X.mjs} +6 -6
- package/dist/{compatibility-CP2tpyhg.mjs.map → compatibility-DH_Gi96X.mjs.map} +1 -1
- package/dist/host.mjs +1 -1
- package/dist/index.mjs +3 -3
- package/dist/{runtime-Bb9Bfk4M.mjs → runtime-BN4E4OtI.mjs} +162 -38
- package/dist/runtime-BN4E4OtI.mjs.map +1 -0
- package/dist/runtime.d.mts +47 -1
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +2 -2
- package/package.json +1 -1
- package/dist/runtime-Bb9Bfk4M.mjs.map +0 -1
|
@@ -4025,9 +4025,7 @@ function subscribeLifecycle(ctx, state) {
|
|
|
4025
4025
|
}
|
|
4026
4026
|
}
|
|
4027
4027
|
});
|
|
4028
|
-
|
|
4029
|
-
const ownedSession = agentSession(state.ownerAgent);
|
|
4030
|
-
if (ownedSession !== void 0 ? session !== ownedSession : isSubagentOrigin(session)) return;
|
|
4028
|
+
const projectSessionEvent = (session, event) => {
|
|
4031
4029
|
const agent = [...state.activeAgents].find((candidate) => candidate.session === session);
|
|
4032
4030
|
const eventContext = contextFor(ctx, state, agent, void 0);
|
|
4033
4031
|
const type = event.type;
|
|
@@ -4174,6 +4172,14 @@ function subscribeLifecycle(ctx, state) {
|
|
|
4174
4172
|
}, eventContext);
|
|
4175
4173
|
await dispatch(state, "agent_settled", { type: "agent_settled" }, eventContext);
|
|
4176
4174
|
}).catch((error) => warn("turn end lifecycle", error));
|
|
4175
|
+
};
|
|
4176
|
+
state.projectSessionEvent = projectSessionEvent;
|
|
4177
|
+
cordis.on("session/event", (session, event) => {
|
|
4178
|
+
if (state.hostAnchor) return;
|
|
4179
|
+
const ownedSession = agentSession(state.ownerAgent);
|
|
4180
|
+
if (ownedSession !== void 0 ? session !== ownedSession : isSubagentOrigin(session)) return;
|
|
4181
|
+
if (ownedSession !== void 0 && state.sessionEventsLive !== true) return;
|
|
4182
|
+
projectSessionEvent(session, event);
|
|
4177
4183
|
});
|
|
4178
4184
|
cordis.on("agent/request", async (payload, next) => {
|
|
4179
4185
|
const config = await next();
|
|
@@ -4208,7 +4214,7 @@ function subscribeLifecycle(ctx, state) {
|
|
|
4208
4214
|
for (const dispose of state.toolDisposers.values()) dispose();
|
|
4209
4215
|
state.toolDisposers.clear();
|
|
4210
4216
|
for (const provider of [...state.ownedProviderRoutes]) releaseSharedProviderRoute(state, provider);
|
|
4211
|
-
state.
|
|
4217
|
+
for (const off of state.eventBusOffs.splice(0)) off();
|
|
4212
4218
|
}, "pi2dsh session shutdown");
|
|
4213
4219
|
}
|
|
4214
4220
|
async function flushPendingSessionStarts(ctx, state) {
|
|
@@ -4226,6 +4232,22 @@ async function flushPendingSessionStarts(ctx, state) {
|
|
|
4226
4232
|
const pending = [...state.pendingSessionStarts];
|
|
4227
4233
|
state.pendingSessionStarts.clear();
|
|
4228
4234
|
for (const [agent, reason] of pending) await startPiSession(ctx, state, agent, reason, void 0);
|
|
4235
|
+
if (state.ownerAgent !== void 0 && state.projectSessionEvent !== void 0) {
|
|
4236
|
+
const session = agentSession(state.ownerAgent);
|
|
4237
|
+
if (session !== void 0) {
|
|
4238
|
+
const events = session.events ?? [];
|
|
4239
|
+
let from = -1;
|
|
4240
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
4241
|
+
if (events[index].type === "turn/end") break;
|
|
4242
|
+
if (events[index].type === "turn/start") {
|
|
4243
|
+
from = index;
|
|
4244
|
+
break;
|
|
4245
|
+
}
|
|
4246
|
+
}
|
|
4247
|
+
if (from >= 0) for (let index = from; index < events.length; index += 1) state.projectSessionEvent(session, events[index]);
|
|
4248
|
+
}
|
|
4249
|
+
state.sessionEventsLive = true;
|
|
4250
|
+
}
|
|
4229
4251
|
}
|
|
4230
4252
|
/**
|
|
4231
4253
|
* Start freshly reloaded extension handlers in every live Pi host session.
|
|
@@ -4589,15 +4611,113 @@ function oauthStoreOf(state) {
|
|
|
4589
4611
|
const COMPANION_ROUTE_PREFIX = "pi2dsh-companion/";
|
|
4590
4612
|
const SHARED_HOST_STATE = /* @__PURE__ */ new WeakMap();
|
|
4591
4613
|
/**
|
|
4592
|
-
*
|
|
4593
|
-
*
|
|
4594
|
-
*
|
|
4595
|
-
*
|
|
4596
|
-
*
|
|
4597
|
-
*
|
|
4598
|
-
* the
|
|
4614
|
+
* Pi's provider ledger is layered, not flat (model-runtime.ts:742-786 at the
|
|
4615
|
+
* pinned upstream): a builtin base map, an extension overlay where defined
|
|
4616
|
+
* fields merge over the base (undefined fields expose the base — a package
|
|
4617
|
+
* overriding only baseUrl keeps the builtin OAuth flow), later registrations
|
|
4618
|
+
* overriding earlier ones, and unregistration restoring the builtin. These
|
|
4619
|
+
* helpers vendor that contract for the shared host ledger. One deliberate
|
|
4620
|
+
* adaptation: the overlay is slotted per PACKAGE and folded in package
|
|
4621
|
+
* first-registration order, because in Pi "last wins" is load order (each
|
|
4622
|
+
* session rebuilds the runtime so registration order is always load order),
|
|
4623
|
+
* while our host ledger accumulates across sessions — folding raw arrival
|
|
4624
|
+
* order would let a later agent's re-registration of package A overturn
|
|
4625
|
+
* package B for no Pi-semantic reason.
|
|
4599
4626
|
*/
|
|
4600
|
-
|
|
4627
|
+
function mergeProviderRegistration(previous, config) {
|
|
4628
|
+
const effective = { ...previous };
|
|
4629
|
+
for (const [key, value] of Object.entries(config)) if (value !== void 0) effective[key] = value;
|
|
4630
|
+
return effective;
|
|
4631
|
+
}
|
|
4632
|
+
function overlayProviderConfig(base, overlay) {
|
|
4633
|
+
const merged = { ...base };
|
|
4634
|
+
for (const [key, value] of Object.entries(overlay)) if (value !== void 0) merged[key] = value;
|
|
4635
|
+
const baseModels = base?.models;
|
|
4636
|
+
if (overlay.models === void 0 && typeof overlay.baseUrl === "string" && Array.isArray(baseModels)) merged.models = baseModels.map((entry) => typeof entry === "object" && entry !== null ? {
|
|
4637
|
+
...entry,
|
|
4638
|
+
baseUrl: overlay.baseUrl
|
|
4639
|
+
} : entry);
|
|
4640
|
+
return merged;
|
|
4641
|
+
}
|
|
4642
|
+
/** Structural fingerprint used to decide whether a recomposition actually
|
|
4643
|
+
* changed the canonical shape. Function identities differ on every factory
|
|
4644
|
+
* run (each agent instance registers fresh closures), so functions compare
|
|
4645
|
+
* by presence — behaviourally equivalent re-registrations keep the existing
|
|
4646
|
+
* canonical reference and the route built on it, exactly like today. */
|
|
4647
|
+
function providerFingerprint(config) {
|
|
4648
|
+
if (config === void 0) return "absent";
|
|
4649
|
+
return JSON.stringify(config, (_key, value) => typeof value === "function" ? "[function]" : value);
|
|
4650
|
+
}
|
|
4651
|
+
function recordPackageProviderRegistration(shared, packageName, name, value) {
|
|
4652
|
+
shared.providerPackages ??= /* @__PURE__ */ new Map();
|
|
4653
|
+
shared.providerPackageOrder ??= [];
|
|
4654
|
+
if (!shared.providerPackageOrder.includes(packageName)) shared.providerPackageOrder.push(packageName);
|
|
4655
|
+
let slots = shared.providerPackages.get(name);
|
|
4656
|
+
if (slots === void 0) {
|
|
4657
|
+
slots = /* @__PURE__ */ new Map();
|
|
4658
|
+
shared.providerPackages.set(name, slots);
|
|
4659
|
+
}
|
|
4660
|
+
slots.set(packageName, mergeProviderRegistration(slots.get(packageName), value));
|
|
4661
|
+
}
|
|
4662
|
+
/** Rebuild the canonical entry for one provider id from builtin + package
|
|
4663
|
+
* slots. Returns whether the composed shape changed (callers retire the
|
|
4664
|
+
* route on change so it is rebuilt from the new canonical). */
|
|
4665
|
+
function recomposeSharedProvider(shared, name) {
|
|
4666
|
+
const builtin = shared.providerBuiltins?.get(name);
|
|
4667
|
+
const slots = shared.providerPackages?.get(name);
|
|
4668
|
+
let canonical;
|
|
4669
|
+
if (slots === void 0 || slots.size === 0) canonical = builtin;
|
|
4670
|
+
else {
|
|
4671
|
+
canonical = { ...builtin ?? {} };
|
|
4672
|
+
for (const packageName of shared.providerPackageOrder ?? []) {
|
|
4673
|
+
const registration = slots.get(packageName);
|
|
4674
|
+
if (registration !== void 0) canonical = overlayProviderConfig(canonical, registration);
|
|
4675
|
+
}
|
|
4676
|
+
}
|
|
4677
|
+
if (!(providerFingerprint(shared.providers.get(name)) !== providerFingerprint(canonical))) return false;
|
|
4678
|
+
if (canonical === void 0) shared.providers.delete(name);
|
|
4679
|
+
else shared.providers.set(name, canonical);
|
|
4680
|
+
return true;
|
|
4681
|
+
}
|
|
4682
|
+
/** Force-retire a provider's route regardless of refcounts: the canonical
|
|
4683
|
+
* definition changed, so a route built on the old shape must not serve it. */
|
|
4684
|
+
function retireSharedProviderRoute(shared, name) {
|
|
4685
|
+
const route = shared.providerRouteDisposers.get(name);
|
|
4686
|
+
if (route === void 0) return;
|
|
4687
|
+
shared.providerRouteDisposers.delete(name);
|
|
4688
|
+
shared.providerRouteOwners.delete(name);
|
|
4689
|
+
route();
|
|
4690
|
+
}
|
|
4691
|
+
function sharedEventBusFor(shared, ownerAgent) {
|
|
4692
|
+
if (ownerAgent === void 0) {
|
|
4693
|
+
if (shared.hostEventBus === void 0) {
|
|
4694
|
+
shared.hostEventBus = new EventEmitter();
|
|
4695
|
+
shared.hostEventBus.setMaxListeners(0);
|
|
4696
|
+
}
|
|
4697
|
+
return shared.hostEventBus;
|
|
4698
|
+
}
|
|
4699
|
+
shared.agentEventBuses ??= /* @__PURE__ */ new WeakMap();
|
|
4700
|
+
let bus = shared.agentEventBuses.get(ownerAgent);
|
|
4701
|
+
if (bus === void 0) {
|
|
4702
|
+
bus = new EventEmitter();
|
|
4703
|
+
bus.setMaxListeners(0);
|
|
4704
|
+
shared.agentEventBuses.set(ownerAgent, bus);
|
|
4705
|
+
}
|
|
4706
|
+
return bus;
|
|
4707
|
+
}
|
|
4708
|
+
function sharedThemeFor(shared, ownerAgent) {
|
|
4709
|
+
if (ownerAgent === void 0) {
|
|
4710
|
+
shared.hostTheme ??= new Theme();
|
|
4711
|
+
return shared.hostTheme;
|
|
4712
|
+
}
|
|
4713
|
+
shared.agentThemes ??= /* @__PURE__ */ new WeakMap();
|
|
4714
|
+
let theme = shared.agentThemes.get(ownerAgent);
|
|
4715
|
+
if (theme === void 0) {
|
|
4716
|
+
theme = new Theme();
|
|
4717
|
+
shared.agentThemes.set(ownerAgent, theme);
|
|
4718
|
+
}
|
|
4719
|
+
return theme;
|
|
4720
|
+
}
|
|
4601
4721
|
function sharedHostStateOf(ctx) {
|
|
4602
4722
|
const key = ctx.root ?? ctx;
|
|
4603
4723
|
let shared = SHARED_HOST_STATE.get(key);
|
|
@@ -5473,7 +5593,7 @@ function registerSharedProviderRoute(ctx, state, name, value) {
|
|
|
5473
5593
|
return existing;
|
|
5474
5594
|
}
|
|
5475
5595
|
const canonical = shared.providers.get(name) ?? value;
|
|
5476
|
-
shared.providers.set(name, canonical);
|
|
5596
|
+
if (!shared.providers.has(name)) shared.providers.set(name, canonical);
|
|
5477
5597
|
const route = registerPiProviderRoute({
|
|
5478
5598
|
llm: llmOf(ctx),
|
|
5479
5599
|
ctx,
|
|
@@ -5528,31 +5648,27 @@ function createPiApi(ctx, state) {
|
|
|
5528
5648
|
const name = typeof providerOrName === "string" ? providerOrName : String(providerOrName?.id ?? providerOrName?.name ?? "unnamed");
|
|
5529
5649
|
const value = typeof providerOrName === "string" ? config ?? {} : providerOrName;
|
|
5530
5650
|
state.providers.set(name, value);
|
|
5531
|
-
|
|
5532
|
-
if (
|
|
5533
|
-
|
|
5534
|
-
|
|
5535
|
-
const stale = state.shared.providerRouteDisposers.get(name);
|
|
5536
|
-
if (stale !== void 0) {
|
|
5537
|
-
state.shared.providerRouteDisposers.delete(name);
|
|
5538
|
-
state.shared.providerRouteOwners.delete(name);
|
|
5539
|
-
stale();
|
|
5540
|
-
}
|
|
5541
|
-
}
|
|
5542
|
-
}
|
|
5543
|
-
if (providerSupportsOAuth(value)) {
|
|
5651
|
+
recordPackageProviderRegistration(state.shared, state.packageName, name, value);
|
|
5652
|
+
if (recomposeSharedProvider(state.shared, name)) retireSharedProviderRoute(state.shared, name);
|
|
5653
|
+
const canonical = state.shared.providers.get(name) ?? value;
|
|
5654
|
+
if (providerSupportsOAuth(canonical)) {
|
|
5544
5655
|
ensureLoginCommand(ctx, state);
|
|
5545
5656
|
logger(ctx).info(`[pi2dsh] Pi provider ${JSON.stringify(name)} supports OAuth — log in with /login ${name}`);
|
|
5546
5657
|
}
|
|
5547
|
-
if (registerSharedProviderRoute(ctx, state, name,
|
|
5658
|
+
if (registerSharedProviderRoute(ctx, state, name, canonical) !== void 0) {
|
|
5548
5659
|
state.modelCatalog?.refresh();
|
|
5549
|
-
if (providerCarriesTransport(
|
|
5550
|
-
} else if (!providerSupportsOAuth(
|
|
5551
|
-
discoverProviderModels(ctx, state, name,
|
|
5660
|
+
if (providerCarriesTransport(canonical)) logger(ctx).info(`[pi2dsh] Pi provider ${JSON.stringify(name)} registered as a native DSH llm route`);
|
|
5661
|
+
} else if (!providerSupportsOAuth(canonical)) logger(ctx).info(`[pi2dsh] recorded Pi provider ${JSON.stringify(name)}; model calls stay on DSH llm adapters`);
|
|
5662
|
+
discoverProviderModels(ctx, state, name, canonical);
|
|
5552
5663
|
},
|
|
5553
5664
|
unregisterProvider(name) {
|
|
5554
5665
|
state.providers.delete(name);
|
|
5555
5666
|
releaseSharedProviderRoute(state, name);
|
|
5667
|
+
if ((state.shared.providerPackages?.get(name))?.delete(state.packageName) === true && recomposeSharedProvider(state.shared, name)) {
|
|
5668
|
+
retireSharedProviderRoute(state.shared, name);
|
|
5669
|
+
const restored = state.shared.providers.get(name);
|
|
5670
|
+
if (restored !== void 0) registerSharedProviderRoute(ctx, state, name, restored);
|
|
5671
|
+
}
|
|
5556
5672
|
},
|
|
5557
5673
|
registerMessageRenderer(customType, renderer) {
|
|
5558
5674
|
state.messageRenderers.set(customType, renderer);
|
|
@@ -5665,7 +5781,11 @@ function createPiApi(ctx, state) {
|
|
|
5665
5781
|
Promise.resolve(handler(data)).catch((error) => logger(ctx).warn(`[pi2dsh] package event ${channel} handler failed: ${String(error)}`));
|
|
5666
5782
|
};
|
|
5667
5783
|
state.eventBus.on(channel, safeHandler);
|
|
5668
|
-
|
|
5784
|
+
const off = () => {
|
|
5785
|
+
state.eventBus.off(channel, safeHandler);
|
|
5786
|
+
};
|
|
5787
|
+
state.eventBusOffs.push(off);
|
|
5788
|
+
return off;
|
|
5669
5789
|
}
|
|
5670
5790
|
}
|
|
5671
5791
|
};
|
|
@@ -5855,13 +5975,14 @@ async function applyPiPackage(ctx, options) {
|
|
|
5855
5975
|
pendingSessionStarts: /* @__PURE__ */ new Map(),
|
|
5856
5976
|
currentSystemPrompt: "",
|
|
5857
5977
|
messageSource: `pi2dsh:${options.manifest.package.name}`,
|
|
5858
|
-
eventBus:
|
|
5978
|
+
eventBus: sharedEventBusFor(shared, ownerAgent),
|
|
5979
|
+
eventBusOffs: [],
|
|
5859
5980
|
agentScope: new AsyncLocalStorage(),
|
|
5860
5981
|
llmBridge: void 0,
|
|
5861
5982
|
piAiRegistry: __createPiAiRuntimeRegistry(),
|
|
5862
5983
|
subagentSessionFactory: void 0,
|
|
5863
5984
|
bridge: new PiSessionBridge(),
|
|
5864
|
-
theme:
|
|
5985
|
+
theme: sharedThemeFor(shared, ownerAgent),
|
|
5865
5986
|
shortcuts: /* @__PURE__ */ new Map(),
|
|
5866
5987
|
messageRenderers: /* @__PURE__ */ new Map(),
|
|
5867
5988
|
entryRenderers: /* @__PURE__ */ new Map(),
|
|
@@ -5892,15 +6013,18 @@ async function applyPiPackage(ctx, options) {
|
|
|
5892
6013
|
}, typeof ownerAgent?.id === "string" ? ownerAgent.id : void 0);
|
|
5893
6014
|
subscribeLifecycle(ctx, state);
|
|
5894
6015
|
subscribeInterceptors(ctx, state);
|
|
6016
|
+
shared.providerBuiltins ??= /* @__PURE__ */ new Map();
|
|
5895
6017
|
for (const provider of builtinProviders()) {
|
|
5896
6018
|
const config = {
|
|
5897
6019
|
name: provider.name,
|
|
5898
6020
|
baseUrl: provider.baseUrl,
|
|
5899
6021
|
oauth: provider.auth.oauth
|
|
5900
6022
|
};
|
|
5901
|
-
BUILTIN_PROVIDER_SEEDS.add(config);
|
|
5902
6023
|
state.providers.set(provider.id, config);
|
|
5903
|
-
if (!shared.
|
|
6024
|
+
if (!shared.providerBuiltins.has(provider.id)) {
|
|
6025
|
+
shared.providerBuiltins.set(provider.id, config);
|
|
6026
|
+
recomposeSharedProvider(shared, provider.id);
|
|
6027
|
+
}
|
|
5904
6028
|
}
|
|
5905
6029
|
ensureLoginCommand(ctx, state);
|
|
5906
6030
|
for (const [name, config] of [...state.providers]) try {
|
|
@@ -6051,7 +6175,7 @@ async function applyPiPackage(ctx, options) {
|
|
|
6051
6175
|
remounts.set(state.packageName, async () => {
|
|
6052
6176
|
state.extensionsReady = false;
|
|
6053
6177
|
state.handlers.clear();
|
|
6054
|
-
state.
|
|
6178
|
+
for (const off of state.eventBusOffs.splice(0)) off();
|
|
6055
6179
|
try {
|
|
6056
6180
|
await registerPromptCommands(ctx, state, rootDir, options.manifest);
|
|
6057
6181
|
await mountExtensions();
|
|
@@ -6080,6 +6204,6 @@ const runtimeInternals = {
|
|
|
6080
6204
|
textBlocks
|
|
6081
6205
|
};
|
|
6082
6206
|
//#endregion
|
|
6083
|
-
export {
|
|
6207
|
+
export { registerVisionCompanions as a, overlayProviderConfig as i, mergeProviderRegistration as n, runtimeInternals as o, normalizeToolSchema as r, applyPiPackage as t };
|
|
6084
6208
|
|
|
6085
|
-
//# sourceMappingURL=runtime-
|
|
6209
|
+
//# sourceMappingURL=runtime-BN4E4OtI.mjs.map
|