@engenty/wizards-runtime 0.7.7 → 0.7.9
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/apps/runtime/dist/authoring/guide.js +8 -3
- package/apps/runtime/dist/browser/fast/classifier.js +9 -4
- package/apps/runtime/dist/cli/main.js +1 -1
- package/apps/runtime/dist/cli/menu.js +5 -1
- package/apps/runtime/dist/cli/ollama.js +302 -0
- package/apps/runtime/dist/cli/setup.js +102 -2
- package/apps/runtime/dist/clients.js +118 -0
- package/apps/runtime/dist/db/client.js +37 -3
- package/apps/runtime/dist/db/migrations/tenant/0017_run_client.sql +1 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/0017_snapshot.json +3333 -0
- package/apps/runtime/dist/db/migrations/tenant/meta/_journal.json +7 -0
- package/apps/runtime/dist/db/schema.js +2 -0
- package/apps/runtime/dist/decision-model.js +33 -0
- package/apps/runtime/dist/docs/dev/api.md +39 -0
- package/apps/runtime/dist/docs/dev/index.md +1 -0
- package/apps/runtime/dist/docs/dev/integration/openui.md +5 -3
- package/apps/runtime/dist/docs/dev/meta.json +1 -1
- package/apps/runtime/dist/docs/user/ai-apps.md +14 -3
- package/apps/runtime/dist/docs/user/command-line.md +1 -1
- package/apps/runtime/dist/docs/user/install.md +1 -0
- package/apps/runtime/dist/engine/decide.js +3 -1
- package/apps/runtime/dist/engine/runner.js +1 -0
- package/apps/runtime/dist/film/project.js +221 -65
- package/apps/runtime/dist/film/step.js +16 -5
- package/apps/runtime/dist/index.js +13 -4
- package/apps/runtime/dist/models.js +43 -3
- package/apps/runtime/dist/plugin.js +24 -8
- package/apps/runtime/dist/routes/runs.js +9 -0
- package/apps/runtime/dist/tools/code.js +53 -13
- package/apps/web/dist/assets/AboutDialog-CShc0mRo.js +1 -0
- package/apps/web/dist/assets/ChangelogDialog-C4dVSwtN.js +1 -0
- package/apps/web/dist/assets/ChatView-KkOboyOo.js +10 -0
- package/apps/web/dist/assets/EditorPage-lQ3YgsFT.js +4 -0
- package/apps/web/dist/assets/{FlowPreview-Dj2gAfuf.js → FlowPreview-oX_Emm7u.js} +1 -1
- package/apps/web/dist/assets/{Harness-SLbsntQF.js → Harness-D6mgLWTb.js} +2 -2
- package/apps/web/dist/assets/{NewWizardChannels-CsDMlji7.js → NewWizardChannels-CPlh_37J.js} +1 -1
- package/apps/web/dist/assets/NewWizardPage-D0FVJtXK.js +7 -0
- package/apps/web/dist/assets/OnboardingPage-BXPOMrQR.js +1 -0
- package/apps/web/dist/assets/ProjectPage-DroTprqs.js +1 -0
- package/apps/web/dist/assets/PublicRunner-j3qoKjQQ.js +1 -0
- package/apps/web/dist/assets/{ReadOnly-CK0piLUV.js → ReadOnly-CKgSQ2z1.js} +1 -1
- package/apps/web/dist/assets/RunDrawer-CJZ_ISAd.js +4 -0
- package/apps/web/dist/assets/RunnerView-BW1h4x63.js +1 -0
- package/apps/web/dist/assets/SettingsPage-BHZ0Z-og.js +1 -0
- package/apps/web/dist/assets/SetupPage-CDkYkjJX.js +1 -0
- package/apps/web/dist/assets/{SharePage-Cc3Opj2F.js → SharePage-BlVjVjHG.js} +1 -1
- package/apps/web/dist/assets/changelog-Be0i5Jjw.js +1 -0
- package/apps/web/dist/assets/engenty-WpMi3xwq.js +1 -0
- package/apps/web/dist/assets/{esm-CfnFE_jE.js → esm-C-ZWeuhU.js} +1 -1
- package/apps/web/dist/assets/{fluffy-engenty-ClRou7yu.js → fluffy-engenty-DPNHytrz.js} +135 -16
- package/apps/web/dist/assets/goose-helmet-Cvc7KjUg.bin +0 -0
- package/apps/web/dist/assets/goose-helmet-livery-CZD9u0XS.webp +0 -0
- package/apps/web/dist/assets/index-C4aHMcg9.css +1 -0
- package/apps/web/dist/assets/index-C61HAltK.js +14 -0
- package/apps/web/dist/assets/oss-credits-qGhcbqiM.js +1 -0
- package/apps/web/dist/assets/{phone-BWOB67tX.js → phone-BjmhIKuT.js} +1 -1
- package/apps/web/dist/assets/{settings-menu-CEQlVs1O.js → settings-menu-Dpkp3f56.js} +1 -1
- package/apps/web/dist/assets/ui-DMmT-cSO.js +137 -0
- package/apps/web/dist/assets/{upload-pBKn2EFp.js → upload-JX9BcMTq.js} +1 -1
- package/apps/web/dist/assets/{lock-DAvRJY4B.js → wrench-BSxnPs2_.js} +1 -1
- package/apps/web/dist/index.html +4 -4
- package/apps/web/dist/install.sh +2 -2
- package/apps/web/dist/mcp/flow.html +142 -23
- package/node_modules/@engenty/wizards/package.json +1 -4
- package/node_modules/@engenty-wizards/shared/dist/claude-plugin.d.ts +7 -0
- package/node_modules/@engenty-wizards/shared/dist/claude-plugin.js +10 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.d.ts +3 -0
- package/node_modules/@engenty-wizards/shared/dist/definition.js +15 -0
- package/node_modules/@engenty-wizards/shared/dist/run.d.ts +2 -0
- package/node_modules/@engenty-wizards/shared/dist/run.js +4 -0
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +28 -6
- package/plugin/README.md +58 -0
- package/plugin/hooks/engenty.ts +140 -0
- package/plugin/hooks/hooks.json +1 -0
- package/plugin/hooks/pane.test.tsx +177 -0
- package/plugin/hooks/register.tsx +396 -0
- package/plugin/types/index.d.ts +44 -0
- package/apps/web/dist/assets/AboutDialog-BP8-Ugxf.js +0 -1
- package/apps/web/dist/assets/ChangelogDialog-CD6CQNW9.js +0 -1
- package/apps/web/dist/assets/ChatView-4T0QarEr.js +0 -10
- package/apps/web/dist/assets/EditorPage-CWdV7Xdn.js +0 -3
- package/apps/web/dist/assets/NewWizardPage-_bFYjlgh.js +0 -7
- package/apps/web/dist/assets/OnboardingPage-DObQeCDg.js +0 -1
- package/apps/web/dist/assets/ProjectPage-DX-oNLWy.js +0 -1
- package/apps/web/dist/assets/PublicRunner-Bn9rVNEb.js +0 -1
- package/apps/web/dist/assets/RunDrawer-CVMTLse_.js +0 -4
- package/apps/web/dist/assets/RunnerView-Cjhuu9ua.js +0 -1
- package/apps/web/dist/assets/SettingsPage-DTzuiSAj.js +0 -1
- package/apps/web/dist/assets/SetupPage-D9jlhgiP.js +0 -1
- package/apps/web/dist/assets/changelog-CJNkd1_L.js +0 -1
- package/apps/web/dist/assets/engenty-eXZ-EAwd.js +0 -1
- package/apps/web/dist/assets/index-AfUa8xKD.css +0 -1
- package/apps/web/dist/assets/index-B5F1_qA_.js +0 -14
- package/apps/web/dist/assets/oss-credits-X2JPiMOR.js +0 -1
- package/apps/web/dist/assets/ui-BmR_4eL2.js +0 -137
- package/node_modules/@engenty/wizards/dist/openui/Wizard.d.ts +0 -20
- package/node_modules/@engenty/wizards/dist/openui/Wizard.js +0 -62
- package/node_modules/@engenty/wizards/dist/openui/index.d.ts +0 -9
- package/node_modules/@engenty/wizards/dist/openui/index.js +0 -9
- package/node_modules/@engenty/wizards/dist/openui/message.d.ts +0 -11
- package/node_modules/@engenty/wizards/dist/openui/message.js +0 -69
- package/node_modules/@engenty/wizards/dist/openui/run.d.ts +0 -8
- package/node_modules/@engenty/wizards/dist/openui/run.js +0 -137
- package/node_modules/@engenty/wizards/dist/openui/server.d.ts +0 -37
- package/node_modules/@engenty/wizards/dist/openui/server.js +0 -77
- package/plugin/.mcp.json +0 -8
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { serve } from "@hono/node-server";
|
|
2
2
|
import { localEntryUrl, purgeSessions } from "./auth/index.js";
|
|
3
|
+
import { startClientChecks } from "./clients.js";
|
|
3
4
|
import { adoptLegacyData } from "./db/adopt.js";
|
|
4
5
|
import { knownTenants, migrateAllTenants, migrateControlDb, openTenantDb, withTenant, } from "./db/client.js";
|
|
5
6
|
import { startRunner, stopRunner } from "./engine/runner.js";
|
|
@@ -20,6 +21,9 @@ import { LOCAL_TENANT } from "./tenants/tenant.js";
|
|
|
20
21
|
import { onRestart, RESTART_EXIT, startUpdateChecks } from "./update.js";
|
|
21
22
|
// Before anything prints: the last lines stay in memory for a look from afar (debug.ts).
|
|
22
23
|
hookConsole();
|
|
24
|
+
// A background job that failed (a dropped connection to a remote database) is logged; the
|
|
25
|
+
// server keeps running for every other request instead of ending with it.
|
|
26
|
+
process.on("unhandledRejection", (err) => console.error("[unhandled]", err));
|
|
23
27
|
await migrateControlDb();
|
|
24
28
|
// What the linked account's plan confirmed last: the Pro modules it includes load with the rest.
|
|
25
29
|
await loadEntitlement();
|
|
@@ -28,9 +32,13 @@ await loadPlugins();
|
|
|
28
32
|
startJobs();
|
|
29
33
|
if (managed) {
|
|
30
34
|
// Every tenant database is brought to this release's schema; a new one migrates when first opened.
|
|
31
|
-
void migrateAllTenants()
|
|
35
|
+
void migrateAllTenants()
|
|
36
|
+
.then(({ migrated, failed }) => {
|
|
32
37
|
console.log(`tenant databases: ${migrated} current${failed.length ? `, failed: ${failed}` : ""}`);
|
|
33
|
-
})
|
|
38
|
+
})
|
|
39
|
+
.catch((err) => console.error("[migrate]", err));
|
|
40
|
+
// Which clients may start runs over the public API, and how often: the Manage-App's list.
|
|
41
|
+
startClientChecks();
|
|
34
42
|
}
|
|
35
43
|
else {
|
|
36
44
|
await adoptLegacyData();
|
|
@@ -43,8 +51,9 @@ else {
|
|
|
43
51
|
startUpdateChecks();
|
|
44
52
|
}
|
|
45
53
|
// The marketplace's starters and the starred entries, kept for offline use; checked hourly.
|
|
46
|
-
void syncMarketplace();
|
|
47
|
-
|
|
54
|
+
const marketplace = () => void syncMarketplace().catch((err) => console.error("[marketplace]", err.message));
|
|
55
|
+
marketplace();
|
|
56
|
+
setInterval(marketplace, 3600_000).unref();
|
|
48
57
|
const { default: app } = await import("./app.js");
|
|
49
58
|
/** Behind a path (APP_URL ends in /w) the proxy may leave the prefix on; the routes know none. */
|
|
50
59
|
function withoutBasePath(request) {
|
|
@@ -11,6 +11,7 @@ import { CAPABILITY_CLASSES, creditsModelOf, isCreditsRef, PROVIDER_IDS, provide
|
|
|
11
11
|
import { note, saidText } from "@engenty-wizards/shared/run";
|
|
12
12
|
import { generateSpeech, generateText, } from "ai";
|
|
13
13
|
import { accountToken, linkedAccount } from "./auth/account.js";
|
|
14
|
+
import { ollamaDecisionModel, ollamaRoot } from "./decision-model.js";
|
|
14
15
|
import { DeviceModel, deviceThinks } from "./engine/device.js";
|
|
15
16
|
import { env } from "./env.js";
|
|
16
17
|
import { appleModel, appleStatus, appleTranscriptionModel, appleUnavailableNote, } from "./harness/apple.js";
|
|
@@ -652,10 +653,37 @@ export async function embeddingModel() {
|
|
|
652
653
|
? { model: gatewayClient(access, {}).embeddingModel("wizards/embedding"), ref: bound.model }
|
|
653
654
|
: null;
|
|
654
655
|
}
|
|
656
|
+
/** What the local Ollama held at the last look, so a decision does not ask it every time. */
|
|
657
|
+
let localDecision = null;
|
|
658
|
+
/** The decision model in the local Ollama (Clef-flash, pulled by the setup), looked up once a minute. */
|
|
659
|
+
async function localDecisionModel(url) {
|
|
660
|
+
if (localDecision?.url === url && Date.now() < localDecision.at) {
|
|
661
|
+
return localDecision.model;
|
|
662
|
+
}
|
|
663
|
+
const model = await ollamaDecisionModel(url);
|
|
664
|
+
localDecision = { url, model, at: Date.now() + 60_000 };
|
|
665
|
+
return model;
|
|
666
|
+
}
|
|
667
|
+
/**
|
|
668
|
+
* Ollama refused the model itself, not the question: a newer Ollama that wants it downloaded
|
|
669
|
+
* again, a model that was removed, one that does not fit into memory. Decisions take the next
|
|
670
|
+
* way for ten minutes, and the log says what Ollama says fixes it.
|
|
671
|
+
*/
|
|
672
|
+
function localModelRefused(url, status, body) {
|
|
673
|
+
const cannotRun = status === 404 ||
|
|
674
|
+
status >= 500 ||
|
|
675
|
+
/no longer supported|re-?download|ollama pull|not found/i.test(body);
|
|
676
|
+
if (!cannotRun) {
|
|
677
|
+
return;
|
|
678
|
+
}
|
|
679
|
+
console.warn(`[decide] the local decision model cannot run, left out for 10 minutes: ${body}`);
|
|
680
|
+
localDecision = { url, model: null, at: Date.now() + 10 * 60_000 };
|
|
681
|
+
}
|
|
655
682
|
/**
|
|
656
|
-
* The way to
|
|
657
|
-
*
|
|
658
|
-
* key
|
|
683
|
+
* The way to a decision model, one that answers typed questions with probabilities and writes
|
|
684
|
+
* no text: the credits on a Manage-App's runtime; alone, TypeSafe's Jev through an AI Gateway
|
|
685
|
+
* key or a TypeSafe key, then Clef-flash in Ollama on this machine, then Jev on the linked
|
|
686
|
+
* account's credits. Null when there is none.
|
|
659
687
|
*/
|
|
660
688
|
export async function systemOneAccess() {
|
|
661
689
|
const cfg = await config();
|
|
@@ -687,6 +715,18 @@ export async function systemOneAccess() {
|
|
|
687
715
|
model: "jev-latest",
|
|
688
716
|
};
|
|
689
717
|
}
|
|
718
|
+
// Free, and nothing leaves the machine: before the credits.
|
|
719
|
+
const ollama = cfg.settings.ollamaUrl ?? env.ollamaUrl;
|
|
720
|
+
const local = await localDecisionModel(ollama);
|
|
721
|
+
if (local) {
|
|
722
|
+
return {
|
|
723
|
+
url: `${ollamaRoot(ollama)}/v1/systemone`,
|
|
724
|
+
headers: {},
|
|
725
|
+
model: local,
|
|
726
|
+
local: true,
|
|
727
|
+
refused: (status, body) => localModelRefused(ollama, status, body),
|
|
728
|
+
};
|
|
729
|
+
}
|
|
690
730
|
const access = await creditAccess(cfg, false).catch(() => null);
|
|
691
731
|
return access ? viaCredits(access) : null;
|
|
692
732
|
}
|
|
@@ -3,19 +3,24 @@ import { existsSync } from "node:fs";
|
|
|
3
3
|
import { readdir, readFile } from "node:fs/promises";
|
|
4
4
|
import { dirname, join, relative, resolve } from "node:path";
|
|
5
5
|
import { fileURLToPath } from "node:url";
|
|
6
|
+
import { marketplaceNameOf } from "@engenty-wizards/shared/claude-plugin";
|
|
6
7
|
import { zipSync } from "fflate";
|
|
7
8
|
import { env } from "./env.js";
|
|
8
9
|
/**
|
|
9
|
-
* The Claude Code plugin for this deployment: the `plugin/` folder
|
|
10
|
-
*
|
|
11
|
-
*
|
|
10
|
+
* The Claude Code plugin for this deployment: the `plugin/` folder, served as a marketplace
|
|
11
|
+
* (`url` source) whose one plugin is a zip (`archive` source), with this server's address as its
|
|
12
|
+
* homepage, the package's version, and an `.mcp.json` that bundles this server. So every
|
|
13
|
+
* deployment hands out its own plugin and no domain is baked into the repo, while the folder in
|
|
14
|
+
* git is a valid plugin as it is: installed from GitHub, it uses the `engenty-wizards` server the
|
|
15
|
+
* person configured.
|
|
12
16
|
*/
|
|
13
17
|
const here = dirname(fileURLToPath(import.meta.url));
|
|
14
18
|
/** The folder that holds `plugin/` and the root package.json: three levels above this file. */
|
|
15
19
|
const base = resolve(here, "../../..");
|
|
16
20
|
const root = existsSync(join(base, "plugin")) ? base : undefined;
|
|
17
|
-
export const PLUGIN_NAME = "
|
|
18
|
-
|
|
21
|
+
export const PLUGIN_NAME = "wizards";
|
|
22
|
+
/** This deployment's marketplace, named after its host; `engenty` is the GitHub one. */
|
|
23
|
+
export const MARKETPLACE_NAME = marketplaceNameOf(env.appUrl);
|
|
19
24
|
export const pluginBase = `${env.appUrl}/api/claude-plugin`;
|
|
20
25
|
async function filesUnder(dir) {
|
|
21
26
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
@@ -32,12 +37,23 @@ export function pluginArchive() {
|
|
|
32
37
|
const dir = join(root, "plugin");
|
|
33
38
|
const files = {};
|
|
34
39
|
for (const path of (await filesUnder(dir)).sort()) {
|
|
35
|
-
const
|
|
40
|
+
const name = relative(dir, path);
|
|
41
|
+
let text = (await readFile(path, "utf8"))
|
|
36
42
|
.replaceAll("{{APP_URL}}", env.appUrl)
|
|
37
43
|
.replaceAll("{{VERSION}}", version);
|
|
44
|
+
if (name === ".claude-plugin/plugin.json") {
|
|
45
|
+
const manifest = JSON.parse(text);
|
|
46
|
+
manifest.version = version;
|
|
47
|
+
manifest.homepage = env.appUrl;
|
|
48
|
+
text = `${JSON.stringify(manifest, null, 2)}\n`;
|
|
49
|
+
}
|
|
38
50
|
// Fixed timestamps keep the archive, and so its sha256, stable across restarts.
|
|
39
|
-
files[
|
|
51
|
+
files[name] = new TextEncoder().encode(text);
|
|
40
52
|
}
|
|
53
|
+
const mcp = {
|
|
54
|
+
mcpServers: { "engenty-wizards": { type: "http", url: `${env.appUrl}/api/mcp` } },
|
|
55
|
+
};
|
|
56
|
+
files[".mcp.json"] = new TextEncoder().encode(`${JSON.stringify(mcp, null, 2)}\n`);
|
|
41
57
|
const zip = zipSync(files, { level: 9, mtime: new Date("2026-01-01T00:00:00Z") });
|
|
42
58
|
return { zip, sha256: createHash("sha256").update(zip).digest("hex"), version };
|
|
43
59
|
})();
|
|
@@ -48,7 +64,7 @@ export async function pluginMarketplace() {
|
|
|
48
64
|
return {
|
|
49
65
|
name: MARKETPLACE_NAME,
|
|
50
66
|
owner: { name: "engenty" },
|
|
51
|
-
description: "engenty wizards for Claude Code",
|
|
67
|
+
description: "engenty wizards for Claude Code, from this deployment",
|
|
52
68
|
plugins: [
|
|
53
69
|
{
|
|
54
70
|
name: PLUGIN_NAME,
|
|
@@ -11,6 +11,7 @@ import { nanoid } from "nanoid";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { principalOf } from "../auth/index.js";
|
|
13
13
|
import { MARK_FOCUSED_PERSONAL } from "../browser/snapshot.js";
|
|
14
|
+
import { clientOf, clientRefused } from "../clients.js";
|
|
14
15
|
import { ConnectError, connectionViews, connectWithCredentials, disconnect, finishOAuth, oauthStateLang, oauthStateRun, startOAuth, } from "../connectors/index.js";
|
|
15
16
|
import { finishPluginOAuth, pluginStateTenant } from "../connectors/plugin-connections.js";
|
|
16
17
|
import { db, schema, withTenant } from "../db/client.js";
|
|
@@ -362,6 +363,13 @@ export const publicRoutes = new Hono()
|
|
|
362
363
|
if (!(await verifyTurnstile(body.turnstileToken, ip))) {
|
|
363
364
|
return refuse(c, { code: "confirmHuman" }, 403);
|
|
364
365
|
}
|
|
366
|
+
// The client that starts it (docs/content/dev/api.md): on a managed runtime the Manage-App's
|
|
367
|
+
// list says which may, and how often an hour.
|
|
368
|
+
const client = clientOf(c);
|
|
369
|
+
const refused = clientRefused(client);
|
|
370
|
+
if (refused) {
|
|
371
|
+
return c.json({ error: noteText({ code: refused.note }, requestLang(c)), code: refused.code }, refused.status);
|
|
372
|
+
}
|
|
365
373
|
const vid = visitorId(c, true, body.embedded);
|
|
366
374
|
const ipHash = hashIp(ip);
|
|
367
375
|
if (await visitorOverLimit(vid, ipHash)) {
|
|
@@ -385,6 +393,7 @@ export const publicRoutes = new Hono()
|
|
|
385
393
|
(await storedTranslation(w.id, body.lang))
|
|
386
394
|
? body.lang
|
|
387
395
|
: null,
|
|
396
|
+
client,
|
|
388
397
|
});
|
|
389
398
|
return c.json({ runId });
|
|
390
399
|
}
|
|
@@ -17,8 +17,15 @@ export const CODE_LIMITS = {
|
|
|
17
17
|
timeoutMs: 120_000,
|
|
18
18
|
/** Tool calls one program may make. */
|
|
19
19
|
maxCalls: 100,
|
|
20
|
+
/** Tool calls all programs of one step may make together: the model may run one program per turn. */
|
|
21
|
+
stepCalls: 300,
|
|
20
22
|
/** Tool calls of one program running at the same time. */
|
|
21
23
|
maxParallel: 4,
|
|
24
|
+
/**
|
|
25
|
+
* Characters of one tool answer a program takes in. QuickJS 0.31 can abort while it frees a
|
|
26
|
+
* runtime that parsed an answer of a million characters and more; this stays well below.
|
|
27
|
+
*/
|
|
28
|
+
answerChars: 200_000,
|
|
22
29
|
/** Characters of the program's answer the model reads. */
|
|
23
30
|
resultChars: 20_000,
|
|
24
31
|
/** Characters of `console.log` output the model reads. */
|
|
@@ -60,15 +67,23 @@ function limiter(max) {
|
|
|
60
67
|
}
|
|
61
68
|
};
|
|
62
69
|
}
|
|
63
|
-
/**
|
|
70
|
+
/**
|
|
71
|
+
* Tools that cost credits on every call: a picture, or a model reading each document. A loop
|
|
72
|
+
* over them spends fast; the model calls them directly, where every call is its own decision.
|
|
73
|
+
*/
|
|
74
|
+
export const PAID_TOOLS = new Set(["generate_image", "scan_documents"]);
|
|
75
|
+
/**
|
|
76
|
+
* What a program may call: tools the server runs itself (a provider's own search has no
|
|
77
|
+
* `execute`) that do not cost credits on every call.
|
|
78
|
+
*/
|
|
64
79
|
function callable(tools) {
|
|
65
|
-
return Object.fromEntries(Object.entries(tools).filter(([, tool]) => typeof tool?.execute === "function"));
|
|
80
|
+
return Object.fromEntries(Object.entries(tools).filter(([key, tool]) => typeof tool?.execute === "function" && !PAID_TOOLS.has(key)));
|
|
66
81
|
}
|
|
67
82
|
/**
|
|
68
|
-
* Wraps each tool for one program run: the
|
|
69
|
-
* tool knows it runs for a program (`inProgram`).
|
|
83
|
+
* Wraps each tool for one program run: the calls of the program and of the step, and the calls
|
|
84
|
+
* in flight are capped, and the tool knows it runs for a program (`inProgram`).
|
|
70
85
|
*/
|
|
71
|
-
function guarded(tools, ctx, limits) {
|
|
86
|
+
function guarded(tools, ctx, limits, step) {
|
|
72
87
|
let calls = 0;
|
|
73
88
|
const slot = limiter(limits.maxParallel);
|
|
74
89
|
return Object.fromEntries(Object.entries(tools).map(([key, tool]) => [
|
|
@@ -77,13 +92,24 @@ function guarded(tools, ctx, limits) {
|
|
|
77
92
|
...tool,
|
|
78
93
|
execute: (input, options) => {
|
|
79
94
|
calls++;
|
|
95
|
+
step.calls++;
|
|
80
96
|
if (calls > limits.maxCalls) {
|
|
81
97
|
throw new Error(`A program makes at most ${limits.maxCalls} tool calls. Split the work.`);
|
|
82
98
|
}
|
|
99
|
+
if (step.calls > limits.stepCalls) {
|
|
100
|
+
throw new Error(`The programs of this step have made ${limits.stepCalls} tool calls, all a step may make. Finish with what you have.`);
|
|
101
|
+
}
|
|
83
102
|
if (ctx.signal.aborted) {
|
|
84
103
|
throw new Error("The run was stopped.");
|
|
85
104
|
}
|
|
86
|
-
return slot(
|
|
105
|
+
return slot(async () => {
|
|
106
|
+
const answer = await program.run(true, () => tool.execute(input, options));
|
|
107
|
+
const size = JSON.stringify(answer ?? null)?.length ?? 0;
|
|
108
|
+
if (size > limits.answerChars) {
|
|
109
|
+
throw new Error(`${key} answered ${size} characters; a program takes at most ${limits.answerChars} from one call. Ask for less, or call ${key} directly.`);
|
|
110
|
+
}
|
|
111
|
+
return answer;
|
|
112
|
+
});
|
|
87
113
|
},
|
|
88
114
|
},
|
|
89
115
|
]));
|
|
@@ -98,6 +124,7 @@ export function codeTool(tools, ctx, limits = CODE_LIMITS) {
|
|
|
98
124
|
return null;
|
|
99
125
|
}
|
|
100
126
|
const config = { id: CODE_TOOL_ID, tools: reachable, timeout: limits.timeoutMs };
|
|
127
|
+
const step = { calls: 0 };
|
|
101
128
|
// The instructions list the tools once; every program runs over fresh guards.
|
|
102
129
|
const { tool: base, instructions } = createCodeMode(config, quickJs());
|
|
103
130
|
const tool = createTool({
|
|
@@ -106,12 +133,25 @@ export function codeTool(tools, ctx, limits = CODE_LIMITS) {
|
|
|
106
133
|
inputSchema: base.inputSchema,
|
|
107
134
|
execute: async (input, options) => {
|
|
108
135
|
await ctx.emit("tool", { code: "runsProgram" });
|
|
109
|
-
const run = createCodeMode({ ...config, tools: guarded(reachable, ctx, limits) }, quickJs()).tool;
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
136
|
+
const run = createCodeMode({ ...config, tools: guarded(reachable, ctx, limits, step) }, quickJs()).tool;
|
|
137
|
+
let result;
|
|
138
|
+
try {
|
|
139
|
+
// Spans need a run being traced; a call without one still runs.
|
|
140
|
+
result = (await run.execute?.(input, {
|
|
141
|
+
...options,
|
|
142
|
+
observe: options?.observe ?? noopObserve,
|
|
143
|
+
}));
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
// QuickJS can fail while it frees a runtime that worked through a large tool answer; the
|
|
147
|
+
// program's result is lost, the next program runs as before.
|
|
148
|
+
return {
|
|
149
|
+
success: false,
|
|
150
|
+
error: {
|
|
151
|
+
message: `The program could not finish (${String(err?.message ?? err).slice(0, 120)}). Work on smaller pieces: return less from each step, or call the tool directly.`,
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
115
155
|
const logs = result.logs?.length ? clip(result.logs.join("\n"), limits.logChars) : "";
|
|
116
156
|
if (!result.success) {
|
|
117
157
|
return { success: false, error: result.error, ...(logs ? { logs } : {}) };
|
|
@@ -128,6 +168,6 @@ export function codeTool(tools, ctx, limits = CODE_LIMITS) {
|
|
|
128
168
|
});
|
|
129
169
|
return {
|
|
130
170
|
tool,
|
|
131
|
-
instructions: `${instructions}\n\nA program makes at most ${limits.maxCalls} tool calls, ${limits.maxParallel} at a time, and stops after ${limits.timeoutMs / 1000} seconds. Return only what you need: a long answer is cut at ${limits.resultChars} characters. A tool that asks the person first cannot run from a program: call
|
|
171
|
+
instructions: `${instructions}\n\nA program makes at most ${limits.maxCalls} tool calls, ${limits.maxParallel} at a time, and stops after ${limits.timeoutMs / 1000} seconds; all programs of this step together make at most ${limits.stepCalls}. Return only what you need: a long answer is cut at ${limits.resultChars} characters. A tool that asks the person first cannot run from a program, and tools that cost credits on every call (${[...PAID_TOOLS].join(", ")}) are not offered there: call them directly.`,
|
|
132
172
|
};
|
|
133
173
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,t as n}from"./jsx-runtime-BNakU3Ej.js";import{Bt as r,Cr as i,Ht as a,Qt as o,Vt as s,Xt as c,_r as l,an as u,qn as d,qt as f,zt as p}from"./ui-DMmT-cSO.js";import{t as m}from"./preload-helper-CNEI7N0N.js";import{Ot as h,Q as g,X as _,Z as v}from"./index-C61HAltK.js";import{c as y,f as b}from"./settings-menu-Dpkp3f56.js";import{ReleaseNotes as x,loadReleases as S,releaseDate as C,releaseLabel as w}from"./ChangelogDialog-C4dVSwtN.js";var T=e(t(),1),E=[{name:`engenty wizards`,description:`credit.engenty-wizards`,homepage:`https://github.com/engenty/wizards`,license:`FSL-1.1-MIT`},{name:`engenty`,description:`credit.engenty`,homepage:`https://github.com/engenty/engenty`,license:`FSL-1.1-MIT`}],D=[{name:`Mastra`,description:`credit.mastra`,homepage:`https://github.com/mastra-ai/mastra`,license:`Apache-2.0`},{name:`AI SDK`,description:`credit.ai-sdk`,homepage:`https://github.com/vercel/ai`,license:`Apache-2.0`},{name:`Model Context Protocol`,description:`credit.model-context-protocol`,homepage:`https://github.com/modelcontextprotocol/typescript-sdk`,license:`MIT`},{name:`Hono`,description:`credit.hono`,homepage:`https://github.com/honojs/hono`,license:`MIT`},{name:`Drizzle ORM`,description:`credit.drizzle-orm`,homepage:`https://github.com/drizzle-team/drizzle-orm`,license:`Apache-2.0`},{name:`libSQL`,description:`credit.libsql`,homepage:`https://github.com/tursodatabase/libsql`,license:`MIT`},{name:`Playwright`,description:`credit.playwright`,homepage:`https://github.com/microsoft/playwright`,license:`Apache-2.0`},{name:`React`,description:`credit.react`,homepage:`https://github.com/facebook/react`,license:`MIT`},{name:`Vite`,description:`credit.vite`,homepage:`https://github.com/vitejs/vite`,license:`MIT`},{name:`Tailwind CSS`,description:`credit.tailwind-css`,homepage:`https://github.com/tailwindlabs/tailwindcss`,license:`MIT`},{name:`React Flow`,description:`credit.react-flow`,homepage:`https://github.com/xyflow/xyflow`,license:`MIT`},{name:`TanStack Query`,description:`credit.tanstack-query`,homepage:`https://github.com/TanStack/query`,license:`MIT`},{name:`xterm.js`,description:`credit.xterm-js`,homepage:`https://github.com/xtermjs/xterm.js`,license:`MIT`},{name:`Lucide`,description:`credit.lucide`,homepage:`https://github.com/lucide-icons/lucide`,license:`ISC`},{name:`Geist & Geist Mono`,description:`credit.geist-geist-mono`,homepage:`https://github.com/vercel/geist-font`,license:`OFL-1.1`},{name:`Space Grotesk`,description:`credit.space-grotesk`,homepage:`https://github.com/floriankarsten/space-grotesk`,license:`OFL-1.1`},{name:`git-cliff`,description:`credit.git-cliff`,homepage:`https://github.com/orhun/git-cliff`,license:`MIT OR Apache-2.0`}],O=e(n(),1),k=(e,...t)=>t.some(t=>t?.toLowerCase().includes(e));function A({name:e,homepage:t,version:n,license:r,description:i}){return(0,O.jsxs)(`li`,{className:`py-2.5`,children:[(0,O.jsxs)(`div`,{className:`flex flex-wrap items-baseline gap-x-2.5 gap-y-0.5`,children:[t?(0,O.jsxs)(`a`,{href:t,target:`_blank`,rel:`noreferrer`,className:`inline-flex items-center gap-1 font-medium text-[0.875rem] text-ink underline-offset-4 hover:underline`,children:[e,(0,O.jsx)(l,{"aria-hidden":!0,className:`size-3 text-ink-4`})]}):(0,O.jsx)(`span`,{className:`font-medium text-[0.875rem] text-ink`,children:e}),n?(0,O.jsx)(`span`,{className:`text-[0.75rem] text-ink-3 tabular-nums`,children:n}):null,(0,O.jsx)(`span`,{className:`text-[0.75rem] text-ink-3`,children:r})]}),i?(0,O.jsx)(`p`,{className:`mt-0.5 text-[0.8125rem] text-ink-3`,children:i}):null]})}function j({title:e,hint:t,children:n}){return(0,O.jsxs)(`section`,{className:`mt-6`,children:[(0,O.jsx)(`h3`,{className:`border-border-soft border-b pb-2 font-display font-semibold text-[1rem]`,children:e}),t?(0,O.jsx)(`p`,{className:`mt-2 text-[0.8125rem] text-ink-3`,children:t}):null,n]})}function M({credits:e}){return(0,O.jsx)(`ul`,{className:`divide-y divide-border-soft`,children:e.map(e=>(0,O.jsx)(A,{name:e.name,homepage:e.homepage,license:e.license,description:u(e.description)},e.name))})}function N({label:e,packages:t}){return(0,O.jsxs)(`div`,{className:`mt-4`,children:[(0,O.jsx)(`h4`,{className:`font-medium text-[0.75rem] text-ink-3 tracking-wide`,children:e}),(0,O.jsx)(`ul`,{className:`divide-y divide-border-soft`,children:t.map(e=>(0,O.jsx)(A,{...e},e.name))})]})}function P({active:e}){let[t,n]=(0,T.useState)(null),[i,o]=(0,T.useState)(``);(0,T.useEffect)(()=>{if(!e||t)return;let r=!1;return m(()=>import(`./oss-credits-qGhcbqiM.js`).then(e=>{r||n(e.default)}),[]),()=>{r=!0}},[e,t]),(0,T.useEffect)(()=>{e||o(``)},[e]);let s=i.trim().toLowerCase(),c=e=>s?e.filter(e=>k(s,e.name,e.license,u(e.description))):e,l=e=>s?e.filter(e=>k(s,e.name,e.license,e.version)):e,d=c(E),p=c(D),h=t?[{id:`shared`,label:u(`about.creditsShared`),packages:l(t.shared)},...t.groups.map(e=>({id:e.id,label:e.label,packages:l(e.packages)}))].filter(e=>e.packages.length>0):[],g=d.length===0&&p.length===0&&h.length===0;return(0,O.jsxs)(O.Fragment,{children:[(0,O.jsx)(`p`,{className:`mb-4 text-[0.875rem] text-ink-3`,children:u(`about.creditsHint`)}),(0,O.jsx)(a,{type:`search`,value:i,placeholder:u(`about.search`),onChange:e=>o(e.target.value)}),d.length>0?(0,O.jsx)(j,{title:u(`about.creditsProduct`),children:(0,O.jsx)(M,{credits:d})}):null,p.length>0?(0,O.jsx)(j,{title:u(`about.creditsBuiltWith`),children:(0,O.jsx)(M,{credits:p})}):null,t===null?(0,O.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,O.jsx)(f,{})}):h.length>0?(0,O.jsx)(j,{title:u(`about.creditsDeps`),hint:s?void 0:u(`about.creditsDepsHint`),children:h.map(e=>(0,O.jsx)(N,{label:e.label,packages:e.packages},e.id))}):null,t!==null&&g?(0,O.jsx)(r,{children:u(`about.noMatches`)}):null]})}var F=[`new`,`earlier`,`credits`],I=e=>u(e===`new`?`about.tab.new`:e===`earlier`?`about.tab.earlier`:`about.credits`),L=e=>e===1?u(`about.change`):u(`about.changes`,{n:e});function R({open:e,onClose:t,me:n}){let r=n?.mode===`local`,{data:a,latest:l}=g(r&&e),[m,E]=(0,T.useState)(null),[D,k]=(0,T.useState)(`new`),A=b(F.indexOf(D)),j=a?.newer&&l?l:v;(0,T.useEffect)(()=>{if(!e)return;let t=!1;return E(null),S(j===`0.7.9`?void 0:j).then(e=>{t||E(e)}),()=>{t=!0}},[e,j]);let M=m?.find(e=>e.version===`v${j}`)??m?.[0]??null,N=m?.filter(e=>e!==M)??[],R=r?a?.kind??null:`cloud`;return(0,O.jsxs)(p,{open:e,onClose:t,wide:!0,height:`tall`,children:[(0,O.jsx)(`div`,{className:`-mt-2 -mr-2 sticky top-0 z-10 flex h-0 justify-end`,children:(0,O.jsx)(s,{label:u(`common.close`),onClick:t,children:(0,O.jsx)(d,{className:`size-4`})})}),(0,O.jsxs)(`div`,{className:`flex flex-col items-center pt-4 text-center`,children:[(0,O.jsx)(h,{size:96}),(0,O.jsxs)(`div`,{className:`mt-4 font-display font-semibold text-[1.5rem] tracking-tight`,children:[`engenty`,(0,O.jsx)(`span`,{className:`text-ember`,children:`.`}),(0,O.jsx)(`span`,{className:`ml-1.5 font-normal text-ink-3`,children:`wizards`})]}),(0,O.jsxs)(`div`,{className:`mt-1 text-[0.9375rem] text-ink-3 tabular-nums`,children:[u(`about.version`,{v}),R?` · ${u(`about.kind.${R}`)}`:``]})]}),r?(0,O.jsx)(`div`,{className:`mt-5`,children:(0,O.jsx)(_,{enabled:e})}):null,(0,O.jsx)(`div`,{className:`mt-6 flex justify-center`,children:(0,O.jsx)(c,{value:D,onChange:k,options:F.map(e=>({id:e,label:I(e)})),label:u(`about.title`)})}),(0,O.jsxs)(`div`,{className:o(`mt-5`,y(A)),children:[D===`new`?m===null?(0,O.jsx)(`div`,{className:`flex justify-center py-6 text-ink-3`,children:(0,O.jsx)(f,{})}):M?(0,O.jsxs)(O.Fragment,{children:[(0,O.jsxs)(`h3`,{className:`flex items-baseline gap-3 border-border-soft border-b pb-2 font-display font-semibold text-[1rem]`,children:[w(M),(0,O.jsx)(`span`,{className:`font-normal font-sans text-[0.8125rem] text-ink-3 tabular-nums`,children:C(M)})]}),(0,O.jsx)(`div`,{className:`mt-3`,children:(0,O.jsx)(x,{release:M})})]}):(0,O.jsx)(`p`,{className:`text-[0.875rem] text-ink-3`,children:u(`about.changelogEmpty`)}):null,D===`earlier`?(0,O.jsx)(`div`,{className:`flex flex-col divide-y divide-border-soft`,children:N.map(e=>(0,O.jsxs)(`details`,{className:`group/r py-2`,children:[(0,O.jsxs)(`summary`,{className:`flex cursor-pointer list-none items-baseline gap-3 text-[0.875rem] [&::-webkit-details-marker]:hidden`,children:[(0,O.jsx)(i,{className:`size-3.5 shrink-0 self-center text-ink-4 transition group-open/r:rotate-90`}),(0,O.jsx)(`span`,{className:`font-medium text-ink tabular-nums`,children:w(e)}),(0,O.jsx)(`span`,{className:`text-[0.8125rem] text-ink-3 tabular-nums`,children:C(e)}),(0,O.jsx)(`span`,{className:`ml-auto text-[0.8125rem] text-ink-4`,children:L(e.commits.length)})]}),(0,O.jsx)(`div`,{className:`mt-2 pl-6`,children:(0,O.jsx)(x,{release:e})})]},e.version??`unreleased`))}):null,D===`credits`?(0,O.jsx)(P,{active:!0}):null]},D)]})}export{R as AboutDialog};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,t as n}from"./jsx-runtime-BNakU3Ej.js";import{Bt as r,Ht as i,Qt as a,an as o,qt as s,zt as c}from"./ui-DMmT-cSO.js";import{t as l}from"./preload-helper-CNEI7N0N.js";var u=e(t(),1),d=e(n(),1);function f(e){switch(e.group){case`Added`:return{label:`NEW`,dot:`bg-moss`};case`Fixed`:return{label:`FIXED`,dot:`bg-amber`};case`Changed`:return{label:`CHANGED`,dot:`bg-cobalt`};case`Performance`:return{label:`PERFORMANCE`,dot:`bg-ember`};case`Deploy`:return{label:`DEPLOY`,dot:`bg-ink-4`};case`Docs`:return{label:`DOCS`,dot:`bg-ink-4`};default:return{label:`OTHER`,dot:`bg-ink-4`}}}var p=e=>e.version?e.version.replace(/^v/,``):o(`about.unreleased`),m=e=>e.timestamp?new Date(e.timestamp*1e3).toISOString().slice(0,10):``,h=e=>e.charAt(0).toUpperCase()+e.slice(1);function g(e,t){let n=t.trim().toLowerCase();if(!n)return e;let r=[];for(let t of e){if(`${p(t)} ${m(t)}`.toLowerCase().includes(n)){r.push(t);continue}let e=t.commits.filter(e=>`${f(e).label} ${e.scope??``} ${e.message}`.toLowerCase().includes(n));e.length>0&&r.push({...t,commits:e})}return r}async function _(e){if(e)try{let t=await fetch(`https://raw.githubusercontent.com/engenty/wizards/v${e}/apps/web/src/about/changelog.json`,{signal:AbortSignal.timeout(5e3)});if(t.ok)return await t.json()}catch{}return(await l(async()=>{let{default:e}=await import(`./changelog-Be0i5Jjw.js`);return{default:e}},[])).default}function v({release:e}){return(0,d.jsx)(`ul`,{className:`flex flex-col gap-2`,children:e.commits.map(e=>{let t=f(e);return(0,d.jsxs)(`li`,{className:`flex items-start gap-2.5 text-[0.875rem]`,children:[(0,d.jsx)(`span`,{className:a(`mt-[7px] size-1.5 shrink-0 rounded-full`,t.dot)}),(0,d.jsxs)(`span`,{className:`min-w-0 text-ink-2`,children:[(0,d.jsxs)(`span`,{className:`font-semibold text-[0.75rem] text-ink tracking-wide`,children:[t.label,e.scope?` [${e.scope}]`:``]}),` `,h(e.message),e.breaking?(0,d.jsx)(`span`,{className:`ml-1.5 rounded-full bg-rose-tint px-1.5 py-0.5 font-medium text-[0.75rem] text-rose`,children:o(`about.breaking`)}):null]})]},e.id)})})}function y({open:e,onClose:t,version:n}){let[a,l]=(0,u.useState)(null),[f,h]=(0,u.useState)(``);(0,u.useEffect)(()=>{if(!e||a)return;let t=!1;return _(n).then(e=>{t||l(e)}),()=>{t=!0}},[e,a,n]),(0,u.useEffect)(()=>{e||h(``)},[e]);let y=a?g(a,f):[];return(0,d.jsxs)(c,{open:e,onClose:t,title:o(`about.changelog`),wide:!0,height:`tall`,children:[(0,d.jsx)(`p`,{className:`-mt-3 mb-4 text-[0.875rem] text-ink-3`,children:o(`about.changelogHint`)}),a===null?(0,d.jsx)(`div`,{className:`flex justify-center py-10 text-ink-3`,children:(0,d.jsx)(s,{})}):a.length===0?(0,d.jsx)(r,{children:o(`about.changelogEmpty`)}):(0,d.jsxs)(d.Fragment,{children:[(0,d.jsx)(i,{type:`search`,value:f,placeholder:o(`about.search`),onChange:e=>h(e.target.value)}),y.length===0?(0,d.jsx)(r,{children:o(`about.noMatches`)}):null,y.map(e=>(0,d.jsxs)(`section`,{className:`mt-6`,children:[(0,d.jsxs)(`h3`,{className:`flex items-baseline gap-3 border-border-soft border-b pb-2 font-display font-semibold text-[1rem]`,children:[p(e),(0,d.jsx)(`span`,{className:`font-normal font-sans text-[0.8125rem] text-ink-3 tabular-nums`,children:m(e)})]}),(0,d.jsx)(`div`,{className:`mt-3`,children:(0,d.jsx)(v,{release:e})})]},e.version??`unreleased`))]})]})}export{y as ChangelogDialog,v as ReleaseNotes,_ as loadReleases,m as releaseDate,p as releaseLabel};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import{r as e}from"./rolldown-runtime-hePW80VL.js";import{n as t,t as n}from"./jsx-runtime-BNakU3Ej.js";import{$ as r,$t as i,An as a,Bn as o,Dt as s,Er as c,Et as l,Jn as u,Kn as d,Nr as f,Qn as p,Qt as m,Tt as h,Vt as g,W as _,Wr as v,Wt as y,Xn as b,Zn as x,Zt as S,_t as C,an as w,ar as T,bt as E,cn as D,cr as O,ct as k,en as A,gn as j,gt as ee,ht as M,kr as N,lt as P,m as F,pt as I,qt as L,st as te,tr as R,ur as z,vt as ne,wt as re,yt as ie}from"./ui-DMmT-cSO.js";import{t as ae}from"./phone-BjmhIKuT.js";import{At as oe,Ct as se,Ht as ce,at as le,it as ue,ot as de,t as fe,zt as pe}from"./index-C61HAltK.js";import{n as me}from"./RunnerView-BW1h4x63.js";var he={name:`hand`,size:24,node:[[`path`,{d:`M18 11V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2`,key:`1fvzgz`}],[`path`,{d:`M14 10V4a2 2 0 0 0-2-2a2 2 0 0 0-2 2v2`,key:`1kc0my`}],[`path`,{d:`M10 10.5V6a2 2 0 0 0-2-2a2 2 0 0 0-2 2v8`,key:`10h0bg`}],[`path`,{d:`M18 8a2 2 0 1 1 4 0v6a8 8 0 0 1-8 8h-2c-2.8 0-4.5-.86-5.99-2.34l-3.6-3.6a2 2 0 0 1 2.83-2.82L7 15`,key:`1s1gnw`}]]};he.node;var ge=f(he),_e={name:`undo-2`,size:24,node:[[`path`,{d:`M9 14 4 9l5-5`,key:`102s5s`}],[`path`,{d:`M4 9h10.5a5.5 5.5 0 0 1 5.5 5.5a5.5 5.5 0 0 1-5.5 5.5H11`,key:`f3b9sd`}]]};_e.node;var ve=f(_e),ye={name:`video-off`,size:24,node:[[`path`,{d:`M10.66 6H14a2 2 0 0 1 2 2v2.5l5.248-3.062A.5.5 0 0 1 22 7.87v8.196`,key:`w8jjjt`}],[`path`,{d:`M16 16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2`,key:`1xawa7`}],[`path`,{d:`m2 2 20 20`,key:`1ooewy`}]]};ye.node;var be=f(ye),xe={name:`volume-x`,size:24,node:[[`path`,{d:`M11 4.702a.7.7 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.7.7 0 0 0 11 19.298z`,key:`1p7khw`}],[`path`,{d:`m16.5 14.5 5-5`,key:`cul3yw`}],[`path`,{d:`m16.5 9.5 5 5`,key:`1akey5`}]]};xe.node;var Se=f(xe),Ce=v(),B=e(t(),1),V=e(n(),1),we=typeof window<`u`&&window.matchMedia(`(pointer: coarse)`).matches;function Te({since:e}){let[t,n]=(0,B.useState)(Date.now());if((0,B.useEffect)(()=>{if(!e)return;let t=setInterval(()=>n(Date.now()),1e3);return()=>clearInterval(t)},[e]),!e)return null;let r=Math.max(0,Math.floor((t-e)/1e3)),i=String(Math.floor(r/60)).padStart(2,`0`),a=String(r%60).padStart(2,`0`);return(0,V.jsxs)(`span`,{className:`font-mono text-[0.8125rem] text-white/60 tabular-nums`,children:[i,`:`,a]})}function H({label:e,on:t,danger:n,busy:r,onClick:i,children:a}){return(0,V.jsx)(`button`,{type:`button`,"aria-label":e,title:e,"aria-pressed":t,disabled:r,onClick:i,className:m(`flex size-12 items-center justify-center rounded-full transition disabled:opacity-50`,n?`bg-rose text-white hover:brightness-110`:t===!1?`bg-white text-neutral-900 hover:bg-white/90`:`bg-white/15 text-white hover:bg-white/25`),children:r?(0,V.jsx)(L,{className:`size-5`}):a})}function Ee({voice:e}){let t=(0,B.useRef)(null),{captions:n}=e;return(0,B.useEffect)(()=>{n.length&&t.current?.scrollIntoView({block:`end`})},[n]),n.length?(0,V.jsx)(`div`,{className:`min-h-0 flex-1 overflow-y-auto px-4 sm:px-5`,children:(0,V.jsxs)(`ol`,{className:`mx-auto flex max-w-[720px] flex-col gap-2 py-2`,children:[n.map(e=>(0,V.jsx)(`li`,{className:m(`text-[0.9375rem] leading-snug`,e.who===`bot`?`text-white/95`:`text-right text-white/50`),children:e.text},e.id)),(0,V.jsx)(`div`,{ref:t})]})}):null}function De({voice:e,view:t,video:n,className:r}){let i=e.state===`live`,a=e.state===`connecting`,[o,s]=(0,B.useState)(null),[c,l]=(0,B.useState)(!1);(0,B.useEffect)(()=>{s(i?Date.now():null)},[i]);let d=async()=>{l(!1),await e.start(),n&&await e.startCamera()},f=()=>{e.stop(),l(!0)},p=n||e.camera,h=[...e.captions].reverse().find(e=>e.who===`bot`),g=[...e.captions].reverse().find(e=>e.who===`me`),_=e.speaking?w(`talk.speaking`):e.listening?w(`talk.listening`):i?w(`talk.live`):a?w(`talk.connecting`):c?w(`video.ended`):``;return(0,V.jsxs)(`section`,{className:m(`relative flex min-h-0 flex-col bg-neutral-950 text-white`,`safe-top`,r),children:[(0,V.jsxs)(`div`,{className:`flex h-14 shrink-0 items-center gap-3 px-4 sm:px-5`,children:[(0,V.jsx)(`div`,{className:`min-w-0 flex-1 truncate font-display font-semibold text-[1rem] tracking-tight`,children:t?.wizard.title??``}),_?(0,V.jsxs)(`span`,{className:`flex items-center gap-1.5 text-[0.8125rem] text-white/70`,children:[i?(0,V.jsx)(`span`,{className:m(`size-2 rounded-full`,e.speaking?`animate-pulse-dot bg-emerald-400`:`bg-rose`)}):null,_]}):null,(0,V.jsx)(Te,{since:o})]}),(0,V.jsxs)(`div`,{className:m(`grid min-h-0 gap-2 px-3 pb-2 sm:px-4`,p?`flex-1 grid-cols-1 sm:grid-cols-2`:`shrink-0 grid-cols-1`,!p&&i&&e.captions.length?`h-[38%]`:p?``:`flex-1`),children:[(0,V.jsxs)(`div`,{className:m(`relative min-h-0 overflow-hidden rounded-2xl bg-neutral-900`,!p&&`hidden`),children:[(0,V.jsx)(`video`,{ref:e.video,muted:!0,playsInline:!0,autoPlay:!0,className:m(`absolute inset-0 h-full w-full object-cover`,e.facing===`user`&&`-scale-x-100`,e.camera?`block`:`hidden`)}),e.camera?null:(0,V.jsxs)(`div`,{className:`absolute inset-0 flex flex-col items-center justify-center gap-2 text-white/50`,children:[(0,V.jsx)(be,{className:`size-8`}),(0,V.jsx)(`span`,{className:`text-[0.8125rem]`,children:w(`video.cameraOff`)})]}),(0,V.jsxs)(`span`,{className:`absolute bottom-2 left-3 rounded-md bg-black/50 px-2 py-0.5 text-[0.75rem]`,children:[w(`video.you`),e.muted?(0,V.jsx)(ce,{className:`ml-1.5 inline size-3`}):null]})]}),(0,V.jsxs)(`div`,{className:m(`relative flex min-h-0 items-center justify-center overflow-hidden rounded-2xl transition-shadow`,p?`bg-neutral-900`:`bg-transparent`,p&&e.speaking&&`ring-2 ring-emerald-400/70`),children:[(0,V.jsx)(`div`,{className:m(`rounded-full transition-shadow duration-500`,!p&&e.listening&&`shadow-[0_0_80px_20px_rgba(244,63,94,0.25)]`,!p&&e.speaking&&`shadow-[0_0_80px_20px_rgba(52,211,153,0.3)]`,e.speaking&&`animate-breathe`),children:(0,V.jsx)(se,{kind:t?.wizard.avatar??`round`,size:p?140:200,fluffy:!0,interactive:!1})}),p?(0,V.jsx)(`span`,{className:`absolute bottom-2 left-3 max-w-[85%] truncate rounded-md bg-black/50 px-2 py-0.5 text-[0.75rem]`,children:t?.wizard.title??``}):null]})]}),i&&!p?(0,V.jsx)(Ee,{voice:e}):i&&(h||g)?(0,V.jsx)(`div`,{className:`shrink-0 px-4 pb-2 sm:px-5`,children:(0,V.jsxs)(`div`,{className:`mx-auto max-w-[720px] space-y-1 text-center`,children:[g?(0,V.jsx)(`p`,{className:`line-clamp-1 text-[0.8125rem] text-white/50`,children:g.text}):null,h?(0,V.jsx)(`p`,{className:`line-clamp-3 text-[0.9375rem] text-white/95 leading-snug`,children:h.text}):null]})}):null,e.error?(0,V.jsx)(`p`,{className:`shrink-0 px-5 pb-2 text-center text-[0.8125rem] text-rose`,children:e.error}):null,(0,V.jsx)(`div`,{className:`flex shrink-0 items-center justify-center gap-3 px-4 pt-1 pb-4`,children:i?(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(H,{label:w(e.muted?`video.unmute`:`video.mute`),on:!e.muted,onClick:e.toggleMute,children:e.muted?(0,V.jsx)(ce,{className:`size-5`}):(0,V.jsx)(z,{className:`size-5`})}),(0,V.jsx)(H,{label:w(e.camera?`talk.cameraOff`:`talk.camera`),on:e.camera,onClick:()=>e.camera?e.stopCamera():void e.startCamera(),children:e.camera?(0,V.jsx)(u,{className:`size-5`}):(0,V.jsx)(be,{className:`size-5`})}),e.camera&&we?(0,V.jsx)(H,{label:w(`video.flip`),onClick:()=>void e.flipCamera(),children:(0,V.jsx)(b,{className:`size-5`})}):null,(0,V.jsx)(H,{label:w(`video.leave`),danger:!0,onClick:f,children:(0,V.jsx)(pe,{className:`size-5`})})]}):(0,V.jsxs)(`div`,{className:`flex flex-col items-center gap-2`,children:[(0,V.jsxs)(`button`,{type:`button`,disabled:a||!t?.talk,onClick:()=>void d(),className:`flex h-12 items-center gap-2 rounded-full bg-emerald-500 px-6 font-medium text-[0.9375rem] text-white transition hover:brightness-110 disabled:opacity-50`,children:[a?(0,V.jsx)(L,{className:`size-4`}):n?(0,V.jsx)(u,{className:`size-5`}):(0,V.jsx)(z,{className:`size-5`}),w(c?`video.rejoin`:n?`video.join`:`talk.start`)]}),!c&&!e.error?(0,V.jsx)(`p`,{className:`max-w-sm text-center text-[0.75rem] text-white/50`,children:w(n?`video.hint`:`talk.joinHint`)}):null]})})]})}var Oe=e=>j[e.kind]!==`device`,ke=1024,Ae=4e3;function je(e,t){return e?e.length>t?`${e.slice(0,t)} …`:e:``}function Me(e,t,n=!1){let r=[`status: ${e.status}`,`camera: ${n?`on`:`off`}`];if(e.ask)return r.push(e.ask.kind===`confirm`?`question: the step wants to "${e.ask.action.summary}" in ${e.ask.service}; answer_ask allows or skips it`:`question: a sign-in at ${e.ask.site.host}; the person types it on the screen, wait`),r.join(`
|
|
2
|
+
`);if(e.status===`running`){let t=[...e.events].reverse().find(e=>e.type===`tool`||e.type===`info`||e.type===`step_started`);return r.push(`working on: ${e.step?.title??``}`),t&&r.push(`doing: ${i(t)}`),r.join(`
|
|
3
|
+
`)}if(e.status===`done`){r.push(`done. made:`);for(let{step:t,output:n}of e.shown)r.push(`- ${t.title}: ${je(n?.text,400)||`(a file, on the screen)`}`);return r.join(`
|
|
4
|
+
`)}if(e.status===`failed`)return r.push(`failed: ${e.error??``}; go_back or the person retries on the screen`),r.join(`
|
|
5
|
+
`);if(t){r.push(`page: ${t.step.title}`);for(let e of t.fields){let n=t.values[e.id],i=n!=null&&n!==``,a=Oe(e)?`by voice`:e.kind===`image`?`with the camera (take_photo) or on the screen`:`on the screen only`,o=e.options?.length?`; options: ${e.options.join(` | `)}`:``;r.push(`- field ${e.id} (${e.kind}${e.required?`, required`:``}, ${a}): ${e.label}${e.help?` – ${e.help}`:``}${o}${i?` = ${je(String(Array.isArray(n)?n.join(`, `):n),120)}`:` = (open)`}`)}return r.join(`
|
|
6
|
+
`)}if(e.step?.type===`review`){r.push(`review: ${e.step.title}`);for(let{step:t,output:n}of e.shown)r.push(`- ${t.id} "${t.title}": ${je(n?.text,600)||`(a picture or file, on the screen)`}`);return r.push(`regenerate allowed: ${e.step.regenerate?`yes`:`no`}`),r.join(`
|
|
7
|
+
`)}return r.push(`step: ${e.step?.title??``}`),r.join(`
|
|
8
|
+
`)}function Ne(e,t,n,r){let[i,a]=(0,B.useState)(`off`),[o,s]=(0,B.useState)(null),[c,l]=(0,B.useState)(!1),[u,d]=(0,B.useState)(!1),[f,p]=(0,B.useState)(!1),[m,h]=(0,B.useState)(`environment`),[g,v]=(0,B.useState)(!1),[y,b]=(0,B.useState)([]),x=(0,B.useRef)(null),S=(0,B.useRef)(null),C=(0,B.useRef)(0),T=(0,B.useRef)(!1);T.current=f;let E=(0,B.useRef)(null),D=(0,B.useRef)(null),O=(0,B.useRef)(null),k=(0,B.useRef)(null),A=(0,B.useRef)(t);A.current=t;let j=(0,B.useRef)(r);j.current=r;let ee=(0,B.useRef)(n);ee.current=n;let M=(0,B.useRef)(``),N=(0,B.useCallback)(e=>{let t=D.current;t&&t.readyState===`open`&&t.send(JSON.stringify(e))},[]),P=(0,B.useCallback)(()=>{let e=x.current;if(!T.current||!e||e.videoWidth===0)return null;let t=Math.min(1,ke/e.videoWidth),n=document.createElement(`canvas`);return n.width=Math.round(e.videoWidth*t),n.height=Math.round(e.videoHeight*t),n.getContext(`2d`)?.drawImage(e,0,0,n.width,n.height),n.toDataURL(`image/jpeg`,.75)},[]),F=(0,B.useCallback)(()=>{for(let e of S.current?.getTracks()??[])e.stop();S.current=null,x.current&&(x.current.srcObject=null),p(!1)},[]),I=(0,B.useCallback)(async e=>{if(S.current)return;let t=e??`environment`;try{let e=await navigator.mediaDevices.getUserMedia({video:{facingMode:{ideal:t},width:{ideal:1280}},audio:!1});S.current=e;let n=e.getVideoTracks()[0]?.getSettings().facingMode;h(n===`user`||n===`environment`?n:t),x.current&&(x.current.srcObject=e,await x.current.play().catch(()=>void 0)),p(!0)}catch(e){s(e.name===`NotAllowedError`?w(`talk.cameraDenied`):e.message)}},[]),L=(0,B.useCallback)(async()=>{let e=m===`user`?`environment`:`user`;F(),await I(e)},[m,F,I]),te=(0,B.useCallback)(()=>{v(e=>{for(let t of k.current?.getAudioTracks()??[])t.enabled=e;return!e})},[]),R=(0,B.useCallback)(()=>{F(),D.current?.close(),D.current=null,E.current?.close(),E.current=null;for(let e of k.current?.getTracks()??[])e.stop();k.current=null,O.current&&=(O.current.srcObject=null,O.current.remove(),null),M.current=``,l(!1),d(!1),v(!1),a(`off`)},[F]);(0,B.useEffect)(()=>()=>R(),[R]);let z=(0,B.useCallback)(async(t,n)=>{let r=A.current,i=j.current,a=ee.current;switch(t){case`get_state`:return r?Me(r,i,T.current):`no run`;case`look`:{let e=P();return e?(N({type:`conversation.item.create`,item:{type:`message`,role:`user`,content:[{type:`input_text`,text:`[camera] what the person shows right now`},{type:`input_image`,image_url:e}]}}),`a picture arrived as the next message`):`the camera is off; ask the person to switch it on`}case`take_photo`:{if(!i)return`no page is open`;let t=i.fields.find(e=>e.id===String(n.field??``));if(t?.kind!==`image`)return`no such photo field on this page`;let r=P();if(!r)return`the camera is off; ask the person to switch it on`;try{let n=await(await fetch(r)).blob(),a=new File([n],`photo-${Date.now()}.jpg`,{type:`image/jpeg`}),o=await _.upload(`/api/runs/${e}/uploads`,a),s=i.values[t.id],c=t.multiple?[...Array.isArray(s)?s:s?[s]:[],o.id]:o.id,l=i.setField(t.id,c);return l?`refused: ${l}`:`the photo is in the field`}catch(e){return`failed: ${e.message}`}}case`set_field`:{if(!i)return`no page is open`;let e=i.setField(String(n.field??``),n.value);return e?`refused: ${e}`:`kept`}case`submit_page`:{if(!i)return`no page is open`;let e=i.fields.filter(e=>e.required&&Oe(e)&&e.kind!==`toggle`&&(i.values[e.id]===void 0||i.values[e.id]===null||i.values[e.id]===``));return e.length?`still open: ${e.map(e=>e.id).join(`, `)}`:(i.submit(),`sent; wait for the next state`)}case`accept_review`:return r?.step?.type===`review`?await a.accept(r.step.id)?`accepted`:a.error??`refused`:`no review is open`;case`regenerate`:return r?.step?.type===`review`?await a.regenerate(r.step.id,String(n.target??``),String(n.note??``))?`the wizard makes it again; wait`:a.error??`refused`:`no review is open`;case`answer_ask`:if(!r?.ask)return`no question is open`;try{return await _.post(`/api/runs/${e}/ask/${r.ask.id}`,{type:n.allow?`done`:`skip`}),n.allow?`allowed`:`skipped`}catch(e){return`refused: ${e.message}`}case`go_back`:return await a.back()?`went back; wait for the state`:a.error??`refused`;default:return`unknown tool ${t}`}},[e,P,N]),ne=(0,B.useCallback)(async()=>{if(!E.current){s(null),b([]),a(`connecting`);try{let t=await _.post(`/api/runs/${e}/talk`),n=await navigator.mediaDevices.getUserMedia({audio:{echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0}});k.current=n;let r=new RTCPeerConnection;E.current=r;let i=document.createElement(`audio`);i.autoplay=!0,i.setAttribute(`playsinline`,``),document.body.append(i),O.current=i,r.ontrack=e=>{i.srcObject=e.streams[0]};for(let e of n.getTracks())r.addTrack(e,n);let o=r.createDataChannel(`oai-events`);D.current=o,o.onmessage=e=>{let t;try{t=JSON.parse(e.data)}catch{return}switch(t.type){case`output_audio_buffer.started`:l(!0);break;case`output_audio_buffer.stopped`:case`output_audio_buffer.cleared`:l(!1);break;case`input_audio_buffer.speech_started`:{d(!0);let e=Date.now()-C.current>Ae?P():null;e&&(C.current=Date.now(),N({type:`conversation.item.create`,item:{type:`message`,role:`user`,content:[{type:`input_text`,text:`[camera] what the person shows while speaking`},{type:`input_image`,image_url:e}]}}));break}case`input_audio_buffer.speech_stopped`:d(!1);break;case`response.output_audio_transcript.done`:case`conversation.item.input_audio_transcription.completed`:{let e=String(t.transcript??``).trim();if(e){let n=t.type===`response.output_audio_transcript.done`?`bot`:`me`;b(t=>[...t.slice(-199),{id:`${Date.now()}:${n}`,who:n,text:e}])}break}case`response.function_call_arguments.done`:{let e=String(t.name??``),n=String(t.call_id??``),r={};try{r=JSON.parse(String(t.arguments??`{}`))}catch{}z(e,r).then(e=>{N({type:`conversation.item.create`,item:{type:`function_call_output`,call_id:n,output:e}}),N({type:`response.create`})});break}case`error`:s(String(t.error?.message??`error`))}},o.onopen=()=>{a(`live`);let e=A.current;e&&(M.current=Me(e,j.current,T.current),N({type:`conversation.item.create`,item:{type:`message`,role:`user`,content:[{type:`input_text`,text:`[state]\n${M.current}\n\nGreet the person in one sentence and ask the first open field.`}]}}),N({type:`response.create`}))},o.onclose=()=>{E.current===r&&R()};let c=await r.createOffer();await r.setLocalDescription(c);let u=await fetch(t.endpoint,{method:`POST`,headers:{authorization:`Bearer ${t.clientSecret}`,"content-type":`application/sdp`},body:c.sdp});if(!u.ok)throw Error(`${w(`talk.failed`)} (${u.status})`);await r.setRemoteDescription({type:`answer`,sdp:await u.text()})}catch(e){R(),s(e.name===`NotAllowedError`?w(`chat.micDenied`):e.message),a(`error`)}}},[e,z,P,N,R]);return(0,B.useEffect)(()=>{if(i!==`live`||!t)return;let e=Me(t,r,f);if(e===M.current)return;let n=M.current;M.current=e,N({type:`conversation.item.create`,item:{type:`message`,role:`user`,content:[{type:`input_text`,text:`[state]\n${e}`}]}}),(t.status===`running`&&n.startsWith(`status: running`)&&!n.includes(`working on: `)||t.status!==`running`||n.split(`
|
|
9
|
+
`)[1]!==e.split(`
|
|
10
|
+
`)[1])&&N({type:`response.create`})},[i,t,r,f,N]),{state:i,error:o,speaking:c,listening:u,start:ne,stop:R,camera:f,facing:m,startCamera:I,stopCamera:F,flipCamera:L,muted:g,toggleMute:te,captions:y,video:x}}var U=(e,t,n)=>({key:e,who:`bot`,node:t,...n}),W=(e,t,n)=>({key:e,who:`me`,node:t,...n}),Pe=(0,B.createContext)(null),G=(0,B.createContext)(null);function Fe(){return(0,B.useContext)(G)?.voice??null}function K({children:e}){let t=(0,B.useContext)(Pe);return t?(0,Ce.createPortal)(e,t):null}function q({header:e,footer:t,children:n}){let[r,i]=(0,B.useState)(null),a=(0,B.useRef)(null),o=(0,B.useRef)(null),s=(0,B.useRef)(!0);return(0,B.useLayoutEffect)(()=>{let e=a.current,t=o.current;if(!e||!t)return;let n=e.scrollTop,r=()=>{e.scrollHeight-e.scrollTop-e.clientHeight<120?s.current=!0:e.scrollTop<n&&(s.current=!1),n=e.scrollTop},i=null,c=new ResizeObserver(()=>{let r=t.querySelector(`[data-anchor]`);r&&r!==i?(i=r,e.scrollTop+=r.getBoundingClientRect().top-e.getBoundingClientRect().top-12,s.current=!1,n=e.scrollTop):s.current&&(e.scrollTop=e.scrollHeight)});return e.scrollTop=e.scrollHeight,e.addEventListener(`scroll`,r,{passive:!0}),c.observe(t),c.observe(e),()=>{c.disconnect(),e.removeEventListener(`scroll`,r)}},[]),(0,V.jsx)(Pe.Provider,{value:r,children:(0,V.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col`,children:[e,(0,V.jsx)(`div`,{ref:a,className:`min-h-0 flex-1 overflow-y-auto overscroll-contain`,children:(0,V.jsx)(`div`,{ref:o,className:`mx-auto flex w-full max-w-[760px] flex-col gap-3 px-3 pt-5 pb-4 sm:px-6`,children:n})}),(0,V.jsxs)(`div`,{className:`shrink-0 border-border-soft border-t bg-background`,onPointerDownCapture:()=>{s.current=!0},onKeyDownCapture:()=>{s.current=!0},children:[(0,V.jsx)(`div`,{ref:i,className:`mx-auto w-full max-w-[760px] px-3 pt-3 sm:px-6`}),t]})]})})}function J({avatar:e,lines:t}){let n=(0,B.useContext)(G),r=(0,B.useMemo)(()=>t.map(e=>({key:e.key,who:e.who,spoken:!e.bare&&!e.wide})),[t]),i=(0,B.useCallback)(e=>{let t=document.querySelector(`[data-say="${CSS.escape(e)}"]`);return t?.querySelector(`[data-say-text]`)?.getAttribute(`data-say-text`)??t?.innerText??null},[]);de(!!n?.readAloud,n?.lang??A,r,i);let a=[];for(let e of t){let t=a.at(-1);t&&t.who===`bot`&&e.who===`bot`?t.lines.push(e):a.push({who:e.who,lines:[e]})}return a.map((t,n)=>t.who===`bot`?(0,V.jsxs)(`div`,{className:`flex items-start gap-2.5`,children:[(0,V.jsx)(`div`,{className:`sticky top-1 shrink-0 pt-0.5`,children:(0,V.jsx)(se,{kind:e,size:30,interactive:n>=a.length-2})}),(0,V.jsx)(`div`,{className:`flex min-w-0 flex-1 flex-col items-start gap-1.5`,children:t.lines.map(e=>(0,V.jsx)(`div`,{"data-anchor":e.anchor?``:void 0,"data-say":e.key,className:m(`animate-rise`,e.bare?`w-full pt-1`:`rounded-2xl rounded-tl-md text-[0.9375rem] text-ink leading-relaxed`,!e.bare&&(e.wide?m(`w-full bg-card p-4 shadow-soft ring-1 ring-border-soft`,e.wide===`most`&&`md:w-4/5`):`max-w-[min(36rem,100%)] bg-card px-4 py-2.5 shadow-soft ring-1 ring-border-soft`),e.tone===`error`&&`bg-rose-tint text-rose shadow-none ring-0`),children:e.node},e.key))})]},t.lines[0].key):t.lines.map(e=>(0,V.jsxs)(`div`,{className:`flex animate-rise flex-col items-end gap-1 pl-10`,children:[(0,V.jsx)(`div`,{className:`max-w-[min(32rem,100%)] whitespace-pre-wrap break-words rounded-2xl rounded-br-md bg-primary px-4 py-2.5 text-[0.9375rem] text-primary-foreground leading-relaxed`,children:e.node}),e.onEdit?(0,V.jsxs)(`button`,{type:`button`,onClick:e.onEdit,className:`inline-flex items-center gap-1 px-1 text-[0.75rem] text-ink-4 transition hover:text-ink-2 coarse:min-h-9`,children:[(0,V.jsx)(T,{className:`size-3`}),` `,w(`chat.change`)]}):null]},e.key)))}function Ie(){return(0,V.jsx)(`span`,{className:`inline-flex items-center gap-1 py-1.5`,role:`status`,"aria-label":w(`run.working`),children:[0,1,2].map(e=>(0,V.jsx)(`span`,{className:`size-1.5 animate-typing rounded-full bg-ink-3`,style:{animationDelay:`${e*160}ms`}},e))})}function Y({children:e}){return(0,V.jsx)(`div`,{className:`flex flex-wrap items-center gap-2`,children:e})}var X=(e,t)=>U(e,(0,V.jsx)(Y,{children:t}),{bare:!0});function Z({onClick:e,children:t,primary:n,on:r,disabled:i,busy:a}){return(0,V.jsxs)(`button`,{type:`button`,"aria-pressed":r,disabled:i||a,onClick:e,className:m(`inline-flex h-10 items-center gap-1.5 rounded-full px-4 font-medium text-[0.875rem] transition active:scale-[0.98] disabled:pointer-events-none disabled:opacity-50 coarse:h-11`,n?`bg-primary text-primary-foreground hover:brightness-[1.06]`:r?`bg-ember-tint text-ink ring-1 ring-ember`:`bg-card text-ink-2 ring-1 ring-input hover:text-ink hover:ring-ink-4`),children:[a?(0,V.jsx)(L,{className:`size-4`}):null,t]})}function Le({initial:e=``,placeholder:t,multiline:n,inputProps:r,busy:i,disabled:a,inputRef:o,onSend:s}){let[c,l]=(0,B.useState)(e),d=(0,B.useRef)(null),f=o??d,p=(0,B.useContext)(G),h=F(c,l,{endpoint:p?`/api/runs/${p.runId}/transcribe`:void 0}),_=!!p&&h.supported&&!a;(0,B.useEffect)(()=>{if(!_)return;let e=e=>{(e.metaKey||e.ctrlKey)&&e.shiftKey&&e.key.toLowerCase()===`m`&&(e.preventDefault(),h.toggle())};return window.addEventListener(`keydown`,e),()=>window.removeEventListener(`keydown`,e)},[_,h.toggle]),(0,B.useEffect)(()=>{!re&&!a&&f.current?.focus()},[a,f]);let v=()=>{i||a||(h.listening&&h.toggle(),s(c)!==!1&&l(``))},y=h.listening?w(`chat.listening`):h.processing?w(`chat.transcribing`):t,b=p?.voice??null,C=!!p?.call,T=p&&!C&&(ue||_||b)?(0,V.jsxs)(`div`,{className:`mb-1 flex shrink-0 items-center`,children:[b?(0,V.jsx)(g,{label:w(b.state===`live`?`talk.stop`:b.state===`connecting`?`talk.connecting`:`talk.start`),"aria-pressed":b.state===`live`,disabled:b.state===`connecting`,onClick:()=>b.state===`live`?b.stop():void b.start(),className:m(`size-9`,b.state===`live`&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`,b.state===`off`&&p.talk&&`bg-primary text-primary-foreground hover:bg-primary`),children:b.state===`connecting`?(0,V.jsx)(L,{className:`size-4`}):b.state===`live`?(0,V.jsx)(pe,{className:`size-4`}):(0,V.jsx)(ae,{className:`size-4`})}):null,b?.state===`live`?(0,V.jsx)(g,{label:w(b.camera?`talk.cameraOff`:`talk.camera`),"aria-pressed":b.camera,onClick:()=>b.camera?b.stopCamera():void b.startCamera(),className:m(`size-9`,b.camera&&`text-ink`),children:b.camera?(0,V.jsx)(u,{className:`size-4`}):(0,V.jsx)(be,{className:`size-4`})}):null,ue?(0,V.jsx)(g,{label:w(p.readAloud?`chat.readAloudOff`:`chat.readAloud`),"aria-pressed":p.readAloud,onClick:()=>p.setReadAloud(!p.readAloud),className:m(`size-9`,p.readAloud&&`text-ink`),children:p.readAloud?(0,V.jsx)(oe,{className:`size-4`}):(0,V.jsx)(Se,{className:`size-4`})}):null,_?(0,V.jsx)(g,{label:w(h.listening?`chat.dictateStop`:`chat.dictate`),"aria-pressed":h.listening,disabled:h.processing,onClick:h.toggle,className:m(`size-9`,h.listening&&`bg-rose-tint text-rose hover:bg-rose-tint hover:text-rose`),children:h.processing?(0,V.jsx)(L,{className:`size-4`}):h.listening?(0,V.jsx)(x,{className:`size-3.5 animate-pulse-dot fill-current`}):(0,V.jsx)(z,{className:`size-4`})}):null]}):null;return(0,V.jsxs)(`form`,{className:`pb-3`,onSubmit:e=>{e.preventDefault(),v()},children:[b&&!C?(0,V.jsx)(`video`,{ref:b.video,muted:!0,playsInline:!0,autoPlay:!0,className:m(`mb-2 ml-auto w-32 rounded-xl bg-black object-cover shadow-soft ring-1 ring-border-soft`,b.camera?`block`:`hidden`)}):null,(0,V.jsxs)(`div`,{className:m(`flex items-end gap-1 rounded-[1.375rem] border border-input bg-card pr-1.5 pl-1 transition focus-within:border-focus focus-within:ring-4 focus-within:ring-focus-glow`,a&&`opacity-60`),children:[T,n?(0,V.jsx)(S,{ref:f,minRows:1,maxRows:6,value:c,disabled:a,placeholder:y,autoCapitalize:`sentences`,onChange:e=>l(e.target.value),onKeyDown:e=>{e.key===`Enter`&&!e.shiftKey&&!re&&!e.nativeEvent.isComposing&&(e.preventDefault(),v())},className:`min-h-11 border-0 bg-transparent py-2.5 shadow-none focus:ring-0`}):(0,V.jsx)(`input`,{ref:f,...r,value:c,disabled:a,placeholder:y,enterKeyHint:`send`,onChange:e=>l(e.target.value),className:`h-11 min-w-0 flex-1 bg-transparent px-3 text-[0.9375rem] text-ink outline-none placeholder:text-ink-4`}),(0,V.jsx)(`button`,{type:`submit`,"aria-label":w(`chat.send`),title:w(`chat.send`),disabled:i||a,className:`mb-1 flex size-9 shrink-0 items-center justify-center rounded-full bg-primary text-primary-foreground transition hover:brightness-[1.06] disabled:opacity-40`,children:i?(0,V.jsx)(L,{className:`size-4`}):(0,V.jsx)(N,{className:`size-4`})})]}),h.error?(0,V.jsx)(`p`,{className:`mt-1.5 px-3 text-[0.75rem] text-rose`,children:h.error===`denied`?w(`chat.micDenied`):h.error}):C?null:b?.error?(0,V.jsx)(`p`,{className:`mt-1.5 px-3 text-[0.75rem] text-rose`,children:b.error}):b?.state===`live`?(0,V.jsx)(`p`,{className:`mt-1.5 px-3 text-[0.75rem] text-ink-3`,children:b.speaking?w(`talk.speaking`):b.listening?w(`talk.listening`):w(`talk.live`)}):p?.talk&&b?.state===`off`?(0,V.jsx)(`p`,{className:`mt-1.5 px-3 text-[0.75rem] text-ink-3`,children:w(`talk.hint`)}):null]})}function Q({placeholder:e=w(`chat.above`)}){return(0,V.jsx)(K,{children:(0,V.jsx)(Le,{disabled:!0,placeholder:e,onSend:()=>!1})})}function Re(e){let t=j[e.kind];return t===`typed`&&!e.scan?`typed`:t===`tapped`?`tapped`:`control`}var ze=e=>e==null||e===``||Array.isArray(e)&&e.length===0;function Be(e,t){let n=e.kind===`toggle`||e.kind===`connection`||e.kind===`list`;if(ze(t))return e.required&&!n?w(`chat.required`):null;let r=String(t).trim();if(e.kind===`email`&&!/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(r))return w(`chat.badEmail`);if(e.kind===`url`)try{new URL(r)}catch{return w(`chat.badUrl`)}return e.kind===`number`&&d(r)===null?w(`chat.badNumber`):Array.isArray(t)&&e.multiple&&e.min&&t.length<e.min?w(`run.filesMin`,{n:t.length,min:e.min}):null}function Ve(e,t){let n=e.kind===`textarea`?t.replace(/\s+$/,``):t.trim();if(n)return e.kind===`url`&&!/^[a-z][a-z0-9+.-]*:/i.test(n)?`https://${n}`:n}function He({field:e}){return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`font-medium`,children:e.label}),e.help?(0,V.jsx)(`span`,{className:`mt-0.5 block text-[0.8125rem] text-ink-3`,children:e.help}):null]})}function Ue({step:e,only:t}){return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`font-medium`,children:e.title}),e.description?(0,V.jsx)(`span`,{className:`mt-0.5 block text-ink-2`,children:e.description}):null,t?.help?(0,V.jsx)(`span`,{className:`mt-1 block text-[0.8125rem] text-ink-3`,children:t.help}):null]})}function We({field:e,value:t,runId:n}){if(e.kind===`connection`)return(0,V.jsx)(V.Fragment,{children:typeof t==`string`&&t?t:w(`chat.connected`)});if(e.kind===`list`)return(0,V.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,V.jsx)(c,{className:`size-4`}),` `,w(`chat.checked`)]});if(e.kind===`toggle`)return(0,V.jsx)(V.Fragment,{children:w(t===!0?`run.yes`:`run.no`)});if(ze(t))return(0,V.jsx)(`span`,{className:`italic opacity-80`,children:w(`chat.skipped`)});switch(e.kind){case`multiselect`:return(0,V.jsx)(V.Fragment,{children:t.map(D).join(`, `)});case`select`:return(0,V.jsx)(V.Fragment,{children:D(String(t))});case`date`:{let e=new Date(`${String(t)}T00:00`);return(0,V.jsx)(V.Fragment,{children:Number.isNaN(e.getTime())?String(t):new Intl.DateTimeFormat(A,{dateStyle:`long`}).format(e)})}case`color`:return(0,V.jsxs)(`span`,{className:`inline-flex items-center gap-2`,children:[(0,V.jsx)(`span`,{className:`size-4 rounded-full ring-1 ring-white/50`,style:{background:String(t)}}),String(t)]});case`image`:case`signature`:return(0,V.jsx)(`span`,{className:`-mx-1.5 flex flex-wrap gap-1.5`,children:(Array.isArray(t)?t:[String(t)]).map(t=>(0,V.jsx)(`img`,{src:r(`/api/runs/${n}/assets/${t}`),alt:``,className:m(`h-16 rounded-lg bg-white`,e.kind===`image`?`w-16 object-cover`:`object-contain px-1`)},t))});case`file`:{let e=Array.isArray(t)?t.length:1;return(0,V.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,V.jsx)(O,{className:`size-4`}),` `,w(e===1?`chat.file`:`chat.files`,{n:e})]})}case`audio`:{let e=t.seconds;return(0,V.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[(0,V.jsx)(z,{className:`size-4`}),` `,w(`chat.voice`),e?` · ${Math.round(e)} s`:``]})}case`location`:{let e=t;return(0,V.jsx)(V.Fragment,{children:e.label||`${e.lat?.toFixed(5)}, ${e.lng?.toFixed(5)}`})}case`items`:return(0,V.jsx)(V.Fragment,{children:w(`chat.rows`,{n:Array.isArray(t)?t.length:0})});default:return(0,V.jsx)(V.Fragment,{children:String(t)})}}function Ge(e,t,n,r,i,a){let o=[U(t,(0,V.jsx)(Ue,{step:e,only:a}))];for(let e of i)a||o.push(U(`${t}:${e.id}`,(0,V.jsx)(He,{field:e}))),o.push(W(`${t}:${e.id}:a`,(0,V.jsx)(We,{field:e,value:n[e.id],runId:r})));return o}var Ke=(e,t)=>e.fields.filter(e=>!e.when&&!a(e)||t[e.id]!==void 0&&t[e.id]!==null);function qe(e,t){let n=[];e.wizard.description&&n.push(U(`hello`,e.wizard.description)),e.wizard.intro&&n.push(U(`intro`,e.wizard.intro));for(let[t,r]of e.answered.entries()){let i=`${t}:${r.id}`;if(r.type===`page`){let t=r.fields.length===1?r.fields[0]:void 0;n.push(...Ge(r,i,e.values,e.id,Ke(r,e.values),t))}else r.type===`review`&&(n.push(U(i,(0,V.jsx)(`span`,{className:`font-medium`,children:r.title}))),n.push(W(`${i}:a`,w(`run.accept`))))}let r=n.at(-1);return t&&r?.who===`me`&&(n[n.length-1]={...r,onEdit:t}),n}function Je(e,t){return e.fields.filter(e=>!a(e)||t.decidedFields?.includes(e.id)).map(e=>t.options?.[e.id]?.length?{...e,options:t.options[e.id]}:e)}function Ye({view:e,run:t,step:n,before:r}){let i=(0,B.useMemo)(()=>Je(n,e),[n,e]),a=e.known??{},[s,c]=(0,B.useState)(()=>te(n,e)),[l,u]=(0,B.useState)(()=>n.fields.some(t=>e.values[t.id]!==void 0)?o(Je(n,e),e.known??{},te(n,e)).slice(0,-1).map(e=>e.id):[]),[d,f]=(0,B.useState)({}),[p,m]=(0,B.useState)(!1),[h,g]=(0,B.useState)(!1),_=o(i,a,s),v=_.filter(e=>l.includes(e.id)),y=_.find(e=>!l.includes(e.id)),b=i.length===1?i[0]:void 0,x=v.at(-1),S=x?()=>u(e=>e.filter(e=>e!==x.id)):void 0;(0,B.useEffect)(()=>{let e=Object.keys(t.fieldErrors),n=o(i,a,s),r=n.findIndex(t=>e.includes(t.id));r>=0&&(u(n.slice(0,r).map(e=>e.id)),f(t.fieldErrors))},[t.fieldErrors]);let C=e=>{t.submitPage(n.id,e).then(g)},T=(0,B.useContext)(G),E=(0,B.useRef)(s);E.current=s;let D=T?.bindPage,O=(0,B.useRef)(C);O.current=C,(0,B.useEffect)(()=>{if(!D)return;let e=o(i,a,s);return D({step:n,fields:e,values:s,setField:(t,n)=>{let r=e.find(e=>e.id===t);return r?Be(r,n)||(c(e=>({...e,[t]:n})),u(e=>e.includes(t)?e:[...e,t]),f({}),null):`no such field on this page`},submit:()=>O.current(E.current)}),()=>D(null)},[D,n,i,a,s]);let k=e=>{if(!y)return!1;let t=Be(y,e);if(t)return f({[y.id]:t}),!1;let n={...s,[y.id]:e},r=[...l,y.id];return c(n),u(r),f({}),o(i,a,n).some(e=>!r.includes(e.id))||C(n),!0},A=[...r.map(e=>l.length?{...e,onEdit:void 0}:e),...Ge(n,`now:${n.id}`,s,e.id,v,b).map((e,t,n)=>t===n.length-1&&e.who===`me`&&y?{...e,onEdit:S}:e)];y?(Re(y)===`control`?A.push(U(`now:${n.id}:${y.id}:control`,(0,V.jsx)(M,{field:y,value:s[y.id],values:s,runId:e.id,view:e,closed:e.closed?.[y.id],onChange:e=>c(t=>({...t,[y.id]:e})),onBusy:m}),{wide:!0})):b||A.push(U(`now:${n.id}:${y.id}`,(0,V.jsx)(He,{field:y}))),d[y.id]&&A.push(U(`now:${n.id}:${y.id}:error`,d[y.id],{tone:`error`}))):t.busy||h?A.push(U(`sending`,(0,V.jsx)(Ie,{}))):t.error&&A.push(U(`send-error`,t.error,{tone:`error`}));let j=(0,V.jsx)(Q,{});if(h||!y&&l.length>0&&t.busy)j=(0,V.jsx)(Q,{placeholder:w(`run.working`)});else if(!y)A.push(X(`now:${n.id}:go`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Z,{primary:!0,busy:t.busy,onClick:()=>C(s),children:n.cta||w(`run.next`)}),S?(0,V.jsx)(Z,{onClick:S,disabled:t.busy,children:w(`run.back`)}):null]})));else{let r=Re(y),i=!y.required&&y.kind!==`connection`&&y.kind!==`list`?(0,V.jsx)(Z,{onClick:()=>k(void 0),children:w(`chat.skip`)}):null;if(r===`typed`){i&&A.push(X(`now:${n.id}:${y.id}:replies`,i));let e=s[y.id];j=(0,V.jsx)(K,{children:(0,V.jsx)(Le,{initial:ze(e)?``:String(e),multiline:y.kind===`textarea`,placeholder:y.placeholder||(b?y.label:w(`chat.placeholder`)),inputProps:Xe(y),busy:t.busy,onSend:e=>k(Ve(y,e))},y.id)})}else if(r===`tapped`)A.push(U(`now:${n.id}:${y.id}:replies`,(0,V.jsx)(Ze,{field:y,view:e,value:s[y.id],onAnswer:k}),{bare:!0}));else{let e=_.filter(e=>!l.includes(e.id)).length===1;A.push(X(`now:${n.id}:${y.id}:replies`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(Z,{primary:!0,disabled:p,onClick:()=>k(s[y.id]),children:e&&n.cta?n.cta:w(`chat.send`)}),i]})))}}return(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(J,{avatar:e.wizard.avatar,lines:A}),j]})}function Xe(e){switch(e.kind){case`number`:return{inputMode:`decimal`,autoComplete:`off`};case`email`:return{type:`email`,inputMode:`email`,autoComplete:`email`,autoCapitalize:`off`,autoCorrect:`off`,spellCheck:!1};case`url`:return{inputMode:`url`,autoComplete:`url`,autoCapitalize:`off`,autoCorrect:`off`,spellCheck:!1};case`date`:return{type:`date`};default:return ee(e)}}function Ze({field:e,view:t,value:n,onAnswer:r}){let i=new Set(t.closed?.[e.id]?.values.map(String)),[a,o]=(0,B.useState)(Array.isArray(n)?n:[]);if(e.kind===`toggle`)return(0,V.jsxs)(Y,{children:[(0,V.jsx)(Z,{on:n===!1,disabled:i.has(`false`),onClick:()=>r(!1),children:w(`run.no`)}),(0,V.jsx)(Z,{on:n===!0,disabled:i.has(`true`),onClick:()=>r(!0),children:w(`run.yes`)})]});let s=e.options??[];return e.kind===`multiselect`?(0,V.jsxs)(Y,{children:[s.map(e=>(0,V.jsx)(Z,{on:a.includes(e),onClick:()=>o(t=>t.includes(e)?t.filter(t=>t!==e):s.filter(n=>n===e||t.includes(n))),children:D(e)},e)),(0,V.jsx)(Z,{primary:!0,disabled:e.required&&!a.length,onClick:()=>r(a),children:a.length||e.required?w(`chat.send`):w(`chat.skip`)})]}):(0,V.jsxs)(Y,{children:[s.map(e=>(0,V.jsx)(Z,{on:n===e,disabled:i.has(e),onClick:()=>r(e),children:D(e)},e)),e.required?null:(0,V.jsx)(Z,{onClick:()=>r(void 0),children:w(`chat.skip`)})]})}function Qe({view:e}){let t=(0,B.useMemo)(()=>[...e.events].reverse().find(t=>t.type===`step_started`&&t.stepId===e.step?.id),[e.events,e.step?.id]),n=t?new Date(t.at).getTime():Date.now(),[a,o]=(0,B.useState)(Date.now());(0,B.useEffect)(()=>{let e=setInterval(()=>o(Date.now()),1e3);return()=>clearInterval(e)},[]);let s=e.events.filter(e=>(e.type===`tool`||e.type===`info`)&&new Date(e.at).getTime()>=n-500),c=s.at(-1),l=[...s].reverse().find(et),u=[...new Set(s.map(e=>e.asset).filter(e=>!!e))];return(0,V.jsxs)(`div`,{className:m(`flex max-w-full flex-col gap-1`,l?`w-full`:`w-96`),"data-say-text":t?.message??e.step?.title??w(`run.working`),children:[(0,V.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,V.jsx)(Ie,{}),(0,V.jsx)(`span`,{className:`font-medium`,children:t?.message??e.step?.title??w(`run.working`)}),(0,V.jsx)(`span`,{className:`text-[0.75rem] text-ink-4 tabular-nums`,children:w(`run.elapsed`,{s:Math.max(0,Math.round((a-n)/1e3))})})]}),c&&c!==l?(0,V.jsxs)(`div`,{className:`flex items-center gap-1.5 text-[0.8125rem] text-ink-3`,children:[(0,V.jsx)(p,{className:`size-3.5 shrink-0 animate-breathe text-ember`}),(0,V.jsx)(`span`,{className:`truncate`,children:i(c)})]}):null,l&&e.status===`running`?(0,V.jsx)(nt,{runId:e.id,event:l}):null,u.length?(0,V.jsx)(`div`,{className:`mt-1.5 flex flex-wrap gap-1.5`,children:u.slice(-6).map(t=>(0,V.jsx)(`img`,{src:r(`/api/runs/${e.id}/assets/${t}`),alt:``,className:`size-14 rounded-lg bg-paper-2 object-cover ring-1 ring-border-soft`},t))}):null]})}var $e=new Set([`opens`,`clicks`,`clicksOn`,`types`,`typesText`,`selects`,`scrolls`,`presses`,`goesBack`,`waitsForPage`,`fastLoop`,`looksAtPage`,`personDrives`,`agentDrives`]);function et(e){return!!e.note&&$e.has(e.note.code)}var tt=1e4;function nt({runId:e,event:t}){let[n,r]=(0,B.useState)(null),[a,o]=(0,B.useState)(`agent`),[c,l]=(0,B.useState)(!1),u=t.note?.code;if((0,B.useEffect)(()=>{u===`personDrives`?o(`person`):u===`agentDrives`&&o(`agent`)},[u]),(0,B.useEffect)(()=>{let t=()=>_.get(`/api/runs/${e}/browser/seat`).then(e=>o(e.seat)).catch(()=>void 0);if(t(),a!==`person`)return;let n=setInterval(t,tt);return()=>clearInterval(n)},[e,a]),n!==null&&n>=t.id)return null;let d=a===`person`,f=async()=>{l(!0);try{let t=await _.post(`/api/runs/${e}/browser/seat`,{to:d?`agent`:`person`});o(t.seat)}catch{}finally{l(!1)}};return(0,V.jsx)(s,{runId:e,driving:d,caption:i(t),hint:w(`browser.driving`),onBroken:()=>r(t.id),className:`mt-1.5`,action:(0,V.jsxs)(`button`,{type:`button`,disabled:c,onClick:()=>void f(),className:m(`flex h-8 items-center gap-1.5 rounded-full px-3 font-medium text-[0.8125rem] shadow-soft transition-colors disabled:opacity-60`,d?`bg-primary text-primary-foreground hover:bg-primary/90`:`bg-card/90 text-ink ring-1 ring-border-soft backdrop-blur hover:bg-card`),children:[d?(0,V.jsx)(ve,{className:`size-3.5`}):(0,V.jsx)(ge,{className:`size-3.5`}),w(d?`browser.handBack`:`browser.takeOver`)]})},n??0)}function $({children:e,end:t}){return(0,V.jsxs)(`div`,{className:`mb-3 flex flex-wrap items-center justify-between gap-2`,children:[(0,V.jsx)(`h3`,{className:`font-display font-semibold text-[1rem]`,children:e}),t]})}function rt({view:e,run:t,step:n,before:r,asked:i,onNote:a}){let o=e.shown.filter(e=>e.output),[s,l]=(0,B.useState)(o.length===1?o[0].step.id:null),u=(0,B.useRef)(null),d=[...r,...i.map((e,t)=>W(`review:${n.id}:asked:${t}`,e)),U(`review:${n.id}`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`font-medium`,children:n.title}),n.description?(0,V.jsx)(`span`,{className:`mt-0.5 block text-ink-2`,children:n.description}):null]}),{anchor:!0}),...o.map(({step:t,output:r})=>U(`review:${n.id}:${t.id}`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)($,{children:t.title}),(0,V.jsx)(I,{base:`/api/runs/${e.id}`,step:t,output:r,onSurfaceAction:n.regenerate?()=>{l(t.id),u.current?.focus()}:void 0})]}),{wide:!0})),...e.lists.map(t=>U(`review:${n.id}:list:${t.def.id}`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)($,{children:t.def.title}),t.def.check?(0,V.jsx)(C,{runId:e.id,list:t}):(0,V.jsx)(ie,{runId:e.id,list:t,editable:!0})]}),{wide:!0}))];t.error&&d.push(U(`review-error`,t.error,{tone:`error`}));let f=n.regenerate&&o.length>0;return d.push(X(`review:${n.id}:replies`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(Z,{primary:!0,busy:t.busy,onClick:()=>void t.accept(n.id),children:[(0,V.jsx)(c,{className:`size-4`}),` `,w(`run.accept`)]}),f&&o.length>1?o.map(({step:e})=>(0,V.jsx)(Z,{on:s===e.id,onClick:()=>l(e.id),children:e.title},e.id)):null]}))),(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(J,{avatar:e.wizard.avatar,lines:d}),f?(0,V.jsx)(K,{children:(0,V.jsx)(Le,{multiline:!0,inputRef:u,busy:t.busy,placeholder:o.length>1&&!s?w(`run.feedbackPick`):w(`run.feedbackPlaceholder`),disabled:!s,onSend:e=>{let r=e.trim();return!r||!s?!1:(a(r),t.regenerate(n.id,s,r),!0)}})}):(0,V.jsx)(Q,{})]})}function it({view:e,run:t,step:n,before:r,onRestart:i}){let a=e.shown.filter(e=>e.output),o=`/api/runs/${e.id}`,s=[...r,U(`result:${n.id}`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`font-display font-semibold text-[1.0625rem]`,children:n.title}),n.message?(0,V.jsx)(`span`,{className:`mt-0.5 block text-ink-2`,children:n.message}):null]}),{anchor:!0}),...a.map(({step:e,output:t,formats:n,label:r})=>U(`result:${e.id}`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)($,{end:(0,V.jsx)(P,{base:o,stepId:e.id,formats:n,title:r??e.title}),children:r??e.title}),(0,V.jsx)(I,{base:o,step:e,output:t}),t?.assets?.some(e=>e.ai)?(0,V.jsx)(`p`,{className:`mt-3 text-[0.75rem] text-ink-3 leading-relaxed`,children:w(`ai.publish`)}):null]}),{wide:!0})),...e.lists.map(t=>U(`result:list:${t.def.id}`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)($,{end:(0,V.jsx)(ne,{runId:e.id,list:t}),children:t.label??t.def.title}),(0,V.jsx)(ie,{runId:e.id,list:t,editable:!0})]}),{wide:!0}))];return s.push(X(`result:replies`,(0,V.jsxs)(V.Fragment,{children:[a.length?(0,V.jsx)(fe,{runId:e.id,title:`${n.title} · ${e.wizard.title}`,initial:e.shareUrl?{url:e.shareUrl,expiresAt:e.expiresAt}:null}):null,i?(0,V.jsxs)(Z,{onClick:i,children:[(0,V.jsx)(R,{className:`size-4`}),` `,w(`run.again`)]}):null,e.canBack?(0,V.jsx)(Z,{onClick:()=>void t.back(),disabled:t.busy,children:w(`run.back`)}):null,e.keeps?(0,V.jsx)(`span`,{className:`ml-1`,children:(0,V.jsx)(E,{runId:e.id})}):null]}))),(0,V.jsx)(J,{avatar:e.wizard.avatar,lines:s})}function at({runId:e,onRestart:t,onView:n,header:r,footer:i,talk:a=!1,call:o=!1}){let s=me(e),{view:c}=s,[u,d]=(0,B.useState)(null),f=Ne(e,c,s,u);(0,B.useEffect)(()=>{n?.(c)},[c,n]);let[p,m]=le(),g=(0,B.useMemo)(()=>({runId:e,lang:c?.lang??A,readAloud:p,setReadAloud:m,voice:c?.talk?f:null,talk:a,call:!!o,bindPage:d}),[e,c?.lang,c?.talk,p,m,f,a,o]);h(c?.status===`running`&&!c.ask),k(c);let[_,v]=(0,B.useState)({}),[b,x]=(0,B.useState)(null);(0,B.useEffect)(()=>{c&&c.status!==`running`&&x(null)},[c]);let S;if(s.notFound)S=(0,V.jsx)(`div`,{className:`py-24 text-center text-ink-3`,children:w(`run.notFound`)});else if(!c)S=(0,V.jsx)(`div`,{className:`flex justify-center py-24 text-ink-4`,children:(0,V.jsx)(L,{})});else{let e=c.step,n=c.status===`waiting_input`,r=qe(c,c.canBack&&n&&!s.busy?()=>void s.back():void 0);if(c.status===`running`&&c.ask)S=(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(J,{avatar:c.wizard.avatar,lines:[...r,U(`ask:${c.ask.id}`,(0,V.jsx)(l,{runId:c.id,ask:c.ask}),{wide:!0})]}),(0,V.jsx)(Q,{})]});else if(c.status===`running`)S=(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(J,{avatar:c.wizard.avatar,lines:[...r,...b?[W(`note`,b)]:[],U(`working:${e?.id}`,(0,V.jsx)(Qe,{view:c}),{wide:c.events.some(t=>t.stepId===e?.id&&et(t))?`most`:void 0})]}),(0,V.jsx)(Q,{placeholder:w(`run.working`)})]});else if(c.status===`failed`)S=(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(J,{avatar:c.wizard.avatar,lines:[...r,U(`failed`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsx)(`span`,{className:`font-medium`,children:w(`run.failed`)}),c.error?(0,V.jsx)(`span`,{className:`mt-0.5 block`,children:(0,V.jsx)(y,{text:c.error})}):null]}),{tone:`error`}),X(`failed:replies`,(0,V.jsxs)(V.Fragment,{children:[(0,V.jsxs)(Z,{primary:!0,busy:s.busy,onClick:()=>void s.retry(),children:[(0,V.jsx)(R,{className:`size-4`}),` `,w(`run.retry`)]}),c.canBack?(0,V.jsx)(Z,{onClick:()=>void s.back(),disabled:s.busy,children:w(`run.back`)}):null]}))]}),(0,V.jsx)(Q,{})]});else if(c.status===`cancelled`)S=(0,V.jsx)(J,{avatar:c.wizard.avatar,lines:[...r,U(`cancelled`,w(`run.cancelled`)),...t?[X(`cancelled:replies`,(0,V.jsxs)(Z,{primary:!0,onClick:t,children:[(0,V.jsx)(R,{className:`size-4`}),` `,w(`run.again`)]}))]:[]]});else if(e?.type===`page`)S=(0,V.jsx)(Ye,{view:c,run:s,step:e,before:r},e.id);else if(e?.type===`review`){let t=c.shown.map(e=>e.output?.at??``).join(`|`);S=(0,V.jsx)(rt,{view:c,run:s,step:e,before:r,asked:_[e.id]??[],onNote:t=>{x(t),v(n=>({...n,[e.id]:[...n[e.id]??[],t]}))}},`${e.id}:${t}`)}else S=e?.type===`result`?(0,V.jsx)(it,{view:c,run:s,step:e,before:r,onRestart:t}):(0,V.jsx)(J,{avatar:c.wizard.avatar,lines:r})}return o?(0,V.jsx)(G.Provider,{value:g,children:(0,V.jsxs)(`div`,{className:`flex h-full min-h-0 flex-col lg:flex-row`,children:[(0,V.jsx)(De,{voice:f,view:c,video:o===`video`,className:`h-[46dvh] shrink-0 lg:h-auto lg:min-h-0 lg:flex-1`}),(0,V.jsx)(`aside`,{className:`flex min-h-0 flex-1 flex-col border-border-soft border-t lg:w-[420px] lg:flex-none lg:border-t-0 lg:border-l`,children:(0,V.jsx)(q,{footer:i,children:S})})]})}):(0,V.jsx)(G.Provider,{value:g,children:(0,V.jsx)(q,{header:r,footer:i,children:S})})}export{J as a,Z as i,q as n,X as o,Q as r,Fe as s,at as t};
|