@opengeni/core 0.28.1 → 1.0.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 +1 -1
- package/dist/access/external-actor-authority.d.ts +47 -0
- package/dist/access/index.d.ts +182 -3
- package/dist/access/service-initiator.d.ts +3 -0
- package/dist/application/api-integration-servers.d.ts +20 -0
- package/dist/application/archived-session-imports.d.ts +6 -0
- package/dist/application/composer-submit.d.ts +24 -0
- package/dist/application/connect-authority.d.ts +13 -0
- package/dist/application/connect-operation.d.ts +31 -0
- package/dist/application/external-continuation.d.ts +15 -0
- package/dist/application/external-identity-lifecycle.d.ts +20 -0
- package/dist/application/external-link-work-admission.d.ts +12 -0
- package/dist/application/external-workspace-members.d.ts +34 -0
- package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
- package/dist/application/new-session-drafts.d.ts +39 -2
- package/dist/application/sandbox-recovery.d.ts +58 -0
- package/dist/application/session-commands.d.ts +26 -13
- package/dist/application/session-mcp-credential-rotation.d.ts +29 -0
- package/dist/application/session-tenancy.d.ts +19 -0
- package/dist/application/user-resource-grants.d.ts +20 -0
- package/dist/billing/limits.d.ts +11 -0
- package/dist/canonical-human-identities.d.ts +7 -2
- package/dist/canonical-human-identities.js +17 -4
- package/dist/canonical-human-identities.js.map +1 -1
- package/dist/{chunk-6WKPWE5S.js → chunk-2MKMRGSY.js} +108 -24
- package/dist/chunk-2MKMRGSY.js.map +1 -0
- package/dist/{chunk-NYPMQ7NO.js → chunk-GVO3N37G.js} +205 -37
- package/dist/chunk-GVO3N37G.js.map +1 -0
- package/dist/{chunk-JJU6I5XD.js → chunk-LCQXNR62.js} +36 -10
- package/dist/chunk-LCQXNR62.js.map +1 -0
- package/dist/chunk-MM6N7CTO.js +387 -0
- package/dist/chunk-MM6N7CTO.js.map +1 -0
- package/dist/chunk-QO5GVFFO.js +235 -0
- package/dist/chunk-QO5GVFFO.js.map +1 -0
- package/dist/codex-model-availability.d.ts +14 -0
- package/dist/default-session-model.d.ts +139 -0
- package/dist/dependencies.d.ts +87 -4
- package/dist/developer-setup-credential-ceiling.d.ts +10 -0
- package/dist/domain/agent-config-resolution.d.ts +49 -0
- package/dist/domain/automations.d.ts +58 -0
- package/dist/domain/capabilities.d.ts +22 -4
- package/dist/domain/company-profile-agent-admin.d.ts +25 -0
- package/dist/domain/connection-account-selection-error.d.ts +8 -0
- package/dist/domain/connector-tool-permissions.d.ts +36 -0
- package/dist/domain/direct-model-provider.d.ts +3 -0
- package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
- package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
- package/dist/domain/editable-artifacts/ports.d.ts +10 -0
- package/dist/domain/editable-artifacts/service.d.ts +4 -3
- package/dist/domain/environments.d.ts +5 -9
- package/dist/domain/external-creation-attribution.d.ts +6 -0
- package/dist/domain/file-owner.d.ts +8 -0
- package/dist/domain/github-action-policies.d.ts +36 -0
- package/dist/domain/github-repository-bindings.d.ts +117 -0
- package/dist/domain/github-skill-source.d.ts +5 -0
- package/dist/domain/governed-learning-slack-publication.d.ts +45 -0
- package/dist/domain/insights-timing.d.ts +16 -0
- package/dist/domain/insights-usage.d.ts +27 -0
- package/dist/domain/insights.d.ts +28 -1
- package/dist/domain/knowledge-files.d.ts +20 -0
- package/dist/domain/knowledge-messages.d.ts +39 -0
- package/dist/domain/knowledge-messages.test.d.ts +1 -0
- package/dist/domain/knowledge-preparation.d.ts +10 -0
- package/dist/domain/knowledge-preparation.test.d.ts +1 -0
- package/dist/domain/knowledge-search.d.ts +15 -0
- package/dist/domain/knowledge-search.test.d.ts +1 -0
- package/dist/domain/knowledge.d.ts +9 -0
- package/dist/domain/mcp-account-bindings.d.ts +19 -0
- package/dist/domain/mcp-account-routes.d.ts +21 -0
- package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
- package/dist/domain/organization-integration-catalog.d.ts +15 -0
- package/dist/domain/organization-membership-lifecycle.d.ts +1 -0
- package/dist/domain/personal-connection-delegations.d.ts +87 -4
- package/dist/domain/pr-review.d.ts +249 -0
- package/dist/domain/resources.d.ts +24 -3
- package/dist/domain/scheduled-task-access.d.ts +247 -0
- package/dist/domain/scheduled-tasks.d.ts +103 -6
- package/dist/domain/session-connection-accounts.d.ts +16 -0
- package/dist/domain/session-file-access.d.ts +4 -0
- package/dist/domain/session-native-connection-replacement.d.ts +14 -0
- package/dist/domain/session-start-timing.d.ts +7 -0
- package/dist/domain/session-tool-policy.d.ts +93 -4
- package/dist/domain/sessions.d.ts +275 -28
- package/dist/domain/skill-imports.d.ts +1 -0
- package/dist/domain/skill-search.d.ts +30 -0
- package/dist/domain/skills.d.ts +117 -0
- package/dist/domain/slack-bot.d.ts +46 -1
- package/dist/domain/workspace-members.d.ts +8 -1
- package/dist/editable-artifact-live/application.d.ts +12 -3
- package/dist/editable-artifact-live/ports.d.ts +0 -1
- package/dist/editable-artifact-live/server.d.ts +5 -2
- package/dist/editable-artifact-live/ticket.d.ts +2 -2
- package/dist/editable-artifact-live/types.d.ts +14 -2
- package/dist/editable-artifact-live.js +2 -2
- package/dist/editable-artifacts.js +10 -4
- package/dist/index.d.ts +49 -3
- package/dist/index.js +18812 -6833
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-sets.d.ts +131 -0
- package/dist/managed-auth-session-sets.js +51 -0
- package/dist/managed-auth-session-sets.js.map +1 -0
- package/dist/managed-session.d.ts +98 -11
- package/dist/model-catalog.d.ts +117 -0
- package/dist/product-usage-metrics.d.ts +30 -0
- package/dist/rigs/index.d.ts +22 -5
- package/dist/rigs/provider-images.d.ts +1 -1
- package/dist/sandbox/fleet.d.ts +59 -10
- package/dist/sandbox/routing.d.ts +22 -2
- package/dist/sandbox/runtime-settings.d.ts +56 -0
- package/dist/session-authorization.d.ts +38 -1
- package/dist/site-session-origin.d.ts +9 -0
- package/dist/transcription.d.ts +12 -1
- package/dist/turn-surface.d.ts +18 -0
- package/dist/user-presence.d.ts +32 -0
- package/package.json +18 -11
- package/src/access/external-actor-authority.ts +94 -0
- package/src/access/index.ts +1386 -44
- package/src/access/service-initiator.ts +50 -0
- package/src/application/api-integration-servers.ts +215 -0
- package/src/application/archived-session-imports.ts +161 -0
- package/src/application/composer-submit.ts +77 -0
- package/src/application/connect-authority.ts +77 -0
- package/src/application/connect-operation.ts +80 -0
- package/src/application/external-continuation.ts +129 -0
- package/src/application/external-identity-lifecycle.ts +48 -0
- package/src/application/external-link-work-admission.ts +90 -0
- package/src/application/external-workspace-members.ts +232 -0
- package/src/application/modal-native-worker-host-transport.ts +263 -0
- package/src/application/new-session-drafts.ts +222 -29
- package/src/application/sandbox-recovery.ts +78 -0
- package/src/application/session-commands.ts +430 -73
- package/src/application/session-mcp-credential-rotation.ts +217 -0
- package/src/application/session-tenancy.ts +445 -0
- package/src/application/user-resource-grants.ts +154 -0
- package/src/billing/limits.ts +103 -24
- package/src/canonical-human-identities.ts +22 -3
- package/src/codex-model-availability.ts +136 -0
- package/src/default-session-model.ts +656 -0
- package/src/dependencies.ts +97 -5
- package/src/developer-setup-credential-ceiling.ts +60 -0
- package/src/domain/agent-config-resolution.ts +148 -0
- package/src/domain/automations.ts +270 -0
- package/src/domain/capabilities.ts +244 -151
- package/src/domain/company-profile-agent-admin.ts +56 -0
- package/src/domain/connection-account-selection-error.ts +19 -0
- package/src/domain/connector-tool-permissions.ts +371 -0
- package/src/domain/direct-model-provider.ts +62 -0
- package/src/domain/editable-artifacts/agent-application.ts +61 -15
- package/src/domain/editable-artifacts/durable-export.ts +100 -5
- package/src/domain/editable-artifacts/in-memory.ts +6 -0
- package/src/domain/editable-artifacts/ports.ts +11 -0
- package/src/domain/editable-artifacts/service.ts +32 -1
- package/src/domain/editable-artifacts/snapshot-compaction.ts +9 -5
- package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +10 -8
- package/src/domain/editable-artifacts/snapshot-verifier.ts +10 -3
- package/src/domain/environments.ts +25 -45
- package/src/domain/external-creation-attribution.ts +22 -0
- package/src/domain/file-owner.ts +67 -0
- package/src/domain/github-action-policies.ts +169 -0
- package/src/domain/github-repository-bindings.ts +295 -0
- package/src/domain/github-skill-source.ts +233 -0
- package/src/domain/governed-learning-slack-publication.ts +157 -0
- package/src/domain/insights-timing.ts +95 -0
- package/src/domain/insights-usage.ts +67 -0
- package/src/domain/insights.ts +270 -169
- package/src/domain/knowledge-files.ts +46 -0
- package/src/domain/knowledge-messages.test.ts +91 -0
- package/src/domain/knowledge-messages.ts +106 -0
- package/src/domain/knowledge-preparation.test.ts +276 -0
- package/src/domain/knowledge-preparation.ts +147 -0
- package/src/domain/knowledge-search.test.ts +561 -0
- package/src/domain/knowledge-search.ts +256 -0
- package/src/domain/knowledge.ts +133 -0
- package/src/domain/mcp-account-bindings.ts +171 -0
- package/src/domain/mcp-account-routes.ts +121 -0
- package/src/domain/native-mcp-connection-admission.ts +14 -0
- package/src/domain/organization-integration-catalog.ts +88 -0
- package/src/domain/organization-membership-lifecycle.ts +10 -0
- package/src/domain/personal-connection-delegations.ts +758 -115
- package/src/domain/pr-review.ts +687 -0
- package/src/domain/resources.ts +182 -25
- package/src/domain/scheduled-task-access.ts +1052 -0
- package/src/domain/scheduled-tasks.ts +1952 -215
- package/src/domain/session-connection-accounts.ts +67 -0
- package/src/domain/session-file-access.ts +47 -0
- package/src/domain/session-native-connection-replacement.ts +64 -0
- package/src/domain/session-start-timing.ts +55 -0
- package/src/domain/session-tool-policy.ts +443 -19
- package/src/domain/sessions.ts +3417 -619
- package/src/domain/skill-imports.ts +137 -17
- package/src/domain/skill-search.ts +221 -0
- package/src/domain/skills.ts +104 -0
- package/src/domain/slack-bot.ts +128 -3
- package/src/domain/workspace-members.ts +34 -2
- package/src/editable-artifact-live/application.ts +29 -4
- package/src/editable-artifact-live/ports.ts +0 -1
- package/src/editable-artifact-live/server.ts +167 -13
- package/src/editable-artifact-live/ticket.ts +87 -6
- package/src/editable-artifact-live/types.ts +16 -2
- package/src/editable-artifact-live/wire.ts +0 -10
- package/src/index.ts +69 -4
- package/src/managed-auth-session-sets.ts +371 -0
- package/src/managed-session.ts +520 -2
- package/src/model-catalog.ts +873 -0
- package/src/product-usage-metrics.ts +101 -0
- package/src/rigs/index.ts +179 -63
- package/src/rigs/provider-images.ts +2 -3
- package/src/sandbox/fleet.ts +471 -59
- package/src/sandbox/routing.ts +160 -33
- package/src/sandbox/runtime-settings.ts +281 -0
- package/src/session-authorization.ts +262 -78
- package/src/site-session-origin.ts +22 -0
- package/src/transcription.ts +13 -1
- package/src/turn-surface.ts +45 -0
- package/src/user-presence.ts +134 -0
- package/dist/chunk-6WKPWE5S.js.map +0 -1
- package/dist/chunk-IBOEYG6N.js +0 -34
- package/dist/chunk-IBOEYG6N.js.map +0 -1
- package/dist/chunk-JJU6I5XD.js.map +0 -1
- package/dist/chunk-NYPMQ7NO.js.map +0 -1
- package/dist/domain/durable-learning-slack-publication.d.ts +0 -72
- package/dist/domain/packs.d.ts +0 -55
- package/src/domain/durable-learning-slack-publication.ts +0 -202
- package/src/domain/packs.ts +0 -556
|
@@ -1,14 +1,42 @@
|
|
|
1
|
-
import type { Settings } from "@opengeni/config";
|
|
2
1
|
import {
|
|
2
|
+
allowedFirstPartyMcpToolsForSession,
|
|
3
|
+
codeSearchDeploymentPolicy,
|
|
4
|
+
resolveModelProviderForTurn,
|
|
5
|
+
resolveFirstPartyDelegationSecret,
|
|
6
|
+
type Settings,
|
|
7
|
+
} from "@opengeni/config";
|
|
8
|
+
import {
|
|
9
|
+
AGENT_SKILL_MANAGE_TOOL_NAMES,
|
|
10
|
+
AUTOMATIC_SESSION_TITLE_FALLBACK,
|
|
11
|
+
DEFAULT_FIRST_PARTY_MCP_PERMISSIONS,
|
|
12
|
+
FIRST_PARTY_IN_PROCESS_TOOL_NAMES,
|
|
13
|
+
type FirstPartyMcpToolName,
|
|
3
14
|
SESSION_EFFECTIVE_TOOL_POLICY_ID_LIMIT,
|
|
4
15
|
SESSION_EFFECTIVE_TOOL_POLICY_ID_MAX_LENGTH,
|
|
5
16
|
mergeToolRefs,
|
|
17
|
+
projectAgentEffectiveTools,
|
|
18
|
+
resolveAgentToolFamilies,
|
|
19
|
+
resolveAgentMediaToolSurface,
|
|
20
|
+
resolveWorkspaceAgentHumanInputEnabled,
|
|
21
|
+
resolveWorkspaceSessionToolDefaults,
|
|
22
|
+
type AgentFunctionToolName,
|
|
23
|
+
type AgentToolEnvironment,
|
|
24
|
+
type AgentMediaAttachment,
|
|
6
25
|
type Session,
|
|
26
|
+
type SessionTurn,
|
|
7
27
|
type SessionEffectiveToolPolicy,
|
|
8
28
|
type SessionToolPolicy,
|
|
9
29
|
type ToolRef,
|
|
10
30
|
} from "@opengeni/contracts";
|
|
11
|
-
import
|
|
31
|
+
import { codeSearchEnabledForTurn } from "@opengeni/contracts/code-search";
|
|
32
|
+
import {
|
|
33
|
+
getSandbox,
|
|
34
|
+
listSkillDescriptors,
|
|
35
|
+
requireWorkspace,
|
|
36
|
+
sessionHasToolRouterHistory,
|
|
37
|
+
type Database,
|
|
38
|
+
} from "@opengeni/db";
|
|
39
|
+
import { resolveWorkspaceCatalogSettings } from "../model-catalog";
|
|
12
40
|
import { settingsWithEnabledCapabilityMcpServers } from "./capabilities";
|
|
13
41
|
|
|
14
42
|
const MANDATORY_SESSION_MCP_SERVER_IDS = ["opengeni"] as const;
|
|
@@ -64,8 +92,11 @@ export function resolveSessionToolPolicy(input: SessionToolPolicyInput): Resolve
|
|
|
64
92
|
availableIds.has(id),
|
|
65
93
|
);
|
|
66
94
|
const mandatoryIdSet = new Set<string>(mandatoryIds);
|
|
67
|
-
const selectedRefs = mergeToolRefs([], input.sessionTools);
|
|
68
95
|
const tracksWorkspaceDefaults = policy.mode === "workspace_default";
|
|
96
|
+
const excludedIds = new Set(tracksWorkspaceDefaults ? policy.excludedMcpServerIds : []);
|
|
97
|
+
const selectedRefs = mergeToolRefs([], input.sessionTools).filter(
|
|
98
|
+
(tool) => !excludedIds.has(tool.id) || mandatoryIdSet.has(tool.id),
|
|
99
|
+
);
|
|
69
100
|
|
|
70
101
|
// Persisted refs may outlive a capability installation, deployment config,
|
|
71
102
|
// or its credentials. Admission remains strict for newly requested refs, but
|
|
@@ -79,7 +110,7 @@ export function resolveSessionToolPolicy(input: SessionToolPolicyInput): Resolve
|
|
|
79
110
|
toolRefs = mergeToolRefs(
|
|
80
111
|
toolRefs,
|
|
81
112
|
sortedIds(defaultIds)
|
|
82
|
-
.filter((id) => availableIds.has(id))
|
|
113
|
+
.filter((id) => availableIds.has(id) && !excludedIds.has(id))
|
|
83
114
|
.map((id) => ({ kind: "mcp" as const, id, optional: true as const })),
|
|
84
115
|
);
|
|
85
116
|
}
|
|
@@ -96,7 +127,7 @@ export function resolveSessionToolPolicy(input: SessionToolPolicyInput): Resolve
|
|
|
96
127
|
selectedRefs,
|
|
97
128
|
tracksWorkspaceDefaults
|
|
98
129
|
? sortedIds(defaultIds)
|
|
99
|
-
.filter((id) => availableIds.has(id))
|
|
130
|
+
.filter((id) => availableIds.has(id) && !excludedIds.has(id))
|
|
100
131
|
.map((id) => ({ kind: "mcp" as const, id, optional: true as const }))
|
|
101
132
|
: [],
|
|
102
133
|
);
|
|
@@ -109,15 +140,12 @@ export function resolveSessionToolPolicy(input: SessionToolPolicyInput): Resolve
|
|
|
109
140
|
const configuredIds = effectiveIds.filter((id) => availableIds.has(id));
|
|
110
141
|
const configuredIdSet = new Set(configuredIds);
|
|
111
142
|
const droppedIds = effectiveIds.filter((id) => !configuredIdSet.has(id));
|
|
112
|
-
// Lazy discovery is scoped to the effective MCP allow-list
|
|
113
|
-
//
|
|
114
|
-
//
|
|
115
|
-
// the existing router creates a false "no connected sources" result. The
|
|
116
|
-
// mandatory first-party OpenGeni server stays eager; every other configured
|
|
117
|
-
// effective server is eligible for bounded schema disclosure.
|
|
143
|
+
// Lazy discovery is scoped to the effective MCP allow-list. Mandatory means
|
|
144
|
+
// selected/fail-loud, not eager: only an exact session ref with eager:true
|
|
145
|
+
// belongs on the first model request's critical path.
|
|
118
146
|
const deferredIds = sortedIds(
|
|
119
147
|
toolRefs
|
|
120
|
-
.filter((tool) => configuredIdSet.has(tool.id) &&
|
|
148
|
+
.filter((tool) => configuredIdSet.has(tool.id) && tool.eager !== true)
|
|
121
149
|
.map((tool) => tool.id),
|
|
122
150
|
);
|
|
123
151
|
const selectedIds = sortedIds(
|
|
@@ -164,6 +192,63 @@ export function resolveSessionToolPolicy(input: SessionToolPolicyInput): Resolve
|
|
|
164
192
|
};
|
|
165
193
|
}
|
|
166
194
|
|
|
195
|
+
/** Null is ordinary work; an empty list is a frozen scheduled selection. */
|
|
196
|
+
export function scheduledTurnMcpServerIds(turn: Pick<SessionTurn, "metadata">): string[] | null {
|
|
197
|
+
const metadata = turn.metadata;
|
|
198
|
+
const value =
|
|
199
|
+
metadata && typeof metadata === "object" && !Array.isArray(metadata)
|
|
200
|
+
? metadata.scheduledEffectiveMcpServerIds
|
|
201
|
+
: null;
|
|
202
|
+
return Array.isArray(value) && value.every((id) => typeof id === "string")
|
|
203
|
+
? sortedIds(value)
|
|
204
|
+
: null;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Execution's canonical turn selection. Ordinary turns use the durable session
|
|
209
|
+
* policy, not the queue's omitted-tools `[]`. Scheduled turns instead retain
|
|
210
|
+
* their frozen registry and refs, including an explicitly empty selection.
|
|
211
|
+
*/
|
|
212
|
+
export function resolveTurnToolPolicy(
|
|
213
|
+
input: Omit<SessionToolPolicyInput, "sessionTools"> & {
|
|
214
|
+
session: Pick<Session, "tools">;
|
|
215
|
+
turn: Pick<SessionTurn, "tools" | "metadata">;
|
|
216
|
+
},
|
|
217
|
+
): ResolvedSessionToolPolicy {
|
|
218
|
+
const scheduledIds = scheduledTurnMcpServerIds(input.turn);
|
|
219
|
+
const availableIds = new Set(input.availableMcpServerIds);
|
|
220
|
+
return resolveSessionToolPolicy({
|
|
221
|
+
toolPolicy: input.toolPolicy,
|
|
222
|
+
sessionTools: scheduledIds ? input.turn.tools : input.session.tools,
|
|
223
|
+
availableMcpServerIds: scheduledIds
|
|
224
|
+
? scheduledIds.filter((id) => availableIds.has(id))
|
|
225
|
+
: availableIds,
|
|
226
|
+
defaultMcpServerIds: scheduledIds ?? input.defaultMcpServerIds ?? [],
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** Resolve availability and defaults from the same subject-scoped registry read. */
|
|
231
|
+
export async function workspaceSessionToolPolicyContext(
|
|
232
|
+
db: Database,
|
|
233
|
+
workspaceId: string,
|
|
234
|
+
settings: Settings,
|
|
235
|
+
subjectId?: string,
|
|
236
|
+
): Promise<{ workspaceServerIds: string[]; workspaceDefaultServerIds: string[] }> {
|
|
237
|
+
const [runtimeSettings, workspace] = await Promise.all([
|
|
238
|
+
settingsWithEnabledCapabilityMcpServers(db, workspaceId, settings, {
|
|
239
|
+
...(subjectId ? { subjectId } : {}),
|
|
240
|
+
}),
|
|
241
|
+
requireWorkspace(db, workspaceId),
|
|
242
|
+
]);
|
|
243
|
+
return {
|
|
244
|
+
workspaceServerIds: sortedIds(runtimeSettings.mcpServers.map((server) => server.id)),
|
|
245
|
+
workspaceDefaultServerIds: workspaceSessionToolPolicyDefaultServerIdsFor(
|
|
246
|
+
runtimeSettings.mcpServers,
|
|
247
|
+
workspace.settings,
|
|
248
|
+
),
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
|
|
167
252
|
/** Current full runtime registry IDs, including configured static servers. */
|
|
168
253
|
export async function workspaceSessionToolPolicyServerIds(
|
|
169
254
|
db: Database,
|
|
@@ -187,7 +272,332 @@ export async function workspaceSessionToolPolicyDefaultServerIds(
|
|
|
187
272
|
const runtimeSettings = await settingsWithEnabledCapabilityMcpServers(db, workspaceId, settings, {
|
|
188
273
|
...(subjectId ? { subjectId } : {}),
|
|
189
274
|
});
|
|
190
|
-
|
|
275
|
+
const workspace = await requireWorkspace(db, workspaceId);
|
|
276
|
+
return workspaceSessionToolPolicyDefaultServerIdsFor(
|
|
277
|
+
runtimeSettings.mcpServers,
|
|
278
|
+
workspace.settings,
|
|
279
|
+
);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* The omitted-tools default for one resolved runtime registry and one
|
|
284
|
+
* workspace settings bag. Pure so a caller that already holds both never has
|
|
285
|
+
* to re-query the capability registry to agree with the worker and the
|
|
286
|
+
* composer on which connectors a `workspace_default` session executes with.
|
|
287
|
+
*/
|
|
288
|
+
export function workspaceSessionToolPolicyDefaultServerIdsFor(
|
|
289
|
+
runtimeMcpServers: Iterable<{ id: string }>,
|
|
290
|
+
workspaceSettings: unknown,
|
|
291
|
+
): string[] {
|
|
292
|
+
const availableDefaults = defaultSessionMcpServerIds(runtimeMcpServers);
|
|
293
|
+
const configured = resolveWorkspaceSessionToolDefaults(workspaceSettings);
|
|
294
|
+
if (!configured?.mcpServerIds) return availableDefaults;
|
|
295
|
+
const available = new Set(availableDefaults);
|
|
296
|
+
return sortedIds([
|
|
297
|
+
...configured.mcpServerIds.filter((id) => available.has(id)),
|
|
298
|
+
...(configured.inheritConnectedMcpServers
|
|
299
|
+
? availableDefaults.filter((id) => !["opengeni", "files", "docs"].includes(id))
|
|
300
|
+
: []),
|
|
301
|
+
]);
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/** Metadata only: no MCP listing, provider probes, account selection or credentials. */
|
|
305
|
+
export type SessionEffectiveToolsContext = {
|
|
306
|
+
settings: Settings;
|
|
307
|
+
humanInputEnabled: boolean;
|
|
308
|
+
hasWorkspaceSkills: boolean;
|
|
309
|
+
workspaceSettings?: unknown;
|
|
310
|
+
objectStorageAvailable: boolean;
|
|
311
|
+
activeSandboxBackends?: ReadonlyMap<string, Settings["sandboxBackend"]>;
|
|
312
|
+
/** Exact build options after adapter/credential resolution, keyed by session. No pool-readiness inference. */
|
|
313
|
+
mediaAttachments?: ReadonlyMap<string, AgentMediaAttachment>;
|
|
314
|
+
routerInHistory?: boolean;
|
|
315
|
+
routerHistorySessionIds?: ReadonlySet<string>;
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Resolve one context for a response page, not one catalog per session. Legacy
|
|
320
|
+
* rows require no additional reads and never acquire an effectiveTools field.
|
|
321
|
+
*/
|
|
322
|
+
export async function workspaceSessionEffectiveToolsContext(
|
|
323
|
+
deps: { db: Database; settings: Settings; objectStorage?: unknown },
|
|
324
|
+
workspaceId: string,
|
|
325
|
+
subjectId: string,
|
|
326
|
+
sessions: readonly Session[],
|
|
327
|
+
): Promise<SessionEffectiveToolsContext> {
|
|
328
|
+
const configured = sessions.filter((session) => session.agent != null);
|
|
329
|
+
const baseline: SessionEffectiveToolsContext = {
|
|
330
|
+
settings: deps.settings,
|
|
331
|
+
humanInputEnabled: false,
|
|
332
|
+
hasWorkspaceSkills: false,
|
|
333
|
+
objectStorageAvailable: Boolean(deps.objectStorage),
|
|
334
|
+
};
|
|
335
|
+
if (configured.length === 0) return baseline;
|
|
336
|
+
const [workspace, catalog, descriptors, sandboxes, routerHistory] = await Promise.all([
|
|
337
|
+
requireWorkspace(deps.db, workspaceId),
|
|
338
|
+
resolveWorkspaceCatalogSettings(deps.db, deps.settings, {
|
|
339
|
+
accountId: configured[0]!.accountId,
|
|
340
|
+
workspaceId,
|
|
341
|
+
retainedProductModelIds: configured.map((session) => session.model),
|
|
342
|
+
}),
|
|
343
|
+
configured.some((session) => session.agent?.capabilities.skills === "read")
|
|
344
|
+
? listSkillDescriptors(deps.db, {
|
|
345
|
+
accountId: configured[0]!.accountId,
|
|
346
|
+
workspaceId,
|
|
347
|
+
subjectId,
|
|
348
|
+
})
|
|
349
|
+
: Promise.resolve([]),
|
|
350
|
+
deps.settings.sandboxSelfhostedEnabled
|
|
351
|
+
? Promise.all(
|
|
352
|
+
sortedIds(configured.flatMap((session) => session.activeSandboxId ?? [])).map(
|
|
353
|
+
async (id) =>
|
|
354
|
+
[
|
|
355
|
+
id,
|
|
356
|
+
await getSandbox(
|
|
357
|
+
deps.db,
|
|
358
|
+
{ accountId: configured[0]!.accountId, workspaceId, subjectId },
|
|
359
|
+
id,
|
|
360
|
+
),
|
|
361
|
+
] as const,
|
|
362
|
+
),
|
|
363
|
+
)
|
|
364
|
+
: Promise.resolve([]),
|
|
365
|
+
Promise.all(
|
|
366
|
+
[...new Map(configured.map((session) => [session.id, session])).values()].map(
|
|
367
|
+
async (session) =>
|
|
368
|
+
[
|
|
369
|
+
session.id,
|
|
370
|
+
await sessionHasToolRouterHistory(deps.db, {
|
|
371
|
+
accountId: session.accountId,
|
|
372
|
+
workspaceId,
|
|
373
|
+
sessionId: session.id,
|
|
374
|
+
}),
|
|
375
|
+
] as const,
|
|
376
|
+
),
|
|
377
|
+
),
|
|
378
|
+
]);
|
|
379
|
+
return {
|
|
380
|
+
...baseline,
|
|
381
|
+
settings: catalog.settings,
|
|
382
|
+
workspaceSettings: workspace.settings,
|
|
383
|
+
humanInputEnabled: resolveWorkspaceAgentHumanInputEnabled(workspace.settings),
|
|
384
|
+
hasWorkspaceSkills: descriptors.some((entry) => entry.activationMode === "workspace_managed"),
|
|
385
|
+
activeSandboxBackends: new Map(
|
|
386
|
+
sandboxes.flatMap(([id, sandbox]) =>
|
|
387
|
+
sandbox?.kind === "selfhosted" ? [[id, "selfhosted" as const]] : [],
|
|
388
|
+
),
|
|
389
|
+
),
|
|
390
|
+
routerHistorySessionIds: new Set(
|
|
391
|
+
routerHistory.filter(([, present]) => present).map(([id]) => id),
|
|
392
|
+
),
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
function sessionHasSkills(session: Session, context: SessionEffectiveToolsContext): boolean {
|
|
397
|
+
if (context.hasWorkspaceSkills || session.skills.length > 0) return true;
|
|
398
|
+
// Undefined is the worker's bundled default. Explicit [] means no bundles.
|
|
399
|
+
if (session.bundledSkillIds === undefined) return true;
|
|
400
|
+
const tools = new Set(
|
|
401
|
+
resolveAgentToolFamilies(session.agent).firstPartyTools(
|
|
402
|
+
allowedFirstPartyMcpToolsForSession(context.settings, session.firstPartyMcpTools),
|
|
403
|
+
),
|
|
404
|
+
);
|
|
405
|
+
return session.bundledSkillIds.some((id) => {
|
|
406
|
+
if (
|
|
407
|
+
[
|
|
408
|
+
"builtin:opengeni-documents",
|
|
409
|
+
"builtin:opengeni-spreadsheets",
|
|
410
|
+
"builtin:opengeni-presentations",
|
|
411
|
+
].includes(id)
|
|
412
|
+
) {
|
|
413
|
+
return tools.has("editable_artifact_list") && tools.has("editable_artifact_get");
|
|
414
|
+
}
|
|
415
|
+
if (id === "builtin:opengeni-sites") {
|
|
416
|
+
return tools.has("artifacts_create") && tools.has("artifacts_publish");
|
|
417
|
+
}
|
|
418
|
+
if (id === "builtin:opengeni-video-generation") {
|
|
419
|
+
return context.mediaAttachments?.get(session.id)?.video === true;
|
|
420
|
+
}
|
|
421
|
+
return true;
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
/** The server can prove attachment policy, not successful future provider calls. */
|
|
426
|
+
export function sessionEffectiveToolProjectionInput(
|
|
427
|
+
session: Session & { agent: NonNullable<Session["agent"]> },
|
|
428
|
+
toolRefs: readonly ToolRef[],
|
|
429
|
+
context?: SessionEffectiveToolsContext,
|
|
430
|
+
) {
|
|
431
|
+
const model = context ? resolveModelProviderForTurn(context.settings, session.model) : undefined;
|
|
432
|
+
const sandboxBackend =
|
|
433
|
+
(session.activeSandboxId
|
|
434
|
+
? context?.activeSandboxBackends?.get(session.activeSandboxId)
|
|
435
|
+
: undefined) ?? session.sandboxBackend;
|
|
436
|
+
const sandboxAvailable = context !== undefined && sandboxBackend !== "none";
|
|
437
|
+
const supportsImages =
|
|
438
|
+
model?.model.api === "responses" && model.model.capabilities.inputModalities.includes("image");
|
|
439
|
+
const hostedToolNames: AgentFunctionToolName[] = [];
|
|
440
|
+
if (model?.provider.kind === "xai-subscription") {
|
|
441
|
+
if (context?.settings.webSearchEnabled) hostedToolNames.push("web_search", "x_search");
|
|
442
|
+
} else if (model?.model.hostedWebSearch) hostedToolNames.push("web_search");
|
|
443
|
+
const mediaAttachment =
|
|
444
|
+
context?.mediaAttachments?.get(session.id) ??
|
|
445
|
+
(context?.objectStorageAvailable === false
|
|
446
|
+
? ({ image: null, video: false } as const)
|
|
447
|
+
: undefined);
|
|
448
|
+
const media = resolveAgentMediaToolSurface(session.agent, mediaAttachment);
|
|
449
|
+
hostedToolNames.push(...media.hosted);
|
|
450
|
+
const runtimeToolNames: AgentFunctionToolName[] = context
|
|
451
|
+
? [
|
|
452
|
+
"request_human_input",
|
|
453
|
+
"list_models",
|
|
454
|
+
"skill_read",
|
|
455
|
+
...AGENT_SKILL_MANAGE_TOOL_NAMES,
|
|
456
|
+
...media.runtime,
|
|
457
|
+
]
|
|
458
|
+
: [];
|
|
459
|
+
const sandboxToolNames: AgentFunctionToolName[] = sandboxAvailable
|
|
460
|
+
? [
|
|
461
|
+
"exec_command",
|
|
462
|
+
"write_stdin",
|
|
463
|
+
"apply_patch",
|
|
464
|
+
...(supportsImages ? ["view_image" as const] : []),
|
|
465
|
+
...(session.resources.some((resource) => resource.kind === "repository")
|
|
466
|
+
? ["repository_skill_read" as const]
|
|
467
|
+
: []),
|
|
468
|
+
...(codeSearchEnabledForTurn(
|
|
469
|
+
session.codeSearchEnabled,
|
|
470
|
+
context?.workspaceSettings,
|
|
471
|
+
codeSearchDeploymentPolicy(context!.settings),
|
|
472
|
+
) && session.sandboxOs !== "windows"
|
|
473
|
+
? ["code_search" as const]
|
|
474
|
+
: []),
|
|
475
|
+
]
|
|
476
|
+
: [];
|
|
477
|
+
const needsTitle =
|
|
478
|
+
session.titleSource !== "user" &&
|
|
479
|
+
(!session.title?.trim() || session.title.trim() === AUTOMATIC_SESSION_TITLE_FALLBACK);
|
|
480
|
+
const firstPartyMcpTools =
|
|
481
|
+
context && toolRefs.some((ref) => ref.id === "opengeni")
|
|
482
|
+
? resolveAgentToolFamilies(session.agent)
|
|
483
|
+
.firstPartyTools(
|
|
484
|
+
allowedFirstPartyMcpToolsForSession(context.settings, session.firstPartyMcpTools),
|
|
485
|
+
)
|
|
486
|
+
.filter((name) => name !== "set_session_title" || !needsTitle)
|
|
487
|
+
: [];
|
|
488
|
+
const interactionNames = new Set<string>(FIRST_PARTY_IN_PROCESS_TOOL_NAMES);
|
|
489
|
+
const firstPartyModelNames = new Map<FirstPartyMcpToolName, string>();
|
|
490
|
+
const permissions: readonly string[] =
|
|
491
|
+
session.firstPartyMcpPermissions ?? DEFAULT_FIRST_PARTY_MCP_PERMISSIONS;
|
|
492
|
+
const permissionAllowed = (permission: string) =>
|
|
493
|
+
permissions.includes(permission as never) || permissions.includes("workspace:admin");
|
|
494
|
+
if (context && resolveFirstPartyDelegationSecret(context.settings)) {
|
|
495
|
+
for (const name of FIRST_PARTY_IN_PROCESS_TOOL_NAMES) {
|
|
496
|
+
const readOnly = [
|
|
497
|
+
"interaction_discover",
|
|
498
|
+
"browser_observe",
|
|
499
|
+
"browser_read",
|
|
500
|
+
"browser_screenshot",
|
|
501
|
+
"browser_clipboard",
|
|
502
|
+
"browser_debug",
|
|
503
|
+
"browser_downloads",
|
|
504
|
+
"computer_targets",
|
|
505
|
+
"computer_observe",
|
|
506
|
+
"computer_clipboard",
|
|
507
|
+
].includes(name);
|
|
508
|
+
if (
|
|
509
|
+
permissionAllowed(readOnly ? "sessions:read" : "sessions:control") &&
|
|
510
|
+
(name !== "browser_download_save" || permissionAllowed("files:upload"))
|
|
511
|
+
) {
|
|
512
|
+
firstPartyModelNames.set(name, `interaction__${name}`);
|
|
513
|
+
if (
|
|
514
|
+
!firstPartyMcpTools.includes(name) &&
|
|
515
|
+
resolveAgentToolFamilies(session.agent).allowsFirstPartyTool(name) &&
|
|
516
|
+
session.firstPartyMcpTools.includes(name)
|
|
517
|
+
)
|
|
518
|
+
firstPartyMcpTools.push(name);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
// Interaction names are never registered by the remote first-party server.
|
|
523
|
+
for (let index = firstPartyMcpTools.length - 1; index >= 0; index--) {
|
|
524
|
+
const name = firstPartyMcpTools[index]!;
|
|
525
|
+
if (interactionNames.has(name) && !firstPartyModelNames.has(name))
|
|
526
|
+
firstPartyMcpTools.splice(index, 1);
|
|
527
|
+
}
|
|
528
|
+
const codex = model?.provider.kind === "codex-subscription";
|
|
529
|
+
const retainedRouter =
|
|
530
|
+
context?.routerInHistory === true || context?.routerHistorySessionIds?.has(session.id) === true;
|
|
531
|
+
const progressiveDisclosure =
|
|
532
|
+
retainedRouter ||
|
|
533
|
+
(context
|
|
534
|
+
? codex
|
|
535
|
+
? context.settings.codexToolSearchEnabled
|
|
536
|
+
: context.settings.lazyToolSearchEnabled
|
|
537
|
+
: false);
|
|
538
|
+
const upfrontToolNames = new Set<string>([
|
|
539
|
+
...hostedToolNames,
|
|
540
|
+
...sandboxToolNames,
|
|
541
|
+
"skill_read",
|
|
542
|
+
"request_human_input",
|
|
543
|
+
"list_models",
|
|
544
|
+
...(toolRefs.some((ref) => ref.id === "opengeni" && ref.eager === true) ||
|
|
545
|
+
!progressiveDisclosure
|
|
546
|
+
? firstPartyMcpTools.filter((name) => !interactionNames.has(name) || !progressiveDisclosure)
|
|
547
|
+
: []),
|
|
548
|
+
...(!progressiveDisclosure ? runtimeToolNames : []),
|
|
549
|
+
]);
|
|
550
|
+
const environment: AgentToolEnvironment = {
|
|
551
|
+
productServerIds: new Set([
|
|
552
|
+
...session.mcpServers.map((server) => server.id),
|
|
553
|
+
...(session.toolPolicy.mode !== "workspace_default"
|
|
554
|
+
? session.tools.map((tool) => tool.id)
|
|
555
|
+
: []),
|
|
556
|
+
]),
|
|
557
|
+
hasSkills: context ? sessionHasSkills(session, context) : false,
|
|
558
|
+
webSearch: hostedToolNames.includes("web_search"),
|
|
559
|
+
humanInput: context?.humanInputEnabled ?? false,
|
|
560
|
+
media: media.toolsKnown ? media.hosted.length + media.runtime.length > 0 : undefined,
|
|
561
|
+
routerInHistory:
|
|
562
|
+
context?.routerInHistory === true ||
|
|
563
|
+
context?.routerHistorySessionIds?.has(session.id) === true,
|
|
564
|
+
};
|
|
565
|
+
const families = resolveAgentToolFamilies(session.agent, environment);
|
|
566
|
+
environment.hasDeferredTools =
|
|
567
|
+
toolRefs.some(
|
|
568
|
+
(ref) => ref.id !== "opengeni" && ref.eager !== true && families.allowsMcpServer(ref.id),
|
|
569
|
+
) ||
|
|
570
|
+
firstPartyMcpTools.some(
|
|
571
|
+
(name) => families.allowsFirstPartyTool(name) && !upfrontToolNames.has(name),
|
|
572
|
+
) ||
|
|
573
|
+
runtimeToolNames.some(
|
|
574
|
+
(name) => families.allowsFunctionTool(name) && !upfrontToolNames.has(name),
|
|
575
|
+
);
|
|
576
|
+
const provider = model?.provider;
|
|
577
|
+
const native =
|
|
578
|
+
codex ||
|
|
579
|
+
(provider?.api === "responses" &&
|
|
580
|
+
(provider.wireProfile === "azure-openai" ||
|
|
581
|
+
(provider.builtin && provider.id === "openai" && provider.baseUrl === undefined)));
|
|
582
|
+
const routerToolNames: AgentFunctionToolName[] =
|
|
583
|
+
progressiveDisclosure && resolveAgentToolFamilies(session.agent, environment).router
|
|
584
|
+
? ["tool_search", "tool_list", ...(native ? [] : ["tool_invoke" as const])]
|
|
585
|
+
: [];
|
|
586
|
+
for (const name of routerToolNames) upfrontToolNames.add(name);
|
|
587
|
+
return {
|
|
588
|
+
config: session.agent,
|
|
589
|
+
firstPartyMcpTools,
|
|
590
|
+
firstPartyModelNames,
|
|
591
|
+
mcpServerIds: toolRefs.map((ref) => ref.id),
|
|
592
|
+
productServerIds: environment.productServerIds ?? new Set<string>(),
|
|
593
|
+
environment,
|
|
594
|
+
runtimeToolNames,
|
|
595
|
+
hostedToolNames,
|
|
596
|
+
sandboxToolNames,
|
|
597
|
+
routerToolNames,
|
|
598
|
+
upfrontToolNames,
|
|
599
|
+
mediaAttachment,
|
|
600
|
+
};
|
|
191
601
|
}
|
|
192
602
|
|
|
193
603
|
/** Add a bounded, secret-safe effective projection to a session response. */
|
|
@@ -195,18 +605,32 @@ export function sessionWithEffectiveToolPolicy(
|
|
|
195
605
|
session: Session,
|
|
196
606
|
workspaceServerIds: Iterable<string>,
|
|
197
607
|
workspaceDefaultServerIds: Iterable<string> = [],
|
|
608
|
+
effectiveToolsContext?: SessionEffectiveToolsContext,
|
|
198
609
|
): Session {
|
|
199
610
|
const availableIds = new Set(workspaceServerIds);
|
|
200
611
|
for (const server of session.mcpServers) {
|
|
201
612
|
availableIds.add(server.id);
|
|
202
613
|
}
|
|
614
|
+
const { effectivePolicy: effectiveToolPolicy, toolRefs } = resolveSessionToolPolicy({
|
|
615
|
+
toolPolicy: session.toolPolicy,
|
|
616
|
+
sessionTools: session.tools,
|
|
617
|
+
availableMcpServerIds: availableIds,
|
|
618
|
+
defaultMcpServerIds: workspaceDefaultServerIds,
|
|
619
|
+
});
|
|
203
620
|
return {
|
|
204
621
|
...session,
|
|
205
|
-
effectiveToolPolicy
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
622
|
+
effectiveToolPolicy,
|
|
623
|
+
// Configured sessions also report what they can use at capability level.
|
|
624
|
+
...(session.agent
|
|
625
|
+
? {
|
|
626
|
+
effectiveTools: projectAgentEffectiveTools(
|
|
627
|
+
sessionEffectiveToolProjectionInput(
|
|
628
|
+
{ ...session, agent: session.agent },
|
|
629
|
+
toolRefs,
|
|
630
|
+
effectiveToolsContext,
|
|
631
|
+
),
|
|
632
|
+
),
|
|
633
|
+
}
|
|
634
|
+
: {}),
|
|
211
635
|
};
|
|
212
636
|
}
|