@opengeni/core 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +138 -26
- package/dist/index.js +485 -50
- package/dist/index.js.map +1 -1
- package/package.json +8 -8
- package/src/access/index.ts +4 -0
- package/src/application/session-commands.ts +527 -0
- package/src/dependencies.ts +4 -13
- package/src/domain/sessions.ts +83 -63
- package/src/index.ts +2 -0
- package/src/workflow-wake-contract.ts +6 -0
package/dist/index.js
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
// src/workflow-wake-contract.ts
|
|
2
|
+
var SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID = "opengeni-session-workflow-wake-dispatcher";
|
|
3
|
+
var SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_TYPE = "sessionWorkflowWakeDispatcherWorkflow";
|
|
4
|
+
var SESSION_WORKFLOW_WAKE_DISPATCHER_PERIOD_MS = 1e4;
|
|
5
|
+
|
|
1
6
|
// src/sandbox/fleet.ts
|
|
2
7
|
import {
|
|
3
8
|
getEnrollment,
|
|
@@ -558,7 +563,9 @@ async function delegatedAccessContext(c, deps, mode, token = bearerToken(c)) {
|
|
|
558
563
|
...payload.sessionId ? { sessionId: payload.sessionId } : {},
|
|
559
564
|
// Caller identity: the turn that minted this token. Tools classify the
|
|
560
565
|
// CALLER from this instead of re-reading the live active pointer.
|
|
561
|
-
...payload.turnId ? { turnId: payload.turnId } : {}
|
|
566
|
+
...payload.turnId ? { turnId: payload.turnId } : {},
|
|
567
|
+
...payload.attemptId ? { attemptId: payload.attemptId } : {},
|
|
568
|
+
...payload.executionGeneration ? { executionGeneration: payload.executionGeneration } : {}
|
|
562
569
|
}
|
|
563
570
|
}
|
|
564
571
|
],
|
|
@@ -2596,7 +2603,6 @@ import {
|
|
|
2596
2603
|
import {
|
|
2597
2604
|
createSession,
|
|
2598
2605
|
createSessionWithIdempotencyKey,
|
|
2599
|
-
enqueueSessionMessageAtomically,
|
|
2600
2606
|
encryptVariableSetValue as encryptVariableSetValue2,
|
|
2601
2607
|
getAnySessionInGroup,
|
|
2602
2608
|
getEnrollment as getEnrollment2,
|
|
@@ -2607,17 +2613,23 @@ import {
|
|
|
2607
2613
|
getSandbox as getSandbox3,
|
|
2608
2614
|
getSession,
|
|
2609
2615
|
getSessionByCreateIdempotencyKey,
|
|
2616
|
+
getSessionEvent,
|
|
2617
|
+
getWorkspaceControlEvent,
|
|
2610
2618
|
getSessionLineage,
|
|
2611
2619
|
getSessionTurn,
|
|
2612
2620
|
getWorkspaceModelPolicy,
|
|
2613
2621
|
initializeSessionStartAtomically,
|
|
2614
2622
|
requireSession as requireSession2,
|
|
2623
|
+
submitHumanPromptInTransaction,
|
|
2615
2624
|
updateSessionTitle as updateSessionTitleRow,
|
|
2616
|
-
|
|
2625
|
+
withWorkspaceSubjectRls,
|
|
2626
|
+
QueueCommandConflictError,
|
|
2627
|
+
SessionControlConflictError
|
|
2617
2628
|
} from "@opengeni/db";
|
|
2618
2629
|
import {
|
|
2619
2630
|
appendAndPublishEvents,
|
|
2620
|
-
publishDurableSessionEvents
|
|
2631
|
+
publishDurableSessionEvents,
|
|
2632
|
+
publishDurableWorkspaceControlEvent
|
|
2621
2633
|
} from "@opengeni/events";
|
|
2622
2634
|
import { HTTPException as HTTPException9 } from "hono/http-exception";
|
|
2623
2635
|
var reservedSessionMcpServerIds = /* @__PURE__ */ new Set(["opengeni", "files", "docs", "codex_apps"]);
|
|
@@ -2942,30 +2954,37 @@ async function postUserMessageTurn(input) {
|
|
|
2942
2954
|
const requestedReasoningEffort = input.reasoningEffort ?? null;
|
|
2943
2955
|
assertConfiguredModel(settings, requestedModel);
|
|
2944
2956
|
await assertWorkspaceModelPolicyAllows(db, settings, workspaceId, requestedModel);
|
|
2957
|
+
const operationKey = input.clientEventId ?? crypto.randomUUID();
|
|
2945
2958
|
let result;
|
|
2946
2959
|
try {
|
|
2947
|
-
result = await
|
|
2948
|
-
|
|
2960
|
+
result = await withWorkspaceSubjectRls(
|
|
2961
|
+
db,
|
|
2949
2962
|
workspaceId,
|
|
2950
|
-
|
|
2951
|
-
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
|
|
2955
|
-
|
|
2956
|
-
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
2962
|
-
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2963
|
+
input.actor ?? accountId,
|
|
2964
|
+
(scoped) => scoped.transaction(
|
|
2965
|
+
(tx) => submitHumanPromptInTransaction(tx, {
|
|
2966
|
+
accountId,
|
|
2967
|
+
workspaceId,
|
|
2968
|
+
sessionId,
|
|
2969
|
+
subjectId: input.actor ?? accountId,
|
|
2970
|
+
actor: { type: "human", subjectId: input.actor ?? accountId },
|
|
2971
|
+
operationKey,
|
|
2972
|
+
delivery: input.delivery ?? "send",
|
|
2973
|
+
controlEtag: input.controlEtag ?? null,
|
|
2974
|
+
expectedDraftRevision: input.expectedDraftRevision ?? null,
|
|
2975
|
+
text: input.text,
|
|
2976
|
+
resources: input.resources,
|
|
2977
|
+
tools: input.tools,
|
|
2978
|
+
model: requestedModel,
|
|
2979
|
+
reasoningEffort: requestedReasoningEffort,
|
|
2980
|
+
reasoningEffortFallback: settings.openaiReasoningEffort,
|
|
2981
|
+
source: input.origin === "operator" ? "api" : "user",
|
|
2982
|
+
mcpCredentialUpdates: input.mcpCredentialUpdates ?? []
|
|
2983
|
+
})
|
|
2984
|
+
)
|
|
2985
|
+
);
|
|
2967
2986
|
} catch (error) {
|
|
2968
|
-
if (error instanceof
|
|
2987
|
+
if (error instanceof QueueCommandConflictError || error instanceof SessionControlConflictError) {
|
|
2969
2988
|
throw new HTTPException9(409, { message: error.message });
|
|
2970
2989
|
}
|
|
2971
2990
|
if (error instanceof Error && error.message.includes("cancelled")) {
|
|
@@ -2976,35 +2995,51 @@ async function postUserMessageTurn(input) {
|
|
|
2976
2995
|
}
|
|
2977
2996
|
throw error;
|
|
2978
2997
|
}
|
|
2979
|
-
await
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
|
|
2985
|
-
|
|
2998
|
+
const events = await Promise.all(
|
|
2999
|
+
result.eventIds.map((eventId) => getSessionEvent(db, workspaceId, eventId))
|
|
3000
|
+
);
|
|
3001
|
+
if (events.some((event) => event === null)) {
|
|
3002
|
+
throw new Error("Committed prompt events could not be reloaded");
|
|
3003
|
+
}
|
|
3004
|
+
const turn = await getSessionTurn(db, workspaceId, result.turnId);
|
|
3005
|
+
if (!turn) throw new Error("Committed prompt turn could not be reloaded");
|
|
3006
|
+
const accepted = events.find((event) => event?.id === result.acceptedEventId);
|
|
3007
|
+
if (!accepted) throw new Error("Committed user.message event could not be reloaded");
|
|
3008
|
+
await publishDurableSessionEvents(
|
|
3009
|
+
bus,
|
|
3010
|
+
workspaceId,
|
|
3011
|
+
sessionId,
|
|
3012
|
+
events.filter((event) => event !== null)
|
|
3013
|
+
);
|
|
3014
|
+
if (result.workspaceControlEventId) {
|
|
3015
|
+
const controlEvent = await getWorkspaceControlEvent(
|
|
3016
|
+
db,
|
|
2986
3017
|
workspaceId,
|
|
2987
|
-
|
|
2988
|
-
|
|
2989
|
-
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
if (result.workflowWakeRevision === null) {
|
|
2994
|
-
throw new Error("Runnable prompt has no workflow wake revision");
|
|
3018
|
+
result.workspaceControlEventId
|
|
3019
|
+
);
|
|
3020
|
+
if (!controlEvent) {
|
|
3021
|
+
throw new Error(
|
|
3022
|
+
`Committed workspace control event disappeared: ${result.workspaceControlEventId}`
|
|
3023
|
+
);
|
|
2995
3024
|
}
|
|
3025
|
+
await publishDurableWorkspaceControlEvent(bus, workspaceId, controlEvent);
|
|
3026
|
+
}
|
|
3027
|
+
try {
|
|
2996
3028
|
await workflowClient.wakeSessionWorkflow({
|
|
2997
3029
|
accountId,
|
|
2998
3030
|
workspaceId,
|
|
2999
3031
|
sessionId,
|
|
3000
|
-
workflowId:
|
|
3001
|
-
wakeRevision: result.
|
|
3032
|
+
workflowId: turn.temporalWorkflowId,
|
|
3033
|
+
wakeRevision: result.wakeRevision,
|
|
3034
|
+
...result.interruptionCount > 0 ? { interruptionRequested: true } : {}
|
|
3002
3035
|
});
|
|
3036
|
+
} catch (error) {
|
|
3037
|
+
console.warn(
|
|
3038
|
+
`[sessions] workflow wake failed for committed prompt ${workspaceId}/${sessionId}; durable outbox will retry`,
|
|
3039
|
+
error
|
|
3040
|
+
);
|
|
3003
3041
|
}
|
|
3004
|
-
return {
|
|
3005
|
-
accepted: result.accepted,
|
|
3006
|
-
turn: result.turn
|
|
3007
|
-
};
|
|
3042
|
+
return { accepted, turn };
|
|
3008
3043
|
}
|
|
3009
3044
|
async function createSessionForRequest(deps, grant, workspaceId, rawPayload) {
|
|
3010
3045
|
const { settings, db, bus, workflowClient, objectStorage } = deps;
|
|
@@ -3290,13 +3325,11 @@ async function acceptSessionUserMessage(deps, grant, workspaceId, sessionId, inp
|
|
|
3290
3325
|
model: input.model ?? null,
|
|
3291
3326
|
reasoningEffort: input.reasoningEffort ?? null,
|
|
3292
3327
|
mcpCredentialUpdates,
|
|
3293
|
-
delivery: input.delivery ?? "
|
|
3328
|
+
delivery: input.delivery ?? "send",
|
|
3294
3329
|
origin: input.origin ?? "human",
|
|
3295
3330
|
actor: grant.subjectId,
|
|
3296
|
-
...input.
|
|
3297
|
-
...input.
|
|
3298
|
-
expectedWorkspaceInferenceGeneration: input.expectedWorkspaceInferenceGeneration
|
|
3299
|
-
} : {},
|
|
3331
|
+
...input.controlEtag !== void 0 ? { controlEtag: input.controlEtag } : {},
|
|
3332
|
+
...input.expectedDraftRevision !== void 0 ? { expectedDraftRevision: input.expectedDraftRevision } : {},
|
|
3300
3333
|
...input.clientEventId ? { clientEventId: input.clientEventId } : {}
|
|
3301
3334
|
});
|
|
3302
3335
|
await recordWorkspaceUsage(deps, {
|
|
@@ -3611,6 +3644,394 @@ function assertWorkspaceDeletable(input) {
|
|
|
3611
3644
|
});
|
|
3612
3645
|
}
|
|
3613
3646
|
}
|
|
3647
|
+
|
|
3648
|
+
// src/application/session-commands.ts
|
|
3649
|
+
import { reasoningEffortForMetadata as reasoningEffortForMetadata2 } from "@opengeni/contracts";
|
|
3650
|
+
import {
|
|
3651
|
+
deleteSessionQueueItemInTransaction,
|
|
3652
|
+
editQueuedTurnInTransaction,
|
|
3653
|
+
getComposerDraftInTransaction,
|
|
3654
|
+
getSession as getSession2,
|
|
3655
|
+
getSessionEvent as getSessionEvent2,
|
|
3656
|
+
getWorkspaceControlEvent as getWorkspaceControlEvent2,
|
|
3657
|
+
getSessionQueueSnapshot,
|
|
3658
|
+
moveQueuedTurnInTransaction,
|
|
3659
|
+
mutateSessionControlInTransaction,
|
|
3660
|
+
mutateWorkspaceControlInTransaction,
|
|
3661
|
+
saveComposerDraftInTransaction,
|
|
3662
|
+
sendAgentMessageInTransaction,
|
|
3663
|
+
serializeEffectiveSessionControl,
|
|
3664
|
+
steerAgentSessionInTransaction,
|
|
3665
|
+
steerQueuedTurnInTransaction,
|
|
3666
|
+
withWorkspaceRls,
|
|
3667
|
+
withWorkspaceSubjectRls as withWorkspaceSubjectRls2
|
|
3668
|
+
} from "@opengeni/db";
|
|
3669
|
+
import {
|
|
3670
|
+
publishDurableSessionEvents as publishDurableSessionEvents2,
|
|
3671
|
+
publishDurableWorkspaceControlEvent as publishDurableWorkspaceControlEvent2
|
|
3672
|
+
} from "@opengeni/events";
|
|
3673
|
+
function agentActor(context) {
|
|
3674
|
+
return {
|
|
3675
|
+
type: "agent_attempt",
|
|
3676
|
+
sessionId: context.callerSessionId,
|
|
3677
|
+
turnId: context.callerTurnId,
|
|
3678
|
+
attemptId: context.callerAttemptId,
|
|
3679
|
+
executionGeneration: context.callerExecutionGeneration
|
|
3680
|
+
};
|
|
3681
|
+
}
|
|
3682
|
+
async function publishAndWakeAgentCommand(deps, input) {
|
|
3683
|
+
await publishSessionEventIds(deps, input.workspaceId, input.sessionId, input.eventIds);
|
|
3684
|
+
if (!input.shouldSignal || input.wakeRevision === null) return;
|
|
3685
|
+
try {
|
|
3686
|
+
await deps.workflowClient.wakeSessionWorkflow({
|
|
3687
|
+
accountId: input.accountId,
|
|
3688
|
+
workspaceId: input.workspaceId,
|
|
3689
|
+
sessionId: input.sessionId,
|
|
3690
|
+
workflowId: input.workflowId,
|
|
3691
|
+
wakeRevision: input.wakeRevision,
|
|
3692
|
+
...input.interruptionCount > 0 ? { interruptionRequested: true } : {}
|
|
3693
|
+
});
|
|
3694
|
+
} catch (error) {
|
|
3695
|
+
console.warn(
|
|
3696
|
+
`[session-commands] immediate Agent command wake failed for ${input.workspaceId}/${input.sessionId}; durable outbox will retry`,
|
|
3697
|
+
error
|
|
3698
|
+
);
|
|
3699
|
+
}
|
|
3700
|
+
}
|
|
3701
|
+
async function requestControlWakeDispatch(deps, wakeCount) {
|
|
3702
|
+
if (wakeCount === 0) return;
|
|
3703
|
+
try {
|
|
3704
|
+
await deps.workflowClient.requestSessionWorkflowWakeDispatch();
|
|
3705
|
+
} catch (error) {
|
|
3706
|
+
console.warn(
|
|
3707
|
+
`[session-commands] immediate control wake dispatch failed for ${wakeCount} committed revisions; durable outbox will retry`,
|
|
3708
|
+
error
|
|
3709
|
+
);
|
|
3710
|
+
}
|
|
3711
|
+
}
|
|
3712
|
+
async function publishSessionEventIds(deps, workspaceId, sessionId, eventIds) {
|
|
3713
|
+
if (eventIds.length === 0) return;
|
|
3714
|
+
const events = await Promise.all(
|
|
3715
|
+
eventIds.map((eventId) => getSessionEvent2(deps.db, workspaceId, eventId))
|
|
3716
|
+
);
|
|
3717
|
+
await publishDurableSessionEvents2(
|
|
3718
|
+
deps.bus,
|
|
3719
|
+
workspaceId,
|
|
3720
|
+
sessionId,
|
|
3721
|
+
events.filter((event) => event !== null)
|
|
3722
|
+
);
|
|
3723
|
+
}
|
|
3724
|
+
async function publishWorkspaceControlEvent(deps, workspaceId, eventId) {
|
|
3725
|
+
if (!eventId) return;
|
|
3726
|
+
const event = await getWorkspaceControlEvent2(deps.db, workspaceId, eventId);
|
|
3727
|
+
if (!event) {
|
|
3728
|
+
throw new Error(`Committed workspace control event disappeared: ${eventId}`);
|
|
3729
|
+
}
|
|
3730
|
+
await publishDurableWorkspaceControlEvent2(deps.bus, workspaceId, event);
|
|
3731
|
+
}
|
|
3732
|
+
async function sendAgentSessionMessage(deps, context, input) {
|
|
3733
|
+
const result = await withWorkspaceRls(
|
|
3734
|
+
deps.db,
|
|
3735
|
+
context.workspaceId,
|
|
3736
|
+
(scoped) => scoped.transaction(
|
|
3737
|
+
(tx) => sendAgentMessageInTransaction(tx, {
|
|
3738
|
+
accountId: context.accountId,
|
|
3739
|
+
workspaceId: context.workspaceId,
|
|
3740
|
+
targetSessionId: input.targetSessionId,
|
|
3741
|
+
actor: agentActor(context),
|
|
3742
|
+
operationKey: input.idempotencyKey,
|
|
3743
|
+
text: input.text
|
|
3744
|
+
})
|
|
3745
|
+
)
|
|
3746
|
+
);
|
|
3747
|
+
await publishAndWakeAgentCommand(deps, {
|
|
3748
|
+
accountId: context.accountId,
|
|
3749
|
+
workspaceId: context.workspaceId,
|
|
3750
|
+
sessionId: input.targetSessionId,
|
|
3751
|
+
eventIds: result.eventIds,
|
|
3752
|
+
workflowId: result.workflowId,
|
|
3753
|
+
wakeRevision: result.wakeRevision,
|
|
3754
|
+
shouldSignal: result.shouldSignal,
|
|
3755
|
+
interruptionCount: 0
|
|
3756
|
+
});
|
|
3757
|
+
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
3758
|
+
return result;
|
|
3759
|
+
}
|
|
3760
|
+
async function steerAgentSession(deps, context, input) {
|
|
3761
|
+
const result = await withWorkspaceRls(
|
|
3762
|
+
deps.db,
|
|
3763
|
+
context.workspaceId,
|
|
3764
|
+
(scoped) => scoped.transaction(
|
|
3765
|
+
(tx) => steerAgentSessionInTransaction(tx, {
|
|
3766
|
+
accountId: context.accountId,
|
|
3767
|
+
workspaceId: context.workspaceId,
|
|
3768
|
+
targetSessionId: input.targetSessionId,
|
|
3769
|
+
actor: agentActor(context),
|
|
3770
|
+
operationKey: input.idempotencyKey,
|
|
3771
|
+
instruction: input.instruction
|
|
3772
|
+
})
|
|
3773
|
+
)
|
|
3774
|
+
);
|
|
3775
|
+
await publishAndWakeAgentCommand(deps, {
|
|
3776
|
+
accountId: context.accountId,
|
|
3777
|
+
workspaceId: context.workspaceId,
|
|
3778
|
+
sessionId: input.targetSessionId,
|
|
3779
|
+
eventIds: result.eventIds,
|
|
3780
|
+
workflowId: result.workflowId,
|
|
3781
|
+
wakeRevision: result.wakeRevision,
|
|
3782
|
+
shouldSignal: result.shouldSignal,
|
|
3783
|
+
interruptionCount: result.interruptionCount
|
|
3784
|
+
});
|
|
3785
|
+
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
3786
|
+
return result;
|
|
3787
|
+
}
|
|
3788
|
+
async function controlAgentSessionWorkstream(deps, context, input) {
|
|
3789
|
+
const result = await withWorkspaceRls(
|
|
3790
|
+
deps.db,
|
|
3791
|
+
context.workspaceId,
|
|
3792
|
+
(scoped) => scoped.transaction(
|
|
3793
|
+
(tx) => mutateSessionControlInTransaction(tx, {
|
|
3794
|
+
accountId: context.accountId,
|
|
3795
|
+
workspaceId: context.workspaceId,
|
|
3796
|
+
sessionId: input.targetSessionId,
|
|
3797
|
+
actor: agentActor(context),
|
|
3798
|
+
operationKey: input.idempotencyKey,
|
|
3799
|
+
action: input.action,
|
|
3800
|
+
reason: input.reason ?? null
|
|
3801
|
+
})
|
|
3802
|
+
)
|
|
3803
|
+
);
|
|
3804
|
+
await publishSessionEventIds(deps, context.workspaceId, input.targetSessionId, [
|
|
3805
|
+
result.sessionControlEventId
|
|
3806
|
+
]);
|
|
3807
|
+
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
3808
|
+
await requestControlWakeDispatch(deps, result.wakeCount);
|
|
3809
|
+
return result;
|
|
3810
|
+
}
|
|
3811
|
+
function receipt(row) {
|
|
3812
|
+
return {
|
|
3813
|
+
id: row.id,
|
|
3814
|
+
action: row.action,
|
|
3815
|
+
operationKey: row.operationKey,
|
|
3816
|
+
targetSessionId: row.targetSessionId,
|
|
3817
|
+
targetTurnId: row.targetTurnId,
|
|
3818
|
+
appliedControlRevision: row.appliedControlRevision,
|
|
3819
|
+
appliedQueueVersion: row.appliedQueueVersion,
|
|
3820
|
+
appliedTurnVersion: row.appliedTurnVersion,
|
|
3821
|
+
appliedDraftRevision: row.appliedDraftRevision,
|
|
3822
|
+
createdAt: row.createdAt.toISOString()
|
|
3823
|
+
};
|
|
3824
|
+
}
|
|
3825
|
+
function composerDraft(row) {
|
|
3826
|
+
if (!row) return null;
|
|
3827
|
+
return {
|
|
3828
|
+
revision: row.revision,
|
|
3829
|
+
text: row.text,
|
|
3830
|
+
resources: row.resources,
|
|
3831
|
+
tools: row.tools,
|
|
3832
|
+
model: row.model,
|
|
3833
|
+
reasoningEffort: row.reasoningEffort,
|
|
3834
|
+
sourceTurnId: row.sourceTurnId,
|
|
3835
|
+
sourceTurnVersion: row.sourceTurnVersion,
|
|
3836
|
+
updatedAt: row.updatedAt.toISOString()
|
|
3837
|
+
};
|
|
3838
|
+
}
|
|
3839
|
+
async function authoritativeQueue(db, workspaceId, sessionId) {
|
|
3840
|
+
const snapshot = await getSessionQueueSnapshot(db, workspaceId, sessionId);
|
|
3841
|
+
if (!snapshot) throw new Error(`Session not found: ${sessionId}`);
|
|
3842
|
+
return snapshot;
|
|
3843
|
+
}
|
|
3844
|
+
async function moveHumanQueuePrompt(deps, context, turnId, input) {
|
|
3845
|
+
const result = await withWorkspaceRls(
|
|
3846
|
+
deps.db,
|
|
3847
|
+
context.workspaceId,
|
|
3848
|
+
(scoped) => scoped.transaction(
|
|
3849
|
+
(tx) => moveQueuedTurnInTransaction(tx, {
|
|
3850
|
+
...context,
|
|
3851
|
+
turnId,
|
|
3852
|
+
beforeTurnId: input.beforeTurnId,
|
|
3853
|
+
expectedQueueVersion: input.expectedQueueVersion,
|
|
3854
|
+
actor: { type: "human", subjectId: context.subjectId },
|
|
3855
|
+
operationKey: input.clientEventId
|
|
3856
|
+
})
|
|
3857
|
+
)
|
|
3858
|
+
);
|
|
3859
|
+
const response = {
|
|
3860
|
+
receipt: receipt(result.receipt),
|
|
3861
|
+
snapshot: await authoritativeQueue(deps.db, context.workspaceId, context.sessionId)
|
|
3862
|
+
};
|
|
3863
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds);
|
|
3864
|
+
return response;
|
|
3865
|
+
}
|
|
3866
|
+
async function deleteHumanQueuePrompt(deps, context, turnId, input) {
|
|
3867
|
+
const result = await withWorkspaceRls(
|
|
3868
|
+
deps.db,
|
|
3869
|
+
context.workspaceId,
|
|
3870
|
+
(scoped) => scoped.transaction(
|
|
3871
|
+
(tx) => deleteSessionQueueItemInTransaction(tx, {
|
|
3872
|
+
...context,
|
|
3873
|
+
turnId,
|
|
3874
|
+
expectedTurnVersion: input.expectedTurnVersion,
|
|
3875
|
+
actor: { type: "human", subjectId: context.subjectId },
|
|
3876
|
+
operationKey: input.clientEventId,
|
|
3877
|
+
reason: input.reason ?? null
|
|
3878
|
+
})
|
|
3879
|
+
)
|
|
3880
|
+
);
|
|
3881
|
+
const response = {
|
|
3882
|
+
receipt: receipt(result.receipt),
|
|
3883
|
+
snapshot: await authoritativeQueue(deps.db, context.workspaceId, context.sessionId)
|
|
3884
|
+
};
|
|
3885
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds);
|
|
3886
|
+
return response;
|
|
3887
|
+
}
|
|
3888
|
+
async function editHumanQueuePrompt(deps, context, turnId, input) {
|
|
3889
|
+
const result = await withWorkspaceSubjectRls2(
|
|
3890
|
+
deps.db,
|
|
3891
|
+
context.workspaceId,
|
|
3892
|
+
context.subjectId,
|
|
3893
|
+
(scoped) => scoped.transaction(
|
|
3894
|
+
(tx) => editQueuedTurnInTransaction(tx, {
|
|
3895
|
+
...context,
|
|
3896
|
+
turnId,
|
|
3897
|
+
expectedTurnVersion: input.expectedTurnVersion,
|
|
3898
|
+
expectedDraftRevision: input.expectedDraftRevision,
|
|
3899
|
+
replaceDraft: input.replaceDraft,
|
|
3900
|
+
actor: { type: "human", subjectId: context.subjectId },
|
|
3901
|
+
operationKey: input.clientEventId
|
|
3902
|
+
})
|
|
3903
|
+
)
|
|
3904
|
+
);
|
|
3905
|
+
const response = {
|
|
3906
|
+
receipt: receipt(result.receipt),
|
|
3907
|
+
snapshot: await authoritativeQueue(deps.db, context.workspaceId, context.sessionId),
|
|
3908
|
+
draft: composerDraft(result.draft)
|
|
3909
|
+
};
|
|
3910
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds);
|
|
3911
|
+
return response;
|
|
3912
|
+
}
|
|
3913
|
+
async function steerHumanQueuePrompt(deps, context, turnId, input) {
|
|
3914
|
+
const result = await withWorkspaceRls(
|
|
3915
|
+
deps.db,
|
|
3916
|
+
context.workspaceId,
|
|
3917
|
+
(scoped) => scoped.transaction(
|
|
3918
|
+
(tx) => steerQueuedTurnInTransaction(tx, {
|
|
3919
|
+
...context,
|
|
3920
|
+
turnId,
|
|
3921
|
+
expectedTurnVersion: input.expectedTurnVersion,
|
|
3922
|
+
controlEtag: input.controlEtag ?? null,
|
|
3923
|
+
actor: { type: "human", subjectId: context.subjectId },
|
|
3924
|
+
operationKey: input.clientEventId
|
|
3925
|
+
})
|
|
3926
|
+
)
|
|
3927
|
+
);
|
|
3928
|
+
const response = {
|
|
3929
|
+
receipt: receipt(result.receipt),
|
|
3930
|
+
snapshot: await authoritativeQueue(deps.db, context.workspaceId, context.sessionId)
|
|
3931
|
+
};
|
|
3932
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds);
|
|
3933
|
+
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
3934
|
+
return response;
|
|
3935
|
+
}
|
|
3936
|
+
async function controlHumanSessionWorkstream(deps, context, input) {
|
|
3937
|
+
const result = await withWorkspaceRls(
|
|
3938
|
+
deps.db,
|
|
3939
|
+
context.workspaceId,
|
|
3940
|
+
(scoped) => scoped.transaction(
|
|
3941
|
+
(tx) => mutateSessionControlInTransaction(tx, {
|
|
3942
|
+
accountId: context.accountId,
|
|
3943
|
+
workspaceId: context.workspaceId,
|
|
3944
|
+
sessionId: context.sessionId,
|
|
3945
|
+
actor: { type: "human", subjectId: context.subjectId },
|
|
3946
|
+
operationKey: input.clientEventId,
|
|
3947
|
+
action: input.action,
|
|
3948
|
+
reason: input.reason ?? null,
|
|
3949
|
+
expectedControlEtag: input.expectedControlEtag ?? null
|
|
3950
|
+
})
|
|
3951
|
+
)
|
|
3952
|
+
);
|
|
3953
|
+
const response = {
|
|
3954
|
+
receipt: receipt(result.receipt),
|
|
3955
|
+
effectiveControl: serializeEffectiveSessionControl(result.control),
|
|
3956
|
+
interruptionCount: result.interruptionCount,
|
|
3957
|
+
wakeCount: result.wakeCount
|
|
3958
|
+
};
|
|
3959
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, [
|
|
3960
|
+
result.sessionControlEventId
|
|
3961
|
+
]);
|
|
3962
|
+
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
3963
|
+
await requestControlWakeDispatch(deps, result.wakeCount);
|
|
3964
|
+
return response;
|
|
3965
|
+
}
|
|
3966
|
+
async function controlHumanWorkspace(deps, context, input) {
|
|
3967
|
+
const result = await withWorkspaceRls(
|
|
3968
|
+
deps.db,
|
|
3969
|
+
context.workspaceId,
|
|
3970
|
+
(scoped) => scoped.transaction(
|
|
3971
|
+
(tx) => mutateWorkspaceControlInTransaction(tx, {
|
|
3972
|
+
accountId: context.accountId,
|
|
3973
|
+
workspaceId: context.workspaceId,
|
|
3974
|
+
actor: { type: "human", subjectId: context.subjectId },
|
|
3975
|
+
operationKey: input.clientEventId,
|
|
3976
|
+
action: input.action,
|
|
3977
|
+
reason: input.reason ?? null,
|
|
3978
|
+
expectedRevision: input.expectedRevision ?? null
|
|
3979
|
+
})
|
|
3980
|
+
)
|
|
3981
|
+
);
|
|
3982
|
+
const response = {
|
|
3983
|
+
receipt: receipt(result.receipt),
|
|
3984
|
+
state: result.workspaceState,
|
|
3985
|
+
revision: result.revision,
|
|
3986
|
+
interruptionCount: result.interruptionCount,
|
|
3987
|
+
wakeCount: result.wakeCount
|
|
3988
|
+
};
|
|
3989
|
+
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
3990
|
+
await requestControlWakeDispatch(deps, result.wakeCount);
|
|
3991
|
+
return response;
|
|
3992
|
+
}
|
|
3993
|
+
async function getHumanComposerDraft(db, context) {
|
|
3994
|
+
const row = await withWorkspaceSubjectRls2(
|
|
3995
|
+
db,
|
|
3996
|
+
context.workspaceId,
|
|
3997
|
+
context.subjectId,
|
|
3998
|
+
(scoped) => getComposerDraftInTransaction(scoped, {
|
|
3999
|
+
workspaceId: context.workspaceId,
|
|
4000
|
+
sessionId: context.sessionId,
|
|
4001
|
+
subjectId: context.subjectId
|
|
4002
|
+
})
|
|
4003
|
+
);
|
|
4004
|
+
const mapped = composerDraft(row);
|
|
4005
|
+
if (mapped) return mapped;
|
|
4006
|
+
const session = await getSession2(db, context.workspaceId, context.sessionId);
|
|
4007
|
+
if (!session) throw new Error(`Session not found: ${context.sessionId}`);
|
|
4008
|
+
return {
|
|
4009
|
+
revision: 0,
|
|
4010
|
+
text: "",
|
|
4011
|
+
resources: [],
|
|
4012
|
+
tools: [],
|
|
4013
|
+
model: session.model,
|
|
4014
|
+
reasoningEffort: reasoningEffortForMetadata2(session.metadata, "medium"),
|
|
4015
|
+
sourceTurnId: null,
|
|
4016
|
+
sourceTurnVersion: null,
|
|
4017
|
+
updatedAt: null
|
|
4018
|
+
};
|
|
4019
|
+
}
|
|
4020
|
+
async function saveHumanComposerDraft(db, context, input) {
|
|
4021
|
+
const row = await withWorkspaceSubjectRls2(
|
|
4022
|
+
db,
|
|
4023
|
+
context.workspaceId,
|
|
4024
|
+
context.subjectId,
|
|
4025
|
+
(scoped) => scoped.transaction(
|
|
4026
|
+
(tx) => saveComposerDraftInTransaction(tx, {
|
|
4027
|
+
...context,
|
|
4028
|
+
...input,
|
|
4029
|
+
subjectId: context.subjectId
|
|
4030
|
+
})
|
|
4031
|
+
)
|
|
4032
|
+
);
|
|
4033
|
+
return composerDraft(row);
|
|
4034
|
+
}
|
|
3614
4035
|
export {
|
|
3615
4036
|
MARKETING_SOCIAL_PACK_ID,
|
|
3616
4037
|
MAX_CHECKS_PER_RIG,
|
|
@@ -3619,6 +4040,9 @@ export {
|
|
|
3619
4040
|
MAX_ENVIRONMENTS_PER_WORKSPACE,
|
|
3620
4041
|
MAX_RIGS_PER_WORKSPACE,
|
|
3621
4042
|
MAX_VARIABLES_PER_ENVIRONMENT,
|
|
4043
|
+
SESSION_WORKFLOW_WAKE_DISPATCHER_PERIOD_MS,
|
|
4044
|
+
SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID,
|
|
4045
|
+
SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_TYPE,
|
|
3622
4046
|
acceptSessionUserMessage,
|
|
3623
4047
|
activateRigVersionForApi,
|
|
3624
4048
|
appendRigSetupCommand,
|
|
@@ -3635,18 +4059,24 @@ export {
|
|
|
3635
4059
|
buildMarketingDailyAnalysisAgentConfig,
|
|
3636
4060
|
checkLimit,
|
|
3637
4061
|
classifyRigVerificationOutcome,
|
|
4062
|
+
controlAgentSessionWorkstream,
|
|
4063
|
+
controlHumanSessionWorkstream,
|
|
4064
|
+
controlHumanWorkspace,
|
|
3638
4065
|
createAndStartSession,
|
|
3639
4066
|
createCatalogItem,
|
|
3640
4067
|
createRigForApi,
|
|
3641
4068
|
createRigVersionForApi,
|
|
3642
4069
|
createSessionForRequest,
|
|
3643
4070
|
createValidatedScheduledTask,
|
|
4071
|
+
deleteHumanQueuePrompt,
|
|
3644
4072
|
deleteRigForApi,
|
|
3645
4073
|
disableCapability,
|
|
3646
4074
|
discoverMcpRegistryCapabilities,
|
|
4075
|
+
editHumanQueuePrompt,
|
|
3647
4076
|
enableCapability,
|
|
3648
4077
|
enabledCapabilityMcpToolRefs,
|
|
3649
4078
|
getCapabilityPack,
|
|
4079
|
+
getHumanComposerDraft,
|
|
3650
4080
|
hasPermission,
|
|
3651
4081
|
isBuiltInCapabilityPack,
|
|
3652
4082
|
isUserMember,
|
|
@@ -3660,6 +4090,7 @@ export {
|
|
|
3660
4090
|
memberCanAdminister,
|
|
3661
4091
|
mergeResourceRefs,
|
|
3662
4092
|
mergeToolRefs,
|
|
4093
|
+
moveHumanQueuePrompt,
|
|
3663
4094
|
normalizeResources,
|
|
3664
4095
|
officialMcpRegistryUrl,
|
|
3665
4096
|
postUserMessageTurn,
|
|
@@ -3691,13 +4122,17 @@ export {
|
|
|
3691
4122
|
rigActorForGrant,
|
|
3692
4123
|
routingEnabled,
|
|
3693
4124
|
runOnSandbox,
|
|
4125
|
+
saveHumanComposerDraft,
|
|
3694
4126
|
scheduledTaskTemporalScheduleId,
|
|
3695
4127
|
scheduledTaskToolsProvided,
|
|
3696
4128
|
scheduledTaskTriggerToken,
|
|
4129
|
+
sendAgentSessionMessage,
|
|
3697
4130
|
settingsWithEnabledCapabilityMcpServers,
|
|
3698
4131
|
settingsWithMcpCapabilityServers,
|
|
3699
4132
|
settingsWithSessionMcpServerMetadata,
|
|
3700
4133
|
stableJson,
|
|
4134
|
+
steerAgentSession,
|
|
4135
|
+
steerHumanQueuePrompt,
|
|
3701
4136
|
swapActiveSandbox,
|
|
3702
4137
|
syncCreatedScheduledTask,
|
|
3703
4138
|
syncUpdatedScheduledTask,
|