@clinebot/core 0.0.29 → 0.0.32
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/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -25
- package/dist/runtime/checkpoint-hooks.d.ts +10 -0
- package/dist/runtime/checkpoint-hooks.d.ts.map +1 -1
- package/dist/session/default-session-manager.d.ts +5 -0
- package/dist/session/default-session-manager.d.ts.map +1 -1
- package/dist/telemetry/OpenTelemetryProvider.d.ts.map +1 -1
- package/dist/telemetry/index.js +2 -2
- package/dist/types/config.d.ts +61 -0
- package/dist/types/config.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/index.ts +2 -0
- package/src/runtime/checkpoint-hooks.test.ts +2 -1
- package/src/runtime/checkpoint-hooks.ts +26 -1
- package/src/session/default-session-manager.test.ts +7 -9
- package/src/session/default-session-manager.ts +24 -6
- package/src/session/persistence-service.test.ts +8 -17
- package/src/telemetry/OpenTelemetryAdapter.ts +1 -1
- package/src/telemetry/OpenTelemetryProvider.test.ts +191 -0
- package/src/telemetry/OpenTelemetryProvider.ts +2 -2
- package/src/types/config.ts +69 -0
package/dist/types/config.d.ts
CHANGED
|
@@ -66,6 +66,66 @@ export interface CoreCompactionConfig {
|
|
|
66
66
|
summarizer?: CoreCompactionSummarizerConfig;
|
|
67
67
|
compact?: (context: CoreCompactionContext) => Promise<CoreCompactionResult | undefined> | CoreCompactionResult | undefined;
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Context passed to a custom `createCheckpoint` implementation.
|
|
71
|
+
*/
|
|
72
|
+
export interface CoreCheckpointContext {
|
|
73
|
+
/** Absolute path to the working directory of the session. */
|
|
74
|
+
cwd: string;
|
|
75
|
+
/** The session identifier. */
|
|
76
|
+
sessionId: string;
|
|
77
|
+
/** Monotonically increasing run counter for this session (starts at 1). */
|
|
78
|
+
runCount: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Configuration for the built-in git-based checkpoint feature.
|
|
82
|
+
*
|
|
83
|
+
* Checkpoints capture a restorable snapshot of the workspace at the start of
|
|
84
|
+
* each root-agent run so that changes made during a session can be rolled back.
|
|
85
|
+
*
|
|
86
|
+
* @example Disable checkpoints entirely:
|
|
87
|
+
* ```ts
|
|
88
|
+
* checkpoint: { enabled: false }
|
|
89
|
+
* ```
|
|
90
|
+
*
|
|
91
|
+
* @example Bring your own checkpoint implementation:
|
|
92
|
+
* ```ts
|
|
93
|
+
* checkpoint: {
|
|
94
|
+
* createCheckpoint: async ({ cwd, sessionId, runCount }) => {
|
|
95
|
+
* const ref = await mySnapshotFn(cwd);
|
|
96
|
+
* return { ref, createdAt: Date.now(), runCount };
|
|
97
|
+
* },
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export interface CoreCheckpointConfig {
|
|
102
|
+
/**
|
|
103
|
+
* Whether to create checkpoints on each root-agent run start.
|
|
104
|
+
* Defaults to `false` — checkpoints are **opt-in**. Set to `true` to
|
|
105
|
+
* enable the built-in git stash/ref checkpoint behaviour for this session.
|
|
106
|
+
*/
|
|
107
|
+
enabled?: boolean;
|
|
108
|
+
/**
|
|
109
|
+
* Replace the built-in git stash/ref checkpoint logic with a custom
|
|
110
|
+
* implementation. Called once at the start of each root-agent run (before
|
|
111
|
+
* the first agent iteration).
|
|
112
|
+
*
|
|
113
|
+
* Return an object with at least `ref`, `createdAt`, and `runCount` to have
|
|
114
|
+
* the entry recorded in session metadata, or return `undefined` to skip
|
|
115
|
+
* writing a checkpoint for that run.
|
|
116
|
+
*/
|
|
117
|
+
createCheckpoint?: (context: CoreCheckpointContext) => Promise<{
|
|
118
|
+
ref: string;
|
|
119
|
+
createdAt: number;
|
|
120
|
+
runCount: number;
|
|
121
|
+
kind?: "stash" | "commit";
|
|
122
|
+
} | undefined> | {
|
|
123
|
+
ref: string;
|
|
124
|
+
createdAt: number;
|
|
125
|
+
runCount: number;
|
|
126
|
+
kind?: "stash" | "commit";
|
|
127
|
+
} | undefined;
|
|
128
|
+
}
|
|
69
129
|
export interface CoreSessionConfig extends CoreModelConfig, CoreRuntimeFeatures, Omit<SessionWorkspaceConfig, "workspaceRoot">, Omit<SessionPromptConfig, "systemPrompt">, Omit<SessionExecutionConfig, "enableTools" | "teamName" | "missionLogIntervalSteps" | "missionLogIntervalMs" | "maxConsecutiveMistakes"> {
|
|
70
130
|
sessionId?: string;
|
|
71
131
|
workspaceRoot?: string;
|
|
@@ -83,6 +143,7 @@ export interface CoreSessionConfig extends CoreModelConfig, CoreRuntimeFeatures,
|
|
|
83
143
|
extensions?: AgentConfig["extensions"];
|
|
84
144
|
execution?: AgentConfig["execution"];
|
|
85
145
|
compaction?: CoreCompactionConfig;
|
|
146
|
+
checkpoint?: CoreCheckpointConfig;
|
|
86
147
|
onTeamEvent?: (event: TeamEvent) => void;
|
|
87
148
|
onConsecutiveMistakeLimitReached?: (context: ConsecutiveMistakeLimitContext) => Promise<ConsecutiveMistakeLimitDecision> | ConsecutiveMistakeLimitDecision;
|
|
88
149
|
toolRoutingRules?: ToolRoutingRule[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,aAAa,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EACX,WAAW,EACX,UAAU,EACV,SAAS,EACT,WAAW,EACX,8BAA8B,EAC9B,+BAA+B,EAC/B,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,IAAI,EACJ,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACzC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAEnE,MAAM,MAAM,aAAa,GAAG,SAAS,CAAC;AAEtC,MAAM,WAAW,eAAe;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC;IAC9C,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACtD;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;OAEG;IACH,eAAe,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;CAClE;AAED,MAAM,WAAW,mBAAmB;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,qBAAqB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,mBAAmB,EAAE,CAAC;IAChC,KAAK,EAAE;QACN,EAAE,EAAE,MAAM,CAAC;QACX,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC;KAC/B,CAAC;IACF,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,oBAAoB;IACpC,QAAQ,EAAE,mBAAmB,EAAE,CAAC;CAChC;AAED,MAAM,WAAW,8BAA8B;IAC9C,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACtD,cAAc,CAAC,EAAE,aAAa,CAAC,cAAc,CAAC;IAC9C,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,SAAS,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,sBAAsB,CAAC;IAClC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,UAAU,CAAC,EAAE,8BAA8B,CAAC;IAC5C,OAAO,CAAC,EAAE,CACT,OAAO,EAAE,qBAAqB,KAE5B,OAAO,CAAC,oBAAoB,GAAG,SAAS,CAAC,GACzC,oBAAoB,GACpB,SAAS,CAAC;CACb;AAED,MAAM,WAAW,iBAChB,SAAQ,eAAe,EACtB,mBAAmB,EACnB,IAAI,CAAC,sBAAsB,EAAE,eAAe,CAAC,EAC7C,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,EACzC,IAAI,CACH,sBAAsB,EACpB,aAAa,GACb,UAAU,GACV,yBAAyB,GACzB,sBAAsB,GACtB,wBAAwB,CAC1B;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,KAAK,CAAC,EAAE,UAAU,CAAC;IACnB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,iBAAiB,CAAC;IAC9B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,UAAU,CAAC,EAAE,IAAI,EAAE,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;IACvC,SAAS,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;IACrC,UAAU,CAAC,EAAE,oBAAoB,CAAC;IAClC,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,CAAC;IACzC,gCAAgC,CAAC,EAAE,CAClC,OAAO,EAAE,8BAA8B,KAErC,OAAO,CAAC,+BAA+B,CAAC,GACxC,+BAA+B,CAAC;IACnC,gBAAgB,CAAC,EAAE,eAAe,EAAE,CAAC;IACrC;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B"}
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/types/config.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@clinebot/core",
|
|
3
3
|
"description": "Cline Core SDK for Node Runtime",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.32",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
7
7
|
"main": "./dist/index.js",
|
|
@@ -36,8 +36,8 @@
|
|
|
36
36
|
"test:watch": "vitest --config vitest.config.ts"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@clinebot/agents": "0.0.
|
|
40
|
-
"@clinebot/llms": "0.0.
|
|
39
|
+
"@clinebot/agents": "0.0.32",
|
|
40
|
+
"@clinebot/llms": "0.0.32",
|
|
41
41
|
"@opentelemetry/api": "^1.9.0",
|
|
42
42
|
"@opentelemetry/api-logs": "^0.214.0",
|
|
43
43
|
"@opentelemetry/exporter-logs-otlp-http": "^0.214.0",
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
60
|
"@clinebot/rpc": "0.0.28",
|
|
61
|
-
"@clinebot/shared": "0.0.
|
|
61
|
+
"@clinebot/shared": "0.0.32"
|
|
62
62
|
},
|
|
63
63
|
"engines": {
|
|
64
64
|
"node": ">=22"
|
package/src/index.ts
CHANGED
|
@@ -535,6 +535,8 @@ export type { SessionStatus } from "./types/common";
|
|
|
535
535
|
export { SESSION_STATUSES, SessionSource } from "./types/common";
|
|
536
536
|
export type {
|
|
537
537
|
CoreAgentMode,
|
|
538
|
+
CoreCheckpointConfig,
|
|
539
|
+
CoreCheckpointContext,
|
|
538
540
|
CoreCompactionConfig,
|
|
539
541
|
CoreCompactionContext,
|
|
540
542
|
CoreCompactionResult,
|
|
@@ -30,7 +30,8 @@ async function createGitRepo(): Promise<string> {
|
|
|
30
30
|
return cwd;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// Currently disabled for process?.env?.CLINE_CHECKPOINT
|
|
34
|
+
describe.skip("createCheckpointHooks", () => {
|
|
34
35
|
it("creates one checkpoint at the start of each root run and appends metadata", async () => {
|
|
35
36
|
const cwd = await createGitRepo();
|
|
36
37
|
let metadata: Record<string, unknown> | undefined;
|
|
@@ -24,6 +24,16 @@ type CreateCheckpointHooksOptions = {
|
|
|
24
24
|
writeSessionMetadata: (
|
|
25
25
|
metadata: Record<string, unknown>,
|
|
26
26
|
) => Promise<void> | void;
|
|
27
|
+
/**
|
|
28
|
+
* Optional custom checkpoint implementation. When provided, the built-in
|
|
29
|
+
* git stash/ref logic is skipped entirely and this function is called
|
|
30
|
+
* instead. Return `undefined` to skip writing a checkpoint for that run.
|
|
31
|
+
*/
|
|
32
|
+
createCheckpoint?: (context: {
|
|
33
|
+
cwd: string;
|
|
34
|
+
sessionId: string;
|
|
35
|
+
runCount: number;
|
|
36
|
+
}) => Promise<CheckpointEntry | undefined> | CheckpointEntry | undefined;
|
|
27
37
|
};
|
|
28
38
|
|
|
29
39
|
function warn(logger: BasicLogger | undefined, message: string): void {
|
|
@@ -99,6 +109,14 @@ export function createCheckpointHooks(
|
|
|
99
109
|
};
|
|
100
110
|
|
|
101
111
|
const createCheckpoint = async (): Promise<CheckpointEntry | undefined> => {
|
|
112
|
+
if (options.createCheckpoint) {
|
|
113
|
+
return await options.createCheckpoint({
|
|
114
|
+
cwd: options.cwd,
|
|
115
|
+
sessionId: options.sessionId,
|
|
116
|
+
runCount,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
|
|
102
120
|
if (!(await ensureGitRepository())) {
|
|
103
121
|
return undefined;
|
|
104
122
|
}
|
|
@@ -137,8 +155,15 @@ export function createCheckpointHooks(
|
|
|
137
155
|
};
|
|
138
156
|
}
|
|
139
157
|
|
|
158
|
+
// Store the stash commit under a private ref namespace so it is
|
|
159
|
+
// invisible to the user's normal `git stash list` workflow.
|
|
160
|
+
// `refs/stash` is what populates that list; writing to any other
|
|
161
|
+
// ref path keeps the object reachable (GC-safe) without surfacing
|
|
162
|
+
// it to the user. The raw SHA already works with `git stash apply`
|
|
163
|
+
// on the restore path, so no restore-side changes are needed.
|
|
164
|
+
const privateRef = `refs/cline/checkpoints/${options.sessionId}/${runCount}`;
|
|
140
165
|
try {
|
|
141
|
-
await runGit(options.cwd, ["
|
|
166
|
+
await runGit(options.cwd, ["update-ref", privateRef, ref]);
|
|
142
167
|
} catch (error) {
|
|
143
168
|
warn(
|
|
144
169
|
options.logger,
|
|
@@ -150,7 +150,6 @@ describe("DefaultSessionManager", () => {
|
|
|
150
150
|
const envSnapshot = {
|
|
151
151
|
HOME: process.env.HOME,
|
|
152
152
|
CLINE_DIR: process.env.CLINE_DIR,
|
|
153
|
-
CLINE_CHECKPOINT: process.env.CLINE_CHECKPOINT,
|
|
154
153
|
};
|
|
155
154
|
let isolatedHomeDir = "";
|
|
156
155
|
|
|
@@ -158,7 +157,6 @@ describe("DefaultSessionManager", () => {
|
|
|
158
157
|
isolatedHomeDir = mkdtempSync(join(tmpdir(), "core-session-home-"));
|
|
159
158
|
process.env.HOME = isolatedHomeDir;
|
|
160
159
|
process.env.CLINE_DIR = join(isolatedHomeDir, ".cline");
|
|
161
|
-
delete process.env.CLINE_CHECKPOINT;
|
|
162
160
|
setHomeDir(isolatedHomeDir);
|
|
163
161
|
setClineDir(process.env.CLINE_DIR);
|
|
164
162
|
});
|
|
@@ -166,7 +164,6 @@ describe("DefaultSessionManager", () => {
|
|
|
166
164
|
afterEach(() => {
|
|
167
165
|
process.env.HOME = envSnapshot.HOME;
|
|
168
166
|
process.env.CLINE_DIR = envSnapshot.CLINE_DIR;
|
|
169
|
-
process.env.CLINE_CHECKPOINT = envSnapshot.CLINE_CHECKPOINT;
|
|
170
167
|
setHomeDir(envSnapshot.HOME ?? "~");
|
|
171
168
|
setClineDir(envSnapshot.CLINE_DIR ?? join("~", ".cline"));
|
|
172
169
|
rmSync(isolatedHomeDir, { recursive: true, force: true });
|
|
@@ -652,7 +649,7 @@ describe("DefaultSessionManager", () => {
|
|
|
652
649
|
);
|
|
653
650
|
});
|
|
654
651
|
|
|
655
|
-
it("does not install checkpoint hooks
|
|
652
|
+
it("does not install checkpoint hooks when checkpoint.enabled is not set in config", async () => {
|
|
656
653
|
const sessionId = "sess-checkpoint-default-off";
|
|
657
654
|
const manifest = createManifest(sessionId);
|
|
658
655
|
const updateSession = vi.fn().mockResolvedValue({ updated: true });
|
|
@@ -737,10 +734,8 @@ describe("DefaultSessionManager", () => {
|
|
|
737
734
|
});
|
|
738
735
|
});
|
|
739
736
|
|
|
740
|
-
it("installs checkpoint hooks when
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
const sessionId = "sess-checkpoint-env-on";
|
|
737
|
+
it("installs checkpoint hooks when checkpoint.enabled=true in config", async () => {
|
|
738
|
+
const sessionId = "sess-checkpoint-config-on";
|
|
744
739
|
const repoCwd = mkdtempSync(join(isolatedHomeDir, "checkpoint-repo-"));
|
|
745
740
|
createGitRepo(repoCwd);
|
|
746
741
|
const manifest = createManifest(sessionId);
|
|
@@ -813,7 +808,10 @@ describe("DefaultSessionManager", () => {
|
|
|
813
808
|
});
|
|
814
809
|
|
|
815
810
|
await manager.start({
|
|
816
|
-
config:
|
|
811
|
+
config: {
|
|
812
|
+
...createConfig({ sessionId, cwd: repoCwd }),
|
|
813
|
+
checkpoint: { enabled: true },
|
|
814
|
+
},
|
|
817
815
|
prompt: "hello",
|
|
818
816
|
interactive: false,
|
|
819
817
|
});
|
|
@@ -115,11 +115,6 @@ type SessionBackend =
|
|
|
115
115
|
const MAX_SCAN_LIMIT = 5000;
|
|
116
116
|
const MAX_USER_FILE_BYTES = 20 * 1_000 * 1_024;
|
|
117
117
|
|
|
118
|
-
// NOTE: Temporarily disabled until checkpoint is ready for production.
|
|
119
|
-
function isCheckpointFeatureEnabled(): boolean {
|
|
120
|
-
return process?.env?.CLINE_CHECKPOINT === "true";
|
|
121
|
-
}
|
|
122
|
-
|
|
123
118
|
async function loadUserFileContent(path: string): Promise<string> {
|
|
124
119
|
const fileStat = await stat(path);
|
|
125
120
|
if (!fileStat.isFile()) {
|
|
@@ -277,11 +272,12 @@ export class DefaultSessionManager implements SessionManager {
|
|
|
277
272
|
};
|
|
278
273
|
configWithProvider.hooks = mergeAgentHooks([
|
|
279
274
|
effectiveConfig.hooks,
|
|
280
|
-
|
|
275
|
+
effectiveConfig.checkpoint?.enabled === true
|
|
281
276
|
? createCheckpointHooks({
|
|
282
277
|
cwd: configWithProvider.cwd,
|
|
283
278
|
sessionId,
|
|
284
279
|
logger: configWithProvider.logger,
|
|
280
|
+
createCheckpoint: effectiveConfig.checkpoint?.createCheckpoint,
|
|
285
281
|
readSessionMetadata: async () =>
|
|
286
282
|
(await this.get(sessionId))?.metadata as
|
|
287
283
|
| Record<string, unknown>
|
|
@@ -344,6 +340,7 @@ export class DefaultSessionManager implements SessionManager {
|
|
|
344
340
|
onConsecutiveMistakeLimitReached:
|
|
345
341
|
configWithProvider.onConsecutiveMistakeLimitReached,
|
|
346
342
|
completionGuard: runtime.completionGuard,
|
|
343
|
+
consumePendingUserMessage: () => this.consumeSteerMessage(sessionId),
|
|
347
344
|
logger: runtime.logger ?? configWithProvider.logger,
|
|
348
345
|
extensionContext: configWithProvider.extensionContext,
|
|
349
346
|
onEvent: (event: AgentEvent) =>
|
|
@@ -964,6 +961,27 @@ export class DefaultSessionManager implements SessionManager {
|
|
|
964
961
|
});
|
|
965
962
|
}
|
|
966
963
|
|
|
964
|
+
/**
|
|
965
|
+
* Consume the first steer-delivery pending prompt for injection into the
|
|
966
|
+
* running agent loop. Called synchronously by the agent between iterations.
|
|
967
|
+
*/
|
|
968
|
+
private consumeSteerMessage(sessionId: string): string | undefined {
|
|
969
|
+
const session = this.sessions.get(sessionId);
|
|
970
|
+
if (!session) {
|
|
971
|
+
return undefined;
|
|
972
|
+
}
|
|
973
|
+
const steerIndex = session.pendingPrompts.findIndex(
|
|
974
|
+
(entry) => entry.delivery === "steer",
|
|
975
|
+
);
|
|
976
|
+
if (steerIndex < 0) {
|
|
977
|
+
return undefined;
|
|
978
|
+
}
|
|
979
|
+
const [steer] = session.pendingPrompts.splice(steerIndex, 1);
|
|
980
|
+
this.emitPendingPrompts(session);
|
|
981
|
+
this.emitPendingPromptSubmitted(session, steer);
|
|
982
|
+
return steer.prompt;
|
|
983
|
+
}
|
|
984
|
+
|
|
967
985
|
private enqueuePendingPrompt(
|
|
968
986
|
sessionId: string,
|
|
969
987
|
entry: {
|
|
@@ -160,13 +160,11 @@ describe("UnifiedSessionPersistenceService", () => {
|
|
|
160
160
|
row.sessionId.includes("__teamtask__java-haiku-agent__"),
|
|
161
161
|
)?.sessionId;
|
|
162
162
|
expect(teammateSessionId).toBeTruthy();
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
rootSessionId,
|
|
166
|
-
"java-haiku-agent__" +
|
|
167
|
-
teammateSessionId?.slice(teammateSessionId?.lastIndexOf("__") + 2) +
|
|
168
|
-
".messages.json",
|
|
163
|
+
const row = childSessions.find(
|
|
164
|
+
(item) => item.sessionId === teammateSessionId,
|
|
169
165
|
);
|
|
166
|
+
expect(row?.messagesPath).toBeTruthy();
|
|
167
|
+
const path = row?.messagesPath as string;
|
|
170
168
|
const payload = JSON.parse(readFileSync(path, "utf8")) as {
|
|
171
169
|
agent?: string;
|
|
172
170
|
sessionId?: string;
|
|
@@ -195,18 +193,11 @@ describe("UnifiedSessionPersistenceService", () => {
|
|
|
195
193
|
cacheWriteTokens: 0,
|
|
196
194
|
cost: 0.123,
|
|
197
195
|
});
|
|
198
|
-
const row = childSessions.find(
|
|
199
|
-
(item) => item.sessionId === teammateSessionId,
|
|
200
|
-
);
|
|
201
196
|
expect(row?.messagesPath).toBe(path);
|
|
202
|
-
expect(row?.transcriptPath).
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
rootSessionId,
|
|
206
|
-
"java-haiku-agent__" +
|
|
207
|
-
teammateSessionId?.slice(teammateSessionId?.lastIndexOf("__") + 2) +
|
|
208
|
-
".log",
|
|
209
|
-
),
|
|
197
|
+
expect(row?.transcriptPath).toBeTruthy();
|
|
198
|
+
expect(row?.transcriptPath).toContain(
|
|
199
|
+
join(sessionsDir, rootSessionId, "java-haiku-agent__"),
|
|
210
200
|
);
|
|
201
|
+
expect(row?.transcriptPath).toMatch(/\.log$/);
|
|
211
202
|
});
|
|
212
203
|
});
|
|
@@ -229,8 +229,8 @@ export class OpenTelemetryAdapter implements ITelemetryAdapter {
|
|
|
229
229
|
): TelemetryProperties {
|
|
230
230
|
return {
|
|
231
231
|
...this.commonProperties,
|
|
232
|
-
...properties,
|
|
233
232
|
...this.metadata,
|
|
233
|
+
...properties,
|
|
234
234
|
...(this.distinctId ? { distinct_id: this.distinctId } : {}),
|
|
235
235
|
...(required ? { _required: true } : {}),
|
|
236
236
|
};
|
|
@@ -98,6 +98,197 @@ describe("createOpenTelemetryTelemetryService", () => {
|
|
|
98
98
|
expect(telemetry).toBeInstanceOf(TelemetryService);
|
|
99
99
|
});
|
|
100
100
|
|
|
101
|
+
it("preserves metadata when disabled", () => {
|
|
102
|
+
const metadata = {
|
|
103
|
+
extension_version: "1.0.0",
|
|
104
|
+
cline_type: "kanban",
|
|
105
|
+
platform: "kanban",
|
|
106
|
+
platform_version: "v22.0.0",
|
|
107
|
+
os_type: "darwin",
|
|
108
|
+
os_version: "15.0",
|
|
109
|
+
};
|
|
110
|
+
const { telemetry } = createConfiguredTelemetryService({
|
|
111
|
+
metadata,
|
|
112
|
+
enabled: false,
|
|
113
|
+
});
|
|
114
|
+
const spy = vi.fn();
|
|
115
|
+
(telemetry as any).adapters.push({
|
|
116
|
+
name: "test",
|
|
117
|
+
emit: spy,
|
|
118
|
+
emitRequired: spy,
|
|
119
|
+
isEnabled: () => true,
|
|
120
|
+
recordCounter: vi.fn(),
|
|
121
|
+
recordHistogram: vi.fn(),
|
|
122
|
+
recordGauge: vi.fn(),
|
|
123
|
+
flush: async () => {},
|
|
124
|
+
dispose: async () => {},
|
|
125
|
+
});
|
|
126
|
+
telemetry.captureRequired("test.event", {});
|
|
127
|
+
expect(spy).toHaveBeenCalledWith(
|
|
128
|
+
"test.event",
|
|
129
|
+
expect.objectContaining({
|
|
130
|
+
cline_type: "kanban",
|
|
131
|
+
platform: "kanban",
|
|
132
|
+
}),
|
|
133
|
+
);
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
it("preserves metadata in the enabled (OTEL) path", async () => {
|
|
137
|
+
const metadata = {
|
|
138
|
+
extension_version: "1.0.0",
|
|
139
|
+
cline_type: "kanban",
|
|
140
|
+
platform: "kanban",
|
|
141
|
+
platform_version: "v22.0.0",
|
|
142
|
+
os_type: "darwin",
|
|
143
|
+
os_version: "15.0",
|
|
144
|
+
};
|
|
145
|
+
const { telemetry, provider } = createOpenTelemetryTelemetryService({
|
|
146
|
+
metadata,
|
|
147
|
+
enabled: true,
|
|
148
|
+
logsExporter: "console",
|
|
149
|
+
});
|
|
150
|
+
const spy = vi.fn();
|
|
151
|
+
(telemetry as any).adapters.push({
|
|
152
|
+
name: "test",
|
|
153
|
+
emit: spy,
|
|
154
|
+
emitRequired: spy,
|
|
155
|
+
isEnabled: () => true,
|
|
156
|
+
recordCounter: vi.fn(),
|
|
157
|
+
recordHistogram: vi.fn(),
|
|
158
|
+
recordGauge: vi.fn(),
|
|
159
|
+
flush: async () => {},
|
|
160
|
+
dispose: async () => {},
|
|
161
|
+
});
|
|
162
|
+
telemetry.captureRequired("test.event", {});
|
|
163
|
+
expect(spy).toHaveBeenCalledWith(
|
|
164
|
+
"test.event",
|
|
165
|
+
expect.objectContaining({
|
|
166
|
+
cline_type: "kanban",
|
|
167
|
+
platform: "kanban",
|
|
168
|
+
}),
|
|
169
|
+
);
|
|
170
|
+
await provider.dispose();
|
|
171
|
+
});
|
|
172
|
+
|
|
173
|
+
it("delivers metadata to the OTEL logger without duplication", async () => {
|
|
174
|
+
const otelEmit = vi.fn();
|
|
175
|
+
const provider = new OpenTelemetryProvider({
|
|
176
|
+
enabled: true,
|
|
177
|
+
});
|
|
178
|
+
// Replace the loggerProvider with a mock so we can inspect emit calls
|
|
179
|
+
(provider as any).loggerProvider = {
|
|
180
|
+
getLogger: () => ({ emit: otelEmit }),
|
|
181
|
+
forceFlush: async () => {},
|
|
182
|
+
shutdown: async () => {},
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
const metadata = {
|
|
186
|
+
extension_version: "1.0.0",
|
|
187
|
+
cline_type: "kanban",
|
|
188
|
+
platform: "kanban",
|
|
189
|
+
platform_version: "v22.0.0",
|
|
190
|
+
os_type: "darwin",
|
|
191
|
+
os_version: "15.0",
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
const telemetry = provider.createTelemetryService({ metadata });
|
|
195
|
+
|
|
196
|
+
telemetry.captureRequired("test.otel_event", { custom_prop: "value" });
|
|
197
|
+
|
|
198
|
+
expect(otelEmit).toHaveBeenCalledTimes(1);
|
|
199
|
+
const emittedAttributes = otelEmit.mock.calls[0][0].attributes;
|
|
200
|
+
|
|
201
|
+
// Metadata fields must be present
|
|
202
|
+
expect(emittedAttributes).toMatchObject({
|
|
203
|
+
cline_type: "kanban",
|
|
204
|
+
platform: "kanban",
|
|
205
|
+
extension_version: "1.0.0",
|
|
206
|
+
custom_prop: "value",
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
// Verify no key appears more than once (flattened object can't have
|
|
210
|
+
// duplicate keys, but this guards against nested duplication patterns
|
|
211
|
+
// like metadata appearing under a sub-prefix)
|
|
212
|
+
const keys = Object.keys(emittedAttributes);
|
|
213
|
+
const metadataKeys = Object.keys(metadata);
|
|
214
|
+
for (const mk of metadataKeys) {
|
|
215
|
+
const occurrences = keys.filter((k) => k === mk || k.endsWith(`.${mk}`));
|
|
216
|
+
expect(
|
|
217
|
+
occurrences,
|
|
218
|
+
`metadata key "${mk}" should appear exactly once, found: ${occurrences.join(", ")}`,
|
|
219
|
+
).toHaveLength(1);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
await provider.dispose();
|
|
223
|
+
});
|
|
224
|
+
|
|
225
|
+
it("propagates updateMetadata to OTEL logger output", async () => {
|
|
226
|
+
const otelEmit = vi.fn();
|
|
227
|
+
const provider = new OpenTelemetryProvider({
|
|
228
|
+
enabled: true,
|
|
229
|
+
});
|
|
230
|
+
(provider as any).loggerProvider = {
|
|
231
|
+
getLogger: () => ({ emit: otelEmit }),
|
|
232
|
+
forceFlush: async () => {},
|
|
233
|
+
shutdown: async () => {},
|
|
234
|
+
};
|
|
235
|
+
|
|
236
|
+
const metadata = {
|
|
237
|
+
extension_version: "1.0.0",
|
|
238
|
+
cline_type: "kanban",
|
|
239
|
+
platform: "kanban",
|
|
240
|
+
platform_version: "v22.0.0",
|
|
241
|
+
os_type: "darwin",
|
|
242
|
+
os_version: "15.0",
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
const telemetry = provider.createTelemetryService({ metadata });
|
|
246
|
+
|
|
247
|
+
// Update metadata after construction
|
|
248
|
+
telemetry.updateMetadata({ cline_type: "kanban-updated" });
|
|
249
|
+
|
|
250
|
+
telemetry.captureRequired("test.updated_event", {});
|
|
251
|
+
|
|
252
|
+
// The OTEL logger should see the updated value
|
|
253
|
+
const emittedAttributes =
|
|
254
|
+
otelEmit.mock.calls[otelEmit.mock.calls.length - 1][0].attributes;
|
|
255
|
+
expect(emittedAttributes.cline_type).toBe("kanban-updated");
|
|
256
|
+
|
|
257
|
+
await provider.dispose();
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
it("preserves logger when disabled", () => {
|
|
261
|
+
const logger: BasicLogger = {
|
|
262
|
+
debug: vi.fn(),
|
|
263
|
+
log: vi.fn(),
|
|
264
|
+
error: vi.fn(),
|
|
265
|
+
};
|
|
266
|
+
const { telemetry } = createConfiguredTelemetryService({
|
|
267
|
+
metadata: {
|
|
268
|
+
extension_version: "1.0.0",
|
|
269
|
+
cline_type: "kanban",
|
|
270
|
+
platform: "kanban",
|
|
271
|
+
platform_version: "v22.0.0",
|
|
272
|
+
os_type: "darwin",
|
|
273
|
+
os_version: "15.0",
|
|
274
|
+
},
|
|
275
|
+
enabled: false,
|
|
276
|
+
logger,
|
|
277
|
+
});
|
|
278
|
+
|
|
279
|
+
telemetry.capture({
|
|
280
|
+
event: "session.started",
|
|
281
|
+
properties: { sessionId: "session-1" },
|
|
282
|
+
});
|
|
283
|
+
|
|
284
|
+
expect(logger.log).toHaveBeenCalledWith(
|
|
285
|
+
"telemetry.event",
|
|
286
|
+
expect.objectContaining({
|
|
287
|
+
event: "session.started",
|
|
288
|
+
}),
|
|
289
|
+
);
|
|
290
|
+
});
|
|
291
|
+
|
|
101
292
|
it("attaches the logger adapter when creating configured telemetry", () => {
|
|
102
293
|
const logger: BasicLogger = {
|
|
103
294
|
debug: vi.fn(),
|
|
@@ -133,10 +133,9 @@ export class OpenTelemetryProvider {
|
|
|
133
133
|
metadata: options.metadata,
|
|
134
134
|
});
|
|
135
135
|
return new TelemetryService({
|
|
136
|
+
...options,
|
|
136
137
|
adapters: [adapter],
|
|
137
138
|
distinctId: resolveCoreDistinctId(options.distinctId),
|
|
138
|
-
commonProperties: options.commonProperties,
|
|
139
|
-
logger: options.logger,
|
|
140
139
|
});
|
|
141
140
|
}
|
|
142
141
|
|
|
@@ -299,6 +298,7 @@ export function createConfiguredTelemetryService(
|
|
|
299
298
|
if (options.enabled !== true) {
|
|
300
299
|
return {
|
|
301
300
|
telemetry: new TelemetryService({
|
|
301
|
+
...options,
|
|
302
302
|
distinctId: resolveCoreDistinctId(options.distinctId),
|
|
303
303
|
}),
|
|
304
304
|
};
|
package/src/types/config.ts
CHANGED
|
@@ -95,6 +95,74 @@ export interface CoreCompactionConfig {
|
|
|
95
95
|
| undefined;
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
/**
|
|
99
|
+
* Context passed to a custom `createCheckpoint` implementation.
|
|
100
|
+
*/
|
|
101
|
+
export interface CoreCheckpointContext {
|
|
102
|
+
/** Absolute path to the working directory of the session. */
|
|
103
|
+
cwd: string;
|
|
104
|
+
/** The session identifier. */
|
|
105
|
+
sessionId: string;
|
|
106
|
+
/** Monotonically increasing run counter for this session (starts at 1). */
|
|
107
|
+
runCount: number;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Configuration for the built-in git-based checkpoint feature.
|
|
112
|
+
*
|
|
113
|
+
* Checkpoints capture a restorable snapshot of the workspace at the start of
|
|
114
|
+
* each root-agent run so that changes made during a session can be rolled back.
|
|
115
|
+
*
|
|
116
|
+
* @example Disable checkpoints entirely:
|
|
117
|
+
* ```ts
|
|
118
|
+
* checkpoint: { enabled: false }
|
|
119
|
+
* ```
|
|
120
|
+
*
|
|
121
|
+
* @example Bring your own checkpoint implementation:
|
|
122
|
+
* ```ts
|
|
123
|
+
* checkpoint: {
|
|
124
|
+
* createCheckpoint: async ({ cwd, sessionId, runCount }) => {
|
|
125
|
+
* const ref = await mySnapshotFn(cwd);
|
|
126
|
+
* return { ref, createdAt: Date.now(), runCount };
|
|
127
|
+
* },
|
|
128
|
+
* }
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
export interface CoreCheckpointConfig {
|
|
132
|
+
/**
|
|
133
|
+
* Whether to create checkpoints on each root-agent run start.
|
|
134
|
+
* Defaults to `false` — checkpoints are **opt-in**. Set to `true` to
|
|
135
|
+
* enable the built-in git stash/ref checkpoint behaviour for this session.
|
|
136
|
+
*/
|
|
137
|
+
enabled?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Replace the built-in git stash/ref checkpoint logic with a custom
|
|
140
|
+
* implementation. Called once at the start of each root-agent run (before
|
|
141
|
+
* the first agent iteration).
|
|
142
|
+
*
|
|
143
|
+
* Return an object with at least `ref`, `createdAt`, and `runCount` to have
|
|
144
|
+
* the entry recorded in session metadata, or return `undefined` to skip
|
|
145
|
+
* writing a checkpoint for that run.
|
|
146
|
+
*/
|
|
147
|
+
createCheckpoint?: (context: CoreCheckpointContext) =>
|
|
148
|
+
| Promise<
|
|
149
|
+
| {
|
|
150
|
+
ref: string;
|
|
151
|
+
createdAt: number;
|
|
152
|
+
runCount: number;
|
|
153
|
+
kind?: "stash" | "commit";
|
|
154
|
+
}
|
|
155
|
+
| undefined
|
|
156
|
+
>
|
|
157
|
+
| {
|
|
158
|
+
ref: string;
|
|
159
|
+
createdAt: number;
|
|
160
|
+
runCount: number;
|
|
161
|
+
kind?: "stash" | "commit";
|
|
162
|
+
}
|
|
163
|
+
| undefined;
|
|
164
|
+
}
|
|
165
|
+
|
|
98
166
|
export interface CoreSessionConfig
|
|
99
167
|
extends CoreModelConfig,
|
|
100
168
|
CoreRuntimeFeatures,
|
|
@@ -124,6 +192,7 @@ export interface CoreSessionConfig
|
|
|
124
192
|
extensions?: AgentConfig["extensions"];
|
|
125
193
|
execution?: AgentConfig["execution"];
|
|
126
194
|
compaction?: CoreCompactionConfig;
|
|
195
|
+
checkpoint?: CoreCheckpointConfig;
|
|
127
196
|
onTeamEvent?: (event: TeamEvent) => void;
|
|
128
197
|
onConsecutiveMistakeLimitReached?: (
|
|
129
198
|
context: ConsecutiveMistakeLimitContext,
|