@bermudi/pi-delegate 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.
- package/README.md +92 -0
- package/agents.ts +347 -0
- package/concurrency.ts +126 -0
- package/config.ts +358 -0
- package/constants.ts +41 -0
- package/delegate.ts +115 -0
- package/dispatch.ts +362 -0
- package/extension.ts +126 -0
- package/file-tracking.ts +57 -0
- package/format.ts +506 -0
- package/host-compat.ts +73 -0
- package/host.ts +814 -0
- package/lifecycle.ts +704 -0
- package/manual.ts +184 -0
- package/model.ts +81 -0
- package/package.json +43 -0
- package/parent-context.ts +42 -0
- package/pool.ts +420 -0
- package/render-branches.ts +380 -0
- package/render-result.ts +182 -0
- package/runner.ts +686 -0
- package/schema.ts +289 -0
- package/sessions.ts +102 -0
- package/settings.ts +78 -0
- package/spill.ts +161 -0
- package/task-resolution.ts +321 -0
- package/tickets.ts +795 -0
- package/timer.ts +46 -0
- package/tools.ts +41 -0
- package/types.ts +243 -0
- package/usage.ts +121 -0
- package/utils.ts +131 -0
package/config.ts
ADDED
|
@@ -0,0 +1,358 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import * as os from "node:os";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import {
|
|
5
|
+
MAX_ASYNC_TICKETS,
|
|
6
|
+
MAX_CONCURRENCY,
|
|
7
|
+
OUTPUT_SPILL_TAIL_CHARS,
|
|
8
|
+
OUTPUT_SPILL_THRESHOLD_CHARS,
|
|
9
|
+
} from "./constants.ts";
|
|
10
|
+
|
|
11
|
+
export interface DelegateConfig {
|
|
12
|
+
agent: {
|
|
13
|
+
/** Global default model for all agent types. */
|
|
14
|
+
default: string | null;
|
|
15
|
+
/** Per-agent-type model overrides. Keys are agent names or "default". */
|
|
16
|
+
[agentType: string]: string | null | undefined;
|
|
17
|
+
};
|
|
18
|
+
/** Per-model and per-provider concurrency limits. */
|
|
19
|
+
concurrency: {
|
|
20
|
+
/** Default concurrency limit for unspecified models. */
|
|
21
|
+
default: number;
|
|
22
|
+
/** Per-provider limits (e.g. "llamacpp": 2). */
|
|
23
|
+
providers?: Record<string, number>;
|
|
24
|
+
/** Per-model limits keyed by "provider/modelId". */
|
|
25
|
+
models?: Record<string, number>;
|
|
26
|
+
};
|
|
27
|
+
/** Hard ceiling on total concurrent agents across all models. */
|
|
28
|
+
maxConcurrent?: number;
|
|
29
|
+
/** Max concurrent async tickets. */
|
|
30
|
+
maxAsyncTickets?: number;
|
|
31
|
+
/** Maximum inactivity before cooperative stall cancellation is requested (0 disables). */
|
|
32
|
+
stallTimeoutMs?: number;
|
|
33
|
+
/** Whole-task transient-error retry settings. */
|
|
34
|
+
retry?: {
|
|
35
|
+
/** Max whole-task retries after the initial attempt (0 = no retry). */
|
|
36
|
+
wholeTaskMaxRetries?: number;
|
|
37
|
+
/** Base delay (ms) for exponential backoff between whole-task retries. */
|
|
38
|
+
wholeTaskBaseDelayMs?: number;
|
|
39
|
+
};
|
|
40
|
+
/** User-scope extension sources to load for subagents by provider. */
|
|
41
|
+
providerExtensions?: {
|
|
42
|
+
[provider: string]: readonly string[];
|
|
43
|
+
};
|
|
44
|
+
/** LLM-facing output bounding: over-threshold final output is spilled to a
|
|
45
|
+
* temp file with a tail kept in-context. See `spill.ts`. */
|
|
46
|
+
output?: {
|
|
47
|
+
/** Over this many chars (strictly), spill. Default 8000. */
|
|
48
|
+
spillThresholdChars?: number;
|
|
49
|
+
/** Tail length (chars) kept in-context when spilled. Default 2000. */
|
|
50
|
+
spillTailChars?: number;
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const DELEGATE_CONFIG_DIR = path.join(os.homedir(), ".pi", "agent");
|
|
55
|
+
const DELEGATE_CONFIG_PATH = path.join(DELEGATE_CONFIG_DIR, "delegate.json");
|
|
56
|
+
|
|
57
|
+
function normalizeProviderExtensions(
|
|
58
|
+
raw: unknown,
|
|
59
|
+
): Record<string, readonly string[]> {
|
|
60
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return {};
|
|
61
|
+
|
|
62
|
+
// A null-prototype map keeps config keys such as `constructor` and
|
|
63
|
+
// `__proto__` from resolving to Object.prototype members or mutating the
|
|
64
|
+
// map's prototype during normalization.
|
|
65
|
+
const out = Object.create(null) as Record<string, readonly string[]>;
|
|
66
|
+
for (const [provider, entries] of Object.entries(
|
|
67
|
+
raw as Record<string, unknown>,
|
|
68
|
+
)) {
|
|
69
|
+
const normalizedProvider = provider.trim().toLowerCase();
|
|
70
|
+
if (!normalizedProvider || !Array.isArray(entries)) continue;
|
|
71
|
+
const normalizedEntries = entries
|
|
72
|
+
.map((entry) => (typeof entry === "string" ? entry.trim() : ""))
|
|
73
|
+
.filter((entry): entry is string => entry.length > 0);
|
|
74
|
+
if (normalizedEntries.length === 0) continue;
|
|
75
|
+
out[normalizedProvider] = [...new Set(normalizedEntries)];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return out;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// Provider-scoped opt-in extension map for subagents. Keep this aligned with
|
|
82
|
+
// the currently shipped codex remote-compaction integration. `delegate.json`
|
|
83
|
+
// `providerExtensions` replaces a provider's entries (it does not append); an
|
|
84
|
+
// empty array is ignored so the default persists.
|
|
85
|
+
const DEFAULT_PROVIDER_EXTENSIONS: Record<string, readonly string[]> = {
|
|
86
|
+
"openai-codex": ["npm:@ogulcancelik/pi-codex-compaction"],
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
function resolveProviderExtensions(
|
|
90
|
+
raw: unknown,
|
|
91
|
+
): Record<string, readonly string[]> {
|
|
92
|
+
const out = Object.create(null) as Record<string, readonly string[]>;
|
|
93
|
+
Object.assign(
|
|
94
|
+
out,
|
|
95
|
+
DEFAULT_PROVIDER_EXTENSIONS,
|
|
96
|
+
normalizeProviderExtensions(raw),
|
|
97
|
+
);
|
|
98
|
+
return out;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const DEFAULT_DELEGATE_CONFIG: DelegateConfig = {
|
|
102
|
+
agent: { default: null },
|
|
103
|
+
concurrency: { default: MAX_CONCURRENCY },
|
|
104
|
+
maxConcurrent: MAX_CONCURRENCY,
|
|
105
|
+
stallTimeoutMs: 15 * 60 * 1000,
|
|
106
|
+
retry: {
|
|
107
|
+
wholeTaskMaxRetries: 3,
|
|
108
|
+
wholeTaskBaseDelayMs: 1_000,
|
|
109
|
+
},
|
|
110
|
+
providerExtensions: DEFAULT_PROVIDER_EXTENSIONS,
|
|
111
|
+
output: {
|
|
112
|
+
spillThresholdChars: OUTPUT_SPILL_THRESHOLD_CHARS,
|
|
113
|
+
spillTailChars: OUTPUT_SPILL_TAIL_CHARS,
|
|
114
|
+
},
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/** Module-level config singleton. Loaded lazily, mutated by setters. */
|
|
118
|
+
let __delegateConfig: DelegateConfig = {
|
|
119
|
+
...DEFAULT_DELEGATE_CONFIG,
|
|
120
|
+
agent: { ...DEFAULT_DELEGATE_CONFIG.agent },
|
|
121
|
+
concurrency: { ...DEFAULT_DELEGATE_CONFIG.concurrency },
|
|
122
|
+
};
|
|
123
|
+
let stallTimeoutOverrideForTesting: number | undefined;
|
|
124
|
+
|
|
125
|
+
/** Read delegate config from disk. Returns defaults if file missing or corrupt. */
|
|
126
|
+
export function loadDelegateConfig(): DelegateConfig {
|
|
127
|
+
try {
|
|
128
|
+
const raw = fs.readFileSync(DELEGATE_CONFIG_PATH, "utf-8");
|
|
129
|
+
const parsed = JSON.parse(raw);
|
|
130
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
131
|
+
return structuredClone(DEFAULT_DELEGATE_CONFIG);
|
|
132
|
+
// Merge with defaults so new fields are always present
|
|
133
|
+
return {
|
|
134
|
+
...DEFAULT_DELEGATE_CONFIG,
|
|
135
|
+
...parsed,
|
|
136
|
+
agent: { ...DEFAULT_DELEGATE_CONFIG.agent, ...(parsed.agent ?? {}) },
|
|
137
|
+
concurrency: {
|
|
138
|
+
...DEFAULT_DELEGATE_CONFIG.concurrency,
|
|
139
|
+
...(parsed.concurrency ?? {}),
|
|
140
|
+
},
|
|
141
|
+
retry: { ...DEFAULT_DELEGATE_CONFIG.retry, ...(parsed.retry ?? {}) },
|
|
142
|
+
providerExtensions: resolveProviderExtensions(parsed.providerExtensions),
|
|
143
|
+
output: { ...DEFAULT_DELEGATE_CONFIG.output, ...(parsed.output ?? {}) },
|
|
144
|
+
} as DelegateConfig;
|
|
145
|
+
} catch {
|
|
146
|
+
return structuredClone(DEFAULT_DELEGATE_CONFIG);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
/** Initialize module config from disk. Called once at extension load. */
|
|
151
|
+
function initDelegateConfig(): void {
|
|
152
|
+
__delegateConfig = loadDelegateConfig();
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
// Auto-init on module load
|
|
156
|
+
initDelegateConfig();
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Test-only seam: reset the module config singleton to compiled defaults.
|
|
160
|
+
*
|
|
161
|
+
* `__delegateConfig` is auto-initialized from `~/.pi/agent/delegate.json` at
|
|
162
|
+
* import time, so any test that exercises the config-dependent renderers
|
|
163
|
+
* (e.g. the `queued (N running)` label, which reads `getMaxConcurrent()`) is
|
|
164
|
+
* otherwise at the mercy of the developer's on-disk `maxConcurrent`. There are
|
|
165
|
+
* no production mutators (the file is the only write path); this restores the
|
|
166
|
+
* deterministic default baseline for tests, mirroring `_resetPoolForTesting` /
|
|
167
|
+
* `_resetGlobalConcurrencyForTesting`.
|
|
168
|
+
*/
|
|
169
|
+
export function _resetDelegateConfigForTesting(): void {
|
|
170
|
+
__delegateConfig = structuredClone(DEFAULT_DELEGATE_CONFIG);
|
|
171
|
+
stallTimeoutOverrideForTesting = undefined;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/** @internal Test-only override; production configuration is file-only. */
|
|
175
|
+
export function _setStallTimeoutForTesting(
|
|
176
|
+
timeoutMs: number | undefined,
|
|
177
|
+
): void {
|
|
178
|
+
stallTimeoutOverrideForTesting = timeoutMs;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Test-only seam: replace delegate config at runtime.
|
|
183
|
+
*
|
|
184
|
+
* This is only for deterministic tests; production config is file-only and not
|
|
185
|
+
* expected to mutate at runtime.
|
|
186
|
+
*/
|
|
187
|
+
export function _setDelegateConfigForTesting(
|
|
188
|
+
config: Partial<DelegateConfig> = {},
|
|
189
|
+
): void {
|
|
190
|
+
__delegateConfig = {
|
|
191
|
+
...DEFAULT_DELEGATE_CONFIG,
|
|
192
|
+
...config,
|
|
193
|
+
agent: {
|
|
194
|
+
...DEFAULT_DELEGATE_CONFIG.agent,
|
|
195
|
+
...(config.agent ?? {}),
|
|
196
|
+
},
|
|
197
|
+
concurrency: {
|
|
198
|
+
...DEFAULT_DELEGATE_CONFIG.concurrency,
|
|
199
|
+
...(config.concurrency ?? {}),
|
|
200
|
+
},
|
|
201
|
+
retry: {
|
|
202
|
+
...DEFAULT_DELEGATE_CONFIG.retry,
|
|
203
|
+
...(config.retry ?? {}),
|
|
204
|
+
},
|
|
205
|
+
providerExtensions: resolveProviderExtensions(config.providerExtensions),
|
|
206
|
+
output: {
|
|
207
|
+
...DEFAULT_DELEGATE_CONFIG.output,
|
|
208
|
+
...(config.output ?? {}),
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
stallTimeoutOverrideForTesting = undefined;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Get the configured provider-scoped extension allowlist for subagents.
|
|
216
|
+
* Explicit configs are normalized here too, so callers using the injected
|
|
217
|
+
* config form get the same case-insensitive and replace-per-provider
|
|
218
|
+
* semantics as the file-backed singleton.
|
|
219
|
+
*/
|
|
220
|
+
export function getSubagentProviderExtensionMap(
|
|
221
|
+
config: DelegateConfig = __delegateConfig,
|
|
222
|
+
): Readonly<Record<string, readonly string[]>> {
|
|
223
|
+
return config.providerExtensions
|
|
224
|
+
? resolveProviderExtensions(config.providerExtensions)
|
|
225
|
+
: DEFAULT_PROVIDER_EXTENSIONS;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/**
|
|
229
|
+
* Get extension sources for a specific provider's subagents. Provider matching is
|
|
230
|
+
* case-insensitive.
|
|
231
|
+
*/
|
|
232
|
+
export function getSubagentProviderExtensionsForProvider(
|
|
233
|
+
provider: string | undefined,
|
|
234
|
+
config: DelegateConfig = __delegateConfig,
|
|
235
|
+
): readonly string[] {
|
|
236
|
+
const normalized = provider?.trim().toLowerCase();
|
|
237
|
+
if (!normalized) return [];
|
|
238
|
+
const extensions = getSubagentProviderExtensionMap(config);
|
|
239
|
+
return Object.prototype.hasOwnProperty.call(extensions, normalized)
|
|
240
|
+
? (extensions[normalized] ?? [])
|
|
241
|
+
: [];
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// ── Config Getters ───────────────────────────────────────────────────────
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Get the effective concurrency limit for a model key.
|
|
248
|
+
*
|
|
249
|
+
* Precedence: per-model → per-provider → default. Accepts an injected config
|
|
250
|
+
* so the precedence chain is testable without touching the module singleton
|
|
251
|
+
* (there are no config mutators — `delegate.json` is the only write path).
|
|
252
|
+
*/
|
|
253
|
+
export function getConcurrencyLimit(
|
|
254
|
+
modelKey: string,
|
|
255
|
+
config: DelegateConfig = __delegateConfig,
|
|
256
|
+
): number {
|
|
257
|
+
// 1. Per-model
|
|
258
|
+
const perModel = config.concurrency.models?.[modelKey];
|
|
259
|
+
if (perModel != null) return perModel;
|
|
260
|
+
// 2. Per-provider
|
|
261
|
+
const provider = modelKey.split("/")[0];
|
|
262
|
+
const perProvider = config.concurrency.providers?.[provider];
|
|
263
|
+
if (perProvider != null) return perProvider;
|
|
264
|
+
// 3. Default
|
|
265
|
+
return config.concurrency.default;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
/** Get the effective max async tickets limit. */
|
|
269
|
+
export function getMaxAsyncTickets(): number {
|
|
270
|
+
return __delegateConfig.maxAsyncTickets ?? MAX_ASYNC_TICKETS;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** Get the hard ceiling on total concurrent agents. */
|
|
274
|
+
export function getMaxConcurrent(): number {
|
|
275
|
+
return __delegateConfig.maxConcurrent ?? MAX_CONCURRENCY;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/** Maximum inactivity before cooperative stall cancellation is requested.
|
|
279
|
+
* `0` disables detection; malformed values fall back to the compiled default. */
|
|
280
|
+
export function getStallTimeoutMs(
|
|
281
|
+
config: DelegateConfig = __delegateConfig,
|
|
282
|
+
): number {
|
|
283
|
+
const configured = stallTimeoutOverrideForTesting ?? config.stallTimeoutMs;
|
|
284
|
+
if (
|
|
285
|
+
typeof configured === "number" &&
|
|
286
|
+
Number.isFinite(configured) &&
|
|
287
|
+
configured >= 0
|
|
288
|
+
) {
|
|
289
|
+
return configured;
|
|
290
|
+
}
|
|
291
|
+
return DEFAULT_DELEGATE_CONFIG.stallTimeoutMs!;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/** Get the max whole-task retries after the initial attempt. */
|
|
295
|
+
export function getWholeTaskMaxRetries(): number {
|
|
296
|
+
return __delegateConfig.retry?.wholeTaskMaxRetries ?? 3;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/** Get the base delay (ms) for whole-task retry exponential backoff. */
|
|
300
|
+
export function getWholeTaskBaseDelayMs(): number {
|
|
301
|
+
return __delegateConfig.retry?.wholeTaskBaseDelayMs ?? 1_000;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** Get the output-spill threshold (chars). Over this, final output is spilled. */
|
|
305
|
+
export function getOutputSpillThreshold(): number {
|
|
306
|
+
return (
|
|
307
|
+
__delegateConfig.output?.spillThresholdChars ?? OUTPUT_SPILL_THRESHOLD_CHARS
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/** Get the output-spill tail length (chars) kept in-context when spilled. */
|
|
312
|
+
export function getOutputSpillTail(): number {
|
|
313
|
+
return __delegateConfig.output?.spillTailChars ?? OUTPUT_SPILL_TAIL_CHARS;
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
/**
|
|
317
|
+
* Resolve an *explicit* model spec string using the precedence chain.
|
|
318
|
+
* Returns the first non-null, non-empty string value, or `undefined` when no
|
|
319
|
+
* explicit spec is set — in which case the caller inherits the parent
|
|
320
|
+
* session's model object directly (see extension.ts).
|
|
321
|
+
*
|
|
322
|
+
* Parent inheritance is intentionally NOT a tier here: the parent model is
|
|
323
|
+
* already a resolved, authenticated Model object. Re-resolving its id string
|
|
324
|
+
* through the registry would be both redundant and lossy for composite ids
|
|
325
|
+
* such as OpenRouter's "provider/upstream/model", whose first segment is an
|
|
326
|
+
* upstream provider name, not a configured pi provider — that misroutes auth
|
|
327
|
+
* lookup to the wrong provider.
|
|
328
|
+
*
|
|
329
|
+
* Precedence (highest to lowest):
|
|
330
|
+
* 1. taskModel — per-task explicit override (from API call)
|
|
331
|
+
* 2. config.agent[agentType] — config per-type (delegate.json)
|
|
332
|
+
* 3. config.agent["default"] — config global
|
|
333
|
+
* 4. frontmatterModel — agent .md frontmatter
|
|
334
|
+
*/
|
|
335
|
+
export function resolveModelSpec(options: {
|
|
336
|
+
taskModel?: string;
|
|
337
|
+
agentType: string;
|
|
338
|
+
frontmatterModel?: string;
|
|
339
|
+
config?: DelegateConfig;
|
|
340
|
+
}): string | undefined {
|
|
341
|
+
const {
|
|
342
|
+
taskModel,
|
|
343
|
+
agentType,
|
|
344
|
+
frontmatterModel,
|
|
345
|
+
config = __delegateConfig,
|
|
346
|
+
} = options;
|
|
347
|
+
|
|
348
|
+
const candidates: Array<string | null | undefined> = [
|
|
349
|
+
taskModel,
|
|
350
|
+
config.agent[agentType] as string | null | undefined,
|
|
351
|
+
config.agent["default"],
|
|
352
|
+
frontmatterModel,
|
|
353
|
+
];
|
|
354
|
+
|
|
355
|
+
return candidates.find(
|
|
356
|
+
(v): v is string => typeof v === "string" && v.length > 0,
|
|
357
|
+
);
|
|
358
|
+
}
|
package/constants.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** Full-capability agent set. Inline-task default and the `*` shorthand.
|
|
2
|
+
* Bash subsumes search, so the dedicated grep/find/ls tools are excluded. */
|
|
3
|
+
export const DEFAULT_TOOLS = ["read", "write", "edit", "bash"];
|
|
4
|
+
|
|
5
|
+
/** Read-only scout set: search without a shell. The `ro` shorthand. */
|
|
6
|
+
export const READONLY_TOOLS = ["read", "grep", "find", "ls"];
|
|
7
|
+
|
|
8
|
+
/** Maximum concurrent subagent tasks. Prevents rate-limit thundering herds. */
|
|
9
|
+
export const MAX_CONCURRENCY = 3;
|
|
10
|
+
|
|
11
|
+
/** Maximum concurrent background async tickets. */
|
|
12
|
+
export const MAX_ASYNC_TICKETS = 5;
|
|
13
|
+
|
|
14
|
+
/** Completed tickets cleaned up after 30 minutes. */
|
|
15
|
+
export const ASYNC_TICKET_TTL_MS = 30 * 60 * 1000;
|
|
16
|
+
|
|
17
|
+
/** Subagent final output longer than this (chars) is spilled to a temp file,
|
|
18
|
+
* keeping only a tail in the LLM-facing context. See `spill.ts`. */
|
|
19
|
+
export const OUTPUT_SPILL_THRESHOLD_CHARS = 8000;
|
|
20
|
+
|
|
21
|
+
/** Tail length (chars) kept in-context when an output is spilled. */
|
|
22
|
+
export const OUTPUT_SPILL_TAIL_CHARS = 2000;
|
|
23
|
+
|
|
24
|
+
/** Literal union of valid thinking levels. Source of truth for both the
|
|
25
|
+
* runtime Set (below) and the TypeBox schema's static type — the `as const`
|
|
26
|
+
* tuple keeps `StringEnum`'s `T[number]` narrow so `DelegateArguments["tasks"]`
|
|
27
|
+
* projects `thinking` to the literal union rather than `string`. */
|
|
28
|
+
export const VALID_THINKING_LEVELS = [
|
|
29
|
+
"off",
|
|
30
|
+
"minimal",
|
|
31
|
+
"low",
|
|
32
|
+
"medium",
|
|
33
|
+
"high",
|
|
34
|
+
"xhigh",
|
|
35
|
+
"max",
|
|
36
|
+
] as const;
|
|
37
|
+
|
|
38
|
+
/** Runtime membership check for thinking levels. Kept as `Set<string>` (not
|
|
39
|
+
* `Set<VALID_THINKING_LEVELS[number]>`) so the `.has(string)` call sites in
|
|
40
|
+
* task-resolution.ts and agents.ts stay ergonomic under strict typing. */
|
|
41
|
+
export const VALID_THINKING: Set<string> = new Set(VALID_THINKING_LEVELS);
|
package/delegate.ts
ADDED
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
export { default } from "./extension.ts";
|
|
2
|
+
|
|
3
|
+
export type {
|
|
4
|
+
AgentConfig,
|
|
5
|
+
SessionAction,
|
|
6
|
+
DelegateAction,
|
|
7
|
+
DelegateArguments,
|
|
8
|
+
TaskDef,
|
|
9
|
+
AsyncTicket,
|
|
10
|
+
ResolvedTask,
|
|
11
|
+
ToolActivity,
|
|
12
|
+
TaskProgress,
|
|
13
|
+
DelegateDetails,
|
|
14
|
+
TaskResult,
|
|
15
|
+
TaskFailureKind,
|
|
16
|
+
ReuseIntent,
|
|
17
|
+
AgentRunConfig,
|
|
18
|
+
TaskRunEnv,
|
|
19
|
+
} from "./types.ts";
|
|
20
|
+
export type { DelegateConfig } from "./config.ts";
|
|
21
|
+
|
|
22
|
+
export {
|
|
23
|
+
DEFAULT_TOOLS,
|
|
24
|
+
READONLY_TOOLS,
|
|
25
|
+
MAX_CONCURRENCY,
|
|
26
|
+
VALID_THINKING,
|
|
27
|
+
} from "./constants.ts";
|
|
28
|
+
export { TOOL_FACTORIES, resolveToolGroups } from "./tools.ts";
|
|
29
|
+
export {
|
|
30
|
+
loadDelegateConfig,
|
|
31
|
+
getConcurrencyLimit,
|
|
32
|
+
getMaxAsyncTickets,
|
|
33
|
+
getMaxConcurrent,
|
|
34
|
+
getStallTimeoutMs,
|
|
35
|
+
resolveModelSpec,
|
|
36
|
+
getOutputSpillThreshold,
|
|
37
|
+
getOutputSpillTail,
|
|
38
|
+
} from "./config.ts";
|
|
39
|
+
export {
|
|
40
|
+
checkout,
|
|
41
|
+
commit,
|
|
42
|
+
configFor,
|
|
43
|
+
closePooledAgent,
|
|
44
|
+
closeAllPooledAgents,
|
|
45
|
+
listPooledAgents,
|
|
46
|
+
withSessionLock,
|
|
47
|
+
} from "./pool.ts";
|
|
48
|
+
export type {
|
|
49
|
+
FrozenConfig,
|
|
50
|
+
ConfigCandidate,
|
|
51
|
+
ConfigMismatch,
|
|
52
|
+
CheckoutResult,
|
|
53
|
+
CommitPayload,
|
|
54
|
+
} from "./pool.ts";
|
|
55
|
+
export {
|
|
56
|
+
ticketRegistry,
|
|
57
|
+
sweepTickets,
|
|
58
|
+
cancelTicketForShutdown,
|
|
59
|
+
isSessionBusy,
|
|
60
|
+
handlePoll,
|
|
61
|
+
handleCancel,
|
|
62
|
+
handleWait,
|
|
63
|
+
notifyWaiters,
|
|
64
|
+
deliverTicketResults,
|
|
65
|
+
resolveFinalTicketStatus,
|
|
66
|
+
formatCompletedTicket,
|
|
67
|
+
} from "./tickets.ts";
|
|
68
|
+
export { runAgentSession } from "./runner.ts";
|
|
69
|
+
export { getHostDeps } from "./host.ts";
|
|
70
|
+
export type { HostDeps, HostDepsOptions } from "./host.ts";
|
|
71
|
+
export {
|
|
72
|
+
emptyUsage,
|
|
73
|
+
snapshotSessionUsage,
|
|
74
|
+
usageDelta,
|
|
75
|
+
addUsage,
|
|
76
|
+
sumUsage,
|
|
77
|
+
} from "./usage.ts";
|
|
78
|
+
export type { SessionUsageSnapshot } from "./usage.ts";
|
|
79
|
+
export {
|
|
80
|
+
truncLine,
|
|
81
|
+
shortenPath,
|
|
82
|
+
getActivityAge,
|
|
83
|
+
fmtDuration,
|
|
84
|
+
fmtTokens,
|
|
85
|
+
trunc,
|
|
86
|
+
tree,
|
|
87
|
+
indent,
|
|
88
|
+
formatFailedTask,
|
|
89
|
+
formatCompletedTask,
|
|
90
|
+
} from "./format.ts";
|
|
91
|
+
export {
|
|
92
|
+
parseFrontmatter,
|
|
93
|
+
findProjectRoot,
|
|
94
|
+
loadAgentFile,
|
|
95
|
+
loadClaudeAgentFile,
|
|
96
|
+
discoverAgents,
|
|
97
|
+
buildSubagentSystemPrompt,
|
|
98
|
+
DEFAULT_SUBAGENT_SYSTEM_PROMPT,
|
|
99
|
+
} from "./agents.ts";
|
|
100
|
+
export { buildParentTranscript, extractTextContent } from "./parent-context.ts";
|
|
101
|
+
export { extractTouchedFromActivities } from "./file-tracking.ts";
|
|
102
|
+
export {
|
|
103
|
+
resolveModel,
|
|
104
|
+
resolveModelRequest,
|
|
105
|
+
findAvailableAlternative,
|
|
106
|
+
} from "./model.ts";
|
|
107
|
+
export { readDelegateSettingsFile, loadDelegateSettings } from "./settings.ts";
|
|
108
|
+
export { resolveCwd, extractOutput, extractUsage } from "./utils.ts";
|
|
109
|
+
export {
|
|
110
|
+
decideSpill,
|
|
111
|
+
spillToTempFile,
|
|
112
|
+
renderOutputForLLM,
|
|
113
|
+
renderOutputForPoll,
|
|
114
|
+
} from "./spill.ts";
|
|
115
|
+
export type { SpillDecision } from "./spill.ts";
|