@fungi.computer/oyster 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/dist/agent-computer-source.d.ts +42 -0
  2. package/dist/agent-computer-source.js +88 -0
  3. package/dist/agent-computers.d.ts +104 -0
  4. package/dist/agent-computers.js +227 -0
  5. package/dist/agents.d.ts +10 -0
  6. package/dist/agents.js +33 -0
  7. package/dist/app-builds.d.ts +1 -1
  8. package/dist/app-builds.js +16 -6
  9. package/dist/boot-capability.d.ts +2 -1
  10. package/dist/boot-capability.js +7 -5
  11. package/dist/browser/boot.d.ts +2 -2
  12. package/dist/browser/boot.js +10 -3
  13. package/dist/browser/browser.d.ts +1 -1
  14. package/dist/browser/browser.js +2 -1
  15. package/dist/browser/cdp-client.d.ts +2 -0
  16. package/dist/browser/errors.d.ts +2 -2
  17. package/dist/browser/errors.js +2 -2
  18. package/dist/browser/index.d.ts +3 -2
  19. package/dist/browser/index.js +3 -2
  20. package/dist/browser/page.js +11 -4
  21. package/dist/browser/sessions.d.ts +7 -4
  22. package/dist/browser/sessions.js +159 -0
  23. package/dist/browser/url-policy.d.ts +4 -2
  24. package/dist/browser/url-policy.js +4 -2
  25. package/dist/build/build-jobs.d.ts +3 -3
  26. package/dist/build/build-jobs.js +10 -5
  27. package/dist/build/candidate-cli.js +5 -3
  28. package/dist/build/candidate-cli.mjs +223 -5
  29. package/dist/build/candidate-diagnostic.d.ts +2 -0
  30. package/dist/build/candidate-diagnostic.js +16 -0
  31. package/dist/computer-control-port.d.ts +26 -0
  32. package/dist/computer-control-port.js +1 -0
  33. package/dist/host.d.ts +3 -0
  34. package/dist/machine-link/delivery.d.ts +1 -1
  35. package/dist/machine-link/delivery.js +2 -3
  36. package/dist/machine-link/host.d.ts +37 -6
  37. package/dist/machine-link/host.js +209 -14
  38. package/dist/machine-link/link.d.ts +13 -1
  39. package/dist/machine-link/link.js +20 -7
  40. package/dist/mcp.d.ts +144 -10
  41. package/dist/mcp.js +130 -13
  42. package/dist/page/computer-handles.d.ts +3 -3
  43. package/dist/page-script.js +1 -1
  44. package/dist/standalone/agent-computers.d.ts +29 -0
  45. package/dist/standalone/agent-computers.js +101 -0
  46. package/dist/standalone/agent-mail.d.ts +41 -18
  47. package/dist/standalone/agent-model-choice.d.ts +29 -0
  48. package/dist/standalone/agent-model-choice.js +72 -0
  49. package/dist/standalone/agents.d.ts +44 -4
  50. package/dist/standalone/agents.js +502 -46
  51. package/dist/standalone/app-set.d.ts +8 -1
  52. package/dist/standalone/app-set.js +46 -31
  53. package/dist/standalone/computer-control.d.ts +4 -0
  54. package/dist/standalone/computer-control.js +62 -0
  55. package/dist/standalone/computer-fleet.d.ts +1 -0
  56. package/dist/standalone/computer-fleet.js +1 -1
  57. package/dist/standalone/computer.d.ts +21 -2
  58. package/dist/standalone/computer.js +12 -0
  59. package/dist/standalone/install-apps-bin.d.ts +2 -0
  60. package/dist/standalone/install-apps-bin.js +3 -0
  61. package/dist/standalone/install-apps-cli.d.ts +3 -1
  62. package/dist/standalone/install-apps-cli.js +27 -17
  63. package/dist/standalone/machine-link.d.ts +10 -0
  64. package/dist/standalone/machine-link.js +6 -0
  65. package/dist/standalone/registry.d.ts +10 -1
  66. package/dist/standalone/registry.js +9 -0
  67. package/dist/standalone/worker.js +12 -0
  68. package/dist/standalone/workflow-binding.d.ts +2 -2
  69. package/dist/standalone/workflow-host.d.ts +11 -11
  70. package/dist/standalone/workflows.d.ts +22 -22
  71. package/dist/storage-frame.d.ts +3 -3
  72. package/dist/workers-git.d.ts +2 -0
  73. package/dist/workers-git.js +2 -0
  74. package/dist/workers.d.ts +8 -8
  75. package/dist/workers.js +9 -1
  76. package/docs/api/agents.md +66 -0
  77. package/docs/api/apps.md +104 -104
  78. package/docs/api/build-contract.md +35 -35
  79. package/docs/api/build.md +12 -12
  80. package/docs/api/host.md +61 -61
  81. package/docs/api/mcp.md +127 -13
  82. package/docs/api/root-data.md +1 -1
  83. package/docs/api/tenancy.md +1 -1
  84. package/docs/api/workers-git.md +3 -2
  85. package/docs/api/workers.md +81 -83
  86. package/package.json +26 -18
@@ -0,0 +1,29 @@
1
+ import { Hono } from "hono";
2
+ import { type ComputerGrant } from "@fungi.computer/computer/fleet";
3
+ import { type AgentComputerProjection, type ComputerAttachmentInput } from "../agent-computers.js";
4
+ import type { AgentComputerConnection, AgentComputerPorts } from "../agent-computer-source.js";
5
+ import { type OysterEnv, type OysterPrincipal } from "../host.js";
6
+ import type { StandaloneAgentComputerRpc } from "./computer.js";
7
+ /** The directory supplies live authority; this adapter never invents a grant. */
8
+ export type StandaloneAgentComputerAccess = Readonly<{
9
+ admit: (connection: AgentComputerConnection) => Promise<ComputerGrant>;
10
+ computer: (computerId: string) => Rpc.Provider<StandaloneAgentComputerRpc>;
11
+ }>;
12
+ /** Native operations use the captured Computer, never the mutable workspace selection. */
13
+ export declare function standaloneAgentComputerPorts(access: StandaloneAgentComputerAccess, connection: AgentComputerConnection): AgentComputerPorts;
14
+ /** Persisted command outcome, with no fabricated attachment result on refusal. */
15
+ export type StandaloneAgentComputerReply = Readonly<{
16
+ kind: "ok";
17
+ projection: AgentComputerProjection;
18
+ }> | Readonly<{
19
+ kind: "refused";
20
+ error: "not_granted" | "not_found" | "request_conflict" | "attachment_identity_conflict";
21
+ }>;
22
+ /** Principal and persisted attachment transitions belong to the directory owner. */
23
+ export type StandaloneAgentComputerControl = Readonly<{
24
+ attach: (principal: OysterPrincipal, command: ComputerAttachmentInput) => Promise<StandaloneAgentComputerReply>;
25
+ detach: (principal: OysterPrincipal, command: ComputerAttachmentInput) => Promise<StandaloneAgentComputerReply>;
26
+ read: (principal: OysterPrincipal, agentId: string) => Promise<StandaloneAgentComputerReply>;
27
+ }>;
28
+ /** Owner HTTP transport over the retained attachment command grammar. */
29
+ export declare function standaloneAgentComputerRoutes(control: StandaloneAgentComputerControl): Hono<OysterEnv>;
@@ -0,0 +1,101 @@
1
+ import { Hono } from "hono";
2
+ import { createComputerFilesPort } from "@fungi.computer/computer";
3
+ import { checkComputerGrant, FleetGrantRefused, } from "@fungi.computer/computer/fleet";
4
+ import { computerCapabilities, computerValueSchema, } from "@fungi.computer/computer-contract";
5
+ import { attachComputerInputSchema, detachComputerInputSchema, readAgentComputersInputSchema, } from "../agent-computers.js";
6
+ import { oysterPrincipalIsOwner, } from "../host.js";
7
+ /** Native operations use the captured Computer, never the mutable workspace selection. */
8
+ export function standaloneAgentComputerPorts(access, connection) {
9
+ const { computerId } = connection.attachment;
10
+ async function authorized(action) {
11
+ const grant = await access.admit(connection);
12
+ if (checkComputerGrant(grant, {
13
+ computerId,
14
+ action,
15
+ now: Date.now(),
16
+ }).kind !== "admitted")
17
+ throw new FleetGrantRefused();
18
+ return grant;
19
+ }
20
+ // Constructing or advertising this port opens no native handle or Workspace.
21
+ async function withFiles(action, context, use) {
22
+ context.signal.throwIfAborted();
23
+ await authorized(action);
24
+ context.signal.throwIfAborted();
25
+ return use(createComputerFilesPort(access.computer(computerId)));
26
+ }
27
+ return {
28
+ files: {
29
+ patch: async (input, context) => {
30
+ context.signal.throwIfAborted();
31
+ const grant = await authorized("files.edit");
32
+ context.signal.throwIfAborted();
33
+ return access.computer(computerId).filePatch(grant, input);
34
+ },
35
+ read: (input, context) => withFiles("files.readBytes", context, (files) => files.read(input, context)),
36
+ list: (input, context) => withFiles("files.list", context, (files) => files.list(input, context)),
37
+ glob: (input, context) => withFiles("files.glob", context, (files) => files.glob(input, context)),
38
+ grep: (input, context) => withFiles("files.grep", context, (files) => files.grep(input, context)),
39
+ replace: (input, context) => withFiles("files.edit", context, (files) => files.replace(input, context)),
40
+ },
41
+ computer: {
42
+ getCapabilities: (signal) => {
43
+ signal.throwIfAborted();
44
+ return Promise.resolve(computerValueSchema.parse(computerCapabilities()));
45
+ },
46
+ call: async (capabilityId, input, context) => {
47
+ context.signal.throwIfAborted();
48
+ // tool() retains the native advertised-operation/action mapping and decoders.
49
+ const grant = await access.admit(connection);
50
+ context.signal.throwIfAborted();
51
+ return computerValueSchema.parse(await access.computer(computerId).tool(grant, capabilityId, input));
52
+ },
53
+ },
54
+ };
55
+ }
56
+ /** Owner HTTP transport over the retained attachment command grammar. */
57
+ export function standaloneAgentComputerRoutes(control) {
58
+ const routes = new Hono();
59
+ routes.post("/api/agents/:agentId/computers/:operation", async (context) => {
60
+ context.header("Cache-Control", "no-store");
61
+ const principal = context.get("principal");
62
+ if (!oysterPrincipalIsOwner(principal))
63
+ return context.json({ error: "not_granted" }, 403);
64
+ const operation = context.req.param("operation");
65
+ if (!["attach", "detach", "read"].includes(operation))
66
+ return context.json({ error: "not_found" }, 404);
67
+ let body;
68
+ try {
69
+ body = await context.req.json();
70
+ }
71
+ catch (error) {
72
+ if (!(error instanceof SyntaxError))
73
+ throw error;
74
+ return context.json({ error: "invalid_input" }, 400);
75
+ }
76
+ const schema = operation === "attach"
77
+ ? attachComputerInputSchema
78
+ : operation === "detach"
79
+ ? detachComputerInputSchema
80
+ : readAgentComputersInputSchema;
81
+ const decoded = schema.safeParse(body);
82
+ if (!decoded.success)
83
+ return context.json({ error: "invalid_input" }, 400);
84
+ if (decoded.data.agentId !== context.req.param("agentId"))
85
+ return context.json({ error: "not_found" }, 404);
86
+ const result = operation === "read"
87
+ ? await control.read(principal, decoded.data.agentId)
88
+ : operation === "attach"
89
+ ? await control.attach(principal, attachComputerInputSchema.parse(decoded.data))
90
+ : await control.detach(principal, detachComputerInputSchema.parse(decoded.data));
91
+ if (result.kind === "ok")
92
+ return context.json(result.projection);
93
+ const status = result.error === "not_granted"
94
+ ? 403
95
+ : result.error === "not_found"
96
+ ? 404
97
+ : 409;
98
+ return context.json({ error: result.error }, status);
99
+ });
100
+ return routes;
101
+ }
@@ -1,24 +1,47 @@
1
+ import type { WatchdogTickResult } from "@fungi.computer/watchdog";
1
2
  import { AgentMail, agentMailRoute } from "@fungi.computer/shiitake/delegation";
2
3
  /** Standalone borrows Shiitake's one Watchdog and Carrier's ordinary durable lane. */
3
4
  export declare function agentMail(options: Omit<ConstructorParameters<typeof AgentMail>[0], "post" | "drain"> & {
4
5
  namespace: Parameters<typeof agentMailRoute>[0];
5
6
  }): {
6
- host: Required<Pick<Readonly<{
7
- meta?: import("@fungi.computer/shiitake").HostMetaOptions;
8
- model: import("@fungi.computer/shiitake").ModelSource;
9
- instructions: import("@fungi.computer/shiitake").InstructionSource;
10
- tools?: readonly [] | import("@fungi.computer/shiitake/cloudflare").CloudflareShiitakeTools;
11
- storagePressure?: import("@fungi.computer/shiitake").StoragePressureCheck;
12
- compaction?: import("@fungi.computer/shiitake").CompactionOptions;
13
- extensions: import("@fungi.computer/shiitake").ExtensionRosterV0;
14
- initialize?: (agent: import("@fungi.computer/shiitake").ShiitakeOwnerAgent) => Promise<void>;
15
- hostWork?: readonly import("@fungi.computer/shiitake/cloudflare").CloudflareHostWork[];
16
- hostJobs?: import("@fungi.computer/shiitake/cloudflare").CloudflareHostJobs;
17
- mailRoom?: import("@fungi.computer/bird-dog/effect").BirdDogEffect;
18
- acp?: (agent: import("@fungi.computer/shiitake").ShiitakeOwnerAgent) => Promise<import("@fungi.computer/shiitake/cloudflare").CloudflareShiitakeAcpServer>;
19
- }>, "mailRoom" | "hostJobs" | "hostWork">>;
20
- deliver: (value: Parameters<AgentMail["send"]>[0]) => Promise<Readonly<{
21
- status: "accepted";
22
- commandId: string;
23
- }>>;
7
+ host: {
8
+ mailRoom: Readonly<{
9
+ fanOut: (settlement: import("@fungi.computer/bird-dog").BirdDogSettlement) => import("effect/Effect").Effect<void, import("@fungi.computer/bird-dog/effect").BirdDogError>;
10
+ postMail?: ((mail: import("@fungi.computer/bird-dog").BirdDogMail) => import("effect/Effect").Effect<void, import("@fungi.computer/bird-dog/effect").BirdDogError>) | undefined;
11
+ drainOutbox: () => import("effect/Effect").Effect<void, import("@fungi.computer/bird-dog/effect").BirdDogError>;
12
+ nextWakeAt: () => import("effect/Effect").Effect<number | undefined, import("@fungi.computer/bird-dog/effect").BirdDogError>;
13
+ }> & {
14
+ stageAcceptedNotice: (mail: import("@fungi.computer/bird-dog").BirdDogMail, scopeId: string) => void;
15
+ };
16
+ hostJobs: {
17
+ lane: string;
18
+ open: (owner: Readonly<{
19
+ transactional: import("@fungi.computer/watchdog").WatchdogTransactionalProjection;
20
+ readJob: (jobId: string) => Promise<import("@fungi.computer/watchdog").WatchdogReadResult>;
21
+ tickConcurrent: () => Promise<WatchdogTickResult>;
22
+ }>) => {
23
+ execute: (job: {
24
+ readonly queue: string;
25
+ readonly priority: number;
26
+ readonly payload: unknown;
27
+ readonly state: "running";
28
+ readonly lane: string;
29
+ readonly jobId: string;
30
+ readonly recovery?: {
31
+ readonly maxRecoveries: number;
32
+ } | undefined;
33
+ }) => Promise<Readonly<{
34
+ kind: "completed";
35
+ }>>;
36
+ };
37
+ };
38
+ hostWork: {
39
+ pending: () => {
40
+ due: boolean;
41
+ nextWakeAt: number | null;
42
+ };
43
+ run: () => Promise<void>;
44
+ }[];
45
+ };
46
+ deliver: (value: Parameters<AgentMail["send"]>[0]) => Promise<import("@fungi.computer/shiitake").DelegationReceipt>;
24
47
  };
@@ -0,0 +1,29 @@
1
+ import type { Api, Model } from "@earendil-works/pi-ai";
2
+ import * as Schema from "effect/Schema";
3
+ /** A credential-source address, not credential material or a custodian locator. */
4
+ export declare const agentModelChoiceSchema: Schema.Struct<{
5
+ readonly keySource: Schema.Literals<readonly ["workers-ai", "ai-gateway", "byok"]>;
6
+ readonly model: Schema.Struct<{
7
+ readonly providerId: Schema.String;
8
+ readonly modelId: Schema.String;
9
+ readonly reasoning: Schema.optional<Schema.Literals<readonly ["minimal", "low", "medium", "high", "xhigh", "max"]>>;
10
+ }>;
11
+ }>;
12
+ /** The Agent's model preference and source reference, never credential material. */
13
+ export type AgentModelChoice = typeof agentModelChoiceSchema.Type;
14
+ /** Stable reason for rejecting a model or credential source before a run. */
15
+ export type AgentModelRefusal = "invalid_model_choice" | "unsupported_key_source" | "key_source_mismatch" | "model_unavailable" | "key_not_connected";
16
+ export declare class AgentModelRefused extends Error {
17
+ readonly reason: AgentModelRefusal;
18
+ constructor(reason: AgentModelRefusal);
19
+ }
20
+ /** Read the maintained Pi catalog; never accept a model from a different egress. */
21
+ export declare function selectAgentModel(choice: AgentModelChoice): Promise<Model<Api>>;
22
+ /** The Agent DO is the only durable owner. Absence is a new-format default, not an old-env reader. */
23
+ export declare function agentModelChoice(storage: Readonly<{
24
+ get<T = unknown>(key: string): Promise<T | undefined>;
25
+ put(key: string, value: AgentModelChoice): Promise<void>;
26
+ }>, admit: (choice: AgentModelChoice) => void): {
27
+ read(): Promise<AgentModelChoice>;
28
+ set(input: AgentModelChoice): Promise<AgentModelChoice>;
29
+ };
@@ -0,0 +1,72 @@
1
+ import { ModelPreferenceSchema } from "@fungi.computer/shiitake/model-preference";
2
+ import { cloudflareWorkersAIProvider } from "@earendil-works/pi-ai/providers/cloudflare-workers-ai";
3
+ import * as Schema from "effect/Schema";
4
+ /** A credential-source address, not credential material or a custodian locator. */
5
+ export const agentModelChoiceSchema = Schema.Struct({
6
+ keySource: Schema.Literals(["workers-ai", "ai-gateway", "byok"]),
7
+ model: ModelPreferenceSchema,
8
+ });
9
+ export class AgentModelRefused extends Error {
10
+ reason;
11
+ constructor(reason) {
12
+ super(reason);
13
+ this.reason = reason;
14
+ this.name = "AgentModelRefused";
15
+ }
16
+ }
17
+ const key = "agent-model-choice";
18
+ const defaultChoice = {
19
+ keySource: "workers-ai",
20
+ model: {
21
+ providerId: "cloudflare-workers-ai",
22
+ modelId: "@cf/moonshotai/kimi-k2.6",
23
+ },
24
+ };
25
+ /** Read the maintained Pi catalog; never accept a model from a different egress. */
26
+ export async function selectAgentModel(choice) {
27
+ if (choice.keySource === "byok")
28
+ throw new AgentModelRefused("unsupported_key_source");
29
+ const { providerId, modelId, reasoning } = choice.model;
30
+ if ((choice.keySource === "workers-ai" &&
31
+ providerId !== "cloudflare-workers-ai") ||
32
+ (choice.keySource === "ai-gateway" &&
33
+ (providerId !== "openai" || modelId !== "openai/gpt-6-luna")))
34
+ throw new AgentModelRefused("key_source_mismatch");
35
+ // Pi's OpenAI provider is needed only when Luna is selected, not at boot.
36
+ const model = choice.keySource === "workers-ai"
37
+ ? cloudflareWorkersAIProvider()
38
+ .getModels()
39
+ .find((item) => item.id === modelId)
40
+ : (await import("@earendil-works/pi-ai/providers/openai"))
41
+ .openaiProvider()
42
+ .getModels()
43
+ .find((item) => item.id === "gpt-6-luna");
44
+ if (model === undefined || (reasoning !== undefined && !model.reasoning))
45
+ throw new AgentModelRefused("model_unavailable");
46
+ return model;
47
+ }
48
+ /** The Agent DO is the only durable owner. Absence is a new-format default, not an old-env reader. */
49
+ export function agentModelChoice(storage, admit) {
50
+ return {
51
+ async read() {
52
+ const stored = await storage.get(key);
53
+ return stored === undefined
54
+ ? defaultChoice
55
+ : Schema.decodeUnknownSync(agentModelChoiceSchema, {
56
+ onExcessProperty: "error",
57
+ })(stored);
58
+ },
59
+ async set(input) {
60
+ const parsed = Schema.decodeUnknownOption(agentModelChoiceSchema, {
61
+ onExcessProperty: "error",
62
+ })(input);
63
+ if (parsed._tag === "None")
64
+ throw new AgentModelRefused("invalid_model_choice");
65
+ const choice = parsed.value;
66
+ await selectAgentModel(choice);
67
+ admit(choice);
68
+ await storage.put(key, choice);
69
+ return choice;
70
+ },
71
+ };
72
+ }
@@ -8,10 +8,15 @@ export type AiBinding = {
8
8
  /** AI binding transport supplied by the Worker runtime. */
9
9
  fetch?: (input: Request | string | URL, init?: RequestInit) => Promise<Response>;
10
10
  };
11
+ import { type ComputerAttachmentInput } from "../agent-computers.js";
12
+ import { type AgentComputerSnapshot, type AgentComputerConnection } from "../agent-computer-source.js";
13
+ import { type StandaloneAgentComputerReply } from "./agent-computers.js";
14
+ import { type ComputerGrant } from "@fungi.computer/computer/fleet";
11
15
  import { DurableObject } from "cloudflare:workers";
12
16
  import type { StandaloneComputerEnv } from "./computer.js";
13
17
  import { ShiitakeDO } from "@fungi.computer/shiitake/cloudflare";
14
18
  import type { CloudflareShiitakeOptions } from "@fungi.computer/shiitake/cloudflare";
19
+ import { type AgentModelChoice, type AgentModelRefusal } from "./agent-model-choice.js";
15
20
  import * as Schema from "effect/Schema";
16
21
  import { type FrameBindingProps } from "../cloudflare.js";
17
22
  import type { Avatar } from "@fungi.computer/sprite/avatar";
@@ -45,8 +50,6 @@ export type StandaloneAgentsEnv = Readonly<{
45
50
  AI_GATEWAY_ID?: string;
46
51
  /** Workers AI, the default model door. */
47
52
  AI?: AiBinding;
48
- /** The model: `@fungi/luna` via AI Gateway, or a Workers AI id (default {@link defaultAgentModel}). */
49
- OYSTER_AGENT_MODEL?: string;
50
53
  /** The AI Gateway the binding routes through (default `default`). */
51
54
  OYSTER_AI_GATEWAY?: string;
52
55
  /** Maintained current-member authority; absent means no nondefault-tenant policy admission. */
@@ -77,6 +80,18 @@ export declare abstract class StandaloneAgentBase<Env extends StandaloneAgentEnv
77
80
  protected abstract hostFor(scope: TenantScope): Promise<OysterHost>;
78
81
  private uiOwner;
79
82
  private machineClient;
83
+ private computerSnapshot;
84
+ private computerSnapshotLoad;
85
+ private computerSnapshotGeneration;
86
+ private computerSnapshotRevision;
87
+ private readonly computerInvalidations;
88
+ /** Host invalidation drops captured discovery, not just its displayed names. */
89
+ invalidateComputerConnections(): void;
90
+ private computerConnections;
91
+ /** Revalidate the owner's generation before reusing a Home or tool snapshot. */
92
+ private preparedComputerSnapshot;
93
+ private readComputerGeneration;
94
+ private readComputerSnapshot;
80
95
  private ui;
81
96
  protected hostFetch(request: Request): Promise<Response> | undefined;
82
97
  protected closeShiitake(): Promise<void>;
@@ -94,8 +109,15 @@ export declare abstract class StandaloneAgentBase<Env extends StandaloneAgentEnv
94
109
  settlement(principal: MachineAgentSettlementPrincipal, sessionId: string, commandId: string): Promise<string | undefined>;
95
110
  /** The root host for this Agent's pinned policy directory; unpinned Agents have no App tools. */
96
111
  private appHost;
97
- /** Choose this agent's model door; override to plug in another. */
112
+ private choice;
113
+ /** Secret-free default of this Agent; stored separately from Session history. */
114
+ readModelChoice(): Promise<AgentModelChoice>;
115
+ setModelChoice(input: AgentModelChoice): Promise<AgentModelChoice | Readonly<{
116
+ error: AgentModelRefusal;
117
+ }>>;
118
+ /** Capture one model and credential source when the Agent's run acquires it. */
98
119
  protected modelSource(): StandaloneModelSource;
120
+ private sourceFor;
99
121
  /** Host-only initialization; Agent/App transports never receive this directory binding. */
100
122
  usePolicyDirectory(input: {
101
123
  directoryName: string;
@@ -127,6 +149,8 @@ export declare abstract class StandaloneAgentBase<Env extends StandaloneAgentEnv
127
149
  }
128
150
  /** Names this Oyster's agents and remembers which Sessions the member opened. */
129
151
  export declare class AgentDirectory extends DurableObject<StandaloneAgentEnv> {
152
+ private readonly computers;
153
+ private readonly computerNames;
130
154
  private readonly directory;
131
155
  private readonly avatars;
132
156
  private composedTenancy;
@@ -169,6 +193,21 @@ export declare class AgentDirectory extends DurableObject<StandaloneAgentEnv> {
169
193
  alarm(): Promise<void>;
170
194
  private grant;
171
195
  constructor(ctx: DurableObjectState, env: StandaloneAgentEnv);
196
+ private computerOwner;
197
+ private loadComputerNames;
198
+ /** Check the existing transactional revision without resolving fleet names. */
199
+ agentComputerRevision(agentId: string, tenantId?: TenantId): Promise<number | null>;
200
+ /** Read the shared owner only after current membership and real fleet lookup. */
201
+ agentComputerSnapshot(agentId: string, tenantId?: TenantId): Promise<AgentComputerSnapshot | null>;
202
+ private computerCommand;
203
+ /** Owner attachment commands retain the shared owner's receipts and versions. */
204
+ attachComputer(command: ComputerAttachmentInput, principal: OysterPrincipal, tenantId?: TenantId): Promise<StandaloneAgentComputerReply>;
205
+ /** Detach advances the owner version and invalidates the Agent's held discovery. */
206
+ detachComputer(command: ComputerAttachmentInput, principal: OysterPrincipal, tenantId?: TenantId): Promise<StandaloneAgentComputerReply>;
207
+ /** The owner HTTP read uses the same projection as direct discovery. */
208
+ readAgentComputers(agentId: string, principal: OysterPrincipal, tenantId?: TenantId): Promise<StandaloneAgentComputerReply>;
209
+ /** Every captured native call rechecks the exact live attachment and credential owner. */
210
+ admitAgentComputer(captured: Pick<AgentComputerConnection, "scopeId" | "agentId" | "attachment">, tenantId: TenantId): Promise<Omit<ComputerGrant, "egress">>;
172
211
  list(): readonly AgentEntry[];
173
212
  has(agentId: string): boolean;
174
213
  /** Resolve the existing recorded creator for host-side owner admission. */
@@ -241,9 +280,9 @@ export declare const agentFrameMethods: {
241
280
  readonly nodeId: string;
242
281
  readonly iteration: string;
243
282
  };
283
+ readonly expiresAt: number;
244
284
  readonly kind: "workflow-review";
245
285
  readonly installationId: string;
246
- readonly expiresAt: number;
247
286
  readonly workflowId: string | null;
248
287
  readonly state: "pending" | "delivered" | "answered" | "timed_out" | "closed";
249
288
  readonly workflowTitle: string;
@@ -281,6 +320,7 @@ export declare const agentFrameMethods: {
281
320
  decodeResult: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Readonly<{
282
321
  status: "accepted";
283
322
  commandId: string;
323
+ sessionId?: string;
284
324
  }>;
285
325
  requiredOperations: () => string[];
286
326
  };