@cogitator-ai/studio 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +74 -0
- package/dist/host/checkpoints.d.ts +11 -0
- package/dist/host/checkpoints.d.ts.map +1 -0
- package/dist/host/checkpoints.js +43 -0
- package/dist/host/checkpoints.js.map +1 -0
- package/dist/host/main.d.ts +2 -0
- package/dist/host/main.d.ts.map +1 -0
- package/dist/host/main.js +49 -0
- package/dist/host/main.js.map +1 -0
- package/dist/host/project.d.ts +22 -0
- package/dist/host/project.d.ts.map +1 -0
- package/dist/host/project.js +88 -0
- package/dist/host/project.js.map +1 -0
- package/dist/host/runner.d.ts +58 -0
- package/dist/host/runner.d.ts.map +1 -0
- package/dist/host/runner.js +507 -0
- package/dist/host/runner.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol.d.ts +398 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +7 -0
- package/dist/protocol.js.map +1 -0
- package/dist/registry.d.ts +8 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +119 -0
- package/dist/registry.js.map +1 -0
- package/dist/server/host-manager.d.ts +52 -0
- package/dist/server/host-manager.d.ts.map +1 -0
- package/dist/server/host-manager.js +267 -0
- package/dist/server/host-manager.js.map +1 -0
- package/dist/server/server.d.ts +41 -0
- package/dist/server/server.d.ts.map +1 -0
- package/dist/server/server.js +437 -0
- package/dist/server/server.js.map +1 -0
- package/dist/server/store.d.ts +88 -0
- package/dist/server/store.d.ts.map +1 -0
- package/dist/server/store.js +602 -0
- package/dist/server/store.js.map +1 -0
- package/dist/ui/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/dist/ui/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/dist/ui/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/dist/ui/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/dist/ui/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/dist/ui/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
- package/dist/ui/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
- package/dist/ui/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
- package/dist/ui/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
- package/dist/ui/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
- package/dist/ui/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
- package/dist/ui/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
- package/dist/ui/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
- package/dist/ui/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
- package/dist/ui/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
- package/dist/ui/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
- package/dist/ui/assets/icons-f6vmKzId.js +1 -0
- package/dist/ui/assets/index-C4hZIqRf.js +8 -0
- package/dist/ui/assets/index-D3MDAGJQ.css +1 -0
- package/dist/ui/assets/markdown-B0lQtlaX.js +39 -0
- package/dist/ui/assets/math-D93AjGz5.css +1 -0
- package/dist/ui/assets/math-Dyab3dfo.js +257 -0
- package/dist/ui/assets/react-Oh0PCTUB.js +9 -0
- package/dist/ui/favicon.svg +1 -0
- package/dist/ui/index.html +21 -0
- package/dist/ui/theme.js +4 -0
- package/package.json +90 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Cogitator Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @cogitator-ai/studio
|
|
2
|
+
|
|
3
|
+
Cogitator Studio: a local debugger for Cogitator agent projects. Chat with every agent of a project, approve the tool calls that need it, read the trace and the cost of each run, run workflows and rerun them from a node, and fork a run from any step to see what a different input or tool result changes.
|
|
4
|
+
|
|
5
|
+
Guide: [cogitator.app/docs/getting-started/studio](https://cogitator.app/docs/getting-started/studio)
|
|
6
|
+
|
|
7
|
+
## Start it
|
|
8
|
+
|
|
9
|
+
In a project created by `create-cogitator-app` or `cogitator init`:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pnpm dev:studio # the script every generated project has
|
|
13
|
+
npx cogitator dev # the same, from @cogitator-ai/cli
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
It opens http://localhost:4321 (the next free port when it is taken). The studio finds the agents, workflows and swarms in `src/cogitator.ts`, the registry generated projects have: export the runtime as `cogitator` and the rest as `agents`, `workflows` and `swarms`.
|
|
17
|
+
|
|
18
|
+
## What it does
|
|
19
|
+
|
|
20
|
+
- **Overview**: the project at a glance, with its runs, success rate, spend in tokens and dollars, p50 and p95 latency, activity over the last two weeks, and every agent and workflow with the model it runs on and how often it ran.
|
|
21
|
+
- **Chat** with any agent: streamed answers rendered as Markdown with highlighted code and LaTeX math (`\(...\)`, `\[...\]` and `$$...$$`, a single `$` stays a dollar), reasoning, tool calls as one line each that opens to its arguments and result, errors, stop, and threads grouped by day. A project without memory gets one from the studio, so threads keep their conversation, also after a restart.
|
|
22
|
+
- **Approvals**: a tool call with `requiresApproval` waits in the chat with its arguments until you approve it, or reject it with a reason the model sees.
|
|
23
|
+
- **Traces**: every run as a waterfall of model calls, tool calls and the runs agent tools start, nested under the call that started them, with the time, the tokens and the cost of each model call (priced from the model registry, `unpriced` for unknown models) and the total, counted live while the run goes. Click a span for its details: cached and reasoning tokens, the finish reason, the arguments and the result of a tool call.
|
|
24
|
+
- **Workflows**: run one with an input state, watch the status and time of each node on its graph, read what each node returned (text an agent wrote is rendered as Markdown, the raw JSON is a click away), and rerun from a node, keeping what the nodes before it produced.
|
|
25
|
+
- **Time-travel forks**: pick a step of a finished run (before each tool call), change the input, add context or replace a tool result, and run on from there. The original and the fork are shown side by side, with the tool calls that differ highlighted.
|
|
26
|
+
- **History**: runs and threads are kept in `.cogitator/studio/` as JSON files, searchable by input, output and error and filtered by agent, workflow or kind. Runs a stopped studio left behind are marked failed.
|
|
27
|
+
- **Keyboard**: `⌘K` (`Ctrl+K`) opens a command palette over agents, workflows, the whole run history and actions, `/` searches the page, `G O` and `G R` go to the overview and the runs, `J` and `K` walk the run list and the trace, `N` starts a thread, and `?` lists every shortcut.
|
|
28
|
+
- **Themes**: light and dark, following the system until you pick one, which the browser remembers.
|
|
29
|
+
|
|
30
|
+
## How it works
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
browser ──HTTP, SSE──▶ studio server (cogitator dev) ──IPC──▶ runtime host (child process)
|
|
34
|
+
React UI run store in .cogitator/studio your project, loaded with tsx
|
|
35
|
+
file watcher cogitator.observe(), TimeTravel,
|
|
36
|
+
WorkflowManager
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- The **runtime host** is a child process that loads `.env` and `src/cogitator.ts` with tsx and runs the project with its own runtime, memory and tools. It watches every run through `cogitator.observe()`, so runs that agent tools start on the same runtime are seen too, and links them to the request that started them with `AsyncLocalStorage`. Forks use the project's `TimeTravel` with checkpoints kept on disk; workflows run on a `WorkflowManager` with file checkpoints, which is what reruns from a node start from.
|
|
40
|
+
- The **server** keeps the runs and threads, prices model calls, puts nested runs under the tool call whose span was open when they started, and pushes every change to the browser over server-sent events.
|
|
41
|
+
- When a file under `src/`, `cogitator.yml`, `.env`, `package.json` or `tsconfig.json` changes, the host is started again with the new code: the server and the browser stay, runs that were going are marked failed with the reason.
|
|
42
|
+
|
|
43
|
+
## Security
|
|
44
|
+
|
|
45
|
+
The server listens on `127.0.0.1` and answers only requests for `localhost`, so another site cannot reach it through DNS rebinding, and refuses cross-site posts. `--host 0.0.0.0` (or any other address) opens it to the network and requires the random token printed in its URL; the token is kept in an `HttpOnly`, `SameSite=Strict` cookie after the first visit.
|
|
46
|
+
|
|
47
|
+
## API
|
|
48
|
+
|
|
49
|
+
```ts
|
|
50
|
+
import { startStudio } from '@cogitator-ai/studio';
|
|
51
|
+
|
|
52
|
+
const studio = await startStudio({ projectDir: process.cwd(), port: 4321 });
|
|
53
|
+
console.log(studio.url);
|
|
54
|
+
await studio.ready();
|
|
55
|
+
// ...
|
|
56
|
+
await studio.close();
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| Option | Default | What it does |
|
|
60
|
+
| ------------ | ---------------------- | ----------------------------------------------------- |
|
|
61
|
+
| `projectDir` | required | The project to run |
|
|
62
|
+
| `host` | `127.0.0.1` | Interface to listen on; anything else needs the token |
|
|
63
|
+
| `port` | `4321` | Port, the next free one unless `strictPort` |
|
|
64
|
+
| `token` | random beyond loopback | Token requests must carry |
|
|
65
|
+
| `watch` | `true` | Reload the project when its files change |
|
|
66
|
+
| `studioDir` | `.cogitator/studio` | Where the history lives |
|
|
67
|
+
| `log` | | Receives the project's output |
|
|
68
|
+
| `price` | model registry | Prices a model call from its model and tokens |
|
|
69
|
+
|
|
70
|
+
The HTTP API the UI uses is open to scripts as well: `GET /api/state`, `GET /api/runs?target=&kind=&q=`, `GET /api/runs/:id`, `GET /api/threads/:id`, `POST /api/chat`, `POST /api/runs/:id/stop`, `POST /api/approvals/:id`, `POST /api/runs/:id/fork`, `POST /api/workflows/:key/run`, `POST /api/runs/:id/rerun`, `GET /api/stats` for the totals of the overview, and `GET /api/events` for the event stream. The shapes are the types exported from the package (`RunRecord`, `ThreadRecord`, `StudioStats`, `StudioEvent` and the rest).
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { InMemoryCheckpointStore } from '@cogitator-ai/core';
|
|
2
|
+
type CheckpointStoreClass = typeof InMemoryCheckpointStore;
|
|
3
|
+
/**
|
|
4
|
+
* A time-travel checkpoint store that keeps every checkpoint as a JSON file in
|
|
5
|
+
* `directory`, so the runs of earlier studio sessions can still be forked.
|
|
6
|
+
* It extends the in-memory store of the project's @cogitator-ai/core, which
|
|
7
|
+
* keeps the indexes and the queries.
|
|
8
|
+
*/
|
|
9
|
+
export declare function openCheckpointStore(Base: CheckpointStoreClass, directory: string): Promise<InMemoryCheckpointStore>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=checkpoints.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoints.d.ts","sourceRoot":"","sources":["../../src/host/checkpoints.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,oBAAoB,CAAC;AAGlE,KAAK,oBAAoB,GAAG,OAAO,uBAAuB,CAAC;AAO3D;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,oBAAoB,EAC1B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,uBAAuB,CAAC,CA+BlC"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
function revive(raw) {
|
|
4
|
+
const parsed = JSON.parse(raw);
|
|
5
|
+
return { ...parsed, createdAt: new Date(parsed.createdAt) };
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* A time-travel checkpoint store that keeps every checkpoint as a JSON file in
|
|
9
|
+
* `directory`, so the runs of earlier studio sessions can still be forked.
|
|
10
|
+
* It extends the in-memory store of the project's @cogitator-ai/core, which
|
|
11
|
+
* keeps the indexes and the queries.
|
|
12
|
+
*/
|
|
13
|
+
export async function openCheckpointStore(Base, directory) {
|
|
14
|
+
mkdirSync(directory, { recursive: true });
|
|
15
|
+
const fileOf = (id) => join(directory, `${id.replace(/[^\w-]/g, '_')}.json`);
|
|
16
|
+
class FileTimeTravelStore extends Base {
|
|
17
|
+
async save(checkpoint) {
|
|
18
|
+
await super.save(checkpoint);
|
|
19
|
+
writeFileSync(fileOf(checkpoint.id), JSON.stringify(checkpoint));
|
|
20
|
+
}
|
|
21
|
+
async delete(id) {
|
|
22
|
+
const deleted = await super.delete(id);
|
|
23
|
+
rmSync(fileOf(id), { force: true });
|
|
24
|
+
return deleted;
|
|
25
|
+
}
|
|
26
|
+
async restore(checkpoint) {
|
|
27
|
+
await super.save(checkpoint);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
const store = new FileTimeTravelStore();
|
|
31
|
+
for (const name of existsSync(directory) ? readdirSync(directory) : []) {
|
|
32
|
+
if (!name.endsWith('.json'))
|
|
33
|
+
continue;
|
|
34
|
+
try {
|
|
35
|
+
await store.restore(revive(readFileSync(join(directory, name), 'utf-8')));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
rmSync(join(directory, name), { force: true });
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return store;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=checkpoints.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checkpoints.js","sourceRoot":"","sources":["../../src/host/checkpoints.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClG,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,SAAS,MAAM,CAAC,GAAW;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAgD,CAAC;IAC9E,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;AAC9D,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,IAA0B,EAC1B,SAAiB;IAEjB,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,CAAC,EAAU,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,OAAO,CAAC,CAAC;IAErF,MAAM,mBAAoB,SAAQ,IAAI;QAC3B,KAAK,CAAC,IAAI,CAAC,UAA+B;YACjD,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAC7B,aAAa,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;QACnE,CAAC;QAEQ,KAAK,CAAC,MAAM,CAAC,EAAU;YAC9B,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACvC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACpC,OAAO,OAAO,CAAC;QACjB,CAAC;QAED,KAAK,CAAC,OAAO,CAAC,UAA+B;YAC3C,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC/B,CAAC;KACF;IAED,MAAM,KAAK,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACxC,KAAK,MAAM,IAAI,IAAI,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;QACvE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC;YACH,MAAM,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC;QAC5E,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/host/main.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { StudioHost } from './runner.js';
|
|
2
|
+
/**
|
|
3
|
+
* The runtime host: a child process of `cogitator dev` that loads the project
|
|
4
|
+
* with tsx and runs it for the studio. It is started again whenever the
|
|
5
|
+
* project changes, so the studio always runs the current code.
|
|
6
|
+
*/
|
|
7
|
+
const [projectDir, studioDir] = process.argv.slice(2);
|
|
8
|
+
function send(message) {
|
|
9
|
+
return new Promise((resolve) => {
|
|
10
|
+
if (!process.send)
|
|
11
|
+
return resolve();
|
|
12
|
+
process.send(message, () => resolve());
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
process.on('unhandledRejection', (reason) => {
|
|
16
|
+
console.error('[studio host] unhandled rejection:', reason);
|
|
17
|
+
});
|
|
18
|
+
process.on('disconnect', () => process.exit(0));
|
|
19
|
+
if (!projectDir || !studioDir) {
|
|
20
|
+
console.error('usage: host <projectDir> <studioDir>');
|
|
21
|
+
process.exit(2);
|
|
22
|
+
}
|
|
23
|
+
try {
|
|
24
|
+
const host = await StudioHost.create(projectDir, studioDir, (event) => {
|
|
25
|
+
void send({ type: 'event', event });
|
|
26
|
+
});
|
|
27
|
+
process.on('message', (request) => {
|
|
28
|
+
host.handle(request).then((data) => send({ type: 'response', requestId: request.requestId, ok: true, data }), (error) => send({
|
|
29
|
+
type: 'response',
|
|
30
|
+
requestId: request.requestId,
|
|
31
|
+
ok: false,
|
|
32
|
+
error: error instanceof Error ? error.message : String(error),
|
|
33
|
+
}));
|
|
34
|
+
});
|
|
35
|
+
process.once('SIGTERM', () => {
|
|
36
|
+
void host.close().finally(() => process.exit(0));
|
|
37
|
+
});
|
|
38
|
+
await send({ type: 'ready', registry: host.registry(), memory: host.memory });
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
const detail = error instanceof Error ? (error.stack ?? error.message) : String(error);
|
|
42
|
+
console.error(detail);
|
|
43
|
+
await send({
|
|
44
|
+
type: 'load-failed',
|
|
45
|
+
error: error instanceof Error ? error.message : String(error),
|
|
46
|
+
});
|
|
47
|
+
process.exit(1);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=main.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../src/host/main.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC;;;;GAIG;AACH,MAAM,CAAC,UAAU,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAEtD,SAAS,IAAI,CAAC,OAAoB;IAChC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC,OAAO,CAAC,IAAI;YAAE,OAAO,OAAO,EAAE,CAAC;QACpC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,MAAM,CAAC,CAAC;AAC9D,CAAC,CAAC,CAAC;AACH,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAEhD,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS,EAAE,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;IACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,CAAC;IACH,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;QACpE,KAAK,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAoB,EAAE,EAAE;QAC7C,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CACvB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,EAClF,CAAC,KAAc,EAAE,EAAE,CACjB,IAAI,CAAC;YACH,IAAI,EAAE,UAAU;YAChB,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;SAC9D,CAAC,CACL,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE;QAC3B,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;IACH,MAAM,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;AAChF,CAAC;AAAC,OAAO,KAAK,EAAE,CAAC;IACf,MAAM,MAAM,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvF,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IACtB,MAAM,IAAI,CAAC;QACT,IAAI,EAAE,aAAa;QACnB,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;KAC9D,CAAC,CAAC;IACH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Agent, Cogitator } from '@cogitator-ai/core';
|
|
2
|
+
import type { Workflow } from '@cogitator-ai/types';
|
|
3
|
+
/**
|
|
4
|
+
* A package as the project resolves it, so the studio uses the very classes
|
|
5
|
+
* the project's runtime was built with; the studio's own copy when the
|
|
6
|
+
* project does not have it.
|
|
7
|
+
*/
|
|
8
|
+
export declare function importFromProject<T>(projectDir: string, name: string): Promise<T>;
|
|
9
|
+
/** Whether the project can resolve `name`. */
|
|
10
|
+
export declare function projectHas(projectDir: string, name: string): boolean;
|
|
11
|
+
export interface LoadedProject {
|
|
12
|
+
cogitator: Cogitator;
|
|
13
|
+
agents: Map<string, Agent>;
|
|
14
|
+
workflows: Map<string, Workflow>;
|
|
15
|
+
module: Record<string, unknown>;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Loads `.env` and the registry of the project: the runtime it exports as
|
|
19
|
+
* `cogitator`, and its agents and workflows by key.
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadProject(projectDir: string): Promise<LoadedProject>;
|
|
22
|
+
//# sourceMappingURL=project.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.d.ts","sourceRoot":"","sources":["../../src/host/project.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAGpD;;;;GAIG;AACH,wBAAsB,iBAAiB,CAAC,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAQvF;AAED,8CAA8C;AAC9C,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAOpE;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,SAAS,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAC3B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AA2CD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAsB5E"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { existsSync } from 'node:fs';
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { pathToFileURL } from 'node:url';
|
|
5
|
+
import { REGISTRY_PATH } from '../registry.js';
|
|
6
|
+
/**
|
|
7
|
+
* A package as the project resolves it, so the studio uses the very classes
|
|
8
|
+
* the project's runtime was built with; the studio's own copy when the
|
|
9
|
+
* project does not have it.
|
|
10
|
+
*/
|
|
11
|
+
export async function importFromProject(projectDir, name) {
|
|
12
|
+
let entry;
|
|
13
|
+
try {
|
|
14
|
+
entry = createRequire(join(projectDir, 'package.json')).resolve(name);
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
entry = undefined;
|
|
18
|
+
}
|
|
19
|
+
return (await import(entry ? pathToFileURL(entry).href : name));
|
|
20
|
+
}
|
|
21
|
+
/** Whether the project can resolve `name`. */
|
|
22
|
+
export function projectHas(projectDir, name) {
|
|
23
|
+
try {
|
|
24
|
+
createRequire(join(projectDir, 'package.json')).resolve(name);
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function isAgent(value) {
|
|
32
|
+
return (typeof value === 'object' &&
|
|
33
|
+
value !== null &&
|
|
34
|
+
'config' in value &&
|
|
35
|
+
typeof value.config === 'object' &&
|
|
36
|
+
value.config !== null &&
|
|
37
|
+
'instructions' in value.config &&
|
|
38
|
+
typeof value.config.instructions === 'string');
|
|
39
|
+
}
|
|
40
|
+
function isWorkflow(value) {
|
|
41
|
+
return (typeof value === 'object' &&
|
|
42
|
+
value !== null &&
|
|
43
|
+
'nodes' in value &&
|
|
44
|
+
value.nodes instanceof Map &&
|
|
45
|
+
'entryPoint' in value &&
|
|
46
|
+
typeof value.entryPoint === 'string');
|
|
47
|
+
}
|
|
48
|
+
function isCogitator(value) {
|
|
49
|
+
return (typeof value === 'object' &&
|
|
50
|
+
value !== null &&
|
|
51
|
+
'run' in value &&
|
|
52
|
+
typeof value.run === 'function' &&
|
|
53
|
+
'observe' in value &&
|
|
54
|
+
typeof value.observe === 'function');
|
|
55
|
+
}
|
|
56
|
+
function entries(group, guard) {
|
|
57
|
+
const found = new Map();
|
|
58
|
+
if (typeof group !== 'object' || group === null)
|
|
59
|
+
return found;
|
|
60
|
+
for (const [key, value] of Object.entries(group))
|
|
61
|
+
if (guard(value))
|
|
62
|
+
found.set(key, value);
|
|
63
|
+
return found;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Loads `.env` and the registry of the project: the runtime it exports as
|
|
67
|
+
* `cogitator`, and its agents and workflows by key.
|
|
68
|
+
*/
|
|
69
|
+
export async function loadProject(projectDir) {
|
|
70
|
+
const envFile = join(projectDir, '.env');
|
|
71
|
+
if (existsSync(envFile))
|
|
72
|
+
process.loadEnvFile(envFile);
|
|
73
|
+
const registryPath = join(projectDir, REGISTRY_PATH);
|
|
74
|
+
if (!existsSync(registryPath)) {
|
|
75
|
+
throw new Error(`${REGISTRY_PATH} not found: Cogitator Studio finds agents, workflows and swarms in the registry projects from create-cogitator-app have. Export your runtime as \`cogitator\` and your agents as \`agents\` from ${REGISTRY_PATH}.`);
|
|
76
|
+
}
|
|
77
|
+
const module = (await import(pathToFileURL(registryPath).href));
|
|
78
|
+
if (!isCogitator(module.cogitator)) {
|
|
79
|
+
throw new Error(`${REGISTRY_PATH} does not export the runtime as \`cogitator\` (a Cogitator from @cogitator-ai/core 0.34 or newer)`);
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
cogitator: module.cogitator,
|
|
83
|
+
agents: entries(module.agents, isAgent),
|
|
84
|
+
workflows: entries(module.workflows, isWorkflow),
|
|
85
|
+
module,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../src/host/project.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAGzC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAE/C;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAI,UAAkB,EAAE,IAAY;IACzE,IAAI,KAAyB,CAAC;IAC9B,IAAI,CAAC;QACH,KAAK,GAAG,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACxE,CAAC;IAAC,MAAM,CAAC;QACP,KAAK,GAAG,SAAS,CAAC;IACpB,CAAC;IACD,OAAO,CAAC,MAAM,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAM,CAAC;AACvE,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,UAAU,CAAC,UAAkB,EAAE,IAAY;IACzD,IAAI,CAAC;QACH,aAAa,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AASD,SAAS,OAAO,CAAC,KAAc;IAC7B,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,QAAQ,IAAI,KAAK;QACjB,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ;QAChC,KAAK,CAAC,MAAM,KAAK,IAAI;QACrB,cAAc,IAAI,KAAK,CAAC,MAAM;QAC9B,OAAO,KAAK,CAAC,MAAM,CAAC,YAAY,KAAK,QAAQ,CAC9C,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,KAAc;IAChC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,OAAO,IAAI,KAAK;QAChB,KAAK,CAAC,KAAK,YAAY,GAAG;QAC1B,YAAY,IAAI,KAAK;QACrB,OAAO,KAAK,CAAC,UAAU,KAAK,QAAQ,CACrC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,KAAK,IAAI,KAAK;QACd,OAAO,KAAK,CAAC,GAAG,KAAK,UAAU;QAC/B,SAAS,IAAI,KAAK;QAClB,OAAO,KAAK,CAAC,OAAO,KAAK,UAAU,CACpC,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAI,KAAc,EAAE,KAAqC;IACvE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAa,CAAC;IACnC,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,KAAK,CAAC;IAC9D,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,KAAK,CAAC,KAAK,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC1F,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAkB;IAClD,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACzC,IAAI,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEtD,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,MAAM,IAAI,KAAK,CACb,GAAG,aAAa,oMAAoM,aAAa,GAAG,CACrO,CAAC;IACJ,CAAC;IACD,MAAM,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAA4B,CAAC;IAC3F,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CACb,GAAG,aAAa,mGAAmG,CACpH,CAAC;IACJ,CAAC;IACD,OAAO;QACL,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;QACvC,SAAS,EAAE,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC;QAChD,MAAM;KACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { HostEvent, HostRequest, RegistryInfo } from '../protocol.js';
|
|
2
|
+
/**
|
|
3
|
+
* Runs the project for the studio: chats with its agents, asks the studio
|
|
4
|
+
* to approve tool calls, forks runs from their steps and runs its workflows.
|
|
5
|
+
* Everything that happens is reported through `emit`, from the runtime's own
|
|
6
|
+
* observer, so runs agent tools start show up too.
|
|
7
|
+
*/
|
|
8
|
+
export declare class StudioHost {
|
|
9
|
+
private readonly project;
|
|
10
|
+
private readonly core;
|
|
11
|
+
private readonly options;
|
|
12
|
+
private readonly als;
|
|
13
|
+
private readonly controllers;
|
|
14
|
+
private readonly approvals;
|
|
15
|
+
private readonly seeded;
|
|
16
|
+
private readonly workflowRunIds;
|
|
17
|
+
private timeTravel?;
|
|
18
|
+
private manager?;
|
|
19
|
+
private constructor();
|
|
20
|
+
static create(projectDir: string, studioDir: string, emit: (event: HostEvent) => void): Promise<StudioHost>;
|
|
21
|
+
get memory(): 'project' | 'studio';
|
|
22
|
+
registry(): RegistryInfo;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
handle(request: HostRequest): Promise<unknown>;
|
|
25
|
+
private emit;
|
|
26
|
+
/** Reports every run started for a studio request, nested ones included. */
|
|
27
|
+
private observer;
|
|
28
|
+
private agent;
|
|
29
|
+
private workflow;
|
|
30
|
+
/**
|
|
31
|
+
* Starts `start` under a new studio request and resolves with the id of
|
|
32
|
+
* the run it started, or rejects when it failed before starting one.
|
|
33
|
+
*/
|
|
34
|
+
private begin;
|
|
35
|
+
/** Replays a thread's earlier messages into the studio's own memory, once per host. */
|
|
36
|
+
private seed;
|
|
37
|
+
private chat;
|
|
38
|
+
/**
|
|
39
|
+
* Reports how a run the studio started ended, with its fork steps. A run
|
|
40
|
+
* with a controller can be stopped from the studio.
|
|
41
|
+
*/
|
|
42
|
+
private finish;
|
|
43
|
+
/** Holds a tool call until the studio approves or rejects it. */
|
|
44
|
+
private ask;
|
|
45
|
+
private decide;
|
|
46
|
+
private stop;
|
|
47
|
+
private travel;
|
|
48
|
+
/** The steps a run can be forked from: one before each tool call, or its start. */
|
|
49
|
+
private steps;
|
|
50
|
+
private fork;
|
|
51
|
+
private workflowManager;
|
|
52
|
+
private nodeCallbacks;
|
|
53
|
+
/** Runs a workflow under a studio id the run is known by from its first event. */
|
|
54
|
+
private startWorkflow;
|
|
55
|
+
private runWorkflow;
|
|
56
|
+
private rerunWorkflow;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/host/runner.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAGV,SAAS,EACT,WAAW,EAEX,YAAY,EAIb,MAAM,gBAAgB,CAAC;AAyFxB;;;;;GAKG;AACH,qBAAa,UAAU;IAUnB,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,OAAO;IAX1B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAuC;IAC3D,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAsC;IAClE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAsC;IAChE,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAA6B;IAC5D,OAAO,CAAC,UAAU,CAAC,CAAsB;IACzC,OAAO,CAAC,OAAO,CAAC,CAAkD;IAElE,OAAO;WAWM,MAAM,CACjB,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,KAAK,IAAI,GAC/B,OAAO,CAAC,UAAU,CAAC;IAetB,IAAI,MAAM,IAAI,SAAS,GAAG,QAAQ,CAEjC;IAED,QAAQ,IAAI,YAAY;IAIlB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAK5B,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;IAiB9C,OAAO,CAAC,IAAI;IAIZ,4EAA4E;IAC5E,OAAO,CAAC,QAAQ;IAsDhB,OAAO,CAAC,KAAK;IAMb,OAAO,CAAC,QAAQ;IAMhB;;;OAGG;YACW,KAAK;IAYnB,uFAAuF;YACzE,IAAI;YAqBJ,IAAI;IAwClB;;;OAGG;IACH,OAAO,CAAC,MAAM;IA6Cd,iEAAiE;IACjE,OAAO,CAAC,GAAG;IAgBX,OAAO,CAAC,MAAM;IAed,OAAO,CAAC,IAAI;IAUZ,OAAO,CAAC,MAAM;IAcd,mFAAmF;YACrE,KAAK;YAkBL,IAAI;IAmClB,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,aAAa;IA4BrB,kFAAkF;IAClF,OAAO,CAAC,aAAa;YAiDP,WAAW;YAUX,aAAa;CAmB5B"}
|