@alisio/core 0.1.0-alpha.9 → 0.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 (187) hide show
  1. package/README.md +52 -7
  2. package/dist/agents/active.d.ts +99 -0
  3. package/dist/agents/active.js +218 -0
  4. package/dist/agents/capabilities.d.ts +26 -0
  5. package/dist/agents/capabilities.js +120 -0
  6. package/dist/agents/create-agent-skill.d.ts +11 -0
  7. package/dist/agents/create-agent-skill.js +60 -0
  8. package/dist/agents/definitions.d.ts +88 -0
  9. package/dist/agents/definitions.js +404 -0
  10. package/dist/agents/draft.d.ts +41 -0
  11. package/dist/agents/draft.js +133 -0
  12. package/dist/agents/service.d.ts +57 -0
  13. package/dist/agents/service.js +86 -0
  14. package/dist/agents/templates.d.ts +8 -0
  15. package/dist/agents/templates.js +102 -0
  16. package/dist/analysis/capabilities.d.ts +48 -0
  17. package/dist/analysis/capabilities.js +90 -0
  18. package/dist/analysis/data/csv.d.ts +46 -0
  19. package/dist/analysis/data/csv.js +240 -0
  20. package/dist/analysis/data/datasets.d.ts +132 -0
  21. package/dist/analysis/data/datasets.js +441 -0
  22. package/dist/analysis/data/describe.d.ts +27 -0
  23. package/dist/analysis/data/describe.js +103 -0
  24. package/dist/analysis/data/engine-client.d.ts +58 -0
  25. package/dist/analysis/data/engine-client.js +304 -0
  26. package/dist/analysis/data/engine-entry.d.ts +1 -0
  27. package/dist/analysis/data/engine-entry.js +59 -0
  28. package/dist/analysis/data/engine-source.d.ts +4 -0
  29. package/dist/analysis/data/engine-source.js +6 -0
  30. package/dist/analysis/data/engine-types.d.ts +86 -0
  31. package/dist/analysis/data/engine-types.js +7 -0
  32. package/dist/analysis/data/infer.d.ts +42 -0
  33. package/dist/analysis/data/infer.js +118 -0
  34. package/dist/analysis/data/ingest-worker.d.ts +17 -0
  35. package/dist/analysis/data/ingest-worker.js +365 -0
  36. package/dist/analysis/data/json.d.ts +19 -0
  37. package/dist/analysis/data/json.js +44 -0
  38. package/dist/analysis/data/query-worker.d.ts +12 -0
  39. package/dist/analysis/data/query-worker.js +75 -0
  40. package/dist/analysis/data/rows.d.ts +39 -0
  41. package/dist/analysis/data/rows.js +120 -0
  42. package/dist/analysis/data/sql-guard.d.ts +20 -0
  43. package/dist/analysis/data/sql-guard.js +129 -0
  44. package/dist/analysis/data/stats.d.ts +18 -0
  45. package/dist/analysis/data/stats.js +77 -0
  46. package/dist/analysis/install-hints.d.ts +33 -0
  47. package/dist/analysis/install-hints.js +144 -0
  48. package/dist/analysis/janitor.d.ts +60 -0
  49. package/dist/analysis/janitor.js +264 -0
  50. package/dist/analysis/jobs.d.ts +94 -0
  51. package/dist/analysis/jobs.js +165 -0
  52. package/dist/analysis/oci.d.ts +129 -0
  53. package/dist/analysis/oci.js +330 -0
  54. package/dist/analysis/python/sources.d.ts +2 -0
  55. package/dist/analysis/python/sources.js +10 -0
  56. package/dist/analysis/requirements.d.ts +32 -0
  57. package/dist/analysis/requirements.js +73 -0
  58. package/dist/analysis/rerun.d.ts +40 -0
  59. package/dist/analysis/rerun.js +136 -0
  60. package/dist/analysis/runtime-manager.d.ts +146 -0
  61. package/dist/analysis/runtime-manager.js +472 -0
  62. package/dist/analysis/status.d.ts +21 -0
  63. package/dist/analysis/status.js +52 -0
  64. package/dist/application.d.ts +105 -3
  65. package/dist/application.js +446 -18
  66. package/dist/artifacts/kinds.d.ts +35 -0
  67. package/dist/artifacts/kinds.js +177 -0
  68. package/dist/artifacts/publisher.d.ts +7 -0
  69. package/dist/artifacts/publisher.js +29 -0
  70. package/dist/artifacts/store.d.ts +119 -0
  71. package/dist/artifacts/store.js +581 -0
  72. package/dist/background/janitor.d.ts +22 -0
  73. package/dist/background/janitor.js +62 -0
  74. package/dist/background/mirror.d.ts +14 -0
  75. package/dist/background/mirror.js +41 -0
  76. package/dist/background/notify.d.ts +58 -0
  77. package/dist/background/notify.js +172 -0
  78. package/dist/background/output.d.ts +46 -0
  79. package/dist/background/output.js +179 -0
  80. package/dist/background/service.d.ts +137 -0
  81. package/dist/background/service.js +410 -0
  82. package/dist/background/store.d.ts +103 -0
  83. package/dist/background/store.js +195 -0
  84. package/dist/changelog/data.d.ts +6 -0
  85. package/dist/changelog/data.js +293 -0
  86. package/dist/changelog/index.d.ts +5 -0
  87. package/dist/changelog/index.js +7 -0
  88. package/dist/changelog/parse.d.ts +53 -0
  89. package/dist/changelog/parse.js +160 -0
  90. package/dist/commands/builtins.d.ts +10 -0
  91. package/dist/commands/builtins.js +161 -0
  92. package/dist/commands/catalog.d.ts +86 -0
  93. package/dist/commands/catalog.js +304 -0
  94. package/dist/config.d.ts +206 -6
  95. package/dist/config.js +426 -20
  96. package/dist/core/compaction.js +13 -2
  97. package/dist/core/contracts.d.ts +180 -3
  98. package/dist/core/opt-in.d.ts +12 -0
  99. package/dist/core/opt-in.js +12 -0
  100. package/dist/core/output-limit.d.ts +34 -0
  101. package/dist/core/output-limit.js +39 -0
  102. package/dist/core/run-stats.d.ts +16 -0
  103. package/dist/core/run-stats.js +8 -0
  104. package/dist/core/runner.d.ts +134 -4
  105. package/dist/core/runner.js +780 -138
  106. package/dist/core/timeout.d.ts +15 -0
  107. package/dist/core/timeout.js +61 -0
  108. package/dist/core/truncation.d.ts +30 -0
  109. package/dist/core/truncation.js +83 -0
  110. package/dist/goal/blockers.d.ts +45 -0
  111. package/dist/goal/blockers.js +51 -0
  112. package/dist/goal/budget.d.ts +24 -0
  113. package/dist/goal/budget.js +53 -0
  114. package/dist/goal/command.d.ts +36 -0
  115. package/dist/goal/command.js +98 -0
  116. package/dist/goal/format.d.ts +19 -0
  117. package/dist/goal/format.js +102 -0
  118. package/dist/goal/host.d.ts +29 -0
  119. package/dist/goal/host.js +42 -0
  120. package/dist/goal/index.d.ts +9 -0
  121. package/dist/goal/index.js +9 -0
  122. package/dist/goal/machine.d.ts +186 -0
  123. package/dist/goal/machine.js +344 -0
  124. package/dist/goal/prompts.d.ts +10 -0
  125. package/dist/goal/prompts.js +75 -0
  126. package/dist/goal/service.d.ts +113 -0
  127. package/dist/goal/service.js +273 -0
  128. package/dist/goal/store.d.ts +59 -0
  129. package/dist/goal/store.js +184 -0
  130. package/dist/index.d.ts +50 -5
  131. package/dist/index.js +49 -4
  132. package/dist/mcp/connector.js +38 -6
  133. package/dist/mcp/rich.d.ts +41 -0
  134. package/dist/mcp/rich.js +362 -0
  135. package/dist/permissions/modes.d.ts +72 -0
  136. package/dist/permissions/modes.js +98 -0
  137. package/dist/plan/exit-plan.d.ts +25 -0
  138. package/dist/plan/exit-plan.js +130 -0
  139. package/dist/plan/state.d.ts +102 -0
  140. package/dist/plan/state.js +165 -0
  141. package/dist/plugins/host.d.ts +34 -1
  142. package/dist/plugins/host.js +143 -9
  143. package/dist/providers/settings.d.ts +15 -0
  144. package/dist/providers/settings.js +38 -0
  145. package/dist/reload.d.ts +75 -0
  146. package/dist/reload.js +204 -0
  147. package/dist/resources/context.js +6 -1
  148. package/dist/runtime/access.d.ts +62 -0
  149. package/dist/runtime/access.js +115 -0
  150. package/dist/runtime/blobs.d.ts +51 -0
  151. package/dist/runtime/blobs.js +177 -0
  152. package/dist/runtime/diff.d.ts +23 -0
  153. package/dist/runtime/diff.js +154 -0
  154. package/dist/runtime/ids.d.ts +8 -0
  155. package/dist/runtime/ids.js +32 -0
  156. package/dist/runtime/paths.d.ts +11 -0
  157. package/dist/runtime/paths.js +17 -1
  158. package/dist/runtime/process.d.ts +22 -0
  159. package/dist/runtime/process.js +100 -15
  160. package/dist/runtime/sqlite.d.ts +2 -0
  161. package/dist/runtime/sqlite.js +18 -0
  162. package/dist/runtime/store.d.ts +91 -3
  163. package/dist/runtime/store.js +465 -11
  164. package/dist/runtime/zip.d.ts +24 -0
  165. package/dist/runtime/zip.js +126 -0
  166. package/dist/sessions/children.js +17 -1
  167. package/dist/sessions/side-questions.d.ts +57 -0
  168. package/dist/sessions/side-questions.js +161 -0
  169. package/dist/tools/analysis.d.ts +37 -0
  170. package/dist/tools/analysis.js +573 -0
  171. package/dist/tools/artifacts.d.ts +14 -0
  172. package/dist/tools/artifacts.js +143 -0
  173. package/dist/tools/background.d.ts +7 -0
  174. package/dist/tools/background.js +165 -0
  175. package/dist/tools/data.d.ts +7 -0
  176. package/dist/tools/data.js +160 -0
  177. package/dist/tools/execute.d.ts +5 -0
  178. package/dist/tools/execute.js +15 -3
  179. package/dist/tools/goal.d.ts +19 -0
  180. package/dist/tools/goal.js +126 -0
  181. package/dist/tools/search.d.ts +17 -3
  182. package/dist/tools/search.js +153 -0
  183. package/dist/tools/standard.d.ts +4 -1
  184. package/dist/tools/standard.js +99 -18
  185. package/dist/version.d.ts +5 -3
  186. package/dist/version.js +35 -6
  187. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import type { CompactionCheckpoint, Message, ToolCall, ToolResult } from "@alisio/sdk";
1
+ import type { AnalysisCapability, ArtifactPublisher, ArtifactRef, CompactionCheckpoint, InstallPreview, Message, ToolCall, ToolResult } from "@alisio/sdk";
2
2
  export interface Session {
3
3
  id: string;
4
4
  workspace: string;
@@ -18,6 +18,10 @@ export interface Session {
18
18
  options?: Record<string, unknown>;
19
19
  createdAt?: number;
20
20
  updatedAt?: number;
21
+ /** Root sessions pinned in web clients (v4). */
22
+ pinned?: boolean;
23
+ /** When a root session was archived in web clients (v4); absent when not archived. */
24
+ archivedAt?: number;
21
25
  }
22
26
  export interface ChildSessionRecord {
23
27
  id?: string;
@@ -30,6 +34,82 @@ export interface ChildSessionRecord {
30
34
  depth: number;
31
35
  options: Record<string, unknown>;
32
36
  }
37
+ /** `queued` and `running` are the only non-terminal run states. */
38
+ export type RunStatus = "queued" | "running" | "completed" | "turns_exceeded" | "failed" | "cancelled" | "interrupted";
39
+ export type TerminalRunStatus = Exclude<RunStatus, "queued" | "running">;
40
+ /** One `AgentRunner.run` execution (v4 `runs` table). `id` equals `RunEvent.runId`. */
41
+ export interface RunRecord {
42
+ id: string;
43
+ session: string;
44
+ status: RunStatus;
45
+ /** Client idempotency key; absent for TUI/headless runs. */
46
+ requestId?: string;
47
+ correlationId?: string;
48
+ /** Process that executes (or executed) the run, for startup reconciliation. */
49
+ ownerPid?: number;
50
+ model?: string;
51
+ createdAt: number;
52
+ startedAt?: number;
53
+ endedAt?: number;
54
+ error?: string;
55
+ usage?: {
56
+ input: number;
57
+ output: number;
58
+ cachedInput?: number;
59
+ };
60
+ }
61
+ export interface BeginRunInput {
62
+ id: string;
63
+ session: string;
64
+ /** `queued` for scheduled runs, `running` (default) when execution starts now. */
65
+ status?: "queued" | "running";
66
+ requestId?: string;
67
+ correlationId?: string;
68
+ model?: string;
69
+ }
70
+ export interface EndRunInput {
71
+ status: TerminalRunStatus;
72
+ error?: string;
73
+ usage?: {
74
+ input: number;
75
+ output: number;
76
+ cachedInput?: number;
77
+ };
78
+ }
79
+ export interface PageOptions {
80
+ /** Only rows with a sequence greater than this (ascending from there). */
81
+ after?: number;
82
+ /** Only rows with a sequence lower than this (the newest `limit` of them). */
83
+ before?: number;
84
+ limit?: number;
85
+ }
86
+ export interface MessagePage {
87
+ items: Array<{
88
+ seq: number;
89
+ message: Message;
90
+ compacted: boolean;
91
+ }>;
92
+ /** More rows exist beyond the page in the paging direction. */
93
+ hasMore: boolean;
94
+ }
95
+ export interface StoredEvent {
96
+ /** Global `events.seq` as a string (same value as `RunEvent.eventId`). */
97
+ eventId: string;
98
+ runId: string;
99
+ type: string;
100
+ data: unknown;
101
+ createdAt?: number;
102
+ correlationId?: string;
103
+ }
104
+ export interface EventPage {
105
+ items: StoredEvent[];
106
+ hasMore: boolean;
107
+ }
108
+ /** Optional tool-call metadata (v4 columns); stores may ignore it. */
109
+ export interface ToolCallMeta {
110
+ runId?: string;
111
+ effect?: string;
112
+ }
33
113
  export interface SessionStore {
34
114
  create(workspace: string, provider: string, model: string): Session;
35
115
  get(id: string): Session;
@@ -64,10 +144,39 @@ export interface SessionStore {
64
144
  overwrite(id: string, messages: Message[]): void;
65
145
  acquire(id: string): void;
66
146
  release(id: string): void;
67
- beginCall(session: string, call: ToolCall): void;
147
+ beginCall(session: string, call: ToolCall, meta?: ToolCallMeta): void;
68
148
  endCall(session: string, call: ToolCall, result: ToolResult): void;
149
+ /** The persisted result of a completed tool call, for replay of rich (ui/image) parts. */
150
+ callResult(session: string, callId: string): ToolResult | undefined;
69
151
  reconcile(id: string, acknowledge?: boolean): void;
70
- event(id: string, runId: string, type: string, data: unknown): void;
152
+ /**
153
+ * Persist a durable run event. Stores that assign a global, monotonic sequence return it; the
154
+ * runner exposes it as `RunEvent.eventId`. Returning nothing is allowed (no `eventId`).
155
+ */
156
+ event(id: string, runId: string, type: string, data: unknown, meta?: {
157
+ correlationId?: string;
158
+ }): number | void;
159
+ /**
160
+ * Records a run, or moves an existing `queued` run with the same id to `running`. A run whose
161
+ * `(session, requestId)` already exists is returned as is (`created: false`): idempotency.
162
+ */
163
+ beginRun?(input: BeginRunInput): {
164
+ run: RunRecord;
165
+ created: boolean;
166
+ };
167
+ /** Moves a non-terminal run to a terminal state; terminal runs are never overwritten. */
168
+ endRun?(id: string, input: EndRunInput): void;
169
+ runByRequest?(session: string, requestId: string): RunRecord | undefined;
170
+ /** Runs of a session, newest first. */
171
+ runs?(session: string, options?: {
172
+ limit?: number;
173
+ }): RunRecord[];
174
+ messagesPage?(session: string, options?: PageOptions & {
175
+ compacted?: boolean;
176
+ }): MessagePage;
177
+ eventsPage?(session: string, options?: PageOptions): EventPage;
178
+ /** Marks queued/running runs whose owner process is not alive as interrupted. */
179
+ interruptRuns?(): number;
71
180
  }
72
181
  export interface ContextSource {
73
182
  /** System instructions; `sessionId` scopes lazily attached nested instructions. */
@@ -79,6 +188,11 @@ export interface Policy {
79
188
  write: boolean;
80
189
  process: boolean;
81
190
  external: boolean;
191
+ /**
192
+ * Pre-allows the `analysis.run` capability only (`--allow-analysis`); never widens `process`.
193
+ * Absent means false.
194
+ */
195
+ analysis?: boolean;
82
196
  }
83
197
  export type ApprovalDecision = "once" | "session" | "deny";
84
198
  export interface ApprovalRequest {
@@ -90,7 +204,70 @@ export interface ApprovalRequest {
90
204
  effect: "write" | "process" | "external";
91
205
  input: Record<string, unknown>;
92
206
  signal: AbortSignal;
207
+ /** The approval is for this capability of the tool, not for the whole effect. */
208
+ capability?: AnalysisCapability;
209
+ /** Capability approvals: the first 40 lines of the script. */
210
+ preview?: string;
211
+ /** Capability approvals: how the code runs (`managed` is not sandboxed). */
212
+ runtime?: "managed" | "oci";
213
+ /** `analysis.install`: the packages, the size estimate and the network need (once or deny). */
214
+ install?: InstallPreview;
215
+ }
216
+ /**
217
+ * Persisted capability grants as the runner sees them (implemented by `CapabilityGrants`). A
218
+ * `session` decision is stored for the ROOT session and survives restarts; `once` and `deny`
219
+ * decisions are audit rows only.
220
+ */
221
+ export interface CapabilityGate {
222
+ granted(capability: AnalysisCapability, sessionId: string): boolean;
223
+ record(input: {
224
+ capability: AnalysisCapability;
225
+ sessionId: string;
226
+ scope: "once" | "session";
227
+ decision: "allow" | "deny";
228
+ source: "tui" | "web" | "flag" | "headless-grant";
229
+ callId?: string;
230
+ runId?: string;
231
+ correlationId?: string;
232
+ }): void;
233
+ /** Recorded as the source of interactive decisions (`tui` or `web`). */
234
+ source?: "tui" | "web";
235
+ /** Runtime mode shown with `analysis.run` approvals (read live: the configuration can change). */
236
+ runtime?: "managed" | "oci";
237
+ /**
238
+ * The script to show in an approval whose input does not carry it (a rerun runs a saved script).
239
+ * Absent or undefined: the preview is taken from `input.code`.
240
+ */
241
+ preview?(input: Record<string, unknown>, sessionId: string): Promise<string | undefined>;
242
+ }
243
+ /** One artifact published during a tool call, with its local path (for `artifact_published`). */
244
+ export interface PublishedArtifactInfo {
245
+ artifact: ArtifactRef;
246
+ path: string;
247
+ warnings: string[];
248
+ executionId?: string;
249
+ }
250
+ /** The publisher core tools receive; `publishOutputs` publishes a whole staging folder at once. */
251
+ export interface CoreArtifactPublisher extends ArtifactPublisher {
252
+ publishOutputs(staging: string, options: {
253
+ executionId: string;
254
+ title?: string;
255
+ partial?: boolean;
256
+ provenance?: Record<string, unknown>;
257
+ }): Promise<PublishedArtifactInfo[]>;
258
+ /** Detailed variant of `publishText` (path and warnings). */
259
+ publishTextDetailed(input: {
260
+ fileName: string;
261
+ title?: string;
262
+ text: string;
263
+ }): Promise<PublishedArtifactInfo>;
93
264
  }
265
+ /** Creates the publisher of one tool call; `announce` emits `artifact_published`. */
266
+ export type ArtifactPublisherFactory = (call: {
267
+ sessionId: string;
268
+ runId: string;
269
+ callId: string;
270
+ }, announce: (published: PublishedArtifactInfo) => void) => CoreArtifactPublisher | undefined;
94
271
  /** Optional interactive approval for write/process/external tools not pre-allowed by the Policy. */
95
272
  export type ApprovalHandler = (request: ApprovalRequest) => Promise<ApprovalDecision>;
96
273
  export interface HookFailure {
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Tools that exist only for runs that ask for them. The registry is shared by the main session,
3
+ * its child sessions and Code Mode, so hiding a tool from "everything but the plan agent" cannot
4
+ * be a filter on the plan run: the tool is hidden by default and a run lists it in
5
+ * `RunOptions.optInTools` to see (and be allowed to call) it.
6
+ */
7
+ export declare const EXIT_PLAN_TOOL = "exit_plan";
8
+ /** The goal tools: offered only while the session has an active goal (see `goal/service.ts`). */
9
+ export declare const GOAL_TOOLS: readonly string[];
10
+ export declare const OPT_IN_TOOLS: ReadonlySet<string>;
11
+ /** Whether `name` may be offered or executed for a run that opted into `optIn`. */
12
+ export declare const optInAllows: (name: string, optIn: readonly string[] | undefined) => boolean;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Tools that exist only for runs that ask for them. The registry is shared by the main session,
3
+ * its child sessions and Code Mode, so hiding a tool from "everything but the plan agent" cannot
4
+ * be a filter on the plan run: the tool is hidden by default and a run lists it in
5
+ * `RunOptions.optInTools` to see (and be allowed to call) it.
6
+ */
7
+ export const EXIT_PLAN_TOOL = "exit_plan";
8
+ /** The goal tools: offered only while the session has an active goal (see `goal/service.ts`). */
9
+ export const GOAL_TOOLS = ["get_goal", "update_goal"];
10
+ export const OPT_IN_TOOLS = new Set([EXIT_PLAN_TOOL, ...GOAL_TOOLS]);
11
+ /** Whether `name` may be offered or executed for a run that opted into `optIn`. */
12
+ export const optInAllows = (name, optIn) => !OPT_IN_TOOLS.has(name) || !!optIn?.includes(name);
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The output-token budget of one model request.
3
+ *
4
+ * Priority: a value the user set explicitly (`limits.maxOutputTokens` in any config layer,
5
+ * `/settings`, a per-run option) always wins, even above the model's declared maximum (they asked
6
+ * for it, and a provider that rejects it says so); otherwise the maximum the model's catalog
7
+ * declares (`ModelInfo.maxOutputTokens`), capped at `MAX_AUTO_OUTPUT_TOKENS`; otherwise
8
+ * `DEFAULT_MAX_OUTPUT_TOKENS`. The value is resolved for the model of each request, so switching
9
+ * model within a session changes it.
10
+ */
11
+ /** Output budget used when neither the user nor the model catalog says anything. */
12
+ export declare const DEFAULT_MAX_OUTPUT_TOKENS = 16384;
13
+ /**
14
+ * Upper bound of a budget taken from a model's declared maximum. Catalogs declare the model's
15
+ * hard limit (hundreds of thousands of tokens for some reasoning models), which is far more than
16
+ * a single agent turn should be allowed to stream; an explicit user value is never capped by it.
17
+ */
18
+ export declare const MAX_AUTO_OUTPUT_TOKENS = 65536;
19
+ /** Where the effective budget came from. */
20
+ export type OutputLimitSource = "user" | "model" | "default";
21
+ export interface OutputLimit {
22
+ value: number;
23
+ source: OutputLimitSource;
24
+ }
25
+ export declare function resolveMaxOutputTokens(input: {
26
+ /** Set by the user (config, settings or a per-run option); `undefined` when only defaulted. */
27
+ explicit?: number | undefined;
28
+ /** `ModelInfo.maxOutputTokens` of the model of the request, when its catalog declares one. */
29
+ declared?: number | undefined;
30
+ /** Used when nothing else applies; `DEFAULT_MAX_OUTPUT_TOKENS` unless the host knows better. */
31
+ fallback?: number | undefined;
32
+ }): OutputLimit;
33
+ /** A short English phrase for messages and logs. */
34
+ export declare function describeOutputLimitSource(source: OutputLimitSource | undefined): string;
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The output-token budget of one model request.
3
+ *
4
+ * Priority: a value the user set explicitly (`limits.maxOutputTokens` in any config layer,
5
+ * `/settings`, a per-run option) always wins, even above the model's declared maximum (they asked
6
+ * for it, and a provider that rejects it says so); otherwise the maximum the model's catalog
7
+ * declares (`ModelInfo.maxOutputTokens`), capped at `MAX_AUTO_OUTPUT_TOKENS`; otherwise
8
+ * `DEFAULT_MAX_OUTPUT_TOKENS`. The value is resolved for the model of each request, so switching
9
+ * model within a session changes it.
10
+ */
11
+ /** Output budget used when neither the user nor the model catalog says anything. */
12
+ export const DEFAULT_MAX_OUTPUT_TOKENS = 16_384;
13
+ /**
14
+ * Upper bound of a budget taken from a model's declared maximum. Catalogs declare the model's
15
+ * hard limit (hundreds of thousands of tokens for some reasoning models), which is far more than
16
+ * a single agent turn should be allowed to stream; an explicit user value is never capped by it.
17
+ */
18
+ export const MAX_AUTO_OUTPUT_TOKENS = 65_536;
19
+ const positive = (value) => typeof value === "number" && Number.isFinite(value) && value >= 1;
20
+ export function resolveMaxOutputTokens(input) {
21
+ if (positive(input.explicit))
22
+ return { value: Math.floor(input.explicit), source: "user" };
23
+ if (positive(input.declared))
24
+ return { value: Math.min(Math.floor(input.declared), MAX_AUTO_OUTPUT_TOKENS), source: "model" };
25
+ return {
26
+ value: positive(input.fallback) ? Math.floor(input.fallback) : DEFAULT_MAX_OUTPUT_TOKENS,
27
+ source: "default",
28
+ };
29
+ }
30
+ /** A short English phrase for messages and logs. */
31
+ export function describeOutputLimitSource(source) {
32
+ if (source === "user")
33
+ return "set by you";
34
+ if (source === "model")
35
+ return "from the model catalog";
36
+ if (source === "default")
37
+ return "default";
38
+ return "current limit";
39
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * What a run that FAILED had already spent. `runner.run` resolves with its usage and tool-call
3
+ * count, but a run that throws (a provider error, a timeout, the token-budget guard) loses them;
4
+ * the goal controller still needs them (a run stopped by its own token cap must count as spent,
5
+ * not as an error). The runner remembers them against the thrown error, outside of it (a
6
+ * WeakMap), so no error object is changed.
7
+ */
8
+ export interface RunStats {
9
+ usage: {
10
+ input: number;
11
+ output: number;
12
+ };
13
+ toolCalls: number;
14
+ }
15
+ export declare function attachRunStats(error: unknown, stats: RunStats): void;
16
+ export declare function runStatsOf(error: unknown): RunStats | undefined;
@@ -0,0 +1,8 @@
1
+ const STATS = new WeakMap();
2
+ export function attachRunStats(error, stats) {
3
+ if (error && typeof error === "object")
4
+ STATS.set(error, stats);
5
+ }
6
+ export function runStatsOf(error) {
7
+ return error && typeof error === "object" ? STATS.get(error) : undefined;
8
+ }
@@ -1,5 +1,6 @@
1
- import { type Attachment, type Message, type ModelProvider, type RunEvent, type ToolDefinition } from "@alisio/sdk";
2
- import type { ApprovalHandler, ContextSource, Policy, RunnerExtensions, SessionStore } from "./contracts.ts";
1
+ import { type Attachment, type DatasetRef, type Message, type ModelProvider, type RunEvent, type ToolDefinition, type ToolResult } from "@alisio/sdk";
2
+ import type { PathAccess } from "../runtime/access.ts";
3
+ import type { ApprovalHandler, ArtifactPublisherFactory, CapabilityGate, ContextSource, Policy, RunnerExtensions, SessionStore } from "./contracts.ts";
3
4
  import type { ToolRegistry } from "./registry.ts";
4
5
  export interface CompactionSettings {
5
6
  /** Compact automatically when context usage crosses `threshold` of a known window. */
@@ -23,8 +24,35 @@ export interface RunnerOptions {
23
24
  workspace: string;
24
25
  maxTurns?: number;
25
26
  timeoutMs?: number;
27
+ /** See `RunnerSettingsPatch.firstTokenTimeoutMs`. */
28
+ firstTokenTimeoutMs?: number;
29
+ /** See `RunnerSettingsPatch.firstTokenRetries`. */
30
+ firstTokenRetries?: number;
31
+ /** See `RunnerSettingsPatch.truncationRecoveries`. */
32
+ truncationRecoveries?: number;
33
+ /**
34
+ * Reasoning effort levels a model advertises (`ModelInfo.effort`), when known. Lets a recovery
35
+ * from an exhausted reasoning budget request one level lower; without it effort is unchanged.
36
+ */
37
+ effortLevels?: (model: string) => {
38
+ supportedLevels: string[];
39
+ defaultLevel?: string;
40
+ } | undefined;
26
41
  maxContextChars?: number;
42
+ /**
43
+ * Output-token budget the USER set (`limits.maxOutputTokens`). Left unset, the budget of each
44
+ * request is the model's declared maximum (`modelOutputLimit`, capped), else
45
+ * `fallbackMaxOutputTokens`. See `resolveMaxOutputTokens`.
46
+ */
27
47
  maxOutputTokens?: number;
48
+ /**
49
+ * The maximum output a model's catalog declares (`ModelInfo.maxOutputTokens`), when known.
50
+ * May be async (a catalog still loading); a failure counts as unknown. Called for the model
51
+ * of every request, so a model switch changes the budget.
52
+ */
53
+ modelOutputLimit?: (model: string) => number | undefined | Promise<number | undefined>;
54
+ /** Budget when neither the user nor the catalog says anything (4096 for bare embedders). */
55
+ fallbackMaxOutputTokens?: number;
28
56
  maxTokens?: number;
29
57
  onEvent?: (event: RunEvent) => void;
30
58
  readConcurrency?: number;
@@ -34,14 +62,28 @@ export interface RunnerOptions {
34
62
  compaction?: CompactionSettings;
35
63
  /** When set, write/process tools not allowed by the policy are offered and ask first. */
36
64
  approve?: ApprovalHandler;
65
+ /**
66
+ * Mediated path policy (workspace plus declared extra directories and external approval).
67
+ * When set, declared tool paths outside the allowed roots ask before the effect gate runs.
68
+ */
69
+ pathAccess?: PathAccess;
37
70
  /** Generic hooks (implemented by the plugin host) for compaction and session start. */
38
71
  extensions?: RunnerExtensions;
72
+ /** Persisted capability grants (`analysis.run`); without it capabilities only follow `effect`. */
73
+ capabilities?: CapabilityGate;
74
+ /** Artifact publisher of each tool call (`ToolContext.artifacts`). */
75
+ artifacts?: ArtifactPublisherFactory;
39
76
  /**
40
77
  * Provider-native tool definitions (for example a hosted `web_search` tool) appended to every
41
78
  * request's `tools` alongside the registry's function tools. Opt-in, set once for the whole
42
79
  * runner; only meaningful for a provider that documents an equivalent server-side tool.
43
80
  */
44
81
  nativeTools?: Array<Record<string, unknown>>;
82
+ /**
83
+ * Default reasoning effort level (a value from the current model's `ModelInfo.effort`), sent on
84
+ * every run unless overridden per-run. Providers that do not advertise effort levels ignore it.
85
+ */
86
+ reasoningEffort?: string;
45
87
  }
46
88
  /** The settings a running TUI can change live; merged into the runner options on apply. */
47
89
  export interface RunnerSettingsPatch {
@@ -55,6 +97,22 @@ export interface RunnerSettingsPatch {
55
97
  maxContextChars?: number;
56
98
  /** Per-run timeout in milliseconds; the next run honors it. */
57
99
  timeoutMs?: number;
100
+ /**
101
+ * Stop a model request that stays completely silent (no text, reasoning or tool-call delta)
102
+ * for this many milliseconds. `0` or unset disables it: only the run timeout applies.
103
+ */
104
+ firstTokenTimeoutMs?: number;
105
+ /**
106
+ * How many times the same request is sent again after a silent timeout (`firstTokenTimeoutMs`).
107
+ * `0` or unset disables it. A retry is not a turn; it only happens while nothing at all was
108
+ * received for the request.
109
+ */
110
+ firstTokenRetries?: number;
111
+ /**
112
+ * How many times a turn is requested again after the response was cut off by the output-token
113
+ * limit before it was usable. `0` or unset disables it. A recovery is not a turn.
114
+ */
115
+ truncationRecoveries?: number;
58
116
  }
59
117
  /**
60
118
  * Per-run overrides used by embedders and child sessions. Callers must only NARROW: `policy`
@@ -65,9 +123,16 @@ export interface RunOptions {
65
123
  display?: string;
66
124
  /** Images attached to this turn's user message, sent as vision content parts. */
67
125
  attachments?: Attachment[];
126
+ /** Datasets attached to this turn (UI chips); their text summary is part of the prompt. */
127
+ datasets?: DatasetRef[];
68
128
  /** Extra system instructions for this run (e.g. an agent persona). */
69
129
  instructions?: string;
70
130
  toolFilter?: (tool: ToolDefinition) => boolean;
131
+ /**
132
+ * Opt-in tools this run may use (see `OPT_IN_TOOLS`): they are hidden from every run that does
133
+ * not list them, for the model and for the executor alike.
134
+ */
135
+ optInTools?: string[];
71
136
  policy?: Policy;
72
137
  /** Allow interactive approvals for this run (default: when the runner has a handler). */
73
138
  approvals?: boolean;
@@ -77,7 +142,21 @@ export interface RunOptions {
77
142
  context?: ContextSource;
78
143
  maxTurns?: number;
79
144
  maxTokens?: number;
145
+ /** Per-call output token budget for this run; beats the runner-level budget when set. */
146
+ maxOutputTokens?: number;
80
147
  timeoutMs?: number;
148
+ /** Silent-request limit for this run; beats the runner-level `firstTokenTimeoutMs`. */
149
+ firstTokenTimeoutMs?: number;
150
+ /** Silent-request retries for this run; beats the runner-level `firstTokenRetries`. */
151
+ firstTokenRetries?: number;
152
+ /** Output-truncation recoveries for this run; beats the runner-level `truncationRecoveries`. */
153
+ truncationRecoveries?: number;
154
+ /** Reasoning effort level for this run; beats the runner-level default when set. */
155
+ reasoningEffort?: string;
156
+ /** Run id to use for this run's events (e.g. preassigned by an embedder); a UUID otherwise. */
157
+ runId?: string;
158
+ /** Copied to every event of this run as `RunEvent.correlationId` (e.g. an HTTP request id). */
159
+ correlationId?: string;
81
160
  }
82
161
  /**
83
162
  * Default cumulative token budget for one run: several context windows (each turn re-sends the
@@ -105,14 +184,23 @@ export declare class AgentRunner {
105
184
  get policy(): Readonly<Policy>;
106
185
  /** Whether write/process tools can be approved interactively. */
107
186
  get approvals(): boolean;
187
+ /**
188
+ * Sets which effects run without asking (a permission mode). The policy object is mutated in
189
+ * place because the application and the runner share it; `analysis` is never touched. Takes
190
+ * effect from the next tool call, so it also drops "allow for this session" widenings.
191
+ */
192
+ setPolicy(next: Partial<Pick<Policy, "write" | "process" | "external">>): void;
108
193
  /**
109
194
  * Live-update runnable settings so the next `run`/`compact` call honors them without restarting
110
195
  * Alisio. Every patch field is merged over the current options; unrelated settings are kept.
111
196
  */
112
197
  applySettings(patch: RunnerSettingsPatch): void;
113
198
  private emitter;
114
- /** Tools offered to the model under the current policy (and optional run narrowing). */
115
- availableTools(run?: RunOptions): ToolDefinition[];
199
+ /**
200
+ * Tools offered to the model under the current policy (and optional run narrowing). With a
201
+ * session, a capability tool is also offered when that session's root holds a persisted grant.
202
+ */
203
+ availableTools(run?: RunOptions, sessionId?: string): ToolDefinition[];
116
204
  /** Abort signal of the session's active run, if any (used to cascade cancellation). */
117
205
  signal(sessionId: string): AbortSignal | undefined;
118
206
  isRunning(sessionId: string): boolean;
@@ -138,6 +226,25 @@ export declare class AgentRunner {
138
226
  basis: "window" | "unknown";
139
227
  compactionAt: number;
140
228
  };
229
+ /**
230
+ * What a tool-less side call about a session needs (for example a `/btw` side question): the
231
+ * session's provider and model, its system instructions, its ACTIVE history and the current
232
+ * limits. Claims no lock and writes nothing, so it is safe while a run is active.
233
+ */
234
+ sideContext(sessionId: string): Promise<{
235
+ provider: ModelProvider;
236
+ model: string;
237
+ instructions: string;
238
+ messages: Message[];
239
+ maxContextChars: number;
240
+ maxOutputTokens: number;
241
+ timeoutMs: number;
242
+ /** Context window of the model in tokens, when known and trusted. */
243
+ contextWindow?: number;
244
+ reasoningEffort?: string;
245
+ }>;
246
+ /** The output-token budget for `model`: user value, else catalog maximum, else fallback. */
247
+ private outputLimit;
141
248
  /** Change the model used by subsequent turns of a session; recorded in the store. */
142
249
  setModel(sessionId: string, model: string): void;
143
250
  /** Manually compact a session outside a run. */
@@ -146,6 +253,27 @@ export declare class AgentRunner {
146
253
  signal?: AbortSignal;
147
254
  }): Promise<CompactionResult | undefined>;
148
255
  private compactLocked;
256
+ /**
257
+ * Gates and executes one tool call: external-directory paths, the capability/effect gate with
258
+ * its approval, the call journal, artifact publishing and the result bound. Shared by model
259
+ * runs and `runToolCall`, so a call started from a UI passes exactly the same gates.
260
+ */
261
+ private executeCall;
262
+ /**
263
+ * Runs ONE tool call without a model (spec §20 `runToolCall`): an action the user started from
264
+ * a UI, such as copying an artifact into the workspace. It is a real run of the session
265
+ * (`run_started` → `tool_*` → `run_completed`, journaled) and the call passes exactly the gates
266
+ * of a model call (`write` approval, capabilities, paths). The transcript stays valid for every
267
+ * provider: a user note (shown as `display`), an assistant message with the call, the tool
268
+ * result and a short assistant summary.
269
+ */
270
+ runToolCall(sessionId: string, name: string, input: Record<string, unknown>, options?: RunOptions & {
271
+ signal?: AbortSignal;
272
+ }): Promise<{
273
+ runId: string;
274
+ status: "completed";
275
+ result: ToolResult;
276
+ }>;
149
277
  run(sessionId: string, prompt: string, signal?: AbortSignal, options?: RunOptions): Promise<{
150
278
  sessionId: string;
151
279
  text: string;
@@ -154,5 +282,7 @@ export declare class AgentRunner {
154
282
  input: number;
155
283
  output: number;
156
284
  };
285
+ /** Tool calls the model made during the run (the goal controller's no-progress breaker). */
286
+ toolCalls: number;
157
287
  }>;
158
288
  }