@opengeni/api-router 5.4.1 → 5.5.0-canary.37090756480001
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/app.js +1 -1
- package/dist/{chunk-2QCRFD6U.js → chunk-ZQ7PIFGF.js} +719 -356
- package/dist/{chunk-2QCRFD6U.js.map → chunk-ZQ7PIFGF.js.map} +1 -1
- package/dist/claude-subscription-usage.d.ts +21 -0
- package/dist/http/api-error.d.ts +7 -0
- package/dist/index.js +1 -1
- package/dist/integrations/github-lens-connect.d.ts +2 -2
- package/dist/integrations/slack-interactions.d.ts +1 -1
- package/dist/mcp/first-party-tool-permissions.d.ts +8 -0
- package/dist/routes/billing.d.ts +4 -1
- package/dist/routes/client-errors.d.ts +104 -0
- package/dist/routes/insights.d.ts +2 -0
- package/dist/routes/sessions.d.ts +1 -0
- package/package.json +20 -20
- package/src/app.ts +28 -0
- package/src/http/api-error.ts +29 -1
- package/src/http/sse.ts +10 -4
- package/src/mcp/first-party-tool-permissions.ts +5 -0
- package/src/mcp/knowledge-entries.ts +3 -3
- package/src/mcp/server.ts +3 -1
- package/src/model-catalog.ts +5 -0
- package/src/routes/api-integrations.ts +6 -0
- package/src/routes/automations.ts +2 -4
- package/src/routes/billing.ts +118 -21
- package/src/routes/browser-sessions.ts +15 -1
- package/src/routes/client-errors.ts +201 -4
- package/src/routes/computer-sessions.ts +15 -1
- package/src/routes/connections.ts +55 -4
- package/src/routes/insights.ts +19 -1
- package/src/routes/pr-review.ts +2 -3
- package/src/routes/sessions.ts +97 -41
- package/src/routes/workspaces.ts +45 -74
- package/src/workspace-deletion.ts +9 -0
|
@@ -10,9 +10,30 @@ export declare function refreshClaudeSubscriptionUsage(db: Database, settings: S
|
|
|
10
10
|
resetsAt: string | null;
|
|
11
11
|
status: "allowed" | "allowed_warning" | "rejected" | null;
|
|
12
12
|
observedAt: string;
|
|
13
|
+
source?: "provider" | "response_headers" | undefined;
|
|
13
14
|
}[];
|
|
14
15
|
observedAt: string | null;
|
|
15
16
|
source: "provider" | "response_headers" | null;
|
|
16
17
|
refreshStatus: "available" | "not_checked" | "reconnect" | "scope_required" | "unavailable";
|
|
17
18
|
refreshCheckedAt: string | null;
|
|
19
|
+
requestStatus?: {
|
|
20
|
+
status: "allowed" | "allowed_warning" | "rejected" | null;
|
|
21
|
+
resetsAt: string | null;
|
|
22
|
+
representativeClaim: "five_hour" | "overage" | "seven_day" | "seven_day_opus" | "seven_day_overage_included" | "seven_day_sonnet" | null;
|
|
23
|
+
overageStatus: "allowed" | "allowed_warning" | "rejected" | null;
|
|
24
|
+
overageResetsAt: string | null;
|
|
25
|
+
upstreamModelId: string | null;
|
|
26
|
+
observedAt: string;
|
|
27
|
+
source?: "provider" | "response_headers" | undefined;
|
|
28
|
+
} | null | undefined;
|
|
29
|
+
requestRestrictions?: {
|
|
30
|
+
status: "allowed" | "allowed_warning" | "rejected" | null;
|
|
31
|
+
resetsAt: string | null;
|
|
32
|
+
representativeClaim: "five_hour" | "overage" | "seven_day" | "seven_day_opus" | "seven_day_overage_included" | "seven_day_sonnet" | null;
|
|
33
|
+
overageStatus: "allowed" | "allowed_warning" | "rejected" | null;
|
|
34
|
+
overageResetsAt: string | null;
|
|
35
|
+
upstreamModelId: string | null;
|
|
36
|
+
observedAt: string;
|
|
37
|
+
source?: "provider" | "response_headers" | undefined;
|
|
38
|
+
}[] | undefined;
|
|
18
39
|
}>;
|
package/dist/http/api-error.d.ts
CHANGED
|
@@ -31,4 +31,11 @@ export declare function workspaceControlBusyHttpError(error: unknown): ApiHttpEr
|
|
|
31
31
|
* code in `details.code` so clients can branch without parsing messages.
|
|
32
32
|
*/
|
|
33
33
|
export declare function agentConfigHttpError(error: unknown): ApiHttpError | null;
|
|
34
|
+
/**
|
|
35
|
+
* The requested or stored model is not in the live catalog. Rendered as the
|
|
36
|
+
* same 422 `validation_failed` with its historical message, plus
|
|
37
|
+
* `details.code: "model_unavailable"` and the model id so clients can ask for
|
|
38
|
+
* another model rather than offer a retry that cannot succeed.
|
|
39
|
+
*/
|
|
40
|
+
export declare function modelUnavailableHttpError(error: unknown): ApiHttpError | null;
|
|
34
41
|
export {};
|
package/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export declare function requireGitHubLensConnect(deps: ApiRouteDeps): Promise<{
|
|
|
7
7
|
eventTypes: string[];
|
|
8
8
|
configuration: {};
|
|
9
9
|
sessionTemplate: {
|
|
10
|
-
bundledSkillIds?: ("builtin:document-parsing" | "builtin:opengeni-client" | "builtin:opengeni-documents" | "builtin:opengeni-help" | "builtin:opengeni-presentations" | "builtin:opengeni-projects" | "builtin:opengeni-sites" | "builtin:opengeni-skills" | "builtin:opengeni-spreadsheets" | "builtin:opengeni-video-generation" | "builtin:opengeni-visualize")[] | undefined;
|
|
10
|
+
bundledSkillIds?: ("builtin:document-parsing" | "builtin:opengeni-client" | "builtin:opengeni-documents" | "builtin:opengeni-help" | "builtin:opengeni-presentations" | "builtin:opengeni-projects" | "builtin:opengeni-schedules" | "builtin:opengeni-sites" | "builtin:opengeni-skills" | "builtin:opengeni-spreadsheets" | "builtin:opengeni-video-generation" | "builtin:opengeni-visualize")[] | undefined;
|
|
11
11
|
prompt: string;
|
|
12
12
|
instructions: string | null;
|
|
13
13
|
resources: ({
|
|
@@ -47,7 +47,7 @@ export declare function requireGitHubLensConnect(deps: ApiRouteDeps): Promise<{
|
|
|
47
47
|
eager?: boolean | undefined;
|
|
48
48
|
optional?: boolean | undefined;
|
|
49
49
|
}[];
|
|
50
|
-
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_model" | "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_prepare_message" | "slack_bot_search" | "slack_bot_send_prepared_message" | "slack_bot_thread_replies" | "slack_bot_upload_file" | "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
|
+
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_download_save" | "browser_downloads" | "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_model" | "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_prepare_message" | "slack_bot_search" | "slack_bot_send_prepared_message" | "slack_bot_thread_replies" | "slack_bot_upload_file" | "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")[];
|
|
51
51
|
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" | "usage_allowances:manage" | "variable-sets:attach" | "variable-sets:list" | "variable-sets:manage" | "variable-sets:read" | "variable-sets:use" | "variable-sets:write" | "workspace:admin" | "workspace:create" | "workspace:read")[];
|
|
52
52
|
model: string | null;
|
|
53
53
|
reasoningEffort: "high" | "low" | "max" | "medium" | "minimal" | "none" | "xhigh" | null;
|
|
@@ -21,7 +21,7 @@ export declare const SLACK_SESSION_INSTRUCTIONS: string;
|
|
|
21
21
|
* tools are explicit-only, so freeze that narrow selection at session creation;
|
|
22
22
|
* ordinary interaction messages remain owned by the durable delivery pump.
|
|
23
23
|
*/
|
|
24
|
-
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_model" | "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_prepare_message" | "slack_bot_search" | "slack_bot_send_prepared_message" | "slack_bot_thread_replies" | "slack_bot_upload_file" | "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")[];
|
|
24
|
+
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_download_save" | "browser_downloads" | "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_model" | "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_prepare_message" | "slack_bot_search" | "slack_bot_send_prepared_message" | "slack_bot_thread_replies" | "slack_bot_upload_file" | "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")[];
|
|
25
25
|
/**
|
|
26
26
|
* The workspace's default first-party selection (or the deployment default)
|
|
27
27
|
* plus the bounded Slack task tools. These are added whatever the base is, then
|
|
@@ -294,6 +294,14 @@ export declare const FIRST_PARTY_TOOL_AUTHORIZATION: {
|
|
|
294
294
|
sessionRequired: true;
|
|
295
295
|
allOf: "sessions:read"[];
|
|
296
296
|
};
|
|
297
|
+
browser_downloads: {
|
|
298
|
+
sessionRequired: true;
|
|
299
|
+
allOf: "sessions:read"[];
|
|
300
|
+
};
|
|
301
|
+
browser_download_save: {
|
|
302
|
+
sessionRequired: true;
|
|
303
|
+
allOf: ("files:upload" | "sessions:control")[];
|
|
304
|
+
};
|
|
297
305
|
browser_auth: {
|
|
298
306
|
sessionRequired: true;
|
|
299
307
|
allOf: "sessions:control"[];
|
package/dist/routes/billing.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export declare function stripeCheckoutSessionCreateParams(input: {
|
|
|
9
9
|
amountMicros: number;
|
|
10
10
|
creditsProductId?: string | undefined;
|
|
11
11
|
publicBaseUrl?: string | undefined;
|
|
12
|
+
webBaseUrl?: string | undefined;
|
|
12
13
|
successUrl?: string | undefined;
|
|
13
14
|
cancelUrl?: string | undefined;
|
|
14
15
|
idempotencyKey: string;
|
|
@@ -16,6 +17,7 @@ export declare function stripeCheckoutSessionCreateParams(input: {
|
|
|
16
17
|
export declare function stripeBillingPortalSessionCreateParams(input: {
|
|
17
18
|
customerId: string;
|
|
18
19
|
publicBaseUrl?: string | undefined;
|
|
20
|
+
webBaseUrl?: string | undefined;
|
|
19
21
|
returnUrl?: string | undefined;
|
|
20
22
|
}): Stripe.BillingPortal.SessionCreateParams;
|
|
21
23
|
export type StripeCheckoutCreditDecision = {
|
|
@@ -31,7 +33,8 @@ export type StripeCheckoutCreditDecision = {
|
|
|
31
33
|
* Sessions created outside OpenGeni on the same Stripe account carry no
|
|
32
34
|
* `opengeni_` metadata and are acknowledged without effect. An OpenGeni
|
|
33
35
|
* session with malformed credit metadata still throws so the failure stays
|
|
34
|
-
* visible. Credits are granted
|
|
36
|
+
* visible. Credits are granted once Stripe reports the payment `paid` or a
|
|
37
|
+
* completed checkout fully covered by a coupon:
|
|
35
38
|
* on `checkout.session.completed` for immediate methods, or on
|
|
36
39
|
* `checkout.session.async_payment_succeeded` for delayed methods, whose
|
|
37
40
|
* completion event arrives `unpaid`. Both events carry the same session
|
|
@@ -16,7 +16,106 @@ export declare const ClientErrorReport: z.ZodObject<{
|
|
|
16
16
|
revision: z.ZodString;
|
|
17
17
|
}, z.core.$strict>;
|
|
18
18
|
export type ClientErrorReport = z.infer<typeof ClientErrorReport>;
|
|
19
|
+
export declare const ClientSignalReport: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
20
|
+
signal: z.ZodLiteral<"request_failure">;
|
|
21
|
+
action: z.ZodEnum<{
|
|
22
|
+
checkout_start: "checkout_start";
|
|
23
|
+
composer_submit: "composer_submit";
|
|
24
|
+
connect_integration: "connect_integration";
|
|
25
|
+
connect_model: "connect_model";
|
|
26
|
+
create_session: "create_session";
|
|
27
|
+
retry_turn: "retry_turn";
|
|
28
|
+
send_message: "send_message";
|
|
29
|
+
steer_message: "steer_message";
|
|
30
|
+
}>;
|
|
31
|
+
reason: z.ZodEnum<{
|
|
32
|
+
network: "network";
|
|
33
|
+
offline: "offline";
|
|
34
|
+
timeout: "timeout";
|
|
35
|
+
}>;
|
|
36
|
+
route: z.ZodString;
|
|
37
|
+
revision: z.ZodString;
|
|
38
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
39
|
+
signal: z.ZodLiteral<"stream">;
|
|
40
|
+
stream: z.ZodEnum<{
|
|
41
|
+
session: "session";
|
|
42
|
+
workspace: "workspace";
|
|
43
|
+
}>;
|
|
44
|
+
event: z.ZodEnum<{
|
|
45
|
+
long_disconnect: "long_disconnect";
|
|
46
|
+
reconnect: "reconnect";
|
|
47
|
+
reconnect_exhausted: "reconnect_exhausted";
|
|
48
|
+
}>;
|
|
49
|
+
route: z.ZodString;
|
|
50
|
+
revision: z.ZodString;
|
|
51
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
52
|
+
signal: z.ZodLiteral<"web_vital">;
|
|
53
|
+
metric: z.ZodEnum<{
|
|
54
|
+
cls: "cls";
|
|
55
|
+
inp: "inp";
|
|
56
|
+
lcp: "lcp";
|
|
57
|
+
ttfb: "ttfb";
|
|
58
|
+
}>;
|
|
59
|
+
page: z.ZodEnum<{
|
|
60
|
+
"account-auth": "account-auth";
|
|
61
|
+
agents: "agents";
|
|
62
|
+
artifacts: "artifacts";
|
|
63
|
+
capabilities: "capabilities";
|
|
64
|
+
"checkout-return": "checkout-return";
|
|
65
|
+
device: "device";
|
|
66
|
+
documents: "documents";
|
|
67
|
+
environments: "environments";
|
|
68
|
+
files: "files";
|
|
69
|
+
home: "home";
|
|
70
|
+
"identity-link": "identity-link";
|
|
71
|
+
insights: "insights";
|
|
72
|
+
"integration-return": "integration-return";
|
|
73
|
+
machines: "machines";
|
|
74
|
+
memory: "memory";
|
|
75
|
+
organization: "organization";
|
|
76
|
+
other: "other";
|
|
77
|
+
"personal-security": "personal-security";
|
|
78
|
+
plugins: "plugins";
|
|
79
|
+
priority: "priority";
|
|
80
|
+
"reset-password": "reset-password";
|
|
81
|
+
rigs: "rigs";
|
|
82
|
+
schedules: "schedules";
|
|
83
|
+
"session-link": "session-link";
|
|
84
|
+
sessions: "sessions";
|
|
85
|
+
settings: "settings";
|
|
86
|
+
"setup-account": "setup-account";
|
|
87
|
+
state: "state";
|
|
88
|
+
"variable-sets": "variable-sets";
|
|
89
|
+
}>;
|
|
90
|
+
value: z.ZodNumber;
|
|
91
|
+
revision: z.ZodString;
|
|
92
|
+
}, z.core.$strict>], "signal">;
|
|
93
|
+
export type ClientSignalReport = z.infer<typeof ClientSignalReport>;
|
|
94
|
+
export type ClientBeaconReport = ClientErrorReport | ClientSignalReport;
|
|
95
|
+
/**
|
|
96
|
+
* Bucket bounds cover the published good/poor thresholds of every metric:
|
|
97
|
+
* CLS 0.1/0.25, INP 0.2/0.5 s, TTFB 0.8/1.8 s, LCP 2.5/4 s.
|
|
98
|
+
*/
|
|
99
|
+
export declare const CLIENT_WEB_VITAL_BUCKETS: number[];
|
|
19
100
|
export type ClientErrorAdmission = KeyedAdmission<ClientErrorKind>;
|
|
101
|
+
/** Keyed by `<signal>:<closed dimension>`, a finite set of buckets. */
|
|
102
|
+
export type ClientSignalAdmission = KeyedAdmission<string>;
|
|
103
|
+
/** Same bounds as the error kinds: one bucket per closed signal key. */
|
|
104
|
+
export declare function createClientSignalAdmission(options?: {
|
|
105
|
+
capacity?: number;
|
|
106
|
+
refillPerSecond?: number;
|
|
107
|
+
now?: () => number;
|
|
108
|
+
}): ClientSignalAdmission;
|
|
109
|
+
/**
|
|
110
|
+
* Web vitals arrive from every page load rather than only on failure, so they
|
|
111
|
+
* get a much larger dedicated bucket per metric (burst 1,200, then 20 a
|
|
112
|
+
* second per process). The browser samples vitals before sending.
|
|
113
|
+
*/
|
|
114
|
+
export declare function createClientWebVitalAdmission(options?: {
|
|
115
|
+
capacity?: number;
|
|
116
|
+
refillPerSecond?: number;
|
|
117
|
+
now?: () => number;
|
|
118
|
+
}): ClientSignalAdmission;
|
|
20
119
|
/**
|
|
21
120
|
* One token bucket per closed kind bounds counter inflation and log volume
|
|
22
121
|
* from any caller, including an anonymous one, without per-client state.
|
|
@@ -27,6 +126,9 @@ export declare function createClientErrorAdmission(options?: {
|
|
|
27
126
|
now?: () => number;
|
|
28
127
|
}): ClientErrorAdmission;
|
|
29
128
|
export declare function parseClientErrorReport(body: string | null): ClientErrorReport | null;
|
|
129
|
+
/** Parse any accepted beacon body: an error report or a closed signal report. */
|
|
130
|
+
export declare function parseClientBeaconReport(body: string | null): ClientBeaconReport | null;
|
|
131
|
+
export declare function isClientSignalReport(report: ClientBeaconReport): report is ClientSignalReport;
|
|
30
132
|
/**
|
|
31
133
|
* The exact beacon request. The app-wide request-body limit skips it because
|
|
32
134
|
* the route enforces its own 512-byte limit on the streamed body; the generic
|
|
@@ -38,4 +140,6 @@ export declare function registerClientErrorRoutes(app: Hono, deps: {
|
|
|
38
140
|
observability: Observability;
|
|
39
141
|
settings: Pick<Settings, "corsAllowOriginRegex" | "publicBaseUrl" | "webBaseUrl">;
|
|
40
142
|
admission?: ClientErrorAdmission;
|
|
143
|
+
signalAdmission?: ClientSignalAdmission;
|
|
144
|
+
webVitalAdmission?: ClientSignalAdmission;
|
|
41
145
|
}): void;
|
|
@@ -25,6 +25,8 @@ export declare function workspaceInsightsCoalesceKey(input: {
|
|
|
25
25
|
range: string;
|
|
26
26
|
provider: string | null;
|
|
27
27
|
model: string | null;
|
|
28
|
+
rootSessionId?: string | null;
|
|
29
|
+
sessionId?: string | null;
|
|
28
30
|
rlsActor: string | null;
|
|
29
31
|
}): string;
|
|
30
32
|
export declare function registerInsightsRoutes(app: Hono, deps: ApiRouteDeps): void;
|
|
@@ -20,6 +20,7 @@ export declare function sessionListQuery(query: Record<string, string>, allowCur
|
|
|
20
20
|
cursor: ReturnType<typeof decodeSessionListCursor> | undefined;
|
|
21
21
|
search: string | undefined;
|
|
22
22
|
pinsOnly: boolean;
|
|
23
|
+
includePinned: boolean;
|
|
23
24
|
archivedOnly: boolean;
|
|
24
25
|
sortBy: "updatedAt" | "createdAt" | "name" | undefined;
|
|
25
26
|
archiveStatus: "active" | "archived" | "all" | undefined;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opengeni/api-router",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.5.0-canary.37090756480001",
|
|
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,25 +43,25 @@
|
|
|
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.1",
|
|
47
|
-
"@opengeni/artifact-tool": "^0.3.
|
|
48
|
-
"@opengeni/capabilities": "^0.3.
|
|
49
|
-
"@opengeni/codemode": "^0.
|
|
50
|
-
"@opengeni/codex": "^0.2.
|
|
51
|
-
"@opengeni/config": "^3.
|
|
52
|
-
"@opengeni/contracts": "^5.
|
|
53
|
-
"@opengeni/core": "^5.
|
|
54
|
-
"@opengeni/db": "^6.
|
|
55
|
-
"@opengeni/documents": "^0.8.
|
|
56
|
-
"@opengeni/events": "^0.4.
|
|
57
|
-
"@opengeni/github": "^0.8.
|
|
58
|
-
"@opengeni/interaction": "^0.4.
|
|
59
|
-
"@opengeni/network": "^0.3.1",
|
|
60
|
-
"@opengeni/observability": "^0.8.
|
|
61
|
-
"@opengeni/runtime": "^4.
|
|
62
|
-
"@opengeni/storage": "^0.2.
|
|
63
|
-
"@opengeni/tool-gateway": "^0.1.
|
|
64
|
-
"@opengeni/xai-subscription": "^0.1.5",
|
|
46
|
+
"@opengeni/agent-proto": "^0.6.1-canary.37090756480001",
|
|
47
|
+
"@opengeni/artifact-tool": "^0.3.38-canary.37090756480001",
|
|
48
|
+
"@opengeni/capabilities": "^0.3.6-canary.37090756480001",
|
|
49
|
+
"@opengeni/codemode": "^0.7.0-canary.37090756480001",
|
|
50
|
+
"@opengeni/codex": "^0.2.32-canary.37090756480001",
|
|
51
|
+
"@opengeni/config": "^3.3.0-canary.37090756480001",
|
|
52
|
+
"@opengeni/contracts": "^5.7.0-canary.37090756480001",
|
|
53
|
+
"@opengeni/core": "^5.2.0-canary.37090756480001",
|
|
54
|
+
"@opengeni/db": "^6.6.0-canary.37090756480001",
|
|
55
|
+
"@opengeni/documents": "^0.8.41-canary.37090756480001",
|
|
56
|
+
"@opengeni/events": "^0.4.39-canary.37090756480001",
|
|
57
|
+
"@opengeni/github": "^0.8.3-canary.37090756480001",
|
|
58
|
+
"@opengeni/interaction": "^0.4.46-canary.37090756480001",
|
|
59
|
+
"@opengeni/network": "^0.3.1-canary.37090756480001",
|
|
60
|
+
"@opengeni/observability": "^0.8.38-canary.37090756480001",
|
|
61
|
+
"@opengeni/runtime": "^4.7.0-canary.37090756480001",
|
|
62
|
+
"@opengeni/storage": "^0.2.139-canary.37090756480001",
|
|
63
|
+
"@opengeni/tool-gateway": "^0.1.19-canary.37090756480001",
|
|
64
|
+
"@opengeni/xai-subscription": "^0.1.5-canary.37090756480001",
|
|
65
65
|
"@temporalio/client": "^1.17.0",
|
|
66
66
|
"better-auth": "^1.6.14",
|
|
67
67
|
"hono": "^4.12.18",
|
package/src/app.ts
CHANGED
|
@@ -23,6 +23,7 @@ import {
|
|
|
23
23
|
configuredAllowedReasoningEfforts,
|
|
24
24
|
resolveFirstPartyMcpToolPolicy,
|
|
25
25
|
resolveVoiceInputProviderRegistry,
|
|
26
|
+
UnsupportedLatencyModeError,
|
|
26
27
|
type Settings,
|
|
27
28
|
} from "@opengeni/config";
|
|
28
29
|
import {
|
|
@@ -87,6 +88,7 @@ import {
|
|
|
87
88
|
ApiHttpError,
|
|
88
89
|
agentConfigHttpError,
|
|
89
90
|
allowanceExhaustedHttpError,
|
|
91
|
+
modelUnavailableHttpError,
|
|
90
92
|
workspaceControlBusyHttpError,
|
|
91
93
|
} from "./http/api-error";
|
|
92
94
|
import {
|
|
@@ -1257,6 +1259,8 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
1257
1259
|
auth: clientAuthConfig(deps.settings),
|
|
1258
1260
|
documentationUrl: deps.settings.documentationUrl,
|
|
1259
1261
|
analytics: clientAnalyticsConfig(deps.settings),
|
|
1262
|
+
legal: clientLegalConfig(deps.settings),
|
|
1263
|
+
...(deps.settings.supportEmail ? { supportEmail: deps.settings.supportEmail } : {}),
|
|
1260
1264
|
// Channel-A structured services (P4.4) ride exec/readFile/createEditor,
|
|
1261
1265
|
// available on every real backend; `none` has no box so they are all off.
|
|
1262
1266
|
// Per-session availability is still negotiated on /stream-capabilities.
|
|
@@ -1682,6 +1686,21 @@ export function createAppComposition(deps: AppDependencies): {
|
|
|
1682
1686
|
: (allowanceExhaustedHttpError(rawError) ??
|
|
1683
1687
|
workspaceControlBusyHttpError(rawError) ??
|
|
1684
1688
|
agentConfigHttpError(rawError) ??
|
|
1689
|
+
modelUnavailableHttpError(rawError) ??
|
|
1690
|
+
(rawError instanceof UnsupportedLatencyModeError
|
|
1691
|
+
? new ApiHttpError(422, {
|
|
1692
|
+
code: "validation_failed",
|
|
1693
|
+
message: rawError.message,
|
|
1694
|
+
retryable: false,
|
|
1695
|
+
outcomeUnknown: false,
|
|
1696
|
+
details: {
|
|
1697
|
+
code: rawError.code,
|
|
1698
|
+
modelId: rawError.modelId,
|
|
1699
|
+
latencyMode: rawError.latencyMode,
|
|
1700
|
+
allowedLatencyModes: [...rawError.allowedLatencyModes],
|
|
1701
|
+
},
|
|
1702
|
+
})
|
|
1703
|
+
: null) ??
|
|
1685
1704
|
requestBodyValidationHttpError(rawError) ??
|
|
1686
1705
|
invalidPathIdentifierHttpError(rawError, new URL(c.req.url).pathname) ??
|
|
1687
1706
|
rawError);
|
|
@@ -2088,6 +2107,15 @@ function clientAnalyticsConfig(settings: AppDependencies["settings"]) {
|
|
|
2088
2107
|
};
|
|
2089
2108
|
}
|
|
2090
2109
|
|
|
2110
|
+
function clientLegalConfig(settings: AppDependencies["settings"]) {
|
|
2111
|
+
return {
|
|
2112
|
+
...(settings.legalPrivacyPolicyUrl ? { privacyPolicyUrl: settings.legalPrivacyPolicyUrl } : {}),
|
|
2113
|
+
...(settings.legalTermsOfServiceUrl
|
|
2114
|
+
? { termsOfServiceUrl: settings.legalTermsOfServiceUrl }
|
|
2115
|
+
: {}),
|
|
2116
|
+
};
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2091
2119
|
function structuredServicesHint(backend: string): {
|
|
2092
2120
|
fileSystem: boolean;
|
|
2093
2121
|
git: boolean;
|
package/src/http/api-error.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
AgentConfigError,
|
|
3
|
+
AllowanceExhaustedRefusal,
|
|
4
|
+
ModelUnavailableError,
|
|
5
|
+
type ErrorCode,
|
|
6
|
+
} from "@opengeni/contracts";
|
|
2
7
|
import { WorkspaceControlBusyError } from "@opengeni/db";
|
|
3
8
|
import type { ContentfulStatusCode } from "hono/utils/http-status";
|
|
4
9
|
import { HTTPException } from "hono/http-exception";
|
|
@@ -94,3 +99,26 @@ export function agentConfigHttpError(error: unknown): ApiHttpError | null {
|
|
|
94
99
|
},
|
|
95
100
|
});
|
|
96
101
|
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* The requested or stored model is not in the live catalog. Rendered as the
|
|
105
|
+
* same 422 `validation_failed` with its historical message, plus
|
|
106
|
+
* `details.code: "model_unavailable"` and the model id so clients can ask for
|
|
107
|
+
* another model rather than offer a retry that cannot succeed.
|
|
108
|
+
*/
|
|
109
|
+
export function modelUnavailableHttpError(error: unknown): ApiHttpError | null {
|
|
110
|
+
const cause =
|
|
111
|
+
error instanceof ModelUnavailableError
|
|
112
|
+
? error
|
|
113
|
+
: error instanceof HTTPException && error.cause instanceof ModelUnavailableError
|
|
114
|
+
? error.cause
|
|
115
|
+
: null;
|
|
116
|
+
if (!cause) return null;
|
|
117
|
+
return new ApiHttpError(422, {
|
|
118
|
+
code: "validation_failed",
|
|
119
|
+
message: cause.message,
|
|
120
|
+
retryable: false,
|
|
121
|
+
outcomeUnknown: false,
|
|
122
|
+
details: { code: cause.code, modelId: cause.modelId },
|
|
123
|
+
});
|
|
124
|
+
}
|
package/src/http/sse.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
} from "@opengeni/contracts";
|
|
6
6
|
import {
|
|
7
7
|
getWorkspaceInteractionRevisionState,
|
|
8
|
-
|
|
8
|
+
listSessionEventPage,
|
|
9
9
|
listWorkspaceControlEvents,
|
|
10
10
|
type Database,
|
|
11
11
|
} from "@opengeni/db";
|
|
@@ -21,6 +21,7 @@ import type { Observability } from "@opengeni/observability";
|
|
|
21
21
|
import { MANAGED_AUTH_ACTOR_EPOCH_HEADER } from "@opengeni/core/managed-auth-session-sets";
|
|
22
22
|
|
|
23
23
|
const SESSION_REPLAY_PAGE_SIZE = 100;
|
|
24
|
+
const SESSION_REPLAY_PAGE_MAX_BYTES = 8 * 1024 * 1024;
|
|
24
25
|
const WORKSPACE_CONTROL_REPLAY_PAGE_SIZE = 100;
|
|
25
26
|
export const SSE_QUEUED_FRAME_MAX_COUNT = 1;
|
|
26
27
|
export const SSE_WRITE_STALL_TIMEOUT_MS = 30_000;
|
|
@@ -277,9 +278,10 @@ export async function sseSessionStream(
|
|
|
277
278
|
options: SessionSseDeliveryOptions = {},
|
|
278
279
|
): Promise<Response> {
|
|
279
280
|
if (isHttp1BrowserBatch(options)) {
|
|
280
|
-
const events = await
|
|
281
|
+
const { events } = await listSessionEventPage(db, workspaceId, sessionId, {
|
|
281
282
|
after,
|
|
282
283
|
limit: SESSION_REPLAY_PAGE_SIZE,
|
|
284
|
+
maxBytes: options.finiteResponseMaxBytes ?? HTTP1_BROWSER_SSE_BATCH_MAX_BYTES,
|
|
283
285
|
});
|
|
284
286
|
await options.reauthorize?.();
|
|
285
287
|
const compactProjection = coalesceSessionEventDeltasWithCoverage(events);
|
|
@@ -353,10 +355,12 @@ export async function sseSessionStream(
|
|
|
353
355
|
targetSequence === undefined
|
|
354
356
|
? SESSION_REPLAY_PAGE_SIZE
|
|
355
357
|
: Math.min(SESSION_REPLAY_PAGE_SIZE, targetSequence - lastSent);
|
|
356
|
-
const
|
|
358
|
+
const replayPage = await listSessionEventPage(db, workspaceId, sessionId, {
|
|
357
359
|
after: lastSent,
|
|
358
360
|
limit,
|
|
361
|
+
maxBytes: SESSION_REPLAY_PAGE_MAX_BYTES,
|
|
359
362
|
});
|
|
363
|
+
const page = replayPage.events;
|
|
360
364
|
const eligible =
|
|
361
365
|
targetSequence === undefined
|
|
362
366
|
? page
|
|
@@ -382,8 +386,10 @@ export async function sseSessionStream(
|
|
|
382
386
|
throw new Error(`Session event replay made no progress after sequence ${lastSent}`);
|
|
383
387
|
}
|
|
384
388
|
if (targetSequence !== undefined && lastSent >= targetSequence) return;
|
|
389
|
+
if (targetSequence === undefined && !replayPage.hasMore) return;
|
|
385
390
|
// A byte-selected page may contain fewer rows than requested, especially
|
|
386
|
-
// when one large message travels alone.
|
|
391
|
+
// when one large message travels alone. Use explicit continuation rather
|
|
392
|
+
// than page length; live publication covers appends after the snapshot.
|
|
387
393
|
}
|
|
388
394
|
};
|
|
389
395
|
let durableDeliveryTail = Promise.resolve();
|
|
@@ -123,6 +123,11 @@ export const FIRST_PARTY_TOOL_AUTHORIZATION = {
|
|
|
123
123
|
browser_act: { sessionRequired: true, allOf: ["sessions:control"] },
|
|
124
124
|
browser_clipboard: { sessionRequired: true, allOf: ["sessions:read"] },
|
|
125
125
|
browser_debug: { sessionRequired: true, allOf: ["sessions:read"] },
|
|
126
|
+
browser_downloads: { sessionRequired: true, allOf: ["sessions:read"] },
|
|
127
|
+
browser_download_save: {
|
|
128
|
+
sessionRequired: true,
|
|
129
|
+
allOf: ["sessions:control", "files:upload"],
|
|
130
|
+
},
|
|
126
131
|
browser_auth: { sessionRequired: true, allOf: ["sessions:control"] },
|
|
127
132
|
interaction_request_human: {
|
|
128
133
|
sessionRequired: true,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
AgentInstructionSaveRequest,
|
|
3
|
+
WORKSPACE_INSTRUCTION_POLICY_CONTENT_MAX_CHARS,
|
|
3
4
|
WorkspaceInstructionPolicyTarget,
|
|
4
5
|
KnowledgeEntryListRequest,
|
|
5
6
|
KnowledgeSavePreparationRequest,
|
|
@@ -92,7 +93,7 @@ export function registerKnowledgeEntryTools(
|
|
|
92
93
|
: state === "42501"
|
|
93
94
|
? "The instruction change is unavailable in this task's scope or Agent learning policy. Off disables authoring, not the task. Do not ask for approval to continue."
|
|
94
95
|
: state === "22023" || state === "23514"
|
|
95
|
-
?
|
|
96
|
+
? `Invalid instruction change. Read the current instruction, use append for a new rule, or edit with one localized exact oldText match to update or remove text. Agents cannot replace the complete instruction. Each supplied text and the resulting instruction must stay within ${WORKSPACE_INSTRUCTION_POLICY_CONTENT_MAX_CHARS} characters, the same limit as the human editor.`
|
|
96
97
|
: "Workspace instructions are temporarily unavailable. Retry the same operation ID only if the prior change may have succeeded."
|
|
97
98
|
: state === "40001"
|
|
98
99
|
? "This entry changed. Read its current revision and retry your correction with the current version."
|
|
@@ -304,8 +305,7 @@ export function registerKnowledgeEntryTools(
|
|
|
304
305
|
server.registerTool(
|
|
305
306
|
"instruction_policy_save",
|
|
306
307
|
{
|
|
307
|
-
description:
|
|
308
|
-
"Change a concise standing workspace instruction through this task's Agent learning policy. Use for short always-on behavior such as 'Keep replies concise; expand when asked', within the intended workspace scope; active instructions enter applicable prompts without Knowledge retrieval. Read the current policy first and submit its exact baseline. Use editMode=append by default for a new rule; it preserves the current content and adds one blank-line separator. Use edit with a localized oldText that occurs exactly once and newText to update or remove only that passage. Agents cannot replace the complete instruction; direct the user to the manual workspace-instruction editor for a whole-policy rewrite. Each supplied text and the resulting instruction are limited to 600 characters. Facts and incidents belong in knowledge_save and reusable procedures or context-specific preferences in skill_save. Preserve personal scope rather than creating a workspace-wide rule. Review first saves an inactive revision and returns pending; continue the task without an approval question. Report the actual receipt; Knowledge is not a workaround for Off, pending review, unavailable scope or size limits.",
|
|
308
|
+
description: `Change a concise standing workspace instruction through this task's Agent learning policy. Use for short always-on behavior such as 'Keep replies concise; expand when asked', within the intended workspace scope; active instructions enter applicable prompts without Knowledge retrieval. Read the current policy first and submit its exact baseline. Use editMode=append by default for a new rule; it preserves the current content and adds one blank-line separator. Use edit with a localized oldText that occurs exactly once and newText to update or remove only that passage. Agents cannot replace the complete instruction; direct the user to the manual workspace-instruction editor for a whole-policy rewrite. Each supplied text and the resulting instruction are limited to ${WORKSPACE_INSTRUCTION_POLICY_CONTENT_MAX_CHARS} characters, the same limit as the human editor. Facts and incidents belong in knowledge_save and reusable procedures or context-specific preferences in skill_save. Preserve personal scope rather than creating a workspace-wide rule. Review first saves an inactive revision and returns pending; continue the task without an approval question. Report the actual receipt; Knowledge is not a workaround for Off, pending review, unavailable scope or size limits.`,
|
|
309
309
|
inputSchema: AgentInstructionSaveRequest.shape,
|
|
310
310
|
},
|
|
311
311
|
(input) => run((context) => saveAgentInstruction(deps.db, context, input), "instruction"),
|
package/src/mcp/server.ts
CHANGED
|
@@ -5314,7 +5314,9 @@ function registerWorkspaceOrchestrationTools(
|
|
|
5314
5314
|
latencyMode: z4
|
|
5315
5315
|
.enum(["standard", "priority", "fast"])
|
|
5316
5316
|
.optional()
|
|
5317
|
-
.describe(
|
|
5317
|
+
.describe(
|
|
5318
|
+
"Omit for standard latency, even when model and reasoning are inherited. Fast or priority must be selected explicitly and supported by the model.",
|
|
5319
|
+
),
|
|
5318
5320
|
sandboxBackend: z4.string().optional(),
|
|
5319
5321
|
// Model-only structural coupling: workingDir cannot exist without a
|
|
5320
5322
|
// targetSandboxId because both live inside one optional object. The
|
package/src/model-catalog.ts
CHANGED
|
@@ -25,12 +25,16 @@ export {
|
|
|
25
25
|
export function projectClientModel(model: ConfiguredModel): ClientModel {
|
|
26
26
|
const anonymousProvider =
|
|
27
27
|
model.credentialSource.kind === "deployment" && model.credentialSource.mechanism === "none";
|
|
28
|
+
const directProvider =
|
|
29
|
+
model.providerId.startsWith("workspace-openai-") ||
|
|
30
|
+
model.providerId.startsWith("workspace-azure-openai-");
|
|
28
31
|
const organizationProvider = model.credentialSource.kind === "organization_connection";
|
|
29
32
|
// Keep the established closed `source` enum compatible for older same-major
|
|
30
33
|
// clients. OpenRouter remains truthfully identified by its public provider
|
|
31
34
|
// id/label and billing metadata; omitting this optional legacy grouping field
|
|
32
35
|
// lets tolerant older contracts parse the additive provider.
|
|
33
36
|
const source =
|
|
37
|
+
directProvider ||
|
|
34
38
|
organizationProvider ||
|
|
35
39
|
model.providerId === "workspace-anthropic" ||
|
|
36
40
|
model.providerId === "workspace-claude-subscription" ||
|
|
@@ -47,6 +51,7 @@ export function projectClientModel(model: ConfiguredModel): ClientModel {
|
|
|
47
51
|
? undefined
|
|
48
52
|
: "opengeni";
|
|
49
53
|
const publicProvider =
|
|
54
|
+
directProvider ||
|
|
50
55
|
anonymousProvider ||
|
|
51
56
|
organizationProvider ||
|
|
52
57
|
model.providerId === "workspace-anthropic" ||
|
|
@@ -27,6 +27,7 @@ import {
|
|
|
27
27
|
} from "@opengeni/core";
|
|
28
28
|
import { withOrganizationIntegrationPolicyFence } from "@opengeni/db/organization-integration-policy";
|
|
29
29
|
import {
|
|
30
|
+
ApiIntegrationConnectionReferenceError,
|
|
30
31
|
ApiIntegrationInstallationVersionConflictError,
|
|
31
32
|
buildConnectionTokenResolver,
|
|
32
33
|
getApiIntegrationUninstallPreview,
|
|
@@ -332,6 +333,11 @@ export function registerApiIntegrationRoutes(
|
|
|
332
333
|
payload.expectedInstanceVersion === undefined ? 201 : 200,
|
|
333
334
|
);
|
|
334
335
|
} catch (error) {
|
|
336
|
+
if (error instanceof ApiIntegrationConnectionReferenceError) {
|
|
337
|
+
throw new HTTPException(error.reason === "not_found" ? 404 : 422, {
|
|
338
|
+
message: error.reason === "not_found" ? "connection not found" : error.message,
|
|
339
|
+
});
|
|
340
|
+
}
|
|
335
341
|
if (
|
|
336
342
|
error instanceof IntegrationFacetBindingVersionConflictError ||
|
|
337
343
|
error instanceof IntegrationFacetBindingVersionRequiredError ||
|