@sayknow-cli/coding-agent 0.3.12 → 0.3.15
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/types/autoresearch/tools/init-experiment.d.ts +1 -1
- package/dist/types/autoresearch/tools/log-experiment.d.ts +2 -2
- package/dist/types/cli/classify-install-target.d.ts +0 -10
- package/dist/types/cli/daemon-cli.d.ts +2 -0
- package/dist/types/cli/initial-message.d.ts +1 -1
- package/dist/types/cli/malloc-env-guard.d.ts +65 -0
- package/dist/types/cli/malloc-env-guard.test.d.ts +1 -0
- package/dist/types/cli/notify-cli.d.ts +3 -1
- package/dist/types/cli/session-picker.d.ts +4 -3
- package/dist/types/cli/update-cli.d.ts +22 -3
- package/dist/types/cli.d.ts +5 -0
- package/dist/types/commands/daemon.d.ts +6 -2
- package/dist/types/commands/launch.d.ts +1 -0
- package/dist/types/commands/notify.d.ts +6 -0
- package/dist/types/commands/web-search.d.ts +1 -1
- package/dist/types/commit/agentic/tools/propose-changelog.d.ts +4 -4
- package/dist/types/commit/agentic/tools/propose-commit.d.ts +9 -9
- package/dist/types/commit/agentic/tools/schemas.d.ts +9 -9
- package/dist/types/commit/agentic/tools/split-commit.d.ts +9 -9
- package/dist/types/commit/analysis/conventional.d.ts +1 -1
- package/dist/types/commit/analysis/summary.d.ts +1 -1
- package/dist/types/commit/changelog/generate.d.ts +3 -3
- package/dist/types/commit/changelog/index.d.ts +2 -2
- package/dist/types/commit/map-reduce/map-phase.d.ts +1 -1
- package/dist/types/commit/map-reduce/reduce-phase.d.ts +1 -1
- package/dist/types/commit/shared-llm.d.ts +9 -9
- package/dist/types/config/keybindings.d.ts +134 -129
- package/dist/types/config/model-profile-activation.d.ts +1 -0
- package/dist/types/config/model-registry.d.ts +35 -35
- package/dist/types/config/models-config-schema.d.ts +111 -111
- package/dist/types/config/settings-schema.d.ts +56 -16
- package/dist/types/config/settings.d.ts +2 -0
- package/dist/types/coordinator/contract.d.ts +1 -1
- package/dist/types/coordinator-mcp/model-preset.d.ts +45 -0
- package/dist/types/coordinator-mcp/policy.d.ts +3 -0
- package/dist/types/coordinator-mcp/server.d.ts +79 -6
- package/dist/types/coordinator-mcp/session-reaper.d.ts +53 -0
- package/dist/types/daemon/control-types.d.ts +10 -0
- package/dist/types/daemon/operator-contract.d.ts +47 -0
- package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/models/catalog.d.ts +4 -0
- package/dist/types/defaults/skc/extensions/grok-cli-vendor/src/shared/errors.d.ts +12 -12
- package/dist/types/discovery/helpers.d.ts +1 -1
- package/dist/types/discovery/substitute-plugin-root.d.ts +0 -4
- package/dist/types/edit/modes/patch.d.ts +2 -2
- package/dist/types/extensibility/extensions/types.d.ts +3 -1
- package/dist/types/goals/tools/goal-tool.d.ts +6 -6
- package/dist/types/i18n/messages/en.d.ts +8 -8
- package/dist/types/internal-urls/local-protocol.d.ts +13 -9
- package/dist/types/lsp/index.d.ts +9 -9
- package/dist/types/lsp/types.d.ts +9 -9
- package/dist/types/main.d.ts +66 -2
- package/dist/types/modes/acp/acp-agent.d.ts +19 -2
- package/dist/types/modes/acp/acp-mode.d.ts +12 -0
- package/dist/types/modes/components/assistant-message.d.ts +1 -1
- package/dist/types/modes/components/custom-editor.d.ts +2 -0
- package/dist/types/modes/components/hook-selector.d.ts +5 -0
- package/dist/types/modes/components/irc-sidebar.d.ts +32 -0
- package/dist/types/modes/components/pet-selector.d.ts +11 -0
- package/dist/types/modes/components/sayknow-pet-widget.d.ts +59 -0
- package/dist/types/modes/components/session-selector.d.ts +22 -9
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/status-line/types.d.ts +1 -1
- package/dist/types/modes/components/status-line.d.ts +0 -10
- package/dist/types/modes/components/tool-execution.d.ts +1 -0
- package/dist/types/modes/components/user-message.d.ts +2 -1
- package/dist/types/modes/controllers/event-controller.d.ts +4 -0
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +24 -2
- package/dist/types/modes/irc-observation-ledger.d.ts +22 -0
- package/dist/types/modes/print-mode.d.ts +3 -4
- package/dist/types/modes/rpc/rpc-client.d.ts +7 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +2 -1
- package/dist/types/modes/rpc/rpc-types.d.ts +17 -1
- package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +8 -0
- package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +5 -0
- package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +45 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +42 -2
- package/dist/types/modes/theme/defaults/index.d.ts +568 -568
- package/dist/types/modes/types.d.ts +28 -2
- package/dist/types/modes/utils/abort-message.d.ts +1 -1
- package/dist/types/modes/utils/context-usage.d.ts +4 -19
- package/dist/types/modes/utils/irc-message.d.ts +38 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +13 -4
- package/dist/types/notifications/config.d.ts +34 -0
- package/dist/types/notifications/daemon-paths.d.ts +7 -0
- package/dist/types/notifications/index.d.ts +27 -0
- package/dist/types/notifications/lifecycle-control-runtime.d.ts +12 -4
- package/dist/types/notifications/notification-service.d.ts +144 -0
- package/dist/types/notifications/rate-limit-pool.d.ts +27 -9
- package/dist/types/notifications/telegram-daemon-control.d.ts +6 -0
- package/dist/types/notifications/telegram-daemon.d.ts +130 -3
- package/dist/types/notifications/telegram-reference.d.ts +19 -2
- package/dist/types/notifications/topic-registry.d.ts +24 -4
- package/dist/types/registry/agent-registry.d.ts +2 -0
- package/dist/types/rlm/index.d.ts +1 -1
- package/dist/types/sdk.d.ts +2 -0
- package/dist/types/secrets/obfuscator.d.ts +1 -1
- package/dist/types/session/agent-session.d.ts +40 -3
- package/dist/types/session/cache-economics.d.ts +79 -0
- package/dist/types/session/context-estimation.d.ts +31 -0
- package/dist/types/session/provider-safety-stop.d.ts +5 -0
- package/dist/types/session/session-manager.d.ts +124 -4
- package/dist/types/session/session-storage.d.ts +155 -13
- package/dist/types/setup/credential-auto-import.d.ts +2 -2
- package/dist/types/skc-runtime/session-state-sidecar.d.ts +34 -3
- package/dist/types/skc-runtime/state-schema.d.ts +19 -19
- package/dist/types/skc-runtime/tmux-common.d.ts +6 -0
- package/dist/types/skc-runtime/tmux-owner-isolation-cli.d.ts +5 -0
- package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +309 -0
- package/dist/types/skc-runtime/tmux-sessions.d.ts +49 -17
- package/dist/types/task/agents.d.ts +2 -2
- package/dist/types/task/executor.d.ts +3 -0
- package/dist/types/task/receipt.d.ts +3 -1
- package/dist/types/task/types.d.ts +35 -27
- package/dist/types/tools/ask-answer-registry.d.ts +5 -0
- package/dist/types/tools/bash.d.ts +1 -1
- package/dist/types/tools/browser/tab-supervisor.d.ts +6 -0
- package/dist/types/tools/browser.d.ts +28 -28
- package/dist/types/tools/computer.d.ts +20 -20
- package/dist/types/tools/cron.d.ts +2 -2
- package/dist/types/tools/debug.d.ts +40 -40
- package/dist/types/tools/gh.d.ts +10 -10
- package/dist/types/tools/image-gen.d.ts +2 -2
- package/dist/types/tools/index.d.ts +58 -6
- package/dist/types/tools/monitor.d.ts +6 -6
- package/dist/types/tools/skill-discovery.d.ts +4 -4
- package/dist/types/tools/subagent.d.ts +12 -12
- package/dist/types/tools/telegram-send.d.ts +7 -0
- package/dist/types/tools/todo-write.d.ts +8 -8
- package/dist/types/utils/external-editor.d.ts +2 -0
- package/dist/types/web/insane/bridge.d.ts +9 -9
- package/dist/types/web/search/index.d.ts +4 -4
- package/package.json +8 -8
- package/scripts/g004-tmux-smoke.ts +196 -36
- package/src/cli/daemon-cli.ts +19 -29
- package/src/cli/malloc-env-guard.test.ts +104 -0
- package/src/cli/malloc-env-guard.ts +149 -0
- package/src/cli/notify-cli.ts +78 -14
- package/src/cli/session-picker.ts +23 -40
- package/src/cli/update-cli.ts +56 -37
- package/src/cli.ts +51 -10
- package/src/commands/daemon.ts +19 -5
- package/src/commands/harness.ts +515 -47
- package/src/commands/launch.ts +11 -3
- package/src/commands/notify.ts +5 -1
- package/src/commands/session.ts +6 -1
- package/src/config/keybindings.ts +5 -0
- package/src/config/model-profile-activation.ts +1 -1
- package/src/config/model-profiles.ts +14 -14
- package/src/config/settings-schema.ts +41 -1
- package/src/config/settings.ts +96 -45
- package/src/coordinator/contract.ts +1 -0
- package/src/coordinator-mcp/model-preset.ts +100 -0
- package/src/coordinator-mcp/policy.ts +30 -0
- package/src/coordinator-mcp/server.ts +2958 -430
- package/src/coordinator-mcp/session-reaper.ts +129 -0
- package/src/daemon/control-types.ts +11 -0
- package/src/daemon/operator-contract.ts +121 -0
- package/src/defaults/skc/extensions/grok-cli-vendor/src/models/catalog.ts +57 -17
- package/src/defaults/skc/extensions/grok-cli-vendor/src/payload/sanitize.ts +15 -2
- package/src/defaults/skc/extensions/grok-cli-vendor/src/provider/register.ts +5 -1
- package/src/extensibility/extensions/runner.ts +1 -1
- package/src/extensibility/extensions/types.ts +3 -1
- package/src/internal-urls/docs-index.generated.ts +10 -9
- package/src/internal-urls/local-protocol.ts +29 -10
- package/src/main.ts +301 -80
- package/src/modes/acp/acp-agent.ts +730 -100
- package/src/modes/acp/acp-mode.ts +29 -2
- package/src/modes/components/assistant-message.ts +32 -3
- package/src/modes/components/bash-execution.ts +43 -13
- package/src/modes/components/custom-editor.ts +5 -0
- package/src/modes/components/footer.ts +3 -3
- package/src/modes/components/hook-selector.ts +12 -0
- package/src/modes/components/irc-sidebar.ts +206 -0
- package/src/modes/components/pet-selector.ts +55 -0
- package/src/modes/components/sayknow-pet-widget.ts +360 -0
- package/src/modes/components/session-selector.ts +222 -221
- package/src/modes/components/settings-selector.ts +10 -0
- package/src/modes/components/status-line/segments.ts +14 -7
- package/src/modes/components/status-line/types.ts +1 -1
- package/src/modes/components/status-line.ts +4 -171
- package/src/modes/components/tool-execution.ts +47 -6
- package/src/modes/components/user-message.ts +26 -9
- package/src/modes/controllers/command-controller.ts +28 -2
- package/src/modes/controllers/event-controller.ts +159 -36
- package/src/modes/controllers/extension-ui-controller.ts +37 -18
- package/src/modes/controllers/input-controller.ts +8 -2
- package/src/modes/controllers/selector-controller.ts +62 -15
- package/src/modes/interactive-mode.ts +199 -7
- package/src/modes/irc-observation-ledger.ts +127 -0
- package/src/modes/print-mode.ts +228 -92
- package/src/modes/rpc/rpc-client.ts +58 -1
- package/src/modes/rpc/rpc-mode.ts +286 -85
- package/src/modes/rpc/rpc-types.ts +15 -1
- package/src/modes/shared/agent-wire/command-dispatch.ts +33 -1
- package/src/modes/shared/agent-wire/command-validation.ts +10 -0
- package/src/modes/shared/agent-wire/deep-interview-gate.ts +45 -2
- package/src/modes/shared/agent-wire/scopes.ts +1 -0
- package/src/modes/shared/agent-wire/unattended-session.ts +288 -1
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +130 -20
- package/src/modes/types.ts +34 -2
- package/src/modes/utils/context-usage.ts +56 -92
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/modes/utils/irc-message.ts +138 -0
- package/src/modes/utils/ui-helpers.ts +216 -50
- package/src/notifications/config.ts +44 -0
- package/src/notifications/daemon-paths.ts +8 -0
- package/src/notifications/index.ts +535 -75
- package/src/notifications/lifecycle-control-runtime.ts +930 -77
- package/src/notifications/notification-service.ts +710 -0
- package/src/notifications/rate-limit-pool.ts +46 -12
- package/src/notifications/telegram-daemon-control.ts +27 -2
- package/src/notifications/telegram-daemon.ts +635 -94
- package/src/notifications/telegram-reference.ts +73 -13
- package/src/notifications/topic-registry.ts +86 -9
- package/src/prompts/system/irc-peer-roster.md +1 -0
- package/src/prompts/system/subagent-system-prompt.md +1 -0
- package/src/prompts/system/system-prompt.md +1 -0
- package/src/prompts/tools/irc.md +1 -1
- package/src/registry/agent-registry.ts +3 -0
- package/src/sdk.ts +52 -1
- package/src/secrets/obfuscator.ts +4 -2
- package/src/session/agent-session.ts +670 -217
- package/src/session/cache-economics.ts +275 -0
- package/src/session/context-estimation.ts +91 -0
- package/src/session/provider-safety-stop.ts +9 -0
- package/src/session/session-dump-format.ts +6 -0
- package/src/session/session-manager.ts +809 -39
- package/src/session/session-storage.ts +582 -38
- package/src/skc-runtime/session-state-sidecar.ts +756 -135
- package/src/skc-runtime/tmux-common.ts +26 -7
- package/src/skc-runtime/tmux-gc.ts +52 -9
- package/src/skc-runtime/tmux-owner-isolation-cli.ts +185 -0
- package/src/skc-runtime/tmux-owner-isolation.ts +2060 -0
- package/src/skc-runtime/tmux-sessions.ts +871 -68
- package/src/slash-commands/builtin-registry.ts +153 -9
- package/src/slash-commands/helpers/context-report.ts +26 -4
- package/src/task/executor.ts +12 -3
- package/src/task/index.ts +8 -0
- package/src/task/receipt.ts +7 -2
- package/src/task/types.ts +26 -0
- package/src/tools/ask-answer-registry.ts +25 -0
- package/src/tools/browser/tab-supervisor.ts +63 -6
- package/src/tools/browser.ts +8 -3
- package/src/tools/index.ts +81 -6
- package/src/tools/sqlite-reader.ts +8 -4
- package/src/tui/output-block.ts +18 -6
- package/src/utils/external-editor.ts +6 -1
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import type { Settings } from "../config/settings";
|
|
3
3
|
import type { DaemonRuntimeInfo } from "../daemon/control-types";
|
|
4
|
+
import { HEARTBEAT_TTL_MS } from "./daemon-paths";
|
|
4
5
|
import { type ControlServerLike, type LifecycleControlServerFactory } from "./lifecycle-control-runtime";
|
|
5
6
|
import { NotificationOperatorRuntime, OperatorBackoffPolicy } from "./operator-runtime";
|
|
6
7
|
import { type AliasTable, type CallbackRoute } from "./telegram-reference";
|
|
@@ -14,6 +15,14 @@ export interface DaemonState {
|
|
|
14
15
|
heartbeatAt: number;
|
|
15
16
|
roots: string[];
|
|
16
17
|
version: 1;
|
|
18
|
+
/**
|
|
19
|
+
* Operational daemon generation of the process that owns the lock, distinct
|
|
20
|
+
* from the persisted state-schema {@link DaemonState.version}. It records the
|
|
21
|
+
* wire generation ({@link DAEMON_GENERATION}) the owning daemon speaks so a
|
|
22
|
+
* freshly-upgraded host can detect — and reload — a still-live pre-upgrade
|
|
23
|
+
* daemon whose schema version is unchanged. Absent on pre-generation state.
|
|
24
|
+
*/
|
|
25
|
+
generation?: number;
|
|
17
26
|
stoppedAt?: number;
|
|
18
27
|
}
|
|
19
28
|
export interface TelegramDaemonFs {
|
|
@@ -43,14 +52,35 @@ export interface TelegramDaemonDeps {
|
|
|
43
52
|
}) => SpawnResult;
|
|
44
53
|
execPath?: string;
|
|
45
54
|
randomId?: () => string;
|
|
55
|
+
/**
|
|
56
|
+
* Signal delivery + poll timing for the stale-generation reload handoff in
|
|
57
|
+
* {@link ensureTelegramDaemonRunning}. Defaults use real signals/timers; tests
|
|
58
|
+
* inject them to drive the handoff deterministically.
|
|
59
|
+
*/
|
|
60
|
+
sendSignal?: (pid: number, signal: NodeJS.Signals) => void;
|
|
61
|
+
sleep?: (ms: number) => Promise<void>;
|
|
62
|
+
waitStepMs?: number;
|
|
46
63
|
}
|
|
47
64
|
export declare const HEARTBEAT_INTERVAL_MS = 5000;
|
|
48
|
-
export
|
|
65
|
+
export { HEARTBEAT_TTL_MS };
|
|
49
66
|
export declare const DAEMON_VERSION = 1;
|
|
50
67
|
/** Capability token advertised when the server supports app-level ping/pong. */
|
|
51
68
|
export declare const CLIENT_PING_PONG_CAPABILITY = "client_ping_pong";
|
|
52
69
|
/** Protocol version the daemon advertises in its ClientHello. */
|
|
53
|
-
export declare const NOTIFICATION_PROTOCOL_VERSION =
|
|
70
|
+
export declare const NOTIFICATION_PROTOCOL_VERSION = 3;
|
|
71
|
+
/** Capability required for typed controls and semantic Selected acknowledgement frames. */
|
|
72
|
+
export declare const ASK_SELECTED_ACK_CAPABILITY = "ask_selected_ack_v1";
|
|
73
|
+
export declare const ASK_CONTROLS_CAPABILITY = "ask_controls_v1";
|
|
74
|
+
/**
|
|
75
|
+
* Operational generation the current daemon build speaks, persisted into
|
|
76
|
+
* {@link DaemonState.generation} on ownership acquisition. It is tied to the
|
|
77
|
+
* wire {@link NOTIFICATION_PROTOCOL_VERSION} so any protocol bump (which is what
|
|
78
|
+
* gates capabilities like {@link ASK_SELECTED_ACK_CAPABILITY}) also bumps the
|
|
79
|
+
* generation, letting a freshly-upgraded host recognise an older, still-live
|
|
80
|
+
* daemon and reload it instead of silently attaching to it. Distinct from the
|
|
81
|
+
* persisted schema {@link DAEMON_VERSION}, which did not change across #1999.
|
|
82
|
+
*/
|
|
83
|
+
export declare const DAEMON_GENERATION = 3;
|
|
54
84
|
export { type DaemonPaths, daemonPaths } from "./daemon-paths";
|
|
55
85
|
/**
|
|
56
86
|
* Attach session-lifecycle control (create/close/resume) to the running daemon.
|
|
@@ -97,6 +127,7 @@ export declare function acquireDaemonOwnership(input: {
|
|
|
97
127
|
attached?: boolean;
|
|
98
128
|
blocked?: boolean;
|
|
99
129
|
reason?: "identity_mismatch";
|
|
130
|
+
reloadRequired?: boolean;
|
|
100
131
|
}>;
|
|
101
132
|
export declare function renewDaemonHeartbeat(input: {
|
|
102
133
|
settings: Settings;
|
|
@@ -126,6 +157,12 @@ export interface TelegramSpawnOwnerResult {
|
|
|
126
157
|
ownerId?: string;
|
|
127
158
|
runtime: DaemonRuntimeInfo;
|
|
128
159
|
warnings: string[];
|
|
160
|
+
/**
|
|
161
|
+
* Set when ownership was NOT acquired because a still-live owner is running an
|
|
162
|
+
* older daemon generation. The caller must hand off via a reload rather than
|
|
163
|
+
* attach; see {@link ensureTelegramDaemonRunning}.
|
|
164
|
+
*/
|
|
165
|
+
reloadRequired?: boolean;
|
|
129
166
|
}
|
|
130
167
|
/**
|
|
131
168
|
* Build the detached spawn command/args for the daemon-internal entrypoint.
|
|
@@ -156,6 +193,7 @@ export declare function ensureTelegramDaemonRunning(input: {
|
|
|
156
193
|
export interface BotApi {
|
|
157
194
|
call(method: string, body: unknown, opts?: {
|
|
158
195
|
signal?: AbortSignal;
|
|
196
|
+
noRetry?: boolean;
|
|
159
197
|
}): Promise<unknown>;
|
|
160
198
|
}
|
|
161
199
|
export interface TelegramTransportOptions {
|
|
@@ -170,13 +208,15 @@ export declare class TelegramBotTransport implements BotApi {
|
|
|
170
208
|
constructor(opts: TelegramTransportOptions);
|
|
171
209
|
call(method: string, body: unknown, opts?: {
|
|
172
210
|
signal?: AbortSignal;
|
|
211
|
+
noRetry?: boolean;
|
|
173
212
|
}): Promise<unknown>;
|
|
174
213
|
}
|
|
214
|
+
export type TelegramUpdateOutcome = "consumed" | "retry";
|
|
175
215
|
export interface TelegramUpdatePollerOptions {
|
|
176
216
|
botApi: BotApi;
|
|
177
217
|
runtime: NotificationOperatorRuntime;
|
|
178
218
|
backoff: OperatorBackoffPolicy;
|
|
179
|
-
processUpdate: (update: unknown) => Promise<
|
|
219
|
+
processUpdate: (update: unknown) => Promise<TelegramUpdateOutcome>;
|
|
180
220
|
}
|
|
181
221
|
/** Owns getUpdates offset, conflict backoff, and per-update error isolation. */
|
|
182
222
|
export declare class TelegramUpdatePoller {
|
|
@@ -239,6 +279,14 @@ export interface TelegramDaemonOptions {
|
|
|
239
279
|
richDraft?: {
|
|
240
280
|
enabled: boolean;
|
|
241
281
|
};
|
|
282
|
+
/**
|
|
283
|
+
* Per-session Telegram forum-topic naming. `nameTemplate` supports the
|
|
284
|
+
* `{repo}`, `{branch}`, and `{title}` placeholders; unset preserves the
|
|
285
|
+
* built-in `{repo}/{branch} - {title}` composition and its fallbacks.
|
|
286
|
+
*/
|
|
287
|
+
topics?: {
|
|
288
|
+
nameTemplate?: string;
|
|
289
|
+
};
|
|
242
290
|
}
|
|
243
291
|
interface SessionSocket {
|
|
244
292
|
sessionId: string;
|
|
@@ -273,6 +321,11 @@ export declare class TelegramNotificationDaemon {
|
|
|
273
321
|
private readonly fsImpl;
|
|
274
322
|
private readonly botApi;
|
|
275
323
|
private readonly topics;
|
|
324
|
+
/** Serializes registry snapshots so an older atomic write cannot overwrite newer rename state. */
|
|
325
|
+
private topicsPersistQueue;
|
|
326
|
+
/** Daemon edit attempts that can race an accepted user service message. */
|
|
327
|
+
private readonly daemonRenameAttempts;
|
|
328
|
+
private readonly selectedAckPending;
|
|
276
329
|
private readonly pool;
|
|
277
330
|
private readonly poller;
|
|
278
331
|
private readonly dispatchState;
|
|
@@ -314,12 +367,24 @@ export declare class TelegramNotificationDaemon {
|
|
|
314
367
|
private readonly pendingLifecycle;
|
|
315
368
|
/** Monotonic counter for unique lifecycle request ids. */
|
|
316
369
|
private lifecycleSeq;
|
|
370
|
+
/** Attempt tombstones live for the daemon lifetime so a commit key can never send twice. */
|
|
371
|
+
private readonly selectedAckCache;
|
|
372
|
+
private cacheSelectedAck;
|
|
373
|
+
private getCachedSelectedAck;
|
|
374
|
+
private finishSelectedAck;
|
|
317
375
|
/**
|
|
318
376
|
* Cooperatively stop the daemon: set the stop flag and abort the in-flight
|
|
319
377
|
* long poll so the run loop wakes immediately instead of waiting out the
|
|
320
378
|
* ~25s getUpdates timeout. Safe to call from a signal handler.
|
|
321
379
|
*/
|
|
322
380
|
requestStop(_reason?: "reload" | "stop" | "signal"): void;
|
|
381
|
+
/**
|
|
382
|
+
* Start the owner-bound lifecycle control server and wire it to the
|
|
383
|
+
* orchestrator. Called from {@link run} ONLY after ownership is confirmed, so
|
|
384
|
+
* exactly one owner ever starts exactly one control server (no second poller
|
|
385
|
+
* / 409). A control-server failure degrades gracefully: the daemon keeps
|
|
386
|
+
* serving notifications without lifecycle control. Returns true when started.
|
|
387
|
+
*/
|
|
323
388
|
private startLifecycleControl;
|
|
324
389
|
/** Stop the lifecycle control server (idempotent); called from run()'s finally. */
|
|
325
390
|
private stopLifecycleControl;
|
|
@@ -334,6 +399,11 @@ export declare class TelegramNotificationDaemon {
|
|
|
334
399
|
private nextLifecycleRequestId;
|
|
335
400
|
/** Build an authenticated lifecycle frame from a parsed command + identity. */
|
|
336
401
|
private buildLifecycleFrame;
|
|
402
|
+
/**
|
|
403
|
+
* Handle a paired-chat /session_* command: validate (shared validator),
|
|
404
|
+
* route to the control endpoint, and reply with the outcome. Returns true
|
|
405
|
+
* when the message was a lifecycle command (so the caller stops processing).
|
|
406
|
+
*/
|
|
337
407
|
private handleLifecycleCommand;
|
|
338
408
|
private refreshBotIdentity;
|
|
339
409
|
/** Map a lifecycle response/error to a user-facing message (G010 surfacing). */
|
|
@@ -366,20 +436,40 @@ export declare class TelegramNotificationDaemon {
|
|
|
366
436
|
private deleteMessageRoutes;
|
|
367
437
|
private static readonly THREADED_FRAMES;
|
|
368
438
|
private topicNameFor;
|
|
439
|
+
/**
|
|
440
|
+
* Render the operator-configured topic name template, or `undefined` when no
|
|
441
|
+
* usable template applies so the caller uses the built-in composition. The
|
|
442
|
+
* template is honored only if it is non-blank AND every placeholder it
|
|
443
|
+
* references (`{repo}`, `{branch}`, `{title}`) has a value for this session,
|
|
444
|
+
* which preserves the default title/repo/branch fallbacks and prevents
|
|
445
|
+
* half-filled names with dangling separators. Unknown placeholders are left
|
|
446
|
+
* verbatim.
|
|
447
|
+
*/
|
|
448
|
+
private renderTopicNameTemplate;
|
|
369
449
|
private topicIdentityKey;
|
|
370
450
|
private topicIdentityBase;
|
|
371
451
|
private topicOwnerForIdentity;
|
|
372
452
|
private sessionCanClaimIdentity;
|
|
373
453
|
private submitThreadedFrame;
|
|
374
454
|
private existingTopicForPrivateChat;
|
|
455
|
+
/** Best-effort re-assertion for a durable user-owned topic name. */
|
|
456
|
+
private reconcileUserTopicName;
|
|
375
457
|
private rememberPendingThreadedFrame;
|
|
376
458
|
private flushPendingThreadedFrames;
|
|
459
|
+
/**
|
|
460
|
+
* Resolve (creating once via `createForumTopic`) the forum topic for a
|
|
461
|
+
* session. On capability failure (e.g. Threaded Mode off) this returns
|
|
462
|
+
* `undefined`; callers then flat-deliver to a private paired chat (with a
|
|
463
|
+
* one-time nudge) or drop fail-closed for a non-private chat.
|
|
464
|
+
*/
|
|
377
465
|
private ensureTopic;
|
|
378
466
|
private topicPastOrphanGrace;
|
|
379
467
|
private deleteOrphanedTopic;
|
|
468
|
+
/** Best-effort delete of a session topic once its local notification endpoint shuts down. */
|
|
380
469
|
private deleteTopic;
|
|
381
470
|
private persistTopics;
|
|
382
471
|
loadTopics(): Promise<void>;
|
|
472
|
+
/** Download a Telegram file by its file_path (from getFile) into memory. */
|
|
383
473
|
private downloadTelegramFile;
|
|
384
474
|
/**
|
|
385
475
|
* Per-session private temp directories (mode 0700) holding inbound non-image
|
|
@@ -387,8 +477,19 @@ export declare class TelegramNotificationDaemon {
|
|
|
387
477
|
* removed when the daemon stops (see {@link cleanupAllAttachmentDirs}).
|
|
388
478
|
*/
|
|
389
479
|
private readonly attachmentDirs;
|
|
480
|
+
/** Lazily create a private, unguessable 0700 temp dir for `sessionId`. */
|
|
390
481
|
private ensureAttachmentDir;
|
|
482
|
+
/** Remove all per-session attachment directories. Called on daemon shutdown. */
|
|
391
483
|
private cleanupAllAttachmentDirs;
|
|
484
|
+
/**
|
|
485
|
+
* Resolve an inbound attachment to inline image bytes (forwarded as images) or
|
|
486
|
+
* a securely-saved file path note (non-images). Non-image bytes are written
|
|
487
|
+
* into a private per-session temp dir (0700) under an unguessable name via an
|
|
488
|
+
* exclusive 0600 create (`wx`), so the files are not world-readable and the
|
|
489
|
+
* write never follows a pre-existing symlink. The directory is removed when the
|
|
490
|
+
* daemon stops. Returns base64 images to inline plus human-readable file notes
|
|
491
|
+
* to append to the injected text.
|
|
492
|
+
*/
|
|
392
493
|
private resolveInboundAttachment;
|
|
393
494
|
/**
|
|
394
495
|
* Serialize all pool flushes. Every caller (`submitThreadedFrame`, the flat
|
|
@@ -400,6 +501,7 @@ export declare class TelegramNotificationDaemon {
|
|
|
400
501
|
*/
|
|
401
502
|
private flushChain;
|
|
402
503
|
private flushPool;
|
|
504
|
+
/** Drain the shared rate-limit pool and deliver each granted send to its topic. */
|
|
403
505
|
private flushPoolInner;
|
|
404
506
|
/**
|
|
405
507
|
* Track the Telegram message id backing a streamed `(sessionId, coalesceKey)`
|
|
@@ -407,25 +509,50 @@ export declare class TelegramNotificationDaemon {
|
|
|
407
509
|
* same-category entries (e.g. prior turns) so the map stays bounded.
|
|
408
510
|
*/
|
|
409
511
|
private recordLiveMessage;
|
|
512
|
+
/**
|
|
513
|
+
* Threaded Mode is unavailable (the bot owner has not enabled forum topics in
|
|
514
|
+
* @BotFather, so `createForumTopic` fails). Deliver the rendered frame flat to
|
|
515
|
+
* the paired chat instead of dropping it, and nudge the user once. Flat delivery
|
|
516
|
+
* is gated on the paired chat being a private chat: for a group/supergroup/channel
|
|
517
|
+
* (e.g. a legacy or hand-edited `chatId`) we keep dropping fail-closed so session
|
|
518
|
+
* content never lands in a shared chat. Identity headers are sent at most once per
|
|
519
|
+
* session in flat mode.
|
|
520
|
+
*/
|
|
410
521
|
private deliverFlatFallback;
|
|
522
|
+
/**
|
|
523
|
+
* Resolve (and cache definitive resolution of) whether the paired `chatId` is
|
|
524
|
+
* a private chat. Topic and flat delivery are only safe in a private DM; an
|
|
525
|
+
* indeterminate `getChat` result fails closed for this attempt and is retried
|
|
526
|
+
* later.
|
|
527
|
+
*/
|
|
528
|
+
private resolvePairedChatPrivacy;
|
|
529
|
+
/** Keep existing outbound callers fail-closed for indeterminate privacy. */
|
|
411
530
|
private pairedChatIsPrivate;
|
|
531
|
+
/** Tell the user once (per daemon run) how to enable Threaded Mode. */
|
|
412
532
|
private notifyThreadedFallback;
|
|
413
533
|
private startFlushTimer;
|
|
414
534
|
private stopFlushTimer;
|
|
535
|
+
/** Run a root scan, guarding against overlapping scans from the timer + loop. */
|
|
415
536
|
private runScan;
|
|
416
537
|
private startScanTimer;
|
|
417
538
|
private stopScanTimer;
|
|
539
|
+
/** Send a single `typing` chat action into a busy session's topic (best-effort). */
|
|
418
540
|
private sendTyping;
|
|
541
|
+
/** Set a native reaction on an inbound thread message (best-effort). */
|
|
419
542
|
private setReaction;
|
|
420
543
|
private startTypingTimer;
|
|
421
544
|
private stopTypingTimer;
|
|
422
545
|
handleSessionMessage(session: SessionSocket, msg: any): Promise<void>;
|
|
423
546
|
private answerCallbackQueryBestEffort;
|
|
424
547
|
private sendStaleGuidance;
|
|
548
|
+
/** Consume Telegram forum-topic rename service messages before text routing. */
|
|
549
|
+
private handleForumTopicEdited;
|
|
550
|
+
private processTelegramUpdate;
|
|
425
551
|
handleTelegramUpdate(update: unknown): Promise<void>;
|
|
426
552
|
pollOnce(signal?: AbortSignal): Promise<number>;
|
|
427
553
|
/** Sync the bot's Telegram command menu to what the daemon actually handles. */
|
|
428
554
|
registerBotCommands(): Promise<void>;
|
|
429
555
|
run(): Promise<void>;
|
|
556
|
+
/** True when a signal-driven stop or an owner-scoped control request asks the loop to exit. */
|
|
430
557
|
private controlStopRequested;
|
|
431
558
|
}
|
|
@@ -18,6 +18,16 @@ export interface InlineButton {
|
|
|
18
18
|
text: string;
|
|
19
19
|
callback_data: string;
|
|
20
20
|
}
|
|
21
|
+
/** Typed action controls are protocol data, never inferred from option labels. */
|
|
22
|
+
export interface TelegramActionControl {
|
|
23
|
+
id: "navigation_forward";
|
|
24
|
+
kind: "navigation";
|
|
25
|
+
label: "Next" | "Done";
|
|
26
|
+
enabled: boolean;
|
|
27
|
+
}
|
|
28
|
+
export type TelegramCallbackAnswer = number | string | {
|
|
29
|
+
controlId: TelegramActionControl["id"];
|
|
30
|
+
};
|
|
21
31
|
/** A rendered Telegram message for an `action_needed`. */
|
|
22
32
|
export interface RenderedMessage {
|
|
23
33
|
text: string;
|
|
@@ -31,10 +41,16 @@ export declare function decodeCallbackData(data: string): {
|
|
|
31
41
|
id: string;
|
|
32
42
|
index: number;
|
|
33
43
|
} | null;
|
|
44
|
+
/** Encode a typed control independently from option labels. */
|
|
45
|
+
export declare function encodeControlCallbackData(actionId: string, controlId: TelegramActionControl["id"]): string;
|
|
46
|
+
export declare function decodeControlCallbackData(data: string): {
|
|
47
|
+
id: string;
|
|
48
|
+
controlId: TelegramActionControl["id"];
|
|
49
|
+
} | null;
|
|
34
50
|
export interface CallbackRoute {
|
|
35
51
|
sessionId: string;
|
|
36
52
|
actionId: string;
|
|
37
|
-
answer:
|
|
53
|
+
answer: TelegramCallbackAnswer;
|
|
38
54
|
}
|
|
39
55
|
export interface SerializedAliasTable {
|
|
40
56
|
version: 1;
|
|
@@ -57,6 +73,7 @@ export declare function buildActionMessage(action: {
|
|
|
57
73
|
id: string;
|
|
58
74
|
question?: string;
|
|
59
75
|
options?: string[];
|
|
76
|
+
controls?: readonly TelegramActionControl[];
|
|
60
77
|
summary?: string;
|
|
61
78
|
}): RenderedMessage;
|
|
62
79
|
/** Render an `action_needed` body as raw markdown (rich-message source; the HTML fallback stays on buildActionMessage). */
|
|
@@ -72,7 +89,7 @@ export declare function sendTelegramHtmlChunks(send: TelegramSend, chatId: strin
|
|
|
72
89
|
export interface ReplyFrame {
|
|
73
90
|
type: "reply";
|
|
74
91
|
id: string;
|
|
75
|
-
answer:
|
|
92
|
+
answer: TelegramCallbackAnswer;
|
|
76
93
|
token: string;
|
|
77
94
|
}
|
|
78
95
|
/**
|
|
@@ -20,8 +20,16 @@ export interface TopicRecord {
|
|
|
20
20
|
identitySent: boolean;
|
|
21
21
|
/** Creation timestamp (ms epoch). */
|
|
22
22
|
createdAt: number;
|
|
23
|
-
/** Last applied
|
|
23
|
+
/** Last applied or observed Telegram topic title. */
|
|
24
24
|
name?: string;
|
|
25
|
+
/** Naming authority. Missing values are legacy daemon-owned records. */
|
|
26
|
+
nameOwner?: "user";
|
|
27
|
+
/** Whether a user-owned name still needs a best-effort Telegram re-assert. */
|
|
28
|
+
nameReconcilePending?: boolean;
|
|
29
|
+
/** Last accepted Telegram update id for a user-owned name. */
|
|
30
|
+
userNameUpdateId?: number;
|
|
31
|
+
/** Stable repo/branch identity used when topic names are user-owned or customized. */
|
|
32
|
+
identityKey?: string;
|
|
25
33
|
}
|
|
26
34
|
/** Serialisable shape persisted to disk. */
|
|
27
35
|
export interface TopicRegistryState {
|
|
@@ -41,7 +49,7 @@ export declare class TopicRegistry {
|
|
|
41
49
|
/** In-flight create promises, keyed by session, to dedupe concurrent creates. */
|
|
42
50
|
private readonly inflight;
|
|
43
51
|
constructor(state?: TopicRegistryState);
|
|
44
|
-
/** Merge
|
|
52
|
+
/** Merge serialized state and normalize authority fields from older releases. */
|
|
45
53
|
load(state: TopicRegistryState): void;
|
|
46
54
|
/** Resolve the owning session for a topic id (for fail-closed inbound routing). */
|
|
47
55
|
sessionForTopic(topicId: string): string | undefined;
|
|
@@ -58,9 +66,21 @@ export declare class TopicRegistry {
|
|
|
58
66
|
markIdentitySent(sessionId: string): void;
|
|
59
67
|
/** Whether the identity header still needs sending for this session. */
|
|
60
68
|
needsIdentity(sessionId: string): boolean;
|
|
61
|
-
/**
|
|
69
|
+
/** Remember stable repo/branch identity independently of the displayed name. */
|
|
70
|
+
markIdentityKey(sessionId: string, identityKey: string): boolean;
|
|
71
|
+
/** Whether daemon identity reconciliation should apply `name`. */
|
|
62
72
|
needsRename(sessionId: string, name: string): boolean;
|
|
63
|
-
/**
|
|
73
|
+
/** The user-owned name that must be preserved, when one exists. */
|
|
74
|
+
userOwnedName(sessionId: string): string | undefined;
|
|
75
|
+
/** A user-owned name whose Telegram reconciliation is still pending. */
|
|
76
|
+
userNameToReconcile(sessionId: string): string | undefined;
|
|
77
|
+
/** Record an explicit Telegram-side user rename, rejecting stale update ids. */
|
|
78
|
+
markUserName(sessionId: string, name: string, updateId: number): "updated" | "duplicate" | "stale";
|
|
79
|
+
/** Mark the matching preserved user name as reconciled with Telegram. */
|
|
80
|
+
markUserNameReconciled(sessionId: string, name: string): boolean;
|
|
81
|
+
/** Restore retryable reconciliation after a failed pending-clear persistence. */
|
|
82
|
+
markUserNamePending(sessionId: string, name: string): boolean;
|
|
83
|
+
/** Commit a successfully-applied daemon topic title. */
|
|
64
84
|
markNameApplied(sessionId: string, name: string): void;
|
|
65
85
|
/** Remove a session topic record after Telegram deletes the topic. */
|
|
66
86
|
delete(sessionId: string): boolean;
|
|
@@ -12,6 +12,7 @@ export type AgentKind = "main" | "sub";
|
|
|
12
12
|
export interface AgentRef {
|
|
13
13
|
id: string;
|
|
14
14
|
displayName: string;
|
|
15
|
+
rosterLabel?: string;
|
|
15
16
|
kind: AgentKind;
|
|
16
17
|
parentId?: string;
|
|
17
18
|
status: AgentStatus;
|
|
@@ -34,6 +35,7 @@ type RegistryListener = (event: RegistryEvent) => void;
|
|
|
34
35
|
export interface RegisterInput {
|
|
35
36
|
id: string;
|
|
36
37
|
displayName: string;
|
|
38
|
+
rosterLabel?: string;
|
|
37
39
|
kind: AgentKind;
|
|
38
40
|
parentId?: string;
|
|
39
41
|
session: AgentSession | null;
|
|
@@ -24,7 +24,7 @@ export declare function extractDataFlag(argv: string[]): {
|
|
|
24
24
|
dataPath: string | undefined;
|
|
25
25
|
rest: string[];
|
|
26
26
|
};
|
|
27
|
-
export declare function createRlmPreset({ dataContext, pythonTool, completeResearchTool, objective, resumeContext, onSessionReady }: RlmPresetOptions): RlmPreset;
|
|
27
|
+
export declare function createRlmPreset({ dataContext, pythonTool, completeResearchTool, objective, resumeContext, onSessionReady, }: RlmPresetOptions): RlmPreset;
|
|
28
28
|
export declare function buildRlmGoalObjective(input: {
|
|
29
29
|
messages: readonly string[];
|
|
30
30
|
dataContext: RlmDataContext | null;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -122,6 +122,8 @@ export interface CreateAgentSessionOptions {
|
|
|
122
122
|
agentId?: string;
|
|
123
123
|
/** Display name for the agent in IRC. Default: "main" or "sub". */
|
|
124
124
|
agentDisplayName?: string;
|
|
125
|
+
/** Compact task label for hidden IRC roster reminders. */
|
|
126
|
+
agentRosterLabel?: string;
|
|
125
127
|
/** Optional restricted bash command prefixes for read-only role agents. */
|
|
126
128
|
bashAllowedPrefixes?: string[];
|
|
127
129
|
/** Restriction policy paired with bashAllowedPrefixes. */
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
*
|
|
13
13
|
* Modes use this class and add their own I/O layer on top.
|
|
14
14
|
*/
|
|
15
|
-
import { type Agent, type AgentEvent, type AgentMessage, type AgentState, type AgentTool, type StablePrefixSnapshot, ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
15
|
+
import { type Agent, type AgentEvent, type AgentMessage, type AgentState, type AgentTool, type ResolvedThinkingLevel, type StablePrefixSnapshot, ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
16
16
|
import { type CompactionResult, type EmergencyCompactionSample } from "@sayknow-cli/agent-core/compaction";
|
|
17
|
-
import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolCall, ToolChoice, UsageReport } from "@sayknow-cli/ai";
|
|
17
|
+
import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolCall, ToolChoice, Usage, UsageReport } from "@sayknow-cli/ai";
|
|
18
18
|
export interface ForkContextSeedMetadata {
|
|
19
19
|
sourceSessionId: string;
|
|
20
20
|
parentMessageCount: number;
|
|
@@ -79,7 +79,7 @@ import { type WorkspaceTree } from "../workspace-tree";
|
|
|
79
79
|
import type { ClientBridge } from "./client-bridge";
|
|
80
80
|
import { type ContributionPrepOptions, type ContributionPrepResult } from "./contribution-prep";
|
|
81
81
|
import { type CustomMessage } from "./messages";
|
|
82
|
-
import type { BranchSummaryEntry, CompactionEntry, NewSessionOptions, SessionContext, SessionManager } from "./session-manager";
|
|
82
|
+
import type { BranchSummaryEntry, CompactionEntry, NewSessionOptions, SessionContext, SessionManager, SessionManagerCloseOutcome } from "./session-manager";
|
|
83
83
|
import { ToolChoiceQueue } from "./tool-choice-queue";
|
|
84
84
|
import { YieldQueue } from "./yield-queue";
|
|
85
85
|
/** Session-specific events that extend the core AgentEvent */
|
|
@@ -309,6 +309,11 @@ export interface RoleModelCycleResult {
|
|
|
309
309
|
thinkingLevel: ThinkingLevel | undefined;
|
|
310
310
|
role: string;
|
|
311
311
|
}
|
|
312
|
+
export interface DefaultModelSelectionResult {
|
|
313
|
+
readonly provider: string;
|
|
314
|
+
readonly modelId: string;
|
|
315
|
+
readonly thinkingLevel: ResolvedThinkingLevel;
|
|
316
|
+
}
|
|
312
317
|
/** Session statistics for /session command */
|
|
313
318
|
export interface SessionStats {
|
|
314
319
|
sessionFile: string | undefined;
|
|
@@ -327,6 +332,7 @@ export interface SessionStats {
|
|
|
327
332
|
};
|
|
328
333
|
premiumRequests: number;
|
|
329
334
|
cost: number;
|
|
335
|
+
costBreakdown?: Usage["cost"];
|
|
330
336
|
}
|
|
331
337
|
export type QueuedMessageEditMode = "steer" | "followUp";
|
|
332
338
|
export interface QueuedMessageEditEntry {
|
|
@@ -483,6 +489,16 @@ export declare class AgentSession {
|
|
|
483
489
|
* Call this when completely done with the session.
|
|
484
490
|
*/
|
|
485
491
|
dispose(): Promise<void>;
|
|
492
|
+
/**
|
|
493
|
+
* Strict writer close for ACP session delete. On the first attempt it flushes
|
|
494
|
+
* pending writes, then returns the certainty-aware close outcome so the caller
|
|
495
|
+
* can block destructive mutation on a non-`closed` result. When the manager
|
|
496
|
+
* retains a retryable writer (a prior `close_failed_retryable`), the flush is
|
|
497
|
+
* NOT repeated: the underlying writer rejects flushes while in the retryable
|
|
498
|
+
* state, and `SessionManager.closeStrict()` owns the flush/close sequencing so
|
|
499
|
+
* a second call can return `closed` once the OS close lands.
|
|
500
|
+
*/
|
|
501
|
+
closeWriterStrict(): Promise<SessionManagerCloseOutcome>;
|
|
486
502
|
/**
|
|
487
503
|
* Bounded, best-effort teardown of the subprocess-spawning resources this session
|
|
488
504
|
* owns: the browser tool's headless/spawned Chrome and the Python eval kernel + JS VM
|
|
@@ -509,6 +525,17 @@ export declare class AgentSession {
|
|
|
509
525
|
drainAsyncJobDeliveriesForAcp(options?: {
|
|
510
526
|
timeoutMs?: number;
|
|
511
527
|
}): Promise<boolean>;
|
|
528
|
+
/**
|
|
529
|
+
* Owner-scoped async-delivery snapshot used by the strict ACP delete
|
|
530
|
+
* quiescence barrier to PROVE quiescence after a best-effort drain. Unlike
|
|
531
|
+
* {@link drainAsyncJobDeliveriesForAcp}'s boolean return (which conflates
|
|
532
|
+
* "nothing to drain" with "timed out"), this reads the live state directly so
|
|
533
|
+
* any remaining queued/delivering work is observable and can block mutation.
|
|
534
|
+
*/
|
|
535
|
+
getAsyncDeliveryStateForAcp(): {
|
|
536
|
+
queued: number;
|
|
537
|
+
delivering: boolean;
|
|
538
|
+
};
|
|
512
539
|
/** Most recent assistant message in agent state. */
|
|
513
540
|
getLastAssistantMessage(): AssistantMessage | undefined;
|
|
514
541
|
/** Current effective system prompt blocks (includes any per-turn extension modifications) */
|
|
@@ -607,6 +634,8 @@ export declare class AgentSession {
|
|
|
607
634
|
get hasPostPromptWork(): boolean;
|
|
608
635
|
/** All messages including custom types like BashExecutionMessage */
|
|
609
636
|
get messages(): AgentMessage[];
|
|
637
|
+
/** Main startup calls this exactly once, after a strict open returned `kind: "opened"`. */
|
|
638
|
+
continuePersistedHistory(): Promise<void>;
|
|
610
639
|
buildDisplaySessionContext(): SessionContext;
|
|
611
640
|
/** Convert session messages using the same pre-LLM pipeline as the active session. */
|
|
612
641
|
convertMessagesToLlm(messages: AgentMessage[], signal?: AbortSignal): Promise<Message[]>;
|
|
@@ -830,6 +859,7 @@ export declare class AgentSession {
|
|
|
830
859
|
setModelTemporary(model: Model, thinkingLevel?: ThinkingLevel, options?: {
|
|
831
860
|
persistAsSessionDefault?: boolean;
|
|
832
861
|
}): Promise<void>;
|
|
862
|
+
setDefaultModelSelection(model: Model, thinkingLevel: ThinkingLevel | undefined): Promise<DefaultModelSelectionResult>;
|
|
833
863
|
/**
|
|
834
864
|
* Cycle to next/previous model.
|
|
835
865
|
* Uses scoped models (from --models flag) if available, otherwise all available models.
|
|
@@ -1084,9 +1114,13 @@ export declare class AgentSession {
|
|
|
1084
1114
|
promptText: string;
|
|
1085
1115
|
onTextDelta?: (delta: string) => void;
|
|
1086
1116
|
signal?: AbortSignal;
|
|
1117
|
+
/** Defer the successful roster-claim commit until the caller accepts its exchange. */
|
|
1118
|
+
deferRosterCommit?: boolean;
|
|
1087
1119
|
}): Promise<{
|
|
1088
1120
|
replyText: string;
|
|
1089
1121
|
assistantMessage: AssistantMessage;
|
|
1122
|
+
commitRosterClaim?: () => void;
|
|
1123
|
+
releaseRosterClaim?: () => void;
|
|
1090
1124
|
}>;
|
|
1091
1125
|
/**
|
|
1092
1126
|
* Reload the current session from disk.
|
|
@@ -1152,6 +1186,9 @@ export declare class AgentSession {
|
|
|
1152
1186
|
* otherwise estimates tokens for all messages.
|
|
1153
1187
|
*/
|
|
1154
1188
|
getContextUsage(): ContextUsage | undefined;
|
|
1189
|
+
getContextUsageObservabilityForTests(): {
|
|
1190
|
+
estimateCount: number;
|
|
1191
|
+
};
|
|
1155
1192
|
fetchUsageReports(signal?: AbortSignal): Promise<UsageReport[] | null>;
|
|
1156
1193
|
/**
|
|
1157
1194
|
* Export session to HTML.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { Usage } from "@sayknow-cli/ai";
|
|
2
|
+
export interface CacheEconomicsPricing {
|
|
3
|
+
input: number;
|
|
4
|
+
cacheRead: number;
|
|
5
|
+
cacheWrite: number;
|
|
6
|
+
}
|
|
7
|
+
export interface CacheEconomicsModelCost extends CacheEconomicsPricing {
|
|
8
|
+
output: number;
|
|
9
|
+
}
|
|
10
|
+
export type CacheEconomicsBasis = {
|
|
11
|
+
kind: "persisted-aggregate";
|
|
12
|
+
costBreakdown: Usage["cost"];
|
|
13
|
+
} | {
|
|
14
|
+
kind: "current-model-estimate";
|
|
15
|
+
pricing: CacheEconomicsPricing;
|
|
16
|
+
};
|
|
17
|
+
export interface CacheEconomicsUsage {
|
|
18
|
+
input: number;
|
|
19
|
+
output?: number;
|
|
20
|
+
cacheRead: number;
|
|
21
|
+
cacheWrite: number;
|
|
22
|
+
total?: number;
|
|
23
|
+
cost?: {
|
|
24
|
+
input?: number;
|
|
25
|
+
output?: number;
|
|
26
|
+
cacheRead?: number;
|
|
27
|
+
cacheWrite?: number;
|
|
28
|
+
total?: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface CacheMissCostSummary {
|
|
32
|
+
inputTokens: number;
|
|
33
|
+
cacheReadTokens: number;
|
|
34
|
+
cacheWriteTokens: number;
|
|
35
|
+
inputCostUsd: number;
|
|
36
|
+
cacheReadCostUsd: number;
|
|
37
|
+
cacheWriteCostUsd: number;
|
|
38
|
+
cacheHitRate: number | undefined;
|
|
39
|
+
missPremiumUsd: number | undefined;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* How a detected cache-miss pattern is attributed, per issue #2020.
|
|
43
|
+
*
|
|
44
|
+
* - `actionable`: usage evidence points to a user-controllable cause and SKC
|
|
45
|
+
* has a concrete remediation.
|
|
46
|
+
* - `diagnostic-only`: a miss pattern is observed but the cause is not
|
|
47
|
+
* determinable from usage alone; describe what is unknown, assert no cause.
|
|
48
|
+
* - `provider-side-suspected`: the provider returned no cache activity, so the
|
|
49
|
+
* miss cannot be attributed to the user's prompt; not user-actionable.
|
|
50
|
+
*/
|
|
51
|
+
export type CacheMissAttribution = "actionable" | "diagnostic-only" | "provider-side-suspected";
|
|
52
|
+
export interface CacheBehaviorWarning {
|
|
53
|
+
code: "expensive_cache_miss" | "cache_write_spike" | "provider_side_cache_miss";
|
|
54
|
+
attribution: CacheMissAttribution;
|
|
55
|
+
reason: string;
|
|
56
|
+
/** Concrete remediation — present only when `attribution` is `actionable`. */
|
|
57
|
+
nextStep?: string;
|
|
58
|
+
/** What SKC cannot determine — present for non-actionable attributions. */
|
|
59
|
+
unknown?: string;
|
|
60
|
+
costUsd: number;
|
|
61
|
+
}
|
|
62
|
+
export interface CacheWarningBuildState {
|
|
63
|
+
warningsEmitted: number;
|
|
64
|
+
}
|
|
65
|
+
export declare function computeCacheMissCostSummary(usage: CacheEconomicsUsage | undefined, basis: CacheEconomicsBasis): CacheMissCostSummary | undefined;
|
|
66
|
+
export declare function formatCacheMissSummaryLines(summary: CacheMissCostSummary): string[];
|
|
67
|
+
export declare function buildCacheBehaviorWarning(usage: Usage | undefined, model: {
|
|
68
|
+
cost: CacheEconomicsModelCost;
|
|
69
|
+
} | undefined | null): CacheBehaviorWarning | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Render a cache warning as a single transcript line. Actionable attributions
|
|
72
|
+
* carry a concrete next step; non-actionable ones state what is unknown and,
|
|
73
|
+
* for provider-side patterns, that the miss is not user-actionable — never
|
|
74
|
+
* asserting a cause or blaming the provider (#2020).
|
|
75
|
+
*/
|
|
76
|
+
export declare function formatCacheWarningLine(warning: CacheBehaviorWarning): string;
|
|
77
|
+
export declare function buildCacheEconomicsWarning(usage: Usage | undefined, model: {
|
|
78
|
+
cost: CacheEconomicsModelCost;
|
|
79
|
+
} | undefined | null, state: CacheWarningBuildState): string | undefined;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { Skill } from "../extensibility/skills";
|
|
2
|
+
import type { Tool } from "../tools";
|
|
3
|
+
import type { AgentSession } from "./agent-session";
|
|
4
|
+
export declare function estimateSkillsTokens(skills: readonly Skill[]): number;
|
|
5
|
+
export declare function estimateToolSchemaTokens(tools: ReadonlyArray<Pick<Tool, "name" | "description" | "parameters">>): number;
|
|
6
|
+
/**
|
|
7
|
+
* Compute just the NON-MESSAGE token total: system prompt (with its skills
|
|
8
|
+
* section subtracted, since skills are tokenized separately) + system context
|
|
9
|
+
* (the rest of the system-prompt array) + tools + skills.
|
|
10
|
+
*
|
|
11
|
+
* Exposed so callers like `StatusLineComponent` can cache the non-message
|
|
12
|
+
* total separately from the message total. Non-message inputs (skills,
|
|
13
|
+
* tools, system prompt) change rarely; the message list grows on every
|
|
14
|
+
* streaming turn. Splitting the two lets the caller refresh each on its own
|
|
15
|
+
* cadence — non-message recomputed only when the inputs identity changes,
|
|
16
|
+
* messages walked incrementally as new entries append.
|
|
17
|
+
*/
|
|
18
|
+
export declare function computeNonMessageTokens(session: AgentSession): number;
|
|
19
|
+
/**
|
|
20
|
+
* Shared helper for the four non-message token totals. Single source of truth
|
|
21
|
+
* for `computeNonMessageTokens` (session estimates + status-line incremental
|
|
22
|
+
* cache) and `computeContextBreakdown` (/context panel). The split avoids
|
|
23
|
+
* drift between the surfaces — they MUST report the same numbers.
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeNonMessageBreakdown(session: AgentSession): {
|
|
26
|
+
rulesTokens: number;
|
|
27
|
+
skillsTokens: number;
|
|
28
|
+
toolsTokens: number;
|
|
29
|
+
systemContextTokens: number;
|
|
30
|
+
systemPromptTokens: number;
|
|
31
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recognizes legacy provider safety-stop labels persisted before `errorKind`.
|
|
3
|
+
* Keep this anchored and conservative so incidental transient-error prose stays retryable.
|
|
4
|
+
*/
|
|
5
|
+
export declare function isLegacyProviderSafetyStopMessage(errorMessage: string): boolean;
|