@opengeni/db 3.6.0 → 3.7.3-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/canonical-human-identities.js +3 -3
- package/dist/{chunk-744DFC65.js → chunk-4NAR7FBA.js} +92 -6
- package/dist/chunk-4NAR7FBA.js.map +1 -0
- package/dist/{chunk-IW6O6G7R.js → chunk-5NNCGFQY.js} +2 -2
- package/dist/{chunk-G3732M3T.js → chunk-DZCYW2WT.js} +2 -2
- package/dist/{chunk-WW7AJ5IC.js → chunk-F6PBS6WE.js} +5 -7
- package/dist/chunk-F6PBS6WE.js.map +1 -0
- package/dist/{chunk-UJ2EW3QI.js → chunk-O56DM5GZ.js} +340 -85
- package/dist/chunk-O56DM5GZ.js.map +1 -0
- package/dist/{chunk-CDMMSUWJ.js → chunk-S3TDDCS2.js} +3 -3
- package/dist/{chunk-Q5YUGQVK.js → chunk-SZAWDXQC.js} +3 -3
- package/dist/{chunk-UGDVSQ6U.js → chunk-U4WPPEBH.js} +2 -2
- package/dist/{chunk-2NT476HD.js → chunk-US4IS6IV.js} +2 -2
- package/dist/codex-token-resolver.d.ts +12 -1
- package/dist/company-profile-agent-admin.d.ts +4 -2
- package/dist/company-profile-agent-policy.d.ts +20 -0
- package/dist/company-profile-schema.d.ts +573 -0
- package/dist/editable-artifact-durable-export.js +2 -2
- package/dist/editable-artifacts.js +3 -3
- package/dist/index.d.ts +382 -18
- package/dist/index.js +4513 -2065
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-sets.js +3 -3
- package/dist/managed-human-provisioning.d.ts +3 -3
- package/dist/memory-domain.d.ts +5 -3
- package/dist/provision-roles.js +1 -1
- package/dist/runtime-posture.d.ts +5 -5
- package/dist/schema.d.ts +725 -4
- package/dist/schema.js +13 -1
- package/dist/session-background-commands.js +3 -3
- package/dist/session-control.d.ts +40 -5
- package/dist/session-queue-commands.d.ts +2 -0
- package/dist/session-tenancy.js +3 -3
- package/dist/user-resource-authority.d.ts +8 -0
- package/dist/video-generation.js +3 -3
- package/drizzle/0369_local_human_personal_authority.sql +350 -0
- package/drizzle/0370_workspace_member_management_scope.sql +98 -0
- package/drizzle/0371_workspace_member_candidate_inventory.sql +128 -0
- package/drizzle/0372_ordered_variable_set_runtime_authority.sql +287 -0
- package/drizzle/0373_sandbox_shared_preparation.sql +59 -0
- package/drizzle/0374_session_event_cursors.sql +315 -0
- package/drizzle/0375_session_recovery_observability.sql +73 -0
- package/drizzle/0376_organization_workspace_inventory.sql +88 -0
- package/drizzle/0377_scoped_rig_health_projection.sql +80 -0
- package/drizzle/0378_scoped_rig_health_audit_timestamp.sql +77 -0
- package/drizzle/0379_session_event_raw_lane_activation.sql +518 -0
- package/drizzle/0380_autonomous_company_profile_agent_policy.sql +829 -0
- package/drizzle/0381_organization_codex_subscription_inheritance.sql +720 -0
- package/drizzle/0382_organization_api_key_provenance.sql +91 -0
- package/drizzle/0383_codex_cooldown_reconciliation.sql +51 -0
- package/drizzle/0384_codex_cooldown_revision_guard_privileges.sql +6 -0
- package/drizzle/0385_connected_machine_legacy_tilde_workdirs.sql +25 -0
- package/drizzle/0386_local_organization_administration.sql +157 -0
- package/package.json +6 -6
- package/src/codex-token-resolver.ts +26 -1
- package/src/company-brain-governed-writes.ts +30 -1
- package/src/company-profile-agent-admin.ts +68 -1
- package/src/company-profile-agent-policy.ts +126 -0
- package/src/company-profile-schema.ts +115 -1
- package/src/database.ts +3 -5
- package/src/index.ts +3626 -456
- package/src/managed-human-provisioning.ts +3 -3
- package/src/memory-domain.ts +9 -4
- package/src/organization-membership-lifecycle.ts +0 -1
- package/src/provision-roles.ts +83 -4
- package/src/runtime-posture.ts +22 -0
- package/src/schema.ts +161 -8
- package/src/session-control.ts +177 -59
- package/src/session-queue-commands.ts +146 -40
- package/src/session-tool-call-settlement.ts +34 -7
- package/src/user-resource-authority.ts +56 -0
- package/dist/chunk-744DFC65.js.map +0 -1
- package/dist/chunk-UJ2EW3QI.js.map +0 -1
- package/dist/chunk-WW7AJ5IC.js.map +0 -1
- /package/dist/{chunk-IW6O6G7R.js.map → chunk-5NNCGFQY.js.map} +0 -0
- /package/dist/{chunk-G3732M3T.js.map → chunk-DZCYW2WT.js.map} +0 -0
- /package/dist/{chunk-CDMMSUWJ.js.map → chunk-S3TDDCS2.js.map} +0 -0
- /package/dist/{chunk-Q5YUGQVK.js.map → chunk-SZAWDXQC.js.map} +0 -0
- /package/dist/{chunk-UGDVSQ6U.js.map → chunk-U4WPPEBH.js.map} +0 -0
- /package/dist/{chunk-2NT476HD.js.map → chunk-US4IS6IV.js.map} +0 -0
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
type TimelineAnnotation,
|
|
30
30
|
type PersonalResourceAttachmentIntent,
|
|
31
31
|
} from "@opengeni/contracts";
|
|
32
|
-
import { and, asc, eq, inArray, sql } from "drizzle-orm";
|
|
32
|
+
import { and, asc, desc, eq, inArray, sql } from "drizzle-orm";
|
|
33
33
|
import { setSubjectRlsContext, type Database, type SessionActivityDatabase } from "./database";
|
|
34
34
|
import {
|
|
35
35
|
fromPostgresLosslessJson,
|
|
@@ -345,11 +345,55 @@ async function lockSession(
|
|
|
345
345
|
|
|
346
346
|
type SteerSupersessionResult = {
|
|
347
347
|
interruptionCount: number;
|
|
348
|
+
steerTargetTurn: typeof schema.sessionTurns.$inferSelect | null;
|
|
348
349
|
replacedTurn: typeof schema.sessionTurns.$inferSelect | null;
|
|
349
350
|
liveCurrentTurnId: string | null;
|
|
351
|
+
deferredUntilCompaction: boolean;
|
|
350
352
|
lastSequence: number;
|
|
351
353
|
};
|
|
352
354
|
|
|
355
|
+
async function turnAttemptIsCompacting(
|
|
356
|
+
db: Database,
|
|
357
|
+
input: {
|
|
358
|
+
workspaceId: string;
|
|
359
|
+
sessionId: string;
|
|
360
|
+
turn: typeof schema.sessionTurns.$inferSelect;
|
|
361
|
+
},
|
|
362
|
+
): Promise<boolean> {
|
|
363
|
+
// A standalone operator compaction is maintenance rather than replaceable
|
|
364
|
+
// direction. Once claimed, let it finish even before its provider-visible
|
|
365
|
+
// started landmark is appended.
|
|
366
|
+
if (input.turn.source === "compaction") return true;
|
|
367
|
+
if (!input.turn.activeAttemptId) return false;
|
|
368
|
+
|
|
369
|
+
// Automatic/proactive/overflow compaction happens inside an ordinary turn.
|
|
370
|
+
// The latest exact-attempt landmark is durable state: `started` means the
|
|
371
|
+
// checkpoint provider call is still in flight, while compacted/skipped opens
|
|
372
|
+
// ordinary Steer interruption again. Multiple compactions in one attempt are
|
|
373
|
+
// therefore handled by the newest lifecycle event rather than a historical
|
|
374
|
+
// existence test.
|
|
375
|
+
const [latest] = await db
|
|
376
|
+
.select({ type: schema.sessionEvents.type })
|
|
377
|
+
.from(schema.sessionEvents)
|
|
378
|
+
.where(
|
|
379
|
+
and(
|
|
380
|
+
eq(schema.sessionEvents.workspaceId, input.workspaceId),
|
|
381
|
+
eq(schema.sessionEvents.sessionId, input.sessionId),
|
|
382
|
+
eq(schema.sessionEvents.turnId, input.turn.id),
|
|
383
|
+
eq(schema.sessionEvents.turnGeneration, input.turn.executionGeneration),
|
|
384
|
+
eq(schema.sessionEvents.turnAttemptId, input.turn.activeAttemptId),
|
|
385
|
+
inArray(schema.sessionEvents.type, [
|
|
386
|
+
"session.context.compaction.started",
|
|
387
|
+
"session.context.compacted",
|
|
388
|
+
"session.context.compaction.skipped",
|
|
389
|
+
]),
|
|
390
|
+
),
|
|
391
|
+
)
|
|
392
|
+
.orderBy(desc(schema.sessionEvents.sequence), desc(schema.sessionEvents.id))
|
|
393
|
+
.limit(1);
|
|
394
|
+
return latest?.type === "session.context.compaction.started";
|
|
395
|
+
}
|
|
396
|
+
|
|
353
397
|
/**
|
|
354
398
|
* One canonical replacement transition shared by human row/new-prompt Steer
|
|
355
399
|
* and Agent Steer. A live owner is interrupted and remains current until exact
|
|
@@ -371,8 +415,10 @@ export async function supersedeSessionCurrentDirectionInTransaction(
|
|
|
371
415
|
if (!input.activeTurnId) {
|
|
372
416
|
return {
|
|
373
417
|
interruptionCount: 0,
|
|
418
|
+
steerTargetTurn: null,
|
|
374
419
|
replacedTurn: null,
|
|
375
420
|
liveCurrentTurnId: null,
|
|
421
|
+
deferredUntilCompaction: false,
|
|
376
422
|
lastSequence: input.lastSequence,
|
|
377
423
|
};
|
|
378
424
|
}
|
|
@@ -391,6 +437,7 @@ export async function supersedeSessionCurrentDirectionInTransaction(
|
|
|
391
437
|
workspaceId: input.workspaceId,
|
|
392
438
|
controlLock: "already_locked",
|
|
393
439
|
workspaceLock: "already_locked",
|
|
440
|
+
sessionIds: [input.sessionId],
|
|
394
441
|
turnIds: [input.activeTurnId],
|
|
395
442
|
attemptIds: preview?.activeAttemptId ? [preview.activeAttemptId] : [],
|
|
396
443
|
});
|
|
@@ -410,6 +457,26 @@ export async function supersedeSessionCurrentDirectionInTransaction(
|
|
|
410
457
|
`Running turn ${current.id} has no first-class attempt owner`,
|
|
411
458
|
);
|
|
412
459
|
}
|
|
460
|
+
if (
|
|
461
|
+
current.activeAttemptId &&
|
|
462
|
+
(await turnAttemptIsCompacting(db, {
|
|
463
|
+
workspaceId: input.workspaceId,
|
|
464
|
+
sessionId: input.sessionId,
|
|
465
|
+
turn: current,
|
|
466
|
+
}))
|
|
467
|
+
) {
|
|
468
|
+
return {
|
|
469
|
+
interruptionCount: 0,
|
|
470
|
+
steerTargetTurn: current,
|
|
471
|
+
// An ordinary turn is superseded cooperatively as soon as its checkpoint
|
|
472
|
+
// settles. Standalone maintenance completes normally, then the Steer is
|
|
473
|
+
// already first in line.
|
|
474
|
+
replacedTurn: current.source === "compaction" ? null : current,
|
|
475
|
+
liveCurrentTurnId: current.id,
|
|
476
|
+
deferredUntilCompaction: true,
|
|
477
|
+
lastSequence: input.lastSequence,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
413
480
|
if (current.activeAttemptId) {
|
|
414
481
|
if (current.status !== "running") {
|
|
415
482
|
throw new SessionControlInvariantError(
|
|
@@ -431,8 +498,10 @@ export async function supersedeSessionCurrentDirectionInTransaction(
|
|
|
431
498
|
.returning({ id: schema.sessionAttemptInterruptions.id });
|
|
432
499
|
return {
|
|
433
500
|
interruptionCount: interruption ? 1 : 0,
|
|
501
|
+
steerTargetTurn: current,
|
|
434
502
|
replacedTurn: current,
|
|
435
503
|
liveCurrentTurnId: current.id,
|
|
504
|
+
deferredUntilCompaction: false,
|
|
436
505
|
lastSequence: input.lastSequence,
|
|
437
506
|
};
|
|
438
507
|
}
|
|
@@ -571,8 +640,10 @@ export async function supersedeSessionCurrentDirectionInTransaction(
|
|
|
571
640
|
}
|
|
572
641
|
return {
|
|
573
642
|
interruptionCount: 0,
|
|
643
|
+
steerTargetTurn: current,
|
|
574
644
|
replacedTurn: current,
|
|
575
645
|
liveCurrentTurnId: null,
|
|
646
|
+
deferredUntilCompaction: false,
|
|
576
647
|
lastSequence,
|
|
577
648
|
};
|
|
578
649
|
}
|
|
@@ -1388,9 +1459,11 @@ export async function steerQueuedTurnInTransaction(
|
|
|
1388
1459
|
lastSequence: session.lastSequence,
|
|
1389
1460
|
});
|
|
1390
1461
|
const interruptionCount = supersession.interruptionCount;
|
|
1462
|
+
const steerTargetTurn = supersession.steerTargetTurn;
|
|
1391
1463
|
const supersededTurnId = supersession.replacedTurn?.id ?? null;
|
|
1392
1464
|
const supersededAttemptId = supersession.replacedTurn?.activeAttemptId ?? null;
|
|
1393
1465
|
const liveCurrentTurnId = supersession.liveCurrentTurnId;
|
|
1466
|
+
const deferredUntilCompaction = supersession.deferredUntilCompaction;
|
|
1394
1467
|
|
|
1395
1468
|
const withoutTarget = rows.filter((row) => row.id !== target.id);
|
|
1396
1469
|
const ordered = [target, ...withoutTarget];
|
|
@@ -1412,6 +1485,7 @@ export async function steerQueuedTurnInTransaction(
|
|
|
1412
1485
|
replacedTurnId: supersededTurnId,
|
|
1413
1486
|
replacedAttemptId: supersededAttemptId,
|
|
1414
1487
|
interruptionCount,
|
|
1488
|
+
...(deferredUntilCompaction ? { deferredUntilCompaction: true } : {}),
|
|
1415
1489
|
},
|
|
1416
1490
|
updatedAt: now,
|
|
1417
1491
|
})
|
|
@@ -1440,12 +1514,16 @@ export async function steerQueuedTurnInTransaction(
|
|
|
1440
1514
|
sessionId: input.sessionId,
|
|
1441
1515
|
sequence: ++sequence,
|
|
1442
1516
|
type: "session.control.steer_requested",
|
|
1443
|
-
turnId:
|
|
1517
|
+
turnId: steerTargetTurn?.id ?? target.id,
|
|
1518
|
+
turnGeneration: steerTargetTurn?.executionGeneration ?? null,
|
|
1519
|
+
turnAttemptId: steerTargetTurn?.activeAttemptId ?? null,
|
|
1520
|
+
turnAssociation: steerTargetTurn ? "current" : null,
|
|
1444
1521
|
payload: {
|
|
1445
1522
|
operationId: reserved.receipt.id,
|
|
1446
1523
|
targetTurnId: target.id,
|
|
1447
1524
|
replacedTurnId: supersededTurnId,
|
|
1448
|
-
stopping: liveCurrentTurnId !== null,
|
|
1525
|
+
stopping: liveCurrentTurnId !== null && !deferredUntilCompaction,
|
|
1526
|
+
...(deferredUntilCompaction ? { deferredUntilCompaction: true } : {}),
|
|
1449
1527
|
},
|
|
1450
1528
|
occurredAt: now,
|
|
1451
1529
|
});
|
|
@@ -1480,6 +1558,7 @@ export async function steerQueuedTurnInTransaction(
|
|
|
1480
1558
|
operationId: reserved.receipt.id,
|
|
1481
1559
|
replacedTurnId: supersededTurnId,
|
|
1482
1560
|
interruptionCount,
|
|
1561
|
+
deferredUntilCompaction,
|
|
1483
1562
|
},
|
|
1484
1563
|
},
|
|
1485
1564
|
"metadata",
|
|
@@ -1501,6 +1580,7 @@ export async function steerQueuedTurnInTransaction(
|
|
|
1501
1580
|
result: {
|
|
1502
1581
|
interruptionCount,
|
|
1503
1582
|
supersededTurnId,
|
|
1583
|
+
deferredUntilCompaction,
|
|
1504
1584
|
wakeRevision,
|
|
1505
1585
|
workspaceControlEventId: resumed.workspaceControlEventId,
|
|
1506
1586
|
},
|
|
@@ -1730,12 +1810,37 @@ export async function submitHumanPromptInTransaction(
|
|
|
1730
1810
|
);
|
|
1731
1811
|
}
|
|
1732
1812
|
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1813
|
+
const draft =
|
|
1814
|
+
input.expectedDraftRevision === null || input.expectedDraftRevision === undefined
|
|
1815
|
+
? null
|
|
1816
|
+
: await getComposerDraftInTransaction(db, {
|
|
1817
|
+
workspaceId: input.workspaceId,
|
|
1818
|
+
sessionId: input.sessionId,
|
|
1819
|
+
subjectId: input.subjectId,
|
|
1820
|
+
lock: true,
|
|
1821
|
+
});
|
|
1822
|
+
const isQueueEditSubmission = draft?.sourceTurnId !== null && draft?.sourceTurnId !== undefined;
|
|
1823
|
+
|
|
1824
|
+
// A normal Send received while the active branch is waiting in
|
|
1825
|
+
// `requires_action` is the human choosing to continue conversationally
|
|
1826
|
+
// instead of through the pending decision surface. Promote only that active
|
|
1827
|
+
// wait to Steer semantics so the frozen wait is cancelled and the new prompt
|
|
1828
|
+
// runs next. A queue-edit submission preserves the identity and placement of
|
|
1829
|
+
// already accepted queued work, so it must never cancel an unrelated active
|
|
1830
|
+
// wait. An explicitly paused branch remains inert until Resume or an explicit
|
|
1831
|
+
// Steer; running, recovering, and capacity-waiting work also retain ordinary
|
|
1832
|
+
// queue semantics.
|
|
1833
|
+
const effectiveDelivery =
|
|
1834
|
+
input.delivery === "send" &&
|
|
1835
|
+
(input.actor.type === "human" || input.actor.type === "operator") &&
|
|
1836
|
+
!isQueueEditSubmission &&
|
|
1837
|
+
before.state === "active" &&
|
|
1838
|
+
session.status === "requires_action" &&
|
|
1839
|
+
session.activeTurnId !== null
|
|
1840
|
+
? "steer"
|
|
1841
|
+
: input.delivery;
|
|
1737
1842
|
const resumed =
|
|
1738
|
-
|
|
1843
|
+
effectiveDelivery === "send"
|
|
1739
1844
|
? {
|
|
1740
1845
|
revision: before.controlVersion,
|
|
1741
1846
|
control: before,
|
|
@@ -1753,16 +1858,6 @@ export async function submitHumanPromptInTransaction(
|
|
|
1753
1858
|
observedControlEtag: input.controlEtag ?? null,
|
|
1754
1859
|
admission,
|
|
1755
1860
|
});
|
|
1756
|
-
|
|
1757
|
-
const draft =
|
|
1758
|
-
input.expectedDraftRevision === null || input.expectedDraftRevision === undefined
|
|
1759
|
-
? null
|
|
1760
|
-
: await getComposerDraftInTransaction(db, {
|
|
1761
|
-
workspaceId: input.workspaceId,
|
|
1762
|
-
sessionId: input.sessionId,
|
|
1763
|
-
subjectId: input.subjectId,
|
|
1764
|
-
lock: true,
|
|
1765
|
-
});
|
|
1766
1861
|
if (input.expectedDraftRevision !== null && input.expectedDraftRevision !== undefined) {
|
|
1767
1862
|
const actualRevision = draft?.revision ?? 0;
|
|
1768
1863
|
if (actualRevision !== input.expectedDraftRevision) {
|
|
@@ -1928,7 +2023,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
1928
2023
|
: (input.modelContext ?? null);
|
|
1929
2024
|
const existingQueued = await loadQueuedTurns(db, input.workspaceId, input.sessionId, true);
|
|
1930
2025
|
const routing: SessionPromptRouting =
|
|
1931
|
-
|
|
2026
|
+
effectiveDelivery === "steer"
|
|
1932
2027
|
? "accepted_for_steering"
|
|
1933
2028
|
: before.state === "paused" || session.activeTurnId || existingQueued.length > 0
|
|
1934
2029
|
? "queued_for_execution"
|
|
@@ -1959,7 +2054,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
1959
2054
|
...(input.model ? { model: input.model } : {}),
|
|
1960
2055
|
...(input.reasoningEffort ? { reasoningEffort: input.reasoningEffort } : {}),
|
|
1961
2056
|
...(input.latencyMode ? { latencyMode: input.latencyMode } : {}),
|
|
1962
|
-
delivery:
|
|
2057
|
+
delivery: effectiveDelivery,
|
|
1963
2058
|
routing,
|
|
1964
2059
|
initiator: frozenInitiator.initiator,
|
|
1965
2060
|
},
|
|
@@ -1980,7 +2075,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
1980
2075
|
status: "queued",
|
|
1981
2076
|
source: input.source,
|
|
1982
2077
|
promptRouting: routing,
|
|
1983
|
-
position:
|
|
2078
|
+
position: effectiveDelivery === "steer" ? 0 : existingQueued.length + 1,
|
|
1984
2079
|
prompt: input.text,
|
|
1985
2080
|
annotations,
|
|
1986
2081
|
modelContext: effectiveModelContext,
|
|
@@ -2072,7 +2167,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2072
2167
|
});
|
|
2073
2168
|
|
|
2074
2169
|
const supersession =
|
|
2075
|
-
|
|
2170
|
+
effectiveDelivery === "steer"
|
|
2076
2171
|
? await supersedeSessionCurrentDirectionInTransaction(db, {
|
|
2077
2172
|
accountId: input.accountId,
|
|
2078
2173
|
workspaceId: input.workspaceId,
|
|
@@ -2085,8 +2180,10 @@ export async function submitHumanPromptInTransaction(
|
|
|
2085
2180
|
})
|
|
2086
2181
|
: {
|
|
2087
2182
|
interruptionCount: 0,
|
|
2183
|
+
steerTargetTurn: null,
|
|
2088
2184
|
replacedTurn: null,
|
|
2089
2185
|
liveCurrentTurnId: null,
|
|
2186
|
+
deferredUntilCompaction: false,
|
|
2090
2187
|
lastSequence: session.lastSequence,
|
|
2091
2188
|
};
|
|
2092
2189
|
// Ownerless Steer settlement may have appended interrupted tool results.
|
|
@@ -2094,9 +2191,11 @@ export async function submitHumanPromptInTransaction(
|
|
|
2094
2191
|
sequence = supersession.lastSequence;
|
|
2095
2192
|
for (const event of eventValues) event.sequence = ++sequence;
|
|
2096
2193
|
const interruptionCount = supersession.interruptionCount;
|
|
2194
|
+
const steerTargetTurn = supersession.steerTargetTurn;
|
|
2097
2195
|
const replacedTurnId = supersession.replacedTurn?.id ?? null;
|
|
2098
2196
|
const replacedAttemptId = supersession.replacedTurn?.activeAttemptId ?? null;
|
|
2099
2197
|
const liveCurrentTurnId = supersession.liveCurrentTurnId;
|
|
2198
|
+
const deferredUntilCompaction = supersession.deferredUntilCompaction;
|
|
2100
2199
|
// Durable provenance for the queue projection. Until the superseded attempt
|
|
2101
2200
|
// loses inference, user-visible output, and workspace-persistence authority,
|
|
2102
2201
|
// its exact first-class attempt has no quiescence receipt. Pairing that
|
|
@@ -2104,7 +2203,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2104
2203
|
// attempt…" truthfully across refresh/reconnect, even though logical
|
|
2105
2204
|
// settlement has already cleared sessions.active_turn_id. Do not infer this
|
|
2106
2205
|
// state from a local request spinner or queue position.
|
|
2107
|
-
if (
|
|
2206
|
+
if (effectiveDelivery === "steer") {
|
|
2108
2207
|
const [updatedTurn] = await db
|
|
2109
2208
|
.update(schema.sessionTurns)
|
|
2110
2209
|
.set({
|
|
@@ -2114,6 +2213,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2114
2213
|
replacedTurnId,
|
|
2115
2214
|
replacedAttemptId,
|
|
2116
2215
|
interruptionCount,
|
|
2216
|
+
...(deferredUntilCompaction ? { deferredUntilCompaction: true } : {}),
|
|
2117
2217
|
},
|
|
2118
2218
|
updatedAt: now,
|
|
2119
2219
|
})
|
|
@@ -2130,8 +2230,8 @@ export async function submitHumanPromptInTransaction(
|
|
|
2130
2230
|
}
|
|
2131
2231
|
committedTurn = updatedTurn;
|
|
2132
2232
|
}
|
|
2133
|
-
if (
|
|
2134
|
-
const current =
|
|
2233
|
+
if (steerTargetTurn) {
|
|
2234
|
+
const current = steerTargetTurn;
|
|
2135
2235
|
if (!liveCurrentTurnId) {
|
|
2136
2236
|
eventValues.push({
|
|
2137
2237
|
accountId: input.accountId,
|
|
@@ -2157,8 +2257,9 @@ export async function submitHumanPromptInTransaction(
|
|
|
2157
2257
|
payload: {
|
|
2158
2258
|
operationId: reserved.receipt.id,
|
|
2159
2259
|
targetTurnId: turnId,
|
|
2160
|
-
replacedTurnId
|
|
2161
|
-
stopping: liveCurrentTurnId !== null,
|
|
2260
|
+
replacedTurnId,
|
|
2261
|
+
stopping: liveCurrentTurnId !== null && !deferredUntilCompaction,
|
|
2262
|
+
...(deferredUntilCompaction ? { deferredUntilCompaction: true } : {}),
|
|
2162
2263
|
},
|
|
2163
2264
|
occurredAt: now,
|
|
2164
2265
|
});
|
|
@@ -2188,7 +2289,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2188
2289
|
}
|
|
2189
2290
|
|
|
2190
2291
|
const ordered =
|
|
2191
|
-
|
|
2292
|
+
effectiveDelivery === "steer" ? [turn, ...existingQueued] : [...existingQueued, turn];
|
|
2192
2293
|
await normalizeQueuePositions(
|
|
2193
2294
|
db,
|
|
2194
2295
|
input.workspaceId,
|
|
@@ -2196,7 +2297,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2196
2297
|
ordered.map((row) => row.id),
|
|
2197
2298
|
);
|
|
2198
2299
|
const noCurrentAfter =
|
|
2199
|
-
|
|
2300
|
+
effectiveDelivery === "steer" ? liveCurrentTurnId === null : !session.activeTurnId;
|
|
2200
2301
|
const nextStatus = noCurrentAfter ? "queued" : session.status;
|
|
2201
2302
|
if (nextStatus !== session.status) {
|
|
2202
2303
|
eventValues.push({
|
|
@@ -2223,12 +2324,12 @@ export async function submitHumanPromptInTransaction(
|
|
|
2223
2324
|
turnId,
|
|
2224
2325
|
channel: null,
|
|
2225
2326
|
text: renderRealtimeHumanInputContext({
|
|
2226
|
-
delivery:
|
|
2327
|
+
delivery: effectiveDelivery,
|
|
2227
2328
|
routing,
|
|
2228
2329
|
text: renderTimelineAnnotationsForModel(input.text, annotations),
|
|
2229
2330
|
}),
|
|
2230
2331
|
payload: {
|
|
2231
|
-
delivery:
|
|
2332
|
+
delivery: effectiveDelivery,
|
|
2232
2333
|
routing,
|
|
2233
2334
|
acceptedEventId,
|
|
2234
2335
|
instruction: "OpenGeni accepted and routed this user input; do not delegate it again.",
|
|
@@ -2242,7 +2343,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2242
2343
|
.set({
|
|
2243
2344
|
resources: mergeResourceRefs(session.resources as ResourceRef[], input.resources),
|
|
2244
2345
|
tools: session.tools,
|
|
2245
|
-
activeTurnId:
|
|
2346
|
+
activeTurnId: effectiveDelivery === "steer" ? liveCurrentTurnId : session.activeTurnId,
|
|
2246
2347
|
status: nextStatus,
|
|
2247
2348
|
queueVersion,
|
|
2248
2349
|
queueHeadPosition: 0,
|
|
@@ -2276,8 +2377,8 @@ export async function submitHumanPromptInTransaction(
|
|
|
2276
2377
|
workspaceId: input.workspaceId,
|
|
2277
2378
|
sessionId: input.sessionId,
|
|
2278
2379
|
temporalWorkflowId: workflowId,
|
|
2279
|
-
reason:
|
|
2280
|
-
controlRequested:
|
|
2380
|
+
reason: effectiveDelivery === "steer" ? "prompt_steer" : "prompt_send",
|
|
2381
|
+
controlRequested: effectiveDelivery === "steer",
|
|
2281
2382
|
});
|
|
2282
2383
|
await db.insert(schema.auditEvents).values(
|
|
2283
2384
|
withLosslessContentWriteVersion(
|
|
@@ -2288,13 +2389,14 @@ export async function submitHumanPromptInTransaction(
|
|
|
2288
2389
|
input.actor.type === "agent_attempt"
|
|
2289
2390
|
? `attempt:${input.actor.attemptId}`
|
|
2290
2391
|
: input.actor.subjectId,
|
|
2291
|
-
action:
|
|
2392
|
+
action: effectiveDelivery === "steer" ? "session.prompt.steer" : "session.prompt.send",
|
|
2292
2393
|
targetType: "session_turn",
|
|
2293
2394
|
targetId: turnId,
|
|
2294
2395
|
metadata: {
|
|
2295
2396
|
operationId: reserved.receipt.id,
|
|
2296
2397
|
replacedTurnId,
|
|
2297
2398
|
interruptionCount,
|
|
2399
|
+
deferredUntilCompaction,
|
|
2298
2400
|
...(input.turnExecutionPolicy
|
|
2299
2401
|
? turnExecutionPolicyAuditMetadata(input.turnExecutionPolicy, turnId)
|
|
2300
2402
|
: {}),
|
|
@@ -2338,6 +2440,7 @@ export async function submitHumanPromptInTransaction(
|
|
|
2338
2440
|
wakeRevision,
|
|
2339
2441
|
interruptionCount,
|
|
2340
2442
|
replacedTurnId,
|
|
2443
|
+
deferredUntilCompaction,
|
|
2341
2444
|
workspaceControlEventId: resumed.workspaceControlEventId,
|
|
2342
2445
|
routing,
|
|
2343
2446
|
...(input.turnExecutionPolicy
|
|
@@ -2815,16 +2918,17 @@ export async function steerAgentSessionInTransaction(
|
|
|
2815
2918
|
sessionId: input.targetSessionId,
|
|
2816
2919
|
sequence: ++sequence,
|
|
2817
2920
|
type: "session.control.steer_requested",
|
|
2818
|
-
turnId: supersession.
|
|
2819
|
-
turnGeneration: supersession.
|
|
2820
|
-
turnAttemptId: supersession.
|
|
2821
|
-
turnAssociation: supersession.
|
|
2921
|
+
turnId: supersession.steerTargetTurn?.id ?? null,
|
|
2922
|
+
turnGeneration: supersession.steerTargetTurn?.executionGeneration ?? null,
|
|
2923
|
+
turnAttemptId: supersession.steerTargetTurn?.activeAttemptId ?? null,
|
|
2924
|
+
turnAssociation: supersession.steerTargetTurn ? "current" : null,
|
|
2822
2925
|
payload: {
|
|
2823
2926
|
operationId: reserved.receipt.id,
|
|
2824
2927
|
targetUpdateId: update.id,
|
|
2825
2928
|
replacedTurnId: supersession.replacedTurn?.id ?? null,
|
|
2826
2929
|
actorSessionId: input.actor.sessionId,
|
|
2827
|
-
stopping: supersession.liveCurrentTurnId !== null,
|
|
2930
|
+
stopping: supersession.liveCurrentTurnId !== null && !supersession.deferredUntilCompaction,
|
|
2931
|
+
...(supersession.deferredUntilCompaction ? { deferredUntilCompaction: true } : {}),
|
|
2828
2932
|
},
|
|
2829
2933
|
occurredAt: now,
|
|
2830
2934
|
},
|
|
@@ -2912,6 +3016,7 @@ export async function steerAgentSessionInTransaction(
|
|
|
2912
3016
|
callerExecutionGeneration: input.actor.executionGeneration,
|
|
2913
3017
|
controlRevision: resumed.revision,
|
|
2914
3018
|
interruptionCount: supersession.interruptionCount,
|
|
3019
|
+
deferredUntilCompaction: supersession.deferredUntilCompaction,
|
|
2915
3020
|
workspaceControlEventId: resumed.workspaceControlEventId,
|
|
2916
3021
|
},
|
|
2917
3022
|
},
|
|
@@ -2928,6 +3033,7 @@ export async function steerAgentSessionInTransaction(
|
|
|
2928
3033
|
wakeRevision,
|
|
2929
3034
|
workflowId,
|
|
2930
3035
|
interruptionCount: supersession.interruptionCount,
|
|
3036
|
+
deferredUntilCompaction: supersession.deferredUntilCompaction,
|
|
2931
3037
|
},
|
|
2932
3038
|
});
|
|
2933
3039
|
return {
|
|
@@ -19,9 +19,16 @@ export function historyCallId(item: Record<string, unknown>): string | null {
|
|
|
19
19
|
item.providerData && typeof item.providerData === "object" && !Array.isArray(item.providerData)
|
|
20
20
|
? (item.providerData as Record<string, unknown>)
|
|
21
21
|
: null;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
// Native tool-search `id` is the provider item id, not the call correlation
|
|
23
|
+
// id. Validate direct and provider identities before the item-id fallback.
|
|
24
|
+
const value = [
|
|
25
|
+
item.callId,
|
|
26
|
+
item.call_id,
|
|
27
|
+
providerData?.callId,
|
|
28
|
+
providerData?.call_id,
|
|
29
|
+
item.id,
|
|
30
|
+
].find((candidate): candidate is string => typeof candidate === "string" && candidate.length > 0);
|
|
31
|
+
return value ?? null;
|
|
25
32
|
}
|
|
26
33
|
|
|
27
34
|
export function historyItemType(item: Record<string, unknown>): string | null {
|
|
@@ -68,13 +75,33 @@ export function interruptedToolCallResult(input: {
|
|
|
68
75
|
}
|
|
69
76
|
if (input.callType === "computer_call") return null;
|
|
70
77
|
if (input.callType === "tool_search_call") {
|
|
78
|
+
const providerData =
|
|
79
|
+
input.callItem.providerData &&
|
|
80
|
+
typeof input.callItem.providerData === "object" &&
|
|
81
|
+
!Array.isArray(input.callItem.providerData)
|
|
82
|
+
? (input.callItem.providerData as Record<string, unknown>)
|
|
83
|
+
: null;
|
|
84
|
+
const execution =
|
|
85
|
+
input.callItem.execution === "client" || input.callItem.execution === "server"
|
|
86
|
+
? input.callItem.execution
|
|
87
|
+
: providerData?.execution === "client" || providerData?.execution === "server"
|
|
88
|
+
? providerData.execution
|
|
89
|
+
: null;
|
|
90
|
+
const providerIdentity =
|
|
91
|
+
typeof providerData?.call_id === "string" || typeof providerData?.callId === "string";
|
|
71
92
|
const snakeId = typeof input.callItem.call_id === "string";
|
|
72
93
|
return {
|
|
73
94
|
type: "tool_search_output",
|
|
74
|
-
...(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
95
|
+
...(providerIdentity
|
|
96
|
+
? {
|
|
97
|
+
providerData: {
|
|
98
|
+
call_id: input.callId,
|
|
99
|
+
...(execution ? { execution } : {}),
|
|
100
|
+
},
|
|
101
|
+
}
|
|
102
|
+
: snakeId
|
|
103
|
+
? { call_id: input.callId, ...(execution ? { execution } : {}) }
|
|
104
|
+
: { callId: input.callId, ...(execution ? { execution } : {}) }),
|
|
78
105
|
status: "incomplete",
|
|
79
106
|
tools: [],
|
|
80
107
|
};
|
|
@@ -301,6 +301,62 @@ export async function issueSelfUserResourceGrant(
|
|
|
301
301
|
});
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
export async function issueSelfLocalConnectionUseGrant(
|
|
305
|
+
db: Database,
|
|
306
|
+
input: {
|
|
307
|
+
accountId: string;
|
|
308
|
+
workspaceId: string;
|
|
309
|
+
subjectId: string;
|
|
310
|
+
authorityId: string;
|
|
311
|
+
context: "user_private" | "workspace_shared";
|
|
312
|
+
workspaceSharedAcknowledged: boolean;
|
|
313
|
+
},
|
|
314
|
+
): Promise<UserResourceAuthorityGrant> {
|
|
315
|
+
return await withOwnerContext(db, input, async (scopedDb) => {
|
|
316
|
+
const [row] = await rawRows<
|
|
317
|
+
Omit<UserResourceAuthorityGrant, "delegation"> & {
|
|
318
|
+
organizationId: string;
|
|
319
|
+
authorityGeneration: number;
|
|
320
|
+
}
|
|
321
|
+
>(
|
|
322
|
+
scopedDb,
|
|
323
|
+
sql`
|
|
324
|
+
select grant_id as "grantId", organization_id as "organizationId",
|
|
325
|
+
authority_generation::int as "authorityGeneration",
|
|
326
|
+
target_workspace_id as "targetWorkspaceId",
|
|
327
|
+
target_session_id as "targetSessionId", action, grant_mode as mode,
|
|
328
|
+
grant_context as context, authority_epoch::int as "authorityEpoch",
|
|
329
|
+
grant_generation::int as generation, grant_status as status,
|
|
330
|
+
expires_at::text as "expiresAt"
|
|
331
|
+
from issue_self_local_connection_use_grant(
|
|
332
|
+
${input.accountId}::uuid, ${input.authorityId}::uuid,
|
|
333
|
+
${input.workspaceId}::uuid, ${input.context},
|
|
334
|
+
${input.workspaceSharedAcknowledged}
|
|
335
|
+
)
|
|
336
|
+
`,
|
|
337
|
+
);
|
|
338
|
+
if (!row) throw new Error("local connection grant was not returned");
|
|
339
|
+
const { organizationId, authorityGeneration, ...grant } = row;
|
|
340
|
+
return {
|
|
341
|
+
...grant,
|
|
342
|
+
expiresAt: rfc3339(grant.expiresAt),
|
|
343
|
+
delegation: {
|
|
344
|
+
authorityId: input.authorityId,
|
|
345
|
+
grantId: grant.grantId,
|
|
346
|
+
organizationId,
|
|
347
|
+
workspaceId: grant.targetWorkspaceId,
|
|
348
|
+
sessionId: grant.targetSessionId,
|
|
349
|
+
action: grant.action,
|
|
350
|
+
mode: grant.mode,
|
|
351
|
+
context: grant.context,
|
|
352
|
+
authorityEpoch: grant.authorityEpoch,
|
|
353
|
+
authorityGeneration,
|
|
354
|
+
grantGeneration: grant.generation,
|
|
355
|
+
},
|
|
356
|
+
};
|
|
357
|
+
});
|
|
358
|
+
}
|
|
359
|
+
|
|
304
360
|
export async function revokeSelfUserResourceGrant(
|
|
305
361
|
db: Database,
|
|
306
362
|
input: { accountId: string; workspaceId: string; subjectId: string; grantId: string },
|