@sensigo/realm-cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +109 -0
- package/dist/agent/agent-utils.d.ts +27 -0
- package/dist/agent/agent-utils.d.ts.map +1 -0
- package/dist/agent/agent-utils.js +79 -0
- package/dist/agent/agent-utils.js.map +1 -0
- package/dist/agent/anthropic-provider.d.ts +23 -0
- package/dist/agent/anthropic-provider.d.ts.map +1 -0
- package/dist/agent/anthropic-provider.js +245 -0
- package/dist/agent/anthropic-provider.js.map +1 -0
- package/dist/agent/gate/slack-gate-notifier.d.ts +80 -0
- package/dist/agent/gate/slack-gate-notifier.d.ts.map +1 -0
- package/dist/agent/gate/slack-gate-notifier.js +315 -0
- package/dist/agent/gate/slack-gate-notifier.js.map +1 -0
- package/dist/agent/gate/slack-gate-server.d.ts +30 -0
- package/dist/agent/gate/slack-gate-server.d.ts.map +1 -0
- package/dist/agent/gate/slack-gate-server.js +99 -0
- package/dist/agent/gate/slack-gate-server.js.map +1 -0
- package/dist/agent/gate/slack-socket-client.d.ts +20 -0
- package/dist/agent/gate/slack-socket-client.d.ts.map +1 -0
- package/dist/agent/gate/slack-socket-client.js +141 -0
- package/dist/agent/gate/slack-socket-client.js.map +1 -0
- package/dist/agent/gate-intent-interpreter.d.ts +29 -0
- package/dist/agent/gate-intent-interpreter.d.ts.map +1 -0
- package/dist/agent/gate-intent-interpreter.js +33 -0
- package/dist/agent/gate-intent-interpreter.js.map +1 -0
- package/dist/agent/index.d.ts +4 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +4 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/llm-provider.d.ts +46 -0
- package/dist/agent/llm-provider.d.ts.map +1 -0
- package/dist/agent/llm-provider.js +55 -0
- package/dist/agent/llm-provider.js.map +1 -0
- package/dist/agent/mcp/mcp-client.d.ts +18 -0
- package/dist/agent/mcp/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp/mcp-client.js +108 -0
- package/dist/agent/mcp/mcp-client.js.map +1 -0
- package/dist/agent/mcp/mcp-extensions.d.ts +40 -0
- package/dist/agent/mcp/mcp-extensions.d.ts.map +1 -0
- package/dist/agent/mcp/mcp-extensions.js +2 -0
- package/dist/agent/mcp/mcp-extensions.js.map +1 -0
- package/dist/agent/mcp-client.d.ts +18 -0
- package/dist/agent/mcp-client.d.ts.map +1 -0
- package/dist/agent/mcp-client.js +108 -0
- package/dist/agent/mcp-client.js.map +1 -0
- package/dist/agent/mcp-types.d.ts +40 -0
- package/dist/agent/mcp-types.d.ts.map +1 -0
- package/dist/agent/mcp-types.js +2 -0
- package/dist/agent/mcp-types.js.map +1 -0
- package/dist/agent/openai-provider.d.ts +30 -0
- package/dist/agent/openai-provider.d.ts.map +1 -0
- package/dist/agent/openai-provider.js +253 -0
- package/dist/agent/openai-provider.js.map +1 -0
- package/dist/agent/openai-reasoning-provider.d.ts +18 -0
- package/dist/agent/openai-reasoning-provider.d.ts.map +1 -0
- package/dist/agent/openai-reasoning-provider.js +76 -0
- package/dist/agent/openai-reasoning-provider.js.map +1 -0
- package/dist/agent/preflight.d.ts +36 -0
- package/dist/agent/preflight.d.ts.map +1 -0
- package/dist/agent/preflight.js +81 -0
- package/dist/agent/preflight.js.map +1 -0
- package/dist/agent/providers/agent-utils.d.ts +27 -0
- package/dist/agent/providers/agent-utils.d.ts.map +1 -0
- package/dist/agent/providers/agent-utils.js +79 -0
- package/dist/agent/providers/agent-utils.js.map +1 -0
- package/dist/agent/providers/anthropic-provider.d.ts +23 -0
- package/dist/agent/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/agent/providers/anthropic-provider.js +257 -0
- package/dist/agent/providers/anthropic-provider.js.map +1 -0
- package/dist/agent/providers/llm-provider.d.ts +46 -0
- package/dist/agent/providers/llm-provider.d.ts.map +1 -0
- package/dist/agent/providers/llm-provider.js +56 -0
- package/dist/agent/providers/llm-provider.js.map +1 -0
- package/dist/agent/providers/openai-provider.d.ts +30 -0
- package/dist/agent/providers/openai-provider.d.ts.map +1 -0
- package/dist/agent/providers/openai-provider.js +253 -0
- package/dist/agent/providers/openai-provider.js.map +1 -0
- package/dist/agent/providers/openai-reasoning-provider.d.ts +19 -0
- package/dist/agent/providers/openai-reasoning-provider.d.ts.map +1 -0
- package/dist/agent/providers/openai-reasoning-provider.js +89 -0
- package/dist/agent/providers/openai-reasoning-provider.js.map +1 -0
- package/dist/agent/run-agent.d.ts +50 -0
- package/dist/agent/run-agent.d.ts.map +1 -0
- package/dist/agent/run-agent.js +327 -0
- package/dist/agent/run-agent.js.map +1 -0
- package/dist/agent/slack-gate-notifier.d.ts +80 -0
- package/dist/agent/slack-gate-notifier.d.ts.map +1 -0
- package/dist/agent/slack-gate-notifier.js +315 -0
- package/dist/agent/slack-gate-notifier.js.map +1 -0
- package/dist/agent/slack-gate-poller.d.ts +28 -0
- package/dist/agent/slack-gate-poller.d.ts.map +1 -0
- package/dist/agent/slack-gate-poller.js +66 -0
- package/dist/agent/slack-gate-poller.js.map +1 -0
- package/dist/agent/slack-gate-server.d.ts +30 -0
- package/dist/agent/slack-gate-server.d.ts.map +1 -0
- package/dist/agent/slack-gate-server.js +99 -0
- package/dist/agent/slack-gate-server.js.map +1 -0
- package/dist/agent/slack-socket-client.d.ts +20 -0
- package/dist/agent/slack-socket-client.d.ts.map +1 -0
- package/dist/agent/slack-socket-client.js +141 -0
- package/dist/agent/slack-socket-client.js.map +1 -0
- package/dist/commands/agent.d.ts +3 -0
- package/dist/commands/agent.d.ts.map +1 -0
- package/dist/commands/agent.js +183 -0
- package/dist/commands/agent.js.map +1 -0
- package/dist/commands/cleanup.d.ts +16 -0
- package/dist/commands/cleanup.d.ts.map +1 -0
- package/dist/commands/cleanup.js +79 -0
- package/dist/commands/cleanup.js.map +1 -0
- package/dist/commands/diff.d.ts +41 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +203 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/init.d.ts +10 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +97 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/inspect.d.ts +14 -0
- package/dist/commands/inspect.d.ts.map +1 -0
- package/dist/commands/inspect.js +224 -0
- package/dist/commands/inspect.js.map +1 -0
- package/dist/commands/list.d.ts +18 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +88 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/mcp.d.ts +8 -0
- package/dist/commands/mcp.d.ts.map +1 -0
- package/dist/commands/mcp.js +22 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +42 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/register.d.ts +6 -0
- package/dist/commands/register.d.ts.map +1 -0
- package/dist/commands/register.js +51 -0
- package/dist/commands/register.js.map +1 -0
- package/dist/commands/replay-format.d.ts +3 -0
- package/dist/commands/replay-format.d.ts.map +1 -0
- package/dist/commands/replay-format.js +10 -0
- package/dist/commands/replay-format.js.map +1 -0
- package/dist/commands/replay.d.ts +38 -0
- package/dist/commands/replay.d.ts.map +1 -0
- package/dist/commands/replay.js +173 -0
- package/dist/commands/replay.js.map +1 -0
- package/dist/commands/respond.d.ts +20 -0
- package/dist/commands/respond.d.ts.map +1 -0
- package/dist/commands/respond.js +49 -0
- package/dist/commands/respond.js.map +1 -0
- package/dist/commands/resume.d.ts +15 -0
- package/dist/commands/resume.d.ts.map +1 -0
- package/dist/commands/resume.js +63 -0
- package/dist/commands/resume.js.map +1 -0
- package/dist/commands/run.d.ts +3 -0
- package/dist/commands/run.d.ts.map +1 -0
- package/dist/commands/run.js +127 -0
- package/dist/commands/run.js.map +1 -0
- package/dist/commands/serve.d.ts +33 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +144 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/test.d.ts +12 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +58 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/commands/validate.d.ts +3 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +35 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/commands/watch.d.ts +18 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +112 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/commands/webhook.d.ts +51 -0
- package/dist/commands/webhook.d.ts.map +1 -0
- package/dist/commands/webhook.js +227 -0
- package/dist/commands/webhook.js.map +1 -0
- package/dist/commands-registry.d.ts +7 -0
- package/dist/commands-registry.d.ts.map +1 -0
- package/dist/commands-registry.js +44 -0
- package/dist/commands-registry.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/index.js.map +1 -0
- package/dist/store/replay-store.d.ts +29 -0
- package/dist/store/replay-store.d.ts.map +1 -0
- package/dist/store/replay-store.js +31 -0
- package/dist/store/replay-store.js.map +1 -0
- package/package.json +83 -0
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# @sensigo/realm-cli
|
|
2
|
+
|
|
3
|
+
Run autonomous agent workflows, host an MCP server over HTTP, and manage workflow definitions and run history from the terminal.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
npm install -g @sensigo/realm-cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Commands
|
|
12
|
+
|
|
13
|
+
### realm workflow \<command\>
|
|
14
|
+
|
|
15
|
+
| Command | Description |
|
|
16
|
+
| ---------- | ----------------------------------------------------- |
|
|
17
|
+
| `init` | Scaffold a new workflow directory |
|
|
18
|
+
| `validate` | Validate a workflow YAML file |
|
|
19
|
+
| `register` | Register a workflow from a directory |
|
|
20
|
+
| `watch` | Watch a workflow directory and re-register on changes |
|
|
21
|
+
| `run` | Start a workflow run |
|
|
22
|
+
| `test` | Run workflow tests |
|
|
23
|
+
| `migrate` | Apply schema migrations to stored runs |
|
|
24
|
+
|
|
25
|
+
### realm run \<command\>
|
|
26
|
+
|
|
27
|
+
| Command | Description |
|
|
28
|
+
| --------- | ---------------------------------- |
|
|
29
|
+
| `list` | List all runs |
|
|
30
|
+
| `inspect` | Inspect a run's steps and evidence |
|
|
31
|
+
| `replay` | Replay a completed run |
|
|
32
|
+
| `diff` | Diff two run records |
|
|
33
|
+
| `resume` | Resume a paused run |
|
|
34
|
+
| `respond` | Submit a response to a human gate |
|
|
35
|
+
| `cleanup` | Delete old or terminal runs |
|
|
36
|
+
|
|
37
|
+
### Top-level commands
|
|
38
|
+
|
|
39
|
+
| Command | Description |
|
|
40
|
+
| ------- | ------------------------------------------ |
|
|
41
|
+
| `mcp` | Start the MCP server over stdio |
|
|
42
|
+
| `serve` | Start the HTTP gateway |
|
|
43
|
+
| `agent` | Run a workflow step using a built-in agent |
|
|
44
|
+
|
|
45
|
+
## Using `realm agent`
|
|
46
|
+
|
|
47
|
+
| Flag | Description |
|
|
48
|
+
| ------------------- | -------------------------------------------------------------- |
|
|
49
|
+
| `--workflow <path>` | Path to workflow directory or `workflow.yaml` file |
|
|
50
|
+
| `--provider <name>` | LLM provider: `openai` or `anthropic` (auto-detected from env) |
|
|
51
|
+
| `--model <name>` | Model name override (default: `gpt-4o` / `claude-sonnet-4-5`) |
|
|
52
|
+
| `--base-url <url>` | Base URL for OpenAI-compatible endpoints |
|
|
53
|
+
| `--run-id <id>` | Attach to an existing run |
|
|
54
|
+
| `--params <json>` | Initial run parameters as JSON |
|
|
55
|
+
| `--register` | Persist the workflow definition to `~/.realm/workflows/` |
|
|
56
|
+
|
|
57
|
+
**DeepSeek / Qwen / other OpenAI-compatible providers:**
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
OPENAI_API_KEY=<your-key> realm agent \
|
|
61
|
+
--workflow ./my-workflow \
|
|
62
|
+
--provider openai \
|
|
63
|
+
--base-url https://api.deepseek.com \
|
|
64
|
+
--model deepseek-chat
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Custom Providers
|
|
68
|
+
|
|
69
|
+
`realm agent` supports custom LLM providers via `--provider-module`. Pass the path to an ESM
|
|
70
|
+
module that exports an instance of `LlmProvider` or `ToolCapableLlmProvider` as its default
|
|
71
|
+
export.
|
|
72
|
+
|
|
73
|
+
**Minimal example:**
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// my-ollama-provider.ts
|
|
77
|
+
import { LlmProvider } from '@sensigo/realm-cli/agent';
|
|
78
|
+
|
|
79
|
+
class OllamaProvider extends LlmProvider {
|
|
80
|
+
async callStep(prompt: string): Promise<Record<string, unknown>> {
|
|
81
|
+
// call your local Ollama endpoint here
|
|
82
|
+
const response = await fetch('http://localhost:11434/api/generate', { ... });
|
|
83
|
+
return await response.json() as Record<string, unknown>;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export default new OllamaProvider();
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
realm agent --workflow ./my-workflow --provider-module ./my-ollama-provider.js
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
The module must export an **instance** (not a class) as its default export. The instance must
|
|
95
|
+
extend `LlmProvider` (for basic steps) or `ToolCapableLlmProvider` (for tool-enabled steps),
|
|
96
|
+
both exported from `@sensigo/realm-cli/agent`.
|
|
97
|
+
|
|
98
|
+
Custom provider modules are user-supplied code executed in the same process as `realm agent`.
|
|
99
|
+
Only use modules you trust.
|
|
100
|
+
|
|
101
|
+
`--provider-module` cannot be combined with `--provider`, `--model`, or `--base-url`.
|
|
102
|
+
|
|
103
|
+
## Programmatic extension
|
|
104
|
+
|
|
105
|
+
The `@sensigo/realm-cli` package exports its command groups for embedding in custom CLI applications. Import `workflowCommands`, `runCommands`, and `topLevelCommands` (arrays of `Command` objects from `commander`) and register them into your own CLI program.
|
|
106
|
+
|
|
107
|
+
## Full documentation
|
|
108
|
+
|
|
109
|
+
Full documentation: https://github.com/sensigo-hq/realm
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Builds the system prompt for an agent step, optionally including the output schema. */
|
|
2
|
+
export declare function buildSystemPrompt(inputSchema?: Record<string, unknown>): string;
|
|
3
|
+
/**
|
|
4
|
+
* Converts an error value to a string and strips sensitive patterns:
|
|
5
|
+
* Bearer tokens, query-string tokens, and any process.env value longer than 4 characters.
|
|
6
|
+
*/
|
|
7
|
+
export declare function sanitizeError(err: unknown): string;
|
|
8
|
+
/**
|
|
9
|
+
* Serializes an MCP tool result to a string and applies the same sanitization pass
|
|
10
|
+
* as sanitizeError to strip any tokens that upstream services may have echoed.
|
|
11
|
+
*/
|
|
12
|
+
export declare function serializeToolResult(result: unknown): string;
|
|
13
|
+
/** Splits "server_id:tool_name" into its components. Throws if the format is invalid. */
|
|
14
|
+
export declare function parseNamespacedId(id: string): {
|
|
15
|
+
serverId: string;
|
|
16
|
+
toolName: string;
|
|
17
|
+
};
|
|
18
|
+
/** Tries to parse JSON; returns a plain object or null if parsing fails or the result is not an object. */
|
|
19
|
+
export declare function tryParseJson(text: string): Record<string, unknown> | null;
|
|
20
|
+
/**
|
|
21
|
+
* Returns true if all required properties from the schema are present in the parsed object.
|
|
22
|
+
* Returns true when no schema is provided.
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateSchema(parsed: Record<string, unknown>, schema?: Record<string, unknown>): boolean;
|
|
25
|
+
/** Returns a Promise that rejects with a timeout error after `ms` milliseconds. */
|
|
26
|
+
export declare function rejectAfter(ms: number): Promise<never>;
|
|
27
|
+
//# sourceMappingURL=agent-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-utils.d.ts","sourceRoot":"","sources":["../../src/agent/agent-utils.ts"],"names":[],"mappings":"AAMA,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAG/E;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,CAiBlD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,CAG3D;AAED,yFAAyF;AACzF,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAMpF;AAED,2GAA2G;AAC3G,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUzE;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,OAAO,CAKT;AAED,mFAAmF;AACnF,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAItD"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// agent-utils.ts — Shared utility functions for LLM provider agentic loops.
|
|
2
|
+
const SYSTEM_PROMPT_BASE = 'You are an AI agent executing a step in a structured workflow.\n' +
|
|
3
|
+
'Your task is described below. Respond with a JSON object only — no markdown, no explanation.';
|
|
4
|
+
/** Builds the system prompt for an agent step, optionally including the output schema. */
|
|
5
|
+
export function buildSystemPrompt(inputSchema) {
|
|
6
|
+
if (inputSchema === undefined)
|
|
7
|
+
return SYSTEM_PROMPT_BASE;
|
|
8
|
+
return `${SYSTEM_PROMPT_BASE}\nThe JSON must conform to this schema: ${JSON.stringify(inputSchema)}`;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Converts an error value to a string and strips sensitive patterns:
|
|
12
|
+
* Bearer tokens, query-string tokens, and any process.env value longer than 4 characters.
|
|
13
|
+
*/
|
|
14
|
+
export function sanitizeError(err) {
|
|
15
|
+
let text;
|
|
16
|
+
if (err instanceof Error) {
|
|
17
|
+
text = err.message;
|
|
18
|
+
}
|
|
19
|
+
else if (typeof err === 'string') {
|
|
20
|
+
text = err;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
text = String(err);
|
|
24
|
+
}
|
|
25
|
+
text = text.replace(/Bearer [A-Za-z0-9._-]+/g, 'Bearer [REDACTED]');
|
|
26
|
+
text = text.replace(/token=[A-Za-z0-9._-]+/g, 'token=[REDACTED]');
|
|
27
|
+
for (const val of Object.values(process.env)) {
|
|
28
|
+
if (val !== undefined && val.length > 4) {
|
|
29
|
+
text = text.split(val).join('[REDACTED]');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return text;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Serializes an MCP tool result to a string and applies the same sanitization pass
|
|
36
|
+
* as sanitizeError to strip any tokens that upstream services may have echoed.
|
|
37
|
+
*/
|
|
38
|
+
export function serializeToolResult(result) {
|
|
39
|
+
const raw = typeof result === 'string' ? result : JSON.stringify(result);
|
|
40
|
+
return sanitizeError(raw);
|
|
41
|
+
}
|
|
42
|
+
/** Splits "server_id:tool_name" into its components. Throws if the format is invalid. */
|
|
43
|
+
export function parseNamespacedId(id) {
|
|
44
|
+
const colonIdx = id.indexOf(':');
|
|
45
|
+
if (colonIdx === -1) {
|
|
46
|
+
throw new Error(`Invalid namespaced tool id '${id}' (expected format: 'serverId:toolName')`);
|
|
47
|
+
}
|
|
48
|
+
return { serverId: id.slice(0, colonIdx), toolName: id.slice(colonIdx + 1) };
|
|
49
|
+
}
|
|
50
|
+
/** Tries to parse JSON; returns a plain object or null if parsing fails or the result is not an object. */
|
|
51
|
+
export function tryParseJson(text) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(text);
|
|
54
|
+
if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Returns true if all required properties from the schema are present in the parsed object.
|
|
65
|
+
* Returns true when no schema is provided.
|
|
66
|
+
*/
|
|
67
|
+
export function validateSchema(parsed, schema) {
|
|
68
|
+
if (!schema)
|
|
69
|
+
return true;
|
|
70
|
+
const required = schema['required'];
|
|
71
|
+
if (!Array.isArray(required))
|
|
72
|
+
return true;
|
|
73
|
+
return required.every((key) => typeof key === 'string' && key in parsed);
|
|
74
|
+
}
|
|
75
|
+
/** Returns a Promise that rejects with a timeout error after `ms` milliseconds. */
|
|
76
|
+
export function rejectAfter(ms) {
|
|
77
|
+
return new Promise((_, reject) => setTimeout(() => reject(new Error(`tool call timed out after ${ms}ms`)), ms));
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=agent-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-utils.js","sourceRoot":"","sources":["../../src/agent/agent-utils.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAE5E,MAAM,kBAAkB,GACtB,kEAAkE;IAClE,8FAA8F,CAAC;AAEjG,0FAA0F;AAC1F,MAAM,UAAU,iBAAiB,CAAC,WAAqC;IACrE,IAAI,WAAW,KAAK,SAAS;QAAE,OAAO,kBAAkB,CAAC;IACzD,OAAO,GAAG,kBAAkB,2CAA2C,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,EAAE,CAAC;AACvG,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAY;IACxC,IAAI,IAAY,CAAC;IACjB,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC;IACrB,CAAC;SAAM,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QACnC,IAAI,GAAG,GAAG,CAAC;IACb,CAAC;SAAM,CAAC;QACN,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,yBAAyB,EAAE,mBAAmB,CAAC,CAAC;IACpE,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,wBAAwB,EAAE,kBAAkB,CAAC,CAAC;IAClE,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAC7C,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAe;IACjD,MAAM,GAAG,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzE,OAAO,aAAa,CAAC,GAAG,CAAC,CAAC;AAC5B,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,MAAM,QAAQ,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,+BAA+B,EAAE,0CAA0C,CAAC,CAAC;IAC/F,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,IAAI,CAAC;QACH,MAAM,MAAM,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5E,OAAO,MAAiC,CAAC;QAC3C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,MAA+B,EAC/B,MAAgC;IAEhC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IACpC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,OAAQ,QAAsB,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,IAAI,MAAM,CAAC,CAAC;AAC1F,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,OAAO,IAAI,OAAO,CAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CACtC,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,EAAE,IAAI,CAAC,CAAC,EAAE,EAAE,CAAC,CAC7E,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { ToolCapableLlmProvider } from './llm-provider.js';
|
|
2
|
+
import type { ToolDefinition, ToolExecutor, StepWithToolsResult } from './mcp-types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Anthropic LLM provider for realm agent.
|
|
5
|
+
* Uses the Messages API and extracts JSON from the first text content block.
|
|
6
|
+
* Retries once if the model returns non-JSON content.
|
|
7
|
+
*/
|
|
8
|
+
export declare class AnthropicProvider extends ToolCapableLlmProvider {
|
|
9
|
+
private readonly model;
|
|
10
|
+
constructor(model: string);
|
|
11
|
+
callStep(prompt: string, inputSchema?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
12
|
+
/**
|
|
13
|
+
* Agentic loop for tool-capable steps. Executes tool calls serially (V1 constraint).
|
|
14
|
+
* All tool results for one turn are accumulated into a single user message with an array
|
|
15
|
+
* of tool_result blocks — the Anthropic API rejects interleaved assistant/user turns.
|
|
16
|
+
*/
|
|
17
|
+
callStepWithTools(prompt: string, tools: ToolDefinition[], executor: ToolExecutor, options: {
|
|
18
|
+
inputSchema?: Record<string, unknown>;
|
|
19
|
+
maxToolCalls?: number;
|
|
20
|
+
toolTimeoutMs?: number;
|
|
21
|
+
}): Promise<StepWithToolsResult>;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=anthropic-provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-provider.d.ts","sourceRoot":"","sources":["../../src/agent/anthropic-provider.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAC3D,OAAO,KAAK,EAEV,cAAc,EACd,YAAY,EACZ,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAWxB;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,sBAAsB;IAC/C,OAAO,CAAC,QAAQ,CAAC,KAAK;gBAAL,KAAK,EAAE,MAAM;IAIpC,QAAQ,CACZ,MAAM,EAAE,MAAM,EACd,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACpC,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAoDnC;;;;OAIG;IACG,iBAAiB,CACrB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,cAAc,EAAE,EACvB,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACtC,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,GACA,OAAO,CAAC,mBAAmB,CAAC;CAiNhC"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
// anthropic-provider.ts — Anthropic LLM provider implementation for realm agent.
|
|
2
|
+
// Requires @anthropic-ai/sdk >= 0.20.0 as an optional peer dependency (npm install @anthropic-ai/sdk).
|
|
3
|
+
import { WorkflowError } from '@sensigo/realm';
|
|
4
|
+
import { ToolCapableLlmProvider } from './llm-provider.js';
|
|
5
|
+
import { sanitizeError, serializeToolResult, parseNamespacedId, tryParseJson, validateSchema, rejectAfter, buildSystemPrompt, } from './agent-utils.js';
|
|
6
|
+
/**
|
|
7
|
+
* Anthropic LLM provider for realm agent.
|
|
8
|
+
* Uses the Messages API and extracts JSON from the first text content block.
|
|
9
|
+
* Retries once if the model returns non-JSON content.
|
|
10
|
+
*/
|
|
11
|
+
export class AnthropicProvider extends ToolCapableLlmProvider {
|
|
12
|
+
model;
|
|
13
|
+
constructor(model) {
|
|
14
|
+
super();
|
|
15
|
+
this.model = model;
|
|
16
|
+
}
|
|
17
|
+
async callStep(prompt, inputSchema) {
|
|
18
|
+
// Dynamically import @anthropic-ai/sdk to keep it an optional peer dependency.
|
|
19
|
+
// See openai-provider.ts for an explanation of the 'string' cast technique.
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
21
|
+
let mod;
|
|
22
|
+
try {
|
|
23
|
+
const moduleId = '@anthropic-ai/sdk';
|
|
24
|
+
mod = await import(moduleId);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
console.error('realm agent requires the @anthropic-ai/sdk package. Run: npm install @anthropic-ai/sdk');
|
|
28
|
+
process.exit(1);
|
|
29
|
+
}
|
|
30
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
31
|
+
const client = new mod.default({
|
|
32
|
+
apiKey: process.env['ANTHROPIC_API_KEY'],
|
|
33
|
+
});
|
|
34
|
+
const systemPrompt = buildSystemPrompt(inputSchema);
|
|
35
|
+
const makeRequest = async (userContent) => {
|
|
36
|
+
const response = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
37
|
+
client.messages.create({
|
|
38
|
+
model: this.model,
|
|
39
|
+
max_tokens: 4096,
|
|
40
|
+
system: systemPrompt,
|
|
41
|
+
messages: [{ role: 'user', content: userContent }],
|
|
42
|
+
});
|
|
43
|
+
const block = response.content.find(
|
|
44
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
45
|
+
(b) => b.type === 'text');
|
|
46
|
+
return block?.text ?? '';
|
|
47
|
+
};
|
|
48
|
+
const content = await makeRequest(prompt);
|
|
49
|
+
try {
|
|
50
|
+
return JSON.parse(content);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Retry once with an explicit reminder to return JSON.
|
|
54
|
+
const retryPrompt = `${prompt}\n\nYour previous response was not valid JSON. Respond with a JSON object only.`;
|
|
55
|
+
const retry = await makeRequest(retryPrompt);
|
|
56
|
+
try {
|
|
57
|
+
return JSON.parse(retry);
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
throw new Error(`Anthropic returned non-JSON content after retry: ${retry.slice(0, 200)}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Agentic loop for tool-capable steps. Executes tool calls serially (V1 constraint).
|
|
66
|
+
* All tool results for one turn are accumulated into a single user message with an array
|
|
67
|
+
* of tool_result blocks — the Anthropic API rejects interleaved assistant/user turns.
|
|
68
|
+
*/
|
|
69
|
+
async callStepWithTools(prompt, tools, executor, options) {
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
let mod;
|
|
72
|
+
try {
|
|
73
|
+
const moduleId = '@anthropic-ai/sdk';
|
|
74
|
+
mod = await import(moduleId);
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
console.error('realm agent requires the @anthropic-ai/sdk package. Run: npm install @anthropic-ai/sdk');
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
81
|
+
const client = new mod.default({
|
|
82
|
+
apiKey: process.env['ANTHROPIC_API_KEY'],
|
|
83
|
+
});
|
|
84
|
+
// toolIdMap: bareName → namespaced id, used to recover routing key from LLM responses.
|
|
85
|
+
// Collision guard: two MCP servers may not expose the same bare tool name in the same step.
|
|
86
|
+
const toolIdMap = new Map();
|
|
87
|
+
const anthropicTools = [];
|
|
88
|
+
for (const tool of tools) {
|
|
89
|
+
if (toolIdMap.has(tool.name)) {
|
|
90
|
+
throw new Error(`invariant: duplicate bare tool name '${tool.name}' in toolIdMap — this should have been caught at toolDefs assembly in run-agent.ts`);
|
|
91
|
+
}
|
|
92
|
+
toolIdMap.set(tool.name, tool.id);
|
|
93
|
+
anthropicTools.push({
|
|
94
|
+
name: tool.name,
|
|
95
|
+
description: tool.description,
|
|
96
|
+
input_schema: tool.inputSchema, // note: input_schema, not parameters
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
const maxCalls = options.maxToolCalls ?? 20;
|
|
100
|
+
let tool_call_count = 0;
|
|
101
|
+
const tool_call_records = [];
|
|
102
|
+
const system = buildSystemPrompt(options.inputSchema);
|
|
103
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
104
|
+
const history = [{ role: 'user', content: prompt }];
|
|
105
|
+
const buildMainCallOpts = () => {
|
|
106
|
+
const opts = {
|
|
107
|
+
model: this.model,
|
|
108
|
+
max_tokens: 4096,
|
|
109
|
+
system,
|
|
110
|
+
messages: history,
|
|
111
|
+
};
|
|
112
|
+
if (anthropicTools.length > 0)
|
|
113
|
+
opts['tools'] = anthropicTools;
|
|
114
|
+
return opts;
|
|
115
|
+
};
|
|
116
|
+
// Calls the API with tool_choice: none and no tools array to force a plain text answer.
|
|
117
|
+
// Does NOT push to history — callers must ensure history ends with a valid user turn.
|
|
118
|
+
const performFinalExtraction = async () => {
|
|
119
|
+
const final = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
120
|
+
client.messages.create({
|
|
121
|
+
model: this.model,
|
|
122
|
+
max_tokens: 4096,
|
|
123
|
+
system,
|
|
124
|
+
messages: history,
|
|
125
|
+
tool_choice: { type: 'none' },
|
|
126
|
+
// NO tools array — enforces text-only response
|
|
127
|
+
// NO response_format — not a valid Anthropic parameter
|
|
128
|
+
});
|
|
129
|
+
const textBlock = final.content.find((b) => b.type === 'text');
|
|
130
|
+
const text = textBlock?.text ?? '';
|
|
131
|
+
const parsed = tryParseJson(text);
|
|
132
|
+
if (parsed && validateSchema(parsed, options.inputSchema)) {
|
|
133
|
+
return { output: parsed, toolCalls: tool_call_records };
|
|
134
|
+
}
|
|
135
|
+
throw new WorkflowError('max_tool_calls reached; final extraction failed', {
|
|
136
|
+
code: 'ENGINE_STEP_FAILED',
|
|
137
|
+
category: 'ENGINE',
|
|
138
|
+
agentAction: 'stop',
|
|
139
|
+
retryable: false,
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
while (true) {
|
|
143
|
+
const response = await // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
144
|
+
client.messages.create(buildMainCallOpts());
|
|
145
|
+
const toolUseBlocks = response.content.filter((b) => b.type === 'tool_use');
|
|
146
|
+
if (toolUseBlocks.length > 0) {
|
|
147
|
+
history.push({ role: 'assistant', content: response.content });
|
|
148
|
+
const anthropic_result_blocks = [];
|
|
149
|
+
let budget_exhausted_mid_batch = false;
|
|
150
|
+
for (const block of toolUseBlocks) {
|
|
151
|
+
const llmToolCallId = block.id; // captured verbatim — "toolu_01abc..."
|
|
152
|
+
if (tool_call_count >= maxCalls) {
|
|
153
|
+
// Budget exhausted — must still answer every id in the assistant message.
|
|
154
|
+
anthropic_result_blocks.push({
|
|
155
|
+
type: 'tool_result',
|
|
156
|
+
tool_use_id: llmToolCallId,
|
|
157
|
+
content: 'Error: tool call budget exhausted',
|
|
158
|
+
});
|
|
159
|
+
budget_exhausted_mid_batch = true;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
const originalId = toolIdMap.get(block.name);
|
|
163
|
+
const { serverId, toolName } = parseNamespacedId(originalId);
|
|
164
|
+
const args = (block.input ?? {});
|
|
165
|
+
const start = Date.now();
|
|
166
|
+
let resultContent;
|
|
167
|
+
let record;
|
|
168
|
+
try {
|
|
169
|
+
const rawResult = await Promise.race([
|
|
170
|
+
executor(originalId, args),
|
|
171
|
+
rejectAfter(options.toolTimeoutMs ?? 30000),
|
|
172
|
+
]);
|
|
173
|
+
const serialized = serializeToolResult(rawResult);
|
|
174
|
+
record = {
|
|
175
|
+
server_id: serverId,
|
|
176
|
+
tool: toolName,
|
|
177
|
+
args,
|
|
178
|
+
result: serialized,
|
|
179
|
+
duration_ms: Date.now() - start,
|
|
180
|
+
};
|
|
181
|
+
resultContent = serialized;
|
|
182
|
+
}
|
|
183
|
+
catch (err) {
|
|
184
|
+
const sanitized = sanitizeError(err);
|
|
185
|
+
const content = sanitized.length > 0 ? `Error: ${sanitized}` : 'Error: (redacted)';
|
|
186
|
+
record = {
|
|
187
|
+
server_id: serverId,
|
|
188
|
+
tool: toolName,
|
|
189
|
+
args,
|
|
190
|
+
result: null,
|
|
191
|
+
duration_ms: Date.now() - start,
|
|
192
|
+
error: sanitized,
|
|
193
|
+
};
|
|
194
|
+
resultContent = content;
|
|
195
|
+
}
|
|
196
|
+
tool_call_records.push(record);
|
|
197
|
+
tool_call_count++;
|
|
198
|
+
anthropic_result_blocks.push({
|
|
199
|
+
type: 'tool_result',
|
|
200
|
+
tool_use_id: llmToolCallId,
|
|
201
|
+
content: resultContent,
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
const exhausted = budget_exhausted_mid_batch || tool_call_count >= maxCalls;
|
|
205
|
+
if (exhausted) {
|
|
206
|
+
// Merge tool results and extraction prompt into a single user message to avoid
|
|
207
|
+
// consecutive user messages, which the Anthropic API rejects with 400.
|
|
208
|
+
history.push({
|
|
209
|
+
role: 'user',
|
|
210
|
+
content: [
|
|
211
|
+
...anthropic_result_blocks,
|
|
212
|
+
{
|
|
213
|
+
type: 'text',
|
|
214
|
+
text: 'You have reached the maximum number of tool calls. Produce your final JSON answer now using only what you have already gathered. No further tool calls will be executed.',
|
|
215
|
+
},
|
|
216
|
+
],
|
|
217
|
+
});
|
|
218
|
+
return performFinalExtraction();
|
|
219
|
+
}
|
|
220
|
+
// Normal continuation — single user message with all tool_result blocks.
|
|
221
|
+
history.push({ role: 'user', content: anthropic_result_blocks });
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
// No tool calls — attempt to parse the final answer.
|
|
225
|
+
const textBlock = response.content.find((b) => b.type === 'text');
|
|
226
|
+
const text = textBlock?.text ?? '';
|
|
227
|
+
const parsed = tryParseJson(text);
|
|
228
|
+
if (parsed && validateSchema(parsed, options.inputSchema)) {
|
|
229
|
+
return { output: parsed, toolCalls: tool_call_records };
|
|
230
|
+
}
|
|
231
|
+
// Schema mismatch — append correction and keep looping.
|
|
232
|
+
history.push({ role: 'assistant', content: response.content });
|
|
233
|
+
history.push({
|
|
234
|
+
role: 'user',
|
|
235
|
+
content: 'Your response did not match the required JSON schema. Try again.',
|
|
236
|
+
});
|
|
237
|
+
tool_call_count++; // schema correction consumes a slot
|
|
238
|
+
if (tool_call_count >= maxCalls) {
|
|
239
|
+
return performFinalExtraction();
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=anthropic-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic-provider.js","sourceRoot":"","sources":["../../src/agent/anthropic-provider.ts"],"names":[],"mappings":"AAAA,iFAAiF;AACjF,uGAAuG;AACvG,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAO3D,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,YAAY,EACZ,cAAc,EACd,WAAW,EACX,iBAAiB,GAClB,MAAM,kBAAkB,CAAC;AAE1B;;;;GAIG;AACH,MAAM,OAAO,iBAAkB,SAAQ,sBAAsB;IAC9B;IAA7B,YAA6B,KAAa;QACxC,KAAK,EAAE,CAAC;QADmB,UAAK,GAAL,KAAK,CAAQ;IAE1C,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,MAAc,EACd,WAAqC;QAErC,+EAA+E;QAC/E,4EAA4E;QAC5E,8DAA8D;QAC9D,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAW,mBAAmB,CAAC;YAC7C,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CACX,wFAAwF,CACzF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,8DAA8D;QAC9D,MAAM,MAAM,GAAG,IAAK,GAAG,CAAC,OAAsD,CAAC;YAC7E,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;SACzC,CAAC,CAAC;QAEH,MAAM,YAAY,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAEpD,MAAM,WAAW,GAAG,KAAK,EAAE,WAAmB,EAAmB,EAAE;YACjE,MAAM,QAAQ,GAAG,MAAM,8DAA8D;aACpF,MAAM,CAAC,QAAQ,CAAC,MAA0D,CAAC;gBAC1E,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI;gBAChB,MAAM,EAAE,YAAY;gBACpB,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC;aACnD,CAAC,CAAC;YACH,MAAM,KAAK,GAAI,QAAQ,CAAC,OAAqB,CAAC,IAAI;YAChD,8DAA8D;YAC9D,CAAC,CAAM,EAAE,EAAE,CAAE,CAAuB,CAAC,IAAI,KAAK,MAAM,CACpB,CAAC;YACnC,OAAO,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC;QAEF,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAC;QACxD,CAAC;QAAC,MAAM,CAAC;YACP,uDAAuD;YACvD,MAAM,WAAW,GAAG,GAAG,MAAM,iFAAiF,CAAC;YAC/G,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,WAAW,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAA4B,CAAC;YACtD,CAAC;YAAC,MAAM,CAAC;gBACP,MAAM,IAAI,KAAK,CAAC,oDAAoD,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7F,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,iBAAiB,CACrB,MAAc,EACd,KAAuB,EACvB,QAAsB,EACtB,OAIC;QAED,8DAA8D;QAC9D,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,MAAM,QAAQ,GAAW,mBAAmB,CAAC;YAC7C,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CACX,wFAAwF,CACzF,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,8DAA8D;QAC9D,MAAM,MAAM,GAAG,IAAK,GAAG,CAAC,OAAsD,CAAC;YAC7E,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;SACzC,CAAC,CAAC;QAEH,uFAAuF;QACvF,4FAA4F;QAC5F,MAAM,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;QAC5C,MAAM,cAAc,GAIf,EAAE,CAAC;QACR,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC7B,MAAM,IAAI,KAAK,CACb,wCAAwC,IAAI,CAAC,IAAI,oFAAoF,CACtI,CAAC;YACJ,CAAC;YACD,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;YAClC,cAAc,CAAC,IAAI,CAAC;gBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,WAAW,EAAE,IAAI,CAAC,WAAW;gBAC7B,YAAY,EAAE,IAAI,CAAC,WAAW,EAAE,qCAAqC;aACtE,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,IAAI,EAAE,CAAC;QAC5C,IAAI,eAAe,GAAG,CAAC,CAAC;QACxB,MAAM,iBAAiB,GAAqB,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,iBAAiB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QAEtD,8DAA8D;QAC9D,MAAM,OAAO,GAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;QAE3D,MAAM,iBAAiB,GAAG,GAA4B,EAAE;YACtD,MAAM,IAAI,GAA4B;gBACpC,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI;gBAChB,MAAM;gBACN,QAAQ,EAAE,OAAO;aAClB,CAAC;YACF,IAAI,cAAc,CAAC,MAAM,GAAG,CAAC;gBAAE,IAAI,CAAC,OAAO,CAAC,GAAG,cAAc,CAAC;YAC9D,OAAO,IAAI,CAAC;QACd,CAAC,CAAC;QAEF,wFAAwF;QACxF,sFAAsF;QACtF,MAAM,sBAAsB,GAAG,KAAK,IAAkC,EAAE;YACtE,MAAM,KAAK,GAAG,MAAM,8DAA8D;aACjF,MAAM,CAAC,QAAQ,CAAC,MAA0D,CAAC;gBAC1E,KAAK,EAAE,IAAI,CAAC,KAAK;gBACjB,UAAU,EAAE,IAAI;gBAChB,MAAM;gBACN,QAAQ,EAAE,OAAO;gBACjB,WAAW,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE;gBAC7B,+CAA+C;gBAC/C,uDAAuD;aACxD,CAAC,CAAC;YACH,MAAM,SAAS,GAAI,KAAK,CAAC,OAAkD,CAAC,IAAI,CAC9E,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CACzB,CAAC;YACF,MAAM,IAAI,GAAG,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC;YACnC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YAClC,IAAI,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;YAC1D,CAAC;YACD,MAAM,IAAI,aAAa,CAAC,iDAAiD,EAAE;gBACzE,IAAI,EAAE,oBAAoB;gBAC1B,QAAQ,EAAE,QAAQ;gBAClB,WAAW,EAAE,MAAM;gBACnB,SAAS,EAAE,KAAK;aACjB,CAAC,CAAC;QACL,CAAC,CAAC;QAEF,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,QAAQ,GAAG,MAAM,8DAA8D;aACpF,MAAM,CAAC,QAAQ,CAAC,MAA0D,CACzE,iBAAiB,EAAE,CACpB,CAAC;YACF,MAAM,aAAa,GACjB,QAAQ,CAAC,OACV,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC;YAEvC,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAE/D,MAAM,uBAAuB,GAIxB,EAAE,CAAC;gBACR,IAAI,0BAA0B,GAAG,KAAK,CAAC;gBAEvC,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;oBAClC,MAAM,aAAa,GAAG,KAAK,CAAC,EAAG,CAAC,CAAC,uCAAuC;oBAExE,IAAI,eAAe,IAAI,QAAQ,EAAE,CAAC;wBAChC,0EAA0E;wBAC1E,uBAAuB,CAAC,IAAI,CAAC;4BAC3B,IAAI,EAAE,aAAa;4BACnB,WAAW,EAAE,aAAa;4BAC1B,OAAO,EAAE,mCAAmC;yBAC7C,CAAC,CAAC;wBACH,0BAA0B,GAAG,IAAI,CAAC;wBAClC,SAAS;oBACX,CAAC;oBAED,MAAM,UAAU,GAAG,SAAS,CAAC,GAAG,CAAC,KAAK,CAAC,IAAK,CAAE,CAAC;oBAC/C,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;oBAC7D,MAAM,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;oBAC5D,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;oBAEzB,IAAI,aAAqB,CAAC;oBAC1B,IAAI,MAAsB,CAAC;oBAE3B,IAAI,CAAC;wBACH,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;4BACnC,QAAQ,CAAC,UAAU,EAAE,IAAI,CAAC;4BAC1B,WAAW,CAAC,OAAO,CAAC,aAAa,IAAI,KAAK,CAAC;yBAC5C,CAAC,CAAC;wBACH,MAAM,UAAU,GAAG,mBAAmB,CAAC,SAAS,CAAC,CAAC;wBAClD,MAAM,GAAG;4BACP,SAAS,EAAE,QAAQ;4BACnB,IAAI,EAAE,QAAQ;4BACd,IAAI;4BACJ,MAAM,EAAE,UAAU;4BAClB,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;yBAChC,CAAC;wBACF,aAAa,GAAG,UAAU,CAAC;oBAC7B,CAAC;oBAAC,OAAO,GAAG,EAAE,CAAC;wBACb,MAAM,SAAS,GAAG,aAAa,CAAC,GAAG,CAAC,CAAC;wBACrC,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,SAAS,EAAE,CAAC,CAAC,CAAC,mBAAmB,CAAC;wBACnF,MAAM,GAAG;4BACP,SAAS,EAAE,QAAQ;4BACnB,IAAI,EAAE,QAAQ;4BACd,IAAI;4BACJ,MAAM,EAAE,IAAI;4BACZ,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;4BAC/B,KAAK,EAAE,SAAS;yBACjB,CAAC;wBACF,aAAa,GAAG,OAAO,CAAC;oBAC1B,CAAC;oBAED,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;oBAC/B,eAAe,EAAE,CAAC;oBAClB,uBAAuB,CAAC,IAAI,CAAC;wBAC3B,IAAI,EAAE,aAAa;wBACnB,WAAW,EAAE,aAAa;wBAC1B,OAAO,EAAE,aAAa;qBACvB,CAAC,CAAC;gBACL,CAAC;gBAED,MAAM,SAAS,GAAG,0BAA0B,IAAI,eAAe,IAAI,QAAQ,CAAC;gBAE5E,IAAI,SAAS,EAAE,CAAC;oBACd,+EAA+E;oBAC/E,uEAAuE;oBACvE,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE;4BACP,GAAG,uBAAuB;4BAC1B;gCACE,IAAI,EAAE,MAAe;gCACrB,IAAI,EAAE,0KAA0K;6BACjL;yBACF;qBACF,CAAC,CAAC;oBACH,OAAO,sBAAsB,EAAE,CAAC;gBAClC,CAAC;gBAED,yEAAyE;gBACzE,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,EAAE,CAAC,CAAC;YACnE,CAAC;iBAAM,CAAC;gBACN,qDAAqD;gBACrD,MAAM,SAAS,GAAI,QAAQ,CAAC,OAAkD,CAAC,IAAI,CACjF,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CACzB,CAAC;gBACF,MAAM,IAAI,GAAG,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC;gBACnC,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;gBAClC,IAAI,MAAM,IAAI,cAAc,CAAC,MAAM,EAAE,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;oBAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,iBAAiB,EAAE,CAAC;gBAC1D,CAAC;gBACD,wDAAwD;gBACxD,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC/D,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,MAAM;oBACZ,OAAO,EAAE,kEAAkE;iBAC5E,CAAC,CAAC;gBACH,eAAe,EAAE,CAAC,CAAC,oCAAoC;gBACvD,IAAI,eAAe,IAAI,QAAQ,EAAE,CAAC;oBAChC,OAAO,sBAAsB,EAAE,CAAC;gBAClC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { type RunStore, type WorkflowDefinition, type PendingGate } from '@sensigo/realm';
|
|
2
|
+
import type { LlmProvider } from '../providers/llm-provider.js';
|
|
3
|
+
/**
|
|
4
|
+
* Formats a gate preview object as human-readable Slack mrkdwn text.
|
|
5
|
+
* Uses `headline` and `message` fields when present; falls back to indented JSON.
|
|
6
|
+
* Exported for testing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function formatGatePreviewForSlack(preview: Record<string, unknown>): string;
|
|
9
|
+
/**
|
|
10
|
+
* POSTs a gate-waiting notification to a Slack Incoming Webhook.
|
|
11
|
+
* Failure is warned but does not abort the workflow run.
|
|
12
|
+
* Exported for testing.
|
|
13
|
+
*/
|
|
14
|
+
export declare function postGateNotificationToSlack(webhookUrl: string, gate: PendingGate, runId: string): Promise<void>;
|
|
15
|
+
/**
|
|
16
|
+
* Posts a gate notification to Slack via chat.postMessage (bot token path).
|
|
17
|
+
* Returns the message ts for use as a thread anchor, or undefined on failure.
|
|
18
|
+
* Exported for testing.
|
|
19
|
+
*/
|
|
20
|
+
export declare function postGateViaApi(botToken: string, channelId: string, gate: PendingGate, runId: string): Promise<string | undefined>;
|
|
21
|
+
/**
|
|
22
|
+
* Posts a reply to an existing Slack thread via chat.postMessage.
|
|
23
|
+
* Failures are warned but not thrown — best-effort.
|
|
24
|
+
* Exported for testing.
|
|
25
|
+
*/
|
|
26
|
+
export declare function postSlackReply(botToken: string, channelId: string, threadTs: string, text: string): Promise<void>;
|
|
27
|
+
/**
|
|
28
|
+
* Starts reminder and escalation timers for an open gate.
|
|
29
|
+
* Returns a cleanup function that clears both timers — must be called when the gate resolves.
|
|
30
|
+
* Exported for testing.
|
|
31
|
+
*/
|
|
32
|
+
export declare function startGateReminderTimers(botToken: string, channelId: string, threadTs: string, gate: PendingGate, reminderIntervalMs: number, escalationThresholdMs: number): () => void;
|
|
33
|
+
/** Parameters for the bidirectional gate handler. Exported for testing. */
|
|
34
|
+
export interface BidirectionalGateParams {
|
|
35
|
+
gate: PendingGate;
|
|
36
|
+
runId: string;
|
|
37
|
+
definition: WorkflowDefinition;
|
|
38
|
+
store: RunStore;
|
|
39
|
+
provider: LlmProvider;
|
|
40
|
+
slackBotToken: string;
|
|
41
|
+
slackChannelId: string;
|
|
42
|
+
gateThreadTs: string | undefined;
|
|
43
|
+
slackSigningSecret?: string;
|
|
44
|
+
slackEventsPort: number;
|
|
45
|
+
/** SLACK_APP_TOKEN — enables Socket Mode when set. */
|
|
46
|
+
slackAppToken?: string;
|
|
47
|
+
gateReminderIntervalMs: number;
|
|
48
|
+
gateEscalationThresholdMs: number;
|
|
49
|
+
pollIntervalMs: number;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Handles a gate using Slack bidirectional resolution:
|
|
53
|
+
* - Events API (when signing secret is present) or Socket Mode (when app token is present)
|
|
54
|
+
* - LLM intent interpretation of Slack replies
|
|
55
|
+
* - Reminder and escalation timers
|
|
56
|
+
* - Falls back to store polling for terminal-command gate resolution
|
|
57
|
+
* Exported for testing.
|
|
58
|
+
*/
|
|
59
|
+
export declare function handleBidirectionalGate(params: BidirectionalGateParams): Promise<void>;
|
|
60
|
+
export interface SlackGateHandlerConfig {
|
|
61
|
+
store: RunStore;
|
|
62
|
+
definition: WorkflowDefinition;
|
|
63
|
+
/** Required by handleBidirectionalGate for LLM intent parsing. */
|
|
64
|
+
provider: LlmProvider;
|
|
65
|
+
webhookUrl?: string;
|
|
66
|
+
botToken?: string;
|
|
67
|
+
channelId?: string;
|
|
68
|
+
signingSecret?: string;
|
|
69
|
+
eventsPort?: number;
|
|
70
|
+
appToken?: string;
|
|
71
|
+
reminderIntervalMs?: number;
|
|
72
|
+
escalationThresholdMs?: number;
|
|
73
|
+
pollIntervalMs?: number;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Creates a gate handler that notifies via Slack and waits for resolution.
|
|
77
|
+
* Returns a function typed (runId, gate) => Promise<void>.
|
|
78
|
+
*/
|
|
79
|
+
export declare function createSlackGateHandler(config: SlackGateHandlerConfig): (runId: string, gate: PendingGate) => Promise<void>;
|
|
80
|
+
//# sourceMappingURL=slack-gate-notifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-gate-notifier.d.ts","sourceRoot":"","sources":["../../../src/agent/gate/slack-gate-notifier.ts"],"names":[],"mappings":"AAIA,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,kBAAkB,EACvB,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIhE;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAgBlF;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,CAC/C,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,IAAI,CAAC,CAiCf;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAgC7B;AAED;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,IAAI,CAAC,CAaf;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CACrC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,EACjB,kBAAkB,EAAE,MAAM,EAC1B,qBAAqB,EAAE,MAAM,GAC5B,MAAM,IAAI,CAyBZ;AAED,2EAA2E;AAC3E,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,WAAW,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,kBAAkB,CAAC;IAC/B,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,WAAW,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,eAAe,EAAE,MAAM,CAAC;IACxB,sDAAsD;IACtD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,sBAAsB,EAAE,MAAM,CAAC;IAC/B,yBAAyB,EAAE,MAAM,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;GAOG;AACH,wBAAsB,uBAAuB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoI5F;AAiCD,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,QAAQ,CAAC;IAChB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,kEAAkE;IAClE,QAAQ,EAAE,WAAW,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,sBAAsB,GAC7B,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,KAAK,OAAO,CAAC,IAAI,CAAC,CAkCrD"}
|