pocket-agent 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.
Files changed (166) hide show
  1. package/README.md +140 -0
  2. package/dist/adapters/createLLMEvaluator.d.ts +19 -0
  3. package/dist/adapters/createLLMEvaluator.d.ts.map +1 -0
  4. package/dist/adapters/createLLMEvaluator.js +150 -0
  5. package/dist/adapters/createLLMEvaluator.js.map +1 -0
  6. package/dist/adapters/models/anthropic.d.ts +15 -0
  7. package/dist/adapters/models/anthropic.d.ts.map +1 -0
  8. package/dist/adapters/models/anthropic.js +45 -0
  9. package/dist/adapters/models/anthropic.js.map +1 -0
  10. package/dist/adapters/models/gemini.d.ts +16 -0
  11. package/dist/adapters/models/gemini.d.ts.map +1 -0
  12. package/dist/adapters/models/gemini.js +58 -0
  13. package/dist/adapters/models/gemini.js.map +1 -0
  14. package/dist/adapters/models/lmStudioStreaming.d.ts +21 -0
  15. package/dist/adapters/models/lmStudioStreaming.d.ts.map +1 -0
  16. package/dist/adapters/models/lmStudioStreaming.js +90 -0
  17. package/dist/adapters/models/lmStudioStreaming.js.map +1 -0
  18. package/dist/adapters/models/lmstudio.d.ts +20 -0
  19. package/dist/adapters/models/lmstudio.d.ts.map +1 -0
  20. package/dist/adapters/models/lmstudio.js +59 -0
  21. package/dist/adapters/models/lmstudio.js.map +1 -0
  22. package/dist/adapters/models/ollama.d.ts +22 -0
  23. package/dist/adapters/models/ollama.d.ts.map +1 -0
  24. package/dist/adapters/models/ollama.js +61 -0
  25. package/dist/adapters/models/ollama.js.map +1 -0
  26. package/dist/adapters/models/ollamaStreaming.d.ts +30 -0
  27. package/dist/adapters/models/ollamaStreaming.d.ts.map +1 -0
  28. package/dist/adapters/models/ollamaStreaming.js +88 -0
  29. package/dist/adapters/models/ollamaStreaming.js.map +1 -0
  30. package/dist/adapters/models/openai.d.ts +17 -0
  31. package/dist/adapters/models/openai.d.ts.map +1 -0
  32. package/dist/adapters/models/openai.js +50 -0
  33. package/dist/adapters/models/openai.js.map +1 -0
  34. package/dist/defaults/defaultExecutor.d.ts +20 -0
  35. package/dist/defaults/defaultExecutor.d.ts.map +1 -0
  36. package/dist/defaults/defaultExecutor.js +67 -0
  37. package/dist/defaults/defaultExecutor.js.map +1 -0
  38. package/dist/defaults/llmPlanner.d.ts +20 -0
  39. package/dist/defaults/llmPlanner.d.ts.map +1 -0
  40. package/dist/defaults/llmPlanner.js +151 -0
  41. package/dist/defaults/llmPlanner.js.map +1 -0
  42. package/dist/defaults/planBuilder.d.ts +48 -0
  43. package/dist/defaults/planBuilder.d.ts.map +1 -0
  44. package/dist/defaults/planBuilder.js +105 -0
  45. package/dist/defaults/planBuilder.js.map +1 -0
  46. package/dist/defaults/singleStepPlanner.d.ts +17 -0
  47. package/dist/defaults/singleStepPlanner.d.ts.map +1 -0
  48. package/dist/defaults/singleStepPlanner.js +52 -0
  49. package/dist/defaults/singleStepPlanner.js.map +1 -0
  50. package/dist/evaluator/StepEvaluator.d.ts +9 -0
  51. package/dist/evaluator/StepEvaluator.d.ts.map +1 -0
  52. package/dist/evaluator/StepEvaluator.js +5 -0
  53. package/dist/evaluator/StepEvaluator.js.map +1 -0
  54. package/dist/events/EventBus.d.ts +13 -0
  55. package/dist/events/EventBus.d.ts.map +1 -0
  56. package/dist/events/EventBus.js +34 -0
  57. package/dist/events/EventBus.js.map +1 -0
  58. package/dist/executor/StepExecutor.d.ts +9 -0
  59. package/dist/executor/StepExecutor.d.ts.map +1 -0
  60. package/dist/executor/StepExecutor.js +5 -0
  61. package/dist/executor/StepExecutor.js.map +1 -0
  62. package/dist/index.d.ts +48 -0
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +22 -0
  65. package/dist/index.js.map +1 -0
  66. package/dist/models/ModelAdapter.d.ts +5 -0
  67. package/dist/models/ModelAdapter.d.ts.map +1 -0
  68. package/dist/models/ModelAdapter.js +5 -0
  69. package/dist/models/ModelAdapter.js.map +1 -0
  70. package/dist/planner/PlanValidator.d.ts +16 -0
  71. package/dist/planner/PlanValidator.d.ts.map +1 -0
  72. package/dist/planner/PlanValidator.js +44 -0
  73. package/dist/planner/PlanValidator.js.map +1 -0
  74. package/dist/planner/Planner.d.ts +10 -0
  75. package/dist/planner/Planner.d.ts.map +1 -0
  76. package/dist/planner/Planner.js +5 -0
  77. package/dist/planner/Planner.js.map +1 -0
  78. package/dist/quickStart.d.ts +49 -0
  79. package/dist/quickStart.d.ts.map +1 -0
  80. package/dist/quickStart.js +77 -0
  81. package/dist/quickStart.js.map +1 -0
  82. package/dist/runner/AgentRunner.d.ts +29 -0
  83. package/dist/runner/AgentRunner.d.ts.map +1 -0
  84. package/dist/runner/AgentRunner.js +223 -0
  85. package/dist/runner/AgentRunner.js.map +1 -0
  86. package/dist/runner/RunStateManager.d.ts +21 -0
  87. package/dist/runner/RunStateManager.d.ts.map +1 -0
  88. package/dist/runner/RunStateManager.js +96 -0
  89. package/dist/runner/RunStateManager.js.map +1 -0
  90. package/dist/runner/RunningExecution.d.ts +14 -0
  91. package/dist/runner/RunningExecution.d.ts.map +1 -0
  92. package/dist/runner/RunningExecution.js +5 -0
  93. package/dist/runner/RunningExecution.js.map +1 -0
  94. package/dist/runner/StepScheduler.d.ts +12 -0
  95. package/dist/runner/StepScheduler.d.ts.map +1 -0
  96. package/dist/runner/StepScheduler.js +42 -0
  97. package/dist/runner/StepScheduler.js.map +1 -0
  98. package/dist/runner/createAgentRunner.d.ts +32 -0
  99. package/dist/runner/createAgentRunner.d.ts.map +1 -0
  100. package/dist/runner/createAgentRunner.js +57 -0
  101. package/dist/runner/createAgentRunner.js.map +1 -0
  102. package/dist/runner/resolveInputs.d.ts +7 -0
  103. package/dist/runner/resolveInputs.d.ts.map +1 -0
  104. package/dist/runner/resolveInputs.js +28 -0
  105. package/dist/runner/resolveInputs.js.map +1 -0
  106. package/dist/tools/ToolAdapter.d.ts +5 -0
  107. package/dist/tools/ToolAdapter.d.ts.map +1 -0
  108. package/dist/tools/ToolAdapter.js +5 -0
  109. package/dist/tools/ToolAdapter.js.map +1 -0
  110. package/dist/types/errors.d.ts +28 -0
  111. package/dist/types/errors.d.ts.map +1 -0
  112. package/dist/types/errors.js +37 -0
  113. package/dist/types/errors.js.map +1 -0
  114. package/dist/types/evaluator.d.ts +14 -0
  115. package/dist/types/evaluator.d.ts.map +1 -0
  116. package/dist/types/evaluator.js +5 -0
  117. package/dist/types/evaluator.js.map +1 -0
  118. package/dist/types/events.d.ts +79 -0
  119. package/dist/types/events.d.ts.map +1 -0
  120. package/dist/types/events.js +17 -0
  121. package/dist/types/events.js.map +1 -0
  122. package/dist/types/executor.d.ts +18 -0
  123. package/dist/types/executor.d.ts.map +1 -0
  124. package/dist/types/executor.js +5 -0
  125. package/dist/types/executor.js.map +1 -0
  126. package/dist/types/models.d.ts +18 -0
  127. package/dist/types/models.d.ts.map +1 -0
  128. package/dist/types/models.js +6 -0
  129. package/dist/types/models.js.map +1 -0
  130. package/dist/types/plan.d.ts +37 -0
  131. package/dist/types/plan.d.ts.map +1 -0
  132. package/dist/types/plan.js +5 -0
  133. package/dist/types/plan.js.map +1 -0
  134. package/dist/types/planner.d.ts +24 -0
  135. package/dist/types/planner.d.ts.map +1 -0
  136. package/dist/types/planner.js +5 -0
  137. package/dist/types/planner.js.map +1 -0
  138. package/dist/types/run.d.ts +48 -0
  139. package/dist/types/run.d.ts.map +1 -0
  140. package/dist/types/run.js +14 -0
  141. package/dist/types/run.js.map +1 -0
  142. package/dist/types/step.d.ts +52 -0
  143. package/dist/types/step.d.ts.map +1 -0
  144. package/dist/types/step.js +5 -0
  145. package/dist/types/step.js.map +1 -0
  146. package/dist/types/tools.d.ts +21 -0
  147. package/dist/types/tools.d.ts.map +1 -0
  148. package/dist/types/tools.js +5 -0
  149. package/dist/types/tools.js.map +1 -0
  150. package/dist/utils/dag.d.ts +18 -0
  151. package/dist/utils/dag.d.ts.map +1 -0
  152. package/dist/utils/dag.js +77 -0
  153. package/dist/utils/dag.js.map +1 -0
  154. package/dist/utils/ids.d.ts +6 -0
  155. package/dist/utils/ids.d.ts.map +1 -0
  156. package/dist/utils/ids.js +11 -0
  157. package/dist/utils/ids.js.map +1 -0
  158. package/dist/utils/schema.d.ts +15 -0
  159. package/dist/utils/schema.d.ts.map +1 -0
  160. package/dist/utils/schema.js +11 -0
  161. package/dist/utils/schema.js.map +1 -0
  162. package/dist/utils/time.d.ts +6 -0
  163. package/dist/utils/time.d.ts.map +1 -0
  164. package/dist/utils/time.js +10 -0
  165. package/dist/utils/time.js.map +1 -0
  166. package/package.json +50 -0
package/README.md ADDED
@@ -0,0 +1,140 @@
1
+ # pocket-agent
2
+
3
+ **Plan-driven agent orchestration for Node.** You plug in a planner, executor, and evaluator (e.g. backed by any LLM); the framework runs the loop-plan → steps → evaluate → retry or replan-so you don’t re-implement it.
4
+
5
+ **Author:** sam_thewise
6
+
7
+ ---
8
+
9
+ ### In a nutshell
10
+
11
+ - **Goal in → plan → steps → evaluate → done.** You give a goal; we get a machine-readable plan, run steps in dependency order, evaluate completion, and retry or replan as needed.
12
+ - **You bring:** planner, executor, evaluator (and optional tools). **We bring:** scheduling, lifecycle events, retries, and structured outputs.
13
+ - **Pocket** = small, drop-in. **Agent** = orchestration that turns your LLM into a plan-first workflow.
14
+
15
+ ---
16
+
17
+ ### What this does (plain terms)
18
+
19
+ You give a **goal** (e.g. “Summarize this contract” or “How does this codebase work?”). The library turns that into a **plan**: a ordered list of **steps**, each with a clear objective and inputs/outputs. It runs the steps one by one (or in order when steps depend on each other), uses your **model** (LLM) and optional **tools** to do the work, then asks an **evaluator** whether each step is actually done. If not, it retries or replans; when everything’s done, you get a single result with all the step outputs. You don’t wire the loop yourself-you plug in *how* to plan, *how* to run a step, and *how* to judge completion; the **runner** does the rest.
20
+
21
+ **Terms you’ll see:**
22
+
23
+ | Term | Meaning |
24
+ |------|--------|
25
+ | **Runner** | The thing you create with `createAgentRunner` or `createQuickAgent`. It runs the full loop: create plan → run steps → evaluate → retry/replan → return result. |
26
+ | **Plan** | A list of **steps** (each has an id, objective, inputs, outputs, dependencies). The runner executes steps in an order that respects dependencies. |
27
+ | **Planner** | Your code (or a built-in) that, given a goal and context, produces a **plan**. “What steps do we need to achieve this goal?” |
28
+ | **Executor** | Your code (or a built-in) that runs *one* step. It gets the step definition, resolved inputs, and optional **model** and **tools**; it returns the step’s output (or error). “Do this step.” |
29
+ | **Evaluator** | Your code (or a built-in LLM evaluator) that, given a step and its attempt result, says whether the step is **complete**, should **retry**, **replan**, or **failed**. “Is this step actually done?” |
30
+ | **Tools** | Optional functions the executor can call during a step (e.g. read a file, call an API). The plan says which steps are allowed to use which tools. |
31
+ | **Model** | The LLM (OpenAI, Anthropic, Gemini, Ollama, etc.) used by the executor (and often the evaluator). You pass it via a **provider** + API key or a custom adapter. |
32
+ | **Provider** | Shortcut name for a model backend: `"openai"`, `"anthropic"`, `"gemini"`, `"ollama"`, `"lmstudio"`. Setting `provider` lets the library create the model adapter and a default evaluator from env. |
33
+
34
+ Once these mean something, the rest of the doc (quick start, fluent plan, default evaluators, contracts) should fall into place.
35
+
36
+ ---
37
+
38
+ ## Features
39
+
40
+ - **Explicit plans** - Machine-readable step list before execution
41
+ - **Dependency-ordered execution** - Steps run when their dependencies are satisfied
42
+ - **Lifecycle events** - `run.started`, `plan.created`, `step.started`, `step.completed`, `run.completed`, etc.
43
+ - **Bounded retries** - Evaluator-driven completion with configurable retry policy
44
+ - **Structured outputs** - Per-step and final run outputs
45
+
46
+ ## Install
47
+
48
+ ```bash
49
+ npm install pocket-agent
50
+ ```
51
+
52
+ ## Examples (quick start)
53
+
54
+ ### 1. Super quick start (one call)
55
+
56
+ Set your API key in the environment, then create and run in two lines. Uses a single-step plan and the LLM to answer; no planner or executor code to write.
57
+
58
+ ```ts
59
+ import { createQuickAgent } from "pocket-agent";
60
+
61
+ const runner = createQuickAgent({ provider: "openai" });
62
+ const run = await runner.run({ goal: "What is 2+2? Explain in one sentence." });
63
+
64
+ console.log(run.outputs?.answer);
65
+ ```
66
+
67
+ Supported `provider`: `"openai"` | `"anthropic"` | `"gemini"` | `"ollama"` | `"lmstudio"`. Each reads from env (e.g. `OPENAI_API_KEY`, `OPENAI_MODEL`). Optional `modelConfig` and `systemPrompt`. No tools in this mode; for tools and multi-step plans, see the docs below.
68
+
69
+ ### 2. Goal-only with LLM-generated steps
70
+
71
+ Give a goal and let the LLM invent the plan (the list of steps). Use `createGoalDrivenAgent` with `useLLMPlanner: true`:
72
+
73
+ ```ts
74
+ import { createGoalDrivenAgent } from "pocket-agent";
75
+
76
+ const runner = createGoalDrivenAgent({
77
+ provider: "openai",
78
+ useLLMPlanner: true,
79
+ llmPlannerOptions: { maxSteps: 5, planHint: "Use 2–4 clear steps." },
80
+ });
81
+
82
+ const run = await runner.run({
83
+ goal: "Explain what an API is in three short steps: definition, why it matters, one example.",
84
+ });
85
+
86
+ console.log(run.plan.steps); // steps were generated by the LLM
87
+ console.log(run.outputs);
88
+ ```
89
+
90
+ ### 3. Custom planner and executor
91
+
92
+ When you want your own plan or execution logic, use `createAgentRunner` with a planner, executor, and evaluator (or `provider` for a default evaluator):
93
+
94
+ ```ts
95
+ import { createAgentRunner } from "pocket-agent";
96
+
97
+ const runner = createAgentRunner({
98
+ provider: "openai",
99
+ planner, // your Planner or use createFixedPlanPlanner(steps)
100
+ executor, // your StepExecutor or use createDefaultExecutor({ model })
101
+ tools: {}, // optional
102
+ });
103
+
104
+ const run = await runner.run({
105
+ goal: "Find the latest contract, extract payment terms, and summarize risks.",
106
+ context: { customerId: "abc123" },
107
+ });
108
+ ```
109
+
110
+ For fluent step definitions and a minimal planner/executor/evaluator, see the docs below.
111
+
112
+ ---
113
+
114
+ ## Documentation
115
+
116
+ More guides live under **`docs/`** (links work on GitHub):
117
+
118
+ | Doc | Description |
119
+ |-----|-------------|
120
+ | [Fluent plan and defaults](docs/fluent-plan-and-defaults.md) | Build plans with `step()` + `createFixedPlanPlanner` and run with `createDefaultExecutor`. |
121
+ | [Custom planner and executor](docs/custom-planner-executor.md) | Minimal planner, executor, and evaluator (full code). |
122
+ | [Default evaluators and providers](docs/default-evaluators-and-providers.md) | Provider table, `provider` in `createAgentRunner`, adapters. |
123
+ | [Contracts](docs/contracts.md) | Planner, StepExecutor, StepEvaluator, Tools. |
124
+ | [Events](docs/events.md) | Event-driven usage with `runner.start()`. |
125
+ | [API key and local models](docs/api-key-and-local-models.md) | Cloud (OpenAI), Ollama, LM Studio, tools, project planner. |
126
+ | [Examples](docs/examples.md) | All runnable scripts (`npm run example:*`). |
127
+
128
+ ## Scripts
129
+
130
+ - `npm run build` - compile TypeScript to `dist/`
131
+ - `npm test` - run tests
132
+ - `npm run test:watch` - run tests in watch mode
133
+ - `npm run example:quick-start` - quick-start example
134
+ - `npm run example:fluent-plan` - fluent plan example
135
+ - `npm run example:goal-driven-llm` - goal-only with LLM-generated steps
136
+ - `npm run example:minimal` - minimal planner/executor/evaluator (no API key)
137
+ - `npm run example:openai` - full run with tools (OpenAI or local)
138
+ - `npm run example:planner` - project structure from a description
139
+
140
+ See [docs/examples.md](docs/examples.md) for the full list and what each script does.
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Default LLM-based step evaluator. Uses any ModelAdapter to judge whether a step
3
+ * attempt satisfies the step's completion criteria.
4
+ */
5
+ import type { StepEvaluator } from "../evaluator/StepEvaluator.js";
6
+ import type { ModelAdapter } from "../types/models.js";
7
+ export interface LLMEvaluatorOptions {
8
+ /** If true, ask the model to return JSON in a ```json block. Default true. */
9
+ useJsonBlock?: boolean;
10
+ /** Max length of rawOutput to include in the prompt. Default 8000. */
11
+ maxOutputChars?: number;
12
+ }
13
+ /**
14
+ * Creates a step evaluator that uses the given model to judge whether a step
15
+ * attempt satisfies the step's completion criteria. Works with any ModelAdapter
16
+ * (OpenAI, Anthropic, Gemini, or custom).
17
+ */
18
+ export declare function createLLMEvaluator(model: ModelAdapter, options?: LLMEvaluatorOptions): StepEvaluator;
19
+ //# sourceMappingURL=createLLMEvaluator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createLLMEvaluator.d.ts","sourceRoot":"","sources":["../../src/adapters/createLLMEvaluator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,sEAAsE;IACtE,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AA+HD;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,mBAAwB,GAChC,aAAa,CAuBf"}
@@ -0,0 +1,150 @@
1
+ /**
2
+ * Default LLM-based step evaluator. Uses any ModelAdapter to judge whether a step
3
+ * attempt satisfies the step's completion criteria.
4
+ */
5
+ const DEFAULT_OPTIONS = {
6
+ useJsonBlock: true,
7
+ maxOutputChars: 8000,
8
+ };
9
+ function truncate(s, max) {
10
+ if (s.length <= max)
11
+ return s;
12
+ return s.slice(0, max) + "\n...[truncated]";
13
+ }
14
+ function buildPrompt(input, options) {
15
+ const { step, attemptResult, priorAttempts } = input;
16
+ const rawStr = attemptResult.rawOutput != null
17
+ ? typeof attemptResult.rawOutput === "string"
18
+ ? attemptResult.rawOutput
19
+ : JSON.stringify(attemptResult.rawOutput, null, 2)
20
+ : "";
21
+ const structuredStr = attemptResult.structuredOutput != null
22
+ ? JSON.stringify(attemptResult.structuredOutput, null, 2)
23
+ : "(none)";
24
+ const rawTruncated = truncate(rawStr, options.maxOutputChars);
25
+ const criteria = (step.completionCriteria ?? []).join("\n- ");
26
+ const priorSummary = priorAttempts.length > 0
27
+ ? `\nPrior attempts: ${priorAttempts.length}. Last had status: ${priorAttempts[priorAttempts.length - 1]?.status}.`
28
+ : "";
29
+ const jsonInstruction = options.useJsonBlock
30
+ ? `Respond with a single JSON object in a fenced code block (\\\`\\\`\\\`json ... \\\`\\\`\\\`). The JSON must have:
31
+ - "verdict": one of "complete", "retry", "needs_replan", "failed"
32
+ - "reasons": array of short strings explaining your decision
33
+ - "missingCriteria" (optional): array of criteria not yet satisfied
34
+ - "confidence" (optional): number 0-1
35
+ - "suggestedAction" (optional): string for retry/replan`
36
+ : `Respond with exactly:
37
+ VERDICT: complete|retry|needs_replan|failed
38
+ REASONS: one or more short lines
39
+ Optional lines: MISSING_CRITERIA: ... CONFIDENCE: 0-1 SUGGESTED_ACTION: ...`;
40
+ return `You are evaluating whether a step in a plan-driven agent run is complete.
41
+
42
+ Step:
43
+ - id: ${step.id}
44
+ - name: ${step.name ?? step.id}
45
+ - objective: ${step.objective}
46
+ - expected outputs: ${(step.outputs ?? []).join(", ")}
47
+
48
+ Completion criteria (all should be satisfied for "complete"):
49
+ - ${criteria || "(none specified)"}
50
+
51
+ Attempt result:
52
+ - status: ${attemptResult.status}
53
+ - structuredOutput: ${structuredStr}
54
+ - rawOutput (excerpt): ${rawTruncated}${priorSummary}
55
+
56
+ Is this step complete, should we retry, replan, or mark failed?
57
+
58
+ ${jsonInstruction}`;
59
+ }
60
+ function parseResponse(content, stepId, attempt, useJsonBlock) {
61
+ const verdicts = ["complete", "retry", "needs_replan", "failed"];
62
+ let verdict = "complete";
63
+ let reasons = [];
64
+ let missingCriteria;
65
+ let confidence;
66
+ let suggestedAction;
67
+ if (useJsonBlock) {
68
+ const blockMatch = content.match(/```(?:json)?\s*([\s\S]*?)```/);
69
+ const jsonStr = blockMatch ? blockMatch[1].trim() : content.trim();
70
+ try {
71
+ const obj = JSON.parse(jsonStr);
72
+ const v = obj.verdict;
73
+ if (typeof v === "string" && verdicts.includes(v)) {
74
+ verdict = v;
75
+ }
76
+ if (Array.isArray(obj.reasons)) {
77
+ reasons = obj.reasons.filter((r) => typeof r === "string");
78
+ }
79
+ else if (typeof obj.reasons === "string") {
80
+ reasons = [obj.reasons];
81
+ }
82
+ if (Array.isArray(obj.missingCriteria)) {
83
+ missingCriteria = obj.missingCriteria.filter((m) => typeof m === "string");
84
+ }
85
+ if (typeof obj.confidence === "number")
86
+ confidence = obj.confidence;
87
+ if (typeof obj.suggestedAction === "string")
88
+ suggestedAction = obj.suggestedAction;
89
+ }
90
+ catch {
91
+ reasons = ["Could not parse model JSON; treating as complete"];
92
+ }
93
+ }
94
+ else {
95
+ const lineMap = {};
96
+ for (const line of content.split("\n")) {
97
+ const [key, ...rest] = line.split(":");
98
+ const value = rest.join(":").trim();
99
+ if (key && value)
100
+ lineMap[key.trim().toUpperCase()] = value;
101
+ }
102
+ const v = lineMap["VERDICT"]?.toLowerCase();
103
+ if (v && verdicts.includes(v))
104
+ verdict = v;
105
+ if (lineMap["REASONS"])
106
+ reasons = [lineMap["REASONS"]];
107
+ if (lineMap["MISSING_CRITERIA"])
108
+ missingCriteria = [lineMap["MISSING_CRITERIA"]];
109
+ if (lineMap["CONFIDENCE"])
110
+ confidence = parseFloat(lineMap["CONFIDENCE"]);
111
+ if (lineMap["SUGGESTED_ACTION"])
112
+ suggestedAction = lineMap["SUGGESTED_ACTION"];
113
+ }
114
+ if (reasons.length === 0)
115
+ reasons = [verdict === "complete" ? "Criteria satisfied" : "See verdict"];
116
+ return {
117
+ stepId,
118
+ attempt,
119
+ verdict,
120
+ reasons,
121
+ missingCriteria,
122
+ confidence,
123
+ suggestedAction,
124
+ };
125
+ }
126
+ /**
127
+ * Creates a step evaluator that uses the given model to judge whether a step
128
+ * attempt satisfies the step's completion criteria. Works with any ModelAdapter
129
+ * (OpenAI, Anthropic, Gemini, or custom).
130
+ */
131
+ export function createLLMEvaluator(model, options = {}) {
132
+ const opts = { ...DEFAULT_OPTIONS, ...options };
133
+ return {
134
+ async evaluate(input) {
135
+ const prompt = buildPrompt(input, opts);
136
+ const out = await model.generate({ prompt });
137
+ const content = (out.content ?? "").trim();
138
+ if (!content) {
139
+ return {
140
+ stepId: input.step.id,
141
+ attempt: input.attemptResult.attempt,
142
+ verdict: "retry",
143
+ reasons: ["Model returned no content for evaluation"],
144
+ };
145
+ }
146
+ return parseResponse(content, input.step.id, input.attemptResult.attempt, opts.useJsonBlock);
147
+ },
148
+ };
149
+ }
150
+ //# sourceMappingURL=createLLMEvaluator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createLLMEvaluator.js","sourceRoot":"","sources":["../../src/adapters/createLLMEvaluator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Anthropic Claude model adapter. Uses ANTHROPIC_API_KEY, ANTHROPIC_MODEL,
3
+ * ANTHROPIC_MAX_TOKENS from env when not provided.
4
+ */
5
+ import type { ModelAdapter } from "../../types/models.js";
6
+ export interface AnthropicModelConfig {
7
+ apiKey?: string;
8
+ model?: string;
9
+ maxTokens?: number;
10
+ }
11
+ /**
12
+ * Creates a ModelAdapter for Anthropic Claude. Install the SDK: npm install @anthropic-ai/sdk
13
+ */
14
+ export declare function createAnthropicModelAdapter(config?: AnthropicModelConfig): ModelAdapter;
15
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/adapters/models/anthropic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,GAAE,oBAAyB,GAAG,YAAY,CAqC3F"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Anthropic Claude model adapter. Uses ANTHROPIC_API_KEY, ANTHROPIC_MODEL,
3
+ * ANTHROPIC_MAX_TOKENS from env when not provided.
4
+ */
5
+ const defaultConfig = () => ({
6
+ apiKey: process.env.ANTHROPIC_API_KEY,
7
+ model: process.env.ANTHROPIC_MODEL ?? process.env.MODEL ?? "claude-3-5-sonnet-20241022",
8
+ maxTokens: process.env.ANTHROPIC_MAX_TOKENS
9
+ ? parseInt(process.env.ANTHROPIC_MAX_TOKENS, 10)
10
+ : 4096,
11
+ });
12
+ /**
13
+ * Creates a ModelAdapter for Anthropic Claude. Install the SDK: npm install @anthropic-ai/sdk
14
+ */
15
+ export function createAnthropicModelAdapter(config = {}) {
16
+ const opts = { ...defaultConfig(), ...config };
17
+ if (!opts.apiKey) {
18
+ throw new Error("Anthropic adapter requires ANTHROPIC_API_KEY. Set it in env or pass apiKey in config.");
19
+ }
20
+ return {
21
+ async generate(input) {
22
+ const Anthropic = (await import("@anthropic-ai/sdk").catch(() => {
23
+ throw new Error("Anthropic adapter requires the '@anthropic-ai/sdk' package. Install it: npm install @anthropic-ai/sdk");
24
+ })).default;
25
+ const client = new Anthropic({ apiKey: opts.apiKey });
26
+ const prompt = typeof input.prompt === "string"
27
+ ? input.prompt
28
+ : Array.isArray(input.messages) && input.messages.length
29
+ ? input.messages
30
+ .map((m) => `${m.role}: ${m.content}`)
31
+ .join("\n")
32
+ : "";
33
+ const maxTokens = Number.isFinite(opts.maxTokens) && opts.maxTokens > 0 ? opts.maxTokens : 4096;
34
+ const message = await client.messages.create({
35
+ model: opts.model ?? "claude-3-5-sonnet-20241022",
36
+ max_tokens: maxTokens,
37
+ messages: [{ role: "user", content: prompt }],
38
+ });
39
+ const textBlock = message.content?.find((b) => b.type === "text");
40
+ const content = textBlock?.text ?? "";
41
+ return { content, raw: message };
42
+ },
43
+ };
44
+ }
45
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/adapters/models/anthropic.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAUH,MAAM,aAAa,GAAG,GAAyB,EAAE,CAAC,CAAC;IACjD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB;IACrC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,4BAA4B;IACvF,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;QACzC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,EAAE,CAAC;QAChD,CAAC,CAAC,IAAI;CACT,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,UAAU,2BAA2B,CAAC,SAA+B,EAAE;IAC3E,MAAM,IAAI,GAAG,EAAE,GAAG,aAAa,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC;IAC/C,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CACb,uFAAuF,CACxF,CAAC;IACJ,CAAC;IACD,OAAO;QACL,KAAK,CAAC,QAAQ,CAAC,KAAK;YAClB,MAAM,SAAS,GAAG,CAAC,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE;gBAC9D,MAAM,IAAI,KAAK,CACb,uGAAuG,CACxG,CAAC;YACJ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YACZ,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;YACtD,MAAM,MAAM,GACV,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;gBAC9B,CAAC,CAAC,KAAK,CAAC,MAAM;gBACd,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM;oBACtD,CAAC,CAAE,KAAK,CAAC,QAAgD;yBACpD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,OAAO,EAAE,CAAC;yBACrC,IAAI,CAAC,IAAI,CAAC;oBACf,CAAC,CAAC,EAAE,CAAC;YACX,MAAM,SAAS,GACb,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,SAAU,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAU,CAAC,CAAC,CAAC,IAAI,CAAC;YAClF,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC3C,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,4BAA4B;gBACjD,UAAU,EAAE,SAAS;gBACrB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;aAC9C,CAAC,CAAC;YACH,MAAM,SAAS,GAAG,OAAO,CAAC,OAAO,EAAE,IAAI,CACrC,CAAC,CAAkC,EAAuC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAC/F,CAAC;YACF,MAAM,OAAO,GAAG,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC;YACtC,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Google Gemini model adapter. Uses GEMINI_API_KEY (or GOOGLE_GENAI_API_KEY),
3
+ * GEMINI_MODEL, GEMINI_MAX_TOKENS from env when not provided.
4
+ * Uses the @google/genai SDK (recommended); falls back to @google/generative-ai if needed.
5
+ */
6
+ import type { ModelAdapter } from "../../types/models.js";
7
+ export interface GeminiModelConfig {
8
+ apiKey?: string;
9
+ model?: string;
10
+ maxTokens?: number;
11
+ }
12
+ /**
13
+ * Creates a ModelAdapter for Google Gemini. Install the SDK: npm install @google/genai
14
+ */
15
+ export declare function createGeminiModelAdapter(config?: GeminiModelConfig): ModelAdapter;
16
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/adapters/models/gemini.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,GAAE,iBAAsB,GAAG,YAAY,CAkDrF"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Google Gemini model adapter. Uses GEMINI_API_KEY (or GOOGLE_GENAI_API_KEY),
3
+ * GEMINI_MODEL, GEMINI_MAX_TOKENS from env when not provided.
4
+ * Uses the @google/genai SDK (recommended); falls back to @google/generative-ai if needed.
5
+ */
6
+ const defaultConfig = () => ({
7
+ apiKey: process.env.GEMINI_API_KEY ?? process.env.GOOGLE_GENAI_API_KEY ?? process.env.GOOGLE_API_KEY,
8
+ model: process.env.GEMINI_MODEL ?? process.env.MODEL ?? "gemini-2.0-flash",
9
+ maxTokens: process.env.GEMINI_MAX_TOKENS
10
+ ? parseInt(process.env.GEMINI_MAX_TOKENS, 10)
11
+ : 4096,
12
+ });
13
+ /**
14
+ * Creates a ModelAdapter for Google Gemini. Install the SDK: npm install @google/genai
15
+ */
16
+ export function createGeminiModelAdapter(config = {}) {
17
+ const opts = { ...defaultConfig(), ...config };
18
+ if (!opts.apiKey) {
19
+ throw new Error("Gemini adapter requires GEMINI_API_KEY (or GOOGLE_GENAI_API_KEY). Set it in env or pass apiKey in config.");
20
+ }
21
+ return {
22
+ async generate(input) {
23
+ const prompt = typeof input.prompt === "string"
24
+ ? input.prompt
25
+ : Array.isArray(input.messages) && input.messages.length
26
+ ? input.messages
27
+ .map((m) => `${m.role}: ${m.content}`)
28
+ .join("\n")
29
+ : "";
30
+ const maxTokens = Number.isFinite(opts.maxTokens) && opts.maxTokens > 0 ? opts.maxTokens : 4096;
31
+ // Prefer @google/genai (new SDK)
32
+ try {
33
+ const { GoogleGenAI } = await import("@google/genai");
34
+ const ai = new GoogleGenAI({ apiKey: opts.apiKey });
35
+ const res = await ai.models.generateContent({
36
+ model: opts.model ?? "gemini-2.0-flash",
37
+ contents: prompt,
38
+ config: { maxOutputTokens: maxTokens },
39
+ });
40
+ const text = res.text ??
41
+ res
42
+ .candidates?.[0]?.content?.parts?.filter((p) => typeof p.text === "string")
43
+ .map((p) => p.text)
44
+ .join("") ??
45
+ "";
46
+ return { content: text, raw: res };
47
+ }
48
+ catch (e) {
49
+ const err = e;
50
+ if (err?.code === "ERR_MODULE_NOT_FOUND" || err?.message?.includes("Cannot find module")) {
51
+ throw new Error("Gemini adapter requires the '@google/genai' package. Install it: npm install @google/genai");
52
+ }
53
+ throw e;
54
+ }
55
+ },
56
+ };
57
+ }
58
+ //# sourceMappingURL=gemini.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/adapters/models/gemini.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * LM Studio native streaming: POST /api/v1/chat with stream: true.
3
+ * Separates reasoning from message content. See https://lmstudio.ai/docs/developer/rest/streaming-events
4
+ */
5
+ export interface LMStudioStreamingOptions {
6
+ baseUrl: string;
7
+ model: string;
8
+ systemPrompt?: string;
9
+ userMessage: string;
10
+ temperature?: number;
11
+ maxOutputTokens?: number;
12
+ apiKey?: string;
13
+ }
14
+ export interface LMStudioStreamingResult {
15
+ content: string;
16
+ reasoning?: string;
17
+ }
18
+ export declare function lmStudioStreamingChat(options: LMStudioStreamingOptions): Promise<LMStudioStreamingResult>;
19
+ /** Strip /v1 from base URL for LM Studio native API. */
20
+ export declare function getLMStudioBaseUrl(openAIBaseUrl: string | undefined): string | null;
21
+ //# sourceMappingURL=lmStudioStreaming.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lmStudioStreaming.d.ts","sourceRoot":"","sources":["../../../src/adapters/models/lmStudioStreaming.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,uBAAuB,CAAC,CA6FlC;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,aAAa,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,IAAI,CAInF"}
@@ -0,0 +1,90 @@
1
+ /**
2
+ * LM Studio native streaming: POST /api/v1/chat with stream: true.
3
+ * Separates reasoning from message content. See https://lmstudio.ai/docs/developer/rest/streaming-events
4
+ */
5
+ export async function lmStudioStreamingChat(options) {
6
+ const { baseUrl, model, systemPrompt, userMessage, temperature, maxOutputTokens, apiKey, } = options;
7
+ const url = `${baseUrl.replace(/\/$/, "")}/api/v1/chat`;
8
+ const body = {
9
+ model,
10
+ input: userMessage,
11
+ stream: true,
12
+ };
13
+ if (systemPrompt != null && systemPrompt !== "")
14
+ body.system_prompt = systemPrompt;
15
+ if (temperature != null)
16
+ body.temperature = temperature;
17
+ if (maxOutputTokens != null && maxOutputTokens > 0)
18
+ body.max_output_tokens = maxOutputTokens;
19
+ const headers = { "Content-Type": "application/json" };
20
+ if (apiKey && apiKey !== "local")
21
+ headers.Authorization = `Bearer ${apiKey}`;
22
+ const res = await fetch(url, { method: "POST", headers, body: JSON.stringify(body) });
23
+ if (!res.ok || !res.body) {
24
+ throw new Error(`LM Studio chat failed: ${res.status} ${res.statusText}`);
25
+ }
26
+ const reasoningChunks = [];
27
+ const messageChunks = [];
28
+ let currentEvent = null;
29
+ const decoder = new TextDecoder();
30
+ let buffer = "";
31
+ for await (const chunk of res.body) {
32
+ buffer += decoder.decode(chunk, { stream: true });
33
+ const lines = buffer.split("\n");
34
+ buffer = lines.pop() ?? "";
35
+ for (const line of lines) {
36
+ if (line.startsWith("event: ")) {
37
+ currentEvent = line.slice(7).trim();
38
+ continue;
39
+ }
40
+ if (line.startsWith("data: ")) {
41
+ const dataStr = line.slice(6).trim();
42
+ if (dataStr === "" || dataStr === "[DONE]") {
43
+ currentEvent = null;
44
+ continue;
45
+ }
46
+ try {
47
+ const data = JSON.parse(dataStr);
48
+ const eventType = (currentEvent ?? data.type);
49
+ if (eventType === "reasoning.delta" && typeof data.content === "string") {
50
+ reasoningChunks.push(data.content);
51
+ }
52
+ if (eventType === "message.delta" && typeof data.content === "string") {
53
+ messageChunks.push(data.content);
54
+ }
55
+ if (eventType === "chat.end") {
56
+ const result = (data.result ?? data);
57
+ const output = result?.output ?? (Array.isArray(data.output) ? data.output : null);
58
+ if (Array.isArray(output)) {
59
+ const messages = output
60
+ .filter((item) => item?.type === "message" && typeof item.content === "string")
61
+ .map((item) => item.content);
62
+ if (messages.length > 0) {
63
+ messageChunks.length = 0;
64
+ messageChunks.push(messages.join("\n"));
65
+ }
66
+ }
67
+ }
68
+ }
69
+ catch {
70
+ // ignore malformed data line
71
+ }
72
+ currentEvent = null;
73
+ }
74
+ }
75
+ }
76
+ const content = messageChunks.join("").trim();
77
+ const reasoning = reasoningChunks.length > 0 ? reasoningChunks.join("") : undefined;
78
+ if (!content && res.ok) {
79
+ throw new Error("LM Studio stream returned no message content (check event format or use OpenAI-compatible endpoint)");
80
+ }
81
+ return { content, reasoning };
82
+ }
83
+ /** Strip /v1 from base URL for LM Studio native API. */
84
+ export function getLMStudioBaseUrl(openAIBaseUrl) {
85
+ if (!openAIBaseUrl)
86
+ return null;
87
+ const u = openAIBaseUrl.replace(/\/v1\/?$/, "");
88
+ return u || null;
89
+ }
90
+ //# sourceMappingURL=lmStudioStreaming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lmStudioStreaming.js","sourceRoot":"","sources":["../../../src/adapters/models/lmStudioStreaming.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * LM Studio model adapter. Supports OpenAI-compatible API and optional native
3
+ * streaming (POST /api/v1/chat with stream: true) to separate reasoning from message.
4
+ */
5
+ import type { ModelAdapter } from "../../types/models.js";
6
+ export interface LmStudioModelConfig {
7
+ baseURL?: string;
8
+ model?: string;
9
+ maxTokens?: number;
10
+ /** Use LM Studio native streaming for generate() when true. Default from USE_LM_STUDIO_STREAMING env. */
11
+ useNativeStreaming?: boolean;
12
+ apiKey?: string;
13
+ }
14
+ /**
15
+ * Creates a ModelAdapter for LM Studio. When useNativeStreaming is true, generate()
16
+ * uses LM Studio's native streaming API (reasoning and message separated).
17
+ * Otherwise uses the OpenAI-compatible endpoint. Install the `openai` package for non-streaming.
18
+ */
19
+ export declare function createLmStudioModelAdapter(config?: LmStudioModelConfig): ModelAdapter;
20
+ //# sourceMappingURL=lmstudio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lmstudio.d.ts","sourceRoot":"","sources":["../../../src/adapters/models/lmstudio.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AAM1D,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yGAAyG;IACzG,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAiBD;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,GAAE,mBAAwB,GAAG,YAAY,CAsCzF"}