@cydm/pie 1.0.50 → 1.0.51

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.
@@ -1,9 +1,9 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createAskUserCapability
4
- } from "../../../chunks/chunk-DZS34ACX.js";
5
- import "../../../chunks/chunk-FKAO25XH.js";
6
- import "../../../chunks/chunk-K6ZOCJ4V.js";
4
+ } from "../../../chunks/chunk-A644H2XX.js";
5
+ import "../../../chunks/chunk-B3SMW2XW.js";
6
+ import "../../../chunks/chunk-S2J3SZZX.js";
7
7
  import "../../../chunks/chunk-LZQXQOPJ.js";
8
8
 
9
9
  // builtin/extensions/ask-user/index.ts
@@ -13,6 +13,22 @@ var PYTHON_CANDIDATES = [
13
13
  function isTextCapable(model) {
14
14
  return (model.input ?? []).includes("text");
15
15
  }
16
+ function supportsInputKind(model, kind) {
17
+ return (model.input ?? []).includes(kind);
18
+ }
19
+ function mediaKindFor(mimeType) {
20
+ if (mimeType.startsWith("image/")) return "image";
21
+ if (mimeType.startsWith("video/")) return "video";
22
+ return void 0;
23
+ }
24
+ var DEFAULT_INLINE_LIMIT_MB = {
25
+ image: 10,
26
+ video: 15
27
+ };
28
+ function inlineLimitMb(model, kind) {
29
+ const configured = model.fileCapabilities?.[kind]?.maxFileSizeMb;
30
+ return typeof configured === "number" && configured > 0 ? configured : DEFAULT_INLINE_LIMIT_MB[kind];
31
+ }
16
32
  function isSupportedDocument(attachment) {
17
33
  return attachment.mimeType === "application/pdf" || attachment.mimeType === "text/html" || attachment.mimeType === "text/plain" || attachment.mimeType === "text/markdown" || attachment.mimeType === "application/json" || attachment.name.endsWith(".html") || attachment.name.endsWith(".htm") || attachment.name.endsWith(".md") || attachment.name.endsWith(".txt") || attachment.name.endsWith(".json") || attachment.name.endsWith(".pdf");
18
34
  }
@@ -138,6 +154,41 @@ function documentAttachmentsExtension(ctx) {
138
154
  };
139
155
  }
140
156
  });
157
+ ctx.registerAttachmentHandler({
158
+ name: "local-media-inline",
159
+ priority: 20,
160
+ matches(model, attachment) {
161
+ const kind = mediaKindFor(attachment.mimeType);
162
+ return Boolean(kind) && supportsInputKind(model, kind) && Boolean(attachment.path);
163
+ },
164
+ async prepare(model, attachment, prepareCtx) {
165
+ prepareCtx.log(`Media handler inlining ${attachment.mimeType} attachment ${attachment.name}`);
166
+ const kind = mediaKindFor(attachment.mimeType);
167
+ const limitMb = inlineLimitMb(model, kind);
168
+ const sizeMb = fs.statSync(attachment.path).size / (1024 * 1024);
169
+ if (sizeMb > limitMb) {
170
+ prepareCtx.log(`Media handler skipped ${attachment.name}: ${sizeMb.toFixed(1)}MB exceeds the ${limitMb}MB inline limit`);
171
+ return {
172
+ items: [
173
+ {
174
+ type: "text",
175
+ text: `[${attachment.name}: ${sizeMb.toFixed(1)}MB exceeds the ${limitMb}MB inline limit for this model \u2014 not attached. Compress or shrink the file first.]`
176
+ }
177
+ ],
178
+ warnings: [`${attachment.name} (${sizeMb.toFixed(1)}MB) exceeds the ${limitMb}MB inline limit and was not attached`]
179
+ };
180
+ }
181
+ return {
182
+ items: [
183
+ {
184
+ type: kind,
185
+ mimeType: attachment.mimeType,
186
+ path: attachment.path
187
+ }
188
+ ]
189
+ };
190
+ }
191
+ });
141
192
  }
142
193
  export {
143
194
  documentAttachmentsExtension as default
@@ -7,11 +7,11 @@ import {
7
7
  isPlanModeSafeCommand,
8
8
  markCompletedPlanSteps,
9
9
  restoreExecutionState
10
- } from "../../../chunks/chunk-DZS34ACX.js";
11
- import "../../../chunks/chunk-FKAO25XH.js";
10
+ } from "../../../chunks/chunk-A644H2XX.js";
11
+ import "../../../chunks/chunk-B3SMW2XW.js";
12
12
  import {
13
13
  Type
14
- } from "../../../chunks/chunk-K6ZOCJ4V.js";
14
+ } from "../../../chunks/chunk-S2J3SZZX.js";
15
15
  import "../../../chunks/chunk-LZQXQOPJ.js";
16
16
 
17
17
  // builtin/extensions/plan-mode/index.ts
@@ -1,13 +1,13 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createCliHostCapabilities
4
- } from "../../../chunks/chunk-XBWFDIAU.js";
4
+ } from "../../../chunks/chunk-KDPAGHYY.js";
5
5
  import {
6
6
  createSharedFileSystemTools,
7
7
  createSubagentCapability
8
- } from "../../../chunks/chunk-DZS34ACX.js";
9
- import "../../../chunks/chunk-FKAO25XH.js";
10
- import "../../../chunks/chunk-K6ZOCJ4V.js";
8
+ } from "../../../chunks/chunk-A644H2XX.js";
9
+ import "../../../chunks/chunk-B3SMW2XW.js";
10
+ import "../../../chunks/chunk-S2J3SZZX.js";
11
11
  import "../../../chunks/chunk-LZQXQOPJ.js";
12
12
 
13
13
  // builtin/extensions/subagent/index.ts
@@ -15,25 +15,20 @@ import * as os from "os";
15
15
  import * as path from "path";
16
16
  function subagentExtension(ctx) {
17
17
  ctx.log("Subagent extension loaded (transparent parallel mode)");
18
- let model = ctx.model;
19
- let apiKey = ctx.apiKey;
20
- if (!model || !apiKey) {
18
+ const resolveRuntimePair = () => {
19
+ if (ctx.model && ctx.apiKey) return { model: ctx.model, apiKey: ctx.apiKey };
21
20
  const fallback = ctx.resolveModelClass?.("balanced");
22
- if (fallback?.model && fallback?.apiKey) {
23
- model = fallback.model;
24
- apiKey = fallback.apiKey;
25
- }
26
- }
21
+ if (fallback?.model && fallback?.apiKey) return { model: fallback.model, apiKey: fallback.apiKey };
22
+ return {};
23
+ };
27
24
  const skills = ctx.skills || [];
28
- if (!apiKey) {
29
- ctx.log("Warning: No API key available for subagent.");
30
- }
31
- if (!model) {
32
- ctx.log("Warning: No model configured for subagent; tasks will fail until a model is available.");
33
- }
34
25
  const capability = createSubagentCapability({
35
- apiKey,
36
- model,
26
+ get apiKey() {
27
+ return resolveRuntimePair().apiKey;
28
+ },
29
+ get model() {
30
+ return resolveRuntimePair().model;
31
+ },
37
32
  skills,
38
33
  yoloMode: ctx.yoloMode,
39
34
  getParentTools: () => ctx.getAllTools(),
@@ -8,9 +8,9 @@ import {
8
8
  executeManageTodoList,
9
9
  executionStateToTodos,
10
10
  restoreExecutionState
11
- } from "../../../chunks/chunk-DZS34ACX.js";
12
- import "../../../chunks/chunk-FKAO25XH.js";
13
- import "../../../chunks/chunk-K6ZOCJ4V.js";
11
+ } from "../../../chunks/chunk-A644H2XX.js";
12
+ import "../../../chunks/chunk-B3SMW2XW.js";
13
+ import "../../../chunks/chunk-S2J3SZZX.js";
14
14
  import "../../../chunks/chunk-LZQXQOPJ.js";
15
15
 
16
16
  // builtin/extensions/todo/index.ts
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  Agent
4
- } from "./chunk-FKAO25XH.js";
4
+ } from "./chunk-B3SMW2XW.js";
5
5
  import {
6
6
  FileSystemGateway,
7
7
  Type,
@@ -11,7 +11,7 @@ import {
11
11
  getPlatformConfig,
12
12
  hashText,
13
13
  streamSimple
14
- } from "./chunk-K6ZOCJ4V.js";
14
+ } from "./chunk-S2J3SZZX.js";
15
15
  import {
16
16
  __commonJS,
17
17
  __toESM
@@ -1690,22 +1690,30 @@ function buildParallelResult(tasks, totalDuration) {
1690
1690
  `;
1691
1691
  return resultText;
1692
1692
  }
1693
+ var TASK_FIELD_ALIASES = ["task", "description", "prompt", "objective"];
1693
1694
  function normalizeTaskDefs(args) {
1694
1695
  const taskDefs = args?.tasks;
1695
1696
  if (!Array.isArray(taskDefs) || taskDefs.length === 0) {
1696
1697
  return { error: "Invalid spawn_subagents_parallel arguments: tasks must be a non-empty array." };
1697
1698
  }
1698
1699
  const normalized = [];
1700
+ const allowedFields = [...TASK_FIELD_ALIASES, "name", "priority", "timeout"];
1699
1701
  for (const [index, def] of taskDefs.entries()) {
1700
1702
  if (!def || typeof def !== "object") {
1701
- return { error: `Invalid task #${index + 1}: expected an object with task.` };
1703
+ return { error: `Invalid task #${index + 1}: expected an object with the objective in "task" (aliases "description"/"prompt"/"objective" accepted).` };
1702
1704
  }
1703
- if ("prompt" in def || "kind" in def || "max_turns" in def) {
1704
- return { error: "Invalid spawn_subagents_parallel arguments: use tasks[].task plus optional name/priority; prompt, kind, and max_turns are no longer supported." };
1705
+ const unknownFields = Object.keys(def).filter((key) => !allowedFields.includes(key));
1706
+ if (unknownFields.length > 0) {
1707
+ return { error: `Invalid task #${index + 1}: unknown field(s) ${unknownFields.map((key) => `"${key}"`).join(", ")}; allowed fields: ${allowedFields.map((key) => `"${key}"`).join(", ")}.` };
1705
1708
  }
1706
- const task = typeof def.task === "string" ? def.task.trim() : "";
1709
+ const taskValues = [
1710
+ ...new Set(
1711
+ TASK_FIELD_ALIASES.map((key) => typeof def[key] === "string" ? def[key].trim() : "").filter((value) => value.length > 0)
1712
+ )
1713
+ ];
1714
+ const task = taskValues.join("\n\n");
1707
1715
  if (!task) {
1708
- return { error: `Invalid task #${index + 1}: task cannot be empty.` };
1716
+ return { error: `Invalid task #${index + 1}: provide the objective in "task" (aliases "description"/"prompt"/"objective" are accepted).` };
1709
1717
  }
1710
1718
  const timeoutSeconds = "timeout" in def ? Number(def.timeout) : DEFAULT_SUBAGENT_TIMEOUT_SECONDS;
1711
1719
  if (!Number.isFinite(timeoutSeconds) || timeoutSeconds <= 0) {
@@ -1721,25 +1729,61 @@ function normalizeTaskDefs(args) {
1721
1729
  }
1722
1730
  return normalized;
1723
1731
  }
1732
+ var DEFAULT_MAX_CONCURRENT_SUBAGENTS = 4;
1733
+ var MAX_TRANSIENT_RETRIES = 2;
1734
+ var TRANSIENT_RETRY_BACKOFF_MS = 2e3;
1735
+ var TRANSIENT_ERROR_PATTERN = /econnreset|econnaborted|etimedout|timeout|enotfound|eai_again|econnrefused|socket hang up|sse stream aborted|fetch failed|status 5\d\d|bad gateway|service unavailable|overloaded/i;
1736
+ function isTransientNetworkError(message) {
1737
+ return TRANSIENT_ERROR_PATTERN.test(message);
1738
+ }
1739
+ function sleep(ms, signal) {
1740
+ return new Promise((resolve3) => {
1741
+ const timer = setTimeout(resolve3, ms);
1742
+ signal?.addEventListener(
1743
+ "abort",
1744
+ () => {
1745
+ clearTimeout(timer);
1746
+ resolve3();
1747
+ },
1748
+ { once: true }
1749
+ );
1750
+ });
1751
+ }
1752
+ async function runWithConcurrencyLimit(jobs, limit) {
1753
+ let next = 0;
1754
+ const workers = Array.from({ length: Math.max(1, Math.min(limit, jobs.length)) }, async () => {
1755
+ while (next < jobs.length) {
1756
+ const current = jobs[next++];
1757
+ await current();
1758
+ }
1759
+ });
1760
+ await Promise.all(workers);
1761
+ }
1724
1762
  function createSubagentCapability(deps) {
1725
1763
  const spawnParallelTool = {
1726
1764
  name: "spawn_subagents_parallel",
1727
1765
  label: "Spawn Subagents",
1728
1766
  description: `Spawn child agents to run bounded sub-tasks in parallel.
1729
1767
 
1730
- Use this for independent investigation, search, review, or triage work. Provide each task as a plain objective. Pie chooses the model class automatically. Use timeout only for unusually long tasks.`,
1768
+ Use this for independent investigation, search, review, or triage work. Provide each task as a plain objective. Pie chooses the model class automatically. Use timeout only for unusually long tasks.
1769
+
1770
+ Arguments shape (each tasks[] item puts the objective in "task" \u2014 "description"/"prompt"/"objective" are accepted as aliases):
1771
+ { "tasks": [{ "task": "<objective text>", "name": "<optional short label>", "priority": "fast" | "thorough", "timeout": 600 }] }`,
1731
1772
  parameters: Type.Object({
1732
1773
  tasks: Type.Array(
1733
1774
  Type.Object(
1734
1775
  {
1735
- task: Type.String({ description: "The bounded sub-task objective. Be specific and include expected output." }),
1776
+ task: Type.Optional(Type.String({ description: "The bounded sub-task objective. Be specific and include expected output. Preferred field name." })),
1777
+ description: Type.Optional(Type.String({ description: "Alias for task." })),
1778
+ prompt: Type.Optional(Type.String({ description: "Alias for task." })),
1779
+ objective: Type.Optional(Type.String({ description: "Alias for task." })),
1736
1780
  name: Type.Optional(Type.String({ description: "Short name for this subagent, shown in progress updates." })),
1737
1781
  priority: Type.Optional(Type.Union([Type.Literal("fast"), Type.Literal("thorough")], { description: "fast uses lower-cost defaults; thorough raises model class when needed." })),
1738
- timeout: Type.Optional(Type.Number({ description: "Timeout in seconds. Default: 1200s (20 minutes). For longer tasks, explicitly set a higher value, e.g. { timeout: 3600 }." }))
1782
+ timeout: Type.Optional(Type.Number({ description: "Timeout in seconds. Default: 1200s (20 minutes). For longer tasks, explicitly set a higher value, e.g. 3600." }))
1739
1783
  },
1740
- { additionalProperties: false }
1784
+ { additionalProperties: false, description: "Objective goes in 'task' (or an accepted alias); plus optional name/priority/timeout." }
1741
1785
  ),
1742
- { description: "Array of tasks to run in parallel", minItems: 1, maxItems: 10 }
1786
+ { description: "Array of tasks to run in parallel; at least one of task/description/prompt/objective must be a non-empty string per item.", minItems: 1, maxItems: 10 }
1743
1787
  )
1744
1788
  }, { additionalProperties: false }),
1745
1789
  async execute(first, second, third, fourth) {
@@ -1782,7 +1826,30 @@ Use this for independent investigation, search, review, or triage work. Provide
1782
1826
  toolContext.log?.(`Spawning ${tasks.length} parallel subagents: ${tasks.map((task) => task.name).join(", ")}`);
1783
1827
  toolContext.reportProgress?.({ message: `Launching ${tasks.length} parallel subagents...`, increment: 5 });
1784
1828
  const startTime = Date.now();
1785
- await Promise.all(tasks.map((task) => runSubagentWithProgress(deps, task, toolContext.reportProgress, signal)));
1829
+ const runTask = async (task) => {
1830
+ for (let attempt = 0; ; attempt++) {
1831
+ await runSubagentWithProgress(deps, task, toolContext.reportProgress, signal);
1832
+ const canRetry = task.status === "failed" && isTransientNetworkError(task.error ?? "") && attempt < MAX_TRANSIENT_RETRIES && !signal?.aborted;
1833
+ if (!canRetry) return;
1834
+ const failureReason = task.error ?? "unknown";
1835
+ task.evidence.length = 0;
1836
+ task.runtimeEvidence.length = 0;
1837
+ task.reportedEvidence.length = 0;
1838
+ task.confidenceSignals.length = 0;
1839
+ task.status = "pending";
1840
+ task.error = void 0;
1841
+ task.completedAt = void 0;
1842
+ const backoffMs = (deps.transientRetryBackoffMs ?? TRANSIENT_RETRY_BACKOFF_MS) * (attempt + 1);
1843
+ toolContext.reportProgress?.({ message: `[${task.name}] Transient error, retrying in ${Math.round(backoffMs / 1e3)}s (attempt ${attempt + 2}/${MAX_TRANSIENT_RETRIES + 1})...` });
1844
+ deps.log(`[subagent] ${task.name} failed with a transient error (${failureReason}); retrying`);
1845
+ await sleep(backoffMs, signal);
1846
+ if (signal?.aborted) return;
1847
+ }
1848
+ };
1849
+ await runWithConcurrencyLimit(
1850
+ tasks.map((task) => () => runTask(task)),
1851
+ Math.max(1, deps.maxConcurrentSubagents ?? DEFAULT_MAX_CONCURRENT_SUBAGENTS)
1852
+ );
1786
1853
  const totalDuration = Date.now() - startTime;
1787
1854
  const completed = tasks.filter((task) => task.status === "completed").length;
1788
1855
  const failed = tasks.filter((task) => task.status === "failed" || task.status === "timeout").length;
@@ -2582,14 +2649,14 @@ function isTransientFileError(error) {
2582
2649
  const message = error instanceof Error ? error.message : String(error);
2583
2650
  return /^(EPERM|EACCES|EBUSY|ENOTEMPTY)$/.test(code) || /\b(EPERM|EACCES|EBUSY|locked|busy)\b/i.test(message);
2584
2651
  }
2585
- function sleep(ms) {
2652
+ function sleep2(ms) {
2586
2653
  return new Promise((resolve3) => setTimeout(resolve3, ms));
2587
2654
  }
2588
2655
  async function retryFileOperation(operation, retryDelaysMs) {
2589
2656
  let lastError;
2590
2657
  for (const [index, delayMs] of retryDelaysMs.entries()) {
2591
2658
  if (delayMs > 0) {
2592
- await sleep(delayMs);
2659
+ await sleep2(delayMs);
2593
2660
  }
2594
2661
  try {
2595
2662
  operation();
@@ -3978,7 +4045,8 @@ var SessionManager = class {
3978
4045
  name: newName ?? `${this.activeSession.metadata.name} (Branch)`,
3979
4046
  createdAt: now,
3980
4047
  updatedAt: now,
3981
- tags: this.activeSession.metadata.tags
4048
+ tags: this.activeSession.metadata.tags,
4049
+ cwd: this.activeSession.metadata.cwd
3982
4050
  }
3983
4051
  );
3984
4052
  return newSessionId;
@@ -4015,7 +4083,8 @@ var SessionManager = class {
4015
4083
  createdAt: now,
4016
4084
  updatedAt: now,
4017
4085
  activeEntryId: newActiveEntryId,
4018
- tags: this.activeSession.metadata.tags
4086
+ tags: this.activeSession.metadata.tags,
4087
+ cwd: this.activeSession.metadata.cwd
4019
4088
  }
4020
4089
  );
4021
4090
  return newSessionId;
@@ -3,7 +3,7 @@ import {
3
3
  EventStream,
4
4
  streamSimple,
5
5
  validateToolArguments
6
- } from "./chunk-K6ZOCJ4V.js";
6
+ } from "./chunk-S2J3SZZX.js";
7
7
 
8
8
  // ../../packages/agent-core/src/agent-loop.ts
9
9
  function createLoopErrorMessage(error, config, signal) {
@@ -8,10 +8,10 @@ import {
8
8
  createSharedWebSearchTool,
9
9
  interpretShellExit,
10
10
  requestInteraction
11
- } from "./chunk-DZS34ACX.js";
11
+ } from "./chunk-A644H2XX.js";
12
12
  import {
13
13
  Type
14
- } from "./chunk-K6ZOCJ4V.js";
14
+ } from "./chunk-S2J3SZZX.js";
15
15
 
16
16
  // src/config.ts
17
17
  import { existsSync, mkdirSync, readFileSync, renameSync } from "fs";
@@ -9911,7 +9911,50 @@ function validateToolArguments(tool, toolCall) {
9911
9911
  throw new Error(`Invalid arguments for tool "${tool.name}"`);
9912
9912
  }
9913
9913
  const path = firstError.path || "/";
9914
- throw new Error(`Invalid arguments for tool "${tool.name}" at ${path}: ${firstError.message}`);
9914
+ const hint = buildArgumentHint(tool.parameters, firstError.path || "", args);
9915
+ throw new Error(
9916
+ `Invalid arguments for tool "${tool.name}" at ${path}: ${firstError.message}${hint ? `; ${hint}` : ""}`
9917
+ );
9918
+ }
9919
+ function buildArgumentHint(schema, errorPath, args) {
9920
+ const parentPath = errorPath.includes("/") ? errorPath.slice(0, errorPath.lastIndexOf("/")) : "";
9921
+ const node = resolveSchemaNode(schema, parentPath);
9922
+ if (!node || typeof node !== "object" || !node.properties) return "";
9923
+ const parts = [];
9924
+ const allowed = Object.keys(node.properties);
9925
+ if (allowed.length > 0) parts.push(`allowed keys: [${allowed.join(", ")}]`);
9926
+ if (Array.isArray(node.required) && node.required.length > 0) {
9927
+ parts.push(`required: [${node.required.map(String).join(", ")}]`);
9928
+ }
9929
+ const received = receivedKeysAt(args, parentPath);
9930
+ if (received) parts.push(`received keys: [${received.join(", ")}]`);
9931
+ return parts.join("; ");
9932
+ }
9933
+ function resolveSchemaNode(schema, path) {
9934
+ let node = schema;
9935
+ for (const segment of path.split("/").filter(Boolean)) {
9936
+ if (!node || typeof node !== "object") return void 0;
9937
+ if (/^\d+$/.test(segment)) {
9938
+ node = node.items;
9939
+ } else if (node.properties && segment in node.properties) {
9940
+ node = node.properties[segment];
9941
+ } else if (node.additionalProperties && typeof node.additionalProperties === "object") {
9942
+ node = node.additionalProperties;
9943
+ } else {
9944
+ return void 0;
9945
+ }
9946
+ }
9947
+ return node;
9948
+ }
9949
+ function receivedKeysAt(args, path) {
9950
+ let target = args;
9951
+ for (const segment of path.split("/").filter(Boolean)) {
9952
+ target = target?.[segment];
9953
+ }
9954
+ if (target && typeof target === "object" && !Array.isArray(target)) {
9955
+ return Object.keys(target);
9956
+ }
9957
+ return void 0;
9915
9958
  }
9916
9959
 
9917
9960
  // ../../packages/ai/src/index.ts
@@ -3,8 +3,8 @@ import {
3
3
  Agent,
4
4
  agentLoop,
5
5
  agentLoopContinue
6
- } from "./chunk-FKAO25XH.js";
7
- import "./chunk-K6ZOCJ4V.js";
6
+ } from "./chunk-B3SMW2XW.js";
7
+ import "./chunk-S2J3SZZX.js";
8
8
  import "./chunk-LZQXQOPJ.js";
9
9
  export {
10
10
  Agent,
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  EventStream
4
- } from "./chunk-K6ZOCJ4V.js";
4
+ } from "./chunk-S2J3SZZX.js";
5
5
  import "./chunk-LZQXQOPJ.js";
6
6
 
7
7
  // src/app/test-stream.ts
package/dist/cli.js CHANGED
@@ -22,7 +22,7 @@ import {
22
22
  getThemesDir,
23
23
  migrateConfigFromAgentDir,
24
24
  truncateHeadTail
25
- } from "./chunks/chunk-XBWFDIAU.js";
25
+ } from "./chunks/chunk-KDPAGHYY.js";
26
26
  import {
27
27
  AGENTS_CONTEXT_FILE_NAME,
28
28
  AgentSessionController,
@@ -73,8 +73,8 @@ import {
73
73
  setExtensionEnabledInSettings,
74
74
  shouldPreserveExecutionStateForUserText,
75
75
  supersedeExecutionState
76
- } from "./chunks/chunk-DZS34ACX.js";
77
- import "./chunks/chunk-FKAO25XH.js";
76
+ } from "./chunks/chunk-A644H2XX.js";
77
+ import "./chunks/chunk-B3SMW2XW.js";
78
78
  import {
79
79
  Deref,
80
80
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -110,7 +110,7 @@ import {
110
110
  setLogger,
111
111
  sortToolModelCandidatesByCapability,
112
112
  type_exports
113
- } from "./chunks/chunk-K6ZOCJ4V.js";
113
+ } from "./chunks/chunk-S2J3SZZX.js";
114
114
  import {
115
115
  __commonJS,
116
116
  __require,
@@ -60809,6 +60809,10 @@ var FileManager = class {
60809
60809
  getPlatformName() {
60810
60810
  return this.platform;
60811
60811
  }
60812
+ /** Whether the active platform has a registered upload adapter. */
60813
+ hasAdapter() {
60814
+ return this.sessionManager.getAdapter(this.platform) !== void 0;
60815
+ }
60812
60816
  getPlatformDisplayName() {
60813
60817
  return getProviderDisplayName(this.platform);
60814
60818
  }
@@ -62674,7 +62678,7 @@ function handleExtensionsCommand(host, args) {
62674
62678
 
62675
62679
  // src/slash-commands.ts
62676
62680
  var BUILTIN_SLASH_COMMANDS = [
62677
- { name: "sessions", description: "Pick a saved session to switch to" },
62681
+ { name: "sessions", description: "Manage sessions: resume, new, tree, fork, compact, info" },
62678
62682
  { name: "sessions/compact", description: "Summarize history and add a compact checkpoint to the session" },
62679
62683
  { name: "sessions/new", description: "Start a new session" },
62680
62684
  { name: "sessions/resume", description: "Resume a different session" },
@@ -63111,10 +63115,12 @@ var SessionSelectorComponent = class extends Container {
63111
63115
  }
63112
63116
  createItem(session) {
63113
63117
  const cwdTag = formatSessionCwdTag(session.cwd, this.options.currentCwd, this.options.homeDir);
63118
+ const unknownTag = cwdTag === void 0 && this.options.currentCwd && !(typeof session.cwd === "string" && session.cwd.length > 0) ? "unknown path" : void 0;
63119
+ const tag = cwdTag ?? unknownTag;
63114
63120
  return {
63115
63121
  value: session.id,
63116
63122
  label: session.name || `Session ${session.id.slice(0, 8)}`,
63117
- description: cwdTag ? `${cwdTag} \xB7 ${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}` : `${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}`
63123
+ description: tag ? `${tag} \xB7 ${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}` : `${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}`
63118
63124
  };
63119
63125
  }
63120
63126
  clearRefreshTimer() {
@@ -64843,6 +64849,7 @@ async function loadSession2(host, sessionId) {
64843
64849
  }
64844
64850
  setControllerBusy(host, false);
64845
64851
  setWaitingForUser(host, false);
64852
+ await host.initializeFileManager();
64846
64853
  const activeSession = host.sessionManager.getActiveSession();
64847
64854
  if (activeSession) {
64848
64855
  host.agent.sessionId = activeSession.id;
@@ -66175,7 +66182,10 @@ async function handleClearCommand(host) {
66175
66182
  if (activeSession) {
66176
66183
  host.agent.sessionId = activeSession.id;
66177
66184
  activeSession.metadata.executionState = host.executionState.createMetadata();
66185
+ activeSession.metadata.cwd = host.options.cwd;
66186
+ activeSession.isDirty = true;
66178
66187
  }
66188
+ await host.initializeFileManager();
66179
66189
  host.syncAgentFromActiveSession();
66180
66190
  host.syncSessionModelMetadata();
66181
66191
  host.planModeEnabled = false;
@@ -66328,8 +66338,7 @@ function createExtensionContextForCommands(host) {
66328
66338
  }
66329
66339
  function registerBuiltinCommands(host) {
66330
66340
  commandTree.register(["sessions"], {
66331
- description: "Pick a saved session to switch to (tree/fork/new below)",
66332
- handler: () => host.handleResumeCommand()
66341
+ description: "Manage sessions: resume, new, tree, fork, compact, info"
66333
66342
  });
66334
66343
  commandTree.register(["sessions", "compact"], {
66335
66344
  description: "Summarize history and replace it with a compact checkpoint",
@@ -68321,7 +68330,11 @@ var MentionHandler = class {
68321
68330
  this.pushPendingStatus(pendingStatusKey, `Preparing ${option.name}...`);
68322
68331
  }
68323
68332
  const mimeType = FileCache.getMimeType(option.path);
68324
- const shouldStageLocally = !mimeType.startsWith("image/") && !mimeType.startsWith("video/");
68333
+ const isMedia = mimeType.startsWith("image/") || mimeType.startsWith("video/");
68334
+ const shouldStageLocally = !isMedia || !this.fileManager.hasAdapter();
68335
+ if (isMedia && shouldStageLocally) {
68336
+ this.pushPendingStatus(pendingStatusKey, `Staging ${option.name} locally (no upload API for this provider)...`);
68337
+ }
68325
68338
  const onProgress = (progress, stage) => {
68326
68339
  this.pushPendingStatus(
68327
68340
  pendingStatusKey,
@@ -68729,7 +68742,7 @@ var MentionHandler = class {
68729
68742
  async function initializeFileManager(host) {
68730
68743
  const sessionId = host.sessionManager.getActiveSession()?.id;
68731
68744
  if (!sessionId) return;
68732
- const platform2 = host.options.model?.filePlatform || "unknown";
68745
+ const platform2 = host.options.model?.filePlatform || host.options.model?.attachmentPlatform || "unknown";
68733
68746
  host.fileManager = new FileManager({
68734
68747
  sessionId,
68735
68748
  platform: platform2,
@@ -68737,7 +68750,7 @@ async function initializeFileManager(host) {
68737
68750
  baseDir: path28.join(host.options.configDir, "files"),
68738
68751
  sessionsDir: path28.join(host.options.configDir, "sessions")
68739
68752
  });
68740
- switch (getFileManagerAdapterKind(host.options.model?.filePlatform)) {
68753
+ switch (getFileManagerAdapterKind(platform2)) {
68741
68754
  case "kimi":
68742
68755
  if (host.options.model?.baseUrl) {
68743
68756
  host.fileManager.registerAdapter(new KimiFileAdapter(host.options.apiKey, host.options.model.baseUrl));
@@ -68746,6 +68759,13 @@ async function initializeFileManager(host) {
68746
68759
  case "gemini":
68747
68760
  host.fileManager.registerAdapter(new GeminiFileAdapter(host.options.apiKey));
68748
68761
  break;
68762
+ case "openai-compatible-files":
68763
+ if (host.options.model?.baseUrl) {
68764
+ host.fileManager.registerAdapter(
68765
+ new OpenAICompatibleFilesAdapter(host.options.apiKey, host.options.model.baseUrl, host.options.model.headers)
68766
+ );
68767
+ }
68768
+ break;
68749
68769
  default:
68750
68770
  break;
68751
68771
  }
@@ -71970,7 +71990,7 @@ var InteractiveMode = class {
71970
71990
  async init() {
71971
71991
  const activeSession = this.sessionManager.getActiveSession();
71972
71992
  this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
71973
- const { Agent } = await import("./chunks/src-HYZFAW4V.js");
71993
+ const { Agent } = await import("./chunks/src-UKCIAX6F.js");
71974
71994
  this.agent = new Agent({
71975
71995
  initialState: {
71976
71996
  systemPrompt: this.buildSystemPrompt(),
@@ -72471,6 +72491,7 @@ async function composeCliRuntime(params) {
72471
72491
  });
72472
72492
  const cwd = params.cwd ?? process.cwd();
72473
72493
  const sessionManager = createSessionManager({ sessionsDir: paths.sessionsDir });
72494
+ let createdNewSession = false;
72474
72495
  if (params.explicitSessionId) {
72475
72496
  const sessionFileExists = params.requireExistingSession ? await sessionManager.hasSession(params.explicitSessionId) : false;
72476
72497
  const loaded = await sessionManager.loadSession(params.explicitSessionId, {
@@ -72484,6 +72505,7 @@ async function composeCliRuntime(params) {
72484
72505
  );
72485
72506
  }
72486
72507
  await sessionManager.createSession(void 0, void 0, params.explicitSessionId);
72508
+ createdNewSession = true;
72487
72509
  } else {
72488
72510
  const restored = restoreSessionModelState({
72489
72511
  activeSession: sessionManager.getActiveSession(),
@@ -72503,10 +72525,11 @@ async function composeCliRuntime(params) {
72503
72525
  }
72504
72526
  } else {
72505
72527
  await sessionManager.createSession();
72528
+ createdNewSession = true;
72506
72529
  }
72507
72530
  const activeSession = sessionManager.getActiveSession();
72508
72531
  syncSessionModelMetadata(sessionManager, model, resolveInitialThinkingLevel({ session: activeSession, settingsManager }));
72509
- if (activeSession && activeSession.metadata.cwd !== cwd) {
72532
+ if (activeSession && createdNewSession) {
72510
72533
  activeSession.metadata.cwd = cwd;
72511
72534
  await sessionManager.save();
72512
72535
  }
@@ -72780,7 +72803,7 @@ async function runPrintMode(params) {
72780
72803
  `);
72781
72804
  console.log("Assistant: ");
72782
72805
  }
72783
- const { Agent: AgentClass } = await import("./chunks/src-HYZFAW4V.js");
72806
+ const { Agent: AgentClass } = await import("./chunks/src-UKCIAX6F.js");
72784
72807
  let agent;
72785
72808
  const printModeExtensions = await loadPrintModeExtensions({
72786
72809
  cwd: runtime.cwd,
@@ -73339,8 +73362,12 @@ async function runJsonEventsMode(params) {
73339
73362
  }
73340
73363
  }
73341
73364
  metadata.name = typeof existing?.name === "string" ? existing.name : `Session ${sessionId.slice(0, 8)}`;
73342
- if (cwd || existing?.cwd || runtime?.cwd) {
73343
- metadata.cwd = cwd ?? existing?.cwd ?? runtime?.cwd;
73365
+ if (existing) {
73366
+ if (existing.cwd) {
73367
+ metadata.cwd = cwd ?? existing.cwd;
73368
+ }
73369
+ } else if (cwd || runtime?.cwd) {
73370
+ metadata.cwd = cwd ?? runtime?.cwd;
73344
73371
  }
73345
73372
  metadata.activeEntryId = activeEntryId;
73346
73373
  metadata.rootEntryId = existing?.rootEntryId ?? rootEntryId;
@@ -73621,7 +73648,7 @@ async function runJsonEventsMode(params) {
73621
73648
  return;
73622
73649
  }
73623
73650
  const parent = agent;
73624
- const { Agent: AgentClass } = await import("./chunks/src-HYZFAW4V.js");
73651
+ const { Agent: AgentClass } = await import("./chunks/src-UKCIAX6F.js");
73625
73652
  const sideAgent = new AgentClass({
73626
73653
  initialState: {
73627
73654
  systemPrompt: parent.state.systemPrompt,
@@ -73947,7 +73974,7 @@ async function runJsonEventsMode(params) {
73947
73974
  if (runtime.initialModel.unconfigured || controller) {
73948
73975
  return;
73949
73976
  }
73950
- const { Agent: AgentClass } = await import("./chunks/src-HYZFAW4V.js");
73977
+ const { Agent: AgentClass } = await import("./chunks/src-UKCIAX6F.js");
73951
73978
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
73952
73979
  const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
73953
73980
  const restoredApiKey = runtime.modelRegistry.getApiKey(runtime.model);
@@ -74536,7 +74563,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
74536
74563
  }
74537
74564
  async function createCliTestStreamFnFromEnv() {
74538
74565
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
74539
- return (await import("./chunks/test-stream-5T7E7C25.js")).createTestStreamFnFromSequenceEnv();
74566
+ return (await import("./chunks/test-stream-NCBFPM2I.js")).createTestStreamFnFromSequenceEnv();
74540
74567
  }
74541
74568
  function resolveJsonEventsDetailFlag() {
74542
74569
  for (let index = 0; index < process.argv.length; index += 1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "1.0.50",
3
+ "version": "1.0.51",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {