@ai-setting/roy-agent-core 1.7.71 → 1.7.75

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 (94) hide show
  1. package/dist/env/agent/agent-component.js +6 -6
  2. package/dist/env/agent/agent-registry.d.ts +4 -1
  3. package/dist/env/agent/index.js +6 -6
  4. package/dist/env/agent/summary-agent.d.ts +6 -15
  5. package/dist/env/agent/types.d.ts +0 -17
  6. package/dist/env/error-reply.d.ts +46 -0
  7. package/dist/env/error-reply.js +3 -1
  8. package/dist/env/event-source/event-source-handlers.js +12 -12
  9. package/dist/env/event-source/index.js +13 -13
  10. package/dist/env/index.js +30 -31
  11. package/dist/env/llm/index.js +2 -2
  12. package/dist/env/llm/orphan-toolcall.d.ts +107 -0
  13. package/dist/env/llm/temperature-policy.d.ts +107 -0
  14. package/dist/env/llm/types.d.ts +2 -2
  15. package/dist/env/plugin/index.js +3 -3
  16. package/dist/env/prompt/index.js +3 -3
  17. package/dist/env/prompt/prompts-index.d.ts +26 -4
  18. package/dist/env/session/__bench__/replay-compact.d.ts +137 -0
  19. package/dist/env/session/__bench__/run-replay.d.ts +15 -0
  20. package/dist/env/session/compact-checkpoint-content.d.ts +67 -0
  21. package/dist/env/session/index.d.ts +1 -0
  22. package/dist/env/session/index.js +4 -5
  23. package/dist/env/session/session-component.d.ts +47 -30
  24. package/dist/env/session/storage/index.js +3 -3
  25. package/dist/env/session/storage/sqlite.d.ts +8 -0
  26. package/dist/env/session/types.d.ts +45 -30
  27. package/dist/env/task/delegate/delegate-tool.d.ts +8 -0
  28. package/dist/env/task/delegate/delegate-tool.js +4 -4
  29. package/dist/env/task/delegate/index.js +4 -4
  30. package/dist/env/task/index.js +7 -7
  31. package/dist/env/task/mcp/index.js +2 -2
  32. package/dist/env/task/plugins/index.d.ts +3 -0
  33. package/dist/env/task/plugins/index.js +32 -9
  34. package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +61 -0
  35. package/dist/env/task/plugins/lark-card-patch-notifier.js +6 -2
  36. package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +42 -0
  37. package/dist/env/task/prompt/index.js +1 -1
  38. package/dist/env/task/prompt/task-discipline.d.ts +9 -3
  39. package/dist/env/task/tools/cancel-tool.d.ts +28 -0
  40. package/dist/env/task/tools/index.d.ts +1 -0
  41. package/dist/env/task/tools/index.js +4 -2
  42. package/dist/env/task/tools/task-types.d.ts +22 -0
  43. package/dist/env/tool/built-in/compact-session-tool.d.ts +120 -0
  44. package/dist/env/tool/built-in/index.d.ts +2 -0
  45. package/dist/env/tool/built-in/index.js +6 -2
  46. package/dist/env/tool/index.js +4 -4
  47. package/dist/env/workflow/engine/index.js +6 -7
  48. package/dist/env/workflow/index.js +15 -14
  49. package/dist/env/workflow/plugins/index.js +2 -2
  50. package/dist/env/workflow/tools/ask-user-tool.d.ts +88 -0
  51. package/dist/env/workflow/tools/index.js +11 -10
  52. package/dist/env/workflow/tools/run-workflow.d.ts +2 -2
  53. package/dist/env/workflow/types/index.js +2 -2
  54. package/dist/env/workflow/types/workflow-hil.d.ts +25 -1
  55. package/dist/env/workflow/utils/index.js +5 -5
  56. package/dist/index.d.ts +1 -1
  57. package/dist/index.js +33 -34
  58. package/dist/shared/@ai-setting/{roy-agent-core-hy3zn2q2.js → roy-agent-core-0qyrk5k0.js} +22 -2
  59. package/dist/shared/@ai-setting/{roy-agent-core-kmbct9yg.js → roy-agent-core-0snm5hc5.js} +1 -1
  60. package/dist/shared/@ai-setting/{roy-agent-core-4jjwewvw.js → roy-agent-core-11shp00p.js} +31 -10
  61. package/dist/shared/@ai-setting/{roy-agent-core-yr1mryb8.js → roy-agent-core-1v4g0d4x.js} +1 -1
  62. package/dist/shared/@ai-setting/{roy-agent-core-02j24hrg.js → roy-agent-core-264qexac.js} +71 -4
  63. package/dist/shared/@ai-setting/{roy-agent-core-9geem94g.js → roy-agent-core-29b6hc39.js} +1 -1
  64. package/dist/shared/@ai-setting/roy-agent-core-2akfd64z.js +374 -0
  65. package/dist/shared/@ai-setting/{roy-agent-core-zv8bswpw.js → roy-agent-core-3e6gg17d.js} +120 -28
  66. package/dist/shared/@ai-setting/{roy-agent-core-8cx7cfdg.js → roy-agent-core-3fh1f7s7.js} +2 -3
  67. package/dist/shared/@ai-setting/{roy-agent-core-mwa6apzx.js → roy-agent-core-4gr3k7qg.js} +17 -4
  68. package/dist/shared/@ai-setting/{roy-agent-core-zsbh9bfv.js → roy-agent-core-60jbrfye.js} +6 -6
  69. package/dist/shared/@ai-setting/{roy-agent-core-add1zqsh.js → roy-agent-core-6cy43nss.js} +22 -1
  70. package/dist/shared/@ai-setting/{roy-agent-core-mw2cen6s.js → roy-agent-core-6rh8k6ba.js} +5 -5
  71. package/dist/shared/@ai-setting/{roy-agent-core-kpg25s2q.js → roy-agent-core-8ez6mccb.js} +4 -2
  72. package/dist/shared/@ai-setting/{roy-agent-core-sjr1kmfz.js → roy-agent-core-acj8ag08.js} +1 -1
  73. package/dist/shared/@ai-setting/{roy-agent-core-mds8tqd0.js → roy-agent-core-cgtq6427.js} +1 -1
  74. package/dist/shared/@ai-setting/{roy-agent-core-9bshyqjn.js → roy-agent-core-ddyk1rc0.js} +183 -132
  75. package/dist/shared/@ai-setting/{roy-agent-core-hfr6bzts.js → roy-agent-core-djpq6yb0.js} +16 -7
  76. package/dist/shared/@ai-setting/{roy-agent-core-002g6nfk.js → roy-agent-core-dqxec05w.js} +7 -6
  77. package/dist/shared/@ai-setting/{roy-agent-core-07fvy74y.js → roy-agent-core-ed233k5z.js} +21 -7
  78. package/dist/shared/@ai-setting/{roy-agent-core-jrj30vq3.js → roy-agent-core-er070zjq.js} +1 -1
  79. package/dist/shared/@ai-setting/{roy-agent-core-40rv283c.js → roy-agent-core-fghc2m8z.js} +152 -2
  80. package/dist/shared/@ai-setting/{roy-agent-core-7sj9xs9c.js → roy-agent-core-hnyk1by7.js} +110 -2
  81. package/dist/shared/@ai-setting/{roy-agent-core-101qtkyc.js → roy-agent-core-jg65qnwa.js} +11 -8
  82. package/dist/shared/@ai-setting/{roy-agent-core-e25xkv53.js → roy-agent-core-mkc3zshb.js} +3 -1
  83. package/dist/shared/@ai-setting/{roy-agent-core-0cb6w0k7.js → roy-agent-core-mww0mnd9.js} +231 -27
  84. package/dist/shared/@ai-setting/{roy-agent-core-5repth1n.js → roy-agent-core-n9q1encx.js} +1 -1
  85. package/dist/shared/@ai-setting/{roy-agent-core-46rv4d7d.js → roy-agent-core-nmx9934r.js} +92 -2
  86. package/dist/shared/@ai-setting/{roy-agent-core-1w9y7mxj.js → roy-agent-core-p3zv1mx5.js} +1 -1
  87. package/dist/shared/@ai-setting/roy-agent-core-snvh4s2p.js +662 -0
  88. package/dist/shared/@ai-setting/{roy-agent-core-dt104qa1.js → roy-agent-core-v85n42ve.js} +1 -1
  89. package/dist/shared/@ai-setting/{roy-agent-core-37tj4y6a.js → roy-agent-core-v87njmq7.js} +3 -3
  90. package/dist/shared/@ai-setting/{roy-agent-core-k13pxrpk.js → roy-agent-core-y7x2qzwc.js} +553 -92
  91. package/package.json +1 -1
  92. package/dist/shared/@ai-setting/roy-agent-core-1gsbqesr.js +0 -1083
  93. package/dist/shared/@ai-setting/roy-agent-core-58804s3j.js +0 -155
  94. package/dist/shared/@ai-setting/roy-agent-core-ze068vc9.js +0 -37
@@ -1,19 +1,22 @@
1
1
  import {
2
+ compactSessionTool,
3
+ createCompactSessionTool,
2
4
  createQueryBackgroundProcessTool
3
- } from "./roy-agent-core-58804s3j.js";
5
+ } from "./roy-agent-core-2akfd64z.js";
4
6
  import {
5
7
  createStopTool
6
8
  } from "./roy-agent-core-jm136jzh.js";
7
9
  import {
8
10
  BackgroundTaskManager,
9
11
  createDelegateTool
10
- } from "./roy-agent-core-101qtkyc.js";
12
+ } from "./roy-agent-core-jg65qnwa.js";
11
13
  import {
12
14
  TaskEntityEventTypes
13
15
  } from "./roy-agent-core-8gxth0eh.js";
14
16
  import {
15
17
  batchArchiveTaskTool,
16
18
  batchDeleteTaskTool,
19
+ cancelTaskTool,
17
20
  completeTaskTool,
18
21
  createTaskTool,
19
22
  deleteTaskTool,
@@ -22,7 +25,7 @@ import {
22
25
  searchTasksTool,
23
26
  treeTasksTool,
24
27
  updateTaskTool
25
- } from "./roy-agent-core-7sj9xs9c.js";
28
+ } from "./roy-agent-core-hnyk1by7.js";
26
29
  import {
27
30
  createOperationTool,
28
31
  deleteOperationTool,
@@ -336,6 +339,9 @@ class TaskComponent extends BaseComponent {
336
339
  await this.registerTools();
337
340
  this.toolComponent.register(createQueryBackgroundProcessTool(this.backgroundTaskManager), "built-in");
338
341
  logger2.debug("[TaskComponent] Injected BackgroundTaskManager into query_background_process tool (factory pattern)");
342
+ const sessionComponent = this.env?.getComponent("session");
343
+ this.toolComponent.register(createCompactSessionTool(this.backgroundTaskManager, sessionComponent ?? null), "built-in");
344
+ logger2.debug("[TaskComponent] Registered compact_session tool (factory pattern)");
339
345
  } else {
340
346
  logger2.warn("[TaskComponent] ToolComponent not found, skipping tool registration");
341
347
  }
@@ -352,6 +358,12 @@ class TaskComponent extends BaseComponent {
352
358
  } catch (err) {
353
359
  logger2.warn(`[TaskComponent] Failed to reset query_background_process tool: ${err.message}`);
354
360
  }
361
+ try {
362
+ this.toolComponent.register(compactSessionTool, "built-in");
363
+ logger2.debug("[TaskComponent] Reset compact_session tool to no-deps default (cleanup)");
364
+ } catch (err) {
365
+ logger2.warn(`[TaskComponent] Failed to reset compact_session tool: ${err.message}`);
366
+ }
355
367
  }
356
368
  if (this.backgroundTaskManager) {
357
369
  await this.backgroundTaskManager.dispose(this.skipAbortRunningTasksOnDispose ? {
@@ -378,7 +390,8 @@ class TaskComponent extends BaseComponent {
378
390
  batchDeleteTaskTool(this),
379
391
  updateTaskTool(this),
380
392
  deleteTaskTool(this),
381
- completeTaskTool(this)
393
+ completeTaskTool(this),
394
+ cancelTaskTool(this)
382
395
  ];
383
396
  const operationToolsList = [
384
397
  createOperationTool(this),
@@ -1,9 +1,6 @@
1
1
  import {
2
2
  defaultLarkCliRunner
3
3
  } from "./roy-agent-core-bxkjk7zx.js";
4
- import {
5
- notifyReactFailure
6
- } from "./roy-agent-core-add1zqsh.js";
7
4
  import {
8
5
  cliCommandHandler
9
6
  } from "./roy-agent-core-v0hf14bj.js";
@@ -13,17 +10,20 @@ import {
13
10
  createPerTaskGroupChatPlugin,
14
11
  extractPerTaskChatId,
15
12
  extractPerTaskChatName
16
- } from "./roy-agent-core-k13pxrpk.js";
13
+ } from "./roy-agent-core-y7x2qzwc.js";
17
14
  import {
18
15
  getSharedEventStore
19
16
  } from "./roy-agent-core-na18zwj0.js";
20
17
  import {
21
18
  createLarkCliWorkflowNotifyHook
22
- } from "./roy-agent-core-1w9y7mxj.js";
19
+ } from "./roy-agent-core-p3zv1mx5.js";
23
20
  import {
24
21
  LarkCardPatchNotifier,
25
22
  buildTaskCard
26
- } from "./roy-agent-core-46rv4d7d.js";
23
+ } from "./roy-agent-core-nmx9934r.js";
24
+ import {
25
+ notifyReactFailure
26
+ } from "./roy-agent-core-6cy43nss.js";
27
27
  import {
28
28
  normalizeLarkAtMentions
29
29
  } from "./roy-agent-core-m880qz3y.js";
@@ -401,6 +401,27 @@ function __resetFailureReplyDedupForTest() {
401
401
  repliedTriggers.clear();
402
402
  }
403
403
  var DEFAULT_REPLY_TIMEOUT_MS = 5000;
404
+ async function deliverAskUserMessage(options) {
405
+ const { chatId, messageId, profile, content } = options;
406
+ if (!chatId && !messageId) {
407
+ return { sent: false, error: "no-target" };
408
+ }
409
+ try {
410
+ await spawnLarkReply({
411
+ chatId,
412
+ messageId,
413
+ content,
414
+ profile,
415
+ timeoutMs: options.timeoutMs ?? DEFAULT_REPLY_TIMEOUT_MS
416
+ });
417
+ return { sent: true };
418
+ } catch (err) {
419
+ return {
420
+ sent: false,
421
+ error: err instanceof Error ? err.message : String(err)
422
+ };
423
+ }
424
+ }
404
425
  function spawnLarkReply(options) {
405
426
  return new Promise((resolve, reject) => {
406
427
  const { chatId, messageId, content, profile } = options;
@@ -521,4 +542,4 @@ async function notifyReactFailure(options) {
521
542
  }
522
543
  }
523
544
 
524
- export { extractRetryAfterSeconds, humanizeRetryAfter, getFailureRuleIds, classifyReactFailure, buildFailureReplyMarkdown, formatCliFailureLine, __resetFailureReplyDedupForTest, notifyReactFailure };
545
+ export { extractRetryAfterSeconds, humanizeRetryAfter, getFailureRuleIds, classifyReactFailure, buildFailureReplyMarkdown, formatCliFailureLine, __resetFailureReplyDedupForTest, deliverAskUserMessage, notifyReactFailure };
@@ -7,7 +7,7 @@ import {
7
7
  import {
8
8
  AgentComponentAdapter,
9
9
  init_agent_component_adapter
10
- } from "./roy-agent-core-002g6nfk.js";
10
+ } from "./roy-agent-core-dqxec05w.js";
11
11
  import {
12
12
  PythonCallNode,
13
13
  SkillNode,
@@ -37,23 +37,23 @@ import {
37
37
  import {
38
38
  TemplateResolver,
39
39
  init_template_resolver
40
- } from "./roy-agent-core-sjr1kmfz.js";
40
+ } from "./roy-agent-core-acj8ag08.js";
41
41
  import {
42
42
  DAGManager,
43
43
  init_dag_manager
44
- } from "./roy-agent-core-mds8tqd0.js";
44
+ } from "./roy-agent-core-cgtq6427.js";
45
45
  import {
46
46
  WorkflowError,
47
47
  createWorkflowEvent,
48
48
  init_event,
49
49
  init_types,
50
50
  init_workflow_error
51
- } from "./roy-agent-core-jrj30vq3.js";
51
+ } from "./roy-agent-core-er070zjq.js";
52
52
  import {
53
53
  AskUserError,
54
54
  createNodeInterruptEvent,
55
55
  init_workflow_hil
56
- } from "./roy-agent-core-e25xkv53.js";
56
+ } from "./roy-agent-core-mkc3zshb.js";
57
57
  import {
58
58
  TracedAs,
59
59
  init_decorator
@@ -2,8 +2,9 @@ import {
2
2
  understandImageTool
3
3
  } from "./roy-agent-core-xwm8zavb.js";
4
4
  import {
5
+ compactSessionTool,
5
6
  queryBackgroundProcessTool
6
- } from "./roy-agent-core-58804s3j.js";
7
+ } from "./roy-agent-core-2akfd64z.js";
7
8
  import {
8
9
  getCurrentProcessRegistry,
9
10
  killProcessTree
@@ -939,7 +940,8 @@ function getAllBuiltInTools() {
939
940
  editFileTool,
940
941
  grepTool,
941
942
  understandImageTool,
942
- queryBackgroundProcessTool
943
+ queryBackgroundProcessTool,
944
+ compactSessionTool
943
945
  ];
944
946
  }
945
947
  function getBuiltInTool(name) {
@@ -7,7 +7,7 @@ import {
7
7
  nodeNotFound,
8
8
  pathNotFound,
9
9
  unresolvedVariable
10
- } from "./roy-agent-core-jrj30vq3.js";
10
+ } from "./roy-agent-core-er070zjq.js";
11
11
  import {
12
12
  TracedAs,
13
13
  init_decorator
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  LoopGuardConfigSchema,
3
3
  init_types
4
- } from "./roy-agent-core-jrj30vq3.js";
4
+ } from "./roy-agent-core-er070zjq.js";
5
5
  import {
6
6
  TracedAs,
7
7
  init_decorator
@@ -1,11 +1,7 @@
1
1
  import {
2
2
  MemorySessionStore,
3
3
  SQLiteSessionStore
4
- } from "./roy-agent-core-hy3zn2q2.js";
5
- import {
6
- init_loose_json,
7
- tryParseJsonFromText
8
- } from "./roy-agent-core-ze068vc9.js";
4
+ } from "./roy-agent-core-0qyrk5k0.js";
9
5
  import {
10
6
  init_search_query_parser,
11
7
  matchesQuery,
@@ -47,7 +43,8 @@ var SESSION_DEFAULTS = {
47
43
  "session.storage.dbPath": undefined,
48
44
  "session.checkpoint.enabled": false,
49
45
  "session.contextLimit": 1e5,
50
- "session.maxSessions": 100
46
+ "session.maxSessions": 100,
47
+ "session.compactModel": undefined
51
48
  };
52
49
  var SESSION_CONFIG_REGISTRATION = {
53
50
  name: "session",
@@ -64,56 +61,108 @@ var SESSION_CONFIG_REGISTRATION = {
64
61
  { key: "session.storage.dbPath", sources: ["env", "file"] },
65
62
  { key: "session.checkpoint.enabled", sources: ["env", "file"] },
66
63
  { key: "session.contextLimit", sources: ["env", "file"] },
67
- { key: "session.maxSessions", sources: ["env", "file"] }
64
+ { key: "session.maxSessions", sources: ["env", "file"] },
65
+ { key: "session.compactModel", sources: ["env", "file"] }
68
66
  ]
69
67
  };
70
68
 
71
69
  // src/env/session/session-component.ts
72
70
  init_search_query_parser();
73
- init_loose_json();
74
71
  import path from "path";
75
- import { z } from "zod";
76
- var logger = createLogger("session");
77
- function normalizeAgentCheckpoint(data) {
78
- return {
79
- title: data.title || "Untitled Checkpoint",
80
- processKeyPoints: data.processKeyPoints || [],
81
- currentState: data.currentState || "",
82
- nextSteps: data.nextSteps || [],
83
- userIntents: data.userIntents || [],
84
- rawResponse: JSON.stringify(data)
85
- };
86
- }
72
+
73
+ // src/env/session/compact-checkpoint-content.ts
87
74
  var DEGRADED_TEXT_SENTINELS = new Set([
88
- "[hint extraction failed]"
75
+ "[hint extraction failed]",
76
+ "maximum iterations reached",
77
+ "no usable checkpoint output"
89
78
  ]);
90
- function isUsableCheckpointText(text) {
79
+ var MIN_CONTENT_LENGTH = 20;
80
+ function normalizeCheckpointContent(text) {
91
81
  const raw = (text ?? "").trim();
92
82
  if (!raw)
93
- return false;
94
- return !DEGRADED_TEXT_SENTINELS.has(raw.toLowerCase());
83
+ return;
84
+ if (DEGRADED_TEXT_SENTINELS.has(raw.toLowerCase()))
85
+ return;
86
+ if (raw.length < MIN_CONTENT_LENGTH)
87
+ return;
88
+ return raw;
95
89
  }
96
- function buildCheckpointFromFinalText(finalText) {
97
- if (!isUsableCheckpointText(finalText))
90
+ function buildCheckpointFromText(text) {
91
+ const content = normalizeCheckpointContent(text);
92
+ if (!content)
98
93
  return;
99
- const raw = finalText.trim();
100
- const parsed = tryParseJsonFromText(raw);
101
- if (parsed && (parsed.title || parsed.currentState || parsed.processKeyPoints)) {
102
- return normalizeAgentCheckpoint(parsed);
103
- }
104
- const lines = raw.split(`
94
+ const lines = content.split(`
105
95
  `).map((l) => l.trim()).filter(Boolean);
106
96
  const heading = lines.find((l) => /^#{1,6}\s+/.test(l)) ?? lines[0] ?? "";
107
97
  const title = heading.replace(/^#{1,6}\s+/, "").replace(/^[*_`\s]+|[*_`\s]+$/g, "").slice(0, 80);
108
98
  return {
109
99
  title: title || "Untitled Checkpoint",
110
- processKeyPoints: [],
111
- currentState: raw,
112
- nextSteps: [],
113
- userIntents: [],
114
- rawResponse: raw
100
+ content
101
+ };
102
+ }
103
+ function isModernCheckpoint(cp) {
104
+ return typeof cp.content === "string" && (cp.content ?? "").trim().length > 0;
105
+ }
106
+ function adaptLegacyCheckpoint(cp) {
107
+ if (isModernCheckpoint(cp))
108
+ return cp;
109
+ const legacy = cp;
110
+ const sections = [];
111
+ const summary = (legacy.summary ?? "").trim();
112
+ if (summary)
113
+ sections.push(summary);
114
+ const points = legacy.processKeyPoints ?? [];
115
+ if (points.length) {
116
+ sections.push(points.map((p, i) => `${i + 1}. ${p}`).join(`
117
+ `));
118
+ }
119
+ const state = (legacy.currentState ?? "").trim();
120
+ if (state)
121
+ sections.push(state);
122
+ const steps = legacy.nextSteps ?? [];
123
+ if (steps.length) {
124
+ sections.push(steps.map((s, i) => `${i + 1}. ${s}`).join(`
125
+ `));
126
+ }
127
+ const intents = legacy.userIntents ?? [];
128
+ if (intents.length) {
129
+ sections.push(intents.map((u, i) => `${i + 1}. ${u}`).join(`
130
+ `));
131
+ }
132
+ let content = sections.join(`
133
+
134
+ `).trim();
135
+ if (!content)
136
+ content = cp.title ?? "";
137
+ if (!normalizeCheckpointContent(content)) {
138
+ content = cp.id ? `Checkpoint ${cp.id}` : "";
139
+ }
140
+ return {
141
+ id: cp.id,
142
+ messageIndex: cp.messageIndex,
143
+ title: cp.title,
144
+ content,
145
+ messageCountBefore: cp.messageCountBefore,
146
+ createdAt: cp.createdAt,
147
+ type: cp.type,
148
+ ...cp.recentMessages ? { recentMessages: cp.recentMessages } : {}
115
149
  };
116
150
  }
151
+ function createCheckpointContent(checkpoint) {
152
+ const adapted = adaptLegacyCheckpoint(checkpoint);
153
+ const lines = [
154
+ `# Checkpoint: ${checkpoint.title}`,
155
+ "",
156
+ adapted.content,
157
+ "",
158
+ `${checkpoint.messageCountBefore} messages compacted at ${new Date(checkpoint.createdAt).toISOString()}`
159
+ ];
160
+ return lines.join(`
161
+ `);
162
+ }
163
+
164
+ // src/env/session/session-component.ts
165
+ var logger = createLogger("session");
117
166
  function sleep(ms) {
118
167
  return new Promise((resolve) => setTimeout(resolve, ms));
119
168
  }
@@ -612,6 +661,10 @@ class SessionComponent extends BaseComponent {
612
661
  const date = new Date().toISOString().replace("T", " ").substring(0, 19);
613
662
  return template.replace("{date}", date);
614
663
  }
664
+ getCompactModel() {
665
+ const model = this.configComponent?.get("session.compactModel");
666
+ return typeof model === "string" && model.trim() ? model.trim() : undefined;
667
+ }
615
668
  async generateCompactHint(sessionId) {
616
669
  const session = await this.get(sessionId);
617
670
  if (!session) {
@@ -626,29 +679,14 @@ class SessionComponent extends BaseComponent {
626
679
  return "";
627
680
  }
628
681
  const agentComponent = this.env.getComponent("agent");
629
- let hintData;
630
- const submitTool = {
631
- name: "workflow_submit_output",
632
- description: "Submit the final result. Call this with your guidance_prompt.",
633
- parameters: z.object({
634
- guidance_prompt: z.string().describe("The compact guidance prompt (3-4 sentences)")
635
- }),
636
- execute: async (args) => {
637
- const parsed = z.object({
638
- guidance_prompt: z.string()
639
- }).parse(args);
640
- hintData = parsed;
641
- return { success: true, output: "OK" };
642
- }
643
- };
644
- await agentComponent.run("compact-hint", "Analyze this conversation and generate a compact guidance prompt for checkpoint generation.", {
682
+ const hintRun = await agentComponent.run("compact-hint", "Analyze this conversation and generate a compact guidance prompt for checkpoint generation.", {
645
683
  sessionId,
646
684
  persistSession: false,
647
- extraTools: [submitTool]
685
+ model: this.getCompactModel()
648
686
  });
649
- const hint = hintData?.guidance_prompt || "";
687
+ const hint = normalizeCheckpointContent(hintRun?.finalText) ?? "";
650
688
  if (!hint) {
651
- logger.warn("[SessionComponent] Compact hint unavailable (compact-hint did not submit) — returning empty hint", { sessionId });
689
+ logger.warn("[SessionComponent] Compact hint unavailable (no usable finalText) — returning empty hint", { sessionId });
652
690
  }
653
691
  logger.info("[SessionComponent] Compact hint generated", {
654
692
  sessionId,
@@ -670,53 +708,36 @@ class SessionComponent extends BaseComponent {
670
708
  }
671
709
  const recentMessages = this.extractRecentMessages(messages, 2);
672
710
  await this.executeBeforeHooks("compact", { session, options });
673
- let summaryResult;
711
+ let checkpointText;
674
712
  try {
675
- const userQuery = options?.scenarioHint ? options.scenarioHint : "Generate a checkpoint from this conversation.";
676
- let checkpointData;
677
- const submitTool = {
678
- name: "workflow_submit_output",
679
- description: "Submit the checkpoint result with title, processKeyPoints, currentState, nextSteps, userIntents.",
680
- parameters: z.object({
681
- title: z.string().describe("Brief checkpoint title (max 30 chars)"),
682
- processKeyPoints: z.array(z.string()).describe("Key discoveries or decisions"),
683
- currentState: z.string().describe("Current progress and status"),
684
- nextSteps: z.array(z.string()).describe("Follow-up items"),
685
- userIntents: z.array(z.string()).describe("User's core intents (2-5 items)")
686
- }),
687
- execute: async (args) => {
688
- const parsed = z.object({
689
- title: z.string(),
690
- processKeyPoints: z.array(z.string()),
691
- currentState: z.string(),
692
- nextSteps: z.array(z.string()),
693
- userIntents: z.array(z.string())
694
- }).parse(args);
695
- checkpointData = parsed;
696
- return { success: true, output: "OK" };
697
- }
698
- };
713
+ const userQuery = options?.scenarioHint ? [
714
+ "Generate a checkpoint from this conversation.",
715
+ "",
716
+ "Scenario hint (focus points from phase 1):",
717
+ options.scenarioHint
718
+ ].join(`
719
+ `) : "Generate a checkpoint from this conversation.";
699
720
  const agentComponent = this.env.getComponent("agent");
700
721
  const runResult = await agentComponent.run("compact", userQuery, {
701
722
  sessionId,
702
723
  persistSession: false,
703
- extraTools: [submitTool]
724
+ model: this.getCompactModel()
704
725
  });
705
- const data = checkpointData;
706
- if (data) {
707
- summaryResult = normalizeAgentCheckpoint(data);
726
+ const fromText = buildCheckpointFromText(runResult?.finalText);
727
+ const fromHint = fromText ? undefined : buildCheckpointFromText(options?.scenarioHint);
728
+ const built = fromText ?? fromHint;
729
+ if (!built) {
730
+ throw new Error(`compact agent returned no usable checkpoint output ` + `(no usable finalText or scenarioHint); ` + `refusing to archive ${messages.length} messages for session ${sessionId}`);
731
+ }
732
+ if (fromText) {
733
+ logger.info("[SessionComponent] compact agent produced natural-language checkpoint", {
734
+ sessionId,
735
+ contentLength: built.content.length
736
+ });
708
737
  } else {
709
- const fallback = buildCheckpointFromFinalText(runResult?.finalText) ?? buildCheckpointFromFinalText(options?.scenarioHint);
710
- if (!fallback) {
711
- throw new Error(`compact agent returned no usable checkpoint output ` + `(no workflow_submit_output call, no usable finalText or scenarioHint); ` + `refusing to archive ${messages.length} messages for session ${sessionId}`);
712
- }
713
- if (runResult?.finalText?.trim()) {
714
- logger.warn(`[SessionComponent] compact agent did not call workflow_submit_output; ` + `falling back to its finalText for the checkpoint (session=${sessionId}, ` + `finalTextLength=${runResult.finalText.length})`);
715
- } else {
716
- logger.warn(`[SessionComponent] compact agent produced neither a tool call nor text; ` + `falling back to scenarioHint for the checkpoint (session=${sessionId})`);
717
- }
718
- summaryResult = fallback;
738
+ logger.warn(`[SessionComponent] compact agent produced no usable text; ` + `falling back to scenarioHint for the checkpoint (session=${sessionId})`);
719
739
  }
740
+ checkpointText = built;
720
741
  } catch (error) {
721
742
  const errorMessage = error instanceof Error ? error.message : String(error);
722
743
  logger.error(`[SessionComponent] Compact agent failed: ${errorMessage}`);
@@ -726,16 +747,8 @@ class SessionComponent extends BaseComponent {
726
747
  const checkpoint = {
727
748
  id: checkpointId,
728
749
  messageIndex: startIndex,
729
- title: summaryResult.title,
730
- summary: [
731
- `Process: ${summaryResult.processKeyPoints.join("; ")}`,
732
- `State: ${summaryResult.currentState}`
733
- ].join(`
734
- `),
735
- processKeyPoints: summaryResult.processKeyPoints,
736
- currentState: summaryResult.currentState,
737
- nextSteps: summaryResult.nextSteps,
738
- userIntents: summaryResult.userIntents,
750
+ title: checkpointText.title,
751
+ content: checkpointText.content,
739
752
  messageCountBefore: messages.length,
740
753
  createdAt: Date.now(),
741
754
  type: "compact",
@@ -833,10 +846,68 @@ class SessionComponent extends BaseComponent {
833
846
  };
834
847
  }
835
848
  async getCheckpoints(sessionId) {
836
- return await this.store.getCheckpoints(sessionId);
849
+ const checkpoints = await this.store.getCheckpoints(sessionId);
850
+ return checkpoints.map((cp) => adaptLegacyCheckpoint(cp));
837
851
  }
838
852
  async getCheckpoint(sessionId, checkpointId) {
839
- return await this.store.getCheckpoint(sessionId, checkpointId);
853
+ const cp = await this.store.getCheckpoint(sessionId, checkpointId);
854
+ return cp ? adaptLegacyCheckpoint(cp) : undefined;
855
+ }
856
+ async readStoredCheckpointsRaw(sessionId) {
857
+ return await this.store.getCheckpoints(sessionId);
858
+ }
859
+ async adaptStoredCheckpoints(sessionId, options) {
860
+ const apply = options?.apply === true;
861
+ const raw = await this.store.getCheckpoints(sessionId);
862
+ const report = {
863
+ sessionId,
864
+ total: raw.length,
865
+ legacy: 0,
866
+ modern: 0,
867
+ applied: 0,
868
+ samples: []
869
+ };
870
+ const adapted = [];
871
+ for (const cp of raw) {
872
+ const o = cp;
873
+ const hasContent = typeof o.content === "string" && o.content.trim().length > 0;
874
+ if (hasContent) {
875
+ report.modern++;
876
+ adapted.push(cp);
877
+ continue;
878
+ }
879
+ report.legacy++;
880
+ const fixed = adaptLegacyCheckpoint(cp);
881
+ adapted.push(fixed);
882
+ if (report.samples.length < 3) {
883
+ report.samples.push({
884
+ id: cp.id,
885
+ title: cp.title,
886
+ contentLength: fixed.content.length,
887
+ contentPreview: fixed.content.slice(0, 200)
888
+ });
889
+ }
890
+ }
891
+ if (apply && report.legacy > 0) {
892
+ await this.writeCheckpointsBack(sessionId, adapted);
893
+ report.applied = report.legacy;
894
+ }
895
+ logger.info("[SessionComponent] adaptStoredCheckpoints", {
896
+ sessionId,
897
+ total: report.total,
898
+ legacy: report.legacy,
899
+ modern: report.modern,
900
+ applied: report.applied,
901
+ dryRun: !apply
902
+ });
903
+ return report;
904
+ }
905
+ async writeCheckpointsBack(sessionId, checkpoints) {
906
+ const store = this.store;
907
+ if (typeof store.replaceCheckpointDetails !== "function") {
908
+ throw new Error("adaptStoredCheckpoints: current store does not support replaceCheckpointDetails " + "(only SQLiteSessionStore does); refusing to write partial data");
909
+ }
910
+ await store.replaceCheckpointDetails(sessionId, checkpoints);
840
911
  }
841
912
  async deleteCheckpoint(sessionId, checkpointId) {
842
913
  await this.executeBeforeHooks("deleteCheckpoint", { sessionId, checkpointId });
@@ -870,7 +941,7 @@ class SessionComponent extends BaseComponent {
870
941
  } else {
871
942
  const latestCheckpointId = session.metadata?.checkpoints?.latestCheckpointId;
872
943
  if (latestCheckpointId) {
873
- startCheckpoint = await this.store.getCheckpoint(sessionId, latestCheckpointId);
944
+ startCheckpoint = await this.getCheckpoint(sessionId, latestCheckpointId);
874
945
  if (startCheckpoint) {
875
946
  const MAX_SAFE_MESSAGES = Number.MAX_SAFE_INTEGER;
876
947
  contextMessages = await this.store.getMessages(sessionId, startCheckpoint.messageIndex, MAX_SAFE_MESSAGES, { includeArchived: false });
@@ -898,7 +969,7 @@ class SessionComponent extends BaseComponent {
898
969
  if (options?.messageLimit) {
899
970
  contextMessages = contextMessages.slice(-options.messageLimit);
900
971
  }
901
- const checkpoints = contextMessages.filter((m) => m.metadata?.isCheckpoint).map((m) => m.metadata.checkpointMeta);
972
+ const checkpoints = contextMessages.filter((m) => m.metadata?.isCheckpoint && m.metadata?.checkpointMeta).map((m) => adaptLegacyCheckpoint(m.metadata.checkpointMeta));
902
973
  const estimatedTokens = contextMessages.reduce((sum, m) => sum + m.content.length * 0.25, 0);
903
974
  return {
904
975
  session,
@@ -997,28 +1068,11 @@ class SessionComponent extends BaseComponent {
997
1068
  const latestId = session.metadata?.checkpoints?.latestCheckpointId;
998
1069
  if (!latestId)
999
1070
  return;
1000
- return session.metadata?.checkpointDetails?.[latestId];
1071
+ const raw = session.metadata?.checkpointDetails?.[latestId];
1072
+ return raw ? adaptLegacyCheckpoint(raw) : undefined;
1001
1073
  }
1002
1074
  createCheckpointMessage(checkpoint) {
1003
- const lines = [
1004
- `# Checkpoint: ${checkpoint.title}`,
1005
- "",
1006
- "## Process Key Points",
1007
- ...checkpoint.processKeyPoints.map((p, i) => `${i + 1}. ${p}`),
1008
- "",
1009
- "## Current State",
1010
- checkpoint.currentState,
1011
- ""
1012
- ];
1013
- if (checkpoint.nextSteps?.length) {
1014
- lines.push("## Next Steps");
1015
- checkpoint.nextSteps.forEach((s, i) => lines.push(`${i + 1}. ${s}`));
1016
- lines.push("");
1017
- }
1018
- lines.push("## Messages Compacted");
1019
- lines.push(`${checkpoint.messageCountBefore} messages compacted at ${new Date(checkpoint.createdAt).toISOString()}`);
1020
- const content = lines.join(`
1021
- `);
1075
+ const content = createCheckpointContent(checkpoint);
1022
1076
  return {
1023
1077
  role: "user",
1024
1078
  content,
@@ -1027,9 +1081,6 @@ class SessionComponent extends BaseComponent {
1027
1081
  checkpointId: checkpoint.id,
1028
1082
  content,
1029
1083
  title: checkpoint.title,
1030
- processKeyPoints: checkpoint.processKeyPoints,
1031
- currentState: checkpoint.currentState,
1032
- nextSteps: checkpoint.nextSteps,
1033
1084
  messageCountBefore: checkpoint.messageCountBefore,
1034
1085
  createdAt: checkpoint.createdAt
1035
1086
  }],