askvireo 0.0.0-stage → 0.1.3
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/access.js +33 -0
- package/dist/access.js.map +1 -0
- package/dist/acp.js +257 -0
- package/dist/acp.js.map +1 -0
- package/dist/actions.js +141 -0
- package/dist/actions.js.map +1 -0
- package/dist/address.js +32 -0
- package/dist/address.js.map +1 -0
- package/dist/aftercare.js +51 -0
- package/dist/aftercare.js.map +1 -0
- package/dist/agents.js +164 -0
- package/dist/agents.js.map +1 -0
- package/dist/app.js +67 -0
- package/dist/app.js.map +1 -0
- package/dist/audit.js +40 -0
- package/dist/audit.js.map +1 -0
- package/dist/browser.js +559 -0
- package/dist/browser.js.map +1 -0
- package/dist/bus.js +27 -0
- package/dist/bus.js.map +1 -0
- package/dist/cards/blocks.js +80 -0
- package/dist/cards/blocks.js.map +1 -0
- package/dist/cards/diff.js +48 -0
- package/dist/cards/diff.js.map +1 -0
- package/dist/cards/kinds.js +139 -0
- package/dist/cards/kinds.js.map +1 -0
- package/dist/cards/store.js +177 -0
- package/dist/cards/store.js.map +1 -0
- package/dist/cli-model.js +593 -0
- package/dist/cli-model.js.map +1 -0
- package/dist/cli.js +245 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +33 -0
- package/dist/config.js.map +1 -0
- package/dist/connect.js +97 -0
- package/dist/connect.js.map +1 -0
- package/dist/db.js +288 -0
- package/dist/db.js.map +1 -0
- package/dist/extract.js +75 -0
- package/dist/extract.js.map +1 -0
- package/dist/fake-llm-server.js +118 -0
- package/dist/fake-llm-server.js.map +1 -0
- package/dist/fake-model.js +517 -0
- package/dist/fake-model.js.map +1 -0
- package/dist/files.js +70 -0
- package/dist/files.js.map +1 -0
- package/dist/hook.js +149 -0
- package/dist/hook.js.map +1 -0
- package/dist/http/browser.js +91 -0
- package/dist/http/browser.js.map +1 -0
- package/dist/http/events.js +54 -0
- package/dist/http/events.js.map +1 -0
- package/dist/http/index.js +91 -0
- package/dist/http/index.js.map +1 -0
- package/dist/http/memory.js +40 -0
- package/dist/http/memory.js.map +1 -0
- package/dist/http/settings.js +74 -0
- package/dist/http/settings.js.map +1 -0
- package/dist/http/test.js +38 -0
- package/dist/http/test.js.map +1 -0
- package/dist/http/threads.js +109 -0
- package/dist/http/threads.js.map +1 -0
- package/dist/http/views.js +43 -0
- package/dist/http/views.js.map +1 -0
- package/dist/http/work.js +27 -0
- package/dist/http/work.js.map +1 -0
- package/dist/identity.js +26 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/integrations/index.js +44 -0
- package/dist/integrations/index.js.map +1 -0
- package/dist/integrations/local.js +144 -0
- package/dist/integrations/local.js.map +1 -0
- package/dist/integrations/types.js +2 -0
- package/dist/integrations/types.js.map +1 -0
- package/dist/lifecycle.js +74 -0
- package/dist/lifecycle.js.map +1 -0
- package/dist/link.js +33 -0
- package/dist/link.js.map +1 -0
- package/dist/memory-sync.js +93 -0
- package/dist/memory-sync.js.map +1 -0
- package/dist/memory-worker.js +146 -0
- package/dist/memory-worker.js.map +1 -0
- package/dist/memory.js +217 -0
- package/dist/memory.js.map +1 -0
- package/dist/messages.js +13 -0
- package/dist/messages.js.map +1 -0
- package/dist/models.js +375 -0
- package/dist/models.js.map +1 -0
- package/dist/net.js +28 -0
- package/dist/net.js.map +1 -0
- package/dist/peers.js +82 -0
- package/dist/peers.js.map +1 -0
- package/dist/plugins/agents/index.js +370 -0
- package/dist/plugins/agents/index.js.map +1 -0
- package/dist/plugins/chat.js +258 -0
- package/dist/plugins/chat.js.map +1 -0
- package/dist/plugins/endpoint/index.js +436 -0
- package/dist/plugins/endpoint/index.js.map +1 -0
- package/dist/plugins/feishu/index.js +256 -0
- package/dist/plugins/feishu/index.js.map +1 -0
- package/dist/plugins/google/api.js +347 -0
- package/dist/plugins/google/api.js.map +1 -0
- package/dist/plugins/google/index.js +170 -0
- package/dist/plugins/google/index.js.map +1 -0
- package/dist/plugins/index.js +523 -0
- package/dist/plugins/index.js.map +1 -0
- package/dist/plugins/mcp/index.js +218 -0
- package/dist/plugins/mcp/index.js.map +1 -0
- package/dist/plugins/nodes/index.js +232 -0
- package/dist/plugins/nodes/index.js.map +1 -0
- package/dist/plugins/search/index.js +122 -0
- package/dist/plugins/search/index.js.map +1 -0
- package/dist/plugins/tailscale/api.js +52 -0
- package/dist/plugins/tailscale/api.js.map +1 -0
- package/dist/plugins/tailscale/daemon.js +203 -0
- package/dist/plugins/tailscale/daemon.js.map +1 -0
- package/dist/plugins/tailscale/index.js +504 -0
- package/dist/plugins/tailscale/index.js.map +1 -0
- package/dist/plugins/telegram/index.js +174 -0
- package/dist/plugins/telegram/index.js.map +1 -0
- package/dist/plugins/types.js +2 -0
- package/dist/plugins/types.js.map +1 -0
- package/dist/pricing.js +113 -0
- package/dist/pricing.js.map +1 -0
- package/dist/procedures.js +57 -0
- package/dist/procedures.js.map +1 -0
- package/dist/prompt.js +106 -0
- package/dist/prompt.js.map +1 -0
- package/dist/push.js +48 -0
- package/dist/push.js.map +1 -0
- package/dist/relay-client.js +176 -0
- package/dist/relay-client.js.map +1 -0
- package/dist/reminders.js +40 -0
- package/dist/reminders.js.map +1 -0
- package/dist/runner.js +350 -0
- package/dist/runner.js.map +1 -0
- package/dist/scheduler.js +182 -0
- package/dist/scheduler.js.map +1 -0
- package/dist/server.js +105 -0
- package/dist/server.js.map +1 -0
- package/dist/service.js +196 -0
- package/dist/service.js.map +1 -0
- package/dist/settings.js +28 -0
- package/dist/settings.js.map +1 -0
- package/dist/threads.js +197 -0
- package/dist/threads.js.map +1 -0
- package/dist/time.js +85 -0
- package/dist/time.js.map +1 -0
- package/dist/tool-gate.js +70 -0
- package/dist/tool-gate.js.map +1 -0
- package/dist/tools/approval.js +22 -0
- package/dist/tools/approval.js.map +1 -0
- package/dist/tools/browser.js +291 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/calendar.js +153 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/cards.js +176 -0
- package/dist/tools/cards.js.map +1 -0
- package/dist/tools/email.js +76 -0
- package/dist/tools/email.js.map +1 -0
- package/dist/tools/files.js +57 -0
- package/dist/tools/files.js.map +1 -0
- package/dist/tools/index.js +16 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/memory.js +90 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/research.js +163 -0
- package/dist/tools/research.js.map +1 -0
- package/dist/tools/setup.js +98 -0
- package/dist/tools/setup.js.map +1 -0
- package/dist/tools/threads.js +132 -0
- package/dist/tools/threads.js.map +1 -0
- package/dist/tools/types.js +16 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/usage.js +75 -0
- package/dist/usage.js.map +1 -0
- package/dist/util.js +71 -0
- package/dist/util.js.map +1 -0
- package/dist/vault.js +81 -0
- package/dist/vault.js.map +1 -0
- package/dist/version.js +4 -0
- package/dist/version.js.map +1 -0
- package/dist/watch.js +104 -0
- package/dist/watch.js.map +1 -0
- package/package.json +45 -4
- package/README.md +0 -3
package/dist/access.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { createPublicKey, verify } from "node:crypto";
|
|
2
|
+
const HEADER = Buffer.from(JSON.stringify({ alg: "EdDSA", typ: "JWT" })).toString("base64url");
|
|
3
|
+
const keys = new Map();
|
|
4
|
+
/**
|
|
5
|
+
* Checks an access token from the app: signed by the cloud this node is
|
|
6
|
+
* linked to, issued for this node, for its owner, and not expired. The same
|
|
7
|
+
* check applies whether the request came through the relay or straight over
|
|
8
|
+
* the tailnet, so the relay is never trusted to decide who gets in.
|
|
9
|
+
*/
|
|
10
|
+
export function verifyAccess(token, identity) {
|
|
11
|
+
if (!token || !identity)
|
|
12
|
+
return undefined;
|
|
13
|
+
const [header, payload, sig] = token.split(".");
|
|
14
|
+
if (header !== HEADER || !payload || !sig)
|
|
15
|
+
return undefined;
|
|
16
|
+
let key = keys.get(identity.publicKey);
|
|
17
|
+
if (!key) {
|
|
18
|
+
key = createPublicKey(identity.publicKey);
|
|
19
|
+
keys.set(identity.publicKey, key);
|
|
20
|
+
}
|
|
21
|
+
if (!verify(null, Buffer.from(`${header}.${payload}`), key, Buffer.from(sig, "base64url")))
|
|
22
|
+
return undefined;
|
|
23
|
+
let claims;
|
|
24
|
+
try {
|
|
25
|
+
claims = JSON.parse(Buffer.from(payload, "base64url").toString());
|
|
26
|
+
}
|
|
27
|
+
catch {
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
const ok = claims.aud === identity.nodeId && claims.sub === identity.owner.id && claims.exp * 1000 > Date.now();
|
|
31
|
+
return ok ? claims : undefined;
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=access.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"access.js","sourceRoot":"","sources":["../src/access.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,EAAkB,MAAM,aAAa,CAAC;AAItE,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;AAC/F,MAAM,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;AAE1C;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAyB,EAAE,QAAkC;IACxF,IAAI,CAAC,KAAK,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC;IAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAChD,IAAI,MAAM,KAAK,MAAM,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG;QAAE,OAAO,SAAS,CAAC;IAC5D,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IACvC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,GAAG,GAAG,eAAe,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;QAC1C,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IACpC,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,OAAO,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAC7G,IAAI,MAAkB,CAAC;IACvB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAe,CAAC;IAClF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,GAAG,KAAK,QAAQ,CAAC,KAAK,CAAC,EAAE,IAAI,MAAM,CAAC,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAChH,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AACjC,CAAC"}
|
package/dist/acp.js
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
/**
|
|
5
|
+
* Coding agents over the Agent Client Protocol.
|
|
6
|
+
*
|
|
7
|
+
* `acpx` (openclaw/acpx) is a headless ACP client: it starts a coding agent,
|
|
8
|
+
* keeps its session, and mediates permission requests. Vireo drives it as a
|
|
9
|
+
* child process and reads its JSON-RPC stream, so every agent acpx knows
|
|
10
|
+
* (Claude Code, Codex, opencode, pi, …) works without more code.
|
|
11
|
+
*/
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
/** acpx's CLI entry, from this package's own dependency: nothing to install globally. */
|
|
14
|
+
export function acpxEntry() {
|
|
15
|
+
return join(dirname(require.resolve("acpx/package.json")), "dist", "cli.js");
|
|
16
|
+
}
|
|
17
|
+
const READ_KINDS = ["read", "search", "think", "fetch"];
|
|
18
|
+
const WRITE_KINDS = ["edit", "move"];
|
|
19
|
+
const DANGEROUS_KINDS = ["delete", "execute", "other"];
|
|
20
|
+
export function permissionArgs(mode) {
|
|
21
|
+
if (mode === "full")
|
|
22
|
+
return ["--approve-all", "--permission-policy", JSON.stringify({ defaultAction: "approve" }), "--non-interactive-permissions", "deny"];
|
|
23
|
+
const policy = mode === "read-only"
|
|
24
|
+
? { autoApprove: READ_KINDS, autoDeny: [...WRITE_KINDS, ...DANGEROUS_KINDS], defaultAction: "deny" }
|
|
25
|
+
: { autoApprove: [...READ_KINDS, ...WRITE_KINDS], autoDeny: DANGEROUS_KINDS, defaultAction: "deny" };
|
|
26
|
+
// The client's own filesystem and terminal capabilities let an agent act without asking for
|
|
27
|
+
// permission at all, so they are what makes a mode mean anything: without the terminal an agent has
|
|
28
|
+
// to ask before running a command, and without the filesystem (read-only) it cannot write at all.
|
|
29
|
+
const args = ["--deny-all", "--permission-policy", JSON.stringify(policy), "--non-interactive-permissions", "deny", "--no-terminal"];
|
|
30
|
+
if (mode === "read-only")
|
|
31
|
+
args.push("--no-fs");
|
|
32
|
+
return args;
|
|
33
|
+
}
|
|
34
|
+
/** Global flags, which acpx requires before the agent name. */
|
|
35
|
+
export function globalArgs(o) {
|
|
36
|
+
const args = ["--cwd", o.cwd, "--format", "json", "--json-strict", "--timeout", String(o.timeoutSeconds), "--ttl", String(o.ttlSeconds), ...permissionArgs(o.mode)];
|
|
37
|
+
if (o.agentCommand)
|
|
38
|
+
args.push("--agent", o.agentCommand);
|
|
39
|
+
if (o.model)
|
|
40
|
+
args.push("--model", o.model);
|
|
41
|
+
return args;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The agent's name, unless the setup runs a command of its own: acpx refuses a positional agent
|
|
45
|
+
* next to --agent, and reads the command's words as the subcommand instead.
|
|
46
|
+
*/
|
|
47
|
+
const agentPart = (agent, o) => (o.agentCommand ? [] : [agent]);
|
|
48
|
+
export const execArgs = (agent, prompt, o) => [...globalArgs(o), ...agentPart(agent, o), "exec", prompt];
|
|
49
|
+
export const sessionPromptArgs = (agent, session, prompt, o) => [...globalArgs(o), ...agentPart(agent, o), "-s", session, "prompt", prompt];
|
|
50
|
+
export const sessionEnsureArgs = (agent, session, o) => [...globalArgs(o), ...agentPart(agent, o), "sessions", "ensure", "--name", session];
|
|
51
|
+
export const sessionListArgs = (agent, o) => [...globalArgs(o), ...agentPart(agent, o), "sessions", "list", "--local"];
|
|
52
|
+
export const sessionCloseArgs = (agent, session, o) => [...globalArgs(o), ...agentPart(agent, o), "sessions", "close", session];
|
|
53
|
+
const OUTPUT_CAP = 4 << 20;
|
|
54
|
+
/**
|
|
55
|
+
* Vireo's own settings and credentials stay with Vireo; the agent gets the rest of the environment
|
|
56
|
+
* (PATH, HOME, its own provider keys) plus what its setup adds.
|
|
57
|
+
*/
|
|
58
|
+
export function agentEnv(base, extra = {}) {
|
|
59
|
+
const env = {};
|
|
60
|
+
for (const [k, v] of Object.entries(base))
|
|
61
|
+
if (!/^(VIREO_|GOOGLE_CLIENT_)/.test(k))
|
|
62
|
+
env[k] = v;
|
|
63
|
+
return { ...env, ...extra };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Runs acpx and collects its output. `onLine` sees every stdout line however long the run, while
|
|
67
|
+
* `stdout` keeps only the first few megabytes; stderr keeps its tail, where the failure is.
|
|
68
|
+
* Stopping a run kills acpx's whole process group, so the agent it started goes too.
|
|
69
|
+
*/
|
|
70
|
+
export function runAcpx(args, opts) {
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
const child = spawn(process.execPath, [acpxEntry(), ...args], {
|
|
73
|
+
cwd: opts.cwd,
|
|
74
|
+
env: agentEnv(process.env, opts.env),
|
|
75
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
76
|
+
detached: process.platform !== "win32",
|
|
77
|
+
});
|
|
78
|
+
let stdout = "";
|
|
79
|
+
let stderr = "";
|
|
80
|
+
let pending = "";
|
|
81
|
+
let timedOut = false;
|
|
82
|
+
let aborted = false;
|
|
83
|
+
let done = false;
|
|
84
|
+
const kill = () => {
|
|
85
|
+
try {
|
|
86
|
+
if (child.pid && process.platform !== "win32")
|
|
87
|
+
process.kill(-child.pid, "SIGKILL");
|
|
88
|
+
else
|
|
89
|
+
child.kill("SIGKILL");
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
child.kill("SIGKILL");
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
const finish = (code) => {
|
|
96
|
+
if (done)
|
|
97
|
+
return;
|
|
98
|
+
done = true;
|
|
99
|
+
clearTimeout(timer);
|
|
100
|
+
opts.signal?.removeEventListener("abort", onAbort);
|
|
101
|
+
if (pending)
|
|
102
|
+
opts.onLine?.(pending);
|
|
103
|
+
resolve({ code, stdout, stderr, timedOut, aborted });
|
|
104
|
+
};
|
|
105
|
+
const timer = setTimeout(() => {
|
|
106
|
+
timedOut = true;
|
|
107
|
+
kill();
|
|
108
|
+
}, opts.timeoutMs);
|
|
109
|
+
const onAbort = () => {
|
|
110
|
+
aborted = true;
|
|
111
|
+
kill();
|
|
112
|
+
};
|
|
113
|
+
if (opts.signal?.aborted)
|
|
114
|
+
onAbort();
|
|
115
|
+
else
|
|
116
|
+
opts.signal?.addEventListener("abort", onAbort, { once: true });
|
|
117
|
+
child.stdout.on("data", (chunk) => {
|
|
118
|
+
const text = chunk.toString("utf8");
|
|
119
|
+
if (stdout.length < OUTPUT_CAP)
|
|
120
|
+
stdout += text;
|
|
121
|
+
if (!opts.onLine)
|
|
122
|
+
return;
|
|
123
|
+
const lines = (pending + text).split("\n");
|
|
124
|
+
pending = lines.pop() ?? "";
|
|
125
|
+
for (const line of lines)
|
|
126
|
+
opts.onLine(line);
|
|
127
|
+
});
|
|
128
|
+
child.stderr.on("data", (chunk) => {
|
|
129
|
+
stderr += chunk.toString("utf8");
|
|
130
|
+
if (stderr.length > OUTPUT_CAP)
|
|
131
|
+
stderr = stderr.slice(-OUTPUT_CAP / 2);
|
|
132
|
+
});
|
|
133
|
+
child.on("error", (err) => {
|
|
134
|
+
stderr += `${stderr ? "\n" : ""}${err.message}`;
|
|
135
|
+
finish(-1);
|
|
136
|
+
});
|
|
137
|
+
child.on("close", (code) => finish(code ?? -1));
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const MAX_TOOLS = 60;
|
|
141
|
+
const MAX_TEXT = 200_000;
|
|
142
|
+
const str = (v) => (typeof v === "string" ? v : undefined);
|
|
143
|
+
function toolSteps(update, turn) {
|
|
144
|
+
const id = str(update.toolCallId);
|
|
145
|
+
if (!id)
|
|
146
|
+
return;
|
|
147
|
+
let step = turn.tools.find((t) => t.id === id);
|
|
148
|
+
if (!step) {
|
|
149
|
+
// Past the cap new calls are left out, but the ones listed still get their updates.
|
|
150
|
+
if (turn.tools.length >= MAX_TOOLS)
|
|
151
|
+
return;
|
|
152
|
+
step = { title: str(update.title) ?? id, id };
|
|
153
|
+
turn.tools.push(step);
|
|
154
|
+
}
|
|
155
|
+
const title = str(update.title);
|
|
156
|
+
if (title)
|
|
157
|
+
step.title = title;
|
|
158
|
+
const kind = str(update.kind);
|
|
159
|
+
if (kind)
|
|
160
|
+
step.kind = kind;
|
|
161
|
+
const status = str(update.status);
|
|
162
|
+
if (status)
|
|
163
|
+
step.status = status;
|
|
164
|
+
const raw = update.rawInput;
|
|
165
|
+
if (raw && typeof raw === "object") {
|
|
166
|
+
const input = raw;
|
|
167
|
+
const detail = str(input.command) ?? str(input.path) ?? str(input.file_path) ?? str(input.pattern);
|
|
168
|
+
if (detail)
|
|
169
|
+
step.detail = detail;
|
|
170
|
+
}
|
|
171
|
+
const content = update.content;
|
|
172
|
+
if (Array.isArray(content)) {
|
|
173
|
+
for (const c of content) {
|
|
174
|
+
if (c.type === "diff" && typeof c.path === "string" && !turn.files.includes(c.path))
|
|
175
|
+
turn.files.push(c.path);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
if (Array.isArray(update.locations)) {
|
|
179
|
+
for (const l of update.locations) {
|
|
180
|
+
if (typeof l.path === "string" && !turn.files.includes(l.path))
|
|
181
|
+
turn.files.push(l.path);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
/** Reads acpx's JSON-RPC stream, line by line, into what the owner (and the model) needs to see. */
|
|
186
|
+
export class TurnReader {
|
|
187
|
+
turn = { text: "", tools: [], files: [], plans: [], errors: [], refused: [], frames: 0 };
|
|
188
|
+
push(line) {
|
|
189
|
+
const turn = this.turn;
|
|
190
|
+
const trimmed = line.trim();
|
|
191
|
+
if (!trimmed.startsWith("{"))
|
|
192
|
+
return;
|
|
193
|
+
let msg;
|
|
194
|
+
try {
|
|
195
|
+
msg = JSON.parse(trimmed);
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
turn.frames += 1;
|
|
201
|
+
const error = msg.error;
|
|
202
|
+
if (error)
|
|
203
|
+
turn.errors.push(str(error.message) ?? JSON.stringify(error));
|
|
204
|
+
const result = msg.result;
|
|
205
|
+
if (result) {
|
|
206
|
+
const stop = str(result.stopReason);
|
|
207
|
+
if (stop)
|
|
208
|
+
turn.stopReason = stop;
|
|
209
|
+
const outcome = result.outcome;
|
|
210
|
+
if (outcome?.outcome === "selected" && !/allow/i.test(String(outcome.optionId)))
|
|
211
|
+
turn.refused.push("a permission request was declined");
|
|
212
|
+
const meta = result._meta;
|
|
213
|
+
const escalation = meta?.acpx;
|
|
214
|
+
if (escalation?.permissionEscalation)
|
|
215
|
+
turn.refused.push("a permission request was escalated but could not be approved here");
|
|
216
|
+
}
|
|
217
|
+
if (msg.method !== "session/update")
|
|
218
|
+
return;
|
|
219
|
+
const params = msg.params;
|
|
220
|
+
const update = params?.update;
|
|
221
|
+
const tag = str(update?.sessionUpdate);
|
|
222
|
+
if (!update || !tag)
|
|
223
|
+
return;
|
|
224
|
+
if (tag === "agent_message_chunk") {
|
|
225
|
+
const content = update.content;
|
|
226
|
+
if (content?.type === "text" && typeof content.text === "string" && turn.text.length < MAX_TEXT)
|
|
227
|
+
turn.text += content.text;
|
|
228
|
+
}
|
|
229
|
+
else if (tag === "tool_call" || tag === "tool_call_update") {
|
|
230
|
+
toolSteps(update, turn);
|
|
231
|
+
}
|
|
232
|
+
else if (tag === "plan") {
|
|
233
|
+
// Each plan update is the whole plan, not an addition to it.
|
|
234
|
+
const entries = update.entries;
|
|
235
|
+
if (Array.isArray(entries)) {
|
|
236
|
+
turn.plans = [];
|
|
237
|
+
for (const e of entries) {
|
|
238
|
+
const content = str(e.content);
|
|
239
|
+
if (content)
|
|
240
|
+
turn.plans.push(`${str(e.status) ?? "pending"}: ${content}`);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
finish() {
|
|
246
|
+
this.turn.text = this.turn.text.trim();
|
|
247
|
+
this.turn.files = [...new Set(this.turn.files)];
|
|
248
|
+
return this.turn;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
export function parseTurn(stdout) {
|
|
252
|
+
const reader = new TurnReader();
|
|
253
|
+
for (const line of stdout.split("\n"))
|
|
254
|
+
reader.push(line);
|
|
255
|
+
return reader.finish();
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=acp.js.map
|
package/dist/acp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acp.js","sourceRoot":"","sources":["../src/acp.ts"],"names":[],"mappings":"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"}
|
package/dist/actions.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { createHmac, randomBytes, timingSafeEqual } from "node:crypto";
|
|
2
|
+
import { forModel } from "./tools/types.js";
|
|
3
|
+
import { errorMessage, newId, now, safeJson, truncate } from "./util.js";
|
|
4
|
+
function toAction(r) {
|
|
5
|
+
return {
|
|
6
|
+
id: r.id,
|
|
7
|
+
threadId: r.thread_id,
|
|
8
|
+
tool: r.tool,
|
|
9
|
+
args: safeJson(r.args, {}),
|
|
10
|
+
summary: r.summary,
|
|
11
|
+
status: r.status,
|
|
12
|
+
result: r.result,
|
|
13
|
+
display: r.display ? safeJson(r.display, null) : null,
|
|
14
|
+
createdAt: r.created_at,
|
|
15
|
+
resolvedAt: r.resolved_at,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export class Actions {
|
|
19
|
+
app;
|
|
20
|
+
constructor(app) {
|
|
21
|
+
this.app = app;
|
|
22
|
+
// An action interrupted mid-execution is not retried automatically: it may
|
|
23
|
+
// already have taken effect, so the owner decides.
|
|
24
|
+
app.db.run("UPDATE actions SET status = 'failed', result = 'Interrupted by a restart; check whether it took effect before retrying.' WHERE status = 'executing'");
|
|
25
|
+
}
|
|
26
|
+
create(threadId, tool, args, summary) {
|
|
27
|
+
const id = newId("act");
|
|
28
|
+
this.app.db.run("INSERT INTO actions (id, thread_id, tool, args, summary, status, created_at) VALUES (?, ?, ?, ?, ?, 'pending', ?)", id, threadId, tool, JSON.stringify(args), summary, now());
|
|
29
|
+
this.app.threads.addNotice(threadId, "action", summary, { data: { actionId: id } });
|
|
30
|
+
this.app.bus.publish({ type: "action.updated", threadId, actionId: id });
|
|
31
|
+
const thread = this.app.threads.get(threadId);
|
|
32
|
+
void this.app.push.notify({
|
|
33
|
+
title: thread ? `Confirm: ${thread.title}` : "Vireo needs your confirmation",
|
|
34
|
+
body: summary,
|
|
35
|
+
url: `/#thread/${threadId}`,
|
|
36
|
+
tag: `action-${id}`,
|
|
37
|
+
decide: { confirm: this.decisionUrl(id, "confirm"), cancel: this.decisionUrl(id, "cancel") },
|
|
38
|
+
});
|
|
39
|
+
return this.get(id);
|
|
40
|
+
}
|
|
41
|
+
/** The key that signs one-tap decision links; made once, kept in the database. */
|
|
42
|
+
decisionKey() {
|
|
43
|
+
let key = this.app.db.getKv("actions.decision_key");
|
|
44
|
+
if (!key) {
|
|
45
|
+
key = randomBytes(32).toString("base64url");
|
|
46
|
+
this.app.db.setKv("actions.decision_key", key);
|
|
47
|
+
}
|
|
48
|
+
return key;
|
|
49
|
+
}
|
|
50
|
+
signature(id, decision) {
|
|
51
|
+
return createHmac("sha256", this.decisionKey()).update(`${id}:${decision}`).digest("base64url");
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* A link that confirms or declines one pending action with no sign-in, for
|
|
55
|
+
* the buttons on a push notification. It is signed for that action and that
|
|
56
|
+
* decision, and only reaches the owner inside their encrypted push.
|
|
57
|
+
*/
|
|
58
|
+
decisionUrl(id, decision) {
|
|
59
|
+
return `${this.app.address.publicUrl().replace(/\/$/, "")}/public/decide/${id}/${decision}?sig=${this.signature(id, decision)}`;
|
|
60
|
+
}
|
|
61
|
+
verifyDecision(id, decision, sig) {
|
|
62
|
+
if ((decision !== "confirm" && decision !== "cancel") || !sig)
|
|
63
|
+
return false;
|
|
64
|
+
const want = Buffer.from(this.signature(id, decision));
|
|
65
|
+
const got = Buffer.from(sig);
|
|
66
|
+
return want.length === got.length && timingSafeEqual(want, got);
|
|
67
|
+
}
|
|
68
|
+
get(id) {
|
|
69
|
+
const r = this.app.db.get("SELECT * FROM actions WHERE id = ?", id);
|
|
70
|
+
return r ? toAction(r) : undefined;
|
|
71
|
+
}
|
|
72
|
+
forThread(threadId) {
|
|
73
|
+
return this.app.db.all("SELECT * FROM actions WHERE thread_id = ? ORDER BY created_at", threadId).map(toAction);
|
|
74
|
+
}
|
|
75
|
+
pending() {
|
|
76
|
+
return this.app.db.all("SELECT * FROM actions WHERE status = 'pending' ORDER BY created_at").map(toAction);
|
|
77
|
+
}
|
|
78
|
+
setStatus(id, status, result, display) {
|
|
79
|
+
this.app.db.run("UPDATE actions SET status = ?, result = ?, display = ?, resolved_at = ? WHERE id = ?", status, result ?? null, display ? JSON.stringify(display) : null, now(), id);
|
|
80
|
+
const a = this.get(id);
|
|
81
|
+
if (a) {
|
|
82
|
+
this.app.bus.publish({ type: "action.updated", threadId: a.threadId, actionId: id });
|
|
83
|
+
this.app.threads.changed(a.threadId);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Runs the confirmed action and resumes the thread. */
|
|
87
|
+
async confirm(id, editedArgs) {
|
|
88
|
+
const claimed = this.app.db.run("UPDATE actions SET status = 'executing' WHERE id = ? AND status = 'pending'", id);
|
|
89
|
+
const action = this.get(id);
|
|
90
|
+
if (!action)
|
|
91
|
+
throw new Error("Action not found");
|
|
92
|
+
if (claimed.changes === 0)
|
|
93
|
+
return action; // already handled on another device
|
|
94
|
+
const tool = this.app.tools.get(action.tool);
|
|
95
|
+
const thread = this.app.threads.get(action.threadId);
|
|
96
|
+
if (!tool || !thread) {
|
|
97
|
+
this.setStatus(id, "failed", "Tool or thread no longer exists");
|
|
98
|
+
return this.get(id);
|
|
99
|
+
}
|
|
100
|
+
const args = editedArgs ? { ...action.args, ...editedArgs } : action.args;
|
|
101
|
+
const edited = Boolean(editedArgs && JSON.stringify(args) !== JSON.stringify(action.args));
|
|
102
|
+
if (edited)
|
|
103
|
+
this.app.db.run("UPDATE actions SET args = ? WHERE id = ?", JSON.stringify(args), id);
|
|
104
|
+
const audit = this.app.audit.start(action.threadId, { tool: action.tool, agent: "owner", args });
|
|
105
|
+
// What the model is told the call returned, framed as outside content when it is.
|
|
106
|
+
let forAgent;
|
|
107
|
+
try {
|
|
108
|
+
const out = await tool.run(args, { app: this.app, thread, agent: "owner", confirmed: true });
|
|
109
|
+
const clip = (v) => this.app.vault.redact(truncate(v, 4000));
|
|
110
|
+
const display = out.display && { output: out.display.output && clip(out.display.output), note: out.display.note && clip(out.display.note) };
|
|
111
|
+
this.setStatus(id, out.failed ? "failed" : "done", clip(out.text), display);
|
|
112
|
+
this.app.audit.end(audit, out.failed ? "error" : "ok", out.text);
|
|
113
|
+
forAgent = forModel(truncate(this.app.vault.redact(out.text), 3000), out.source);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
forAgent = `Failed: ${this.app.vault.redact(errorMessage(err))}`;
|
|
117
|
+
this.setStatus(id, "failed", forAgent);
|
|
118
|
+
this.app.audit.end(audit, "error", forAgent);
|
|
119
|
+
}
|
|
120
|
+
this.app.threads.addNotice(action.threadId, "action_result", `The owner ${edited ? "edited and confirmed" : "confirmed"}: ${action.summary}${edited ? ` (final arguments: ${JSON.stringify(args)})` : ""}. Result: ${forAgent}\nContinue the task from here.`, { llm: true, data: { actionId: id } });
|
|
121
|
+
this.app.threads.update(action.threadId, { needs_you: 0 });
|
|
122
|
+
if (!tool.settles)
|
|
123
|
+
this.app.runner.schedule(action.threadId);
|
|
124
|
+
return this.get(id);
|
|
125
|
+
}
|
|
126
|
+
cancel(id, reason) {
|
|
127
|
+
const claimed = this.app.db.run("UPDATE actions SET status = 'cancelled', resolved_at = ? WHERE id = ? AND status = 'pending'", now(), id);
|
|
128
|
+
const action = this.get(id);
|
|
129
|
+
if (!action)
|
|
130
|
+
throw new Error("Action not found");
|
|
131
|
+
if (claimed.changes === 0)
|
|
132
|
+
return action;
|
|
133
|
+
this.app.bus.publish({ type: "action.updated", threadId: action.threadId, actionId: id });
|
|
134
|
+
this.app.threads.addNotice(action.threadId, "action_result", `The owner cancelled: ${action.summary}${reason ? `. Reason: ${reason}` : ""}. Do not retry it unless the owner asks.`, { llm: true, data: { actionId: id } });
|
|
135
|
+
this.app.threads.update(action.threadId, { needs_you: 0 });
|
|
136
|
+
if (!this.app.tools.get(action.tool)?.settles)
|
|
137
|
+
this.app.runner.schedule(action.threadId);
|
|
138
|
+
return action;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
//# sourceMappingURL=actions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actions.js","sourceRoot":"","sources":["../src/actions.ts"],"names":[],"mappings":"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"}
|
package/dist/address.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Where this node can be reached: by browsers, by itself, and directly when a plugin serves it. */
|
|
2
|
+
export class Address {
|
|
3
|
+
config;
|
|
4
|
+
identity;
|
|
5
|
+
/** Set while a plugin serves this node at a direct address (e.g. https://box.tailnet.ts.net). */
|
|
6
|
+
directUrl;
|
|
7
|
+
/** Called when the direct address changes, so the cloud can be told. */
|
|
8
|
+
onChange = () => undefined;
|
|
9
|
+
constructor(config, identity) {
|
|
10
|
+
this.config = config;
|
|
11
|
+
this.identity = identity;
|
|
12
|
+
}
|
|
13
|
+
setDirectUrl(url) {
|
|
14
|
+
if (url === this.directUrl)
|
|
15
|
+
return;
|
|
16
|
+
this.directUrl = url;
|
|
17
|
+
this.onChange();
|
|
18
|
+
}
|
|
19
|
+
/** The node's address on the cloud relay, once linked in relay mode. */
|
|
20
|
+
relayUrl() {
|
|
21
|
+
const id = this.identity.get();
|
|
22
|
+
return id?.mode === "relay" ? `${id.cloudUrl}/n/${id.nodeId}` : undefined;
|
|
23
|
+
}
|
|
24
|
+
/** Base URL for OAuth redirects and webhooks: configured, else direct, else the relay, else where the request came from. */
|
|
25
|
+
publicUrl(req) {
|
|
26
|
+
return this.config.publicUrl ?? this.directUrl ?? this.relayUrl() ?? req?.origin ?? this.localUrl();
|
|
27
|
+
}
|
|
28
|
+
localUrl() {
|
|
29
|
+
return `http://127.0.0.1:${this.config.port}`;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=address.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":"AAIA,oGAAoG;AACpG,MAAM,OAAO,OAAO;IAOC,MAAM;IACN,QAAQ;IAP3B,iGAAiG;IACjG,SAAS,CAAqB;IAC9B,wEAAwE;IACxE,QAAQ,GAAe,GAAG,EAAE,CAAC,SAAS,CAAC;IAEvC,YACmB,MAAc,EACd,QAAkB;sBADlB,MAAM;wBACN,QAAQ;IACxB,CAAC;IAEJ,YAAY,CAAC,GAAuB;QAClC,IAAI,GAAG,KAAK,IAAI,CAAC,SAAS;YAAE,OAAO;QACnC,IAAI,CAAC,SAAS,GAAG,GAAG,CAAC;QACrB,IAAI,CAAC,QAAQ,EAAE,CAAC;IAClB,CAAC;IAED,wEAAwE;IACxE,QAAQ;QACN,MAAM,EAAE,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC;QAC/B,OAAO,EAAE,EAAE,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,QAAQ,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;IAC5E,CAAC;IAED,4HAA4H;IAC5H,SAAS,CAAC,GAAiB;QACzB,OAAO,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,QAAQ,EAAE,IAAI,GAAG,EAAE,MAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;IACtG,CAAC;IAED,QAAQ;QACN,OAAO,oBAAoB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;IAChD,CAAC;CACF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { messageText, OVERVIEW_ID } from "./threads.js";
|
|
2
|
+
import { now, truncate } from "./util.js";
|
|
3
|
+
/**
|
|
4
|
+
* What follows a finished run: the thread's status line, "Needs you" when
|
|
5
|
+
* Vireo ended on a question, a notification when the owner should know, and
|
|
6
|
+
* memory upkeep. The runner only announces that a run ended.
|
|
7
|
+
*/
|
|
8
|
+
export class RunAftercare {
|
|
9
|
+
app;
|
|
10
|
+
constructor(app) {
|
|
11
|
+
this.app = app;
|
|
12
|
+
this.app.bus.subscribe((e) => {
|
|
13
|
+
if (e.type === "run.finished")
|
|
14
|
+
this.after(e.threadId, e.startedAt);
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
after(threadId, startedAt) {
|
|
18
|
+
const thread = this.app.threads.get(threadId);
|
|
19
|
+
if (!thread)
|
|
20
|
+
return;
|
|
21
|
+
const last = this.app.threads
|
|
22
|
+
.messages(threadId, { limit: 6 })
|
|
23
|
+
.reverse()
|
|
24
|
+
.find((m) => m.role === "assistant" && messageText(m.body));
|
|
25
|
+
const text = last ? messageText(last.body) : "";
|
|
26
|
+
const saidThisRun = Boolean(last && last.createdAt >= startedAt);
|
|
27
|
+
const patch = {};
|
|
28
|
+
// A status the agent set during this run wins over the first line of its reply.
|
|
29
|
+
const statusSetAt = this.app.db.getKv(`thread.status_set.${threadId}`) ?? 0;
|
|
30
|
+
if (statusSetAt < startedAt) {
|
|
31
|
+
const firstLine = text
|
|
32
|
+
.replace(/[*_#>`]/g, "")
|
|
33
|
+
.split(/\n|(?<=[.!?。!?])\s/)[0]
|
|
34
|
+
?.trim();
|
|
35
|
+
patch.status_line = firstLine ? truncate(firstLine, 100) : thread.statusLine === "Working…" ? "" : thread.statusLine;
|
|
36
|
+
}
|
|
37
|
+
const asksOwner = saidThisRun && threadId !== OVERVIEW_ID && /[??]\s*$/.test(text.trim());
|
|
38
|
+
if (asksOwner)
|
|
39
|
+
patch.needs_you = 1;
|
|
40
|
+
this.app.threads.update(threadId, patch);
|
|
41
|
+
const title = this.app.threads.get(threadId).title;
|
|
42
|
+
const notify = { body: truncate(text, 140), url: `/#thread/${threadId}`, tag: threadId };
|
|
43
|
+
if (asksOwner)
|
|
44
|
+
void this.app.push.notify({ title, ...notify });
|
|
45
|
+
else if (saidThisRun && now() - startedAt > 30_000)
|
|
46
|
+
void this.app.push.notify({ title: `Done: ${title}`, ...notify });
|
|
47
|
+
if (!thread.temporary)
|
|
48
|
+
this.app.memoryWorker.afterRun(threadId);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=aftercare.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aftercare.js","sourceRoot":"","sources":["../src/aftercare.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1C;;;;GAIG;AACH,MAAM,OAAO,YAAY;IACM,GAAG;IAAhC,YAA6B,GAAQ;mBAAR,GAAG;QAC9B,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE;YAC3B,IAAI,CAAC,CAAC,IAAI,KAAK,cAAc;gBAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;QACrE,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,QAAgB,EAAE,SAAiB;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAC9C,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO;aAC1B,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;aAChC,OAAO,EAAE;aACT,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9D,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC,SAAS,IAAI,SAAS,CAAC,CAAC;QAEjE,MAAM,KAAK,GAA4C,EAAE,CAAC;QAC1D,gFAAgF;QAChF,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAS,qBAAqB,QAAQ,EAAE,CAAC,IAAI,CAAC,CAAC;QACpF,IAAI,WAAW,GAAG,SAAS,EAAE,CAAC;YAC5B,MAAM,SAAS,GAAG,IAAI;iBACnB,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;iBACvB,KAAK,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC;gBAC/B,EAAE,IAAI,EAAE,CAAC;YACX,KAAK,CAAC,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACvH,CAAC;QACD,MAAM,SAAS,GAAG,WAAW,IAAI,QAAQ,KAAK,WAAW,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1F,IAAI,SAAS;YAAE,KAAK,CAAC,SAAS,GAAG,CAAC,CAAC;QACnC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QAEzC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAE,CAAC,KAAK,CAAC;QACpD,MAAM,MAAM,GAAG,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,YAAY,QAAQ,EAAE,EAAE,GAAG,EAAE,QAAQ,EAAE,CAAC;QACzF,IAAI,SAAS;YAAE,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;aAC1D,IAAI,WAAW,IAAI,GAAG,EAAE,GAAG,SAAS,GAAG,MAAM;YAAE,KAAK,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,SAAS,KAAK,EAAE,EAAE,GAAG,MAAM,EAAE,CAAC,CAAC;QAEtH,IAAI,CAAC,MAAM,CAAC,SAAS;YAAE,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC;CACF"}
|