@nodetool-ai/runtime 0.7.0-rc.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bridge-protocol.d.ts +39 -0
- package/dist/bridge-protocol.d.ts.map +1 -0
- package/dist/bridge-protocol.js +39 -0
- package/dist/bridge-protocol.js.map +1 -0
- package/dist/comfy-executor.d.ts +41 -0
- package/dist/comfy-executor.d.ts.map +1 -0
- package/dist/comfy-executor.js +305 -0
- package/dist/comfy-executor.js.map +1 -0
- package/dist/context-packer.d.ts +22 -0
- package/dist/context-packer.d.ts.map +1 -0
- package/dist/context-packer.js +66 -0
- package/dist/context-packer.js.map +1 -0
- package/dist/context.d.ts +405 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +1455 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/node-executor.d.ts +53 -0
- package/dist/node-executor.d.ts.map +1 -0
- package/dist/node-executor.js +9 -0
- package/dist/node-executor.js.map +1 -0
- package/dist/providers/aki-manifest.json +34 -0
- package/dist/providers/aki-provider.d.ts +65 -0
- package/dist/providers/aki-provider.d.ts.map +1 -0
- package/dist/providers/aki-provider.js +517 -0
- package/dist/providers/aki-provider.js.map +1 -0
- package/dist/providers/anthropic-provider.d.ts +55 -0
- package/dist/providers/anthropic-provider.d.ts.map +1 -0
- package/dist/providers/anthropic-provider.js +563 -0
- package/dist/providers/anthropic-provider.js.map +1 -0
- package/dist/providers/base-provider.d.ts +194 -0
- package/dist/providers/base-provider.d.ts.map +1 -0
- package/dist/providers/base-provider.js +515 -0
- package/dist/providers/base-provider.js.map +1 -0
- package/dist/providers/cerebras-provider.d.ts +20 -0
- package/dist/providers/cerebras-provider.d.ts.map +1 -0
- package/dist/providers/cerebras-provider.js +52 -0
- package/dist/providers/cerebras-provider.js.map +1 -0
- package/dist/providers/claude-agent-provider.d.ts +107 -0
- package/dist/providers/claude-agent-provider.d.ts.map +1 -0
- package/dist/providers/claude-agent-provider.js +586 -0
- package/dist/providers/claude-agent-provider.js.map +1 -0
- package/dist/providers/cohere-provider.d.ts +36 -0
- package/dist/providers/cohere-provider.d.ts.map +1 -0
- package/dist/providers/cohere-provider.js +116 -0
- package/dist/providers/cohere-provider.js.map +1 -0
- package/dist/providers/cost-calculator.d.ts +109 -0
- package/dist/providers/cost-calculator.d.ts.map +1 -0
- package/dist/providers/cost-calculator.js +475 -0
- package/dist/providers/cost-calculator.js.map +1 -0
- package/dist/providers/deepseek-provider.d.ts +25 -0
- package/dist/providers/deepseek-provider.d.ts.map +1 -0
- package/dist/providers/deepseek-provider.js +58 -0
- package/dist/providers/deepseek-provider.js.map +1 -0
- package/dist/providers/fake-provider.d.ts +52 -0
- package/dist/providers/fake-provider.d.ts.map +1 -0
- package/dist/providers/fake-provider.js +107 -0
- package/dist/providers/fake-provider.js.map +1 -0
- package/dist/providers/fal-provider.d.ts +32 -0
- package/dist/providers/fal-provider.d.ts.map +1 -0
- package/dist/providers/fal-provider.js +445 -0
- package/dist/providers/fal-provider.js.map +1 -0
- package/dist/providers/gemini-provider.d.ts +109 -0
- package/dist/providers/gemini-provider.d.ts.map +1 -0
- package/dist/providers/gemini-provider.js +943 -0
- package/dist/providers/gemini-provider.js.map +1 -0
- package/dist/providers/groq-provider.d.ts +20 -0
- package/dist/providers/groq-provider.d.ts.map +1 -0
- package/dist/providers/groq-provider.js +52 -0
- package/dist/providers/groq-provider.js.map +1 -0
- package/dist/providers/huggingface-provider.d.ts +59 -0
- package/dist/providers/huggingface-provider.d.ts.map +1 -0
- package/dist/providers/huggingface-provider.js +305 -0
- package/dist/providers/huggingface-provider.js.map +1 -0
- package/dist/providers/index.d.ts +69 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +137 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/jina-provider.d.ts +37 -0
- package/dist/providers/jina-provider.d.ts.map +1 -0
- package/dist/providers/jina-provider.js +118 -0
- package/dist/providers/jina-provider.js.map +1 -0
- package/dist/providers/kie-provider.d.ts +19 -0
- package/dist/providers/kie-provider.d.ts.map +1 -0
- package/dist/providers/kie-provider.js +118 -0
- package/dist/providers/kie-provider.js.map +1 -0
- package/dist/providers/llama-provider.d.ts +49 -0
- package/dist/providers/llama-provider.d.ts.map +1 -0
- package/dist/providers/llama-provider.js +381 -0
- package/dist/providers/llama-provider.js.map +1 -0
- package/dist/providers/lmstudio-provider.d.ts +22 -0
- package/dist/providers/lmstudio-provider.d.ts.map +1 -0
- package/dist/providers/lmstudio-provider.js +63 -0
- package/dist/providers/lmstudio-provider.js.map +1 -0
- package/dist/providers/manifest-models.d.ts +12 -0
- package/dist/providers/manifest-models.d.ts.map +1 -0
- package/dist/providers/manifest-models.js +96 -0
- package/dist/providers/manifest-models.js.map +1 -0
- package/dist/providers/meshy-provider.d.ts +53 -0
- package/dist/providers/meshy-provider.d.ts.map +1 -0
- package/dist/providers/meshy-provider.js +230 -0
- package/dist/providers/meshy-provider.js.map +1 -0
- package/dist/providers/minimax-provider.d.ts +66 -0
- package/dist/providers/minimax-provider.d.ts.map +1 -0
- package/dist/providers/minimax-provider.js +531 -0
- package/dist/providers/minimax-provider.js.map +1 -0
- package/dist/providers/mistral-provider.d.ts +26 -0
- package/dist/providers/mistral-provider.d.ts.map +1 -0
- package/dist/providers/mistral-provider.js +74 -0
- package/dist/providers/mistral-provider.js.map +1 -0
- package/dist/providers/moonshot-provider.d.ts +24 -0
- package/dist/providers/moonshot-provider.d.ts.map +1 -0
- package/dist/providers/moonshot-provider.js +43 -0
- package/dist/providers/moonshot-provider.js.map +1 -0
- package/dist/providers/ollama-provider.d.ts +71 -0
- package/dist/providers/ollama-provider.d.ts.map +1 -0
- package/dist/providers/ollama-provider.js +480 -0
- package/dist/providers/ollama-provider.js.map +1 -0
- package/dist/providers/openai-provider.d.ts +103 -0
- package/dist/providers/openai-provider.d.ts.map +1 -0
- package/dist/providers/openai-provider.js +917 -0
- package/dist/providers/openai-provider.js.map +1 -0
- package/dist/providers/openrouter-provider.d.ts +49 -0
- package/dist/providers/openrouter-provider.d.ts.map +1 -0
- package/dist/providers/openrouter-provider.js +147 -0
- package/dist/providers/openrouter-provider.js.map +1 -0
- package/dist/providers/provider-registry.d.ts +24 -0
- package/dist/providers/provider-registry.d.ts.map +1 -0
- package/dist/providers/provider-registry.js +124 -0
- package/dist/providers/provider-registry.js.map +1 -0
- package/dist/providers/python-provider.d.ts +75 -0
- package/dist/providers/python-provider.d.ts.map +1 -0
- package/dist/providers/python-provider.js +157 -0
- package/dist/providers/python-provider.js.map +1 -0
- package/dist/providers/replicate-provider.d.ts +73 -0
- package/dist/providers/replicate-provider.d.ts.map +1 -0
- package/dist/providers/replicate-provider.js +484 -0
- package/dist/providers/replicate-provider.js.map +1 -0
- package/dist/providers/rodin-provider.d.ts +41 -0
- package/dist/providers/rodin-provider.d.ts.map +1 -0
- package/dist/providers/rodin-provider.js +236 -0
- package/dist/providers/rodin-provider.js.map +1 -0
- package/dist/providers/scripted-provider.d.ts +141 -0
- package/dist/providers/scripted-provider.d.ts.map +1 -0
- package/dist/providers/scripted-provider.js +246 -0
- package/dist/providers/scripted-provider.js.map +1 -0
- package/dist/providers/together-provider.d.ts +20 -0
- package/dist/providers/together-provider.d.ts.map +1 -0
- package/dist/providers/together-provider.js +56 -0
- package/dist/providers/together-provider.js.map +1 -0
- package/dist/providers/types.d.ts +202 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/providers/vllm-provider.d.ts +22 -0
- package/dist/providers/vllm-provider.d.ts.map +1 -0
- package/dist/providers/vllm-provider.js +66 -0
- package/dist/providers/vllm-provider.js.map +1 -0
- package/dist/providers/voyage-provider.d.ts +37 -0
- package/dist/providers/voyage-provider.d.ts.map +1 -0
- package/dist/providers/voyage-provider.js +124 -0
- package/dist/providers/voyage-provider.js.map +1 -0
- package/dist/providers/xai-provider.d.ts +24 -0
- package/dist/providers/xai-provider.d.ts.map +1 -0
- package/dist/providers/xai-provider.js +57 -0
- package/dist/providers/xai-provider.js.map +1 -0
- package/dist/python-bridge-types.d.ts +70 -0
- package/dist/python-bridge-types.d.ts.map +1 -0
- package/dist/python-bridge-types.js +2 -0
- package/dist/python-bridge-types.js.map +1 -0
- package/dist/python-node-executor.d.ts +20 -0
- package/dist/python-node-executor.d.ts.map +1 -0
- package/dist/python-node-executor.js +219 -0
- package/dist/python-node-executor.js.map +1 -0
- package/dist/python-stdio-bridge.d.ts +67 -0
- package/dist/python-stdio-bridge.d.ts.map +1 -0
- package/dist/python-stdio-bridge.js +704 -0
- package/dist/python-stdio-bridge.js.map +1 -0
- package/dist/recommended-models.d.ts +17 -0
- package/dist/recommended-models.d.ts.map +1 -0
- package/dist/recommended-models.js +139 -0
- package/dist/recommended-models.js.map +1 -0
- package/dist/telemetry.d.ts +61 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +128 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/trace-exporters.d.ts +72 -0
- package/dist/trace-exporters.d.ts.map +1 -0
- package/dist/trace-exporters.js +216 -0
- package/dist/trace-exporters.js.map +1 -0
- package/dist/tracing-helpers.d.ts +99 -0
- package/dist/tracing-helpers.d.ts.map +1 -0
- package/dist/tracing-helpers.js +217 -0
- package/dist/tracing-helpers.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge protocol versioning between the JS runtime and the Python worker.
|
|
3
|
+
*
|
|
4
|
+
* Bumped only when the stdio worker protocol changes in a non-backward-
|
|
5
|
+
* compatible way (new message types, framing changes, schema breaks).
|
|
6
|
+
* Most JS or Python releases do NOT bump this — we want to allow the JS
|
|
7
|
+
* and Python sides to ship on independent cadences.
|
|
8
|
+
*
|
|
9
|
+
* Coupling rules:
|
|
10
|
+
*
|
|
11
|
+
* - `BRIDGE_PROTOCOL_VERSION` is what the JS runtime speaks. The Python
|
|
12
|
+
* worker reports its own value in its `discover` response.
|
|
13
|
+
* - `MIN_NODETOOL_CORE_VERSION` is the lowest published `nodetool-core`
|
|
14
|
+
* PEP 440 version that ships `BRIDGE_PROTOCOL_VERSION`. The Electron
|
|
15
|
+
* installer pins `nodetool-core>=MIN_NODETOOL_CORE_VERSION` and the
|
|
16
|
+
* prebuild check refuses to ship if the registry has no wheel that
|
|
17
|
+
* satisfies the constraint.
|
|
18
|
+
*
|
|
19
|
+
* On a breaking protocol change:
|
|
20
|
+
*
|
|
21
|
+
* 1. Bump `BRIDGE_PROTOCOL_VERSION` here AND in
|
|
22
|
+
* `nodetool-core/src/nodetool/worker/__init__.py` (lockstep).
|
|
23
|
+
* 2. Cut a new `nodetool-core` release containing the bump.
|
|
24
|
+
* 3. Update `MIN_NODETOOL_CORE_VERSION` to that new release.
|
|
25
|
+
*/
|
|
26
|
+
export declare const BRIDGE_PROTOCOL_VERSION = 1;
|
|
27
|
+
/**
|
|
28
|
+
* Lowest published nodetool-core version (PEP 440 string) that speaks
|
|
29
|
+
* `BRIDGE_PROTOCOL_VERSION` AND reports it in its `discover` response.
|
|
30
|
+
* Used by the prebuild registry check and the Electron installer's pin
|
|
31
|
+
* specifier.
|
|
32
|
+
*
|
|
33
|
+
* IMPORTANT: when you publish a new nodetool-core release that bumps
|
|
34
|
+
* BRIDGE_PROTOCOL_VERSION, update this string to that new release. The
|
|
35
|
+
* prebuild check will refuse to build the Electron app until a wheel
|
|
36
|
+
* satisfying this lower bound exists on the registry.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MIN_NODETOOL_CORE_VERSION = "0.7.0rc8";
|
|
39
|
+
//# sourceMappingURL=bridge-protocol.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-protocol.d.ts","sourceRoot":"","sources":["../src/bridge-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,eAAO,MAAM,yBAAyB,aAAa,CAAC"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Bridge protocol versioning between the JS runtime and the Python worker.
|
|
3
|
+
*
|
|
4
|
+
* Bumped only when the stdio worker protocol changes in a non-backward-
|
|
5
|
+
* compatible way (new message types, framing changes, schema breaks).
|
|
6
|
+
* Most JS or Python releases do NOT bump this — we want to allow the JS
|
|
7
|
+
* and Python sides to ship on independent cadences.
|
|
8
|
+
*
|
|
9
|
+
* Coupling rules:
|
|
10
|
+
*
|
|
11
|
+
* - `BRIDGE_PROTOCOL_VERSION` is what the JS runtime speaks. The Python
|
|
12
|
+
* worker reports its own value in its `discover` response.
|
|
13
|
+
* - `MIN_NODETOOL_CORE_VERSION` is the lowest published `nodetool-core`
|
|
14
|
+
* PEP 440 version that ships `BRIDGE_PROTOCOL_VERSION`. The Electron
|
|
15
|
+
* installer pins `nodetool-core>=MIN_NODETOOL_CORE_VERSION` and the
|
|
16
|
+
* prebuild check refuses to ship if the registry has no wheel that
|
|
17
|
+
* satisfies the constraint.
|
|
18
|
+
*
|
|
19
|
+
* On a breaking protocol change:
|
|
20
|
+
*
|
|
21
|
+
* 1. Bump `BRIDGE_PROTOCOL_VERSION` here AND in
|
|
22
|
+
* `nodetool-core/src/nodetool/worker/__init__.py` (lockstep).
|
|
23
|
+
* 2. Cut a new `nodetool-core` release containing the bump.
|
|
24
|
+
* 3. Update `MIN_NODETOOL_CORE_VERSION` to that new release.
|
|
25
|
+
*/
|
|
26
|
+
export const BRIDGE_PROTOCOL_VERSION = 1;
|
|
27
|
+
/**
|
|
28
|
+
* Lowest published nodetool-core version (PEP 440 string) that speaks
|
|
29
|
+
* `BRIDGE_PROTOCOL_VERSION` AND reports it in its `discover` response.
|
|
30
|
+
* Used by the prebuild registry check and the Electron installer's pin
|
|
31
|
+
* specifier.
|
|
32
|
+
*
|
|
33
|
+
* IMPORTANT: when you publish a new nodetool-core release that bumps
|
|
34
|
+
* BRIDGE_PROTOCOL_VERSION, update this string to that new release. The
|
|
35
|
+
* prebuild check will refuse to build the Electron app until a wheel
|
|
36
|
+
* satisfying this lower bound exists on the registry.
|
|
37
|
+
*/
|
|
38
|
+
export const MIN_NODETOOL_CORE_VERSION = "0.7.0rc8";
|
|
39
|
+
//# sourceMappingURL=bridge-protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bridge-protocol.js","sourceRoot":"","sources":["../src/bridge-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC;AAEzC;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,UAAU,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export interface ComfyImage {
|
|
2
|
+
type: "image";
|
|
3
|
+
data: string;
|
|
4
|
+
filename: string;
|
|
5
|
+
}
|
|
6
|
+
export interface ComfyExecutorResult {
|
|
7
|
+
status: "completed" | "failed";
|
|
8
|
+
images?: ComfyImage[];
|
|
9
|
+
raw_output?: Record<string, unknown>;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
/** Progress events emitted during execution. */
|
|
13
|
+
export interface ComfyProgressEvent {
|
|
14
|
+
type: "executing" | "progress" | "executed" | "execution_cached" | "execution_start" | "execution_error" | "execution_interrupted";
|
|
15
|
+
node?: string | null;
|
|
16
|
+
progress?: number;
|
|
17
|
+
total?: number;
|
|
18
|
+
output?: Record<string, unknown>;
|
|
19
|
+
error?: string;
|
|
20
|
+
cached_nodes?: string[];
|
|
21
|
+
}
|
|
22
|
+
type ComfyPrompt = Record<string, {
|
|
23
|
+
class_type: string;
|
|
24
|
+
inputs: Record<string, unknown>;
|
|
25
|
+
}>;
|
|
26
|
+
/** Handle returned by executeComfy for cancellation support. */
|
|
27
|
+
export interface ComfyExecutionHandle {
|
|
28
|
+
/** Promise that resolves when execution completes or fails. */
|
|
29
|
+
result: Promise<ComfyExecutorResult>;
|
|
30
|
+
/** Cancel the execution — closes WS and sends interrupt to ComfyUI. */
|
|
31
|
+
cancel: () => void;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Execute a ComfyUI workflow against a ComfyUI server.
|
|
35
|
+
* Connects to ComfyUI's WebSocket for real-time progress events.
|
|
36
|
+
*
|
|
37
|
+
* Returns a handle with a result promise and a cancel() method.
|
|
38
|
+
*/
|
|
39
|
+
export declare function executeComfy(prompt: ComfyPrompt, addr: string, onProgress?: (event: ComfyProgressEvent) => void, timeoutMs?: number): ComfyExecutionHandle;
|
|
40
|
+
export {};
|
|
41
|
+
//# sourceMappingURL=comfy-executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comfy-executor.d.ts","sourceRoot":"","sources":["../src/comfy-executor.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EACA,WAAW,GACX,UAAU,GACV,UAAU,GACV,kBAAkB,GAClB,iBAAiB,GACjB,iBAAiB,GACjB,uBAAuB,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,KAAK,WAAW,GAAG,MAAM,CACvB,MAAM,EACN;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CACxD,CAAC;AAEF,gEAAgE;AAChE,MAAM,WAAW,oBAAoB;IACnC,+DAA+D;IAC/D,MAAM,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACrC,uEAAuE;IACvE,MAAM,EAAE,MAAM,IAAI,CAAC;CACpB;AAeD;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,WAAW,EACnB,IAAI,EAAE,MAAM,EACZ,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,EAChD,SAAS,SAAS,GACjB,oBAAoB,CAmHtB"}
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ComfyUI workflow executor — submits prompts to any ComfyUI server
|
|
3
|
+
* and streams progress via ComfyUI's WebSocket.
|
|
4
|
+
*/
|
|
5
|
+
import { createLogger } from "@nodetool-ai/config";
|
|
6
|
+
import WebSocket from "ws";
|
|
7
|
+
const log = createLogger("runtime:comfy-executor");
|
|
8
|
+
function normalizeBaseUrl(addr) {
|
|
9
|
+
const url = addr.startsWith("http") ? addr : `http://${addr}`;
|
|
10
|
+
let end = url.length;
|
|
11
|
+
while (end > 0 && url[end - 1] === "/")
|
|
12
|
+
end--;
|
|
13
|
+
return url.slice(0, end);
|
|
14
|
+
}
|
|
15
|
+
function toWsUrl(httpBase, clientId) {
|
|
16
|
+
return httpBase.replace(/^http/, "ws") + `/ws?clientId=${clientId}`;
|
|
17
|
+
}
|
|
18
|
+
const IMAGE_FETCH_TIMEOUT_MS = 30_000;
|
|
19
|
+
/**
|
|
20
|
+
* Execute a ComfyUI workflow against a ComfyUI server.
|
|
21
|
+
* Connects to ComfyUI's WebSocket for real-time progress events.
|
|
22
|
+
*
|
|
23
|
+
* Returns a handle with a result promise and a cancel() method.
|
|
24
|
+
*/
|
|
25
|
+
export function executeComfy(prompt, addr, onProgress, timeoutMs = 600000) {
|
|
26
|
+
const base = normalizeBaseUrl(addr);
|
|
27
|
+
const clientId = `nodetool-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
28
|
+
let cancelled = false;
|
|
29
|
+
let ws = null;
|
|
30
|
+
const cancel = () => {
|
|
31
|
+
if (cancelled)
|
|
32
|
+
return;
|
|
33
|
+
cancelled = true;
|
|
34
|
+
// Tell ComfyUI to interrupt
|
|
35
|
+
void fetch(`${base}/interrupt`, { method: "POST" }).catch((err) => {
|
|
36
|
+
log.warn("Failed to send ComfyUI interrupt request", {
|
|
37
|
+
error: String(err)
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
if (ws) {
|
|
41
|
+
try {
|
|
42
|
+
ws.close();
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
/* Intentional: best-effort WebSocket close during cleanup */
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const result = (async () => {
|
|
50
|
+
// Connect WebSocket FIRST so we don't miss any events
|
|
51
|
+
const wsUrl = toWsUrl(base, clientId);
|
|
52
|
+
try {
|
|
53
|
+
ws = new WebSocket(wsUrl);
|
|
54
|
+
await new Promise((resolve, reject) => {
|
|
55
|
+
ws.on("open", resolve);
|
|
56
|
+
ws.on("error", reject);
|
|
57
|
+
});
|
|
58
|
+
log.info(`ComfyUI WebSocket connected: ${wsUrl}`);
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
62
|
+
log.error(`Failed to connect ComfyUI WebSocket: ${msg}`);
|
|
63
|
+
return { status: "failed", error: `WebSocket connection failed: ${msg}` };
|
|
64
|
+
}
|
|
65
|
+
if (cancelled) {
|
|
66
|
+
try {
|
|
67
|
+
ws.close();
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
/* Intentional: best-effort WebSocket close during cleanup */
|
|
71
|
+
}
|
|
72
|
+
return { status: "failed", error: "Cancelled before submission" };
|
|
73
|
+
}
|
|
74
|
+
// Submit prompt (with client_id so ComfyUI routes events to our WS)
|
|
75
|
+
let promptId;
|
|
76
|
+
try {
|
|
77
|
+
const url = `${base}/prompt`;
|
|
78
|
+
const body = JSON.stringify({ prompt, client_id: clientId });
|
|
79
|
+
log.info(`Submitting prompt to ${url} (${body.length} bytes, ${Object.keys(prompt).length} nodes)`);
|
|
80
|
+
const submitRes = await fetch(url, {
|
|
81
|
+
method: "POST",
|
|
82
|
+
headers: { "Content-Type": "application/json" },
|
|
83
|
+
body
|
|
84
|
+
});
|
|
85
|
+
if (!submitRes.ok) {
|
|
86
|
+
const text = await submitRes.text();
|
|
87
|
+
log.error(`Submit failed: HTTP ${submitRes.status} — ${text}`);
|
|
88
|
+
try {
|
|
89
|
+
ws.close();
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
/* Intentional: best-effort WebSocket close during cleanup */
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
status: "failed",
|
|
96
|
+
error: `Submit failed (${submitRes.status}): ${text}`
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const submitData = (await submitRes.json());
|
|
100
|
+
promptId = submitData.prompt_id;
|
|
101
|
+
log.info(`Prompt accepted: ${promptId}`);
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
const errMsg = err instanceof Error
|
|
105
|
+
? `${err.message} (${err.cause ?? "no cause"})`
|
|
106
|
+
: String(err);
|
|
107
|
+
log.error(`Submit error to ${base}/prompt: ${errMsg}`);
|
|
108
|
+
try {
|
|
109
|
+
ws.close();
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
/* Intentional: best-effort WebSocket close during cleanup */
|
|
113
|
+
}
|
|
114
|
+
return { status: "failed", error: `Submit error: ${errMsg}` };
|
|
115
|
+
}
|
|
116
|
+
// Listen for progress events on the already-connected WebSocket
|
|
117
|
+
const listenResult = await listenForCompletion(ws, promptId, onProgress, timeoutMs);
|
|
118
|
+
if (listenResult.status === "failed") {
|
|
119
|
+
return listenResult;
|
|
120
|
+
}
|
|
121
|
+
// Fetch images from history
|
|
122
|
+
const images = await fetchOutputImages(base, promptId);
|
|
123
|
+
return {
|
|
124
|
+
status: "completed",
|
|
125
|
+
images,
|
|
126
|
+
raw_output: listenResult.raw_output
|
|
127
|
+
};
|
|
128
|
+
})();
|
|
129
|
+
return { result, cancel };
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Listen on an already-connected ComfyUI WebSocket for the prompt to complete,
|
|
133
|
+
* streaming progress events along the way.
|
|
134
|
+
*/
|
|
135
|
+
function listenForCompletion(ws, promptId, onProgress, timeoutMs) {
|
|
136
|
+
return new Promise((resolve) => {
|
|
137
|
+
let settled = false;
|
|
138
|
+
let currentNode = null;
|
|
139
|
+
const settle = (result) => {
|
|
140
|
+
if (settled)
|
|
141
|
+
return;
|
|
142
|
+
settled = true;
|
|
143
|
+
clearTimeout(timer);
|
|
144
|
+
// Remove message listener before closing to prevent stale callbacks
|
|
145
|
+
ws.removeAllListeners("message");
|
|
146
|
+
try {
|
|
147
|
+
ws.close();
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
/* Intentional: best-effort WebSocket close during cleanup */
|
|
151
|
+
}
|
|
152
|
+
resolve(result);
|
|
153
|
+
};
|
|
154
|
+
const timer = setTimeout(() => {
|
|
155
|
+
log.error(`Timeout waiting for prompt ${promptId} after ${timeoutMs}ms`);
|
|
156
|
+
settle({ status: "failed", error: "Timeout waiting for ComfyUI result" });
|
|
157
|
+
}, timeoutMs);
|
|
158
|
+
ws.on("error", (err) => {
|
|
159
|
+
log.error(`ComfyUI WebSocket error: ${err.message}`);
|
|
160
|
+
settle({ status: "failed", error: `WebSocket error: ${err.message}` });
|
|
161
|
+
});
|
|
162
|
+
ws.on("close", () => {
|
|
163
|
+
if (!settled) {
|
|
164
|
+
settle({
|
|
165
|
+
status: "failed",
|
|
166
|
+
error: "ComfyUI WebSocket closed unexpectedly"
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
ws.on("message", (raw) => {
|
|
171
|
+
if (settled)
|
|
172
|
+
return; // Guard against late messages in receive buffer
|
|
173
|
+
let msg;
|
|
174
|
+
try {
|
|
175
|
+
msg = JSON.parse(raw.toString());
|
|
176
|
+
}
|
|
177
|
+
catch {
|
|
178
|
+
return; // binary preview frame or malformed — skip
|
|
179
|
+
}
|
|
180
|
+
const type = msg.type;
|
|
181
|
+
const data = msg.data ?? {};
|
|
182
|
+
const msgPromptId = data.prompt_id;
|
|
183
|
+
// Skip messages for other prompts
|
|
184
|
+
if (msgPromptId && msgPromptId !== promptId)
|
|
185
|
+
return;
|
|
186
|
+
switch (type) {
|
|
187
|
+
case "execution_start":
|
|
188
|
+
onProgress?.({ type: "execution_start" });
|
|
189
|
+
break;
|
|
190
|
+
case "execution_cached": {
|
|
191
|
+
const nodes = Array.isArray(data.nodes) ? data.nodes.map(String) : [];
|
|
192
|
+
onProgress?.({ type: "execution_cached", cached_nodes: nodes });
|
|
193
|
+
break;
|
|
194
|
+
}
|
|
195
|
+
case "executing": {
|
|
196
|
+
const nodeId = data.node != null ? String(data.node) : null;
|
|
197
|
+
currentNode = nodeId;
|
|
198
|
+
// Always emit the executing event (even for null/end-of-execution)
|
|
199
|
+
onProgress?.({ type: "executing", node: nodeId });
|
|
200
|
+
if (nodeId === null) {
|
|
201
|
+
// null node means execution finished — but prefer execution_success
|
|
202
|
+
// for the actual settle, as it carries richer data. Only settle here
|
|
203
|
+
// if execution_success doesn't arrive within a short window.
|
|
204
|
+
setTimeout(() => {
|
|
205
|
+
if (!settled) {
|
|
206
|
+
settle({ status: "completed", raw_output: {} });
|
|
207
|
+
}
|
|
208
|
+
}, 500);
|
|
209
|
+
}
|
|
210
|
+
break;
|
|
211
|
+
}
|
|
212
|
+
case "progress": {
|
|
213
|
+
const value = typeof data.value === "number" ? data.value : 0;
|
|
214
|
+
const max = typeof data.max === "number" ? data.max : 1;
|
|
215
|
+
onProgress?.({
|
|
216
|
+
type: "progress",
|
|
217
|
+
node: currentNode,
|
|
218
|
+
progress: value,
|
|
219
|
+
total: max
|
|
220
|
+
});
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
case "executed": {
|
|
224
|
+
const nodeId = data.node != null ? String(data.node) : null;
|
|
225
|
+
const output = (data.output ?? {});
|
|
226
|
+
onProgress?.({ type: "executed", node: nodeId, output });
|
|
227
|
+
break;
|
|
228
|
+
}
|
|
229
|
+
case "execution_success":
|
|
230
|
+
settle({ status: "completed", raw_output: data });
|
|
231
|
+
break;
|
|
232
|
+
case "execution_error": {
|
|
233
|
+
const errMsg = typeof data.exception_message === "string"
|
|
234
|
+
? data.exception_message
|
|
235
|
+
: "ComfyUI execution error";
|
|
236
|
+
const nodeId = data.node != null ? String(data.node) : currentNode;
|
|
237
|
+
onProgress?.({
|
|
238
|
+
type: "execution_error",
|
|
239
|
+
node: nodeId,
|
|
240
|
+
error: errMsg
|
|
241
|
+
});
|
|
242
|
+
settle({ status: "failed", error: errMsg });
|
|
243
|
+
break;
|
|
244
|
+
}
|
|
245
|
+
case "execution_interrupted":
|
|
246
|
+
onProgress?.({ type: "execution_interrupted" });
|
|
247
|
+
settle({ status: "failed", error: "Execution interrupted" });
|
|
248
|
+
break;
|
|
249
|
+
}
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Fetch output images from ComfyUI history after prompt completes.
|
|
255
|
+
*/
|
|
256
|
+
async function fetchOutputImages(base, promptId) {
|
|
257
|
+
const images = [];
|
|
258
|
+
try {
|
|
259
|
+
const histRes = await fetch(`${base}/history/${promptId}`, {
|
|
260
|
+
signal: AbortSignal.timeout(IMAGE_FETCH_TIMEOUT_MS)
|
|
261
|
+
});
|
|
262
|
+
if (!histRes.ok)
|
|
263
|
+
return images;
|
|
264
|
+
const histData = (await histRes.json());
|
|
265
|
+
const entry = histData[promptId];
|
|
266
|
+
if (!entry)
|
|
267
|
+
return images;
|
|
268
|
+
const outputs = entry.outputs;
|
|
269
|
+
if (outputs) {
|
|
270
|
+
for (const nodeOutput of Object.values(outputs)) {
|
|
271
|
+
if (!nodeOutput.images)
|
|
272
|
+
continue;
|
|
273
|
+
for (const img of nodeOutput.images) {
|
|
274
|
+
try {
|
|
275
|
+
const params = new URLSearchParams({
|
|
276
|
+
filename: img.filename,
|
|
277
|
+
subfolder: img.subfolder,
|
|
278
|
+
type: img.type
|
|
279
|
+
});
|
|
280
|
+
const viewRes = await fetch(`${base}/view?${params.toString()}`, {
|
|
281
|
+
signal: AbortSignal.timeout(IMAGE_FETCH_TIMEOUT_MS)
|
|
282
|
+
});
|
|
283
|
+
if (viewRes.ok) {
|
|
284
|
+
const buffer = await viewRes.arrayBuffer();
|
|
285
|
+
const base64 = Buffer.from(buffer).toString("base64");
|
|
286
|
+
images.push({
|
|
287
|
+
type: "image",
|
|
288
|
+
data: base64,
|
|
289
|
+
filename: img.filename
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
log.warn(`Failed to fetch image ${img.filename}: ${String(err)}`);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
catch (err) {
|
|
301
|
+
log.warn(`Failed to fetch history for ${promptId}: ${String(err)}`);
|
|
302
|
+
}
|
|
303
|
+
return images;
|
|
304
|
+
}
|
|
305
|
+
//# sourceMappingURL=comfy-executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comfy-executor.js","sourceRoot":"","sources":["../src/comfy-executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context packer — T-MSG-1.
|
|
3
|
+
*
|
|
4
|
+
* Truncates a conversation to fit within a token budget.
|
|
5
|
+
* Drops oldest messages first, keeping the most recent ones.
|
|
6
|
+
* Uses a simple estimate: 1 token ~ 4 characters.
|
|
7
|
+
*/
|
|
8
|
+
import type { Message } from "./providers/types.js";
|
|
9
|
+
export interface PackedContext {
|
|
10
|
+
messages: Message[];
|
|
11
|
+
systemPrompt: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Pack messages and system prompt into a token budget.
|
|
15
|
+
*
|
|
16
|
+
* Strategy:
|
|
17
|
+
* 1. If system prompt exceeds budget, truncate it.
|
|
18
|
+
* 2. Starting from the most recent message, add messages until budget exhausted.
|
|
19
|
+
* 3. Oldest messages are dropped first.
|
|
20
|
+
*/
|
|
21
|
+
export declare function packContext(messages: Message[], systemPrompt: string, maxTokens: number): PackedContext;
|
|
22
|
+
//# sourceMappingURL=context-packer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-packer.d.ts","sourceRoot":"","sources":["../src/context-packer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAkB,MAAM,sBAAsB,CAAC;AA2BpE,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CACzB,QAAQ,EAAE,OAAO,EAAE,EACnB,YAAY,EAAE,MAAM,EACpB,SAAS,EAAE,MAAM,GAChB,aAAa,CA2Bf"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context packer — T-MSG-1.
|
|
3
|
+
*
|
|
4
|
+
* Truncates a conversation to fit within a token budget.
|
|
5
|
+
* Drops oldest messages first, keeping the most recent ones.
|
|
6
|
+
* Uses a simple estimate: 1 token ~ 4 characters.
|
|
7
|
+
*/
|
|
8
|
+
/** Rough estimate: 1 token ≈ 4 characters. */
|
|
9
|
+
const CHARS_PER_TOKEN = 4;
|
|
10
|
+
/** Fixed token overhead for non-text content blocks (images, audio). */
|
|
11
|
+
const NON_TEXT_BLOCK_CHARS = 100;
|
|
12
|
+
function charsToTokens(chars) {
|
|
13
|
+
return Math.ceil(chars / CHARS_PER_TOKEN);
|
|
14
|
+
}
|
|
15
|
+
function estimateMessageTokens(msg) {
|
|
16
|
+
if (msg.content === null || msg.content === undefined)
|
|
17
|
+
return 1;
|
|
18
|
+
if (typeof msg.content === "string")
|
|
19
|
+
return charsToTokens(msg.content.length);
|
|
20
|
+
// MessageContent array
|
|
21
|
+
let chars = 0;
|
|
22
|
+
for (const part of msg.content) {
|
|
23
|
+
if (part.type === "text") {
|
|
24
|
+
chars += part.text.length;
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
chars += NON_TEXT_BLOCK_CHARS;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return charsToTokens(chars);
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Pack messages and system prompt into a token budget.
|
|
34
|
+
*
|
|
35
|
+
* Strategy:
|
|
36
|
+
* 1. If system prompt exceeds budget, truncate it.
|
|
37
|
+
* 2. Starting from the most recent message, add messages until budget exhausted.
|
|
38
|
+
* 3. Oldest messages are dropped first.
|
|
39
|
+
*/
|
|
40
|
+
export function packContext(messages, systemPrompt, maxTokens) {
|
|
41
|
+
let sysPrompt = systemPrompt;
|
|
42
|
+
let sysTokens = charsToTokens(sysPrompt.length);
|
|
43
|
+
// If system prompt alone exceeds budget, truncate it
|
|
44
|
+
if (sysTokens > maxTokens) {
|
|
45
|
+
const maxChars = maxTokens * CHARS_PER_TOKEN;
|
|
46
|
+
sysPrompt = sysPrompt.slice(0, maxChars);
|
|
47
|
+
sysTokens = maxTokens;
|
|
48
|
+
}
|
|
49
|
+
let remaining = maxTokens - sysTokens;
|
|
50
|
+
if (remaining <= 0)
|
|
51
|
+
return { messages: [], systemPrompt: sysPrompt };
|
|
52
|
+
// Walk messages from most recent to oldest
|
|
53
|
+
const kept = [];
|
|
54
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
55
|
+
const tokens = estimateMessageTokens(messages[i]);
|
|
56
|
+
if (tokens <= remaining) {
|
|
57
|
+
kept.unshift(messages[i]);
|
|
58
|
+
remaining -= tokens;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
break; // stop at the first message that doesn't fit
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return { messages: kept, systemPrompt: sysPrompt };
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=context-packer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-packer.js","sourceRoot":"","sources":["../src/context-packer.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,8CAA8C;AAC9C,MAAM,eAAe,GAAG,CAAC,CAAC;AAE1B,wEAAwE;AACxE,MAAM,oBAAoB,GAAG,GAAG,CAAC;AAEjC,SAAS,aAAa,CAAC,KAAa;IAClC,OAAO,IAAI,CAAC,IAAI,CAAC,KAAK,GAAG,eAAe,CAAC,CAAC;AAC5C,CAAC;AAED,SAAS,qBAAqB,CAAC,GAAY;IACzC,IAAI,GAAG,CAAC,OAAO,KAAK,IAAI,IAAI,GAAG,CAAC,OAAO,KAAK,SAAS;QAAE,OAAO,CAAC,CAAC;IAChE,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,aAAa,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC9E,uBAAuB;IACvB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,OAA2B,EAAE,CAAC;QACnD,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzB,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QAC5B,CAAC;aAAM,CAAC;YACN,KAAK,IAAI,oBAAoB,CAAC;QAChC,CAAC;IACH,CAAC;IACD,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;AAC9B,CAAC;AAOD;;;;;;;GAOG;AACH,MAAM,UAAU,WAAW,CACzB,QAAmB,EACnB,YAAoB,EACpB,SAAiB;IAEjB,IAAI,SAAS,GAAG,YAAY,CAAC;IAC7B,IAAI,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAEhD,qDAAqD;IACrD,IAAI,SAAS,GAAG,SAAS,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,SAAS,GAAG,eAAe,CAAC;QAC7C,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;QACzC,SAAS,GAAG,SAAS,CAAC;IACxB,CAAC;IAED,IAAI,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IACtC,IAAI,SAAS,IAAI,CAAC;QAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;IAErE,2CAA2C;IAC3C,MAAM,IAAI,GAAc,EAAE,CAAC;IAC3B,KAAK,IAAI,CAAC,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,MAAM,MAAM,GAAG,qBAAqB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAClD,IAAI,MAAM,IAAI,SAAS,EAAE,CAAC;YACxB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1B,SAAS,IAAI,MAAM,CAAC;QACtB,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,6CAA6C;QACtD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,SAAS,EAAE,CAAC;AACrD,CAAC"}
|