@loopingai/core 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/LICENSE +674 -0
- package/README.md +279 -0
- package/dist/a2a/agent-stub.d.ts +61 -0
- package/dist/a2a/agent-stub.d.ts.map +1 -0
- package/dist/a2a/agent-stub.js +2 -0
- package/dist/a2a/agent-stub.js.map +1 -0
- package/dist/a2a/card.d.ts +119 -0
- package/dist/a2a/card.d.ts.map +1 -0
- package/dist/a2a/card.js +115 -0
- package/dist/a2a/card.js.map +1 -0
- package/dist/a2a/context.d.ts +14 -0
- package/dist/a2a/context.d.ts.map +1 -0
- package/dist/a2a/context.js +55 -0
- package/dist/a2a/context.js.map +1 -0
- package/dist/a2a/executor.d.ts +85 -0
- package/dist/a2a/executor.d.ts.map +1 -0
- package/dist/a2a/executor.js +107 -0
- package/dist/a2a/executor.js.map +1 -0
- package/dist/a2a/index.d.ts +18 -0
- package/dist/a2a/index.d.ts.map +1 -0
- package/dist/a2a/index.js +17 -0
- package/dist/a2a/index.js.map +1 -0
- package/dist/a2a/notify.d.ts +75 -0
- package/dist/a2a/notify.d.ts.map +1 -0
- package/dist/a2a/notify.js +161 -0
- package/dist/a2a/notify.js.map +1 -0
- package/dist/a2a/parts.d.ts +46 -0
- package/dist/a2a/parts.d.ts.map +1 -0
- package/dist/a2a/parts.js +95 -0
- package/dist/a2a/parts.js.map +1 -0
- package/dist/a2a/task-store.d.ts +45 -0
- package/dist/a2a/task-store.d.ts.map +1 -0
- package/dist/a2a/task-store.js +100 -0
- package/dist/a2a/task-store.js.map +1 -0
- package/dist/a2a/task.d.ts +86 -0
- package/dist/a2a/task.d.ts.map +1 -0
- package/dist/a2a/task.js +16 -0
- package/dist/a2a/task.js.map +1 -0
- package/dist/a2a/verify.d.ts +64 -0
- package/dist/a2a/verify.d.ts.map +1 -0
- package/dist/a2a/verify.js +122 -0
- package/dist/a2a/verify.js.map +1 -0
- package/dist/agent/budget.d.ts +47 -0
- package/dist/agent/budget.d.ts.map +1 -0
- package/dist/agent/budget.js +43 -0
- package/dist/agent/budget.js.map +1 -0
- package/dist/agent/control.d.ts +110 -0
- package/dist/agent/control.d.ts.map +1 -0
- package/dist/agent/control.js +115 -0
- package/dist/agent/control.js.map +1 -0
- package/dist/agent/final-reply.d.ts +49 -0
- package/dist/agent/final-reply.d.ts.map +1 -0
- package/dist/agent/final-reply.js +52 -0
- package/dist/agent/final-reply.js.map +1 -0
- package/dist/agent/history.d.ts +83 -0
- package/dist/agent/history.d.ts.map +1 -0
- package/dist/agent/history.js +117 -0
- package/dist/agent/history.js.map +1 -0
- package/dist/agent/index.d.ts +17 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +17 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/inference.d.ts +52 -0
- package/dist/agent/inference.d.ts.map +1 -0
- package/dist/agent/inference.js +79 -0
- package/dist/agent/inference.js.map +1 -0
- package/dist/agent/model.d.ts +75 -0
- package/dist/agent/model.d.ts.map +1 -0
- package/dist/agent/model.js +62 -0
- package/dist/agent/model.js.map +1 -0
- package/dist/agent/session.d.ts +92 -0
- package/dist/agent/session.d.ts.map +1 -0
- package/dist/agent/session.js +80 -0
- package/dist/agent/session.js.map +1 -0
- package/dist/config.d.ts +159 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +92 -0
- package/dist/config.js.map +1 -0
- package/dist/contract/index.d.ts +10 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +9 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/plugin.d.ts +163 -0
- package/dist/contract/plugin.d.ts.map +1 -0
- package/dist/contract/plugin.js +39 -0
- package/dist/contract/plugin.js.map +1 -0
- package/dist/contract/recipe.d.ts +170 -0
- package/dist/contract/recipe.d.ts.map +1 -0
- package/dist/contract/recipe.js +2 -0
- package/dist/contract/recipe.js.map +1 -0
- package/dist/contract/validation.d.ts +86 -0
- package/dist/contract/validation.d.ts.map +1 -0
- package/dist/contract/validation.js +76 -0
- package/dist/contract/validation.js.map +1 -0
- package/dist/db/db.d.ts +131 -0
- package/dist/db/db.d.ts.map +1 -0
- package/dist/db/db.js +91 -0
- package/dist/db/db.js.map +1 -0
- package/dist/db/index.d.ts +9 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +9 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/migrations/index.d.ts +21 -0
- package/dist/db/migrations/index.d.ts.map +1 -0
- package/dist/db/migrations/index.js +54 -0
- package/dist/db/migrations/index.js.map +1 -0
- package/dist/db/models/subtasks.d.ts +102 -0
- package/dist/db/models/subtasks.d.ts.map +1 -0
- package/dist/db/models/subtasks.js +285 -0
- package/dist/db/models/subtasks.js.map +1 -0
- package/dist/db/models/tasks.d.ts +92 -0
- package/dist/db/models/tasks.d.ts.map +1 -0
- package/dist/db/models/tasks.js +212 -0
- package/dist/db/models/tasks.js.map +1 -0
- package/dist/db/schema.d.ts +488 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +91 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/env.d.ts +46 -0
- package/dist/env.d.ts.map +1 -0
- package/dist/env.js +40 -0
- package/dist/env.js.map +1 -0
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -0
- package/dist/platform.d.ts +47 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +47 -0
- package/dist/platform.js.map +1 -0
- package/dist/runtime/index.d.ts +86 -0
- package/dist/runtime/index.d.ts.map +1 -0
- package/dist/runtime/index.js +123 -0
- package/dist/runtime/index.js.map +1 -0
- package/dist/runtime/tool-families.d.ts +33 -0
- package/dist/runtime/tool-families.d.ts.map +1 -0
- package/dist/runtime/tool-families.js +62 -0
- package/dist/runtime/tool-families.js.map +1 -0
- package/dist/subagent/fingerprint.d.ts +38 -0
- package/dist/subagent/fingerprint.d.ts.map +1 -0
- package/dist/subagent/fingerprint.js +97 -0
- package/dist/subagent/fingerprint.js.map +1 -0
- package/dist/subagent/index.d.ts +147 -0
- package/dist/subagent/index.d.ts.map +1 -0
- package/dist/subagent/index.js +299 -0
- package/dist/subagent/index.js.map +1 -0
- package/dist/subagent/prompt.d.ts +34 -0
- package/dist/subagent/prompt.d.ts.map +1 -0
- package/dist/subagent/prompt.js +46 -0
- package/dist/subagent/prompt.js.map +1 -0
- package/dist/subagent/run.d.ts +151 -0
- package/dist/subagent/run.d.ts.map +1 -0
- package/dist/subagent/run.js +491 -0
- package/dist/subagent/run.js.map +1 -0
- package/dist/subagent/workspace.d.ts +65 -0
- package/dist/subagent/workspace.d.ts.map +1 -0
- package/dist/subagent/workspace.js +53 -0
- package/dist/subagent/workspace.js.map +1 -0
- package/dist/subtasks/catalog.d.ts +40 -0
- package/dist/subtasks/catalog.d.ts.map +1 -0
- package/dist/subtasks/catalog.js +36 -0
- package/dist/subtasks/catalog.js.map +1 -0
- package/dist/subtasks/decomposition.d.ts +90 -0
- package/dist/subtasks/decomposition.d.ts.map +1 -0
- package/dist/subtasks/decomposition.js +205 -0
- package/dist/subtasks/decomposition.js.map +1 -0
- package/dist/subtasks/delegate.d.ts +77 -0
- package/dist/subtasks/delegate.d.ts.map +1 -0
- package/dist/subtasks/delegate.js +102 -0
- package/dist/subtasks/delegate.js.map +1 -0
- package/dist/subtasks/index.d.ts +11 -0
- package/dist/subtasks/index.d.ts.map +1 -0
- package/dist/subtasks/index.js +11 -0
- package/dist/subtasks/index.js.map +1 -0
- package/dist/subtasks/scheduler.d.ts +49 -0
- package/dist/subtasks/scheduler.d.ts.map +1 -0
- package/dist/subtasks/scheduler.js +48 -0
- package/dist/subtasks/scheduler.js.map +1 -0
- package/dist/subtasks/subtask-types.d.ts +100 -0
- package/dist/subtasks/subtask-types.d.ts.map +1 -0
- package/dist/subtasks/subtask-types.js +111 -0
- package/dist/subtasks/subtask-types.js.map +1 -0
- package/dist/subtasks/types.d.ts +321 -0
- package/dist/subtasks/types.d.ts.map +1 -0
- package/dist/subtasks/types.js +16 -0
- package/dist/subtasks/types.js.map +1 -0
- package/dist/testing/auth.d.ts +12 -0
- package/dist/testing/auth.d.ts.map +1 -0
- package/dist/testing/auth.js +25 -0
- package/dist/testing/auth.js.map +1 -0
- package/dist/testing/do.d.ts +30 -0
- package/dist/testing/do.d.ts.map +1 -0
- package/dist/testing/do.js +26 -0
- package/dist/testing/do.js.map +1 -0
- package/dist/testing/fake-session.d.ts +27 -0
- package/dist/testing/fake-session.d.ts.map +1 -0
- package/dist/testing/fake-session.js +38 -0
- package/dist/testing/fake-session.js.map +1 -0
- package/dist/testing/fixtures.d.ts +27 -0
- package/dist/testing/fixtures.d.ts.map +1 -0
- package/dist/testing/fixtures.js +67 -0
- package/dist/testing/fixtures.js.map +1 -0
- package/dist/testing/index.d.ts +31 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +31 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/mock-model.d.ts +43 -0
- package/dist/testing/mock-model.d.ts.map +1 -0
- package/dist/testing/mock-model.js +62 -0
- package/dist/testing/mock-model.js.map +1 -0
- package/dist/testing/node.d.ts +24 -0
- package/dist/testing/node.d.ts.map +1 -0
- package/dist/testing/node.js +24 -0
- package/dist/testing/node.js.map +1 -0
- package/dist/testing/vcr-global-setup.d.ts +3 -0
- package/dist/testing/vcr-global-setup.d.ts.map +1 -0
- package/dist/testing/vcr-global-setup.js +9 -0
- package/dist/testing/vcr-global-setup.js.map +1 -0
- package/dist/testing/vcr-shared.d.ts +21 -0
- package/dist/testing/vcr-shared.d.ts.map +1 -0
- package/dist/testing/vcr-shared.js +21 -0
- package/dist/testing/vcr-shared.js.map +1 -0
- package/dist/testing/vcr-spec.d.ts +17 -0
- package/dist/testing/vcr-spec.d.ts.map +1 -0
- package/dist/testing/vcr-spec.js +72 -0
- package/dist/testing/vcr-spec.js.map +1 -0
- package/dist/testing/vcr.d.ts +81 -0
- package/dist/testing/vcr.d.ts.map +1 -0
- package/dist/testing/vcr.js +211 -0
- package/dist/testing/vcr.js.map +1 -0
- package/dist/worker/index.d.ts +62 -0
- package/dist/worker/index.d.ts.map +1 -0
- package/dist/worker/index.js +194 -0
- package/dist/worker/index.js.map +1 -0
- package/eslint-rules/index.js +31 -0
- package/eslint-rules/no-deprecated-object-properties.js +81 -0
- package/package.json +147 -0
- package/scripts/generate-keys.mjs +53 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { StepResult, ToolSet } from "ai";
|
|
2
|
+
/**
|
|
3
|
+
* Shared Workers-AI plumbing for the agent's inference operations — the pieces
|
|
4
|
+
* every model call needs regardless of *which* operation it belongs to.
|
|
5
|
+
*
|
|
6
|
+
* The two loops themselves are deliberately separate, not layered on a common
|
|
7
|
+
* one: the main agent's Session-coupled round lives in
|
|
8
|
+
* {@link file://./turn.ts turn.ts}, and the Session-less subagent loop in
|
|
9
|
+
* {@link file://../subagent/run.ts run.ts}. They share error classification and
|
|
10
|
+
* progress streaming; their control flow has nothing in common worth abstracting.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Called with each **intermediate** assistant content message — text the model
|
|
14
|
+
* emits in a step that also makes tool calls (`finishReason:"tool-calls"`), i.e.
|
|
15
|
+
* before the final reply. Used to stream those messages out live; the final reply
|
|
16
|
+
* is the operation's return value, not an `onContent` call. `stepIndex` is the
|
|
17
|
+
* 0-based step ordinal (stable enough across a primary→fallback re-run for the
|
|
18
|
+
* gateway to dedupe on). Best-effort — the caller must swallow its own failures.
|
|
19
|
+
*/
|
|
20
|
+
export type OnContent = (text: string, stepIndex: number) => void | Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Whether an error is a transient availability condition rather than a
|
|
23
|
+
* deterministic bad-output one.
|
|
24
|
+
*
|
|
25
|
+
* The distinction decides who handles it: transient throws out of the attempt loop
|
|
26
|
+
* so the Workflow step retries the whole round, while everything else burns the
|
|
27
|
+
* model slot and hands over to the fallback. Classifying a capacity blip as
|
|
28
|
+
* deterministic is the expensive mistake — it spends both slots on an outage and
|
|
29
|
+
* fails a Task that would have succeeded a second later.
|
|
30
|
+
*
|
|
31
|
+
* Structured signals first: the SDK's own `APICallError.isRetryable`, then the
|
|
32
|
+
* status code, then `RetryError` (raised once the SDK's internal backoff is
|
|
33
|
+
* exhausted). The message fragments stay as the last resort for the Workers-AI
|
|
34
|
+
* error codes, which arrive as prose on a plain `Error`.
|
|
35
|
+
*/
|
|
36
|
+
export declare function isTransientAiError(err: unknown): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Returns a fresh `onStepEnd` callback for one `generateText` attempt.
|
|
39
|
+
* Fires `onContent` for each intermediate step (text that accompanies tool
|
|
40
|
+
* calls); the final step is skipped because its text is the operation's return
|
|
41
|
+
* value. A fresh handler per attempt resets the 0-based `stepIndex` counter so a
|
|
42
|
+
* primary→fallback re-run reuses the same indices and the gateway dedupes.
|
|
43
|
+
*
|
|
44
|
+
* `terminalToolNames` are the loop's **halting** control tools (e.g. the main
|
|
45
|
+
* agent's `delegate`): a step that calls one still has `finishReason:"tool-calls"`,
|
|
46
|
+
* but it is the round's *final* step, and its accompanying text is the round's
|
|
47
|
+
* acknowledgment — which the caller publishes separately as a milestone. Streaming
|
|
48
|
+
* it here too would double-post the same text under a second messageId, so those
|
|
49
|
+
* steps are skipped. Default `[]` (the subagent loop has no control tools).
|
|
50
|
+
*/
|
|
51
|
+
export declare function buildIntermediateContentHandler(onContent: OnContent, terminalToolNames?: string[]): (step: StepResult<ToolSet>) => Promise<void>;
|
|
52
|
+
//# sourceMappingURL=inference.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inference.d.ts","sourceRoot":"","sources":["../../src/agent/inference.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,UAAU,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAG5D;;;;;;;;;GASG;AAEH;;;;;;;GAOG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,MAAM,KACd,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAoB1B;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAWxD;AAOD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,SAAS,EACpB,iBAAiB,GAAE,MAAM,EAAO,GAC/B,CAAC,IAAI,EAAE,UAAU,CAAC,OAAO,CAAC,KAAK,OAAO,CAAC,IAAI,CAAC,CAU9C"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { APICallError, RetryError } from "ai";
|
|
2
|
+
/** Workers-AI error codes and message fragments that mean "try again later". */
|
|
3
|
+
const TRANSIENT_MESSAGE_FRAGMENTS = [
|
|
4
|
+
"3040",
|
|
5
|
+
"3046",
|
|
6
|
+
"capacity temporarily exceeded",
|
|
7
|
+
"request timeout",
|
|
8
|
+
"rate limit",
|
|
9
|
+
"too many requests",
|
|
10
|
+
"overloaded",
|
|
11
|
+
"service unavailable"
|
|
12
|
+
];
|
|
13
|
+
/** HTTP statuses worth another attempt: timeout, conflict, throttle, any 5xx. */
|
|
14
|
+
function isRetryableStatus(status) {
|
|
15
|
+
if (status === undefined)
|
|
16
|
+
return false;
|
|
17
|
+
return status === 408 || status === 409 || status === 429 || status >= 500;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Whether an error is a transient availability condition rather than a
|
|
21
|
+
* deterministic bad-output one.
|
|
22
|
+
*
|
|
23
|
+
* The distinction decides who handles it: transient throws out of the attempt loop
|
|
24
|
+
* so the Workflow step retries the whole round, while everything else burns the
|
|
25
|
+
* model slot and hands over to the fallback. Classifying a capacity blip as
|
|
26
|
+
* deterministic is the expensive mistake — it spends both slots on an outage and
|
|
27
|
+
* fails a Task that would have succeeded a second later.
|
|
28
|
+
*
|
|
29
|
+
* Structured signals first: the SDK's own `APICallError.isRetryable`, then the
|
|
30
|
+
* status code, then `RetryError` (raised once the SDK's internal backoff is
|
|
31
|
+
* exhausted). The message fragments stay as the last resort for the Workers-AI
|
|
32
|
+
* error codes, which arrive as prose on a plain `Error`.
|
|
33
|
+
*/
|
|
34
|
+
export function isTransientAiError(err) {
|
|
35
|
+
if (APICallError.isInstance(err)) {
|
|
36
|
+
if (err.isRetryable)
|
|
37
|
+
return true;
|
|
38
|
+
if (isRetryableStatus(err.statusCode))
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
if (RetryError.isInstance(err))
|
|
42
|
+
return true;
|
|
43
|
+
if (!(err instanceof Error))
|
|
44
|
+
return false;
|
|
45
|
+
const message = err.message.toLowerCase();
|
|
46
|
+
return TRANSIENT_MESSAGE_FRAGMENTS.some((fragment) => message.includes(fragment));
|
|
47
|
+
}
|
|
48
|
+
/** A step is "intermediate" when it makes tool calls — more content follows. */
|
|
49
|
+
function isIntermediateStep(step) {
|
|
50
|
+
return step.finishReason === "tool-calls";
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Returns a fresh `onStepEnd` callback for one `generateText` attempt.
|
|
54
|
+
* Fires `onContent` for each intermediate step (text that accompanies tool
|
|
55
|
+
* calls); the final step is skipped because its text is the operation's return
|
|
56
|
+
* value. A fresh handler per attempt resets the 0-based `stepIndex` counter so a
|
|
57
|
+
* primary→fallback re-run reuses the same indices and the gateway dedupes.
|
|
58
|
+
*
|
|
59
|
+
* `terminalToolNames` are the loop's **halting** control tools (e.g. the main
|
|
60
|
+
* agent's `delegate`): a step that calls one still has `finishReason:"tool-calls"`,
|
|
61
|
+
* but it is the round's *final* step, and its accompanying text is the round's
|
|
62
|
+
* acknowledgment — which the caller publishes separately as a milestone. Streaming
|
|
63
|
+
* it here too would double-post the same text under a second messageId, so those
|
|
64
|
+
* steps are skipped. Default `[]` (the subagent loop has no control tools).
|
|
65
|
+
*/
|
|
66
|
+
export function buildIntermediateContentHandler(onContent, terminalToolNames = []) {
|
|
67
|
+
let stepIndex = 0;
|
|
68
|
+
return async (step) => {
|
|
69
|
+
const i = stepIndex++;
|
|
70
|
+
if (!isIntermediateStep(step))
|
|
71
|
+
return;
|
|
72
|
+
if (step.toolCalls.some((c) => terminalToolNames.includes(c.toolName)))
|
|
73
|
+
return;
|
|
74
|
+
const content = step.text.trim();
|
|
75
|
+
if (content)
|
|
76
|
+
await onContent(content, i);
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=inference.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inference.js","sourceRoot":"","sources":["../../src/agent/inference.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AA0B9C,gFAAgF;AAChF,MAAM,2BAA2B,GAAG;IAClC,MAAM;IACN,MAAM;IACN,+BAA+B;IAC/B,iBAAiB;IACjB,YAAY;IACZ,mBAAmB;IACnB,YAAY;IACZ,qBAAqB;CACtB,CAAC;AAEF,iFAAiF;AACjF,SAAS,iBAAiB,CAAC,MAA0B;IACnD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACvC,OAAO,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,IAAI,GAAG,CAAC;AAC7E,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAY;IAC7C,IAAI,YAAY,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,IAAI,GAAG,CAAC,WAAW;YAAE,OAAO,IAAI,CAAC;QACjC,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;IACrD,CAAC;IACD,IAAI,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,CAAC,CAAC,GAAG,YAAY,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1C,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;IAC1C,OAAO,2BAA2B,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE,CACnD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAC3B,CAAC;AACJ,CAAC;AAED,gFAAgF;AAChF,SAAS,kBAAkB,CAAC,IAAoC;IAC9D,OAAO,IAAI,CAAC,YAAY,KAAK,YAAY,CAAC;AAC5C,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,+BAA+B,CAC7C,SAAoB,EACpB,oBAA8B,EAAE;IAEhC,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,OAAO,KAAK,EAAE,IAAI,EAAE,EAAE;QACpB,MAAM,CAAC,GAAG,SAAS,EAAE,CAAC;QACtB,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC;YAAE,OAAO;QACtC,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;YACpE,OAAO;QACT,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACjC,IAAI,OAAO;YAAE,MAAM,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import type { LanguageModel } from "ai";
|
|
2
|
+
import type { ModelConfig } from "../config.js";
|
|
3
|
+
/**
|
|
4
|
+
* The Workers-AI model pair every loop runs on, built per agent instance.
|
|
5
|
+
*
|
|
6
|
+
* The predecessor read `env.AI` and five config constants as module-level
|
|
7
|
+
* imports. Neither survives packaging: `env` does not exist at module scope on
|
|
8
|
+
* Workers, and a module constant cannot be overridden by a consumer. So this is
|
|
9
|
+
* a factory over an injected binding and an injected {@link ModelConfig}.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* Embed a batch of texts for episodic recall. Uses the same Workers-AI + AI
|
|
13
|
+
* Gateway path as the chat models so embeddings get the same gateway
|
|
14
|
+
* observability/caching. The output dimension must match the Vectorize index.
|
|
15
|
+
*/
|
|
16
|
+
export type Embed = (texts: string[]) => Promise<number[][]>;
|
|
17
|
+
/**
|
|
18
|
+
* Custom metadata attached to the AI Gateway log for every call a pair makes.
|
|
19
|
+
* The gateway's own `metadata` is otherwise `null`, so a model call can only be
|
|
20
|
+
* tied back to its task by timestamp; stamping `{ taskId, round }` (a turn) or
|
|
21
|
+
* `{ taskId, subtaskId }` (a chunk) makes correlation exact. Values are limited
|
|
22
|
+
* to the gateway's accepted scalar set.
|
|
23
|
+
*/
|
|
24
|
+
export type GatewayMetadata = Record<string, number | string | boolean>;
|
|
25
|
+
export interface ModelOverrides {
|
|
26
|
+
/** Test override for the primary slot. */
|
|
27
|
+
model?: LanguageModel;
|
|
28
|
+
/** Test override for the fallback slot. */
|
|
29
|
+
fallbackModel?: LanguageModel;
|
|
30
|
+
/**
|
|
31
|
+
* Workers-AI id for the primary slot (a recipe's, already code-validated
|
|
32
|
+
* against the allowlist by `validateRecipe`). Defaults to the configured
|
|
33
|
+
* `chatModelId`.
|
|
34
|
+
*/
|
|
35
|
+
primaryModelId?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Workers-AI id for the fallback slot (already code-validated). Defaults to
|
|
38
|
+
* the configured `fallbackChatModelId`.
|
|
39
|
+
*/
|
|
40
|
+
fallbackModelId?: string;
|
|
41
|
+
/** AI Gateway log metadata for correlation — see {@link GatewayMetadata}. */
|
|
42
|
+
metadata?: GatewayMetadata;
|
|
43
|
+
}
|
|
44
|
+
/** The primary/fallback models (lazily memoized) plus their ids for logging. */
|
|
45
|
+
export interface ModelPair {
|
|
46
|
+
primary: () => LanguageModel;
|
|
47
|
+
fallback: () => LanguageModel;
|
|
48
|
+
primaryId: () => string;
|
|
49
|
+
fallbackId: () => string;
|
|
50
|
+
}
|
|
51
|
+
export interface ModelRuntime {
|
|
52
|
+
/**
|
|
53
|
+
* Lazily build + memoize a primary/fallback model pair (overridable in tests,
|
|
54
|
+
* id-parameterized for recipes). No allowlisting happens here —
|
|
55
|
+
* `validateRecipe` is the single validation owner for recipe-supplied ids.
|
|
56
|
+
*/
|
|
57
|
+
createModelPair(overrides?: ModelOverrides): ModelPair;
|
|
58
|
+
embedTexts: Embed;
|
|
59
|
+
}
|
|
60
|
+
export interface ModelRuntimeDeps {
|
|
61
|
+
/** The `AI` binding. Read lazily — see {@link createModelRuntime}. */
|
|
62
|
+
ai: Ai;
|
|
63
|
+
config: ModelConfig;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Build the model runtime for one agent instance.
|
|
67
|
+
*
|
|
68
|
+
* The provider is constructed on first *use*, not here. During `wrangler deploy`
|
|
69
|
+
* Cloudflare evaluates module scope to validate the new version, and bindings
|
|
70
|
+
* are not populated at that point — constructing eagerly makes `createWorkersAI`
|
|
71
|
+
* throw "you must provide either a binding or credentials". The same laziness
|
|
72
|
+
* protects a consumer who builds their runtime early.
|
|
73
|
+
*/
|
|
74
|
+
export declare function createModelRuntime(deps: ModelRuntimeDeps): ModelRuntime;
|
|
75
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,IAAI,CAAC;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;;GAOG;AAEH;;;;GAIG;AACH,MAAM,MAAM,KAAK,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAE7D;;;;;;GAMG;AACH,MAAM,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAC;AAExE,MAAM,WAAW,cAAc;IAC7B,0CAA0C;IAC1C,KAAK,CAAC,EAAE,aAAa,CAAC;IACtB,2CAA2C;IAC3C,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,gFAAgF;AAChF,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,aAAa,CAAC;IAC7B,QAAQ,EAAE,MAAM,aAAa,CAAC;IAC9B,SAAS,EAAE,MAAM,MAAM,CAAC;IACxB,UAAU,EAAE,MAAM,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,eAAe,CAAC,SAAS,CAAC,EAAE,cAAc,GAAG,SAAS,CAAC;IACvD,UAAU,EAAE,KAAK,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,sEAAsE;IACtE,EAAE,EAAE,EAAE,CAAC;IACP,MAAM,EAAE,WAAW,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,GAAG,YAAY,CAuDvE"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { createWorkersAI } from "workers-ai-provider";
|
|
2
|
+
import { embedMany } from "ai";
|
|
3
|
+
/**
|
|
4
|
+
* Build the model runtime for one agent instance.
|
|
5
|
+
*
|
|
6
|
+
* The provider is constructed on first *use*, not here. During `wrangler deploy`
|
|
7
|
+
* Cloudflare evaluates module scope to validate the new version, and bindings
|
|
8
|
+
* are not populated at that point — constructing eagerly makes `createWorkersAI`
|
|
9
|
+
* throw "you must provide either a binding or credentials". The same laziness
|
|
10
|
+
* protects a consumer who builds their runtime early.
|
|
11
|
+
*/
|
|
12
|
+
export function createModelRuntime(deps) {
|
|
13
|
+
const { config } = deps;
|
|
14
|
+
let provider;
|
|
15
|
+
const workersai = () => (provider ??= createWorkersAI({
|
|
16
|
+
binding: deps.ai,
|
|
17
|
+
gateway: { id: config.aiGatewayId }
|
|
18
|
+
}));
|
|
19
|
+
/**
|
|
20
|
+
* Per-model Workers-AI settings: pin the gateway id (so per-call metadata does
|
|
21
|
+
* not drop the gateway route), attach correlation metadata when supplied, and
|
|
22
|
+
* set the reasoning budget.
|
|
23
|
+
*
|
|
24
|
+
* Always returns a settings object, even with no metadata: `reasoning_effort`
|
|
25
|
+
* has to reach the binding on every call, and an `undefined` return drops it.
|
|
26
|
+
*/
|
|
27
|
+
const chatSettings = (metadata) => ({
|
|
28
|
+
gateway: { id: config.aiGatewayId, ...(metadata ? { metadata } : {}) },
|
|
29
|
+
reasoning_effort: config.reasoningEffort
|
|
30
|
+
});
|
|
31
|
+
return {
|
|
32
|
+
createModelPair(overrides = {}) {
|
|
33
|
+
const primaryId = overrides.primaryModelId ?? config.chatModelId;
|
|
34
|
+
const fallbackId = overrides.fallbackModelId ?? config.fallbackChatModelId;
|
|
35
|
+
let primary;
|
|
36
|
+
let fallback;
|
|
37
|
+
const settings = chatSettings(overrides.metadata);
|
|
38
|
+
return {
|
|
39
|
+
primary: () => (primary ??= overrides.model ?? workersai()(primaryId, settings)),
|
|
40
|
+
fallback: () => (fallback ??=
|
|
41
|
+
overrides.fallbackModel ??
|
|
42
|
+
overrides.model ??
|
|
43
|
+
workersai()(fallbackId, settings)),
|
|
44
|
+
primaryId: () => primaryId,
|
|
45
|
+
fallbackId: () => fallbackId
|
|
46
|
+
};
|
|
47
|
+
},
|
|
48
|
+
async embedTexts(texts) {
|
|
49
|
+
if (texts.length === 0)
|
|
50
|
+
return [];
|
|
51
|
+
const { embeddings } = await embedMany({
|
|
52
|
+
model: workersai().embedding(config.embeddingModelId),
|
|
53
|
+
values: texts,
|
|
54
|
+
// Failures surface to the caller (best-effort archival swallows them);
|
|
55
|
+
// the SDK's retry/backoff would only add latency on a hard failure.
|
|
56
|
+
maxRetries: 0
|
|
57
|
+
});
|
|
58
|
+
return embeddings;
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/agent/model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAEtD,OAAO,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAwE/B;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAsB;IACvD,MAAM,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IACxB,IAAI,QAAwD,CAAC;IAC7D,MAAM,SAAS,GAAG,GAAG,EAAE,CACrB,CAAC,QAAQ,KAAK,eAAe,CAAC;QAC5B,OAAO,EAAE,IAAI,CAAC,EAAE;QAChB,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,WAAW,EAAE;KACpC,CAAC,CAAC,CAAC;IAEN;;;;;;;OAOG;IACH,MAAM,YAAY,GAAG,CAAC,QAA0B,EAAE,EAAE,CAAC,CAAC;QACpD,OAAO,EAAE,EAAE,EAAE,EAAE,MAAM,CAAC,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE;QACtE,gBAAgB,EAAE,MAAM,CAAC,eAAe;KACzC,CAAC,CAAC;IAEH,OAAO;QACL,eAAe,CAAC,YAA4B,EAAE;YAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,cAAc,IAAI,MAAM,CAAC,WAAW,CAAC;YACjE,MAAM,UAAU,GACd,SAAS,CAAC,eAAe,IAAI,MAAM,CAAC,mBAAmB,CAAC;YAC1D,IAAI,OAAkC,CAAC;YACvC,IAAI,QAAmC,CAAC;YACxC,MAAM,QAAQ,GAAG,YAAY,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YAClD,OAAO;gBACL,OAAO,EAAE,GAAG,EAAE,CACZ,CAAC,OAAO,KAAK,SAAS,CAAC,KAAK,IAAI,SAAS,EAAE,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;gBACnE,QAAQ,EAAE,GAAG,EAAE,CACb,CAAC,QAAQ;oBACP,SAAS,CAAC,aAAa;wBACvB,SAAS,CAAC,KAAK;wBACf,SAAS,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;gBACtC,SAAS,EAAE,GAAG,EAAE,CAAC,SAAS;gBAC1B,UAAU,EAAE,GAAG,EAAE,CAAC,UAAU;aAC7B,CAAC;QACJ,CAAC;QAED,KAAK,CAAC,UAAU,CAAC,KAAe;YAC9B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,EAAE,CAAC;YAClC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,SAAS,CAAC;gBACrC,KAAK,EAAE,SAAS,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,gBAAgB,CAAC;gBACrD,MAAM,EAAE,KAAK;gBACb,uEAAuE;gBACvE,oEAAoE;gBACpE,UAAU,EAAE,CAAC;aACd,CAAC,CAAC;YACH,OAAO,UAAU,CAAC;QACpB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type { LanguageModel, ToolSet } from "ai";
|
|
2
|
+
import { Session } from "agents/experimental/memory/session";
|
|
3
|
+
import type { SessionMessage } from "agents/experimental/memory/session";
|
|
4
|
+
import { createCompactFunction } from "agents/experimental/memory/utils";
|
|
5
|
+
/**
|
|
6
|
+
* The one continuous {@link Session} an agent Durable Object owns. Ported from
|
|
7
|
+
* the looping-gateway admin agent's `shared/session.ts` (single Session per DO —
|
|
8
|
+
* soul + memory + compaction). Recall (Vectorize) archival is Phase 3: the
|
|
9
|
+
* `onArchive` seam is present but left unwired for now.
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* The SQLite-backed host the Sessions API needs — satisfied by the Agents SDK
|
|
13
|
+
* `Agent` (`this.sql`).
|
|
14
|
+
*/
|
|
15
|
+
export interface SessionHost {
|
|
16
|
+
sql<T = Record<string, string | number | boolean | null>>(strings: TemplateStringsArray, ...values: (string | number | boolean | null)[]): T[];
|
|
17
|
+
}
|
|
18
|
+
/** The subset of `Session` the agent loop drives — lets tests inject a fake. */
|
|
19
|
+
export interface SessionLike {
|
|
20
|
+
appendMessage(message: SessionMessage, parentId?: string | null): Promise<unknown> | unknown;
|
|
21
|
+
getHistory(): Promise<SessionMessage[]>;
|
|
22
|
+
/**
|
|
23
|
+
* Read one message by id, or null. Reads the **raw stored row**, so it is
|
|
24
|
+
* unaffected by compaction overlays — a message folded into a summary is still
|
|
25
|
+
* readable here. That is what makes {@link appendOnce}'s read-back a reliable
|
|
26
|
+
* recovery path for a phase whose Workflow step re-ran.
|
|
27
|
+
*/
|
|
28
|
+
getMessage(id: string): Promise<SessionMessage | null>;
|
|
29
|
+
refreshSystemPrompt(): Promise<string>;
|
|
30
|
+
tools(): Promise<ToolSet>;
|
|
31
|
+
/** Compaction overlays so far — non-empty ⇒ an episodic archive exists. */
|
|
32
|
+
getCompactions(): Promise<unknown[]>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Append a message with a deterministic id exactly once, and return the text that
|
|
36
|
+
* is **durably stored** under that id.
|
|
37
|
+
*
|
|
38
|
+
* `Session.appendMessage` is already idempotent by id: appending an id that
|
|
39
|
+
* exists is a no-op. The read-back is what matters for a re-run phase — if the
|
|
40
|
+
* step crashed after appending and the retry re-inferred a *different* reply, the
|
|
41
|
+
* append no-ops and this returns the original, durable text. The Session and the
|
|
42
|
+
* value the caller goes on to deliver therefore never disagree.
|
|
43
|
+
*
|
|
44
|
+
* Falls back to the message's own text if the read-back returns null (it cannot,
|
|
45
|
+
* having just been appended) rather than failing a phase over a missing echo.
|
|
46
|
+
*/
|
|
47
|
+
export declare function appendOnce(session: SessionLike, message: SessionMessage): Promise<string>;
|
|
48
|
+
export interface AgentSessionOptions {
|
|
49
|
+
/** Read-only identity block injected into the system prompt every turn. */
|
|
50
|
+
soul: () => string | Promise<string>;
|
|
51
|
+
/** Description of the writable SQLite `"memory"` scratchpad the model self-edits. */
|
|
52
|
+
memoryDescription: string;
|
|
53
|
+
/** Soft cap (tokens) for the `"memory"` block. */
|
|
54
|
+
memoryMaxTokens: number;
|
|
55
|
+
/** History token threshold that triggers compaction. */
|
|
56
|
+
compactAfterTokens: number;
|
|
57
|
+
/**
|
|
58
|
+
* Tokens of recent history compaction keeps verbatim. Coupled to
|
|
59
|
+
* {@link compactAfterTokens} — see `SessionConfig.compactTailTokens` for the
|
|
60
|
+
* invariant that binds them, which `resolveConfig` enforces.
|
|
61
|
+
*/
|
|
62
|
+
compactTailTokens: number;
|
|
63
|
+
/**
|
|
64
|
+
* Output-token ceiling for the summarizer call. An unbounded summary is not
|
|
65
|
+
* the risk; a silently truncated one is — it becomes this caller's memory of
|
|
66
|
+
* everything that scrolled out, with no way to tell it was cut short.
|
|
67
|
+
*/
|
|
68
|
+
maxOutputTokens: number;
|
|
69
|
+
/**
|
|
70
|
+
* Archive the raw messages displaced by each compaction (episodic recall).
|
|
71
|
+
* Best-effort: a throw here must never abort compaction. (Wired in Phase 3.)
|
|
72
|
+
*/
|
|
73
|
+
onArchive?: (messages: SessionMessage[]) => Promise<void>;
|
|
74
|
+
}
|
|
75
|
+
type CompactFn = ReturnType<typeof createCompactFunction>;
|
|
76
|
+
/**
|
|
77
|
+
* Wrap a compaction function so the raw messages it folds into a summary are
|
|
78
|
+
* also handed to `onArchive` (which embeds them for later recall). The displaced
|
|
79
|
+
* range is `fromMessageId..toMessageId` of the result, sliced from the `history`
|
|
80
|
+
* the compaction saw. Archival failure is swallowed — compaction must still
|
|
81
|
+
* shorten history even if the recall store is briefly unavailable.
|
|
82
|
+
*/
|
|
83
|
+
export declare function archivingCompaction(base: CompactFn, onArchive?: (messages: SessionMessage[]) => Promise<void>): CompactFn;
|
|
84
|
+
/**
|
|
85
|
+
* Build the one continuous `Session` an agent Durable Object owns: a read-only
|
|
86
|
+
* `"soul"` identity block + a writable `"memory"` scratchpad, with history
|
|
87
|
+
* compaction summarized by the same model. All of a caller's turns (any channel
|
|
88
|
+
* or thread) accumulate into this single conversation.
|
|
89
|
+
*/
|
|
90
|
+
export declare function buildAgentSession(agent: SessionHost, model: LanguageModel, opts: AgentSessionOptions): Session;
|
|
91
|
+
export {};
|
|
92
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAEjD,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAC7D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AACzE,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAGzE;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EACtD,OAAO,EAAE,oBAAoB,EAC7B,GAAG,MAAM,EAAE,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EAAE,GAC9C,CAAC,EAAE,CAAC;CACR;AAED,gFAAgF;AAChF,MAAM,WAAW,WAAW;IAC1B,aAAa,CACX,OAAO,EAAE,cAAc,EACvB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;IAC9B,UAAU,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACxC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC,CAAC;IACvD,mBAAmB,IAAI,OAAO,CAAC,MAAM,CAAC,CAAC;IACvC,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1B,2EAA2E;IAC3E,cAAc,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;CACtC;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,UAAU,CAC9B,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAIjB;AAED,MAAM,WAAW,mBAAmB;IAClC,2EAA2E;IAC3E,IAAI,EAAE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IACrC,qFAAqF;IACrF,iBAAiB,EAAE,MAAM,CAAC;IAC1B,kDAAkD;IAClD,eAAe,EAAE,MAAM,CAAC;IACxB,wDAAwD;IACxD,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;OAIG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3D;AAED,KAAK,SAAS,GAAG,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE1D;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,SAAS,EACf,SAAS,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,GACxD,SAAS,CAiBX;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,WAAW,EAClB,KAAK,EAAE,aAAa,EACpB,IAAI,EAAE,mBAAmB,GACxB,OAAO,CA2BT"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { generateText } from "ai";
|
|
2
|
+
import { Session } from "agents/experimental/memory/session";
|
|
3
|
+
import { createCompactFunction } from "agents/experimental/memory/utils";
|
|
4
|
+
import { sessionText } from "./history.js";
|
|
5
|
+
/**
|
|
6
|
+
* Append a message with a deterministic id exactly once, and return the text that
|
|
7
|
+
* is **durably stored** under that id.
|
|
8
|
+
*
|
|
9
|
+
* `Session.appendMessage` is already idempotent by id: appending an id that
|
|
10
|
+
* exists is a no-op. The read-back is what matters for a re-run phase — if the
|
|
11
|
+
* step crashed after appending and the retry re-inferred a *different* reply, the
|
|
12
|
+
* append no-ops and this returns the original, durable text. The Session and the
|
|
13
|
+
* value the caller goes on to deliver therefore never disagree.
|
|
14
|
+
*
|
|
15
|
+
* Falls back to the message's own text if the read-back returns null (it cannot,
|
|
16
|
+
* having just been appended) rather than failing a phase over a missing echo.
|
|
17
|
+
*/
|
|
18
|
+
export async function appendOnce(session, message) {
|
|
19
|
+
await session.appendMessage(message);
|
|
20
|
+
const stored = await session.getMessage(message.id);
|
|
21
|
+
return stored ? sessionText(stored) : sessionText(message);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Wrap a compaction function so the raw messages it folds into a summary are
|
|
25
|
+
* also handed to `onArchive` (which embeds them for later recall). The displaced
|
|
26
|
+
* range is `fromMessageId..toMessageId` of the result, sliced from the `history`
|
|
27
|
+
* the compaction saw. Archival failure is swallowed — compaction must still
|
|
28
|
+
* shorten history even if the recall store is briefly unavailable.
|
|
29
|
+
*/
|
|
30
|
+
export function archivingCompaction(base, onArchive) {
|
|
31
|
+
if (!onArchive)
|
|
32
|
+
return base;
|
|
33
|
+
return async (history, options) => {
|
|
34
|
+
const result = await base(history, options);
|
|
35
|
+
if (result) {
|
|
36
|
+
const from = history.findIndex((m) => m.id === result.fromMessageId);
|
|
37
|
+
const to = history.findIndex((m) => m.id === result.toMessageId);
|
|
38
|
+
if (from !== -1 && to !== -1) {
|
|
39
|
+
try {
|
|
40
|
+
await onArchive(history.slice(from, to + 1));
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
console.error("[recall] archive on compaction failed", err);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Build the one continuous `Session` an agent Durable Object owns: a read-only
|
|
52
|
+
* `"soul"` identity block + a writable `"memory"` scratchpad, with history
|
|
53
|
+
* compaction summarized by the same model. All of a caller's turns (any channel
|
|
54
|
+
* or thread) accumulate into this single conversation.
|
|
55
|
+
*/
|
|
56
|
+
export function buildAgentSession(agent, model, opts) {
|
|
57
|
+
const compact = archivingCompaction(createCompactFunction({
|
|
58
|
+
// The one boundary worth owning. `protectHead` (3) and `minTailMessages`
|
|
59
|
+
// (2) keep the SDK defaults: the head is the conversation's opening and is
|
|
60
|
+
// cheap, and the tail floor is a safety net rather than a budget.
|
|
61
|
+
tailTokenBudget: opts.compactTailTokens,
|
|
62
|
+
// Bounded like every other call: an unbounded summary is not the risk, a
|
|
63
|
+
// silently truncated one is — it becomes this caller's memory of everything
|
|
64
|
+
// that scrolled out, with no way to tell it was cut short.
|
|
65
|
+
summarize: (prompt) => generateText({
|
|
66
|
+
model,
|
|
67
|
+
prompt,
|
|
68
|
+
maxOutputTokens: opts.maxOutputTokens
|
|
69
|
+
}).then((r) => r.text)
|
|
70
|
+
}), opts.onArchive);
|
|
71
|
+
return Session.create(agent)
|
|
72
|
+
.withContext("soul", { provider: { get: async () => opts.soul() } })
|
|
73
|
+
.withContext("memory", {
|
|
74
|
+
description: opts.memoryDescription,
|
|
75
|
+
maxTokens: opts.memoryMaxTokens
|
|
76
|
+
})
|
|
77
|
+
.onCompaction(compact)
|
|
78
|
+
.compactAfter(opts.compactAfterTokens);
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/agent/session.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,oCAAoC,CAAC;AAE7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAwC3C;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,OAAoB,EACpB,OAAuB;IAEvB,MAAM,OAAO,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IACrC,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IACpD,OAAO,MAAM,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;AAC7D,CAAC;AAgCD;;;;;;GAMG;AACH,MAAM,UAAU,mBAAmB,CACjC,IAAe,EACf,SAAyD;IAEzD,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,EAAE;QAChC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC5C,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,aAAa,CAAC,CAAC;YACrE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,WAAW,CAAC,CAAC;YACjE,IAAI,IAAI,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC;oBACH,MAAM,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC;gBAC/C,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,OAAO,CAAC,KAAK,CAAC,uCAAuC,EAAE,GAAG,CAAC,CAAC;gBAC9D,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAC/B,KAAkB,EAClB,KAAoB,EACpB,IAAyB;IAEzB,MAAM,OAAO,GAAG,mBAAmB,CACjC,qBAAqB,CAAC;QACpB,yEAAyE;QACzE,2EAA2E;QAC3E,kEAAkE;QAClE,eAAe,EAAE,IAAI,CAAC,iBAAiB;QACvC,yEAAyE;QACzE,4EAA4E;QAC5E,2DAA2D;QAC3D,SAAS,EAAE,CAAC,MAAM,EAAE,EAAE,CACpB,YAAY,CAAC;YACX,KAAK;YACL,MAAM;YACN,eAAe,EAAE,IAAI,CAAC,eAAe;SACtC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;KACzB,CAAC,EACF,IAAI,CAAC,SAAS,CACf,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;SACzB,WAAW,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC;SACnE,WAAW,CAAC,QAAQ,EAAE;QACrB,WAAW,EAAE,IAAI,CAAC,iBAAiB;QACnC,SAAS,EAAE,IAAI,CAAC,eAAe;KAChC,CAAC;SACD,YAAY,CAAC,OAAO,CAAC;SACrB,YAAY,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;AAC3C,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shapes of everything an agent tunes, plus a working set of defaults.
|
|
3
|
+
*
|
|
4
|
+
* In the predecessor repos this file held bare `export const`s that ~12 modules
|
|
5
|
+
* imported directly. That is what this package cannot do: a module-level constant
|
|
6
|
+
* read at import time is not overridable by a consumer, and it freezes the value
|
|
7
|
+
* into the module graph before `env` exists. So core owns the *shapes* and a
|
|
8
|
+
* baseline; a consuming agent passes overrides to {@link resolveConfig} once, at
|
|
9
|
+
* DO start, and the resolved object is threaded through explicitly.
|
|
10
|
+
*
|
|
11
|
+
* The distinction against {@link file://./platform.ts} stays sharp: nothing here
|
|
12
|
+
* is a platform fact, and nothing there is tunable.
|
|
13
|
+
*/
|
|
14
|
+
/** Model ids and per-call generation settings. */
|
|
15
|
+
export interface ModelConfig {
|
|
16
|
+
/** Workers AI model for the tool loop. Must support function calling. */
|
|
17
|
+
chatModelId: string;
|
|
18
|
+
/**
|
|
19
|
+
* Tried when the primary throws. Should be a *different vendor and family* —
|
|
20
|
+
* a same-family fallback shares the failure mode you are falling back from.
|
|
21
|
+
*/
|
|
22
|
+
fallbackChatModelId: string;
|
|
23
|
+
/** AI Gateway slug; `"default"` auto-provisions on first request. */
|
|
24
|
+
aiGatewayId: string;
|
|
25
|
+
/**
|
|
26
|
+
* Output-token ceiling for every chat call. Left unset, the binding applies a
|
|
27
|
+
* per-model default which a reasoning model spends on `reasoning_content`
|
|
28
|
+
* before emitting the tool call — a truncated round that reads as a clean
|
|
29
|
+
* answer. Generous on purpose: it bounds a runaway, it does not ration.
|
|
30
|
+
*/
|
|
31
|
+
maxOutputTokens: number;
|
|
32
|
+
/** Reasoning budget forwarded on the binding's `inputs` by workers-ai-provider. */
|
|
33
|
+
reasoningEffort: "low" | "medium" | "high";
|
|
34
|
+
/**
|
|
35
|
+
* Embedding model backing recall. Its dimension/metric must match the
|
|
36
|
+
* Vectorize index (1024-dim, cosine); changing it means recreating the index.
|
|
37
|
+
*/
|
|
38
|
+
embeddingModelId: string;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* An execution budget, in the only two currencies that mean anything: **turns**
|
|
42
|
+
* (what it costs) and **wall clock** (how long it can run away for).
|
|
43
|
+
*
|
|
44
|
+
* Rounds, chunks and steps are *mechanics*, not budgets — a round is the
|
|
45
|
+
* delegate/answer loop, a chunk is a durable slice sized by the Workers step
|
|
46
|
+
* timeout. None of them is tunable and none belongs here. Conflating the two is
|
|
47
|
+
* what once made an overnight runaway look healthy to every cap in the system.
|
|
48
|
+
*
|
|
49
|
+
* Reaching either ceiling does the same thing at either level: one final call
|
|
50
|
+
* with **no tools** — "you have spent your budget, answer now from what you
|
|
51
|
+
* have". A ceiling yields an answer; it never drops the work.
|
|
52
|
+
*/
|
|
53
|
+
export interface AgentLimits {
|
|
54
|
+
/**
|
|
55
|
+
* Tool-loop steps, summed across every round *and* across the
|
|
56
|
+
* primary→fallback attempt within a round — a fallback attempt is real spend.
|
|
57
|
+
*/
|
|
58
|
+
maxTurns: number;
|
|
59
|
+
/**
|
|
60
|
+
* Measured from the first durable step. Note for whoever implements
|
|
61
|
+
* escalation: this must be **rebased** after a `step.waitForEvent(...)`
|
|
62
|
+
* returns, or a human's thinking time is charged to the agent and a task that
|
|
63
|
+
* asks a question at minute 5 is dead before the answer arrives. Turns need no
|
|
64
|
+
* such care — waiting costs none.
|
|
65
|
+
*/
|
|
66
|
+
maxWallMs: number;
|
|
67
|
+
}
|
|
68
|
+
/** Session memory + compaction tuning. */
|
|
69
|
+
export interface SessionConfig {
|
|
70
|
+
/** Soft cap (tokens) for the self-edited `"memory"` scratchpad block. */
|
|
71
|
+
memoryMaxTokens: number;
|
|
72
|
+
/** Live-history token threshold that triggers automatic compaction. */
|
|
73
|
+
compactAfterTokens: number;
|
|
74
|
+
/**
|
|
75
|
+
* Tokens of the most recent history compaction keeps **verbatim**.
|
|
76
|
+
*
|
|
77
|
+
* Read this together with {@link compactAfterTokens}; neither means anything
|
|
78
|
+
* alone. After a compaction the floor is `system + protectHead + summary +
|
|
79
|
+
* tail`, so the conversation that must accumulate before compaction fires
|
|
80
|
+
* again is `Δ = compactAfterTokens − floor`, and the SDK sizes each summary at
|
|
81
|
+
* 20% of the middle it folded, so at equilibrium `S ≈ 0.2Δ`.
|
|
82
|
+
*
|
|
83
|
+
* INVARIANT: `compactAfterTokens − compactTailTokens >= 10_000`, asserted in
|
|
84
|
+
* `session.spec.ts`. Below it the fixed floor eats the gap and compaction
|
|
85
|
+
* fires on nearly every append, each firing spending a summarizer call on a
|
|
86
|
+
* near-empty middle. Never lower the threshold without lowering the tail too.
|
|
87
|
+
*/
|
|
88
|
+
compactTailTokens: number;
|
|
89
|
+
/** One-line description shown to the model for the writable `"memory"` block. */
|
|
90
|
+
memoryDescription: string;
|
|
91
|
+
}
|
|
92
|
+
/** Episodic-recall (Vectorize) tuning. */
|
|
93
|
+
export interface RecallConfig {
|
|
94
|
+
/** Default number of archived messages one `recall` query returns. */
|
|
95
|
+
topK: number;
|
|
96
|
+
/**
|
|
97
|
+
* Max chars of a message's text stored in its vector metadata. Keeps each
|
|
98
|
+
* vector under Vectorize's ~10 KiB/vector limit; recall returns this snippet
|
|
99
|
+
* plus provenance, not the full original message.
|
|
100
|
+
*/
|
|
101
|
+
metadataTextMax: number;
|
|
102
|
+
}
|
|
103
|
+
export interface CoreConfig {
|
|
104
|
+
model: ModelConfig;
|
|
105
|
+
/** What bounds the MAIN agent across every round of one task. */
|
|
106
|
+
mainAgentLimits: AgentLimits;
|
|
107
|
+
/**
|
|
108
|
+
* The baseline every subagent branch runs under. A recipe may override either
|
|
109
|
+
* field — to any positive integer, larger included — and inherits the baseline
|
|
110
|
+
* for whatever it does not validly declare. A default, not a ceiling.
|
|
111
|
+
*/
|
|
112
|
+
subagentLimits: AgentLimits;
|
|
113
|
+
/**
|
|
114
|
+
* How many of the most recent assistant turns keep their tool **results** in a
|
|
115
|
+
* subagent's rolling window. Older results are stubbed; the tool *calls* and
|
|
116
|
+
* the model's own text always survive the full `historyWindow`, because that
|
|
117
|
+
* is where a recipe's model keeps whatever it wrote down for itself.
|
|
118
|
+
*
|
|
119
|
+
* A mechanic of the window, not a property of a domain — which is why it is
|
|
120
|
+
* deliberately not a recipe field: recipe fields are fingerprinted, and
|
|
121
|
+
* changing a fingerprint strands every in-flight run behind a mismatch that
|
|
122
|
+
* costs it its whole history.
|
|
123
|
+
*/
|
|
124
|
+
toolOutputWindow: number;
|
|
125
|
+
/**
|
|
126
|
+
* Upper bound on subtasks per **round** — a core invariant: a delegating round
|
|
127
|
+
* emits `1..maxSubtasks` subtasks, which is also what bounds its fan-out (all
|
|
128
|
+
* dependency-ready subtasks run concurrently, with no other concurrency cap).
|
|
129
|
+
*
|
|
130
|
+
* Not a budget but a shape: it is what the delegation schema offers the model,
|
|
131
|
+
* and the data layer re-checks it as the durable guard.
|
|
132
|
+
*/
|
|
133
|
+
maxSubtasks: number;
|
|
134
|
+
session: SessionConfig;
|
|
135
|
+
recall: RecallConfig;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A working baseline. Every value is overridable; none is a ceiling. These are
|
|
139
|
+
* the values both predecessor agents converged on in production, so they are a
|
|
140
|
+
* reasonable place to start rather than an opinion about your domain.
|
|
141
|
+
*/
|
|
142
|
+
export declare const DEFAULT_CORE_CONFIG: CoreConfig;
|
|
143
|
+
/** One level of optionality per nested group — enough for a config this shallow. */
|
|
144
|
+
export type CoreConfigOverrides = {
|
|
145
|
+
[K in keyof CoreConfig]?: CoreConfig[K] extends object ? Partial<CoreConfig[K]> : CoreConfig[K];
|
|
146
|
+
};
|
|
147
|
+
export declare class ConfigError extends Error {
|
|
148
|
+
constructor(message: string);
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Merge overrides onto {@link DEFAULT_CORE_CONFIG} and check the invariants that
|
|
152
|
+
* are cheap to get wrong and expensive to notice.
|
|
153
|
+
*
|
|
154
|
+
* Called once, at DO start, and the result threaded explicitly from there. Do
|
|
155
|
+
* not call it per-request: the point of resolving is that every module downstream
|
|
156
|
+
* reads the same object.
|
|
157
|
+
*/
|
|
158
|
+
export declare function resolveConfig(overrides?: CoreConfigOverrides): CoreConfig;
|
|
159
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,kDAAkD;AAClD,MAAM,WAAW,WAAW;IAC1B,yEAAyE;IACzE,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,mBAAmB,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,eAAe,EAAE,MAAM,CAAC;IACxB,mFAAmF;IACnF,eAAe,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC3C;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,WAAW,WAAW;IAC1B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,0CAA0C;AAC1C,MAAM,WAAW,aAAa;IAC5B,yEAAyE;IACzE,eAAe,EAAE,MAAM,CAAC;IACxB,uEAAuE;IACvE,kBAAkB,EAAE,MAAM,CAAC;IAC3B;;;;;;;;;;;;;OAaG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iFAAiF;IACjF,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,0CAA0C;AAC1C,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,iEAAiE;IACjE,eAAe,EAAE,WAAW,CAAC;IAC7B;;;;OAIG;IACH,cAAc,EAAE,WAAW,CAAC;IAC5B;;;;;;;;;;OAUG;IACH,gBAAgB,EAAE,MAAM,CAAC;IACzB;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,EAAE,UAsBjC,CAAC;AAEF,oFAAoF;AACpF,MAAM,MAAM,mBAAmB,GAAG;KAC/B,CAAC,IAAI,MAAM,UAAU,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,SAAS,MAAM,GAClD,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,GACtB,UAAU,CAAC,CAAC,CAAC;CAClB,CAAC;AAEF,qBAAa,WAAY,SAAQ,KAAK;gBACxB,OAAO,EAAE,MAAM;CAI5B;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,SAAS,GAAE,mBAAwB,GAAG,UAAU,CA4C7E"}
|