nolo-cli 0.1.41 → 0.1.43

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 (136) hide show
  1. package/README.md +27 -12
  2. package/agent-runtime/agentThread.ts +222 -0
  3. package/agent-runtime/agentThreadAdmission.ts +74 -0
  4. package/agent-runtime/dialogWritePlan.ts +42 -0
  5. package/agent-runtime/hostAdapter.ts +1 -0
  6. package/agent-runtime/index.ts +43 -0
  7. package/agent-runtime/localLoop.ts +31 -2
  8. package/agent-runtime/localToolPolicy.ts +1 -0
  9. package/agent-runtime/localWorkspaceTools.ts +1258 -78
  10. package/agent-runtime/noloWorkspaceTools.ts +20 -1
  11. package/agent-runtime/runtimeToolPolicy.ts +1 -5
  12. package/agent-runtime/runtimeToolSurface.ts +1 -0
  13. package/agentAliases.ts +29 -9
  14. package/agentInternalCommandEntries.ts +11 -3
  15. package/agentMachineCommands.ts +1 -0
  16. package/agentRecordCommands.ts +2 -2
  17. package/agentRecordHelpers.ts +59 -6
  18. package/agentRunCommand.ts +84 -19
  19. package/ai/agent/buildSystemPrompt.ts +14 -0
  20. package/ai/agent/cliExecutor.ts +202 -43
  21. package/ai/agent/createAgentSchema.ts +2 -2
  22. package/ai/agent/liveAudioModel.ts +1 -1
  23. package/ai/agent/streamAgentChatTurn.ts +154 -20
  24. package/ai/agent/streamAgentChatTurnUtils.ts +63 -0
  25. package/ai/ai.locale.ts +70 -0
  26. package/ai/chat/inlineImageUrlsForCustomProvider.ts +7 -2
  27. package/ai/chat/sendOpenAICompletionsRequest.ts +25 -1
  28. package/ai/llm/kimi.ts +0 -1
  29. package/ai/llm/openrouterModels.ts +27 -2
  30. package/ai/memory/policy.ts +49 -0
  31. package/ai/memory/queryShared.ts +10 -4
  32. package/ai/memory/recentRelationshipRecap.ts +4 -0
  33. package/ai/memory/remember.ts +48 -104
  34. package/ai/memory/scope.ts +74 -0
  35. package/ai/memory/types.ts +6 -0
  36. package/ai/memory/understanding.ts +10 -18
  37. package/ai/policy/runtimePolicy.ts +95 -23
  38. package/ai/tools/agent/agentTools.ts +0 -21
  39. package/ai/tools/agent/startAgentDialogTool.ts +2 -1
  40. package/ai/tools/index.ts +2 -20
  41. package/ai/tools/prepareTools.ts +171 -1
  42. package/ai/tools/readXhsProfileTool.ts +80 -69
  43. package/ai/tools/table/createTableTool.ts +11 -0
  44. package/ai/tools/toolPacks.ts +19 -0
  45. package/ai/types.ts +3 -0
  46. package/app/favorite/deletedFavoriteProjection.ts +31 -0
  47. package/app/hooks/deleteDbKey.ts +24 -3
  48. package/app/i18n/translations/interface.locale.ts +48 -16
  49. package/app/types/appSummary.ts +4 -0
  50. package/app/utils/desktopAgentRuntimeTurnClient.ts +2 -0
  51. package/auth/adminPermissions.ts +64 -4
  52. package/auth/routes.ts +5 -0
  53. package/chat/chat.locale.ts +4 -0
  54. package/chat/dialog/actions/handleSendMessageAction.ts +7 -2
  55. package/chat/dialog/dialogAttachmentCleanup.ts +135 -0
  56. package/chat/dialog/dialogSlice.ts +117 -4
  57. package/chat/messages/activityCompletion.ts +97 -0
  58. package/chat/messages/imagePayloadPersistence.ts +22 -0
  59. package/chat/messages/messageContent.ts +20 -16
  60. package/chat/messages/messageSlice.ts +20 -1
  61. package/chat/messages/toolThunks.ts +32 -11
  62. package/chat/messages/types.ts +8 -1
  63. package/chat/messages/web/toolDisplayName.ts +686 -0
  64. package/cli/agentAliases.ts +29 -9
  65. package/cli/agentInternalCommandEntries.ts +11 -3
  66. package/cli/agentMachineCommands.ts +1 -0
  67. package/cli/agentRecordCommands.ts +2 -2
  68. package/cli/agentRecordHelpers.ts +59 -6
  69. package/cli/agentRunCommand.ts +84 -19
  70. package/cli/client/agentRun.ts +65 -253
  71. package/cli/client/localRuntimeAdapter.ts +179 -53
  72. package/cli/commandRegistry.ts +7 -4
  73. package/cli/dialogAttachmentCleanup.ts +151 -0
  74. package/cli/dialogCommands.ts +163 -61
  75. package/cli/dialogInternalCommandEntries.ts +1 -1
  76. package/cli/docCreateCommands.ts +345 -0
  77. package/cli/docInternalCommandEntries.ts +11 -0
  78. package/cli/docPageHelpers.ts +80 -0
  79. package/cli/docSkillHelpers.ts +67 -0
  80. package/cli/docSpaceHelpers.ts +46 -0
  81. package/cli/internalCommandEntries.ts +4 -0
  82. package/cli/machineCommands.ts +18 -34
  83. package/cli/memoryCommands.ts +253 -0
  84. package/cli/memoryInternalCommandEntries.ts +9 -0
  85. package/cli/qoderUsageProbe.ts +252 -0
  86. package/cli/scriptCommandEntries.ts +0 -3
  87. package/cli/secretScan.ts +31 -0
  88. package/cli/tableCommands.ts +248 -13
  89. package/cli/workflowInternalCommandEntries.ts +2 -3
  90. package/client/agentRun.test.ts +68 -84
  91. package/client/agentRun.ts +65 -253
  92. package/client/localRuntimeAdapter.test.ts +505 -74
  93. package/client/localRuntimeAdapter.ts +179 -53
  94. package/commandRegistry.ts +7 -4
  95. package/connector-experimental/capabilities.ts +10 -9
  96. package/create/space/sidebarVisibleTypes.ts +19 -0
  97. package/dialogAttachmentCleanup.ts +151 -0
  98. package/dialogCommands.ts +163 -61
  99. package/dialogInternalCommandEntries.ts +1 -1
  100. package/docCreateCommands.ts +345 -0
  101. package/docInternalCommandEntries.ts +11 -0
  102. package/docPageHelpers.ts +80 -0
  103. package/docSkillHelpers.ts +67 -0
  104. package/docSpaceHelpers.ts +46 -0
  105. package/integrations/google/models.ts +4 -4
  106. package/integrations/openai/generateOpenAIRequestBody.ts +0 -3
  107. package/integrations/xhs-reader/types.ts +36 -3
  108. package/integrations/xhs-reader/url.ts +24 -1
  109. package/internalCommandEntries.ts +4 -0
  110. package/machineCommands.ts +18 -34
  111. package/memoryCommands.ts +253 -0
  112. package/memoryInternalCommandEntries.ts +9 -0
  113. package/package.json +141 -114
  114. package/qoderUsageProbe.ts +252 -0
  115. package/render/contentIcon/types.ts +167 -0
  116. package/render/page/docSlice.ts +30 -3
  117. package/render/page/types.ts +2 -0
  118. package/render/table/createTableAction.ts +4 -0
  119. package/render/table/tableSlice.ts +61 -0
  120. package/render/table/types.ts +10 -0
  121. package/scriptCommandEntries.ts +0 -3
  122. package/secretScan.ts +31 -0
  123. package/server/handlers/agentRun/types.ts +24 -23
  124. package/tableCommands.ts +248 -13
  125. package/workflowInternalCommandEntries.ts +2 -3
  126. package/ai/tools/agent/taskRunTool.ts +0 -112
  127. package/cli/client/taskRunPrompt.ts +0 -27
  128. package/cli/taskRunCommand.ts +0 -265
  129. package/client/taskRunPrompt.ts +0 -27
  130. package/integrations/xhs-reader/analyze/profileAnalyzer.ts +0 -205
  131. package/integrations/xhs-reader/backends/playwrightProfileCollector.ts +0 -624
  132. package/integrations/xhs-reader/bridge/readXhsProfileWithBridge.ts +0 -227
  133. package/integrations/xhs-reader/client/xhsWebApiClient.ts +0 -229
  134. package/integrations/xhs-reader/normalize.ts +0 -390
  135. package/integrations/xhs-reader/orchestrator.ts +0 -178
  136. package/taskRunCommand.ts +0 -265
@@ -1,34 +1,31 @@
1
- import { join } from "node:path";
2
1
  import { runLocalAgentTurn } from "../agentRuntimeLocal";
3
2
  import { LOCAL_AGENT_CONFIG_MISSING_CODE } from "../agent-runtime/localLoop";
4
3
  import {
5
4
  MIMO_MONTH_AGENT_KEY,
6
5
  NOLO_PROJECT_MANAGER_AGENT_KEY,
7
- NOLO_SENIOR_FULLSTACK_AGENT_KEY,
8
6
  WIN_CODEX_AGENT_KEY,
9
7
  } from "../agentAliases";
10
8
  import type { LocalAgentToolEvent } from "../agent-runtime/localLoop";
11
9
  import type { AgentRuntimeHostAdapter, AgentRuntimeRequestedMode } from "../agentRuntimeLocal";
12
10
  import { createCliLocalRuntimeAdapter, isBuiltinNoloAgentRef } from "./localRuntimeAdapter";
13
11
  import { createStreamingTextWriter } from "./streamingOutput";
14
- import { prependTaskRunPrompt, type TaskRunPromptContext } from "./taskRunPrompt";
15
12
 
16
13
  type EnvLike = Record<string, string | undefined>;
17
14
 
18
15
  type OutputLike = {
19
16
  write(chunk: string): unknown;
20
17
  };
18
+ type AgentRunSubjectRef = {
19
+ kind: string;
20
+ id: string;
21
+ role?: string;
22
+ };
21
23
 
22
- type TaskRunAgentRole = "pm" | "frontend" | "fullstack" | "reviewer" | "codex";
23
- type TaskRunReviewStatus = "passed" | "needs_changes" | "blocked";
24
- type TaskRunToolEvidence = {
25
- toolsUsed: string[];
26
- summary: {
27
- callCount: number;
28
- resultCount: number;
29
- errorCount: number;
30
- rounds: number;
31
- };
24
+ type TaskContextReviewStatus = "passed" | "needs_changes" | "blocked";
25
+
26
+ export type TaskRowContext = {
27
+ rowDbKey: string;
28
+ artifactIds?: string[];
32
29
  };
33
30
 
34
31
  type RunAgentTurnOptions = {
@@ -42,6 +39,8 @@ type RunAgentTurnOptions = {
42
39
  category?: string;
43
40
  inheritedFromDialogKey?: string;
44
41
  parentDialogId?: string;
42
+ subjectDialogKey?: string;
43
+ subjectRefs?: AgentRunSubjectRef[];
45
44
  background?: boolean;
46
45
  noStream?: boolean;
47
46
  scriptDir: string;
@@ -54,15 +53,7 @@ type RunAgentTurnOptions = {
54
53
  timeoutMs?: number;
55
54
  traceTools?: boolean;
56
55
  eventsMode?: "jsonl";
57
- taskRunContext?: TaskRunPromptContext;
58
- taskRunRecorder?: (args: {
59
- options: RunAgentTurnOptions;
60
- status: "running" | "completed" | "failed";
61
- dialogId?: string;
62
- resultSummary?: string;
63
- errorCode?: string;
64
- toolEvidence?: TaskRunToolEvidence;
65
- }) => Promise<void>;
56
+ taskRowContext?: TaskRowContext;
66
57
  fetchImpl?: typeof fetch;
67
58
  };
68
59
 
@@ -120,7 +111,6 @@ const SERVER_PLATFORM_TOOL_NAMES = new Set([
120
111
  "deleteTableRows",
121
112
  "queryTableRows",
122
113
  "streamParallelAgents",
123
- "taskRun",
124
114
  "updateTableRow",
125
115
  "updateTableRows",
126
116
  ]);
@@ -129,7 +119,6 @@ const KNOWN_SERVER_PLATFORM_AGENT_KEYS = new Set([
129
119
  MIMO_MONTH_AGENT_KEY,
130
120
  NOLO_PROJECT_MANAGER_AGENT_KEY,
131
121
  WIN_CODEX_AGENT_KEY,
132
- NOLO_SENIOR_FULLSTACK_AGENT_KEY,
133
122
  ]);
134
123
 
135
124
  const KNOWN_SERVER_PLATFORM_AGENT_ALIASES = new Set([
@@ -295,6 +284,37 @@ function buildUserInputContent(message: string, imageUrls: string[] = []) {
295
284
  ];
296
285
  }
297
286
 
287
+ function buildSubjectRefs(options: RunAgentTurnOptions) {
288
+ const refs: AgentRunSubjectRef[] = [];
289
+ const seen = new Set<string>();
290
+ const pushRef = (ref: AgentRunSubjectRef) => {
291
+ const kind = ref.kind.trim();
292
+ const id = ref.id.trim();
293
+ const role = ref.role?.trim();
294
+ if (!kind || !id) return;
295
+ const key = `${kind}\u0000${id}\u0000${role ?? ""}`;
296
+ if (seen.has(key)) return;
297
+ seen.add(key);
298
+ refs.push({ kind, id, ...(role ? { role } : {}) });
299
+ };
300
+ for (const ref of options.subjectRefs ?? []) pushRef(ref);
301
+ if (options.subjectDialogKey) {
302
+ pushRef({
303
+ kind: "dialog",
304
+ id: options.subjectDialogKey,
305
+ role: "subject",
306
+ });
307
+ }
308
+ if (options.taskRowContext?.rowDbKey) {
309
+ pushRef({
310
+ kind: "table-row",
311
+ id: options.taskRowContext.rowDbKey,
312
+ role: "task",
313
+ });
314
+ }
315
+ return refs.length ? refs : undefined;
316
+ }
317
+
298
318
  function shouldTraceLocalTools(options: RunAgentTurnOptions) {
299
319
  const setting = (options.env.NOLO_TRACE_TOOLS ?? "").trim().toLowerCase();
300
320
  if (setting === "0" || setting === "false" || setting === "off") return false;
@@ -306,32 +326,6 @@ function resolveAgentEventMode(options: RunAgentTurnOptions): "text" | "jsonl" {
306
326
  return options.env.NOLO_AGENT_EVENTS === "jsonl" ? "jsonl" : "text";
307
327
  }
308
328
 
309
- function shouldCollectLocalToolEvidence(options: RunAgentTurnOptions) {
310
- return Boolean(options.taskRunContext?.rowDbKey);
311
- }
312
-
313
- function summarizeLocalToolEvidence(events: LocalAgentToolEvent[]): TaskRunToolEvidence | undefined {
314
- if (events.length === 0) return undefined;
315
- const toolsUsed = [
316
- ...new Set(
317
- events
318
- .filter((event) => event.type === "tool-call")
319
- .map((event) => event.toolName)
320
- .filter(Boolean)
321
- ),
322
- ];
323
- const rounds = new Set(events.map((event) => event.round)).size;
324
- return {
325
- toolsUsed,
326
- summary: {
327
- callCount: events.filter((event) => event.type === "tool-call").length,
328
- resultCount: events.filter((event) => event.type === "tool-result").length,
329
- errorCount: events.filter((event) => event.type === "tool-error").length,
330
- rounds,
331
- },
332
- };
333
- }
334
-
335
329
  function isMissingLocalAgentConfigError(error: unknown, agentRef: string) {
336
330
  return Boolean(
337
331
  error &&
@@ -368,6 +362,7 @@ function formatToolJsonEvent(event: LocalAgentToolEvent) {
368
362
  ...(typeof event.elapsedMs === "number" ? { elapsedMs: event.elapsedMs } : {}),
369
363
  ...(event.summary ? { summary: event.summary } : {}),
370
364
  ...(event.message ? { message: event.message } : {}),
365
+ ...(event.metadata ? { metadata: event.metadata } : {}),
371
366
  })}\n`;
372
367
  }
373
368
 
@@ -389,21 +384,12 @@ function shouldAttemptAutoLocal(options: RunAgentTurnOptions) {
389
384
  );
390
385
  }
391
386
 
392
- function inferTaskRunAgentRole(agentRef: string): TaskRunAgentRole {
393
- const normalized = agentRef.toLowerCase();
394
- if (normalized.includes("project-manager") || normalized.includes("manager")) return "pm";
395
- if (normalized.includes("frontend")) return "frontend";
396
- if (normalized.includes("fullstack")) return "fullstack";
397
- if (normalized.includes("review")) return "reviewer";
398
- return "codex";
399
- }
400
-
401
- export function classifyTaskRunReviewStatus(summary?: string): TaskRunReviewStatus | undefined {
387
+ export function classifyTaskContextReviewStatus(summary?: string): TaskContextReviewStatus | undefined {
402
388
  const normalized = summary?.toLowerCase().trim();
403
389
  if (!normalized) return undefined;
404
390
 
405
391
  const explicit = normalized.match(/review\s+decision\s*:\s*(passed|needs_changes|blocked)/);
406
- if (explicit?.[1]) return explicit[1] as TaskRunReviewStatus;
392
+ if (explicit?.[1]) return explicit[1] as TaskContextReviewStatus;
407
393
 
408
394
  if (/\b(blocked|cannot review|unable to review)\b|无法审查|阻塞/.test(normalized)) {
409
395
  return "blocked";
@@ -421,141 +407,6 @@ export function classifyTaskRunReviewStatus(summary?: string): TaskRunReviewStat
421
407
  return undefined;
422
408
  }
423
409
 
424
- async function runTaskRunCli(args: {
425
- options: RunAgentTurnOptions;
426
- cliArgs: string[];
427
- }) {
428
- const scriptPath = join(args.options.scriptDir, "taskRun.ts");
429
- const proc = Bun.spawn({
430
- cmd: [process.execPath, scriptPath, ...args.cliArgs],
431
- stdout: "pipe",
432
- stderr: "pipe",
433
- env: {
434
- ...process.env,
435
- ...args.options.env,
436
- BASE_URL: args.options.serverUrl,
437
- },
438
- });
439
- const [stdout, stderr, exitCode] = await Promise.all([
440
- new Response(proc.stdout).text(),
441
- new Response(proc.stderr).text(),
442
- proc.exited,
443
- ]);
444
- if (exitCode !== 0) {
445
- throw new Error((stderr || stdout || `taskRun.ts exited ${exitCode}`).trim());
446
- }
447
- }
448
-
449
- async function defaultTaskRunRecorder(args: {
450
- options: RunAgentTurnOptions;
451
- status: "running" | "completed" | "failed";
452
- dialogId?: string;
453
- resultSummary?: string;
454
- errorCode?: string;
455
- toolEvidence?: TaskRunToolEvidence;
456
- }) {
457
- const context = args.options.taskRunContext;
458
- if (!context?.rowDbKey) return;
459
- const role = inferTaskRunAgentRole(args.options.agentName || args.options.agentKey);
460
- if (role === "reviewer" && args.status !== "running") {
461
- await runTaskRunCli({
462
- options: args.options,
463
- cliArgs: [
464
- "request-review",
465
- "--row-dbkey",
466
- context.rowDbKey,
467
- "--base-url",
468
- args.options.serverUrl,
469
- "--reviewer-agent-key",
470
- args.options.agentKey,
471
- ...(context.artifactIds?.length ? ["--artifact-ids", context.artifactIds.join(",")] : []),
472
- ...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
473
- ],
474
- });
475
- }
476
- await runTaskRunCli({
477
- options: args.options,
478
- cliArgs: [
479
- "record-agent-run",
480
- "--row-dbkey",
481
- context.rowDbKey,
482
- "--base-url",
483
- args.options.serverUrl,
484
- "--agent-key",
485
- args.options.agentKey,
486
- "--role",
487
- role,
488
- "--run-status",
489
- args.status,
490
- ...(context.workItemId ? ["--work-item-id", context.workItemId] : []),
491
- ...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
492
- ...(args.resultSummary ? ["--result-summary", args.resultSummary.slice(0, 240)] : []),
493
- ...(args.errorCode ? ["--error-code", args.errorCode] : []),
494
- ...(args.toolEvidence?.toolsUsed?.length
495
- ? ["--tools-used", args.toolEvidence.toolsUsed.join(",")]
496
- : []),
497
- ...(args.toolEvidence?.summary
498
- ? ["--tool-trace-summary", JSON.stringify(args.toolEvidence.summary)]
499
- : []),
500
- ],
501
- });
502
- if (context.workItemId && args.dialogId) {
503
- await runTaskRunCli({
504
- options: args.options,
505
- cliArgs: [
506
- "update-work-item",
507
- "--row-dbkey",
508
- context.rowDbKey,
509
- "--base-url",
510
- args.options.serverUrl,
511
- "--id",
512
- context.workItemId,
513
- "--dialog-ids",
514
- args.dialogId,
515
- ],
516
- });
517
- }
518
- if (role === "reviewer" && args.status !== "running") {
519
- const reviewStatus =
520
- args.status === "failed" ? "blocked" : classifyTaskRunReviewStatus(args.resultSummary);
521
- if (reviewStatus) {
522
- await runTaskRunCli({
523
- options: args.options,
524
- cliArgs: [
525
- "review-result",
526
- "--row-dbkey",
527
- context.rowDbKey,
528
- "--base-url",
529
- args.options.serverUrl,
530
- "--review-status",
531
- reviewStatus,
532
- "--reviewer-agent-key",
533
- args.options.agentKey,
534
- ...(context.artifactIds?.length ? ["--artifact-ids", context.artifactIds.join(",")] : []),
535
- ...(args.dialogId ? ["--dialog-id", args.dialogId] : []),
536
- ],
537
- });
538
- }
539
- }
540
- }
541
-
542
- async function recordTaskRunOutcome(args: {
543
- options: RunAgentTurnOptions;
544
- status: "running" | "completed" | "failed";
545
- dialogId?: string;
546
- resultSummary?: string;
547
- errorCode?: string;
548
- toolEvidence?: TaskRunToolEvidence;
549
- }) {
550
- if (!args.options.taskRunContext?.rowDbKey) return;
551
- try {
552
- await (args.options.taskRunRecorder ?? defaultTaskRunRecorder)(args);
553
- } catch (error) {
554
- args.options.output.write(
555
- `[nolo] task-run writeback failed: ${error instanceof Error ? error.message : String(error)}\n`
556
- );
557
- }
558
- }
559
410
 
560
411
  function formatUsage(usage: any, dialogId: unknown) {
561
412
  const parts: string[] = [];
@@ -595,10 +446,11 @@ function buildTransportErrorHint(serverUrl: string, error: unknown) {
595
446
 
596
447
  async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string) {
597
448
  const spinner = new Spinner(options.output, `${options.agentName} -> working`);
598
- spinner.start();
599
-
600
- const fetchImpl = options.fetchImpl ?? fetch;
601
- let res: Response;
449
+ spinner.start();
450
+
451
+ const fetchImpl = options.fetchImpl ?? fetch;
452
+ const subjectRefs = buildSubjectRefs(options);
453
+ let res: Response;
602
454
  try {
603
455
  res = await fetchImpl(`${options.serverUrl}/api/agent/run`, {
604
456
  method: "POST",
@@ -609,7 +461,7 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
609
461
  body: JSON.stringify({
610
462
  agentKey: options.agentKey,
611
463
  userInput: buildUserInputContent(
612
- prependTaskRunPrompt(options.message, options.taskRunContext),
464
+ options.message,
613
465
  options.imageUrls
614
466
  ),
615
467
  runtimeContext: {
@@ -618,22 +470,7 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
618
470
  runtime: "bun",
619
471
  entrypoint: "nolo-cli",
620
472
  capabilities: ["text-io", "streaming", "slash-commands"],
621
- ...(options.taskRunContext
622
- ? {
623
- taskRun: {
624
- rowDbKey: options.taskRunContext.rowDbKey,
625
- ...(options.taskRunContext.taskRunId
626
- ? { taskRunId: options.taskRunContext.taskRunId }
627
- : {}),
628
- ...(options.taskRunContext.workItemId
629
- ? { workItemId: options.taskRunContext.workItemId }
630
- : {}),
631
- ...(options.taskRunContext.artifactIds?.length
632
- ? { artifactIds: options.taskRunContext.artifactIds }
633
- : {}),
634
- },
635
- }
636
- : {}),
473
+ ...(subjectRefs ? { subjectRefs } : {}),
637
474
  },
638
475
  ...(options.continueDialogId
639
476
  ? { continueDialogId: options.continueDialogId }
@@ -659,16 +496,6 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
659
496
  if (contentType.includes("text/event-stream") && res.body) {
660
497
  spinner.stop();
661
498
  const result = await readStreamingAgentRun(options, res);
662
- await recordTaskRunOutcome({
663
- options,
664
- status: result.streamInterrupted
665
- ? "running"
666
- : result.exitCode === 0
667
- ? "completed"
668
- : "failed",
669
- dialogId: result.dialogId,
670
- ...(result.exitCode !== 0 ? { errorCode: "STREAM_FAILED" } : {}),
671
- });
672
499
  return result;
673
500
  }
674
501
 
@@ -686,6 +513,7 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
686
513
  const messageText = typeof data?.message === "string" ? data.message.trim() : "";
687
514
  const reasonText = typeof data?.reason === "string" ? data.reason.trim() : "";
688
515
  const codeText = typeof data?.code === "string" ? data.code.trim() : "";
516
+ const dialogIdText = typeof data?.dialogId === "string" ? data.dialogId.trim() : "";
689
517
  if (errorText || messageText) {
690
518
  options.output.write(`${errorText || messageText}\n`);
691
519
  if (messageText && messageText !== errorText) {
@@ -698,13 +526,13 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
698
526
  options.output.write(`reason=${reasonText}\n`);
699
527
  }
700
528
  }
701
- await recordTaskRunOutcome({
702
- options,
703
- status: "failed",
704
- errorCode: `HTTP_${res.status}`,
705
- resultSummary: String(data?.error || data?.message || "").trim() || undefined,
706
- });
707
- return { exitCode: 1 };
529
+ if (dialogIdText) {
530
+ options.output.write(`[nolo] failed dialog: ${dialogIdText}\n`);
531
+ options.output.write(
532
+ `[nolo] continue with: nolo agent run ${options.agentKey} --continue ${dialogIdText} --msg "retry"\n`
533
+ );
534
+ }
535
+ return dialogIdText ? { exitCode: 1, dialogId: dialogIdText } : { exitCode: 1 };
708
536
  }
709
537
 
710
538
  const content = String(data?.content ?? data?.message ?? "").trim();
@@ -722,12 +550,6 @@ async function runHttpAgentTurn(options: RunAgentTurnOptions, authToken: string)
722
550
  ? { dialogId: data.dialogId }
723
551
  : {}),
724
552
  };
725
- await recordTaskRunOutcome({
726
- options,
727
- status: options.background ? "running" : "completed",
728
- dialogId: result.dialogId,
729
- ...(!options.background && content ? { resultSummary: content } : {}),
730
- });
731
553
  return result;
732
554
  }
733
555
 
@@ -754,16 +576,14 @@ async function runLocalAgentTurnForCli(
754
576
 
755
577
  const spinner = new Spinner(options.output, `${options.agentName} -> working locally`);
756
578
  spinner.start();
757
- const toolEvents: LocalAgentToolEvent[] = [];
758
579
  try {
759
580
  const traceLocalTools = shouldTraceLocalTools(options);
760
- const collectToolEvidence = shouldCollectLocalToolEvidence(options);
761
581
  const eventMode = resolveAgentEventMode(options);
762
582
  const result = await runLocalAgentTurn({
763
583
  adapter,
764
584
  agentRef: options.agentKey,
765
585
  input: buildUserInputContent(
766
- prependTaskRunPrompt(options.message, options.taskRunContext),
586
+ options.message,
767
587
  options.imageUrls
768
588
  ),
769
589
  continueDialogId: options.continueDialogId,
@@ -774,10 +594,9 @@ async function runLocalAgentTurnForCli(
774
594
  background: options.background,
775
595
  noStream: options.noStream,
776
596
  ...(typeof options.timeoutMs === "number" ? { timeoutMs: options.timeoutMs } : {}),
777
- ...(traceLocalTools || collectToolEvidence
597
+ ...(traceLocalTools
778
598
  ? {
779
599
  onToolEvent: (event) => {
780
- if (collectToolEvidence) toolEvents.push(event);
781
600
  if (traceLocalTools) {
782
601
  spinner.stop();
783
602
  options.output.write(
@@ -797,13 +616,6 @@ async function runLocalAgentTurnForCli(
797
616
  } else {
798
617
  options.output.write(`\n${options.agentName} > (no text response)\n`);
799
618
  }
800
- await recordTaskRunOutcome({
801
- options,
802
- status: options.background ? "running" : "completed",
803
- dialogId: result.dialogId,
804
- ...(!options.background && content ? { resultSummary: content } : {}),
805
- toolEvidence: summarizeLocalToolEvidence(toolEvents),
806
- });
807
619
  return { exitCode: 0, dialogId: result.dialogId };
808
620
  } catch (error) {
809
621
  spinner.stop();
@@ -814,7 +626,7 @@ async function runLocalAgentTurnForCli(
814
626
  }\n`
815
627
  );
816
628
  }
817
- return { exitCode: 1, localError: error, toolEvidence: summarizeLocalToolEvidence(toolEvents) };
629
+ return { exitCode: 1, localError: error };
818
630
  }
819
631
  }
820
632