feat(core,cli,server,web): add goal mode — loop Tasks on one Session until an objective completes (#66)
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -29,6 +29,7 @@ import {
|
||||
parseSkillsMessage,
|
||||
parseUserSteeringText,
|
||||
startsWithMarker,
|
||||
stripConversationMarkers,
|
||||
stripMarkerBlocks,
|
||||
transcribeToolCall,
|
||||
transcribeUserInput,
|
||||
@@ -68,10 +69,48 @@ describe("marker block primitives", () => {
|
||||
MARKER_TAGS.handoffFrom,
|
||||
MARKER_TAGS.scheduledTask,
|
||||
MARKER_TAGS.modelSwitchFrom,
|
||||
MARKER_TAGS.goal,
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("stripConversationMarkers (whole-message title cleaning)", () => {
|
||||
it("removes machine marker blocks, keeps the human body", () => {
|
||||
// The skill-invocation block that wraps a first user message must not reach the title.
|
||||
expect(
|
||||
stripConversationMarkers(
|
||||
"[use_skills]\nskills: penguin-sdk, web-design\n[/use_skills]\n做一个 RAG 应用",
|
||||
),
|
||||
).toBe("做一个 RAG 应用");
|
||||
// Handoff and scheduled-task markers are stripped too; ordinary bracketed text stays.
|
||||
expect(stripConversationMarkers("[handoff_from]data_analyst[/handoff_from]继续分析")).toBe(
|
||||
"继续分析",
|
||||
);
|
||||
// The /model switch origin block (the new session's first message) must not leak into the title either.
|
||||
expect(
|
||||
stripConversationMarkers(
|
||||
"[model_switch_from]\nsession: session-01\ntrace: /t/x_001.jsonl\n[/model_switch_from]\n继续这个任务",
|
||||
),
|
||||
).toBe("继续这个任务");
|
||||
expect(stripConversationMarkers("render a <div> element")).toBe("render a <div> element");
|
||||
expect(stripConversationMarkers("check the [config] section")).toBe(
|
||||
"check the [config] section",
|
||||
);
|
||||
});
|
||||
|
||||
it("the old angle-bracket marker form is still stripped (material from old Traces)", () => {
|
||||
expect(
|
||||
stripConversationMarkers("<use_skills>\nskills: web-design\n</use_skills>\n做一个落地页"),
|
||||
).toBe("做一个落地页");
|
||||
expect(stripConversationMarkers("<handoff_from>data_analyst</handoff_from>继续分析")).toBe(
|
||||
"继续分析",
|
||||
);
|
||||
expect(
|
||||
stripConversationMarkers("<model_switch_from>session: s1</model_switch_from>继续这个任务"),
|
||||
).toBe("继续这个任务");
|
||||
});
|
||||
});
|
||||
|
||||
describe("engine blocks ([turn_aborted] / [turn_retried] / [context_summary] / [summary])", () => {
|
||||
it("wraps a compaction summary as the new context's first input", () => {
|
||||
expect(buildContextSummaryText("the gist")).toBe(
|
||||
|
||||
Reference in New Issue
Block a user