@sayknow-cli/coding-agent 0.3.7 → 0.3.9
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/append-only-mode.d.ts +31 -0
- package/dist/types/capability/rule.d.ts +8 -0
- package/dist/types/cli/completion-cli.d.ts +41 -0
- package/dist/types/cli/config-cli.d.ts +1 -0
- package/dist/types/cli/fixture-report.d.ts +20 -0
- package/dist/types/cli/fixture-report.test.d.ts +1 -0
- package/dist/types/cli/nofile-limit.d.ts +11 -0
- package/dist/types/cli/notify-cli.d.ts +7 -0
- package/dist/types/cli/update-cli.d.ts +22 -0
- package/dist/types/cli.d.ts +124 -1
- package/dist/types/commands/completion.d.ts +29 -0
- package/dist/types/commands/config.d.ts +3 -0
- package/dist/types/commands/deep-interview.d.ts +3 -0
- package/dist/types/config/file-lock.d.ts +7 -6
- package/dist/types/config/keybindings.d.ts +2 -2
- package/dist/types/config/model-profile-activation.d.ts +6 -0
- package/dist/types/config/model-profiles.d.ts +1 -0
- package/dist/types/config/settings-schema.d.ts +119 -1
- package/dist/types/config/settings.d.ts +8 -0
- package/dist/types/discovery/index.d.ts +1 -0
- package/dist/types/export/html/template.generated.d.ts +1 -1
- package/dist/types/export/ttsr.d.ts +14 -3
- package/dist/types/extensibility/extensions/runner.d.ts +2 -1
- package/dist/types/extensibility/extensions/types.d.ts +8 -0
- package/dist/types/goals/runtime.d.ts +1 -0
- package/dist/types/hooks/native-skill-hook.d.ts +12 -0
- package/dist/types/main.d.ts +4 -1
- package/dist/types/modes/components/assistant-message.d.ts +5 -1
- package/dist/types/modes/components/model-selector.d.ts +4 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +12 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/status-line.d.ts +9 -0
- package/dist/types/modes/components/thinking-selector.d.ts +2 -2
- package/dist/types/modes/controllers/command-controller.d.ts +1 -0
- package/dist/types/modes/controllers/event-controller.d.ts +5 -0
- package/dist/types/modes/controllers/input-controller.d.ts +1 -3
- package/dist/types/modes/controllers/selector-controller.d.ts +1 -0
- package/dist/types/modes/interactive-mode.d.ts +4 -0
- package/dist/types/modes/print-mode.d.ts +13 -1
- package/dist/types/modes/prompt-action-autocomplete.d.ts +1 -1
- package/dist/types/modes/rpc/rpc-mode.d.ts +1 -3
- package/dist/types/modes/rpc/rpc-socket-security.d.ts +3 -0
- package/dist/types/modes/rpc/rpc-types.d.ts +14 -0
- package/dist/types/modes/shared/agent-wire/event-contract.d.ts +19 -0
- package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +23 -1
- package/dist/types/modes/types.d.ts +3 -0
- package/dist/types/modes/utils/injected-user-submission.d.ts +52 -0
- package/dist/types/modes/utils/ui-helpers.d.ts +1 -0
- package/dist/types/notifications/config-commands.d.ts +9 -0
- package/dist/types/notifications/config.d.ts +30 -1
- package/dist/types/notifications/daemon-paths.d.ts +1 -0
- package/dist/types/notifications/index.d.ts +8 -3
- package/dist/types/notifications/lifecycle-commands.d.ts +12 -3
- package/dist/types/notifications/lifecycle-control-runtime.d.ts +2 -1
- package/dist/types/notifications/reply-sent-store.d.ts +53 -0
- package/dist/types/notifications/rich-draft.d.ts +68 -0
- package/dist/types/notifications/rich-render.d.ts +90 -0
- package/dist/types/notifications/telegram-daemon.d.ts +45 -3
- package/dist/types/notifications/telegram-reference.d.ts +7 -5
- package/dist/types/notifications/threaded-render.d.ts +14 -0
- package/dist/types/runtime-api-key.d.ts +7 -0
- package/dist/types/sdk.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +61 -6
- package/dist/types/session/agent-storage.d.ts +1 -0
- package/dist/types/session/file-mention-pruning.d.ts +8 -0
- package/dist/types/session/messages.d.ts +4 -0
- package/dist/types/session/session-manager.d.ts +17 -1
- package/dist/types/skc-runtime/deep-interview-ambiguity.d.ts +39 -0
- package/dist/types/skc-runtime/deep-interview-recorder.d.ts +10 -1
- package/dist/types/skc-runtime/deep-interview-state.d.ts +17 -2
- package/dist/types/skc-runtime/session-state-sidecar.d.ts +7 -0
- package/dist/types/skc-runtime/state-writer.d.ts +3 -0
- package/dist/types/skc-runtime/tmux-common.d.ts +1 -0
- package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +42 -0
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +120 -13
- package/dist/types/skill-state/active-state.d.ts +18 -1
- package/dist/types/system-prompt.d.ts +18 -2
- package/dist/types/task/executor.d.ts +3 -0
- package/dist/types/task/fork-context-budget.d.ts +7 -0
- package/dist/types/task/token-log.d.ts +30 -0
- package/dist/types/task/token-log.test.d.ts +1 -0
- package/dist/types/tools/bisect.d.ts +81 -0
- package/dist/types/tools/computer.d.ts +2 -2
- package/dist/types/tools/index.d.ts +1 -0
- package/dist/types/tools/search.d.ts +2 -2
- package/dist/types/tools/ultragoal-ask-guard.d.ts +9 -2
- package/dist/types/utils/file-mentions.d.ts +14 -0
- package/dist/types/utils/git.d.ts +32 -0
- package/dist/types/utils/pasted-image-path.d.ts +30 -0
- package/dist/types/web/scrapers/youtube.d.ts +8 -0
- package/dist/types/workflow/workflow-intent-diff.d.ts +8 -2
- package/dist/types/workflow/workflow-intent-report-consumer.d.ts +50 -0
- package/dist/types/workflow/workflow-intent-report-schema.d.ts +2 -0
- package/dist/types/workflow/workflow-intent-report.d.ts +48 -0
- package/package.json +8 -8
- package/src/append-only-mode.ts +58 -0
- package/src/autoresearch/prompt.md +1 -1
- package/src/autoresearch/tools/log-experiment.ts +1 -1
- package/src/capability/rule.ts +9 -0
- package/src/cli/completion-cli.ts +234 -0
- package/src/cli/config-cli.ts +61 -9
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/fixture-report.test.ts +230 -0
- package/src/cli/fixture-report.ts +171 -0
- package/src/cli/nofile-limit.ts +48 -0
- package/src/cli/notify-cli.ts +103 -17
- package/src/cli/telegram-cli.ts +1 -1
- package/src/cli/update-cli.ts +148 -33
- package/src/cli.ts +29 -1
- package/src/commands/completion.ts +84 -0
- package/src/commands/config.ts +2 -0
- package/src/commands/contribution-prep.ts +1 -1
- package/src/commands/deep-interview.ts +2 -1
- package/src/config/file-lock.ts +73 -34
- package/src/config/keybindings.ts +3 -3
- package/src/config/model-profile-activation.ts +65 -0
- package/src/config/model-profiles.ts +31 -2
- package/src/config/settings-schema.ts +76 -1
- package/src/config/settings.ts +22 -0
- package/src/defaults/skc/skills/team/SKILL.md +17 -14
- package/src/defaults/skc/skills/ultragoal/SKILL.md +59 -4
- package/src/defaults/skc/skills/ultragoal/pipeline-validation-contracts.md +30 -0
- package/src/defaults/skc-defaults.ts +9 -0
- package/src/discovery/helpers.ts +10 -0
- package/src/discovery/index.ts +1 -0
- package/src/export/html/template.generated.ts +1 -1
- package/src/export/html/template.js +60 -2
- package/src/export/ttsr.ts +96 -18
- package/src/extensibility/extensions/runner.ts +183 -219
- package/src/extensibility/extensions/types.ts +9 -0
- package/src/extensibility/skc-plugins/runtime-adapters.ts +156 -44
- package/src/goals/runtime.ts +10 -2
- package/src/hindsight/backend.ts +1 -3
- package/src/hooks/native-skill-hook.ts +124 -4
- package/src/internal-urls/docs-index.generated.ts +17 -8
- package/src/lsp/client.ts +1 -0
- package/src/main.ts +95 -43
- package/src/memories/index.ts +12 -1
- package/src/modes/components/assistant-message.ts +241 -82
- package/src/modes/components/custom-editor.ts +1 -0
- package/src/modes/components/footer.ts +7 -2
- package/src/modes/components/model-selector.ts +54 -11
- package/src/modes/components/queued-message-selector.ts +92 -0
- package/src/modes/components/settings-selector.ts +4 -0
- package/src/modes/components/status-line.ts +167 -54
- package/src/modes/components/thinking-selector.ts +10 -8
- package/src/modes/components/tool-execution.ts +44 -19
- package/src/modes/components/welcome.ts +181 -44
- package/src/modes/controllers/command-controller.ts +40 -4
- package/src/modes/controllers/event-controller.ts +77 -49
- package/src/modes/controllers/extension-ui-controller.ts +12 -11
- package/src/modes/controllers/input-controller.ts +192 -35
- package/src/modes/controllers/selector-controller.ts +168 -24
- package/src/modes/interactive-mode.ts +56 -16
- package/src/modes/print-mode.ts +43 -4
- package/src/modes/prompt-action-autocomplete.ts +21 -20
- package/src/modes/rpc/rpc-mode.ts +32 -12
- package/src/modes/rpc/rpc-socket-security.ts +13 -1
- package/src/modes/rpc/rpc-types.ts +9 -0
- package/src/modes/shared/agent-wire/command-validation.ts +4 -0
- package/src/modes/shared/agent-wire/event-contract.ts +22 -0
- package/src/modes/shared/agent-wire/event-envelope.ts +82 -0
- package/src/modes/shared/agent-wire/scopes.ts +1 -0
- package/src/modes/types.ts +3 -0
- package/src/modes/utils/hotkeys-markdown.ts +1 -0
- package/src/modes/utils/injected-user-submission.ts +94 -0
- package/src/modes/utils/ui-helpers.ts +20 -7
- package/src/notifications/config-commands.ts +20 -0
- package/src/notifications/config.ts +52 -5
- package/src/notifications/daemon-paths.ts +2 -0
- package/src/notifications/index.ts +144 -18
- package/src/notifications/lifecycle-commands.ts +74 -23
- package/src/notifications/lifecycle-control-runtime.ts +8 -3
- package/src/notifications/lifecycle-orchestrator.ts +19 -6
- package/src/notifications/reply-sent-store.ts +134 -0
- package/src/notifications/rich-draft.ts +107 -0
- package/src/notifications/rich-render.ts +142 -0
- package/src/notifications/telegram-daemon-control.ts +5 -3
- package/src/notifications/telegram-daemon.ts +606 -98
- package/src/notifications/telegram-reference.ts +17 -16
- package/src/notifications/threaded-render.ts +45 -2
- package/src/prompts/agents/architect.md +19 -10
- package/src/prompts/agents/critic.md +16 -18
- package/src/prompts/agents/executor.md +14 -11
- package/src/prompts/agents/planner.md +18 -13
- package/src/prompts/ci-green-request.md +3 -8
- package/src/prompts/goals/goal-continuation.md +0 -5
- package/src/prompts/goals/goal-mode-active.md +0 -5
- package/src/prompts/system/agent-creation-architect.md +2 -2
- package/src/prompts/system/plan-mode-active.md +1 -1
- package/src/prompts/system/plan-mode-subagent.md +3 -3
- package/src/prompts/system/project-prompt.md +0 -13
- package/src/prompts/system/subagent-system-prompt.md +3 -2
- package/src/prompts/system/system-prompt.md +29 -17
- package/src/prompts/system/volatile-project-context.md +10 -0
- package/src/prompts/system/web-search.md +4 -7
- package/src/prompts/tools/apply-patch.md +6 -0
- package/src/prompts/tools/ast-edit.md +1 -0
- package/src/prompts/tools/bash.md +1 -1
- package/src/prompts/tools/bisect.md +22 -0
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/computer.md +2 -2
- package/src/prompts/tools/cron.md +0 -2
- package/src/prompts/tools/eval.md +2 -2
- package/src/prompts/tools/find.md +1 -1
- package/src/prompts/tools/github.md +6 -6
- package/src/prompts/tools/goal.md +1 -3
- package/src/prompts/tools/image-gen.md +12 -5
- package/src/prompts/tools/irc.md +5 -4
- package/src/prompts/tools/job.md +2 -2
- package/src/prompts/tools/lsp.md +1 -1
- package/src/prompts/tools/monitor.md +2 -2
- package/src/prompts/tools/patch.md +2 -2
- package/src/prompts/tools/replace.md +2 -21
- package/src/prompts/tools/rewind.md +1 -1
- package/src/prompts/tools/search-tool-bm25.md +6 -11
- package/src/prompts/tools/search.md +1 -1
- package/src/prompts/tools/skill.md +3 -2
- package/src/prompts/tools/ssh.md +2 -1
- package/src/prompts/tools/subagent.md +2 -2
- package/src/prompts/tools/task.md +4 -5
- package/src/prompts/tools/todo-write.md +1 -1
- package/src/prompts/tools/vim.md +1 -0
- package/src/prompts/tools/web-search.md +2 -0
- package/src/prompts/tools/write.md +8 -2
- package/src/runtime-api-key.ts +16 -0
- package/src/sdk.ts +88 -36
- package/src/session/agent-session.ts +1013 -141
- package/src/session/agent-storage.ts +4 -0
- package/src/session/file-mention-pruning.ts +64 -0
- package/src/session/messages.ts +4 -0
- package/src/session/session-manager.ts +103 -4
- package/src/skc-runtime/deep-interview-ambiguity.ts +206 -0
- package/src/skc-runtime/deep-interview-recorder.ts +62 -8
- package/src/skc-runtime/deep-interview-state.ts +44 -2
- package/src/skc-runtime/session-state-sidecar.ts +263 -20
- package/src/skc-runtime/state-runtime.ts +12 -2
- package/src/skc-runtime/state-writer.ts +15 -0
- package/src/skc-runtime/tmux-common.ts +1 -0
- package/src/skc-runtime/ultragoal-guard.ts +55 -66
- package/src/skc-runtime/ultragoal-receipt-freshness.ts +315 -0
- package/src/skc-runtime/ultragoal-runtime.ts +1672 -159
- package/src/skc-runtime/workflow-manifest.generated.json +113 -2
- package/src/skc-runtime/workflow-manifest.ts +74 -1
- package/src/skill-state/active-state.ts +141 -5
- package/src/skill-state/deep-interview-mutation-guard.ts +67 -3
- package/src/slash-commands/builtin-registry.ts +296 -72
- package/src/system-prompt.ts +57 -16
- package/src/task/executor.ts +132 -24
- package/src/task/fork-context-advisory.ts +2 -7
- package/src/task/fork-context-budget.ts +9 -0
- package/src/task/index.ts +13 -6
- package/src/task/output-manager.ts +20 -8
- package/src/task/receipt.ts +26 -7
- package/src/task/token-log.test.ts +188 -0
- package/src/task/token-log.ts +179 -0
- package/src/tools/bisect.ts +367 -0
- package/src/tools/computer.ts +246 -43
- package/src/tools/index.ts +3 -0
- package/src/tools/output-meta.ts +116 -4
- package/src/tools/search.ts +8 -2
- package/src/tools/skill.ts +15 -0
- package/src/tools/telegram-send.ts +6 -0
- package/src/tools/ultragoal-ask-guard.ts +39 -5
- package/src/utils/file-mentions.ts +39 -7
- package/src/utils/git.ts +73 -0
- package/src/utils/pasted-image-path.ts +170 -0
- package/src/web/scrapers/youtube.ts +24 -12
- package/src/workflow/workflow-intent-diff.ts +29 -6
- package/src/workflow/workflow-intent-report-consumer.ts +221 -0
- package/src/workflow/workflow-intent-report-schema.ts +129 -0
- package/src/workflow/workflow-intent-report.ts +135 -0
|
@@ -17,7 +17,8 @@
|
|
|
17
17
|
* Enable with Settings notifications config, `SKC_NOTIFICATIONS=1` (a token is
|
|
18
18
|
* generated), or `SKC_NOTIFICATIONS_TOKEN`.
|
|
19
19
|
*/
|
|
20
|
-
import
|
|
20
|
+
import { Settings } from "../config/settings";
|
|
21
|
+
import type { ExtensionAPI } from "../extensibility/extensions";
|
|
21
22
|
/** Where a `session_create` should run. Discriminated by `kind`. */
|
|
22
23
|
export type SessionCreateTarget = {
|
|
23
24
|
kind: "existing_path";
|
|
@@ -60,6 +61,8 @@ export interface SessionCreateFrame {
|
|
|
60
61
|
target: SessionCreateTarget;
|
|
61
62
|
/** Reference to the daemon-written, once-consumed startup-prompt file. */
|
|
62
63
|
startupPromptRef?: string;
|
|
64
|
+
/** Model profile preset to activate for the spawned session (--mpreset). */
|
|
65
|
+
modelPreset?: string;
|
|
63
66
|
}
|
|
64
67
|
/** Close (hard-kill, history preserved) a session. */
|
|
65
68
|
export interface SessionCloseFrame {
|
|
@@ -69,7 +72,7 @@ export interface SessionCloseFrame {
|
|
|
69
72
|
chatId: string;
|
|
70
73
|
token: string;
|
|
71
74
|
target: SessionCloseTarget;
|
|
72
|
-
/**
|
|
75
|
+
/** Required force-only close flag; false/omitted is rejected by daemon policy. */
|
|
73
76
|
force?: boolean;
|
|
74
77
|
}
|
|
75
78
|
/** Resume a session (reattach if alive, else cold-restart from history). */
|
|
@@ -173,4 +176,6 @@ export interface SessionReadyFrame {
|
|
|
173
176
|
*/
|
|
174
177
|
export declare function readGitRepoName(cwd: string): string | undefined;
|
|
175
178
|
export declare function notificationsEnabled(): boolean;
|
|
176
|
-
export declare
|
|
179
|
+
export declare function createNotificationsExtension(api: ExtensionAPI, options?: {
|
|
180
|
+
settings?: Settings;
|
|
181
|
+
}): void;
|
|
@@ -4,6 +4,7 @@ export type LifecycleCommandVerb = "session_create" | "session_close" | "session
|
|
|
4
4
|
export type ParsedLifecycleCommand = {
|
|
5
5
|
kind: "create";
|
|
6
6
|
target: SessionCreateTarget;
|
|
7
|
+
modelPreset?: string;
|
|
7
8
|
} | {
|
|
8
9
|
kind: "close";
|
|
9
10
|
target: SessionCloseTarget;
|
|
@@ -23,8 +24,13 @@ export type ParsedLifecycleCommand = {
|
|
|
23
24
|
} | {
|
|
24
25
|
kind: "none";
|
|
25
26
|
};
|
|
26
|
-
/** True when the text begins
|
|
27
|
-
export declare function
|
|
27
|
+
/** True when the text begins with any /session_* token, regardless of addressability. */
|
|
28
|
+
export declare function isLifecycleCommandLikeText(text: string | undefined): boolean;
|
|
29
|
+
/** True when the text begins an addressable /session_* command (cheap pre-gate). */
|
|
30
|
+
export declare function isLifecycleCommandText(text: string | undefined, ctx?: {
|
|
31
|
+
chatType?: string;
|
|
32
|
+
botUsername?: string;
|
|
33
|
+
}): boolean;
|
|
28
34
|
/**
|
|
29
35
|
* Parse a paired-chat message into a lifecycle command. Returns `none` for
|
|
30
36
|
* non-lifecycle text, `usage`/`reject` for malformed input (no side effect), or
|
|
@@ -33,7 +39,10 @@ export declare function isLifecycleCommandText(text: string | undefined): boolea
|
|
|
33
39
|
* The caller MUST have already enforced paired-chat authorization; this function
|
|
34
40
|
* performs grammar + target validation only.
|
|
35
41
|
*/
|
|
36
|
-
export declare function parseLifecycleCommand(text: string | undefined
|
|
42
|
+
export declare function parseLifecycleCommand(text: string | undefined, ctx?: {
|
|
43
|
+
chatType?: string;
|
|
44
|
+
botUsername?: string;
|
|
45
|
+
}): ParsedLifecycleCommand;
|
|
37
46
|
/** The canonical usage text (exported for the daemon's help replies). */
|
|
38
47
|
export declare function lifecycleUsage(): string;
|
|
39
48
|
/**
|
|
@@ -35,7 +35,8 @@ export declare function createRateLimiter(maxPerWindow: number, windowMs: number
|
|
|
35
35
|
* The launched session id is carried via `SKC_SESSION_ID` in the child env (see
|
|
36
36
|
* {@link daemonSpawnCreate}); the root `skc` launcher has no `--session-id`
|
|
37
37
|
* flag, so it must never appear in argv. Only flags the launch parser actually
|
|
38
|
-
* supports are emitted (`--worktree <branch>` for worktree targets
|
|
38
|
+
* supports are emitted (`--worktree <branch>` for worktree targets,
|
|
39
|
+
* `--mpreset <profile>` for model presets). */
|
|
39
40
|
export declare function buildCreateArgv(frame: SessionCreateFrame, _ids: {
|
|
40
41
|
intendedSessionId: string;
|
|
41
42
|
startupPromptRef?: string;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Index of rich messages the daemon sent, mapping `${chat_id}:${message_id}` to
|
|
3
|
+
* the original markdown. Telegram does not echo a `sendRichMessage` message's
|
|
4
|
+
* text in a reply's `reply_to_message`, so a user replying to a rich final
|
|
5
|
+
* answer would otherwise strand the agent without the quoted context. The daemon
|
|
6
|
+
* records the markdown on every promoted send and looks it up on inbound replies
|
|
7
|
+
* to restore that context.
|
|
8
|
+
*
|
|
9
|
+
* Fail-closed and off-path-neutral: nothing is recorded unless a send was
|
|
10
|
+
* actually promoted to rich, `record` is a no-op on any error (the in-memory map
|
|
11
|
+
* is only mutated after the atomic persist succeeds), and `lookup` returns
|
|
12
|
+
* undefined on any miss or error, so a bad index write/read never kills the
|
|
13
|
+
* daemon.
|
|
14
|
+
*/
|
|
15
|
+
import * as fs from "node:fs";
|
|
16
|
+
/**
|
|
17
|
+
* Minimal async filesystem surface the store needs. Structurally a subset of the
|
|
18
|
+
* daemon's `TelegramDaemonFs`, so the daemon can pass its own `fs` straight
|
|
19
|
+
* through and tests can inject a fake.
|
|
20
|
+
*/
|
|
21
|
+
export interface ReplySentStoreFs {
|
|
22
|
+
mkdir(path: string, opts?: fs.MakeDirectoryOptions): Promise<unknown>;
|
|
23
|
+
readFile(path: string, encoding: BufferEncoding): Promise<string>;
|
|
24
|
+
writeFile(path: string, data: string, opts?: fs.WriteFileOptions): Promise<void>;
|
|
25
|
+
rename(oldPath: string, newPath: string): Promise<void>;
|
|
26
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
27
|
+
}
|
|
28
|
+
export declare class ReplySentStore {
|
|
29
|
+
#private;
|
|
30
|
+
constructor(input: {
|
|
31
|
+
agentDir: string;
|
|
32
|
+
fs?: ReplySentStoreFs;
|
|
33
|
+
now?: () => number;
|
|
34
|
+
});
|
|
35
|
+
/** Restore the persisted index into memory. No-op on a missing or corrupt file. */
|
|
36
|
+
load(): Promise<void>;
|
|
37
|
+
/**
|
|
38
|
+
* Record the original markdown of a rich message the daemon just sent. The
|
|
39
|
+
* text is capped at {@link MAX_TEXT_LENGTH}; the index is capped at
|
|
40
|
+
* {@link MAX_ENTRIES} (oldest-by-timestamp evicted). No-op on any failure: the
|
|
41
|
+
* in-memory map is only replaced after the atomic persist succeeds.
|
|
42
|
+
*/
|
|
43
|
+
record(input: {
|
|
44
|
+
chatId: string | number;
|
|
45
|
+
messageId: number;
|
|
46
|
+
text: string;
|
|
47
|
+
}): Promise<void>;
|
|
48
|
+
/** Look up the original markdown for a message the daemon sent. undefined on miss or failure. */
|
|
49
|
+
lookup(input: {
|
|
50
|
+
chatId: string | number;
|
|
51
|
+
messageId: number;
|
|
52
|
+
}): string | undefined;
|
|
53
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Opt-in rich-draft streaming for a turn's in-progress preview.
|
|
3
|
+
*
|
|
4
|
+
* When the operator opts in (`richDraft.enabled`) the daemon streams LIVE turn
|
|
5
|
+
* markdown to the Bot API `sendRichMessageDraft` method as a debounced preview.
|
|
6
|
+
* Every failure is a harmless no-op (warn once, keep the daemon alive), and when
|
|
7
|
+
* off no draft call is ever made — so the off-state request bodies stay
|
|
8
|
+
* byte-identical.
|
|
9
|
+
*/
|
|
10
|
+
import type { BotApi } from "./telegram-daemon";
|
|
11
|
+
import type { ThreadedSend } from "./threaded-render";
|
|
12
|
+
/** Minimum gap between two draft sends for one session (debounce floor). */
|
|
13
|
+
export declare const DRAFT_DEBOUNCE_MS = 1500;
|
|
14
|
+
/**
|
|
15
|
+
* Wrap raw markdown + a monotonic draft id in the `sendRichMessageDraft` request
|
|
16
|
+
* payload shape: mirrors `buildRichMessage`'s proven `rich_message.markdown`
|
|
17
|
+
* content wrapper, with a top-level `draft_id` selecting the draft revision to
|
|
18
|
+
* update (a routing param, like `message_thread_id`).
|
|
19
|
+
*/
|
|
20
|
+
export declare function buildRichDraft(draftId: number, raw: string): {
|
|
21
|
+
draft_id: number;
|
|
22
|
+
rich_message: {
|
|
23
|
+
markdown: string;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Whether a granted send should stream a rich draft. Fail-closed: every clause
|
|
28
|
+
* must hold, otherwise no draft is sent. Mirrors `shouldPromoteRich` but targets
|
|
29
|
+
* the LIVE lane and the live-only `richDraftMarkdown` marker (set by
|
|
30
|
+
* `renderThreadedFrame` for non-finalized turn frames).
|
|
31
|
+
*/
|
|
32
|
+
export declare function shouldStreamDraft(input: {
|
|
33
|
+
enabled?: boolean;
|
|
34
|
+
send: ThreadedSend;
|
|
35
|
+
}): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Per-session debounce + monotonic draft-id state for draft streaming. Skips a
|
|
38
|
+
* draft when less than `debounceMs` has elapsed since the session's last SENT
|
|
39
|
+
* draft (the rate-limit pool already coalesces live frames to the latest, so a
|
|
40
|
+
* skipped frame is naturally superseded by the next one). `reset` clears a
|
|
41
|
+
* session's window when its turn finalizes so the next turn starts fresh.
|
|
42
|
+
*/
|
|
43
|
+
export declare class DraftStreamState {
|
|
44
|
+
#private;
|
|
45
|
+
constructor(debounceMs?: number);
|
|
46
|
+
/**
|
|
47
|
+
* If enough time has elapsed since the session's last draft, record `now` as
|
|
48
|
+
* the new last-sent time and return the next monotonic draft id; otherwise
|
|
49
|
+
* return `undefined` (debounced — the caller skips this frame).
|
|
50
|
+
*/
|
|
51
|
+
tryClaim(sessionId: string, now: number): number | undefined;
|
|
52
|
+
/** Clear a session's debounce window (called when its turn finalizes). The
|
|
53
|
+
* global draft id keeps incrementing so ids are never reused across turns. */
|
|
54
|
+
reset(sessionId: string): void;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Best-effort delivery of a rich draft. Never throws and has no HTML fallback: a
|
|
58
|
+
* draft is a purely additive preview, so on any failure (a thrown transport
|
|
59
|
+
* error or an `{ ok: false }` JSON response — the transport returns `res.json()`
|
|
60
|
+
* for JSON methods, so `ok:false` does not throw) it warns exactly once and
|
|
61
|
+
* returns; the unchanged live HTML send still carries the content.
|
|
62
|
+
*/
|
|
63
|
+
export declare function deliverDraft(botApi: BotApi, base: {
|
|
64
|
+
chat_id: string | number;
|
|
65
|
+
message_thread_id?: number;
|
|
66
|
+
}, draftId: number, raw: string, log?: {
|
|
67
|
+
warn(msg: string): void;
|
|
68
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rich-message promotion for stable non-editable Telegram text sends.
|
|
3
|
+
*
|
|
4
|
+
* When enabled, the daemon promotes eligible finalized `sendMessage` payloads
|
|
5
|
+
* carrying raw markdown to the Bot API `sendRichMessage` method. On any miss or
|
|
6
|
+
* failure the daemon keeps the unchanged HTML `sendMessage` path, so the
|
|
7
|
+
* off-state request bodies are byte-identical.
|
|
8
|
+
*/
|
|
9
|
+
import type { BotApi } from "./telegram-daemon";
|
|
10
|
+
import type { ThreadedSend } from "./threaded-render";
|
|
11
|
+
/**
|
|
12
|
+
* Telegram's hard per-message character ceiling (4096). Surfaced here purely as
|
|
13
|
+
* documentation and a marker for a future native rich-message splitter — it is
|
|
14
|
+
* intentionally NON-BEHAVIORAL and MUST stay that way: nothing in the rich path
|
|
15
|
+
* branches on this value.
|
|
16
|
+
*
|
|
17
|
+
* Overflow is already safe without it. The production final-answer text is capped
|
|
18
|
+
* at 3500 chars upstream (`summaryFromMessage(..., 3500)`), so a promoted
|
|
19
|
+
* `sendRichMessage` never approaches this ceiling; and if the Bot API ever rejects
|
|
20
|
+
* an oversized rich payload it returns `{ ok: false }`, which
|
|
21
|
+
* `deliverRichWithFallback` (below) turns into the chunked HTML `splitTelegramHtml`
|
|
22
|
+
* fallback (each chunk ≤ TELEGRAM_MESSAGE_LIMIT). This constant only marks where a
|
|
23
|
+
* future rich splitter would read its ceiling; wiring it into a branch would change
|
|
24
|
+
* byte-for-byte behavior and is out of scope.
|
|
25
|
+
*/
|
|
26
|
+
export declare const RICH_MESSAGE_LIMIT = 4096;
|
|
27
|
+
/** Wrap raw markdown in the `sendRichMessage` request payload shape. */
|
|
28
|
+
export declare function buildRichMessage(raw: string, extras?: {
|
|
29
|
+
reply_markup?: unknown;
|
|
30
|
+
}): {
|
|
31
|
+
rich_message: {
|
|
32
|
+
markdown: string;
|
|
33
|
+
};
|
|
34
|
+
reply_markup?: unknown;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Whether a granted send should be promoted to `sendRichMessage`. Fail-closed
|
|
38
|
+
* and class-aware: every clause must hold, otherwise the daemon keeps the HTML path.
|
|
39
|
+
*/
|
|
40
|
+
export declare function shouldPromoteRich(input: {
|
|
41
|
+
enabled?: boolean;
|
|
42
|
+
send: ThreadedSend;
|
|
43
|
+
}): boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Deliver the promoted rich message, falling back to `fallbackDeliver` (the
|
|
46
|
+
* unchanged HTML `sendMessage` loop) on any failure. A failure is either a
|
|
47
|
+
* thrown transport error or a `{ ok: false }` JSON response (the transport
|
|
48
|
+
* returns `res.json()` for JSON methods, so `ok:false` does not throw). On
|
|
49
|
+
* failure exactly one diagnostic is logged before the fallback runs; on success
|
|
50
|
+
* the fallback never runs.
|
|
51
|
+
*
|
|
52
|
+
* Returns the sent message's `message_id` on success (when the response carries
|
|
53
|
+
* one), otherwise `undefined` — including every failure/fallback path and a
|
|
54
|
+
* success whose response omits `result.message_id`. Callers that ignore the
|
|
55
|
+
* return value are unaffected.
|
|
56
|
+
*/
|
|
57
|
+
export declare function deliverRichWithFallback(botApi: BotApi, base: {
|
|
58
|
+
chat_id: string | number;
|
|
59
|
+
message_thread_id?: number;
|
|
60
|
+
}, send: ThreadedSend, fallbackDeliver: () => Promise<void>, log?: {
|
|
61
|
+
warn(msg: string): void;
|
|
62
|
+
}): Promise<number | undefined>;
|
|
63
|
+
/**
|
|
64
|
+
* Deliver an action-needed (ask/idle) message via `sendRichMessage`, falling
|
|
65
|
+
* back to the unchanged HTML chunk loop on any failure. Mirrors
|
|
66
|
+
* {@link deliverRichWithFallback} but takes an explicit markdown body plus an
|
|
67
|
+
* optional top-level `reply_markup` (probe-confirmed: `sendRichMessage` accepts
|
|
68
|
+
* `reply_markup` alongside `rich_message`), and surfaces a structured outcome so
|
|
69
|
+
* the daemon can route inbound replies to the resulting message id.
|
|
70
|
+
*
|
|
71
|
+
* On rich success: returns `{ messageId, usedRich: true, usedFallback: false }`
|
|
72
|
+
* where `messageId` is `res.result.message_id` when present. On a `{ ok:false }`
|
|
73
|
+
* response or a thrown transport error: warns exactly once, runs `htmlFallback`,
|
|
74
|
+
* and returns `{ messageId, usedRich: false, usedFallback: true }` where
|
|
75
|
+
* `messageId` is the fallback's return value (the last HTML chunk's id).
|
|
76
|
+
*/
|
|
77
|
+
export declare function deliverRichActionWithFallback(botApi: BotApi, base: {
|
|
78
|
+
chat_id: string | number;
|
|
79
|
+
message_thread_id?: number;
|
|
80
|
+
}, opts: {
|
|
81
|
+
markdown: string;
|
|
82
|
+
replyMarkup?: unknown;
|
|
83
|
+
requireMessageId?: boolean;
|
|
84
|
+
}, htmlFallback: () => Promise<number | undefined>, log?: {
|
|
85
|
+
warn(msg: string): void;
|
|
86
|
+
}): Promise<{
|
|
87
|
+
messageId?: number;
|
|
88
|
+
usedRich: boolean;
|
|
89
|
+
usedFallback: boolean;
|
|
90
|
+
}>;
|
|
@@ -3,8 +3,8 @@ import type { Settings } from "../config/settings";
|
|
|
3
3
|
import type { DaemonRuntimeInfo } from "../daemon/control-types";
|
|
4
4
|
import { type ControlServerLike, type LifecycleControlServerFactory } from "./lifecycle-control-runtime";
|
|
5
5
|
import { NotificationOperatorRuntime, OperatorBackoffPolicy } from "./operator-runtime";
|
|
6
|
-
import { type AliasTable, type CallbackRoute
|
|
7
|
-
export type EnsureDaemonResult = "owner_spawned" | "attached" | "disabled";
|
|
6
|
+
import { type AliasTable, type CallbackRoute } from "./telegram-reference";
|
|
7
|
+
export type EnsureDaemonResult = "owner_spawned" | "attached" | "disabled" | "blocked";
|
|
8
8
|
export interface DaemonState {
|
|
9
9
|
pid: number;
|
|
10
10
|
ownerId: string;
|
|
@@ -95,6 +95,8 @@ export declare function acquireDaemonOwnership(input: {
|
|
|
95
95
|
acquired: boolean;
|
|
96
96
|
ownerId?: string;
|
|
97
97
|
attached?: boolean;
|
|
98
|
+
blocked?: boolean;
|
|
99
|
+
reason?: "identity_mismatch";
|
|
98
100
|
}>;
|
|
99
101
|
export declare function renewDaemonHeartbeat(input: {
|
|
100
102
|
settings: Settings;
|
|
@@ -229,6 +231,14 @@ export interface TelegramDaemonOptions {
|
|
|
229
231
|
* default applies (e.g. lifecycle control disabled), no control server starts.
|
|
230
232
|
*/
|
|
231
233
|
createLifecycleControlServer?: LifecycleControlServerFactory | null;
|
|
234
|
+
/** Rich text promotion (enabled by default; see rich-render.ts). */
|
|
235
|
+
rich?: {
|
|
236
|
+
enabled: boolean;
|
|
237
|
+
};
|
|
238
|
+
/** Opt-in rich-draft streaming of live turn previews (off by default; see rich-draft.ts). */
|
|
239
|
+
richDraft?: {
|
|
240
|
+
enabled: boolean;
|
|
241
|
+
};
|
|
232
242
|
}
|
|
233
243
|
interface SessionSocket {
|
|
234
244
|
sessionId: string;
|
|
@@ -252,6 +262,8 @@ export declare class TelegramNotificationDaemon {
|
|
|
252
262
|
private readonly opts;
|
|
253
263
|
readonly aliasTable: AliasTable;
|
|
254
264
|
readonly messageRoutes: Map<string | number, CallbackRoute | Omit<CallbackRoute, "answer">>;
|
|
265
|
+
/** Telegram message id backing each streamed `${sessionId}:${coalesceKey}`, for in-place edits. */
|
|
266
|
+
private readonly liveMessages;
|
|
255
267
|
readonly sessions: Map<string, SessionSocket>;
|
|
256
268
|
private readonly runtime;
|
|
257
269
|
private readonly sessionRouter;
|
|
@@ -264,6 +276,10 @@ export declare class TelegramNotificationDaemon {
|
|
|
264
276
|
private readonly pool;
|
|
265
277
|
private readonly poller;
|
|
266
278
|
private readonly dispatchState;
|
|
279
|
+
/** Original markdown of rich messages we sent (chat+message_id), for restoring reply context on inbound replies. */
|
|
280
|
+
private readonly replyStore;
|
|
281
|
+
/** Per-session debounce + monotonic draft-id state for opt-in draft streaming. */
|
|
282
|
+
private readonly draftStream;
|
|
267
283
|
/** Identity-bearing sessions by repo/branch surface, used to avoid transient duplicate topics. */
|
|
268
284
|
private readonly topicOwnerByIdentity;
|
|
269
285
|
/** Non-identity frames held until identity creates the correct thread. */
|
|
@@ -276,6 +292,8 @@ export declare class TelegramNotificationDaemon {
|
|
|
276
292
|
private readonly flatIdentitySent;
|
|
277
293
|
/** Cached result of whether the paired chat is a private chat (flat-fallback gate). */
|
|
278
294
|
private pairedChatPrivate;
|
|
295
|
+
/** Bot username from getMe, cached once at owner startup for group/forum command targeting. */
|
|
296
|
+
private botUsername;
|
|
279
297
|
/** Sessions whose agent loop is currently busy (drives the typing indicator). */
|
|
280
298
|
private get busy();
|
|
281
299
|
/** Inbound update id → originating Telegram message, for delivery reactions. */
|
|
@@ -317,12 +335,17 @@ export declare class TelegramNotificationDaemon {
|
|
|
317
335
|
/** Build an authenticated lifecycle frame from a parsed command + identity. */
|
|
318
336
|
private buildLifecycleFrame;
|
|
319
337
|
private handleLifecycleCommand;
|
|
338
|
+
private refreshBotIdentity;
|
|
320
339
|
/** Map a lifecycle response/error to a user-facing message (G010 surfacing). */
|
|
321
340
|
private formatLifecycleResponse;
|
|
322
341
|
constructor(opts: TelegramDaemonOptions);
|
|
323
342
|
private createSessionRouter;
|
|
324
343
|
loadAliases(): Promise<void>;
|
|
325
344
|
persistAliases(): Promise<void>;
|
|
345
|
+
loadSeenUpdateIds(): Promise<void>;
|
|
346
|
+
persistSeenUpdateIds(): Promise<void>;
|
|
347
|
+
private pruneSeenUpdateIds;
|
|
348
|
+
private rememberSeenUpdateId;
|
|
326
349
|
scanRoots(): Promise<void>;
|
|
327
350
|
connectSession(sessionId: string, url: string, token: string): void;
|
|
328
351
|
/**
|
|
@@ -340,12 +363,15 @@ export declare class TelegramNotificationDaemon {
|
|
|
340
363
|
* the socket. `scanRoots()` then reconnects the session.
|
|
341
364
|
*/
|
|
342
365
|
private dropSession;
|
|
366
|
+
private deleteMessageRoutes;
|
|
343
367
|
private static readonly THREADED_FRAMES;
|
|
344
368
|
private topicNameFor;
|
|
345
369
|
private topicIdentityKey;
|
|
346
370
|
private topicIdentityBase;
|
|
347
371
|
private topicOwnerForIdentity;
|
|
372
|
+
private sessionCanClaimIdentity;
|
|
348
373
|
private submitThreadedFrame;
|
|
374
|
+
private existingTopicForPrivateChat;
|
|
349
375
|
private rememberPendingThreadedFrame;
|
|
350
376
|
private flushPendingThreadedFrames;
|
|
351
377
|
private ensureTopic;
|
|
@@ -362,7 +388,23 @@ export declare class TelegramNotificationDaemon {
|
|
|
362
388
|
private ensureAttachmentDir;
|
|
363
389
|
private cleanupAllAttachmentDirs;
|
|
364
390
|
private resolveInboundAttachment;
|
|
391
|
+
/**
|
|
392
|
+
* Serialize all pool flushes. Every caller (`submitThreadedFrame`, the flat
|
|
393
|
+
* fallback, the drain timer's `void this.flushPool()`, topic teardown) goes
|
|
394
|
+
* through one promise chain, so two flushes never interleave — a live send can
|
|
395
|
+
* never be in-flight while a finalized flush reads `liveMessages` and decides
|
|
396
|
+
* to post a fresh (duplicate) final. Errors are swallowed so one failed flush
|
|
397
|
+
* never poisons the queue (each flush is already best-effort internally).
|
|
398
|
+
*/
|
|
399
|
+
private flushChain;
|
|
365
400
|
private flushPool;
|
|
401
|
+
private flushPoolInner;
|
|
402
|
+
/**
|
|
403
|
+
* Track the Telegram message id backing a streamed `(sessionId, coalesceKey)`
|
|
404
|
+
* so later live/finalized frames edit it in place. Evicts this session's stale
|
|
405
|
+
* same-category entries (e.g. prior turns) so the map stays bounded.
|
|
406
|
+
*/
|
|
407
|
+
private recordLiveMessage;
|
|
366
408
|
private deliverFlatFallback;
|
|
367
409
|
private pairedChatIsPrivate;
|
|
368
410
|
private notifyThreadedFallback;
|
|
@@ -376,7 +418,7 @@ export declare class TelegramNotificationDaemon {
|
|
|
376
418
|
private startTypingTimer;
|
|
377
419
|
private stopTypingTimer;
|
|
378
420
|
handleSessionMessage(session: SessionSocket, msg: any): Promise<void>;
|
|
379
|
-
|
|
421
|
+
private answerCallbackQueryBestEffort;
|
|
380
422
|
private sendStaleGuidance;
|
|
381
423
|
handleTelegramUpdate(update: unknown): Promise<void>;
|
|
382
424
|
pollOnce(signal?: AbortSignal): Promise<number>;
|
|
@@ -59,6 +59,13 @@ export declare function buildActionMessage(action: {
|
|
|
59
59
|
options?: string[];
|
|
60
60
|
summary?: string;
|
|
61
61
|
}): RenderedMessage;
|
|
62
|
+
/** Render an `action_needed` body as raw markdown (rich-message source; the HTML fallback stays on buildActionMessage). */
|
|
63
|
+
export declare function buildActionMarkdown(action: {
|
|
64
|
+
kind: "ask" | "idle";
|
|
65
|
+
question?: string;
|
|
66
|
+
options?: string[];
|
|
67
|
+
summary?: string;
|
|
68
|
+
}): string;
|
|
62
69
|
/** Send Telegram HTML text chunks sequentially so long messages preserve order. */
|
|
63
70
|
export declare function sendTelegramHtmlChunks(send: TelegramSend, chatId: string, text: string, inlineKeyboard?: InlineButton[][]): Promise<void>;
|
|
64
71
|
/** A protocol `reply` frame the client should send to the server. */
|
|
@@ -81,14 +88,9 @@ export type RouteDecision = ({
|
|
|
81
88
|
} | {
|
|
82
89
|
kind: "ignore";
|
|
83
90
|
};
|
|
84
|
-
export interface PendingAsk {
|
|
85
|
-
sessionId: string;
|
|
86
|
-
actionId: string;
|
|
87
|
-
}
|
|
88
91
|
export interface RouteInboundContext {
|
|
89
92
|
aliasTable: Pick<AliasTable, "get">;
|
|
90
93
|
messageRoutes: Map<string | number, CallbackRoute | Omit<CallbackRoute, "answer">>;
|
|
91
|
-
pendingBySession: (sessionId?: string) => PendingAsk[];
|
|
92
94
|
pairedChatId: string;
|
|
93
95
|
}
|
|
94
96
|
/** Route a Telegram update to a session/action without I/O. Fail closed under ambiguity. */
|
|
@@ -28,6 +28,19 @@ export interface ThreadedSend {
|
|
|
28
28
|
coalesceKey?: string;
|
|
29
29
|
/** True for the one-time identity header (the daemon pins it once). */
|
|
30
30
|
identity?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* When true the daemon may deliver this as an in-place edit of the message
|
|
33
|
+
* previously sent under the same `(sessionId, coalesceKey)` instead of a new
|
|
34
|
+
* message. Set for streamed turn frames so live + finalized share one message.
|
|
35
|
+
*/
|
|
36
|
+
editable?: boolean;
|
|
37
|
+
/** Rich message class metadata. Only finalized final-answer sends are ever
|
|
38
|
+
* rich-promoted; the daemon gate (`shouldPromoteRich`) requires exactly this. */
|
|
39
|
+
richClass?: "final";
|
|
40
|
+
/** Rich final-answer markdown (raw). Delivery marker derived ONLY from a frame's `finalAnswer` bit; never inferred from `phase`. */
|
|
41
|
+
richMarkdown?: string;
|
|
42
|
+
/** Live-turn raw markdown for opt-in draft streaming (set ONLY on non-finalized turn frames; never triggers rich-final promotion, which requires `lane === "finalized"`). */
|
|
43
|
+
richDraftMarkdown?: string;
|
|
31
44
|
}
|
|
32
45
|
interface ThreadedFrame {
|
|
33
46
|
type?: unknown;
|
|
@@ -44,6 +57,7 @@ interface ThreadedFrame {
|
|
|
44
57
|
diff?: unknown;
|
|
45
58
|
cwd?: unknown;
|
|
46
59
|
phase?: unknown;
|
|
60
|
+
finalAnswer?: boolean;
|
|
47
61
|
text?: unknown;
|
|
48
62
|
messageRef?: unknown;
|
|
49
63
|
source?: unknown;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export interface RuntimeApiKeyTarget {
|
|
2
|
+
setRuntimeApiKey(provider: string, apiKey: string): void;
|
|
3
|
+
}
|
|
4
|
+
export interface RuntimeApiKeyModel {
|
|
5
|
+
provider: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function applyCliRuntimeApiKeyOverride(target: RuntimeApiKeyTarget, apiKey: string | undefined, model: RuntimeApiKeyModel | undefined): void;
|
package/dist/types/sdk.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type AgentTelemetryConfig, type ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
2
2
|
import { type Model, type ProviderSessionState } from "@sayknow-cli/ai";
|
|
3
|
+
import { createAppendOnlyContextManager, providerSupportsAppendOnlyAuto, resolveAppendOnlyMode } from "./append-only-mode";
|
|
3
4
|
import { type Rule } from "./capability/rule";
|
|
4
5
|
import { ModelRegistry } from "./config/model-registry";
|
|
5
6
|
import { type ScopedModelSelection } from "./config/model-resolver";
|
|
@@ -241,5 +242,7 @@ export interface BuildSystemPromptOptions {
|
|
|
241
242
|
* as separate entries so providers can cache prompt prefixes without concatenating blocks.
|
|
242
243
|
*/
|
|
243
244
|
export declare function buildSystemPrompt(options?: BuildSystemPromptOptions): Promise<BuildSystemPromptResult>;
|
|
245
|
+
export { createAppendOnlyContextManager, providerSupportsAppendOnlyAuto, resolveAppendOnlyMode };
|
|
244
246
|
export declare function createPluginHooksExtension(hooks: ConstrainedPluginHook[]): ExtensionFactory;
|
|
247
|
+
export declare function resolveIntentTracingEnabled(intentTracingSetting: boolean | undefined, hasUI: boolean): boolean;
|
|
245
248
|
export declare function createAgentSession(options?: CreateAgentSessionOptions): Promise<CreateAgentSessionResult>;
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { type Agent, type AgentEvent, type AgentMessage, type AgentState, type AgentTool, 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, ToolChoice, UsageReport } from "@sayknow-cli/ai";
|
|
17
|
+
import type { AssistantMessage, Effort, ImageContent, Message, MessageAttribution, Model, ProviderSessionState, ServiceTier, SimpleStreamOptions, TextContent, ToolCall, ToolChoice, UsageReport } from "@sayknow-cli/ai";
|
|
18
18
|
export interface ForkContextSeedMetadata {
|
|
19
19
|
sourceSessionId: string;
|
|
20
20
|
parentMessageCount: number;
|
|
@@ -75,6 +75,7 @@ import { type DiscoverableTool, type DiscoverableToolSearchIndex } from "../tool
|
|
|
75
75
|
import type { AskAnswerSource, ToolSession } from "../tools";
|
|
76
76
|
import type { CheckpointState } from "../tools/checkpoint";
|
|
77
77
|
import { type TodoItem, type TodoPhase } from "../tools/todo-write";
|
|
78
|
+
import { type WorkspaceTree } from "../workspace-tree";
|
|
78
79
|
import type { ClientBridge } from "./client-bridge";
|
|
79
80
|
import { type ContributionPrepOptions, type ContributionPrepResult } from "./contribution-prep";
|
|
80
81
|
import { type CustomMessage } from "./messages";
|
|
@@ -159,7 +160,7 @@ export interface AgentSessionConfig {
|
|
|
159
160
|
agent: Agent;
|
|
160
161
|
sessionManager: SessionManager;
|
|
161
162
|
settings: Settings;
|
|
162
|
-
/** Models to cycle through with
|
|
163
|
+
/** Models to cycle through with Alt+N (from --models flag) */
|
|
163
164
|
scopedModels?: ScopedModelSelection[];
|
|
164
165
|
/** Initial session thinking selector. */
|
|
165
166
|
thinkingLevel?: ThinkingLevel;
|
|
@@ -200,6 +201,8 @@ export interface AgentSessionConfig {
|
|
|
200
201
|
rebuildSystemPrompt?: (toolNames: string[], tools: Map<string, AgentTool>) => Promise<{
|
|
201
202
|
systemPrompt: string[];
|
|
202
203
|
}>;
|
|
204
|
+
/** Initial workspace tree snapshot used for the first volatile per-turn context message. */
|
|
205
|
+
workspaceTree?: WorkspaceTree;
|
|
203
206
|
/** Rebuild the SSH tool from current capability discovery results. */
|
|
204
207
|
reloadSshTool?: () => Promise<AgentTool | null>;
|
|
205
208
|
requestedToolNames?: ReadonlySet<string>;
|
|
@@ -317,6 +320,13 @@ export interface SessionStats {
|
|
|
317
320
|
premiumRequests: number;
|
|
318
321
|
cost: number;
|
|
319
322
|
}
|
|
323
|
+
export type QueuedMessageEditMode = "steer" | "followUp";
|
|
324
|
+
export interface QueuedMessageEditEntry {
|
|
325
|
+
id: string;
|
|
326
|
+
text: string;
|
|
327
|
+
mode: QueuedMessageEditMode;
|
|
328
|
+
label: string;
|
|
329
|
+
}
|
|
320
330
|
/** A custom message contributed at the before-agent-start point. */
|
|
321
331
|
export type BeforeAgentStartInternalMessage = Pick<CustomMessage, "customType" | "content" | "display" | "details" | "attribution">;
|
|
322
332
|
/**
|
|
@@ -329,6 +339,33 @@ export type BeforeAgentStartContributor = (event: {
|
|
|
329
339
|
images?: ImageContent[];
|
|
330
340
|
sessionId: string | undefined;
|
|
331
341
|
}) => Promise<BeforeAgentStartInternalMessage | undefined>;
|
|
342
|
+
export declare class WorkerIntegrationRequestScheduler {
|
|
343
|
+
#private;
|
|
344
|
+
readonly request: () => Promise<void>;
|
|
345
|
+
constructor(request: () => Promise<void>);
|
|
346
|
+
enqueue(): void;
|
|
347
|
+
flush(): Promise<void>;
|
|
348
|
+
}
|
|
349
|
+
export type StreamingEditParsedToolCall = {
|
|
350
|
+
toolCall: ToolCall;
|
|
351
|
+
path: string;
|
|
352
|
+
resolvedPath: string;
|
|
353
|
+
diff?: string;
|
|
354
|
+
op?: string;
|
|
355
|
+
rename?: string;
|
|
356
|
+
};
|
|
357
|
+
export type StreamingEditParsedCacheEntry = {
|
|
358
|
+
version: string;
|
|
359
|
+
parsed: StreamingEditParsedToolCall | undefined;
|
|
360
|
+
};
|
|
361
|
+
export declare function getStreamingEditToolCallForEvent(event: AgentEvent, cache: Map<string, StreamingEditParsedCacheEntry>, resolvePath: (filePath: string) => string | undefined): StreamingEditParsedToolCall | undefined;
|
|
362
|
+
/** Test-only counters for AgentSession event fan-out hot-path assertions. */
|
|
363
|
+
export declare const __agentSessionPerfCounters: {
|
|
364
|
+
listenerSnapshotRebuilds: number;
|
|
365
|
+
messageUpdateExtensionQueues: number;
|
|
366
|
+
reset(): void;
|
|
367
|
+
};
|
|
368
|
+
export declare function buildContextInjectionSignature(kind: string, parts: readonly string[]): string;
|
|
332
369
|
export declare class AgentSession {
|
|
333
370
|
#private;
|
|
334
371
|
readonly agent: Agent;
|
|
@@ -337,6 +374,13 @@ export declare class AgentSession {
|
|
|
337
374
|
readonly taskDepth: number;
|
|
338
375
|
readonly yieldQueue: YieldQueue;
|
|
339
376
|
readonly configWarnings: string[];
|
|
377
|
+
readonly streamingEditDebugCounters: {
|
|
378
|
+
guardRuns: number;
|
|
379
|
+
processedChars: number;
|
|
380
|
+
checkedRemovedLines: number;
|
|
381
|
+
fullChecks: number;
|
|
382
|
+
nonEditDeterminations: number;
|
|
383
|
+
};
|
|
340
384
|
readonly rawSseDebugBuffer: RawSseDebugBuffer;
|
|
341
385
|
constructor(config: AgentSessionConfig);
|
|
342
386
|
/** Model registry for API key resolution and model discovery */
|
|
@@ -670,8 +714,11 @@ export declare class AgentSession {
|
|
|
670
714
|
steering: readonly string[];
|
|
671
715
|
followUp: readonly string[];
|
|
672
716
|
};
|
|
717
|
+
getQueuedMessageEntries(): QueuedMessageEditEntry[];
|
|
718
|
+
removeQueuedMessageForEditing(id: string): string | undefined;
|
|
719
|
+
moveQueuedMessageForEditing(id: string, direction: "up" | "down"): boolean;
|
|
673
720
|
/**
|
|
674
|
-
* Pop the
|
|
721
|
+
* Pop the newest queued message across steering and follow-up queues.
|
|
675
722
|
* Used by dequeue keybinding to restore messages to editor one at a time.
|
|
676
723
|
* Returns the popped entry's `.text`; the tag (if any) dies with the
|
|
677
724
|
* record — no orphan state can outlive the queue entry.
|
|
@@ -706,6 +753,11 @@ export declare class AgentSession {
|
|
|
706
753
|
* @returns true if completed, false if cancelled by hook
|
|
707
754
|
*/
|
|
708
755
|
newSession(options?: NewSessionOptions): Promise<boolean>;
|
|
756
|
+
/**
|
|
757
|
+
* Clear active conversational/model context while preserving the current
|
|
758
|
+
* session identity and durable history trail.
|
|
759
|
+
*/
|
|
760
|
+
clearContext(): Promise<boolean>;
|
|
709
761
|
/**
|
|
710
762
|
* Set a display name for the current session.
|
|
711
763
|
*/
|
|
@@ -905,9 +957,12 @@ export declare class AgentSession {
|
|
|
905
957
|
*/
|
|
906
958
|
setAutoRetryEnabled(enabled: boolean): void;
|
|
907
959
|
/**
|
|
908
|
-
* Manually retry the last failed assistant turn
|
|
909
|
-
*
|
|
910
|
-
*
|
|
960
|
+
* Manually retry the last failed assistant turn, or resume an interrupted tail
|
|
961
|
+
* left by a non-graceful process exit after the user/custom/tool-result message
|
|
962
|
+
* was persisted but before the agent emitted a terminal assistant response.
|
|
963
|
+
* Removes failed/aborted/unresolved tool-use assistant tails before
|
|
964
|
+
* re-attempting with a fresh retry budget.
|
|
965
|
+
* @returns true if retry/resume was initiated, false if no retryable tail exists or agent is busy
|
|
911
966
|
*/
|
|
912
967
|
retry(): Promise<boolean>;
|
|
913
968
|
/**
|
|
@@ -93,6 +93,7 @@ export declare class AgentStorage {
|
|
|
93
93
|
* Sets a cached value with expiry time (unix seconds).
|
|
94
94
|
*/
|
|
95
95
|
setCache(key: string, value: string, expiresAtSec: number): void;
|
|
96
|
+
deleteCachePrefix(prefix: string): void;
|
|
96
97
|
/**
|
|
97
98
|
* Deletes expired cache entries. Call periodically for cleanup.
|
|
98
99
|
*/
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SessionEntry, SessionMessageEntry } from "./session-manager";
|
|
2
|
+
export interface FileMentionPruneResult {
|
|
3
|
+
changed: SessionMessageEntry[];
|
|
4
|
+
bytesSaved: number;
|
|
5
|
+
}
|
|
6
|
+
/** Notice injected in place of a superseded file-mention body. */
|
|
7
|
+
export declare function stalefileMentionNotice(path: string): string;
|
|
8
|
+
export declare function pruneStaleFileMentions(entries: readonly SessionEntry[], resolveAbs: (path: string) => string): FileMentionPruneResult;
|