@opengeni/core 0.12.7 → 0.14.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/dist/access/index.d.ts +22 -0
  2. package/dist/application/new-session-drafts.d.ts +14 -0
  3. package/dist/application/session-commands.d.ts +107 -0
  4. package/dist/billing/limits.d.ts +29 -0
  5. package/dist/dependencies.d.ts +137 -0
  6. package/dist/domain/capabilities.d.ts +62 -0
  7. package/dist/domain/environments.d.ts +33 -0
  8. package/dist/domain/insights.d.ts +11 -0
  9. package/dist/domain/packs.d.ts +27 -0
  10. package/dist/domain/resources.d.ts +32 -0
  11. package/dist/domain/scheduled-tasks.d.ts +72 -0
  12. package/dist/domain/session-tool-policy.d.ts +31 -0
  13. package/dist/domain/sessions.d.ts +256 -0
  14. package/dist/domain/slack-bot.d.ts +19 -0
  15. package/dist/domain/workspace-members.d.ts +34 -0
  16. package/dist/index.d.ts +23 -1189
  17. package/dist/index.js +758 -115
  18. package/dist/index.js.map +1 -1
  19. package/dist/managed-auth-type.d.ts +2 -0
  20. package/dist/rigs/index.d.ts +57 -0
  21. package/dist/sandbox/fleet.d.ts +197 -0
  22. package/dist/sandbox/routing.d.ts +55 -0
  23. package/dist/sandbox-types.d.ts +52 -0
  24. package/dist/session-authorization.d.ts +36 -0
  25. package/dist/transcription.d.ts +71 -0
  26. package/dist/workflow-wake-contract.d.ts +4 -0
  27. package/package.json +11 -11
  28. package/src/access/index.ts +73 -2
  29. package/src/application/new-session-drafts.ts +3 -0
  30. package/src/application/session-commands.ts +22 -9
  31. package/src/dependencies.ts +5 -0
  32. package/src/domain/insights.ts +480 -0
  33. package/src/domain/session-tool-policy.ts +22 -39
  34. package/src/domain/sessions.ts +140 -72
  35. package/src/domain/slack-bot.ts +2 -4
  36. package/src/index.ts +2 -0
  37. package/src/sandbox/fleet.ts +96 -33
  38. package/src/sandbox/routing.ts +29 -7
  39. package/src/transcription.ts +142 -0
@@ -0,0 +1,256 @@
1
+ import { type Settings } from "@opengeni/config";
2
+ import { SessionSpawnDenial, type AccessGrant, type CreateSessionResponse, type GoalSpec, type FirstPartyMcpToolName, type Permission, type ReasoningEffort, type ResourceRef, type Session, type SessionSkill, type SessionEvent, SessionMcpApprovalPolicy, type SessionMcpCredentialUpdateInput, type SessionMcpServerMetadata, type UpdateSessionMcpApprovalPolicyResponse, type UpdateSessionToolPolicyRequest, type SessionAuthorizationPort, type SessionToolPolicy, type SessionTurn, type ToolRef, type TurnInitiator, type TurnInitiatorContext, type TurnExecutionPolicyV1 } from "@opengeni/contracts";
3
+ import { type CreateSessionMcpServerInput, type Database, type UpdateSessionMcpServerCredentialsInput, type SessionCommandActor } from "@opengeni/db";
4
+ import { type EventBus } from "@opengeni/events";
5
+ import type { AcceptSessionUserMessageDependencies, ApiRouteDeps, SessionWorkflowClient } from "../dependencies";
6
+ /** Transport-neutral typed denial raised only after its audit row committed. */
7
+ export declare class SessionSpawnDeniedError extends Error {
8
+ readonly denial: SessionSpawnDenial;
9
+ constructor(denial: SessionSpawnDenial);
10
+ }
11
+ /**
12
+ * Resolve per-session first-party tool visibility without consulting
13
+ * authorization. Top-level omission snapshots the complete runtime default;
14
+ * child omission snapshots the parent's exact effective selection. Explicit
15
+ * [] is authoritative and must never widen.
16
+ */
17
+ export declare function resolveFirstPartyMcpToolsForCreate(requested: FirstPartyMcpToolName[] | undefined, parentStored: FirstPartyMcpToolName[] | null | undefined): FirstPartyMcpToolName[];
18
+ export declare function sessionSpawnDenialEnvelope(error: SessionSpawnDeniedError): {
19
+ readonly error: {
20
+ readonly code: "nested_agent_depth_exceeded" | "nested_agent_depth_override_forbidden";
21
+ readonly message: string;
22
+ readonly details: {
23
+ readonly denial: {
24
+ id: string;
25
+ accountId: string;
26
+ workspaceId: string;
27
+ parentSessionId: string | null;
28
+ rootSessionId: string | null;
29
+ currentDepth: number;
30
+ attemptedDepth: number;
31
+ effectiveMaxNestedAgentDepth: number;
32
+ requestedMaxNestedAgentDepthOverride: number | null;
33
+ policySource: "default" | "deployment" | "session" | "workspace";
34
+ policySessionId: string | null;
35
+ subjectId: string | null;
36
+ code: "nested_agent_depth_exceeded" | "nested_agent_depth_override_forbidden";
37
+ idempotencyKey: string | null;
38
+ createdAt: string;
39
+ };
40
+ };
41
+ };
42
+ };
43
+ export declare function settingsWithSessionMcpServerMetadata(settings: Settings, servers: SessionMcpServerMetadata[]): Settings;
44
+ export declare function createAndStartSession(input: {
45
+ requestedSessionId?: string;
46
+ db: Database;
47
+ bus: EventBus;
48
+ workflowClient: SessionWorkflowClient;
49
+ accountId: string;
50
+ workspaceId: string;
51
+ initialMessage: string;
52
+ turnInstructions?: string | null;
53
+ resources: ResourceRef[];
54
+ skills?: SessionSkill[];
55
+ tools: ToolRef[];
56
+ toolPolicy: SessionToolPolicy;
57
+ clientEventId?: string;
58
+ model: string;
59
+ reasoningEffort: Settings["openaiReasoningEffort"];
60
+ /** Session default Fast/standard; mirrored into metadata when set. */
61
+ latencyMode?: "standard" | "priority" | "fast";
62
+ turnExecutionPolicy: TurnExecutionPolicyV1;
63
+ sandboxBackend: Settings["sandboxBackend"];
64
+ metadata: Record<string, unknown>;
65
+ createdBy?: TurnInitiator;
66
+ createdByContext?: TurnInitiatorContext;
67
+ createdByActor?: Extract<SessionCommandActor, {
68
+ type: "agent_attempt";
69
+ }> | null;
70
+ variableSet?: {
71
+ id: string;
72
+ name: string;
73
+ } | null;
74
+ rigId?: string | null;
75
+ rigVersionId?: string | null;
76
+ goal?: GoalSpec | null;
77
+ instructions?: string | null;
78
+ firstPartyMcpPermissions?: Permission[] | null;
79
+ firstPartyMcpTools: FirstPartyMcpToolName[];
80
+ mcpServers?: CreateSessionMcpServerInput[];
81
+ sessionMcpServers?: SessionMcpServerMetadata[];
82
+ parentSessionId?: string | null;
83
+ createIdempotencyKey?: string | null;
84
+ sandboxGroupId?: string | null;
85
+ sandboxOs?: Session["sandboxOs"];
86
+ seedTargetSandbox?: {
87
+ sandboxId: string;
88
+ settings: Settings;
89
+ workingDir?: string | null;
90
+ } | null;
91
+ consumeNewSessionDraft?: {
92
+ subjectId: string;
93
+ expectedRevision: number;
94
+ } | null;
95
+ maxNestedAgentDepthOverride?: number | null;
96
+ allowNestedAgentDepthIncrease?: boolean;
97
+ subjectId?: string | null;
98
+ }): Promise<CreateSessionResponse>;
99
+ export declare function workflowIdForSession(sessionId: string): string;
100
+ /**
101
+ * Reject an explicit model that the host does not expose. The set of usable
102
+ * models is the union surfaced by `configuredAllowedModels` (the built-in
103
+ * provider's allow-list plus every registry provider's ids); a `model` outside
104
+ * it cannot be resolved to a provider at run time, so we fail the request at
105
+ * the API edge with 422 rather than enqueuing a turn the worker can't honor.
106
+ *
107
+ * `model` is the explicit, caller-supplied value (null/undefined when omitted).
108
+ * An omitted model defaults to `settings.openaiModel` downstream — which is
109
+ * always first in `configuredAllowedModels` — so only an explicit value is
110
+ * checked. Centralized here so every model-carrying choke point
111
+ * (create-session, user-message/turn-accept, queued-turn update, and
112
+ * scheduled-task agentConfig — a scheduled task is a session the worker runs
113
+ * later) and the MCP surfaces that share them validate identically and cannot
114
+ * drift.
115
+ */
116
+ export declare function canonicalConfiguredModel(settings: Settings, model: string | null | undefined): string | null | undefined;
117
+ export declare function assertConfiguredModel(settings: Settings, model: string | null | undefined): void;
118
+ export declare const CODEX_COMPACTION_V2_PROVIDER_LOCKED: "codex_compaction_v2_provider_locked";
119
+ /** Session is frozen on Codex remote compaction v2; non-Codex models are refused. */
120
+ export declare class CodexCompactionV2ProviderLockedError extends Error {
121
+ readonly code: "codex_compaction_v2_provider_locked";
122
+ readonly productModelId: string;
123
+ constructor(productModelId: string);
124
+ }
125
+ /**
126
+ * Fail closed when a remote_v2 session would run a non-Codex product model.
127
+ * Portable sessions and non-Codex sessions keep free mid-session provider swap.
128
+ */
129
+ export declare function assertSessionAllowsProductModel(session: Pick<Session, "codexCompactionMode">, productModelId: string | null | undefined): void;
130
+ /**
131
+ * Reject a model the WORKSPACE's model policy blocks, at the same choke points
132
+ * as assertConfiguredModel — a 422 at the edge instead of a queued turn the
133
+ * worker's authoritative post-resolution gate would fail. `model` is the
134
+ * EFFECTIVE value the caller is about to persist: pass the explicit value at
135
+ * message/turn-update/scheduled-task edges (omitted inherits an
136
+ * already-validated stored default), but at session CREATION pass
137
+ * `payload.model ?? settings.openaiModel` — an omitted model stamps the
138
+ * deployment default onto the session, and under a restricted policy that
139
+ * default may be exactly the provider the policy exists to block.
140
+ */
141
+ export declare function assertWorkspaceModelPolicyAllows(db: Database, settings: Settings, workspaceId: string, model: string | null | undefined): Promise<void>;
142
+ export declare function requireQueuedTurnForApi(db: Database, workspaceId: string, sessionId: string, turnId: string): Promise<SessionTurn>;
143
+ export declare function reasoningEffortForSession(metadata: Record<string, unknown>, fallback: Settings["openaiReasoningEffort"]): Settings["openaiReasoningEffort"];
144
+ export declare function latencyModeForSession(metadata: Record<string, unknown>, fallback?: "standard" | "priority" | "fast"): "standard" | "priority" | "fast";
145
+ /**
146
+ * Appends a `user.message` to an existing session and enqueues the resulting
147
+ * turn, merging requested resources/tools into the session and waking the
148
+ * workflow. Shared by the public events route and the first-party MCP
149
+ * `session_send_message` tool so the two surfaces cannot drift. Callers own
150
+ * resource/tool validation and the per-message usage limit before calling.
151
+ */
152
+ export declare function postUserMessageTurn(input: {
153
+ db: Database;
154
+ bus: EventBus;
155
+ workflowClient: Pick<SessionWorkflowClient, "wakeSessionWorkflow">;
156
+ settings: Settings;
157
+ accountId: string;
158
+ workspaceId: string;
159
+ sessionId: string;
160
+ text: string;
161
+ turnInstructions?: string | null;
162
+ resources: ResourceRef[];
163
+ model?: string | null;
164
+ reasoningEffort?: Settings["openaiReasoningEffort"] | null;
165
+ latencyMode?: "standard" | "priority" | "fast" | null;
166
+ clientEventId?: string;
167
+ mcpCredentialUpdates?: UpdateSessionMcpServerCredentialsInput[];
168
+ delivery?: "send" | "steer";
169
+ origin?: "human" | "operator";
170
+ actor?: string;
171
+ actorLabel?: string;
172
+ commandActor?: SessionCommandActor;
173
+ controlEtag?: string | null;
174
+ expectedDraftRevision?: number | null;
175
+ reasoningEffortFallback?: Settings["openaiReasoningEffort"];
176
+ turnExecutionPolicy: TurnExecutionPolicyV1;
177
+ }): Promise<{
178
+ accepted: SessionEvent;
179
+ turn: SessionTurn;
180
+ }>;
181
+ /**
182
+ * Full create-session flow shared by `POST /sessions` and the first-party MCP
183
+ * `session_create` tool: payload validation, resource/tool/variableSet
184
+ * checks, usage limits, session start, and usage recording. `rawPayload` is
185
+ * the unparsed request body so absent-vs-empty execution-context fields keep
186
+ * their meaning: a child inherits omitted resources/tools/mcpServers from its
187
+ * trusted immediate parent, while explicit arrays (including []) win. A
188
+ * top-level create with omitted tools applies workspace-default capability MCPs.
189
+ */
190
+ export declare function createSessionForRequest(deps: ApiRouteDeps, grant: AccessGrant, workspaceId: string, rawPayload: unknown): Promise<Session>;
191
+ /**
192
+ * Full accept-user-message flow shared by the `user.message` branch of
193
+ * `POST /sessions/:id/events` and the first-party MCP `session_send_message`
194
+ * tool: resource/tool validation, usage limits, the locked append + turn
195
+ * enqueue, and usage recording. `toolsProvided: false` durably preserves an
196
+ * Tool selection is durable session state and never rides a follow-up prompt.
197
+ */
198
+ export declare function acceptSessionUserMessage(deps: AcceptSessionUserMessageDependencies, grant: AccessGrant, workspaceId: string, sessionId: string, input: {
199
+ text: string;
200
+ turnInstructions?: string | null;
201
+ resources?: ResourceRef[];
202
+ model?: string | null;
203
+ reasoningEffort?: ReasoningEffort | null;
204
+ latencyMode?: "standard" | "priority" | "fast" | null;
205
+ clientEventId?: string;
206
+ mcpCredentialUpdates?: SessionMcpCredentialUpdateInput[];
207
+ delivery?: "send" | "steer";
208
+ origin?: "human" | "operator";
209
+ controlEtag?: string | null;
210
+ expectedDraftRevision?: number | null;
211
+ }): Promise<{
212
+ accepted: SessionEvent;
213
+ turn: SessionTurn;
214
+ }>;
215
+ /**
216
+ * Shared title-write path for the manual rename route AND both MCP tools
217
+ * (set_session_title / set_other_session_title). The clobber guard lives in
218
+ * the db `updateSessionTitle` UPDATE: an agent write is skipped when a user
219
+ * title already pinned the session. On a real write we emit `session.title_set`
220
+ * exactly like goal mutations emit their events; when nothing changed (agent
221
+ * write blocked by the user lock) we emit nothing. Returns whether a write
222
+ * happened so callers can avoid double work.
223
+ */
224
+ export declare function updateSessionTitle(deps: {
225
+ db: Database;
226
+ bus: EventBus;
227
+ sessionAuthorization?: SessionAuthorizationPort | null;
228
+ }, grant: AccessGrant, sessionId: string, title: string, source: "user" | "agent"): Promise<{
229
+ updated: boolean;
230
+ title: string | null;
231
+ relatedSessionAccess: "target" | "root";
232
+ }>;
233
+ /**
234
+ * Update one existing session MCP server's approval policy. The database
235
+ * serializes this write with attempt claim under the session lock: an already
236
+ * claimed attempt retains its immutable snapshot, while the next claim captures
237
+ * this value. No attempt is cancelled, restarted, or reinterpreted.
238
+ */
239
+ export declare function updateSessionMcpApprovalPolicy(deps: {
240
+ db: Database;
241
+ bus: EventBus;
242
+ sessionAuthorization?: SessionAuthorizationPort | null;
243
+ }, grant: AccessGrant, sessionId: string, serverId: string, requireApproval: SessionMcpApprovalPolicy): Promise<UpdateSessionMcpApprovalPolicyResponse>;
244
+ /**
245
+ * Replace the durable session tool policy. The target and its parent (when
246
+ * present) are locked by the DB event-writer helper, and the update/event are
247
+ * committed under one version-fenced transaction. An already claimed turn
248
+ * keeps its immutable snapshot; the next attempt observes this policy.
249
+ */
250
+ export declare function updateSessionToolPolicy(deps: {
251
+ db: Database;
252
+ bus: EventBus;
253
+ settings: Settings;
254
+ sessionAuthorization?: SessionAuthorizationPort | null;
255
+ }, grant: AccessGrant, sessionId: string, request: UpdateSessionToolPolicyRequest): Promise<Session>;
256
+ export declare function readSessionLineage(deps: Pick<ApiRouteDeps, "db" | "sessionAuthorization">, grant: AccessGrant, sessionId: string): Promise<import("@opengeni/db").SessionLineage>;
@@ -0,0 +1,19 @@
1
+ import { type AccessGrant, type ConnectionMetadata, type OpenGeniSlackBotConnectionMetadata as OpenGeniSlackBotMetadata, type Session } from "@opengeni/contracts";
2
+ import { type ConnectionMetadataWithVerification, type Database } from "@opengeni/db";
3
+ export declare function openGeniSlackBotMetadata(metadata: Record<string, unknown>): OpenGeniSlackBotMetadata | null;
4
+ export declare function isOpenGeniSlackBotConnection(connection: ConnectionMetadata & Partial<Pick<ConnectionMetadataWithVerification, "verifiedInstallAt" | "verifiedInstallVersion">>): boolean;
5
+ export declare function hasReservedOpenGeniSlackBotMetadata(metadata: Record<string, unknown> | null | undefined): boolean;
6
+ export declare function hasReservedOpenGeniSlackBotSessionMetadata(metadata: Record<string, unknown> | null | undefined): boolean;
7
+ /**
8
+ * Internal, pre-authorized lookup used by the scheduler and Slack tool adapter.
9
+ * Public callers must perform their permission check before calling this helper.
10
+ */
11
+ export declare function requireOpenGeniSlackBotConnection(db: Database, workspaceId: string, connectionId: string): Promise<ConnectionMetadata>;
12
+ export declare function validateOpenGeniSlackBotConnectionSelection(db: Database, grant: AccessGrant, workspaceId: string, connectionId: string): Promise<ConnectionMetadata>;
13
+ export declare function scheduledSlackBotConnectionId(metadata: Record<string, unknown> | null | undefined): string | null;
14
+ /**
15
+ * The scheduler writes the connection pointer together with immutable creator
16
+ * provenance. Requiring both prevents ordinary session metadata from becoming
17
+ * an authorization mechanism for a workspace-shared bot credential.
18
+ */
19
+ export declare function isTrustedScheduledSlackBotSession(session: Pick<Session, "createdBy" | "createdByContext" | "metadata">): boolean;
@@ -0,0 +1,34 @@
1
+ import type { WorkspaceMember } from "@opengeni/contracts";
2
+ /** A member can manage other members (directly or via the admin wildcard). */
3
+ export declare function memberCanAdminister(member: Pick<WorkspaceMember, "permissions">): boolean;
4
+ /** Only `user:` subjects are people; `api_key:` subjects belong to API keys. */
5
+ export declare function isUserMember(member: Pick<WorkspaceMember, "subjectId">): boolean;
6
+ /**
7
+ * Turn an email lookup result into the membership subject id. A null id means
8
+ * no registered user matched the email — email invites for not-yet-registered
9
+ * users are deferred, so that is a 404 (not a 400) at the API surface.
10
+ */
11
+ export declare function resolveMemberSubjectId(userId: string | null): string;
12
+ /**
13
+ * Guard the member-remove path. Refuses (409) to remove the caller's own
14
+ * membership and refuses to remove the last member that still holds an admin
15
+ * permission, so a workspace can never be orphaned with no one able to manage
16
+ * it. `members` is the full roster (every subject, including api_key ones —
17
+ * an api_key with workspace:admin still counts as an administering subject).
18
+ */
19
+ export declare function assertWorkspaceMemberRemovable(input: {
20
+ members: WorkspaceMember[];
21
+ subjectId: string;
22
+ callerSubjectId: string;
23
+ }): void;
24
+ /**
25
+ * Guard the workspace-delete path before any external/DB mutation. Refuses
26
+ * (409) to delete the account's last workspace, and refuses while any session
27
+ * could still be running in Temporal (there is no clean per-session terminate
28
+ * to call first, so we will not orphan a workflow — the operator must stop the
29
+ * sessions first).
30
+ */
31
+ export declare function assertWorkspaceDeletable(input: {
32
+ workspaceCountForAccount: number;
33
+ activeSessionCount: number;
34
+ }): void;