skydive-cli 0.1.0-beta.49 → 0.1.0-beta.58
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/js/bin.mjs
CHANGED
|
@@ -13,7 +13,7 @@ import fs from "node:fs";
|
|
|
13
13
|
import zlib from "node:zlib";
|
|
14
14
|
|
|
15
15
|
//#region package.json
|
|
16
|
-
var version$1 = "0.1.0-beta.
|
|
16
|
+
var version$1 = "0.1.0-beta.58";
|
|
17
17
|
|
|
18
18
|
//#endregion
|
|
19
19
|
//#region src/types.ts
|
|
@@ -447,7 +447,7 @@ async function getActiveWorkspaceId({ appUrl, sessionToken }) {
|
|
|
447
447
|
}
|
|
448
448
|
async function setActiveWorkspace({ appUrl, sessionToken, organizationId }) {
|
|
449
449
|
try {
|
|
450
|
-
const res = await fetch(`${appUrl}/api/
|
|
450
|
+
const res = await fetch(`${appUrl}/api/v1/workspaces/switch`, {
|
|
451
451
|
method: "POST",
|
|
452
452
|
headers: {
|
|
453
453
|
...authHeaders(sessionToken),
|
|
@@ -455,7 +455,7 @@ async function setActiveWorkspace({ appUrl, sessionToken, organizationId }) {
|
|
|
455
455
|
},
|
|
456
456
|
body: JSON.stringify({ organizationId })
|
|
457
457
|
});
|
|
458
|
-
if (!res.ok) return err({ message: `failed to
|
|
458
|
+
if (!res.ok) return err({ message: `failed to switch workspace (${res.status})` });
|
|
459
459
|
return ok(void 0);
|
|
460
460
|
} catch (e) {
|
|
461
461
|
return err({ message: e instanceof Error ? e.message : String(e) });
|
|
@@ -2046,7 +2046,7 @@ const chatCommand = {
|
|
|
2046
2046
|
printError(`Unknown theme "${themeId}". Valid themes: ${themes.map((t) => t.id).join(", ")}`);
|
|
2047
2047
|
process.exit(1);
|
|
2048
2048
|
}
|
|
2049
|
-
const { runChat } = await import("./boot-
|
|
2049
|
+
const { runChat } = await import("./boot-BUk9yMvA.mjs");
|
|
2050
2050
|
await runChat({
|
|
2051
2051
|
appUrl,
|
|
2052
2052
|
sessionToken: session.value.sessionToken,
|
|
@@ -2064,7 +2064,7 @@ async function runPrintMode({ argv, appUrl }) {
|
|
|
2064
2064
|
printError(`${session.error.message} For non-interactive use, run \`skydive auth login --web\` first, or set SKYDIVE_SESSION_TOKEN.`);
|
|
2065
2065
|
process.exit(1);
|
|
2066
2066
|
}
|
|
2067
|
-
const { runPrint, readStdin } = await import("./print-
|
|
2067
|
+
const { runPrint, readStdin } = await import("./print-BtMdNPJR.mjs").then((n) => n.t);
|
|
2068
2068
|
let prompt = (argv.print ?? "").trim();
|
|
2069
2069
|
if (!prompt) {
|
|
2070
2070
|
if (process.stdin.isTTY) {
|
|
@@ -2137,7 +2137,7 @@ async function runList(argv, { hint }) {
|
|
|
2137
2137
|
w.name,
|
|
2138
2138
|
w.slug
|
|
2139
2139
|
]));
|
|
2140
|
-
if (hint && !argv.quiet) console.log("\nRun `skydive workspace switch
|
|
2140
|
+
if (hint && !argv.quiet) console.log("\nRun `skydive workspace switch` to pick a workspace, or pass its slug directly.");
|
|
2141
2141
|
}
|
|
2142
2142
|
const listCommand = {
|
|
2143
2143
|
command: "list",
|
|
@@ -2145,15 +2145,28 @@ const listCommand = {
|
|
|
2145
2145
|
handler: (argv) => runList(argv, { hint: false })
|
|
2146
2146
|
};
|
|
2147
2147
|
const switchCommand = {
|
|
2148
|
-
command: "switch
|
|
2148
|
+
command: "switch [workspace]",
|
|
2149
2149
|
describe: "Switch which workspace `skydive chat` uses",
|
|
2150
2150
|
builder: (y) => y.positional("workspace", {
|
|
2151
2151
|
type: "string",
|
|
2152
|
-
demandOption:
|
|
2152
|
+
demandOption: false,
|
|
2153
2153
|
describe: "Workspace slug, name, or ID"
|
|
2154
2154
|
}),
|
|
2155
2155
|
handler: async (argv) => {
|
|
2156
2156
|
const session = requireSession(argv);
|
|
2157
|
+
if (!argv.workspace) {
|
|
2158
|
+
if (argv.json || argv.quiet || isNonInteractive()) {
|
|
2159
|
+
printError("Interactive workspace switching needs a terminal. Pass a workspace slug, name, or ID.");
|
|
2160
|
+
process.exit(1);
|
|
2161
|
+
}
|
|
2162
|
+
if (await ensureBunAndReexec((message) => process.stderr.write(`${message}\n`)) === "unavailable") {
|
|
2163
|
+
printError("The workspace picker needs the Bun runtime and it could not be set up automatically. Pass a workspace slug instead, or install Bun and retry.");
|
|
2164
|
+
process.exit(1);
|
|
2165
|
+
}
|
|
2166
|
+
const { runWorkspacePicker } = await import("./boot-BUk9yMvA.mjs");
|
|
2167
|
+
await runWorkspacePicker(session);
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2157
2170
|
const workspaces = await listWorkspaces(session);
|
|
2158
2171
|
if (workspaces.isErr()) {
|
|
2159
2172
|
printError(workspaces.error.message);
|
|
@@ -2277,4 +2290,4 @@ function resolveArgv(args, tty = {
|
|
|
2277
2290
|
createCli(resolveArgv(hideBin(process.argv))).parse();
|
|
2278
2291
|
|
|
2279
2292
|
//#endregion
|
|
2280
|
-
export {
|
|
2293
|
+
export { getSavedTheme as _, noColorRequested as a, themeMode as c, themesForMode as d, getActiveWorkspaceId as f, DEFAULT_APP_URL as g, DEFAULT_API_URL as h, monoTheme as i, themeModeFromColorFgBg as l, setActiveWorkspace as m, applyTheme as n, theme as o, listWorkspaces as p, findTheme as r, themeForMode as s, DEFAULT_THEME_ID as t, themeVersion as u, resolveWebUrl as v, saveTheme as y };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { i as createRestClient, n as resolveAgent, r as HttpError } from "./print-
|
|
3
|
-
import { _ as
|
|
2
|
+
import { i as createRestClient, n as resolveAgent, r as HttpError } from "./print-BtMdNPJR.mjs";
|
|
3
|
+
import { _ as getSavedTheme, a as noColorRequested, c as themeMode, d as themesForMode, f as getActiveWorkspaceId, g as DEFAULT_APP_URL, h as DEFAULT_API_URL, i as monoTheme, l as themeModeFromColorFgBg, m as setActiveWorkspace, n as applyTheme, o as theme, p as listWorkspaces, r as findTheme, s as themeForMode, t as DEFAULT_THEME_ID, u as themeVersion, v as resolveWebUrl, y as saveTheme } from "./bin.mjs";
|
|
4
4
|
import path, { basename, isAbsolute, join, win32 } from "node:path";
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import open from "open";
|
|
@@ -1226,6 +1226,7 @@ function screenLabel(screen, chatTitle) {
|
|
|
1226
1226
|
case "error": return "";
|
|
1227
1227
|
case "agent-picker": return "pick an agent";
|
|
1228
1228
|
case "agent-create": return "create an agent";
|
|
1229
|
+
case "workspace-picker": return "switch workspace";
|
|
1229
1230
|
case "conversation-picker": return `${screen.agent.name} · pick a conversation`;
|
|
1230
1231
|
case "chat": {
|
|
1231
1232
|
const c = screen.conversation;
|
|
@@ -1258,7 +1259,8 @@ function AgentPickerScreen() {
|
|
|
1258
1259
|
const [cache, setCache] = useState({});
|
|
1259
1260
|
const [state, setState] = useState({ kind: "loading" });
|
|
1260
1261
|
useKeyboard((key) => {
|
|
1261
|
-
if (key.name === "
|
|
1262
|
+
if (key.name === "w" && key.ctrl) goTo({ kind: "workspace-picker" });
|
|
1263
|
+
else if (key.name === "n" && key.ctrl) goTo({ kind: "agent-create" });
|
|
1262
1264
|
else if (key.name === "tab") setScope((s) => s === "mine" ? "org" : "mine");
|
|
1263
1265
|
});
|
|
1264
1266
|
useEffect(() => {
|
|
@@ -1324,7 +1326,7 @@ function AgentPickerScreen() {
|
|
|
1324
1326
|
});
|
|
1325
1327
|
if (state.agents.length === 0) return /* @__PURE__ */ jsx("text", {
|
|
1326
1328
|
fg: theme.muted,
|
|
1327
|
-
children: scope === "mine" ? "no agents of yours yet. press tab to see all agents, or ctrl+n to create one." : "no agents in this workspace. press ctrl+n to create one."
|
|
1329
|
+
children: scope === "mine" ? "no agents of yours yet. press tab to see all agents, ctrl+w to switch workspace, or ctrl+n to create one." : "no agents in this workspace. press ctrl+w to switch workspace, or ctrl+n to create one."
|
|
1328
1330
|
});
|
|
1329
1331
|
return /* @__PURE__ */ jsx(FilterableAgentList, {
|
|
1330
1332
|
agents: state.agents,
|
|
@@ -1391,7 +1393,7 @@ function FilterableAgentList({ agents, scope, onPick }) {
|
|
|
1391
1393
|
" ",
|
|
1392
1394
|
"· tab ",
|
|
1393
1395
|
scope === "mine" ? "all" : "mine",
|
|
1394
|
-
" · ↑/↓ move · ↵ open · ctrl+n new"
|
|
1396
|
+
" · ↑/↓ move · ↵ open · ctrl+w workspace · ctrl+n new"
|
|
1395
1397
|
]
|
|
1396
1398
|
}),
|
|
1397
1399
|
/* @__PURE__ */ jsx("box", {
|
|
@@ -1568,6 +1570,146 @@ function AgentCreateScreen() {
|
|
|
1568
1570
|
});
|
|
1569
1571
|
}
|
|
1570
1572
|
|
|
1573
|
+
//#endregion
|
|
1574
|
+
//#region src/chat/tui/screens/workspace-picker.tsx
|
|
1575
|
+
function WorkspacePicker({ appUrl, sessionToken, onSelect, onCancel }) {
|
|
1576
|
+
const { height } = useTerminalDimensions();
|
|
1577
|
+
const [state, setState] = useState({ kind: "loading" });
|
|
1578
|
+
const [highlight, setHighlight] = useState(0);
|
|
1579
|
+
const [switching, setSwitching] = useState(false);
|
|
1580
|
+
useEffect(() => {
|
|
1581
|
+
let cancelled = false;
|
|
1582
|
+
(async () => {
|
|
1583
|
+
const [workspaces, activeId] = await Promise.all([listWorkspaces({
|
|
1584
|
+
appUrl,
|
|
1585
|
+
sessionToken
|
|
1586
|
+
}), getActiveWorkspaceId({
|
|
1587
|
+
appUrl,
|
|
1588
|
+
sessionToken
|
|
1589
|
+
})]);
|
|
1590
|
+
if (cancelled) return;
|
|
1591
|
+
if (workspaces.isErr()) {
|
|
1592
|
+
setState({
|
|
1593
|
+
kind: "error",
|
|
1594
|
+
message: workspaces.error.message
|
|
1595
|
+
});
|
|
1596
|
+
return;
|
|
1597
|
+
}
|
|
1598
|
+
if (activeId.isErr()) {
|
|
1599
|
+
setState({
|
|
1600
|
+
kind: "error",
|
|
1601
|
+
message: activeId.error.message
|
|
1602
|
+
});
|
|
1603
|
+
return;
|
|
1604
|
+
}
|
|
1605
|
+
setHighlight(Math.max(0, workspaces.value.findIndex((workspace) => workspace.id === activeId.value)));
|
|
1606
|
+
setState({
|
|
1607
|
+
kind: "ready",
|
|
1608
|
+
workspaces: workspaces.value,
|
|
1609
|
+
activeId: activeId.value
|
|
1610
|
+
});
|
|
1611
|
+
})();
|
|
1612
|
+
return () => {
|
|
1613
|
+
cancelled = true;
|
|
1614
|
+
};
|
|
1615
|
+
}, [appUrl, sessionToken]);
|
|
1616
|
+
const rows = state.kind === "ready" ? state.workspaces : [];
|
|
1617
|
+
const clamped = Math.min(highlight, Math.max(0, rows.length - 1));
|
|
1618
|
+
useKeyboard((key) => {
|
|
1619
|
+
if (switching) return;
|
|
1620
|
+
if (key.name === "escape" || key.name === "c" && key.ctrl) onCancel();
|
|
1621
|
+
else if (key.name === "up") setHighlight(Math.max(0, clamped - 1));
|
|
1622
|
+
else if (key.name === "down") setHighlight(Math.min(rows.length - 1, clamped + 1));
|
|
1623
|
+
else if (key.name === "return") {
|
|
1624
|
+
const workspace = rows[clamped];
|
|
1625
|
+
if (!workspace) return;
|
|
1626
|
+
setSwitching(true);
|
|
1627
|
+
(async () => {
|
|
1628
|
+
const result = await setActiveWorkspace({
|
|
1629
|
+
appUrl,
|
|
1630
|
+
sessionToken,
|
|
1631
|
+
organizationId: workspace.id
|
|
1632
|
+
});
|
|
1633
|
+
if (result.isErr()) {
|
|
1634
|
+
setState({
|
|
1635
|
+
kind: "error",
|
|
1636
|
+
message: result.error.message
|
|
1637
|
+
});
|
|
1638
|
+
setSwitching(false);
|
|
1639
|
+
return;
|
|
1640
|
+
}
|
|
1641
|
+
onSelect(workspace);
|
|
1642
|
+
})();
|
|
1643
|
+
}
|
|
1644
|
+
});
|
|
1645
|
+
if (state.kind === "loading") return /* @__PURE__ */ jsx("text", {
|
|
1646
|
+
fg: theme.muted,
|
|
1647
|
+
children: "loading workspaces…"
|
|
1648
|
+
});
|
|
1649
|
+
if (state.kind === "error") return /* @__PURE__ */ jsxs("box", {
|
|
1650
|
+
style: { flexDirection: "column" },
|
|
1651
|
+
children: [/* @__PURE__ */ jsxs("text", {
|
|
1652
|
+
fg: theme.error,
|
|
1653
|
+
children: ["error: ", state.message]
|
|
1654
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
1655
|
+
fg: theme.dim,
|
|
1656
|
+
children: "esc cancel"
|
|
1657
|
+
})]
|
|
1658
|
+
});
|
|
1659
|
+
if (rows.length === 0) return /* @__PURE__ */ jsxs("box", {
|
|
1660
|
+
style: { flexDirection: "column" },
|
|
1661
|
+
children: [/* @__PURE__ */ jsx("text", {
|
|
1662
|
+
fg: theme.muted,
|
|
1663
|
+
children: "no workspaces available"
|
|
1664
|
+
}), /* @__PURE__ */ jsx("text", {
|
|
1665
|
+
fg: theme.dim,
|
|
1666
|
+
children: "esc cancel"
|
|
1667
|
+
})]
|
|
1668
|
+
});
|
|
1669
|
+
const visibleRows = Math.max(3, height - 6);
|
|
1670
|
+
const start = windowStart(clamped, rows.length, visibleRows);
|
|
1671
|
+
const windowed = rows.slice(start, start + visibleRows);
|
|
1672
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
1673
|
+
style: {
|
|
1674
|
+
flexDirection: "column",
|
|
1675
|
+
flexGrow: 1
|
|
1676
|
+
},
|
|
1677
|
+
children: [
|
|
1678
|
+
/* @__PURE__ */ jsx("text", {
|
|
1679
|
+
fg: theme.accent,
|
|
1680
|
+
children: "switch workspace"
|
|
1681
|
+
}),
|
|
1682
|
+
/* @__PURE__ */ jsx("box", {
|
|
1683
|
+
style: {
|
|
1684
|
+
flexDirection: "column",
|
|
1685
|
+
flexGrow: 1,
|
|
1686
|
+
marginTop: 1
|
|
1687
|
+
},
|
|
1688
|
+
children: windowed.map((workspace, index) => {
|
|
1689
|
+
const selected = start + index === clamped;
|
|
1690
|
+
const active = workspace.id === state.activeId;
|
|
1691
|
+
return /* @__PURE__ */ jsxs("text", {
|
|
1692
|
+
fg: selected ? theme.accent : theme.fg,
|
|
1693
|
+
children: [
|
|
1694
|
+
selected ? "› " : " ",
|
|
1695
|
+
active ? "● " : " ",
|
|
1696
|
+
workspace.name,
|
|
1697
|
+
/* @__PURE__ */ jsxs("span", {
|
|
1698
|
+
fg: theme.dim,
|
|
1699
|
+
children: [" ", workspace.slug]
|
|
1700
|
+
})
|
|
1701
|
+
]
|
|
1702
|
+
}, workspace.id);
|
|
1703
|
+
})
|
|
1704
|
+
}),
|
|
1705
|
+
/* @__PURE__ */ jsx("text", {
|
|
1706
|
+
fg: theme.dim,
|
|
1707
|
+
children: switching ? "switching…" : "↑/↓ move · ↵ select · esc cancel"
|
|
1708
|
+
})
|
|
1709
|
+
]
|
|
1710
|
+
});
|
|
1711
|
+
}
|
|
1712
|
+
|
|
1571
1713
|
//#endregion
|
|
1572
1714
|
//#region src/chat/tui/screens/conversation-picker.tsx
|
|
1573
1715
|
function ConversationPickerScreen({ agent }) {
|
|
@@ -2999,6 +3141,17 @@ function RenderItem({ item }) {
|
|
|
2999
3141
|
barColor: null,
|
|
3000
3142
|
children: /* @__PURE__ */ jsx(CardItem, { item })
|
|
3001
3143
|
});
|
|
3144
|
+
case "recap": return /* @__PURE__ */ jsx(Row, {
|
|
3145
|
+
barColor: null,
|
|
3146
|
+
children: /* @__PURE__ */ jsxs("text", {
|
|
3147
|
+
fg: theme.dim,
|
|
3148
|
+
children: [
|
|
3149
|
+
/* @__PURE__ */ jsx("b", { children: "recap" }),
|
|
3150
|
+
" ",
|
|
3151
|
+
/* @__PURE__ */ jsx("i", { children: item.text })
|
|
3152
|
+
]
|
|
3153
|
+
})
|
|
3154
|
+
});
|
|
3002
3155
|
}
|
|
3003
3156
|
}
|
|
3004
3157
|
function StreamingAssistantText({ text }) {
|
|
@@ -4786,9 +4939,15 @@ function ChatScreen({ agent, conversation }) {
|
|
|
4786
4939
|
let cancelled = false;
|
|
4787
4940
|
(async () => {
|
|
4788
4941
|
try {
|
|
4789
|
-
const messages = await rest.listMessages({ conversationId: initialConversationId });
|
|
4942
|
+
const [messages, recapText] = await Promise.all([rest.listMessages({ conversationId: initialConversationId }), rest.getRecap({ conversationId: initialConversationId }).catch(() => null)]);
|
|
4790
4943
|
if (cancelled) return;
|
|
4791
|
-
|
|
4944
|
+
const loaded = uiMessagesToItems(messages);
|
|
4945
|
+
if (recapText && loaded.length > 0) loaded.push({
|
|
4946
|
+
kind: "recap",
|
|
4947
|
+
id: `recap-${initialConversationId}`,
|
|
4948
|
+
text: recapText
|
|
4949
|
+
});
|
|
4950
|
+
setItems(loaded);
|
|
4792
4951
|
} catch (err) {
|
|
4793
4952
|
if (cancelled) return;
|
|
4794
4953
|
setItems((prev) => [...prev, {
|
|
@@ -5897,6 +6056,15 @@ function App({ appUrl, sessionToken, shareMachine, promptHistoryPath, notificati
|
|
|
5897
6056
|
screen.kind === "error" && /* @__PURE__ */ jsx(ErrorScreen, { message: screen.message }),
|
|
5898
6057
|
screen.kind === "agent-picker" && rest && /* @__PURE__ */ jsx(AgentPickerScreen, {}),
|
|
5899
6058
|
screen.kind === "agent-create" && rest && /* @__PURE__ */ jsx(AgentCreateScreen, {}),
|
|
6059
|
+
screen.kind === "workspace-picker" && /* @__PURE__ */ jsx(WorkspacePicker, {
|
|
6060
|
+
appUrl,
|
|
6061
|
+
sessionToken,
|
|
6062
|
+
onCancel: () => goTo({ kind: "agent-picker" }),
|
|
6063
|
+
onSelect: (workspace) => {
|
|
6064
|
+
setWorkspaceName(workspace.name);
|
|
6065
|
+
goTo({ kind: "agent-picker" });
|
|
6066
|
+
}
|
|
6067
|
+
}),
|
|
5900
6068
|
screen.kind === "conversation-picker" && rest && /* @__PURE__ */ jsx(ConversationPickerScreen, { agent: screen.agent }),
|
|
5901
6069
|
screen.kind === "chat" && rest && /* @__PURE__ */ jsx(ChatScreen, {
|
|
5902
6070
|
agent: screen.agent,
|
|
@@ -6185,6 +6353,27 @@ async function runChat({ appUrl, sessionToken, shareMachine, promptHistoryPath,
|
|
|
6185
6353
|
agentSelector: agentSelector ?? null
|
|
6186
6354
|
}));
|
|
6187
6355
|
}
|
|
6356
|
+
/** Open the same workspace picker used by the initial agent screen. */
|
|
6357
|
+
async function runWorkspacePicker({ appUrl, sessionToken }) {
|
|
6358
|
+
const renderer = await createCliRenderer({ exitOnCtrlC: false });
|
|
6359
|
+
const detected = await renderer.waitForThemeMode() ?? themeModeFromColorFgBg() ?? "dark";
|
|
6360
|
+
useStore.getState().setThemeMode(detected);
|
|
6361
|
+
const close = () => renderer.destroy();
|
|
6362
|
+
createRoot(renderer).render(/* @__PURE__ */ jsx("box", {
|
|
6363
|
+
style: {
|
|
6364
|
+
flexDirection: "column",
|
|
6365
|
+
flexGrow: 1,
|
|
6366
|
+
padding: 1,
|
|
6367
|
+
backgroundColor: theme.background
|
|
6368
|
+
},
|
|
6369
|
+
children: /* @__PURE__ */ jsx(WorkspacePicker, {
|
|
6370
|
+
appUrl,
|
|
6371
|
+
sessionToken,
|
|
6372
|
+
onSelect: close,
|
|
6373
|
+
onCancel: close
|
|
6374
|
+
})
|
|
6375
|
+
}));
|
|
6376
|
+
}
|
|
6188
6377
|
|
|
6189
6378
|
//#endregion
|
|
6190
|
-
export { runChat };
|
|
6379
|
+
export { runChat, runWorkspacePicker };
|
|
@@ -107,6 +107,10 @@ function createRestClient({ appUrl, sessionToken }) {
|
|
|
107
107
|
const { messages } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/messages`, listMessagesResponseSchema);
|
|
108
108
|
return messages;
|
|
109
109
|
},
|
|
110
|
+
getRecap: async ({ conversationId }) => {
|
|
111
|
+
const { recap } = await get(`/api/v1/conversations/${encodeURIComponent(conversationId)}/recap`, recapResponseSchema);
|
|
112
|
+
return recap?.text ?? null;
|
|
113
|
+
},
|
|
110
114
|
uploadAttachment: async ({ agentId, fileName, mediaType, data }) => {
|
|
111
115
|
const size = data.byteLength;
|
|
112
116
|
const presign = await post("/api/v1/attachments/presign", {
|
|
@@ -311,6 +315,7 @@ const uiMessageSchema = z.object({
|
|
|
311
315
|
role: z.string(),
|
|
312
316
|
parts: z.array(uiMessagePartSchema)
|
|
313
317
|
});
|
|
318
|
+
const recapResponseSchema = z.object({ recap: z.object({ text: z.string() }).nullable() });
|
|
314
319
|
const listMessagesResponseSchema = z.object({ messages: z.array(uiMessageSchema) });
|
|
315
320
|
const sendResultSchema = z.object({
|
|
316
321
|
runId: z.string(),
|