klyro 0.1.63 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/anthropic-adapter.d.ts +36 -0
- package/dist/agent/anthropic-adapter.js +73 -16
- package/dist/agent/capabilities.d.ts +145 -0
- package/dist/agent/capabilities.js +191 -0
- package/dist/agent/child-worker.d.ts +104 -0
- package/dist/agent/child-worker.js +250 -0
- package/dist/agent/orchestrator.d.ts +232 -0
- package/dist/agent/orchestrator.js +589 -0
- package/dist/agent/provider-adapter.d.ts +17 -0
- package/dist/agent/provider-adapter.js +35 -3
- package/dist/agent/registry.d.ts +1 -0
- package/dist/agent/registry.js +1 -0
- package/dist/agent/retry.d.ts +13 -2
- package/dist/agent/retry.js +21 -3
- package/dist/agent/runtime.d.ts +70 -8
- package/dist/agent/runtime.js +205 -34
- package/dist/agent/scoped-registry.d.ts +22 -0
- package/dist/agent/scoped-registry.js +42 -0
- package/dist/agent/task-manager.d.ts +115 -0
- package/dist/agent/task-manager.js +250 -0
- package/dist/agent/worker-spawner.d.ts +17 -12
- package/dist/agent/worker-spawner.js +26 -20
- package/dist/agent/worktree-manager.d.ts +74 -0
- package/dist/agent/worktree-manager.js +189 -0
- package/dist/checkpoints/store.js +30 -5
- package/dist/cli/auth.js +16 -1
- package/dist/cli/config.d.ts +9 -3
- package/dist/cli/config.js +64 -3
- package/dist/cli/dotenv.d.ts +3 -0
- package/dist/cli/dotenv.js +57 -0
- package/dist/cli/eval.d.ts +6 -1
- package/dist/cli/eval.js +9 -0
- package/dist/cli/repl.js +183 -17
- package/dist/cli/run.d.ts +10 -11
- package/dist/cli/run.js +176 -14
- package/dist/cli/update.d.ts +5 -0
- package/dist/cli/update.js +62 -10
- package/dist/context/import-graph.d.ts +2 -0
- package/dist/context/import-graph.js +31 -3
- package/dist/context/klyro-md.d.ts +6 -0
- package/dist/context/klyro-md.js +25 -16
- package/dist/context/memory.d.ts +8 -0
- package/dist/context/memory.js +50 -2
- package/dist/context/project-map.d.ts +6 -0
- package/dist/context/project-map.js +50 -2
- package/dist/context/repo-map.d.ts +2 -0
- package/dist/context/repo-map.js +31 -1
- package/dist/context/trust.d.ts +42 -0
- package/dist/context/trust.js +111 -0
- package/dist/events/catalog.d.ts +99 -0
- package/dist/index.js +93 -4
- package/dist/mcp/client.d.ts +55 -0
- package/dist/mcp/client.js +294 -0
- package/dist/mcp/config.d.ts +40 -0
- package/dist/mcp/config.js +99 -0
- package/dist/mcp/policy.d.ts +13 -0
- package/dist/mcp/policy.js +12 -0
- package/dist/mcp/registry.d.ts +72 -0
- package/dist/mcp/registry.js +244 -0
- package/dist/mcp/schema.d.ts +18 -0
- package/dist/mcp/schema.js +57 -0
- package/dist/mcp/trust.d.ts +20 -0
- package/dist/mcp/trust.js +74 -0
- package/dist/persistence/audit.d.ts +28 -0
- package/dist/persistence/audit.js +101 -1
- package/dist/persistence/store.d.ts +26 -2
- package/dist/persistence/store.js +140 -13
- package/dist/policy/approval.d.ts +14 -0
- package/dist/policy/approval.js +44 -2
- package/dist/policy/engine.d.ts +1 -0
- package/dist/policy/engine.js +91 -10
- package/dist/policy/secret-redactor.js +4 -0
- package/dist/providers/model-info.d.ts +17 -0
- package/dist/providers/model-info.js +35 -2
- package/dist/repl.d.ts +6 -0
- package/dist/repl.js +12 -7
- package/dist/tools/agent/spawn-agent.d.ts +9 -0
- package/dist/tools/agent/spawn-agent.js +50 -0
- package/dist/tools/agent/task-apply.d.ts +4 -0
- package/dist/tools/agent/task-apply.js +44 -0
- package/dist/tools/agent/task-get.d.ts +8 -0
- package/dist/tools/agent/task-get.js +40 -0
- package/dist/tools/agent/task-list.d.ts +4 -0
- package/dist/tools/agent/task-list.js +41 -0
- package/dist/tools/agent/task-stop.d.ts +6 -0
- package/dist/tools/agent/task-stop.js +39 -0
- package/dist/tools/agent/task-wait.d.ts +17 -0
- package/dist/tools/agent/task-wait.js +79 -0
- package/dist/tools/fs/apply-patch.js +71 -0
- package/dist/tools/fs/edit-file.js +65 -0
- package/dist/tools/fs/multi-edit.d.ts +4 -0
- package/dist/tools/fs/multi-edit.js +66 -0
- package/dist/tools/fs/write-file.js +67 -0
- package/dist/tools/plan/todo-write.d.ts +1 -1
- package/dist/tools/registry.js +12 -0
- package/dist/tools/shell/background.js +6 -3
- package/dist/tools/shell/sandbox.d.ts +51 -0
- package/dist/tools/shell/sandbox.js +143 -0
- package/dist/tools/shell/shell-exec.d.ts +1 -0
- package/dist/tools/shell/shell-exec.js +83 -11
- package/dist/tools/shell/worker-entry.d.ts +12 -0
- package/dist/tools/shell/worker-entry.js +43 -0
- package/dist/tools/types.d.ts +18 -0
- package/dist/tools/verify/run-verify.js +3 -1
- package/dist/trace/writer.d.ts +13 -0
- package/dist/trace/writer.js +55 -4
- package/dist/tui/app.js +1 -1
- package/dist/tui/approval.js +20 -21
- package/dist/util.d.ts +1 -0
- package/dist/util.js +1 -0
- package/dist/verification/baseline.js +17 -3
- package/dist/verification/classify.js +23 -12
- package/dist/verification/engine.js +3 -1
- package/dist/verification/registry.d.ts +2 -0
- package/dist/verification/registry.js +33 -0
- package/dist/verification/scoped.js +28 -6
- package/package.json +1 -1
|
@@ -12,6 +12,25 @@
|
|
|
12
12
|
*/
|
|
13
13
|
import { redact } from '../policy/secret-redactor.js';
|
|
14
14
|
const DEFAULT_TIMEOUT_MS = 120_000;
|
|
15
|
+
/**
|
|
16
|
+
* Parse a `Retry-After` response header value into milliseconds.
|
|
17
|
+
* Returns undefined when absent or unparseable. Handles both forms:
|
|
18
|
+
* delay-seconds ("120") and HTTP-date ("Wed, 21 Oct 2015 07:28:00 GMT",
|
|
19
|
+
* clamped at 0 when the date is in the past).
|
|
20
|
+
*/
|
|
21
|
+
export function parseRetryAfterMs(value) {
|
|
22
|
+
if (value == null)
|
|
23
|
+
return undefined;
|
|
24
|
+
const v = value.trim();
|
|
25
|
+
if (!v)
|
|
26
|
+
return undefined;
|
|
27
|
+
if (/^\d+$/.test(v))
|
|
28
|
+
return Number(v) * 1000;
|
|
29
|
+
const t = Date.parse(v);
|
|
30
|
+
if (!Number.isNaN(t))
|
|
31
|
+
return Math.max(0, t - Date.now());
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
15
34
|
/** Convert a Zod schema to a permissive JSON Schema object for tool defs. */
|
|
16
35
|
export function zodToJsonSchema(schema) {
|
|
17
36
|
// We keep this simple: zod's own _def is enough to give the model a
|
|
@@ -89,8 +108,12 @@ function zodFieldSchema(s) {
|
|
|
89
108
|
*/
|
|
90
109
|
export function buildChatCompletionsBody(req) {
|
|
91
110
|
const messages = [];
|
|
111
|
+
// OpenAI has no system array form: the volatile suffix rides along as a
|
|
112
|
+
// plain concatenation (behavior-preserving when absent).
|
|
92
113
|
if (req.system)
|
|
93
|
-
messages.push({ role: 'system', content: req.system });
|
|
114
|
+
messages.push({ role: 'system', content: req.systemSuffix ? `${req.system}\n\n${req.systemSuffix}` : req.system });
|
|
115
|
+
else if (req.systemSuffix)
|
|
116
|
+
messages.push({ role: 'system', content: req.systemSuffix });
|
|
94
117
|
for (const m of req.messages) {
|
|
95
118
|
if (m.role === 'assistant') {
|
|
96
119
|
const text = m.content.filter((b) => b.kind === 'text').map((b) => b.text).join('');
|
|
@@ -183,11 +206,20 @@ async function* streamChatCompletions(url, opts, req, fetchImpl) {
|
|
|
183
206
|
req.signal?.removeEventListener('abort', onAbort);
|
|
184
207
|
const rawErr = await res.text().catch(() => '');
|
|
185
208
|
const errText = redact(rawErr).slice(0, 500);
|
|
209
|
+
// Context overflow is a client-side budget problem, not a transient
|
|
210
|
+
// failure: surface a dedicated code (never retryable here — the runtime
|
|
211
|
+
// owns the compress-and-retry recovery) so callers can distinguish it
|
|
212
|
+
// from 429/5xx backoff cases.
|
|
213
|
+
const isOverflow = res.status === 413 || /request_too_large|too_large|prompt_too_long|context_length|maximum context length/i.test(rawErr);
|
|
214
|
+
const retryable = !isOverflow && (res.status >= 500 || res.status === 429);
|
|
215
|
+
const retryAfterMs = retryable ? parseRetryAfterMs(res.headers?.get('retry-after')) : undefined;
|
|
186
216
|
yield {
|
|
187
217
|
kind: 'error',
|
|
188
|
-
code: `HTTP_${res.status}`,
|
|
218
|
+
code: isOverflow ? 'REQUEST_TOO_LARGE' : `HTTP_${res.status}`,
|
|
189
219
|
message: `provider returned ${res.status}: ${errText}`,
|
|
190
|
-
retryable
|
|
220
|
+
retryable,
|
|
221
|
+
status: String(res.status),
|
|
222
|
+
...(retryAfterMs !== undefined ? { retryAfterMs } : {}),
|
|
191
223
|
};
|
|
192
224
|
return;
|
|
193
225
|
}
|
package/dist/agent/registry.d.ts
CHANGED
package/dist/agent/registry.js
CHANGED
package/dist/agent/retry.d.ts
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
*
|
|
16
16
|
* delay = min(maxMs, baseMs * 2^attempt) ± jitter
|
|
17
17
|
*
|
|
18
|
-
* The default policy matches the L6 plan:
|
|
18
|
+
* The default policy matches the L6 plan: 5 attempts, 500ms base, 8s cap.
|
|
19
19
|
*/
|
|
20
20
|
import type { ProviderAdapter } from './provider-adapter.js';
|
|
21
21
|
export interface RetryOptions {
|
|
@@ -28,8 +28,19 @@ export interface RetryOptions {
|
|
|
28
28
|
sleep?: (ms: number) => Promise<void>;
|
|
29
29
|
/** Test hook: called once per attempt with 0-indexed attempt number. */
|
|
30
30
|
onAttempt?: (attempt: number) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Retry telemetry hook (operator-visible; the model stays blind).
|
|
33
|
+
* Called each time a retryable error is buffered and another attempt
|
|
34
|
+
* will follow (NOT on the terminal failure). `attempt` is the
|
|
35
|
+
* 1-indexed retry number (1 = first retry after the initial failure).
|
|
36
|
+
*/
|
|
37
|
+
onRetry?: (info: {
|
|
38
|
+
attempt: number;
|
|
39
|
+
status: string;
|
|
40
|
+
retryAfterMs?: number;
|
|
41
|
+
}) => void;
|
|
31
42
|
}
|
|
32
|
-
export declare const DEFAULT_RETRY: Required<Omit<RetryOptions, 'signal' | 'onAttempt'>>;
|
|
43
|
+
export declare const DEFAULT_RETRY: Required<Omit<RetryOptions, 'signal' | 'onAttempt' | 'onRetry'>>;
|
|
33
44
|
/**
|
|
34
45
|
* Sleep that resolves early when `signal` aborts (never rejects — callers
|
|
35
46
|
* check `signal.aborted` themselves after waking).
|
package/dist/agent/retry.js
CHANGED
|
@@ -15,10 +15,10 @@
|
|
|
15
15
|
*
|
|
16
16
|
* delay = min(maxMs, baseMs * 2^attempt) ± jitter
|
|
17
17
|
*
|
|
18
|
-
* The default policy matches the L6 plan:
|
|
18
|
+
* The default policy matches the L6 plan: 5 attempts, 500ms base, 8s cap.
|
|
19
19
|
*/
|
|
20
20
|
export const DEFAULT_RETRY = {
|
|
21
|
-
maxAttempts:
|
|
21
|
+
maxAttempts: 5,
|
|
22
22
|
baseMs: 500,
|
|
23
23
|
maxMs: 8_000,
|
|
24
24
|
sleep: defaultSleep,
|
|
@@ -152,7 +152,25 @@ export function retryingAdapter(inner, opts = {}) {
|
|
|
152
152
|
yield lastError;
|
|
153
153
|
return;
|
|
154
154
|
}
|
|
155
|
-
|
|
155
|
+
// Telemetry for the operator: a retryable error was buffered and
|
|
156
|
+
// another attempt will follow. The consumer stream never sees the
|
|
157
|
+
// buffered error, so the model stays blind.
|
|
158
|
+
const errRec = lastError;
|
|
159
|
+
const statusRaw = errRec?.['status'];
|
|
160
|
+
const codeRaw = errRec?.['code'];
|
|
161
|
+
const status = typeof statusRaw === 'string' && statusRaw.length > 0
|
|
162
|
+
? statusRaw
|
|
163
|
+
: typeof codeRaw === 'string' && codeRaw.length > 0
|
|
164
|
+
? codeRaw
|
|
165
|
+
: 'retryable';
|
|
166
|
+
const retryAfterRaw = errRec?.['retryAfterMs'];
|
|
167
|
+
const retryAfterMs = typeof retryAfterRaw === 'number' && Number.isFinite(retryAfterRaw) && retryAfterRaw >= 0
|
|
168
|
+
? retryAfterRaw
|
|
169
|
+
: undefined;
|
|
170
|
+
opts.onRetry?.({ attempt: attempt + 1, status, ...(retryAfterMs !== undefined ? { retryAfterMs } : {}) });
|
|
171
|
+
// Honor a server-provided Retry-After delay when present; otherwise
|
|
172
|
+
// fall back to exponential backoff with jitter.
|
|
173
|
+
const delay = retryAfterMs ?? computeBackoff(attempt, cfg.baseMs, cfg.maxMs);
|
|
156
174
|
// Abort-aware backoff: Ctrl+C during the sleep must stop promptly
|
|
157
175
|
// instead of stalling up to maxMs before noticing.
|
|
158
176
|
if (delay > 0)
|
package/dist/agent/runtime.d.ts
CHANGED
|
@@ -19,6 +19,16 @@ import type { Message } from './message.js';
|
|
|
19
19
|
import type { ToolRegistry } from '../tools/registry.js';
|
|
20
20
|
import type { PolicyEngine } from '../policy/engine.js';
|
|
21
21
|
import type { ApprovalPrompt } from '../policy/approval.js';
|
|
22
|
+
/**
|
|
23
|
+
* Verification mode. The canonical definition lives in verification/engine.ts
|
|
24
|
+
* (sibling-owned: `export type VerifyMode = 'strict'|'advisory'|'off'`). It is
|
|
25
|
+
* resolved conditionally here so this file typechecks regardless of sibling
|
|
26
|
+
* landing order — and converges to the sibling type automatically once the
|
|
27
|
+
* sibling export exists.
|
|
28
|
+
*/
|
|
29
|
+
export type VerifyMode = typeof import('../verification/engine.js') extends {
|
|
30
|
+
VerifyMode: infer V;
|
|
31
|
+
} ? V : 'strict' | 'advisory' | 'off';
|
|
22
32
|
export interface RuntimeDeps {
|
|
23
33
|
adapter: ProviderAdapter;
|
|
24
34
|
registry: ToolRegistry;
|
|
@@ -26,15 +36,34 @@ export interface RuntimeDeps {
|
|
|
26
36
|
approval: ApprovalPrompt;
|
|
27
37
|
/**
|
|
28
38
|
* Build a system prompt given cwd + the current Level-7 runtime telemetry.
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
39
|
+
*
|
|
40
|
+
* TELEMETRY SPLIT: the fn may return either a plain string (legacy —
|
|
41
|
+
* telemetry already concatenated, cache-unfriendly) or
|
|
42
|
+
* `{system, suffix}` where `suffix` is the volatile telemetry block.
|
|
43
|
+
* The runtime forwards both halves via CallRequest (`system` +
|
|
44
|
+
* `systemSuffix`) so adapters can keep the suffix out of the cacheable
|
|
45
|
+
* prefix (Anthropic array form) or concatenate it (OpenAI — unchanged).
|
|
46
|
+
* Both shapes are accepted so custom fns keep compiling.
|
|
32
47
|
*/
|
|
33
|
-
systemPrompt:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
48
|
+
systemPrompt: SystemPromptFn;
|
|
49
|
+
}
|
|
50
|
+
/** Split system-prompt result: stable prefix + volatile telemetry suffix. */
|
|
51
|
+
export interface SystemPromptResult {
|
|
52
|
+
system: string;
|
|
53
|
+
suffix?: string;
|
|
37
54
|
}
|
|
55
|
+
export type SystemPromptFn = (ctx: {
|
|
56
|
+
cwd: string;
|
|
57
|
+
telemetry?: string;
|
|
58
|
+
}) => string | SystemPromptResult;
|
|
59
|
+
/** Normalize either systemPrompt shape into {system, suffix}. */
|
|
60
|
+
export declare function resolveSystemPrompt(fn: SystemPromptFn, ctx: {
|
|
61
|
+
cwd: string;
|
|
62
|
+
telemetry?: string;
|
|
63
|
+
}): {
|
|
64
|
+
system: string;
|
|
65
|
+
suffix?: string;
|
|
66
|
+
};
|
|
38
67
|
export type Phase = 'understanding' | 'exploring' | 'planning' | 'implementing' | 'verifying' | 'done' | 'blocked' | 'limit';
|
|
39
68
|
export interface RunOptions {
|
|
40
69
|
task: string;
|
|
@@ -77,6 +106,9 @@ export interface RunOptions {
|
|
|
77
106
|
maxRepairAttempts?: number;
|
|
78
107
|
timeoutMs?: number;
|
|
79
108
|
requireVerify?: boolean;
|
|
109
|
+
/** Verification mode (default 'strict'). 'off' skips the pipeline;
|
|
110
|
+
* 'advisory' runs verify once on completion without repair turns. */
|
|
111
|
+
mode?: VerifyMode;
|
|
80
112
|
};
|
|
81
113
|
/**
|
|
82
114
|
* Level 9 — persistence. When a SessionStore is provided, every message
|
|
@@ -87,6 +119,28 @@ export interface RunOptions {
|
|
|
87
119
|
store?: import('../persistence/store.js').SessionStore;
|
|
88
120
|
sessionId?: string;
|
|
89
121
|
};
|
|
122
|
+
/**
|
|
123
|
+
* Orchestration context (P0). Present for any agent that is itself managed
|
|
124
|
+
* by an AgentOrchestrator — so a child knows who its parent is, how deep the
|
|
125
|
+
* call stack is, which tools it may use, and which task/session it belongs to.
|
|
126
|
+
*/
|
|
127
|
+
parentContext?: {
|
|
128
|
+
taskId?: string;
|
|
129
|
+
parentTaskId?: string;
|
|
130
|
+
sessionId: string;
|
|
131
|
+
depth: number;
|
|
132
|
+
maxDepth: number;
|
|
133
|
+
allowedTools?: ReadonlySet<string>;
|
|
134
|
+
/** Path allow-set inherited from the parent (sibling C contract). */
|
|
135
|
+
allowedPaths?: readonly string[];
|
|
136
|
+
model?: string;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Delegation bridge (P0). Present on the root run so the model can call
|
|
140
|
+
* spawn_agent / task_list / task_get. The tool layer reads it from the
|
|
141
|
+
* ToolContext.
|
|
142
|
+
*/
|
|
143
|
+
agentBridge?: import('./orchestrator.js').AgentSpawnBridge;
|
|
90
144
|
}
|
|
91
145
|
/** A single plan step emitted by the agent. */
|
|
92
146
|
export interface PlanStep {
|
|
@@ -140,6 +194,8 @@ export type RuntimeEvent = {
|
|
|
140
194
|
input: number;
|
|
141
195
|
output: number;
|
|
142
196
|
estimated?: boolean;
|
|
197
|
+
cacheRead?: number;
|
|
198
|
+
cacheWrite?: number;
|
|
143
199
|
} | {
|
|
144
200
|
kind: 'final_text';
|
|
145
201
|
text: string;
|
|
@@ -183,6 +239,8 @@ export interface RunResult {
|
|
|
183
239
|
input: number;
|
|
184
240
|
output: number;
|
|
185
241
|
estimated?: boolean;
|
|
242
|
+
cacheRead?: number;
|
|
243
|
+
cacheWrite?: number;
|
|
186
244
|
};
|
|
187
245
|
/** Number of policy-driven user prompts the user accepted. */
|
|
188
246
|
repairs?: number;
|
|
@@ -192,6 +250,10 @@ export interface RunResult {
|
|
|
192
250
|
command?: string;
|
|
193
251
|
attempts: number;
|
|
194
252
|
failureType?: string;
|
|
253
|
+
repairTokens?: {
|
|
254
|
+
input: number;
|
|
255
|
+
output: number;
|
|
256
|
+
};
|
|
195
257
|
};
|
|
196
258
|
/** 5.1 phase */
|
|
197
259
|
phase?: Phase;
|
|
@@ -208,4 +270,4 @@ export declare function run(opts: RunOptions, deps: RuntimeDeps): Promise<RunRes
|
|
|
208
270
|
export declare function defaultSystemPrompt(ctx: {
|
|
209
271
|
cwd: string;
|
|
210
272
|
telemetry?: string;
|
|
211
|
-
}):
|
|
273
|
+
}): SystemPromptResult;
|