@cydm/pie 2.6.0 → 2.6.1

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,7 +1,7 @@
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-AZ336HKF.js";
4
+ } from "../../../chunks/chunk-IKLQHWY2.js";
5
5
  import "../../../chunks/chunk-Y4CYXJR7.js";
6
6
  import "../../../chunks/chunk-O2DKMLNX.js";
7
7
  import "../../../chunks/chunk-XXGYUYXI.js";
@@ -7932,7 +7932,7 @@ function currentLookOrThrow() {
7932
7932
  }
7933
7933
  function ensurePointIsInLookImage(x, y, look, errorPrefix = "Coordinates") {
7934
7934
  if (!look.image?.jpegBase64) {
7935
- throw new Error(`${errorPrefix} require an image-bearing root. This look is outline-only; use an @e ref with a semantic action or observe an image-bearing root.`);
7935
+ throw new Error(`${errorPrefix} require an image-bearing root, but this look is outline-only. If the action already used an @e ref, that element exposes no semantic action here (text input or picture-only) and fell back to coordinates. Call observe_ui with mode "visual" to capture an image, then act again by @e ref or by coordinates from that image.`);
7936
7936
  }
7937
7937
  if (!Number.isFinite(x) || !Number.isFinite(y)) {
7938
7938
  throw new Error(`${errorPrefix} must be finite numbers.`);
@@ -8279,6 +8279,13 @@ function validateCondition(params) {
8279
8279
  if (value && !params.ref) throw new Error("A value UI condition requires an exact ref.");
8280
8280
  return { text, role, value, scopeRef, scopeExact: Boolean(params.ref), gone: params.until === "absent", timeoutMs: normalizeWaitTimeoutMs(params.timeoutMs) };
8281
8281
  }
8282
+ function expectCondition(expect) {
8283
+ if (!expect) return void 0;
8284
+ const hasMatcher = Boolean(trimOrUndefined(expect.text) ?? trimOrUndefined(expect.role) ?? trimOrUndefined(expect.value));
8285
+ const hasScope = Boolean(conditionScopeRef(expect));
8286
+ if (!hasMatcher && !hasScope) return void 0;
8287
+ return validateCondition(expect);
8288
+ }
8282
8289
  function nodeWithinScope(node, scopeRef, scopeExact) {
8283
8290
  if (!scopeRef) return true;
8284
8291
  if (scopeExact) return node.ref === scopeRef;
@@ -8696,7 +8703,7 @@ async function performDesktopTransaction(params, actions, signal) {
8696
8703
  validateStateId(params.stateId);
8697
8704
  const look = currentLookOrThrow();
8698
8705
  const baseView = { stateId: state.currentCapture.stateId, outline: state.currentOutline };
8699
- const condition = params.expect ? validateCondition(params.expect) : void 0;
8706
+ const condition = expectCondition(params.expect);
8700
8707
  const scopeNode = condition ? conditionScopeNode(look.parsedOutline, condition) : void 0;
8701
8708
  const target = await ensureTargetWindowId(await resolveCurrentTarget(signal), signal);
8702
8709
  const noteBefore = state.currentNote;
@@ -8759,7 +8766,7 @@ async function performBrowserTransaction(params, actions, signal) {
8759
8766
  const baseSnapshot = operationState().browserSnapshot;
8760
8767
  if (!baseSnapshot) throw new Error("Browser transaction requires a complete base observation.");
8761
8768
  const baseView = { stateId: baseSnapshot.snapshotId, outline: baseSnapshot.outline };
8762
- const condition = params.expect ? validateCondition(params.expect) : void 0;
8769
+ const condition = expectCondition(params.expect);
8763
8770
  if (condition) conditionScopeNode(restoreOutline(baseSnapshot.outline), condition);
8764
8771
  const prepared = actions.map((action) => {
8765
8772
  if (!BROWSER_TRANSACTION_ACTIONS.has(action.action)) throw new Error(`Browser transactions do not support '${action.action}'.`);
@@ -7,7 +7,7 @@ import {
7
7
  isPlanModeSafeCommand,
8
8
  markCompletedPlanSteps,
9
9
  restoreExecutionState
10
- } from "../../../chunks/chunk-AZ336HKF.js";
10
+ } from "../../../chunks/chunk-IKLQHWY2.js";
11
11
  import "../../../chunks/chunk-Y4CYXJR7.js";
12
12
  import "../../../chunks/chunk-O2DKMLNX.js";
13
13
  import {
@@ -1,11 +1,11 @@
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-G6KCJA6B.js";
4
+ } from "../../../chunks/chunk-3F5ZP2CV.js";
5
5
  import {
6
6
  createSharedFileSystemTools,
7
7
  createSubagentCapability
8
- } from "../../../chunks/chunk-AZ336HKF.js";
8
+ } from "../../../chunks/chunk-IKLQHWY2.js";
9
9
  import "../../../chunks/chunk-Y4CYXJR7.js";
10
10
  import "../../../chunks/chunk-O2DKMLNX.js";
11
11
  import "../../../chunks/chunk-5353DEEC.js";
@@ -8,7 +8,7 @@ import {
8
8
  executeManageTodoList,
9
9
  executionStateToTodos,
10
10
  restoreExecutionState
11
- } from "../../../chunks/chunk-AZ336HKF.js";
11
+ } from "../../../chunks/chunk-IKLQHWY2.js";
12
12
  import "../../../chunks/chunk-Y4CYXJR7.js";
13
13
  import "../../../chunks/chunk-O2DKMLNX.js";
14
14
  import "../../../chunks/chunk-XXGYUYXI.js";
@@ -8,7 +8,7 @@ import {
8
8
  createSharedWebSearchTool,
9
9
  interpretShellExit,
10
10
  requestInteraction
11
- } from "./chunk-AZ336HKF.js";
11
+ } from "./chunk-IKLQHWY2.js";
12
12
  import {
13
13
  getBuiltinDir,
14
14
  getConfigDir
@@ -1525,6 +1525,9 @@ function buildSubagentPlan(deps, task, name, priority, timeoutSeconds, modelOver
1525
1525
  };
1526
1526
  return { plan, tools: filteredTools, apiKey, model };
1527
1527
  }
1528
+ function subagentOutputBudget(model) {
1529
+ return Math.min(model.maxTokens || 8192, 16384);
1530
+ }
1528
1531
  function createAgentInstance(deps, systemPrompt, tools, model, apiKey, thinkingLevel) {
1529
1532
  if (deps.createAgent) {
1530
1533
  return deps.createAgent({
@@ -1542,7 +1545,14 @@ function createAgentInstance(deps, systemPrompt, tools, model, apiKey, thinkingL
1542
1545
  tools,
1543
1546
  thinkingLevel
1544
1547
  },
1545
- apiKey
1548
+ apiKey,
1549
+ // Subagent turns are single-purpose report generations: request an
1550
+ // explicit output budget (see subagentOutputBudget) instead of leaving
1551
+ // it to endpoint defaults that silently truncate long reports.
1552
+ streamFn: (streamModel, context, options) => streamSimple(streamModel, context, {
1553
+ ...options,
1554
+ maxTokens: options?.maxTokens ?? subagentOutputBudget(streamModel)
1555
+ })
1546
1556
  });
1547
1557
  }
1548
1558
  function extractEvidenceFromToolArgs(toolName, args) {
@@ -1629,6 +1639,7 @@ ${formatSkillsForPrompt(deps.skills ?? [])}`;
1629
1639
  const subagent = createAgentInstance(deps, systemPrompt, tools, model, apiKey, plan.thinkingLevel);
1630
1640
  let assistantTurns = 0;
1631
1641
  let toolCalls = 0;
1642
+ let outputTruncated = false;
1632
1643
  let rejectTimeout = () => void 0;
1633
1644
  let timeout;
1634
1645
  let unsubscribe;
@@ -1675,6 +1686,7 @@ ${formatSkillsForPrompt(deps.skills ?? [])}`;
1675
1686
  }
1676
1687
  if (event.type === "message_end" && event.message?.role === "assistant") {
1677
1688
  assistantTurns++;
1689
+ if (event.message.stopReason === "length") outputTruncated = true;
1678
1690
  }
1679
1691
  });
1680
1692
  let prompt = task.task;
@@ -1701,7 +1713,19 @@ ${formatSkillsForPrompt(deps.skills ?? [])}`;
1701
1713
  }
1702
1714
  const messages = subagent.state.messages;
1703
1715
  deps.log(`[Subagent ${task.name}] Total messages: ${messages.length}`);
1704
- const response = collectLastAssistantText(messages) || "[No response]";
1716
+ const lastAssistant = [...messages].reverse().find((m) => m?.role === "assistant");
1717
+ const terminalStopReason = lastAssistant?.stopReason;
1718
+ const terminalError = typeof lastAssistant?.errorMessage === "string" ? lastAssistant.errorMessage : void 0;
1719
+ const collectedResponse = collectLastAssistantText(messages);
1720
+ if (terminalStopReason === "error" || terminalStopReason === "aborted" || terminalError || !collectedResponse) {
1721
+ const detail = terminalError ? `: ${terminalError.slice(0, 200)}` : "";
1722
+ throw new Error(`Subagent stream interrupted (SSE stream aborted before the report was produced, stopReason=${terminalStopReason ?? "none"}${collectedResponse ? ", partial transcript discarded" : ", no text response"})${detail}`);
1723
+ }
1724
+ let response = collectedResponse;
1725
+ if (outputTruncated) {
1726
+ task.confidenceSignals.push({ type: "output_truncated", message: "final response hit the provider's output token limit" });
1727
+ response += "\n\n[Incomplete report: the subagent's final response was cut off by the provider's output token limit (stopReason=length). The items above may be a partial list \u2014 rerun the task with a narrower scope, or ask for the remaining items.]";
1728
+ }
1705
1729
  const reportedEvidence = extractEvidenceFromText(response).map((evidence) => ({ ...evidence, source: "reported" }));
1706
1730
  task.evidence.push(...reportedEvidence.map(({ source: _source, ...evidence }) => evidence));
1707
1731
  task.reportedEvidence.push(...reportedEvidence);
@@ -1715,9 +1739,10 @@ ${formatSkillsForPrompt(deps.skills ?? [])}`;
1715
1739
  task.details = {
1716
1740
  turns: assistantTurns,
1717
1741
  toolCalls,
1718
- durationMs
1742
+ durationMs,
1743
+ ...outputTruncated ? { outputTruncated: true } : {}
1719
1744
  };
1720
- task.parentHandoffRequired = isParentHandoffRequired(task);
1745
+ task.parentHandoffRequired = isParentHandoffRequired(task) || outputTruncated;
1721
1746
  task.completedAt = Date.now();
1722
1747
  reportProgress({ message: `[${task.name}] Completed (${durationMs}ms, ${toolCalls} tools)`, increment: 100 });
1723
1748
  } catch (error) {
@@ -12844,7 +12869,7 @@ function createGrepTextTool(cwd, options) {
12844
12869
  Type.Boolean({ description: "Treat pattern as literal string instead of regex (default: false)" })
12845
12870
  ),
12846
12871
  context: Type.Optional(
12847
- Type.Integer({ minimum: 0, maximum: MAX_GREP_CONTEXT_LINES, description: `Number of lines to show before and after each match (default: 0, maximum: ${MAX_GREP_CONTEXT_LINES})` })
12872
+ Type.Integer({ minimum: 0, maximum: MAX_GREP_CONTEXT_LINES * 10, description: `Number of lines to show before and after each match (default: 0; values above ${MAX_GREP_CONTEXT_LINES} are clamped to ${MAX_GREP_CONTEXT_LINES})` })
12848
12873
  ),
12849
12874
  outputMode: Type.Optional(Type.Union([
12850
12875
  Type.Literal("content"),
@@ -12899,8 +12924,7 @@ function createGrepTextTool(cwd, options) {
12899
12924
  const offset = normalizeNonNegativeInteger(rawOffset, 0, "offset");
12900
12925
  const effectiveLimit = normalizeNonNegativeInteger(limit, DEFAULT_LIMIT2, "limit");
12901
12926
  if (effectiveLimit < 1 || effectiveLimit > MAX_GREP_RESULT_LIMIT) throw new Error(`Invalid grep_text arguments: limit must be between 1 and ${MAX_GREP_RESULT_LIMIT}.`);
12902
- const ctx = normalizeNonNegativeInteger(contextLines, 0, "context");
12903
- if (ctx > MAX_GREP_CONTEXT_LINES) throw new Error(`Invalid grep_text arguments: context must be at most ${MAX_GREP_CONTEXT_LINES}.`);
12927
+ const ctx = Math.min(normalizeNonNegativeInteger(contextLines, 0, "context"), MAX_GREP_CONTEXT_LINES);
12904
12928
  let isDir;
12905
12929
  try {
12906
12930
  const stat = await fs2.stat(searchPath);
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createCliWebResearchHealthStore,
8
8
  formatSize,
9
9
  truncateHeadTail
10
- } from "./chunks/chunk-G6KCJA6B.js";
10
+ } from "./chunks/chunk-3F5ZP2CV.js";
11
11
  import {
12
12
  AGENTS_CONTEXT_FILE_NAME,
13
13
  AgentSessionController,
@@ -60,7 +60,7 @@ import {
60
60
  setExtensionEnabledInSettings,
61
61
  shouldPreserveExecutionStateForUserText,
62
62
  supersedeExecutionState
63
- } from "./chunks/chunk-AZ336HKF.js";
63
+ } from "./chunks/chunk-IKLQHWY2.js";
64
64
  import "./chunks/chunk-Y4CYXJR7.js";
65
65
  import {
66
66
  Deref,
@@ -53690,6 +53690,13 @@ var SettingsManager = class {
53690
53690
  this.settings.calmMode = enabled;
53691
53691
  this.writeSettings();
53692
53692
  }
53693
+ getToolOutputExpanded() {
53694
+ return this.settings.toolOutputExpanded === true;
53695
+ }
53696
+ setToolOutputExpanded(expanded) {
53697
+ this.settings.toolOutputExpanded = expanded;
53698
+ this.writeSettings();
53699
+ }
53693
53700
  // ==========================================================================
53694
53701
  // Extension enablement (user ~/.pie/settings.json + project ./.pie/settings.json)
53695
53702
  // ==========================================================================
@@ -72844,12 +72851,6 @@ async function loadSession(host, sessionId) {
72844
72851
  host.agentSessionController?.drainQueuedInputsForEditor();
72845
72852
  host.updatePendingMessagesDisplay();
72846
72853
  renderChatHistory(host, messages);
72847
- if (messages.length > 50) {
72848
- host.chatContainer.addChild(new Spacer(1));
72849
- host.chatContainer.addChild(
72850
- new Text(theme.fg("dim", `... (${messages.length - 50} earlier messages hidden)`), 1, 0)
72851
- );
72852
- }
72853
72854
  host.chatContainer.addChild(new Spacer(1));
72854
72855
  host.chatContainer.addChild(
72855
72856
  new Text(theme.fg("accent", `\u2713 Loaded session: ${sessionId.slice(0, 8)}...`), 1, 0)
@@ -73073,7 +73074,7 @@ async function navigateToEntry(host, entryId) {
73073
73074
  }
73074
73075
  }
73075
73076
  function renderChatHistory(host, messages) {
73076
- const messagesToShow = messages.slice(-50);
73077
+ const messagesToShow = messages;
73077
73078
  const toolResultMap = /* @__PURE__ */ new Map();
73078
73079
  for (const msg of messages) {
73079
73080
  if (msg.role === "toolResult") {
@@ -79839,6 +79840,7 @@ var InteractiveMode = class {
79839
79840
  this.skillsSection = formatSkillsForPrompt(options.skills);
79840
79841
  this.knowledgeSection = buildCliProjectContextSection(options.cwd);
79841
79842
  this.calmMode = options.settingsManager.getCalmModeEnabled();
79843
+ this.toolOutputExpanded = options.settingsManager.getToolOutputExpanded();
79842
79844
  }
79843
79845
  options;
79844
79846
  get runtimeEventHost() {
@@ -80391,7 +80393,8 @@ var InteractiveMode = class {
80391
80393
  return interactiveCommands.some((cmd) => commandPath.startsWith(cmd));
80392
80394
  }
80393
80395
  toggleToolsExpansion() {
80394
- return toggleToolsExpansion(this.uiHelperHost);
80396
+ toggleToolsExpansion(this.uiHelperHost);
80397
+ this.options.settingsManager.setToolOutputExpanded(this.toolOutputExpanded);
80395
80398
  }
80396
80399
  showSelector(create) {
80397
80400
  return showSelector(this.uiHelperHost, create);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "2.6.0",
3
+ "version": "2.6.1",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {