@opengeni/core 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -0
- package/dist/index.d.ts +735 -0
- package/dist/index.js +2627 -0
- package/dist/index.js.map +1 -0
- package/package.json +55 -0
- package/src/access/index.ts +186 -0
- package/src/billing/limits.ts +207 -0
- package/src/dependencies.ts +70 -0
- package/src/domain/capabilities.ts +959 -0
- package/src/domain/environments.ts +115 -0
- package/src/domain/packs.ts +241 -0
- package/src/domain/resources.ts +221 -0
- package/src/domain/scheduled-tasks.ts +321 -0
- package/src/domain/sessions.ts +812 -0
- package/src/domain/workspace-members.ts +80 -0
- package/src/index.ts +59 -0
- package/src/managed-auth-type.ts +20 -0
- package/src/sandbox/fleet.ts +460 -0
- package/src/sandbox/routing.ts +127 -0
- package/src/sandbox-types.ts +61 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,735 @@
|
|
|
1
|
+
import { Settings } from '@opengeni/config';
|
|
2
|
+
import { ScheduledTask, Document, Permission, AccessContext, AccessGrant, LimitAction, LimitDecision, CapabilityCatalogResponse, CreateCapabilityCatalogItemRequest, CapabilityCatalogItem, CapabilityInstallation, EnableCapabilityRequest, WorkspaceEnvironment, CapabilityPack, SocialConnection, ScheduledTaskAgentConfig, ToolRef, ResourceRef, CreateScheduledTaskRequest, UpdateScheduledTaskRequest, ReasoningEffort, SessionEvent, SessionTurn, GoalSpec, Session, WorkspaceMember } from '@opengeni/contracts';
|
|
3
|
+
export { mergeToolRefs, stableJson } from '@opengeni/contracts';
|
|
4
|
+
import { Database, SandboxRecord, EnabledMcpCapabilityServer, UpdateScheduledTaskInput } from '@opengeni/db';
|
|
5
|
+
import { DocumentServices } from '@opengeni/documents';
|
|
6
|
+
import { EventBus } from '@opengeni/events';
|
|
7
|
+
import { Observability } from '@opengeni/observability';
|
|
8
|
+
import { createObjectStorage } from '@opengeni/storage';
|
|
9
|
+
import { Auth } from 'better-auth';
|
|
10
|
+
import { SelfhostedRelayConfig, EstablishedSandboxSession } from '@opengeni/runtime/sandbox';
|
|
11
|
+
import { Context } from 'hono';
|
|
12
|
+
|
|
13
|
+
type ManagedAuth = Auth<any>;
|
|
14
|
+
|
|
15
|
+
type ApiSandboxSession = {
|
|
16
|
+
state?: Record<string, unknown> & {
|
|
17
|
+
sandboxId?: string;
|
|
18
|
+
};
|
|
19
|
+
running?(): Promise<boolean>;
|
|
20
|
+
exec?(args: {
|
|
21
|
+
cmd: string;
|
|
22
|
+
workdir?: string;
|
|
23
|
+
runAs?: string;
|
|
24
|
+
yieldTimeMs?: number;
|
|
25
|
+
maxOutputTokens?: number;
|
|
26
|
+
}): Promise<unknown>;
|
|
27
|
+
execCommand?(args: {
|
|
28
|
+
cmd: string;
|
|
29
|
+
workdir?: string;
|
|
30
|
+
runAs?: string;
|
|
31
|
+
yieldTimeMs?: number;
|
|
32
|
+
maxOutputTokens?: number;
|
|
33
|
+
}): Promise<string>;
|
|
34
|
+
shutdown?(options?: unknown): Promise<void>;
|
|
35
|
+
delete?(options?: unknown): Promise<void>;
|
|
36
|
+
close?(): Promise<void>;
|
|
37
|
+
};
|
|
38
|
+
type ApiSandboxClient = {
|
|
39
|
+
backendId: string;
|
|
40
|
+
deserializeSessionState?(state: Record<string, unknown>): Promise<unknown>;
|
|
41
|
+
resume?(state: unknown, options?: unknown): Promise<ApiSandboxSession>;
|
|
42
|
+
delete?(state: unknown): Promise<void>;
|
|
43
|
+
};
|
|
44
|
+
type ResumeBoxByIdInput = {
|
|
45
|
+
/**
|
|
46
|
+
* The backend the box was created on — the lease's `resume_backend_id`. Must
|
|
47
|
+
* match the API's configured sandbox client backendId, or the resume is
|
|
48
|
+
* rejected (a cross-backend envelope can never deserialize correctly).
|
|
49
|
+
*/
|
|
50
|
+
backend: string;
|
|
51
|
+
/**
|
|
52
|
+
* The serialized resume-state envelope — the lease's `resume_state` jsonb
|
|
53
|
+
* (the record produced by `client.serializeSessionState(state)`). This is the
|
|
54
|
+
* box identity + reattach descriptor; resume() reattaches to the live box by
|
|
55
|
+
* id (warm reattach) or cold-restores from its snapshot.
|
|
56
|
+
*/
|
|
57
|
+
resumeState: Record<string, unknown>;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* A live, resumed sandbox session for a SINGLE in-process op. The caller
|
|
61
|
+
* resumes → uses (exec/readFile/resolvePort) → drops it; lifecycle/refcount is
|
|
62
|
+
* the lease's job (P1.x), NOT this handle's. The session is non-owned by
|
|
63
|
+
* construction (resume-by-id never owns the box), so dropping it does not
|
|
64
|
+
* terminate the box.
|
|
65
|
+
*/
|
|
66
|
+
type ResumedSandboxSession = ApiSandboxSession;
|
|
67
|
+
|
|
68
|
+
type SessionWorkflowClient = {
|
|
69
|
+
signalUserMessage: (input: {
|
|
70
|
+
sessionId: string;
|
|
71
|
+
eventId: string;
|
|
72
|
+
workflowId: string;
|
|
73
|
+
}) => Promise<void>;
|
|
74
|
+
wakeSessionWorkflow: (input: {
|
|
75
|
+
accountId: string;
|
|
76
|
+
workspaceId: string;
|
|
77
|
+
sessionId: string;
|
|
78
|
+
workflowId: string;
|
|
79
|
+
}) => Promise<void>;
|
|
80
|
+
signalApprovalDecision: (input: {
|
|
81
|
+
sessionId: string;
|
|
82
|
+
eventId: string;
|
|
83
|
+
workflowId: string;
|
|
84
|
+
}) => Promise<void>;
|
|
85
|
+
signalInterrupt: (input: {
|
|
86
|
+
accountId: string;
|
|
87
|
+
workspaceId: string;
|
|
88
|
+
sessionId: string;
|
|
89
|
+
eventId: string;
|
|
90
|
+
workflowId: string;
|
|
91
|
+
}) => Promise<void>;
|
|
92
|
+
syncScheduledTask: (input: {
|
|
93
|
+
task: ScheduledTask;
|
|
94
|
+
}) => Promise<void>;
|
|
95
|
+
deleteScheduledTaskSchedule: (input: {
|
|
96
|
+
temporalScheduleId: string;
|
|
97
|
+
}) => Promise<void>;
|
|
98
|
+
triggerScheduledTask: (input: {
|
|
99
|
+
task: ScheduledTask;
|
|
100
|
+
agentRunUsageIdempotencyKey?: string;
|
|
101
|
+
triggerWorkflowId?: string;
|
|
102
|
+
}) => Promise<void>;
|
|
103
|
+
};
|
|
104
|
+
type DocumentIndexClient = {
|
|
105
|
+
indexDocument: (input: {
|
|
106
|
+
accountId: string;
|
|
107
|
+
workspaceId: string;
|
|
108
|
+
documentId: string;
|
|
109
|
+
}) => Promise<Document | void>;
|
|
110
|
+
};
|
|
111
|
+
type AppDependencies = {
|
|
112
|
+
settings: Settings;
|
|
113
|
+
db: Database;
|
|
114
|
+
bus: EventBus;
|
|
115
|
+
workflowClient: SessionWorkflowClient;
|
|
116
|
+
documentIndexer?: DocumentIndexClient;
|
|
117
|
+
documentServices?: DocumentServices;
|
|
118
|
+
observability?: Observability;
|
|
119
|
+
githubStateSecret?: string;
|
|
120
|
+
managedAuth?: ManagedAuth | null;
|
|
121
|
+
sandboxClient?: ApiSandboxClient;
|
|
122
|
+
/**
|
|
123
|
+
* Resume a box by id from a serialized resume_state envelope (the lease's
|
|
124
|
+
* `resume_state` + `resume_backend_id` from P1.1) and return a live session
|
|
125
|
+
* for a single in-process op. resume → use → drop; the lease owns lifecycle,
|
|
126
|
+
* the returned handle does NOT own the box. Throws SandboxResumeError on a
|
|
127
|
+
* backend mismatch or a resume failure.
|
|
128
|
+
*/
|
|
129
|
+
resumeBoxById?: (input: ResumeBoxByIdInput) => Promise<ResumedSandboxSession>;
|
|
130
|
+
};
|
|
131
|
+
type ObjectStorageDependency = ReturnType<typeof createObjectStorage>;
|
|
132
|
+
type ApiRouteDeps = AppDependencies & {
|
|
133
|
+
objectStorage: ObjectStorageDependency;
|
|
134
|
+
githubStateSecret: string;
|
|
135
|
+
documentIndexer: DocumentIndexClient;
|
|
136
|
+
getDocumentServices: () => DocumentServices;
|
|
137
|
+
resumeBoxById: (input: ResumeBoxByIdInput) => Promise<ResumedSandboxSession>;
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
type FleetServices = {
|
|
141
|
+
db: Database;
|
|
142
|
+
settings: Settings;
|
|
143
|
+
bus?: EventBus;
|
|
144
|
+
};
|
|
145
|
+
type FleetContext = {
|
|
146
|
+
accountId: string;
|
|
147
|
+
workspaceId: string;
|
|
148
|
+
/** The calling session (the pointer the attach/swap mutates + whose group box
|
|
149
|
+
* is the default fleet member). */
|
|
150
|
+
sessionId: string;
|
|
151
|
+
/** The session's own group sandbox backend (modal/selfhosted/…). */
|
|
152
|
+
sessionBackend: string;
|
|
153
|
+
/** The session's own group sandbox id (the lease group). */
|
|
154
|
+
sessionGroupId: string;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* Build a session-scoped {@link FleetContext}: load the session (workspace-
|
|
158
|
+
* scoped), reject a session with no box (backend:none — the fleet is only
|
|
159
|
+
* meaningful for a sandboxed session), and project its group backend/id. Shared
|
|
160
|
+
* by the worker-signed MCP fleet tools and the user-authenticated swap REST
|
|
161
|
+
* route so both resolve the SAME context (no drift). The `accountId`/`workspaceId`/
|
|
162
|
+
* `sessionId` come from the trusted grant/route; the backend + group id come from
|
|
163
|
+
* the session row.
|
|
164
|
+
*/
|
|
165
|
+
declare function buildFleetContextForSession(deps: {
|
|
166
|
+
db: Database;
|
|
167
|
+
}, ctx: {
|
|
168
|
+
accountId: string;
|
|
169
|
+
workspaceId: string;
|
|
170
|
+
sessionId: string;
|
|
171
|
+
}): Promise<FleetContext>;
|
|
172
|
+
/** The dominant liveness of a fleet member, surfaced to the dock + the agent. */
|
|
173
|
+
type FleetLiveness = "online" | "reconnecting" | "offline";
|
|
174
|
+
/**
|
|
175
|
+
* A fleet member as the agent + the dock see it (the M8b/M9 UI seam — the
|
|
176
|
+
* `sandboxes_list` response entry the dock renders). STABLE shape: the dock keys
|
|
177
|
+
* on `id`, renders `name`/`kind`/`liveness`, and marks `active`. The session's own
|
|
178
|
+
* Modal group box is a synthetic entry with `id: groupId`, `kind: "modal"`, and a
|
|
179
|
+
* null `enrollmentId`; an enrolled machine carries its sandbox + enrollment ids.
|
|
180
|
+
*/
|
|
181
|
+
type FleetSandboxEntry = {
|
|
182
|
+
/** The sandbox id used as the attach/swap/run_on `target`. For the session's
|
|
183
|
+
* own group box this is the group id (a null active pointer == this box). */
|
|
184
|
+
id: string;
|
|
185
|
+
kind: "modal" | "selfhosted";
|
|
186
|
+
name: string;
|
|
187
|
+
liveness: FleetLiveness;
|
|
188
|
+
/** True for the session's currently-active sandbox (the routing target). */
|
|
189
|
+
active: boolean;
|
|
190
|
+
/** True for the session's own group box (the default/home sandbox). */
|
|
191
|
+
isSessionGroup: boolean;
|
|
192
|
+
enrollmentId: string | null;
|
|
193
|
+
/** Whether this target can be attached/swapped to right now (live + addressable). */
|
|
194
|
+
attachable: boolean;
|
|
195
|
+
/** Selfhosted only: whether whole-machine + screen-control consent is acked. */
|
|
196
|
+
consented?: boolean;
|
|
197
|
+
/** Selfhosted only: whether a display (real/Xvfb) is present. */
|
|
198
|
+
hasDisplay?: boolean;
|
|
199
|
+
lastSeenAt?: string | null;
|
|
200
|
+
};
|
|
201
|
+
type FleetListResult = {
|
|
202
|
+
/** The session's currently-active sandbox id, or null == the group box. */
|
|
203
|
+
activeSandboxId: string | null;
|
|
204
|
+
activeEpoch: number;
|
|
205
|
+
sandboxes: FleetSandboxEntry[];
|
|
206
|
+
};
|
|
207
|
+
/** A swap/attach outcome the tool returns. */
|
|
208
|
+
type FleetSwapResult = {
|
|
209
|
+
swapped: boolean;
|
|
210
|
+
activeSandboxId: string | null;
|
|
211
|
+
activeEpoch: number;
|
|
212
|
+
reason?: string;
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* List the fleet: the session's own Modal group box (a synthetic entry) + the
|
|
216
|
+
* workspace's first-class selfhosted sandboxes (each probed for liveness), each
|
|
217
|
+
* with an `active` marker derived from the session's active pointer.
|
|
218
|
+
*/
|
|
219
|
+
declare function listFleet(services: FleetServices, ctx: FleetContext): Promise<FleetListResult>;
|
|
220
|
+
/**
|
|
221
|
+
* THE SWAP (and attach — identical mechanic). Validate the target's ownership +
|
|
222
|
+
* liveness, then repoint the session via the epoch-fenced CAS `setActiveSandbox`:
|
|
223
|
+
* read the current epoch, then CAS on it. A concurrent double-swap lets exactly
|
|
224
|
+
* one win; the loser re-reads + may retry. The bumped epoch fences any in-flight
|
|
225
|
+
* op cached against the old pointer, which then retries against the new active
|
|
226
|
+
* sandbox (the routing proxy's fenced-retry role).
|
|
227
|
+
*/
|
|
228
|
+
declare function swapActiveSandbox(services: FleetServices, ctx: FleetContext, target: string, workingDir?: string | null): Promise<FleetSwapResult>;
|
|
229
|
+
type RunOnOp = {
|
|
230
|
+
kind: "exec";
|
|
231
|
+
cmd: string;
|
|
232
|
+
workdir?: string;
|
|
233
|
+
} | {
|
|
234
|
+
kind: "read";
|
|
235
|
+
path: string;
|
|
236
|
+
} | {
|
|
237
|
+
kind: "write";
|
|
238
|
+
path: string;
|
|
239
|
+
content: string;
|
|
240
|
+
};
|
|
241
|
+
type RunOnResult = {
|
|
242
|
+
target: string;
|
|
243
|
+
kind: string;
|
|
244
|
+
ok: boolean;
|
|
245
|
+
stdout?: string;
|
|
246
|
+
stderr?: string;
|
|
247
|
+
exitCode?: number | null;
|
|
248
|
+
content?: string;
|
|
249
|
+
bytesWritten?: number;
|
|
250
|
+
reason?: string;
|
|
251
|
+
};
|
|
252
|
+
/**
|
|
253
|
+
* Run a ONE-OFF op against a SPECIFIC target WITHOUT changing the active pointer
|
|
254
|
+
* (the dossier `run_on`). Only selfhosted targets are routable as a one-off here
|
|
255
|
+
* (a Modal target is the session's group box, reached via the normal Channel-A /
|
|
256
|
+
* turn path — `run_on` is for reaching a NON-active enrolled machine without
|
|
257
|
+
* swapping). The op is fenced under the target's enrollment, addressed to its
|
|
258
|
+
* agent subject; an offline machine surfaces a clear reason, never a wrong-box
|
|
259
|
+
* landing.
|
|
260
|
+
*/
|
|
261
|
+
declare function runOnSandbox(services: FleetServices, ctx: FleetContext, target: string, op: RunOnOp): Promise<RunOnResult>;
|
|
262
|
+
type ProvisionResult = {
|
|
263
|
+
kind: "selfhosted";
|
|
264
|
+
instructions: string;
|
|
265
|
+
installCommandUnix: string;
|
|
266
|
+
installCommandWindows: string;
|
|
267
|
+
verificationUri: string;
|
|
268
|
+
note: string;
|
|
269
|
+
} | {
|
|
270
|
+
kind: "modal";
|
|
271
|
+
sandbox: SandboxRecord;
|
|
272
|
+
note: string;
|
|
273
|
+
};
|
|
274
|
+
/**
|
|
275
|
+
* Provision a new fleet member.
|
|
276
|
+
* - selfhosted → return the device-flow enrollment instructions (the agent
|
|
277
|
+
* surfaces them to a HUMAN, who installs the agent + enrolls — the agent
|
|
278
|
+
* cannot click the loud whole-machine consent itself).
|
|
279
|
+
* - modal → create a first-class named modal `sandboxes` record (a swap target).
|
|
280
|
+
* NOTE: the Modal BOX is materialized lazily when first swapped-to (Modal
|
|
281
|
+
* lifecycle is owned by the lease — unchanged per dossier §21).
|
|
282
|
+
*/
|
|
283
|
+
declare function provisionSandbox(services: FleetServices, ctx: FleetContext, input: {
|
|
284
|
+
kind: "selfhosted" | "modal";
|
|
285
|
+
name?: string;
|
|
286
|
+
}): Promise<ProvisionResult>;
|
|
287
|
+
|
|
288
|
+
type ChannelARoutingServices = {
|
|
289
|
+
db: Database;
|
|
290
|
+
settings: Settings;
|
|
291
|
+
bus?: EventBus;
|
|
292
|
+
};
|
|
293
|
+
/** Map the deployment relay URL to the leaf's `SelfhostedRelayConfig` shape. The
|
|
294
|
+
* relay URL (`OPENGENI_SELFHOSTED_RELAY_URL`) may carry a path (the relay's wss
|
|
295
|
+
* route); a path-less URL defaults to the relay's `/stream` route (M8b). */
|
|
296
|
+
declare function relayConfigFromSettings(settings: Settings): SelfhostedRelayConfig;
|
|
297
|
+
/** The canonical relay dial-BASE URL (`scheme://host[:port]/stream`) handed to the
|
|
298
|
+
* agent PRODUCER. The agent's relay channel appends ONLY its routing query to
|
|
299
|
+
* this base (`channel.rs`: `format!("{relay_url}{sep}{query}")`) and relies on the
|
|
300
|
+
* base ALREADY carrying the relay's `/stream` route. `OPENGENI_SELFHOSTED_RELAY_URL`
|
|
301
|
+
* is frequently pathless (e.g. `wss://relay.<env>.app.opengeni.ai`), which made the
|
|
302
|
+
* producer dial a path-less URL the relay 400s. Derive the base from the SAME parser
|
|
303
|
+
* the CONSUMER uses (`relayConfigFromSettings`) so producer + consumer always agree
|
|
304
|
+
* on `/stream` — even when the configured URL omits it. An unconfigured relay maps to
|
|
305
|
+
* `""` (graceful degrade: the agent reports no-relay rather than dialing a synthetic
|
|
306
|
+
* host). Fixes preview AND managed prod with no agent rebuild (dossier §V5/§V6). */
|
|
307
|
+
declare function relayDialBaseFromSettings(settings: Settings): string;
|
|
308
|
+
/** Whether the routing proxy should wrap the Channel-A box: gated by the
|
|
309
|
+
* selfhosted flag (the active pointer + swap are only meaningful then). */
|
|
310
|
+
declare function routingEnabled(settings: Settings): boolean;
|
|
311
|
+
/**
|
|
312
|
+
* Wrap an established group-box session in a `RoutingSandboxSession` so a
|
|
313
|
+
* Channel-A op routes to the session's currently-active sandbox. Returns the
|
|
314
|
+
* established handle with its `session` replaced by the stable proxy. With the
|
|
315
|
+
* default pointer (active_sandbox_id == null) this routes to the group box
|
|
316
|
+
* unchanged; a selfhosted active pointer routes the op to the machine.
|
|
317
|
+
*/
|
|
318
|
+
declare function wrapChannelABoxWithRouting(services: ChannelARoutingServices, ids: {
|
|
319
|
+
workspaceId: string;
|
|
320
|
+
sessionId: string;
|
|
321
|
+
}, established: EstablishedSandboxSession): EstablishedSandboxSession;
|
|
322
|
+
|
|
323
|
+
type AccessDeps = {
|
|
324
|
+
db: Database;
|
|
325
|
+
settings: Settings;
|
|
326
|
+
managedAuth?: ManagedAuth | null;
|
|
327
|
+
};
|
|
328
|
+
declare function requireAccessContext(c: Context, deps: AccessDeps): Promise<AccessContext>;
|
|
329
|
+
declare function requireAccessGrant(c: Context, deps: AccessDeps, workspaceId: string, permission?: Permission): Promise<AccessGrant>;
|
|
330
|
+
declare function requirePermission(grant: AccessGrant, permission: Permission): void;
|
|
331
|
+
declare function hasPermission(permissions: Permission[], permission: Permission): boolean;
|
|
332
|
+
|
|
333
|
+
type LimitCheckInput = {
|
|
334
|
+
accountId: string;
|
|
335
|
+
workspaceId?: string;
|
|
336
|
+
action: LimitAction;
|
|
337
|
+
quantity?: number;
|
|
338
|
+
model?: string | null;
|
|
339
|
+
};
|
|
340
|
+
declare function requireLimit(deps: ApiRouteDeps, input: LimitCheckInput): Promise<void>;
|
|
341
|
+
declare function checkLimit(deps: ApiRouteDeps, input: LimitCheckInput): Promise<LimitDecision>;
|
|
342
|
+
declare function recordWorkspaceUsage(deps: ApiRouteDeps, input: {
|
|
343
|
+
accountId: string;
|
|
344
|
+
workspaceId: string;
|
|
345
|
+
subjectId?: string | null;
|
|
346
|
+
eventType: "agent_run.created" | "file.uploaded" | "document.indexed" | "scheduled_task.fired";
|
|
347
|
+
quantity: number;
|
|
348
|
+
unit: string;
|
|
349
|
+
sourceResourceType: string;
|
|
350
|
+
sourceResourceId: string;
|
|
351
|
+
idempotencyKey: string;
|
|
352
|
+
}): Promise<void>;
|
|
353
|
+
|
|
354
|
+
declare const officialMcpRegistryUrl = "https://registry.modelcontextprotocol.io";
|
|
355
|
+
declare function buildCapabilityCatalog(input: {
|
|
356
|
+
db: Database;
|
|
357
|
+
workspaceId: string;
|
|
358
|
+
settings: Settings;
|
|
359
|
+
}): Promise<CapabilityCatalogResponse>;
|
|
360
|
+
declare function createCatalogItem(input: {
|
|
361
|
+
db: Database;
|
|
362
|
+
accountId: string;
|
|
363
|
+
workspaceId: string;
|
|
364
|
+
payload: CreateCapabilityCatalogItemRequest;
|
|
365
|
+
}): Promise<CapabilityCatalogItem>;
|
|
366
|
+
declare function enableCapability(input: {
|
|
367
|
+
db: Database;
|
|
368
|
+
grant: AccessGrant;
|
|
369
|
+
accountId: string;
|
|
370
|
+
workspaceId: string;
|
|
371
|
+
settings: Settings;
|
|
372
|
+
capabilityId: string;
|
|
373
|
+
payload: EnableCapabilityRequest;
|
|
374
|
+
probeMcpServer?: McpCapabilityProbe;
|
|
375
|
+
}): Promise<CapabilityInstallation>;
|
|
376
|
+
type McpCapabilityProbeInput = {
|
|
377
|
+
id: string;
|
|
378
|
+
name: string;
|
|
379
|
+
url: string;
|
|
380
|
+
timeoutMs: number;
|
|
381
|
+
headers?: Record<string, string>;
|
|
382
|
+
};
|
|
383
|
+
type McpCapabilityProbeResult = {
|
|
384
|
+
toolCount: number;
|
|
385
|
+
};
|
|
386
|
+
type McpCapabilityProbe = (input: McpCapabilityProbeInput) => Promise<McpCapabilityProbeResult>;
|
|
387
|
+
declare function validateMcpCapabilityConnection(item: CapabilityCatalogItem, probe?: McpCapabilityProbe, headers?: Record<string, string>): Promise<Record<string, unknown>>;
|
|
388
|
+
declare function disableCapability(input: {
|
|
389
|
+
db: Database;
|
|
390
|
+
accountId: string;
|
|
391
|
+
workspaceId: string;
|
|
392
|
+
settings: Settings;
|
|
393
|
+
capabilityId: string;
|
|
394
|
+
}): Promise<CapabilityInstallation>;
|
|
395
|
+
declare function settingsWithEnabledCapabilityMcpServers(db: Database, workspaceId: string, settings: Settings): Promise<Settings>;
|
|
396
|
+
declare function settingsWithMcpCapabilityServers(settings: Settings, enabled: EnabledMcpCapabilityServer[]): Settings;
|
|
397
|
+
declare function discoverMcpRegistryCapabilities(input: {
|
|
398
|
+
query?: string;
|
|
399
|
+
limit?: number;
|
|
400
|
+
fetchImpl?: McpRegistryFetch;
|
|
401
|
+
timeoutMs?: number;
|
|
402
|
+
}): Promise<CapabilityCatalogItem[]>;
|
|
403
|
+
|
|
404
|
+
type McpRegistryFetch = (input: URL, init?: RequestInit) => Promise<Response>;
|
|
405
|
+
|
|
406
|
+
declare const MAX_ENVIRONMENTS_PER_WORKSPACE = 25;
|
|
407
|
+
declare const MAX_VARIABLES_PER_ENVIRONMENT = 100;
|
|
408
|
+
declare function assertAllowedEnvironmentVariableName(name: string): void;
|
|
409
|
+
declare function requireEnvironmentEncryption(settings: Settings): Uint8Array;
|
|
410
|
+
declare function requireEnvironmentForApi(db: Database, workspaceId: string, environmentId: string): Promise<WorkspaceEnvironment>;
|
|
411
|
+
/**
|
|
412
|
+
* Validates an environment attachment supplied in a request payload (session
|
|
413
|
+
* create, scheduled task create/update, pack enable). Requires the
|
|
414
|
+
* `environments:use` permission unless the attachment was already authorized
|
|
415
|
+
* (pack-installation-inherited attachments), and maps a missing or
|
|
416
|
+
* cross-workspace environment to 422 because the id is payload, not the route
|
|
417
|
+
* target. RLS plus the workspace_id clause make cross-workspace ids
|
|
418
|
+
* indistinguishable from missing ones.
|
|
419
|
+
*/
|
|
420
|
+
declare function validateEnvironmentAttachment(deps: {
|
|
421
|
+
settings: Settings;
|
|
422
|
+
db: Database;
|
|
423
|
+
}, grant: AccessGrant, workspaceId: string, environmentId: string, options?: {
|
|
424
|
+
preauthorized?: boolean;
|
|
425
|
+
}): Promise<WorkspaceEnvironment>;
|
|
426
|
+
declare function recordEnvironmentAuditEvent(db: Database, input: {
|
|
427
|
+
grant: AccessGrant;
|
|
428
|
+
action: "environment.created" | "environment.updated" | "environment.deleted" | "environment.variable.set" | "environment.variable.deleted";
|
|
429
|
+
environmentId: string;
|
|
430
|
+
variableName?: string;
|
|
431
|
+
}): Promise<void>;
|
|
432
|
+
|
|
433
|
+
declare const MARKETING_SOCIAL_PACK_ID = "marketing-social-daily-analysis";
|
|
434
|
+
declare function listCapabilityPacks(): CapabilityPack[];
|
|
435
|
+
declare function getCapabilityPack(packId: string): CapabilityPack | null;
|
|
436
|
+
declare function isBuiltInCapabilityPack(packId: string): boolean;
|
|
437
|
+
/**
|
|
438
|
+
* Built-in packs plus the manifests registered for this workspace. Stored
|
|
439
|
+
* manifests were validated at registration time; rows that no longer parse
|
|
440
|
+
* (for example after a contract tightening) are skipped instead of breaking
|
|
441
|
+
* the whole catalog.
|
|
442
|
+
*/
|
|
443
|
+
declare function listWorkspaceCapabilityPacks(db: Database, workspaceId: string): Promise<CapabilityPack[]>;
|
|
444
|
+
declare function resolveCapabilityPack(db: Database, workspaceId: string, packId: string): Promise<CapabilityPack | null>;
|
|
445
|
+
/**
|
|
446
|
+
* v1 pack-scoped runtime rule: at most one enabled pack per workspace may
|
|
447
|
+
* declare a `sandboxImage` — there is deliberately no image composition or
|
|
448
|
+
* layering. Enforced when a pack is enabled (both the packs endpoint and the
|
|
449
|
+
* generic capability enable path) and re-checked at session start by the
|
|
450
|
+
* worker, which also covers manifests re-registered after enablement.
|
|
451
|
+
*/
|
|
452
|
+
declare function assertPackSandboxImageCompatible(db: Database, workspaceId: string, pack: CapabilityPack): Promise<void>;
|
|
453
|
+
declare function buildMarketingDailyAnalysisAgentConfig(input: {
|
|
454
|
+
connections: SocialConnection[];
|
|
455
|
+
documentBaseIds: string[];
|
|
456
|
+
promptInstructions?: string;
|
|
457
|
+
}): ScheduledTaskAgentConfig;
|
|
458
|
+
|
|
459
|
+
declare function validateToolRefs(tools: ToolRef[], settings: Settings): ToolRef[];
|
|
460
|
+
type McpSettings = Pick<Settings, "mcpServers">;
|
|
461
|
+
declare function enabledCapabilityMcpToolRefs(settings: McpSettings, runtimeSettings: McpSettings): ToolRef[];
|
|
462
|
+
declare function withDefaultEnabledCapabilityMcpTools(tools: ToolRef[], settings: McpSettings, runtimeSettings: McpSettings): ToolRef[];
|
|
463
|
+
declare function normalizeResources(resources: ResourceRef[]): ResourceRef[];
|
|
464
|
+
declare function mergeResourceRefs(existing: ResourceRef[], additions: ResourceRef[]): ResourceRef[];
|
|
465
|
+
declare function validateGitHubRepositorySelectionShape(resources: ResourceRef[]): number | null;
|
|
466
|
+
declare function validateGitHubRepositorySelection(db: Database, workspaceId: string, resources: ResourceRef[]): Promise<void>;
|
|
467
|
+
declare function validateFileResources(db: Database, workspaceId: string, resources: ResourceRef[]): Promise<void>;
|
|
468
|
+
|
|
469
|
+
/**
|
|
470
|
+
* Whether a raw scheduled-task payload explicitly set agentConfig.tools.
|
|
471
|
+
* Zod's `.default([])` erases the distinction between "absent" and
|
|
472
|
+
* "explicitly empty", so callers detect it on the raw payload — the same
|
|
473
|
+
* contract sessions use: absent tools mean "give me the workspace defaults
|
|
474
|
+
* (enabled capability MCP servers)", an explicit list (even empty) is taken
|
|
475
|
+
* verbatim.
|
|
476
|
+
*/
|
|
477
|
+
declare function scheduledTaskToolsProvided(rawPayload: unknown): boolean;
|
|
478
|
+
declare function createValidatedScheduledTask(input: {
|
|
479
|
+
settings: Settings;
|
|
480
|
+
db: Database;
|
|
481
|
+
objectStorage: ObjectStorageDependency;
|
|
482
|
+
grant: AccessGrant;
|
|
483
|
+
payload: CreateScheduledTaskRequest;
|
|
484
|
+
toolsProvided?: boolean;
|
|
485
|
+
environmentPreauthorized?: boolean;
|
|
486
|
+
}): Promise<ScheduledTask>;
|
|
487
|
+
declare function validatedScheduledTaskUpdate(input: {
|
|
488
|
+
settings: Settings;
|
|
489
|
+
db: Database;
|
|
490
|
+
objectStorage: ObjectStorageDependency;
|
|
491
|
+
grant: AccessGrant;
|
|
492
|
+
existing: ScheduledTask;
|
|
493
|
+
payload: UpdateScheduledTaskRequest;
|
|
494
|
+
/** See createValidatedScheduledTask; only consulted when agentConfig is updated. */
|
|
495
|
+
toolsProvided?: boolean;
|
|
496
|
+
}): Promise<UpdateScheduledTaskInput>;
|
|
497
|
+
declare function requireScheduledTaskForApi(db: Database, workspaceId: string, taskId: string): Promise<ScheduledTask>;
|
|
498
|
+
declare function restoreScheduledTask(db: Database, task: ScheduledTask): Promise<ScheduledTask>;
|
|
499
|
+
declare function syncCreatedScheduledTask(input: {
|
|
500
|
+
db: Database;
|
|
501
|
+
workflowClient: SessionWorkflowClient;
|
|
502
|
+
task: ScheduledTask;
|
|
503
|
+
}): Promise<void>;
|
|
504
|
+
declare function syncUpdatedScheduledTask(input: {
|
|
505
|
+
db: Database;
|
|
506
|
+
workflowClient: SessionWorkflowClient;
|
|
507
|
+
previous: ScheduledTask;
|
|
508
|
+
task: ScheduledTask;
|
|
509
|
+
}): Promise<void>;
|
|
510
|
+
declare function scheduledTaskTemporalScheduleId(taskId: string): string;
|
|
511
|
+
/**
|
|
512
|
+
* Stable token that identifies a single logical manual trigger. A client that
|
|
513
|
+
* retries a `/trigger` POST (network blip, lambda re-invocation) passes the
|
|
514
|
+
* SAME token so the retry is idempotent — one usage charge, one workflow run.
|
|
515
|
+
* When the client supplies nothing we mint one UUID PER REQUEST and reuse it
|
|
516
|
+
* for both the idempotency key and the workflowId, so a single request stays
|
|
517
|
+
* internally consistent while two genuinely-distinct manual triggers (no token,
|
|
518
|
+
* fired a second apart) still each get their own run. The token is sanitized to
|
|
519
|
+
* the Temporal workflow-id-safe charset so a client value cannot smuggle a
|
|
520
|
+
* collision into a different task's id space.
|
|
521
|
+
*/
|
|
522
|
+
declare function scheduledTaskTriggerToken(clientTriggerId?: string | null): string;
|
|
523
|
+
/**
|
|
524
|
+
* Deterministic Temporal workflow id for a manual trigger. Derived purely from
|
|
525
|
+
* the task id and the stable trigger token, so a retry with the same token maps
|
|
526
|
+
* to the same id and `workflowIdReusePolicy: "REJECT_DUPLICATE"` collapses the
|
|
527
|
+
* second start into a no-op instead of spawning a second run.
|
|
528
|
+
*/
|
|
529
|
+
declare function manualScheduledTaskTriggerWorkflowId(taskId: string, triggerToken: string): string;
|
|
530
|
+
/**
|
|
531
|
+
* Deterministic usage idempotency key for a manual trigger's agent_run.created
|
|
532
|
+
* charge. Shares the stable trigger token with the workflow id so the charge
|
|
533
|
+
* and the run dedupe together under retry.
|
|
534
|
+
*/
|
|
535
|
+
declare function manualScheduledTaskTriggerUsageKey(workspaceId: string, taskId: string, triggerToken: string): string;
|
|
536
|
+
|
|
537
|
+
declare function createAndStartSession(input: {
|
|
538
|
+
db: Database;
|
|
539
|
+
bus: EventBus;
|
|
540
|
+
workflowClient: SessionWorkflowClient;
|
|
541
|
+
accountId: string;
|
|
542
|
+
workspaceId: string;
|
|
543
|
+
initialMessage: string;
|
|
544
|
+
resources: ResourceRef[];
|
|
545
|
+
tools: ToolRef[];
|
|
546
|
+
clientEventId?: string;
|
|
547
|
+
model: string;
|
|
548
|
+
reasoningEffort: Settings["openaiReasoningEffort"];
|
|
549
|
+
sandboxBackend: Settings["sandboxBackend"];
|
|
550
|
+
metadata: Record<string, unknown>;
|
|
551
|
+
environment?: {
|
|
552
|
+
id: string;
|
|
553
|
+
name: string;
|
|
554
|
+
} | null;
|
|
555
|
+
goal?: GoalSpec | null;
|
|
556
|
+
firstPartyMcpPermissions?: Permission[] | null;
|
|
557
|
+
parentSessionId?: string | null;
|
|
558
|
+
createIdempotencyKey?: string | null;
|
|
559
|
+
sandboxGroupId?: string | null;
|
|
560
|
+
sandboxOs?: Session["sandboxOs"];
|
|
561
|
+
seedTargetSandbox?: {
|
|
562
|
+
sandboxId: string;
|
|
563
|
+
settings: Settings;
|
|
564
|
+
workingDir?: string | null;
|
|
565
|
+
} | null;
|
|
566
|
+
}): Promise<{
|
|
567
|
+
id: string;
|
|
568
|
+
workspaceId: string;
|
|
569
|
+
accountId: string;
|
|
570
|
+
status: "queued" | "running" | "idle" | "requires_action" | "failed" | "cancelled";
|
|
571
|
+
initialMessage: string;
|
|
572
|
+
title: string | null;
|
|
573
|
+
titleSource: "user" | "agent" | null;
|
|
574
|
+
resources: ({
|
|
575
|
+
kind: "repository";
|
|
576
|
+
uri: string;
|
|
577
|
+
ref: string;
|
|
578
|
+
mountPath?: string | undefined;
|
|
579
|
+
subpath?: string | undefined;
|
|
580
|
+
githubInstallationId?: number | undefined;
|
|
581
|
+
githubRepositoryId?: number | undefined;
|
|
582
|
+
} | {
|
|
583
|
+
kind: "file";
|
|
584
|
+
fileId: string;
|
|
585
|
+
mountPath?: string | undefined;
|
|
586
|
+
})[];
|
|
587
|
+
tools: {
|
|
588
|
+
kind: "mcp";
|
|
589
|
+
id: string;
|
|
590
|
+
optional?: boolean | undefined;
|
|
591
|
+
}[];
|
|
592
|
+
metadata: Record<string, unknown>;
|
|
593
|
+
model: string;
|
|
594
|
+
sandboxBackend: "docker" | "modal" | "local" | "none" | "daytona" | "runloop" | "e2b" | "blaxel" | "cloudflare" | "vercel" | "selfhosted";
|
|
595
|
+
sandboxOs: "linux" | "macos" | "windows";
|
|
596
|
+
sandboxGroupId: string;
|
|
597
|
+
activeSandboxId: string | null;
|
|
598
|
+
activeEpoch: number;
|
|
599
|
+
environmentId: string | null;
|
|
600
|
+
firstPartyMcpPermissions: ("account:read" | "account:admin" | "members:manage" | "workspace:create" | "billing:read" | "billing:manage" | "workspace:read" | "workspace:admin" | "sessions:create" | "sessions:read" | "sessions:control" | "stream:view" | "stream:control" | "stream:acknowledge" | "files:upload" | "files:read" | "files:write" | "terminal:attach" | "documents:manage" | "documents:search" | "scheduled_tasks:manage" | "scheduled_tasks:run" | "github:manage" | "github:use" | "api_keys:manage" | "environments:manage" | "environments:use" | "goals:manage" | "enrollments:read" | "enrollments:manage")[] | null;
|
|
601
|
+
parentSessionId: string | null;
|
|
602
|
+
createIdempotencyKey: string | null;
|
|
603
|
+
temporalWorkflowId: string | null;
|
|
604
|
+
activeTurnId: string | null;
|
|
605
|
+
lastInputTokens: number | null;
|
|
606
|
+
lastSequence: number;
|
|
607
|
+
codexPinnedCredentialId: string | null;
|
|
608
|
+
codexLastCredentialId: string | null;
|
|
609
|
+
createdAt: string;
|
|
610
|
+
updatedAt: string;
|
|
611
|
+
}>;
|
|
612
|
+
declare function workflowIdForSession(sessionId: string): string;
|
|
613
|
+
/**
|
|
614
|
+
* Reject an explicit model that the host does not expose. The set of usable
|
|
615
|
+
* models is the union surfaced by `configuredAllowedModels` (the built-in
|
|
616
|
+
* provider's allow-list plus every registry provider's ids); a `model` outside
|
|
617
|
+
* it cannot be resolved to a provider at run time, so we fail the request at
|
|
618
|
+
* the API edge with 422 rather than enqueuing a turn the worker can't honor.
|
|
619
|
+
*
|
|
620
|
+
* `model` is the explicit, caller-supplied value (null/undefined when omitted).
|
|
621
|
+
* An omitted model defaults to `settings.openaiModel` downstream — which is
|
|
622
|
+
* always first in `configuredAllowedModels` — so only an explicit value is
|
|
623
|
+
* checked. Centralized here so every model-carrying choke point
|
|
624
|
+
* (create-session, user-message/turn-accept, queued-turn update, and
|
|
625
|
+
* scheduled-task agentConfig — a scheduled task is a session the worker runs
|
|
626
|
+
* later) and the MCP surfaces that share them validate identically and cannot
|
|
627
|
+
* drift.
|
|
628
|
+
*/
|
|
629
|
+
declare function assertConfiguredModel(settings: Settings, model: string | null | undefined): void;
|
|
630
|
+
declare function requireQueuedTurnForApi(db: Database, workspaceId: string, sessionId: string, turnId: string): Promise<SessionTurn>;
|
|
631
|
+
declare function reasoningEffortForSession(metadata: Record<string, unknown>, fallback: Settings["openaiReasoningEffort"]): Settings["openaiReasoningEffort"];
|
|
632
|
+
/**
|
|
633
|
+
* Appends a `user.message` to an existing session and enqueues the resulting
|
|
634
|
+
* turn, merging requested resources/tools into the session and waking the
|
|
635
|
+
* workflow. Shared by the public events route and the first-party MCP
|
|
636
|
+
* `session_send_message` tool so the two surfaces cannot drift. Callers own
|
|
637
|
+
* resource/tool validation and the per-message usage limit before calling.
|
|
638
|
+
*/
|
|
639
|
+
declare function postUserMessageTurn(input: {
|
|
640
|
+
db: Database;
|
|
641
|
+
bus: EventBus;
|
|
642
|
+
workflowClient: SessionWorkflowClient;
|
|
643
|
+
settings: Settings;
|
|
644
|
+
accountId: string;
|
|
645
|
+
workspaceId: string;
|
|
646
|
+
sessionId: string;
|
|
647
|
+
text: string;
|
|
648
|
+
resources: ResourceRef[];
|
|
649
|
+
tools: ToolRef[];
|
|
650
|
+
model?: string | null;
|
|
651
|
+
reasoningEffort?: Settings["openaiReasoningEffort"] | null;
|
|
652
|
+
clientEventId?: string;
|
|
653
|
+
}): Promise<{
|
|
654
|
+
accepted: SessionEvent;
|
|
655
|
+
turn: SessionTurn;
|
|
656
|
+
}>;
|
|
657
|
+
/**
|
|
658
|
+
* Full create-session flow shared by `POST /sessions` and the first-party MCP
|
|
659
|
+
* `session_create` tool: payload validation, resource/tool/environment
|
|
660
|
+
* checks, usage limits, session start, and usage recording. `rawPayload` is
|
|
661
|
+
* the unparsed request body so absent-vs-empty `tools` keeps its meaning
|
|
662
|
+
* (absent applies the workspace's default capability MCP tools).
|
|
663
|
+
*/
|
|
664
|
+
declare function createSessionForRequest(deps: ApiRouteDeps, grant: AccessGrant, workspaceId: string, rawPayload: unknown): Promise<Session>;
|
|
665
|
+
/**
|
|
666
|
+
* Full accept-user-message flow shared by the `user.message` branch of
|
|
667
|
+
* `POST /sessions/:id/events` and the first-party MCP `session_send_message`
|
|
668
|
+
* tool: resource/tool validation, usage limits, the locked append + turn
|
|
669
|
+
* enqueue, and usage recording. `toolsProvided: false` applies the
|
|
670
|
+
* workspace's default capability MCP tools, matching an absent `tools` key.
|
|
671
|
+
*/
|
|
672
|
+
declare function acceptSessionUserMessage(deps: ApiRouteDeps, grant: AccessGrant, workspaceId: string, sessionId: string, input: {
|
|
673
|
+
text: string;
|
|
674
|
+
resources?: ResourceRef[];
|
|
675
|
+
tools?: ToolRef[];
|
|
676
|
+
toolsProvided: boolean;
|
|
677
|
+
model?: string | null;
|
|
678
|
+
reasoningEffort?: ReasoningEffort | null;
|
|
679
|
+
clientEventId?: string;
|
|
680
|
+
}): Promise<{
|
|
681
|
+
accepted: SessionEvent;
|
|
682
|
+
turn: SessionTurn;
|
|
683
|
+
}>;
|
|
684
|
+
/**
|
|
685
|
+
* Shared title-write path for the manual rename route AND both MCP tools
|
|
686
|
+
* (set_session_title / set_other_session_title). The clobber guard lives in
|
|
687
|
+
* the db `updateSessionTitle` UPDATE: an agent write is skipped when a user
|
|
688
|
+
* title already pinned the session. On a real write we emit `session.title_set`
|
|
689
|
+
* exactly like goal mutations emit their events; when nothing changed (agent
|
|
690
|
+
* write blocked by the user lock) we emit nothing. Returns whether a write
|
|
691
|
+
* happened so callers can avoid double work.
|
|
692
|
+
*/
|
|
693
|
+
declare function updateSessionTitle(deps: {
|
|
694
|
+
db: Database;
|
|
695
|
+
bus: EventBus;
|
|
696
|
+
}, workspaceId: string, sessionId: string, title: string, source: "user" | "agent"): Promise<{
|
|
697
|
+
updated: boolean;
|
|
698
|
+
title: string | null;
|
|
699
|
+
}>;
|
|
700
|
+
|
|
701
|
+
/** A member can manage other members (directly or via the admin wildcard). */
|
|
702
|
+
declare function memberCanAdminister(member: Pick<WorkspaceMember, "permissions">): boolean;
|
|
703
|
+
/** Only `user:` subjects are people; `api_key:` subjects belong to API keys. */
|
|
704
|
+
declare function isUserMember(member: Pick<WorkspaceMember, "subjectId">): boolean;
|
|
705
|
+
/**
|
|
706
|
+
* Turn an email lookup result into the membership subject id. A null id means
|
|
707
|
+
* no registered user matched the email — email invites for not-yet-registered
|
|
708
|
+
* users are deferred, so that is a 404 (not a 400) at the API surface.
|
|
709
|
+
*/
|
|
710
|
+
declare function resolveMemberSubjectId(userId: string | null): string;
|
|
711
|
+
/**
|
|
712
|
+
* Guard the member-remove path. Refuses (409) to remove the caller's own
|
|
713
|
+
* membership and refuses to remove the last member that still holds an admin
|
|
714
|
+
* permission, so a workspace can never be orphaned with no one able to manage
|
|
715
|
+
* it. `members` is the full roster (every subject, including api_key ones —
|
|
716
|
+
* an api_key with workspace:admin still counts as an administering subject).
|
|
717
|
+
*/
|
|
718
|
+
declare function assertWorkspaceMemberRemovable(input: {
|
|
719
|
+
members: WorkspaceMember[];
|
|
720
|
+
subjectId: string;
|
|
721
|
+
callerSubjectId: string;
|
|
722
|
+
}): void;
|
|
723
|
+
/**
|
|
724
|
+
* Guard the workspace-delete path before any external/DB mutation. Refuses
|
|
725
|
+
* (409) to delete the account's last workspace, and refuses while any session
|
|
726
|
+
* could still be running in Temporal (there is no clean per-session terminate
|
|
727
|
+
* to call first, so we will not orphan a workflow — the operator must stop the
|
|
728
|
+
* sessions first).
|
|
729
|
+
*/
|
|
730
|
+
declare function assertWorkspaceDeletable(input: {
|
|
731
|
+
workspaceCountForAccount: number;
|
|
732
|
+
activeSessionCount: number;
|
|
733
|
+
}): void;
|
|
734
|
+
|
|
735
|
+
export { type AccessDeps, type ApiRouteDeps, type ApiSandboxClient, type ApiSandboxSession, type AppDependencies, type ChannelARoutingServices, type DocumentIndexClient, type FleetContext, type FleetListResult, type FleetLiveness, type FleetSandboxEntry, type FleetServices, type FleetSwapResult, type LimitCheckInput, MARKETING_SOCIAL_PACK_ID, MAX_ENVIRONMENTS_PER_WORKSPACE, MAX_VARIABLES_PER_ENVIRONMENT, type ManagedAuth, type McpCapabilityProbe, type McpCapabilityProbeInput, type McpCapabilityProbeResult, type ObjectStorageDependency, type ProvisionResult, type ResumeBoxByIdInput, type ResumedSandboxSession, type RunOnOp, type RunOnResult, type SessionWorkflowClient, acceptSessionUserMessage, assertAllowedEnvironmentVariableName, assertConfiguredModel, assertPackSandboxImageCompatible, assertWorkspaceDeletable, assertWorkspaceMemberRemovable, buildCapabilityCatalog, buildFleetContextForSession, buildMarketingDailyAnalysisAgentConfig, checkLimit, createAndStartSession, createCatalogItem, createSessionForRequest, createValidatedScheduledTask, disableCapability, discoverMcpRegistryCapabilities, enableCapability, enabledCapabilityMcpToolRefs, getCapabilityPack, hasPermission, isBuiltInCapabilityPack, isUserMember, listCapabilityPacks, listFleet, listWorkspaceCapabilityPacks, manualScheduledTaskTriggerUsageKey, manualScheduledTaskTriggerWorkflowId, memberCanAdminister, mergeResourceRefs, normalizeResources, officialMcpRegistryUrl, postUserMessageTurn, provisionSandbox, reasoningEffortForSession, recordEnvironmentAuditEvent, recordWorkspaceUsage, relayConfigFromSettings, relayDialBaseFromSettings, requireAccessContext, requireAccessGrant, requireEnvironmentEncryption, requireEnvironmentForApi, requireLimit, requirePermission, requireQueuedTurnForApi, requireScheduledTaskForApi, resolveCapabilityPack, resolveMemberSubjectId, restoreScheduledTask, routingEnabled, runOnSandbox, scheduledTaskTemporalScheduleId, scheduledTaskToolsProvided, scheduledTaskTriggerToken, settingsWithEnabledCapabilityMcpServers, settingsWithMcpCapabilityServers, swapActiveSandbox, syncCreatedScheduledTask, syncUpdatedScheduledTask, updateSessionTitle, validateEnvironmentAttachment, validateFileResources, validateGitHubRepositorySelection, validateGitHubRepositorySelectionShape, validateMcpCapabilityConnection, validateToolRefs, validatedScheduledTaskUpdate, withDefaultEnabledCapabilityMcpTools, workflowIdForSession, wrapChannelABoxWithRouting };
|