@oh-my-pi/pi-coding-agent 17.0.9 → 17.1.0

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.
Files changed (285) hide show
  1. package/CHANGELOG.md +54 -0
  2. package/README.md +1 -1
  3. package/dist/cli.js +4659 -4261
  4. package/dist/types/async/job-manager.d.ts +37 -1
  5. package/dist/types/cli/args.d.ts +2 -0
  6. package/dist/types/cli/bench-cli.d.ts +41 -0
  7. package/dist/types/commands/bench.d.ts +15 -3
  8. package/dist/types/commands/launch.d.ts +4 -0
  9. package/dist/types/config/model-registry.d.ts +3 -1
  10. package/dist/types/config/models-config-schema.d.ts +18 -6
  11. package/dist/types/config/models-config.d.ts +14 -5
  12. package/dist/types/config/provider-globals.d.ts +2 -2
  13. package/dist/types/config/service-tier.d.ts +5 -1
  14. package/dist/types/config/settings-schema.d.ts +316 -47
  15. package/dist/types/config/settings.d.ts +7 -0
  16. package/dist/types/dap/client.d.ts +20 -0
  17. package/dist/types/exec/bash-executor.d.ts +38 -0
  18. package/dist/types/exec/direnv.d.ts +33 -0
  19. package/dist/types/export/html/args.d.ts +15 -0
  20. package/dist/types/export/html/index.d.ts +11 -26
  21. package/dist/types/export/html/web-palette.d.ts +55 -116
  22. package/dist/types/extensibility/extensions/loader.d.ts +3 -0
  23. package/dist/types/extensibility/extensions/types.d.ts +17 -2
  24. package/dist/types/extensibility/plugins/legacy-pi-compat.d.ts +13 -0
  25. package/dist/types/live/controller.d.ts +40 -0
  26. package/dist/types/live/protocol.d.ts +85 -0
  27. package/dist/types/live/protocol.test.d.ts +1 -0
  28. package/dist/types/live/transport.d.ts +48 -0
  29. package/dist/types/live/visualizer.d.ts +33 -0
  30. package/dist/types/lsp/client.d.ts +16 -1
  31. package/dist/types/mcp/config-writer.test.d.ts +1 -0
  32. package/dist/types/mcp/oauth-discovery.d.ts +2 -0
  33. package/dist/types/mcp/smithery-auth.d.ts +1 -1
  34. package/dist/types/mcp/smithery-auth.test.d.ts +1 -0
  35. package/dist/types/memory-backend/tool-names.d.ts +2 -0
  36. package/dist/types/modes/components/login-dialog.d.ts +2 -2
  37. package/dist/types/modes/components/plan-review-overlay.d.ts +26 -0
  38. package/dist/types/modes/components/settings-defs.d.ts +7 -1
  39. package/dist/types/modes/components/status-line/component.jj-cache.test.d.ts +1 -0
  40. package/dist/types/modes/components/tool-execution.d.ts +9 -1
  41. package/dist/types/modes/controllers/command-controller.d.ts +1 -1
  42. package/dist/types/modes/controllers/event-controller.d.ts +6 -1
  43. package/dist/types/modes/controllers/live-command-controller.d.ts +14 -0
  44. package/dist/types/modes/interactive-mode.d.ts +5 -0
  45. package/dist/types/modes/theme/theme.d.ts +1 -1
  46. package/dist/types/modes/types.d.ts +3 -1
  47. package/dist/types/modes/utils/context-usage.d.ts +12 -2
  48. package/dist/types/plan-mode/plan-files.d.ts +10 -0
  49. package/dist/types/registry/agent-lifecycle.d.ts +21 -9
  50. package/dist/types/registry/agent-registry.d.ts +11 -4
  51. package/dist/types/sdk.d.ts +15 -1
  52. package/dist/types/secrets/index.d.ts +15 -2
  53. package/dist/types/secrets/obfuscator.d.ts +113 -15
  54. package/dist/types/session/acp-permission-gate.d.ts +19 -0
  55. package/dist/types/session/agent-session-events.d.ts +84 -0
  56. package/dist/types/session/agent-session-types.d.ts +314 -0
  57. package/dist/types/session/agent-session.d.ts +118 -755
  58. package/dist/types/session/async-job-delivery.d.ts +28 -0
  59. package/dist/types/session/bash-runner.d.ts +75 -0
  60. package/dist/types/session/blob-store.d.ts +11 -1
  61. package/dist/types/session/blob-store.test.d.ts +1 -0
  62. package/dist/types/session/checkpoint-entries.d.ts +28 -0
  63. package/dist/types/session/eval-runner.d.ts +49 -0
  64. package/dist/types/session/irc-bridge.d.ts +46 -0
  65. package/dist/types/session/messages.d.ts +22 -0
  66. package/dist/types/session/model-controls.d.ts +180 -0
  67. package/dist/types/session/prewalk.d.ts +46 -0
  68. package/dist/types/session/queued-messages.d.ts +22 -0
  69. package/dist/types/session/redis-session-storage.d.ts +1 -0
  70. package/dist/types/session/retry-fallback-chains.d.ts +74 -0
  71. package/dist/types/session/role-models.d.ts +15 -0
  72. package/dist/types/session/session-advisors.d.ts +228 -0
  73. package/dist/types/session/session-entries.d.ts +8 -0
  74. package/dist/types/session/session-handoff.d.ts +70 -0
  75. package/dist/types/session/session-history-format.d.ts +6 -1
  76. package/dist/types/session/session-maintenance.d.ts +246 -0
  77. package/dist/types/session/session-manager.d.ts +41 -0
  78. package/dist/types/session/session-memory.d.ts +56 -0
  79. package/dist/types/session/session-provider-boundary.d.ts +62 -0
  80. package/dist/types/session/session-stats.d.ts +48 -0
  81. package/dist/types/session/session-tools.d.ts +143 -0
  82. package/dist/types/session/session-workspace.d.ts +32 -0
  83. package/dist/types/session/stream-guards.d.ts +44 -0
  84. package/dist/types/session/todo-tracker.d.ts +56 -0
  85. package/dist/types/session/ttsr-coordinator.d.ts +51 -0
  86. package/dist/types/session/turn-recovery.d.ts +225 -0
  87. package/dist/types/system-prompt.d.ts +2 -0
  88. package/dist/types/task/executor.d.ts +4 -1
  89. package/dist/types/task/output-manager.d.ts +3 -1
  90. package/dist/types/tools/approval.d.ts +1 -0
  91. package/dist/types/tools/browser/launch.d.ts +5 -0
  92. package/dist/types/tools/image-gen.d.ts +4 -4
  93. package/dist/types/tools/image-providers.d.ts +38 -0
  94. package/dist/types/tools/index.d.ts +5 -0
  95. package/dist/types/tools/path-utils.d.ts +8 -0
  96. package/dist/types/tools/todo.d.ts +10 -4
  97. package/dist/types/tools/xdev.d.ts +5 -1
  98. package/dist/types/tts/streaming-player.d.ts +14 -0
  99. package/dist/types/tts/vocalizer.d.ts +5 -0
  100. package/dist/types/utils/jj.d.ts +29 -0
  101. package/dist/types/utils/lang-from-path.d.ts +1 -0
  102. package/dist/types/utils/title-generator.d.ts +30 -0
  103. package/dist/types/vibe/runtime.d.ts +36 -8
  104. package/dist/types/web/search/index.d.ts +1 -1
  105. package/dist/types/web/search/provider.d.ts +15 -5
  106. package/dist/types/web/search/types.d.ts +94 -0
  107. package/package.json +12 -12
  108. package/scripts/generate-share-viewer.ts +4 -6
  109. package/src/advisor/__tests__/advisor.test.ts +643 -0
  110. package/src/advisor/runtime.ts +144 -43
  111. package/src/async/job-manager.ts +90 -2
  112. package/src/cli/args.ts +2 -0
  113. package/src/cli/auth-gateway-cli.ts +18 -3
  114. package/src/cli/bench-cli.ts +395 -29
  115. package/src/cli/flag-tables.ts +3 -0
  116. package/src/cli/gc-cli.ts +2 -2
  117. package/src/cli/usage-cli.ts +10 -1
  118. package/src/collab/host.ts +3 -2
  119. package/src/commands/bench.ts +18 -4
  120. package/src/commands/launch.ts +4 -0
  121. package/src/config/model-registry.ts +10 -2
  122. package/src/config/models-config-schema.ts +15 -4
  123. package/src/config/provider-globals.ts +9 -9
  124. package/src/config/service-tier.ts +26 -1
  125. package/src/config/settings-schema.ts +209 -51
  126. package/src/config/settings.ts +81 -2
  127. package/src/dap/client.ts +37 -4
  128. package/src/edit/index.ts +49 -12
  129. package/src/eval/py/executor.ts +103 -33
  130. package/src/exec/bash-executor.ts +89 -6
  131. package/src/exec/direnv.ts +145 -0
  132. package/src/export/html/args.ts +20 -0
  133. package/src/export/html/index.ts +45 -47
  134. package/src/export/html/template.css +19 -1
  135. package/src/export/html/template.html +6 -0
  136. package/src/export/html/template.js +21 -0
  137. package/src/export/html/tool-views.generated.js +31 -31
  138. package/src/export/html/web-palette.ts +116 -132
  139. package/src/export/share.ts +249 -49
  140. package/src/extensibility/extensions/loader.ts +29 -1
  141. package/src/extensibility/extensions/runner.ts +6 -0
  142. package/src/extensibility/extensions/types.ts +33 -2
  143. package/src/extensibility/plugins/legacy-pi-compat.ts +19 -1
  144. package/src/hindsight/state.ts +64 -6
  145. package/src/internal-urls/local-protocol.ts +2 -1
  146. package/src/internal-urls/memory-protocol.ts +2 -2
  147. package/src/internal-urls/skill-protocol.ts +2 -2
  148. package/src/internal-urls/ssh-protocol.ts +2 -1
  149. package/src/internal-urls/vault-protocol.ts +2 -1
  150. package/src/live/audio-worklet.txt +59 -0
  151. package/src/live/browser-runtime.txt +221 -0
  152. package/src/live/controller.ts +464 -0
  153. package/src/live/prompts/agent-final-message.md +3 -0
  154. package/src/live/prompts/live-instructions.md +23 -0
  155. package/src/live/protocol.test.ts +140 -0
  156. package/src/live/protocol.ts +233 -0
  157. package/src/live/transport.ts +490 -0
  158. package/src/live/visualizer.ts +234 -0
  159. package/src/lsp/client.ts +29 -9
  160. package/src/lsp/index.ts +19 -4
  161. package/src/main.ts +8 -1
  162. package/src/mcp/config-writer.test.ts +43 -0
  163. package/src/mcp/config-writer.ts +109 -82
  164. package/src/mcp/oauth-discovery.ts +10 -2
  165. package/src/mcp/smithery-auth.test.ts +29 -0
  166. package/src/mcp/smithery-auth.ts +3 -2
  167. package/src/memories/index.ts +40 -20
  168. package/src/memory-backend/tool-names.ts +2 -0
  169. package/src/mnemopi/backend.ts +24 -7
  170. package/src/modes/acp/acp-agent.ts +56 -10
  171. package/src/modes/acp/acp-event-mapper.ts +8 -1
  172. package/src/modes/components/agent-hub.ts +1 -1
  173. package/src/modes/components/login-dialog.ts +14 -4
  174. package/src/modes/components/plan-review-overlay.ts +350 -35
  175. package/src/modes/components/settings-defs.ts +23 -1
  176. package/src/modes/components/settings-selector.ts +169 -1
  177. package/src/modes/components/status-line/component.jj-cache.test.ts +229 -0
  178. package/src/modes/components/status-line/component.ts +123 -2
  179. package/src/modes/components/tool-execution.ts +11 -2
  180. package/src/modes/controllers/command-controller.ts +56 -15
  181. package/src/modes/controllers/event-controller.ts +111 -16
  182. package/src/modes/controllers/extension-ui-controller.test.ts +1 -0
  183. package/src/modes/controllers/extension-ui-controller.ts +20 -4
  184. package/src/modes/controllers/live-command-controller.ts +178 -0
  185. package/src/modes/controllers/mcp-command-controller.ts +10 -1
  186. package/src/modes/controllers/omfg-controller.ts +44 -40
  187. package/src/modes/controllers/selector-controller.ts +18 -10
  188. package/src/modes/controllers/session-focus-controller.ts +6 -1
  189. package/src/modes/interactive-mode.ts +157 -38
  190. package/src/modes/runtime-init.ts +2 -0
  191. package/src/modes/setup-wizard/scenes/web-search.ts +17 -9
  192. package/src/modes/theme/theme.ts +1 -1
  193. package/src/modes/types.ts +3 -1
  194. package/src/modes/utils/context-usage.ts +23 -7
  195. package/src/modes/utils/ui-helpers.ts +10 -5
  196. package/src/plan-mode/plan-files.ts +40 -0
  197. package/src/prompts/bench/cache-prefix-chunk.md +1 -0
  198. package/src/prompts/bench/cache-prefix.md +3 -0
  199. package/src/prompts/bench/cache-suffix.md +1 -0
  200. package/src/prompts/system/custom-system-prompt.md +1 -1
  201. package/src/prompts/system/project-prompt.md +8 -1
  202. package/src/prompts/system/subagent-async-pending.md +6 -0
  203. package/src/prompts/system/system-prompt.md +1 -1
  204. package/src/prompts/system/workflow-notice.md +48 -40
  205. package/src/prompts/system/xdev-mount-notice.md +4 -0
  206. package/src/prompts/tools/todo.md +3 -1
  207. package/src/registry/agent-lifecycle.ts +116 -46
  208. package/src/registry/agent-registry.ts +35 -8
  209. package/src/registry/persisted-agents.ts +26 -2
  210. package/src/sdk.ts +210 -136
  211. package/src/secrets/index.ts +127 -4
  212. package/src/secrets/obfuscator.ts +2328 -105
  213. package/src/session/acp-permission-gate.ts +165 -0
  214. package/src/session/agent-session-error-log.test.ts +1 -1
  215. package/src/session/agent-session-events.ts +66 -0
  216. package/src/session/agent-session-types.ts +334 -0
  217. package/src/session/agent-session.ts +1892 -12226
  218. package/src/session/artifacts.ts +6 -5
  219. package/src/session/async-job-delivery.ts +74 -0
  220. package/src/session/bash-runner.ts +326 -0
  221. package/src/session/blob-store.test.ts +56 -0
  222. package/src/session/blob-store.ts +18 -2
  223. package/src/session/checkpoint-entries.ts +81 -0
  224. package/src/session/eval-runner.ts +212 -0
  225. package/src/session/indexed-session-storage.ts +9 -2
  226. package/src/session/irc-bridge.ts +203 -0
  227. package/src/session/messages.ts +263 -1
  228. package/src/session/model-controls.ts +714 -0
  229. package/src/session/prewalk.ts +252 -0
  230. package/src/session/queued-messages.ts +93 -0
  231. package/src/session/redis-session-storage.ts +51 -11
  232. package/src/session/retry-fallback-chains.ts +455 -0
  233. package/src/session/role-models.ts +85 -0
  234. package/src/session/session-advisors.ts +1679 -0
  235. package/src/session/session-context.ts +6 -3
  236. package/src/session/session-entries.ts +8 -0
  237. package/src/session/session-handoff.ts +308 -0
  238. package/src/session/session-history-format.ts +20 -9
  239. package/src/session/session-loader.ts +0 -46
  240. package/src/session/session-maintenance.ts +2983 -0
  241. package/src/session/session-manager.ts +390 -30
  242. package/src/session/session-memory.ts +222 -0
  243. package/src/session/session-provider-boundary.ts +307 -0
  244. package/src/session/session-stats.ts +293 -0
  245. package/src/session/session-tools.ts +943 -0
  246. package/src/session/session-workspace.ts +53 -0
  247. package/src/session/stream-guards.ts +417 -0
  248. package/src/session/todo-tracker.ts +380 -0
  249. package/src/session/ttsr-coordinator.ts +496 -0
  250. package/src/session/turn-recovery.ts +1629 -0
  251. package/src/slash-commands/builtin-registry.ts +92 -11
  252. package/src/slash-commands/helpers/usage-report.ts +22 -3
  253. package/src/system-prompt.ts +41 -17
  254. package/src/task/executor.ts +285 -70
  255. package/src/task/index.ts +98 -105
  256. package/src/task/output-manager.ts +25 -3
  257. package/src/task/persisted-revive.ts +4 -3
  258. package/src/task/structured-subagent.ts +1 -0
  259. package/src/tools/approval.ts +55 -10
  260. package/src/tools/bash-interactive.ts +26 -0
  261. package/src/tools/bash-skill-urls.ts +28 -2
  262. package/src/tools/bash.ts +339 -123
  263. package/src/tools/browser/launch.ts +9 -1
  264. package/src/tools/browser/tab-supervisor.ts +8 -5
  265. package/src/tools/browser.ts +94 -47
  266. package/src/tools/image-gen.ts +20 -28
  267. package/src/tools/image-providers.ts +50 -0
  268. package/src/tools/index.ts +9 -0
  269. package/src/tools/path-utils.ts +49 -2
  270. package/src/tools/read.ts +156 -88
  271. package/src/tools/renderers.ts +7 -1
  272. package/src/tools/todo.ts +101 -11
  273. package/src/tools/vibe.ts +1 -2
  274. package/src/tools/write.ts +51 -1
  275. package/src/tools/xdev.ts +67 -3
  276. package/src/tts/streaming-player.ts +62 -4
  277. package/src/tts/vocalizer.ts +18 -1
  278. package/src/utils/jj.ts +125 -4
  279. package/src/utils/lang-from-path.ts +7 -0
  280. package/src/utils/title-generator.ts +137 -1
  281. package/src/vibe/runtime.ts +852 -72
  282. package/src/web/search/index.ts +3 -6
  283. package/src/web/search/provider.ts +31 -16
  284. package/src/web/search/providers/xai.ts +7 -1
  285. package/src/web/search/types.ts +3 -0
@@ -0,0 +1,28 @@
1
+ import type { AsyncJob } from "../async/index.js";
2
+ import type { CustomMessage } from "./messages.js";
3
+ /**
4
+ * `customType` of the injected async-result follow-up message. The task
5
+ * executor's run monitor matches on it to invalidate a previously recorded
6
+ * yield: a result injected after the yield supersedes that yield's payload.
7
+ */
8
+ export declare const ASYNC_RESULT_MESSAGE_TYPE = "async-result";
9
+ /** Result payloads longer than this spill to an artifact with an inline preview. */
10
+ export declare const ASYNC_INLINE_RESULT_MAX_CHARS = 12000;
11
+ export declare const ASYNC_PREVIEW_MAX_CHARS = 4000;
12
+ export interface AsyncResultEntry {
13
+ jobId: string;
14
+ result: string;
15
+ job: AsyncJob | undefined;
16
+ durationMs: number | undefined;
17
+ }
18
+ type AsyncResultJobDetails = {
19
+ jobId: string;
20
+ type?: "bash" | "task";
21
+ label?: string;
22
+ durationMs?: number;
23
+ };
24
+ export type AsyncResultDetails = {
25
+ jobs: AsyncResultJobDetails[];
26
+ };
27
+ export declare function buildAsyncResultBatchMessage(entries: AsyncResultEntry[]): CustomMessage<AsyncResultDetails> | null;
28
+ export {};
@@ -0,0 +1,75 @@
1
+ import type { Agent } from "@oh-my-pi/pi-agent-core";
2
+ import type { Settings } from "../config/settings.js";
3
+ import { type BashResult } from "../exec/bash-executor.js";
4
+ import type { ExtensionRunner } from "../extensibility/extensions/index.js";
5
+ import type { SessionManager } from "./session-manager.js";
6
+ /** Destination that owns a bash result after a session or branch transition. */
7
+ export type BashAppendDestination = {
8
+ kind: "current";
9
+ manager: SessionManager;
10
+ } | {
11
+ kind: "detached";
12
+ manager: SessionManager;
13
+ } | {
14
+ kind: "branch";
15
+ manager: SessionManager;
16
+ parentId: string | null;
17
+ };
18
+ /** Reference-counted session target captured when a bash execution starts. */
19
+ export interface BashSessionTarget {
20
+ sessionId: string;
21
+ refs: number;
22
+ destination?: BashAppendDestination;
23
+ pending?: Promise<BashAppendDestination>;
24
+ }
25
+ /** Ownership snapshot spanning a session or branch transition. */
26
+ export interface BashSessionTransition {
27
+ oldTarget: BashSessionTarget;
28
+ newTarget: BashSessionTarget;
29
+ oldSessionId: string;
30
+ oldSessionFile: string | undefined;
31
+ oldLeafId: string | null;
32
+ detachedManager: SessionManager | undefined;
33
+ resolveOld: ((destination: BashAppendDestination) => void) | undefined;
34
+ resolveNew: (destination: BashAppendDestination) => void;
35
+ }
36
+ /** Capabilities the bash runner borrows from its owning session. */
37
+ export interface BashRunnerHost {
38
+ agent: Agent;
39
+ sessionManager: SessionManager;
40
+ settings: Settings;
41
+ extensionRunner(): ExtensionRunner | undefined;
42
+ isStreaming(): boolean;
43
+ }
44
+ /** Owns bash execution and preserves result ownership across transcript transitions. */
45
+ export declare class BashRunner {
46
+ #private;
47
+ constructor(host: BashRunnerHost);
48
+ /** Executes a bash command while retaining the session and branch that owned its start. */
49
+ executeBash(command: string, onChunk?: (chunk: string) => void, options?: {
50
+ excludeFromContext?: boolean;
51
+ useUserShell?: boolean;
52
+ }): Promise<BashResult>;
53
+ /** Records a bash result supplied outside executeBash in the current ownership scope. */
54
+ recordBashResult(command: string, result: BashResult, options?: {
55
+ excludeFromContext?: boolean;
56
+ }): void;
57
+ /** Cancels every running bash command. */
58
+ abort(): void;
59
+ /** Whether a bash command is currently running. */
60
+ get isRunning(): boolean;
61
+ /** Whether bash results are waiting for a safe persistence boundary. */
62
+ get hasPendingMessages(): boolean;
63
+ /** Flushes deferred bash results without changing their captured ownership. */
64
+ flushPending(): Promise<void>;
65
+ /** Runs a leaf rewrite while retaining in-flight bash on its originating branch. */
66
+ withBranchTransition<T>(mutate: () => T): T;
67
+ /** Snapshots the owner of in-flight bash before a session or branch transition. */
68
+ beginSessionTransition(options?: {
69
+ persistDetached?: boolean;
70
+ }): BashSessionTransition;
71
+ /** Adopts a transition's new target as the live bash owner. */
72
+ markSessionTransition(transition: BashSessionTransition): void;
73
+ /** Resolves destinations opened by beginSessionTransition. */
74
+ finishSessionTransition(transition: BashSessionTransition, success: boolean): void;
75
+ }
@@ -1,3 +1,5 @@
1
+ /** Canonical blob hash shape: exactly 64 lowercase hex chars (a SHA-256 digest). */
2
+ export declare const BLOB_HASH_RE: RegExp;
1
3
  export interface BlobPutOptions {
2
4
  /** Optional file extension for a sidecar hardlink/copy that OS openers can type-detect. */
3
5
  extension?: string;
@@ -34,7 +36,15 @@ export declare class BlobStore {
34
36
  }
35
37
  /** Check if a data string is a blob reference. */
36
38
  export declare function isBlobRef(data: string): boolean;
37
- /** Extract the SHA-256 hash from a blob reference string. */
39
+ /**
40
+ * Extract the SHA-256 hash from a blob reference string.
41
+ *
42
+ * Returns null when the string is not a blob ref, or when the suffix is not a
43
+ * canonical 64-char lowercase hex hash. Rejecting non-hash suffixes here is the
44
+ * single choke point that keeps every resolution path confined to the blob dir:
45
+ * `get`/`getSync` feed this value into `path.join(this.dir, hash)`, so an
46
+ * unvalidated `../` suffix would otherwise escape the store and read arbitrary files.
47
+ */
38
48
  export declare function parseBlobRef(data: string): string | null;
39
49
  /** Identify provider transport image data URLs so persistence can externalize and restore them losslessly. */
40
50
  export declare function isImageDataUrl(data: string): boolean;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
+ import type { ImageContent, TextContent } from "@oh-my-pi/pi-ai";
3
+ import type { CompletedRewindState } from "../tools/checkpoint.js";
4
+ import type { SessionEntry } from "./session-entries.js";
5
+ /** Extracts text from custom message content. */
6
+ export declare function customMessageContentText(content: string | (TextContent | ImageContent)[]): string;
7
+ /** Extracts the report body from persisted rewind-report content. */
8
+ export declare function reportFromRewindReportContent(content: string): string;
9
+ /** Checkpoint-domain tool names normalized from native and xdev calls. */
10
+ export type SemanticCheckpointToolName = "checkpoint" | "rewind";
11
+ /** Normalized checkpoint-domain tool result. */
12
+ export interface SemanticToolResult {
13
+ toolName: SemanticCheckpointToolName;
14
+ details?: unknown;
15
+ }
16
+ /** Normalizes checkpoint and rewind results across native calls and xdev dispatches. */
17
+ export declare function semanticToolResult(toolName: string | undefined, result: unknown): SemanticToolResult | undefined;
18
+ /** Restores completed rewind state from a persisted session entry. */
19
+ export declare function completedRewindFromEntry(entry: SessionEntry): CompletedRewindState | undefined;
20
+ /** Whether an entry is a successful checkpoint tool result. */
21
+ export declare function isSuccessfulCheckpointEntry(entry: SessionEntry): entry is SessionEntry & {
22
+ type: "message";
23
+ message: Extract<AgentMessage, {
24
+ role: "toolResult";
25
+ }>;
26
+ };
27
+ /** Returns the checkpoint start timestamp represented by an entry. */
28
+ export declare function checkpointStartedAtFromEntry(entry: SessionEntry): string | undefined;
@@ -0,0 +1,49 @@
1
+ import type { Agent } from "@oh-my-pi/pi-agent-core";
2
+ import type { Settings } from "../config/settings.js";
3
+ import { type PythonResult } from "../eval/py/executor.js";
4
+ import type { ExtensionRunner } from "../extensibility/extensions/index.js";
5
+ import type { PythonExecutionMessage } from "./messages.js";
6
+ import type { SessionManager } from "./session-manager.js";
7
+ /** Capabilities the eval runner borrows from its owning session. */
8
+ export interface EvalRunnerHost {
9
+ agent: Agent;
10
+ sessionManager: SessionManager;
11
+ settings: Settings;
12
+ extensionRunner(): ExtensionRunner | undefined;
13
+ isStreaming(): boolean;
14
+ appendSessionMessage(message: PythonExecutionMessage): void;
15
+ }
16
+ /** Owns user-initiated Python execution and retained eval-kernel lifecycle. */
17
+ export declare class EvalRunner {
18
+ #private;
19
+ constructor(host: EvalRunnerHost, options: {
20
+ kernelOwnerId: string;
21
+ parentSessionId: string | undefined;
22
+ });
23
+ /** Executes Python in the session's shared kernel. */
24
+ executePython(code: string, onChunk?: (chunk: string) => void, options?: {
25
+ excludeFromContext?: boolean;
26
+ }): Promise<PythonResult>;
27
+ /** Rejects new eval work once session disposal begins. */
28
+ assertExecutionAllowed(): void;
29
+ /** Tracks externally started Python work so disposal can await and abort it. */
30
+ trackExecution<T>(execution: Promise<T>, abortController: AbortController): Promise<T>;
31
+ /** Records a Python execution result in session history. */
32
+ recordPythonResult(code: string, result: PythonResult, options?: {
33
+ excludeFromContext?: boolean;
34
+ }): void;
35
+ /** Cancels every running Python execution. */
36
+ abort(): void;
37
+ /** Whether a Python execution is currently running. */
38
+ get isRunning(): boolean;
39
+ /** Whether Python results are waiting for a safe persistence boundary. */
40
+ get hasPendingMessages(): boolean;
41
+ /** Returns the eval session shared with the Python backend. */
42
+ getSessionId(): string | null;
43
+ /** Flushes deferred Python results into agent state and persistence. */
44
+ flushPending(): void;
45
+ /** Prevents new Python executions before asynchronous disposal starts. */
46
+ beginDispose(): void;
47
+ /** Waits for active work and disposes every retained eval kernel owned by the session. */
48
+ disposeKernels(): Promise<void>;
49
+ }
@@ -0,0 +1,46 @@
1
+ import type { Agent } from "@oh-my-pi/pi-agent-core";
2
+ import type { Settings } from "../config/settings.js";
3
+ import { type IrcMessage } from "../irc/bus.js";
4
+ import type { AgentSessionEvent } from "./agent-session-events.js";
5
+ import type { CustomMessage } from "./messages.js";
6
+ import type { SessionManager } from "./session-manager.js";
7
+ /** Capabilities the IRC bridge borrows from its owning session. */
8
+ export interface IrcBridgeHost {
9
+ agent: Agent;
10
+ sessionManager: SessionManager;
11
+ settings: Settings;
12
+ isDisposed(): boolean;
13
+ isStreaming(): boolean;
14
+ planModeEnabled(): boolean;
15
+ emitSessionEvent(event: AgentSessionEvent): Promise<void>;
16
+ wakeForIrc(records: CustomMessage[]): void;
17
+ runEphemeralTurn(args: {
18
+ promptText: string;
19
+ }): Promise<{
20
+ replyText: string;
21
+ }>;
22
+ }
23
+ /** Owns incoming IRC queues, injection, and side-channel auto-replies. */
24
+ export declare class IrcBridge {
25
+ #private;
26
+ constructor(host: IrcBridgeHost);
27
+ /** Whether an incoming peer message can interrupt a wait. */
28
+ hasInterrupts(): boolean;
29
+ /** Whether any undelivered IRC record remains queued. */
30
+ hasPending(): boolean;
31
+ /** Takes every queued IRC record in interrupt-before-aside order. */
32
+ drainPending(): CustomMessage[];
33
+ /** Surfaces and consumes queued incoming records before automatic injection. */
34
+ drainInboxMessages(agentId: string, opts?: {
35
+ from?: string;
36
+ limit?: number;
37
+ }): IrcMessage[];
38
+ /** Delivers an IRC message into the recipient session without awaiting any wake turn. */
39
+ deliver(msg: IrcMessage, opts?: {
40
+ expectsReply?: boolean;
41
+ }): Promise<"injected" | "woken">;
42
+ /** Emits an IRC relay observation for rendering without persisting it. */
43
+ emitRelayObservation(record: CustomMessage): void;
44
+ /** Persists queued IRC records that missed their step-boundary injection. */
45
+ flushPending(): void;
46
+ }
@@ -12,6 +12,28 @@ import type { OutputMeta } from "../tools/output-meta.js";
12
12
  export declare const SKILL_PROMPT_MESSAGE_TYPE = "skill-prompt";
13
13
  export declare const LSP_LATE_DIAGNOSTIC_MESSAGE_TYPE = "lsp-late-diagnostic";
14
14
  export declare const BACKGROUND_TAN_DISPATCH_MESSAGE_TYPE = "background-tan-dispatch";
15
+ /**
16
+ * Logs provider-error turns so their actual cause is available outside the
17
+ * session transcript. No-op for non-error stop reasons.
18
+ */
19
+ export declare function logProviderTurnError(msg: AssistantMessage): void;
20
+ /**
21
+ * Removes replay-bound provider state before reparenting an assistant message
22
+ * under a different user turn.
23
+ */
24
+ export declare function sanitizeAssistantForReparentedHistory(message: AssistantMessage): AssistantMessage;
25
+ /**
26
+ * Collapses degenerate repeated lines and bounds an ephemeral side-channel
27
+ * reply to 4 KiB.
28
+ */
29
+ export declare function dedupeEphemeralReply(text: string): string;
30
+ /** Builds the recent user/assistant context supplied to title regeneration. */
31
+ export declare function buildReplanTitleContext(messages: AgentMessage[]): string;
32
+ /**
33
+ * Compares session messages by provider-replay semantics, ignoring runtime-only
34
+ * fields that do not change a restored request.
35
+ */
36
+ export declare function didSessionMessagesChange(previousMessages: AgentMessage[], nextMessages: AgentMessage[]): boolean;
15
37
  /** Fallback type for extension-injected messages that omit a custom type. */
16
38
  export declare const DEFAULT_CUSTOM_MESSAGE_TYPE = "custom-message";
17
39
  /** Content shape accepted for extension-injected messages. */
@@ -0,0 +1,180 @@
1
+ import { type Agent, ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
+ import type { Model, ProviderSessionState, ServiceTier, ServiceTierByFamily, ServiceTierFamily } from "@oh-my-pi/pi-ai";
3
+ import { Effort } from "@oh-my-pi/pi-ai";
4
+ import type { ModelRegistry } from "../config/model-registry.js";
5
+ import { type ResolvedModelRoleValue } from "../config/model-resolver.js";
6
+ import type { Settings } from "../config/settings.js";
7
+ import { type ConfiguredThinkingLevel } from "../thinking.js";
8
+ import type { EditMode } from "../utils/edit-mode.js";
9
+ import type { AgentSessionEvent } from "./agent-session-events.js";
10
+ import type { ModelCycleResult, ResolvedRoleModel, RoleModelCycle, RoleModelCycleResult } from "./agent-session-types.js";
11
+ import type { SessionManager } from "./session-manager.js";
12
+ /** Capabilities borrowed from the owning AgentSession. */
13
+ export interface ModelControlsHost {
14
+ agent: Agent;
15
+ settings: Settings;
16
+ modelRegistry: ModelRegistry;
17
+ sessionManager: SessionManager;
18
+ providerSessionState: Map<string, ProviderSessionState>;
19
+ model(): Model | undefined;
20
+ sessionId(): string;
21
+ promptGeneration(): number;
22
+ resolveActiveEditMode(): EditMode;
23
+ syncAfterModelChange(previousEditMode: EditMode): Promise<void>;
24
+ setModelWithProviderSessionReset(model: Model): void;
25
+ clearActiveRetryFallback(): void;
26
+ clearInheritedProviderPromptCacheKey(): void;
27
+ magicKeywordEnabled(keyword: "orchestrate" | "ultrathink" | "workflow"): boolean;
28
+ emit(event: AgentSessionEvent): void;
29
+ emitSessionEvent(event: AgentSessionEvent): Promise<void>;
30
+ emitNotice(level: "info" | "warning" | "error", message: string, source?: string): void;
31
+ }
32
+ /** Owns model selection, thinking effort, role cycling, and service tiers. */
33
+ export declare class ModelControls {
34
+ #private;
35
+ constructor(host: ModelControlsHost, options: {
36
+ scopedModels?: Array<{
37
+ model: Model;
38
+ thinkingLevel?: ThinkingLevel;
39
+ }>;
40
+ thinkingLevel?: ConfiguredThinkingLevel;
41
+ serviceTierByFamily?: ServiceTierByFamily;
42
+ });
43
+ /** Effective metadata-clamped thinking level applied to the agent. */
44
+ get thinkingLevel(): ThinkingLevel | undefined;
45
+ /** Configured selector, preserving `auto` while classification is active. */
46
+ configuredThinkingLevel(): ConfiguredThinkingLevel | undefined;
47
+ /** Whether per-turn automatic thinking classification is enabled. */
48
+ get isAutoThinking(): boolean;
49
+ /** Last concrete effort selected by automatic classification. */
50
+ get autoResolvedThinkingLevel(): Effort | undefined;
51
+ /** Models explicitly scoped to the session's cycle command. */
52
+ get scopedModels(): ReadonlyArray<{
53
+ model: Model;
54
+ thinkingLevel?: ThinkingLevel;
55
+ }>;
56
+ /** Live per-provider-family service-tier selection. */
57
+ get serviceTierByFamily(): ServiceTierByFamily;
58
+ /** Restores thinking state from a transcript without persisting a new entry. */
59
+ restoreThinkingLevel(level: ConfiguredThinkingLevel | undefined): void;
60
+ /** Restores an exact thinking snapshot after a failed session switch. */
61
+ restoreThinkingSnapshot(level: ThinkingLevel | undefined, auto: boolean, resolved: Effort | undefined): void;
62
+ /** Restores service tiers without persisting a duplicate transcript entry. */
63
+ restoreServiceTiers(tiers: ServiceTierByFamily): void;
64
+ resolveRoleModel(role: string): Model | undefined;
65
+ resolveRoleModelWithThinking(role: string): ResolvedModelRoleValue;
66
+ resolveTemporaryModelThinkingLevel(model: Model): ConfiguredThinkingLevel | undefined;
67
+ setModel(model: Model, role?: string, options?: {
68
+ selector?: string;
69
+ thinkingLevel?: ThinkingLevel;
70
+ persist?: boolean;
71
+ currentContextTokens?: number;
72
+ }): Promise<{
73
+ switched: boolean;
74
+ }>;
75
+ /**
76
+ * Set model temporarily (for this session only).
77
+ * Validates that a credential source is configured (synchronously, without
78
+ * refreshing OAuth or running command-backed key programs), saves to session
79
+ * log but NOT to settings.
80
+ * @throws Error if no API key available for the model
81
+ */
82
+ setModelTemporary(model: Model, thinkingLevel?: ConfiguredThinkingLevel, options?: {
83
+ ephemeral?: boolean;
84
+ }): Promise<void>;
85
+ /**
86
+ * Cycle to next/previous model.
87
+ * Uses scoped models (from --models flag) if available, otherwise all available models.
88
+ * @param direction - "forward" (default) or "backward"
89
+ * @returns The new model info, or undefined if only one model available
90
+ */
91
+ cycleModel(direction?: "forward" | "backward"): Promise<ModelCycleResult | undefined>;
92
+ /**
93
+ * Resolve the configured role models in the given order plus the index of
94
+ * the currently active one. Roles that have no configured model, or whose
95
+ * configured model is not currently available, are skipped. The `default`
96
+ * role falls back to the active model when no explicit assignment exists.
97
+ *
98
+ * Returns `undefined` only when there is no current model or no available
99
+ * models at all; an empty `models` array is never returned (callers should
100
+ * still guard on `models.length`).
101
+ */
102
+ getRoleModelCycle(roleOrder: readonly string[]): RoleModelCycle | undefined;
103
+ /**
104
+ * Apply a resolved role model as the active model without changing global
105
+ * settings. Shared with role cycling and the plan-approval model slider.
106
+ */
107
+ applyRoleModel(entry: ResolvedRoleModel): Promise<void>;
108
+ /**
109
+ * Cycle through configured role models in a fixed order.
110
+ * Skips missing roles and changes only the active session model.
111
+ * @param roleOrder - Order of roles to cycle through (e.g., ["slow", "default", "smol"])
112
+ * @param direction - "forward" (default) or "backward"
113
+ */
114
+ cycleRoleModels(roleOrder: readonly string[], direction?: "forward" | "backward"): Promise<RoleModelCycleResult | undefined>;
115
+ /**
116
+ * Get all available models with valid API keys, filtered by `enabledModels` when configured.
117
+ * See {@link filterAvailableModelsByEnabledPatterns} for supported pattern forms and limitations.
118
+ */
119
+ getAvailableModels(): Model[];
120
+ /**
121
+ * Set the thinking level. `auto` enables per-turn classification. Entering
122
+ * auto writes its provisional level plus `configured: "auto"` immediately,
123
+ * giving external readers an authoritative selection receipt before the next
124
+ * user turn. Later classifications persist only changed concrete resolutions.
125
+ */
126
+ setThinkingLevel(level: ConfiguredThinkingLevel | undefined, persist?: boolean): void;
127
+ /**
128
+ * Cycle to next thinking level: off → auto → minimal..max → off.
129
+ * @returns New selector, or undefined if model doesn't support thinking
130
+ */
131
+ cycleThinkingLevel(): ConfiguredThinkingLevel | undefined;
132
+ /**
133
+ * Classify the current user turn and set the effective thinking level for it.
134
+ * Bounded by a timeout + abort; on any failure (no smol model, timeout, parse
135
+ * error) it falls back to the provisional concrete level and continues. Never
136
+ * throws into the turn, and never clears `#autoThinking` (auto stays active).
137
+ */
138
+ applyAutoThinkingLevel(promptText: string, generation: number): Promise<void>;
139
+ /**
140
+ * True when the currently selected model's family is set to `priority` — the
141
+ * `/fast` on/off state for the active model. Returns false when no model is
142
+ * selected or the model exposes no service-tier family (e.g. Fireworks, which
143
+ * has its own Providers › Fireworks Tier toggle).
144
+ *
145
+ * For "is priority actually applied to the next request?" use
146
+ * {@link isFastModeActive} instead.
147
+ */
148
+ isFastModeEnabled(): boolean;
149
+ /**
150
+ * True when `priority` is actually realized on the wire for the currently
151
+ * selected model (OpenAI/Google `service_tier`, direct Anthropic fast mode,
152
+ * or Fireworks priority). Returns false for tiers the active model can't
153
+ * realize and when no model is selected.
154
+ */
155
+ isFastModeActive(): boolean;
156
+ /**
157
+ * Effective wire service-tier for a request to `model`. Fireworks models take
158
+ * the Priority serving path only when the Providers › Fireworks Tier setting
159
+ * is `"priority"` (and never for `-fast` variants, whose Fast serving path is
160
+ * mutually exclusive with Priority). Every other model resolves the live
161
+ * per-family tier map down to the entry for its family.
162
+ */
163
+ effectiveServiceTier(model?: Model | undefined): ServiceTier | undefined;
164
+ /** The live per-family tier map, or `null` when empty (for session persistence). */
165
+ serviceTierEntry(): ServiceTierByFamily | null;
166
+ /** Set one family's tier (or clear it with `undefined`); persists the change. */
167
+ setServiceTierFamily(family: ServiceTierFamily, tier: ServiceTier | undefined): void;
168
+ /**
169
+ * `/fast on|off` targets the family of the currently selected model: it sets
170
+ * (or clears) that family's `priority` tier. Returns `false` when the model
171
+ * has no service-tier family, so callers can report that fast mode is
172
+ * unavailable instead of claiming success.
173
+ */
174
+ setFastMode(enabled: boolean): boolean;
175
+ toggleFastMode(): boolean;
176
+ /**
177
+ * Get available thinking levels for current model.
178
+ */
179
+ getAvailableThinkingLevels(): ReadonlyArray<Effort>;
180
+ }
@@ -0,0 +1,46 @@
1
+ import type { Agent, AgentMessage, AgentTurnEndContext } from "@oh-my-pi/pi-agent-core";
2
+ import type { Model } from "@oh-my-pi/pi-ai";
3
+ import type { LocalProtocolOptions } from "../internal-urls/index.js";
4
+ import type { PlanModeState } from "../plan-mode/state.js";
5
+ import type { ConfiguredThinkingLevel } from "../thinking.js";
6
+ import type { PlanProposalHandler } from "../tools/resolve.js";
7
+ import type { PlanYolo, Prewalk } from "./agent-session-types.js";
8
+ import type { SessionManager } from "./session-manager.js";
9
+ /** Capabilities the prewalk coordinator borrows from its owning session. */
10
+ export interface PrewalkCoordinatorHost {
11
+ agent: Agent;
12
+ sessionManager: SessionManager;
13
+ model(): Model | undefined;
14
+ emitNotice(level: "info" | "warning" | "error", message: string, source?: string): void;
15
+ setModelTemporary(model: Model, thinkingLevel?: ConfiguredThinkingLevel, options?: {
16
+ ephemeral?: boolean;
17
+ }): Promise<void>;
18
+ setActiveToolsByName(names: string[]): Promise<void>;
19
+ getActiveToolNames(): string[];
20
+ getEnabledToolNames(): string[];
21
+ hasBuiltInTool(name: string): boolean;
22
+ getPlanModeState(): PlanModeState | undefined;
23
+ setPlanModeState(state: PlanModeState | undefined): void;
24
+ getPlanReferencePath(): string;
25
+ setPlanProposalHandler(handler: PlanProposalHandler | null): void;
26
+ waitForSessionMessagePersistence(message: AgentMessage): Promise<void>;
27
+ localProtocolOptions(): LocalProtocolOptions;
28
+ }
29
+ /** Initial state for prewalk and plan-yolo startup flows. */
30
+ export interface PrewalkCoordinatorOptions {
31
+ prewalk?: Prewalk;
32
+ planYolo?: PlanYolo;
33
+ }
34
+ /** Coordinates one-way model prewalks and automatic plan-yolo handoffs. */
35
+ export declare class PrewalkCoordinator {
36
+ #private;
37
+ constructor(host: PrewalkCoordinatorHost, options?: PrewalkCoordinatorOptions);
38
+ /** Current prewalk target, if the one-way switch remains armed. */
39
+ get state(): Prewalk | undefined;
40
+ /** Advances the one-way prewalk switch at a completed assistant-turn boundary. */
41
+ advanceAtTurnEnd(liveMessages: AgentMessage[], context: AgentTurnEndContext | undefined): Promise<void>;
42
+ /** Arms a prewalk immediately for an explicit slash-command request. */
43
+ arm(target: Model, thinkingLevel?: ConfiguredThinkingLevel): void;
44
+ /** Lazily enables plan-yolo's plan phase before the first prompt is built. */
45
+ armPlanYoloIfNeeded(): Promise<void>;
46
+ }
@@ -0,0 +1,22 @@
1
+ import type { AgentMessage } from "@oh-my-pi/pi-agent-core";
2
+ import type { AssistantMessage } from "@oh-my-pi/pi-ai";
3
+ import type { RestoredQueuedMessage } from "./agent-session-types.js";
4
+ import { type CustomMessage } from "./messages.js";
5
+ /** Whether a queued message should render in the queue UI. */
6
+ export declare function isDisplayableQueuedMessage(message: AgentMessage): boolean;
7
+ /** Whether a queued message is an advisor card. */
8
+ export declare function isAdvisorCard(message: AgentMessage): message is CustomMessage;
9
+ /** Whether a message is a terminal assistant answer containing text and no tools. */
10
+ export declare function isTerminalTextAssistantAnswer(message: AgentMessage | undefined): message is AssistantMessage;
11
+ /** Whether queued content was authored by the user and can be restored to the editor. */
12
+ export declare function isUserQueuedMessage(message: AgentMessage): boolean;
13
+ /** Hidden magic-keyword notices queued alongside a user prompt. */
14
+ export declare const MAGIC_KEYWORD_NOTICE_TYPES: Record<string, true>;
15
+ /** Hidden companion carrying vision descriptions for a text-only model. */
16
+ export declare const IMAGE_ATTACHMENT_DESCRIPTION_TYPE = "image-attachment-description";
17
+ /** Whether a hidden queued message is a companion of an adjacent user prompt. */
18
+ export declare function isHiddenUserCompanion(message: AgentMessage): boolean;
19
+ /** Human-readable text shown for a queued-message chip. */
20
+ export declare function queueChipText(message: AgentMessage): string;
21
+ /** Converts a queued user message to editor-restorable content. */
22
+ export declare function toRestoredQueuedMessage(message: AgentMessage): RestoredQueuedMessage;
@@ -6,6 +6,7 @@ import { IndexedSessionStorage } from "./indexed-session-storage.js";
6
6
  * without dragging the entire Bun typings into this module.
7
7
  */
8
8
  export interface RedisSessionStorageClient {
9
+ send(command: string, args: string[]): Promise<unknown>;
9
10
  get(key: string): Promise<string | null>;
10
11
  getrange(key: string, start: number, end: number): Promise<string>;
11
12
  strlen(key: string): Promise<number>;
@@ -0,0 +1,74 @@
1
+ import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
+ import type { Model } from "@oh-my-pi/pi-ai";
3
+ import type { ModelRegistry } from "../config/model-registry.js";
4
+ import type { Settings } from "../config/settings.js";
5
+ import { type ConfiguredThinkingLevel } from "../thinking.js";
6
+ /** Configured fallback chains keyed by role or model selector. */
7
+ export type RetryFallbackChains = Record<string, string[]>;
8
+ /** Policy controlling restoration of a fallback chain's primary model. */
9
+ export type RetryFallbackRevertPolicy = "never" | "cooldown-expiry";
10
+ /** Parsed model selector used by retry fallback resolution. */
11
+ export interface RetryFallbackSelector {
12
+ raw: string;
13
+ provider: string;
14
+ id: string;
15
+ thinkingLevel: ThinkingLevel | undefined;
16
+ }
17
+ /** Minimal model lookup needed by fallback-chain resolution. */
18
+ export interface RetryFallbackModelLookup {
19
+ find(provider: string, id: string): Model | undefined;
20
+ hasProvider(provider: string): boolean;
21
+ }
22
+ /**
23
+ * Inputs shared by startup (sdk) and runtime (turn-recovery) fallback-chain
24
+ * resolution. `chains` is pre-expanded so callers can apply the default chain
25
+ * to roles beyond the configured model roles (e.g. a subagent fallback role).
26
+ */
27
+ export interface RetryFallbackResolutionContext {
28
+ chains: RetryFallbackChains;
29
+ getModelRole(role: string): string | undefined;
30
+ modelLookup: RetryFallbackModelLookup;
31
+ }
32
+ /** Active retry fallback state retained until the primary can be restored. */
33
+ export interface ActiveRetryFallbackState {
34
+ /** Chain key that produced this fallback: a model-role name or a model-selector key. */
35
+ role: string;
36
+ originalSelector: string;
37
+ originalThinkingLevel: ConfiguredThinkingLevel | undefined;
38
+ lastAppliedFallbackThinkingLevel: ConfiguredThinkingLevel | undefined;
39
+ pinned: boolean;
40
+ }
41
+ /** Calculates capped exponential retry delay with downward jitter. */
42
+ export declare function calculateRetryBackoffDelayMs(baseDelayMs: number, attempt: number): number;
43
+ /** Parses a configured retry fallback selector. */
44
+ export declare function parseRetryFallbackSelector(selector: string, modelLookup?: Pick<RetryFallbackModelLookup, "find">): RetryFallbackSelector | undefined;
45
+ /** Whether a fallback-chain key is a model selector rather than a role. */
46
+ export declare function isRetryFallbackModelKey(key: string): boolean;
47
+ /** Whether a fallback-chain key or entry is a provider wildcard. */
48
+ export declare function isRetryFallbackWildcardKey(key: string): boolean;
49
+ /** Splits a wildcard selector into provider and optional model-id prefix. */
50
+ export declare function parseRetryFallbackWildcard(key: string, isKnownProvider: (provider: string) => boolean): {
51
+ provider: string;
52
+ idPrefix: string | undefined;
53
+ };
54
+ /** Formats a concrete model and thinking level as a fallback selector. */
55
+ export declare function formatRetryFallbackSelector(model: Model, thinkingLevel: ThinkingLevel | undefined): string;
56
+ /** Whether a provider is registered or configured for discovery. */
57
+ export declare function isKnownProvider(modelRegistry: ModelRegistry, provider: string): boolean;
58
+ /** Apply the configured default chain to roles without their own chain. */
59
+ export declare function expandDefaultRetryFallbackChains(configuredChains: RetryFallbackChains, roleNames: readonly string[]): RetryFallbackChains;
60
+ /** Resolves configured fallback chains, applying the default chain to named roles. */
61
+ export declare function getRetryFallbackChains(settings: Settings): RetryFallbackChains;
62
+ /** Validates configured fallback chains and reports each warning. */
63
+ export declare function validateRetryFallbackChains(settings: Settings, modelRegistry: ModelRegistry, warn: (message: string) => void): void;
64
+ /** Returns the configured fallback-primary restoration policy. */
65
+ export declare function getRetryFallbackRevertPolicy(settings: Settings): RetryFallbackRevertPolicy;
66
+ /**
67
+ * Resolve the chain key for a concrete selector by specificity: exact model,
68
+ * longest matching wildcard, hinted/configured role, then default.
69
+ */
70
+ export declare function resolveRetryFallbackChainKey(context: RetryFallbackResolutionContext, currentSelector: string, currentModel?: Model | null, roleHint?: string): string | undefined;
71
+ /** Return the candidates after the current selector in an effective chain. */
72
+ export declare function findRetryFallbackCandidates(context: RetryFallbackResolutionContext, chainKey: string, currentSelector: string, currentModel?: Model | null, options?: {
73
+ allowMissingPrimary?: boolean;
74
+ }): RetryFallbackSelector[];
@@ -0,0 +1,15 @@
1
+ import type { ThinkingLevel } from "@oh-my-pi/pi-agent-core";
2
+ import type { Model } from "@oh-my-pi/pi-ai";
3
+ import type { ModelRegistry } from "../config/model-registry.js";
4
+ import { type ResolvedModelRoleValue } from "../config/model-resolver.js";
5
+ import type { Settings } from "../config/settings.js";
6
+ /** Formats a role assignment while preserving its explicit thinking selector. */
7
+ export declare function formatRoleModelValue(settings: Settings, modelRegistry: ModelRegistry, role: string, model: Model, selectorOverride?: string, thinkingLevelOverride?: ThinkingLevel): string;
8
+ /** Resolves a configured model target relative to the current provider. */
9
+ export declare function resolveConfiguredModelTarget(configuredTarget: string | undefined, currentModel: Model, availableModels: Model[]): Model | undefined;
10
+ /** Resolves a model's configured context-promotion target. */
11
+ export declare function resolveContextPromotionConfiguredTarget(currentModel: Model, availableModels: Model[]): Model | undefined;
12
+ /** Resolves a model's configured compaction target. */
13
+ export declare function resolveCompactionConfiguredTarget(currentModel: Model, availableModels: Model[]): Model | undefined;
14
+ /** Resolves a model role and its explicit thinking selection. */
15
+ export declare function resolveRoleModelFull(settings: Settings, role: string, availableModels: Model[], currentModel: Model | undefined): ResolvedModelRoleValue;