pi2dsh 0.15.1 → 0.15.2

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/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
 
2
- import { a as registerVisionCompanions } from "./runtime-D1DI60RQ.mjs";
2
+ import { a as registerVisionCompanions } from "./runtime-BlbKWw7W.mjs";
3
3
  import { t as resolvePiPackage } from "./source-0sA5z08z.mjs";
4
4
  import { applyPiHost, applyPreparedPiHost, manifestForInstalled, preparePiHost } from "./host.mjs";
5
- import { a as PI_AI_PACKAGES, c as UI_CONTEXT_RULES, d as ruleForEvent, f as ruleForHostImport, i as HOST_IMPORT_RULES, l as ruleForApi, n as CONTEXT_RULES, o as PI_CODING_AGENT_PACKAGES, p as ruleForUiContextProperty, r as EVENT_RULES, s as PI_TUI_PACKAGES, t as API_RULES, u as ruleForContextProperty } from "./compatibility-DH_Gi96X.mjs";
5
+ import { a as PI_AI_PACKAGES, c as UI_CONTEXT_RULES, d as ruleForEvent, f as ruleForHostImport, i as HOST_IMPORT_RULES, l as ruleForApi, n as CONTEXT_RULES, o as PI_CODING_AGENT_PACKAGES, p as ruleForUiContextProperty, r as EVENT_RULES, s as PI_TUI_PACKAGES, t as API_RULES, u as ruleForContextProperty } from "./compatibility-DVMqXJux.mjs";
6
6
  import { n as convertPiMcpConfig, r as renderMcpPatch, t as collectPiMcpServers } from "./mcp-config-jmzbgdHa.mjs";
7
7
  import { readFile } from "node:fs/promises";
8
8
  import { existsSync } from "node:fs";
@@ -234,7 +234,7 @@ async function apply(ctx, config = {}) {
234
234
  * @returns the compatibility report.
235
235
  */
236
236
  async function analyzePackage(pkg) {
237
- const { analyzePackage: run } = await import("./analyzer-er3QPDc0.mjs");
237
+ const { analyzePackage: run } = await import("./analyzer-C5FQXB7R.mjs");
238
238
  return run(pkg);
239
239
  }
240
240
  //#endregion
@@ -2,7 +2,7 @@
2
2
  import { En as PiCapabilityError, F as generateBranchSummary, Tn as CapabilityLedger, b as Theme, d as ExtensionRunner, w as __runWithSubagentSessionFactory } from "./pi-coding-agent-DK8hbJP5.mjs";
3
3
  import { t as getAgentDir } from "./pi-config-shim-CZ1wFzqM.mjs";
4
4
  import { $ as isContextOverflow, Q as AssistantMessageEventStream, S as getSupportedThinkingLevels, c as builtinProviders, o as __runWithPiAiRuntime, r as __createPiAiRuntimeRegistry } from "./pi-ai-DpqiLdPA.mjs";
5
- import { W as getKeybindings } from "./pi-tui-DruSeKmd.mjs";
5
+ import { W as getKeybindings, _t as stripTerminalSequences } from "./pi-tui-DruSeKmd.mjs";
6
6
  import { a as FileCredentialStore, c as providerSupportsOAuth, i as oauthCredentialRef, l as resolvePiProviderAuth, o as joinSignals, s as loginPiProvider, u as storedOAuthCredential } from "./credentials-oauth-Didpkkjx.mjs";
7
7
  import { createRequire } from "node:module";
8
8
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
@@ -13,7 +13,7 @@ import { tmpdir } from "node:os";
13
13
  import { EventEmitter } from "node:events";
14
14
  import { AsyncLocalStorage } from "node:async_hooks";
15
15
  import { createJiti } from "jiti";
16
- import { CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, LlmError, QUOTA_EXCEEDED_CODE, createUserMessage, isContextWindowExceededError, isQuotaExceededError } from "@deepseek-ai/dsh-llm";
16
+ import { CONTEXT_WINDOW_EXCEEDED_CODE, EMPTY_RESPONSE_CODE, LlmAdapter, LlmError, QUOTA_EXCEEDED_CODE, createUserMessage, isContextWindowExceededError, isQuotaExceededError } from "@deepseek-ai/dsh-llm";
17
17
  import { scopeOf } from "@deepseek-ai/dsh-scope";
18
18
  import { renderPrompt } from "@deepseek-ai/dsh-system-prompt";
19
19
  import { randomUUID } from "node:crypto";
@@ -2252,6 +2252,18 @@ function piCarriedFields(model) {
2252
2252
  * Wrap one Pi provider object as a DSH LlmAdapter-shaped route handler.
2253
2253
  * Structural typing carries it through `llm.registerAdapter`.
2254
2254
  */
2255
+ /** Build the route handler ON the host's own LlmAdapter base class. The
2256
+ * 0.1.0-rc.8 dispatch reads adapter methods structurally, so a plain object
2257
+ * worked; 0.1.1's dispatch calls `adapter.prepareCall` — a method the BASE
2258
+ * CLASS provides (it binds resolveModel + stream into a one-shot prepared
2259
+ * call). Because `@deepseek-ai/dsh-llm` is a peer, `LlmAdapter` here is
2260
+ * whichever generation the host installed: own-property methods carry the
2261
+ * bridge behavior on both, and everything the base contributes on newer
2262
+ * generations (prepareCall, retry-policy defaults) is inherited instead of
2263
+ * re-implemented. */
2264
+ function llmAdapterInstance(methods) {
2265
+ return Object.assign(new LlmAdapter(), methods);
2266
+ }
2255
2267
  function piProviderDshAdapter(providerId, provider, host) {
2256
2268
  let warnedStop = false;
2257
2269
  const warnStopUnsupported = () => {
@@ -2259,7 +2271,7 @@ function piProviderDshAdapter(providerId, provider, host) {
2259
2271
  warnedStop = true;
2260
2272
  host.warn(`[pi2dsh] a request to Pi provider ${JSON.stringify(providerId)} carries stop sequences, which Pi models at no layer — they cannot be forwarded, so the model will not halt on them`);
2261
2273
  };
2262
- return {
2274
+ return llmAdapterInstance({
2263
2275
  providerInfo: (id) => ({
2264
2276
  id,
2265
2277
  name: typeof provider.name === "string" ? provider.name : id
@@ -2333,7 +2345,7 @@ function piProviderDshAdapter(providerId, provider, host) {
2333
2345
  reasoningEffort: reasoning
2334
2346
  }), contextWindow);
2335
2347
  }
2336
- };
2348
+ });
2337
2349
  }
2338
2350
  const IMAGE_OMITTED_TEXT = "[image attachment omitted: the selected model reads text only]";
2339
2351
  const imageNoticeText = (path) => path === void 0 ? IMAGE_OMITTED_TEXT : `[image attached at ${path} — the selected model reads text only; use an image-capable tool to view it]`;
@@ -2382,7 +2394,7 @@ function imageAdmissionCompanionAdapter(options) {
2382
2394
  inputModalities: modalities
2383
2395
  };
2384
2396
  };
2385
- return {
2397
+ return llmAdapterInstance({
2386
2398
  providerInfo: (id) => {
2387
2399
  return {
2388
2400
  id,
@@ -2405,7 +2417,7 @@ function imageAdmissionCompanionAdapter(options) {
2405
2417
  ...Array.isArray(streamOptions.messages) ? { messages: await textOnlyMessages(streamOptions.messages, materialize) } : {}
2406
2418
  });
2407
2419
  }
2408
- };
2420
+ });
2409
2421
  }
2410
2422
  /** A wire protocol DSH's official adapter can serve, or undefined. */
2411
2423
  function protocolOf(value) {
@@ -3254,9 +3266,56 @@ function dialogAbortSignal(opts) {
3254
3266
  if (signals.length === 0) return void 0;
3255
3267
  return signals.length === 1 ? signals[0] : AbortSignal.any(signals);
3256
3268
  }
3269
+ const OSC8_HYPERLINK = /\u001b\]8;[^;]*;([^\u0007\u001b]*)(?:\u0007|\u001b\\)([\s\S]*?)\u001b\]8;;(?:\u0007|\u001b\\)/gu;
3270
+ const MARKDOWN_LINK = /\[([^\]]+)\]\(([^)]+)\)/gu;
3271
+ /**
3272
+ * Translate terminal-oriented Pi dialog copy into DSH's native question
3273
+ * shape. Pi packages legitimately put OSC 8 links and a multi-line body in
3274
+ * the dialog title because Pi's TUI owns that whole text block. DSH separates
3275
+ * a plain-text heading from a Markdown detail block, and its Web client renders
3276
+ * terminal control bytes literally. Keep the plugin's words and destination,
3277
+ * but move them onto the host's real presentation contract.
3278
+ */
3279
+ function projectDialogPrompt(title, supplementalDetail, linkMode) {
3280
+ const linkedUrls = /* @__PURE__ */ new Set();
3281
+ const normalize = (value) => {
3282
+ const formatted = String(value).replace(OSC8_HYPERLINK, (whole, url, label) => {
3283
+ linkedUrls.add(url);
3284
+ if (linkMode === "terminal") return whole;
3285
+ return `[${stripTerminalSequences(label).replace(/([\\\[\]])/gu, "\\$1")}](${url})`;
3286
+ });
3287
+ return (linkMode === "terminal" ? formatted : stripTerminalSequences(formatted)).replace(/\r\n?/gu, "\n");
3288
+ };
3289
+ const titleLines = normalize(title).split("\n");
3290
+ while (titleLines[0]?.trim() === "") titleLines.shift();
3291
+ while (titleLines.at(-1)?.trim() === "") titleLines.pop();
3292
+ const headingLine = titleLines.shift()?.trim() || "Input required";
3293
+ const headingHasLink = linkMode === "terminal" ? headingLine.includes("\x1B]8;") : [...headingLine.matchAll(MARKDOWN_LINK)].length > 0;
3294
+ const question = linkMode === "terminal" ? stripTerminalSequences(headingLine) : headingLine.replace(MARKDOWN_LINK, "$1");
3295
+ if (headingHasLink) titleLines.unshift("", headingLine);
3296
+ const detailLines = [...titleLines];
3297
+ if (supplementalDetail !== void 0) {
3298
+ if (detailLines.length > 0 && detailLines.at(-1)?.trim() !== "") detailLines.push("");
3299
+ detailLines.push(...normalize(supplementalDetail).split("\n"));
3300
+ }
3301
+ const deduplicated = [];
3302
+ for (const line of detailLines) {
3303
+ if (linkedUrls.has(line.trim())) continue;
3304
+ if (line.trim() === "" && deduplicated.at(-1)?.trim() === "") continue;
3305
+ deduplicated.push(line.replace(/[ \t]+$/gu, ""));
3306
+ }
3307
+ while (deduplicated[0]?.trim() === "") deduplicated.shift();
3308
+ while (deduplicated.at(-1)?.trim() === "") deduplicated.pop();
3309
+ const detail = deduplicated.join("\n");
3310
+ return {
3311
+ question,
3312
+ ...detail.length === 0 ? {} : { detail }
3313
+ };
3314
+ }
3257
3315
  function contextFor(ctx, state, agent, signal, command = false, sessionOverride) {
3258
3316
  const notices = [];
3259
3317
  const userQuestions = optionalService(ctx, "userQuestions");
3318
+ const dialogLinkMode = optionalService(ctx, "tuiScenes") === void 0 ? "markdown" : "terminal";
3260
3319
  const ui = {
3261
3320
  notify(message, type) {
3262
3321
  const text = String(message);
@@ -3269,7 +3328,7 @@ function contextFor(ctx, state, agent, signal, command = false, sessionOverride)
3269
3328
  const labels = options.map((option) => String(option));
3270
3329
  const answered = await askOne(ctx, agent, joinSignals(signal, dialogAbortSignal(opts)), {
3271
3330
  id: "pi2dsh-select",
3272
- question: String(title),
3331
+ ...projectDialogPrompt(title, void 0, dialogLinkMode),
3273
3332
  options: labels.map((label) => ({ label }))
3274
3333
  });
3275
3334
  return answered === void 0 ? void 0 : resolveOfferedChoice(answered, labels);
@@ -3277,28 +3336,24 @@ function contextFor(ctx, state, agent, signal, command = false, sessionOverride)
3277
3336
  async confirm(title, message, opts) {
3278
3337
  return await askOne(ctx, agent, joinSignals(signal, dialogAbortSignal(opts)), {
3279
3338
  id: "pi2dsh-confirm",
3280
- question: String(title),
3281
- detail: String(message),
3339
+ ...projectDialogPrompt(title, message, dialogLinkMode),
3282
3340
  options: [{ label: "Yes" }, { label: "No" }]
3283
3341
  }) === "Yes";
3284
3342
  },
3285
3343
  input: (title, placeholder, opts) => askOne(ctx, agent, joinSignals(signal, dialogAbortSignal(opts)), {
3286
3344
  id: "pi2dsh-input",
3287
- question: String(title),
3288
- ...placeholder === void 0 ? {} : { detail: String(placeholder) }
3345
+ ...projectDialogPrompt(title, placeholder, dialogLinkMode)
3289
3346
  }),
3290
3347
  deviceCode: async (title, detail, opts) => {
3291
3348
  await askOne(ctx, agent, joinSignals(signal, dialogAbortSignal(opts)), {
3292
3349
  id: "pi2dsh-device-code",
3293
- question: String(title),
3294
- detail: String(detail),
3350
+ ...projectDialogPrompt(title, detail, dialogLinkMode),
3295
3351
  options: [{ label: "Cancel login" }]
3296
3352
  });
3297
3353
  },
3298
3354
  editor: (title, prefill) => askOne(ctx, agent, signal, {
3299
3355
  id: "pi2dsh-editor",
3300
- question: String(title),
3301
- ...prefill === void 0 ? {} : { detail: `Current text:\n${String(prefill)}` }
3356
+ ...projectDialogPrompt(title, prefill === void 0 ? void 0 : `Current text:\n${String(prefill)}`, dialogLinkMode)
3302
3357
  }),
3303
3358
  setStatus: (key, text) => {
3304
3359
  state.shared.browserSurfaces?.setStatus(sessionIdOf(state, agent), state.packageName, String(key), text);
@@ -6231,4 +6286,4 @@ const runtimeInternals = {
6231
6286
  //#endregion
6232
6287
  export { registerVisionCompanions as a, overlayProviderConfig as i, mergeProviderRegistration as n, runtimeInternals as o, normalizeToolSchema as r, applyPiPackage as t };
6233
6288
 
6234
- //# sourceMappingURL=runtime-D1DI60RQ.mjs.map
6289
+ //# sourceMappingURL=runtime-BlbKWw7W.mjs.map