@jxburros/ai-nugget 0.4.1 → 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.
- package/README.md +158 -382
- package/UPGRADING.md +182 -0
- package/dist/adapters/engines/anthropic.d.ts +7 -1
- package/dist/adapters/engines/anthropic.js +82 -37
- package/dist/adapters/engines/base.d.ts +29 -2
- package/dist/adapters/engines/base.js +52 -8
- package/dist/adapters/engines/google.d.ts +7 -1
- package/dist/adapters/engines/google.js +80 -29
- package/dist/adapters/engines/ollama.d.ts +2 -1
- package/dist/adapters/engines/ollama.js +57 -15
- package/dist/adapters/engines/openaiChat.d.ts +8 -1
- package/dist/adapters/engines/openaiChat.js +109 -29
- package/dist/adapters/profiles.d.ts +21 -1
- package/dist/adapters/profiles.js +12 -2
- package/dist/agent/loop.d.ts +45 -1
- package/dist/agent/loop.js +117 -12
- package/dist/cjs/adapters/engines/anthropic.js +326 -0
- package/dist/cjs/adapters/engines/base.js +147 -0
- package/dist/cjs/adapters/engines/google.js +291 -0
- package/dist/cjs/adapters/engines/ollama.js +205 -0
- package/dist/cjs/adapters/engines/openaiChat.js +312 -0
- package/dist/cjs/adapters/index.js +22 -0
- package/dist/cjs/adapters/profiles.js +125 -0
- package/dist/cjs/agent/index.js +18 -0
- package/dist/cjs/agent/loop.js +373 -0
- package/dist/cjs/agent/tools.js +51 -0
- package/dist/cjs/connect.js +27 -0
- package/dist/cjs/errors.js +110 -0
- package/dist/cjs/handler.js +586 -0
- package/dist/cjs/index.js +28 -0
- package/dist/cjs/json.js +121 -0
- package/dist/cjs/keys.js +81 -0
- package/dist/cjs/package.json +3 -0
- package/dist/cjs/policy.js +42 -0
- package/dist/cjs/reasoning.js +159 -0
- package/dist/cjs/redact.js +78 -0
- package/dist/cjs/tokens.js +22 -0
- package/dist/cjs/transport.js +172 -0
- package/dist/cjs/types.js +6 -0
- package/dist/cjs/util.js +126 -0
- package/dist/errors.js +25 -1
- package/dist/handler.d.ts +67 -1
- package/dist/handler.js +266 -61
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/reasoning.d.ts +45 -0
- package/dist/reasoning.js +154 -0
- package/dist/redact.d.ts +18 -0
- package/dist/redact.js +29 -1
- package/dist/transport.d.ts +3 -1
- package/dist/transport.js +21 -1
- package/dist/types.d.ts +112 -2
- package/dist/util.d.ts +22 -0
- package/dist/util.js +59 -0
- package/nugget/VERSION.txt +2 -2
- package/nugget/dist/adapters/engines/anthropic.d.ts +14 -0
- package/nugget/dist/adapters/engines/anthropic.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/anthropic.js +323 -0
- package/nugget/dist/adapters/engines/anthropic.js.map +1 -0
- package/nugget/dist/adapters/engines/base.d.ts +50 -0
- package/nugget/dist/adapters/engines/base.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/base.js +137 -0
- package/nugget/dist/adapters/engines/base.js.map +1 -0
- package/nugget/dist/adapters/engines/google.d.ts +24 -0
- package/nugget/dist/adapters/engines/google.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/google.js +288 -0
- package/nugget/dist/adapters/engines/google.js.map +1 -0
- package/nugget/dist/adapters/engines/ollama.d.ts +11 -0
- package/nugget/dist/adapters/engines/ollama.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/ollama.js +202 -0
- package/nugget/dist/adapters/engines/ollama.js.map +1 -0
- package/nugget/dist/adapters/engines/openaiChat.d.ts +22 -0
- package/nugget/dist/adapters/engines/openaiChat.d.ts.map +1 -0
- package/nugget/dist/adapters/engines/openaiChat.js +308 -0
- package/nugget/dist/adapters/engines/openaiChat.js.map +1 -0
- package/nugget/dist/adapters/index.d.ts +5 -0
- package/nugget/dist/adapters/index.d.ts.map +1 -0
- package/nugget/dist/adapters/index.js +17 -0
- package/nugget/dist/adapters/index.js.map +1 -0
- package/nugget/dist/adapters/profiles.d.ts +62 -0
- package/nugget/dist/adapters/profiles.d.ts.map +1 -0
- package/nugget/dist/adapters/profiles.js +121 -0
- package/nugget/dist/adapters/profiles.js.map +1 -0
- package/nugget/dist/agent/index.d.ts +3 -0
- package/nugget/dist/agent/index.d.ts.map +1 -0
- package/nugget/dist/agent/index.js +3 -0
- package/nugget/dist/agent/index.js.map +1 -0
- package/nugget/dist/agent/loop.d.ts +114 -0
- package/nugget/dist/agent/loop.d.ts.map +1 -0
- package/nugget/dist/agent/loop.js +371 -0
- package/nugget/dist/agent/loop.js.map +1 -0
- package/nugget/dist/agent/tools.d.ts +29 -0
- package/nugget/dist/agent/tools.d.ts.map +1 -0
- package/nugget/dist/agent/tools.js +48 -0
- package/nugget/dist/agent/tools.js.map +1 -0
- package/nugget/dist/cjs/adapters/engines/anthropic.js +326 -0
- package/nugget/dist/cjs/adapters/engines/base.js +147 -0
- package/nugget/dist/cjs/adapters/engines/google.js +291 -0
- package/nugget/dist/cjs/adapters/engines/ollama.js +205 -0
- package/nugget/dist/cjs/adapters/engines/openaiChat.js +312 -0
- package/nugget/dist/cjs/adapters/index.js +22 -0
- package/nugget/dist/cjs/adapters/profiles.js +125 -0
- package/nugget/dist/cjs/agent/index.js +18 -0
- package/nugget/dist/cjs/agent/loop.js +373 -0
- package/nugget/dist/cjs/agent/tools.js +51 -0
- package/nugget/dist/cjs/connect.js +27 -0
- package/nugget/dist/cjs/errors.js +110 -0
- package/nugget/dist/cjs/handler.js +586 -0
- package/nugget/dist/cjs/index.js +28 -0
- package/nugget/dist/cjs/json.js +121 -0
- package/nugget/dist/cjs/keys.js +81 -0
- package/nugget/dist/cjs/package.json +3 -0
- package/nugget/dist/cjs/policy.js +42 -0
- package/nugget/dist/cjs/reasoning.js +159 -0
- package/nugget/dist/cjs/redact.js +78 -0
- package/nugget/dist/cjs/tokens.js +22 -0
- package/nugget/dist/cjs/transport.js +172 -0
- package/nugget/dist/cjs/types.js +6 -0
- package/nugget/dist/cjs/util.js +126 -0
- package/nugget/dist/connect.d.ts +31 -0
- package/nugget/dist/connect.d.ts.map +1 -0
- package/nugget/dist/connect.js +25 -0
- package/nugget/dist/connect.js.map +1 -0
- package/nugget/dist/errors.d.ts +22 -0
- package/nugget/dist/errors.d.ts.map +1 -0
- package/nugget/dist/errors.js +104 -0
- package/nugget/dist/errors.js.map +1 -0
- package/nugget/dist/handler.d.ts +114 -0
- package/nugget/dist/handler.d.ts.map +1 -0
- package/nugget/dist/handler.js +582 -0
- package/nugget/dist/handler.js.map +1 -0
- package/nugget/dist/index.d.ts +13 -0
- package/nugget/dist/index.d.ts.map +1 -0
- package/nugget/dist/index.js +13 -0
- package/nugget/dist/index.js.map +1 -0
- package/nugget/dist/json.d.ts +7 -0
- package/nugget/dist/json.d.ts.map +1 -0
- package/nugget/dist/json.js +114 -0
- package/nugget/dist/json.js.map +1 -0
- package/nugget/dist/keys.d.ts +7 -0
- package/nugget/dist/keys.d.ts.map +1 -0
- package/nugget/dist/keys.js +75 -0
- package/nugget/dist/keys.js.map +1 -0
- package/nugget/dist/policy.d.ts +6 -0
- package/nugget/dist/policy.d.ts.map +1 -0
- package/nugget/dist/policy.js +37 -0
- package/nugget/dist/policy.js.map +1 -0
- package/nugget/dist/reasoning.d.ts +45 -0
- package/nugget/dist/reasoning.d.ts.map +1 -0
- package/nugget/dist/reasoning.js +154 -0
- package/nugget/dist/reasoning.js.map +1 -0
- package/nugget/dist/redact.d.ts +26 -0
- package/nugget/dist/redact.d.ts.map +1 -0
- package/nugget/dist/redact.js +74 -0
- package/nugget/dist/redact.js.map +1 -0
- package/nugget/dist/tokens.d.ts +5 -0
- package/nugget/dist/tokens.d.ts.map +1 -0
- package/nugget/dist/tokens.js +18 -0
- package/nugget/dist/tokens.js.map +1 -0
- package/nugget/dist/transport.d.ts +30 -0
- package/nugget/dist/transport.d.ts.map +1 -0
- package/nugget/dist/transport.js +165 -0
- package/nugget/dist/transport.js.map +1 -0
- package/nugget/dist/types.d.ts +301 -0
- package/nugget/dist/types.d.ts.map +1 -0
- package/nugget/dist/types.js +4 -0
- package/nugget/dist/types.js.map +1 -0
- package/nugget/dist/util.d.ts +31 -0
- package/nugget/dist/util.d.ts.map +1 -0
- package/nugget/dist/util.js +114 -0
- package/nugget/dist/util.js.map +1 -0
- package/nugget/src/adapters/engines/anthropic.ts +78 -37
- package/nugget/src/adapters/engines/base.ts +50 -7
- package/nugget/src/adapters/engines/google.ts +79 -29
- package/nugget/src/adapters/engines/ollama.ts +56 -17
- package/nugget/src/adapters/engines/openaiChat.ts +104 -30
- package/nugget/src/adapters/profiles.ts +53 -3
- package/nugget/src/agent/loop.ts +156 -13
- package/nugget/src/errors.ts +25 -1
- package/nugget/src/handler.ts +308 -59
- package/nugget/src/index.ts +1 -0
- package/nugget/src/reasoning.ts +174 -0
- package/nugget/src/redact.ts +32 -1
- package/nugget/src/transport.ts +20 -1
- package/nugget/src/types.ts +113 -1
- package/nugget/src/util.ts +64 -0
- package/package.json +18 -5
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import type { AIHandler } from '../handler.js';
|
|
2
|
+
import type { AIErrorKind, ChatMessage, Connection, ReasoningEffort, StreamEvent, ToolCall, Usage } from '../types.js';
|
|
3
|
+
import type { ToolSpec } from './tools.js';
|
|
4
|
+
export interface AgentOptions {
|
|
5
|
+
handler: AIHandler;
|
|
6
|
+
connection: Connection;
|
|
7
|
+
model: string;
|
|
8
|
+
tools: ToolSpec[];
|
|
9
|
+
messages: ChatMessage[];
|
|
10
|
+
/**
|
|
11
|
+
* `native` sends `tools` on the request; `promptJson` describes tools in a
|
|
12
|
+
* system message and parses a JSON directive back out of plain text.
|
|
13
|
+
* `auto` (the default) picks per-call from the connection's provider
|
|
14
|
+
* capability profile (`profileFor(provider).capabilities.nativeTools`) —
|
|
15
|
+
* hosted providers with reliable tool-calling get `native`, local runtimes
|
|
16
|
+
* (Ollama, llama.cpp, LM Studio, vLLM) and the `openai-compat` escape hatch
|
|
17
|
+
* default to `promptJson` since native tool support there is model-
|
|
18
|
+
* dependent, not protocol-guaranteed.
|
|
19
|
+
*/
|
|
20
|
+
toolMode?: 'native' | 'promptJson' | 'auto';
|
|
21
|
+
/**
|
|
22
|
+
* Discovered capabilities of the specific model (e.g. Ollama `/api/show`
|
|
23
|
+
* `["tools"]`). When `toolMode` is `auto`, a `tools` capability here upgrades a
|
|
24
|
+
* local model to `native` tool-calling instead of the profile's conservative
|
|
25
|
+
* `promptJson` default — so a capable local model isn't forced onto the fallback.
|
|
26
|
+
*/
|
|
27
|
+
modelCapabilities?: string[];
|
|
28
|
+
/** Sampler/decoding options forwarded to every model turn (parity with a plain chat call). */
|
|
29
|
+
temperature?: number;
|
|
30
|
+
maxTokens?: number;
|
|
31
|
+
topP?: number;
|
|
32
|
+
stopSequences?: string[];
|
|
33
|
+
/** Reasoning effort forwarded to every turn — see {@link ChatRequest.reasoningEffort}. */
|
|
34
|
+
reasoningEffort?: ReasoningEffort;
|
|
35
|
+
/** Provider-native passthrough forwarded to every turn — see {@link ChatRequest.providerOptions}. */
|
|
36
|
+
providerOptions?: Record<string, unknown>;
|
|
37
|
+
budget?: {
|
|
38
|
+
maxSteps?: number;
|
|
39
|
+
maxTokens?: number;
|
|
40
|
+
deadlineMs?: number;
|
|
41
|
+
};
|
|
42
|
+
approval?: ApprovalGate;
|
|
43
|
+
/**
|
|
44
|
+
* Which tools require the approval gate. `sideEffectsOnly` (default) gates only
|
|
45
|
+
* tools declared `sideEffects: true`; `all` gates every tool — so `tool_denied`
|
|
46
|
+
* is reachable without marking each tool, and a consumer can require approval
|
|
47
|
+
* for a whole run in one place.
|
|
48
|
+
*/
|
|
49
|
+
approvalMode?: 'sideEffectsOnly' | 'all';
|
|
50
|
+
/**
|
|
51
|
+
* Bounds and framing applied to each tool result before it re-enters the
|
|
52
|
+
* model's context. `maxChars` truncates oversized results (with a notice) so a
|
|
53
|
+
* single large return can't blow the next turn's window; `wrapUntrusted` fences
|
|
54
|
+
* the result in an `<untrusted_tool_output>` envelope. Both are opt-in.
|
|
55
|
+
*/
|
|
56
|
+
toolResult?: {
|
|
57
|
+
maxChars?: number;
|
|
58
|
+
wrapUntrusted?: boolean;
|
|
59
|
+
};
|
|
60
|
+
onEvent?: (e: AgentEvent) => void;
|
|
61
|
+
signal?: AbortSignal;
|
|
62
|
+
metadata?: Record<string, unknown>;
|
|
63
|
+
}
|
|
64
|
+
export type ApprovalGate = (req: {
|
|
65
|
+
call: ToolCall;
|
|
66
|
+
tool: ToolSpec;
|
|
67
|
+
step: number;
|
|
68
|
+
}) => Promise<'allow' | 'deny' | {
|
|
69
|
+
modifiedArguments: unknown;
|
|
70
|
+
}>;
|
|
71
|
+
export type AgentEvent = StreamEvent | {
|
|
72
|
+
type: 'step_start';
|
|
73
|
+
step: number;
|
|
74
|
+
} | {
|
|
75
|
+
type: 'tool_mode';
|
|
76
|
+
mode: 'native' | 'promptJson';
|
|
77
|
+
} | {
|
|
78
|
+
type: 'tool_start';
|
|
79
|
+
step: number;
|
|
80
|
+
call: ToolCall;
|
|
81
|
+
} | {
|
|
82
|
+
type: 'tool_result';
|
|
83
|
+
step: number;
|
|
84
|
+
call: ToolCall;
|
|
85
|
+
result: unknown;
|
|
86
|
+
isError: boolean;
|
|
87
|
+
} | {
|
|
88
|
+
type: 'tool_denied';
|
|
89
|
+
step: number;
|
|
90
|
+
call: ToolCall;
|
|
91
|
+
reason: string;
|
|
92
|
+
} | {
|
|
93
|
+
type: 'agent_done';
|
|
94
|
+
result: AgentResult;
|
|
95
|
+
};
|
|
96
|
+
export interface AgentResult {
|
|
97
|
+
finalText: string;
|
|
98
|
+
messages: ChatMessage[];
|
|
99
|
+
usage: Usage;
|
|
100
|
+
steps: number;
|
|
101
|
+
stopReason: 'finished' | 'max_steps' | 'budget' | 'deadline' | 'canceled' | 'error';
|
|
102
|
+
/**
|
|
103
|
+
* Populated when `stopReason` is `error`: the failure that ended the run, so
|
|
104
|
+
* the caller can see what went wrong without replaying the event stream.
|
|
105
|
+
*/
|
|
106
|
+
error?: {
|
|
107
|
+
kind: AIErrorKind;
|
|
108
|
+
message: string;
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
export declare function runAgent(opts: AgentOptions): AsyncIterable<AgentEvent> & {
|
|
112
|
+
result: Promise<AgentResult>;
|
|
113
|
+
};
|
|
114
|
+
//# sourceMappingURL=loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
import { profileFor } from '../adapters/profiles.js';
|
|
2
|
+
import { AIError } from '../errors.js';
|
|
3
|
+
import { extractJson } from '../json.js';
|
|
4
|
+
import { mergeUsage } from '../tokens.js';
|
|
5
|
+
import { asRecord, sleep } from '../util.js';
|
|
6
|
+
import { validateToolArgs } from './tools.js';
|
|
7
|
+
export function runAgent(opts) {
|
|
8
|
+
let resolveResult;
|
|
9
|
+
const result = new Promise((resolve) => {
|
|
10
|
+
resolveResult = resolve;
|
|
11
|
+
});
|
|
12
|
+
const iterable = run(opts, resolveResult);
|
|
13
|
+
return Object.assign(iterable, { result });
|
|
14
|
+
}
|
|
15
|
+
async function* run(opts, resolveResult) {
|
|
16
|
+
const messages = [...opts.messages];
|
|
17
|
+
const toolMode = resolveToolMode(opts);
|
|
18
|
+
const maxSteps = opts.budget?.maxSteps ?? 8;
|
|
19
|
+
const agentSignal = createAgentSignal(opts.signal, opts.budget?.deadlineMs);
|
|
20
|
+
let usage;
|
|
21
|
+
let finalText = '';
|
|
22
|
+
let step = 0;
|
|
23
|
+
let settled = false;
|
|
24
|
+
// Disclose the resolved tool protocol once up front (a silent promptJson
|
|
25
|
+
// fallback was the friction behind FR‑2).
|
|
26
|
+
yield emit(opts, { type: 'tool_mode', mode: toolMode });
|
|
27
|
+
try {
|
|
28
|
+
while (step < maxSteps) {
|
|
29
|
+
step += 1;
|
|
30
|
+
if (agentSignal.signal?.aborted)
|
|
31
|
+
return yield* yieldDone(agentSignal.timedOut() ? 'deadline' : 'canceled');
|
|
32
|
+
yield emit(opts, { type: 'step_start', step });
|
|
33
|
+
const calls = [];
|
|
34
|
+
let stepText = '';
|
|
35
|
+
let streamFailure;
|
|
36
|
+
// In promptJson mode a tool directive must not leak into the visible
|
|
37
|
+
// stream, so directive-looking text is withheld from `delta` events (still
|
|
38
|
+
// accumulated in `stepText` for parsing). Prose streams normally.
|
|
39
|
+
const filter = toolMode === 'promptJson' ? new PromptJsonDeltaFilter() : undefined;
|
|
40
|
+
const requestMessages = toolMode === 'promptJson' ? withPromptJsonInstruction(messages, opts.tools) : messages;
|
|
41
|
+
for await (const event of opts.handler.stream(opts.connection, {
|
|
42
|
+
model: opts.model,
|
|
43
|
+
messages: requestMessages,
|
|
44
|
+
tools: toolMode === 'promptJson' ? undefined : opts.tools,
|
|
45
|
+
temperature: opts.temperature,
|
|
46
|
+
maxTokens: opts.maxTokens,
|
|
47
|
+
topP: opts.topP,
|
|
48
|
+
stopSequences: opts.stopSequences,
|
|
49
|
+
reasoningEffort: opts.reasoningEffort,
|
|
50
|
+
providerOptions: opts.providerOptions,
|
|
51
|
+
signal: agentSignal.signal,
|
|
52
|
+
metadata: { ...opts.metadata, agentStep: step },
|
|
53
|
+
})) {
|
|
54
|
+
if (event.type === 'delta') {
|
|
55
|
+
stepText += event.text;
|
|
56
|
+
if (filter) {
|
|
57
|
+
const visible = filter.push(event.text);
|
|
58
|
+
if (visible)
|
|
59
|
+
yield emit(opts, { type: 'delta', text: visible });
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (event.type === 'tool_call')
|
|
64
|
+
calls.push(event.call);
|
|
65
|
+
if (event.type === 'error')
|
|
66
|
+
streamFailure = event.error;
|
|
67
|
+
if (event.type === 'done') {
|
|
68
|
+
usage = usage ? mergeUsage(usage, event.result.usage) : event.result.usage;
|
|
69
|
+
if (toolMode === 'promptJson' && calls.length === 0)
|
|
70
|
+
calls.push(...callsFromPromptJson(stepText));
|
|
71
|
+
}
|
|
72
|
+
yield emit(opts, event);
|
|
73
|
+
}
|
|
74
|
+
// If withheld text turned out not to be a real directive, flush it so the
|
|
75
|
+
// user still sees the model's answer.
|
|
76
|
+
if (filter && calls.length === 0) {
|
|
77
|
+
const flushed = filter.flush();
|
|
78
|
+
if (flushed)
|
|
79
|
+
yield emit(opts, { type: 'delta', text: flushed });
|
|
80
|
+
}
|
|
81
|
+
// A handler-level failure (auth, policy, cancel, exhausted retries) must
|
|
82
|
+
// stop the loop honestly rather than looking like an empty completion.
|
|
83
|
+
if (streamFailure)
|
|
84
|
+
return yield* yieldDone(agentSignal.timedOut() ? 'deadline' : streamFailure.kind === 'canceled' ? 'canceled' : 'error', errorInfo(streamFailure));
|
|
85
|
+
finalText = stepText;
|
|
86
|
+
messages.push(toolMode === 'promptJson'
|
|
87
|
+
? { role: 'assistant', content: stepText }
|
|
88
|
+
: { role: 'assistant', content: stepText, toolCalls: calls.length ? calls : undefined });
|
|
89
|
+
if (calls.length === 0)
|
|
90
|
+
return yield* yieldDone('finished');
|
|
91
|
+
for (const call of calls) {
|
|
92
|
+
if (agentSignal.signal?.aborted)
|
|
93
|
+
return yield* yieldDone(agentSignal.timedOut() ? 'deadline' : 'canceled');
|
|
94
|
+
const tool = opts.tools.find((candidate) => candidate.name === call.name);
|
|
95
|
+
if (!tool) {
|
|
96
|
+
yield* appendToolError(opts, messages, step, call, `Unknown tool: ${call.name}`);
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
const validation = validateToolArgs(tool, call);
|
|
100
|
+
if (!validation.ok) {
|
|
101
|
+
yield* appendToolError(opts, messages, step, call, validation.message);
|
|
102
|
+
continue;
|
|
103
|
+
}
|
|
104
|
+
let args = validation.args;
|
|
105
|
+
const requiresApproval = tool.sideEffects || opts.approvalMode === 'all';
|
|
106
|
+
if (requiresApproval) {
|
|
107
|
+
if (!opts.approval) {
|
|
108
|
+
yield* appendToolDenied(opts, messages, step, call, 'No approval gate configured');
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
const approval = await opts.approval({ call, tool, step });
|
|
112
|
+
if (agentSignal.signal?.aborted)
|
|
113
|
+
return yield* yieldDone(agentSignal.timedOut() ? 'deadline' : 'canceled');
|
|
114
|
+
if (approval === 'deny') {
|
|
115
|
+
yield* appendToolDenied(opts, messages, step, call, 'Denied by approval gate');
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
if (approval !== 'allow') {
|
|
119
|
+
const modified = validateToolArgs(tool, { ...call, arguments: approval.modifiedArguments });
|
|
120
|
+
if (!modified.ok) {
|
|
121
|
+
yield* appendToolError(opts, messages, step, call, modified.message);
|
|
122
|
+
continue;
|
|
123
|
+
}
|
|
124
|
+
args = modified.args;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
yield emit(opts, { type: 'tool_start', step, call });
|
|
128
|
+
let executed;
|
|
129
|
+
try {
|
|
130
|
+
const result = await tool.execute(args, {
|
|
131
|
+
signal: agentSignal.signal ?? new AbortController().signal,
|
|
132
|
+
callId: call.id,
|
|
133
|
+
step,
|
|
134
|
+
metadata: opts.metadata,
|
|
135
|
+
});
|
|
136
|
+
executed = { ok: true, result };
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
executed = { ok: false, message: error instanceof Error ? error.message : 'Tool failed' };
|
|
140
|
+
}
|
|
141
|
+
if (!executed.ok) {
|
|
142
|
+
yield* appendToolError(opts, messages, step, call, executed.message);
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
try {
|
|
146
|
+
// Guard against a tool returning `undefined` (JSON.stringify(undefined)
|
|
147
|
+
// is the value `undefined`, not a string) — an unguarded value here
|
|
148
|
+
// used to crash the next step's message mapper and kill the whole run.
|
|
149
|
+
const serialized = JSON.stringify(executed.result) ?? 'null';
|
|
150
|
+
messages.push({ role: 'tool', toolCallId: call.id, name: call.name, content: formatToolResult(serialized, opts.toolResult) });
|
|
151
|
+
// A tool that returns a structured `{ ok: false, ... }` is a recoverable
|
|
152
|
+
// error the model should react to — surface it as an error result.
|
|
153
|
+
const record = asRecord(executed.result);
|
|
154
|
+
const isError = record?.ok === false;
|
|
155
|
+
yield emit(opts, { type: 'tool_result', step, call, result: executed.result, isError });
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
const message = error instanceof Error ? error.message : 'Tool result was not serializable';
|
|
159
|
+
yield* appendToolError(opts, messages, step, call, message);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
const totalTokens = (usage?.inputTokens ?? 0) + (usage?.outputTokens ?? 0);
|
|
163
|
+
if (opts.budget?.maxTokens && totalTokens > opts.budget.maxTokens)
|
|
164
|
+
return yield* yieldDone('budget');
|
|
165
|
+
await sleep(0, agentSignal.signal);
|
|
166
|
+
}
|
|
167
|
+
return yield* yieldDone('max_steps');
|
|
168
|
+
}
|
|
169
|
+
catch (error) {
|
|
170
|
+
const stopReason = agentSignal.timedOut() ? 'deadline' : (agentSignal.signal?.aborted || (error instanceof AIError && error.kind === 'canceled')) ? 'canceled' : 'error';
|
|
171
|
+
const result = makeResult(finalText, messages, usage ?? { estimated: true }, step, stopReason, stopReason === 'error' ? errorInfo(error) : undefined);
|
|
172
|
+
settled = true;
|
|
173
|
+
resolveResult(result);
|
|
174
|
+
yield emit(opts, { type: 'agent_done', result });
|
|
175
|
+
}
|
|
176
|
+
finally {
|
|
177
|
+
agentSignal.dispose();
|
|
178
|
+
if (!settled) {
|
|
179
|
+
const result = makeResult(finalText, messages, usage ?? { estimated: true }, step, 'canceled');
|
|
180
|
+
resolveResult(result);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
function* yieldDone(stopReason, error) {
|
|
184
|
+
const result = makeResult(finalText, messages, usage ?? { estimated: true }, step, stopReason, error);
|
|
185
|
+
settled = true;
|
|
186
|
+
resolveResult(result);
|
|
187
|
+
yield emit(opts, { type: 'agent_done', result });
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
function emit(opts, event) {
|
|
191
|
+
opts.onEvent?.(event);
|
|
192
|
+
return event;
|
|
193
|
+
}
|
|
194
|
+
function makeResult(finalText, messages, usage, steps, stopReason, error) {
|
|
195
|
+
return error ? { finalText, messages, usage, steps, stopReason, error } : { finalText, messages, usage, steps, stopReason };
|
|
196
|
+
}
|
|
197
|
+
function errorInfo(error) {
|
|
198
|
+
if (error instanceof AIError)
|
|
199
|
+
return { kind: error.kind, message: error.message };
|
|
200
|
+
return { kind: 'tool_error', message: error instanceof Error ? error.message : 'Agent run failed' };
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Applies the optional size cap and untrusted-content framing to a serialized
|
|
204
|
+
* tool result before it re-enters the model's context.
|
|
205
|
+
*/
|
|
206
|
+
function formatToolResult(serialized, opts) {
|
|
207
|
+
let out = serialized;
|
|
208
|
+
const max = opts?.maxChars;
|
|
209
|
+
if (max !== undefined && out.length > max) {
|
|
210
|
+
out = `${out.slice(0, max)}\n…[truncated ${out.length - max} chars]`;
|
|
211
|
+
}
|
|
212
|
+
if (opts?.wrapUntrusted) {
|
|
213
|
+
out = `<untrusted_tool_output>\n${out}\n</untrusted_tool_output>`;
|
|
214
|
+
}
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Withholds a promptJson tool directive from the visible `delta` stream. Once
|
|
219
|
+
* the leading non-whitespace character is known: a `{`, `[`, or fence marks a
|
|
220
|
+
* directive candidate whose text is buffered (never streamed); anything else is
|
|
221
|
+
* prose that streams through untouched. `flush()` returns any buffered text when
|
|
222
|
+
* the stream ended without yielding a parsed directive.
|
|
223
|
+
*/
|
|
224
|
+
class PromptJsonDeltaFilter {
|
|
225
|
+
decided = false;
|
|
226
|
+
withhold = false;
|
|
227
|
+
buffer = '';
|
|
228
|
+
push(text) {
|
|
229
|
+
if (!this.decided) {
|
|
230
|
+
this.buffer += text;
|
|
231
|
+
const lead = this.buffer.replace(/^\s+/, '');
|
|
232
|
+
if (lead.length === 0)
|
|
233
|
+
return '';
|
|
234
|
+
this.decided = true;
|
|
235
|
+
this.withhold = /^[[{`]/.test(lead);
|
|
236
|
+
if (this.withhold)
|
|
237
|
+
return '';
|
|
238
|
+
const flushed = this.buffer;
|
|
239
|
+
this.buffer = '';
|
|
240
|
+
return flushed;
|
|
241
|
+
}
|
|
242
|
+
if (this.withhold) {
|
|
243
|
+
this.buffer += text;
|
|
244
|
+
return '';
|
|
245
|
+
}
|
|
246
|
+
return text;
|
|
247
|
+
}
|
|
248
|
+
flush() {
|
|
249
|
+
if (!this.withhold)
|
|
250
|
+
return '';
|
|
251
|
+
const out = this.buffer;
|
|
252
|
+
this.buffer = '';
|
|
253
|
+
return out;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
function* appendToolError(opts, messages, step, call, message) {
|
|
257
|
+
const result = { error: message };
|
|
258
|
+
messages.push({ role: 'tool', toolCallId: call.id, name: call.name, content: JSON.stringify(result) });
|
|
259
|
+
yield emit(opts, { type: 'tool_result', step, call, result, isError: true });
|
|
260
|
+
}
|
|
261
|
+
function* appendToolDenied(opts, messages, step, call, reason) {
|
|
262
|
+
messages.push({ role: 'tool', toolCallId: call.id, name: call.name, content: JSON.stringify({ denied: true, reason }) });
|
|
263
|
+
yield emit(opts, { type: 'tool_denied', step, call, reason });
|
|
264
|
+
}
|
|
265
|
+
function resolveToolMode(opts) {
|
|
266
|
+
const mode = opts.toolMode ?? 'auto';
|
|
267
|
+
if (mode !== 'auto')
|
|
268
|
+
return mode;
|
|
269
|
+
// A model that actually advertises tool support gets native tool-calling even
|
|
270
|
+
// on a local runtime whose profile is conservatively `nativeTools: false`.
|
|
271
|
+
if (opts.modelCapabilities?.includes('tools'))
|
|
272
|
+
return 'native';
|
|
273
|
+
return profileFor(opts.connection.provider, opts.connection.baseUrl).capabilities.nativeTools ? 'native' : 'promptJson';
|
|
274
|
+
}
|
|
275
|
+
function withPromptJsonInstruction(messages, tools) {
|
|
276
|
+
// Include each tool's parameter schema, not just its description, so the model
|
|
277
|
+
// knows the argument shape instead of guessing it (FR‑3).
|
|
278
|
+
const catalog = tools
|
|
279
|
+
.map((tool) => `- ${tool.name}: ${tool.description}\n parameters: ${JSON.stringify(tool.parameters)}`)
|
|
280
|
+
.join('\n');
|
|
281
|
+
return [
|
|
282
|
+
{
|
|
283
|
+
role: 'system',
|
|
284
|
+
content: `When you need tools, respond only with JSON. For one tool: {"tool":"name","input":{...}}. For several in one turn: {"tools":[{"tool":"name","input":{...}}]}. The "input" object must match the tool's parameters schema. Available tools:\n${catalog}`,
|
|
285
|
+
},
|
|
286
|
+
...messages.map(toPromptJsonMessage),
|
|
287
|
+
];
|
|
288
|
+
}
|
|
289
|
+
function toPromptJsonMessage(message) {
|
|
290
|
+
if (message.role === 'tool') {
|
|
291
|
+
return {
|
|
292
|
+
role: 'user',
|
|
293
|
+
content: `Tool ${message.name ?? message.toolCallId ?? 'unknown'} returned: ${textContent(message.content)}`,
|
|
294
|
+
};
|
|
295
|
+
}
|
|
296
|
+
return {
|
|
297
|
+
role: message.role,
|
|
298
|
+
content: textContent(message.content),
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* Parses a promptJson tool directive into zero or more calls. Accepts the single
|
|
303
|
+
* form ({"tool","input"}), the batched form ({"tools":[...]}), and a bare array
|
|
304
|
+
* of directives, so a promptJson-mode model can request several tools per turn
|
|
305
|
+
* just like native tool-calling can. Malformed entries are skipped, not thrown.
|
|
306
|
+
*/
|
|
307
|
+
function callsFromPromptJson(text) {
|
|
308
|
+
const value = extractJson(text);
|
|
309
|
+
if (!value || typeof value !== 'object')
|
|
310
|
+
return [];
|
|
311
|
+
const entries = Array.isArray(value)
|
|
312
|
+
? value
|
|
313
|
+
: Array.isArray(value.tools)
|
|
314
|
+
? value.tools
|
|
315
|
+
: [value];
|
|
316
|
+
const calls = [];
|
|
317
|
+
for (const entry of entries) {
|
|
318
|
+
if (!entry || typeof entry !== 'object' || Array.isArray(entry))
|
|
319
|
+
continue;
|
|
320
|
+
const record = entry;
|
|
321
|
+
if (typeof record.tool !== 'string')
|
|
322
|
+
continue;
|
|
323
|
+
calls.push({
|
|
324
|
+
id: randomId(),
|
|
325
|
+
name: record.tool,
|
|
326
|
+
arguments: record.input && typeof record.input === 'object' ? record.input : {},
|
|
327
|
+
raw: JSON.stringify(record.input ?? {}),
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
return calls;
|
|
331
|
+
}
|
|
332
|
+
function randomId() {
|
|
333
|
+
return globalThis.crypto?.randomUUID?.() ?? `tool_${Date.now()}_${Math.random().toString(36).slice(2)}`;
|
|
334
|
+
}
|
|
335
|
+
function textContent(content) {
|
|
336
|
+
if (typeof content === 'string')
|
|
337
|
+
return content;
|
|
338
|
+
if (!content)
|
|
339
|
+
return '';
|
|
340
|
+
return content.filter((part) => part.type === 'text').map((part) => part.text ?? '').join('\n');
|
|
341
|
+
}
|
|
342
|
+
function createAgentSignal(signal, deadlineMs) {
|
|
343
|
+
if (!signal && deadlineMs === undefined)
|
|
344
|
+
return { signal: undefined, timedOut: () => false, dispose: () => undefined };
|
|
345
|
+
const controller = new AbortController();
|
|
346
|
+
let didTimeOut = false;
|
|
347
|
+
let timer;
|
|
348
|
+
const onAbort = () => controller.abort(signal?.reason);
|
|
349
|
+
if (signal) {
|
|
350
|
+
if (signal.aborted)
|
|
351
|
+
onAbort();
|
|
352
|
+
else
|
|
353
|
+
signal.addEventListener('abort', onAbort, { once: true });
|
|
354
|
+
}
|
|
355
|
+
if (deadlineMs !== undefined) {
|
|
356
|
+
timer = setTimeout(() => {
|
|
357
|
+
didTimeOut = true;
|
|
358
|
+
controller.abort(new AIError(`Agent deadline exceeded after ${deadlineMs}ms`, { kind: 'budget_exceeded', retryable: false }));
|
|
359
|
+
}, deadlineMs);
|
|
360
|
+
}
|
|
361
|
+
return {
|
|
362
|
+
signal: controller.signal,
|
|
363
|
+
timedOut: () => didTimeOut,
|
|
364
|
+
dispose() {
|
|
365
|
+
if (timer)
|
|
366
|
+
clearTimeout(timer);
|
|
367
|
+
signal?.removeEventListener('abort', onAbort);
|
|
368
|
+
},
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
//# sourceMappingURL=loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loop.js","sourceRoot":"","sources":["../../src/agent/loop.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ToolCall, ToolSchema } from '../types.js';
|
|
2
|
+
export interface ToolSpec<A = unknown, R = unknown> extends ToolSchema {
|
|
3
|
+
sideEffects?: boolean;
|
|
4
|
+
execute(args: A, ctx: ToolContext): Promise<R> | R;
|
|
5
|
+
}
|
|
6
|
+
export interface ToolContext {
|
|
7
|
+
signal: AbortSignal;
|
|
8
|
+
callId: string;
|
|
9
|
+
step: number;
|
|
10
|
+
metadata?: Record<string, unknown>;
|
|
11
|
+
}
|
|
12
|
+
export declare function defineTool<A, R>(spec: ToolSpec<A, R>): ToolSpec<A, R>;
|
|
13
|
+
/**
|
|
14
|
+
* Light validation only: object-ness, `required` presence, and top-level
|
|
15
|
+
* `properties[key].type` against JS typeof/Array.isArray/Number.isInteger.
|
|
16
|
+
* It does not implement full JSON Schema — no `enum`, nested `properties`,
|
|
17
|
+
* `oneOf`/`anyOf`, numeric bounds, string `pattern`, array `items` schemas, or
|
|
18
|
+
* `additionalProperties`. That's intentional for a zero-dependency nugget; a
|
|
19
|
+
* caller that needs stricter guarantees should validate `args` again inside
|
|
20
|
+
* `tool.execute` with its own schema library.
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateToolArgs(tool: ToolSpec, call: ToolCall): {
|
|
23
|
+
ok: true;
|
|
24
|
+
args: unknown;
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
message: string;
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/agent/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAExD,MAAM,WAAW,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,OAAO,CAAE,SAAQ,UAAU;IACpE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,WAAW,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAErE;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAmB7H"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export function defineTool(spec) {
|
|
2
|
+
return spec;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Light validation only: object-ness, `required` presence, and top-level
|
|
6
|
+
* `properties[key].type` against JS typeof/Array.isArray/Number.isInteger.
|
|
7
|
+
* It does not implement full JSON Schema — no `enum`, nested `properties`,
|
|
8
|
+
* `oneOf`/`anyOf`, numeric bounds, string `pattern`, array `items` schemas, or
|
|
9
|
+
* `additionalProperties`. That's intentional for a zero-dependency nugget; a
|
|
10
|
+
* caller that needs stricter guarantees should validate `args` again inside
|
|
11
|
+
* `tool.execute` with its own schema library.
|
|
12
|
+
*/
|
|
13
|
+
export function validateToolArgs(tool, call) {
|
|
14
|
+
const schema = tool.parameters;
|
|
15
|
+
if (schema.type && schema.type !== 'object')
|
|
16
|
+
return { ok: false, message: `Tool ${tool.name} parameters must be an object schema` };
|
|
17
|
+
if (typeof call.arguments !== 'object' || call.arguments === null || Array.isArray(call.arguments)) {
|
|
18
|
+
return { ok: false, message: `Tool ${tool.name} expected object arguments` };
|
|
19
|
+
}
|
|
20
|
+
const args = call.arguments;
|
|
21
|
+
const required = Array.isArray(schema.required) ? schema.required.filter((key) => typeof key === 'string') : [];
|
|
22
|
+
for (const key of required) {
|
|
23
|
+
if (!(key in args))
|
|
24
|
+
return { ok: false, message: `Tool ${tool.name} missing required argument: ${key}` };
|
|
25
|
+
}
|
|
26
|
+
const properties = schema.properties && typeof schema.properties === 'object' ? schema.properties : {};
|
|
27
|
+
for (const [key, spec] of Object.entries(properties)) {
|
|
28
|
+
if (!(key in args) || spec.type === undefined)
|
|
29
|
+
continue;
|
|
30
|
+
const value = args[key];
|
|
31
|
+
const ok = matchesType(value, spec.type);
|
|
32
|
+
if (!ok)
|
|
33
|
+
return { ok: false, message: `Tool ${tool.name} argument ${key} must be ${spec.type}` };
|
|
34
|
+
}
|
|
35
|
+
return { ok: true, args };
|
|
36
|
+
}
|
|
37
|
+
function matchesType(value, type) {
|
|
38
|
+
if (type === 'array')
|
|
39
|
+
return Array.isArray(value);
|
|
40
|
+
if (type === 'integer')
|
|
41
|
+
return typeof value === 'number' && Number.isInteger(value);
|
|
42
|
+
if (type === 'null')
|
|
43
|
+
return value === null;
|
|
44
|
+
if (type === 'object')
|
|
45
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
46
|
+
return typeof value === type;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/agent/tools.ts"],"names":[],"mappings":"AAcA,MAAM,UAAU,UAAU,CAAO,IAAoB;IACnD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAc,EAAE,IAAc;IAC7D,MAAM,MAAM,GAAG,IAAI,CAAC,UAA0E,CAAC;IAC/F,IAAI,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,sCAAsC,EAAE,CAAC;IACpI,IAAI,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,IAAI,IAAI,CAAC,SAAS,KAAK,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;QACnG,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,4BAA4B,EAAE,CAAC;IAC/E,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAoC,CAAC;IACvD,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG,EAAiB,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/H,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,+BAA+B,GAAG,EAAE,EAAE,CAAC;IAC3G,CAAC;IACD,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,IAAI,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,UAA+C,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5I,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QACrD,IAAI,CAAC,CAAC,GAAG,IAAI,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,SAAS;QACxD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC;QACxB,MAAM,EAAE,GAAG,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,IAAI,CAAC,IAAI,aAAa,GAAG,YAAY,IAAI,CAAC,IAAI,EAAE,EAAE,CAAC;IACnG,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,SAAS,WAAW,CAAC,KAAc,EAAE,IAAY;IAC/C,IAAI,IAAI,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IAClD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IACpF,IAAI,IAAI,KAAK,MAAM;QAAE,OAAO,KAAK,KAAK,IAAI,CAAC;IAC3C,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;IACnG,OAAO,OAAO,KAAK,KAAK,IAAI,CAAC;AAC/B,CAAC"}
|