@opengeni/api-router 4.1.0 → 4.1.2-canary.36079201993001

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/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createOpenGeniSlackBotInteractionClient,
8
8
  startSlackInteractionPump,
9
9
  startTemporalScheduleCleanupPump
10
- } from "./chunk-24C5LPNE.js";
10
+ } from "./chunk-PTO4RZT5.js";
11
11
 
12
12
  // src/index.ts
13
13
  import { scheduledTaskKnowledgeSource } from "@opengeni/contracts";
@@ -46,7 +46,7 @@ export declare function requireGitHubLensConnect(deps: ApiRouteDeps): Promise<{
46
46
  eager?: boolean | undefined;
47
47
  optional?: boolean | undefined;
48
48
  }[];
49
- 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_enroll_token" | "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_get" | "instruction_policy_propose" | "instruction_policy_save" | "interaction_discover" | "interaction_request_human" | "knowledge_archive" | "knowledge_browse" | "knowledge_correct" | "knowledge_get" | "knowledge_prepare_save" | "knowledge_propose" | "knowledge_retain_file" | "knowledge_retain_message" | "knowledge_save" | "knowledge_search" | "memory_correct" | "memory_save" | "memory_search" | "preference_propose" | "preference_registry_get" | "preference_registry_summary" | "project_create" | "project_delete" | "project_get" | "project_list" | "project_reorder" | "project_update" | "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_set_project" | "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")[];
49
+ 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_read" | "browser_screenshot" | "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_enroll_token" | "connected_machine_remove" | "custom_mcp_setup_request" | "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_get" | "instruction_policy_propose" | "instruction_policy_save" | "interaction_discover" | "interaction_request_human" | "knowledge_archive" | "knowledge_browse" | "knowledge_correct" | "knowledge_get" | "knowledge_prepare_save" | "knowledge_propose" | "knowledge_retain_file" | "knowledge_retain_message" | "knowledge_save" | "knowledge_search" | "memory_correct" | "memory_save" | "memory_search" | "preference_propose" | "preference_registry_get" | "preference_registry_summary" | "project_create" | "project_delete" | "project_get" | "project_list" | "project_reorder" | "project_update" | "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_set_project" | "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")[];
50
50
  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")[];
51
51
  model: string | null;
52
52
  reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
@@ -19,7 +19,7 @@ export declare const SLACK_SESSION_INSTRUCTIONS: string;
19
19
  * selection at session creation while keeping Slack mutations out of the model
20
20
  * surface; interaction delivery remains owned by the durable delivery pump.
21
21
  */
22
- export declare const SLACK_TASK_FIRST_PARTY_MCP_TOOLS: ("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_enroll_token" | "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_get" | "instruction_policy_propose" | "instruction_policy_save" | "interaction_discover" | "interaction_request_human" | "knowledge_archive" | "knowledge_browse" | "knowledge_correct" | "knowledge_get" | "knowledge_prepare_save" | "knowledge_propose" | "knowledge_retain_file" | "knowledge_retain_message" | "knowledge_save" | "knowledge_search" | "memory_correct" | "memory_save" | "memory_search" | "preference_propose" | "preference_registry_get" | "preference_registry_summary" | "project_create" | "project_delete" | "project_get" | "project_list" | "project_reorder" | "project_update" | "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_set_project" | "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")[];
22
+ export declare const SLACK_TASK_FIRST_PARTY_MCP_TOOLS: ("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_read" | "browser_screenshot" | "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_enroll_token" | "connected_machine_remove" | "custom_mcp_setup_request" | "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_get" | "instruction_policy_propose" | "instruction_policy_save" | "interaction_discover" | "interaction_request_human" | "knowledge_archive" | "knowledge_browse" | "knowledge_correct" | "knowledge_get" | "knowledge_prepare_save" | "knowledge_propose" | "knowledge_retain_file" | "knowledge_retain_message" | "knowledge_save" | "knowledge_search" | "memory_correct" | "memory_save" | "memory_search" | "preference_propose" | "preference_registry_get" | "preference_registry_summary" | "project_create" | "project_delete" | "project_get" | "project_list" | "project_reorder" | "project_update" | "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_set_project" | "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")[];
23
23
  export type NormalizedSlackInteraction = {
24
24
  providerEventId: string;
25
25
  providerMessageId: string;
@@ -1,3 +1,4 @@
1
+ import type { Settings } from "@opengeni/config";
1
2
  import type { DocumentServices } from "@opengeni/documents";
2
3
  import { type KnowledgeContext, type Database } from "@opengeni/db";
3
4
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -5,4 +6,5 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
5
6
  * chunk/base retrieval is retired: it cannot bypass pending Knowledge review. */
6
7
  export declare function buildDocumentsMcpServer(db: Database, accountId: string, workspaceId: string, documentServices: DocumentServices, options: {
7
8
  knowledge: KnowledgeContext;
9
+ settings?: Settings;
8
10
  }): McpServer;
@@ -271,6 +271,14 @@ export declare const FIRST_PARTY_TOOL_AUTHORIZATION: {
271
271
  sessionRequired: true;
272
272
  allOf: "sessions:read"[];
273
273
  };
274
+ browser_read: {
275
+ sessionRequired: true;
276
+ allOf: "sessions:read"[];
277
+ };
278
+ browser_screenshot: {
279
+ sessionRequired: true;
280
+ allOf: "sessions:read"[];
281
+ };
274
282
  browser_act: {
275
283
  sessionRequired: true;
276
284
  allOf: "sessions:control"[];
@@ -351,6 +359,10 @@ export declare const FIRST_PARTY_TOOL_AUTHORIZATION: {
351
359
  sessionRequired: true;
352
360
  allOf: "workspace:read"[];
353
361
  };
362
+ custom_mcp_setup_request: {
363
+ sessionRequired: true;
364
+ allOf: "workspace:read"[];
365
+ };
354
366
  github_connect_link: {
355
367
  allOf: "github:use"[];
356
368
  };
@@ -82,8 +82,8 @@ export declare function scheduledTaskMcpSummary(task: ScheduledTask): {
82
82
  runMode: "existing_session" | "new_session_per_run" | "reusable_session";
83
83
  overlapPolicy: "allow_concurrent" | "buffer_one" | "skip";
84
84
  action: {
85
+ readonly sourceId?: never;
85
86
  kind: "agent_turn";
86
- sourceId?: never;
87
87
  sourceGeneration?: never;
88
88
  sourceLifecycleGeneration?: never;
89
89
  destination?: never;
@@ -205,8 +205,8 @@ export declare function boundScheduledTaskDetailMcp(task: ScheduledTask): {
205
205
  runMode: "existing_session" | "new_session_per_run" | "reusable_session";
206
206
  overlapPolicy: "allow_concurrent" | "buffer_one" | "skip";
207
207
  action: {
208
+ readonly sourceId?: never;
208
209
  kind: "agent_turn";
209
- sourceId?: never;
210
210
  sourceGeneration?: never;
211
211
  sourceLifecycleGeneration?: never;
212
212
  destination?: never;
@@ -389,8 +389,8 @@ export declare function boundScheduledTaskMcpPage(input: {
389
389
  runMode: "existing_session" | "new_session_per_run" | "reusable_session";
390
390
  overlapPolicy: "allow_concurrent" | "buffer_one" | "skip";
391
391
  action: {
392
+ readonly sourceId?: never;
392
393
  kind: "agent_turn";
393
- sourceId?: never;
394
394
  sourceGeneration?: never;
395
395
  sourceLifecycleGeneration?: never;
396
396
  destination?: never;
@@ -1,5 +1,6 @@
1
1
  import { InteractionActor, type AccessGrant, type FileAsset } from "@opengeni/contracts";
2
2
  import { type ApiRouteDeps, type ResolvedSessionAuthorization } from "@opengeni/core";
3
+ import { type BrowserControlScreenshotOptions, type BrowserControlFrame } from "@opengeni/runtime/sandbox";
3
4
  import type { Hono } from "hono";
4
5
  export declare function registerBrowserSessionRoutes(app: Hono, deps: ApiRouteDeps): void;
5
6
  export declare function browserNeedsStandaloneDisplayStack(input: {
@@ -7,6 +8,8 @@ export declare function browserNeedsStandaloneDisplayStack(input: {
7
8
  linkedComputer: boolean;
8
9
  nativeBrowserControl: boolean;
9
10
  }): boolean;
11
+ export declare function parseBrowserScreenshotOptions(query: URLSearchParams): BrowserControlScreenshotOptions;
12
+ export declare function browserScreenshotResponse(frame: Pick<BrowserControlFrame, "data" | "mediaType" | "metadataHeader">): Response;
10
13
  export declare function interactionActorForGrant(grant: AccessGrant): ReturnType<typeof InteractionActor.parse>;
11
14
  /** Resolve Drive authority from the same immutable session authorization that
12
15
  * admitted the browser action. Agent-attempt subjects are technical worker
@@ -0,0 +1,5 @@
1
+ import type { GitHubInstallationBindingCandidate } from "@opengeni/contracts";
2
+ export declare function githubInstallationChooserHtml(candidates: GitHubInstallationBindingCandidate[], state: string, workspaceId: string, baseUrl: string): string;
3
+ export declare function githubSetupSuccessHtml(account: string, returnUrl: string): string;
4
+ export declare function githubSetupPendingHtml(): string;
5
+ export declare function githubSuccessHtml(envLines: string[]): string;
@@ -1,4 +1,30 @@
1
1
  import { type ApiRouteDeps, type WorkspaceInsightsFilterField } from "@opengeni/core";
2
2
  import type { Hono } from "hono";
3
3
  export declare function normalizeWorkspaceInsightsQueryFilter(value: string | null | undefined, field: WorkspaceInsightsFilterField): string | null;
4
+ /**
5
+ * Share one in-flight computation between identical concurrent callers.
6
+ *
7
+ * A reload, a second tab, or a retried fetch joins the rollup already running
8
+ * instead of starting another multi-second aggregate on the database.
9
+ * Authorization and filter validation still run per request before a caller
10
+ * may join; the map only ever holds running work. The caller supplies the
11
+ * complete sharing key, which must identify everything the result depends on.
12
+ */
13
+ export declare function createInFlightCoalescer<T>(): {
14
+ run: (key: string, work: () => Promise<T>) => Promise<T>;
15
+ readonly size: number;
16
+ };
17
+ /**
18
+ * Insights rows are filtered by the database RLS actor (private sessions are
19
+ * visible only to their owner), so two administrators of one workspace can
20
+ * legitimately receive different responses. The actor identity is part of
21
+ * the key; requests share work only when every visibility input is equal.
22
+ */
23
+ export declare function workspaceInsightsCoalesceKey(input: {
24
+ workspaceId: string;
25
+ range: string;
26
+ provider: string | null;
27
+ model: string | null;
28
+ rlsActor: string | null;
29
+ }): string;
4
30
  export declare function registerInsightsRoutes(app: Hono, deps: ApiRouteDeps): void;
@@ -1,6 +1,7 @@
1
1
  import { SandboxFileArtifactReceipt, type AccessGrant, type Session } from "@opengeni/contracts";
2
2
  import { type ApiRouteDeps, type AccessGrantAuthorization } from "@opengeni/core";
3
3
  import { getFile } from "@opengeni/db";
4
+ import { type SandboxChannelAService } from "@opengeni/runtime/sandbox";
4
5
  /** Original bytes inherit the already-authorized source session's ownership. */
5
6
  export declare function publishSandboxFileArtifact(deps: ApiRouteDeps, input: Parameters<typeof publishSandboxFileArtifactInScope>[1]): Promise<SandboxFileArtifactReceipt>;
6
7
  declare function publishSandboxFileArtifactInScope(deps: ApiRouteDeps, input: {
@@ -10,7 +11,22 @@ declare function publishSandboxFileArtifactInScope(deps: ApiRouteDeps, input: {
10
11
  path: string;
11
12
  signal?: AbortSignal | undefined;
12
13
  }): Promise<SandboxFileArtifactReceipt>;
13
- export declare function sandboxArtifactRelativePath(value: string): string;
14
+ /** Use the root captured by the same fenced Channel-A service that reads bytes,
15
+ * not the session's placement-home label or a caller-supplied root. */
16
+ export declare function readSandboxArtifactFile(service: Pick<SandboxChannelAService, "capabilities" | "fsRead">, value: string, maxBytes: number): Promise<{
17
+ path: string;
18
+ sandboxPath: string;
19
+ read: {
20
+ path: string;
21
+ encoding: "base64" | "utf8";
22
+ content: string;
23
+ sizeBytes: number;
24
+ truncated: boolean;
25
+ isBinary: boolean;
26
+ revision: number;
27
+ };
28
+ }>;
29
+ export declare function sandboxArtifactRelativePath(value: string, workspaceRoot?: string): string;
14
30
  export declare function sandboxArtifactSafeFilename(filename: string): string;
15
31
  export declare function sandboxFileContentType(filename: string): string;
16
32
  export declare function sandboxArtifactIdentity(input: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/api-router",
3
- "version": "4.1.0",
3
+ "version": "4.1.2-canary.36079201993001",
4
4
  "description": "OpenGeni HTTP surface: the Hono adapter/router (createApp), routes, MCP HTTP transport, and HTTP access adapters over @opengeni/core. An engine-distribution surface — its runtime closure includes engine-internal packages.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -43,24 +43,24 @@
43
43
  "@hono/zod-validator": "^0.7.6",
44
44
  "@llamaindex/liteparse": "2.14.2",
45
45
  "@modelcontextprotocol/sdk": "^1.29.0",
46
- "@opengeni/agent-proto": "^0.6.0",
47
- "@opengeni/artifact-tool": "^0.3.31",
48
- "@opengeni/capabilities": "^0.3.4",
49
- "@opengeni/codemode": "^0.6.1",
50
- "@opengeni/codex": "^0.2.25",
51
- "@opengeni/config": "^2.1.0",
52
- "@opengeni/contracts": "^5.1.0",
53
- "@opengeni/core": "^4.0.1",
54
- "@opengeni/db": "^6.0.1",
55
- "@opengeni/documents": "^0.8.32",
56
- "@opengeni/events": "^0.4.30",
57
- "@opengeni/github": "^0.7.15",
58
- "@opengeni/network": "^0.3.1",
59
- "@opengeni/observability": "^0.8.31",
60
- "@opengeni/runtime": "^4.0.1",
61
- "@opengeni/storage": "^0.2.132",
62
- "@opengeni/tool-gateway": "^0.1.12",
63
- "@opengeni/xai-subscription": "^0.1.4",
46
+ "@opengeni/agent-proto": "^0.6.0-canary.36079201993001",
47
+ "@opengeni/artifact-tool": "^0.3.32-canary.36079201993001",
48
+ "@opengeni/capabilities": "^0.3.4-canary.36079201993001",
49
+ "@opengeni/codemode": "^0.6.2-canary.36079201993001",
50
+ "@opengeni/codex": "^0.2.26-canary.36079201993001",
51
+ "@opengeni/config": "^2.1.1-canary.36079201993001",
52
+ "@opengeni/contracts": "^5.1.1-canary.36079201993001",
53
+ "@opengeni/core": "^4.0.3-canary.36079201993001",
54
+ "@opengeni/db": "^6.0.3-canary.36079201993001",
55
+ "@opengeni/documents": "^0.8.34-canary.36079201993001",
56
+ "@opengeni/events": "^0.4.32-canary.36079201993001",
57
+ "@opengeni/github": "^0.7.16-canary.36079201993001",
58
+ "@opengeni/network": "^0.3.1-canary.36079201993001",
59
+ "@opengeni/observability": "^0.8.32-canary.36079201993001",
60
+ "@opengeni/runtime": "^4.0.3-canary.36079201993001",
61
+ "@opengeni/storage": "^0.2.133-canary.36079201993001",
62
+ "@opengeni/tool-gateway": "^0.1.13-canary.36079201993001",
63
+ "@opengeni/xai-subscription": "^0.1.4-canary.36079201993001",
64
64
  "@temporalio/client": "^1.17.0",
65
65
  "better-auth": "^1.6.14",
66
66
  "hono": "^4.12.18",
@@ -1,4 +1,5 @@
1
1
  import { searchKnowledgeEntries } from "@opengeni/core";
2
+ import type { Settings } from "@opengeni/config";
2
3
  import { KnowledgeEntryListRequest } from "@opengeni/contracts";
3
4
  import type { DocumentServices } from "@opengeni/documents";
4
5
  import {
@@ -17,7 +18,7 @@ export function buildDocumentsMcpServer(
17
18
  accountId: string,
18
19
  workspaceId: string,
19
20
  documentServices: DocumentServices,
20
- options: { knowledge: KnowledgeContext },
21
+ options: { knowledge: KnowledgeContext; settings?: Settings },
21
22
  ): McpServer {
22
23
  const context = options.knowledge;
23
24
  if (context.accountId !== accountId || context.workspaceId !== workspaceId)
@@ -39,7 +40,13 @@ export function buildDocumentsMcpServer(
39
40
  {
40
41
  type: "text",
41
42
  text: JSON.stringify(
42
- await searchKnowledgeEntries(db, context, input, () => documentServices.embedder),
43
+ await searchKnowledgeEntries(
44
+ db,
45
+ context,
46
+ input,
47
+ () => documentServices.embedder,
48
+ options.settings,
49
+ ),
43
50
  ),
44
51
  },
45
52
  ],
@@ -117,6 +117,8 @@ export const FIRST_PARTY_TOOL_AUTHORIZATION = {
117
117
  browser_open: { sessionRequired: true, allOf: ["sessions:control"] },
118
118
  browser_tabs: { sessionRequired: true, allOf: ["sessions:control"] },
119
119
  browser_observe: { sessionRequired: true, allOf: ["sessions:read"] },
120
+ browser_read: { sessionRequired: true, allOf: ["sessions:read"] },
121
+ browser_screenshot: { sessionRequired: true, allOf: ["sessions:read"] },
120
122
  browser_act: { sessionRequired: true, allOf: ["sessions:control"] },
121
123
  browser_clipboard: { sessionRequired: true, allOf: ["sessions:read"] },
122
124
  browser_debug: { sessionRequired: true, allOf: ["sessions:read"] },
@@ -152,6 +154,10 @@ export const FIRST_PARTY_TOOL_AUTHORIZATION = {
152
154
  sessionRequired: true,
153
155
  allOf: ["workspace:read"],
154
156
  },
157
+ custom_mcp_setup_request: {
158
+ sessionRequired: true,
159
+ allOf: ["workspace:read"],
160
+ },
155
161
  github_connect_link: { allOf: ["github:use"] },
156
162
  github_repositories_list: { allOf: ["github:use"] },
157
163
  social_connections_list: { allOf: ["connections:read"] },
@@ -142,7 +142,14 @@ export function registerKnowledgeEntryTools(
142
142
  },
143
143
  (input) =>
144
144
  run((context) =>
145
- prepareKnowledgeSave(deps.db, context, input, () => deps.getDocumentServices().embedder),
145
+ prepareKnowledgeSave(
146
+ deps.db,
147
+ context,
148
+ input,
149
+ () => deps.getDocumentServices().embedder,
150
+ undefined,
151
+ deps.settings,
152
+ ),
146
153
  ),
147
154
  );
148
155
  server.registerTool(
@@ -159,7 +166,13 @@ export function registerKnowledgeEntryTools(
159
166
  },
160
167
  (input) =>
161
168
  run((context) =>
162
- searchKnowledgeEntries(deps.db, context, input, () => deps.getDocumentServices().embedder),
169
+ searchKnowledgeEntries(
170
+ deps.db,
171
+ context,
172
+ input,
173
+ () => deps.getDocumentServices().embedder,
174
+ deps.settings,
175
+ ),
163
176
  ),
164
177
  );
165
178
  server.registerTool(
package/src/mcp/server.ts CHANGED
@@ -2521,7 +2521,7 @@ function registerGoalTools(
2521
2521
  "goal_update",
2522
2522
  {
2523
2523
  description:
2524
- "Propose or apply a semantic goal revision under the session's mutation policy. Retain the standing goal unless explicit user direction or meaningful new evidence justifies the declared refinement, adaptation, or replacement. Every rewrite must use the exact expected objective revision and a concise rationale. Root constraints cannot be changed by an agent. A rewrite is not an execution-progress audit fact; use the optional goal_progress tool when such a fact should be recorded.",
2524
+ "Maintain your operational goal as user direction or meaningful new evidence clarifies the intended outcome. Changes apply directly unless the user explicitly configured review_changes; refinement, adaptation, and replacement are audit classifications, not approval gates under the default policy. Use the exact expected objective revision and a concise rationale. Updating a goal grants no additional authority and cannot change root constraints. Use goal_progress for an execution-progress audit fact rather than a goal rewrite.",
2525
2525
  inputSchema: {
2526
2526
  text: goalText.optional(),
2527
2527
  successCriteria: successCriteriaSchema.nullable().optional(),
@@ -5854,9 +5854,14 @@ function registerCapabilityDiscoveryTools(
5854
5854
  // This is a readiness projection, never credential resolution or a new grant.
5855
5855
  const setupProjections = async (items: CapabilityCatalogItem[]) => {
5856
5856
  const availableServerIds = new Set<string>();
5857
+ const availableFirstPartyTools = new Set<string>();
5857
5858
  const acceptedServerIds = new Set<string>();
5858
5859
  let accountSelectionKnown = false;
5859
- if (items.some((item) => item.enabled && item.connectionRef)) {
5860
+ if (
5861
+ items.some(
5862
+ (item) => item.enabled && (item.connectionRef || item.surfaceType === "first_party_fiken"),
5863
+ )
5864
+ ) {
5860
5865
  const claims = exactAgentCommandContext(grant, sessionId);
5861
5866
  const attemptCatalog = await getAttemptToolCatalog(deps.db, {
5862
5867
  accountId: grant.accountId,
@@ -5868,7 +5873,11 @@ function registerCapabilityDiscoveryTools(
5868
5873
  attemptCatalog.turnId === claims.callerTurnId &&
5869
5874
  attemptCatalog.executionGeneration === claims.callerExecutionGeneration
5870
5875
  ) {
5871
- for (const entry of attemptCatalog.entries) availableServerIds.add(entry.identity.serverId);
5876
+ for (const entry of attemptCatalog.entries) {
5877
+ availableServerIds.add(entry.identity.serverId);
5878
+ if (entry.identity.serverId === "opengeni")
5879
+ availableFirstPartyTools.add(entry.identity.toolName);
5880
+ }
5872
5881
  const bindings = await getSessionTurnMcpAccountBindings(
5873
5882
  deps.db,
5874
5883
  grant.workspaceId,
@@ -5890,6 +5899,8 @@ function registerCapabilityDiscoveryTools(
5890
5899
  availableServerIds,
5891
5900
  acceptedServerIds,
5892
5901
  accountSelectionKnown,
5902
+ availableFirstPartyTools,
5903
+ new Set((grant.metadata?.firstPartyMcpTools as string[] | undefined) ?? []),
5893
5904
  ),
5894
5905
  ),
5895
5906
  );
@@ -6015,6 +6026,72 @@ function registerCapabilityDiscoveryTools(
6015
6026
  });
6016
6027
  },
6017
6028
  );
6029
+
6030
+ server.registerTool(
6031
+ "custom_mcp_setup_request",
6032
+ {
6033
+ description:
6034
+ "Show a review card for a remote HTTPS MCP server that is not in the workspace catalog. Use only an endpoint supplied by the user or established by reliable documentation; do not invent a URL. Never include query parameters or secrets in this URL; the human can edit it in the protected setup form. The agent cannot add, enable, or contact the server. Search the catalog first and do not propose an already available integration.",
6035
+ inputSchema: {
6036
+ name: z4.string().trim().min(1).max(256),
6037
+ endpointUrl: z4
6038
+ .string()
6039
+ .url()
6040
+ .max(2048)
6041
+ .refine((url) => {
6042
+ const parsed = new URL(url);
6043
+ return (
6044
+ parsed.protocol === "https:" &&
6045
+ !parsed.username &&
6046
+ !parsed.password &&
6047
+ !parsed.hash &&
6048
+ !parsed.search
6049
+ );
6050
+ }),
6051
+ rationale: z4.string().trim().min(1).max(2000),
6052
+ },
6053
+ },
6054
+ async ({ name, endpointUrl, rationale }) => {
6055
+ await authorize();
6056
+ const current = await catalog();
6057
+ const existing = current.items.find(
6058
+ (item) => item.kind === "mcp" && item.endpointUrl === endpointUrl && !item.stale,
6059
+ );
6060
+ if (existing) {
6061
+ return json({
6062
+ status: "already_in_catalog",
6063
+ capabilityId: existing.id,
6064
+ message: "Use the catalog authorization flow for this server instead.",
6065
+ });
6066
+ }
6067
+ const claims = exactAgentCommandContext(grant, sessionId);
6068
+ const payload = ToolAuthNeededPayload.parse({
6069
+ serverId: "opengeni",
6070
+ toolName: "custom_mcp_setup_request",
6071
+ providerDomain: new URL(endpointUrl).hostname,
6072
+ reason: "missing_connection",
6073
+ setupRequest: { kind: "mcp", name, endpointUrl, rationale },
6074
+ });
6075
+ const appended = await appendAndPublishTurnEventsFenced(
6076
+ deps.db,
6077
+ deps.bus,
6078
+ grant.workspaceId,
6079
+ sessionId,
6080
+ claims.callerTurnId,
6081
+ claims.callerExecutionGeneration,
6082
+ claims.callerAttemptId,
6083
+ [{ type: "tool.auth_needed", payload }],
6084
+ );
6085
+ if (!appended.accepted) {
6086
+ throw new Error("The calling turn was replaced before the setup request committed.");
6087
+ }
6088
+ return json({
6089
+ status: "setup_requested",
6090
+ eventId: appended.events[0]?.id ?? null,
6091
+ message: "The human review card was posted. No server was added or contacted.",
6092
+ });
6093
+ },
6094
+ );
6018
6095
  }
6019
6096
 
6020
6097
  async function capabilitySetupProjection(
@@ -6024,7 +6101,45 @@ async function capabilitySetupProjection(
6024
6101
  availableServerIds: ReadonlySet<string>,
6025
6102
  acceptedServerIds: ReadonlySet<string>,
6026
6103
  accountSelectionKnown: boolean,
6104
+ availableFirstPartyTools: ReadonlySet<string>,
6105
+ selectedFirstPartyTools: ReadonlySet<string>,
6027
6106
  ): Promise<CapabilitySetupProjection> {
6107
+ if (item.surfaceType === "first_party_fiken") {
6108
+ if (!item.enabled || item.metadata.connectionStatus !== "active") {
6109
+ return {
6110
+ status: "authorization_required",
6111
+ action: "connect",
6112
+ detail:
6113
+ item.metadata.connectionStatus === "needs_reauth"
6114
+ ? "The workspace Fiken connection needs reconnection."
6115
+ : "Connect Fiken through the protected setup form.",
6116
+ };
6117
+ }
6118
+ const selected = FIRST_PARTY_MCP_TOOL_NAMES.filter(
6119
+ (name) => name.startsWith("fiken_") && selectedFirstPartyTools.has(name),
6120
+ );
6121
+ if (selected.length === 0) {
6122
+ return {
6123
+ status: "authorization_required",
6124
+ action: "enable",
6125
+ detail:
6126
+ "Fiken is connected, but its tools are not selected for this conversation. Ask the user to add its tools through the setup card, then send a new message.",
6127
+ };
6128
+ }
6129
+ if (selected.some((name) => availableFirstPartyTools.has(name))) {
6130
+ return {
6131
+ status: "ready",
6132
+ action: null,
6133
+ detail: "Fiken is connected and has tools available in this turn.",
6134
+ };
6135
+ }
6136
+ return {
6137
+ status: "unavailable",
6138
+ action: null,
6139
+ detail:
6140
+ "Fiken is connected, but its selected tools are unavailable in this execution. Check tool permissions and setup before retrying; reconnection is not required by this status.",
6141
+ };
6142
+ }
6028
6143
  if (item.id === "api:github-app" || item.surfaceType === "first_party_github") {
6029
6144
  const missing = githubAppMissingSettings(deps.settings);
6030
6145
  if (missing.length > 0) {