pi2dsh 0.10.0 → 0.12.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/README.md +311 -151
- package/README.zh.md +262 -132
- package/dist/host.mjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{runtime-Ce3PTbWU.mjs → runtime-Bh5k4Kjt.mjs} +163 -9
- package/dist/runtime-Bh5k4Kjt.mjs.map +1 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +4 -2
- package/dist/runtime-Ce3PTbWU.mjs.map +0 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { F as AssistantMessageEventStream, a as builtinProviders, i as __setPiAiLlmBridge } from "./pi-ai-Dyg4zyLZ.mjs";
|
|
2
|
+
import { F as AssistantMessageEventStream, a as builtinProviders, h as getSupportedThinkingLevels, i as __setPiAiLlmBridge } from "./pi-ai-Dyg4zyLZ.mjs";
|
|
3
3
|
import { P as generateBranchSummary, Tn as PiCapabilityError, b as Theme, d as ExtensionRunner, w as __setSubagentSessionFactory, wn as CapabilityLedger } from "./pi-coding-agent-Ctw-BhoY.mjs";
|
|
4
4
|
import { t as getAgentDir } from "./pi-config-shim-CZ1wFzqM.mjs";
|
|
5
5
|
import { a as resolvePiProviderAuth, n as loginPiProvider, r as providerSupportsOAuth, t as FileCredentialStore } from "./oauth-bridge-CfyImWx4.mjs";
|
|
@@ -303,9 +303,22 @@ var PiSessionBridge = class {
|
|
|
303
303
|
//#endregion
|
|
304
304
|
//#region src/subagent-bridge.ts
|
|
305
305
|
let subagentSerial = 0;
|
|
306
|
+
/** Flatten a Pi message's content to text for transcript seeding. */
|
|
307
|
+
function piMessageText(message) {
|
|
308
|
+
const content = message.content;
|
|
309
|
+
if (typeof content === "string") return content;
|
|
310
|
+
if (!Array.isArray(content)) return "";
|
|
311
|
+
return content.map((block) => {
|
|
312
|
+
const record = block;
|
|
313
|
+
if (record?.type === "text" && typeof record.text === "string") return record.text;
|
|
314
|
+
if (record?.type === "toolCall" && typeof record.name === "string") return `(tool ${record.name})`;
|
|
315
|
+
return "";
|
|
316
|
+
}).filter((text) => text.length > 0).join("\n");
|
|
317
|
+
}
|
|
306
318
|
var PiBridgedAgentSession = class {
|
|
307
319
|
agent = {};
|
|
308
320
|
messages = [];
|
|
321
|
+
#seed = [];
|
|
309
322
|
#host;
|
|
310
323
|
#handle;
|
|
311
324
|
#session;
|
|
@@ -313,6 +326,10 @@ var PiBridgedAgentSession = class {
|
|
|
313
326
|
#subscribers = /* @__PURE__ */ new Set();
|
|
314
327
|
#disposers = [];
|
|
315
328
|
#activeToolNames;
|
|
329
|
+
#state;
|
|
330
|
+
#model;
|
|
331
|
+
#streaming = false;
|
|
332
|
+
#pendingToolCalls = /* @__PURE__ */ new Set();
|
|
316
333
|
#sessionName = "";
|
|
317
334
|
#turns = 0;
|
|
318
335
|
#aborted = false;
|
|
@@ -341,6 +358,51 @@ var PiBridgedAgentSession = class {
|
|
|
341
358
|
return next();
|
|
342
359
|
});
|
|
343
360
|
this.#disposers.push(offEvents, offPre);
|
|
361
|
+
const session = this;
|
|
362
|
+
this.#state = {
|
|
363
|
+
get systemPrompt() {
|
|
364
|
+
return "";
|
|
365
|
+
},
|
|
366
|
+
get model() {
|
|
367
|
+
return session.#model;
|
|
368
|
+
},
|
|
369
|
+
get thinkingLevel() {
|
|
370
|
+
return "off";
|
|
371
|
+
},
|
|
372
|
+
get tools() {
|
|
373
|
+
return [...session.#tools];
|
|
374
|
+
},
|
|
375
|
+
set tools(_next) {},
|
|
376
|
+
get messages() {
|
|
377
|
+
return [...session.messages];
|
|
378
|
+
},
|
|
379
|
+
set messages(next) {
|
|
380
|
+
session.#assignTranscript(next);
|
|
381
|
+
},
|
|
382
|
+
get isStreaming() {
|
|
383
|
+
return session.#streaming;
|
|
384
|
+
},
|
|
385
|
+
get pendingToolCalls() {
|
|
386
|
+
return new Set(session.#pendingToolCalls);
|
|
387
|
+
}
|
|
388
|
+
};
|
|
389
|
+
this.agent.state = this.#state;
|
|
390
|
+
}
|
|
391
|
+
/** Pi's AgentState projection, shared by `session.state` and `session.agent.state`. */
|
|
392
|
+
get state() {
|
|
393
|
+
return this.#state;
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* Pi's `state.messages = …` assignment. Messages already present in this
|
|
397
|
+
* child's projection stay as they are (they are durable); anything new is
|
|
398
|
+
* queued and delivered with the next prompt so the child model really sees
|
|
399
|
+
* the transcript the package seeded.
|
|
400
|
+
*/
|
|
401
|
+
#assignTranscript(next) {
|
|
402
|
+
const identity = (message) => JSON.stringify([message.role, message.content]);
|
|
403
|
+
const known = new Set(this.messages.map(identity));
|
|
404
|
+
this.#seed = next.filter((message) => !known.has(identity(message)));
|
|
405
|
+
for (const message of this.#seed) this.messages.push(message);
|
|
344
406
|
}
|
|
345
407
|
#project(event) {
|
|
346
408
|
const type = event.type;
|
|
@@ -349,12 +411,27 @@ var PiBridgedAgentSession = class {
|
|
|
349
411
|
handler(piEvent);
|
|
350
412
|
} catch {}
|
|
351
413
|
};
|
|
352
|
-
if (type === "turn/start")
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
414
|
+
if (type === "turn/start") {
|
|
415
|
+
this.#streaming = true;
|
|
416
|
+
emit({
|
|
417
|
+
type: "turn_start",
|
|
418
|
+
turnIndex: Number(event.data.turn ?? 1) - 1
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
if (type === "request/header") {
|
|
422
|
+
const config = event.data.config ?? {};
|
|
423
|
+
if (typeof config.model === "string") this.#model = {
|
|
424
|
+
id: config.model,
|
|
425
|
+
provider: String(config.provider ?? "")
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
if (type === "tools/result" || type === "tool/result") {
|
|
429
|
+
const data = event.data;
|
|
430
|
+
this.#pendingToolCalls.delete(String(data.callId ?? ""));
|
|
431
|
+
}
|
|
356
432
|
if (type === "tool/call") {
|
|
357
433
|
const data = event.data;
|
|
434
|
+
this.#pendingToolCalls.add(String(data.callId ?? ""));
|
|
358
435
|
let args = {};
|
|
359
436
|
try {
|
|
360
437
|
args = JSON.parse(String(data.arguments ?? "{}"));
|
|
@@ -401,6 +478,8 @@ var PiBridgedAgentSession = class {
|
|
|
401
478
|
}
|
|
402
479
|
if (type === "turn/end") {
|
|
403
480
|
this.#turns += 1;
|
|
481
|
+
this.#streaming = false;
|
|
482
|
+
this.#pendingToolCalls.clear();
|
|
404
483
|
emit({
|
|
405
484
|
type: "turn_end",
|
|
406
485
|
turnIndex: Number(event.data.turn ?? 1) - 1,
|
|
@@ -417,6 +496,28 @@ var PiBridgedAgentSession = class {
|
|
|
417
496
|
return () => this.#subscribers.delete(handler);
|
|
418
497
|
}
|
|
419
498
|
async prompt(text) {
|
|
499
|
+
if (this.#seed.length > 0) {
|
|
500
|
+
const seeded = this.#seed;
|
|
501
|
+
this.#seed = [];
|
|
502
|
+
const rendered = seeded.map((message) => {
|
|
503
|
+
const role = String(message.role ?? "user");
|
|
504
|
+
const content = piMessageText(message);
|
|
505
|
+
return content.length === 0 ? void 0 : `[${role}]: ${content}`;
|
|
506
|
+
}).filter((line) => line !== void 0);
|
|
507
|
+
if (rendered.length > 0) {
|
|
508
|
+
const seedBlocks = await this.#host.piContentToDsh([{
|
|
509
|
+
type: "text",
|
|
510
|
+
text: `<prior-conversation>\n${rendered.join("\n\n")}\n</prior-conversation>`
|
|
511
|
+
}]);
|
|
512
|
+
this.#host.deliver(this.#handle.agent, createUserMessage({
|
|
513
|
+
content: seedBlocks,
|
|
514
|
+
source: {
|
|
515
|
+
kind: "plugin",
|
|
516
|
+
plugin: this.#host.messageSource
|
|
517
|
+
}
|
|
518
|
+
}), "inject");
|
|
519
|
+
}
|
|
520
|
+
}
|
|
420
521
|
const blocks = await this.#host.piContentToDsh([{
|
|
421
522
|
type: "text",
|
|
422
523
|
text: String(text)
|
|
@@ -496,6 +597,18 @@ var PiBridgedAgentSession = class {
|
|
|
496
597
|
await this.#handle.dispose();
|
|
497
598
|
}
|
|
498
599
|
};
|
|
600
|
+
/**
|
|
601
|
+
* The name DSH's own child catalog shows for a side thread. Pi packages rarely
|
|
602
|
+
* label a child, so the package that started it is the honest fallback: with
|
|
603
|
+
* several Pi packages installed, their threads stay apart in one list.
|
|
604
|
+
* @param requested - a label the calling package supplied, if any.
|
|
605
|
+
* @param packageName - the Pi package the call came from.
|
|
606
|
+
*/
|
|
607
|
+
function childLabel(requested, packageName) {
|
|
608
|
+
if (typeof requested === "string" && requested.trim().length > 0) return requested.trim().slice(0, 80);
|
|
609
|
+
const owner = packageName?.trim();
|
|
610
|
+
return owner === void 0 || owner.length === 0 ? "Pi side conversation" : `${owner} side conversation`;
|
|
611
|
+
}
|
|
499
612
|
async function createBridgedAgentSession(host, options) {
|
|
500
613
|
const agents = host.cordis.get("agents");
|
|
501
614
|
if (agents?.create === void 0) throw new Error("pi2dsh: createAgentSession() needs the DSH agent registry in the host composition");
|
|
@@ -536,6 +649,17 @@ async function createBridgedAgentSession(host, options) {
|
|
|
536
649
|
throw new Error(`pi2dsh: subagent creation needs the DSH host loop (model runtime) to provide the agent factory; this composition cannot run one (${error instanceof Error ? error.message : String(error)})`);
|
|
537
650
|
}
|
|
538
651
|
const tools = [...Array.isArray(options.tools) ? options.tools : [], ...Array.isArray(options.customTools) ? options.customTools : []];
|
|
652
|
+
const childSession = handle.agent.session;
|
|
653
|
+
if (typeof childSession?.append === "function") try {
|
|
654
|
+
childSession.append("subagent/descriptor", {
|
|
655
|
+
version: 2,
|
|
656
|
+
mode: "continuable",
|
|
657
|
+
provider: "pi2dsh",
|
|
658
|
+
label: childLabel(options.label, host.packageName)
|
|
659
|
+
});
|
|
660
|
+
} catch (error) {
|
|
661
|
+
host.cordis.logger?.warn?.(`[pi2dsh] child session could not record its subagent identity: ${error instanceof Error ? error.message : String(error)}`);
|
|
662
|
+
}
|
|
539
663
|
return { session: new PiBridgedAgentSession(host, handle, tools) };
|
|
540
664
|
}
|
|
541
665
|
//#endregion
|
|
@@ -1155,6 +1279,33 @@ const PI_CARRIED_FIELDS = [
|
|
|
1155
1279
|
"compat",
|
|
1156
1280
|
"headers"
|
|
1157
1281
|
];
|
|
1282
|
+
/**
|
|
1283
|
+
* Pi's reasoning capability, in DSH's shape.
|
|
1284
|
+
*
|
|
1285
|
+
* The two sides say the same thing differently: Pi carries a `reasoning`
|
|
1286
|
+
* boolean plus a `thinkingLevelMap` whose `null` entries mark unsupported
|
|
1287
|
+
* levels, while DSH asks an adapter for the selectable efforts directly.
|
|
1288
|
+
* Translating is this layer's job — carrying Pi's boolean through under the
|
|
1289
|
+
* name `reasoning` would collide with DSH's `{efforts}` object, and carrying
|
|
1290
|
+
* nothing (what this bridge did before) leaves every package-registered route
|
|
1291
|
+
* with no selectable effort at all, so any reasoning request is rejected.
|
|
1292
|
+
*
|
|
1293
|
+
* The mapping is DSH's own: its native pi-ai adapter derives efforts from
|
|
1294
|
+
* `getSupportedThinkingLevels` and names them the same way, so a route a Pi
|
|
1295
|
+
* package registers offers exactly the efforts it would through the host's
|
|
1296
|
+
* own adapter. It belongs to the exact-route resolve, not the catalog listing
|
|
1297
|
+
* — `reasoning` is a resolved-model field in DSH's contract.
|
|
1298
|
+
* @param model - the Pi model descriptor as its package declared it.
|
|
1299
|
+
*/
|
|
1300
|
+
function reasoningProjection(model) {
|
|
1301
|
+
if (model.reasoning !== true) return {};
|
|
1302
|
+
const levels = getSupportedThinkingLevels(model);
|
|
1303
|
+
if (levels.length === 0) return {};
|
|
1304
|
+
return { reasoning: { efforts: levels.map((level) => ({
|
|
1305
|
+
id: level,
|
|
1306
|
+
name: `${level.charAt(0).toUpperCase()}${level.slice(1)}`
|
|
1307
|
+
})) } };
|
|
1308
|
+
}
|
|
1158
1309
|
function piCarriedFields(model) {
|
|
1159
1310
|
const carried = {};
|
|
1160
1311
|
for (const field of PI_CARRIED_FIELDS) if (model[field] !== void 0) carried[field] = model[field];
|
|
@@ -1182,6 +1333,7 @@ function piProviderDshAdapter(providerId, provider, host) {
|
|
|
1182
1333
|
const known = providerModels(provider).find((model) => model.id === modelId);
|
|
1183
1334
|
return {
|
|
1184
1335
|
...known === void 0 ? {} : piCarriedFields(known),
|
|
1336
|
+
...known === void 0 ? {} : reasoningProjection(known),
|
|
1185
1337
|
provider: id,
|
|
1186
1338
|
id: modelId,
|
|
1187
1339
|
name: String(known?.name ?? modelId),
|
|
@@ -1203,7 +1355,8 @@ function piProviderDshAdapter(providerId, provider, host) {
|
|
|
1203
1355
|
...auth?.headers === void 0 ? {} : { headers: auth.headers },
|
|
1204
1356
|
...options.signal instanceof AbortSignal ? { signal: options.signal } : {},
|
|
1205
1357
|
...typeof options.maxTokens === "number" ? { maxTokens: options.maxTokens } : {},
|
|
1206
|
-
...typeof options.temperature === "number" ? { temperature: options.temperature } : {}
|
|
1358
|
+
...typeof options.temperature === "number" ? { temperature: options.temperature } : {},
|
|
1359
|
+
...typeof options.reasoningEffort === "string" ? { reasoningEffort: options.reasoningEffort } : {}
|
|
1207
1360
|
};
|
|
1208
1361
|
yield* piEventsToDshChunks(provider.stream(model, piContext, piOptions));
|
|
1209
1362
|
}
|
|
@@ -2908,7 +3061,7 @@ function registerCommand(ctx, state, command) {
|
|
|
2908
3061
|
const definitionFor = (dshName) => ({
|
|
2909
3062
|
name: dshName,
|
|
2910
3063
|
description: command.description || `Migrated Pi command /${command.name}`,
|
|
2911
|
-
|
|
3064
|
+
input: { hint: command.argumentHint ?? "arguments (optional)" },
|
|
2912
3065
|
async handler(invocation) {
|
|
2913
3066
|
const agent = invocation.agent;
|
|
2914
3067
|
const commandContext = contextFor(ctx, state, agent, invocation.signal, true);
|
|
@@ -3368,7 +3521,8 @@ async function applyPiPackage(ctx, options) {
|
|
|
3368
3521
|
piContentToDsh: (content) => piToDshContent(ctx, content),
|
|
3369
3522
|
deliver: (agent, message, mode) => deliverAgentMessage(agent, message, mode),
|
|
3370
3523
|
messageFromSessionEvent,
|
|
3371
|
-
messageSource: state.messageSource
|
|
3524
|
+
messageSource: state.messageSource,
|
|
3525
|
+
packageName: state.packageName
|
|
3372
3526
|
}, subagentOptions));
|
|
3373
3527
|
ctx.effect(() => () => __setSubagentSessionFactory(void 0));
|
|
3374
3528
|
await registerPromptCommands(ctx, state, rootDir, options.manifest);
|
|
@@ -3410,4 +3564,4 @@ const runtimeInternals = {
|
|
|
3410
3564
|
//#endregion
|
|
3411
3565
|
export { runtimeInternals as i, normalizeToolSchema as n, registerVisionCompanions as r, applyPiPackage as t };
|
|
3412
3566
|
|
|
3413
|
-
//# sourceMappingURL=runtime-
|
|
3567
|
+
//# sourceMappingURL=runtime-Bh5k4Kjt.mjs.map
|