@ai-setting/roy-agent-core 1.7.70 → 1.7.72
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 +2 -2
- package/dist/env/agent/index.js +2 -2
- package/dist/env/agent/summary-agent.d.ts +6 -15
- package/dist/env/agent/types.d.ts +0 -17
- package/dist/env/event-source/event-source-handlers.js +6 -6
- package/dist/env/event-source/index.js +7 -7
- package/dist/env/event-source/reset-command.d.ts +41 -0
- package/dist/env/index.js +19 -20
- package/dist/env/llm/index.js +1 -1
- package/dist/env/llm/temperature-policy.d.ts +107 -0
- package/dist/env/llm/types.d.ts +2 -2
- package/dist/env/prompt/index.js +3 -3
- package/dist/env/prompt/prompts-index.d.ts +341 -3
- 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 +2 -3
- package/dist/env/session/session-component.d.ts +47 -30
- package/dist/env/session/storage/index.js +1 -1
- 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.js +4 -4
- package/dist/env/task/delegate/index.js +4 -4
- package/dist/env/task/index.js +6 -6
- package/dist/env/task/mcp/index.js +2 -2
- package/dist/env/task/plugins/index.js +4 -4
- package/dist/env/task/plugins/lark-card-patch-notifier.d.ts +50 -0
- package/dist/env/task/plugins/lark-card-patch-notifier.js +3 -1
- package/dist/env/task/prompt/index.d.ts +11 -0
- package/dist/env/task/prompt/index.js +16 -0
- package/dist/env/task/prompt/task-discipline.d.ts +32 -0
- package/dist/env/task/tools/index.js +2 -2
- package/dist/env/workflow/engine/index.js +2 -3
- package/dist/env/workflow/index.js +6 -7
- package/dist/env/workflow/plugins/index.js +2 -2
- package/dist/env/workflow/tools/index.js +3 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +39 -28
- package/dist/shared/@ai-setting/{roy-agent-core-bk8kyzv8.js → roy-agent-core-1p6syv85.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-8bjj3d1b.js → roy-agent-core-1w9y7mxj.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-nersksh1.js → roy-agent-core-2gzt2q8c.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-27f59kjv.js → roy-agent-core-34jz9mgh.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-tadj19vp.js → roy-agent-core-46rv4d7d.js} +71 -49
- package/dist/shared/@ai-setting/roy-agent-core-4jjwewvw.js +182 -0
- package/dist/shared/@ai-setting/{roy-agent-core-hx46nhh1.js → roy-agent-core-5gw0qa8m.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-0j94tj1z.js → roy-agent-core-7qvw65jt.js} +4 -4
- package/dist/shared/@ai-setting/{roy-agent-core-h5vmff8w.js → roy-agent-core-7sj9xs9c.js} +7 -33
- package/dist/shared/@ai-setting/{roy-agent-core-002g6nfk.js → roy-agent-core-attpry6g.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-37tj4y6a.js → roy-agent-core-gr48c89p.js} +3 -3
- package/dist/shared/@ai-setting/{roy-agent-core-0cb6w0k7.js → roy-agent-core-hfyfavp3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-hfr6bzts.js → roy-agent-core-jgb3bb42.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-9bshyqjn.js → roy-agent-core-pakhchy7.js} +183 -132
- package/dist/shared/@ai-setting/roy-agent-core-qkdegdvc.js +0 -0
- package/dist/shared/@ai-setting/{roy-agent-core-02j24hrg.js → roy-agent-core-rxb00gjm.js} +70 -3
- package/dist/shared/@ai-setting/{roy-agent-core-8cx7cfdg.js → roy-agent-core-skyc30qx.js} +1 -2
- package/dist/shared/@ai-setting/{roy-agent-core-hy3zn2q2.js → roy-agent-core-sm0sf6sb.js} +20 -0
- package/dist/shared/@ai-setting/{roy-agent-core-mw2cen6s.js → roy-agent-core-vah6g5yx.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-07fvy74y.js → roy-agent-core-vm8h5zyj.js} +20 -6
- package/dist/shared/@ai-setting/{roy-agent-core-x3xpkx84.js → roy-agent-core-wr7mv7k3.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-npvejsg8.js → roy-agent-core-y12kyxwa.js} +83 -3
- package/dist/shared/@ai-setting/{roy-agent-core-vaz9350j.js → roy-agent-core-yhwxpj12.js} +34 -175
- package/dist/test-utils/ipc-test-server.d.ts +10 -0
- package/package.json +6 -1
- package/dist/shared/@ai-setting/roy-agent-core-6m4bw8jy.js +0 -6
- package/dist/shared/@ai-setting/roy-agent-core-ze068vc9.js +0 -37
|
@@ -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-sm0sf6sb.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
|
}],
|
|
File without changes
|
|
@@ -241,7 +241,7 @@ var LLMConfigSchema = z.object({
|
|
|
241
241
|
defaultModel: z.string().optional(),
|
|
242
242
|
providers: z.record(z.string(), ProviderConfigSchema),
|
|
243
243
|
defaultProvider: z.string(),
|
|
244
|
-
temperature: z.number().min(0).max(2).
|
|
244
|
+
temperature: z.number().min(0).max(2).optional(),
|
|
245
245
|
maxTokens: z.number().int().positive().optional(),
|
|
246
246
|
topP: z.number().min(0).max(1).optional(),
|
|
247
247
|
stream: z.boolean().default(true),
|
|
@@ -627,6 +627,58 @@ import { randomUUID } from "crypto";
|
|
|
627
627
|
import * as fs from "node:fs/promises";
|
|
628
628
|
import * as os from "node:os";
|
|
629
629
|
import * as path from "node:path";
|
|
630
|
+
|
|
631
|
+
// src/env/llm/temperature-policy.ts
|
|
632
|
+
var FIXED_TEMPERATURE_ENDPOINTS = [
|
|
633
|
+
{
|
|
634
|
+
id: "kimi-for-coding",
|
|
635
|
+
baseURLIncludes: "api.kimi.com/coding",
|
|
636
|
+
providerIds: ["kimi-coding"],
|
|
637
|
+
temperature: 1,
|
|
638
|
+
reason: "Kimi For Coding 端点(api.kimi.com/coding)对所有它服务的模型都只接受 temperature=1 或不传;" + "发 0.7 会 400 invalid temperature(Task #4946 实测 6 个模型全覆盖)"
|
|
639
|
+
}
|
|
640
|
+
];
|
|
641
|
+
function findFixedTemperatureRule(input) {
|
|
642
|
+
const { providerId, baseURL } = input;
|
|
643
|
+
if (baseURL) {
|
|
644
|
+
const normalized = baseURL.toLowerCase();
|
|
645
|
+
for (const rule of FIXED_TEMPERATURE_ENDPOINTS) {
|
|
646
|
+
if (normalized.includes(rule.baseURLIncludes.toLowerCase()))
|
|
647
|
+
return rule;
|
|
648
|
+
}
|
|
649
|
+
return;
|
|
650
|
+
}
|
|
651
|
+
if (providerId) {
|
|
652
|
+
for (const rule of FIXED_TEMPERATURE_ENDPOINTS) {
|
|
653
|
+
if (rule.providerIds?.includes(providerId))
|
|
654
|
+
return rule;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
return;
|
|
658
|
+
}
|
|
659
|
+
var DEFAULT_TEMPERATURE = 0.7;
|
|
660
|
+
function toNumberOrUndefined(value) {
|
|
661
|
+
if (typeof value === "number")
|
|
662
|
+
return Number.isFinite(value) ? value : undefined;
|
|
663
|
+
if (typeof value === "string" && value.trim() !== "") {
|
|
664
|
+
const n = Number(value);
|
|
665
|
+
return Number.isFinite(n) ? n : undefined;
|
|
666
|
+
}
|
|
667
|
+
return;
|
|
668
|
+
}
|
|
669
|
+
function resolveTemperature(input) {
|
|
670
|
+
const base = toNumberOrUndefined(input.requestTemperature) ?? toNumberOrUndefined(input.globalTemperature) ?? toNumberOrUndefined(input.providerTemperature) ?? DEFAULT_TEMPERATURE;
|
|
671
|
+
const rule = findFixedTemperatureRule({
|
|
672
|
+
providerId: input.providerId,
|
|
673
|
+
baseURL: input.baseURL
|
|
674
|
+
});
|
|
675
|
+
if (rule) {
|
|
676
|
+
return { temperature: rule.temperature, clampedBy: rule };
|
|
677
|
+
}
|
|
678
|
+
return { temperature: base };
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
// src/env/llm/llm.ts
|
|
630
682
|
var logger = createLogger("llm");
|
|
631
683
|
function normalizeUsage(usage) {
|
|
632
684
|
if (!usage)
|
|
@@ -886,7 +938,7 @@ class LLMComponent extends BaseComponent {
|
|
|
886
938
|
resolveRequest(request) {
|
|
887
939
|
const defaultModel = this.getLLMConfig("llm.defaultModel", "gpt-4o");
|
|
888
940
|
const defaultProvider = this.getLLMConfig("llm.defaultProvider", "openai");
|
|
889
|
-
const
|
|
941
|
+
const configuredGlobalTemperature = this.getLLMConfig("llm.temperature");
|
|
890
942
|
const defaultMaxTokens = this.getLLMConfig("llm.maxTokens", 4096);
|
|
891
943
|
const defaultTopP = this.getLLMConfig("llm.topP", 1);
|
|
892
944
|
const rawModel = request.model || defaultModel;
|
|
@@ -915,6 +967,21 @@ class LLMComponent extends BaseComponent {
|
|
|
915
967
|
const capabilities = provider?.capabilities;
|
|
916
968
|
const thinkingInText = capabilities?.thinkingInText;
|
|
917
969
|
const effectiveThinkingInText = thinkingInText !== undefined ? thinkingInText : undefined;
|
|
970
|
+
const temperatureResolution = resolveTemperature({
|
|
971
|
+
requestTemperature: request.temperature,
|
|
972
|
+
globalTemperature: configuredGlobalTemperature,
|
|
973
|
+
providerTemperature: provider?.temperature,
|
|
974
|
+
providerId,
|
|
975
|
+
baseURL: provider?.baseURL
|
|
976
|
+
});
|
|
977
|
+
if (temperatureResolution.clampedBy) {
|
|
978
|
+
logger.debug(`[LLMComponent] temperature 被端点硬约束钳制:${providerId} → ${temperatureResolution.temperature}`, {
|
|
979
|
+
provider: providerId,
|
|
980
|
+
requested: request.temperature ?? configuredGlobalTemperature ?? provider?.temperature,
|
|
981
|
+
forced: temperatureResolution.clampedBy.temperature,
|
|
982
|
+
reason: temperatureResolution.clampedBy.reason
|
|
983
|
+
});
|
|
984
|
+
}
|
|
918
985
|
return {
|
|
919
986
|
providerId,
|
|
920
987
|
model,
|
|
@@ -934,7 +1001,7 @@ class LLMComponent extends BaseComponent {
|
|
|
934
1001
|
} : {}
|
|
935
1002
|
},
|
|
936
1003
|
messages,
|
|
937
|
-
temperature:
|
|
1004
|
+
temperature: temperatureResolution.temperature,
|
|
938
1005
|
maxTokens: request.maxTokens ?? defaultMaxTokens,
|
|
939
1006
|
topP: request.topP ?? defaultTopP,
|
|
940
1007
|
abortSignal: request.abortSignal
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentComponentAdapter,
|
|
3
3
|
init_agent_component_adapter
|
|
4
|
-
} from "./roy-agent-core-
|
|
4
|
+
} from "./roy-agent-core-attpry6g.js";
|
|
5
5
|
import"./roy-agent-core-1db4vpc6.js";
|
|
6
|
-
import"./roy-agent-core-ze068vc9.js";
|
|
7
6
|
import"./roy-agent-core-e25xkv53.js";
|
|
8
7
|
import"./roy-agent-core-cpcd24n2.js";
|
|
9
8
|
import"./roy-agent-core-qqaak24r.js";
|
|
@@ -1042,6 +1042,26 @@ class SQLiteSessionStore extends BaseSessionStore {
|
|
|
1042
1042
|
return [];
|
|
1043
1043
|
return Object.values(checkpointDetails);
|
|
1044
1044
|
}
|
|
1045
|
+
async replaceCheckpointDetails(sessionId, checkpoints) {
|
|
1046
|
+
await this.initialize();
|
|
1047
|
+
const session = await this.get(sessionId);
|
|
1048
|
+
if (!session) {
|
|
1049
|
+
throw new Error(`Session not found: ${sessionId}`);
|
|
1050
|
+
}
|
|
1051
|
+
const meta = session.metadata || {};
|
|
1052
|
+
const details = meta.checkpointDetails || {};
|
|
1053
|
+
for (const cp of checkpoints) {
|
|
1054
|
+
details[cp.id] = cp;
|
|
1055
|
+
}
|
|
1056
|
+
meta.checkpointDetails = details;
|
|
1057
|
+
session.metadata = meta;
|
|
1058
|
+
session.updatedAt = Date.now();
|
|
1059
|
+
this.db.prepare("UPDATE session SET metadata = ?, updated_at = ? WHERE id = ?").run(JSON.stringify(session.metadata), session.updatedAt, sessionId);
|
|
1060
|
+
this.checkpointsCache.set(sessionId, Object.values(details));
|
|
1061
|
+
this.sessionsCache.set(sessionId, session);
|
|
1062
|
+
logger.info(`[SQLiteSessionStore] replaceCheckpointDetails: wrote ${checkpoints.length} checkpoint(s) for ${sessionId}`);
|
|
1063
|
+
return true;
|
|
1064
|
+
}
|
|
1045
1065
|
async getCheckpoint(sessionId, checkpointId) {
|
|
1046
1066
|
await this.initialize();
|
|
1047
1067
|
const checkpoints = await this.getCheckpoints(sessionId);
|
|
@@ -270,34 +270,48 @@ class AgentRegistry {
|
|
|
270
270
|
}
|
|
271
271
|
registerCompactAgent() {
|
|
272
272
|
const name = "compact";
|
|
273
|
-
if (this.agents.has(name))
|
|
274
|
-
return;
|
|
275
273
|
const agent = {
|
|
276
274
|
name,
|
|
277
275
|
type: "sub",
|
|
278
276
|
description: "压缩子智能体 — 从父 session 的历史消息中提取结构化 checkpoint JSON",
|
|
279
277
|
systemPromptRef: "compact",
|
|
280
|
-
allowedTools: [
|
|
278
|
+
allowedTools: [],
|
|
281
279
|
deniedTools: [],
|
|
282
280
|
maxIterations: 3,
|
|
283
281
|
filterHistory: false
|
|
284
282
|
};
|
|
283
|
+
const existing = this.agents.get(name);
|
|
284
|
+
if (existing) {
|
|
285
|
+
this.agents.set(name, {
|
|
286
|
+
...agent,
|
|
287
|
+
description: existing.description ?? agent.description
|
|
288
|
+
});
|
|
289
|
+
logger.info(`[AgentRegistry] Built-in compact agent overrode user-level definition ` + `(tool whitelist enforced: allowedTools=[])`);
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
285
292
|
this.agents.set(name, agent);
|
|
286
293
|
}
|
|
287
294
|
registerCompactHintAgent() {
|
|
288
295
|
const name = "compact-hint";
|
|
289
|
-
if (this.agents.has(name))
|
|
290
|
-
return;
|
|
291
296
|
const agent = {
|
|
292
297
|
name,
|
|
293
298
|
type: "sub",
|
|
294
299
|
description: "压缩提示子智能体 — 分析父 session 历史,生成场景化压缩指导提示",
|
|
295
300
|
systemPromptRef: "compact-hint",
|
|
296
|
-
allowedTools: [
|
|
301
|
+
allowedTools: [],
|
|
297
302
|
deniedTools: [],
|
|
298
303
|
maxIterations: 3,
|
|
299
304
|
filterHistory: false
|
|
300
305
|
};
|
|
306
|
+
const existing = this.agents.get(name);
|
|
307
|
+
if (existing) {
|
|
308
|
+
this.agents.set(name, {
|
|
309
|
+
...agent,
|
|
310
|
+
description: existing.description ?? agent.description
|
|
311
|
+
});
|
|
312
|
+
logger.info(`[AgentRegistry] Built-in compact-hint agent overrode user-level definition ` + `(tool whitelist enforced: allowedTools=[])`);
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
301
315
|
this.agents.set(name, agent);
|
|
302
316
|
}
|
|
303
317
|
registerRoyAgent() {
|