@opengeni/db 1.0.1 → 3.1.0-canary.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/attached-browser-devices.d.ts +7 -0
- package/dist/automations.d.ts +154 -0
- package/dist/canonical-human-identities.js +3 -3
- package/dist/capability-integrations.d.ts +13 -0
- package/dist/child-lifecycle-notices.d.ts +68 -0
- package/dist/{chunk-LTG3S6ZY.js → chunk-EULAN2NP.js} +2 -2
- package/dist/{chunk-CUPM3FGB.js → chunk-NJVZPWXY.js} +3 -3
- package/dist/{chunk-4SR4HKKA.js → chunk-NMUBV7Z5.js} +19 -11
- package/dist/chunk-NMUBV7Z5.js.map +1 -0
- package/dist/chunk-OF5OBB76.js +4457 -0
- package/dist/chunk-OF5OBB76.js.map +1 -0
- package/dist/{chunk-6ZYKCRFO.js → chunk-PR2WMLOQ.js} +7580 -4417
- package/dist/chunk-PR2WMLOQ.js.map +1 -0
- package/dist/{chunk-ZWREYEWA.js → chunk-SCPUJS53.js} +41 -4
- package/dist/chunk-SCPUJS53.js.map +1 -0
- package/dist/{chunk-SK7YYHBI.js → chunk-SIBYBA2D.js} +46 -1
- package/dist/chunk-SIBYBA2D.js.map +1 -0
- package/dist/chunk-TIKF3KTI.js +383 -0
- package/dist/chunk-TIKF3KTI.js.map +1 -0
- package/dist/chunk-ZZ5LJEFX.js +516 -0
- package/dist/chunk-ZZ5LJEFX.js.map +1 -0
- package/dist/codemode-operations.d.ts +1 -6
- package/dist/company-brain-context-selection-schema.d.ts +705 -0
- package/dist/company-brain-context-selection.d.ts +94 -0
- package/dist/company-brain-governed-writes.d.ts +24 -0
- package/dist/company-brain.d.ts +55 -0
- package/dist/company-profile-agent-admin.d.ts +15 -0
- package/dist/company-profile-schema.d.ts +619 -2
- package/dist/company-profile.d.ts +9 -4
- package/dist/connection-authority.d.ts +95 -0
- package/dist/connection-scopes.d.ts +8 -0
- package/dist/connection-tenancy-backfill.d.ts +41 -0
- package/dist/connection-token-resolver.d.ts +30 -1
- package/dist/database.d.ts +19 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.d.ts +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/governed-learning-activation-schema.d.ts +984 -0
- package/dist/governed-learning-activation.d.ts +98 -0
- package/dist/governed-learning-evaluator-schema.d.ts +633 -0
- package/dist/governed-learning-evaluator.d.ts +28 -0
- package/dist/index.d.ts +1595 -81
- package/dist/index.js +21571 -8126
- package/dist/index.js.map +1 -1
- package/dist/insights.d.ts +18 -0
- package/dist/integration-bindings.d.ts +1 -0
- package/dist/integration-facets.d.ts +30 -0
- package/dist/interaction-placement-loss.d.ts +22 -0
- package/dist/managed-human-provisioning.d.ts +25 -0
- package/dist/memory-domain.d.ts +3 -3
- package/dist/migrate.d.ts +11 -1
- package/dist/migrate.js +1 -1
- package/dist/new-session-drafts.d.ts +43 -5
- package/dist/organization-membership-backfill.d.ts +174 -0
- package/dist/organization-membership-lifecycle.d.ts +162 -0
- package/dist/pr-review.d.ts +107 -0
- package/dist/preference-registry-schema.d.ts +2 -0
- package/dist/preference-registry.d.ts +2 -0
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +22 -8
- package/dist/schema.d.ts +24914 -13703
- package/dist/schema.js +99 -1
- package/dist/scoped-knowledge-schema.d.ts +52 -1
- package/dist/session-background-commands.d.ts +125 -0
- package/dist/session-background-commands.js +34 -0
- package/dist/session-background-commands.js.map +1 -0
- package/dist/session-control.d.ts +156 -3
- package/dist/session-goal-pacing.d.ts +68 -0
- package/dist/session-queue-commands.d.ts +41 -4
- package/dist/session-realtime-ledger.d.ts +2 -0
- package/dist/session-tenancy.d.ts +71 -1
- package/dist/session-tenancy.js +25 -3
- package/dist/session-tool-call-settlement.d.ts +9 -4
- package/dist/slack-routing-personal-workspace.d.ts +23 -0
- package/dist/slack-routing.d.ts +153 -0
- package/dist/slack-task-policy-schema.d.ts +34 -0
- package/dist/slack-task-policy.d.ts +8 -0
- package/dist/slack-user-link-access.d.ts +1 -0
- package/dist/task-notes-schema.d.ts +594 -0
- package/dist/task-notes.d.ts +39 -0
- package/dist/turn-initiator.d.ts +2 -0
- package/dist/user-resource-authority.d.ts +109 -0
- package/dist/video-generation.js +3 -3
- package/dist/workspace-authority.d.ts +81 -0
- package/dist/workspace-instruction-policies-schema.d.ts +279 -0
- package/dist/workspace-instruction-policies.d.ts +62 -0
- package/dist/workspace-learning-policy.d.ts +1 -0
- package/dist/workspace-membership-permissions.d.ts +2 -0
- package/drizzle/0240_enrollment_connection_authority.sql +39 -0
- package/drizzle/0241_atomic_personal_resource_delegation.sql +1000 -0
- package/drizzle/0241_enrollment_agent_runtime.sql +70 -0
- package/drizzle/0244_slack_app_home_refresh_queue.sql +120 -0
- package/drizzle/0245_model_context_contribution_facts.sql +88 -0
- package/drizzle/0246_integration_personal_instance_authority.sql +70 -0
- package/drizzle/0247_terraform_stacks_provenance_repair.sql +428 -0
- package/drizzle/0248_terraform_stacks_component_resolution_fence.sql +83 -0
- package/drizzle/0249_personal_resource_delegation_authority_correction.sql +662 -0
- package/drizzle/0250_direct_retained_process_owner_liveness.sql +199 -0
- package/drizzle/0251_connected_machine_operation_policy.sql +45 -0
- package/drizzle/0252_scheduled_personal_resource_delegation.sql +1867 -0
- package/drizzle/0253_common_user_resource_authority_lifecycle.sql +1555 -0
- package/drizzle/0254_scoped_variable_set_authority.sql +1255 -0
- package/drizzle/0255_company_brain_governed_write_proposals.sql +524 -0
- package/drizzle/0256_connection_authority_delegation.sql +703 -0
- package/drizzle/0257_goal_revision_decisions_and_root_constraints.sql +436 -0
- package/drizzle/0258_three_scope_document_knowledge_authority.sql +1273 -0
- package/drizzle/0259_company_brain_context_selection_receipts.sql +869 -0
- package/drizzle/0260_task_note_knowledge_promotion.sql +820 -0
- package/drizzle/0261_preference_knowledge_proposal_actor_binding.sql +471 -0
- package/drizzle/0262_scoped_connected_machines_and_rigs.sql +1700 -0
- package/drizzle/0263_organization_membership_lifecycle.sql +3284 -0
- package/drizzle/0264_connection_authority_runtime_activation.sql +1084 -0
- package/drizzle/0266_company_brain_context_receipt_inspection.sql +156 -0
- package/drizzle/0268_governed_learning_decision_receipts.sql +825 -0
- package/drizzle/0269_governed_learning_activation_controller.sql +1874 -0
- package/drizzle/0270_governed_learning_history_inspection.sql +170 -0
- package/drizzle/0271_company_brain_retrieval_only_default.sql +524 -0
- package/drizzle/0272_human_confirmed_learning_activation.sql +591 -0
- package/drizzle/0273_scheduled_variable_set_materialization.sql +268 -0
- package/drizzle/0274_human_confirmed_knowledge_review.sql +310 -0
- package/drizzle/0275_scheduled_connection_authority.sql +5527 -0
- package/drizzle/0276_onboarding_proposal_initiating_human_guc.sql +198 -0
- package/drizzle/0277_workspace_writer_authority_attribution.sql +393 -0
- package/drizzle/0278_workspace_membership_removal_fencing.sql +1174 -0
- package/drizzle/0279_workspace_connection_use_lane.sql +343 -0
- package/drizzle/0280_connection_and_variable_set_audit_attribution.sql +773 -0
- package/drizzle/0281_viewer_holder_authority_claims.sql +52 -0
- package/drizzle/0282_variable_set_session_attach_attribution.sql +178 -0
- package/drizzle/0283_editable_spreadsheet_authored_state.sql +82 -0
- package/drizzle/0284_truthful_human_confirmed_review_reason.sql +930 -0
- package/drizzle/0285_organization_tenancy_inventory.sql +329 -0
- package/drizzle/0286_widen_task_note_expiry_ceiling.sql +391 -0
- package/drizzle/0287_open_suffix_pending_tool_calls.sql +18 -0
- package/drizzle/0288_attached_browser_reenrollment.sql +64 -0
- package/drizzle/0289_session_composer_policy_authority.sql +597 -0
- package/drizzle/0290_organization_membership_backfill.sql +268 -0
- package/drizzle/0291_resource_authority_classification_assertion.sql +371 -0
- package/drizzle/0292_truthful_tenancy_inventory_counters.sql +291 -0
- package/drizzle/0293_confirm_time_rule_rebaseline.sql +615 -0
- package/drizzle/0294_preference_activation_authority.sql +237 -0
- package/drizzle/0295_retire_legacy_standing_memory_mode.sql +476 -0
- package/drizzle/0296_force_rls_backfill_noop_repair.sql +215 -0
- package/drizzle/0297_session_ownership_classification_and_backfill.sql +752 -0
- package/drizzle/0298_organization_tenancy_parity.sql +609 -0
- package/drizzle/0299_organization_membership_lock_order.sql +291 -0
- package/drizzle/0300_tenancy_backfill_ledger.sql +459 -0
- package/drizzle/0301_session_snapshot_and_pin_visibility.sql +181 -0
- package/drizzle/0302_personal_workspace_session_ownership.sql +303 -0
- package/drizzle/0303_session_tenancy_product_activation.sql +919 -0
- package/drizzle/0304_personal_workspace_private_session_reads.sql +97 -0
- package/drizzle/0305_personal_resource_grant_management.sql +584 -0
- package/drizzle/0306_atomic_personal_resource_attachments.sql +1374 -0
- package/drizzle/0307_session_attention_state.sql +51 -0
- package/drizzle/0308_session_archives.sql +35 -0
- package/drizzle/0309_channel_project_pins.sql +6 -0
- package/drizzle/0310_channel_project_order.sql +27 -0
- package/drizzle/0311_company_scope_and_private_session_create.sql +656 -0
- package/drizzle/0312_quiescent_session_tree_deletion.sql +39 -0
- package/drizzle/0313_private_child_session_authority.sql +365 -0
- package/drizzle/0314_unregistered_organization_invitations.sql +606 -0
- package/drizzle/0315_personal_github_repository_selection.sql +624 -0
- package/drizzle/0316_human_confirmed_activation_resumed_generation.sql +869 -0
- package/drizzle/0317_session_goal_continuation_hold.sql +64 -0
- package/drizzle/0318_session_turn_startup_milestones.sql +115 -0
- package/drizzle/0319_event_triggered_automations.sql +254 -0
- package/drizzle/0320_pr_review_pack.sql +113 -0
- package/drizzle/0321_slack_bot_environment_display_name.sql +15 -0
- package/drizzle/0322_session_turns_unclaimed_prompt_trigger_index.sql +5 -0
- package/drizzle/0323_organization_private_session_enablement.sql +489 -0
- package/drizzle/0324_human_confirmed_company_profile_agent_admin.sql +856 -0
- package/drizzle/0325_child_lifecycle_notices.sql +44 -0
- package/drizzle/0326_interaction_operation_error_codes.sql +62 -0
- package/drizzle/0327_slack_first_task_hint.sql +29 -0
- package/drizzle/0328_session_background_commands.sql +590 -0
- package/drizzle/0329_slack_orchestration_delivery_events.sql +91 -0
- package/drizzle/0330_api_key_descriptions.sql +20 -0
- package/drizzle/0331_managed_organization_creation.sql +163 -0
- package/drizzle/0332_organization_shared_workspace_control_plane.sql +539 -0
- package/drizzle/0333_session_turn_prompt_routing.sql +45 -0
- package/drizzle/0334_connected_machine_workspace_root.sql +99 -0
- package/drizzle/0335_slack_workspace_routing.sql +460 -0
- package/drizzle/0336_atomic_session_fork_visibility.sql +667 -0
- package/drizzle/0337_slack_routed_action_handles.sql +189 -0
- package/drizzle/0338_atomic_connected_machine_attachments.sql +410 -0
- package/drizzle/0339_document_authority_reclassification.sql +1153 -0
- package/drizzle/0340_tenancy_backfill_activation_evidence.sql +1347 -0
- package/drizzle/0341_slack_routing_probe_organization_fence.sql +109 -0
- package/package.json +10 -6
- package/src/attached-browser-devices.ts +233 -5
- package/src/automations.ts +911 -0
- package/src/browser-sessions.ts +10 -0
- package/src/capability-integrations.ts +175 -1
- package/src/child-lifecycle-notices.ts +241 -0
- package/src/codemode-operations.ts +1 -35
- package/src/company-brain-context-selection-schema.ts +100 -0
- package/src/company-brain-context-selection.ts +359 -0
- package/src/company-brain-governed-writes.ts +1170 -0
- package/src/company-brain.ts +309 -0
- package/src/company-profile-agent-admin.ts +225 -0
- package/src/company-profile-schema.ts +121 -1
- package/src/company-profile.ts +21 -0
- package/src/computer-sessions.ts +10 -1
- package/src/connection-authority.ts +290 -0
- package/src/connection-scopes.ts +20 -0
- package/src/connection-tenancy-backfill.ts +81 -0
- package/src/connection-token-resolver.ts +263 -31
- package/src/database.ts +75 -2
- package/src/editable-artifacts-schema.ts +10 -5
- package/src/editable-artifacts.ts +21 -11
- package/src/governed-learning-activation-schema.ts +121 -0
- package/src/governed-learning-activation.ts +588 -0
- package/src/governed-learning-evaluator-schema.ts +72 -0
- package/src/governed-learning-evaluator.ts +217 -0
- package/src/index.ts +11651 -1548
- package/src/insights.ts +107 -0
- package/src/integration-bindings.ts +88 -6
- package/src/integration-facets.ts +287 -84
- package/src/interaction-placement-loss.ts +234 -0
- package/src/managed-human-provisioning.ts +116 -0
- package/src/memory-domain.ts +27 -32
- package/src/migrate.ts +77 -1
- package/src/new-session-drafts.ts +229 -35
- package/src/organization-membership-backfill.ts +735 -0
- package/src/organization-membership-lifecycle.ts +985 -0
- package/src/pr-review.ts +890 -0
- package/src/preference-registry.ts +31 -1
- package/src/provision-roles.ts +877 -6
- package/src/runtime-posture-cli.ts +2 -0
- package/src/runtime-posture.ts +1291 -76
- package/src/schema.ts +3303 -428
- package/src/scoped-knowledge-schema.ts +16 -8
- package/src/scoped-knowledge.ts +1 -1
- package/src/session-background-commands.ts +759 -0
- package/src/session-control.ts +640 -74
- package/src/session-goal-pacing.ts +126 -0
- package/src/session-queue-commands.ts +437 -84
- package/src/session-realtime-context.ts +3 -3
- package/src/session-realtime-ledger.ts +22 -11
- package/src/session-realtime-mirror.ts +1 -1
- package/src/session-tenancy.ts +403 -49
- package/src/session-tool-call-settlement.ts +38 -29
- package/src/slack-routing-personal-workspace.ts +67 -0
- package/src/slack-routing.ts +469 -0
- package/src/slack-task-policy-schema.ts +5 -0
- package/src/slack-task-policy.ts +18 -0
- package/src/slack-user-link-access.ts +17 -1
- package/src/task-notes-schema.ts +74 -0
- package/src/task-notes.ts +124 -2
- package/src/turn-initiator.ts +8 -0
- package/src/user-resource-authority.ts +377 -0
- package/src/workspace-authority.ts +160 -0
- package/src/workspace-instruction-policies-schema.ts +53 -1
- package/src/workspace-instruction-policies.ts +528 -77
- package/src/workspace-learning-policy.ts +21 -5
- package/src/workspace-membership-permissions.ts +9 -0
- package/dist/chunk-4SR4HKKA.js.map +0 -1
- package/dist/chunk-6ZYKCRFO.js.map +0 -1
- package/dist/chunk-NXAFLCQX.js +0 -2468
- package/dist/chunk-NXAFLCQX.js.map +0 -1
- package/dist/chunk-SK7YYHBI.js.map +0 -1
- package/dist/chunk-WD5ROSLL.js +0 -117
- package/dist/chunk-WD5ROSLL.js.map +0 -1
- package/dist/chunk-ZWREYEWA.js.map +0 -1
- /package/dist/{chunk-LTG3S6ZY.js.map → chunk-EULAN2NP.js.map} +0 -0
- /package/dist/{chunk-CUPM3FGB.js.map → chunk-NJVZPWXY.js.map} +0 -0
|
@@ -1,17 +1,44 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
NewSessionDraftOptions,
|
|
3
|
+
NewSessionSelectionHistory,
|
|
3
4
|
LatencyMode,
|
|
4
5
|
ReasoningEffort,
|
|
5
6
|
RepositoryResourceRef,
|
|
6
7
|
ResourceRef,
|
|
7
8
|
ToolRef,
|
|
8
9
|
} from "@opengeni/contracts";
|
|
9
|
-
import {
|
|
10
|
+
import { stableJson } from "@opengeni/contracts";
|
|
11
|
+
import { and, eq, sql } from "drizzle-orm";
|
|
10
12
|
import type { Database } from "./database";
|
|
11
13
|
import * as schema from "./schema";
|
|
14
|
+
import {
|
|
15
|
+
accountIdInRlsScope,
|
|
16
|
+
subjectHasLiveWorkspaceAuthorityInScope,
|
|
17
|
+
} from "./workspace-authority";
|
|
12
18
|
|
|
13
19
|
export type NewSessionDraftRow = typeof schema.newSessionDrafts.$inferSelect;
|
|
14
20
|
|
|
21
|
+
async function lockNewSessionDraftIdentity(
|
|
22
|
+
db: Database,
|
|
23
|
+
workspaceId: string,
|
|
24
|
+
subjectId: string,
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
await db.execute(
|
|
27
|
+
sql`select pg_advisory_xact_lock(hashtextextended(${`new-session-draft:${workspaceId}:${subjectId}`}, 0))`,
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export type NewSessionDraftSnapshot = {
|
|
32
|
+
text: string;
|
|
33
|
+
resources: ResourceRef[];
|
|
34
|
+
tools: ToolRef[];
|
|
35
|
+
toolsProvided: boolean;
|
|
36
|
+
model: string;
|
|
37
|
+
reasoningEffort: ReasoningEffort;
|
|
38
|
+
latencyMode: LatencyMode;
|
|
39
|
+
options: NewSessionDraftOptions;
|
|
40
|
+
};
|
|
41
|
+
|
|
15
42
|
export class NewSessionDraftConflictError extends Error {
|
|
16
43
|
readonly name = "NewSessionDraftConflictError";
|
|
17
44
|
|
|
@@ -31,13 +58,54 @@ export class NewSessionDraftAccessError extends Error {
|
|
|
31
58
|
type StoredNewSessionDraftOptions = NewSessionDraftOptions & {
|
|
32
59
|
/** JSONB-only compatibility marker; deliberately not part of public options. */
|
|
33
60
|
toolsProvided?: boolean;
|
|
61
|
+
/** Successful-create preference state, separate from transient draft edits. */
|
|
62
|
+
selectionHistory?: NewSessionSelectionHistory;
|
|
34
63
|
};
|
|
35
64
|
|
|
65
|
+
const REMEMBERED_WORKING_DIR_MAX_LENGTH = 4096;
|
|
66
|
+
|
|
36
67
|
function storedOptions(
|
|
37
68
|
options: NewSessionDraftOptions,
|
|
38
69
|
toolsProvided: boolean,
|
|
70
|
+
selectionHistory: NewSessionSelectionHistory = { projects: [] },
|
|
39
71
|
): StoredNewSessionDraftOptions {
|
|
40
|
-
return { ...options, toolsProvided };
|
|
72
|
+
return { ...options, toolsProvided, selectionHistory };
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export function newSessionSelectionHistory(row: NewSessionDraftRow): NewSessionSelectionHistory {
|
|
76
|
+
const raw = (row.sessionOptions as StoredNewSessionDraftOptions).selectionHistory;
|
|
77
|
+
if (!raw || !Array.isArray(raw.projects)) return { projects: [] };
|
|
78
|
+
return {
|
|
79
|
+
projects: raw.projects.slice(0, 50).flatMap((project) => {
|
|
80
|
+
if (!project || (project.channelId !== null && typeof project.channelId !== "string")) {
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
return [
|
|
84
|
+
{
|
|
85
|
+
channelId: project.channelId,
|
|
86
|
+
targetSandboxId:
|
|
87
|
+
typeof project.targetSandboxId === "string" ? project.targetSandboxId : null,
|
|
88
|
+
machines: Array.isArray(project.machines)
|
|
89
|
+
? project.machines.slice(0, 20).flatMap((machine) =>
|
|
90
|
+
machine && typeof machine.sandboxId === "string"
|
|
91
|
+
? [
|
|
92
|
+
{
|
|
93
|
+
sandboxId: machine.sandboxId,
|
|
94
|
+
workingDir:
|
|
95
|
+
typeof machine.workingDir === "string" &&
|
|
96
|
+
machine.workingDir.length > 0 &&
|
|
97
|
+
machine.workingDir.length <= REMEMBERED_WORKING_DIR_MAX_LENGTH
|
|
98
|
+
? machine.workingDir
|
|
99
|
+
: null,
|
|
100
|
+
},
|
|
101
|
+
]
|
|
102
|
+
: [],
|
|
103
|
+
)
|
|
104
|
+
: [],
|
|
105
|
+
},
|
|
106
|
+
];
|
|
107
|
+
}),
|
|
108
|
+
};
|
|
41
109
|
}
|
|
42
110
|
|
|
43
111
|
export function newSessionDraftToolsProvided(row: NewSessionDraftRow): boolean {
|
|
@@ -53,6 +121,7 @@ export function newSessionDraftToolsProvided(row: NewSessionDraftRow): boolean {
|
|
|
53
121
|
export function publicNewSessionDraftOptions(row: NewSessionDraftRow): NewSessionDraftOptions {
|
|
54
122
|
const options = { ...(row.sessionOptions as StoredNewSessionDraftOptions) };
|
|
55
123
|
delete options.toolsProvided;
|
|
124
|
+
delete options.selectionHistory;
|
|
56
125
|
return options;
|
|
57
126
|
}
|
|
58
127
|
|
|
@@ -87,10 +156,16 @@ export async function saveNewSessionDraftInTransaction(
|
|
|
87
156
|
toolsProvided: boolean;
|
|
88
157
|
model: string;
|
|
89
158
|
reasoningEffort: ReasoningEffort;
|
|
90
|
-
latencyMode
|
|
159
|
+
latencyMode: LatencyMode;
|
|
91
160
|
options: NewSessionDraftOptions;
|
|
92
161
|
/** API-key and delegated service subjects have no workspace-membership row. */
|
|
93
162
|
requireWorkspaceMembership?: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* May this caller use the owner-only managed personal-workspace exception?
|
|
165
|
+
* See `PersonalWorkspaceOwnerException` in `@opengeni/db`. Absent means the
|
|
166
|
+
* historical bare-membership fence, unchanged.
|
|
167
|
+
*/
|
|
168
|
+
personalWorkspaceOwnerException?: boolean;
|
|
94
169
|
},
|
|
95
170
|
): Promise<NewSessionDraftRow> {
|
|
96
171
|
if (input.requireWorkspaceMembership !== false) {
|
|
@@ -109,9 +184,36 @@ export async function saveNewSessionDraftInTransaction(
|
|
|
109
184
|
)
|
|
110
185
|
.for("key share")
|
|
111
186
|
.limit(1);
|
|
112
|
-
|
|
187
|
+
// The owner of a managed personal workspace never has a membership row there
|
|
188
|
+
// (migration 0219 raises on one), so the bare probe above would 403 the
|
|
189
|
+
// composer inside the one workspace they always belong to. Ask the canonical
|
|
190
|
+
// resolver instead of re-deriving that rule — it runs on this same
|
|
191
|
+
// transaction handle, and there is no membership row for removeWorkspaceMember()
|
|
192
|
+
// to delete in a personal workspace, so nothing is lost by taking no
|
|
193
|
+
// `FOR KEY SHARE` on this path.
|
|
194
|
+
if (
|
|
195
|
+
!membership &&
|
|
196
|
+
!(
|
|
197
|
+
input.personalWorkspaceOwnerException === true &&
|
|
198
|
+
(await subjectHasLiveWorkspaceAuthorityInScope(db, {
|
|
199
|
+
// Scope-derived, NOT `input.accountId`: the applied RLS GUC is the
|
|
200
|
+
// tenant this transaction actually runs under, so an authority
|
|
201
|
+
// decision never reads a caller-supplied account. Matches
|
|
202
|
+
// listSessionsForSubject and setSessionPin.
|
|
203
|
+
accountId: await accountIdInRlsScope(db),
|
|
204
|
+
workspaceId: input.workspaceId,
|
|
205
|
+
subjectId: input.subjectId,
|
|
206
|
+
}))
|
|
207
|
+
)
|
|
208
|
+
) {
|
|
209
|
+
throw new NewSessionDraftAccessError();
|
|
210
|
+
}
|
|
113
211
|
}
|
|
114
|
-
|
|
212
|
+
await lockNewSessionDraftIdentity(db, input.workspaceId, input.subjectId);
|
|
213
|
+
const current = await getNewSessionDraftInTransaction(db, {
|
|
214
|
+
...input,
|
|
215
|
+
lock: true,
|
|
216
|
+
});
|
|
115
217
|
const currentRevision = current?.revision ?? 0;
|
|
116
218
|
if (currentRevision !== input.expectedRevision) {
|
|
117
219
|
throw new NewSessionDraftConflictError(currentRevision);
|
|
@@ -128,10 +230,14 @@ export async function saveNewSessionDraftInTransaction(
|
|
|
128
230
|
tools: input.tools,
|
|
129
231
|
model: input.model,
|
|
130
232
|
reasoningEffort: input.reasoningEffort,
|
|
131
|
-
latencyMode: input.latencyMode
|
|
233
|
+
latencyMode: input.latencyMode,
|
|
132
234
|
// Keep the explicit/omitted policy in the existing JSONB extension point;
|
|
133
235
|
// adding a column here would turn a client preference into a migration.
|
|
134
|
-
sessionOptions: storedOptions(
|
|
236
|
+
sessionOptions: storedOptions(
|
|
237
|
+
input.options,
|
|
238
|
+
input.toolsProvided,
|
|
239
|
+
current ? newSessionSelectionHistory(current) : { projects: [] },
|
|
240
|
+
),
|
|
135
241
|
updatedAt: new Date(),
|
|
136
242
|
};
|
|
137
243
|
if (current) {
|
|
@@ -155,7 +261,10 @@ export async function saveNewSessionDraftInTransaction(
|
|
|
155
261
|
})
|
|
156
262
|
.returning();
|
|
157
263
|
if (inserted) return inserted;
|
|
158
|
-
const raced = await getNewSessionDraftInTransaction(db, {
|
|
264
|
+
const raced = await getNewSessionDraftInTransaction(db, {
|
|
265
|
+
...input,
|
|
266
|
+
lock: true,
|
|
267
|
+
});
|
|
159
268
|
throw new NewSessionDraftConflictError(raced?.revision ?? 0);
|
|
160
269
|
}
|
|
161
270
|
|
|
@@ -177,38 +286,94 @@ function safeRepositoryResource(resource: RepositoryResourceRef): RepositoryReso
|
|
|
177
286
|
};
|
|
178
287
|
}
|
|
179
288
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
289
|
+
export type AcceptedNewSessionSelection = {
|
|
290
|
+
channelId: string | null;
|
|
291
|
+
targetSandboxId: string | null;
|
|
292
|
+
workingDir: string | null;
|
|
293
|
+
};
|
|
294
|
+
|
|
295
|
+
export function rememberNewSessionSelection(
|
|
296
|
+
history: NewSessionSelectionHistory,
|
|
297
|
+
selection: AcceptedNewSessionSelection,
|
|
298
|
+
): NewSessionSelectionHistory {
|
|
299
|
+
const existingProject = history.projects.find(
|
|
300
|
+
(project) => project.channelId === selection.channelId,
|
|
301
|
+
);
|
|
302
|
+
let machines = existingProject?.machines ?? [];
|
|
303
|
+
if (selection.targetSandboxId) {
|
|
304
|
+
machines = [
|
|
305
|
+
{
|
|
306
|
+
sandboxId: selection.targetSandboxId,
|
|
307
|
+
workingDir:
|
|
308
|
+
selection.workingDir && selection.workingDir.length <= REMEMBERED_WORKING_DIR_MAX_LENGTH
|
|
309
|
+
? selection.workingDir
|
|
310
|
+
: null,
|
|
311
|
+
},
|
|
312
|
+
...machines.filter((machine) => machine.sandboxId !== selection.targetSandboxId),
|
|
313
|
+
].slice(0, 20);
|
|
197
314
|
}
|
|
198
|
-
return
|
|
315
|
+
return {
|
|
316
|
+
projects: [
|
|
317
|
+
{
|
|
318
|
+
channelId: selection.channelId,
|
|
319
|
+
targetSandboxId: selection.targetSandboxId,
|
|
320
|
+
machines,
|
|
321
|
+
},
|
|
322
|
+
...history.projects.filter((project) => project.channelId !== selection.channelId),
|
|
323
|
+
].slice(0, 50),
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Record a successful create without consuming the editable draft. Realtime
|
|
329
|
+
* session creation uses this path because it must preserve the actor's pending
|
|
330
|
+
* text/files for a later ordinary session. The hidden preference update shares
|
|
331
|
+
* the draft identity lock with saves, and deliberately leaves its OCC revision
|
|
332
|
+
* unchanged because no browser-editable field changed.
|
|
333
|
+
*/
|
|
334
|
+
export async function rememberNewSessionSelectionInTransaction(
|
|
335
|
+
db: Database,
|
|
336
|
+
input: {
|
|
337
|
+
workspaceId: string;
|
|
338
|
+
subjectId: string;
|
|
339
|
+
acceptedSelection: AcceptedNewSessionSelection;
|
|
340
|
+
},
|
|
341
|
+
): Promise<boolean> {
|
|
342
|
+
await lockNewSessionDraftIdentity(db, input.workspaceId, input.subjectId);
|
|
343
|
+
const current = await getNewSessionDraftInTransaction(db, { ...input, lock: true });
|
|
344
|
+
if (!current) return false;
|
|
345
|
+
const [updated] = await db
|
|
346
|
+
.update(schema.newSessionDrafts)
|
|
347
|
+
.set({
|
|
348
|
+
sessionOptions: storedOptions(
|
|
349
|
+
publicNewSessionDraftOptions(current),
|
|
350
|
+
newSessionDraftToolsProvided(current),
|
|
351
|
+
rememberNewSessionSelection(newSessionSelectionHistory(current), input.acceptedSelection),
|
|
352
|
+
),
|
|
353
|
+
})
|
|
354
|
+
.where(eq(schema.newSessionDrafts.id, current.id))
|
|
355
|
+
.returning({ id: schema.newSessionDrafts.id });
|
|
356
|
+
return Boolean(updated);
|
|
199
357
|
}
|
|
200
358
|
|
|
201
359
|
/**
|
|
202
360
|
* Replace one exact accepted draft with the next-create safe seed. The row is
|
|
203
|
-
*
|
|
204
|
-
*
|
|
205
|
-
*
|
|
361
|
+
* identity-serialized before the revision check so even the absent-row
|
|
362
|
+
* revision-zero case cannot race a first save. Exact create callers receive a
|
|
363
|
+
* typed conflict; legacy revision-only callers retain the old false/no-op
|
|
364
|
+
* result. A missing row is an idempotent no-op.
|
|
206
365
|
*/
|
|
207
366
|
export async function seedNewSessionDraftInTransaction(
|
|
208
367
|
db: Database,
|
|
209
|
-
input: {
|
|
368
|
+
input: {
|
|
369
|
+
workspaceId: string;
|
|
370
|
+
subjectId: string;
|
|
371
|
+
expectedRevision: number;
|
|
372
|
+
expectedSnapshot?: NewSessionDraftSnapshot;
|
|
373
|
+
acceptedSelection?: AcceptedNewSessionSelection;
|
|
374
|
+
},
|
|
210
375
|
): Promise<boolean> {
|
|
211
|
-
|
|
376
|
+
await lockNewSessionDraftIdentity(db, input.workspaceId, input.subjectId);
|
|
212
377
|
const [current] = await db
|
|
213
378
|
.select()
|
|
214
379
|
.from(schema.newSessionDrafts)
|
|
@@ -220,7 +385,27 @@ export async function seedNewSessionDraftInTransaction(
|
|
|
220
385
|
)
|
|
221
386
|
.for("update")
|
|
222
387
|
.limit(1);
|
|
223
|
-
if (!current || current.revision !== input.expectedRevision)
|
|
388
|
+
if (!current || current.revision !== input.expectedRevision) {
|
|
389
|
+
if (input.expectedSnapshot) {
|
|
390
|
+
throw new NewSessionDraftConflictError(current?.revision ?? 0);
|
|
391
|
+
}
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
if (
|
|
395
|
+
input.expectedSnapshot &&
|
|
396
|
+
stableJson({
|
|
397
|
+
text: current.text,
|
|
398
|
+
resources: current.resources,
|
|
399
|
+
tools: newSessionDraftToolsProvided(current) ? current.tools : [],
|
|
400
|
+
toolsProvided: newSessionDraftToolsProvided(current),
|
|
401
|
+
model: current.model,
|
|
402
|
+
reasoningEffort: current.reasoningEffort,
|
|
403
|
+
latencyMode: current.latencyMode,
|
|
404
|
+
options: publicNewSessionDraftOptions(current),
|
|
405
|
+
}) !== stableJson(input.expectedSnapshot)
|
|
406
|
+
) {
|
|
407
|
+
throw new NewSessionDraftConflictError(current.revision);
|
|
408
|
+
}
|
|
224
409
|
|
|
225
410
|
const options = current.sessionOptions as StoredNewSessionDraftOptions;
|
|
226
411
|
const targetSandboxId =
|
|
@@ -228,8 +413,8 @@ export async function seedNewSessionDraftInTransaction(
|
|
|
228
413
|
const safeOptions: NewSessionDraftOptions = {
|
|
229
414
|
...(options.sandboxBackend ? { sandboxBackend: options.sandboxBackend } : {}),
|
|
230
415
|
...(targetSandboxId ? { targetSandboxId } : {}),
|
|
231
|
-
...(
|
|
232
|
-
? { workingDir:
|
|
416
|
+
...(targetSandboxId && typeof options.workingDir === "string"
|
|
417
|
+
? { workingDir: options.workingDir }
|
|
233
418
|
: {}),
|
|
234
419
|
...(options.variableSetId ? { variableSetId: options.variableSetId } : {}),
|
|
235
420
|
...(options.rigId ? { rigId: options.rigId } : {}),
|
|
@@ -252,7 +437,16 @@ export async function seedNewSessionDraftInTransaction(
|
|
|
252
437
|
model: current.model,
|
|
253
438
|
reasoningEffort: current.reasoningEffort,
|
|
254
439
|
latencyMode: current.latencyMode,
|
|
255
|
-
sessionOptions: storedOptions(
|
|
440
|
+
sessionOptions: storedOptions(
|
|
441
|
+
safeOptions,
|
|
442
|
+
newSessionDraftToolsProvided(current),
|
|
443
|
+
input.acceptedSelection
|
|
444
|
+
? rememberNewSessionSelection(
|
|
445
|
+
newSessionSelectionHistory(current),
|
|
446
|
+
input.acceptedSelection,
|
|
447
|
+
)
|
|
448
|
+
: newSessionSelectionHistory(current),
|
|
449
|
+
),
|
|
256
450
|
updatedAt: new Date(),
|
|
257
451
|
})
|
|
258
452
|
.where(
|