pi2dsh 0.25.2 → 0.27.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 +23 -20
- package/README.zh.md +15 -4
- package/dist/{analyzer-BmnsTRE1.mjs → analyzer-BCHAvJ70.mjs} +2 -2
- package/dist/{analyzer-BmnsTRE1.mjs.map → analyzer-BCHAvJ70.mjs.map} +1 -1
- package/dist/cli.mjs +2 -2
- package/dist/{compatibility-rEeEyLP1.mjs → compatibility-B1F_96JT.mjs} +4 -4
- package/dist/compatibility-B1F_96JT.mjs.map +1 -0
- package/dist/host.mjs +1 -1
- package/dist/index.d.mts +5 -16
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +20 -70
- package/dist/index.mjs.map +1 -1
- package/dist/{runtime-C6AOQRt7.mjs → runtime-BFJsumJX.mjs} +186 -94
- package/dist/runtime-BFJsumJX.mjs.map +1 -0
- package/dist/runtime.d.mts +6 -0
- package/dist/runtime.d.mts.map +1 -1
- package/dist/runtime.mjs +1 -1
- package/package.json +45 -43
- package/dist/compatibility-rEeEyLP1.mjs.map +0 -1
- package/dist/runtime-C6AOQRt7.mjs.map +0 -1
|
@@ -17,7 +17,7 @@ import { EventEmitter } from "node:events";
|
|
|
17
17
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
18
18
|
import { createJiti } from "jiti";
|
|
19
19
|
import * as llm from "@deepseek-ai/dsh-llm";
|
|
20
|
-
import { CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, LlmAdapter, LlmError, QUOTA_EXCEEDED_CODE, createUserMessage, isContextWindowExceededError, isQuotaExceededError } from "@deepseek-ai/dsh-llm";
|
|
20
|
+
import { CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, LlmAdapter, LlmError, QUOTA_EXCEEDED_CODE, ToolCallId, createToolResultMessage, createUserMessage, isContextWindowExceededError, isQuotaExceededError } from "@deepseek-ai/dsh-llm";
|
|
21
21
|
import { scopeOf } from "@deepseek-ai/dsh-scope";
|
|
22
22
|
import { renderPrompt } from "@deepseek-ai/dsh-system-prompt";
|
|
23
23
|
import { foldSurface } from "@deepseek-ai/dsh-session";
|
|
@@ -626,7 +626,6 @@ var PiSessionBridge = class {
|
|
|
626
626
|
});
|
|
627
627
|
} else if (type === "tool/result") {
|
|
628
628
|
const message = data.message ?? {};
|
|
629
|
-
const tool = (Array.isArray(message.content) ? message.content : []).find((block) => block.type === "tool-result");
|
|
630
629
|
merged.push({
|
|
631
630
|
time,
|
|
632
631
|
entry: {
|
|
@@ -635,9 +634,9 @@ var PiSessionBridge = class {
|
|
|
635
634
|
timestamp: new Date(time).toISOString(),
|
|
636
635
|
message: {
|
|
637
636
|
role: "toolResult",
|
|
638
|
-
toolCallId:
|
|
639
|
-
content: dshToPiContent$1(
|
|
640
|
-
isError:
|
|
637
|
+
toolCallId: message.toolCallId,
|
|
638
|
+
content: dshToPiContent$1(message.content ?? []),
|
|
639
|
+
isError: message.isError === true
|
|
641
640
|
}
|
|
642
641
|
}
|
|
643
642
|
});
|
|
@@ -834,6 +833,9 @@ var PiBridgedAgentSession = class {
|
|
|
834
833
|
#aborted = false;
|
|
835
834
|
#liveStreamAttempt;
|
|
836
835
|
#streamingText = "";
|
|
836
|
+
#turnAssistant;
|
|
837
|
+
#pendingPrompt;
|
|
838
|
+
#promptActive = false;
|
|
837
839
|
constructor(host, handle, tools, thinkingLevel) {
|
|
838
840
|
this.#thinkingLevel = typeof thinkingLevel === "string" && thinkingLevel.length > 0 ? thinkingLevel : "off";
|
|
839
841
|
this.#host = host;
|
|
@@ -962,35 +964,30 @@ var PiBridgedAgentSession = class {
|
|
|
962
964
|
});
|
|
963
965
|
}
|
|
964
966
|
if (type === "request/header") {
|
|
965
|
-
const config = event.data.config ?? {};
|
|
967
|
+
const config = event.data.header?.config ?? {};
|
|
966
968
|
if (typeof config.model === "string") this.#model = {
|
|
967
969
|
id: config.model,
|
|
968
970
|
provider: String(config.provider ?? "")
|
|
969
971
|
};
|
|
970
972
|
}
|
|
971
973
|
if (type === "tools/result" || type === "tool/result") {
|
|
972
|
-
const
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
for (const block of blocks) {
|
|
976
|
-
const record = block;
|
|
977
|
-
if (record?.type !== "tool-result") continue;
|
|
978
|
-
const callId = String(record.toolCallId ?? (message?.source)?.callId ?? data.callId ?? "");
|
|
974
|
+
const message = event.data.message;
|
|
975
|
+
if (message?.role === "tool") {
|
|
976
|
+
const callId = String(message.toolCallId ?? "");
|
|
979
977
|
this.#pendingToolCalls.delete(callId);
|
|
980
|
-
const isError =
|
|
978
|
+
const isError = message.isError === true;
|
|
981
979
|
emit({
|
|
982
980
|
type: "tool_execution_end",
|
|
983
981
|
toolCallId: callId,
|
|
984
982
|
toolName: this.#toolCallNames.get(callId) ?? "",
|
|
985
983
|
result: {
|
|
986
|
-
content:
|
|
984
|
+
content: message.content ?? [],
|
|
987
985
|
isError
|
|
988
986
|
},
|
|
989
987
|
isError
|
|
990
988
|
});
|
|
991
989
|
this.#toolCallNames.delete(callId);
|
|
992
990
|
}
|
|
993
|
-
if (blocks.length === 0) this.#pendingToolCalls.delete(String(data.callId ?? ""));
|
|
994
991
|
}
|
|
995
992
|
if (type === "tool/call") {
|
|
996
993
|
const data = event.data;
|
|
@@ -1037,6 +1034,10 @@ var PiBridgedAgentSession = class {
|
|
|
1037
1034
|
if (message === void 0) return;
|
|
1038
1035
|
if ((event.data?.source)?.form === "snapshot") this.#carried.add(message);
|
|
1039
1036
|
this.messages.push(message);
|
|
1037
|
+
if (type === "assistant/message") this.#turnAssistant = {
|
|
1038
|
+
turn: Number(event.data.turn),
|
|
1039
|
+
message
|
|
1040
|
+
};
|
|
1040
1041
|
emit({
|
|
1041
1042
|
type: "message_start",
|
|
1042
1043
|
message
|
|
@@ -1051,15 +1052,51 @@ var PiBridgedAgentSession = class {
|
|
|
1051
1052
|
this.#streaming = false;
|
|
1052
1053
|
this.#pendingToolCalls.clear();
|
|
1053
1054
|
this.#messageProjection = this.#messageProjection.then(() => {
|
|
1055
|
+
const data = event.data;
|
|
1056
|
+
const turn = Number(data.turn);
|
|
1057
|
+
const reason = data.reason;
|
|
1058
|
+
const stopReason = reason?.kind === "error" || reason?.kind === "blocked" ? "error" : reason?.kind === "aborted" ? "aborted" : reason?.kind === "max-tokens" ? "length" : "stop";
|
|
1059
|
+
let message = this.#turnAssistant?.turn === turn ? this.#turnAssistant.message : void 0;
|
|
1060
|
+
const synthetic = message === void 0 && stopReason !== "stop";
|
|
1061
|
+
if (message === void 0 && stopReason !== "stop") {
|
|
1062
|
+
message = {
|
|
1063
|
+
role: "assistant",
|
|
1064
|
+
content: [],
|
|
1065
|
+
timestamp: Date.now()
|
|
1066
|
+
};
|
|
1067
|
+
this.messages.push(message);
|
|
1068
|
+
}
|
|
1069
|
+
if (message !== void 0) {
|
|
1070
|
+
message.stopReason = stopReason;
|
|
1071
|
+
if (stopReason === "error") {
|
|
1072
|
+
const failure = reason?.error;
|
|
1073
|
+
message.errorMessage = reason?.kind === "blocked" ? "DSH blocked the child turn before completion" : String(failure?.message ?? "DSH child turn failed");
|
|
1074
|
+
}
|
|
1075
|
+
if (synthetic) {
|
|
1076
|
+
emit({
|
|
1077
|
+
type: "message_start",
|
|
1078
|
+
message
|
|
1079
|
+
});
|
|
1080
|
+
emit({
|
|
1081
|
+
type: "message_end",
|
|
1082
|
+
message
|
|
1083
|
+
});
|
|
1084
|
+
}
|
|
1085
|
+
}
|
|
1054
1086
|
emit({
|
|
1055
1087
|
type: "turn_end",
|
|
1056
|
-
turnIndex:
|
|
1057
|
-
message: {
|
|
1088
|
+
turnIndex: turn - 1,
|
|
1089
|
+
message: message ?? {
|
|
1058
1090
|
role: "assistant",
|
|
1059
|
-
content: []
|
|
1091
|
+
content: [],
|
|
1092
|
+
stopReason
|
|
1060
1093
|
},
|
|
1061
1094
|
toolResults: []
|
|
1062
1095
|
});
|
|
1096
|
+
emit({
|
|
1097
|
+
type: "agent_end",
|
|
1098
|
+
messages: [...this.messages]
|
|
1099
|
+
});
|
|
1063
1100
|
});
|
|
1064
1101
|
}
|
|
1065
1102
|
}
|
|
@@ -1068,6 +1105,15 @@ var PiBridgedAgentSession = class {
|
|
|
1068
1105
|
return () => this.#subscribers.delete(handler);
|
|
1069
1106
|
}
|
|
1070
1107
|
async prompt(text) {
|
|
1108
|
+
if (this.#promptActive) throw new Error("pi2dsh: this child session is already processing a prompt");
|
|
1109
|
+
this.#promptActive = true;
|
|
1110
|
+
try {
|
|
1111
|
+
await this.#runPrompt(text);
|
|
1112
|
+
} finally {
|
|
1113
|
+
this.#promptActive = false;
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
async #runPrompt(text) {
|
|
1071
1117
|
this.#aborted = false;
|
|
1072
1118
|
if (this.#seed.length > 0) {
|
|
1073
1119
|
const seeded = this.#seed;
|
|
@@ -1085,7 +1131,7 @@ var PiBridgedAgentSession = class {
|
|
|
1085
1131
|
this.#host.deliver(this.#handle.agent, createUserMessage({
|
|
1086
1132
|
content: seedBlocks,
|
|
1087
1133
|
source: {
|
|
1088
|
-
kind: "
|
|
1134
|
+
kind: "pi2dsh",
|
|
1089
1135
|
plugin: this.#host.messageSource
|
|
1090
1136
|
}
|
|
1091
1137
|
}), "inject");
|
|
@@ -1096,26 +1142,43 @@ var PiBridgedAgentSession = class {
|
|
|
1096
1142
|
text: String(text)
|
|
1097
1143
|
}]);
|
|
1098
1144
|
const cordis = unscopedEventContext(this.#host.cordis);
|
|
1099
|
-
const
|
|
1100
|
-
const off = cordis.on("session/event", (session, event) => {
|
|
1101
|
-
if (session !== this.#session) return;
|
|
1102
|
-
if (event.type === "turn/end") {
|
|
1103
|
-
off();
|
|
1104
|
-
resolve();
|
|
1105
|
-
}
|
|
1106
|
-
});
|
|
1107
|
-
this.#disposers.push(off);
|
|
1108
|
-
});
|
|
1109
|
-
this.#host.deliver(this.#handle.agent, createUserMessage({
|
|
1145
|
+
const message = createUserMessage({
|
|
1110
1146
|
content: blocks,
|
|
1111
1147
|
source: {
|
|
1112
|
-
kind: "
|
|
1148
|
+
kind: "pi2dsh",
|
|
1113
1149
|
plugin: this.#host.messageSource,
|
|
1114
1150
|
form: "relay"
|
|
1115
1151
|
}
|
|
1116
|
-
})
|
|
1117
|
-
|
|
1118
|
-
|
|
1152
|
+
});
|
|
1153
|
+
let turn;
|
|
1154
|
+
const offs = [];
|
|
1155
|
+
const cleanup = () => {
|
|
1156
|
+
for (const off of offs.splice(0)) off();
|
|
1157
|
+
};
|
|
1158
|
+
const completed = new Promise((resolve, reject) => {
|
|
1159
|
+
this.#pendingPrompt = {
|
|
1160
|
+
reject,
|
|
1161
|
+
dispose: cleanup
|
|
1162
|
+
};
|
|
1163
|
+
offs.push(cordis.on("agent/inbox/claimed", (payload) => {
|
|
1164
|
+
if (payload.agent === this.#handle.agent && payload.message?.id === message.id) turn = Number(payload.turn);
|
|
1165
|
+
}));
|
|
1166
|
+
offs.push(cordis.on("agent/disposed", (payload) => {
|
|
1167
|
+
if (payload.agent === this.#handle.agent) reject(/* @__PURE__ */ new Error("pi2dsh: child agent was disposed before its prompt completed"));
|
|
1168
|
+
}));
|
|
1169
|
+
offs.push(cordis.on("session/event", (session, event) => {
|
|
1170
|
+
if (session !== this.#session) return;
|
|
1171
|
+
if (event.type === "turn/end" && turn !== void 0 && Number(event.data.turn) === turn) resolve();
|
|
1172
|
+
}));
|
|
1173
|
+
});
|
|
1174
|
+
try {
|
|
1175
|
+
this.#host.deliver(this.#handle.agent, message, "followup");
|
|
1176
|
+
await completed;
|
|
1177
|
+
await this.#messageProjection;
|
|
1178
|
+
} finally {
|
|
1179
|
+
cleanup();
|
|
1180
|
+
this.#pendingPrompt = void 0;
|
|
1181
|
+
}
|
|
1119
1182
|
}
|
|
1120
1183
|
async steer(text, images) {
|
|
1121
1184
|
await this.#queueMessage(text, images, "steer");
|
|
@@ -1133,7 +1196,7 @@ var PiBridgedAgentSession = class {
|
|
|
1133
1196
|
this.#host.deliver(this.#handle.agent, createUserMessage({
|
|
1134
1197
|
content: blocks,
|
|
1135
1198
|
source: {
|
|
1136
|
-
kind: "
|
|
1199
|
+
kind: "pi2dsh",
|
|
1137
1200
|
plugin: this.#host.messageSource
|
|
1138
1201
|
}
|
|
1139
1202
|
}), mode);
|
|
@@ -1231,6 +1294,8 @@ var PiBridgedAgentSession = class {
|
|
|
1231
1294
|
} catch {}
|
|
1232
1295
|
}
|
|
1233
1296
|
async dispose() {
|
|
1297
|
+
this.#pendingPrompt?.reject(/* @__PURE__ */ new Error("pi2dsh: child session was disposed before its prompt completed"));
|
|
1298
|
+
this.#pendingPrompt?.dispose();
|
|
1234
1299
|
for (const dispose of this.#disposers.splice(0)) try {
|
|
1235
1300
|
dispose();
|
|
1236
1301
|
} catch {}
|
|
@@ -2403,7 +2468,7 @@ function dshBlocksFromPiContent(content) {
|
|
|
2403
2468
|
}
|
|
2404
2469
|
/**
|
|
2405
2470
|
* Pi request context → DSH GenerateOptions parts. System prompt moves to the
|
|
2406
|
-
* dedicated slot; toolResult messages become DSH tool-
|
|
2471
|
+
* dedicated slot; toolResult messages become native DSH tool-role messages.
|
|
2407
2472
|
*/
|
|
2408
2473
|
function piRequestToDshMessages(context) {
|
|
2409
2474
|
const messages = [];
|
|
@@ -2422,19 +2487,11 @@ function piRequestToDshMessages(context) {
|
|
|
2422
2487
|
model: String(message.model ?? context.model ?? "unknown")
|
|
2423
2488
|
}
|
|
2424
2489
|
});
|
|
2425
|
-
else if (message.role === "toolResult") messages.push({
|
|
2426
|
-
|
|
2427
|
-
content:
|
|
2428
|
-
|
|
2429
|
-
|
|
2430
|
-
content: dshBlocksFromPiContent(message.content),
|
|
2431
|
-
isError: message.isError === true
|
|
2432
|
-
}],
|
|
2433
|
-
source: {
|
|
2434
|
-
kind: "tool",
|
|
2435
|
-
callId: String(message.toolCallId ?? "")
|
|
2436
|
-
}
|
|
2437
|
-
});
|
|
2490
|
+
else if (message.role === "toolResult") messages.push(createToolResultMessage({
|
|
2491
|
+
callId: ToolCallId(String(message.toolCallId ?? "")),
|
|
2492
|
+
content: dshBlocksFromPiContent(message.content),
|
|
2493
|
+
isError: message.isError === true
|
|
2494
|
+
}));
|
|
2438
2495
|
const system = typeof context.systemPrompt === "string" && context.systemPrompt.length > 0 ? context.systemPrompt : void 0;
|
|
2439
2496
|
return {
|
|
2440
2497
|
...system === void 0 ? {} : { system },
|
|
@@ -2712,18 +2769,17 @@ async function dshRequestToPiContext(options, attachments) {
|
|
|
2712
2769
|
}
|
|
2713
2770
|
for (const message of history) {
|
|
2714
2771
|
const content = Array.isArray(message.content) ? message.content : [];
|
|
2715
|
-
const source = message.source;
|
|
2716
2772
|
if (message.role === "system") throw new Error("pi2dsh: this Pi provider cannot represent an in-history system prompt update");
|
|
2717
|
-
else if (message.role === "
|
|
2718
|
-
|
|
2719
|
-
const toolCallId = String(
|
|
2773
|
+
else if (message.role === "developer") throw new LlmError("pi2dsh: this Pi provider cannot represent developer messages", "UNSUPPORTED_CONTENT");
|
|
2774
|
+
else if (message.role === "tool") {
|
|
2775
|
+
const toolCallId = String(message.toolCallId ?? "");
|
|
2720
2776
|
const toolName = toolNamesById.get(toolCallId);
|
|
2721
2777
|
piMessages.push({
|
|
2722
2778
|
role: "toolResult",
|
|
2723
2779
|
toolCallId,
|
|
2724
2780
|
...toolName === void 0 ? {} : { toolName },
|
|
2725
|
-
content: await piContentFromDshBlocks(
|
|
2726
|
-
isError:
|
|
2781
|
+
content: await piContentFromDshBlocks(content, attachments),
|
|
2782
|
+
isError: message.isError === true
|
|
2727
2783
|
});
|
|
2728
2784
|
} else if (message.role === "user") piMessages.push({
|
|
2729
2785
|
role: "user",
|
|
@@ -3310,6 +3366,7 @@ const DSH_THINKING_FORMATS = /* @__PURE__ */ new Set([
|
|
|
3310
3366
|
"deepseek",
|
|
3311
3367
|
"openrouter",
|
|
3312
3368
|
"together",
|
|
3369
|
+
"baseten",
|
|
3313
3370
|
"zai",
|
|
3314
3371
|
"qwen",
|
|
3315
3372
|
"chat-template",
|
|
@@ -3321,6 +3378,7 @@ const DSH_MAX_TOKENS_FIELDS = /* @__PURE__ */ new Set(["max_completion_tokens",
|
|
|
3321
3378
|
const DSH_CACHE_CONTROL_FORMATS = /* @__PURE__ */ new Set(["anthropic"]);
|
|
3322
3379
|
const DSH_CHAT_TEMPLATE_VARS = /* @__PURE__ */ new Set(["thinking.enabled", "thinking.effort"]);
|
|
3323
3380
|
const COMPLETIONS = /* @__PURE__ */ new Set(["openai-completions"]);
|
|
3381
|
+
const RESPONSES = /* @__PURE__ */ new Set(["openai-responses"]);
|
|
3324
3382
|
const ANTHROPIC = /* @__PURE__ */ new Set(["anthropic-messages"]);
|
|
3325
3383
|
const COMPLETIONS_AND_RESPONSES = /* @__PURE__ */ new Set(["openai-completions", "openai-responses"]);
|
|
3326
3384
|
const DSH_COMPAT_FIELD_PROTOCOLS = {
|
|
@@ -3331,6 +3389,9 @@ const DSH_COMPAT_FIELD_PROTOCOLS = {
|
|
|
3331
3389
|
supportsFinishReason: COMPLETIONS,
|
|
3332
3390
|
chatTemplateArgs: COMPLETIONS,
|
|
3333
3391
|
supportsThinkingTokenBudget: COMPLETIONS,
|
|
3392
|
+
thinkingTokenBudgetField: COMPLETIONS,
|
|
3393
|
+
vllmPriority: COMPLETIONS,
|
|
3394
|
+
supportsMaxOutputTokens: RESPONSES,
|
|
3334
3395
|
maxTokensField: COMPLETIONS,
|
|
3335
3396
|
requiresToolResultName: COMPLETIONS,
|
|
3336
3397
|
requiresAssistantAfterToolResult: COMPLETIONS,
|
|
@@ -3385,9 +3446,13 @@ function compatProfileOf(value, api) {
|
|
|
3385
3446
|
const candidate = compat[field];
|
|
3386
3447
|
if (field === "maxTokensField") {
|
|
3387
3448
|
if (typeof candidate === "string" && DSH_MAX_TOKENS_FIELDS.has(candidate)) output[field] = candidate;
|
|
3449
|
+
} else if (field === "vllmPriority") {
|
|
3450
|
+
if (typeof candidate === "number" && Number.isSafeInteger(candidate)) output[field] = candidate;
|
|
3451
|
+
} else if (field === "thinkingTokenBudgetField") {
|
|
3452
|
+
if (candidate === "thinking_token_budget" || candidate === "thinking_budget" || candidate === "thinking_budget_tokens") output[field] = candidate;
|
|
3388
3453
|
} else if (field === "thinkingFormat") {
|
|
3389
3454
|
if (typeof candidate === "string" && DSH_THINKING_FORMATS.has(candidate)) output[field] = candidate;
|
|
3390
|
-
} else if (field === "chatTemplateKwargs") {
|
|
3455
|
+
} else if (field === "chatTemplateKwargs" || field === "chatTemplateArgs") {
|
|
3391
3456
|
const kwargs = chatTemplateKwargsOf(candidate);
|
|
3392
3457
|
if (kwargs !== void 0) output[field] = kwargs;
|
|
3393
3458
|
} else if (field === "cacheControlFormat") {
|
|
@@ -4087,12 +4152,16 @@ async function createPiTuiExtensionSurfaceAdapter(ctx, packageName, instanceKey)
|
|
|
4087
4152
|
const extensionService = service(ctx);
|
|
4088
4153
|
if (extensionService === void 0) return void 0;
|
|
4089
4154
|
const api = extensionService.api();
|
|
4090
|
-
if (api.apiVersion !==
|
|
4155
|
+
if (api.apiVersion !== 2 || !api.capabilities.has("unstable.surface.handle")) {
|
|
4091
4156
|
ctx.logger?.warn(`pi2dsh: piTuiExtensions cannot host Pi components (api=${api.apiVersion}, raw surface=${api.capabilities.has("unstable.surface.handle")})`);
|
|
4092
4157
|
return;
|
|
4093
4158
|
}
|
|
4094
4159
|
try {
|
|
4095
|
-
const
|
|
4160
|
+
const hostEntry = "@xmoon76/dsh-pi-tui";
|
|
4161
|
+
const unstableEntry = "@xmoon76/dsh-pi-tui/extensions/unstable";
|
|
4162
|
+
const loader = ctx.get("loader", false);
|
|
4163
|
+
const importPublic = (name) => loader === void 0 ? import(name) : loader.import(name);
|
|
4164
|
+
const [hostModule, unstableModule] = await Promise.all([importPublic(hostEntry), importPublic(unstableEntry)]);
|
|
4096
4165
|
if (unstableModule.UNSTABLE_API_LEVEL !== 1) {
|
|
4097
4166
|
ctx.logger?.warn(`pi2dsh: unsupported dsh-pi-tui unstable API level ${unstableModule.UNSTABLE_API_LEVEL}`);
|
|
4098
4167
|
return;
|
|
@@ -4744,21 +4813,7 @@ function contextFor(ctx, state, agent, signal, command = false, sessionOverride,
|
|
|
4744
4813
|
...auth.baseUrl === void 0 && config.baseUrl === void 0 ? {} : { baseUrl: auth.baseUrl ?? config.baseUrl }
|
|
4745
4814
|
};
|
|
4746
4815
|
}
|
|
4747
|
-
|
|
4748
|
-
const entry = llmOf(ctx)?.listConfigurableProviders?.()?.find((candidate) => candidate.provider === provider);
|
|
4749
|
-
if (entry === void 0) return { ok: false };
|
|
4750
|
-
const section = ctx.get("settings")?.get(entry.settingsNs);
|
|
4751
|
-
const ref = entry.settingsPath.reduce((node, key) => typeof node === "object" && node !== null ? node[key] : void 0, section)?.apiKeyEnv;
|
|
4752
|
-
if (typeof ref !== "string" || ref.length === 0) return { ok: false };
|
|
4753
|
-
const resolved = await ctx.get("credentials")?.resolve(ref);
|
|
4754
|
-
if (typeof resolved?.value !== "string" || resolved.value.length === 0) return { ok: false };
|
|
4755
|
-
return {
|
|
4756
|
-
ok: true,
|
|
4757
|
-
apiKey: resolved.value
|
|
4758
|
-
};
|
|
4759
|
-
} catch {
|
|
4760
|
-
return { ok: false };
|
|
4761
|
-
}
|
|
4816
|
+
return resolveHostModelAuth(ctx, provider);
|
|
4762
4817
|
},
|
|
4763
4818
|
getProviderAuthStatus: (provider) => providerSupportsOAuth(providerConfig(provider)) ? "oauth" : "none",
|
|
4764
4819
|
getProvider: (provider) => {
|
|
@@ -5216,12 +5271,12 @@ async function messageFromSessionEvent(ctx, event) {
|
|
|
5216
5271
|
};
|
|
5217
5272
|
}
|
|
5218
5273
|
if (type === "tool/result") {
|
|
5219
|
-
const
|
|
5274
|
+
const message = record.message;
|
|
5220
5275
|
return {
|
|
5221
5276
|
role: "toolResult",
|
|
5222
|
-
toolCallId:
|
|
5223
|
-
content: await dshToPiContent(ctx,
|
|
5224
|
-
isError:
|
|
5277
|
+
toolCallId: message?.toolCallId,
|
|
5278
|
+
content: await dshToPiContent(ctx, message?.content ?? []),
|
|
5279
|
+
isError: message?.isError === true
|
|
5225
5280
|
};
|
|
5226
5281
|
}
|
|
5227
5282
|
}
|
|
@@ -5231,12 +5286,9 @@ function sourceReason(value) {
|
|
|
5231
5286
|
/**
|
|
5232
5287
|
* Claim Pi's once-per-session `session_start` event.
|
|
5233
5288
|
*
|
|
5234
|
-
*
|
|
5235
|
-
*
|
|
5236
|
-
*
|
|
5237
|
-
* The command bridge uses this same claim before invoking a Pi command; when
|
|
5238
|
-
* DSH later announces the real agent lifecycle, the durable session id keeps
|
|
5239
|
-
* the second path from restarting the extension.
|
|
5289
|
+
* Normal engine mounts complete inside DSH's serial agent/created event.
|
|
5290
|
+
* The same idempotent claim also protects direct runtime users and reloads:
|
|
5291
|
+
* command/tool entry must not restart an already initialized Pi extension.
|
|
5240
5292
|
*/
|
|
5241
5293
|
function claimPiSessionStart(state, agent) {
|
|
5242
5294
|
const id = agentSession(agent)?.id;
|
|
@@ -5362,7 +5414,7 @@ async function startPiSession(ctx, state, agent, reason, signal) {
|
|
|
5362
5414
|
function subscribeLifecycle(ctx, state) {
|
|
5363
5415
|
const cordis = ctx;
|
|
5364
5416
|
const warn = (event, error) => logger(ctx).warn(`[pi2dsh] ${event} handler failed: ${String(error)}`);
|
|
5365
|
-
cordis.on("agent/
|
|
5417
|
+
cordis.on("agent/created", async (payload) => {
|
|
5366
5418
|
const agent = payload.agent;
|
|
5367
5419
|
if (!acceptsAgent(state, agent)) return;
|
|
5368
5420
|
state.activeAgents.add(agent);
|
|
@@ -5374,7 +5426,7 @@ function subscribeLifecycle(ctx, state) {
|
|
|
5374
5426
|
state.pendingSessionStarts.set(agent, sourceReason(payload.source));
|
|
5375
5427
|
return;
|
|
5376
5428
|
}
|
|
5377
|
-
startPiSession(ctx, state, agent, sourceReason(payload.source),
|
|
5429
|
+
await startPiSession(ctx, state, agent, sourceReason(payload.source), payload.signal);
|
|
5378
5430
|
});
|
|
5379
5431
|
cordis.on("agent/disposed", (payload) => {
|
|
5380
5432
|
const agent = payload.agent;
|
|
@@ -5668,7 +5720,7 @@ async function flushPendingSessionStarts(ctx, state) {
|
|
|
5668
5720
|
* session guard must deliberately NOT suppress this replay: from the new
|
|
5669
5721
|
* instance's point of view this is its first `session_start`. The command's
|
|
5670
5722
|
* AsyncLocalStorage agent is included because a lean composition can execute
|
|
5671
|
-
* a Pi command
|
|
5723
|
+
* a Pi command through the runtime directly, outside engine-managed creation.
|
|
5672
5724
|
*/
|
|
5673
5725
|
async function restartReloadedPiSessions(ctx, state) {
|
|
5674
5726
|
state.extensionsReady = true;
|
|
@@ -6041,7 +6093,7 @@ async function runBeforeAgentStart(ctx, state, agent, signal, assembled) {
|
|
|
6041
6093
|
injected.push(createUserMessage({
|
|
6042
6094
|
content: blocks,
|
|
6043
6095
|
source: {
|
|
6044
|
-
kind: "
|
|
6096
|
+
kind: "pi2dsh",
|
|
6045
6097
|
plugin: state.messageSource,
|
|
6046
6098
|
...typeof message.customType === "string" ? { piCustomType: message.customType } : {}
|
|
6047
6099
|
}
|
|
@@ -6199,7 +6251,7 @@ async function applyPiContextTransform(ctx, state, agent, signal, pending) {
|
|
|
6199
6251
|
rebuilt.push(createUserMessage({
|
|
6200
6252
|
content: blocks.map((block) => block.type === "text" ? files.get(block.text) ?? block : block),
|
|
6201
6253
|
source: original.source ?? {
|
|
6202
|
-
kind: "
|
|
6254
|
+
kind: "pi2dsh",
|
|
6203
6255
|
plugin: state.messageSource
|
|
6204
6256
|
}
|
|
6205
6257
|
}));
|
|
@@ -6547,6 +6599,7 @@ async function materializeAttachmentImage(ctx, attachment) {
|
|
|
6547
6599
|
}
|
|
6548
6600
|
function ensureLoginCommand(ctx, state) {
|
|
6549
6601
|
if (!shouldRegisterCompatibilityCommand("login", state.tuiSurfaces?.nativeCommands) && optionalService(ctx, "authorization") !== void 0) {
|
|
6602
|
+
state.shared.retireLoginCommand?.();
|
|
6550
6603
|
logger(ctx).debug("[pi2dsh] native terminal owns /login and the authorization service is composed; Pi OAuth flows are available through it");
|
|
6551
6604
|
return;
|
|
6552
6605
|
}
|
|
@@ -6554,8 +6607,26 @@ function ensureLoginCommand(ctx, state) {
|
|
|
6554
6607
|
state.shared.loginCommandRegistered = true;
|
|
6555
6608
|
try {
|
|
6556
6609
|
registerLoginCommand(ctx, state);
|
|
6557
|
-
|
|
6558
|
-
state.
|
|
6610
|
+
const retire = () => {
|
|
6611
|
+
state.commandDisposers.get("login")?.();
|
|
6612
|
+
state.commandDisposers.delete("login");
|
|
6613
|
+
state.commands.delete("login");
|
|
6614
|
+
for (const [name, owner] of state.dshCommandOwners) if (owner === "login") state.dshCommandOwners.delete(name);
|
|
6615
|
+
if (state.shared.retireLoginCommand === retire) {
|
|
6616
|
+
delete state.shared.retireLoginCommand;
|
|
6617
|
+
state.shared.loginCommandRegistered = false;
|
|
6618
|
+
}
|
|
6619
|
+
};
|
|
6620
|
+
state.shared.retireLoginCommand = retire;
|
|
6621
|
+
ctx.effect(() => retire);
|
|
6622
|
+
ctx.inject(["piTuiExtensions", "authorization"], async (inner) => {
|
|
6623
|
+
const terminal = await createPiTuiExtensionSurfaceAdapter(inner, state.packageName);
|
|
6624
|
+
if (terminal === void 0) return;
|
|
6625
|
+
try {
|
|
6626
|
+
if (!shouldRegisterCompatibilityCommand("login", terminal.nativeCommands)) retire();
|
|
6627
|
+
} finally {
|
|
6628
|
+
terminal.dispose();
|
|
6629
|
+
}
|
|
6559
6630
|
});
|
|
6560
6631
|
} catch (error) {
|
|
6561
6632
|
state.shared.loginCommandRegistered = false;
|
|
@@ -7280,7 +7351,7 @@ async function sendPiMessage(ctx, state, content, mode, sessionOverride, customT
|
|
|
7280
7351
|
const message = createUserMessage({
|
|
7281
7352
|
content: blocks,
|
|
7282
7353
|
source: {
|
|
7283
|
-
kind: "
|
|
7354
|
+
kind: "pi2dsh",
|
|
7284
7355
|
plugin: state.messageSource,
|
|
7285
7356
|
...customType === void 0 ? { form: "relay" } : { piCustomType: customType }
|
|
7286
7357
|
}
|
|
@@ -7882,7 +7953,7 @@ async function registerPromptCommands(ctx, state, rootDir, manifest) {
|
|
|
7882
7953
|
text: expandPrompt(text, rawInput)
|
|
7883
7954
|
}],
|
|
7884
7955
|
source: {
|
|
7885
|
-
kind: "
|
|
7956
|
+
kind: "pi2dsh",
|
|
7886
7957
|
plugin: `pi2dsh:${manifest.package.name}`,
|
|
7887
7958
|
form: "relay"
|
|
7888
7959
|
}
|
|
@@ -8524,7 +8595,28 @@ async function applyPiPackage(ctx, options) {
|
|
|
8524
8595
|
const healthSuffix = health === void 0 || health.status === "ok" ? "" : ` — ${health.status.toUpperCase()}: missing Pi capabilities ${health.gaps.join(", ")}`;
|
|
8525
8596
|
logger(ctx).info(`[pi2dsh] loaded ${options.manifest.package.name}: ${state.tools.size} tools, ${state.commands.size} commands, ${options.manifest.skillDirs.length} skill roots${healthSuffix}${state.hostAnchor ? " (host anchor)" : ""}`);
|
|
8526
8597
|
}
|
|
8598
|
+
/** Resolve a host-owned route through its public config descriptor and credential reference. */
|
|
8599
|
+
async function resolveHostModelAuth(ctx, provider) {
|
|
8600
|
+
try {
|
|
8601
|
+
const entry = ctx.get("llm")?.listConfigurableProviders().find((candidate) => candidate.provider === provider);
|
|
8602
|
+
if (entry === void 0) return { ok: false };
|
|
8603
|
+
const section = ctx.get("settings")?.describe({ redactSecrets: true }).find((item) => item.ns === entry.settingsNs)?.value;
|
|
8604
|
+
const ref = entry.settingsPath.reduce((node, key) => typeof node === "object" && node !== null ? node[key] : void 0, section)?.apiKeyEnv;
|
|
8605
|
+
if (typeof ref !== "string" || ref.length === 0) return { ok: false };
|
|
8606
|
+
const resolved = await ctx.get("credentials")?.resolve(ref);
|
|
8607
|
+
return typeof resolved?.value === "string" && resolved.value.length > 0 ? {
|
|
8608
|
+
ok: true,
|
|
8609
|
+
apiKey: resolved.value
|
|
8610
|
+
} : { ok: false };
|
|
8611
|
+
} catch (error) {
|
|
8612
|
+
return {
|
|
8613
|
+
ok: false,
|
|
8614
|
+
error: `Host credential resolution failed: ${error instanceof Error ? error.message : String(error)}`
|
|
8615
|
+
};
|
|
8616
|
+
}
|
|
8617
|
+
}
|
|
8527
8618
|
const runtimeInternals = {
|
|
8619
|
+
resolveHostModelAuth,
|
|
8528
8620
|
compactionReason,
|
|
8529
8621
|
resolveOfferedChoice,
|
|
8530
8622
|
currentPiModel,
|
|
@@ -8543,4 +8635,4 @@ const runtimeInternals = {
|
|
|
8543
8635
|
//#endregion
|
|
8544
8636
|
export { overlayProviderConfig as a, runtimeInternals as c, normalizeToolSchema as i, getSharedChildExtensionCatalog as n, registerChildExtensionCatalog as o, mergeProviderRegistration as r, registerVisionCompanions as s, applyPiPackage as t };
|
|
8545
8637
|
|
|
8546
|
-
//# sourceMappingURL=runtime-
|
|
8638
|
+
//# sourceMappingURL=runtime-BFJsumJX.mjs.map
|