@opengeni/api-router 0.30.3 → 2.2.0-canary.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/dist/api-websocket.d.ts +18 -0
- package/dist/app.js +1 -1
- package/dist/auth/managed-auth.d.ts +6 -0
- package/dist/{chunk-WCXHI3FF.js → chunk-3TP54PPX.js} +26692 -15389
- package/dist/chunk-3TP54PPX.js.map +1 -0
- package/dist/codemode.d.ts +8 -1
- package/dist/company-brain-okf.d.ts +24 -0
- package/dist/connected-machine-computer-access.d.ts +11 -0
- package/dist/connection-authority-owner.d.ts +59 -0
- package/dist/connection-ownership.d.ts +47 -0
- package/dist/controller-data-plane.d.ts +16 -0
- package/dist/editable-artifact-websocket.d.ts +5 -15
- package/dist/editable-artifact-workspace-files.d.ts +1 -1
- package/dist/http/api-error.d.ts +10 -0
- package/dist/http/cors.d.ts +5 -0
- package/dist/http/interaction-control-error.d.ts +13 -0
- package/dist/http/sse.d.ts +2 -3
- package/dist/index.d.ts +5 -2
- package/dist/index.js +326 -82
- package/dist/index.js.map +1 -1
- package/dist/integrations/atlassian.d.ts +17 -0
- package/dist/integrations/fiken.d.ts +7 -2
- package/dist/integrations/google-drive.d.ts +18 -0
- package/dist/integrations/oauth-client.d.ts +22 -3
- package/dist/integrations/oauth-profiles.d.ts +195 -0
- package/dist/integrations/personal-github-repositories.d.ts +45 -0
- package/dist/integrations/personal-github.d.ts +40 -0
- package/dist/integrations/pr-review-provider.d.ts +22 -0
- package/dist/integrations/provider-oauth.d.ts +8 -0
- package/dist/integrations/slack-app-home.d.ts +24 -0
- package/dist/integrations/slack-bot.d.ts +157 -9
- package/dist/integrations/slack-interactions.d.ts +39 -5
- package/dist/integrations/slack-routing.d.ts +120 -0
- package/dist/integrations/social-oauth.d.ts +5 -0
- package/dist/interaction-frame-proxy.d.ts +68 -0
- package/dist/mcp/company-brain-governed-writes.d.ts +26 -0
- package/dist/mcp/company-profile-agent-admin.d.ts +44 -0
- package/dist/mcp/documents.d.ts +1 -0
- package/dist/mcp/remember.d.ts +28 -0
- package/dist/mcp/request-abort.d.ts +19 -0
- package/dist/mcp/scheduled-task-view.d.ts +4 -4
- package/dist/mcp/server.d.ts +15 -2
- package/dist/mcp/session-view.d.ts +4 -0
- package/dist/mcp/session-wait.d.ts +137 -0
- package/dist/routes/automations.d.ts +4 -0
- package/dist/routes/billing.d.ts +5 -0
- package/dist/routes/browser-sessions.d.ts +4 -1
- package/dist/routes/company-brain.d.ts +3 -0
- package/dist/routes/company-profile.d.ts +2 -1
- package/dist/routes/connection-authorities.d.ts +3 -0
- package/dist/routes/personal-github-git-broker.d.ts +29 -0
- package/dist/routes/personal-github.d.ts +3 -0
- package/dist/routes/pr-review.d.ts +3 -0
- package/dist/routes/sessions.d.ts +1 -0
- package/dist/routes/user-resource-authorities.d.ts +3 -0
- package/dist/routes/workspace-capture.d.ts +10 -2
- package/dist/routes/workspace-learning.d.ts +3 -0
- package/dist/routes/workspaces.d.ts +19 -0
- package/dist/sandbox/channel-a.d.ts +11 -1
- package/dist/sandbox/connection-authority.d.ts +3 -0
- package/dist/sandbox/enrollment.d.ts +2 -0
- package/dist/sandbox/machines.d.ts +2 -2
- package/dist/sandbox/metrics-ingestion.d.ts +10 -20
- package/dist/sandbox/viewer.d.ts +24 -1
- package/dist/sandbox-file-artifacts.d.ts +11 -0
- package/dist/scheduled-task-deletion.d.ts +14 -0
- package/dist/slack-reaction-files.d.ts +1 -1
- package/dist/temporal-schedule-cleanup.d.ts +1 -0
- package/package.json +20 -18
- package/src/api-websocket.ts +23 -0
- package/src/app.ts +161 -23
- package/src/auth/managed-auth.ts +25 -3
- package/src/codemode.ts +53 -23
- package/src/codex-realtime.ts +8 -2
- package/src/company-brain-okf.ts +340 -0
- package/src/connected-machine-computer-access.ts +33 -0
- package/src/connection-authority-owner.ts +61 -0
- package/src/connection-ownership.ts +180 -0
- package/src/controller-data-plane.ts +47 -0
- package/src/editable-artifact-native-kernel.ts +26 -15
- package/src/editable-artifact-office-import.ts +28 -3
- package/src/editable-artifact-production.ts +13 -7
- package/src/editable-artifact-websocket.ts +11 -18
- package/src/editable-artifact-workspace-files.ts +31 -6
- package/src/http/api-error.ts +28 -0
- package/src/http/auth.ts +4 -0
- package/src/http/cors.ts +35 -0
- package/src/http/interaction-control-error.ts +164 -0
- package/src/http/sse.ts +112 -66
- package/src/index.ts +46 -6
- package/src/integrations/atlassian.ts +146 -35
- package/src/integrations/fiken.ts +102 -22
- package/src/integrations/google-drive.ts +301 -92
- package/src/integrations/oauth-client.ts +272 -143
- package/src/integrations/oauth-profiles.ts +477 -0
- package/src/integrations/personal-github-repositories.ts +445 -0
- package/src/integrations/personal-github.ts +705 -0
- package/src/integrations/pr-review-provider.ts +246 -0
- package/src/integrations/provider-oauth.ts +121 -5
- package/src/integrations/slack-app-home.ts +300 -0
- package/src/integrations/slack-bot.ts +342 -57
- package/src/integrations/slack-interactions.ts +1898 -259
- package/src/integrations/slack-routing.ts +337 -0
- package/src/integrations/social-oauth.ts +25 -0
- package/src/interaction-frame-proxy.ts +409 -0
- package/src/mcp/company-brain-governed-writes.ts +262 -0
- package/src/mcp/company-profile-agent-admin.ts +205 -0
- package/src/mcp/documents.ts +37 -6
- package/src/mcp/files.ts +16 -1
- package/src/mcp/remember.ts +181 -0
- package/src/mcp/request-abort.ts +44 -0
- package/src/mcp/scheduled-task-view.ts +1 -0
- package/src/mcp/server.ts +719 -369
- package/src/mcp/session-view.ts +54 -0
- package/src/mcp/session-wait.ts +554 -0
- package/src/model-catalog.ts +20 -12
- package/src/routes/api-integrations.ts +4 -0
- package/src/routes/api-keys.ts +1 -0
- package/src/routes/automations.ts +534 -0
- package/src/routes/billing.ts +57 -1
- package/src/routes/browser-sessions.ts +329 -79
- package/src/routes/channels.ts +17 -1
- package/src/routes/codex.ts +50 -0
- package/src/routes/company-brain.ts +367 -0
- package/src/routes/company-profile.ts +1 -1
- package/src/routes/computer-sessions.ts +320 -93
- package/src/routes/connection-authorities.ts +139 -0
- package/src/routes/connections.ts +144 -34
- package/src/routes/documents.ts +353 -4
- package/src/routes/editable-artifacts.ts +11 -3
- package/src/routes/enrollments.ts +116 -26
- package/src/routes/environments.ts +127 -55
- package/src/routes/files.ts +72 -11
- package/src/routes/install.ts +82 -28
- package/src/routes/integration-facets.ts +29 -0
- package/src/routes/interaction-resources.ts +20 -2
- package/src/routes/machines.ts +275 -13
- package/src/routes/organization-memberships.ts +717 -28
- package/src/routes/packs.ts +4 -3
- package/src/routes/personal-github-git-broker.ts +785 -0
- package/src/routes/personal-github.ts +319 -0
- package/src/routes/pr-review.ts +531 -0
- package/src/routes/rigs.ts +104 -39
- package/src/routes/scheduled-tasks.ts +19 -21
- package/src/routes/sessions.ts +775 -38
- package/src/routes/social.ts +14 -2
- package/src/routes/supergrok.ts +23 -4
- package/src/routes/transcription-recordings.ts +8 -2
- package/src/routes/user-resource-authorities.ts +138 -0
- package/src/routes/workspace-artifacts.ts +4 -1
- package/src/routes/workspace-capture.ts +21 -0
- package/src/routes/workspace-learning.ts +228 -0
- package/src/routes/workspaces.ts +59 -6
- package/src/sandbox/auth-callout.ts +38 -12
- package/src/sandbox/channel-a.ts +242 -19
- package/src/sandbox/connection-authority.ts +3 -0
- package/src/sandbox/enrollment.ts +15 -3
- package/src/sandbox/machines.ts +186 -64
- package/src/sandbox/metrics-ingestion.ts +220 -58
- package/src/sandbox/viewer.ts +243 -19
- package/src/sandbox-file-artifacts.ts +329 -0
- package/src/scheduled-task-deletion.ts +127 -0
- package/src/slack-reaction-files.ts +16 -5
- package/src/temporal-schedule-cleanup.ts +13 -0
- package/dist/chunk-WCXHI3FF.js.map +0 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { WebStandardStreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/webStandardStreamableHttp.js";
|
|
2
|
+
/**
|
|
3
|
+
* Serve one first-party MCP POST and bind the tool handlers' `extra.signal` to
|
|
4
|
+
* the HTTP client's connection.
|
|
5
|
+
*
|
|
6
|
+
* The API builds a fresh transport plus `McpServer` per POST, so an MCP
|
|
7
|
+
* `notifications/cancelled` from the worker would land on a different Protocol
|
|
8
|
+
* instance and never reach the handler. The only cancellation evidence this
|
|
9
|
+
* process can observe is the HTTP request's own abort (`Request.signal`, which
|
|
10
|
+
* Bun fires when the client disconnects). Closing the transport runs the SDK
|
|
11
|
+
* `Protocol._onclose`, which aborts every in-flight request handler's
|
|
12
|
+
* controller, so a blocking tool such as `session_wait` stops promptly when the
|
|
13
|
+
* worker drops the call (Steer, Pause, turn interruption).
|
|
14
|
+
*
|
|
15
|
+
* In JSON-response mode the SDK's `handleRequest` promise never settles once
|
|
16
|
+
* its stream mapping is cleared, so the race resolves a client-gone response
|
|
17
|
+
* instead of leaving the route handler pending.
|
|
18
|
+
*/
|
|
19
|
+
export declare function handleMcpRequestWithClientAbort(transport: Pick<WebStandardStreamableHTTPServerTransport, "handleRequest" | "close">, request: Request, clientSignal: AbortSignal | undefined): Promise<Response>;
|
|
@@ -137,7 +137,7 @@ export declare function scheduledTaskMcpSummary(task: ScheduledTask): {
|
|
|
137
137
|
configuration: {
|
|
138
138
|
model: string | null;
|
|
139
139
|
reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
|
|
140
|
-
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "runloop" | "selfhosted" | "vercel" | null;
|
|
140
|
+
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "opensandbox" | "runloop" | "selfhosted" | "vercel" | null;
|
|
141
141
|
hasGoal: boolean;
|
|
142
142
|
promptBytes: number;
|
|
143
143
|
resourceCount: number;
|
|
@@ -260,7 +260,7 @@ export declare function boundScheduledTaskDetailMcp(task: ScheduledTask): {
|
|
|
260
260
|
configuration: {
|
|
261
261
|
model: string | null;
|
|
262
262
|
reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
|
|
263
|
-
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "runloop" | "selfhosted" | "vercel" | null;
|
|
263
|
+
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "opensandbox" | "runloop" | "selfhosted" | "vercel" | null;
|
|
264
264
|
hasGoal: boolean;
|
|
265
265
|
promptBytes: number;
|
|
266
266
|
resourceCount: number;
|
|
@@ -310,7 +310,7 @@ export declare function boundScheduledTaskDetailMcp(task: ScheduledTask): {
|
|
|
310
310
|
metadataKeys: string[];
|
|
311
311
|
model: string | null;
|
|
312
312
|
reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
|
|
313
|
-
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "runloop" | "selfhosted" | "vercel" | null;
|
|
313
|
+
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "opensandbox" | "runloop" | "selfhosted" | "vercel" | null;
|
|
314
314
|
goal: {
|
|
315
315
|
text: string;
|
|
316
316
|
successCriteria: string | null;
|
|
@@ -444,7 +444,7 @@ export declare function boundScheduledTaskMcpPage(input: {
|
|
|
444
444
|
configuration: {
|
|
445
445
|
model: string | null;
|
|
446
446
|
reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
|
|
447
|
-
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "runloop" | "selfhosted" | "vercel" | null;
|
|
447
|
+
sandboxBackend: "blaxel" | "cloudflare" | "daytona" | "docker" | "e2b" | "local" | "modal" | "none" | "opensandbox" | "runloop" | "selfhosted" | "vercel" | null;
|
|
448
448
|
hasGoal: boolean;
|
|
449
449
|
promptBytes: number;
|
|
450
450
|
resourceCount: number;
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type AccessGrant, type SessionAuthorizationActor, type WorkspaceMemoryPromptMode } from "@opengeni/contracts";
|
|
1
|
+
import { type AccessGrant, type GitHubRepository, type ResourceRef, type SessionAuthorizationActor, type WorkspaceMemoryPromptMode } from "@opengeni/contracts";
|
|
2
2
|
import { listSessionDiscoverySummaries, type SessionDiscoveryCursor, type SessionDiscoveryOrderBy } from "@opengeni/db";
|
|
3
3
|
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
4
|
import type { ApiRouteDeps } from "@opengeni/core";
|
|
@@ -45,6 +45,16 @@ export declare function memorySlackPublicationActor(actor: Extract<SessionAuthor
|
|
|
45
45
|
};
|
|
46
46
|
ownerLabel: string | null;
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* Project one allowlisted GitHub App repository into the resource an agent or
|
|
50
|
+
* scheduled task attaches. Every listed repository is in the workspace
|
|
51
|
+
* allowlist, public or private, so every resource carries the stable ids
|
|
52
|
+
* that mint the scoped installation token; a bare URI would clone anonymously
|
|
53
|
+
* and could never push.
|
|
54
|
+
*/
|
|
55
|
+
export declare function repositoryWithScheduledTaskResource(repository: GitHubRepository): GitHubRepository & {
|
|
56
|
+
resource: ResourceRef;
|
|
57
|
+
};
|
|
48
58
|
export declare function encodeSessionDiscoveryCursor(cursor: SessionDiscoveryCursor): string;
|
|
49
59
|
export declare function decodeSessionDiscoveryCursor(value: string): SessionDiscoveryCursor;
|
|
50
60
|
export declare function capSessionDiscoveryPage(page: Awaited<ReturnType<typeof listSessionDiscoverySummaries>>, includeLastMessage: boolean): {
|
|
@@ -79,10 +89,13 @@ export declare function capSessionDiscoveryPage(page: Awaited<ReturnType<typeof
|
|
|
79
89
|
attentionDescendants: number;
|
|
80
90
|
pausedDescendants: number;
|
|
81
91
|
failedDescendants: number;
|
|
92
|
+
unreadDescendants?: number | undefined;
|
|
93
|
+
activelyWorkingDescendants?: number | undefined;
|
|
94
|
+
attentionSince?: string | null | undefined;
|
|
82
95
|
truncated: boolean;
|
|
83
96
|
};
|
|
84
97
|
latestMessage?: {
|
|
85
|
-
type: "agent.message.completed" | "agent.message.delta" | "agent.model.request" | "agent.model.usage" | "agent.reasoning.delta" | "agent.toolCall.created" | "agent.toolCall.output" | "agent.updated" | "artifact.created" | "codex.account.switched" | "codex.capacity.resumed" | "codex.capacity.superseded" | "codex.capacity.waiting" | "codex.credential.selected" | "codex.fleet.decision" | "credential.auth_needed" | "fs.changed" | "git.changed" | "goal.cleared" | "goal.completed" | "goal.continuation" | "goal.paused" | "goal.progress" | "goal.resumed" | "goal.rewrite.proposed" | "goal.rewrite.rejected" | "goal.set" | "goal.updated" | "machine.link.lost" | "machine.link.restored" | "machine.op.failed" | "machine.op.recovered" | "machine.runner.restarted" | "memory.corrected" | "memory.saved" | "recording.available" | "recording.failed" | "recording.started" | "rig.setup.completed" | "rig.setup.failed" | "rig.setup.skipped" | "rig.setup.started" | "sandbox.box.created" | "sandbox.box.lost" | "sandbox.box.snapshot" | "sandbox.box.terminated" | "sandbox.command.output.delta" | "sandbox.env.drift" | "sandbox.operation.completed" | "sandbox.operation.failed" | "sandbox.operation.started" | "session.context.cleared" | "session.context.compacted" | "session.context.compaction.requested" | "session.context.compaction.skipped" | "session.context.compaction.started" | "session.control.paused" | "session.control.resumed" | "session.control.steer_requested" | "session.created" | "session.event.envelope_omitted" | "session.humanInput.requested" | "session.mcp.approval_policy.updated" | "session.queue.changed" | "session.queue.history" | "session.queue.prompt.cancelled" | "session.realtime.ended" | "session.realtime.started" | "session.requiresAction" | "session.route.reconciled" | "session.status.changed" | "session.title_set" | "session.tool_policy.updated" | "session.visibility.changed" | "stream.closed" | "stream.opened" | "stream.revoked" | "stream.url.rotated" | "system.update.cancelled" | "system.update.delivered" | "system.update.pending" | "system.update.settled" | "system.update.superseded" | "terminal.pty.exited" | "terminal.pty.output.delta" | "terminal.pty.started" | "tool.auth_needed" | "turn.cancelled" | "turn.capacity_waiting" | "turn.completed" | "turn.event.rejected_late" | "turn.failed" | "turn.queued" | "turn.recovery.requested" | "turn.started" | "turn.superseded" | "user.approvalDecision" | "user.humanInputResponse" | "user.message" | "user.pause" | "workspace.inference.paused" | "workspace.inference.resumed" | "workspace.revision.captured" | "workspace.revision.degraded";
|
|
98
|
+
type: "agent.message.completed" | "agent.message.delta" | "agent.model.request" | "agent.model.usage" | "agent.reasoning.delta" | "agent.toolCall.created" | "agent.toolCall.output" | "agent.updated" | "artifact.created" | "codex.account.switched" | "codex.capacity.resumed" | "codex.capacity.superseded" | "codex.capacity.waiting" | "codex.credential.selected" | "codex.fleet.decision" | "credential.auth_needed" | "fs.changed" | "git.changed" | "goal.cleared" | "goal.completed" | "goal.continuation" | "goal.held" | "goal.paused" | "goal.progress" | "goal.resumed" | "goal.rewrite.proposed" | "goal.rewrite.rejected" | "goal.set" | "goal.updated" | "machine.link.lost" | "machine.link.restored" | "machine.op.failed" | "machine.op.recovered" | "machine.runner.restarted" | "memory.corrected" | "memory.saved" | "recording.available" | "recording.failed" | "recording.started" | "rig.setup.completed" | "rig.setup.failed" | "rig.setup.skipped" | "rig.setup.started" | "sandbox.box.created" | "sandbox.box.lost" | "sandbox.box.snapshot" | "sandbox.box.terminated" | "sandbox.command.output.delta" | "sandbox.env.drift" | "sandbox.operation.completed" | "sandbox.operation.failed" | "sandbox.operation.started" | "session.command.backgrounded" | "session.command.finished" | "session.context.cleared" | "session.context.compacted" | "session.context.compaction.requested" | "session.context.compaction.skipped" | "session.context.compaction.started" | "session.control.paused" | "session.control.resumed" | "session.control.steer_requested" | "session.created" | "session.event.envelope_omitted" | "session.humanInput.requested" | "session.mcp.approval_policy.updated" | "session.personal_resources.attached" | "session.queue.changed" | "session.queue.history" | "session.queue.prompt.cancelled" | "session.realtime.ended" | "session.realtime.started" | "session.requiresAction" | "session.route.reconciled" | "session.status.changed" | "session.title_set" | "session.tool_policy.updated" | "session.visibility.changed" | "stream.closed" | "stream.opened" | "stream.revoked" | "stream.url.rotated" | "system.update.cancelled" | "system.update.delivered" | "system.update.pending" | "system.update.settled" | "system.update.superseded" | "terminal.pty.exited" | "terminal.pty.output.delta" | "terminal.pty.started" | "tool.auth_needed" | "turn.cancelled" | "turn.capacity_waiting" | "turn.completed" | "turn.event.rejected_late" | "turn.failed" | "turn.queued" | "turn.recovery.requested" | "turn.started" | "turn.startup.phase.completed" | "turn.startup.phase.failed" | "turn.startup.phase.started" | "turn.superseded" | "user.approvalDecision" | "user.humanInputResponse" | "user.message" | "user.pause" | "workspace.inference.paused" | "workspace.inference.resumed" | "workspace.revision.captured" | "workspace.revision.degraded";
|
|
86
99
|
preview: string | null;
|
|
87
100
|
previewTruncated: boolean;
|
|
88
101
|
} | null;
|
|
@@ -93,6 +93,7 @@ export declare function boundSessionDetailMcp(session: Session, effectiveControl
|
|
|
93
93
|
rigId: string | null;
|
|
94
94
|
rigVersionId: string | null;
|
|
95
95
|
firstPartyMcpPermissions: unknown;
|
|
96
|
+
effectiveToolPolicy: unknown;
|
|
96
97
|
mcpServers: unknown;
|
|
97
98
|
parentSessionId: string | null;
|
|
98
99
|
createIdempotencyKey: string | null;
|
|
@@ -118,6 +119,9 @@ export declare function boundSessionDetailMcp(session: Session, effectiveControl
|
|
|
118
119
|
attentionDescendants: number;
|
|
119
120
|
pausedDescendants: number;
|
|
120
121
|
failedDescendants: number;
|
|
122
|
+
unreadDescendants?: number | undefined;
|
|
123
|
+
activelyWorkingDescendants?: number | undefined;
|
|
124
|
+
attentionSince?: string | null | undefined;
|
|
121
125
|
truncated: boolean;
|
|
122
126
|
};
|
|
123
127
|
createdAt: string;
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `session_wait`: one blocking first-party MCP call that replaces the
|
|
3
|
+
* `sleep 55` plus three or four `session_events`/`session_get` probes an agent
|
|
4
|
+
* otherwise runs per loop while it waits for a child or peer session.
|
|
5
|
+
*
|
|
6
|
+
* The durable `session_events` table is the only authority. The NATS event bus
|
|
7
|
+
* is live fanout only, so every wake (bus, deadline, or the initial call) is
|
|
8
|
+
* followed by a database read and the returned rows are always the exact
|
|
9
|
+
* durable events, never the bus payload. Subscriptions are opened before the
|
|
10
|
+
* first read so an event committed between the read and the subscription
|
|
11
|
+
* cannot be missed.
|
|
12
|
+
*
|
|
13
|
+
* Timing facts: the built-in `opengeni` MCP server entry carries no
|
|
14
|
+
* `timeoutMs`, so the worker's MCP client uses the SDK default request timeout
|
|
15
|
+
* of 60 s and a longer call would surface as a `-32001` tool error. The wait is
|
|
16
|
+
* therefore capped at {@link SESSION_WAIT_MAX_SECONDS} both in the tool schema
|
|
17
|
+
* and inside {@link waitForSessionChanges}. The API's `Bun.serve`
|
|
18
|
+
* `idleTimeout` is 255 s, far above that cap.
|
|
19
|
+
*
|
|
20
|
+
* Cancellation: the API serves one transport per POST, so the worker's MCP
|
|
21
|
+
* `notifications/cancelled` never reaches this handler; instead the route binds
|
|
22
|
+
* the HTTP request's own abort to `transport.close()` (`request-abort.ts`),
|
|
23
|
+
* which aborts `extra.signal`. A worker that drops the call on Steer/Pause
|
|
24
|
+
* therefore ends the server-side wait promptly; the deadline bounds it anyway.
|
|
25
|
+
*
|
|
26
|
+
* The live bus is best-effort: a failed subscription degrades the wait to the
|
|
27
|
+
* durable pre-check plus the deadline re-check and is reported as
|
|
28
|
+
* `liveFanout: false` rather than failing the tool.
|
|
29
|
+
*/
|
|
30
|
+
import type { SessionEvent, SessionEventSemanticClass, SessionEventType } from "@opengeni/contracts";
|
|
31
|
+
export declare const SESSION_WAIT_MAX_TARGETS = 16;
|
|
32
|
+
export declare const SESSION_WAIT_MAX_SECONDS = 50;
|
|
33
|
+
export declare const SESSION_WAIT_DEFAULT_SECONDS = 45;
|
|
34
|
+
/** Newest-first durable rows read per target on every database check. */
|
|
35
|
+
export declare const SESSION_WAIT_EVENTS_PER_TARGET = 20;
|
|
36
|
+
/**
|
|
37
|
+
* The durable event types that matter to a waiter: turn lifecycle, completed
|
|
38
|
+
* agent messages, blocking failures, goal facts, and session status/control
|
|
39
|
+
* changes. Raw deltas, tool receipts, sandbox/machine diagnostics, and PTY
|
|
40
|
+
* noise never wake a waiter; `session_events` remains the drill-down for them.
|
|
41
|
+
*/
|
|
42
|
+
export declare const SESSION_WAIT_EVENT_TYPES: readonly ["turn.started", "turn.completed", "turn.failed", "turn.cancelled", "turn.superseded", "turn.capacity_waiting", "agent.message.completed", "session.status.changed", "session.requiresAction", "session.humanInput.requested", "session.control.paused", "session.control.resumed", "tool.auth_needed", "credential.auth_needed", "rig.setup.failed", "goal.set", "goal.updated", "goal.progress", "goal.rewrite.proposed", "goal.rewrite.rejected", "goal.completed", "goal.paused", "goal.resumed", "goal.cleared", "goal.continuation"];
|
|
43
|
+
/** The self-session event that announces a newly pending machine input. */
|
|
44
|
+
export declare const SESSION_WAIT_OWN_PENDING_EVENT_TYPE = "system.update.pending";
|
|
45
|
+
/**
|
|
46
|
+
* Whether a pending own machine input of this kind ends the wait. Every
|
|
47
|
+
* pre-existing kind and `child_requires_action` are `immediate`; deferred
|
|
48
|
+
* child notices are reported but do not end the wait by themselves.
|
|
49
|
+
*/
|
|
50
|
+
export declare function ownPendingKindWakes(kind: string): boolean;
|
|
51
|
+
export declare function sessionWaitSemanticClass(type: SessionEventType): SessionEventSemanticClass;
|
|
52
|
+
export type SessionWaitTarget = {
|
|
53
|
+
sessionId: string;
|
|
54
|
+
afterSequence: number;
|
|
55
|
+
};
|
|
56
|
+
export type SessionWaitEventSummary = {
|
|
57
|
+
id: string;
|
|
58
|
+
sequence: number;
|
|
59
|
+
type: SessionEventType;
|
|
60
|
+
occurredAt: string;
|
|
61
|
+
turnId: string | null;
|
|
62
|
+
turnGeneration: number | null;
|
|
63
|
+
status: string;
|
|
64
|
+
text: string | null;
|
|
65
|
+
failure: {
|
|
66
|
+
error: string | null;
|
|
67
|
+
code: string | null;
|
|
68
|
+
retryable: boolean | null;
|
|
69
|
+
recovery: string | null;
|
|
70
|
+
} | null;
|
|
71
|
+
result?: unknown;
|
|
72
|
+
};
|
|
73
|
+
export type SessionWaitTargetResult = {
|
|
74
|
+
sessionId: string;
|
|
75
|
+
afterSequence: number;
|
|
76
|
+
/** Cursor for the next `session_wait`/`session_events after=` call. */
|
|
77
|
+
latestSequence: number;
|
|
78
|
+
hasMore: boolean;
|
|
79
|
+
events: SessionWaitEventSummary[];
|
|
80
|
+
};
|
|
81
|
+
export type SessionWaitResult = {
|
|
82
|
+
changed: SessionWaitTargetResult[];
|
|
83
|
+
ownPendingUpdates: number;
|
|
84
|
+
ownPendingUpdateKinds: string[];
|
|
85
|
+
/**
|
|
86
|
+
* Pending own inputs whose kind wakes the session by itself (every
|
|
87
|
+
* pre-existing kind plus `child_requires_action`). Only these end the wait;
|
|
88
|
+
* `deferred` child notices (resolution, pause, capacity wait, progress) are
|
|
89
|
+
* reported but keep the wait on the targets.
|
|
90
|
+
*/
|
|
91
|
+
ownPendingImmediateUpdates: number;
|
|
92
|
+
ownPendingDeferredUpdateKinds: string[];
|
|
93
|
+
waitedMs: number;
|
|
94
|
+
timedOut: boolean;
|
|
95
|
+
aborted: boolean;
|
|
96
|
+
/** False when at least one live-fanout subscription failed; the wait then relied on the deadline re-check. */
|
|
97
|
+
liveFanout: boolean;
|
|
98
|
+
truncated: boolean;
|
|
99
|
+
bytes: number;
|
|
100
|
+
maxBytes: number;
|
|
101
|
+
};
|
|
102
|
+
export type SessionWaitTargetRead = {
|
|
103
|
+
events: readonly SessionEvent[];
|
|
104
|
+
hasMore: boolean;
|
|
105
|
+
};
|
|
106
|
+
export type SessionWaitSource = {
|
|
107
|
+
/** Durable forward read of matching events strictly after the target cursor. */
|
|
108
|
+
readTargetEvents: (target: SessionWaitTarget) => Promise<SessionWaitTargetRead>;
|
|
109
|
+
/** Kinds of the caller's own pending machine inputs; null disables self tracking. */
|
|
110
|
+
readOwnPendingUpdateKinds: (() => Promise<readonly string[]>) | null;
|
|
111
|
+
/** Live fanout subscription for one session; the returned function unsubscribes. */
|
|
112
|
+
subscribe: (sessionId: string, onEvents: (events: SessionEvent[]) => void | Promise<void>) => Promise<() => void>;
|
|
113
|
+
/**
|
|
114
|
+
* Re-run target authorization for the sessions about to be returned after a
|
|
115
|
+
* wait (parity with SSE re-authorization). Throws to refuse the result.
|
|
116
|
+
*/
|
|
117
|
+
reauthorizeTargets?: ((sessionIds: readonly string[]) => Promise<void>) | undefined;
|
|
118
|
+
};
|
|
119
|
+
export type SessionWaitInput = {
|
|
120
|
+
targets: readonly SessionWaitTarget[];
|
|
121
|
+
ownSessionId: string | null;
|
|
122
|
+
maxWaitMs: number;
|
|
123
|
+
source: SessionWaitSource;
|
|
124
|
+
signal?: AbortSignal | undefined;
|
|
125
|
+
now?: (() => number) | undefined;
|
|
126
|
+
maxBytes?: number | undefined;
|
|
127
|
+
};
|
|
128
|
+
export declare function waitForSessionChanges(input: SessionWaitInput): Promise<SessionWaitResult>;
|
|
129
|
+
/** One bounded, result-bearing summary of a durable event for a waiter. */
|
|
130
|
+
export declare function summarizeSessionWaitEvent(event: SessionEvent, textChars?: number): SessionWaitEventSummary;
|
|
131
|
+
/**
|
|
132
|
+
* Keep the whole model-visible result at or below the `session_events` MCP
|
|
133
|
+
* envelope. Text is tightened first; only then are newest rows dropped from the
|
|
134
|
+
* largest target, which keeps each target's `latestSequence` an exact cursor
|
|
135
|
+
* for the rows actually delivered and marks the remainder as `hasMore`.
|
|
136
|
+
*/
|
|
137
|
+
export declare function boundSessionWaitResult(input: Omit<SessionWaitResult, "truncated" | "bytes" | "maxBytes">, maxBytes?: number): SessionWaitResult;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type ApiRouteDeps } from "@opengeni/core";
|
|
2
|
+
import type { Hono } from "hono";
|
|
3
|
+
export declare function registerAutomationRoutes(app: Hono, deps: ApiRouteDeps): void;
|
|
4
|
+
export declare function readAutomationWebhookBody(request: Request, maxBytes: number): Promise<Uint8Array>;
|
package/dist/routes/billing.d.ts
CHANGED
|
@@ -13,4 +13,9 @@ export declare function stripeCheckoutSessionCreateParams(input: {
|
|
|
13
13
|
cancelUrl?: string | undefined;
|
|
14
14
|
idempotencyKey: string;
|
|
15
15
|
}): Stripe.Checkout.SessionCreateParams;
|
|
16
|
+
export declare function stripeBillingPortalSessionCreateParams(input: {
|
|
17
|
+
customerId: string;
|
|
18
|
+
publicBaseUrl?: string | undefined;
|
|
19
|
+
returnUrl?: string | undefined;
|
|
20
|
+
}): Stripe.BillingPortal.SessionCreateParams;
|
|
16
21
|
export declare function stripeCustomerProvider(input: ApiRouteDeps | Stripe.Event): "stripe:live" | "stripe:test";
|
|
@@ -2,7 +2,10 @@ import { InteractionActor, type AccessGrant, type FileAsset } from "@opengeni/co
|
|
|
2
2
|
import { type ApiRouteDeps, type ResolvedSessionAuthorization } from "@opengeni/core";
|
|
3
3
|
import type { Hono } from "hono";
|
|
4
4
|
export declare function registerBrowserSessionRoutes(app: Hono, deps: ApiRouteDeps): void;
|
|
5
|
-
export declare function
|
|
5
|
+
export declare function browserNeedsStandaloneDisplayStack(input: {
|
|
6
|
+
headless: boolean;
|
|
7
|
+
linkedComputer: boolean;
|
|
8
|
+
}): boolean;
|
|
6
9
|
export declare function interactionActorForGrant(grant: AccessGrant): ReturnType<typeof InteractionActor.parse>;
|
|
7
10
|
/** Resolve Drive authority from the same immutable session authorization that
|
|
8
11
|
* admitted the browser action. Agent-attempt subjects are technical worker
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
import { type ApiRouteDeps } from "@opengeni/core";
|
|
1
|
+
import { type AccessGrantAuthorization, type ApiRouteDeps } from "@opengeni/core";
|
|
2
2
|
import type { Hono } from "hono";
|
|
3
|
+
export declare function requireDirectAccountAdmin(access: AccessGrantAuthorization): void;
|
|
3
4
|
export declare function registerCompanyProfileRoutes(app: Hono, deps: ApiRouteDeps): void;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ApiRouteDeps } from "@opengeni/core";
|
|
2
|
+
import { type PersonalGitHubGitBrokerClaims, type PersonalGitHubGitBrokerRepositoryClaim } from "@opengeni/github";
|
|
3
|
+
import type { Hono } from "hono";
|
|
4
|
+
export declare const PERSONAL_GITHUB_GIT_BROKER_PATH_PREFIX = "/v1/git/personal/";
|
|
5
|
+
type BrokerOperation = "info_refs" | "upload_pack" | "receive_pack";
|
|
6
|
+
type BrokerRepository = Omit<PersonalGitHubGitBrokerRepositoryClaim, "routeId">;
|
|
7
|
+
type BrokerAuthority = {
|
|
8
|
+
claims: PersonalGitHubGitBrokerClaims;
|
|
9
|
+
repository: BrokerRepository;
|
|
10
|
+
providerPrincipalId: string;
|
|
11
|
+
};
|
|
12
|
+
export type PersonalGitHubGitBrokerServices = {
|
|
13
|
+
openClaims: (token: string) => PersonalGitHubGitBrokerClaims | null;
|
|
14
|
+
resolveAuthority: (claims: PersonalGitHubGitBrokerClaims, routeId: string) => Promise<BrokerAuthority>;
|
|
15
|
+
authorizeProviderRequest: (authority: BrokerAuthority, destinationUrl: string, operation: "identity_verify" | "repository_verify" | BrokerOperation) => Promise<string>;
|
|
16
|
+
fetch: typeof fetch;
|
|
17
|
+
idleTimeoutMs?: number;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Register the three closed Git smart-HTTP operations. These routes are not a
|
|
21
|
+
* product-auth bypass: their only credential is the short-lived encrypted,
|
|
22
|
+
* exact-attempt broker bearer and every physical provider request is fenced
|
|
23
|
+
* again against current database authority.
|
|
24
|
+
*/
|
|
25
|
+
export declare function registerPersonalGitHubGitBrokerRoutes(app: Hono, deps: ApiRouteDeps, services?: PersonalGitHubGitBrokerServices): void;
|
|
26
|
+
export declare function isPersonalGitHubGitBrokerPath(pathname: string): boolean;
|
|
27
|
+
export declare function isPersonalGitHubGitBrokerRequest(method: string, pathname: string): boolean;
|
|
28
|
+
export declare function handlePersonalGitHubGitBrokerRequest(request: Request, routeId: string, operation: BrokerOperation, services: PersonalGitHubGitBrokerServices): Promise<Response>;
|
|
29
|
+
export {};
|
|
@@ -12,6 +12,7 @@ export declare function goalProposalMatchesExpectedRevision(revision: Pick<Sessi
|
|
|
12
12
|
* host-managed mode; standalone deployments never consult this classifier.
|
|
13
13
|
*/
|
|
14
14
|
export declare function sessionAuthorizationOperationForHttp(method: string, pathname: string, sessionId: string): SessionAuthorizationOperation | null;
|
|
15
|
+
export declare function sessionTenancyHttpError(error: unknown): Error;
|
|
15
16
|
export type AgentTopologyCursorEnvelope = {
|
|
16
17
|
cursor: SessionDiscoveryCursor;
|
|
17
18
|
parentSessionId: string | null;
|
|
@@ -46,7 +46,15 @@ export declare class WorkspaceCaptureManifestCache {
|
|
|
46
46
|
* manifest blob has been GC'd (all graceful cold-fallback states — never errors).
|
|
47
47
|
* Inline manifest for ≤2MB, signed URL above.
|
|
48
48
|
*/
|
|
49
|
-
|
|
49
|
+
/** Awaited before a signed capture URL is returned to the caller: the route
|
|
50
|
+
* records the metadata-only issuance audit fact. A throwing recorder fails
|
|
51
|
+
* the serve closed - no recorded fact, no bearer capability. */
|
|
52
|
+
export type CaptureSignedUrlIssuanceRecorder = (fact: {
|
|
53
|
+
kind: "capture_manifest" | "capture_file";
|
|
54
|
+
revision: number;
|
|
55
|
+
expiresAt: string;
|
|
56
|
+
}) => Promise<void>;
|
|
57
|
+
export declare function serveWorkspaceCapture(row: WorkspaceCaptureRow | null, storage: CaptureStoragePort, cache?: WorkspaceCaptureManifestCache, onSignedUrlIssued?: CaptureSignedUrlIssuanceRecorder): Promise<GetWorkspaceCaptureResponse>;
|
|
50
58
|
/**
|
|
51
59
|
* Shape the GET …/workspace/capture/file response from a loaded row (the row
|
|
52
60
|
* already resolved to the requested revision, or the latest). Throws
|
|
@@ -55,5 +63,5 @@ export declare function serveWorkspaceCapture(row: WorkspaceCaptureRow | null, s
|
|
|
55
63
|
* a captured file whose after-image blob is missing). Inline content for ≤256KB,
|
|
56
64
|
* signed URL above.
|
|
57
65
|
*/
|
|
58
|
-
export declare function serveWorkspaceCaptureFile(row: WorkspaceCaptureRow | null, path: string, storage: CaptureStoragePort): Promise<GetWorkspaceCaptureFileResponse>;
|
|
66
|
+
export declare function serveWorkspaceCaptureFile(row: WorkspaceCaptureRow | null, path: string, storage: CaptureStoragePort, onSignedUrlIssued?: CaptureSignedUrlIssuanceRecorder): Promise<GetWorkspaceCaptureFileResponse>;
|
|
59
67
|
export {};
|
|
@@ -1,5 +1,24 @@
|
|
|
1
|
+
import { type WorkspaceMember as WorkspaceMemberValue } from "@opengeni/contracts";
|
|
1
2
|
import type { Hono } from "hono";
|
|
2
3
|
import type { ApiRouteDeps } from "@opengeni/core";
|
|
3
4
|
import { type Settings } from "@opengeni/config";
|
|
4
5
|
export declare function canonicalWorkspacePolicyModelIds(settings: Settings, modelIds: string[] | null | undefined): string[] | null;
|
|
6
|
+
type WorkspaceMemberProjectionInput = Omit<WorkspaceMemberValue, "permissions"> & {
|
|
7
|
+
permissions: unknown;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Keep the roster readable across stored-permission contract changes. Unknown
|
|
11
|
+
* values are never re-authorized: they are omitted from the public projection,
|
|
12
|
+
* while every currently recognized permission is preserved in stored order.
|
|
13
|
+
*/
|
|
14
|
+
export declare function workspaceMembersResponse(members: readonly WorkspaceMemberProjectionInput[]): {
|
|
15
|
+
members: {
|
|
16
|
+
subjectId: string;
|
|
17
|
+
subjectLabel: string | null;
|
|
18
|
+
role: string;
|
|
19
|
+
permissions: ("account:admin" | "account:read" | "api_keys:manage" | "artifacts:publish" | "artifacts:read" | "billing:manage" | "billing:read" | "codemode:call" | "connections:read" | "connections:write" | "documents:manage" | "documents:search" | "enrollments:manage" | "enrollments:read" | "environments:manage" | "environments:use" | "files:read" | "files:upload" | "files:write" | "github:manage" | "github:use" | "goals:manage" | "mcp_servers:attach" | "members:manage" | "rigs:manage" | "rigs:use" | "scheduled_tasks:manage" | "scheduled_tasks:run" | "secrets:list" | "secrets:read" | "secrets:write" | "sessions:control" | "sessions:create" | "sessions:read" | "stream:acknowledge" | "stream:control" | "stream:view" | "terminal:attach" | "variable-sets:attach" | "variable-sets:list" | "variable-sets:manage" | "variable-sets:read" | "variable-sets:use" | "variable-sets:write" | "workspace:admin" | "workspace:create" | "workspace:read")[];
|
|
20
|
+
createdAt: string;
|
|
21
|
+
}[];
|
|
22
|
+
};
|
|
5
23
|
export declare function registerWorkspaceRoutes(app: Hono, deps: ApiRouteDeps): void;
|
|
24
|
+
export {};
|
|
@@ -10,7 +10,7 @@ export type ChannelAServices = {
|
|
|
10
10
|
bus: EventBus;
|
|
11
11
|
observability?: Observability | undefined;
|
|
12
12
|
};
|
|
13
|
-
export type ChannelAOperation = "fs.list" | "fs.list-batch" | "fs.read" | "fs.write" | "fs.delete" | "fs.move" | "fs.mkdir" | "git.status" | "git.diff" | "git.read-batch" | "git.log" | "git.show" | "terminal.exec" | "terminal.pty.open" | "terminal.pty.write" | "terminal.pty.resize" | "terminal.pty.close" | "browser.create" | "browser.resume" | "browser.suspend" | "browser.end" | "browser.read" | "browser.action" | "browser.control" | "browser.download.save" | "browser.attach" | "computer.create" | "computer.end" | "computer.read" | "computer.action" | "computer.control" | "computer.attach";
|
|
13
|
+
export type ChannelAOperation = "fs.list" | "fs.list-batch" | "fs.read" | "artifact.publish" | "fs.write" | "fs.delete" | "fs.move" | "fs.mkdir" | "git.status" | "git.diff" | "git.read-batch" | "git.log" | "git.show" | "terminal.exec" | "terminal.pty.open" | "terminal.pty.write" | "terminal.pty.resize" | "terminal.pty.close" | "browser.create" | "browser.resume" | "browser.suspend" | "browser.end" | "browser.read" | "browser.action" | "browser.control" | "browser.download.save" | "browser.attach" | "computer.create" | "computer.end" | "computer.read" | "computer.action" | "computer.control" | "computer.attach";
|
|
14
14
|
export type ChannelAContext = {
|
|
15
15
|
accountId: string;
|
|
16
16
|
workspaceId: string;
|
|
@@ -100,4 +100,14 @@ export declare function isChannelARequestCancellation(error: unknown, waitSignal
|
|
|
100
100
|
/** Structural classification only: exact provider exception text, codes, URLs,
|
|
101
101
|
* and identifiers never cross the telemetry boundary. */
|
|
102
102
|
export declare function channelAOperationFailureDiagnostic(error: unknown, waitSignal?: AbortSignal): ChannelAOperationFailureDiagnostic;
|
|
103
|
+
/** Exported for the telemetry contract tests; not a route surface. */
|
|
104
|
+
export declare function observeChannelAOperationFailure(services: ChannelAServices, input: {
|
|
105
|
+
workspaceId: string;
|
|
106
|
+
sandboxGroupId: string;
|
|
107
|
+
backend: string;
|
|
108
|
+
operation: string;
|
|
109
|
+
durationMs: number;
|
|
110
|
+
error: unknown;
|
|
111
|
+
waitSignal?: AbortSignal | undefined;
|
|
112
|
+
}): void;
|
|
103
113
|
export {};
|
|
@@ -35,6 +35,8 @@ export declare function startDeviceEnrollment(services: EnrollmentServices, inpu
|
|
|
35
35
|
export declare function approveDeviceEnrollment(services: EnrollmentServices, input: {
|
|
36
36
|
accountId: string;
|
|
37
37
|
workspaceId: string;
|
|
38
|
+
scope?: "organization" | "workspace" | "user";
|
|
39
|
+
allowOrganization?: boolean;
|
|
38
40
|
userCode: string;
|
|
39
41
|
allowScreenControl: boolean;
|
|
40
42
|
approvedBySubjectId: string;
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import type { Settings } from "@opengeni/config";
|
|
2
2
|
import { type Database, type MachineMetricsRow } from "@opengeni/db";
|
|
3
|
-
import type { EventBus } from "@opengeni/events";
|
|
4
3
|
import { MetricSample, type MachinesResponse } from "@opengeni/contracts";
|
|
5
4
|
export type MachinesServices = {
|
|
6
5
|
db: Database;
|
|
7
6
|
settings: Settings;
|
|
8
|
-
bus?: EventBus;
|
|
9
7
|
};
|
|
10
8
|
/**
|
|
11
9
|
* Project a stored `machine_metrics_latest` row to the contract `MetricSample`.
|
|
@@ -24,6 +22,8 @@ export declare function metricRowToSample(row: MachineMetricsRow): MetricSample;
|
|
|
24
22
|
* the enrolled machines are listed.
|
|
25
23
|
*/
|
|
26
24
|
export declare function listMachines(services: MachinesServices, input: {
|
|
25
|
+
accountId?: string;
|
|
27
26
|
workspaceId: string;
|
|
27
|
+
subjectId?: string;
|
|
28
28
|
sessionId?: string | null;
|
|
29
29
|
}): Promise<MachinesResponse>;
|
|
@@ -4,18 +4,20 @@ import { type EventBus } from "@opengeni/events";
|
|
|
4
4
|
import type { Observability } from "@opengeni/observability";
|
|
5
5
|
import { Hello, type AttachedBrowserInventorySnapshot as WireAttachedBrowserInventorySnapshot, type MetricsSample } from "@opengeni/agent-proto";
|
|
6
6
|
/** The wildcard subject the agent event plane publishes heartbeats on. */
|
|
7
|
-
export declare const AGENT_EVENTS_SUBJECT = "agent.*.*.events";
|
|
7
|
+
export declare const AGENT_EVENTS_SUBJECT = "agent.*.*.connection.*.events";
|
|
8
8
|
/** The wildcard subject the agent publishes its connect Hello on. */
|
|
9
|
-
export declare const AGENT_HELLO_SUBJECT = "agent.*.*.hello";
|
|
10
|
-
/** Parse
|
|
9
|
+
export declare const AGENT_HELLO_SUBJECT = "agent.*.*.connection.*.hello";
|
|
10
|
+
/** Parse the exact process events subject (heartbeat plane). */
|
|
11
11
|
export declare function parseAgentEventSubject(subject: string): {
|
|
12
12
|
workspaceId: string;
|
|
13
13
|
agentId: string;
|
|
14
|
+
connectionInstanceId: string;
|
|
14
15
|
} | null;
|
|
15
|
-
/** Parse
|
|
16
|
+
/** Parse the exact process hello subject (connect plane). */
|
|
16
17
|
export declare function parseAgentHelloSubject(subject: string): {
|
|
17
18
|
workspaceId: string;
|
|
18
19
|
agentId: string;
|
|
20
|
+
connectionInstanceId: string;
|
|
19
21
|
} | null;
|
|
20
22
|
/**
|
|
21
23
|
* Project a wire `MetricsSample` (proto, ms-stamped, GPU as a repeated list) to
|
|
@@ -32,20 +34,6 @@ export declare function wireSampleToDbSample(wire: MetricsSample): MachineMetric
|
|
|
32
34
|
* discovery. Unknown enum values and unsafe uint64 counters reject the whole
|
|
33
35
|
* authoritative snapshot instead of partially disconnecting good endpoints. */
|
|
34
36
|
export declare function wireAttachedBrowserInventoryToContract(wire: WireAttachedBrowserInventorySnapshot): AttachedBrowserInventoryContractValue;
|
|
35
|
-
/**
|
|
36
|
-
* Ingest ONE decoded heartbeat for an enrolled machine. Resolves the enrollment's
|
|
37
|
-
* accountId (needed for the RLS-scoped writes) from the enrollment row; an
|
|
38
|
-
* unknown/cross-workspace agentId is ignored (no row → no write). Touches
|
|
39
|
-
* last-seen + upserts latest + downsamples the series.
|
|
40
|
-
*/
|
|
41
|
-
export declare function ingestHeartbeat(db: Database, input: {
|
|
42
|
-
workspaceId: string;
|
|
43
|
-
agentId: string;
|
|
44
|
-
sample: MetricsSample;
|
|
45
|
-
}): Promise<{
|
|
46
|
-
ingested: boolean;
|
|
47
|
-
seriesAppended: boolean;
|
|
48
|
-
}>;
|
|
49
37
|
/**
|
|
50
38
|
* Decode a raw `AgentEvent` payload + ingest it (the per-message handler). A
|
|
51
39
|
* heartbeat carrying a metrics sample is ingested; a going-offline records the
|
|
@@ -55,7 +43,7 @@ export declare function ingestHeartbeat(db: Database, input: {
|
|
|
55
43
|
*/
|
|
56
44
|
export declare function handleAgentEventPayload(db: Database, observability: Observability | undefined, payload: Uint8Array, subject: string, bus?: EventBus): Promise<void>;
|
|
57
45
|
/**
|
|
58
|
-
* Start the metrics-ingestion consumer: subscribe
|
|
46
|
+
* Start the metrics-ingestion consumer: subscribe exact process events and ingest
|
|
59
47
|
* every heartbeat. Gated by sandboxSelfhostedEnabled (the caller checks the flag;
|
|
60
48
|
* a disabled deployment never starts the consumer). Returns the unsubscribe fn.
|
|
61
49
|
*/
|
|
@@ -95,6 +83,7 @@ export declare function refreshEnrollmentDisplay(db: Database, input: {
|
|
|
95
83
|
agentId: string;
|
|
96
84
|
hasDisplay: boolean;
|
|
97
85
|
desktopUnavailableReason?: string | null;
|
|
86
|
+
connectionInstanceId?: string;
|
|
98
87
|
}): Promise<{
|
|
99
88
|
updated: boolean;
|
|
100
89
|
}>;
|
|
@@ -108,6 +97,7 @@ export declare function refreshEnrollmentOpStream(db: Database, input: {
|
|
|
108
97
|
workspaceId: string;
|
|
109
98
|
agentId: string;
|
|
110
99
|
opStream: boolean;
|
|
100
|
+
connectionInstanceId?: string;
|
|
111
101
|
}): Promise<{
|
|
112
102
|
updated: boolean;
|
|
113
103
|
}>;
|
|
@@ -121,7 +111,7 @@ export declare function refreshEnrollmentOpStream(db: Database, input: {
|
|
|
121
111
|
*/
|
|
122
112
|
export declare function handleHelloPayload(db: Database, observability: Observability | undefined, payload: Uint8Array, subject: string, bus?: EventBus): Promise<void>;
|
|
123
113
|
/**
|
|
124
|
-
* Start the Hello display-refresh consumer: subscribe
|
|
114
|
+
* Start the Hello display-refresh consumer: subscribe exact process hellos and
|
|
125
115
|
* reconcile `has_display` to the live capability the agent reports on every
|
|
126
116
|
* connect. Gated by sandboxSelfhostedEnabled (the caller checks the flag). Returns
|
|
127
117
|
* the unsubscribe fn.
|
package/dist/sandbox/viewer.d.ts
CHANGED
|
@@ -51,7 +51,10 @@ export type ViewerAttachResult = {
|
|
|
51
51
|
* cannot change manifest environment variables" whenever a viewer attach (an open
|
|
52
52
|
* session page) won the cold-create race against the first turn.
|
|
53
53
|
*/
|
|
54
|
-
export declare function sessionAttachEnvironment(services: ViewerServices, workspaceId: string, session: Session
|
|
54
|
+
export declare function sessionAttachEnvironment(services: ViewerServices, workspaceId: string, session: Session,
|
|
55
|
+
/** The authenticated route subject driving this attach (0282); recorded on
|
|
56
|
+
* the materialization audit fact. Null records the legacy service sentinel. */
|
|
57
|
+
attachSubjectId: string | null): Promise<Record<string, string>>;
|
|
55
58
|
/**
|
|
56
59
|
* Acquire a `viewer` holder on the group lease, spinning up the box IN-PROCESS
|
|
57
60
|
* when cold. Mirrors the worker's resumeBoxForTurn spawner/attached branches,
|
|
@@ -65,6 +68,9 @@ export declare function attachViewer(services: ViewerServices, input: {
|
|
|
65
68
|
workspaceId: string;
|
|
66
69
|
session: Session;
|
|
67
70
|
viewerId?: string;
|
|
71
|
+
/** The authenticated subject attaching this viewer (0281): recorded on
|
|
72
|
+
* the holder row together with the live session authority epoch. */
|
|
73
|
+
viewerSubjectId?: string;
|
|
68
74
|
/** Cancel lifecycle waiting when the originating HTTP request disconnects. */
|
|
69
75
|
waitSignal?: AbortSignal;
|
|
70
76
|
}): Promise<ViewerAttachResult>;
|
|
@@ -84,6 +90,10 @@ export declare function ensureSessionGroupReady(services: ViewerServices, input:
|
|
|
84
90
|
accountId: string;
|
|
85
91
|
workspaceId: string;
|
|
86
92
|
session: Session;
|
|
93
|
+
/** The authenticated subject driving the fleet attach/swap (0282): recorded
|
|
94
|
+
* on the viewer holder and the materialization audit fact. Omitting it
|
|
95
|
+
* records the explicit service sentinel, so forward the route subject. */
|
|
96
|
+
subjectId?: string | null;
|
|
87
97
|
}): Promise<SessionGroupReadinessHold>;
|
|
88
98
|
/**
|
|
89
99
|
* Refresh a viewer holder's TTL (the app-level viewer heartbeat). Epoch-fenced:
|
|
@@ -148,6 +158,11 @@ export type DesktopStreamMint = {
|
|
|
148
158
|
export type MintDesktopStreamInput = {
|
|
149
159
|
accountId: string;
|
|
150
160
|
workspaceId: string;
|
|
161
|
+
resourceSubjectId?: string;
|
|
162
|
+
/** True when the route grant is a signed delegated token (metadata.delegated):
|
|
163
|
+
* its authority is the token, not membership rows, so the mint-time
|
|
164
|
+
* live-authority recheck does not apply. */
|
|
165
|
+
resourceSubjectDelegated?: boolean;
|
|
151
166
|
session: Session;
|
|
152
167
|
/** The viewer holder id the scoped token is minted for. */
|
|
153
168
|
viewerId: string;
|
|
@@ -197,6 +212,9 @@ type SelfhostedStreamMint = Omit<TerminalStreamMint, "transport">;
|
|
|
197
212
|
export type MintTerminalStreamInput = {
|
|
198
213
|
accountId: string;
|
|
199
214
|
workspaceId: string;
|
|
215
|
+
resourceSubjectId?: string;
|
|
216
|
+
/** See MintDesktopStreamInput.resourceSubjectDelegated. */
|
|
217
|
+
resourceSubjectDelegated?: boolean;
|
|
200
218
|
session: Session;
|
|
201
219
|
/** The viewer holder / principal id the scoped token is minted for. */
|
|
202
220
|
viewerId: string;
|
|
@@ -233,6 +251,11 @@ export type MintSelfhostedStreamInput = {
|
|
|
233
251
|
* THIS as its leaseEpoch claim so the relay rejects a stale-epoch (swapped-away)
|
|
234
252
|
* viewer. */
|
|
235
253
|
activeEpoch: number;
|
|
254
|
+
/** 0281 viewer authority claims stamped into the relay stream token. */
|
|
255
|
+
viewerAuthority?: {
|
|
256
|
+
subjectId?: string;
|
|
257
|
+
authorityEpoch: number;
|
|
258
|
+
};
|
|
236
259
|
/** The exposed stream port (6080 desktop / 7681 terminal). */
|
|
237
260
|
port: number;
|
|
238
261
|
/** The resolvable selfhosted session (the routing proxy resolves the active
|