@cerebriline/core 4.100.246 → 4.100.247
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/assets/prompt-templates/claude.md +2 -0
- package/assets/prompt-templates/deepseek.md +1 -0
- package/assets/prompt-templates/default.md +2 -1
- package/assets/prompt-templates/kimi-k3.md +1 -0
- package/assets/prompt-templates/kimi.md +1 -0
- package/assets/prompt-templates/minimax.md +2 -0
- package/assets/prompt-templates/nemotron.md +1 -0
- package/assets/skills/browser-automation/SKILL.md +113 -0
- package/dist/ClineCore.d.ts +9 -0
- package/dist/account/index.d.ts +1 -0
- package/dist/account/telemetry.d.ts +22 -0
- package/dist/cloud/api.d.ts +122 -0
- package/dist/cloud/controller.d.ts +172 -0
- package/dist/cloud/index.d.ts +9 -0
- package/dist/cloud/index.js +21 -0
- package/dist/cloud/models.d.ts +9 -0
- package/dist/cloud/repositories.d.ts +21 -0
- package/dist/cloud/snapshots.d.ts +22 -0
- package/dist/cloud/state.d.ts +13 -0
- package/dist/cloud/types.d.ts +84 -0
- package/dist/cron/events/cron-event-ingress.d.ts +4 -2
- package/dist/cron/runner/cron-runner.d.ts +5 -2
- package/dist/cron/service/cron-service.d.ts +2 -1
- package/dist/cron/service/schedule-service.d.ts +2 -1
- package/dist/cron/store/sqlite-cron-store.d.ts +7 -1
- package/dist/extensions/composio/composio-meta-tools.d.ts +39 -0
- package/dist/extensions/composio/composio-tools-extension.d.ts +13 -0
- package/dist/extensions/context/agentic-compaction.d.ts +1 -1
- package/dist/extensions/context/cap-thoughts.d.ts +39 -0
- package/dist/extensions/context/compaction-shared.d.ts +76 -1
- package/dist/extensions/context/compaction.d.ts +75 -3
- package/dist/extensions/mcp/client.d.ts +1 -1
- package/dist/extensions/tools/definitions.d.ts +5 -5
- package/dist/extensions/tools/executors/bash.d.ts +26 -0
- package/dist/extensions/tools/executors/index.d.ts +1 -1
- package/dist/extensions/tools/index.d.ts +1 -1
- package/dist/extensions/tools/task-progress.d.ts +37 -0
- package/dist/extensions/tools/team/index.d.ts +1 -0
- package/dist/extensions/tools/team/multi-agent.d.ts +48 -0
- package/dist/extensions/tools/team/persistence-policy.d.ts +56 -0
- package/dist/extensions/tools/team/runtime.d.ts +1 -1
- package/dist/extensions/tools/team/sanitize-team-name.d.ts +5 -0
- package/dist/extensions/tools/team/team-tools.d.ts +1 -1
- package/dist/hooks/checkpoint-hooks.d.ts +23 -1
- package/dist/hooks/hook-file-hooks.d.ts +27 -0
- package/dist/hooks/subprocess-runner.d.ts +23 -0
- package/dist/hooks/subprocess.d.ts +10 -0
- package/dist/hub/client/index.d.ts +29 -3
- package/dist/hub/client/session-client.d.ts +0 -3
- package/dist/hub/daemon/bind-diagnostics.d.ts +16 -0
- package/dist/hub/daemon/entry.js +689 -640
- package/dist/hub/daemon/index.d.ts +17 -8
- package/dist/hub/discovery/index.d.ts +1 -0
- package/dist/hub/index.js +675 -627
- package/dist/hub/runtime-host/hub-runtime-host.d.ts +4 -2
- package/dist/hub/server/handlers/session-handlers.d.ts +6 -1
- package/dist/index.d.ts +21 -11
- package/dist/index.js +1032 -964
- package/dist/remote/remote-environments.d.ts +155 -0
- package/dist/remote/remote-helper-entry.d.ts +1 -0
- package/dist/remote/remote-helper-entry.js +5 -0
- package/dist/remote/remote-helper.d.ts +29 -0
- package/dist/remote/remote-helper.js +4 -0
- package/dist/remote/shell-path.d.ts +88 -0
- package/dist/runtime/host/local-runtime-host.d.ts +2 -2
- package/dist/runtime/host/runtime-host.d.ts +13 -1
- package/dist/runtime/orchestration/oauth-refresh-lock.d.ts +6 -0
- package/dist/runtime/orchestration/session-runtime-orchestrator.d.ts +7 -0
- package/dist/runtime/orchestration/team-persistence-writer.d.ts +65 -0
- package/dist/runtime/safety/rules.d.ts +11 -0
- package/dist/runtime/turn-queue/pending-prompt-service.d.ts +1 -0
- package/dist/services/agent-events.d.ts +1 -0
- package/dist/services/cloud-handoff/git-preflight.d.ts +24 -0
- package/dist/services/cloud-handoff/index.d.ts +4 -0
- package/dist/services/cloud-handoff/metadata.d.ts +7 -0
- package/dist/services/cloud-handoff/transcript.d.ts +5 -0
- package/dist/services/cloud-handoff/types.d.ts +35 -0
- package/dist/services/feature-flags/FeatureFlagsService.d.ts +2 -0
- package/dist/services/feature-flags/cline-account-feature-flags.d.ts +5 -0
- package/dist/services/llms/cline-recommended-models.d.ts +1 -0
- package/dist/services/llms/handler-factory.d.ts +12 -0
- package/dist/services/llms/provider-defaults.d.ts +1 -1
- package/dist/services/llms/provider-settings.d.ts +19 -17
- package/dist/services/local-runtime-bootstrap.d.ts +7 -0
- package/dist/services/mcp-install.d.ts +9 -0
- package/dist/services/plugin-commands.d.ts +28 -0
- package/dist/services/providers/local-provider-registry.d.ts +8 -3
- package/dist/services/providers/local-provider-service.d.ts +20 -10
- package/dist/services/providers/model-source.d.ts +6 -1
- package/dist/services/providers/provider-config-fields.d.ts +11 -0
- package/dist/services/session-import/claude-code.d.ts +1 -1
- package/dist/services/session-import/paths.d.ts +9 -0
- package/dist/services/storage/file-team-store.d.ts +10 -4
- package/dist/services/storage/sqlite-team-store.d.ts +48 -5
- package/dist/services/storage/team-store.d.ts +1 -0
- package/dist/services/telemetry/core-events.d.ts +97 -5
- package/dist/services/telemetry/index.d.ts +1 -0
- package/dist/services/telemetry/index.js +1 -1
- package/dist/services/telemetry/scoped-telemetry.d.ts +31 -0
- package/dist/services/workspace/workspace-manifest.d.ts +34 -0
- package/dist/services/workspace/workspace-telemetry.d.ts +5 -0
- package/dist/session/fork-metadata.d.ts +7 -0
- package/dist/session/models/session-compaction.d.ts +8 -1
- package/dist/session/services/message-builder.d.ts +8 -1
- package/dist/session/services/persistence-service.d.ts +4 -1
- package/dist/session/services/tool-result-cache.d.ts +30 -0
- package/dist/session/session-versioning-service.d.ts +8 -0
- package/dist/session/stores/session-manifest-store.d.ts +2 -4
- package/dist/session/team/team-session-coordinator.d.ts +3 -1
- package/dist/tasks/task-tool.d.ts +2 -2
- package/dist/types/provider-settings.d.ts +11 -0
- package/dist/types/session.d.ts +2 -0
- package/dist/types/storage.d.ts +22 -1
- package/package.json +16 -4
- package/dist/cron/runner/resource-limiter.d.ts +0 -8
- package/dist/services/storage/team-events-retention.d.ts +0 -25
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { TeamRuntimeState, TeamTeammateSpec } from "@cerebriline/shared";
|
|
2
2
|
import type { TeamEvent } from "../../extensions/tools/team";
|
|
3
|
-
import type { TeamStore } from "../../types/storage";
|
|
4
|
-
|
|
5
|
-
export interface FileTeamStoreOptions extends TeamEventsRetention {
|
|
3
|
+
import type { TeamPersistenceBatch, TeamStore } from "../../types/storage";
|
|
4
|
+
export interface FileTeamStoreOptions {
|
|
6
5
|
teamDir?: string;
|
|
7
6
|
}
|
|
8
7
|
export interface TeamRuntimeLoadResult {
|
|
@@ -12,7 +11,6 @@ export interface TeamRuntimeLoadResult {
|
|
|
12
11
|
}
|
|
13
12
|
export declare class FileTeamStore implements TeamStore {
|
|
14
13
|
private readonly teamDirPath;
|
|
15
|
-
private readonly eventsPrune;
|
|
16
14
|
constructor(options?: FileTeamStoreOptions);
|
|
17
15
|
/** Nothing is held open between calls; present so both stores close alike. */
|
|
18
16
|
close(): void;
|
|
@@ -22,6 +20,14 @@ export declare class FileTeamStore implements TeamStore {
|
|
|
22
20
|
readHistory(teamName: string, limit?: number): unknown[];
|
|
23
21
|
loadRuntime(teamName: string): TeamRuntimeLoadResult;
|
|
24
22
|
handleTeamEvent(teamName: string, event: TeamEvent): void;
|
|
23
|
+
/**
|
|
24
|
+
* The file store cannot apply deltas, so it rewrites `state.json` once per
|
|
25
|
+
* batch. Batching plus compacted run results keep that file small.
|
|
26
|
+
*/
|
|
27
|
+
persistBatch(teamName: string, batch: TeamPersistenceBatch): void;
|
|
28
|
+
private appendHistory;
|
|
29
|
+
/** Keep the newest `retentionPerTeam` lines once the file grows too big. */
|
|
30
|
+
private compactHistoryIfNeeded;
|
|
25
31
|
persistRuntime(teamName: string, state: TeamRuntimeState, teammates: TeamTeammateSpec[]): void;
|
|
26
32
|
markInProgressRunsInterrupted(teamName: string, reason: string): string[];
|
|
27
33
|
private ensureTeamDir;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { type TeamRuntimeState, type TeamTeammateSpec } from "@cerebriline/shared";
|
|
2
2
|
import type { TeamEvent } from "../../extensions/tools/team";
|
|
3
|
-
import type { TeamStore } from "../../types/storage";
|
|
4
|
-
|
|
5
|
-
export interface SqliteTeamStoreOptions extends TeamEventsRetention {
|
|
3
|
+
import type { TeamPersistenceBatch, TeamStore } from "../../types/storage";
|
|
4
|
+
export interface SqliteTeamStoreOptions {
|
|
6
5
|
teamDir?: string;
|
|
7
6
|
}
|
|
8
7
|
export interface TeamRuntimeLoadResult {
|
|
@@ -10,11 +9,20 @@ export interface TeamRuntimeLoadResult {
|
|
|
10
9
|
teammates: TeamTeammateSpec[];
|
|
11
10
|
interruptedRunIds: string[];
|
|
12
11
|
}
|
|
12
|
+
/** Durable event rows kept per team (history tool reads newest-first). */
|
|
13
|
+
export declare const TEAM_EVENT_RETENTION_PER_TEAM = 2000;
|
|
14
|
+
/** Event rows older than this are pruned regardless of count. */
|
|
15
|
+
export declare const TEAM_EVENT_RETENTION_MS: number;
|
|
16
|
+
export interface SqliteTeamStoreTuning {
|
|
17
|
+
eventRetentionPerTeam?: number;
|
|
18
|
+
eventRetentionMs?: number;
|
|
19
|
+
}
|
|
13
20
|
export declare class SqliteTeamStore implements TeamStore {
|
|
14
21
|
private readonly teamDirPath;
|
|
15
22
|
private db;
|
|
16
|
-
private readonly
|
|
17
|
-
|
|
23
|
+
private readonly retentionPerTeam;
|
|
24
|
+
private readonly retentionMs;
|
|
25
|
+
constructor(options?: SqliteTeamStoreOptions & SqliteTeamStoreTuning);
|
|
18
26
|
init(): void;
|
|
19
27
|
/**
|
|
20
28
|
* Releases the database handle. The next call reopens it, so a store that
|
|
@@ -26,17 +34,52 @@ export declare class SqliteTeamStore implements TeamStore {
|
|
|
26
34
|
private dbPath;
|
|
27
35
|
private getRawDb;
|
|
28
36
|
private ensureSchema;
|
|
37
|
+
/**
|
|
38
|
+
* Moves any non-empty `state_json` into entity rows, then clears it.
|
|
39
|
+
* v2+ builds only ever write `''`, so a non-empty value was written by an
|
|
40
|
+
* older build (e.g. after an image rollback). Runs on every open, not just
|
|
41
|
+
* the v2 migration, so those writes are recovered after re-upgrading.
|
|
42
|
+
* Caller owns the transaction.
|
|
43
|
+
*/
|
|
44
|
+
private importLegacySnapshots;
|
|
45
|
+
/**
|
|
46
|
+
* v2 migration (one-time, transactional):
|
|
47
|
+
* - adds `data_json` to entity tables and new members/mailbox/mission-log
|
|
48
|
+
* tables, so state is rebuilt from rows instead of `state_json`;
|
|
49
|
+
* - moves each existing snapshot into rows, compacting run results;
|
|
50
|
+
* - deletes telemetry events and strips transcripts from retained ones;
|
|
51
|
+
* - clears `state_json` (the column stays for downgrade-safe schema).
|
|
52
|
+
* Run `vacuum()` afterwards to give the space back to the OS.
|
|
53
|
+
*/
|
|
54
|
+
private migrateToV2;
|
|
29
55
|
private run;
|
|
30
56
|
private queryOne;
|
|
31
57
|
private queryAll;
|
|
32
58
|
/** Runs `work` in a single SQLite transaction (rollback on any error). */
|
|
33
59
|
private withTransaction;
|
|
34
60
|
listTeamNames(): string[];
|
|
61
|
+
/** Rebuild state from per-entity rows. Cost is O(live entities). */
|
|
35
62
|
readState(teamName: string): TeamRuntimeState | undefined;
|
|
36
63
|
readHistory(teamName: string, limit?: number): unknown[];
|
|
37
64
|
loadRuntime(teamName: string): TeamRuntimeLoadResult;
|
|
38
65
|
appendTeamEvent(teamName: string, eventType: string, payload: unknown, correlationId?: string): void;
|
|
66
|
+
/**
|
|
67
|
+
* Incremental write: appends events and upserts only changed entities in
|
|
68
|
+
* one transaction. Cost is O(changes in batch), independent of history.
|
|
69
|
+
*/
|
|
70
|
+
persistBatch(teamName: string, batch: TeamPersistenceBatch): void;
|
|
71
|
+
/** Full rewrite, expressed as a reset delta (no `state_json` blob). */
|
|
39
72
|
persistRuntime(teamName: string, state: TeamRuntimeState, teammates: TeamTeammateSpec[]): void;
|
|
73
|
+
private writeTeammates;
|
|
74
|
+
private writeDelta;
|
|
75
|
+
/** Cap `team_events` per team by count and by age. */
|
|
76
|
+
private pruneTeamEvents;
|
|
77
|
+
/**
|
|
78
|
+
* Return free pages to the OS after the v2 migration or heavy pruning.
|
|
79
|
+
* VACUUM rewrites the whole file, so it is explicit, not automatic.
|
|
80
|
+
*/
|
|
81
|
+
vacuum(): void;
|
|
40
82
|
markInProgressRunsInterrupted(teamName: string, reason: string): string[];
|
|
83
|
+
/** Legacy single-event path: telemetry is dropped, payloads compacted. */
|
|
41
84
|
handleTeamEvent(teamName: string, event: TeamEvent): void;
|
|
42
85
|
}
|
|
@@ -10,6 +10,7 @@ export declare function createLocalTeamStore(options?: SqliteTeamStoreOptions):
|
|
|
10
10
|
readHistory(teamName: string, limit?: number): unknown[];
|
|
11
11
|
loadRuntime(teamName: string): ReturnType<FileTeamStore["loadRuntime"]>;
|
|
12
12
|
handleTeamEvent: FileTeamStore["handleTeamEvent"];
|
|
13
|
+
persistBatch: FileTeamStore["persistBatch"];
|
|
13
14
|
persistRuntime: FileTeamStore["persistRuntime"];
|
|
14
15
|
markInProgressRunsInterrupted: FileTeamStore["markInProgressRunsInterrupted"];
|
|
15
16
|
close(): void;
|
|
@@ -14,12 +14,17 @@ export interface TelemetryAgentIdentityProperties {
|
|
|
14
14
|
teamAgentId?: string;
|
|
15
15
|
}
|
|
16
16
|
export declare const CORE_TELEMETRY_EVENTS: {
|
|
17
|
+
readonly SCHEDULE: {
|
|
18
|
+
readonly RUN_STARTED: "schedule.run_started";
|
|
19
|
+
readonly RUN_FINISHED: "schedule.run_finished";
|
|
20
|
+
};
|
|
17
21
|
readonly CLIENT: {
|
|
18
22
|
readonly EXTENSION_ACTIVATED: "user.extension_activated";
|
|
19
23
|
};
|
|
20
24
|
readonly SESSION: {
|
|
21
25
|
readonly STARTED: "session.started";
|
|
22
26
|
readonly ENDED: "session.ended";
|
|
27
|
+
readonly ERROR_RECORDED: "session.error_recorded";
|
|
23
28
|
};
|
|
24
29
|
readonly AGENT: {
|
|
25
30
|
readonly UNEXPECTED_REASONING_TOKENS: "agent.reasoning.unexpected_tokens";
|
|
@@ -38,6 +43,7 @@ export declare const CORE_TELEMETRY_EVENTS: {
|
|
|
38
43
|
readonly CREATED: "task.created";
|
|
39
44
|
readonly RESTARTED: "task.restarted";
|
|
40
45
|
readonly COMPLETED: "task.completed";
|
|
46
|
+
readonly GIT_SNAPSHOT: "task.git_snapshot";
|
|
41
47
|
readonly CONVERSATION_TURN: "task.conversation_turn";
|
|
42
48
|
readonly TOKEN_USAGE: "task.tokens";
|
|
43
49
|
readonly MODE_SWITCH: "task.mode";
|
|
@@ -50,6 +56,7 @@ export declare const CORE_TELEMETRY_EVENTS: {
|
|
|
50
56
|
readonly PROVIDER_STREAM_STARTED: "task.provider_stream_started";
|
|
51
57
|
readonly FIRST_CHUNK_RECEIVED: "task.first_chunk_received";
|
|
52
58
|
readonly PROVIDER_STREAM_FAILED: "task.provider_stream_failed";
|
|
59
|
+
readonly MAX_TOKENS_RECOVERY: "task.max_tokens_recovery";
|
|
53
60
|
readonly CANCELLED: "task.cancelled";
|
|
54
61
|
readonly MENTION_USED: "task.mention_used";
|
|
55
62
|
readonly MENTION_FAILED: "task.mention_failed";
|
|
@@ -64,6 +71,7 @@ export declare const CORE_TELEMETRY_EVENTS: {
|
|
|
64
71
|
};
|
|
65
72
|
readonly HOOKS: {
|
|
66
73
|
readonly DISCOVERY_COMPLETED: "hooks.discovery_completed";
|
|
74
|
+
readonly DETACHED_RUNTIME: "hooks.detached_runtime";
|
|
67
75
|
};
|
|
68
76
|
readonly WORKSPACE: {
|
|
69
77
|
readonly INITIALIZED: "workspace.initialized";
|
|
@@ -96,6 +104,46 @@ export interface RunCommandsTimeoutTelemetryProperties {
|
|
|
96
104
|
tool_call_id?: string;
|
|
97
105
|
}
|
|
98
106
|
export { captureAgentUnexpectedReasoningTokens, captureTaskLifecycleEvent, type CaptureAgentUnexpectedReasoningTokensInput, type CaptureTaskLifecycleEventInput, };
|
|
107
|
+
export interface GitSnapshotProperties {
|
|
108
|
+
schema_version: 1;
|
|
109
|
+
/** Actual Core session ID; ulid duplicates it for existing export consumers. */
|
|
110
|
+
sessionId: string;
|
|
111
|
+
ulid: string;
|
|
112
|
+
providerId: string;
|
|
113
|
+
workspace_id: string;
|
|
114
|
+
/** VS Code workspace-folder count at observation start, not Git repo count; 0 with no folders, even outside Git. */
|
|
115
|
+
workspace_root_count: number;
|
|
116
|
+
observation_window_id: string;
|
|
117
|
+
observation_sequence: number;
|
|
118
|
+
/** ISO observation-start time, after the model response. Git reads are not atomic. */
|
|
119
|
+
observed_at: string;
|
|
120
|
+
/** Background observation triggered by this response; tools may execute during the read. */
|
|
121
|
+
boundary: "model_call";
|
|
122
|
+
runId?: string;
|
|
123
|
+
iteration?: number;
|
|
124
|
+
agentId?: string;
|
|
125
|
+
/** Surfaced response's backend ID, when available; never synthesized or inherited from an earlier request. */
|
|
126
|
+
request_id?: string;
|
|
127
|
+
request_id_status: "present" | "missing";
|
|
128
|
+
git: {
|
|
129
|
+
/** partial: status hit its timeout/output cap but separate reads recovered HEAD and/or branch. */
|
|
130
|
+
state: "ok" | "unborn" | "non_git" | "unavailable" | "partial";
|
|
131
|
+
head_sha?: string;
|
|
132
|
+
branch?: string;
|
|
133
|
+
/** Any staged/unstaged/untracked changes. All four flags are absent for partial/non_git/unavailable, not false. */
|
|
134
|
+
dirty?: boolean;
|
|
135
|
+
/** Index changes, including unmerged entries; does not imply commit readiness. */
|
|
136
|
+
staged?: boolean;
|
|
137
|
+
/** Worktree changes, including unmerged entries. */
|
|
138
|
+
unstaged?: boolean;
|
|
139
|
+
/** Non-ignored untracked files. */
|
|
140
|
+
untracked?: boolean;
|
|
141
|
+
remote_url?: string;
|
|
142
|
+
remote_state?: "ok" | "none" | "unsupported" | "unavailable";
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/** Ordinary telemetry: use a consent-aware service, never captureRequired. */
|
|
146
|
+
export declare function captureGitSnapshot(telemetry: ITelemetryService | undefined, properties: GitSnapshotProperties): void;
|
|
99
147
|
export interface WorkspaceInitializedProperties {
|
|
100
148
|
root_count: number;
|
|
101
149
|
vcs_types: ReadonlyArray<string>;
|
|
@@ -181,15 +229,23 @@ export declare function identifyAccount(telemetry: ITelemetryService | undefined
|
|
|
181
229
|
organizationName?: string;
|
|
182
230
|
memberId?: string;
|
|
183
231
|
}): void;
|
|
232
|
+
/**
|
|
233
|
+
* Restore anonymous process identity after an account signs out.
|
|
234
|
+
*
|
|
235
|
+
* Account properties are explicitly set to undefined so they replace values
|
|
236
|
+
* previously merged into a long-lived telemetry service. Implementations
|
|
237
|
+
* remove undefined attributes before export.
|
|
238
|
+
*/
|
|
239
|
+
export declare function clearAccountTelemetryIdentity(telemetry: ITelemetryService | undefined, anonymousDistinctId?: string): void;
|
|
184
240
|
export declare function captureTaskCreated(telemetry: ITelemetryService | undefined, properties: {
|
|
185
241
|
ulid: string;
|
|
186
|
-
|
|
187
|
-
|
|
242
|
+
provider?: string;
|
|
243
|
+
model?: string;
|
|
188
244
|
} & Partial<TelemetryAgentIdentityProperties>): void;
|
|
189
245
|
export declare function captureTaskRestarted(telemetry: ITelemetryService | undefined, properties: {
|
|
190
246
|
ulid: string;
|
|
191
|
-
|
|
192
|
-
|
|
247
|
+
provider?: string;
|
|
248
|
+
model?: string;
|
|
193
249
|
} & Partial<TelemetryAgentIdentityProperties>): void;
|
|
194
250
|
/**
|
|
195
251
|
* Distinguishes the trigger that produced a `task.completed` telemetry event.
|
|
@@ -206,7 +262,7 @@ export type TaskCompletedSource = "submit_and_exit" | "shutdown";
|
|
|
206
262
|
export declare function captureTaskCompleted(telemetry: ITelemetryService | undefined, properties: {
|
|
207
263
|
ulid: string;
|
|
208
264
|
provider?: string;
|
|
209
|
-
|
|
265
|
+
model?: string;
|
|
210
266
|
mode?: string;
|
|
211
267
|
durationMs?: number;
|
|
212
268
|
source?: TaskCompletedSource;
|
|
@@ -222,11 +278,14 @@ export declare function captureTokenUsage(telemetry: ITelemetryService | undefin
|
|
|
222
278
|
ulid: string;
|
|
223
279
|
/** Uncached input tokens only — disjoint from the cache buckets. */
|
|
224
280
|
tokensIn: number;
|
|
281
|
+
/** Non-reasoning output tokens only — reasoningTokenCount is disjoint from this. */
|
|
225
282
|
tokensOut: number;
|
|
226
283
|
cacheWriteTokens?: number;
|
|
227
284
|
cacheReadTokens?: number;
|
|
228
285
|
/** This request's cost delta, not a running total. */
|
|
229
286
|
totalCost?: number;
|
|
287
|
+
/** Reasoning/thinking tokens for this request, reported separately since they're no longer folded into tokensOut. */
|
|
288
|
+
reasoningTokenCount?: number;
|
|
230
289
|
provider?: string;
|
|
231
290
|
model: string;
|
|
232
291
|
} & Partial<TelemetryAgentIdentityProperties>): void;
|
|
@@ -316,6 +375,20 @@ export declare function captureSubagentExecution(telemetry: ITelemetryService |
|
|
|
316
375
|
errorMessage?: string;
|
|
317
376
|
type?: "agent" | "team";
|
|
318
377
|
} & Partial<TelemetryAgentIdentityProperties>): void;
|
|
378
|
+
/**
|
|
379
|
+
* Records how long a fire-and-forget hook ran. Detached hooks are never
|
|
380
|
+
* awaited, so their runtime is otherwise invisible — this is the evidence for
|
|
381
|
+
* whether any of them could safely be made blocking. `exited: false` marks a
|
|
382
|
+
* censored observation: the hook was still running when the observation
|
|
383
|
+
* window closed, so treat `durationMs` as a lower bound and count these
|
|
384
|
+
* separately rather than averaging them in.
|
|
385
|
+
*/
|
|
386
|
+
export declare function captureDetachedHookRuntime(telemetry: ITelemetryService | undefined, event: {
|
|
387
|
+
hookName: string;
|
|
388
|
+
durationMs: number;
|
|
389
|
+
exitCode: number | null;
|
|
390
|
+
exited: boolean;
|
|
391
|
+
}): void;
|
|
319
392
|
export declare function captureHookDiscovery(telemetry: ITelemetryService | undefined, hookName: string, globalCount: number, workspaceCount: number): void;
|
|
320
393
|
/**
|
|
321
394
|
* Identifies which compaction implementation produced a
|
|
@@ -394,3 +467,22 @@ export interface CaptureCompactionBudgetEmergencyProperties {
|
|
|
394
467
|
modelId?: string;
|
|
395
468
|
}
|
|
396
469
|
export declare function captureCompactionBudgetEmergency(telemetry: ITelemetryService | undefined, properties: CaptureCompactionBudgetEmergencyProperties & Partial<TelemetryAgentIdentityProperties>): void;
|
|
470
|
+
/** A terminal failure was recorded as a display-only transcript entry. */
|
|
471
|
+
export declare function captureSessionErrorRecorded(telemetry: ITelemetryService | undefined, details: {
|
|
472
|
+
sessionId?: string;
|
|
473
|
+
provider: string;
|
|
474
|
+
model: string;
|
|
475
|
+
source: "result" | "thrown";
|
|
476
|
+
}): void;
|
|
477
|
+
/** Bounded scheduler diagnostics; never include prompts, paths, or raw errors. */
|
|
478
|
+
export declare function captureScheduleRun(telemetry: ITelemetryService | undefined, input: {
|
|
479
|
+
triggerKind: "one_off" | "schedule" | "event" | "manual" | "retry";
|
|
480
|
+
attemptCount: number;
|
|
481
|
+
startDelayMs: number;
|
|
482
|
+
} & ({
|
|
483
|
+
phase: "started";
|
|
484
|
+
} | {
|
|
485
|
+
phase: "finished";
|
|
486
|
+
outcome: "success" | "failed" | "timeout" | "superseded" | "cancelled";
|
|
487
|
+
durationMs: number;
|
|
488
|
+
})): void;
|
|
@@ -2,3 +2,4 @@ export { resolveCoreDeviceId, resolveCoreDistinctId } from "./distinct-id";
|
|
|
2
2
|
export type { ITelemetryAdapter, TelemetryArray, TelemetryMetadata, TelemetryObject, TelemetryPrimitive, TelemetryProperties, TelemetryValue, } from "./ITelemetryAdapter";
|
|
3
3
|
export { OpenTelemetryAdapter, type OpenTelemetryAdapterOptions, } from "./OpenTelemetryAdapter";
|
|
4
4
|
export { type ConfiguredTelemetryHandle, type CreateOpenTelemetryTelemetryServiceOptions, createConfiguredTelemetryHandle, createConfiguredTelemetryService, createOpenTelemetryTelemetryService, OpenTelemetryProvider, type OpenTelemetryProviderOptions, } from "./OpenTelemetryProvider";
|
|
5
|
+
export { type ClientTelemetryContext, createClientScopedTelemetryService, createScopedTelemetryService, resolveClientTelemetryProperties, } from "./scoped-telemetry";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{existsSync as N,mkdirSync as G,readFileSync as v,writeFileSync as u}from"node:fs";import{resolve as b}from"node:path";import{resolveSessionDataDir as S}from"@cerebriline/shared/storage";import{nanoid as g}from"nanoid";import*as c from"node-machine-id";var m="machine-id",C,w=!1;function B(){if(!w)C=h(),w=!0;return C??q()}function X(f){let P=f?.trim();if(P)return P;let A=h();if(A)return A;return q()}function d(){let f=c;return f.machineIdSync??f.default?.machineIdSync}function h(){try{let f=d();if(!f)return;return f().trim()||void 0}catch{return}}function q(){let f=S(),P=b(f,m);try{if(N(P)){let O=v(P,"utf8").trim();if(O.length>0)return O}}catch{}let A=`cl-${g()}`;try{G(f,{recursive:!0}),u(P,A,"utf8")}catch{}return A}class Y{name;metadata;meter;logger;enabled;distinctId;commonProperties;counters=new Map;histograms=new Map;gauges=new Map;gaugeValues=new Map;meterProvider;loggerProvider;constructor(f){this.name=f.name??"OpenTelemetryAdapter",this.metadata={...f.metadata},this.meterProvider=f.meterProvider,this.loggerProvider=f.loggerProvider,this.meter=f.meterProvider?.getMeter("cline")??null,this.logger=f.loggerProvider?.getLogger("cline")??null,this.enabled=f.enabled??!0,this.distinctId=f.distinctId,this.commonProperties=f.commonProperties?{...f.commonProperties}:{}}emit(f,P){if(!this.isEnabled())return;this.emitLog(f,P,!1)}emitRequired(f,P){this.emitLog(f,P,!0)}recordCounter(f,P,A,O,j=!1){if(!this.meter||!j&&!this.isEnabled())return;let H=this.counters.get(f);if(!H)H=this.meter.createCounter(f,O?{description:O}:void 0),this.counters.set(f,H);H.add(P,this.flattenProperties(this.buildAttributes(A)))}recordHistogram(f,P,A,O,j=!1){if(!this.meter||!j&&!this.isEnabled())return;let H=this.histograms.get(f);if(!H)H=this.meter.createHistogram(f,O?{description:O}:void 0),this.histograms.set(f,H);H.record(P,this.flattenProperties(this.buildAttributes(A)))}recordGauge(f,P,A,O,j=!1){if(!this.meter||!j&&!this.isEnabled())return;let H=this.buildAttributes(A),J=JSON.stringify(H),K=this.gaugeValues.get(f);if(P===null){if(K){if(K.delete(J),K.size===0)this.gaugeValues.delete(f),this.gauges.delete(f)}return}let T=K;if(!T)T=new Map,this.gaugeValues.set(f,T);if(!this.gauges.has(f)){let W=this.meter.createObservableGauge(f,O?{description:O}:void 0);W.addCallback((R)=>{for(let M of this.snapshotGaugeSeries(f))R.observe(M.value,this.flattenProperties(M.attributes))}),this.gauges.set(f,W)}T.set(J,{value:P,attributes:H})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}setDistinctId(f){this.distinctId=f}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}async flush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.()])}emitLog(f,P,A){if(!this.logger)return;let O=this.flattenProperties(this.buildAttributes(P,A));this.logger.emit({severityText:"INFO",body:f,attributes:O})}buildAttributes(f,P=!1){return{...this.commonProperties,...this.metadata,...f,...this.distinctId?{distinct_id:this.distinctId}:{},...P?{_required:!0}:{}}}snapshotGaugeSeries(f){let P=this.gaugeValues.get(f);if(!P)return[];return Array.from(P.values(),(A)=>({value:A.value,attributes:A.attributes?{...A.attributes}:void 0}))}flattenProperties(f,P="",A=new WeakSet,O=0){if(!f)return{};let j={},H=100,J=10;for(let[K,T]of Object.entries(f)){if(K==="__proto__"||K==="constructor"||K==="prototype")continue;let W=P?`${P}.${K}`:K;if(T===null||T===void 0){j[W]=String(T);continue}if(Array.isArray(T)){let R=T.length>H?T.slice(0,H):T;try{j[W]=JSON.stringify(R)}catch{j[W]="[UnserializableArray]"}if(T.length>H)j[`${W}_truncated`]=!0,j[`${W}_original_length`]=T.length;continue}if(typeof T==="object"){if(T instanceof Date){j[W]=T.toISOString();continue}if(T instanceof Error){j[W]=T.message;continue}if(A.has(T)){j[W]="[Circular]";continue}if(O>=J){j[W]="[MaxDepthExceeded]";continue}A.add(T),Object.assign(j,this.flattenProperties(T,W,A,O+1));continue}if(r(T)){j[W]=T;continue}try{j[W]=JSON.stringify(T)}catch{j[W]=String(T)}}return j}}function r(f){return typeof f==="string"||typeof f==="number"||typeof f==="boolean"}import{metrics as Of,trace as jf}from"@opentelemetry/api";import{logs as Hf}from"@opentelemetry/api-logs";import{OTLPLogExporter as Tf}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPMetricExporter as $f}from"@opentelemetry/exporter-metrics-otlp-http";import{OTLPTraceExporter as Jf}from"@opentelemetry/exporter-trace-otlp-http";import{resourceFromAttributes as Wf}from"@opentelemetry/resources";import{BatchLogRecordProcessor as Kf,ConsoleLogRecordExporter as Xf,LoggerProvider as Yf}from"@opentelemetry/sdk-logs";import{ConsoleMetricExporter as Zf,MeterProvider as Qf,PeriodicExportingMetricReader as y}from"@opentelemetry/sdk-metrics";import{BatchSpanProcessor as Rf,ConsoleSpanExporter as Bf,SimpleSpanProcessor as Ff}from"@opentelemetry/sdk-trace-base";import{NodeTracerProvider as Vf}from"@opentelemetry/sdk-trace-node";import{ATTR_SERVICE_NAME as Uf,ATTR_SERVICE_VERSION as _f}from"@opentelemetry/semantic-conventions";import{mkdirSync as rf,readFileSync as l,statSync as n,writeFileSync as lf}from"node:fs";import{CONFIGURABLE_MODEL_TOOL_NAMES as p}from"@cerebriline/shared";import{resolveGlobalSettingsPath as a}from"@cerebriline/shared/storage";import{z as $}from"zod";import{AGENT_UNEXPECTED_REASONING_TOKENS_EVENT as zf,captureAgentUnexpectedReasoningTokens as xf,captureTaskLifecycleEvent as Nf,SDK_ERROR_TELEMETRY_EVENT as Gf,TASK_CANCELLED_EVENT as vf,TASK_FIRST_CHUNK_RECEIVED_EVENT as uf,TASK_PROVIDER_REQUEST_STARTED_EVENT as bf,TASK_PROVIDER_STREAM_FAILED_EVENT as Sf,TASK_PROVIDER_STREAM_STARTED_EVENT as gf}from"@cerebriline/shared";var F=$.preprocess((f)=>Array.isArray(f)?f.filter((P)=>typeof P==="string").map((P)=>P.trim()).filter(Boolean):void 0,$.array($.string()).optional()).transform((f)=>{if(!f)return;let P=[...new Set(f)].sort((A,O)=>A.localeCompare(O));return P.length>0?P:void 0}),i=$.enum(["basic","agentic"]).catch("agentic"),s=$.partialRecord($.enum(p),$.object({enabled:$.boolean()}).strip()).optional(),o=$.record($.string(),$.object({enabled:$.boolean()}).strip()).optional().catch(void 0),t=$.enum(["plan","act"]),E=$.object({telemetryOptOut:$.boolean().default(!1).catch(!1),autoUpdateEnabled:$.boolean().default(!0).catch(!0),compactionStrategy:i.optional(),compactionEnabled:$.boolean().optional().catch(void 0),planActMode:t.optional().catch(void 0),toolAutoApprove:$.boolean().optional().catch(void 0),tuiTheme:$.string().optional().catch(void 0),disabledTools:F.optional(),tools:s,disabledPlugins:F.optional(),disabledAgentPlugins:F.optional(),bundledSkills:o}).strip().transform((f)=>{let P={autoUpdateEnabled:f.autoUpdateEnabled,telemetryOptOut:f.telemetryOptOut};if(f.compactionStrategy)P.compactionStrategy=f.compactionStrategy;if(f.compactionEnabled!==void 0)P.compactionEnabled=f.compactionEnabled;if(f.planActMode)P.planActMode=f.planActMode;if(f.toolAutoApprove!==void 0)P.toolAutoApprove=f.toolAutoApprove;if(f.tuiTheme?.trim())P.tuiTheme=f.tuiTheme.trim();if(f.disabledTools?.length)P.disabledTools=f.disabledTools;if(f.tools&&Object.keys(f.tools).length>0)P.tools=f.tools;if(f.disabledPlugins?.length)P.disabledPlugins=f.disabledPlugins;if(f.disabledAgentPlugins?.length)P.disabledAgentPlugins=f.disabledAgentPlugins;if(f.bundledSkills&&Object.keys(f.bundledSkills).length>0)P.bundledSkills=f.bundledSkills;return P});function Z(){return E.parse({})}var V;function e(f){if(f.disabledTools)Object.freeze(f.disabledTools);if(f.tools){for(let P of Object.values(f.tools))Object.freeze(P);Object.freeze(f.tools)}if(f.disabledPlugins)Object.freeze(f.disabledPlugins);if(f.disabledAgentPlugins)Object.freeze(f.disabledAgentPlugins);return Object.freeze(f)}function ff(f){let P;try{P=l(f,"utf8")}catch{return Z()}try{let A=E.safeParse(JSON.parse(P));return A.success?A.data:Z()}catch{return Z()}}function Pf(){let f=a(),P=n(f,{throwIfNoEntry:!1}),A=P?.mtimeMs??0,O=P?.size??0,j=V;if(j&&j.path===f&&j.mtimeMs===A&&j.size===O)return j;let H=e(P?ff(f):Z());return V={path:f,mtimeMs:A,size:O,value:H},V}function Af(){return Pf().value}function I(){return Af().telemetryOptOut}class U{name;logger;enabled;constructor(f={}){this.name=f.name??"TelemetryLoggerSink",this.logger=f.logger,this.enabled=f.enabled??!0}emit(f,P){if(!this.isEnabled())return;this.logger?.log("telemetry.event",{telemetrySink:this.name,event:f,properties:P})}emitRequired(f,P){this.logger?.log("telemetry.required_event",{telemetrySink:this.name,severity:"warn",event:f,properties:P})}recordCounter(f,P,A,O,j){if(!j&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"counter",name:f,value:P,attributes:A,description:O,required:j===!0})}recordHistogram(f,P,A,O,j){if(!j&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"histogram",name:f,value:P,attributes:A,description:O,required:j===!0})}recordGauge(f,P,A,O,j){if(!j&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"gauge",name:f,value:P,attributes:A,description:O,required:j===!0})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}async flush(){}async dispose(){}}class Q{adapters;metadata;distinctId;deviceId;commonProperties;constructor(f={}){if(this.adapters=[...f.adapters??[]],f.logger)this.adapters.push(new U({logger:f.logger}));this.metadata={...f.metadata??{}},this.distinctId=f.distinctId,this.deviceId=f.deviceId??B(),this.commonProperties={...f.commonProperties??{}}}addAdapter(f){this.adapters.push(f)}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return this.adapters.some((f)=>f.isEnabled())}capture(f){let P=this.buildAttributes(f.properties);for(let A of this.adapters)A.emit(f.event,P)}captureRequired(f,P){let A=this.buildAttributes(P);for(let O of this.adapters)O.emitRequired(f,A)}recordCounter(f,P,A,O,j=!1){let H=this.buildAttributes(A);for(let J of this.adapters)J.recordCounter(f,P,H,O,j)}recordHistogram(f,P,A,O,j=!1){let H=this.buildAttributes(A);for(let J of this.adapters)J.recordHistogram(f,P,H,O,j)}recordGauge(f,P,A,O,j=!1){let H=this.buildAttributes(A);for(let J of this.adapters)J.recordGauge(f,P,H,O,j)}async flush(){await Promise.all(this.adapters.map((f)=>f.flush()))}async dispose(){await Promise.all(this.adapters.map((f)=>f.dispose()))}buildAttributes(f){return{...this.commonProperties,...f,...this.metadata,...this.distinctId?{distinct_id:this.distinctId}:{},device_id:this.deviceId}}}class D{distinctId;metadata;commonProperties;constructor(f={}){this.distinctId=f.distinctId,this.metadata={...f.metadata??{}},this.commonProperties={...f.commonProperties??{}}}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return!1}capture(f){this.resolveProperties(f.properties)}captureRequired(f,P){this.resolveProperties(P)}recordCounter(){}recordHistogram(){}recordGauge(){}async flush(){}async dispose(){}resolveProperties(f){return{...this.commonProperties,...f,...this.metadata,...this.distinctId?{distinct_id:this.distinctId}:{}}}}class L{meterProvider;loggerProvider;tracerProvider;options;constructor(f={}){this.options=f;let P=Wf({[Uf]:f.serviceName??"cline",...f.serviceVersion?{[_f]:f.serviceVersion}:{}});if(this.meterProvider=this.createMeterProvider(P),this.loggerProvider=this.createLoggerProvider(P),this.tracerProvider=this.createTracerProvider(P),this.meterProvider)Of.setGlobalMeterProvider(this.meterProvider);if(this.loggerProvider)Hf.setGlobalLoggerProvider(this.loggerProvider);if(this.tracerProvider)this.tracerProvider.register()}getTracer(f="cline",P){return jf.getTracer(f,P??this.options.serviceVersion)}createAdapter(f){return new Y({...f,meterProvider:this.meterProvider,loggerProvider:this.loggerProvider})}createTelemetryService(f){let P=this.createAdapter({name:f.name,enabled:this.options.enabled,metadata:f.metadata});return new Q({...f,adapters:[P],distinctId:X(f.distinctId)})}async forceFlush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.(),this.tracerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.(),this.tracerProvider?.shutdown?.()])}createMeterProvider(f){let P=_(this.options.metricsExporter);if(P.length===0)return null;let A=Math.max(1000,this.options.metricExportIntervalMs??this.options.metricExportInterval??60000),O=Math.min(30000,Math.floor(A*0.8)),j=P.map((H)=>Cf(H,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json",interval:A,timeout:O})).filter((H)=>H!==null);if(j.length===0)return null;return new Qf({resource:f,readers:j})}createTracerProvider(f){let P=_(this.options.tracesExporter);if(P.length===0)return null;let A=this.options.otlpTracesEndpoint??this.options.otlpEndpoint,O=this.options.otlpTracesHeaders??this.options.otlpHeaders,j=[];for(let H of P){let J=Mf(H,{endpoint:A,headers:O,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(J)j.push(J)}if(j.length===0)return null;return new Vf({resource:f,spanProcessors:j})}createLoggerProvider(f){let P=_(this.options.logsExporter);if(P.length===0)return null;let A=P.map((O)=>{let j=kf(O,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(!j)return null;return new Kf(j,{maxQueueSize:this.options.logMaxQueueSize??2048,maxExportBatchSize:this.options.logBatchSize??512,scheduledDelayMillis:this.options.logBatchTimeoutMs??this.options.logBatchTimeout??5000})}).filter((O)=>O!==null);if(A.length===0)return null;return new Yf({resource:f,processors:A})}}function z(f){let P=new L(f),A=P.createTelemetryService(f),O=()=>{A.captureRequired("telemetry.provider_created",{provider:"opentelemetry",enabled:f.enabled??!0,logsExporter:Array.isArray(f.logsExporter)?f.logsExporter.join(","):f.logsExporter,metricsExporter:Array.isArray(f.metricsExporter)?f.metricsExporter.join(","):f.metricsExporter,tracesExporter:Array.isArray(f.tracesExporter)?f.tracesExporter.join(","):f.tracesExporter,otlpProtocol:f.otlpProtocol,hasOtlpEndpoint:Boolean(f.otlpEndpoint),serviceName:f.serviceName,serviceVersion:f.serviceVersion})};if(!f.deferProviderCreatedEvent)O();return{provider:P,telemetry:A,emitProviderCreated:O}}function x(f){if(I())return{telemetry:new D(f)};if(f.enabled!==!0)return{telemetry:new Q({...f,distinctId:X(f.distinctId)})};return z(f)}function Lf(f){let{telemetry:P,provider:A,emitProviderCreated:O}=x(f);return{telemetry:P,provider:A,flush:async()=>{let J=A;if(J&&typeof J.forceFlush==="function")try{await J.forceFlush()}catch{}},dispose:async()=>{await Promise.allSettled([P.dispose(),A?.dispose()])},...f.deferProviderCreatedEvent&&O?{emitProviderCreated:O}:{}}}function _(f){if(!f)return[];return(Array.isArray(f)?f:f.split(",")).map((A)=>A.trim()).filter((A)=>A==="console"||A==="otlp")}function kf(f,P){if(f==="console")return new Xf;if(!P.endpoint)return null;let A=k(P.endpoint,"/v1/logs");return new Tf({url:A,headers:P.headers})}function Mf(f,P){if(f==="console")return new Ff(new Bf);if(!P.endpoint)return null;let A=k(P.endpoint,"/v1/traces");return new Rf(new Jf({url:A,headers:P.headers}))}function Cf(f,P){if(f==="console")return new y({exporter:new Zf,exportIntervalMillis:P.interval,exportTimeoutMillis:P.timeout});if(!P.endpoint)return null;let A=k(P.endpoint,"/v1/metrics");return new y({exporter:new $f({url:A,headers:P.headers}),exportIntervalMillis:P.interval,exportTimeoutMillis:P.timeout})}function k(f,P){let A=new URL(f),O=A.pathname.endsWith("/")?A.pathname.slice(0,-1):A.pathname;return A.pathname=O.endsWith(P)?O:`${O}${P}`,A.toString()}export{X as resolveCoreDistinctId,B as resolveCoreDeviceId,z as createOpenTelemetryTelemetryService,x as createConfiguredTelemetryService,Lf as createConfiguredTelemetryHandle,L as OpenTelemetryProvider,Y as OpenTelemetryAdapter};
|
|
1
|
+
import{existsSync as g,mkdirSync as u,readFileSync as c,writeFileSync as m}from"node:fs";import{resolve as d}from"node:path";import{resolveSessionDataDir as l}from"@cerebriline/shared/storage";import{nanoid as p}from"nanoid";import*as r from"node-machine-id";var a="machine-id",q,h=!1;function R(){if(!h)q=E(),h=!0;return q??z()}function Y(f){let j=f?.trim();if(j)return j;let $=E();if($)return $;return z()}function n(){let f=r;return f.machineIdSync??f.default?.machineIdSync}function E(){try{let f=n();if(!f)return;return f().trim()||void 0}catch{return}}function z(){let f=l(),j=d(f,a);try{if(g(j)){let A=c(j,"utf8").trim();if(A.length>0)return A}}catch{}let $=`cl-${p()}`;try{u(f,{recursive:!0}),m(j,$,"utf8")}catch{}return $}class B{name;metadata;meter;logger;enabled;distinctId;commonProperties;counters=new Map;histograms=new Map;gauges=new Map;gaugeValues=new Map;meterProvider;loggerProvider;constructor(f){this.name=f.name??"OpenTelemetryAdapter",this.metadata={...f.metadata},this.meterProvider=f.meterProvider,this.loggerProvider=f.loggerProvider,this.meter=f.meterProvider?.getMeter("cline")??null,this.logger=f.loggerProvider?.getLogger("cline")??null,this.enabled=f.enabled??!0,this.distinctId=f.distinctId,this.commonProperties=f.commonProperties?{...f.commonProperties}:{}}emit(f,j){if(!this.isEnabled())return;this.emitLog(f,j,!1)}emitRequired(f,j){this.emitLog(f,j,!0)}recordCounter(f,j,$,A,J=!1){if(!this.meter||!J&&!this.isEnabled())return;let W=this.counters.get(f);if(!W)W=this.meter.createCounter(f,A?{description:A}:void 0),this.counters.set(f,W);W.add(j,this.flattenProperties(this.buildAttributes($)))}recordHistogram(f,j,$,A,J=!1){if(!this.meter||!J&&!this.isEnabled())return;let W=this.histograms.get(f);if(!W)W=this.meter.createHistogram(f,A?{description:A}:void 0),this.histograms.set(f,W);W.record(j,this.flattenProperties(this.buildAttributes($)))}recordGauge(f,j,$,A,J=!1){if(!this.meter||!J&&!this.isEnabled())return;let W=this.buildAttributes($),H=JSON.stringify(W),X=this.gaugeValues.get(f);if(j===null){if(X){if(X.delete(H),X.size===0)this.gaugeValues.delete(f),this.gauges.delete(f)}return}let O=X;if(!O)O=new Map,this.gaugeValues.set(f,O);if(!this.gauges.has(f)){let Z=this.meter.createObservableGauge(f,A?{description:A}:void 0);Z.addCallback((Q)=>{for(let w of this.snapshotGaugeSeries(f))Q.observe(w.value,this.flattenProperties(w.attributes))}),this.gauges.set(f,Z)}O.set(H,{value:j,attributes:W})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}setDistinctId(f){this.distinctId=f}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}async flush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.()])}emitLog(f,j,$){if(!this.logger)return;let A=this.flattenProperties(this.buildAttributes(j,$));this.logger.emit({severityText:"INFO",body:f,attributes:A})}buildAttributes(f,j=!1){return{...this.commonProperties,...this.metadata,...f,...this.distinctId?{distinct_id:this.distinctId}:{},...j?{_required:!0}:{}}}snapshotGaugeSeries(f){let j=this.gaugeValues.get(f);if(!j)return[];return Array.from(j.values(),($)=>({value:$.value,attributes:$.attributes?{...$.attributes}:void 0}))}flattenProperties(f,j="",$=new WeakSet,A=0){if(!f)return{};let J={},W=100,H=10;for(let[X,O]of Object.entries(f)){if(X==="__proto__"||X==="constructor"||X==="prototype")continue;let Z=j?`${j}.${X}`:X;if(O===null||O===void 0){J[Z]=String(O);continue}if(Array.isArray(O)){let Q=O.length>W?O.slice(0,W):O;try{J[Z]=JSON.stringify(Q)}catch{J[Z]="[UnserializableArray]"}if(O.length>W)J[`${Z}_truncated`]=!0,J[`${Z}_original_length`]=O.length;continue}if(typeof O==="object"){if(O instanceof Date){J[Z]=O.toISOString();continue}if(O instanceof Error){J[Z]=O.message;continue}if($.has(O)){J[Z]="[Circular]";continue}if(A>=H){J[Z]="[MaxDepthExceeded]";continue}$.add(O),Object.assign(J,this.flattenProperties(O,Z,$,A+1));continue}if(s(O)){J[Z]=O;continue}try{J[Z]=JSON.stringify(O)}catch{J[Z]=String(O)}}return J}}function s(f){return typeof f==="string"||typeof f==="number"||typeof f==="boolean"}import{LangfuseAttributesSpanProcessor as Xf}from"@cerebriline/llms";import{markOtlpTraceRelayProvider as Zf}from"@cerebriline/shared";import{metrics as Kf,trace as Pf}from"@opentelemetry/api";import{logs as Qf}from"@opentelemetry/api-logs";import{OTLPLogExporter as Tf}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPMetricExporter as Yf}from"@opentelemetry/exporter-metrics-otlp-http";import{OTLPTraceExporter as Bf}from"@opentelemetry/exporter-trace-otlp-http";import{resourceFromAttributes as Ff}from"@opentelemetry/resources";import{BatchLogRecordProcessor as Vf,ConsoleLogRecordExporter as Rf,LoggerProvider as Uf}from"@opentelemetry/sdk-logs";import{ConsoleMetricExporter as Lf,MeterProvider as kf,PeriodicExportingMetricReader as G}from"@opentelemetry/sdk-metrics";import{BatchSpanProcessor as Cf,ConsoleSpanExporter as _f,SimpleSpanProcessor as Mf}from"@opentelemetry/sdk-trace-base";import{NodeTracerProvider as wf}from"@opentelemetry/sdk-trace-node";import{ATTR_SERVICE_NAME as qf,ATTR_SERVICE_VERSION as hf}from"@opentelemetry/semantic-conventions";import{mkdirSync as f0,readFileSync as i,statSync as o,writeFileSync as j0}from"node:fs";import{CONFIGURABLE_MODEL_TOOL_NAMES as t}from"@cerebriline/shared";import{resolveGlobalSettingsPath as e}from"@cerebriline/shared/storage";import{z as K}from"zod";import{AGENT_UNEXPECTED_REASONING_TOKENS_EVENT as uf,captureAgentUnexpectedReasoningTokens as cf,captureTaskLifecycleEvent as mf,SDK_ERROR_TELEMETRY_EVENT as df,TASK_CANCELLED_EVENT as lf,TASK_FIRST_CHUNK_RECEIVED_EVENT as pf,TASK_MAX_TOKENS_RECOVERY_EVENT as rf,TASK_PROVIDER_REQUEST_STARTED_EVENT as af,TASK_PROVIDER_STREAM_FAILED_EVENT as nf,TASK_PROVIDER_STREAM_STARTED_EVENT as sf}from"@cerebriline/shared";var U=K.preprocess((f)=>Array.isArray(f)?f.filter((j)=>typeof j==="string").map((j)=>j.trim()).filter(Boolean):void 0,K.array(K.string()).optional()).transform((f)=>{if(!f)return;let j=[...new Set(f)].sort(($,A)=>$.localeCompare(A));return j.length>0?j:void 0}),ff=K.enum(["basic","agentic"]).catch("agentic"),jf=K.partialRecord(K.enum(t),K.object({enabled:K.boolean()}).strip()).optional(),$f=K.record(K.string(),K.object({enabled:K.boolean()}).strip()).optional().catch(void 0),Af=K.enum(["plan","act"]),D=K.object({telemetryOptOut:K.boolean().default(!1).catch(!1),autoUpdateEnabled:K.boolean().default(!0).catch(!0),compactionStrategy:ff.optional(),compactionEnabled:K.boolean().optional().catch(void 0),planActMode:Af.optional().catch(void 0),toolAutoApprove:K.boolean().optional().catch(void 0),tuiTheme:K.string().optional().catch(void 0),disabledTools:U.optional(),tools:jf,disabledPlugins:U.optional(),disabledAgentPlugins:U.optional(),bundledSkills:$f}).strip().transform((f)=>{let j={autoUpdateEnabled:f.autoUpdateEnabled,telemetryOptOut:f.telemetryOptOut};if(f.compactionStrategy)j.compactionStrategy=f.compactionStrategy;if(f.compactionEnabled!==void 0)j.compactionEnabled=f.compactionEnabled;if(f.planActMode)j.planActMode=f.planActMode;if(f.toolAutoApprove!==void 0)j.toolAutoApprove=f.toolAutoApprove;if(f.tuiTheme?.trim())j.tuiTheme=f.tuiTheme.trim();if(f.disabledTools?.length)j.disabledTools=f.disabledTools;if(f.tools&&Object.keys(f.tools).length>0)j.tools=f.tools;if(f.disabledPlugins?.length)j.disabledPlugins=f.disabledPlugins;if(f.disabledAgentPlugins?.length)j.disabledAgentPlugins=f.disabledAgentPlugins;if(f.bundledSkills&&Object.keys(f.bundledSkills).length>0)j.bundledSkills=f.bundledSkills;return j});function F(){return D.parse({})}var L;function Jf(f){if(f.disabledTools)Object.freeze(f.disabledTools);if(f.tools){for(let j of Object.values(f.tools))Object.freeze(j);Object.freeze(f.tools)}if(f.disabledPlugins)Object.freeze(f.disabledPlugins);if(f.disabledAgentPlugins)Object.freeze(f.disabledAgentPlugins);return Object.freeze(f)}function Hf(f){let j;try{j=i(f,"utf8")}catch{return{value:F(),loadFailed:!0}}try{let $=D.safeParse(JSON.parse(j));return $.success?{value:$.data,loadFailed:!1}:{value:F(),loadFailed:!0}}catch{return{value:F(),loadFailed:!0}}}function Wf(){let f=e(),j=o(f,{throwIfNoEntry:!1}),$=j?.mtimeMs??0,A=j?.size??0,J=L;if(J&&J.path===f&&J.mtimeMs===$&&J.size===A)return J;let W=j?Hf(f):{value:F(),loadFailed:!1},H=Jf(W.value);return L={path:f,mtimeMs:$,size:A,value:H,loadFailed:W.loadFailed},L}function Of(){return Wf().value}function I(){return Of().telemetryOptOut}class k{name;logger;enabled;constructor(f={}){this.name=f.name??"TelemetryLoggerSink",this.logger=f.logger,this.enabled=f.enabled??!0}emit(f,j){if(!this.isEnabled())return;this.logger?.log("telemetry.event",{telemetrySink:this.name,event:f,properties:j})}emitRequired(f,j){this.logger?.log("telemetry.required_event",{telemetrySink:this.name,severity:"warn",event:f,properties:j})}recordCounter(f,j,$,A,J){if(!J&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"counter",name:f,value:j,attributes:$,description:A,required:J===!0})}recordHistogram(f,j,$,A,J){if(!J&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"histogram",name:f,value:j,attributes:$,description:A,required:J===!0})}recordGauge(f,j,$,A,J){if(!J&&!this.isEnabled())return;this.logger?.debug("telemetry.metric",{telemetrySink:this.name,instrument:"gauge",name:f,value:j,attributes:$,description:A,required:J===!0})}isEnabled(){return typeof this.enabled==="function"?this.enabled():this.enabled}async flush(){}async dispose(){}}class V{adapters;metadata;distinctId;deviceId;commonProperties;constructor(f={}){if(this.adapters=[...f.adapters??[]],f.logger)this.adapters.push(new k({logger:f.logger}));this.metadata={...f.metadata??{}},this.distinctId=f.distinctId,this.deviceId=f.deviceId??R(),this.commonProperties={...f.commonProperties??{}}}addAdapter(f){this.adapters.push(f)}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return this.adapters.some((f)=>f.isEnabled())}capture(f){let j=this.buildAttributes(f.properties);for(let $ of this.adapters)$.emit(f.event,j)}captureRequired(f,j){let $=this.buildAttributes(j);for(let A of this.adapters)A.emitRequired(f,$)}recordCounter(f,j,$,A,J=!1){let W=this.buildAttributes($);for(let H of this.adapters)H.recordCounter(f,j,W,A,J)}recordHistogram(f,j,$,A,J=!1){let W=this.buildAttributes($);for(let H of this.adapters)H.recordHistogram(f,j,W,A,J)}recordGauge(f,j,$,A,J=!1){let W=this.buildAttributes($);for(let H of this.adapters)H.recordGauge(f,j,W,A,J)}async flush(){await Promise.all(this.adapters.map((f)=>f.flush()))}async dispose(){await Promise.all(this.adapters.map((f)=>f.dispose()))}buildAttributes(f){let j=typeof f?.distinct_id==="string"&&f.distinct_id.trim()?f.distinct_id.trim():this.distinctId,$={...this.commonProperties,...this.metadata,...f,...j?{distinct_id:j}:{},device_id:this.deviceId};return Object.fromEntries(Object.entries($).filter(([,A])=>A!==void 0))}}class x{distinctId;metadata;commonProperties;constructor(f={}){this.distinctId=f.distinctId,this.metadata={...f.metadata??{}},this.commonProperties={...f.commonProperties??{}}}setDistinctId(f){this.distinctId=f}setMetadata(f){this.metadata={...f}}updateMetadata(f){this.metadata={...this.metadata,...f}}setCommonProperties(f){this.commonProperties={...f}}updateCommonProperties(f){this.commonProperties={...this.commonProperties,...f}}isEnabled(){return!1}capture(f){this.resolveProperties(f.properties)}captureRequired(f,j){this.resolveProperties(j)}recordCounter(){}recordHistogram(){}recordGauge(){}async flush(){}async dispose(){}resolveProperties(f){let j=typeof f?.distinct_id==="string"&&f.distinct_id.trim()?f.distinct_id.trim():this.distinctId,$={...this.commonProperties,...this.metadata,...f,...j?{distinct_id:j}:{}};return Object.fromEntries(Object.entries($).filter(([,A])=>A!==void 0))}}class _{meterProvider;loggerProvider;tracerProvider;options;constructor(f={}){this.options=f;let j=Ff({[qf]:f.serviceName??"cline",...f.serviceVersion?{[hf]:f.serviceVersion}:{}});if(this.meterProvider=this.createMeterProvider(j),this.loggerProvider=this.createLoggerProvider(j),this.tracerProvider=this.createTracerProvider(j),this.meterProvider)Kf.setGlobalMeterProvider(this.meterProvider);if(this.loggerProvider)Qf.setGlobalLoggerProvider(this.loggerProvider);if(this.tracerProvider)this.tracerProvider.register()}getTracer(f="cline",j){return Pf.getTracer(f,j??this.options.serviceVersion)}createAdapter(f){return new B({...f,meterProvider:this.meterProvider,loggerProvider:this.loggerProvider})}createTelemetryService(f){let j=this.createAdapter({name:f.name,enabled:this.options.enabled,metadata:f.metadata});return new V({...f,adapters:[j],distinctId:Y(f.distinctId)})}async forceFlush(){await Promise.all([this.meterProvider?.forceFlush?.(),this.loggerProvider?.forceFlush?.(),this.tracerProvider?.forceFlush?.()])}async dispose(){await Promise.all([this.meterProvider?.shutdown?.(),this.loggerProvider?.shutdown?.(),this.tracerProvider?.shutdown?.()])}createMeterProvider(f){let j=C(this.options.metricsExporter);if(j.length===0)return null;let $=Math.max(1000,this.options.metricExportIntervalMs??this.options.metricExportInterval??60000),A=Math.min(30000,Math.floor($*0.8)),J=j.map((W)=>If(W,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json",interval:$,timeout:A})).filter((W)=>W!==null);if(J.length===0)return null;return new kf({resource:f,readers:J})}createTracerProvider(f){let j=C(this.options.tracesExporter);if(j.length===0)return null;let $=this.options.otlpTracesEndpoint??this.options.otlpEndpoint,A=this.options.otlpTracesHeaders??this.options.otlpHeaders,J=[],W=!1;for(let X of j){let O=Df(X,{endpoint:$,headers:A,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(O){if(J.push(O),X!=="console")W=!0}}if(J.length===0)return null;let H=new wf({resource:f,spanProcessors:W?[new Xf,...J]:J});if(W)Zf(H);return H}createLoggerProvider(f){let j=C(this.options.logsExporter);if(j.length===0)return null;let $=j.map((A)=>{let J=zf(A,{endpoint:this.options.otlpEndpoint,headers:this.options.otlpHeaders,insecure:this.options.otlpInsecure??!1,protocol:"http/json"});if(!J)return null;return new Vf(J,{maxQueueSize:this.options.logMaxQueueSize??2048,maxExportBatchSize:this.options.logBatchSize??512,scheduledDelayMillis:this.options.logBatchTimeoutMs??this.options.logBatchTimeout??5000})}).filter((A)=>A!==null);if($.length===0)return null;return new Uf({resource:f,processors:$})}}function N(f){let j=new _(f),$=j.createTelemetryService(f),A=()=>{$.captureRequired("telemetry.provider_created",{provider:"opentelemetry",enabled:f.enabled??!0,logsExporter:Array.isArray(f.logsExporter)?f.logsExporter.join(","):f.logsExporter,metricsExporter:Array.isArray(f.metricsExporter)?f.metricsExporter.join(","):f.metricsExporter,tracesExporter:Array.isArray(f.tracesExporter)?f.tracesExporter.join(","):f.tracesExporter,otlpProtocol:f.otlpProtocol,hasOtlpEndpoint:Boolean(f.otlpEndpoint),serviceName:f.serviceName,serviceVersion:f.serviceVersion})};if(!f.deferProviderCreatedEvent)A();return{provider:j,telemetry:$,emitProviderCreated:A}}function y(f){if(I())return{telemetry:new x(f)};if(f.enabled!==!0)return{telemetry:new V({...f,distinctId:Y(f.distinctId)})};return N(f)}function Ef(f){let{telemetry:j,provider:$,emitProviderCreated:A}=y(f);return{telemetry:j,provider:$,flush:async()=>{let H=$;if(H&&typeof H.forceFlush==="function")try{await H.forceFlush()}catch{}},dispose:async()=>{await Promise.allSettled([j.dispose(),$?.dispose()])},...f.deferProviderCreatedEvent&&A?{emitProviderCreated:A}:{}}}function C(f){if(!f)return[];return(Array.isArray(f)?f:f.split(",")).map(($)=>$.trim()).filter(($)=>$==="console"||$==="otlp")}function zf(f,j){if(f==="console")return new Rf;if(!j.endpoint)return null;let $=M(j.endpoint,"/v1/logs");return new Tf({url:$,headers:j.headers})}function Df(f,j){if(f==="console")return new Mf(new _f);if(!j.endpoint)return null;let $=M(j.endpoint,"/v1/traces");return new Cf(new Bf({url:$,headers:j.headers}))}function If(f,j){if(f==="console")return new G({exporter:new Lf,exportIntervalMillis:j.interval,exportTimeoutMillis:j.timeout});if(!j.endpoint)return null;let $=M(j.endpoint,"/v1/metrics");return new G({exporter:new Yf({url:$,headers:j.headers}),exportIntervalMillis:j.interval,exportTimeoutMillis:j.timeout})}function M(f,j){let $=new URL(f),A=$.pathname.endsWith("/")?$.pathname.slice(0,-1):$.pathname;return $.pathname=A.endsWith(j)?A:`${A}${j}`,$.toString()}import{SESSION_STATUS_VALUES as D0}from"@cerebriline/shared";var T={CORE:"core",CLI:"cli",SUBAGENT:"subagent",DESKTOP:"desktop",KANBAN:"kanban",API:"api",WEB:"web",VSCODE:"vscode",ENTERPRISE:"enterprise",IDE:"ide",JETBRAINS:"jetbrains",NEOVIM:"neovim",UNKNOWN:"unknown"};function b(f){let j=[f?.name,f?.platform].filter(($)=>typeof $==="string").join(" ").toLowerCase();if(!j)return;if(j.includes("vscode")||j.includes("visual studio code"))return T.VSCODE;if(j.includes("jetbrains")||j.includes("webstorm")||j.includes("intellij")||j.includes("pycharm")||j.includes("goland")||j.includes("clion")||j.includes("rider")||j.includes("android studio"))return T.JETBRAINS;if(j.includes("neovim"))return T.NEOVIM;if(j.includes("kanban"))return T.KANBAN;if(j.includes("desktop"))return T.DESKTOP;if(j.includes("cline-platform"))return T.WEB;if(j.includes("cline-cli")||j.includes("cline-acp"))return T.CLI;if(j.includes("cline-sdk")||j.includes("cline-core"))return T.CORE;return}function P(f){let j=f?.trim();return j?j:void 0}function S(f){let j=f.client,$=b(j)??P(f.source),A=P(j.version),J=P(j.platform)??P(j.name),W=P(j.platformVersion)??A,H={cline_type:$,extension_version:A,platform:J,platform_version:W};if(f.user?.accountId===void 0)return H;let X=typeof f.user.accountId==="string"?P(f.user.accountId):void 0;return{...H,distinct_id:X??P(f.user.distinctId),user_id:X,account_id:X,account_email:X?P(f.user.email):void 0,organization_id:X?P(f.user.organizationId):void 0}}function v(f,j){let $={},A={},J,W=(H)=>({...j,...A,...$,...H,...J?{distinct_id:J}:{}});return{setDistinctId(H){J=P(H)},setMetadata(H){$={...H}},updateMetadata(H){$={...$,...H}},setCommonProperties(H){A={...H}},updateCommonProperties(H){A={...A,...H}},isEnabled:()=>f.isEnabled(),capture:(H)=>f.capture({event:H.event,properties:W(H.properties)}),captureRequired:(H,X)=>f.captureRequired(H,W(X)),recordCounter:(H,X,O,Z,Q)=>f.recordCounter(H,X,W(O),Z,Q),recordHistogram:(H,X,O,Z,Q)=>f.recordHistogram(H,X,W(O),Z,Q),recordGauge:(H,X,O,Z,Q)=>f.recordGauge(H,X,W(O),Z,Q),flush:()=>f.flush(),dispose:async()=>{}}}function Gf(f,j){return v(f,S(j))}export{Y as resolveCoreDistinctId,R as resolveCoreDeviceId,S as resolveClientTelemetryProperties,v as createScopedTelemetryService,N as createOpenTelemetryTelemetryService,y as createConfiguredTelemetryService,Ef as createConfiguredTelemetryHandle,Gf as createClientScopedTelemetryService,_ as OpenTelemetryProvider,B as OpenTelemetryAdapter};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ClientContext, ITelemetryService, TelemetryProperties, UserContext } from "@cerebriline/shared";
|
|
2
|
+
/**
|
|
3
|
+
* Client identity that can safely cross a runtime boundary and be attached to
|
|
4
|
+
* telemetry emitted by the process that actually executes a session.
|
|
5
|
+
*/
|
|
6
|
+
export interface ClientTelemetryContext {
|
|
7
|
+
client: ClientContext;
|
|
8
|
+
source?: string;
|
|
9
|
+
user?: UserContext;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Converts the shared client context into the established cross-surface
|
|
13
|
+
* analytics dimensions. Event-specific fields still take precedence.
|
|
14
|
+
*/
|
|
15
|
+
export declare function resolveClientTelemetryProperties(context: ClientTelemetryContext): TelemetryProperties;
|
|
16
|
+
/**
|
|
17
|
+
* A non-owning view over a host telemetry service. It adds immutable
|
|
18
|
+
* per-session properties without mutating the host singleton, which is
|
|
19
|
+
* essential for a Hub process that can execute sessions from several clients
|
|
20
|
+
* concurrently.
|
|
21
|
+
*
|
|
22
|
+
* The returned view never disposes the parent. The process that created the
|
|
23
|
+
* parent telemetry service remains responsible for its lifecycle.
|
|
24
|
+
*/
|
|
25
|
+
export declare function createScopedTelemetryService(parent: ITelemetryService, properties: TelemetryProperties): ITelemetryService;
|
|
26
|
+
/**
|
|
27
|
+
* Scopes a host telemetry singleton to one runtime client. This is the
|
|
28
|
+
* reusable bridge used by Hub-hosted sessions; local clients that already
|
|
29
|
+
* provide their own telemetry service do not need it.
|
|
30
|
+
*/
|
|
31
|
+
export declare function createClientScopedTelemetryService(parent: ITelemetryService, context: ClientTelemetryContext): ITelemetryService;
|
|
@@ -1,4 +1,38 @@
|
|
|
1
1
|
import type { WorkspaceInfo } from "@cerebriline/shared";
|
|
2
|
+
export type GitCommand = (args: readonly string[], options: {
|
|
3
|
+
cwd: string;
|
|
4
|
+
signal?: AbortSignal;
|
|
5
|
+
}) => Promise<{
|
|
6
|
+
stdout: string;
|
|
7
|
+
stderr?: string;
|
|
8
|
+
}>;
|
|
9
|
+
export declare function gitCommandErrorMessage(error: unknown): string;
|
|
10
|
+
export declare function gitCommandExitCode(error: unknown): number | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* Shared Git queries, without metadata fallback or cloud-handoff policy.
|
|
13
|
+
* Display branches retain simple-git's detached/unborn semantics; symbolic
|
|
14
|
+
* branches are strict and preserve Git exit codes for callers that require one.
|
|
15
|
+
* Commands are lazy so metadata reads never collect status or contact a remote.
|
|
16
|
+
* Structured display queries use simple-git; raw queries use the injectable
|
|
17
|
+
* runner to retain exit codes, timeouts, and cancellation for strict checks.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createWorkspaceGitReader(input: {
|
|
20
|
+
cwd: string;
|
|
21
|
+
git?: GitCommand;
|
|
22
|
+
signal?: AbortSignal;
|
|
23
|
+
}): {
|
|
24
|
+
isInsideWorkTree(): Promise<boolean>;
|
|
25
|
+
remotes: () => import("simple-git").Response<import("simple-git").RemoteWithRefs[]>;
|
|
26
|
+
displayBranch: () => Promise<string>;
|
|
27
|
+
symbolicBranch: () => Promise<string>;
|
|
28
|
+
headSha: () => Promise<string>;
|
|
29
|
+
workspacePrefix: () => Promise<string>;
|
|
30
|
+
worktreeStatus: () => Promise<string>;
|
|
31
|
+
branchRemote: (branch: string) => Promise<string>;
|
|
32
|
+
branchMergeRef: (branch: string) => Promise<string>;
|
|
33
|
+
remoteUrl: (remote: string) => Promise<string>;
|
|
34
|
+
remoteRefs: (remote: string, ref: string) => Promise<string>;
|
|
35
|
+
};
|
|
2
36
|
export interface WorkspaceInfoDiagnostics {
|
|
3
37
|
info: WorkspaceInfo;
|
|
4
38
|
vcsType: "git" | "none";
|
|
@@ -2,6 +2,11 @@ import type { ITelemetryService, WorkspaceInfo } from "@cerebriline/shared";
|
|
|
2
2
|
export interface WorkspaceLifecycleTelemetryInput {
|
|
3
3
|
telemetry?: ITelemetryService;
|
|
4
4
|
rootPath: string;
|
|
5
|
+
/**
|
|
6
|
+
* Optional client identity used for de-duplication in a shared runtime
|
|
7
|
+
* process. The same workspace still emits once per client surface.
|
|
8
|
+
*/
|
|
9
|
+
dedupeScope?: string;
|
|
5
10
|
workspaceInfo?: WorkspaceInfo;
|
|
6
11
|
rootCount?: number;
|
|
7
12
|
vcsType?: "git" | "none";
|
|
@@ -18,5 +18,12 @@ export declare function createSessionCompactionState(input: {
|
|
|
18
18
|
systemPrompt?: string;
|
|
19
19
|
updatedAt?: string;
|
|
20
20
|
}): SessionCompactionState;
|
|
21
|
-
export declare function projectSessionCompactionState(state: SessionCompactionState, sourceMessages: readonly MessageWithMetadata[]
|
|
21
|
+
export declare function projectSessionCompactionState(state: SessionCompactionState, sourceMessages: readonly MessageWithMetadata[],
|
|
22
|
+
/**
|
|
23
|
+
* The same transcript as it is about to be sent, when a stage ahead of
|
|
24
|
+
* compaction rewrote a message in it. The state is matched against
|
|
25
|
+
* `sourceMessages`; the tail that follows the compacted part is taken from
|
|
26
|
+
* here, so the rewrite is not undone by the projection.
|
|
27
|
+
*/
|
|
28
|
+
tailMessages?: readonly MessageWithMetadata[]): MessageWithMetadata[] | undefined;
|
|
22
29
|
export declare function parseSessionCompactionState(value: unknown): SessionCompactionState | undefined;
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* tool-result truncation and outdated-file-content rewrite for compaction.
|
|
9
9
|
* Per-instance caches make this host state.
|
|
10
10
|
*/
|
|
11
|
-
import { type MediaBudgetOptions, type Message } from "@cerebriline/shared";
|
|
11
|
+
import { type MediaBudgetOptions, type Message, type ToolResultContent } from "@cerebriline/shared";
|
|
12
12
|
export declare const DEFAULT_MAX_TOOL_RESULT_CHARS = 32000;
|
|
13
13
|
export declare const DEFAULT_MAX_FILE_CONTENT_CHARS = 50000;
|
|
14
14
|
export declare const DEFAULT_MAX_TOTAL_TEXT_BYTES = 6000000;
|
|
@@ -49,6 +49,10 @@ export declare const MESSAGE_BUILDER_LIMIT_ENV: {
|
|
|
49
49
|
readonly minOutdatedRewriteBytes: "CLINE_MESSAGE_BUILDER_MIN_OUTDATED_REWRITE_BYTES";
|
|
50
50
|
};
|
|
51
51
|
export interface MessageBuilderOptions {
|
|
52
|
+
/** Synchronous Core-owned recovery lookup; undefined leaves the normal result projection unchanged. */
|
|
53
|
+
getToolResultRecovery?: (result: ToolResultContent) => {
|
|
54
|
+
uri?: string;
|
|
55
|
+
} | undefined;
|
|
52
56
|
maxToolResultChars?: number;
|
|
53
57
|
maxFileContentChars?: number;
|
|
54
58
|
maxTotalTextBytes?: number;
|
|
@@ -67,6 +71,9 @@ export declare function getMessageBuilderOptionsFromEnv(env?: Record<string, str
|
|
|
67
71
|
* Builds an API-safe message copy without mutating original conversation history.
|
|
68
72
|
*/
|
|
69
73
|
export declare class MessageBuilder {
|
|
74
|
+
private readonly recoveryNotices;
|
|
75
|
+
private readonly getToolResultRecovery?;
|
|
76
|
+
private recoveryNoticeBytes;
|
|
70
77
|
private indexedMessageCount;
|
|
71
78
|
private indexedTailRef;
|
|
72
79
|
private readonly toolNameByIdCache;
|
|
@@ -52,6 +52,7 @@ export declare class UnifiedSessionPersistenceService {
|
|
|
52
52
|
title?: string | null;
|
|
53
53
|
}): Promise<{
|
|
54
54
|
updated: boolean;
|
|
55
|
+
metadata?: Record<string, unknown> | null;
|
|
55
56
|
}>;
|
|
56
57
|
queueSpawnRequest(event: HookEventPayload): Promise<void>;
|
|
57
58
|
upsertSubagentSession(input: import("../models/session-row").UpsertSubagentInput): Promise<string | undefined>;
|
|
@@ -73,7 +74,9 @@ export declare class UnifiedSessionPersistenceService {
|
|
|
73
74
|
handleSubAgentEnd(rootSessionId: string, context: SubAgentEndContext): Promise<void>;
|
|
74
75
|
private isPidAlive;
|
|
75
76
|
private reconcileDeadRunningSession;
|
|
76
|
-
listSessions(limit?: number
|
|
77
|
+
listSessions(limit?: number, options?: {
|
|
78
|
+
rootOnly?: boolean;
|
|
79
|
+
}): Promise<SessionRow[]>;
|
|
77
80
|
/**
|
|
78
81
|
* Lightweight, effectively unbounded listing of session ids + metadata
|
|
79
82
|
* (no manifest reads, no dead-session reconciliation). listSessions caps
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ImageContent } from "@cerebriline/shared";
|
|
2
|
+
export declare const TOOL_RESULT_CACHE_MAX_BYTES: number;
|
|
3
|
+
export declare const TOOL_RESULT_CACHE_IDLE_ITERATIONS = 5;
|
|
4
|
+
export declare const TOOL_RESULT_CACHE_MISS = "Cache not found. Make a new tool call for the latest result again if needed. DO NOT repeat side-effecting actions to recover output.";
|
|
5
|
+
/** Session-owned volatile text cache. Looking up a URI never extends its lifetime. */
|
|
6
|
+
export declare class ToolResultCache {
|
|
7
|
+
private readonly sessionId;
|
|
8
|
+
private readonly maxBytes;
|
|
9
|
+
private readonly entries;
|
|
10
|
+
private readonly referencesByToolCall;
|
|
11
|
+
private iteration;
|
|
12
|
+
private bytes;
|
|
13
|
+
constructor(sessionId: string, maxBytes?: number);
|
|
14
|
+
store(toolCallId: string, text: string): string | undefined;
|
|
15
|
+
uriFor(toolCallId: string): string | undefined;
|
|
16
|
+
read(uri: string): string;
|
|
17
|
+
advanceIteration(): void;
|
|
18
|
+
clear(): void;
|
|
19
|
+
private remove;
|
|
20
|
+
}
|
|
21
|
+
/** Size and truncate the persisted representation sent to the model. */
|
|
22
|
+
export declare function prepareToolResultPreview(content: unknown): {
|
|
23
|
+
text: string | undefined;
|
|
24
|
+
images: ImageContent[];
|
|
25
|
+
};
|
|
26
|
+
/** YAML is only the readable recovery copy, not the truncation threshold. */
|
|
27
|
+
export declare function prepareToolResultRecovery(output: unknown): {
|
|
28
|
+
text: string | undefined;
|
|
29
|
+
images: ImageContent[];
|
|
30
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type * as LlmsProviders from "@cerebriline/llms";
|
|
2
|
+
import type { ITelemetryService } from "@cerebriline/shared";
|
|
2
3
|
import type { CheckpointEntry, CheckpointMetadata } from "../hooks/checkpoint-hooks";
|
|
3
4
|
import type { RestoreSessionInput } from "../runtime/host/runtime-host";
|
|
4
5
|
import type { SessionRecord } from "../types/sessions";
|
|
@@ -44,6 +45,13 @@ export interface SessionCheckpointRestoreInput<TRestoreStartInput, TStartInput,
|
|
|
44
45
|
applyWorkspaceCheckpoint?: (cwd: string, checkpoint: CheckpointEntry) => Promise<void>;
|
|
45
46
|
beginWorkspaceRestoreTransaction?: (cwd: string) => Promise<WorktreeRestoreTransaction>;
|
|
46
47
|
retainCheckpointRefs?: (cwd: string, sessionId: string, history: CheckpointEntry[]) => Promise<void>;
|
|
48
|
+
/**
|
|
49
|
+
* Emits one `checkpoint.restore` event per restore attempt. Restores are
|
|
50
|
+
* rare and destructive, so field visibility matters: outcome, duration
|
|
51
|
+
* (the worktree transaction hashes all untracked files), and the
|
|
52
|
+
* checkpoint kind. Never file paths or contents.
|
|
53
|
+
*/
|
|
54
|
+
telemetry?: Pick<ITelemetryService, "capture">;
|
|
47
55
|
}
|
|
48
56
|
export declare class SessionVersioningService {
|
|
49
57
|
restoreCheckpoint<TRestoreStartInput, TStartInput, TStartResult>(input: SessionCheckpointRestoreInput<TRestoreStartInput, TStartInput, TStartResult>): Promise<SessionCheckpointRestoreResult<TStartResult>>;
|
|
@@ -31,12 +31,10 @@ export declare class SessionManifestStore {
|
|
|
31
31
|
path: string;
|
|
32
32
|
manifest?: SessionManifest;
|
|
33
33
|
};
|
|
34
|
+
readSessionRowFromManifest(sessionId: string): SessionRow | undefined;
|
|
34
35
|
/**
|
|
35
36
|
* Resolve the session row backing a message write, re-adopting it from the
|
|
36
|
-
* on-disk manifest when the
|
|
37
|
-
* or copied while the session DB was rebuilt). Sessions with neither a row
|
|
38
|
-
* nor a manifest throw so message writes cannot silently recreate
|
|
39
|
-
* orphaned session files.
|
|
37
|
+
* on-disk manifest when the index was rebuilt or the artifacts were restored.
|
|
40
38
|
*/
|
|
41
39
|
private resolveSessionRow;
|
|
42
40
|
persistSessionMessages(sessionId: string, messages: LlmsProviders.MessageWithMetadata[], systemPrompt?: string): Promise<void>;
|