@glbgpt/cli 0.1.0-test.4 → 0.1.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.
Files changed (143) hide show
  1. package/README.md +79 -6
  2. package/dist/src/auth/authClient.d.ts +21 -2
  3. package/dist/src/auth/authClient.js +67 -3
  4. package/dist/src/auth/authClient.js.map +1 -1
  5. package/dist/src/auth/loginFlow.js +5 -2
  6. package/dist/src/auth/loginFlow.js.map +1 -1
  7. package/dist/src/auth/loopbackServer.d.ts +2 -1
  8. package/dist/src/auth/loopbackServer.js +6 -3
  9. package/dist/src/auth/loopbackServer.js.map +1 -1
  10. package/dist/src/commands/accountCommand.js +10 -4
  11. package/dist/src/commands/accountCommand.js.map +1 -1
  12. package/dist/src/commands/configCommand.d.ts +5 -0
  13. package/dist/src/commands/configCommand.js +15 -2
  14. package/dist/src/commands/configCommand.js.map +1 -1
  15. package/dist/src/commands/execCommand.d.ts +6 -0
  16. package/dist/src/commands/execCommand.js +61 -9
  17. package/dist/src/commands/execCommand.js.map +1 -1
  18. package/dist/src/commands/loginCommand.js +9 -6
  19. package/dist/src/commands/loginCommand.js.map +1 -1
  20. package/dist/src/commands/mediaCommand.js +3 -2
  21. package/dist/src/commands/mediaCommand.js.map +1 -1
  22. package/dist/src/commands/skillCommand.d.ts +30 -0
  23. package/dist/src/commands/skillCommand.js +160 -0
  24. package/dist/src/commands/skillCommand.js.map +1 -0
  25. package/dist/src/config/configFile.d.ts +12 -0
  26. package/dist/src/config/configFile.js +12 -0
  27. package/dist/src/config/configFile.js.map +1 -1
  28. package/dist/src/config/env.d.ts +18 -0
  29. package/dist/src/config/env.js +57 -7
  30. package/dist/src/config/env.js.map +1 -1
  31. package/dist/src/core/catalog.d.ts +8 -1
  32. package/dist/src/core/catalog.js +13 -2
  33. package/dist/src/core/catalog.js.map +1 -1
  34. package/dist/src/core/contextPrune.d.ts +13 -0
  35. package/dist/src/core/contextPrune.js +61 -0
  36. package/dist/src/core/contextPrune.js.map +1 -0
  37. package/dist/src/core/httpChatBackend.js +22 -5
  38. package/dist/src/core/httpChatBackend.js.map +1 -1
  39. package/dist/src/core/runChat.d.ts +9 -5
  40. package/dist/src/core/runChat.js +10 -7
  41. package/dist/src/core/runChat.js.map +1 -1
  42. package/dist/src/core/session.d.ts +15 -0
  43. package/dist/src/core/session.js +29 -1
  44. package/dist/src/core/session.js.map +1 -1
  45. package/dist/src/core/toolRegistry.d.ts +14 -3
  46. package/dist/src/core/toolRegistry.js +24 -15
  47. package/dist/src/core/toolRegistry.js.map +1 -1
  48. package/dist/src/core/turnLoop.d.ts +4 -0
  49. package/dist/src/core/turnLoop.js +62 -13
  50. package/dist/src/core/turnLoop.js.map +1 -1
  51. package/dist/src/core/types.d.ts +6 -0
  52. package/dist/src/core/updateCheck.d.ts +46 -0
  53. package/dist/src/core/updateCheck.js +139 -0
  54. package/dist/src/core/updateCheck.js.map +1 -0
  55. package/dist/src/exec/media.d.ts +32 -0
  56. package/dist/src/exec/media.js +70 -0
  57. package/dist/src/exec/media.js.map +1 -0
  58. package/dist/src/exec/output.d.ts +16 -0
  59. package/dist/src/exec/output.js +41 -0
  60. package/dist/src/exec/output.js.map +1 -1
  61. package/dist/src/fs/globTool.d.ts +8 -0
  62. package/dist/src/fs/globTool.js +117 -0
  63. package/dist/src/fs/globTool.js.map +1 -0
  64. package/dist/src/fs/grepTool.d.ts +4 -0
  65. package/dist/src/fs/grepTool.js +146 -0
  66. package/dist/src/fs/grepTool.js.map +1 -0
  67. package/dist/src/fs/index.d.ts +8 -0
  68. package/dist/src/fs/index.js +13 -0
  69. package/dist/src/fs/index.js.map +1 -0
  70. package/dist/src/fs/limits.d.ts +34 -0
  71. package/dist/src/fs/limits.js +74 -0
  72. package/dist/src/fs/limits.js.map +1 -0
  73. package/dist/src/fs/listDirTool.d.ts +2 -0
  74. package/dist/src/fs/listDirTool.js +68 -0
  75. package/dist/src/fs/listDirTool.js.map +1 -0
  76. package/dist/src/fs/readFileTool.d.ts +2 -0
  77. package/dist/src/fs/readFileTool.js +102 -0
  78. package/dist/src/fs/readFileTool.js.map +1 -0
  79. package/dist/src/fs/walk.d.ts +11 -0
  80. package/dist/src/fs/walk.js +38 -0
  81. package/dist/src/fs/walk.js.map +1 -0
  82. package/dist/src/fs/workspaceGuard.d.ts +27 -0
  83. package/dist/src/fs/workspaceGuard.js +96 -0
  84. package/dist/src/fs/workspaceGuard.js.map +1 -0
  85. package/dist/src/index.js +47 -3
  86. package/dist/src/index.js.map +1 -1
  87. package/dist/src/mcp/mediaTools.d.ts +63 -0
  88. package/dist/src/mcp/mediaTools.js +385 -0
  89. package/dist/src/mcp/mediaTools.js.map +1 -0
  90. package/dist/src/mcp/server.d.ts +6 -2
  91. package/dist/src/mcp/server.js +19 -9
  92. package/dist/src/mcp/server.js.map +1 -1
  93. package/dist/src/media/aiApiClient.d.ts +5 -0
  94. package/dist/src/media/aiApiClient.js +12 -1
  95. package/dist/src/media/aiApiClient.js.map +1 -1
  96. package/dist/src/media/budget.d.ts +42 -0
  97. package/dist/src/media/budget.js +95 -0
  98. package/dist/src/media/budget.js.map +1 -0
  99. package/dist/src/media/executor.d.ts +9 -0
  100. package/dist/src/media/executor.js +1 -1
  101. package/dist/src/media/executor.js.map +1 -1
  102. package/dist/src/media/generateImageTool.d.ts +20 -2
  103. package/dist/src/media/generateImageTool.js +102 -2
  104. package/dist/src/media/generateImageTool.js.map +1 -1
  105. package/dist/src/media/promptSanitizer.d.ts +11 -0
  106. package/dist/src/media/promptSanitizer.js +33 -0
  107. package/dist/src/media/promptSanitizer.js.map +1 -0
  108. package/dist/src/media/taskManager.d.ts +8 -1
  109. package/dist/src/media/taskManager.js +1 -1
  110. package/dist/src/media/taskManager.js.map +1 -1
  111. package/dist/src/tui/App.js +38 -8
  112. package/dist/src/tui/App.js.map +1 -1
  113. package/dist/src/tui/ParamEditor.d.ts +11 -2
  114. package/dist/src/tui/ParamEditor.js +48 -3
  115. package/dist/src/tui/ParamEditor.js.map +1 -1
  116. package/dist/src/tui/atPopup.d.ts +8 -0
  117. package/dist/src/tui/atPopup.js +1 -1
  118. package/dist/src/tui/atPopup.js.map +1 -1
  119. package/dist/src/tui/attachments.d.ts +12 -0
  120. package/dist/src/tui/attachments.js +12 -1
  121. package/dist/src/tui/attachments.js.map +1 -1
  122. package/dist/src/tui/chatController.d.ts +73 -2
  123. package/dist/src/tui/chatController.js +272 -43
  124. package/dist/src/tui/chatController.js.map +1 -1
  125. package/dist/src/tui/models.d.ts +6 -0
  126. package/dist/src/tui/models.js +14 -6
  127. package/dist/src/tui/models.js.map +1 -1
  128. package/dist/src/tui/run.js +55 -16
  129. package/dist/src/tui/run.js.map +1 -1
  130. package/dist/src/util/brokenPipe.d.ts +10 -0
  131. package/dist/src/util/brokenPipe.js +19 -0
  132. package/dist/src/util/brokenPipe.js.map +1 -0
  133. package/package.json +3 -2
  134. package/skills/globalgpt/SKILL.md +94 -0
  135. package/skills/globalgpt/references/troubleshooting.md +34 -0
  136. package/skills/globalgpt-coding/SKILL.md +65 -0
  137. package/skills/globalgpt-coding/references/troubleshooting.md +34 -0
  138. package/skills/globalgpt-image/SKILL.md +109 -0
  139. package/skills/globalgpt-image/references/recipes.md +52 -0
  140. package/skills/globalgpt-image/references/troubleshooting.md +49 -0
  141. package/skills/globalgpt-video/SKILL.md +109 -0
  142. package/skills/globalgpt-video/references/recipes.md +50 -0
  143. package/skills/globalgpt-video/references/troubleshooting.md +49 -0
@@ -0,0 +1,95 @@
1
+ import { getConfigValueSync } from '../config/configFile.js';
2
+ import { DEFAULT_SESSION_MAX_CREDITS } from '../fs/limits.js';
3
+ import { GenerationExecutor } from './executor.js';
4
+ /**
5
+ * Session-cumulative credit budget for the unattended surfaces (MCP server, exec).
6
+ * One instance per process; TUI generations are human-confirmed and do not use it.
7
+ * Reservations happen at the confirm gate (authoritative backend estimate in hand)
8
+ * and are released if the submit then fails — see BudgetConfirmer (added in Task 2).
9
+ */
10
+ export class SessionBudget {
11
+ cap;
12
+ spentCredits = 0;
13
+ constructor(cap) {
14
+ this.cap = cap;
15
+ }
16
+ get spent() {
17
+ return this.spentCredits;
18
+ }
19
+ /** Atomically check-and-add. False (and no change) when the cap would be crossed. */
20
+ tryReserve(credits) {
21
+ if (this.spentCredits + credits > this.cap)
22
+ return false;
23
+ this.spentCredits += credits;
24
+ return true;
25
+ }
26
+ release(credits) {
27
+ this.spentCredits = Math.max(0, this.spentCredits - credits);
28
+ }
29
+ describe() {
30
+ return `${this.spentCredits} of ${this.cap} credits spent this session`;
31
+ }
32
+ }
33
+ /**
34
+ * Cap precedence: explicit flag > GLBGPT_MAX_CREDITS env > config 'max-credits' > default.
35
+ *
36
+ * `0` is a valid flag value meaning "no media spending this session" (a SessionBudget with
37
+ * cap 0 rejects every reserve); the CLI rejects NaN/negative flag values before they ever
38
+ * reach here (usage error, not a silent fallback). Garbage from env/config still falls back
39
+ * to the default — those aren't user-typed-right-now input, so failing soft is preferable.
40
+ */
41
+ export function resolveMaxCredits(flag) {
42
+ if (typeof flag === 'number' && Number.isFinite(flag) && flag >= 0)
43
+ return Math.floor(flag);
44
+ const raw = process.env.GLBGPT_MAX_CREDITS ?? getConfigValueSync('max-credits');
45
+ const n = raw !== undefined ? Number.parseInt(raw, 10) : Number.NaN;
46
+ return Number.isFinite(n) && n > 0 ? n : DEFAULT_SESSION_MAX_CREDITS;
47
+ }
48
+ /**
49
+ * The unattended confirm gate: reserve the estimated credits or reject with an
50
+ * actionable message. One instance per execute() call (budgetedExecutor) so a
51
+ * failed submit can roll back exactly its own reservation.
52
+ */
53
+ export class BudgetConfirmer {
54
+ budget;
55
+ reserved = 0;
56
+ constructor(budget) {
57
+ this.budget = budget;
58
+ }
59
+ async confirm(info) {
60
+ if (this.budget.tryReserve(info.credits)) {
61
+ this.reserved = info.credits;
62
+ return { action: 'generate' };
63
+ }
64
+ return {
65
+ action: 'cancel',
66
+ reason: `Budget exceeded: this generation (~${info.credits} credits) would bring session spend to ` +
67
+ `${this.budget.spent + info.credits} of ${this.budget.cap} credits. Ask the user to restart ` +
68
+ `with --max-credits <n> or run 'glbgpt config set max-credits <n>'.`,
69
+ };
70
+ }
71
+ /** Undo the reservation after a failed submit (the money was never spent). */
72
+ rollback() {
73
+ if (this.reserved > 0) {
74
+ this.budget.release(this.reserved);
75
+ this.reserved = 0;
76
+ }
77
+ }
78
+ }
79
+ /** Budget-gated executor for unattended surfaces: fresh gate per call, rolled back on a thrown submit. */
80
+ export function budgetedExecutor(client, budget) {
81
+ return {
82
+ async execute(modelId, params) {
83
+ const gate = new BudgetConfirmer(budget);
84
+ const executor = new GenerationExecutor(client, gate);
85
+ try {
86
+ return await executor.execute(modelId, params);
87
+ }
88
+ catch (err) {
89
+ gate.rollback();
90
+ throw err;
91
+ }
92
+ },
93
+ };
94
+ }
95
+ //# sourceMappingURL=budget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"budget.js","sourceRoot":"","sources":["../../../src/media/budget.ts"],"names":[],"mappings":"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"}
@@ -17,6 +17,7 @@ export type ConfirmDecision = {
17
17
  action: 'generate';
18
18
  } | {
19
19
  action: 'cancel';
20
+ reason?: string;
20
21
  } | {
21
22
  action: 'edit';
22
23
  model: string;
@@ -34,10 +35,18 @@ export type ExecuteOutcome = {
34
35
  params: MediaGenParams;
35
36
  } | {
36
37
  status: 'cancelled';
38
+ reason?: string;
37
39
  } | {
38
40
  status: 'not_sellable';
39
41
  reasonCode: string | null;
40
42
  };
43
+ /**
44
+ * The executor surface the media tools depend on. GenerationExecutor implements it
45
+ * structurally; budget wrappers (budgetedExecutor) implement it too.
46
+ */
47
+ export interface MediaExecutor {
48
+ execute(modelId: string, rawParams: MediaGenParams): Promise<ExecuteOutcome>;
49
+ }
41
50
  /**
42
51
  * Shared generation pipeline: validate → estimate → confirm → upload local images → submit.
43
52
  *
@@ -39,7 +39,7 @@ export class GenerationExecutor {
39
39
  credits,
40
40
  });
41
41
  if (decision.action === 'cancel') {
42
- return { status: 'cancelled' };
42
+ return decision.reason ? { status: 'cancelled', reason: decision.reason } : { status: 'cancelled' };
43
43
  }
44
44
  if (decision.action === 'edit') {
45
45
  model = decision.model;
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/media/executor.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../src/media/executor.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,29 @@
1
1
  import type { ClientTool } from '../core/types.js';
2
- import type { GenerationExecutor } from './executor.js';
2
+ import type { MediaExecutor } from './executor.js';
3
3
  import type { TaskManager } from './taskManager.js';
4
4
  import type { TaskLedger } from './taskLedger.js';
5
5
  export interface MediaToolDeps {
6
- executor: GenerationExecutor;
6
+ executor: MediaExecutor;
7
7
  taskManager: TaskManager;
8
8
  ledger: TaskLedger;
9
+ /**
10
+ * Resolve a reference-image value the model passed (a prior generation's local path, an http
11
+ * URL, or "last") into a submittable value. Returns undefined only when "last" was requested
12
+ * but nothing has been generated yet. When omitted, references pass through unchanged.
13
+ */
14
+ resolveReference?: (ref: string) => string | undefined;
15
+ /**
16
+ * Images the user attached to THIS message (hosted URLs / local paths). When the user attaches
17
+ * an image and asks to build on it, these are used as the reference even if the model didn't
18
+ * pass one — the confirmation shows them so a false positive is caught before spending.
19
+ */
20
+ pendingReferences?: () => string[];
21
+ /**
22
+ * Every media reference this session knows about (generated output URLs and their local paths).
23
+ * Used to move a reference the model pasted INTO THE PROMPT TEXT back into the reference
24
+ * parameter. Exact-match only — links that are not session-known media are never touched.
25
+ */
26
+ knownMediaRefs?: () => string[];
9
27
  }
10
28
  /** Back-compat alias. */
11
29
  export type GenerateImageToolDeps = MediaToolDeps;
@@ -1,6 +1,7 @@
1
1
  import { DEFAULT_IMAGE_MODEL, DEFAULT_VIDEO_MODEL, IMAGE_MODELS, VIDEO_MODELS, findModel } from './manifest.js';
2
2
  import { PaymentRequiredError } from './aiApiClient.js';
3
3
  import { describePaymentRequired, describeNotSellable } from './errors.js';
4
+ import { extractKnownRefs } from './promptSanitizer.js';
4
5
  /**
5
6
  * The real in-chat media tools (contract §4): estimate → confirm (via the executor's Confirmer) →
6
7
  * submit, then return the task id to the model immediately. The TaskManager polls and downloads in
@@ -26,6 +27,11 @@ function buildTool(kind, deps) {
26
27
  seed: { type: 'integer', description: 'Set only if the user gives a seed' },
27
28
  negative_prompt: { type: 'string', description: 'Set only if the user says what to avoid' },
28
29
  };
30
+ const refHint = 'Reference an image by the local path shown in a prior generation ("Saved locally at …"), ' +
31
+ 'an http(s) URL, or "last" for the most recently generated image. Only set when the user wants ' +
32
+ 'to build on an existing image; not all models support it. Pass references ONLY via this ' +
33
+ 'parameter — never write an image URL or file path into the prompt text (the prompt is literal ' +
34
+ 'text for the media model, which cannot fetch links from it).';
29
35
  if (isVideo) {
30
36
  properties.duration = { type: 'integer', description: 'Video length in seconds — set only if the user asks' };
31
37
  properties.generate_audio = {
@@ -33,13 +39,25 @@ function buildTool(kind, deps) {
33
39
  description: 'Sound on/off. Set ONLY if the user explicitly asks for it. Omit otherwise — each model ' +
34
40
  'uses its own default, which you do not know. Do not assume the result has or lacks sound.',
35
41
  };
42
+ properties.start_image = { type: 'string', description: `First frame for image-to-video. ${refHint}` };
43
+ properties.end_image = { type: 'string', description: `Last frame (with start_image). ${refHint}` };
44
+ }
45
+ else {
46
+ properties.reference_images = {
47
+ type: 'array',
48
+ items: { type: 'string' },
49
+ description: `Images to build on / edit (image-to-image). ${refHint}`,
50
+ };
36
51
  }
37
52
  // NOTE: multi-image `count`/`n` is intentionally NOT exposed — the download path handles a
38
53
  // single output, so a count>1 would be charged per image but only one delivered. Re-add once
39
54
  // multi-output (N URLs + downloading/showing all N) is wired end to end.
40
55
  return {
41
56
  name: isVideo ? 'generate_video' : 'generate_image',
42
- description: `Generate ${isVideo ? 'a video' : 'an image'} from a text prompt. Returns a task id immediately; ` +
57
+ description: `Generate ${isVideo ? 'a video' : 'an image'} from a text prompt. When the user asks for ${isVideo ? 'a video' : 'an image'}, call this tool immediately — anything you say first may only state intent (e.g. "I'll generate ` +
58
+ `that now"). NEVER announce, estimate, or guess costs, prices, credits, or settings beforehand: ` +
59
+ `you do not know them, and the system already displays an authoritative cost estimate with a ` +
60
+ `confirmation dialog as part of this call. Returns a task id immediately; ` +
43
61
  `the ${noun} runs in the background and appears in the conversation when ready (do not wait for it). ` +
44
62
  `After calling, tell the user generation has STARTED — never claim the ${noun} is already done. ` +
45
63
  `Set a parameter ONLY when the user explicitly asked for it; otherwise omit it and the system ` +
@@ -47,9 +65,16 @@ function buildTool(kind, deps) {
47
65
  `user which settings were used or predict any property of the result.`,
48
66
  parameters: { type: 'object', properties, required: ['prompt'] },
49
67
  async execute(args) {
50
- const prompt = typeof args.prompt === 'string' ? args.prompt : '';
68
+ let prompt = typeof args.prompt === 'string' ? args.prompt : '';
51
69
  if (!prompt.trim())
52
70
  return { error: 'prompt is required' };
71
+ // Models sometimes paste a prior output's URL into the prompt instead of the reference
72
+ // parameter — move it back where the media model can actually receive it.
73
+ let promptRefs = [];
74
+ const known = deps.knownMediaRefs?.() ?? [];
75
+ if (known.length > 0) {
76
+ ({ prompt, refs: promptRefs } = extractKnownRefs(prompt, known));
77
+ }
53
78
  const modelId = typeof args.model === 'string' && args.model ? args.model : defaultModel;
54
79
  const params = {
55
80
  prompt,
@@ -60,8 +85,26 @@ function buildTool(kind, deps) {
60
85
  params.seed = args.seed;
61
86
  if (typeof args.negative_prompt === 'string' && args.negative_prompt)
62
87
  params.negativePrompt = args.negative_prompt;
88
+ // Resolve reference images ("last" / generated path / URL) into submittable values.
89
+ const resolveRef = (ref) => {
90
+ if (typeof ref !== 'string' || !ref.trim())
91
+ return undefined;
92
+ const resolved = deps.resolveReference ? deps.resolveReference(ref) : ref;
93
+ return resolved ?? null; // null = "last" requested but nothing generated yet
94
+ };
95
+ const noLastImage = 'No previously generated image to reference yet — generate one first.';
63
96
  const warnings = [];
64
97
  if (isVideo) {
98
+ const start = resolveRef(args.start_image);
99
+ if (start === null)
100
+ return { error: noLastImage };
101
+ if (start)
102
+ params.startImage = start;
103
+ const end = resolveRef(args.end_image);
104
+ if (end === null)
105
+ return { error: noLastImage };
106
+ if (end)
107
+ params.endImage = end;
65
108
  if (typeof args.duration === 'number')
66
109
  params.duration = args.duration;
67
110
  if (typeof args.generate_audio === 'boolean') {
@@ -80,9 +123,66 @@ function buildTool(kind, deps) {
80
123
  }
81
124
  }
82
125
  }
126
+ else if (Array.isArray(args.reference_images) && args.reference_images.length > 0) {
127
+ const refs = [];
128
+ for (const ref of args.reference_images) {
129
+ const resolved = resolveRef(ref);
130
+ if (resolved === null)
131
+ return { error: noLastImage };
132
+ if (resolved)
133
+ refs.push(resolved);
134
+ }
135
+ if (refs.length > 0)
136
+ params.images = refs;
137
+ }
138
+ // References extracted from the prompt text fill still-empty slots (an explicit parameter
139
+ // wins; a duplicate of it is just dropped). Resolved like any other ref so a local output
140
+ // path becomes its hosted URL.
141
+ if (promptRefs.length > 0) {
142
+ const used = new Set([params.startImage, params.endImage, ...(params.images ?? [])].filter(Boolean));
143
+ const fresh = promptRefs
144
+ .map((r) => resolveRef(r))
145
+ .filter((r) => typeof r === 'string' && !used.has(r));
146
+ let moved = false;
147
+ if (isVideo) {
148
+ for (const r of fresh) {
149
+ if (!params.startImage) {
150
+ params.startImage = r;
151
+ moved = true;
152
+ }
153
+ else if (!params.endImage && r !== params.startImage) {
154
+ params.endImage = r;
155
+ moved = true;
156
+ }
157
+ }
158
+ }
159
+ else if ((!params.images || params.images.length === 0) && fresh.length > 0) {
160
+ params.images = fresh;
161
+ moved = true;
162
+ }
163
+ if (moved) {
164
+ warnings.push('A generated image reference was found INSIDE the prompt text and was moved to the ' +
165
+ `${isVideo ? 'start_image' : 'reference_images'} parameter (the media model cannot read links ` +
166
+ 'from prompt text). Next time pass references only via the parameter.');
167
+ }
168
+ }
169
+ // Auto-reference: the user attached an image and asked to build on it, but the model passed
170
+ // no explicit reference — use the attachment. The confirmation lists it so a false positive
171
+ // (an unrelated attached image) is caught before spending.
172
+ const attached = deps.pendingReferences?.() ?? [];
173
+ if (attached.length > 0) {
174
+ if (isVideo && !params.startImage)
175
+ params.startImage = attached[0];
176
+ else if (!isVideo && (!params.images || params.images.length === 0))
177
+ params.images = attached;
178
+ }
83
179
  try {
84
180
  const outcome = await deps.executor.execute(modelId, params);
85
181
  if (outcome.status === 'cancelled') {
182
+ // A reasoned cancel is a policy gate (e.g. session budget), not a user decline —
183
+ // report it as an error so the agent relays it instead of "the user declined".
184
+ if (outcome.reason)
185
+ return { error: outcome.reason };
86
186
  return {
87
187
  cancelled: true,
88
188
  note: 'The user declined this generation (they may adjust the parameters and retry).',
@@ -1 +1 @@
1
- {"version":3,"file":"generateImageTool.js","sourceRoot":"","sources":["../../../src/media/generateImageTool.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"generateImageTool.js","sourceRoot":"","sources":["../../../src/media/generateImageTool.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAEhH,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,uBAAuB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AA6BxD;;;;;GAKG;AACH,MAAM,UAAU,uBAAuB,CAAC,IAAmB;IACzD,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,IAAmB;IACzD,OAAO,SAAS,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;AAClC,CAAC;AAED,SAAS,SAAS,CAAC,IAAuB,EAAE,IAAmB;IAC7D,MAAM,OAAO,GAAG,IAAI,KAAK,OAAO,CAAC;IACjC,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1E,MAAM,YAAY,GAAG,OAAO,CAAC,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC,mBAAmB,CAAC;IACzE,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAEzC,MAAM,UAAU,GAA4B;QAC1C,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE;QAC3D,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,IAAI,mBAAmB,YAAY,GAAG,EAAE;QACjG,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kDAAkD,EAAE;QACjG,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,8BAA8B,OAAO,CAAC,CAAC,CAAC,wBAAwB,CAAC,CAAC,CAAC,iBAAiB,GAAG,EAAE;QACpI,IAAI,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,mCAAmC,EAAE;QAC3E,eAAe,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;KAC5F,CAAC;IACF,MAAM,OAAO,GACX,2FAA2F;QAC3F,gGAAgG;QAChG,0FAA0F;QAC1F,gGAAgG;QAChG,8DAA8D,CAAC;IACjE,IAAI,OAAO,EAAE,CAAC;QACZ,UAAU,CAAC,QAAQ,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,WAAW,EAAE,qDAAqD,EAAE,CAAC;QAC9G,UAAU,CAAC,cAAc,GAAG;YAC1B,IAAI,EAAE,SAAS;YACf,WAAW,EACT,yFAAyF;gBACzF,2FAA2F;SAC9F,CAAC;QACF,UAAU,CAAC,WAAW,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,OAAO,EAAE,EAAE,CAAC;QACvG,UAAU,CAAC,SAAS,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kCAAkC,OAAO,EAAE,EAAE,CAAC;IACtG,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,gBAAgB,GAAG;YAC5B,IAAI,EAAE,OAAO;YACb,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;YACzB,WAAW,EAAE,+CAA+C,OAAO,EAAE;SACtE,CAAC;IACJ,CAAC;IACD,2FAA2F;IAC3F,6FAA6F;IAC7F,yEAAyE;IAEzE,OAAO;QACL,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,gBAAgB;QACnD,WAAW,EACT,YAAY,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UAAU,+CAC1C,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,UACxB,mGAAmG;YACnG,iGAAiG;YACjG,8FAA8F;YAC9F,2EAA2E;YAC3E,OAAO,IAAI,2FAA2F;YACtG,yEAAyE,IAAI,oBAAoB;YACjG,+FAA+F;YAC/F,oGAAoG;YACpG,sEAAsE;QACxE,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE;QAChE,KAAK,CAAC,OAAO,CAAC,IAA6B;YACzC,IAAI,MAAM,GAAG,OAAO,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE;gBAAE,OAAO,EAAE,KAAK,EAAE,oBAAoB,EAAE,CAAC;YAC3D,uFAAuF;YACvF,0EAA0E;YAC1E,IAAI,UAAU,GAAa,EAAE,CAAC;YAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,EAAE,CAAC;YAC5C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACrB,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC;YACnE,CAAC;YACD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;YACzF,MAAM,MAAM,GAAmB;gBAC7B,MAAM;gBACN,WAAW,EAAE,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC;gBACnC,UAAU,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,CAAC;aACjC,CAAC;YACF,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ;gBAAE,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YAC3D,IAAI,OAAO,IAAI,CAAC,eAAe,KAAK,QAAQ,IAAI,IAAI,CAAC,eAAe;gBAAE,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,eAAe,CAAC;YAEnH,oFAAoF;YACpF,MAAM,UAAU,GAAG,CAAC,GAAY,EAA6B,EAAE;gBAC7D,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;oBAAE,OAAO,SAAS,CAAC;gBAC7D,MAAM,QAAQ,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBAC1E,OAAO,QAAQ,IAAI,IAAI,CAAC,CAAC,oDAAoD;YAC/E,CAAC,CAAC;YACF,MAAM,WAAW,GAAG,sEAAsE,CAAC;YAC3F,MAAM,QAAQ,GAAa,EAAE,CAAC;YAC9B,IAAI,OAAO,EAAE,CAAC;gBACZ,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;gBAC3C,IAAI,KAAK,KAAK,IAAI;oBAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;gBAClD,IAAI,KAAK;oBAAE,MAAM,CAAC,UAAU,GAAG,KAAK,CAAC;gBACrC,MAAM,GAAG,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvC,IAAI,GAAG,KAAK,IAAI;oBAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;gBAChD,IAAI,GAAG;oBAAE,MAAM,CAAC,QAAQ,GAAG,GAAG,CAAC;gBAC/B,IAAI,OAAO,IAAI,CAAC,QAAQ,KAAK,QAAQ;oBAAE,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;gBACvE,IAAI,OAAO,IAAI,CAAC,cAAc,KAAK,SAAS,EAAE,CAAC;oBAC7C,gFAAgF;oBAChF,kFAAkF;oBAClF,mFAAmF;oBACnF,uCAAuC;oBACvC,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;oBAChC,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,CAAC;wBAC/D,8EAA8E;wBAC9E,oEAAoE;wBACpE,QAAQ,CAAC,IAAI,CAAC,GAAG,OAAO,+FAA+F,CAAC,CAAC;oBAC3H,CAAC;yBAAM,CAAC;wBACN,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,cAAc,CAAC;oBAC7C,CAAC;gBACH,CAAC;YACH,CAAC;iBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACpF,MAAM,IAAI,GAAa,EAAE,CAAC;gBAC1B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;oBACxC,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;oBACjC,IAAI,QAAQ,KAAK,IAAI;wBAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC;oBACrD,IAAI,QAAQ;wBAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACpC,CAAC;gBACD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC;oBAAE,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;YAC5C,CAAC;YAED,0FAA0F;YAC1F,0FAA0F;YAC1F,+BAA+B;YAC/B,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC1B,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;gBACrG,MAAM,KAAK,GAAG,UAAU;qBACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;qBACzB,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBACrE,IAAI,KAAK,GAAG,KAAK,CAAC;gBAClB,IAAI,OAAO,EAAE,CAAC;oBACZ,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;wBACtB,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;4BAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;4BAAC,KAAK,GAAG,IAAI,CAAC;wBAAC,CAAC;6BAC3D,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,CAAC,KAAK,MAAM,CAAC,UAAU,EAAE,CAAC;4BAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;4BAAC,KAAK,GAAG,IAAI,CAAC;wBAAC,CAAC;oBAC9F,CAAC;gBACH,CAAC;qBAAM,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC9E,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;oBACtB,KAAK,GAAG,IAAI,CAAC;gBACf,CAAC;gBACD,IAAI,KAAK,EAAE,CAAC;oBACV,QAAQ,CAAC,IAAI,CACX,oFAAoF;wBAClF,GAAG,OAAO,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,kBAAkB,gDAAgD;wBAC/F,sEAAsE,CACzE,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,4FAA4F;YAC5F,4FAA4F;YAC5F,2DAA2D;YAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,CAAC;YAClD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACxB,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,UAAU;oBAAE,MAAM,CAAC,UAAU,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;qBAC9D,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;oBAAE,MAAM,CAAC,MAAM,GAAG,QAAQ,CAAC;YAChG,CAAC;YAED,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC7D,IAAI,OAAO,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC;oBACnC,iFAAiF;oBACjF,+EAA+E;oBAC/E,IAAI,OAAO,CAAC,MAAM;wBAAE,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;oBACrD,OAAO;wBACL,SAAS,EAAE,IAAI;wBACf,IAAI,EAAE,+EAA+E;qBACtF,CAAC;gBACJ,CAAC;gBACD,IAAI,OAAO,CAAC,MAAM,KAAK,cAAc,EAAE,CAAC;oBACtC,OAAO,EAAE,KAAK,EAAE,mBAAmB,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5D,CAAC;gBACD,oEAAoE;gBACpE,KAAK,IAAI,CAAC,MAAM;qBACb,MAAM,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC;qBACvF,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACnB,KAAK,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;gBACjG,OAAO;oBACL,OAAO,EAAE,OAAO,CAAC,MAAM;oBACvB,MAAM,EAAE,WAAW;oBACnB,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,iBAAiB,EAAE,OAAO,CAAC,OAAO;oBAClC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;oBACxC,IAAI,EACF,OAAO,IAAI,6EAA6E;wBACxF,uFAAuF;wBACvF,mFAAmF;wBACnF,kEAAkE,IAAI,gBAAgB;wBACtF,yFAAyF;wBACzF,sFAAsF;wBACtF,oFAAoF;iBACvF,CAAC;YACJ,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO;oBACL,KAAK,EACH,GAAG,YAAY,oBAAoB;wBACjC,CAAC,CAAC,uBAAuB,CAAC,GAAG,CAAC;wBAC9B,CAAC,CAAC,GAAG,YAAY,KAAK;4BACpB,CAAC,CAAC,GAAG,CAAC,OAAO;4BACb,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACpB,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,GAAG,CAAC,CAAU;IACrB,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACpD,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Moves session-known media references (generated output URLs / local paths) out of a generation
3
+ * prompt's text. Models sometimes paste a prior output's URL into the prompt instead of the
4
+ * reference parameter — the media model then never receives the reference and may even render the
5
+ * URL as literal text. Matching is EXACT against the known list only: any other link the user
6
+ * wrote (a website, an external image, …) is left byte-for-byte untouched by design.
7
+ */
8
+ export declare function extractKnownRefs(prompt: string, known: string[]): {
9
+ prompt: string;
10
+ refs: string[];
11
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Moves session-known media references (generated output URLs / local paths) out of a generation
3
+ * prompt's text. Models sometimes paste a prior output's URL into the prompt instead of the
4
+ * reference parameter — the media model then never receives the reference and may even render the
5
+ * URL as literal text. Matching is EXACT against the known list only: any other link the user
6
+ * wrote (a website, an external image, …) is left byte-for-byte untouched by design.
7
+ */
8
+ /** A "参考图:" / "reference image:" style label directly before an extracted ref. */
9
+ const LABEL_BEFORE = /(?:参考图片?|reference(?:\s+images?)?|image)\s*[::]\s*$/i;
10
+ export function extractKnownRefs(prompt, known) {
11
+ const refs = [];
12
+ let out = prompt;
13
+ // Longest first, so a ref that contains another as a prefix is matched whole.
14
+ const candidates = [...new Set(known.filter(Boolean))].sort((a, b) => b.length - a.length);
15
+ for (const ref of candidates) {
16
+ if (!out.includes(ref))
17
+ continue;
18
+ refs.push(ref);
19
+ let idx;
20
+ while ((idx = out.indexOf(ref)) !== -1) {
21
+ const label = LABEL_BEFORE.exec(out.slice(0, idx));
22
+ const start = label ? idx - label[0].length : idx;
23
+ out = out.slice(0, start) + out.slice(idx + ref.length);
24
+ }
25
+ }
26
+ if (refs.length === 0)
27
+ return { prompt, refs };
28
+ const cleaned = out.replace(/[ \t]{2,}/g, ' ').trim();
29
+ // A prompt that was ONLY the reference would become empty — keep the original text then,
30
+ // since the media model still needs some prompt.
31
+ return { prompt: cleaned.length > 0 ? cleaned : prompt, refs };
32
+ }
33
+ //# sourceMappingURL=promptSanitizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promptSanitizer.js","sourceRoot":"","sources":["../../../src/media/promptSanitizer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,kFAAkF;AAClF,MAAM,YAAY,GAAG,sDAAsD,CAAC;AAE5E,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,KAAe;IAC9D,MAAM,IAAI,GAAa,EAAE,CAAC;IAC1B,IAAI,GAAG,GAAG,MAAM,CAAC;IACjB,8EAA8E;IAC9E,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC;IAC3F,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QACjC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACf,IAAI,GAAW,CAAC;QAChB,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YACnD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC;YAClD,GAAG,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;IAC/C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,yFAAyF;IACzF,iDAAiD;IACjD,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AACjE,CAAC"}
@@ -10,10 +10,17 @@ export type TaskEvent = {
10
10
  localPath: string;
11
11
  outputUrl: string;
12
12
  mediaType?: number | null;
13
- } | {
13
+ }
14
+ /**
15
+ * `timedOut: true` marks OUR poll loop giving up, not an authoritative backend
16
+ * verdict — the task may still be running and may still succeed. Consumers must
17
+ * not cache it as a terminal failure (MCP check_task treats it as "still generating").
18
+ */
19
+ | {
14
20
  type: 'task_failed';
15
21
  taskId: string;
16
22
  reason: string;
23
+ timedOut?: boolean;
17
24
  };
18
25
  export interface TaskMeta {
19
26
  model?: string;
@@ -59,7 +59,7 @@ export class TaskManager {
59
59
  const elapsedMs = Date.now() - start;
60
60
  this.emit({ type: 'task_progress', taskId, elapsedMs, status: info.status });
61
61
  if (elapsedMs >= this.timeoutMs) {
62
- return this.emit({ type: 'task_failed', taskId, reason: 'Timed out waiting for the task.' });
62
+ return this.emit({ type: 'task_failed', taskId, reason: 'Timed out waiting for the task.', timedOut: true });
63
63
  }
64
64
  await this.sleep(this.pollMs);
65
65
  }
@@ -1 +1 @@
1
- {"version":3,"file":"taskManager.js","sourceRoot":"","sources":["../../../src/media/taskManager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAsBlD;;;;;;GAMG;AACH,MAAM,OAAO,WAAW;IAQH;IACA;IARF,WAAW,GAAG,IAAI,GAAG,EAA0B,CAAC;IAChD,MAAM,CAAS;IACf,SAAS,CAAS;IAClB,QAAQ,CAAmD;IAC3D,KAAK,CAAgC;IAEtD,YACmB,MAAmB,EACnB,IAAwB;QADxB,WAAM,GAAN,MAAM,CAAa;QACnB,SAAI,GAAJ,IAAI,CAAoB;QAEzC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,GAAG,MAAM,CAAC;QAC/C,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAe,CAAC;QACjD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IAC7E,CAAC;IAED,SAAS,CAAC,EAA0B;QAClC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QACzB,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,sGAAsG;IACtG,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,OAAiB,EAAE;QAChD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACzB,SAAS,CAAC;YACR,IAAI,IAAc,CAAC;YACnB,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC3C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC9G,CAAC;YAED,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;gBAC9B,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;oBACxB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,4CAA4C,EAAE,CAAC,CAAC;gBAC1G,CAAC;gBACD,IAAI,CAAC;oBACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;oBAChE,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC;gBACvH,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,qGAAqG;oBACrG,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,oBAAoB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;gBACpI,CAAC;YACH,CAAC;YACD,IAAI,IAAI,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC7B,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,mBAAmB,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;YACpH,CAAC;YAED,4CAA4C;YAC5C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC;YACrC,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7E,IAAI,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,EAAE,iCAAiC,EAAE,CAAC,CAAC;YAC/F,CAAC;YACD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,MAAc,EAAE,IAAc,EAAE,IAAc;QACzE,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzD,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,aAAc,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;QACxD,MAAM,IAAI,GAAG,UAAU,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;QACrE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;QAC9D,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAc,EAAE,IAAI,CAAC,CAAC;QAE/C,oFAAoF;QACpF,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,CAAC,CAAC;QACrC,IAAI,OAAO,IAAI,OAAO,KAAK,GAAG,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,IAAI,IAAI,OAAO,EAAE,CAAC,CAAC;YACvE,MAAM,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACjC,OAAO,SAAS,CAAC;QACnB,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAEO,IAAI,CAAC,CAAY;QACvB,KAAK,MAAM,EAAE,IAAI,IAAI,CAAC,WAAW;YAAE,EAAE,CAAC,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,CAAC;IACX,CAAC;CACF;AAED,SAAS,MAAM,CAAC,GAAW,EAAE,SAAyB;IACpD,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;IACzD,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,SAAS,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AACzC,CAAC;AAED,qFAAqF;AACrF,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC3B,MAAM,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAC;YACjD,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC;QACjC,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,KAAK,EAAE,CAAC;QACnB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3F,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9G,IAAI,GAAG,CAAC,MAAM,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC3F,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,KAAK,MAAM;QAAE,OAAO,MAAM,CAAC;IACzH,IAAI,GAAG,CAAC,MAAM,IAAI,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,MAAM;QAAE,OAAO,KAAK,CAAC;IAC7E,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,QAAgB;IAC1D,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,CAAC,CAAC;IAC7B,IAAI,CAAC,GAAG,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,GAAG,CAAC,MAAM,SAAS,GAAG,EAAE,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC;IACjD,MAAM,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;AACpC,CAAC"}
1
+ {"version":3,"file":"taskManager.js","sourceRoot":"","sources":["../../../src/media/taskManager.ts"],"names":[],"mappings":"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"}
@@ -5,13 +5,14 @@ import wrapAnsi from 'wrap-ansi';
5
5
  import { MultilineInput } from './MultilineInput.js';
6
6
  import { getChatModels, modelDisplay } from './models.js';
7
7
  import { findModel } from '../media/manifest.js';
8
- import { ParamEditor } from './ParamEditor.js';
8
+ import { ParamEditor, displayMediaRef } from './ParamEditor.js';
9
9
  import { filterCommands, SLASH_COMMANDS } from './commands.js';
10
10
  import { LOGO_FRAMES, TAGLINE, brandTitle, supportsTruecolor } from './branding.js';
11
11
  import { applyMarkdown } from './markdown.js';
12
12
  import { hyperlink, fileUrl } from '../util/hyperlink.js';
13
13
  import { atCandidates } from './atPopup.js';
14
14
  import { readClipboardImage } from '../util/clipboardImage.js';
15
+ import { MAX_TOOL_CALLS_PER_TURN } from '../fs/index.js';
15
16
  /**
16
17
  * Chat TUI (phase 1). A thin view over {@link ChatController}: it renders the timeline,
17
18
  * handles slash commands and the `/model` selector, and forwards user input to the
@@ -78,7 +79,7 @@ export function App({ controller, confirmationBridge, sessionPicker, firstRun, f
78
79
  return;
79
80
  }
80
81
  let alive = true;
81
- void atCandidates(atPartial).then((c) => {
82
+ void atCandidates(atPartial, { hasLastImage: controller.resolveMediaReference('last') !== undefined }).then((c) => {
82
83
  if (alive) {
83
84
  setAtCands(c);
84
85
  setAtIndex(0);
@@ -388,13 +389,13 @@ export function App({ controller, confirmationBridge, sessionPicker, firstRun, f
388
389
  controller.note(`Unknown command: /${cmd}`);
389
390
  }
390
391
  };
391
- return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: staticItems, children: (item, i) => item === 'welcome' ? (_jsx(WelcomeBlock, { model: state.model, accountLine: accountLine, firstRun: firstRun ?? false, settled: true }, "welcome")) : (_jsx(TimelineRow, { item: item, columns: columns }, i)) }, staticEpoch), !conversationStarted && (_jsx(WelcomeBlock, { model: state.model, accountLine: accountLine, firstRun: firstRun ?? false })), liveItems.map((item, i) => (_jsx(TimelineRow, { item: item, columns: columns, awaitingConfirm: !!pending }, frozen + i))), state.busy && !pending && _jsx(BusySpinner, {}), state.runningTasks.length > 0 && _jsx(TaskSummaryBar, { tasks: state.runningTasks }), pending && editingParams ? (_jsx(ParamEditor, { info: pending, columns: columns, onApply: (model, params) => confirmationBridge?.resolve({ action: 'edit', model, params }), onCancel: () => setEditingParams(false) })) : pending ? (_jsx(ConfirmationBlock, { info: pending })) : sessions ? (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "Resume a conversation (\u2191/\u2193, Enter to choose, Esc to cancel):" }), sessions.map((s, i) => (_jsxs(Text, { color: i === sessIndex ? 'cyan' : undefined, children: [i === sessIndex ? '❯ ' : ' ', s.preview, " ", _jsxs(Text, { color: "gray", children: ["\u00B7 ", s.model, " \u00B7 ", timeAgo(s.updatedAt)] })] }, s.id)))] })) : selecting ? (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "Select a model (\u2191/\u2193, Enter to choose, Esc to cancel):" }), getChatModels().map((m, i) => (_jsxs(Text, { color: i === selIndex ? 'cyan' : undefined, children: [i === selIndex ? '❯ ' : ' ', modelDisplay(m)] }, m.id)))] })) : (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [showSuggestions && (_jsxs(Box, { flexDirection: "column", children: [suggestions.map((c, i) => (_jsxs(Text, { color: c === selectedSuggestion ? 'cyan' : undefined, children: [c === selectedSuggestion ? '❯ ' : ' ', "/", c.name, _jsxs(Text, { color: "gray", children: [c.args ? ` ${c.args}` : '', " \u2014 ", c.description] })] }, c.name))), _jsx(Text, { color: "gray", dimColor: true, children: "\u2191/\u2193 select \u00B7 Tab complete \u00B7 Enter run" })] })), showAt && (_jsxs(Box, { flexDirection: "column", children: [atCands.map((c) => (_jsxs(Text, { color: c === selectedAt ? 'cyan' : undefined, children: [c === selectedAt ? '❯ ' : ' ', c.label, _jsxs(Text, { color: "gray", children: [" \u2014 ", c.hint] })] }, c.label))), _jsx(Text, { color: "gray", dimColor: true, children: "\u2191/\u2193 select \u00B7 Tab/Enter complete" })] })), state.queued.map((q, i) => (_jsxs(Text, { color: "gray", dimColor: true, children: [' ↳ queued: ', q.display] }, i))), _jsxs(Box, { borderStyle: "round", borderLeft: false, borderRight: false, borderColor: "gray", paddingLeft: 1, children: [_jsx(Text, { color: "cyan", children: '› ' }), _jsx(MultilineInput, { value: input, onChange: onInputChange, onSubmit: onSubmit, onHistoryUp: onHistoryUp, onHistoryDown: onHistoryDown, recallActive: recallActive, columns: Math.max(20, columns - 4), verticalNav: !showAt && !showSuggestions, placeholder: 'Type a message, or /help for commands (\\ + Enter for a new line)' })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { color: exitArmed ? 'yellow' : 'gray', dimColor: !exitArmed, children: exitArmed
392
+ return (_jsxs(Box, { flexDirection: "column", children: [_jsx(Static, { items: staticItems, children: (item, i) => item === 'welcome' ? (_jsx(WelcomeBlock, { model: state.model, accountLine: accountLine, firstRun: firstRun ?? false, settled: true }, "welcome")) : (_jsx(TimelineRow, { item: item, columns: columns }, i)) }, staticEpoch), !conversationStarted && (_jsx(WelcomeBlock, { model: state.model, accountLine: accountLine, firstRun: firstRun ?? false })), liveItems.map((item, i) => (_jsx(TimelineRow, { item: item, columns: columns, awaitingConfirm: !!pending }, frozen + i))), state.busy && !pending && _jsx(BusySpinner, {}), state.runningTasks.length > 0 && _jsx(TaskSummaryBar, { tasks: state.runningTasks }), pending && editingParams ? (_jsx(ParamEditor, { info: pending, columns: columns, onApply: (model, params) => confirmationBridge?.resolve({ action: 'edit', model, params }), onCancel: () => setEditingParams(false), nameFor: (r) => controller.localNameForUrl(r) })) : pending ? (_jsx(ConfirmationBlock, { info: pending, nameFor: (r) => controller.localNameForUrl(r) })) : sessions ? (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "Resume a conversation (\u2191/\u2193, Enter to choose, Esc to cancel):" }), sessions.map((s, i) => (_jsxs(Text, { color: i === sessIndex ? 'cyan' : undefined, children: [i === sessIndex ? '❯ ' : ' ', s.preview, " ", _jsxs(Text, { color: "gray", children: ["\u00B7 ", s.model, " \u00B7 ", timeAgo(s.updatedAt)] })] }, s.id)))] })) : selecting ? (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { color: "cyan", children: "Select a model (\u2191/\u2193, Enter to choose, Esc to cancel):" }), getChatModels().map((m, i) => (_jsxs(Text, { color: i === selIndex ? 'cyan' : undefined, children: [i === selIndex ? '❯ ' : ' ', modelDisplay(m)] }, m.id)))] })) : (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [showSuggestions && (_jsxs(Box, { flexDirection: "column", children: [suggestions.map((c, i) => (_jsxs(Text, { color: c === selectedSuggestion ? 'cyan' : undefined, children: [c === selectedSuggestion ? '❯ ' : ' ', "/", c.name, _jsxs(Text, { color: "gray", children: [c.args ? ` ${c.args}` : '', " \u2014 ", c.description] })] }, c.name))), _jsx(Text, { color: "gray", dimColor: true, children: "\u2191/\u2193 select \u00B7 Tab complete \u00B7 Enter run" })] })), showAt && (_jsxs(Box, { flexDirection: "column", children: [atCands.map((c) => (_jsxs(Text, { color: c === selectedAt ? 'cyan' : undefined, children: [c === selectedAt ? '❯ ' : ' ', c.label, _jsxs(Text, { color: "gray", children: [" \u2014 ", c.hint] })] }, c.label))), _jsx(Text, { color: "gray", dimColor: true, children: "\u2191/\u2193 select \u00B7 Tab/Enter complete" })] })), state.queued.map((q, i) => (_jsxs(Text, { color: "gray", dimColor: true, children: [' ↳ queued: ', q.display] }, i))), _jsxs(Box, { borderStyle: "round", borderLeft: false, borderRight: false, borderColor: "gray", paddingLeft: 1, children: [_jsx(Text, { color: "cyan", children: '› ' }), _jsx(MultilineInput, { value: input, onChange: onInputChange, onSubmit: onSubmit, onHistoryUp: onHistoryUp, onHistoryDown: onHistoryDown, recallActive: recallActive, columns: Math.max(20, columns - 4), verticalNav: !showAt && !showSuggestions, placeholder: 'Type a message, or /help for commands (\\ + Enter for a new line)' })] }), _jsxs(Box, { justifyContent: "space-between", children: [_jsx(Text, { color: exitArmed ? 'yellow' : 'gray', dimColor: !exitArmed, children: exitArmed
392
393
  ? 'Press ctrl+c again to exit'
393
394
  : state.busy
394
395
  ? 'Esc interrupt · Enter to queue'
395
396
  : '/ commands · @ attach image' }), _jsxs(Text, { color: "gray", dimColor: true, children: [state.model, state.sessionUsage.promptTokens + state.sessionUsage.completionTokens > 0
396
397
  ? ` · ${formatTokens(state.sessionUsage.promptTokens + state.sessionUsage.completionTokens)} tok`
397
- : '', state.sessionUsage.mediaCreditsEstimated > 0 ? ` · ~${state.sessionUsage.mediaCreditsEstimated} cr` : '', state.runningTasks.length > 0 ? ` · ${state.runningTasks.length} task${state.runningTasks.length > 1 ? 's' : ''} running` : ''] })] })] }))] }));
398
+ : '', state.sessionUsage.mediaCreditsEstimated > 0 ? ` · ~${state.sessionUsage.mediaCreditsEstimated} cr` : '', state.runningTasks.length > 0 ? ` · ${state.runningTasks.length} task${state.runningTasks.length > 1 ? 's' : ''} running` : '', state.busy && state.toolCallsUsed > 0 ? (_jsxs(Text, { color: "gray", children: [" \u00B7 \u2692 tools ", state.toolCallsUsed, "/", MAX_TOOL_CALLS_PER_TURN] })) : null] })] })] }))] }));
398
399
  }
399
400
  /**
400
401
  * Full brand welcome area shown until the conversation starts (baseline §2/§3): logo raster
@@ -437,7 +438,8 @@ function timeAgo(ts) {
437
438
  * set is shown as-is; an unset value shows the model's default where known, or "model default"
438
439
  * where the upstream decides. Audio is always spelled out for video so the user never has to infer.
439
440
  */
440
- function effectiveSettings(info) {
441
+ function effectiveSettings(info, nameFor) {
442
+ const shortRef = (ref) => displayMediaRef(ref, nameFor);
441
443
  const p = info.params;
442
444
  const s = findModel(info.model)?.support;
443
445
  const isVideo = info.type === 'video';
@@ -469,10 +471,18 @@ function effectiveSettings(info) {
469
471
  rows.push(['seed', String(p.seed)]);
470
472
  if (p.negativePrompt)
471
473
  rows.push(['avoid', p.negativePrompt]);
474
+ // Reference images — show what the generation builds on, so the user sees it (not the model).
475
+ if (p.startImage)
476
+ rows.push(['start frame', shortRef(p.startImage)]);
477
+ if (p.endImage)
478
+ rows.push(['end frame', shortRef(p.endImage)]);
479
+ if (p.images && p.images.length > 0) {
480
+ rows.push(['reference', p.images.length === 1 ? shortRef(p.images[0]) : `${p.images.length} images`]);
481
+ }
472
482
  return rows;
473
483
  }
474
- function ConfirmationBlock({ info }) {
475
- const rows = effectiveSettings(info);
484
+ function ConfirmationBlock({ info, nameFor, }) {
485
+ const rows = effectiveSettings(info, nameFor);
476
486
  const labelWidth = Math.max(...rows.map(([label]) => label.length));
477
487
  return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsxs(Text, { color: "yellow", children: ["Generate ", info.type === 'video' ? 'a video' : 'an image', " with ", info.displayName, "?"] }), _jsxs(Text, { color: "gray", children: [" \u201C", info.params.prompt, "\u201D"] }), _jsxs(Text, { color: "gray", children: [" model", ' ', info.model] }), rows.map(([label, value]) => (_jsxs(Text, { color: "gray", children: [' ', label.padEnd(labelWidth), " ", value] }, label))), _jsxs(Text, { color: "gray", children: [" ~", info.credits, " credits"] }), _jsx(Text, { color: "cyan", children: " [g] Generate [e] Edit params [c] Cancel" })] }));
478
488
  }
@@ -497,6 +507,17 @@ function BusySpinner() {
497
507
  const DOT = '●';
498
508
  /** Dot color: brand coral (from the logo) on truecolor terminals; plain elsewhere. */
499
509
  const DOT_COLOR = supportsTruecolor() ? '#F15B66' : undefined;
510
+ /**
511
+ * The one place semantic rich-note styles become colors (see RichSpan in chatController):
512
+ * header = section title (bold, default fg), accent = ids/actions (matches the cyan used
513
+ * for interactive selection), dim = descriptions/hints, warn = attention.
514
+ */
515
+ const RICH_STYLE_COLORS = {
516
+ header: undefined,
517
+ accent: 'cyan',
518
+ dim: 'gray',
519
+ warn: 'yellow',
520
+ };
500
521
  /**
501
522
  * Pre-wrap ANSI-styled text to fit beside a fixed indent column. Ink's flex measurement
502
523
  * doesn't subtract sibling widths when wrapping <Text>, so long styled lines overflow the
@@ -537,6 +558,13 @@ function TimelineRow({ item, columns, awaitingConfirm, }) {
537
558
  }
538
559
  case 'note':
539
560
  return (_jsx(Box, { children: _jsx(Text, { color: "gray", children: item.text }) }));
561
+ case 'rich':
562
+ return (_jsx(Box, { flexDirection: "column", children: item.lines.map((line, i) => (_jsx(Text, { children: line.length === 0
563
+ ? ' '
564
+ : line.map((span, j) => (
565
+ // dim = gray alone (matching plain notes); gray + dimColor stacked is
566
+ // near-invisible on some dark themes.
567
+ _jsx(Text, { bold: span.style === 'header', color: span.style ? RICH_STYLE_COLORS[span.style] : undefined, children: span.text }, j))) }, i))) }));
540
568
  case 'error':
541
569
  return (_jsx(Box, { children: _jsxs(Text, { color: "red", children: ["error: ", item.text] }) }));
542
570
  }
@@ -548,6 +576,8 @@ function summarizeResult(result) {
548
576
  return `failed: ${result.error}`;
549
577
  if (result.cancelled === true)
550
578
  return 'cancelled';
579
+ if (typeof result.summary === 'string')
580
+ return result.summary;
551
581
  if (typeof result.task_id === 'string') {
552
582
  const credits = typeof result.estimated_credits === 'number' ? ` · ~${result.estimated_credits} credits` : '';
553
583
  return `task ${result.task_id} submitted${credits} — generating in the background`;
@@ -567,7 +597,7 @@ function summarizeArgs(args) {
567
597
  const p = args.prompt;
568
598
  bits.push(p.length > 40 ? `${p.slice(0, 39)}…` : p);
569
599
  }
570
- for (const key of ['model', 'aspect_ratio', 'resolution', 'duration']) {
600
+ for (const key of ['model', 'aspect_ratio', 'resolution', 'duration', 'path', 'pattern', 'include']) {
571
601
  const v = args[key];
572
602
  if (v !== undefined && v !== null && v !== '')
573
603
  bits.push(`${key.replace('_', ' ')}: ${String(v)}`);