feat: add durable AgentOS slice execution

This commit is contained in:
-Puter
2026-07-28 14:50:45 +05:30
parent 05a3baaac3
commit 359d9e2285
29 changed files with 2000 additions and 150 deletions

View File

@@ -17,6 +17,7 @@ import {
RotateCcw,
Send,
Sparkles,
Settings,
X,
} from "lucide-react";
import { useMemo, useRef, useState } from "react";
@@ -258,19 +259,61 @@ const WorkCard = ({ onSourceSelect, work, slice }: WorkCardProps) => {
Build
</p>
{latestRun ? (
<p className="mt-1 leading-5 text-[#626057]">
Run {latestRun.status}:{" "}
{latestRun.terminalSummary ??
latestRun.terminalClassification ??
"activity is still arriving"}
</p>
<div className="mt-1 space-y-2 text-[#626057]">
<p className="leading-5">
{latestRun.executionKind === "real"
? "AgentOS"
: "Simulation"}{" "}
run {latestRun.status}:{" "}
{latestRun.terminalSummary ??
latestRun.terminalClassification ??
"activity is still arriving"}
</p>
{latestRun.attemptEvents?.slice(-5).map((item) => (
<p
className="border-l-2 border-[#b8c760] pl-2"
key={item._id}
>
{item.message}
</p>
))}
{latestRun.baseRevision ? (
<p className="font-mono text-[10px] text-[#747168]">
{latestRun.baseRevision.slice(0, 8)} {" "}
{latestRun.candidateRevision?.slice(0, 8) ?? "working"}
</p>
) : null}
{latestRun.artifacts?.map((artifact) => (
<a
className="block font-medium underline"
href={artifact.uri}
key={artifact._id}
rel="noreferrer"
target="_blank"
>
{artifact.title}
</a>
))}
</div>
) : (
<p className="mt-1 text-[#747168]">No simulation Run yet.</p>
<p className="mt-1 text-[#747168]">No implementation Run yet.</p>
)}
<div className="mt-2 flex flex-wrap gap-2">
{work.status === "ready" ? (
<Button
size="sm"
disabled={!slice.projectGitConnection}
onClick={() =>
void slice.startExecution(work._id, design?.slices?.[0]?.id)
}
>
<Play className="size-3.5" /> Run
</Button>
) : null}
{work.status === "ready" ? (
<Button
size="sm"
variant="outline"
onClick={() =>
void slice.startSimulation(
work._id,
@@ -286,7 +329,11 @@ const WorkCard = ({ onSourceSelect, work, slice }: WorkCardProps) => {
<Button
size="sm"
variant="outline"
onClick={() => void slice.cancelSimulation(latestRun._id)}
onClick={() =>
void (latestRun.executionKind === "real"
? slice.cancelExecution(latestRun._id)
: slice.cancelSimulation(latestRun._id))
}
>
<X className="size-3.5" /> Cancel
</Button>
@@ -388,6 +435,10 @@ export const SliceOnePage = () => {
const attachments = useChatImages();
const imageInput = useRef<HTMLInputElement>(null);
const [drawerOpen, setDrawerOpen] = useState(false);
const [settingsOpen, setSettingsOpen] = useState(false);
const [giteaUrl, setGiteaUrl] = useState("https://git.openputer.com");
const [giteaUsername, setGiteaUsername] = useState("");
const [giteaToken, setGiteaToken] = useState("");
const [highlightedMessageId, setHighlightedMessageId] = useState<string>();
const highlightTimer = useRef<ReturnType<typeof setTimeout> | null>(null);
const works = slice.works ?? EMPTY_WORKS;
@@ -450,7 +501,7 @@ export const SliceOnePage = () => {
style={viewportStyle}
>
<section className="flex min-w-0 flex-1 flex-col">
<header className="flex h-14 shrink-0 items-center border-b border-[#d7d3c7] bg-[#faf9f4] px-4">
<header className="relative flex h-14 shrink-0 items-center border-b border-[#d7d3c7] bg-[#faf9f4] px-4">
<div className="min-w-0 flex-1 pr-2">
<select
aria-label="Current project"
@@ -468,6 +519,15 @@ export const SliceOnePage = () => {
Conversation to proposed Work
</p>
</div>
<Button
aria-label="Project settings"
className="mr-2 size-9"
onClick={() => setSettingsOpen((open) => !open)}
size="icon"
variant="outline"
>
<Settings className="size-4" />
</Button>
<button
className="flex h-9 items-center gap-2 border border-[#c9c5b9] bg-white px-3 text-xs lg:hidden"
onClick={() => setDrawerOpen(true)}
@@ -476,6 +536,78 @@ export const SliceOnePage = () => {
<Menu className="size-4" /> Work{" "}
{slice.works === undefined ? "…" : works.length}
</button>
{settingsOpen ? (
<section className="absolute right-4 top-12 z-40 w-[min(92vw,360px)] border border-[#c9c5b9] bg-[#fffefa] p-4 shadow-xl">
<div className="flex items-center justify-between">
<h2 className="text-sm font-semibold">Project Git</h2>
<button
aria-label="Close settings"
onClick={() => setSettingsOpen(false)}
type="button"
>
<X className="size-4" />
</button>
</div>
<p className="mt-1 text-xs text-[#747168]">
{slice.projectGitConnection
? `${slice.projectGitConnection.provider} · ${slice.projectGitConnection.serverUrl}`
: "No Git credentials attached"}
</p>
<div className="mt-4 flex gap-2">
<Button
size="sm"
variant="outline"
onClick={() => void slice.authorizeGithub()}
>
Authorize GitHub
</Button>
<Button
size="sm"
onClick={() => void slice.connectLinkedGithub()}
>
Use GitHub
</Button>
</div>
<div className="mt-4 space-y-2 border-t border-[#e7e3d9] pt-4">
<input
aria-label="Gitea server URL"
className="h-9 w-full border px-2 text-xs"
onChange={(event) => setGiteaUrl(event.target.value)}
value={giteaUrl}
/>
<input
aria-label="Gitea username"
className="h-9 w-full border px-2 text-xs"
onChange={(event) => setGiteaUsername(event.target.value)}
placeholder="Username (optional)"
value={giteaUsername}
/>
<input
aria-label="Gitea access token"
className="h-9 w-full border px-2 text-xs"
onChange={(event) => setGiteaToken(event.target.value)}
placeholder="Personal access token"
type="password"
value={giteaToken}
/>
<Button
className="w-full"
disabled={!giteaToken.trim()}
size="sm"
onClick={() => {
void slice.connectGitea({
serverUrl: giteaUrl,
token: giteaToken,
username: giteaUsername || undefined,
});
setGiteaToken("");
}}
>
Connect Gitea
</Button>
</div>
</section>
) : null}
</header>
<Conversation className="min-h-0 flex-1">
<ConversationContent className="mx-auto min-h-full w-full max-w-2xl gap-4 px-4 py-5 sm:px-6">

View File

@@ -1,3 +1,4 @@
import { authClient } from "@code/auth/web";
import { api } from "@code/backend/convex/_generated/api";
import type { Id } from "@code/backend/convex/_generated/dataModel";
import { useAction, useMutation, useQuery } from "convex/react";
@@ -27,6 +28,23 @@ interface WorkRecord {
readonly designs: readonly unknown[];
readonly slices: readonly unknown[];
readonly runs: readonly {
readonly artifacts?: readonly {
_id: string;
kind: string;
metadataJson: string;
sourceRevision?: string;
title: string;
uri?: string;
}[];
readonly attemptEvents?: readonly {
_id: string;
kind: string;
message: string;
occurredAt: number;
}[];
readonly baseRevision?: string;
readonly candidateRevision?: string;
readonly executionKind?: string;
_id: Id<"workRuns">;
status: string;
terminalClassification?: string;
@@ -96,6 +114,57 @@ const retrySimulationRef = makeFunctionReference<
{ runId: Id<"workRuns"> },
unknown
>("workExecution:retrySimulatedExecution");
const startExecutionRef = makeFunctionReference<
"mutation",
{ workId: Id<"works">; sliceId?: string },
unknown
>("workExecutionWorkflow:startExecution");
const cancelExecutionRef = makeFunctionReference<
"mutation",
{ runId: Id<"workRuns"> },
unknown
>("workExecutionWorkflow:cancelExecution");
const listGitConnectionsRef = makeFunctionReference<
"query",
Record<string, never>,
readonly {
id: string;
provider: "github" | "gitea";
serverUrl: string;
username?: string;
}[]
>("gitConnectionData:list");
const projectGitConnectionRef = makeFunctionReference<
"query",
{ projectId: Id<"projects"> },
{
id: string;
provider: "github" | "gitea";
serverUrl: string;
username?: string;
} | null
>("gitConnectionData:getForProject");
const connectGiteaRef = makeFunctionReference<
"action",
{ serverUrl: string; token: string; username?: string },
{ connectionId: Id<"gitConnections"> }
>("gitConnections:connectGitea");
const connectGithubRef = makeFunctionReference<
"action",
Record<string, never>,
{ connectionId: Id<"gitConnections"> }
>("gitConnections:connectGithub");
const attachGitConnectionRef = makeFunctionReference<
"mutation",
{ connectionId: Id<"gitConnections">; projectId: Id<"projects"> },
unknown
>("gitConnectionData:attachToProject");
const authorizeGithub = () =>
authClient.signIn.social({
callbackURL: window.location.href,
provider: "github",
});
export const useSliceOne = () => {
const organization = usePersonalOrganization();
@@ -120,6 +189,14 @@ export const useSliceOne = () => {
workListRef,
activeProjectId ? { projectId: activeProjectId } : "skip"
);
const gitConnections = useQuery(
listGitConnectionsRef,
organization.organizationId ? {} : "skip"
);
const projectGitConnection = useQuery(
projectGitConnectionRef,
activeProjectId ? { projectId: activeProjectId } : "skip"
);
const requestDefinitionMutation = useMutation(requestDefinitionRef);
const saveDefinitionMutation = useMutation(saveDefinitionRef);
const approveDefinitionMutation = useMutation(approveDefinitionRef);
@@ -128,6 +205,11 @@ export const useSliceOne = () => {
const startSimulationMutation = useMutation(startSimulationRef);
const cancelSimulationMutation = useMutation(cancelSimulationRef);
const retrySimulationMutation = useMutation(retrySimulationRef);
const startExecutionMutation = useMutation(startExecutionRef);
const cancelExecutionMutation = useMutation(cancelExecutionRef);
const attachGitConnectionMutation = useMutation(attachGitConnectionRef);
const connectGiteaAction = useAction(connectGiteaRef);
const connectGithubAction = useAction(connectGithubRef);
const selectedProject = useMemo(
() =>
projects?.find(
@@ -185,15 +267,46 @@ export const useSliceOne = () => {
cancelSimulationMutation({ runId });
const retrySimulation = (runId: Id<"workRuns">) =>
retrySimulationMutation({ runId });
const startExecution = (workId: Id<"works">, sliceId?: string) =>
startExecutionMutation({ sliceId, workId });
const cancelExecution = (runId: Id<"workRuns">) =>
cancelExecutionMutation({ runId });
const attachConnection = async (connectionId: Id<"gitConnections">) => {
if (!activeProjectId) {
throw new Error("Select a project first");
}
await attachGitConnectionMutation({
connectionId,
projectId: activeProjectId,
});
};
const connectGitea = async (input: {
serverUrl: string;
token: string;
username?: string;
}) => {
const result = await connectGiteaAction(input);
await attachConnection(result.connectionId);
};
const connectLinkedGithub = async () => {
const result = await connectGithubAction({});
await attachConnection(result.connectionId);
};
return {
agent,
approveDefinition,
approveDesign,
authorizeGithub,
cancelExecution,
cancelSimulation,
connectGitea,
connectLinkedGithub,
connectRepository,
error,
gitConnections,
pending,
projectGitConnection,
projects,
repository,
requestDefinition,
@@ -203,6 +316,7 @@ export const useSliceOne = () => {
selectProject,
selectedProject,
setRepository,
startExecution,
startSimulation,
works,
} as const;

230
bun.lock
View File

@@ -64,11 +64,16 @@
"name": "@code/agents",
"version": "0.0.0",
"dependencies": {
"@agentos-software/codex-cli": "0.3.4",
"@agentos-software/git": "0.3.3",
"@code/backend": "workspace:*",
"@code/env": "workspace:*",
"@code/primitives": "workspace:*",
"@flue/runtime": "latest",
"@rivet-dev/agentos": "0.2.10",
"convex": "catalog:",
"hono": "catalog:",
"rivetkit": "2.3.9",
"valibot": "catalog:",
},
"devDependencies": {
@@ -114,6 +119,7 @@
"@code/env": "workspace:*",
"@code/primitives": "workspace:*",
"@convex-dev/better-auth": "catalog:",
"@convex-dev/workflow": "0.4.4",
"better-auth": "catalog:",
"convex": "catalog:",
"effect": "catalog:",
@@ -242,7 +248,7 @@
"@agentos-software/codex-cli": ["@agentos-software/codex-cli@0.3.4", "", {}, "sha512-SAw3EOTa90dJLgEVVoE7JJIxHwticzdD9cEM9v00gpxhxC9vdLkeBva6rgWIUB9+qD1JEYBvUCyNkIpD2kT5YQ=="],
"@agentos-software/common": ["@agentos-software/common@0.2.14", "", { "dependencies": { "@agentos-software/coreutils": "0.3.4", "@agentos-software/diffutils": "0.3.4", "@agentos-software/findutils": "0.3.4", "@agentos-software/gawk": "0.3.4", "@agentos-software/grep": "0.3.4", "@agentos-software/gzip": "0.3.4", "@agentos-software/sed": "0.3.4", "@agentos-software/tar": "0.3.5" } }, "sha512-ve/ks2MZtXFN9JK+kcFnSMGI1tqoUy36sTKWYGqApcgg/3JJwqnMs4JIKL5OXjgCtDuTvTjRySbQvEKxGkeeSQ=="],
"@agentos-software/common": ["@agentos-software/common@0.2.10", "", { "dependencies": { "@agentos-software/coreutils": "0.3.4", "@agentos-software/diffutils": "0.3.4", "@agentos-software/findutils": "0.3.4", "@agentos-software/gawk": "0.3.4", "@agentos-software/grep": "0.3.4", "@agentos-software/gzip": "0.3.4", "@agentos-software/sed": "0.3.4", "@agentos-software/tar": "0.3.4" } }, "sha512-hkqm0U2tlPraKdAIB7oi4YT7vNN6JT6fk2eRhF9r2tqeOdn2JN/Zql5gQh1+wKYIgdWu1JBj5TJlf99Px010Hg=="],
"@agentos-software/coreutils": ["@agentos-software/coreutils@0.3.4", "", {}, "sha512-tGd0gQjUjHnm+5KgOBwidwUtlkKnl9biQuD7X2sZl15VOhYqUJpnyLF33h/nF3r9WtOTclSiLj/dc2xCxmAXnw=="],
@@ -258,7 +264,7 @@
"@agentos-software/gzip": ["@agentos-software/gzip@0.3.4", "", {}, "sha512-l7Y/Vwiwsqgna68yYwdNCnUBPGBg5zdmtjEFeG3hnDDFLe/02h17q0gUIqJmDBIAy1q9GoizqcFi7zXO2xygKg=="],
"@agentos-software/manifest": ["@agentos-software/manifest@0.2.14", "", {}, "sha512-c1lGWN7/d1lku6Kl+wj6w1YoLX6wI93IyiUoE6M/Hgl1PP1YIPUqGFM5P5sZ9gG9M0qQ86T/587gECj1elZQBg=="],
"@agentos-software/manifest": ["@agentos-software/manifest@0.2.10", "", {}, "sha512-eKmqcnmrzowntVV8F65JD7ZzJHD8u6zM7YKz3o+r3qq8Z5JF/0iGpxCVnTt66/Abg/5vZqjhEIRHkik+2snrWw=="],
"@agentos-software/opencode": ["@agentos-software/opencode@0.2.7", "", { "bin": { "agentos-opencode-acp": "dist/adapter.js" } }, "sha512-lZspCiMgM0+kPAA08CEvyNy8lfBx463wObKpAwbYyaVvc0KfGvbAPS6VmnuZQWmaBmJJuRMtSo14nmb8XCD16g=="],
@@ -266,7 +272,7 @@
"@agentos-software/sed": ["@agentos-software/sed@0.3.4", "", {}, "sha512-J10nZnZmme2SvXK5WMK2unQlOVncMQVUCS20GZB579a2gNoayLJYHGvfJ9a4+42wOHgDKL1u74byWlydCkEyOQ=="],
"@agentos-software/tar": ["@agentos-software/tar@0.3.5", "", {}, "sha512-hSf6PY4q1luIomFSDgVHxVDDIPdAVZxdgwrQFEYH4aIE6TXX9qatVmzR36uYLWpnFGAZTR6srREGoTnmOGV4Lg=="],
"@agentos-software/tar": ["@agentos-software/tar@0.3.4", "", {}, "sha512-/SSqfgS5xOufvulsz5kVDTCFxpDy+5s7Og1iJe9krjU7Jvtgnp9TpPaJnSr721h6uY6tsWHcs3u8E457EwSkNw=="],
"@ai-sdk/gateway": ["@ai-sdk/gateway@4.0.28", "", { "dependencies": { "@ai-sdk/provider": "4.0.3", "@ai-sdk/provider-utils": "5.0.12", "@vercel/oidc": "3.2.0" }, "peerDependencies": { "zod": "^3.25.76 || ^4.1.8" } }, "sha512-ee9TsNO3mkgHDWmTmJ8Fvltr6PFh52zhrV2+FaKJY3F3iu7kWZi5tCRJCR1HVhhlpj6lHniUb28nLQdPHkA/1Q=="],
@@ -566,6 +572,10 @@
"@convex-dev/better-auth": ["@convex-dev/better-auth@0.12.5", "", { "dependencies": { "@better-fetch/fetch": "^1.1.18", "common-tags": "^1.8.2", "convex-helpers": "^0.1.95", "jose": "^6.1.0", "remeda": "^2.32.0", "semver": "^7.7.3", "type-fest": "^5.0.0", "zod": "^4.0.0" }, "peerDependencies": { "better-auth": ">=1.6.11 <1.7.0", "convex": "^1.25.0", "react": "^18.3.1 || ^19.0.0" } }, "sha512-YFUbGk04OlINno9FpOTNZN67AP+kSQsblfep5zs1f/WTgMWjD5FymU6rSSh3mu52gukmDNnBJTjC/lj4QRpjlQ=="],
"@convex-dev/workflow": ["@convex-dev/workflow@0.4.4", "", { "dependencies": { "async-channel": "^0.2.0" }, "peerDependencies": { "@convex-dev/workpool": "^0.4.4", "convex": "^1.36.1", "convex-helpers": "^0.1.99" } }, "sha512-ZQfVspAAxG4zZJEep2qaRtupw8OewwMezq6KNKaXKjo/gA+YffS9bXz13x+L/TSt9/Lb6gioae6Y9PDrqh7xQg=="],
"@convex-dev/workpool": ["@convex-dev/workpool@0.4.8", "", { "peerDependencies": { "convex": "^1.36.1", "convex-helpers": "^0.1.94" } }, "sha512-ExUV3dVxUK/m2gQGB0PGuTNX/8pNtJM1T2Z+iprEhu7/4UBKM5flmu5odKBcffDnTzlGTPUQ2X+dwzy8l9T19g=="],
"@cspotcode/source-map-support": ["@cspotcode/source-map-support@0.8.1", "", { "dependencies": { "@jridgewell/trace-mapping": "0.3.9" } }, "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw=="],
"@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.75.1", "", { "dependencies": { "@dotenvx/primitives": "^0.8.0", "commander": "^11.1.0", "conf": "^10.2.0", "dotenv": "^17.2.1", "enquirer": "^2.4.1", "env-paths": "^2.2.1", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "open": "^8.4.2", "picomatch": "^4.0.4", "systeminformation": "^5.22.11", "undici": "^7.11.0", "which": "^4.0.0", "yocto-spinner": "^1.1.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-/BITOC9dmS/edY2zQwZNicQ059O6RKabtQfyEafV0nGtfYRNHYy1DIPiYVcov40+tob9hfmBnbR963dS+EQ1DQ=="],
@@ -1106,31 +1116,31 @@
"@rivet-dev/agent-os-python": ["@rivet-dev/agent-os-python@0.1.0", "", { "dependencies": { "@secure-exec/core": "^0.2.1", "pyodide": "^0.28.3" } }, "sha512-1tH1beMf1ceSpicQKwN/a6h+NmJrmfuT4GStiRDZmvN/UWfZhkxuy7HR5VPTQpE/feUZJ01FdtBS3Em/Qoxb2Q=="],
"@rivet-dev/agentos": ["@rivet-dev/agentos@0.2.14", "", { "dependencies": { "@agentclientprotocol/sdk": "0.16.1", "@agentos-software/common": "0.2.14", "@rivet-dev/agentos-core": "0.2.14", "@rivetkit/react": "2.3.9", "rivetkit": "2.3.9", "zod": "^4.1.11" }, "peerDependencies": { "react": "^18 || ^19", "react-dom": "^18 || ^19" }, "optionalPeers": ["react", "react-dom"] }, "sha512-dr7GU8AA02wB906gdQ6tyfCTyOa08KtT8djpUdtprbx7GLkaUQpq0j60BVeS/OkTUzEwYexWEKmKyGL1U/EgiQ=="],
"@rivet-dev/agentos": ["@rivet-dev/agentos@0.2.10", "", { "dependencies": { "@agentclientprotocol/sdk": "0.16.1", "@agentos-software/common": "0.2.10", "@rivet-dev/agentos-core": "0.2.10", "@rivetkit/react": "2.3.7", "rivetkit": "2.3.7", "zod": "^4.1.11" }, "peerDependencies": { "react": "^18 || ^19", "react-dom": "^18 || ^19" }, "optionalPeers": ["react", "react-dom"] }, "sha512-0R/1p1iesYJtOSarHmfO5pV6BurCQx0z7V+ssIAIXtNaNs7pgMFRrooWsr9UnAJj/xWJ+lM9xIUTHe+o8dE3dw=="],
"@rivet-dev/agentos-core": ["@rivet-dev/agentos-core@0.2.14", "", { "dependencies": { "@agentclientprotocol/sdk": "0.16.1", "@agentos-software/claude-code": "0.2.7", "@agentos-software/codex-cli": "0.3.4", "@agentos-software/common": "0.2.14", "@agentos-software/manifest": "0.2.14", "@agentos-software/opencode": "0.2.7", "@agentos-software/pi": "0.2.7", "@aws-sdk/client-s3": "^3.1019.0", "@rivet-dev/agentos-runtime-core": "0.2.14", "@rivet-dev/agentos-sidecar": "0.2.14", "@rivetkit/bare-ts": "^0.6.2", "@xterm/headless": "^6.0.0", "better-sqlite3": "^12.8.0", "croner": "^10.0.1", "googleapis": "^144.0.0", "isolated-vm": "^6.0.0", "long-timeout": "^0.1.1", "minimatch": "^10.2.4", "zod": "^4.1.11", "zod-to-json-schema": "^3.25.2" } }, "sha512-YAbK0NpauQKlcuSKl0eXB95ZdNopMGmXw1dBaoSlODKVYoKTjOEKwUtSEvx/zZB0Cse2kSQ/IrJpLe183QeQPw=="],
"@rivet-dev/agentos-core": ["@rivet-dev/agentos-core@0.2.10", "", { "dependencies": { "@agentclientprotocol/sdk": "0.16.1", "@agentos-software/claude-code": "0.2.7", "@agentos-software/codex-cli": "0.3.4", "@agentos-software/common": "0.2.10", "@agentos-software/manifest": "0.2.10", "@agentos-software/opencode": "0.2.7", "@agentos-software/pi": "0.2.7", "@aws-sdk/client-s3": "^3.1019.0", "@rivet-dev/agentos-runtime-core": "0.2.10", "@rivet-dev/agentos-sidecar": "0.2.10", "@rivetkit/bare-ts": "^0.6.2", "@xterm/headless": "^6.0.0", "better-sqlite3": "^12.8.0", "croner": "^10.0.1", "googleapis": "^144.0.0", "isolated-vm": "^6.0.0", "long-timeout": "^0.1.1", "minimatch": "^10.2.4", "zod": "^4.1.11", "zod-to-json-schema": "^3.25.2" } }, "sha512-0UMQgBFOmMtiZ0UhQ3cJei44tRmY9VzTpkJh4a+g0HWjAz5thUH2OCYtmF+tGNU8qzHhyN9hBFwT744YMRV/Dg=="],
"@rivet-dev/agentos-runtime-core": ["@rivet-dev/agentos-runtime-core@0.2.14", "", { "dependencies": { "@rivet-dev/agentos-runtime-sidecar": "0.2.14", "@rivetkit/bare-ts": "^0.6.2", "zod": "^4.1.11" } }, "sha512-mZYas5wUZXjwLLLHq6uMOaajtyc/3iLQ6vGzOH4E3OHBwCfK054YwGU8iunRqWtk+Wd7MPetzstxzdu+72nBug=="],
"@rivet-dev/agentos-runtime-core": ["@rivet-dev/agentos-runtime-core@0.2.10", "", { "dependencies": { "@rivet-dev/agentos-runtime-sidecar": "0.2.10", "@rivetkit/bare-ts": "^0.6.2", "zod": "^4.1.11" } }, "sha512-qMmWhDZ/IWL0QOKnASl1STHwRQaDknX34DTX1p+fCjcWbf2QD+ScQMTLdll52oyhQl8KhXn+Tlyhp+XTdqaySQ=="],
"@rivet-dev/agentos-runtime-sidecar": ["@rivet-dev/agentos-runtime-sidecar@0.2.14", "", { "optionalDependencies": { "@rivet-dev/agentos-runtime-sidecar-darwin-arm64": "0.2.14", "@rivet-dev/agentos-runtime-sidecar-darwin-x64": "0.2.14", "@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu": "0.2.14", "@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu": "0.2.14" } }, "sha512-dsA1wNg+0Y6DYRB8no962k1tAQk1y5kfdAbrpKjJQJjfgfwkv0q8XZ3ybtt1hLml/thgE32CI++8F7MRWz4TFA=="],
"@rivet-dev/agentos-runtime-sidecar": ["@rivet-dev/agentos-runtime-sidecar@0.2.10", "", { "optionalDependencies": { "@rivet-dev/agentos-runtime-sidecar-darwin-arm64": "0.2.10", "@rivet-dev/agentos-runtime-sidecar-darwin-x64": "0.2.10", "@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu": "0.2.10", "@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu": "0.2.10" } }, "sha512-v2KXHTTQYHdMpNFhBt3/wCyKajwxq9o4jKLYpaa9mYiaBdHfORuBaDI9e3WDGEly7HCIEWNnwvkNMvoQoHnXnQ=="],
"@rivet-dev/agentos-runtime-sidecar-darwin-arm64": ["@rivet-dev/agentos-runtime-sidecar-darwin-arm64@0.2.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5pKvG7TC3lKbCMbQZptyXd3QPQyfiJ+wKqA+u5SqoP+Lqwim9C4PVSYMLUaxx0QqxliNuNu+VWif1xM91yECiw=="],
"@rivet-dev/agentos-runtime-sidecar-darwin-arm64": ["@rivet-dev/agentos-runtime-sidecar-darwin-arm64@0.2.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-PJ5rJZmgpS/EX9Zn1UA6Z5Ol0Y31UJKfD7Fisdqy7hlJuxhQVS9cVFrp3bud2og9s3n32riEYTx1mUE1PVQKZA=="],
"@rivet-dev/agentos-runtime-sidecar-darwin-x64": ["@rivet-dev/agentos-runtime-sidecar-darwin-x64@0.2.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-mTSDuMXKHSpMJ3SVLCb/3sBCpOaBw0fnEsnLzVSuicuSWSzhNe4yyUeAcyz4wsuT4l+M+Z5mDH1eydfpz7nltw=="],
"@rivet-dev/agentos-runtime-sidecar-darwin-x64": ["@rivet-dev/agentos-runtime-sidecar-darwin-x64@0.2.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-+C4gEE7/pT36fclYqdUYt6bMUj6CsDDZ+2Kxuej57/q06cSa9W5Od2zIO4wxZbI6g0EoN5zVJ8qXv+jSOtTLbg=="],
"@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu": ["@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu@0.2.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-bVtITOH4sNxcq8RuBMJF+Srlwa/Rl1ARZIej+MUDBR8VM7DGnBMWCaCHvYxy3JBmdP5aTb3gCwUm6e7m4/Khgw=="],
"@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu": ["@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu@0.2.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-BSs/LkKkNxvNBD9qEmxPWHmdHQokNGkGS3dcI3LTY4D6Sgat1Vun1OQ53v1HQSGf/TuAfgYOzbQPikvOU3zkmQ=="],
"@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu": ["@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu@0.2.14", "", { "os": "linux", "cpu": "x64" }, "sha512-NOI1m456Ev06ey4O0pVnITaYA7emeoKR2lJIFJP4j9Kv0XuXpbmaz1aigfa3/SZQ7AvqOzxbNLCcH5m22iO8ng=="],
"@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu": ["@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu@0.2.10", "", { "os": "linux", "cpu": "x64" }, "sha512-IIM0ILGdPNjettgBVOXvrNTICggo/xNtKO0V3kM7XJiQ4DkQQkjA1/Y0JBdLvsigt7HAcEJ38zQ3ahl+HOXK8w=="],
"@rivet-dev/agentos-sidecar": ["@rivet-dev/agentos-sidecar@0.2.14", "", { "optionalDependencies": { "@rivet-dev/agentos-sidecar-darwin-arm64": "0.2.14", "@rivet-dev/agentos-sidecar-darwin-x64": "0.2.14", "@rivet-dev/agentos-sidecar-linux-arm64-gnu": "0.2.14", "@rivet-dev/agentos-sidecar-linux-x64-gnu": "0.2.14" } }, "sha512-aISMeC7UY5Mjum/DiYp3idZa/EnNZ76FGke29FVQHmBfwVX6dTx2R/FHjZdEE+iOCi9APxAHIvdu8C+EVp6q2A=="],
"@rivet-dev/agentos-sidecar": ["@rivet-dev/agentos-sidecar@0.2.10", "", { "optionalDependencies": { "@rivet-dev/agentos-sidecar-darwin-arm64": "0.2.10", "@rivet-dev/agentos-sidecar-darwin-x64": "0.2.10", "@rivet-dev/agentos-sidecar-linux-arm64-gnu": "0.2.10", "@rivet-dev/agentos-sidecar-linux-x64-gnu": "0.2.10" } }, "sha512-3bq7k/OrtMffUT+aDSeXPIEDEaJLbPXzQ5oUqnjsU+6Hsmvvf+nAl/zTvHyQOMmriQiQ1BPMPqgNyXAc5BrV3w=="],
"@rivet-dev/agentos-sidecar-darwin-arm64": ["@rivet-dev/agentos-sidecar-darwin-arm64@0.2.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U1R4wYvlsLCdASC5Lf6oP/6bW6ONGsiILtTQSVgxIHl/J1TrmOifrAbRgDC205kThJEZQ2op8kVzol5aEWOpbA=="],
"@rivet-dev/agentos-sidecar-darwin-arm64": ["@rivet-dev/agentos-sidecar-darwin-arm64@0.2.10", "", { "os": "darwin", "cpu": "arm64" }, "sha512-q+54J8WLa/Diyn5H+TVZwIHt4kVFCBkwtco5DjUmFmG6y5ozzPl6MM0vVzIx6iNTzhWiYOFLz5PybICmy6j7BQ=="],
"@rivet-dev/agentos-sidecar-darwin-x64": ["@rivet-dev/agentos-sidecar-darwin-x64@0.2.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-vuij3BYGjVSCGMNB3HbS0EiDS50xG68cjH3ItuZL77GPHsw5V765TOheWDVgUOo1Q3+VWjdMaS2wNWv63qCf0w=="],
"@rivet-dev/agentos-sidecar-darwin-x64": ["@rivet-dev/agentos-sidecar-darwin-x64@0.2.10", "", { "os": "darwin", "cpu": "x64" }, "sha512-Q0rAxtGjddpDcaB9keicukuExtIiynwX+DqVRG6hWjki0PSYqFqqrNFCzPiUswWf0u5Pakq1iBM+RgNu19PxZA=="],
"@rivet-dev/agentos-sidecar-linux-arm64-gnu": ["@rivet-dev/agentos-sidecar-linux-arm64-gnu@0.2.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-nauooe07/NhHb+Wn4xvJTUMNFzhOvrNoPwceiC0eGvkK7+imRyZpAgSGB4qRiaa2NRyuNRVh+d6kzp5iKzBwnA=="],
"@rivet-dev/agentos-sidecar-linux-arm64-gnu": ["@rivet-dev/agentos-sidecar-linux-arm64-gnu@0.2.10", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVgsnPczeT4oMoiUTrOfadAtDGoHhd30lrAU2p/xxyeCOhHAsZt1h0xo2oCteLmZ78DJm3rLcsR+4zhY6AhtOw=="],
"@rivet-dev/agentos-sidecar-linux-x64-gnu": ["@rivet-dev/agentos-sidecar-linux-x64-gnu@0.2.14", "", { "os": "linux", "cpu": "x64" }, "sha512-PaGPXi5mS0Ef023nqS9lbMkMH6KGoOsHA3apAaOQz95lrmVx7E/z5BPzKYl3aYMYjmlo004mnNETVBZOy0VbQw=="],
"@rivet-dev/agentos-sidecar-linux-x64-gnu": ["@rivet-dev/agentos-sidecar-linux-x64-gnu@0.2.10", "", { "os": "linux", "cpu": "x64" }, "sha512-WXKLIeZJvOo2Kxw2wPmPNc7QWM0lq69Xt/Yy2W86gYKORAFPVJ9GVag85ywP3LrjIW1oEDwzqrvMp3PGVkvVXg=="],
"@rivetkit/bare-ts": ["@rivetkit/bare-ts@0.6.2", "", {}, "sha512-3qndQUQXLdwafMEqfhz24hUtDPcsf1Bu3q52Kb8MqeH8JUh3h6R4HYW3ZJXiQsLcyYyFM68PuIwlLRlg1xDEpg=="],
@@ -1148,11 +1158,11 @@
"@rivetkit/engine-envoy-protocol": ["@rivetkit/engine-envoy-protocol@2.3.9", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2" } }, "sha512-2IK41V9U8sgMnEYd/P6u/68nCufCU2dvxuHVV3uAV0uIVCdtRV8lkjuR2fSr05bwHmzSmewdqsbiNMiC/GWt8w=="],
"@rivetkit/framework-base": ["@rivetkit/framework-base@2.3.9", "", { "dependencies": { "@tanstack/store": "^0.7.1", "fast-deep-equal": "^3.1.3", "rivetkit": "2.3.9" } }, "sha512-ZSxrclYcpmdGsLMiVE2dfWNfUB6diSx+t8k4EQgL4cN02ThzJD3BM5mhU+zQVCCwfNw42eRZVIoxydYDLl/yHw=="],
"@rivetkit/framework-base": ["@rivetkit/framework-base@2.3.7", "", { "dependencies": { "@tanstack/store": "^0.7.1", "fast-deep-equal": "^3.1.3", "rivetkit": "2.3.7" } }, "sha512-zxmdAzFogA3PeT3ZgFIoYlEAJVi3iCwbPBXczZKf2x2QMCl2cTZ2jswFCAgHUUMQWj+AWiX65usxq73a9Ls/qQ=="],
"@rivetkit/on-change": ["@rivetkit/on-change@6.0.1", "", {}, "sha512-QBN/KRBXLJdCgN4gBTL3XAc/zKm58atSnieXWMOyFSPmo6F1/yIVV/LTRdvAktfCttrGx7W6c32i/lwqCHWnsQ=="],
"@rivetkit/react": ["@rivetkit/react@2.3.9", "", { "dependencies": { "@rivetkit/framework-base": "2.3.9", "@tanstack/react-store": "^0.7.1", "rivetkit": "2.3.9" }, "peerDependencies": { "react": "^18 || ^19", "react-dom": "^18 || ^19" } }, "sha512-j9t82h/yIqqSt17coQZeRu3F9Q5w2FgWPDUC9fCyQUJp9PTjO7ea494PR0lSWvuEiwMRqE5JpgbHdYUQ1woE9w=="],
"@rivetkit/react": ["@rivetkit/react@2.3.7", "", { "dependencies": { "@rivetkit/framework-base": "2.3.7", "@tanstack/react-store": "^0.7.1", "rivetkit": "2.3.7" }, "peerDependencies": { "react": "^18 || ^19", "react-dom": "^18 || ^19" } }, "sha512-Y3UoUYhkLKDQrJdloCmYK+fhJMlPw5BPHbRb5VutFh5L8csIRZLoCoMitzV7mjNUxuDE1+k10iGuUHYPZUP4aA=="],
"@rivetkit/rivetkit-napi": ["@rivetkit/rivetkit-napi@2.3.9", "", { "dependencies": { "@napi-rs/cli": "^2.18.4", "@rivetkit/engine-envoy-protocol": "2.3.9" }, "optionalDependencies": { "@rivetkit/rivetkit-napi-darwin-arm64": "2.3.9", "@rivetkit/rivetkit-napi-darwin-x64": "2.3.9", "@rivetkit/rivetkit-napi-linux-arm64-gnu": "2.3.9", "@rivetkit/rivetkit-napi-linux-arm64-musl": "2.3.9", "@rivetkit/rivetkit-napi-linux-x64-gnu": "2.3.9", "@rivetkit/rivetkit-napi-linux-x64-musl": "2.3.9", "@rivetkit/rivetkit-napi-win32-x64-msvc": "2.3.9" } }, "sha512-lUuOK1ja6ZMwnNRsdtqJeXChbBEqyvHuI/1h5XQWHfBUu7DgX5zuyA/FJ+BY6YFWtwnkHnOVCBJeNx/3gj8Xhg=="],
@@ -1610,6 +1620,8 @@
"ast-types": ["ast-types@0.16.1", "", { "dependencies": { "tslib": "^2.0.1" } }, "sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg=="],
"async-channel": ["async-channel@0.2.0", "", {}, "sha512-BJyjI/sfKlyijaBt2hbOSxT28xGNtLR0QLzAKO1Hlnv5BULY7sAoYoTPW3lfr1ZIC7y+FxabxO9T8GXpyoofGg=="],
"atomic-sleep": ["atomic-sleep@1.0.0", "", {}, "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ=="],
"atomically": ["atomically@1.7.0", "", {}, "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w=="],
@@ -2330,7 +2342,7 @@
"hono-openapi": ["hono-openapi@1.3.1", "", { "peerDependencies": { "@hono/standard-validator": "^0.2.0", "@standard-community/standard-json": "^0.3.5", "@standard-community/standard-openapi": "^0.2.9", "@types/json-schema": "^7.0.15", "hono": "^4.11.2", "openapi-types": "^12.1.3" }, "optionalPeers": ["@hono/standard-validator", "hono"] }, "sha512-NLVeVkhKZ3drmQNEIPac8HX8Y54uf1hJAgIM/7MfDsaeVVmB+QILWQxx5x3R3NvRHgedcbEbOCGY2uR7WQYyMw=="],
"hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="],
"hosted-git-info": ["hosted-git-info@9.0.3", "", { "dependencies": { "lru-cache": "^11.1.0" } }, "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg=="],
"html-url-attributes": ["html-url-attributes@3.0.1", "", {}, "sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ=="],
@@ -3020,7 +3032,7 @@
"pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"pure-rand": ["pure-rand@8.4.2", "", {}, "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng=="],
@@ -3642,6 +3654,8 @@
"@babel/plugin-transform-runtime/semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
"@code/primitives/@rivet-dev/agentos": ["@rivet-dev/agentos@0.2.14", "", { "dependencies": { "@agentclientprotocol/sdk": "0.16.1", "@agentos-software/common": "0.2.14", "@rivet-dev/agentos-core": "0.2.14", "@rivetkit/react": "2.3.9", "rivetkit": "2.3.9", "zod": "^4.1.11" }, "peerDependencies": { "react": "^18 || ^19", "react-dom": "^18 || ^19" }, "optionalPeers": ["react", "react-dom"] }, "sha512-dr7GU8AA02wB906gdQ6tyfCTyOa08KtT8djpUdtprbx7GLkaUQpq0j60BVeS/OkTUzEwYexWEKmKyGL1U/EgiQ=="],
"@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
"@dotenvx/dotenvx/commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
@@ -3702,8 +3716,6 @@
"@mariozechner/pi-ai/@sinclair/typebox": ["@sinclair/typebox@0.34.52", "", {}, "sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw=="],
"@mariozechner/pi-coding-agent/hosted-git-info": ["hosted-git-info@9.0.3", "", { "dependencies": { "lru-cache": "^11.1.0" } }, "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg=="],
"@mariozechner/pi-coding-agent/ignore": ["ignore@7.0.6", "", {}, "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw=="],
"@mariozechner/pi-coding-agent/marked": ["marked@15.0.12", "", { "bin": { "marked": "bin/marked.js" } }, "sha512-8dD6FusOQSrpv9Z1rdNMdlSgQOIP880DHqnohobOmYLElGEqAL/JvxvuxZO16r4HtjTlfPRDC1hbvxC9dPN2nA=="],
@@ -3724,10 +3736,16 @@
"@react-router/dev/react-refresh": ["react-refresh@0.18.0", "", {}, "sha512-QgT5//D3jfjJb6Gsjxv0Slpj23ip+HtOpnNgnb2S5zU3CB26G/IDPGoy4RJB42wzFE46DRsstbW6tKHoKbhAxw=="],
"@rivet-dev/agentos/rivetkit": ["rivetkit@2.3.7", "", { "dependencies": { "@hono/zod-openapi": "^1.1.5", "@rivet-dev/agent-os-core": "^0.1.1", "@rivetkit/bare-ts": "^0.6.2", "@rivetkit/engine-cli": "2.3.7", "@rivetkit/engine-envoy-protocol": "2.3.7", "@rivetkit/on-change": "6.0.1", "@rivetkit/rivetkit-napi": "2.3.7", "@rivetkit/rivetkit-wasm": "2.3.7", "@rivetkit/traces": "2.3.7", "@rivetkit/virtual-websocket": "2.3.7", "@rivetkit/workflow-engine": "2.3.7", "cbor-x": "^1.6.0", "drizzle-orm": "^0.44.2", "hono": "^4.7.0", "invariant": "^2.2.4", "p-retry": "^6.2.1", "pino": "^9.5.0", "uuid": "^12.0.0", "vbare": "^0.0.4", "zod": "^4.1.0" }, "peerDependencies": { "drizzle-kit": "^0.31.2", "eventsource": "^4.0.0", "ws": "^8.0.0" }, "optionalPeers": ["drizzle-kit", "eventsource", "ws"] }, "sha512-V2IWlXq9SRLJWrcYVa8WUftELCpbdsBVWZIqz2WQjhhzRK9Aan65RfMoZVx62A9k8HuIO6MH1nAPLhOuk1xePQ=="],
"@rivetkit/framework-base/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
"@rivetkit/framework-base/rivetkit": ["rivetkit@2.3.7", "", { "dependencies": { "@hono/zod-openapi": "^1.1.5", "@rivet-dev/agent-os-core": "^0.1.1", "@rivetkit/bare-ts": "^0.6.2", "@rivetkit/engine-cli": "2.3.7", "@rivetkit/engine-envoy-protocol": "2.3.7", "@rivetkit/on-change": "6.0.1", "@rivetkit/rivetkit-napi": "2.3.7", "@rivetkit/rivetkit-wasm": "2.3.7", "@rivetkit/traces": "2.3.7", "@rivetkit/virtual-websocket": "2.3.7", "@rivetkit/workflow-engine": "2.3.7", "cbor-x": "^1.6.0", "drizzle-orm": "^0.44.2", "hono": "^4.7.0", "invariant": "^2.2.4", "p-retry": "^6.2.1", "pino": "^9.5.0", "uuid": "^12.0.0", "vbare": "^0.0.4", "zod": "^4.1.0" }, "peerDependencies": { "drizzle-kit": "^0.31.2", "eventsource": "^4.0.0", "ws": "^8.0.0" }, "optionalPeers": ["drizzle-kit", "eventsource", "ws"] }, "sha512-V2IWlXq9SRLJWrcYVa8WUftELCpbdsBVWZIqz2WQjhhzRK9Aan65RfMoZVx62A9k8HuIO6MH1nAPLhOuk1xePQ=="],
"@rivetkit/react/@tanstack/react-store": ["@tanstack/react-store@0.7.7", "", { "dependencies": { "@tanstack/store": "0.7.7", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg=="],
"@rivetkit/react/rivetkit": ["rivetkit@2.3.7", "", { "dependencies": { "@hono/zod-openapi": "^1.1.5", "@rivet-dev/agent-os-core": "^0.1.1", "@rivetkit/bare-ts": "^0.6.2", "@rivetkit/engine-cli": "2.3.7", "@rivetkit/engine-envoy-protocol": "2.3.7", "@rivetkit/on-change": "6.0.1", "@rivetkit/rivetkit-napi": "2.3.7", "@rivetkit/rivetkit-wasm": "2.3.7", "@rivetkit/traces": "2.3.7", "@rivetkit/virtual-websocket": "2.3.7", "@rivetkit/workflow-engine": "2.3.7", "cbor-x": "^1.6.0", "drizzle-orm": "^0.44.2", "hono": "^4.7.0", "invariant": "^2.2.4", "p-retry": "^6.2.1", "pino": "^9.5.0", "uuid": "^12.0.0", "vbare": "^0.0.4", "zod": "^4.1.0" }, "peerDependencies": { "drizzle-kit": "^0.31.2", "eventsource": "^4.0.0", "ws": "^8.0.0" }, "optionalPeers": ["drizzle-kit", "eventsource", "ws"] }, "sha512-V2IWlXq9SRLJWrcYVa8WUftELCpbdsBVWZIqz2WQjhhzRK9Aan65RfMoZVx62A9k8HuIO6MH1nAPLhOuk1xePQ=="],
"@secure-exec/nodejs/es-module-lexer": ["es-module-lexer@1.7.0", "", {}, "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA=="],
"@secure-exec/nodejs/esbuild": ["esbuild@0.27.7", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.27.7", "@esbuild/android-arm": "0.27.7", "@esbuild/android-arm64": "0.27.7", "@esbuild/android-x64": "0.27.7", "@esbuild/darwin-arm64": "0.27.7", "@esbuild/darwin-x64": "0.27.7", "@esbuild/freebsd-arm64": "0.27.7", "@esbuild/freebsd-x64": "0.27.7", "@esbuild/linux-arm": "0.27.7", "@esbuild/linux-arm64": "0.27.7", "@esbuild/linux-ia32": "0.27.7", "@esbuild/linux-loong64": "0.27.7", "@esbuild/linux-mips64el": "0.27.7", "@esbuild/linux-ppc64": "0.27.7", "@esbuild/linux-riscv64": "0.27.7", "@esbuild/linux-s390x": "0.27.7", "@esbuild/linux-x64": "0.27.7", "@esbuild/netbsd-arm64": "0.27.7", "@esbuild/netbsd-x64": "0.27.7", "@esbuild/openbsd-arm64": "0.27.7", "@esbuild/openbsd-x64": "0.27.7", "@esbuild/openharmony-arm64": "0.27.7", "@esbuild/sunos-x64": "0.27.7", "@esbuild/win32-arm64": "0.27.7", "@esbuild/win32-ia32": "0.27.7", "@esbuild/win32-x64": "0.27.7" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w=="],
@@ -3856,8 +3874,6 @@
"hoist-non-react-statics/react-is": ["react-is@16.13.1", "", {}, "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="],
"hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"import-fresh/resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"is-inside-container/is-docker": ["is-docker@3.0.0", "", { "bin": { "is-docker": "cli.js" } }, "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ=="],
@@ -3900,7 +3916,7 @@
"morgan/debug": ["debug@2.6.9", "", { "dependencies": { "ms": "2.0.0" } }, "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA=="],
"node-stdlib-browser/punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"npm-package-arg/hosted-git-info": ["hosted-git-info@7.0.2", "", { "dependencies": { "lru-cache": "^10.0.1" } }, "sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w=="],
"npm-package-arg/validate-npm-package-name": ["validate-npm-package-name@5.0.1", "", {}, "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ=="],
@@ -3974,7 +3990,7 @@
"type-is/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
"url/punycode": ["punycode@1.4.1", "", {}, "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ=="],
"uri-js/punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"vite-plus/oxfmt": ["oxfmt@0.57.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.57.0", "@oxfmt/binding-android-arm64": "0.57.0", "@oxfmt/binding-darwin-arm64": "0.57.0", "@oxfmt/binding-darwin-x64": "0.57.0", "@oxfmt/binding-freebsd-x64": "0.57.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.57.0", "@oxfmt/binding-linux-arm-musleabihf": "0.57.0", "@oxfmt/binding-linux-arm64-gnu": "0.57.0", "@oxfmt/binding-linux-arm64-musl": "0.57.0", "@oxfmt/binding-linux-ppc64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-gnu": "0.57.0", "@oxfmt/binding-linux-riscv64-musl": "0.57.0", "@oxfmt/binding-linux-s390x-gnu": "0.57.0", "@oxfmt/binding-linux-x64-gnu": "0.57.0", "@oxfmt/binding-linux-x64-musl": "0.57.0", "@oxfmt/binding-openharmony-arm64": "0.57.0", "@oxfmt/binding-win32-arm64-msvc": "0.57.0", "@oxfmt/binding-win32-ia32-msvc": "0.57.0", "@oxfmt/binding-win32-x64-msvc": "0.57.0" }, "peerDependencies": { "svelte": "^5.0.0", "vite-plus": "*" }, "optionalPeers": ["svelte", "vite-plus"], "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-ZB7Bi+rGDSqmVIo9jwcLyFgjxXvQhDdU+jx+ZrVy6VRiVXK2+CHc4hO3J4dUQjHe7V0ymHB+MDuv5z+NhK07HA=="],
@@ -4024,6 +4040,12 @@
"@anthropic-ai/claude-agent-sdk/@img/sharp-linuxmusl-x64/@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
"@code/primitives/@rivet-dev/agentos/@agentos-software/common": ["@agentos-software/common@0.2.14", "", { "dependencies": { "@agentos-software/coreutils": "0.3.4", "@agentos-software/diffutils": "0.3.4", "@agentos-software/findutils": "0.3.4", "@agentos-software/gawk": "0.3.4", "@agentos-software/grep": "0.3.4", "@agentos-software/gzip": "0.3.4", "@agentos-software/sed": "0.3.4", "@agentos-software/tar": "0.3.5" } }, "sha512-ve/ks2MZtXFN9JK+kcFnSMGI1tqoUy36sTKWYGqApcgg/3JJwqnMs4JIKL5OXjgCtDuTvTjRySbQvEKxGkeeSQ=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core": ["@rivet-dev/agentos-core@0.2.14", "", { "dependencies": { "@agentclientprotocol/sdk": "0.16.1", "@agentos-software/claude-code": "0.2.7", "@agentos-software/codex-cli": "0.3.4", "@agentos-software/common": "0.2.14", "@agentos-software/manifest": "0.2.14", "@agentos-software/opencode": "0.2.7", "@agentos-software/pi": "0.2.7", "@aws-sdk/client-s3": "^3.1019.0", "@rivet-dev/agentos-runtime-core": "0.2.14", "@rivet-dev/agentos-sidecar": "0.2.14", "@rivetkit/bare-ts": "^0.6.2", "@xterm/headless": "^6.0.0", "better-sqlite3": "^12.8.0", "croner": "^10.0.1", "googleapis": "^144.0.0", "isolated-vm": "^6.0.0", "long-timeout": "^0.1.1", "minimatch": "^10.2.4", "zod": "^4.1.11", "zod-to-json-schema": "^3.25.2" } }, "sha512-YAbK0NpauQKlcuSKl0eXB95ZdNopMGmXw1dBaoSlODKVYoKTjOEKwUtSEvx/zZB0Cse2kSQ/IrJpLe183QeQPw=="],
"@code/primitives/@rivet-dev/agentos/@rivetkit/react": ["@rivetkit/react@2.3.9", "", { "dependencies": { "@rivetkit/framework-base": "2.3.9", "@tanstack/react-store": "^0.7.1", "rivetkit": "2.3.9" }, "peerDependencies": { "react": "^18 || ^19", "react-dom": "^18 || ^19" } }, "sha512-j9t82h/yIqqSt17coQZeRu3F9Q5w2FgWPDUC9fCyQUJp9PTjO7ea494PR0lSWvuEiwMRqE5JpgbHdYUQ1woE9w=="],
"@dotenvx/dotenvx/execa/get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
"@dotenvx/dotenvx/execa/human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
@@ -4098,8 +4120,56 @@
"@react-native/dev-middleware/serve-static/send": ["send@0.19.2", "", { "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "~0.5.2", "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", "on-finished": "~2.4.1", "range-parser": "~1.2.1", "statuses": "~2.0.2" } }, "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-cli": ["@rivetkit/engine-cli@2.3.7", "", { "optionalDependencies": { "@rivetkit/engine-cli-darwin-arm64": "2.3.7", "@rivetkit/engine-cli-darwin-x64": "2.3.7", "@rivetkit/engine-cli-linux-arm64-musl": "2.3.7", "@rivetkit/engine-cli-linux-x64-musl": "2.3.7", "@rivetkit/engine-cli-win32-x64": "2.3.7" } }, "sha512-CezLwJ0B7dWDbA7qM6Aq04mwnrJAdrDActRrrcb4NBa20h7wO9KPAYBwyJz/dRnKm9EUUNcFZ6hrSDpp6T3+Rg=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-envoy-protocol": ["@rivetkit/engine-envoy-protocol@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2" } }, "sha512-lsJM3ERwozQCebaOMKJzqIQlcLbbN3LXurRB0+7LsM6FUUL2l6hMoq5I2De/G35DJ6OWDva9AmzfvzI+5f1GPg=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi": ["@rivetkit/rivetkit-napi@2.3.7", "", { "dependencies": { "@napi-rs/cli": "^2.18.4", "@rivetkit/engine-envoy-protocol": "2.3.7" }, "optionalDependencies": { "@rivetkit/rivetkit-napi-darwin-arm64": "2.3.7", "@rivetkit/rivetkit-napi-darwin-x64": "2.3.7", "@rivetkit/rivetkit-napi-linux-arm64-gnu": "2.3.7", "@rivetkit/rivetkit-napi-linux-arm64-musl": "2.3.7", "@rivetkit/rivetkit-napi-linux-x64-gnu": "2.3.7", "@rivetkit/rivetkit-napi-linux-x64-musl": "2.3.7", "@rivetkit/rivetkit-napi-win32-x64-msvc": "2.3.7" } }, "sha512-1d3HtNKzJwdkznWDWSpCwg1rBn+nVwUfcKrApINTfiEhfDyVeznwbVFkfHWqOBHsjU17vvWFfjjTtf8QsjLwUQ=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-wasm": ["@rivetkit/rivetkit-wasm@2.3.7", "", {}, "sha512-o7QBtFOJrajyPVBIDQ32k8sDNFsUc8v2ETfNpr+Ch374ydmZMzCv3XKJU9vubc9bZa7WpCHSzf5ztc8b8i/Xpg=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/traces": ["@rivetkit/traces@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2", "cbor-x": "^1.6.0", "fdb-tuple": "^1.0.0", "vbare": "^0.0.4" } }, "sha512-B7QYjFP2HPxyfPsVjfcNIV7FPLWgGWGypmlT/dZM1i1Cf1WRdeuBumPLffgs3YceiY7Pm4D/gZZVt5p0m4Cx+A=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/virtual-websocket": ["@rivetkit/virtual-websocket@2.3.7", "", {}, "sha512-jwxDvYbr3YB6vFuxwRdB/AqUUMwdtC1rIAc4tNN6VQR3weHbE+PrDoHKbe85zrtlBtcnG89/p8tlovrj8qyQWA=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/workflow-engine": ["@rivetkit/workflow-engine@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2", "cbor-x": "^1.6.0", "fdb-tuple": "^1.0.0", "pino": "^9.6.0", "vbare": "^0.0.4" } }, "sha512-+C4kGuSNysrw2zs/LQoYxouOxufKHHMxiIXKF8Ab9GU2BCJ32RUST9dYU/gaQE/w9uM+hqAHUz0DTlOBYU6p6g=="],
"@rivet-dev/agentos/rivetkit/uuid": ["uuid@12.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-9obBF8sMIHJWNQaO6IGOG8giGa/jUpKX34bz6o4whVs8M0WAvhID2tNxYp6A2XEBJPuZSX8wsS/6TEKfIDc+nw=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-cli": ["@rivetkit/engine-cli@2.3.7", "", { "optionalDependencies": { "@rivetkit/engine-cli-darwin-arm64": "2.3.7", "@rivetkit/engine-cli-darwin-x64": "2.3.7", "@rivetkit/engine-cli-linux-arm64-musl": "2.3.7", "@rivetkit/engine-cli-linux-x64-musl": "2.3.7", "@rivetkit/engine-cli-win32-x64": "2.3.7" } }, "sha512-CezLwJ0B7dWDbA7qM6Aq04mwnrJAdrDActRrrcb4NBa20h7wO9KPAYBwyJz/dRnKm9EUUNcFZ6hrSDpp6T3+Rg=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-envoy-protocol": ["@rivetkit/engine-envoy-protocol@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2" } }, "sha512-lsJM3ERwozQCebaOMKJzqIQlcLbbN3LXurRB0+7LsM6FUUL2l6hMoq5I2De/G35DJ6OWDva9AmzfvzI+5f1GPg=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi": ["@rivetkit/rivetkit-napi@2.3.7", "", { "dependencies": { "@napi-rs/cli": "^2.18.4", "@rivetkit/engine-envoy-protocol": "2.3.7" }, "optionalDependencies": { "@rivetkit/rivetkit-napi-darwin-arm64": "2.3.7", "@rivetkit/rivetkit-napi-darwin-x64": "2.3.7", "@rivetkit/rivetkit-napi-linux-arm64-gnu": "2.3.7", "@rivetkit/rivetkit-napi-linux-arm64-musl": "2.3.7", "@rivetkit/rivetkit-napi-linux-x64-gnu": "2.3.7", "@rivetkit/rivetkit-napi-linux-x64-musl": "2.3.7", "@rivetkit/rivetkit-napi-win32-x64-msvc": "2.3.7" } }, "sha512-1d3HtNKzJwdkznWDWSpCwg1rBn+nVwUfcKrApINTfiEhfDyVeznwbVFkfHWqOBHsjU17vvWFfjjTtf8QsjLwUQ=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-wasm": ["@rivetkit/rivetkit-wasm@2.3.7", "", {}, "sha512-o7QBtFOJrajyPVBIDQ32k8sDNFsUc8v2ETfNpr+Ch374ydmZMzCv3XKJU9vubc9bZa7WpCHSzf5ztc8b8i/Xpg=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/traces": ["@rivetkit/traces@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2", "cbor-x": "^1.6.0", "fdb-tuple": "^1.0.0", "vbare": "^0.0.4" } }, "sha512-B7QYjFP2HPxyfPsVjfcNIV7FPLWgGWGypmlT/dZM1i1Cf1WRdeuBumPLffgs3YceiY7Pm4D/gZZVt5p0m4Cx+A=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/virtual-websocket": ["@rivetkit/virtual-websocket@2.3.7", "", {}, "sha512-jwxDvYbr3YB6vFuxwRdB/AqUUMwdtC1rIAc4tNN6VQR3weHbE+PrDoHKbe85zrtlBtcnG89/p8tlovrj8qyQWA=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/workflow-engine": ["@rivetkit/workflow-engine@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2", "cbor-x": "^1.6.0", "fdb-tuple": "^1.0.0", "pino": "^9.6.0", "vbare": "^0.0.4" } }, "sha512-+C4kGuSNysrw2zs/LQoYxouOxufKHHMxiIXKF8Ab9GU2BCJ32RUST9dYU/gaQE/w9uM+hqAHUz0DTlOBYU6p6g=="],
"@rivetkit/framework-base/rivetkit/uuid": ["uuid@12.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-9obBF8sMIHJWNQaO6IGOG8giGa/jUpKX34bz6o4whVs8M0WAvhID2tNxYp6A2XEBJPuZSX8wsS/6TEKfIDc+nw=="],
"@rivetkit/react/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-cli": ["@rivetkit/engine-cli@2.3.7", "", { "optionalDependencies": { "@rivetkit/engine-cli-darwin-arm64": "2.3.7", "@rivetkit/engine-cli-darwin-x64": "2.3.7", "@rivetkit/engine-cli-linux-arm64-musl": "2.3.7", "@rivetkit/engine-cli-linux-x64-musl": "2.3.7", "@rivetkit/engine-cli-win32-x64": "2.3.7" } }, "sha512-CezLwJ0B7dWDbA7qM6Aq04mwnrJAdrDActRrrcb4NBa20h7wO9KPAYBwyJz/dRnKm9EUUNcFZ6hrSDpp6T3+Rg=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-envoy-protocol": ["@rivetkit/engine-envoy-protocol@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2" } }, "sha512-lsJM3ERwozQCebaOMKJzqIQlcLbbN3LXurRB0+7LsM6FUUL2l6hMoq5I2De/G35DJ6OWDva9AmzfvzI+5f1GPg=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi": ["@rivetkit/rivetkit-napi@2.3.7", "", { "dependencies": { "@napi-rs/cli": "^2.18.4", "@rivetkit/engine-envoy-protocol": "2.3.7" }, "optionalDependencies": { "@rivetkit/rivetkit-napi-darwin-arm64": "2.3.7", "@rivetkit/rivetkit-napi-darwin-x64": "2.3.7", "@rivetkit/rivetkit-napi-linux-arm64-gnu": "2.3.7", "@rivetkit/rivetkit-napi-linux-arm64-musl": "2.3.7", "@rivetkit/rivetkit-napi-linux-x64-gnu": "2.3.7", "@rivetkit/rivetkit-napi-linux-x64-musl": "2.3.7", "@rivetkit/rivetkit-napi-win32-x64-msvc": "2.3.7" } }, "sha512-1d3HtNKzJwdkznWDWSpCwg1rBn+nVwUfcKrApINTfiEhfDyVeznwbVFkfHWqOBHsjU17vvWFfjjTtf8QsjLwUQ=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-wasm": ["@rivetkit/rivetkit-wasm@2.3.7", "", {}, "sha512-o7QBtFOJrajyPVBIDQ32k8sDNFsUc8v2ETfNpr+Ch374ydmZMzCv3XKJU9vubc9bZa7WpCHSzf5ztc8b8i/Xpg=="],
"@rivetkit/react/rivetkit/@rivetkit/traces": ["@rivetkit/traces@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2", "cbor-x": "^1.6.0", "fdb-tuple": "^1.0.0", "vbare": "^0.0.4" } }, "sha512-B7QYjFP2HPxyfPsVjfcNIV7FPLWgGWGypmlT/dZM1i1Cf1WRdeuBumPLffgs3YceiY7Pm4D/gZZVt5p0m4Cx+A=="],
"@rivetkit/react/rivetkit/@rivetkit/virtual-websocket": ["@rivetkit/virtual-websocket@2.3.7", "", {}, "sha512-jwxDvYbr3YB6vFuxwRdB/AqUUMwdtC1rIAc4tNN6VQR3weHbE+PrDoHKbe85zrtlBtcnG89/p8tlovrj8qyQWA=="],
"@rivetkit/react/rivetkit/@rivetkit/workflow-engine": ["@rivetkit/workflow-engine@2.3.7", "", { "dependencies": { "@rivetkit/bare-ts": "^0.6.2", "cbor-x": "^1.6.0", "fdb-tuple": "^1.0.0", "pino": "^9.6.0", "vbare": "^0.0.4" } }, "sha512-+C4kGuSNysrw2zs/LQoYxouOxufKHHMxiIXKF8Ab9GU2BCJ32RUST9dYU/gaQE/w9uM+hqAHUz0DTlOBYU6p6g=="],
"@rivetkit/react/rivetkit/uuid": ["uuid@12.0.1", "", { "bin": { "uuid": "dist/bin/uuid" } }, "sha512-9obBF8sMIHJWNQaO6IGOG8giGa/jUpKX34bz6o4whVs8M0WAvhID2tNxYp6A2XEBJPuZSX8wsS/6TEKfIDc+nw=="],
"@secure-exec/nodejs/esbuild/@esbuild/aix-ppc64": ["@esbuild/aix-ppc64@0.27.7", "", { "os": "aix", "cpu": "ppc64" }, "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg=="],
"@secure-exec/nodejs/esbuild/@esbuild/android-arm": ["@esbuild/android-arm@0.27.7", "", { "os": "android", "cpu": "arm" }, "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ=="],
@@ -4246,6 +4316,8 @@
"morgan/debug/ms": ["ms@2.0.0", "", {}, "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="],
"npm-package-arg/hosted-git-info/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"ora/string-width/emoji-regex": ["emoji-regex@10.6.0", "", {}, "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A=="],
"pkg-up/find-up/locate-path": ["locate-path@3.0.0", "", { "dependencies": { "p-locate": "^3.0.0", "path-exists": "^3.0.0" } }, "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A=="],
@@ -4380,6 +4452,18 @@
"wrangler/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.28.1", "", { "os": "win32", "cpu": "x64" }, "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A=="],
"@code/primitives/@rivet-dev/agentos/@agentos-software/common/@agentos-software/tar": ["@agentos-software/tar@0.3.5", "", {}, "sha512-hSf6PY4q1luIomFSDgVHxVDDIPdAVZxdgwrQFEYH4aIE6TXX9qatVmzR36uYLWpnFGAZTR6srREGoTnmOGV4Lg=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@agentos-software/manifest": ["@agentos-software/manifest@0.2.14", "", {}, "sha512-c1lGWN7/d1lku6Kl+wj6w1YoLX6wI93IyiUoE6M/Hgl1PP1YIPUqGFM5P5sZ9gG9M0qQ86T/587gECj1elZQBg=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-runtime-core": ["@rivet-dev/agentos-runtime-core@0.2.14", "", { "dependencies": { "@rivet-dev/agentos-runtime-sidecar": "0.2.14", "@rivetkit/bare-ts": "^0.6.2", "zod": "^4.1.11" } }, "sha512-mZYas5wUZXjwLLLHq6uMOaajtyc/3iLQ6vGzOH4E3OHBwCfK054YwGU8iunRqWtk+Wd7MPetzstxzdu+72nBug=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-sidecar": ["@rivet-dev/agentos-sidecar@0.2.14", "", { "optionalDependencies": { "@rivet-dev/agentos-sidecar-darwin-arm64": "0.2.14", "@rivet-dev/agentos-sidecar-darwin-x64": "0.2.14", "@rivet-dev/agentos-sidecar-linux-arm64-gnu": "0.2.14", "@rivet-dev/agentos-sidecar-linux-x64-gnu": "0.2.14" } }, "sha512-aISMeC7UY5Mjum/DiYp3idZa/EnNZ76FGke29FVQHmBfwVX6dTx2R/FHjZdEE+iOCi9APxAHIvdu8C+EVp6q2A=="],
"@code/primitives/@rivet-dev/agentos/@rivetkit/react/@rivetkit/framework-base": ["@rivetkit/framework-base@2.3.9", "", { "dependencies": { "@tanstack/store": "^0.7.1", "fast-deep-equal": "^3.1.3", "rivetkit": "2.3.9" } }, "sha512-ZSxrclYcpmdGsLMiVE2dfWNfUB6diSx+t8k4EQgL4cN02ThzJD3BM5mhU+zQVCCwfNw42eRZVIoxydYDLl/yHw=="],
"@code/primitives/@rivet-dev/agentos/@rivetkit/react/@tanstack/react-store": ["@tanstack/react-store@0.7.7", "", { "dependencies": { "@tanstack/store": "0.7.7", "use-sync-external-store": "^1.5.0" }, "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-qqT0ufegFRDGSof9D/VqaZgjNgp4tRPHZIJq2+QIHkMUtHjaJ0lYrrXjeIUJvjnTbgPfSD1XgOMEt0lmANn6Zg=="],
"@expo/cli/accepts/mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"@expo/cli/ora/chalk/ansi-styles": ["ansi-styles@3.2.1", "", { "dependencies": { "color-convert": "^1.9.0" } }, "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA=="],
@@ -4410,6 +4494,78 @@
"@react-native/dev-middleware/serve-static/send/range-parser": ["range-parser@1.2.1", "", {}, "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-darwin-arm64": ["@rivetkit/engine-cli-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-F3yGSDIaW94BZzuAm3erQRT/Ki55wHJ/b6tOaE7d9tRmTAZw/XqHmjNdUYjOvFUQKLb+SSsOittM4dINrAANQQ=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-darwin-x64": ["@rivetkit/engine-cli-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-P8BbQsamIvv8U/cEoJUFr+uAzwjjl9cG+ZZxjDX9OJxbuD11ESpHvDLgge54ijynO3IjoP8cIzjIXat6mr2Gkw=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-linux-arm64-musl": ["@rivetkit/engine-cli-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-G3s76BHfIs6R9rm6JYI13sOjPLy08+C8WvVoFwSdMqsibEaqlfo36wVkp/x1g0sEZUek/dBxVrKqMMR7c4/gug=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-linux-x64-musl": ["@rivetkit/engine-cli-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-LWhrUVzULcsZ4ufCLsx23YfrdMW2INd9g0ANBac9+PzGwL8qYfVIXnDpR3587lapu68EbSEPZcconf1tBlvJxQ=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-win32-x64": ["@rivetkit/engine-cli-win32-x64@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-jyA5PlHivHXyyq2ehnuXwxd5TUSbB4emomnph9EovsJo7qIdmSNaaCO13NYBT483fd0uXiNI0MK/lkJa9ePY5A=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-darwin-arm64": ["@rivetkit/rivetkit-napi-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gI1wMe6z85VDeR4K/wnzevVakXTg5UCfvjlDOp1+23nyU3NlInhN156dEWO8EsfRMrs+1bYoGdc4rcoN+4PUrw=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-darwin-x64": ["@rivetkit/rivetkit-napi-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-H5tUwvCbKwTIBiyQG01ikK5mdc9ISg+bv8gPUw41mYOKq8rb9nBLkcl2TKcreFHac8KaGxtnBZzYcjbUV3NcwQ=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-arm64-gnu": ["@rivetkit/rivetkit-napi-linux-arm64-gnu@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-MpOeiO5M737e93hM/FjcH+zv8xBEX1tgBd/59K/Uw7qlRbWW7JGz8WGjavdxv211LRqxsn8EUlGRxcADDsXnBA=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-arm64-musl": ["@rivetkit/rivetkit-napi-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-0GsUgd/HHvIq6v92kp0H175mGm2Exvs4krBLih0MIpVAkqJk8EIcKI6wJhCwY04Fr0MS8sHkUhjuHXa7QcmlYA=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-x64-gnu": ["@rivetkit/rivetkit-napi-linux-x64-gnu@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-8wCD1FuDpM+yiKRG8ro1K8ILVpJXzCNKViJ1axq1b4Nyqgod/nyEvvKDaT4qhA5+Om+W5i6YRO1uddjC6QjJSQ=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-x64-musl": ["@rivetkit/rivetkit-napi-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-8RGzXD33GH1/DWufFzCZRI+npF5IL/9z7Ja3pthsuYgrL+axGG0iqfAjbwj5HHnB/ceUGQVT+uCKzoLnG+odtw=="],
"@rivet-dev/agentos/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-win32-x64-msvc": ["@rivetkit/rivetkit-napi-win32-x64-msvc@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-n1by/coKxWOb2FZDGLM2qmULxcLSqx8hxJuk7Hsb1gl4uNHGviUzYr+r7WAiOzonK/Dgy477u3OKf5yBie743A=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-darwin-arm64": ["@rivetkit/engine-cli-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-F3yGSDIaW94BZzuAm3erQRT/Ki55wHJ/b6tOaE7d9tRmTAZw/XqHmjNdUYjOvFUQKLb+SSsOittM4dINrAANQQ=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-darwin-x64": ["@rivetkit/engine-cli-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-P8BbQsamIvv8U/cEoJUFr+uAzwjjl9cG+ZZxjDX9OJxbuD11ESpHvDLgge54ijynO3IjoP8cIzjIXat6mr2Gkw=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-linux-arm64-musl": ["@rivetkit/engine-cli-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-G3s76BHfIs6R9rm6JYI13sOjPLy08+C8WvVoFwSdMqsibEaqlfo36wVkp/x1g0sEZUek/dBxVrKqMMR7c4/gug=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-linux-x64-musl": ["@rivetkit/engine-cli-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-LWhrUVzULcsZ4ufCLsx23YfrdMW2INd9g0ANBac9+PzGwL8qYfVIXnDpR3587lapu68EbSEPZcconf1tBlvJxQ=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-win32-x64": ["@rivetkit/engine-cli-win32-x64@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-jyA5PlHivHXyyq2ehnuXwxd5TUSbB4emomnph9EovsJo7qIdmSNaaCO13NYBT483fd0uXiNI0MK/lkJa9ePY5A=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-darwin-arm64": ["@rivetkit/rivetkit-napi-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gI1wMe6z85VDeR4K/wnzevVakXTg5UCfvjlDOp1+23nyU3NlInhN156dEWO8EsfRMrs+1bYoGdc4rcoN+4PUrw=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-darwin-x64": ["@rivetkit/rivetkit-napi-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-H5tUwvCbKwTIBiyQG01ikK5mdc9ISg+bv8gPUw41mYOKq8rb9nBLkcl2TKcreFHac8KaGxtnBZzYcjbUV3NcwQ=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-arm64-gnu": ["@rivetkit/rivetkit-napi-linux-arm64-gnu@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-MpOeiO5M737e93hM/FjcH+zv8xBEX1tgBd/59K/Uw7qlRbWW7JGz8WGjavdxv211LRqxsn8EUlGRxcADDsXnBA=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-arm64-musl": ["@rivetkit/rivetkit-napi-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-0GsUgd/HHvIq6v92kp0H175mGm2Exvs4krBLih0MIpVAkqJk8EIcKI6wJhCwY04Fr0MS8sHkUhjuHXa7QcmlYA=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-x64-gnu": ["@rivetkit/rivetkit-napi-linux-x64-gnu@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-8wCD1FuDpM+yiKRG8ro1K8ILVpJXzCNKViJ1axq1b4Nyqgod/nyEvvKDaT4qhA5+Om+W5i6YRO1uddjC6QjJSQ=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-x64-musl": ["@rivetkit/rivetkit-napi-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-8RGzXD33GH1/DWufFzCZRI+npF5IL/9z7Ja3pthsuYgrL+axGG0iqfAjbwj5HHnB/ceUGQVT+uCKzoLnG+odtw=="],
"@rivetkit/framework-base/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-win32-x64-msvc": ["@rivetkit/rivetkit-napi-win32-x64-msvc@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-n1by/coKxWOb2FZDGLM2qmULxcLSqx8hxJuk7Hsb1gl4uNHGviUzYr+r7WAiOzonK/Dgy477u3OKf5yBie743A=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-darwin-arm64": ["@rivetkit/engine-cli-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-F3yGSDIaW94BZzuAm3erQRT/Ki55wHJ/b6tOaE7d9tRmTAZw/XqHmjNdUYjOvFUQKLb+SSsOittM4dINrAANQQ=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-darwin-x64": ["@rivetkit/engine-cli-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-P8BbQsamIvv8U/cEoJUFr+uAzwjjl9cG+ZZxjDX9OJxbuD11ESpHvDLgge54ijynO3IjoP8cIzjIXat6mr2Gkw=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-linux-arm64-musl": ["@rivetkit/engine-cli-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-G3s76BHfIs6R9rm6JYI13sOjPLy08+C8WvVoFwSdMqsibEaqlfo36wVkp/x1g0sEZUek/dBxVrKqMMR7c4/gug=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-linux-x64-musl": ["@rivetkit/engine-cli-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-LWhrUVzULcsZ4ufCLsx23YfrdMW2INd9g0ANBac9+PzGwL8qYfVIXnDpR3587lapu68EbSEPZcconf1tBlvJxQ=="],
"@rivetkit/react/rivetkit/@rivetkit/engine-cli/@rivetkit/engine-cli-win32-x64": ["@rivetkit/engine-cli-win32-x64@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-jyA5PlHivHXyyq2ehnuXwxd5TUSbB4emomnph9EovsJo7qIdmSNaaCO13NYBT483fd0uXiNI0MK/lkJa9ePY5A=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-darwin-arm64": ["@rivetkit/rivetkit-napi-darwin-arm64@2.3.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-gI1wMe6z85VDeR4K/wnzevVakXTg5UCfvjlDOp1+23nyU3NlInhN156dEWO8EsfRMrs+1bYoGdc4rcoN+4PUrw=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-darwin-x64": ["@rivetkit/rivetkit-napi-darwin-x64@2.3.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-H5tUwvCbKwTIBiyQG01ikK5mdc9ISg+bv8gPUw41mYOKq8rb9nBLkcl2TKcreFHac8KaGxtnBZzYcjbUV3NcwQ=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-arm64-gnu": ["@rivetkit/rivetkit-napi-linux-arm64-gnu@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-MpOeiO5M737e93hM/FjcH+zv8xBEX1tgBd/59K/Uw7qlRbWW7JGz8WGjavdxv211LRqxsn8EUlGRxcADDsXnBA=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-arm64-musl": ["@rivetkit/rivetkit-napi-linux-arm64-musl@2.3.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-0GsUgd/HHvIq6v92kp0H175mGm2Exvs4krBLih0MIpVAkqJk8EIcKI6wJhCwY04Fr0MS8sHkUhjuHXa7QcmlYA=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-x64-gnu": ["@rivetkit/rivetkit-napi-linux-x64-gnu@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-8wCD1FuDpM+yiKRG8ro1K8ILVpJXzCNKViJ1axq1b4Nyqgod/nyEvvKDaT4qhA5+Om+W5i6YRO1uddjC6QjJSQ=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-linux-x64-musl": ["@rivetkit/rivetkit-napi-linux-x64-musl@2.3.7", "", { "os": "linux", "cpu": "x64" }, "sha512-8RGzXD33GH1/DWufFzCZRI+npF5IL/9z7Ja3pthsuYgrL+axGG0iqfAjbwj5HHnB/ceUGQVT+uCKzoLnG+odtw=="],
"@rivetkit/react/rivetkit/@rivetkit/rivetkit-napi/@rivetkit/rivetkit-napi-win32-x64-msvc": ["@rivetkit/rivetkit-napi-win32-x64-msvc@2.3.7", "", { "os": "win32", "cpu": "x64" }, "sha512-n1by/coKxWOb2FZDGLM2qmULxcLSqx8hxJuk7Hsb1gl4uNHGviUzYr+r7WAiOzonK/Dgy477u3OKf5yBie743A=="],
"cli-highlight/yargs/cliui/strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"googleapis-common/google-auth-library/gcp-metadata/google-logging-utils": ["google-logging-utils@0.0.2", "", {}, "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ=="],
@@ -4434,6 +4590,20 @@
"ripemd160/hash-base/readable-stream/string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-runtime-core/@rivet-dev/agentos-runtime-sidecar": ["@rivet-dev/agentos-runtime-sidecar@0.2.14", "", { "optionalDependencies": { "@rivet-dev/agentos-runtime-sidecar-darwin-arm64": "0.2.14", "@rivet-dev/agentos-runtime-sidecar-darwin-x64": "0.2.14", "@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu": "0.2.14", "@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu": "0.2.14" } }, "sha512-dsA1wNg+0Y6DYRB8no962k1tAQk1y5kfdAbrpKjJQJjfgfwkv0q8XZ3ybtt1hLml/thgE32CI++8F7MRWz4TFA=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-sidecar/@rivet-dev/agentos-sidecar-darwin-arm64": ["@rivet-dev/agentos-sidecar-darwin-arm64@0.2.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-U1R4wYvlsLCdASC5Lf6oP/6bW6ONGsiILtTQSVgxIHl/J1TrmOifrAbRgDC205kThJEZQ2op8kVzol5aEWOpbA=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-sidecar/@rivet-dev/agentos-sidecar-darwin-x64": ["@rivet-dev/agentos-sidecar-darwin-x64@0.2.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-vuij3BYGjVSCGMNB3HbS0EiDS50xG68cjH3ItuZL77GPHsw5V765TOheWDVgUOo1Q3+VWjdMaS2wNWv63qCf0w=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-sidecar/@rivet-dev/agentos-sidecar-linux-arm64-gnu": ["@rivet-dev/agentos-sidecar-linux-arm64-gnu@0.2.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-nauooe07/NhHb+Wn4xvJTUMNFzhOvrNoPwceiC0eGvkK7+imRyZpAgSGB4qRiaa2NRyuNRVh+d6kzp5iKzBwnA=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-sidecar/@rivet-dev/agentos-sidecar-linux-x64-gnu": ["@rivet-dev/agentos-sidecar-linux-x64-gnu@0.2.14", "", { "os": "linux", "cpu": "x64" }, "sha512-PaGPXi5mS0Ef023nqS9lbMkMH6KGoOsHA3apAaOQz95lrmVx7E/z5BPzKYl3aYMYjmlo004mnNETVBZOy0VbQw=="],
"@code/primitives/@rivet-dev/agentos/@rivetkit/react/@rivetkit/framework-base/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
"@code/primitives/@rivet-dev/agentos/@rivetkit/react/@tanstack/react-store/@tanstack/store": ["@tanstack/store@0.7.7", "", {}, "sha512-xa6pTan1bcaqYDS9BDpSiS63qa6EoDkPN9RsRaxHuDdVDNntzq3xNwR5YKTU/V3SkSyC9T4YVOPh2zRQN0nhIQ=="],
"@expo/cli/ora/chalk/ansi-styles/color-convert": ["color-convert@1.9.3", "", { "dependencies": { "color-name": "1.1.3" } }, "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg=="],
"@expo/cli/ora/chalk/supports-color/has-flag": ["has-flag@3.0.0", "", {}, "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw=="],
@@ -4454,6 +4624,14 @@
"pkg-up/find-up/locate-path/p-locate/p-limit": ["p-limit@2.3.0", "", { "dependencies": { "p-try": "^2.0.0" } }, "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-runtime-core/@rivet-dev/agentos-runtime-sidecar/@rivet-dev/agentos-runtime-sidecar-darwin-arm64": ["@rivet-dev/agentos-runtime-sidecar-darwin-arm64@0.2.14", "", { "os": "darwin", "cpu": "arm64" }, "sha512-5pKvG7TC3lKbCMbQZptyXd3QPQyfiJ+wKqA+u5SqoP+Lqwim9C4PVSYMLUaxx0QqxliNuNu+VWif1xM91yECiw=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-runtime-core/@rivet-dev/agentos-runtime-sidecar/@rivet-dev/agentos-runtime-sidecar-darwin-x64": ["@rivet-dev/agentos-runtime-sidecar-darwin-x64@0.2.14", "", { "os": "darwin", "cpu": "x64" }, "sha512-mTSDuMXKHSpMJ3SVLCb/3sBCpOaBw0fnEsnLzVSuicuSWSzhNe4yyUeAcyz4wsuT4l+M+Z5mDH1eydfpz7nltw=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-runtime-core/@rivet-dev/agentos-runtime-sidecar/@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu": ["@rivet-dev/agentos-runtime-sidecar-linux-arm64-gnu@0.2.14", "", { "os": "linux", "cpu": "arm64" }, "sha512-bVtITOH4sNxcq8RuBMJF+Srlwa/Rl1ARZIej+MUDBR8VM7DGnBMWCaCHvYxy3JBmdP5aTb3gCwUm6e7m4/Khgw=="],
"@code/primitives/@rivet-dev/agentos/@rivet-dev/agentos-core/@rivet-dev/agentos-runtime-core/@rivet-dev/agentos-runtime-sidecar/@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu": ["@rivet-dev/agentos-runtime-sidecar-linux-x64-gnu@0.2.14", "", { "os": "linux", "cpu": "x64" }, "sha512-NOI1m456Ev06ey4O0pVnITaYA7emeoKR2lJIFJP4j9Kv0XuXpbmaz1aigfa3/SZQ7AvqOzxbNLCcH5m22iO8ng=="],
"@expo/cli/ora/chalk/ansi-styles/color-convert/color-name": ["color-name@1.1.3", "", {}, "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw=="],
"@expo/cli/ora/cli-cursor/restore-cursor/onetime/mimic-fn": ["mimic-fn@1.2.0", "", {}, "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="],

View File

@@ -0,0 +1,8 @@
FROM oven/bun:1.3.14
WORKDIR /app
COPY . .
RUN bun install --frozen-lockfile
CMD ["bun", "packages/agents/src/runner.ts"]

View File

@@ -0,0 +1,11 @@
services:
zopu-agentos-runner:
build:
context: ../../..
dockerfile: deploy/zopu-runtime/runner/Dockerfile
environment:
RIVET_ENDPOINT: ${RIVET_ENDPOINT}
RIVET_PUBLIC_ENDPOINT: ${RIVET_PUBLIC_ENDPOINT}
RIVET_RUNNER: default
RIVET_RUNNER_VERSION: ${RIVET_RUNNER_VERSION}
restart: unless-stopped

View File

@@ -18,29 +18,28 @@ Convex application backend
├── normalized product data
├── conversation turn queue
└── reactive client projections
│ service-authenticated dispatch
durable Workflow steps + service-authenticated dispatch
FLUE orchestration service
├── model calls
├── typed tools
── canonical Flue persistence in Convex
│ later execution commands
Private agent backend
├── FLUE product agents and typed tools
├── AgentOS execution environments
── Codex implementation harness
└── canonical events/results returned to Convex
│ optional attached full sandbox
Rivet Engine + AgentOS (post-Slice 1)
└── sandboxes, harnesses, and durable execution
Cube/E2B-compatible runtime (later)
```
Clients MUST communicate only with Convex. FLUE and future Rivet/AgentOS
services are private workers: Convex admits durable commands, invokes the
worker, and stores the product-facing result before clients observe it.
Clients MUST communicate only with Convex. FLUE and future Rivet/AgentOS services are private workers: Convex admits durable commands, invokes the worker, and stores the product-facing result before clients observe it.
### Ownership
| Layer | Owns |
|---|---|
| --- | --- |
| Convex | authentication, normalized product records, command admission, reactive reads |
| FLUE | private programmable orchestration and domain-specific agents |
| Rivet actors (later) | serialized execution ownership, recovery, timers, leases |
| Convex Workflow | durable sequencing, retries, cancellation, scheduling, and completion callbacks |
| Agent backend | private programmable agents and execution adapters |
| Rivet Engine + runners | placement, routing, sleep/wake, and execution ownership for AgentOS workspaces |
| Harness | bounded coding/tool loop |
| Sandbox/runtime | filesystem, processes, network, isolation |
| Git | source revision history |
@@ -63,11 +62,7 @@ signals ──< signalWorkAttachments >── works
works ──< workEvents
```
Convex mutations provide atomic transactions and optimistic serializability.
Foreign-key integrity and uniqueness are enforced in the owning mutations;
composite indexes back every identity and relation lookup. Flue's adapter
tables remain isolated infrastructure persistence and are not product-domain
relations.
Convex mutations provide atomic transactions and optimistic serializability. Foreign-key integrity and uniqueness are enforced in the owning mutations; composite indexes back every identity and relation lookup. Flue's adapter tables remain isolated infrastructure persistence and are not product-domain relations.
## 2. Domain boundaries
@@ -106,93 +101,93 @@ Avoid package proliferation in v0; logical boundaries may begin as folders.
Minimal durable model:
```ts
type Id = string
type Id = string;
interface Message {
id: Id
projectId: Id
content: string
createdAt: number
id: Id;
projectId: Id;
content: string;
createdAt: number;
}
interface Signal {
id: Id
projectId: Id
sourceType: string
sourceId: string
sourcePayloadRef?: string
summary: string
fingerprint: string
status: "candidate" | "accepted" | "dismissed"
id: Id;
projectId: Id;
sourceType: string;
sourceId: string;
sourcePayloadRef?: string;
summary: string;
fingerprint: string;
status: "candidate" | "accepted" | "dismissed";
}
interface Work {
id: Id
projectId: Id
title: string
objective: string
risk: "low" | "medium" | "high"
status: WorkStatus
definitionVersion?: number
designVersion?: number
createdAt: number
updatedAt: number
id: Id;
projectId: Id;
title: string;
objective: string;
risk: "low" | "medium" | "high";
status: WorkStatus;
definitionVersion?: number;
designVersion?: number;
createdAt: number;
updatedAt: number;
}
interface Step {
id: Id
workId: Id
sliceId?: Id
kind: "design" | "implement" | "verify" | "integrate" | "publish" | "observe"
objective: string
dependsOn: readonly Id[]
status: StepStatus
id: Id;
workId: Id;
sliceId?: Id;
kind: "design" | "implement" | "verify" | "integrate" | "publish" | "observe";
objective: string;
dependsOn: readonly Id[];
status: StepStatus;
}
interface Run {
id: Id
workId: Id
stepId: Id
kitVersion: string
status: RunStatus
id: Id;
workId: Id;
stepId: Id;
kitVersion: string;
status: RunStatus;
}
interface Attempt {
id: Id
runId: Id
number: number
harness: string
runtime: string
sourceRevision: string
status: AttemptStatus
startedAt?: number
endedAt?: number
id: Id;
runId: Id;
number: number;
harness: string;
runtime: string;
sourceRevision: string;
status: AttemptStatus;
startedAt?: number;
endedAt?: number;
}
interface Artifact {
id: Id
workId: Id
stepId?: Id
runId?: Id
attemptId?: Id
type: string
uri?: string
contentHash?: string
sourceRevision?: string
environmentId?: string
metadata: unknown
id: Id;
workId: Id;
stepId?: Id;
runId?: Id;
attemptId?: Id;
type: string;
uri?: string;
contentHash?: string;
sourceRevision?: string;
environmentId?: string;
metadata: unknown;
}
interface Question {
id: Id
workId: Id
stepId?: Id
attemptId?: Id
prompt: string
recommendation?: string
alternatives: readonly string[]
status: "open" | "answered" | "withdrawn"
answer?: string
id: Id;
workId: Id;
stepId?: Id;
attemptId?: Id;
prompt: string;
recommendation?: string;
alternatives: readonly string[];
status: "open" | "answered" | "withdrawn";
answer?: string;
}
```
@@ -337,35 +332,49 @@ Keep domain/application code provider-neutral.
```ts
interface HarnessRuntime {
open(input: OpenHarnessInput): Effect.Effect<HarnessSession, HarnessError>
prompt(id: string, content: string): Effect.Effect<void, HarnessError>
events(id: string): Stream.Stream<HarnessEvent, HarnessError>
approve(input: PermissionDecision): Effect.Effect<void, HarnessError>
abort(id: string): Effect.Effect<void, HarnessError>
close(id: string): Effect.Effect<void, HarnessError>
open(input: OpenHarnessInput): Effect.Effect<HarnessSession, HarnessError>;
prompt(id: string, content: string): Effect.Effect<void, HarnessError>;
events(id: string): Stream.Stream<HarnessEvent, HarnessError>;
approve(input: PermissionDecision): Effect.Effect<void, HarnessError>;
abort(id: string): Effect.Effect<void, HarnessError>;
close(id: string): Effect.Effect<void, HarnessError>;
}
interface SandboxRuntime {
create(spec: SandboxSpec): Effect.Effect<SandboxLease, SandboxError>
exec(lease: SandboxLease, cmd: Command): Effect.Effect<CommandResult, SandboxError>
readFile(lease: SandboxLease, path: string): Effect.Effect<Uint8Array, SandboxError>
writeFile(lease: SandboxLease, path: string, body: Uint8Array): Effect.Effect<void, SandboxError>
pause(lease: SandboxLease): Effect.Effect<void, SandboxError>
resume(id: string): Effect.Effect<SandboxLease, SandboxError>
terminate(lease: SandboxLease): Effect.Effect<void, SandboxError>
create(spec: SandboxSpec): Effect.Effect<SandboxLease, SandboxError>;
exec(
lease: SandboxLease,
cmd: Command
): Effect.Effect<CommandResult, SandboxError>;
readFile(
lease: SandboxLease,
path: string
): Effect.Effect<Uint8Array, SandboxError>;
writeFile(
lease: SandboxLease,
path: string,
body: Uint8Array
): Effect.Effect<void, SandboxError>;
pause(lease: SandboxLease): Effect.Effect<void, SandboxError>;
resume(id: string): Effect.Effect<SandboxLease, SandboxError>;
terminate(lease: SandboxLease): Effect.Effect<void, SandboxError>;
}
interface SourceControl {
prepareWorktree(input: WorktreeInput): Effect.Effect<Worktree, GitError>
diff(worktree: Worktree): Effect.Effect<DiffArtifact, GitError>
commit(input: CommitInput): Effect.Effect<CommitArtifact, GitError>
push(input: PushInput): Effect.Effect<BranchArtifact, GitError>
createPullRequest(input: PullRequestInput): Effect.Effect<PullRequestArtifact, GitError>
prepareWorktree(input: WorktreeInput): Effect.Effect<Worktree, GitError>;
diff(worktree: Worktree): Effect.Effect<DiffArtifact, GitError>;
commit(input: CommitInput): Effect.Effect<CommitArtifact, GitError>;
push(input: PushInput): Effect.Effect<BranchArtifact, GitError>;
createPullRequest(
input: PullRequestInput
): Effect.Effect<PullRequestArtifact, GitError>;
}
interface VerificationRuntime {
execute(plan: VerificationPlan, env: EnvironmentRef):
Effect.Effect<VerificationResult, VerificationError>
execute(
plan: VerificationPlan,
env: EnvironmentRef
): Effect.Effect<VerificationResult, VerificationError>;
}
```
@@ -420,6 +429,10 @@ Zopu owns Work, branches, worktrees, budgets, approvals, artifacts, and completi
## 10. Runtime strategy
### Convex orchestration
Slice 5 uses the Convex Workflow component as the durable product orchestration layer. Workflow steps call private agent-backend actions, while all user-visible state, events, artifacts, idempotency keys, and cancellation remain canonical in Convex.
### CubeSandbox
Best for full Linux execution:
@@ -443,7 +456,7 @@ Best for:
- actor-adjacent orchestration;
- context/files/networking that fit runtime limits.
Use an attached full sandbox when native/heavy tooling is needed.
Slice 5 starts here with one Codex-backed AgentOS actor and one authenticated repository checkout per project. Convex Workflow owns product orchestration; Rivet Engine coordinates placement while a normal runner executes the actor. Use an attached full sandbox through the E2B-compatible boundary when native/heavy tooling is needed.
### Persistent project machine

View File

@@ -211,16 +211,18 @@ Zopu implements one approved slice in an isolated repository environment and str
Initial adapter choice:
```text
SandboxRuntime = CubeSandboxLive
HarnessRuntime = OmpHarnessLive (or one chosen harness)
SandboxRuntime = AgentOsSandboxLive
HarnessRuntime = CodexHarnessLive
Durable orchestration = Convex Workflow
```
Flow:
```text
prepare worktree
create sandbox
→ clone/mount repo
load the project's authenticated Git connection
start durable Convex workflow
→ create AgentOS execution environment
→ clone the single configured repo
→ inject context
→ run one slice
→ normalize events
@@ -230,14 +232,15 @@ prepare worktree
Security:
- scoped Git/model tokens;
- GitHub OAuth or self-hosted Gitea PAT, scoped to one project;
- scoped Git/model tokens passed only to private execution;
- isolated HOME/worktree;
- one mutating attempt per worktree;
- timeout/cancel cleanup.
### Frontend
Current activity, changed files, artifact links, expandable raw logs.
Project selector/settings, Git connection status, current activity, changed files, artifact links, expandable raw logs, cancel/retry, and manual Git delivery controls.
### Acceptance
@@ -247,6 +250,8 @@ Current activity, changed files, artifact links, expandable raw logs.
- provider failure becomes classified attempt outcome;
- exact base/candidate revision recorded.
Rivet Engine coordinates AgentOS actor placement through a normal runner, but does not own product orchestration; Convex Workflow remains canonical for the Run lifecycle. Cube/Kubernetes sandbox support remains behind `SandboxRuntime` and can be mounted through AgentOS incrementally.
---
## Slice 6 — Independent verification and repair
@@ -490,4 +495,4 @@ browser-tester integration-coordinator
1 → 2 → 3 → 4 → 5 → 6 → 7 → 8 → 9 → 10 → 11 → 12
```
Parallel engineering is allowed *within* a slice after contracts land, but product release order remains sequential.
Parallel engineering is allowed _within_ a slice after contracts land, but product release order remains sequential.

View File

@@ -9,15 +9,21 @@
"dev": "bun --env-file=../../.env flue dev",
"dev:tailscale": "bun --env-file=../../.env flue dev",
"run": "bun --env-file=../../.env flue run",
"runner": "bun --env-file=../../.env src/runner.ts",
"run:zopu": "bun --env-file=../../.env flue run zopu",
"run:work-planner": "bun --env-file=../../.env flue run work-planner"
},
"dependencies": {
"@agentos-software/codex-cli": "0.3.4",
"@agentos-software/git": "0.3.3",
"@code/backend": "workspace:*",
"@code/env": "workspace:*",
"@code/primitives": "workspace:*",
"@flue/runtime": "latest",
"@rivet-dev/agentos": "0.2.10",
"convex": "catalog:",
"hono": "catalog:",
"rivetkit": "2.3.9",
"valibot": "catalog:"
},
"devDependencies": {

View File

@@ -2,6 +2,13 @@ import { parseAgentEnv } from "@code/env/agent";
import { registerProvider } from "@flue/runtime";
import type { Fetchable } from "@flue/runtime/routing";
import { flue } from "@flue/runtime/routing";
import { Hono } from "hono";
import {
cancelAgentOsAttempt,
executeAgentOsAttempt,
runtimeRegistry,
} from "./runtime/agent-os";
const agentEnv = parseAgentEnv(process.env);
@@ -24,5 +31,35 @@ registerProvider(agentEnv.AGENT_MODEL_PROVIDER, {
},
});
// flue() returns a complete Hono app; the Fetchable contract accepts it.
export default flue() satisfies Fetchable;
const app = new Hono();
app.post("/internal/work-attempts/execute", async (context) => {
if (
context.req.header("authorization") !== `Bearer ${agentEnv.FLUE_DB_TOKEN}`
) {
return context.json({ error: "Unauthorized" }, 401);
}
try {
return context.json(await executeAgentOsAttempt(await context.req.json()));
} catch (error) {
return context.json(
{ error: error instanceof Error ? error.message : "Execution failed" },
500
);
}
});
app.post("/internal/work-attempts/:workspaceKey/cancel", async (context) => {
if (
context.req.header("authorization") !== `Bearer ${agentEnv.FLUE_DB_TOKEN}`
) {
return context.json({ error: "Unauthorized" }, 401);
}
await cancelAgentOsAttempt(context.req.param("workspaceKey"));
return context.json({ cancelled: true });
});
app.all("/api/rivet/*", (context) => runtimeRegistry.handler(context.req.raw));
app.route("/", flue());
export default app satisfies Fetchable;

View File

@@ -0,0 +1,3 @@
import { runtimeRegistry } from "./runtime/agent-os";
await runtimeRegistry.startEnvoy();

View File

@@ -0,0 +1,213 @@
import { parseAgentEnv } from "@code/env/agent";
import { agentOS, setup } from "@rivet-dev/agentos";
import { createClient } from "@rivet-dev/agentos/client";
import { Effect } from "effect";
import {
codexSessionEnv,
makeCodexAgentOsConfig,
} from "../../../primitives/src/agent-os";
import { decodeWorkAttemptExecutionInput } from "../../../primitives/src/execution-runtime";
import type {
ExecutionEvent,
WorkAttemptExecutionResult,
} from "../../../primitives/src/execution-runtime";
const workspace = agentOS(makeCodexAgentOsConfig() as never);
export const runtimeRegistry = setup({ use: { workspace } });
const shellQuote = (value: string): string =>
`'${value.replaceAll("'", `'"'"'`)}'`;
const event = (
sequence: number,
kind: ExecutionEvent["kind"],
message: string,
metadata: Record<string, string> = {}
): ExecutionEvent => ({
kind,
message,
metadata,
occurredAt: Date.now(),
sequence,
});
const requireSuccess = (
result: { exitCode: number; stderr: string; stdout: string },
operation: string
) => {
if (result.exitCode !== 0) {
throw new Error(`${operation} failed: ${result.stderr || result.stdout}`);
}
return result.stdout.trim();
};
const gitAuthEnv = (username: string, credential: string) => ({
GIT_CONFIG_COUNT: "1",
GIT_CONFIG_KEY_0: "http.extraHeader",
GIT_CONFIG_VALUE_0: `Authorization: Basic ${Buffer.from(`${username}:${credential}`).toString("base64")}`,
});
export const executeAgentOsAttempt = async (
rawInput: unknown
): Promise<WorkAttemptExecutionResult> => {
const input = await Effect.runPromise(
decodeWorkAttemptExecutionInput(rawInput)
);
const env = parseAgentEnv(process.env);
const client = createClient<typeof runtimeRegistry>({
endpoint: env.RIVET_PUBLIC_ENDPOINT ?? env.RIVET_ENDPOINT,
});
const vm = client.workspace.getOrCreate([input.workspaceKey]);
const events: ExecutionEvent[] = [
event(0, "runtime.preparing", "AgentOS workspace selected", {
workspaceKey: input.workspaceKey,
}),
];
const authEnv = gitAuthEnv(
input.auth.username ??
(input.auth.provider === "github" ? "x-access-token" : "git"),
input.auth.credential
);
await vm.mkdir("/workspace", { recursive: true });
if (!(await vm.exists("/workspace/repository/.git"))) {
events.push(event(1, "repository.cloning", "Cloning project repository"));
const clone = await vm.execArgv(
"git",
["clone", input.repositoryUrl, "/workspace/repository"],
{
cwd: "/workspace",
env: authEnv,
}
);
requireSuccess(clone, "Repository clone");
}
const checkout = await vm.exec(
`git fetch origin ${shellQuote(input.baseBranch)} && git checkout -B ${shellQuote(`zopu/${input.runId}`)} ${shellQuote(`origin/${input.baseBranch}`)}`,
{ cwd: "/workspace/repository", env: authEnv }
);
requireSuccess(checkout, "Repository checkout");
const baseRevision = requireSuccess(
await vm.execArgv("git", ["rev-parse", "HEAD"], {
cwd: "/workspace/repository",
}),
"Base revision lookup"
);
events.push(
event(2, "repository.ready", "Repository checkout is ready", {
baseRevision,
})
);
const sessionId = `codex-${input.attemptId}`;
await vm.openSession({
additionalInstructions:
"Work only inside /workspace/repository. Do not reveal credentials. Make the requested change and run focused verification. Do not push or open a pull request.",
agent: "codex",
cwd: "/workspace/repository",
env: codexSessionEnv({
apiKey: env.AGENT_MODEL_API_KEY,
baseUrl: env.AGENT_MODEL_BASE_URL,
model: env.AGENT_MODEL_NAME,
}),
permissionPolicy: "allow_all",
sessionId,
});
events.push(
event(3, "harness.started", "Codex implementation session started")
);
const promptResult = await vm.prompt({
content: [{ text: input.prompt, type: "text" }],
idempotencyKey: input.attemptId,
sessionId,
});
events.push(
event(4, "harness.progress", "Codex implementation turn completed", {
stopReason: String(promptResult.stopReason),
})
);
const status = requireSuccess(
await vm.execArgv("git", ["status", "--porcelain"], {
cwd: "/workspace/repository",
}),
"Changed file lookup"
);
const diff = requireSuccess(
await vm.execArgv("git", ["diff", "--binary", "HEAD"], {
cwd: "/workspace/repository",
}),
"Diff collection"
);
const changedFiles = status
.split("\n")
.filter(Boolean)
.map((line) => line.slice(3).trim());
let candidateRevision = baseRevision;
if (changedFiles.length > 0) {
requireSuccess(
await vm.execArgv("git", ["add", "-A"], { cwd: "/workspace/repository" }),
"Candidate staging"
);
const tree = requireSuccess(
await vm.execArgv("git", ["write-tree"], {
cwd: "/workspace/repository",
}),
"Candidate tree creation"
);
candidateRevision = requireSuccess(
await vm.exec(
`printf %s ${shellQuote(`Zopu candidate for ${input.attemptId}`)} | git commit-tree ${shellQuote(tree)} -p ${shellQuote(baseRevision)}`,
{
cwd: "/workspace/repository",
env: {
GIT_AUTHOR_EMAIL: "agent@zopu.dev",
GIT_AUTHOR_NAME: "Zopu Agent",
GIT_COMMITTER_EMAIL: "agent@zopu.dev",
GIT_COMMITTER_NAME: "Zopu Agent",
},
}
),
"Candidate revision creation"
);
requireSuccess(
await vm.execArgv("git", ["reset"], { cwd: "/workspace/repository" }),
"Candidate index reset"
);
}
events.push(
event(
5,
"repository.changed",
`${changedFiles.length} changed file(s) collected`,
{
candidateRevision,
}
),
event(6, "runtime.completed", "AgentOS execution completed")
);
return {
baseRevision,
candidateRevision,
changedFiles,
diff,
environmentId: input.workspaceKey,
events,
summary:
changedFiles.length > 0
? `Codex changed ${changedFiles.length} file(s)`
: "Codex completed without repository changes",
};
};
export const cancelAgentOsAttempt = async (workspaceKey: string) => {
const env = parseAgentEnv(process.env);
const client = createClient<typeof runtimeRegistry>({
endpoint: env.RIVET_PUBLIC_ENDPOINT ?? env.RIVET_ENDPOINT,
});
await client.workspace.getOrCreate([workspaceKey]).cancelPrompt({});
};

View File

@@ -11,7 +11,10 @@
import type * as auth from "../auth.js";
import type * as authz from "../authz.js";
import type * as conversationMessages from "../conversationMessages.js";
import type * as crons from "../crons.js";
import type * as fluePersistence from "../fluePersistence.js";
import type * as gitConnectionData from "../gitConnectionData.js";
import type * as gitConnections from "../gitConnections.js";
import type * as healthCheck from "../healthCheck.js";
import type * as http from "../http.js";
import type * as organizations from "../organizations.js";
@@ -19,6 +22,11 @@ import type * as privateData from "../privateData.js";
import type * as projects from "../projects.js";
import type * as publicGit from "../publicGit.js";
import type * as signalRouting from "../signalRouting.js";
import type * as workArtifacts from "../workArtifacts.js";
import type * as workExecution from "../workExecution.js";
import type * as workExecutionAgent from "../workExecutionAgent.js";
import type * as workExecutionWorkflow from "../workExecutionWorkflow.js";
import type * as workPlanning from "../workPlanning.js";
import type * as works from "../works.js";
import type {
@@ -31,7 +39,10 @@ declare const fullApi: ApiFromModules<{
auth: typeof auth;
authz: typeof authz;
conversationMessages: typeof conversationMessages;
crons: typeof crons;
fluePersistence: typeof fluePersistence;
gitConnectionData: typeof gitConnectionData;
gitConnections: typeof gitConnections;
healthCheck: typeof healthCheck;
http: typeof http;
organizations: typeof organizations;
@@ -39,6 +50,11 @@ declare const fullApi: ApiFromModules<{
projects: typeof projects;
publicGit: typeof publicGit;
signalRouting: typeof signalRouting;
workArtifacts: typeof workArtifacts;
workExecution: typeof workExecution;
workExecutionAgent: typeof workExecutionAgent;
workExecutionWorkflow: typeof workExecutionWorkflow;
workPlanning: typeof workPlanning;
works: typeof works;
}>;
@@ -70,4 +86,5 @@ export declare const internal: FilterApi<
export declare const components: {
betterAuth: import("@convex-dev/better-auth/_generated/component.js").ComponentApi<"betterAuth">;
workflow: import("@convex-dev/workflow/_generated/component.js").ComponentApi<"workflow">;
};

View File

@@ -25,10 +25,14 @@ import type { DataModel } from "./dataModel.js";
* Typesafe environment variables declared in `convex.config.ts`.
*/
type Env = {
readonly AGENT_BACKEND_URL: string | undefined;
readonly FLUE_DB_TOKEN: string;
readonly FLUE_URL: string | undefined;
readonly GITEA_TOKEN: string | undefined;
readonly GITEA_URL: string | undefined;
readonly GITHUB_CLIENT_ID: string | undefined;
readonly GITHUB_CLIENT_SECRET: string | undefined;
readonly GIT_CREDENTIAL_ENCRYPTION_KEY: string | undefined;
readonly NATIVE_APP_URL: string | undefined;
readonly SITE_URL: string;
};

View File

@@ -30,6 +30,15 @@ const createAuth = (ctx: GenericCtx<DataModel>) =>
jwksRotateOnTokenGenerationError: true,
}),
],
socialProviders:
env.GITHUB_CLIENT_ID && env.GITHUB_CLIENT_SECRET
? {
github: {
clientId: env.GITHUB_CLIENT_ID,
clientSecret: env.GITHUB_CLIENT_SECRET,
},
}
: {},
trustedOrigins: [siteUrl, nativeAppUrl, "exp://"],
});

View File

@@ -1,17 +1,23 @@
import betterAuth from "@convex-dev/better-auth/convex.config";
import workflow from "@convex-dev/workflow/convex.config.js";
import { defineApp } from "convex/server";
import { v } from "convex/values";
const app = defineApp({
env: {
AGENT_BACKEND_URL: v.optional(v.string()),
FLUE_DB_TOKEN: v.string(),
FLUE_URL: v.optional(v.string()),
GITEA_TOKEN: v.optional(v.string()),
GITEA_URL: v.optional(v.string()),
GITHUB_CLIENT_ID: v.optional(v.string()),
GITHUB_CLIENT_SECRET: v.optional(v.string()),
GIT_CREDENTIAL_ENCRYPTION_KEY: v.optional(v.string()),
NATIVE_APP_URL: v.optional(v.string()),
SITE_URL: v.string(),
},
});
app.use(betterAuth);
app.use(workflow);
export default app;

View File

@@ -0,0 +1,119 @@
import { ConvexError, v } from "convex/values";
import { internalMutation, mutation, query } from "./_generated/server";
import { requireCurrentOrganization, requireProjectMember } from "./authz";
export const persist = internalMutation({
args: {
credentialCiphertext: v.string(),
credentialIv: v.string(),
credentialKind: v.union(v.literal("oauth"), v.literal("token")),
provider: v.union(v.literal("github"), v.literal("gitea")),
serverUrl: v.string(),
userId: v.string(),
username: v.optional(v.string()),
},
handler: async (ctx, args) => {
const organization = await ctx.db
.query("organizations")
.withIndex("by_createdBy_and_kind", (q) =>
q.eq("createdBy", args.userId).eq("kind", "personal")
)
.unique();
if (!organization) {
throw new ConvexError("Organization not found");
}
const existing = await ctx.db
.query("gitConnections")
.withIndex("by_organizationId_and_provider_and_serverUrl", (q) =>
q
.eq("organizationId", organization._id)
.eq("provider", args.provider)
.eq("serverUrl", args.serverUrl)
)
.unique();
const timestamp = Date.now();
if (existing) {
await ctx.db.patch(existing._id, {
credentialCiphertext: args.credentialCiphertext,
credentialIv: args.credentialIv,
credentialKind: args.credentialKind,
updatedAt: timestamp,
username: args.username,
});
return existing._id;
}
return await ctx.db.insert("gitConnections", {
connectedAt: timestamp,
credentialCiphertext: args.credentialCiphertext,
credentialIv: args.credentialIv,
credentialKind: args.credentialKind,
organizationId: organization._id,
provider: args.provider,
serverUrl: args.serverUrl,
updatedAt: timestamp,
username: args.username,
});
},
});
export const list = query({
args: {},
handler: async (ctx) => {
const { organizationId } = await requireCurrentOrganization(ctx);
const connections = await ctx.db
.query("gitConnections")
.withIndex("by_organizationId", (q) =>
q.eq("organizationId", organizationId)
)
.collect();
return connections.map((connection) => ({
connectedAt: connection.connectedAt,
credentialKind: connection.credentialKind,
id: String(connection._id),
provider: connection.provider,
serverUrl: connection.serverUrl,
username: connection.username,
}));
},
});
export const getForProject = query({
args: { projectId: v.id("projects") },
handler: async (ctx, args) => {
await requireProjectMember(ctx, args.projectId);
const project = await ctx.db.get(args.projectId);
const connection = project?.gitConnectionId
? await ctx.db.get(project.gitConnectionId)
: null;
return connection
? {
connectedAt: connection.connectedAt,
credentialKind: connection.credentialKind,
id: String(connection._id),
provider: connection.provider,
serverUrl: connection.serverUrl,
username: connection.username,
}
: null;
},
});
export const attachToProject = mutation({
args: {
connectionId: v.id("gitConnections"),
projectId: v.id("projects"),
},
handler: async (ctx, args) => {
const { organizationId } = await requireProjectMember(ctx, args.projectId);
const connection = await ctx.db.get(args.connectionId);
if (!connection || connection.organizationId !== organizationId) {
throw new ConvexError("Git connection not found");
}
await ctx.db.patch(args.projectId, {
gitConnectionId: connection._id,
updatedAt: Date.now(),
});
return { attached: true };
},
});

View File

@@ -0,0 +1,124 @@
"use node";
import { env } from "@code/env/convex";
import { decodeGitConnectionInput } from "@code/primitives/execution-runtime";
import { ConvexError, v } from "convex/values";
import { Effect } from "effect";
import { internal } from "./_generated/api";
import type { Id } from "./_generated/dataModel";
import { action } from "./_generated/server";
import { authComponent, createAuth } from "./auth";
const encryptionKey = async (): Promise<CryptoKey> => {
if (!env.GIT_CREDENTIAL_ENCRYPTION_KEY) {
throw new ConvexError("Git credential encryption is not configured");
}
const bytes = Buffer.from(env.GIT_CREDENTIAL_ENCRYPTION_KEY, "base64url");
if (bytes.byteLength !== 32) {
throw new ConvexError("Git credential encryption key must be 32 bytes");
}
return await crypto.subtle.importKey("raw", bytes, "AES-GCM", false, [
"encrypt",
"decrypt",
]);
};
const encryptCredential = async (credential: string) => {
const iv = crypto.getRandomValues(new Uint8Array(12));
const encrypted = await crypto.subtle.encrypt(
{ iv, name: "AES-GCM" },
await encryptionKey(),
new TextEncoder().encode(credential)
);
return {
credentialCiphertext: Buffer.from(encrypted).toString("base64url"),
credentialIv: Buffer.from(iv).toString("base64url"),
};
};
export const decryptCredential = async (
credentialCiphertext: string,
credentialIv: string
): Promise<string> => {
const decrypted = await crypto.subtle.decrypt(
{
iv: Buffer.from(credentialIv, "base64url"),
name: "AES-GCM",
},
await encryptionKey(),
Buffer.from(credentialCiphertext, "base64url")
);
return new TextDecoder().decode(decrypted);
};
export const connectGitea = action({
args: {
serverUrl: v.string(),
token: v.string(),
username: v.optional(v.string()),
},
handler: async (
ctx,
args
): Promise<{ connectionId: Id<"gitConnections"> }> => {
const userId = await ctx.auth.getUserIdentity().then((identity) => {
if (!identity) {
throw new ConvexError("Authentication required");
}
return identity.tokenIdentifier;
});
const connection = await Effect.runPromise(
decodeGitConnectionInput({
credential: args.token,
credentialKind: "token",
provider: "gitea",
serverUrl: args.serverUrl,
username: args.username,
})
);
const encrypted = await encryptCredential(connection.credential);
const connectionId = await ctx.runMutation(
internal.gitConnectionData.persist,
{
...encrypted,
credentialKind: connection.credentialKind,
provider: connection.provider,
serverUrl: connection.serverUrl,
userId,
username: connection.username,
}
);
return { connectionId };
},
});
export const connectGithub = action({
args: {},
handler: async (ctx): Promise<{ connectionId: Id<"gitConnections"> }> => {
const identity = await ctx.auth.getUserIdentity();
if (!identity) {
throw new ConvexError("Authentication required");
}
const { auth, headers } = await authComponent.getAuth(createAuth, ctx);
const token = await auth.api.getAccessToken({
body: { providerId: "github" },
headers,
});
if (!token.accessToken) {
throw new ConvexError("GitHub account is not connected");
}
const encrypted = await encryptCredential(token.accessToken);
const connectionId = await ctx.runMutation(
internal.gitConnectionData.persist,
{
...encrypted,
credentialKind: "oauth",
provider: "github",
serverUrl: "https://github.com",
userId: identity.tokenIdentifier,
}
);
return { connectionId };
},
});

View File

@@ -44,10 +44,28 @@ export default defineSchema({
.index("by_userId", ["userId"])
.index("by_organizationId", ["organizationId"])
.index("by_organizationId_and_userId", ["organizationId", "userId"]),
gitConnections: defineTable({
connectedAt: v.number(),
credentialCiphertext: v.string(),
credentialIv: v.string(),
credentialKind: v.union(v.literal("oauth"), v.literal("token")),
organizationId: v.id("organizations"),
provider: v.union(v.literal("github"), v.literal("gitea")),
serverUrl: v.string(),
updatedAt: v.number(),
username: v.optional(v.string()),
})
.index("by_organizationId", ["organizationId"])
.index("by_organizationId_and_provider_and_serverUrl", [
"organizationId",
"provider",
"serverUrl",
]),
projects: defineTable({
createdAt: v.number(),
defaultBranch: v.optional(v.string()),
description: v.optional(v.string()),
gitConnectionId: v.optional(v.id("gitConnections")),
name: v.string(),
normalizedSourceUrl: v.string(),
organizationId: v.id("organizations"),
@@ -314,11 +332,17 @@ export default defineSchema({
]),
workRuns: defineTable({
baseRevision: v.optional(v.string()),
candidateRevision: v.optional(v.string()),
createdAt: v.number(),
designVersion: v.optional(v.number()),
endedAt: v.optional(v.number()),
kitId: v.string(),
kitVersion: v.string(),
environmentId: v.optional(v.string()),
executionKind: v.optional(
v.union(v.literal("simulated"), v.literal("real"))
),
scenario: v.union(
v.literal("success"),
v.literal("transient-failure-then-success"),
@@ -337,6 +361,7 @@ export default defineSchema({
),
terminalClassification: v.optional(attemptClassification),
terminalSummary: v.optional(v.string()),
workflowId: v.optional(v.string()),
workId: v.id("works"),
}).index("by_work_and_createdAt", ["workId", "createdAt"]),
@@ -356,6 +381,7 @@ export default defineSchema({
),
summary: v.optional(v.string()),
workId: v.id("works"),
workspaceKey: v.optional(v.string()),
})
.index("by_runId_and_number", ["runId", "number"])
.index("by_status_and_leaseExpiresAt", ["status", "leaseExpiresAt"]),

View File

@@ -0,0 +1,80 @@
"use node";
import { env } from "@code/env/convex";
import { decodeWorkAttemptExecutionResult } from "@code/primitives/execution-runtime";
import { ConvexError, v } from "convex/values";
import { Effect } from "effect";
import { internal } from "./_generated/api";
import { internalAction } from "./_generated/server";
import { decryptCredential } from "./gitConnections";
const backendUrl = () => env.AGENT_BACKEND_URL ?? env.FLUE_URL;
export const executeAttempt = internalAction({
args: { attemptId: v.id("workAttempts") },
handler: async (ctx, args) => {
const running = await ctx.runMutation(
internal.workExecutionWorkflow.markAttemptRunning,
args
);
if (!running) {
throw new ConvexError("Attempt is no longer runnable");
}
const context = await ctx.runQuery(
internal.workExecutionWorkflow.executionContext,
args
);
const credential = await decryptCredential(
context.connection.credentialCiphertext,
context.connection.credentialIv
);
const response = await fetch(
`${backendUrl()}/internal/work-attempts/execute`,
{
body: JSON.stringify({
attemptId: String(context.attempt._id),
auth: {
credential,
provider: context.connection.provider,
serverUrl: context.connection.serverUrl,
username: context.connection.username,
},
baseBranch: context.project.defaultBranch ?? "main",
prompt: context.prompt,
repositoryUrl: context.project.sourceUrl,
runId: String(context.run._id),
workId: String(context.work._id),
workspaceKey: context.attempt.workspaceKey,
}),
headers: {
authorization: `Bearer ${env.FLUE_DB_TOKEN}`,
"content-type": "application/json",
},
method: "POST",
}
);
const payload = (await response.json()) as unknown;
if (!response.ok) {
throw new ConvexError(
typeof payload === "object" && payload && "error" in payload
? String(payload.error)
: `Agent backend returned ${response.status}`
);
}
return await Effect.runPromise(decodeWorkAttemptExecutionResult(payload));
},
});
export const cancelAttempt = internalAction({
args: { workspaceKey: v.string() },
handler: async (_ctx, args) => {
await fetch(
`${backendUrl()}/internal/work-attempts/${encodeURIComponent(args.workspaceKey)}/cancel`,
{
headers: { authorization: `Bearer ${env.FLUE_DB_TOKEN}` },
method: "POST",
}
);
},
});

View File

@@ -0,0 +1,111 @@
import { convexTest } from "convex-test";
import { anyApi } from "convex/server";
import { describe, expect, test } from "vitest";
import schema from "./schema";
const modules = import.meta.glob("./**/*.ts");
const api = anyApi;
describe("real work execution persistence", () => {
test("records revisions, activity, diff, and terminal state atomically", async () => {
const t = convexTest({ modules, schema });
const seeded = await t.run(async (ctx) => {
const organizationId = await ctx.db.insert("organizations", {
createdAt: 1,
createdBy: "user",
kind: "personal",
name: "Personal",
});
const projectId = await ctx.db.insert("projects", {
createdAt: 1,
name: "Zopu",
normalizedSourceUrl: "https://example.com/zopu",
organizationId,
repositoryPath: "puter/zopu",
sourceHost: "example.com",
sourceUrl: "https://example.com/zopu",
updatedAt: 1,
});
const workId = await ctx.db.insert("works", {
createdAt: 1,
objective: "Implement a real slice",
organizationId,
projectId,
status: "executing",
title: "Real execution",
updatedAt: 1,
});
const sliceRowId = await ctx.db.insert("workSlices", {
designVersion: 1,
objective: "Change the repo",
observableBehavior: "A diff exists",
ordinal: 0,
payloadJson: "{}",
sliceId: "slice-1",
status: "running",
title: "Implementation",
workId,
});
const runId = await ctx.db.insert("workRuns", {
createdAt: 1,
designVersion: 1,
executionKind: "real",
kitId: "coding-v0",
kitVersion: "1",
scenario: "success",
sliceId: "slice-1",
sliceRowId,
status: "running",
workId,
});
const attemptId = await ctx.db.insert("workAttempts", {
number: 1,
runId,
status: "running",
workId,
workspaceKey: "workspace-1",
});
return { attemptId, runId, workId };
});
await t.mutation(api.workExecutionWorkflow.completeAttempt, {
attemptId: seeded.attemptId,
result: {
baseRevision: "base123",
candidateRevision: "candidate456",
changedFiles: ["src/index.ts"],
diff: "+export const ready = true;",
environmentId: "workspace-1",
events: [
{
kind: "runtime.completed",
message: "completed",
metadata: {},
occurredAt: 2,
sequence: 0,
},
],
summary: "Changed one file",
},
});
const state = await t.run(async (ctx) => ({
artifacts: await ctx.db.query("workArtifacts").collect(),
attempt: await ctx.db.get(seeded.attemptId),
run: await ctx.db.get(seeded.runId),
work: await ctx.db.get(seeded.workId),
}));
expect(state.attempt?.classification).toBe("Succeeded");
expect(state.run).toMatchObject({
baseRevision: "base123",
candidateRevision: "candidate456",
terminalClassification: "Succeeded",
});
expect(state.work?.status).toBe("completed");
expect(state.artifacts[0]).toMatchObject({
kind: "diff",
sourceRevision: "candidate456",
});
});
});

View File

@@ -0,0 +1,403 @@
import { defaultCodingKitV0 } from "@code/primitives/resolver";
import { WorkflowManager } from "@convex-dev/workflow";
import type { WorkflowId } from "@convex-dev/workflow";
import { ConvexError, v } from "convex/values";
import { components, internal } from "./_generated/api";
import type { Doc, Id } from "./_generated/dataModel";
import { internalMutation, internalQuery, mutation } from "./_generated/server";
import type { MutationCtx } from "./_generated/server";
import { requireProjectMember } from "./authz";
export const workflow = new WorkflowManager(components.workflow);
const resolveReadySlice = async (
ctx: MutationCtx,
work: Doc<"works">,
sliceId?: string
) => {
if (work.designVersion === undefined) {
throw new ConvexError("Work has no approved Design to execute");
}
const slices = await ctx.db
.query("workSlices")
.withIndex("by_workId_and_designVersion", (q) =>
q.eq("workId", work._id).eq("designVersion", work.designVersion!)
)
.collect();
const slice = sliceId
? slices.find((candidate) => candidate.sliceId === sliceId)
: slices
.sort((left, right) => left.ordinal - right.ordinal)
.find((candidate) => candidate.status === "ready");
if (!slice || slice.status !== "ready") {
throw new ConvexError("Only the next ready slice can be executed");
}
return slice;
};
export const execute = workflow
.define({ args: { attemptId: v.id("workAttempts") } })
.handler(async (step, args): Promise<void> => {
try {
const result = await step.runAction(
internal.workExecutionAgent.executeAttempt,
args,
{ retry: true }
);
await step.runMutation(internal.workExecutionWorkflow.completeAttempt, {
attemptId: args.attemptId,
result: {
...result,
changedFiles: [...result.changedFiles],
events: result.events.map((item) => ({
...item,
metadata: { ...item.metadata },
})),
},
});
} catch (error) {
await step.runMutation(internal.workExecutionWorkflow.failAttempt, {
attemptId: args.attemptId,
summary: error instanceof Error ? error.message : "Execution failed",
});
}
});
export const startExecution = mutation({
args: {
sliceId: v.optional(v.string()),
workId: v.id("works"),
},
handler: async (
ctx,
args
): Promise<{
attemptId: Id<"workAttempts">;
runId: Id<"workRuns">;
workflowId: WorkflowId;
}> => {
const work = await ctx.db.get(args.workId);
if (!work) {
throw new ConvexError("Work not found");
}
await requireProjectMember(ctx, work.projectId);
if (work.status !== "ready") {
throw new ConvexError("Work must be Ready before execution");
}
if (
work.definitionApprovalVersion !== work.definitionVersion ||
work.designApprovalVersion !== work.designVersion
) {
throw new ConvexError("Execution requires exact approved versions");
}
const project = await ctx.db.get(work.projectId);
if (!project?.gitConnectionId) {
throw new ConvexError("Connect Git credentials to this project first");
}
const slice = await resolveReadySlice(ctx, work, args.sliceId);
const createdAt = Date.now();
const runId = await ctx.db.insert("workRuns", {
createdAt,
designVersion: slice.designVersion,
executionKind: "real",
kitId: defaultCodingKitV0.id,
kitVersion: defaultCodingKitV0.version,
scenario: "success",
sliceId: slice.sliceId,
sliceRowId: slice._id,
status: "running",
workId: work._id,
});
const workspaceKey = `work-${work._id}-run-${runId}`;
const attemptId = await ctx.db.insert("workAttempts", {
number: 1,
runId,
status: "queued",
workId: work._id,
workspaceKey,
});
const workflowId: WorkflowId = await workflow.start(
ctx,
internal.workExecutionWorkflow.execute,
{ attemptId }
);
await ctx.db.patch(runId, { startedAt: createdAt, workflowId });
await ctx.db.patch(slice._id, { status: "running" });
await ctx.db.patch(work._id, { status: "executing", updatedAt: createdAt });
await ctx.db.insert("workEvents", {
createdAt,
idempotencyKey: `real-run-started:${runId}`,
kind: "run.started",
referenceId: String(runId),
workId: work._id,
});
return { attemptId, runId, workflowId };
},
});
export const executionContext = internalQuery({
args: { attemptId: v.id("workAttempts") },
handler: async (ctx, args) => {
const attempt = await ctx.db.get(args.attemptId);
if (!attempt) {
throw new ConvexError("Attempt not found");
}
const run = await ctx.db.get(attempt.runId);
const work = await ctx.db.get(attempt.workId);
if (!run || !work || !run.sliceRowId) {
throw new ConvexError("Execution records are incomplete");
}
const [slice, project] = await Promise.all([
ctx.db.get(run.sliceRowId),
ctx.db.get(work.projectId),
]);
if (!slice || !project?.gitConnectionId) {
throw new ConvexError("Project execution configuration is incomplete");
}
const connection = await ctx.db.get(project.gitConnectionId);
if (!connection) {
throw new ConvexError("Git connection not found");
}
return {
attempt,
connection,
project,
prompt: [
`Implement this approved Zopu slice: ${slice.title}`,
`Objective: ${slice.objective}`,
`Observable behavior: ${slice.observableBehavior}`,
"Inspect the repository instructions first. Make focused changes and run relevant checks.",
].join("\n\n"),
run,
work,
};
},
});
export const markAttemptRunning = internalMutation({
args: { attemptId: v.id("workAttempts") },
handler: async (ctx, args) => {
const attempt = await ctx.db.get(args.attemptId);
if (!attempt || attempt.status !== "queued") {
return false;
}
await ctx.db.patch(attempt._id, {
startedAt: Date.now(),
status: "running",
});
return true;
},
});
const settleSliceAndWork = async (
ctx: MutationCtx,
run: Doc<"workRuns">,
succeeded: boolean
) => {
if (!run.sliceRowId) {
return;
}
const slice = await ctx.db.get(run.sliceRowId);
if (!slice) {
return;
}
await ctx.db.patch(slice._id, { status: succeeded ? "completed" : "ready" });
const work = await ctx.db.get(run.workId);
if (!work) {
return;
}
let status: Doc<"works">["status"] = succeeded ? "completed" : "failed";
if (succeeded) {
const slices = await ctx.db
.query("workSlices")
.withIndex("by_workId_and_designVersion", (q) =>
q.eq("workId", work._id).eq("designVersion", slice.designVersion)
)
.collect();
const next = slices
.sort((left, right) => left.ordinal - right.ordinal)
.find((candidate) => candidate.status === "planned");
if (next) {
await ctx.db.patch(next._id, { status: "ready" });
status = "ready";
}
}
await ctx.db.patch(work._id, { status, updatedAt: Date.now() });
};
export const completeAttempt = internalMutation({
args: {
attemptId: v.id("workAttempts"),
result: v.object({
baseRevision: v.string(),
candidateRevision: v.string(),
changedFiles: v.array(v.string()),
diff: v.string(),
environmentId: v.string(),
events: v.array(
v.object({
kind: v.string(),
message: v.string(),
metadata: v.record(v.string(), v.string()),
occurredAt: v.number(),
sequence: v.number(),
})
),
summary: v.string(),
}),
},
handler: async (ctx, args) => {
const attempt = await ctx.db.get(args.attemptId);
if (!attempt || attempt.status === "terminal") {
return;
}
const run = await ctx.db.get(attempt.runId);
const work = await ctx.db.get(attempt.workId);
if (!run || !work) {
throw new ConvexError("Execution records not found");
}
for (const item of args.result.events) {
await ctx.db.insert("workAttemptEvents", {
attemptId: attempt._id,
kind: item.kind,
message: item.message,
metadataJson: JSON.stringify(item.metadata),
occurredAt: item.occurredAt,
sequence: item.sequence,
});
}
const endedAt = Date.now();
await ctx.db.patch(attempt._id, {
classification: "Succeeded",
endedAt,
status: "terminal",
summary: args.result.summary,
});
await ctx.db.patch(run._id, {
baseRevision: args.result.baseRevision,
candidateRevision: args.result.candidateRevision,
endedAt,
environmentId: args.result.environmentId,
status: "terminal",
terminalClassification: "Succeeded",
terminalSummary: args.result.summary,
});
await ctx.db.insert("workArtifacts", {
attemptId: attempt._id,
createdAt: endedAt,
designVersion: run.designVersion,
environmentId: args.result.environmentId,
idempotencyKey: `real-diff:${attempt._id}`,
kind: "diff",
metadataJson: JSON.stringify({ changedFiles: args.result.changedFiles }),
organizationId: work.organizationId,
producer: "agentos-codex",
projectId: work.projectId,
provenanceJson: JSON.stringify({
baseRevision: args.result.baseRevision,
}),
runId: run._id,
sliceId: run.sliceId,
sourceRevision: args.result.candidateRevision,
title: "Implementation diff",
verificationStatus: "unverified",
workId: work._id,
...(args.result.diff.length > 0
? {
uri: `data:text/plain;charset=utf-8,${encodeURIComponent(args.result.diff.slice(0, 50_000))}`,
}
: {}),
});
await settleSliceAndWork(ctx, run, true);
await ctx.db.insert("workEvents", {
createdAt: endedAt,
idempotencyKey: `real-run-completed:${run._id}`,
kind: "run.completed",
payloadJson: JSON.stringify({ classification: "Succeeded" }),
referenceId: String(run._id),
workId: work._id,
});
},
});
export const failAttempt = internalMutation({
args: { attemptId: v.id("workAttempts"), summary: v.string() },
handler: async (ctx, args) => {
const attempt = await ctx.db.get(args.attemptId);
if (!attempt || attempt.status === "terminal") {
return;
}
const run = await ctx.db.get(attempt.runId);
if (!run) {
return;
}
const endedAt = Date.now();
await ctx.db.patch(attempt._id, {
classification: "PermanentFailure",
endedAt,
status: "terminal",
summary: args.summary,
});
await ctx.db.patch(run._id, {
endedAt,
status: "terminal",
terminalClassification: "PermanentFailure",
terminalSummary: args.summary,
});
await settleSliceAndWork(ctx, run, false);
},
});
export const cancelExecution = mutation({
args: { runId: v.id("workRuns") },
handler: async (ctx, args) => {
const run = await ctx.db.get(args.runId);
if (!run) {
throw new ConvexError("Run not found");
}
await requireProjectMember(ctx, (await ctx.db.get(run.workId))!.projectId);
if (run.status !== "running") {
return { cancelled: false };
}
if (run.workflowId) {
await workflow.cancel(ctx, run.workflowId as WorkflowId);
}
const attempts = await ctx.db
.query("workAttempts")
.withIndex("by_runId_and_number", (q) => q.eq("runId", run._id))
.collect();
const attempt = attempts.find(
(candidate) => candidate.status !== "terminal"
);
if (attempt?.workspaceKey) {
await ctx.scheduler.runAfter(
0,
internal.workExecutionAgent.cancelAttempt,
{
workspaceKey: attempt.workspaceKey,
}
);
await ctx.db.patch(attempt._id, {
classification: "Cancelled",
endedAt: Date.now(),
status: "terminal",
summary: "Execution cancelled",
});
}
await ctx.db.patch(run._id, {
endedAt: Date.now(),
status: "cancelled",
terminalClassification: "Cancelled",
terminalSummary: "Execution cancelled",
});
if (run.sliceRowId) {
await ctx.db.patch(run.sliceRowId, { status: "ready" });
}
const work = await ctx.db.get(run.workId);
if (work) {
await ctx.db.patch(work._id, { status: "ready", updatedAt: Date.now() });
}
return { cancelled: true };
},
});

View File

@@ -771,13 +771,41 @@ export const listForProject = query({
.eq("designVersion", work.designVersion ?? 0)
)
.collect();
const runs = await ctx.db
const runRows = await ctx.db
.query("workRuns")
.withIndex("by_work_and_createdAt", (q: any) =>
q.eq("workId", work._id)
)
.order("desc")
.take(10);
const runs = await Promise.all(
runRows.map(async (run) => {
const attempts = await ctx.db
.query("workAttempts")
.withIndex("by_runId_and_number", (q) => q.eq("runId", run._id))
.collect();
const eventsByAttempt = await Promise.all(
attempts.map((attempt) =>
ctx.db
.query("workAttemptEvents")
.withIndex("by_attempt_and_sequence", (q: any) =>
q.eq("attemptId", attempt._id)
)
.collect()
)
);
const attemptEvents = eventsByAttempt
.flat()
.sort((left, right) => left.occurredAt - right.occurredAt);
const artifacts = await ctx.db
.query("workArtifacts")
.withIndex("by_runId_and_createdAt", (q) =>
q.eq("runId", run._id)
)
.collect();
return { ...run, artifacts, attemptEvents, attempts };
})
);
const events = await ctx.db
.query("workEvents")
.withIndex("by_work_and_createdAt", (q: any) =>

View File

@@ -16,6 +16,7 @@
"@code/env": "workspace:*",
"@code/primitives": "workspace:*",
"@convex-dev/better-auth": "catalog:",
"@convex-dev/workflow": "0.4.4",
"better-auth": "catalog:",
"convex": "catalog:",
"effect": "catalog:",

View File

@@ -14,6 +14,8 @@ const agentEnvSchema = z.object({
GITEA_TOKEN: z.string().min(1).optional(),
GITEA_URL: z.url().default("https://git.openputer.com"),
OPENROUTER_API_KEY: z.string().min(1).optional(),
RIVET_ENDPOINT: z.url(),
RIVET_PUBLIC_ENDPOINT: z.url().optional(),
});
export type AgentEnv = z.infer<typeof agentEnvSchema>;

View File

@@ -5,10 +5,15 @@ export const env = createEnv({
emptyStringAsUndefined: true,
runtimeEnv: process.env,
server: {
AGENT_BACKEND_URL: z.url().optional(),
CONVEX_SITE_URL: z.url(),
FLUE_DB_TOKEN: z.string().min(1),
FLUE_URL: z.url().optional(),
GITEA_TOKEN: z.string().min(1).optional(),
GITEA_URL: z.url().default("https://git.openputer.com"),
GITHUB_CLIENT_ID: z.string().min(1).optional(),
GITHUB_CLIENT_SECRET: z.string().min(1).optional(),
GIT_CREDENTIAL_ENCRYPTION_KEY: z.string().min(43).optional(),
NATIVE_APP_URL: z.string().min(1).default("code://"),
SITE_URL: z.url(),
},

View File

@@ -6,6 +6,7 @@
"exports": {
".": "./src/index.ts",
"./agent-os": "./src/agent-os.ts",
"./execution-runtime": "./src/execution-runtime.ts",
"./git": "./src/git.ts",
"./git-local-runtime": "./src/git-local-runtime.ts",
"./git-remote-runtime": "./src/git-remote-runtime.ts",

View File

@@ -0,0 +1,38 @@
import { Effect } from "effect";
import { describe, expect, test } from "vitest";
import {
decodeGitConnectionInput,
decodeWorkAttemptExecutionResult,
} from "./execution-runtime";
describe("execution runtime contracts", () => {
test("accepts one authenticated Gitea connection", async () => {
const decoded = await Effect.runPromise(
decodeGitConnectionInput({
credential: "secret",
credentialKind: "token",
provider: "gitea",
serverUrl: "https://git.example.com",
username: "zopu",
})
);
expect(decoded.provider).toBe("gitea");
});
test("requires exact base and candidate revisions", async () => {
await expect(
Effect.runPromise(
decodeWorkAttemptExecutionResult({
baseRevision: "",
candidateRevision: "abc123",
changedFiles: [],
diff: "",
environmentId: "workspace-1",
events: [],
summary: "done",
})
)
).rejects.toMatchObject({ reason: "InvalidInput" });
});
});

View File

@@ -0,0 +1,155 @@
/* eslint-disable max-classes-per-file -- execution boundary errors live with their schemas. */
import { Effect, Schema } from "effect";
const Text = Schema.String.check(
Schema.makeFilter((value) => value.trim().length > 0, {
expected: "a non-empty string",
})
);
const HttpUrl = Schema.String.check(
Schema.makeFilter(
(value) => {
try {
const url = new URL(value);
return url.protocol === "http:" || url.protocol === "https:";
} catch {
return false;
}
},
{ expected: "an HTTP URL" }
)
);
export const GitProvider = Schema.Literals(["github", "gitea"]);
export type GitProvider = typeof GitProvider.Type;
export const GitCredentialKind = Schema.Literals(["oauth", "token"]);
export type GitCredentialKind = typeof GitCredentialKind.Type;
export const GitConnectionInput = Schema.Struct({
credential: Text,
credentialKind: GitCredentialKind,
provider: GitProvider,
serverUrl: HttpUrl,
username: Schema.optional(Text),
});
export type GitConnectionInput = typeof GitConnectionInput.Type;
export const GitConnectionView = Schema.Struct({
connectedAt: Schema.Number,
credentialKind: GitCredentialKind,
id: Text,
provider: GitProvider,
serverUrl: HttpUrl,
username: Schema.optional(Text),
});
export type GitConnectionView = typeof GitConnectionView.Type;
export const RepositoryExecutionAuth = Schema.Struct({
credential: Text,
provider: GitProvider,
serverUrl: HttpUrl,
username: Schema.optional(Text),
});
export type RepositoryExecutionAuth = typeof RepositoryExecutionAuth.Type;
export const ExecutionEventKind = Schema.Literals([
"runtime.preparing",
"repository.cloning",
"repository.ready",
"harness.started",
"harness.progress",
"harness.log",
"repository.changed",
"runtime.completed",
"runtime.failed",
"runtime.cancelled",
]);
export type ExecutionEventKind = typeof ExecutionEventKind.Type;
export const ExecutionEvent = Schema.Struct({
kind: ExecutionEventKind,
message: Text,
metadata: Schema.Record(Schema.String, Schema.String),
occurredAt: Schema.Number,
sequence: Schema.Int,
});
export type ExecutionEvent = typeof ExecutionEvent.Type;
export const WorkAttemptExecutionInput = Schema.Struct({
attemptId: Text,
auth: RepositoryExecutionAuth,
baseBranch: Text,
prompt: Text,
repositoryUrl: HttpUrl,
runId: Text,
workId: Text,
workspaceKey: Text,
});
export type WorkAttemptExecutionInput = typeof WorkAttemptExecutionInput.Type;
export const WorkAttemptExecutionResult = Schema.Struct({
baseRevision: Text,
candidateRevision: Text,
changedFiles: Schema.Array(Text),
diff: Schema.String,
environmentId: Text,
events: Schema.Array(ExecutionEvent),
summary: Text,
});
export type WorkAttemptExecutionResult = typeof WorkAttemptExecutionResult.Type;
export const WorkAttemptExecutionErrorReason = Schema.Literals([
"Authentication",
"Cancelled",
"HarnessFailed",
"InvalidInput",
"ProviderUnavailable",
"RepositoryFailed",
"Timeout",
]);
export type WorkAttemptExecutionErrorReason =
typeof WorkAttemptExecutionErrorReason.Type;
export class WorkAttemptExecutionError extends Schema.TaggedErrorClass<WorkAttemptExecutionError>()(
"WorkAttemptExecutionError",
{
message: Schema.String,
reason: WorkAttemptExecutionErrorReason,
retryable: Schema.Boolean,
}
) {}
const invalidInput = (message: string) =>
new WorkAttemptExecutionError({
message,
reason: "InvalidInput",
retryable: false,
});
export const decodeGitConnectionInput = (input: unknown) =>
Schema.decodeUnknownEffect(GitConnectionInput)(input).pipe(
Effect.mapError((cause) => invalidInput(cause.message))
);
export const decodeWorkAttemptExecutionInput = (input: unknown) =>
Schema.decodeUnknownEffect(WorkAttemptExecutionInput)(input).pipe(
Effect.mapError((cause) => invalidInput(cause.message))
);
export const decodeWorkAttemptExecutionResult = (input: unknown) =>
Schema.decodeUnknownEffect(WorkAttemptExecutionResult)(input).pipe(
Effect.mapError((cause) => invalidInput(cause.message))
);
export interface SandboxRuntime {
readonly name: string;
readonly execute: (
input: WorkAttemptExecutionInput,
signal?: AbortSignal
) => Effect.Effect<WorkAttemptExecutionResult, WorkAttemptExecutionError>;
readonly cancel: (
workspaceKey: string
) => Effect.Effect<void, WorkAttemptExecutionError>;
}

View File

@@ -1,5 +1,6 @@
// oxlint-disable-next-line no-barrel-file -- The package root intentionally exposes its public modules.
export * from "./agent-os";
export * from "./execution-runtime";
export * from "./git";
export * from "./git-local-runtime";
export * from "./git-remote-runtime";