@xingjisoft/neutrino 0.6.0 → 0.7.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 (169) hide show
  1. package/README.md +6 -1
  2. package/assets/fast-planner.txt +57 -0
  3. package/assets/fast-replanner.txt +28 -0
  4. package/dist/agents.d.ts +25 -0
  5. package/dist/app.d.ts +206 -0
  6. package/dist/app.js +15 -0
  7. package/dist/background.d.ts +96 -0
  8. package/dist/bin.d.ts +2 -0
  9. package/dist/bin.js +40 -3
  10. package/dist/browser.d.ts +18 -0
  11. package/dist/clipboard.d.ts +16 -0
  12. package/dist/colors.d.ts +29 -0
  13. package/dist/compact.d.ts +52 -0
  14. package/dist/config.d.ts +221 -0
  15. package/dist/config.js +22 -7
  16. package/dist/cwd.d.ts +19 -0
  17. package/dist/fast/artifacts.d.ts +26 -0
  18. package/dist/fast/artifacts.js +109 -0
  19. package/dist/fast/engine.d.ts +78 -0
  20. package/dist/fast/engine.js +657 -0
  21. package/dist/fast/evidence.d.ts +21 -0
  22. package/dist/fast/evidence.js +68 -0
  23. package/dist/fast/planner.d.ts +10 -0
  24. package/dist/fast/planner.js +51 -0
  25. package/dist/fast/pool.d.ts +17 -0
  26. package/dist/fast/pool.js +78 -0
  27. package/dist/fast/scheduler.d.ts +54 -0
  28. package/dist/fast/scheduler.js +383 -0
  29. package/dist/fast/types.d.ts +100 -0
  30. package/dist/fast/types.js +21 -0
  31. package/dist/fast/worker.d.ts +23 -0
  32. package/dist/fast/worker.js +185 -0
  33. package/dist/header.d.ts +3 -0
  34. package/dist/index.d.ts +5 -0
  35. package/dist/llm/approval.d.ts +204 -0
  36. package/dist/llm/approval.js +14 -3
  37. package/dist/llm/client.d.ts +118 -0
  38. package/dist/llm/client.js +57 -8
  39. package/dist/llm/codeExecutor.d.ts +14 -0
  40. package/dist/llm/codemode.d.ts +15 -0
  41. package/dist/llm/context.d.ts +29 -0
  42. package/dist/llm/context.js +17 -4
  43. package/dist/llm/diagnostics.d.ts +91 -0
  44. package/dist/llm/diagnostics.js +242 -0
  45. package/dist/llm/plan.d.ts +148 -0
  46. package/dist/llm/retry.d.ts +80 -0
  47. package/dist/llm/risk.d.ts +21 -0
  48. package/dist/llm/risk.js +7 -0
  49. package/dist/llm/runtime.d.ts +189 -0
  50. package/dist/llm/runtime.js +178 -24
  51. package/dist/llm/search.d.ts +2 -0
  52. package/dist/llm/searchNetwork.d.ts +8 -0
  53. package/dist/llm/subagent.d.ts +112 -0
  54. package/dist/llm/subagent.js +25 -12
  55. package/dist/llm/tools.d.ts +20 -0
  56. package/dist/llm/tools.js +4 -1
  57. package/dist/llm/workspace.d.ts +6 -0
  58. package/dist/llm/workspace.js +271 -0
  59. package/dist/markdown.d.ts +58 -0
  60. package/dist/migration.d.ts +8 -0
  61. package/dist/persistence.d.ts +14 -0
  62. package/dist/plugins/catalog.d.ts +20 -0
  63. package/dist/plugins/catalog.js +45 -0
  64. package/dist/plugins/cli.d.ts +1 -0
  65. package/dist/plugins/cli.js +106 -0
  66. package/dist/plugins/host.d.ts +121 -0
  67. package/dist/plugins/host.js +450 -0
  68. package/dist/plugins/manager.d.ts +24 -0
  69. package/dist/plugins/manager.js +288 -0
  70. package/dist/plugins/package.d.ts +5 -0
  71. package/dist/plugins/package.js +53 -0
  72. package/dist/plugins/runner.d.ts +1 -0
  73. package/dist/plugins/runner.js +227 -0
  74. package/dist/plugins/session.d.ts +12 -0
  75. package/dist/plugins/session.js +97 -0
  76. package/dist/plugins/terminal.d.ts +22 -0
  77. package/dist/plugins/terminal.js +33 -0
  78. package/dist/plugins/types.d.ts +178 -0
  79. package/dist/plugins/types.js +6 -0
  80. package/dist/plugins/validation.d.ts +14 -0
  81. package/dist/plugins/validation.js +174 -0
  82. package/dist/plugins/web-sdk.d.ts +58 -0
  83. package/dist/plugins/web-sdk.js +1 -0
  84. package/dist/pro/agents.d.ts +34 -0
  85. package/dist/pro/agents.js +1 -1
  86. package/dist/pro/config.d.ts +75 -0
  87. package/dist/pro/config.js +3 -2
  88. package/dist/pro/preflight.d.ts +21 -0
  89. package/dist/sanitize.d.ts +34 -0
  90. package/dist/screens/agentConversation.d.ts +28 -0
  91. package/dist/screens/agentHistory.d.ts +25 -0
  92. package/dist/screens/agentSelect.d.ts +16 -0
  93. package/dist/screens/chat.d.ts +292 -0
  94. package/dist/screens/chat.js +179 -65
  95. package/dist/screens/history.d.ts +23 -0
  96. package/dist/screens/modelSelect.d.ts +29 -0
  97. package/dist/screens/plugins.d.ts +29 -0
  98. package/dist/screens/plugins.js +196 -0
  99. package/dist/screens/settings.d.ts +42 -0
  100. package/dist/screens/start.d.ts +43 -0
  101. package/dist/screens/start.js +25 -17
  102. package/dist/screens/updatePrompt.d.ts +41 -0
  103. package/dist/selection.d.ts +75 -0
  104. package/dist/state.d.ts +26 -0
  105. package/dist/terminal/buffer.d.ts +47 -0
  106. package/dist/terminal/input.d.ts +70 -0
  107. package/dist/terminal/renderer.d.ts +43 -0
  108. package/dist/terminal/restore.d.ts +41 -0
  109. package/dist/terminal/screen.d.ts +57 -0
  110. package/dist/tray.d.ts +14 -0
  111. package/dist/ui.d.ts +123 -0
  112. package/dist/update.d.ts +71 -0
  113. package/dist/updateWatch.d.ts +43 -0
  114. package/dist/web/approvalQueue.d.ts +8 -0
  115. package/dist/web/approvalQueue.js +59 -0
  116. package/dist/web/auth.d.ts +14 -0
  117. package/dist/web/clientState.d.ts +16 -0
  118. package/dist/web/folderPicker.d.ts +34 -0
  119. package/dist/web/folderPicker.js +544 -0
  120. package/dist/web/hub.d.ts +213 -0
  121. package/dist/web/hub.js +14 -2
  122. package/dist/web/localApi.d.ts +11 -0
  123. package/dist/web/localApi.js +260 -0
  124. package/dist/web/plugins.d.ts +8 -0
  125. package/dist/web/plugins.js +64 -0
  126. package/dist/web/server.d.ts +81 -0
  127. package/dist/web/server.js +127 -19
  128. package/dist/web/service.d.ts +7 -0
  129. package/dist/web/service.js +1 -0
  130. package/dist/web/session.d.ts +176 -0
  131. package/dist/web/session.js +170 -21
  132. package/dist/web/settings.d.ts +65 -0
  133. package/dist/web/terminalBridge.d.ts +15 -0
  134. package/dist/web/terminalBridge.js +8 -2
  135. package/dist/width.d.ts +6 -0
  136. package/docs/plugins/README.md +126 -0
  137. package/docs/plugins/agent-sdk.md +92 -0
  138. package/docs/plugins/architecture.md +64 -0
  139. package/docs/plugins/compatibility.md +34 -0
  140. package/docs/plugins/development.md +55 -0
  141. package/docs/plugins/manifest.md +59 -0
  142. package/docs/plugins/manifest.schema.json +286 -0
  143. package/docs/plugins/security.md +53 -0
  144. package/docs/plugins/skills-prompts.md +69 -0
  145. package/docs/plugins/ui-sdk.md +109 -0
  146. package/examples/local-api.py +105 -0
  147. package/examples/plugins/cards/card.html +6 -0
  148. package/examples/plugins/cards/neutrino.plugin.json +42 -0
  149. package/examples/plugins/composer/editor.html +10 -0
  150. package/examples/plugins/composer/neutrino.plugin.json +10 -0
  151. package/examples/plugins/function-tools/agent.js +32 -0
  152. package/examples/plugins/function-tools/neutrino.plugin.json +15 -0
  153. package/examples/plugins/menus-tabs/neutrino.plugin.json +15 -0
  154. package/examples/plugins/menus-tabs/panel.html +6 -0
  155. package/examples/plugins/skills-prompts/neutrino.plugin.json +13 -0
  156. package/examples/plugins/skills-prompts/prompts/evidence.md +1 -0
  157. package/examples/plugins/skills-prompts/prompts/reviewer.md +1 -0
  158. package/examples/plugins/skills-prompts/skills/review/SKILL.md +8 -0
  159. package/examples/plugins/theme/neutrino.plugin.json +12 -0
  160. package/package.json +66 -42
  161. package/web/LOCAL-API.md +65 -0
  162. package/web/README.md +30 -8
  163. package/web/app.js +256 -67
  164. package/web/i18n.js +18 -3
  165. package/web/index.html +3 -1
  166. package/web/plugins.css +10 -0
  167. package/web/plugins.js +230 -0
  168. package/web/style.css +12 -3
  169. package/web/turns.js +7 -8
@@ -0,0 +1,148 @@
1
+ import { type TaskRuntime } from "./runtime.js";
2
+ import type { ToolDefinition } from "./tools.js";
3
+ /** `active` is the step the worker is on; the rest are its past and future. */
4
+ export type PlanStepStatus = "pending" | "active" | "done" | "failed" | "blocked" | "cancelled" | "skipped";
5
+ export interface PlanStep {
6
+ id?: string;
7
+ dependsOn?: string[];
8
+ acceptanceCriteria?: string[];
9
+ evidenceIds?: string[];
10
+ artifacts?: string[];
11
+ summary?: string;
12
+ deliverable?: string;
13
+ /** One imperative action, in the language of the request. */
14
+ title: string;
15
+ /** What the step needs: files, parameters, acceptance criteria. */
16
+ detail?: string;
17
+ status: PlanStepStatus;
18
+ }
19
+ /** The plan of one user turn, persisted with the session. */
20
+ export interface PlanState {
21
+ /** The request restated in one line. */
22
+ goal: string;
23
+ steps: PlanStep[];
24
+ /** The turn stopped before the last step: paused, cancelled, or interrupted. */
25
+ stopped?: boolean;
26
+ }
27
+ /**
28
+ * One step is not a plan, it is the answer: such a turn runs as a plain turn.
29
+ * The ceiling keeps the card readable and the turn's cost proportionate.
30
+ */
31
+ export declare const PLAN_MIN_STEPS = 2;
32
+ export declare const PLAN_MAX_STEPS = 10;
33
+ export declare const PLAN_MAX_TITLE = 160;
34
+ export declare const PLAN_MAX_DETAIL = 400;
35
+ /**
36
+ * A request longer than this many columns is treated as a brief and planned.
37
+ * In practice that is roughly eighty Chinese characters or one hundred and
38
+ * eighty ASCII ones — past that, "one action" is already unlikely.
39
+ */
40
+ export declare const PLAN_LENGTH_LIMIT = 180;
41
+ /**
42
+ * Does this request need a plan at all?
43
+ *
44
+ * Planning costs a model round-trip before any work starts, and for "rename
45
+ * this variable" that round-trip is pure friction. A request is planned only
46
+ * when it shows a reason to be split into steps: it asks for more than one
47
+ * thing, brings its own structure (a list), reads as a brief (long), or asks
48
+ * for a plan. Everything else runs in one pass, where the system prompt still
49
+ * has the agent state the steps it is taking in its own answer.
50
+ */
51
+ export declare function needsPlan(request: string): boolean;
52
+ /** Turn an already-parsed planner answer into a plan, or null when unusable. */
53
+ export declare function normalizePlan(value: unknown, minSteps?: number): PlanState | null;
54
+ /**
55
+ * Read a planner answer. JSON first, because that is what the prompt asks for,
56
+ * then a numbered list so a model that ignores the format still produces a
57
+ * usable plan. Anything else is "no plan": the turn then runs as before.
58
+ */
59
+ export declare function parsePlan(text: string, minSteps?: number): PlanState | null;
60
+ export interface PlannerInput {
61
+ /** The request being planned. */
62
+ request: string;
63
+ /** The conversation before that request, oldest first. */
64
+ transcript?: string;
65
+ /** Directory the work happens in. */
66
+ cwd?: string;
67
+ }
68
+ /**
69
+ * The user turn handed to the planner agent. The planner gets no tools, so
70
+ * everything it needs to make the steps concrete is in this text: where the
71
+ * work happens, what was said before, and what is being asked now.
72
+ */
73
+ export declare function buildPlannerInput(input: PlannerInput): string;
74
+ /** The plan as numbered text: what the worker and the reviewers read. */
75
+ export declare function planSpec(plan: PlanState): string;
76
+ /**
77
+ * The plan as the user reads it in the transcript. It is an ordinary assistant
78
+ * message on purpose: it is saved, replayed, folded and sent back to the model
79
+ * exactly like any other answer.
80
+ *
81
+ * A detail stays on its step's line: markdown renderers fold an indented line
82
+ * into the list item before it, which would run two steps together in the log.
83
+ */
84
+ export declare function planMessage(plan: PlanState): string;
85
+ /**
86
+ * The system text for one step. It repeats the whole plan so the worker knows
87
+ * where the step sits, and states the two rules the split exists for: do only
88
+ * this step, and stop when it is verified.
89
+ */
90
+ export declare function renderStepDirective(template: string, plan: PlanState, index: number): string;
91
+ /** How far a plan got. Used by the card header and by tests. */
92
+ export declare function planProgress(plan: PlanState): {
93
+ done: number;
94
+ total: number;
95
+ active: number;
96
+ };
97
+ /** A plan loaded from disk was, by definition, no longer running. */
98
+ export declare function resumePlan(loaded: PlanState | null | undefined): PlanState | null;
99
+ /** Point the plan at one step. Returns false when there was nothing to change. */
100
+ export declare function advancePlan(plan: PlanState | null, index: number, status: PlanStepStatus): boolean;
101
+ /** A turn that cannot continue must not leave a step looking alive. */
102
+ export declare function stopPlan(plan: PlanState | null): boolean;
103
+ /** The message shape both loops share: enough to tell the planner what happened. */
104
+ export interface TranscriptMessage {
105
+ role: string;
106
+ content?: string;
107
+ name?: string;
108
+ result?: string;
109
+ }
110
+ /** The user message a turn answers. */
111
+ export declare function lastRequestText(messages: readonly TranscriptMessage[]): string;
112
+ /**
113
+ * The exchanges before the current request, for the planner.
114
+ *
115
+ * Tool output is clipped hard: the planner needs to know what was done, not to
116
+ * re-read it, and a long log must not crowd the request out of its own plan.
117
+ */
118
+ export declare function planTranscript(messages: readonly TranscriptMessage[]): string;
119
+ /**
120
+ * One row of the info card. The kind carries the meaning (and therefore the
121
+ * colour); the text is what goes on screen.
122
+ */
123
+ export type PlanRowKind = "header" | "step-active" | "step-done" | "step-pending" | "step-failed" | "step-blocked" | "step-cancelled" | "step-skipped" | "connector" | "more" | "line";
124
+ export interface PlanRow {
125
+ kind: PlanRowKind;
126
+ text: string;
127
+ }
128
+ /**
129
+ * Lay the plan out as a vertical timeline, top to bottom in execution order.
130
+ *
131
+ * A finished step is drawn dark, a step still to come is drawn lit, and the step
132
+ * being worked on is the one highlighted row — so the card reads as "these are
133
+ * done, this is running, these are next" without a legend. When the plan is
134
+ * longer than the room, a window around the running step is shown with the
135
+ * number of steps above and below it, rather than dropping the middle.
136
+ */
137
+ export declare function planCardRows(plan: PlanState, options: {
138
+ width: number;
139
+ maxRows: number;
140
+ }): PlanRow[];
141
+ /** The width a card row actually needs, in columns. */
142
+ export declare function planRowsWidth(rows: PlanRow[]): number;
143
+ /** Pro plans use explicit step acceptance instead of inferring success from prose. */
144
+ export declare const FINISH_STEP_TOOL = "finish_step";
145
+ export declare const FINISH_STEP_DEFINITION: ToolDefinition;
146
+ export declare function preparePlan(plan: PlanState): PlanState;
147
+ export declare function finishPlanStep(plan: PlanState | null, args: Record<string, unknown>, runtime: TaskRuntime): string;
148
+ export declare function settlePlan(plan: PlanState | null, cancelled?: boolean): void;
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Retry policy for the model connection.
3
+ *
4
+ * A single turn is minutes of work, and the connection carries it the whole way.
5
+ * Providers, and the proxies and load balancers in front of them, drop sockets
6
+ * for reasons a client can never observe: an idle timeout, a rolling restart, a
7
+ * middlebox resetting the flow. Those blips clear on their own within seconds,
8
+ * so a failed request that is simply re-sent saves the turn — while surfacing
9
+ * the error throws away everything the user typed and everything the model had
10
+ * already produced.
11
+ *
12
+ * The policy is exponential: seven attempts in total, waiting 5s, 10s, 20s,
13
+ * 40s, 80s and finally 160s between them (about five minutes end to end). The
14
+ * waits grow because a link that is merely flaky recovers long before the
15
+ * budget runs out, and a link that is genuinely down must not be hammered.
16
+ */
17
+ /** Total tries, the first one included. */
18
+ export declare const DEFAULT_NETWORK_ATTEMPTS = 7;
19
+ /** Wait before the first retry; every further retry doubles it. */
20
+ export declare const DEFAULT_RETRY_DELAY_MS = 5000;
21
+ export interface RetryPolicy {
22
+ /** Total tries, including the first one. */
23
+ attempts: number;
24
+ /** Wait before the first retry; doubled for each retry after that. */
25
+ baseDelayMs: number;
26
+ }
27
+ /**
28
+ * The policy in force.
29
+ *
30
+ * Read on every use rather than cached at import time, so the environment can
31
+ * tune it (`NEUTRINO_NETWORK_ATTEMPTS`, `NEUTRINO_RETRY_DELAY_MS`) without a
32
+ * rebuild and the tests can collapse the waits to a millisecond.
33
+ */
34
+ export declare function retryPolicy(): RetryPolicy;
35
+ /** Wait before retry number `retry` (0-based): base, 2×base, 4×base, … */
36
+ export declare function retryDelayMs(retry: number, policy?: RetryPolicy): number;
37
+ /** What the UI is told before a retried request goes out again. */
38
+ export interface RetryNotice {
39
+ /** The attempt about to go out (2 = the first retry), 1-based. */
40
+ attempt: number;
41
+ /** Total attempts allowed. */
42
+ attempts: number;
43
+ /** How long this attempt waits before it is sent. */
44
+ delayMs: number;
45
+ /** What went wrong, in the same wording the transcript uses. */
46
+ reason: string;
47
+ }
48
+ /** A wait in human terms: "5s", "40s", "2m 40s". */
49
+ export declare function formatDelay(ms: number): string;
50
+ export declare const DROP_HINT_RE: RegExp;
51
+ /**
52
+ * Flatten an error and its `cause` chain into one readable line.
53
+ *
54
+ * `fetch` reports almost every transport problem as a bare
55
+ * `TypeError: fetch failed`; the actual reason (`ECONNRESET`, `EMFILE`,
56
+ * `ENOTFOUND`, `UND_ERR_…`) is tucked away in `error.cause`. Without walking
57
+ * that chain a failure is impossible to diagnose, so this always reports it.
58
+ */
59
+ export declare function describeError(e: unknown): string;
60
+ /**
61
+ * Whether a failed request is worth retrying: a transient connection problem
62
+ * (reset / refused / DNS / timeout) rather than a real response from the API.
63
+ */
64
+ export declare function isRetriableNetworkError(e: unknown): boolean;
65
+ export declare function isRetriableStatus(status: number): boolean;
66
+ /** A response that did arrive, but carried a failure status. */
67
+ export declare class HttpStatusError extends Error {
68
+ readonly status: number;
69
+ constructor(status: number, body: string);
70
+ }
71
+ /** Whether a failure is transient, including HTTP statuses that invite a retry. */
72
+ export declare function isRetriableFailure(e: unknown): boolean;
73
+ /**
74
+ * Sleep before retry number `retry`, in short slices.
75
+ *
76
+ * The wait can reach 160s, so it must not be a single `setTimeout`: a paused
77
+ * turn or a newer message has to be able to cut it short. Returns false when
78
+ * `cancelled` fired, which tells the caller to stop without an error.
79
+ */
80
+ export declare function waitBeforeRetry(retry: number, policy: RetryPolicy, cancelled?: () => boolean): Promise<boolean>;
@@ -0,0 +1,21 @@
1
+ export type RiskLevel = "high" | "extreme";
2
+ export interface RiskAssessment {
3
+ level: RiskLevel;
4
+ /** Tool that was called. */
5
+ tool: string;
6
+ /** One-line description of what is about to happen. */
7
+ summary: string;
8
+ /** Why this was flagged. Shown to the user (and to the AI reviewer). */
9
+ reasons: string[];
10
+ }
11
+ /** Score a shell command. */
12
+ export declare function assessCommand(command: string, cwd: string): {
13
+ level: RiskLevel;
14
+ reasons: string[];
15
+ };
16
+ /**
17
+ * Classify a single tool call.
18
+ *
19
+ * Returns `null` when the call is routine and may run without approval.
20
+ */
21
+ export declare function assessToolCall(name: string, args: Record<string, unknown>, cwd: string): RiskAssessment | null;
package/dist/llm/risk.js CHANGED
@@ -14,6 +14,7 @@
14
14
  */
15
15
  import os from "node:os";
16
16
  import path from "node:path";
17
+ import { currentTask } from "./runtime.js";
17
18
  /** Wrappers that merely delegate to the command that follows them. */
18
19
  const WRAPPERS = new Set([
19
20
  "sudo",
@@ -355,6 +356,12 @@ function summarizeArgs(name, args) {
355
356
  export function assessToolCall(name, args, cwd) {
356
357
  const workingDir = path.resolve(cwd || process.cwd());
357
358
  const summary = summarizeArgs(name, args);
359
+ const plugin = currentTask()?.runtime.plugins?.toolPolicy(name);
360
+ if (plugin && (plugin.native || plugin.effects.some(e => e !== "filesystem.read"))) {
361
+ return { level: "high", tool: name, summary, reasons: [plugin.native ? "runs a fully trusted native plugin" : `plugin declares: ${plugin.effects.join(", ")}`] };
362
+ }
363
+ if (name === "plugin_fetch")
364
+ return { level: "high", tool: name, summary: String(args.url ?? name), reasons: ["sends an HTTP request from a plugin"] };
358
365
  if (name === "web_search") {
359
366
  return {
360
367
  level: "high", tool: name, summary,
@@ -0,0 +1,189 @@
1
+ import { DiagnosticRecorder } from "./diagnostics.js";
2
+ import type { PlanState } from "./plan.js";
3
+ import type { AgentMode } from "../config.js";
4
+ import type { PluginHost } from "../plugins/host.js";
5
+ import type { PluginPin } from "../plugins/types.js";
6
+ import type { OwnedUI } from "../plugins/host.js";
7
+ export type AgentStatus = "completed" | "partial" | "blocked" | "failed" | "cancelled";
8
+ export interface AgentError {
9
+ code: string;
10
+ message: string;
11
+ }
12
+ export interface AgentResult {
13
+ runId: string;
14
+ status: AgentStatus;
15
+ report: string;
16
+ evidenceIds: string[];
17
+ artifacts: string[];
18
+ blockers: string[];
19
+ error?: AgentError;
20
+ }
21
+ export interface TaskLimits {
22
+ agentRuns: number;
23
+ modelRequests: number;
24
+ toolCalls: number;
25
+ tokens: number;
26
+ durationMs: number;
27
+ }
28
+ export type TaskBudgetScope = "task" | "delegation";
29
+ export declare function taskBudgetScope(config: Record<string, unknown>): TaskBudgetScope;
30
+ export interface TaskBudgetStop {
31
+ code: string;
32
+ scope: TaskBudgetScope;
33
+ limit: number;
34
+ used: number;
35
+ requested: number;
36
+ reserved?: number;
37
+ runId: string;
38
+ }
39
+ export declare const DEFAULT_TASK_LIMITS: Readonly<TaskLimits>;
40
+ export declare function taskLimits(config: Record<string, unknown>): TaskLimits;
41
+ export interface TaskPolicy {
42
+ readonly readOnly: boolean;
43
+ /** Each group is an additional restriction; a write must match every group. */
44
+ readonly writePathGroups: readonly (readonly string[])[];
45
+ }
46
+ export interface TaskScope {
47
+ readonly signal: AbortSignal;
48
+ readonly runtime: TaskRuntime;
49
+ readonly runId: string;
50
+ readonly parentRunId?: string;
51
+ readonly role: string;
52
+ readonly depth: number;
53
+ readonly policy: TaskPolicy;
54
+ readonly ancestors: readonly string[];
55
+ }
56
+ export interface ToolEvidence {
57
+ id: string;
58
+ runId: string;
59
+ name: string;
60
+ arguments: Record<string, unknown>;
61
+ result: string;
62
+ status: "completed" | "failed" | "denied" | "cancelled";
63
+ }
64
+ export interface TaskSnapshot {
65
+ execution_mode?: AgentMode | "pro";
66
+ plugins?: PluginPin[];
67
+ pluginErrors?: string[];
68
+ pluginUI?: OwnedUI[];
69
+ pluginPrompt?: {
70
+ role: string;
71
+ sections: unknown;
72
+ };
73
+ rootRunId: string;
74
+ state: "running" | "cancelling" | AgentStatus;
75
+ counts: {
76
+ agentRuns: number;
77
+ modelRequests: number;
78
+ toolCalls: number;
79
+ tokens: number;
80
+ };
81
+ limits: TaskLimits;
82
+ budgetScope?: TaskBudgetScope;
83
+ delegatedCounts?: {
84
+ modelRequests: number;
85
+ toolCalls: number;
86
+ tokens: number;
87
+ };
88
+ budgetStop?: TaskBudgetStop;
89
+ journal?: string;
90
+ persistenceError?: string;
91
+ }
92
+ /** A saved task has no live worker after restart. Never replay its tool ledger. */
93
+ export declare function resumeTaskSnapshot(snapshot: TaskSnapshot | undefined): TaskSnapshot | undefined;
94
+ export declare class TaskControlError extends Error {
95
+ readonly code: string;
96
+ constructor(code: string, message: string);
97
+ }
98
+ export declare function currentTask(): TaskScope | undefined;
99
+ /** Node 18-compatible signal composition with deterministic listener cleanup. */
100
+ export declare function linkSignals(...values: Array<AbortSignal | undefined>): {
101
+ signal: AbortSignal;
102
+ dispose(): void;
103
+ };
104
+ /** One user turn owns one ledger and cancellation tree, with optional root limits. */
105
+ export declare class TaskRuntime {
106
+ private readonly executionMode?;
107
+ plugins?: PluginHost;
108
+ private pluginPrompt?;
109
+ readonly rootRunId: `${string}-${string}-${string}-${string}-${string}`;
110
+ readonly diagnostics?: DiagnosticRecorder;
111
+ readonly signal: AbortSignal;
112
+ readonly originalRequest: string;
113
+ readonly priorUserRequests: readonly string[];
114
+ readonly cwd: string;
115
+ readonly workspaceOnly: boolean;
116
+ readonly limits: Readonly<TaskLimits>;
117
+ readonly budgetScope: TaskBudgetScope;
118
+ readonly root: TaskScope;
119
+ readonly evidence: ToolEvidence[];
120
+ readonly results: AgentResult[];
121
+ plan?: PlanState;
122
+ private readonly controller;
123
+ private readonly deadline?;
124
+ private readonly delegationController;
125
+ private delegationDeadline?;
126
+ private delegationStarted?;
127
+ private readonly started;
128
+ private readonly pending;
129
+ private readonly usage;
130
+ private readonly delegatedUsage;
131
+ private reservedTokens;
132
+ private delegatedReservedTokens;
133
+ private budgetStop?;
134
+ private state;
135
+ private persistenceError?;
136
+ private readonly journal?;
137
+ private journalStarted;
138
+ private journalDiscarded;
139
+ private readonly detachSignal?;
140
+ constructor(options: {
141
+ request: string;
142
+ cwd?: string;
143
+ priorUserRequests?: readonly string[];
144
+ limits?: Partial<TaskLimits>;
145
+ budgetScope?: TaskBudgetScope;
146
+ executionMode?: AgentMode | "pro";
147
+ signal?: AbortSignal;
148
+ readOnly?: boolean;
149
+ writePaths?: readonly string[];
150
+ workspaceOnly?: boolean;
151
+ journalDir?: string;
152
+ diagnostics?: DiagnosticRecorder;
153
+ });
154
+ run<T>(callback: () => T): T;
155
+ withSignal<T>(signal: AbortSignal, callback: () => Promise<T>): Promise<T>;
156
+ child<T>(role: string, task: string, callback: (scope: TaskScope) => Promise<T>, options?: {
157
+ readOnly?: boolean;
158
+ writePaths?: readonly string[];
159
+ }): Promise<T>;
160
+ check(): void;
161
+ cancel(reason?: string): void;
162
+ track<T>(operation: Promise<T>): Promise<T>;
163
+ activity(): () => void;
164
+ get settling(): boolean;
165
+ drain(): Promise<void>;
166
+ finish(status: AgentStatus): void;
167
+ snapshot(): TaskSnapshot;
168
+ instructions(scope?: TaskScope): string;
169
+ assertTool(name: string, args: Record<string, unknown>, scope?: TaskScope): void;
170
+ availableTools<T extends {
171
+ function: {
172
+ name: string;
173
+ };
174
+ }>(tools: T[], scope?: TaskScope): T[];
175
+ tool(name: string, args: Record<string, unknown>, execute: () => Promise<string>): Promise<string>;
176
+ recordTool(name: string, args: Record<string, unknown>, result: string, status: ToolEvidence["status"], id?: `${string}-${string}-${string}-${string}-${string}`, runId?: string): ToolEvidence;
177
+ recordResult(result: AgentResult): void;
178
+ evidenceFor(runId: string): ToolEvidence[];
179
+ partialReport(): string;
180
+ /** Reserve before every actual HTTP attempt, including retries, reviews and summaries. */
181
+ request(inputTokens: number, outputTokens: number, final?: boolean): {
182
+ settle(used: number): void;
183
+ };
184
+ private isDelegated;
185
+ private expireTask;
186
+ private stopBudget;
187
+ note(type: string, data: unknown): void;
188
+ private event;
189
+ }