tesseract-agent 0.10.2 → 0.10.4

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.
Files changed (2) hide show
  1. package/dist-bundle/cli.js +56 -16
  2. package/package.json +1 -1
@@ -24215,7 +24215,11 @@ CRITICAL RULES:
24215
24215
  - Use screenshot to see the visual state.
24216
24216
  - When element selectors are provided, use click or evaluate to interact.
24217
24217
  - You can read and edit project source files if a project directory is configured.
24218
- - Always confirm before making destructive changes to source files.`
24218
+ - Always confirm before making destructive changes to source files.
24219
+ - When you name a file, write its FULL ABSOLUTE PATH (e.g. \`/Users/me/work/proj/docs/plan.md\`),
24220
+ not a project-relative one. The app turns file references in your replies into clickable links,
24221
+ and a relative path is ambiguous the moment more than one project is open \u2014 it resolves against
24222
+ the wrong root, or nothing, and the link does not open. An absolute path always opens.`
24219
24223
  },
24220
24224
  {
24221
24225
  id: "agent.system.unattended-report",
@@ -24280,6 +24284,30 @@ This is a guided website build. Read \`.tesseract/brief.md\` (the user's brief),
24280
24284
  3. After approval, scaffold and implement the project (use the appropriate framework for the brief), reproducing the reference's structure & style with ORIGINAL copy, themed strictly by the design tokens.
24281
24285
  4. Keep the dev server runnable and tell the user the local preview URL.
24282
24286
  Never paste these protocol instructions into the conversation.`
24287
+ },
24288
+ {
24289
+ id: "agent.unattended.decide",
24290
+ group: "agent",
24291
+ label: "Unattended \u2014 answer it yourself",
24292
+ help: "Sent back to the agent when it asks a question during an unattended run. There is no human to pick an option in either mode, so the question is handed straight back rather than parked.",
24293
+ vars: [],
24294
+ content: `This is an unattended run \u2014 nobody is at the keyboard to answer, and no answer is coming. Choose the best option yourself, proceed, and briefly note which decision you made and why.`
24295
+ },
24296
+ {
24297
+ id: "agent.unattended.decline",
24298
+ group: "agent",
24299
+ label: "Unattended \u2014 request declined",
24300
+ help: "Sent when a scheduled run asks for something it will not be granted. Declining unblocks the turn; parking would hang it for ever, since a scheduled fire has no client to answer.",
24301
+ vars: [],
24302
+ content: `This is a scheduled unattended run \u2014 there is no one to approve this, so it is declined rather than left waiting. Continue with what you can do without it, and say clearly in your final message what you skipped and why.`
24303
+ },
24304
+ {
24305
+ id: "agent.unattended.capped",
24306
+ group: "agent",
24307
+ label: "Unattended \u2014 decision budget spent",
24308
+ help: "Sent once a turn has burned its whole auto-answer budget, which means it is looping rather than progressing. Ends the turn with whatever it has instead of spinning.",
24309
+ vars: ["max"],
24310
+ content: `This turn has already been auto-answered {{max}} times, which means it is looping rather than progressing. No further prompts will be answered. Stop asking, finish with what you have, and report what remains unresolved.`
24283
24311
  }
24284
24312
  ];
24285
24313
  }
@@ -33874,7 +33902,7 @@ function unattendedAnswer(mode, prompt2, opts) {
33874
33902
  case "question":
33875
33903
  return {
33876
33904
  behavior: "deny",
33877
- message: capped ? UNATTENDED_CAPPED_NOTE : UNATTENDED_DECIDE_NOTE,
33905
+ message: capped ? unattendedCappedNote() : unattendedDecideNote(),
33878
33906
  decision: capped ? "Told the agent to stop asking and finish" : "Handed back to the agent to decide and continue"
33879
33907
  };
33880
33908
  case "plan":
@@ -33882,7 +33910,7 @@ function unattendedAnswer(mode, prompt2, opts) {
33882
33910
  return { behavior: "allow", decision: "Approved the plan and continued" };
33883
33911
  return {
33884
33912
  behavior: "deny",
33885
- message: capped ? UNATTENDED_CAPPED_NOTE : UNATTENDED_DECLINE_NOTE,
33913
+ message: capped ? unattendedCappedNote() : unattendedDeclineNote(),
33886
33914
  decision: "Declined to approve the plan (nobody was there to approve it)"
33887
33915
  };
33888
33916
  case "permission":
@@ -33891,13 +33919,13 @@ function unattendedAnswer(mode, prompt2, opts) {
33891
33919
  }
33892
33920
  return {
33893
33921
  behavior: "deny",
33894
- message: capped ? UNATTENDED_CAPPED_NOTE : UNATTENDED_DECLINE_NOTE,
33922
+ message: capped ? unattendedCappedNote() : unattendedDeclineNote(),
33895
33923
  decision: `Declined ${prompt2.displayName || prompt2.tool}`
33896
33924
  };
33897
33925
  case "elicitation":
33898
33926
  return {
33899
33927
  behavior: "decline",
33900
- message: UNATTENDED_DECLINE_NOTE,
33928
+ message: unattendedDeclineNote(),
33901
33929
  decision: `Declined \u201C${prompt2.serverName}\u201D request for input`
33902
33930
  };
33903
33931
  case "skill_ui":
@@ -34007,17 +34035,18 @@ function scheduleUnattendedAnswer(prompt2, deps) {
34007
34035
  }, deps.delayMs ?? UNATTENDED_ANSWER_DELAY_MS);
34008
34036
  timer2.unref?.();
34009
34037
  }
34010
- var UNATTENDED_ANSWER_DELAY_MS, UNATTENDED_MAX_DECISIONS, UNATTENDED_DECIDE_NOTE, UNATTENDED_DECLINE_NOTE, UNATTENDED_CAPPED_NOTE, DIALOG_ANSWERS;
34038
+ var UNATTENDED_ANSWER_DELAY_MS, UNATTENDED_MAX_DECISIONS, unattendedDecideNote, unattendedDeclineNote, unattendedCappedNote, DIALOG_ANSWERS;
34011
34039
  var init_unattended = __esm({
34012
34040
  "../../packages/agent-core/dist/unattended.js"() {
34013
34041
  "use strict";
34014
34042
  init_dist();
34015
34043
  init_unattended_log();
34044
+ init_prompts();
34016
34045
  UNATTENDED_ANSWER_DELAY_MS = 700;
34017
34046
  UNATTENDED_MAX_DECISIONS = 100;
34018
- UNATTENDED_DECIDE_NOTE = "This is an unattended run \u2014 nobody is at the keyboard to answer, and no answer is coming. Choose the best option yourself, proceed, and briefly note which decision you made and why.";
34019
- UNATTENDED_DECLINE_NOTE = "This is a scheduled unattended run \u2014 there is no one to approve this, so it is declined rather than left waiting. Continue with what you can do without it, and say clearly in your final message what you skipped and why.";
34020
- UNATTENDED_CAPPED_NOTE = `This turn has already been auto-answered ${UNATTENDED_MAX_DECISIONS} times, which means it is looping rather than progressing. No further prompts will be answered. Stop asking, finish with what you have, and report what remains unresolved.`;
34047
+ unattendedDecideNote = () => prompt("agent.unattended.decide");
34048
+ unattendedDeclineNote = () => prompt("agent.unattended.decline");
34049
+ unattendedCappedNote = () => prompt("agent.unattended.capped", { max: UNATTENDED_MAX_DECISIONS });
34021
34050
  DIALOG_ANSWERS = {
34022
34051
  refusal_fallback_prompt: { result: "retry_fallback", decision: "Retried on the fallback model" },
34023
34052
  fable_overage_consent_prompt: { result: "switch_default", decision: "Switched models rather than spend usage credits" }
@@ -36013,6 +36042,9 @@ function sessionStoreFor(mode) {
36013
36042
  return sharedSessionStore;
36014
36043
  return { ...sharedSessionStore, load: async () => null };
36015
36044
  }
36045
+ function unattendedReportDirective(send4) {
36046
+ return unattendedModeFor({ optedIn: send4.unattended, origin: send4.origin }) !== "off" ? prompt("agent.system.unattended-report") : "";
36047
+ }
36016
36048
  function unknownModelEnv(model) {
36017
36049
  const id = (model ?? "").trim();
36018
36050
  if (!id || /^claude-/i.test(id))
@@ -38564,10 +38596,15 @@ ${prompt("agent.system.website-build")}` : "";
38564
38596
  } else if (live.sessionId) {
38565
38597
  this.narrator.startTurn(live.sessionId, live.lastPrompt ?? params.message);
38566
38598
  }
38599
+ const lateDirective = live.unattendedReportSent ? "" : unattendedReportDirective(params);
38600
+ if (lateDirective)
38601
+ live.unattendedReportSent = true;
38567
38602
  const sdkMsg = {
38568
38603
  type: "user",
38569
38604
  parent_tool_use_id: null,
38570
- message: { role: "user", content: userText }
38605
+ message: { role: "user", content: lateDirective ? `${userText}
38606
+
38607
+ ${lateDirective}` : userText }
38571
38608
  };
38572
38609
  live.pump.push(sdkMsg);
38573
38610
  }
@@ -38597,6 +38634,9 @@ ${prompt("agent.system.website-build")}` : "";
38597
38634
  const isNewSession = !params.sessionId;
38598
38635
  const pendingTitle = isNewSession ? params.message.trim().slice(0, 80) : "";
38599
38636
  const live = {
38637
+ // The system prompt below carries the directive whenever this send is unattended, so
38638
+ // the resident path must not append it again on the very first turn.
38639
+ ...unattendedReportDirective(params) ? { unattendedReportSent: true } : {},
38600
38640
  sessionId: params.sessionId ?? "",
38601
38641
  clientRequestId: params.clientRequestId,
38602
38642
  lastPrompt: params.message,
@@ -39304,9 +39344,9 @@ ${prompt("agent.system.website-build")}` : "";
39304
39344
 
39305
39345
  ${params.appendSystemPrompt}` : "") + (params.reinforcedVerification ? `
39306
39346
 
39307
- ${rvPhaseDirective()}` : "") + (unattendedModeFor({ optedIn: params.unattended, origin: params.origin }) !== "off" ? `
39347
+ ${rvPhaseDirective()}` : "") + (unattendedReportDirective(params) ? `
39308
39348
 
39309
- ${prompt("agent.system.unattended-report")}` : ""), live.sessionId) },
39349
+ ${unattendedReportDirective(params)}` : ""), live.sessionId) },
39310
39350
  includePartialMessages: true,
39311
39351
  // Emit a predicted follow-up prompt after each turn (git/context-aware) — rendered
39312
39352
  // as a clickable suggestion chip. Off by default in the SDK, so opt in here.
@@ -40703,7 +40743,6 @@ __export(dist_exports2, {
40703
40743
  TOKENS_CSS_FILE: () => TOKENS_CSS_FILE,
40704
40744
  TOKENS_FILE: () => TOKENS_FILE,
40705
40745
  UNATTENDED_ANSWER_DELAY_MS: () => UNATTENDED_ANSWER_DELAY_MS,
40706
- UNATTENDED_DECIDE_NOTE: () => UNATTENDED_DECIDE_NOTE,
40707
40746
  UNATTENDED_MAX_DECISIONS: () => UNATTENDED_MAX_DECISIONS,
40708
40747
  appendCanvasArtifact: () => appendCanvasArtifact,
40709
40748
  appendImageArtifact: () => appendImageArtifact,
@@ -40774,6 +40813,7 @@ __export(dist_exports2, {
40774
40813
  toolSpecJsonSchema: () => specParametersJsonSchema,
40775
40814
  transferSession: () => transferSession,
40776
40815
  unattendedAnswer: () => unattendedAnswer,
40816
+ unattendedDecideNote: () => unattendedDecideNote,
40777
40817
  unattendedLogPath: () => unattendedLogPath,
40778
40818
  unattendedModeFor: () => unattendedModeFor,
40779
40819
  walkTokens: () => walkTokens,
@@ -85304,7 +85344,7 @@ function askRdeskConsent(opts) {
85304
85344
  fullscreenable: false,
85305
85345
  show: false,
85306
85346
  backgroundColor: "#00000000",
85307
- webPreferences: { preload: daemonPreloadPath(), contextIsolation: true, sandbox: false }
85347
+ webPreferences: { preload: daemonPreloadPath(), contextIsolation: true, sandbox: false, partition: "tess-ui-consent" }
85308
85348
  });
85309
85349
  win3.setAlwaysOnTop(true, "screen-saver");
85310
85350
  win3.setVisibleOnAllWorkspaces(true, { visibleOnFullScreen: true });
@@ -107454,7 +107494,7 @@ async function runDaemon(opts = {}) {
107454
107494
  const otherDaemonPids = () => {
107455
107495
  try {
107456
107496
  const raw = execFileSync5("ps", ["-axww", "-o", "pid=,command="], { encoding: "utf8", timeout: 3e3 });
107457
- return raw.split("\n").filter((l) => /Tesseract\.app|host-daemon|--merged/.test(l) && !/\bgrep\b|ps -axww/.test(l)).map((l) => Number(l.trim().split(/\s+/)[0])).filter((pid) => Number.isFinite(pid) && pid !== process.pid && pid !== process.ppid);
107497
+ return raw.split("\n").filter((l) => /Tesseract\.app|host-daemon/.test(l) && !/\bgrep\b|ps -axww/.test(l)).map((l) => Number(l.trim().split(/\s+/)[0])).filter((pid) => Number.isFinite(pid) && pid !== process.pid && pid !== process.ppid);
107458
107498
  } catch {
107459
107499
  return [];
107460
107500
  }
@@ -107553,7 +107593,7 @@ async function runDaemon(opts = {}) {
107553
107593
  process.exit(code);
107554
107594
  }
107555
107595
  startSystemEvents({ version: VERSION2, log: (m) => log9(m) });
107556
- const mergedProcess = opts.merged ?? (process.env.CCB_MERGED_PROCESS === "1" || process.argv.includes("--merged"));
107596
+ const mergedProcess = opts.merged === true;
107557
107597
  const deliberateMergedQuit = () => !!globalThis.__ccbDeliberateQuit;
107558
107598
  const onTermSignal = (sig) => {
107559
107599
  if (mergedProcess && !deliberateMergedQuit()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tesseract-agent",
3
- "version": "0.10.2",
3
+ "version": "0.10.4",
4
4
  "license": "UNLICENSED",
5
5
  "publishConfig": {
6
6
  "access": "public",