@opengeni/core 2.7.2-canary.0 → 2.7.5-canary.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -68,6 +68,16 @@ export declare function accessGrantAuthorizationFromContext(context: AccessConte
68
68
  * access resolver are present in `resolvedAccessGrantAuthorizations`.
69
69
  */
70
70
  export declare function requireAccountAdminAuthorizationStamp(authorization: AccessGrantAuthorization): AccountAdminAuthorizationStamp;
71
+ /**
72
+ * Verify that an access authorization was minted by the canonical request
73
+ * resolver for this exact subject and workspace.
74
+ *
75
+ * This is the protocol-neutral boundary for request-local services that need
76
+ * the authenticated grant rather than a caller-supplied grant-shaped object.
77
+ * Object identity is intentional: matching fields alone are not proof that the
78
+ * request authenticated the named subject.
79
+ */
80
+ export declare function requireResolvedAccessGrantAuthorization(authorization: AccessGrantAuthorization, workspaceId: string): AccessGrant;
71
81
  /**
72
82
  * Resolve the exact built-in single-user local administrator for an account.
73
83
  *
@@ -0,0 +1,20 @@
1
+ import { type IntegrationInvocationAuthority } from "@opengeni/capabilities";
2
+ import type { Settings } from "@opengeni/config";
3
+ import type { ToolAuthNeededPayload } from "@opengeni/contracts";
4
+ import type { ApiIntegrationRuntime, ResolveConnectionCredentialInput, ResolveConnectionCredentialResult } from "@opengeni/db";
5
+ import type { FetchLike } from "@opengeni/network";
6
+ import type { LocalMcpServerRegistration } from "@opengeni/runtime";
7
+ export type BuildApiIntegrationServersInput = {
8
+ settings: Settings;
9
+ integrations: readonly ApiIntegrationRuntime[];
10
+ authority: Omit<IntegrationInvocationAuthority, "connectionRef">;
11
+ resolveCredential: (input: ResolveConnectionCredentialInput) => Promise<ResolveConnectionCredentialResult>;
12
+ onAuthNeeded?: (payload: ToolAuthNeededPayload) => Promise<void> | void;
13
+ fetchImpl?: FetchLike;
14
+ };
15
+ /**
16
+ * Compile active persisted API facets into ordinary in-process MCP providers.
17
+ * The caller supplies its authority resolver, so agent attempts and current
18
+ * humans use the same provider assembly without sharing credentials or policy.
19
+ */
20
+ export declare function buildApiIntegrationMcpServers(input: BuildApiIntegrationServersInput): LocalMcpServerRegistration[];
@@ -0,0 +1,36 @@
1
+ import type { GitHubActionPolicyActor, GitHubActionPolicyActorState, GitHubActionPolicyDecision, GitHubActionPolicyGroup } from "@opengeni/contracts";
2
+ import { type ConnectorActionPolicySnapshotEntry, type Database } from "@opengeni/db";
3
+ import { GITHUB_REST_MCP_APP_SERVER_ID, GITHUB_REST_MCP_PERSONAL_SERVER_ID } from "@opengeni/runtime/github-rest-mcp";
4
+ export declare const GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES: {
5
+ readonly routine: ("issue_comment" | "issue_create" | "issue_update" | "pull_request_comment" | "pull_request_create" | "pull_request_request_review" | "pull_request_update" | "ref_create")[];
6
+ readonly review: readonly ["pull_request_review_submit"];
7
+ readonly merge: readonly ["pull_request_merge"];
8
+ };
9
+ export type GitHubActionPolicyActorBinding = {
10
+ actor: GitHubActionPolicyActor;
11
+ label: string;
12
+ connectionId: string;
13
+ serverId: typeof GITHUB_REST_MCP_APP_SERVER_ID | typeof GITHUB_REST_MCP_PERSONAL_SERVER_ID;
14
+ };
15
+ export declare function projectGitHubActionPolicyActor(policies: readonly ConnectorActionPolicySnapshotEntry[], binding: GitHubActionPolicyActorBinding): GitHubActionPolicyActorState;
16
+ export declare function listGitHubActionPolicyActors(db: Database, input: {
17
+ accountId: string;
18
+ workspaceId: string;
19
+ actors: readonly GitHubActionPolicyActorBinding[];
20
+ }): Promise<GitHubActionPolicyActorState[]>;
21
+ export declare function updateGitHubActionPolicyGroup(db: Database, input: {
22
+ accountId: string;
23
+ workspaceId: string;
24
+ subjectId: string;
25
+ actor: GitHubActionPolicyActorBinding;
26
+ group: GitHubActionPolicyGroup;
27
+ decision: GitHubActionPolicyDecision;
28
+ }): Promise<GitHubActionPolicyActorState>;
29
+ export declare function githubAppActionPolicyActor(input: {
30
+ installationId: number;
31
+ accountLogin: string | null;
32
+ }): GitHubActionPolicyActorBinding;
33
+ export declare function personalGitHubActionPolicyActor(input: {
34
+ connectionId: string;
35
+ githubLogin: string;
36
+ }): GitHubActionPolicyActorBinding;
@@ -80,7 +80,7 @@ export declare const prReviewAutomationAdapter: {
80
80
  eager?: boolean | undefined;
81
81
  optional?: boolean | undefined;
82
82
  }[];
83
- firstPartyMcpTools: ("artifacts_create" | "artifacts_get_source" | "artifacts_list" | "artifacts_publish" | "artifacts_rollback" | "atlassian_get" | "atlassian_search" | "atlassian_sources_list" | "browser_act" | "browser_auth" | "browser_clipboard" | "browser_debug" | "browser_identity" | "browser_lifecycle" | "browser_observe" | "browser_open" | "browser_publish" | "browser_tabs" | "capability_authorization_request" | "capability_catalog_search" | "company_profile_confirm" | "company_profile_propose" | "computer_act" | "computer_clipboard" | "computer_lifecycle" | "computer_observe" | "computer_open" | "computer_targets" | "connected_machine_remove" | "editable_artifact_apply" | "editable_artifact_create" | "editable_artifact_export" | "editable_artifact_export_status" | "editable_artifact_get" | "editable_artifact_import" | "editable_artifact_inspect" | "editable_artifact_list" | "environment_list" | "environment_set_variable" | "fiken_bank_accounts_list" | "fiken_companies_list" | "fiken_contact_create" | "fiken_contacts_list" | "fiken_invoice_draft_create" | "fiken_invoice_get" | "fiken_invoices_list" | "fiken_products_list" | "fiken_purchases_list" | "fiken_sales_list" | "github_connect_link" | "github_repositories_list" | "goal_complete" | "goal_pause" | "goal_progress" | "goal_set" | "goal_update" | "goal_wait" | "instruction_policy_propose" | "interaction_discover" | "interaction_request_human" | "knowledge_correct" | "knowledge_propose" | "memory_correct" | "memory_save" | "memory_search" | "preference_propose" | "preference_registry_get" | "preference_registry_summary" | "reddit_accounts_list" | "reddit_mentions_live" | "reddit_post_reply" | "reddit_posts_sync" | "reddit_search_live" | "reddit_thread_fetch" | "remember" | "remember_confirm" | "rig_get" | "rig_list" | "rig_promote" | "rig_propose_change" | "rig_verify" | "run_on" | "sandbox_attach" | "sandbox_file_publish" | "sandbox_provision" | "sandbox_swap" | "sandboxes_list" | "scheduled_task_runs_list" | "scheduled_tasks_create" | "scheduled_tasks_delete" | "scheduled_tasks_get" | "scheduled_tasks_list" | "scheduled_tasks_pause" | "scheduled_tasks_resume" | "scheduled_tasks_trigger" | "scheduled_tasks_update" | "session_create" | "session_events" | "session_get" | "session_human_input_respond" | "session_pause" | "session_resume" | "session_send_message" | "session_steer" | "session_wait" | "sessions_list" | "set_other_session_title" | "set_session_title" | "slack_bot_channel_history" | "slack_bot_delete_message" | "slack_bot_file_content" | "slack_bot_file_info" | "slack_bot_list_channels" | "slack_bot_list_files" | "slack_bot_list_users" | "slack_bot_post_message" | "slack_bot_search" | "slack_bot_thread_replies" | "social_connections_list" | "social_daily_analysis_context" | "social_mentions_live" | "social_post_reply" | "social_posts_recent" | "social_posts_sync" | "social_search_live" | "social_thread_fetch" | "task_note_archive" | "task_note_promote_instruction_policy" | "task_note_promote_knowledge" | "task_note_promote_preference" | "task_note_replace" | "task_note_save" | "task_notes_list" | "variable_set_get_variable" | "variable_set_list" | "variable_set_set_variable" | "work_claim_release" | "work_claim_upsert" | "x_accounts_list" | "x_mentions_live" | "x_post_reply" | "x_posts_sync" | "x_search_live" | "x_thread_fetch")[];
83
+ firstPartyMcpTools: ("artifacts_archive" | "artifacts_create" | "artifacts_get_source" | "artifacts_list" | "artifacts_prepare_upload" | "artifacts_publish" | "artifacts_restore" | "artifacts_rollback" | "atlassian_get" | "atlassian_search" | "atlassian_sources_list" | "browser_act" | "browser_auth" | "browser_clipboard" | "browser_debug" | "browser_identity" | "browser_lifecycle" | "browser_observe" | "browser_open" | "browser_publish" | "browser_tabs" | "capability_authorization_request" | "capability_catalog_search" | "command_read" | "command_wait" | "company_profile_confirm" | "company_profile_propose" | "computer_act" | "computer_clipboard" | "computer_lifecycle" | "computer_observe" | "computer_open" | "computer_targets" | "connected_machine_remove" | "editable_artifact_apply" | "editable_artifact_create" | "editable_artifact_export" | "editable_artifact_export_status" | "editable_artifact_get" | "editable_artifact_import" | "editable_artifact_inspect" | "editable_artifact_list" | "environment_list" | "environment_set_variable" | "fiken_bank_accounts_list" | "fiken_companies_list" | "fiken_contact_create" | "fiken_contacts_list" | "fiken_invoice_draft_create" | "fiken_invoice_get" | "fiken_invoices_list" | "fiken_products_list" | "fiken_purchases_list" | "fiken_sales_list" | "github_connect_link" | "github_repositories_list" | "goal_complete" | "goal_pause" | "goal_progress" | "goal_resume" | "goal_set" | "goal_update" | "instruction_policy_propose" | "interaction_discover" | "interaction_request_human" | "knowledge_correct" | "knowledge_propose" | "memory_correct" | "memory_save" | "memory_search" | "preference_propose" | "preference_registry_get" | "preference_registry_summary" | "reddit_accounts_list" | "reddit_mentions_live" | "reddit_post_reply" | "reddit_posts_sync" | "reddit_search_live" | "reddit_thread_fetch" | "remember" | "remember_confirm" | "rig_get" | "rig_list" | "rig_promote" | "rig_propose_change" | "rig_verify" | "run_on" | "sandbox_attach" | "sandbox_file_publish" | "sandbox_provision" | "sandbox_swap" | "sandboxes_list" | "scheduled_task_runs_list" | "scheduled_tasks_create" | "scheduled_tasks_delete" | "scheduled_tasks_get" | "scheduled_tasks_list" | "scheduled_tasks_pause" | "scheduled_tasks_resume" | "scheduled_tasks_trigger" | "scheduled_tasks_update" | "session_create" | "session_events" | "session_get" | "session_human_input_respond" | "session_pause" | "session_resume" | "session_send_message" | "session_steer" | "session_wait" | "sessions_list" | "set_other_session_title" | "set_session_title" | "slack_bot_channel_history" | "slack_bot_delete_message" | "slack_bot_file_content" | "slack_bot_file_info" | "slack_bot_list_channels" | "slack_bot_list_files" | "slack_bot_list_users" | "slack_bot_post_message" | "slack_bot_search" | "slack_bot_thread_replies" | "social_connections_list" | "social_daily_analysis_context" | "social_mentions_live" | "social_post_reply" | "social_posts_recent" | "social_posts_sync" | "social_search_live" | "social_thread_fetch" | "task_note_archive" | "task_note_promote_instruction_policy" | "task_note_promote_knowledge" | "task_note_promote_preference" | "task_note_replace" | "task_note_save" | "task_notes_list" | "variable_set_get_variable" | "variable_set_list" | "variable_set_set_variable" | "wait_for_input" | "work_claim_release" | "work_claim_upsert" | "x_accounts_list" | "x_mentions_live" | "x_post_reply" | "x_posts_sync" | "x_search_live" | "x_thread_fetch")[];
84
84
  firstPartyMcpPermissions: ("account:admin" | "account:read" | "api_keys:manage" | "artifacts:publish" | "artifacts:read" | "billing:manage" | "billing:read" | "capabilities:manage" | "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")[];
85
85
  model: string | null;
86
86
  reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export * from "./domain/product-integration-pack.js";
23
23
  export * from "./domain/personal-connection-delegations.js";
24
24
  export * from "./domain/resources.js";
25
25
  export * from "./domain/github-repository-bindings.js";
26
+ export * from "./domain/github-action-policies.js";
26
27
  export * from "./domain/session-tool-policy.js";
27
28
  export * from "./domain/scheduled-tasks.js";
28
29
  export * from "./domain/sessions.js";
@@ -49,5 +50,6 @@ export * from "./application/composer-submit.js";
49
50
  export * from "./application/session-commands.js";
50
51
  export * from "./application/session-tenancy.js";
51
52
  export * from "./application/user-resource-grants.js";
53
+ export * from "./application/api-integration-servers.js";
52
54
  export * from "./editable-artifact-live.js";
53
55
  export * from "./editable-artifacts.js";
package/dist/index.js CHANGED
@@ -731,7 +731,6 @@ import {
731
731
  verifyDirectWorkspaceMutationSettlement,
732
732
  verifyRetainedProcessMutationSettlement
733
733
  } from "@opengeni/db";
734
- import { settleSessionBackgroundCommandForRetainedProcess } from "@opengeni/db/session-background-commands";
735
734
  import { appendAndPublishEvents } from "@opengeni/events";
736
735
  import {
737
736
  isProviderSandboxGoneDuringRoutedOperation,
@@ -965,14 +964,9 @@ function wrapChannelABoxWithRouting(services, ids, established) {
965
964
  reason: proof.reason,
966
965
  idleGraceMs: settings.sandboxIdleGraceMs
967
966
  });
968
- const backgroundSettlement = retainedProcessBackgroundSettlement(settlement.process, proof);
969
- await settleSessionBackgroundCommandForRetainedProcess(db, {
970
- accountId: ids.accountId,
971
- workspaceId: ids.workspaceId,
972
- sessionId: ids.sessionId,
973
- retainedProcessId: process.id,
974
- ...backgroundSettlement
975
- });
967
+ if (settlement.backgroundCommandEvents.length > 0 && bus) {
968
+ await bus.publish(ids.workspaceId, ids.sessionId, settlement.backgroundCommandEvents).catch(() => void 0);
969
+ }
976
970
  } : void 0;
977
971
  const resolver = makeActiveBackendResolver({
978
972
  workspaceId: ids.workspaceId,
@@ -1027,6 +1021,7 @@ function wrapChannelABoxWithRouting(services, ids, established) {
1027
1021
  } : {}
1028
1022
  });
1029
1023
  const proxy = new RoutingSandboxSession({
1024
+ bindActiveRouteOnFirstResolve: true,
1030
1025
  defaultResolved: {
1031
1026
  session: established.session,
1032
1027
  sandboxId: null,
@@ -2086,6 +2081,13 @@ function requireAccountAdminAuthorizationStamp(authorization) {
2086
2081
  permission: "account:admin"
2087
2082
  });
2088
2083
  }
2084
+ function requireResolvedAccessGrantAuthorization(authorization, workspaceId) {
2085
+ const { grant } = authorization;
2086
+ if (!resolvedAccessGrantAuthorizations.has(authorization) || !authorization.contextIntegrity || authorization.authenticatedSubjectId !== grant.subjectId || grant.workspaceId !== workspaceId) {
2087
+ throw new HTTPException(403, { message: "workspace access authorization is invalid" });
2088
+ }
2089
+ return grant;
2090
+ }
2089
2091
  async function requireCanonicalLocalAccountAdministrator(c, deps, accountId) {
2090
2092
  if (c.req.header("authorization")) {
2091
2093
  throw new HTTPException(401, { message: "organization administrator session required" });
@@ -7940,6 +7942,111 @@ function applyGitHubRepositoryBindings(resources, bindings) {
7940
7942
  });
7941
7943
  }
7942
7944
 
7945
+ // src/domain/github-action-policies.ts
7946
+ import {
7947
+ listConnectorActionPolicies,
7948
+ resolveConnectorActionPolicy,
7949
+ upsertConnectorActionPolicies
7950
+ } from "@opengeni/db";
7951
+ import {
7952
+ GITHUB_REST_MCP_APP_SERVER_ID,
7953
+ GITHUB_REST_MCP_PERSONAL_SERVER_ID,
7954
+ GITHUB_REST_WRITE_TOOL_NAMES
7955
+ } from "@opengeni/runtime/github-rest-mcp";
7956
+ var GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES = {
7957
+ routine: GITHUB_REST_WRITE_TOOL_NAMES.filter(
7958
+ (toolName) => toolName !== "pull_request_review_submit" && toolName !== "pull_request_merge"
7959
+ ),
7960
+ review: ["pull_request_review_submit"],
7961
+ merge: ["pull_request_merge"]
7962
+ };
7963
+ var groupedToolNames = Object.values(GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES).flat();
7964
+ if (groupedToolNames.length !== new Set(groupedToolNames).size || GITHUB_REST_WRITE_TOOL_NAMES.some((toolName) => !groupedToolNames.includes(toolName))) {
7965
+ throw new Error("GitHub action policy groups must cover every write tool exactly once");
7966
+ }
7967
+ function effectiveToolDecision(policies, actor, toolName) {
7968
+ const resolved = resolveConnectorActionPolicy(policies, {
7969
+ connectionId: actor.connectionId,
7970
+ serverId: actor.serverId,
7971
+ toolName,
7972
+ actionName: toolName
7973
+ });
7974
+ if (!resolved.managed) return "allow";
7975
+ if (resolved.entry) return resolved.entry.policy;
7976
+ return resolved.decision;
7977
+ }
7978
+ function effectiveGroupDecision(policies, actor, group) {
7979
+ const decisions = new Set(
7980
+ GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES[group].map(
7981
+ (toolName) => effectiveToolDecision(policies, actor, toolName)
7982
+ )
7983
+ );
7984
+ return decisions.size === 1 ? decisions.values().next().value : "mixed";
7985
+ }
7986
+ function projectGitHubActionPolicyActor(policies, binding) {
7987
+ const groups = {
7988
+ routine: effectiveGroupDecision(policies, binding, "routine"),
7989
+ review: effectiveGroupDecision(policies, binding, "review"),
7990
+ merge: effectiveGroupDecision(policies, binding, "merge")
7991
+ };
7992
+ return binding.actor.kind === "workspace_app" ? {
7993
+ kind: "workspace_app",
7994
+ installationId: binding.actor.installationId,
7995
+ label: binding.label,
7996
+ groups
7997
+ } : {
7998
+ kind: "personal",
7999
+ connectionId: binding.actor.connectionId,
8000
+ label: binding.label,
8001
+ groups
8002
+ };
8003
+ }
8004
+ async function listGitHubActionPolicyActors(db, input) {
8005
+ const policies = await listConnectorActionPolicies(db, {
8006
+ accountId: input.accountId,
8007
+ workspaceId: input.workspaceId,
8008
+ connectionIds: input.actors.map((actor) => actor.connectionId)
8009
+ });
8010
+ return input.actors.map((actor) => projectGitHubActionPolicyActor(policies, actor));
8011
+ }
8012
+ async function updateGitHubActionPolicyGroup(db, input) {
8013
+ await upsertConnectorActionPolicies(
8014
+ db,
8015
+ GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES[input.group].map((toolName) => ({
8016
+ accountId: input.accountId,
8017
+ workspaceId: input.workspaceId,
8018
+ subjectId: input.subjectId,
8019
+ connectionId: input.actor.connectionId,
8020
+ serverId: input.actor.serverId,
8021
+ toolName,
8022
+ actionName: toolName,
8023
+ policy: input.decision
8024
+ }))
8025
+ );
8026
+ const policies = await listConnectorActionPolicies(db, {
8027
+ accountId: input.accountId,
8028
+ workspaceId: input.workspaceId,
8029
+ connectionIds: [input.actor.connectionId]
8030
+ });
8031
+ return projectGitHubActionPolicyActor(policies, input.actor);
8032
+ }
8033
+ function githubAppActionPolicyActor(input) {
8034
+ return {
8035
+ actor: { kind: "workspace_app", installationId: input.installationId },
8036
+ label: input.accountLogin ? `OpenGeni bot on ${input.accountLogin}` : "OpenGeni bot",
8037
+ connectionId: `github-app:${input.installationId}`,
8038
+ serverId: GITHUB_REST_MCP_APP_SERVER_ID
8039
+ };
8040
+ }
8041
+ function personalGitHubActionPolicyActor(input) {
8042
+ return {
8043
+ actor: { kind: "personal", connectionId: input.connectionId },
8044
+ label: `@${input.githubLogin}`,
8045
+ connectionId: input.connectionId,
8046
+ serverId: GITHUB_REST_MCP_PERSONAL_SERVER_ID
8047
+ };
8048
+ }
8049
+
7943
8050
  // src/domain/session-tool-policy.ts
7944
8051
  import {
7945
8052
  SESSION_EFFECTIVE_TOOL_POLICY_ID_LIMIT,
@@ -14920,6 +15027,7 @@ import {
14920
15027
  getSandbox as getSandbox5,
14921
15028
  getVariableSet as getVariableSet4,
14922
15029
  NewSessionDraftAccessError,
15030
+ newSessionDraftSelectedProjectChannelId,
14923
15031
  newSessionDraftToolsProvided,
14924
15032
  newSessionSelectionHistory,
14925
15033
  publicNewSessionDraftOptions,
@@ -14933,6 +15041,7 @@ function hasOwn(value, key) {
14933
15041
  }
14934
15042
  function mapNewSessionDraft(row) {
14935
15043
  if (!row) return null;
15044
+ const selectedProjectChannelId = newSessionDraftSelectedProjectChannelId(row);
14936
15045
  return NewSessionDraft.parse({
14937
15046
  revision: row.revision,
14938
15047
  text: row.text,
@@ -14942,6 +15051,7 @@ function mapNewSessionDraft(row) {
14942
15051
  model: row.model,
14943
15052
  reasoningEffort: row.reasoningEffort,
14944
15053
  latencyMode: row.latencyMode,
15054
+ ...selectedProjectChannelId !== void 0 ? { selectedProjectChannelId } : {},
14945
15055
  options: publicNewSessionDraftOptions(row),
14946
15056
  selectionHistory: newSessionSelectionHistory(row),
14947
15057
  updatedAt: row.updatedAt.toISOString()
@@ -15102,6 +15212,7 @@ async function saveActorNewSessionDraft(deps, grant, workspaceId, rawInput, cano
15102
15212
  model: input.model,
15103
15213
  reasoningEffort: input.reasoningEffort,
15104
15214
  latencyMode: input.latencyMode,
15215
+ ...input.selectedProjectChannelId !== void 0 ? { selectedProjectChannelId: input.selectedProjectChannelId } : {},
15105
15216
  options: input.options,
15106
15217
  // Only managed people are removed through removeWorkspaceMember().
15107
15218
  // API keys and delegated service actors (for example the first-party
@@ -15508,7 +15619,7 @@ async function controlAgentSessionWorkstream(deps, context, input) {
15508
15619
  wakeRevision: result.workflowWake.wakeRevision,
15509
15620
  shouldSignal: true,
15510
15621
  interruptionCount: result.interruptionCount,
15511
- controlRequested: true
15622
+ controlRequested: input.action === "pause"
15512
15623
  });
15513
15624
  }
15514
15625
  }
@@ -15796,7 +15907,7 @@ async function controlHumanSessionWorkstreamWithOutcome(deps, context, input) {
15796
15907
  wakeRevision: result.workflowWake.wakeRevision,
15797
15908
  shouldSignal: true,
15798
15909
  interruptionCount: result.interruptionCount,
15799
- controlRequested: true
15910
+ controlRequested: input.action === "pause"
15800
15911
  });
15801
15912
  }
15802
15913
  }
@@ -16009,6 +16120,143 @@ async function revokeManagedHumanUserResourceGrant(deps, authorization, workspac
16009
16120
  grantId
16010
16121
  });
16011
16122
  }
16123
+
16124
+ // src/application/api-integration-servers.ts
16125
+ import {
16126
+ createGraphqlMcpServer,
16127
+ createOpenApiMcpServer,
16128
+ createPinnedIntegrationTransport,
16129
+ directIntegrationTransport,
16130
+ IntegrationInvocationError
16131
+ } from "@opengeni/capabilities";
16132
+ function buildApiIntegrationMcpServers(input) {
16133
+ const transport = createPinnedIntegrationTransport({
16134
+ network: input.settings,
16135
+ ...input.fetchImpl ? { fetchImpl: input.fetchImpl } : {}
16136
+ });
16137
+ return input.integrations.map((integration) => {
16138
+ const authority = {
16139
+ ...input.authority,
16140
+ ...integration.connectionRef?.connectionId ? { connectionRef: integration.connectionRef.connectionId } : {}
16141
+ };
16142
+ const credentialResolver = integration.connectionRef ? integrationCredentialResolver(input, integration, "execution") : void 0;
16143
+ const buildServer = (serverTransport, serverCredentialResolver = credentialResolver) => integration.revision.protocol === "openapi" ? createOpenApiMcpServer({
16144
+ revision: integration.revision,
16145
+ transport: serverTransport,
16146
+ authority,
16147
+ ...serverCredentialResolver ? { credentialResolver: serverCredentialResolver } : {}
16148
+ }) : createGraphqlMcpServer({
16149
+ revision: integration.revision,
16150
+ endpoint: integration.baseUrl,
16151
+ transport: serverTransport,
16152
+ authority,
16153
+ ...serverCredentialResolver ? { credentialResolver: serverCredentialResolver } : {}
16154
+ });
16155
+ const server = buildServer(transport);
16156
+ const preflightCredentialResolver = integration.connectionRef ? integrationCredentialResolver(input, integration, "preflight") : void 0;
16157
+ const preflightServer = preflightCredentialResolver ? buildServer(providerBlockingPreflightTransport, preflightCredentialResolver) : null;
16158
+ return {
16159
+ id: integration.serverId,
16160
+ server,
16161
+ approvalAuthority: {
16162
+ kind: "api_integration",
16163
+ capabilityId: integration.capabilityId,
16164
+ pluginKey: integration.pluginKey,
16165
+ pluginInstallationId: integration.pluginInstallationId,
16166
+ installationVersion: integration.installationVersion,
16167
+ instanceId: integration.instanceId,
16168
+ instanceKey: integration.instanceKey,
16169
+ instanceVersion: integration.instanceVersion,
16170
+ definitionId: integration.definitionId,
16171
+ definitionProvenance: integration.definitionProvenance,
16172
+ revisionId: integration.revision.id,
16173
+ baseUrl: integration.baseUrl,
16174
+ providerDomain: integration.providerDomain,
16175
+ connectionRef: integration.connectionRef,
16176
+ connectionAuthorityGeneration: integration.connectionAuthorityGeneration
16177
+ },
16178
+ ...integration.connectionRef?.connectionId ? { resolvedConnectionId: integration.connectionRef.connectionId } : {},
16179
+ ...credentialResolver ? {
16180
+ preflightCall: async (toolName, args, options) => await preflightApiIntegrationCall(preflightServer, toolName, args, options)
16181
+ } : {}
16182
+ };
16183
+ });
16184
+ }
16185
+ var providerBlockingPreflightTransport = directIntegrationTransport(async () => {
16186
+ throw new Error("integration provider request blocked by preflight");
16187
+ });
16188
+ async function preflightApiIntegrationCall(server, toolName, args, options) {
16189
+ try {
16190
+ await server.callTool(toolName, args, null, options);
16191
+ } catch (error) {
16192
+ if (error instanceof IntegrationInvocationError && error.code === "request_failed") return;
16193
+ throw error;
16194
+ }
16195
+ throw new Error("integration preflight unexpectedly crossed the provider request boundary");
16196
+ }
16197
+ function integrationCredentialResolver(input, integration, credentialResolutionMode) {
16198
+ const connectionRef = integration.connectionRef;
16199
+ if (!connectionRef) throw new Error("Integration credential resolver requires a connection");
16200
+ const expectedAuthorityGeneration = integration.connectionAuthorityGeneration;
16201
+ if (expectedAuthorityGeneration === null) {
16202
+ throw new Error("Integration credential resolver requires a connection authority generation");
16203
+ }
16204
+ return {
16205
+ resolve: async (request) => {
16206
+ const result = await input.resolveCredential({
16207
+ workspaceId: input.authority.workspaceId,
16208
+ serverId: integration.serverId,
16209
+ toolName: request.operationKey,
16210
+ connectionRef,
16211
+ destinationUrl: request.destinationUrl,
16212
+ credentialTarget: "http_api",
16213
+ forceRefresh: request.forceRefresh === true,
16214
+ credentialResolutionMode,
16215
+ expectedAuthorityGeneration
16216
+ });
16217
+ if (result.status === "auth_needed") {
16218
+ await publishAuthNeeded(
16219
+ input,
16220
+ integration.serverId,
16221
+ request.operationKey,
16222
+ result,
16223
+ connectionRef
16224
+ );
16225
+ return null;
16226
+ }
16227
+ const destination = new URL(request.destinationUrl);
16228
+ return {
16229
+ audience: { origin: destination.origin, pathPrefix: "/" },
16230
+ placements: result.placements ?? Object.entries(result.headers).map(([name, value]) => ({
16231
+ carrier: "header",
16232
+ name,
16233
+ value
16234
+ })),
16235
+ ...result.authorizeProviderRequest ? { authorizeProviderRequest: result.authorizeProviderRequest } : {},
16236
+ ...result.expiresAt ? { expiresAt: result.expiresAt.toISOString() } : {},
16237
+ ...connectionRef.scopes ? { scope: [...connectionRef.scopes] } : {}
16238
+ };
16239
+ }
16240
+ };
16241
+ }
16242
+ async function publishAuthNeeded(input, serverId, toolName, result, connectionRef) {
16243
+ try {
16244
+ await input.onAuthNeeded?.({
16245
+ serverId,
16246
+ toolName,
16247
+ providerDomain: result.providerDomain,
16248
+ ...result.provider ? { provider: result.provider } : {},
16249
+ reason: result.reason,
16250
+ ...result.connectionId ? { connectionId: result.connectionId } : {},
16251
+ ...result.authoritySource === "host" || connectionRef.authoritySource === "host" ? { authoritySource: "host" } : {},
16252
+ ...result.scopes ? { scopes: result.scopes } : {},
16253
+ ...result.resource ? { resource: result.resource } : {},
16254
+ ...result.selectedResources ? { selectedResources: result.selectedResources } : {},
16255
+ ...result.authorizationUrl ? { authorizationUrl: result.authorizationUrl } : {}
16256
+ });
16257
+ } catch {
16258
+ }
16259
+ }
16012
16260
  export {
16013
16261
  CODEX_COMPACTION_V2_PROVIDER_LOCKED,
16014
16262
  CONVERSATION_ATTACHMENT_MAX_COUNT,
@@ -16071,6 +16319,7 @@ export {
16071
16319
  EditableArtifactSnapshotVerificationError,
16072
16320
  EditableArtifactStaleBaseError,
16073
16321
  EditableArtifactUndoTargetError,
16322
+ GITHUB_ACTION_POLICY_GROUP_TOOL_NAMES,
16074
16323
  InMemoryEditableArtifactLiveTicketStore,
16075
16324
  InMemoryEditableArtifactStableIdFactory,
16076
16325
  InMemoryEditableArtifactStore,
@@ -16168,6 +16417,7 @@ export {
16168
16417
  authorizedSocialConnectionsForGrant,
16169
16418
  automationRequestDigest,
16170
16419
  availableToolRefs,
16420
+ buildApiIntegrationMcpServers,
16171
16421
  buildAutomationAcceptedExecution,
16172
16422
  buildCapabilityCatalog,
16173
16423
  buildFleetContextForSession,
@@ -16276,6 +16526,7 @@ export {
16276
16526
  getManagedHumanSessionCreateCapabilities,
16277
16527
  getManagedSession,
16278
16528
  getWorkspaceInsights,
16529
+ githubAppActionPolicyActor,
16279
16530
  googleDrivePublicationDelegationFromVisibleConnections,
16280
16531
  governedLearningEvidenceIsSlackDerived,
16281
16532
  governedLearningSlackImportance,
@@ -16306,6 +16557,7 @@ export {
16306
16557
  legacySandboxRuntimeFromPacks,
16307
16558
  listCapabilityPacks,
16308
16559
  listFleet,
16560
+ listGitHubActionPolicyActors,
16309
16561
  listGitHubRepositoryBindingCandidates,
16310
16562
  listManagedHumanUserResourceAuthorities,
16311
16563
  listRigChangesForApi,
@@ -16353,6 +16605,7 @@ export {
16353
16605
  personalConnectionDelegationsEqual,
16354
16606
  personalConnectionDelegationsFromParent,
16355
16607
  personalConnectionDelegationsFromVisibleConnections,
16608
+ personalGitHubActionPolicyActor,
16356
16609
  personalGitHubRepositoryResources,
16357
16610
  portableSkillCapabilityId,
16358
16611
  portableSkillPluginKey,
@@ -16367,6 +16620,7 @@ export {
16367
16620
  preferredFikenConnection,
16368
16621
  preflightCreateTimeSandboxTarget,
16369
16622
  previewCapabilityPackInstallation,
16623
+ projectGitHubActionPolicyActor,
16370
16624
  promoteSetupAppendChange,
16371
16625
  promoteVerifiedDefinitionEditChangeForApi,
16372
16626
  proposeRigChangeForApi,
@@ -16399,6 +16653,7 @@ export {
16399
16653
  requireOpenGeniSlackBotConnection,
16400
16654
  requirePermission,
16401
16655
  requireQueuedTurnForApi,
16656
+ requireResolvedAccessGrantAuthorization,
16402
16657
  requireRigChangeForApi,
16403
16658
  requireRigForApi,
16404
16659
  requireScheduledTaskForApi,
@@ -16472,6 +16727,7 @@ export {
16472
16727
  syncCreatedScheduledTask,
16473
16728
  syncUpdatedScheduledTask,
16474
16729
  unboundGitHubRepositoryResources,
16730
+ updateGitHubActionPolicyGroup,
16475
16731
  updateManagedHumanSessionVisibility,
16476
16732
  updateRigForApi,
16477
16733
  updateScheduledTaskForApi,