@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.
- package/dist/env/agent/agent-component.js +6 -6
- package/dist/env/agent/agent-registry.d.ts +4 -1
- package/dist/env/agent/index.js +6 -6
- package/dist/env/agent/summary-agent.d.ts +6 -15
- package/dist/env/agent/types.d.ts +0 -17
- package/dist/env/error-reply.d.ts +46 -0
- package/dist/env/error-reply.js +3 -1
- package/dist/env/event-source/event-source-handlers.js +12 -12
- package/dist/env/event-source/index.js +13 -13
- package/dist/env/index.js +30 -31
- package/dist/env/llm/index.js +2 -2
- package/dist/env/llm/orphan-toolcall.d.ts +107 -0
- package/dist/env/llm/temperature-policy.d.ts +107 -0
- package/dist/env/llm/types.d.ts +2 -2
- package/dist/env/plugin/index.js +3 -3
- package/dist/env/prompt/index.js +3 -3
- package/dist/env/prompt/prompts-index.d.ts +26 -4
- package/dist/env/session/__bench__/replay-compact.d.ts +137 -0
- package/dist/env/session/__bench__/run-replay.d.ts +15 -0
- package/dist/env/session/compact-checkpoint-content.d.ts +67 -0
- package/dist/env/session/index.d.ts +1 -0
- package/dist/env/session/index.js +4 -5
- package/dist/env/session/session-component.d.ts +47 -30
- package/dist/env/session/storage/index.js +3 -3
- package/dist/env/session/storage/sqlite.d.ts +8 -0
- package/dist/env/session/types.d.ts +45 -30
- package/dist/env/task/delegate/delegate-tool.d.ts +8 -0
- package/dist/env/task/delegate/delegate-tool.js +4 -4
- package/dist/env/task/delegate/index.js +4 -4
- package/dist/env/task/index.js +7 -7
- package/dist/env/task/mcp/index.js +2 -2
- package/dist/env/task/plugins/index.d.ts +3 -0
- package/dist/env/task/plugins/index.js +32 -9
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +61 -0
- package/dist/env/task/plugins/lark-card-patch-notifier.js +6 -2
- package/dist/env/task/plugins/lark-cli-task-notify-plugin.d.ts +42 -0
- package/dist/env/task/prompt/index.js +1 -1
- package/dist/env/task/prompt/task-discipline.d.ts +9 -3
- package/dist/env/task/tools/cancel-tool.d.ts +28 -0
- package/dist/env/task/tools/index.d.ts +1 -0
- package/dist/env/task/tools/index.js +4 -2
- package/dist/env/task/tools/task-types.d.ts +22 -0
- package/dist/env/tool/built-in/compact-session-tool.d.ts +120 -0
- package/dist/env/tool/built-in/index.d.ts +2 -0
- package/dist/env/tool/built-in/index.js +6 -2
- package/dist/env/tool/index.js +4 -4
- package/dist/env/workflow/engine/index.js +6 -7
- package/dist/env/workflow/index.js +15 -14
- package/dist/env/workflow/plugins/index.js +2 -2
- package/dist/env/workflow/tools/ask-user-tool.d.ts +88 -0
- package/dist/env/workflow/tools/index.js +11 -10
- package/dist/env/workflow/tools/run-workflow.d.ts +2 -2
- package/dist/env/workflow/types/index.js +2 -2
- package/dist/env/workflow/types/workflow-hil.d.ts +25 -1
- package/dist/env/workflow/utils/index.js +5 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +33 -34
- package/dist/shared/@ai-setting/{roy-agent-core-hy3zn2q2.js → roy-agent-core-0qyrk5k0.js} +22 -2
- package/dist/shared/@ai-setting/{roy-agent-core-kmbct9yg.js → roy-agent-core-0snm5hc5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-4jjwewvw.js → roy-agent-core-11shp00p.js} +31 -10
- package/dist/shared/@ai-setting/{roy-agent-core-yr1mryb8.js → roy-agent-core-1v4g0d4x.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-02j24hrg.js → roy-agent-core-264qexac.js} +71 -4
- package/dist/shared/@ai-setting/{roy-agent-core-9geem94g.js → roy-agent-core-29b6hc39.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-2akfd64z.js +374 -0
- package/dist/shared/@ai-setting/{roy-agent-core-zv8bswpw.js → roy-agent-core-3e6gg17d.js} +120 -28
- package/dist/shared/@ai-setting/{roy-agent-core-8cx7cfdg.js → roy-agent-core-3fh1f7s7.js} +2 -3
- package/dist/shared/@ai-setting/{roy-agent-core-mwa6apzx.js → roy-agent-core-4gr3k7qg.js} +17 -4
- package/dist/shared/@ai-setting/{roy-agent-core-zsbh9bfv.js → roy-agent-core-60jbrfye.js} +6 -6
- package/dist/shared/@ai-setting/{roy-agent-core-add1zqsh.js → roy-agent-core-6cy43nss.js} +22 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mw2cen6s.js → roy-agent-core-6rh8k6ba.js} +5 -5
- package/dist/shared/@ai-setting/{roy-agent-core-kpg25s2q.js → roy-agent-core-8ez6mccb.js} +4 -2
- package/dist/shared/@ai-setting/{roy-agent-core-sjr1kmfz.js → roy-agent-core-acj8ag08.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-mds8tqd0.js → roy-agent-core-cgtq6427.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-9bshyqjn.js → roy-agent-core-ddyk1rc0.js} +183 -132
- package/dist/shared/@ai-setting/{roy-agent-core-hfr6bzts.js → roy-agent-core-djpq6yb0.js} +16 -7
- package/dist/shared/@ai-setting/{roy-agent-core-002g6nfk.js → roy-agent-core-dqxec05w.js} +7 -6
- package/dist/shared/@ai-setting/{roy-agent-core-07fvy74y.js → roy-agent-core-ed233k5z.js} +21 -7
- package/dist/shared/@ai-setting/{roy-agent-core-jrj30vq3.js → roy-agent-core-er070zjq.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-40rv283c.js → roy-agent-core-fghc2m8z.js} +152 -2
- package/dist/shared/@ai-setting/{roy-agent-core-7sj9xs9c.js → roy-agent-core-hnyk1by7.js} +110 -2
- package/dist/shared/@ai-setting/{roy-agent-core-101qtkyc.js → roy-agent-core-jg65qnwa.js} +11 -8
- package/dist/shared/@ai-setting/{roy-agent-core-e25xkv53.js → roy-agent-core-mkc3zshb.js} +3 -1
- package/dist/shared/@ai-setting/{roy-agent-core-0cb6w0k7.js → roy-agent-core-mww0mnd9.js} +231 -27
- package/dist/shared/@ai-setting/{roy-agent-core-5repth1n.js → roy-agent-core-n9q1encx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-46rv4d7d.js → roy-agent-core-nmx9934r.js} +92 -2
- package/dist/shared/@ai-setting/{roy-agent-core-1w9y7mxj.js → roy-agent-core-p3zv1mx5.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-snvh4s2p.js +662 -0
- package/dist/shared/@ai-setting/{roy-agent-core-dt104qa1.js → roy-agent-core-v85n42ve.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-37tj4y6a.js → roy-agent-core-v87njmq7.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-k13pxrpk.js → roy-agent-core-y7x2qzwc.js} +553 -92
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-1gsbqesr.js +0 -1083
- package/dist/shared/@ai-setting/roy-agent-core-58804s3j.js +0 -155
- 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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
19
|
+
} from "./roy-agent-core-p3zv1mx5.js";
|
|
23
20
|
import {
|
|
24
21
|
LarkCardPatchNotifier,
|
|
25
22
|
buildTaskCard
|
|
26
|
-
} from "./roy-agent-core-
|
|
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-
|
|
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-
|
|
40
|
+
} from "./roy-agent-core-acj8ag08.js";
|
|
41
41
|
import {
|
|
42
42
|
DAGManager,
|
|
43
43
|
init_dag_manager
|
|
44
|
-
} from "./roy-agent-core-
|
|
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-
|
|
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-
|
|
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-
|
|
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) {
|
|
@@ -1,11 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
MemorySessionStore,
|
|
3
3
|
SQLiteSessionStore
|
|
4
|
-
} from "./roy-agent-core-
|
|
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
|
-
|
|
76
|
-
|
|
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
|
-
|
|
79
|
+
var MIN_CONTENT_LENGTH = 20;
|
|
80
|
+
function normalizeCheckpointContent(text) {
|
|
91
81
|
const raw = (text ?? "").trim();
|
|
92
82
|
if (!raw)
|
|
93
|
-
return
|
|
94
|
-
|
|
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
|
|
97
|
-
|
|
90
|
+
function buildCheckpointFromText(text) {
|
|
91
|
+
const content = normalizeCheckpointContent(text);
|
|
92
|
+
if (!content)
|
|
98
93
|
return;
|
|
99
|
-
const
|
|
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
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
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
|
-
|
|
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
|
-
|
|
685
|
+
model: this.getCompactModel()
|
|
648
686
|
});
|
|
649
|
-
const hint =
|
|
687
|
+
const hint = normalizeCheckpointContent(hintRun?.finalText) ?? "";
|
|
650
688
|
if (!hint) {
|
|
651
|
-
logger.warn("[SessionComponent] Compact hint unavailable (
|
|
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
|
|
711
|
+
let checkpointText;
|
|
674
712
|
try {
|
|
675
|
-
const userQuery = options?.scenarioHint ?
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
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
|
-
|
|
724
|
+
model: this.getCompactModel()
|
|
704
725
|
});
|
|
705
|
-
const
|
|
706
|
-
|
|
707
|
-
|
|
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
|
-
|
|
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:
|
|
730
|
-
|
|
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
|
-
|
|
849
|
+
const checkpoints = await this.store.getCheckpoints(sessionId);
|
|
850
|
+
return checkpoints.map((cp) => adaptLegacyCheckpoint(cp));
|
|
837
851
|
}
|
|
838
852
|
async getCheckpoint(sessionId, checkpointId) {
|
|
839
|
-
|
|
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.
|
|
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
|
-
|
|
1071
|
+
const raw = session.metadata?.checkpointDetails?.[latestId];
|
|
1072
|
+
return raw ? adaptLegacyCheckpoint(raw) : undefined;
|
|
1001
1073
|
}
|
|
1002
1074
|
createCheckpointMessage(checkpoint) {
|
|
1003
|
-
const
|
|
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
|
}],
|