@opengeni/core 0.28.0 → 1.0.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/README.md +1 -1
- package/dist/access/external-actor-authority.d.ts +47 -0
- package/dist/access/index.d.ts +182 -3
- package/dist/access/service-initiator.d.ts +3 -0
- package/dist/application/api-integration-servers.d.ts +20 -0
- package/dist/application/archived-session-imports.d.ts +6 -0
- package/dist/application/composer-submit.d.ts +24 -0
- package/dist/application/connect-authority.d.ts +13 -0
- package/dist/application/connect-operation.d.ts +31 -0
- package/dist/application/external-continuation.d.ts +15 -0
- package/dist/application/external-identity-lifecycle.d.ts +20 -0
- package/dist/application/external-link-work-admission.d.ts +12 -0
- package/dist/application/external-workspace-members.d.ts +34 -0
- package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
- package/dist/application/new-session-drafts.d.ts +39 -2
- package/dist/application/sandbox-recovery.d.ts +58 -0
- package/dist/application/session-commands.d.ts +26 -13
- package/dist/application/session-mcp-credential-rotation.d.ts +29 -0
- package/dist/application/session-tenancy.d.ts +19 -0
- package/dist/application/user-resource-grants.d.ts +20 -0
- package/dist/billing/limits.d.ts +11 -0
- package/dist/canonical-human-identities.d.ts +7 -2
- package/dist/canonical-human-identities.js +17 -4
- package/dist/canonical-human-identities.js.map +1 -1
- package/dist/{chunk-6WKPWE5S.js → chunk-2MKMRGSY.js} +108 -24
- package/dist/chunk-2MKMRGSY.js.map +1 -0
- package/dist/{chunk-NYPMQ7NO.js → chunk-GVO3N37G.js} +205 -37
- package/dist/chunk-GVO3N37G.js.map +1 -0
- package/dist/{chunk-JJU6I5XD.js → chunk-LCQXNR62.js} +36 -10
- package/dist/chunk-LCQXNR62.js.map +1 -0
- package/dist/chunk-MM6N7CTO.js +387 -0
- package/dist/chunk-MM6N7CTO.js.map +1 -0
- package/dist/chunk-QO5GVFFO.js +235 -0
- package/dist/chunk-QO5GVFFO.js.map +1 -0
- package/dist/codex-model-availability.d.ts +14 -0
- package/dist/default-session-model.d.ts +139 -0
- package/dist/dependencies.d.ts +87 -4
- package/dist/developer-setup-credential-ceiling.d.ts +10 -0
- package/dist/domain/agent-config-resolution.d.ts +49 -0
- package/dist/domain/automations.d.ts +58 -0
- package/dist/domain/capabilities.d.ts +22 -4
- package/dist/domain/company-profile-agent-admin.d.ts +25 -0
- package/dist/domain/connection-account-selection-error.d.ts +8 -0
- package/dist/domain/connector-tool-permissions.d.ts +36 -0
- package/dist/domain/direct-model-provider.d.ts +3 -0
- package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
- package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
- package/dist/domain/editable-artifacts/ports.d.ts +10 -0
- package/dist/domain/editable-artifacts/service.d.ts +4 -3
- package/dist/domain/environments.d.ts +5 -9
- package/dist/domain/external-creation-attribution.d.ts +6 -0
- package/dist/domain/file-owner.d.ts +8 -0
- package/dist/domain/github-action-policies.d.ts +36 -0
- package/dist/domain/github-repository-bindings.d.ts +117 -0
- package/dist/domain/github-skill-source.d.ts +5 -0
- package/dist/domain/governed-learning-slack-publication.d.ts +45 -0
- package/dist/domain/insights-timing.d.ts +16 -0
- package/dist/domain/insights-usage.d.ts +27 -0
- package/dist/domain/insights.d.ts +28 -1
- package/dist/domain/knowledge-files.d.ts +20 -0
- package/dist/domain/knowledge-messages.d.ts +39 -0
- package/dist/domain/knowledge-messages.test.d.ts +1 -0
- package/dist/domain/knowledge-preparation.d.ts +10 -0
- package/dist/domain/knowledge-preparation.test.d.ts +1 -0
- package/dist/domain/knowledge-search.d.ts +15 -0
- package/dist/domain/knowledge-search.test.d.ts +1 -0
- package/dist/domain/knowledge.d.ts +9 -0
- package/dist/domain/mcp-account-bindings.d.ts +19 -0
- package/dist/domain/mcp-account-routes.d.ts +21 -0
- package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
- package/dist/domain/organization-integration-catalog.d.ts +15 -0
- package/dist/domain/organization-membership-lifecycle.d.ts +1 -0
- package/dist/domain/personal-connection-delegations.d.ts +87 -4
- package/dist/domain/pr-review.d.ts +249 -0
- package/dist/domain/resources.d.ts +24 -3
- package/dist/domain/scheduled-task-access.d.ts +247 -0
- package/dist/domain/scheduled-tasks.d.ts +103 -6
- package/dist/domain/session-connection-accounts.d.ts +16 -0
- package/dist/domain/session-file-access.d.ts +4 -0
- package/dist/domain/session-native-connection-replacement.d.ts +14 -0
- package/dist/domain/session-start-timing.d.ts +7 -0
- package/dist/domain/session-tool-policy.d.ts +93 -4
- package/dist/domain/sessions.d.ts +275 -28
- package/dist/domain/skill-imports.d.ts +1 -0
- package/dist/domain/skill-search.d.ts +30 -0
- package/dist/domain/skills.d.ts +117 -0
- package/dist/domain/slack-bot.d.ts +46 -1
- package/dist/domain/workspace-members.d.ts +8 -1
- package/dist/editable-artifact-live/application.d.ts +12 -3
- package/dist/editable-artifact-live/ports.d.ts +0 -1
- package/dist/editable-artifact-live/server.d.ts +5 -2
- package/dist/editable-artifact-live/ticket.d.ts +2 -2
- package/dist/editable-artifact-live/types.d.ts +14 -2
- package/dist/editable-artifact-live.js +2 -2
- package/dist/editable-artifacts.js +10 -4
- package/dist/index.d.ts +49 -3
- package/dist/index.js +18826 -6847
- package/dist/index.js.map +1 -1
- package/dist/managed-auth-session-sets.d.ts +131 -0
- package/dist/managed-auth-session-sets.js +51 -0
- package/dist/managed-auth-session-sets.js.map +1 -0
- package/dist/managed-session.d.ts +98 -11
- package/dist/model-catalog.d.ts +117 -0
- package/dist/product-usage-metrics.d.ts +30 -0
- package/dist/rigs/index.d.ts +22 -5
- package/dist/rigs/provider-images.d.ts +1 -1
- package/dist/sandbox/fleet.d.ts +59 -10
- package/dist/sandbox/routing.d.ts +22 -2
- package/dist/sandbox/runtime-settings.d.ts +56 -0
- package/dist/session-authorization.d.ts +38 -1
- package/dist/site-session-origin.d.ts +9 -0
- package/dist/transcription.d.ts +12 -1
- package/dist/turn-surface.d.ts +18 -0
- package/dist/user-presence.d.ts +32 -0
- package/package.json +18 -11
- package/src/access/external-actor-authority.ts +94 -0
- package/src/access/index.ts +1386 -44
- package/src/access/service-initiator.ts +50 -0
- package/src/application/api-integration-servers.ts +215 -0
- package/src/application/archived-session-imports.ts +161 -0
- package/src/application/composer-submit.ts +77 -0
- package/src/application/connect-authority.ts +77 -0
- package/src/application/connect-operation.ts +80 -0
- package/src/application/external-continuation.ts +129 -0
- package/src/application/external-identity-lifecycle.ts +48 -0
- package/src/application/external-link-work-admission.ts +90 -0
- package/src/application/external-workspace-members.ts +232 -0
- package/src/application/modal-native-worker-host-transport.ts +263 -0
- package/src/application/new-session-drafts.ts +222 -29
- package/src/application/sandbox-recovery.ts +78 -0
- package/src/application/session-commands.ts +430 -73
- package/src/application/session-mcp-credential-rotation.ts +217 -0
- package/src/application/session-tenancy.ts +445 -0
- package/src/application/user-resource-grants.ts +154 -0
- package/src/billing/limits.ts +103 -24
- package/src/canonical-human-identities.ts +22 -3
- package/src/codex-model-availability.ts +136 -0
- package/src/default-session-model.ts +656 -0
- package/src/dependencies.ts +97 -5
- package/src/developer-setup-credential-ceiling.ts +60 -0
- package/src/domain/agent-config-resolution.ts +148 -0
- package/src/domain/automations.ts +270 -0
- package/src/domain/capabilities.ts +244 -151
- package/src/domain/company-profile-agent-admin.ts +56 -0
- package/src/domain/connection-account-selection-error.ts +19 -0
- package/src/domain/connector-tool-permissions.ts +371 -0
- package/src/domain/direct-model-provider.ts +62 -0
- package/src/domain/editable-artifacts/agent-application.ts +61 -15
- package/src/domain/editable-artifacts/durable-export.ts +100 -5
- package/src/domain/editable-artifacts/in-memory.ts +6 -0
- package/src/domain/editable-artifacts/ports.ts +11 -0
- package/src/domain/editable-artifacts/service.ts +32 -1
- package/src/domain/editable-artifacts/snapshot-compaction.ts +9 -5
- package/src/domain/editable-artifacts/snapshot-verifier-genesis.ts +10 -8
- package/src/domain/editable-artifacts/snapshot-verifier.ts +10 -3
- package/src/domain/environments.ts +25 -45
- package/src/domain/external-creation-attribution.ts +22 -0
- package/src/domain/file-owner.ts +67 -0
- package/src/domain/github-action-policies.ts +169 -0
- package/src/domain/github-repository-bindings.ts +295 -0
- package/src/domain/github-skill-source.ts +233 -0
- package/src/domain/governed-learning-slack-publication.ts +157 -0
- package/src/domain/insights-timing.ts +95 -0
- package/src/domain/insights-usage.ts +67 -0
- package/src/domain/insights.ts +270 -169
- package/src/domain/knowledge-files.ts +46 -0
- package/src/domain/knowledge-messages.test.ts +91 -0
- package/src/domain/knowledge-messages.ts +106 -0
- package/src/domain/knowledge-preparation.test.ts +276 -0
- package/src/domain/knowledge-preparation.ts +147 -0
- package/src/domain/knowledge-search.test.ts +561 -0
- package/src/domain/knowledge-search.ts +256 -0
- package/src/domain/knowledge.ts +133 -0
- package/src/domain/mcp-account-bindings.ts +171 -0
- package/src/domain/mcp-account-routes.ts +121 -0
- package/src/domain/native-mcp-connection-admission.ts +14 -0
- package/src/domain/organization-integration-catalog.ts +88 -0
- package/src/domain/organization-membership-lifecycle.ts +10 -0
- package/src/domain/personal-connection-delegations.ts +758 -115
- package/src/domain/pr-review.ts +687 -0
- package/src/domain/resources.ts +182 -25
- package/src/domain/scheduled-task-access.ts +1052 -0
- package/src/domain/scheduled-tasks.ts +1952 -215
- package/src/domain/session-connection-accounts.ts +67 -0
- package/src/domain/session-file-access.ts +47 -0
- package/src/domain/session-native-connection-replacement.ts +64 -0
- package/src/domain/session-start-timing.ts +55 -0
- package/src/domain/session-tool-policy.ts +443 -19
- package/src/domain/sessions.ts +3417 -619
- package/src/domain/skill-imports.ts +137 -17
- package/src/domain/skill-search.ts +221 -0
- package/src/domain/skills.ts +104 -0
- package/src/domain/slack-bot.ts +128 -3
- package/src/domain/workspace-members.ts +34 -2
- package/src/editable-artifact-live/application.ts +29 -4
- package/src/editable-artifact-live/ports.ts +0 -1
- package/src/editable-artifact-live/server.ts +167 -13
- package/src/editable-artifact-live/ticket.ts +87 -6
- package/src/editable-artifact-live/types.ts +16 -2
- package/src/editable-artifact-live/wire.ts +0 -10
- package/src/index.ts +69 -4
- package/src/managed-auth-session-sets.ts +371 -0
- package/src/managed-session.ts +520 -2
- package/src/model-catalog.ts +873 -0
- package/src/product-usage-metrics.ts +101 -0
- package/src/rigs/index.ts +179 -63
- package/src/rigs/provider-images.ts +2 -3
- package/src/sandbox/fleet.ts +471 -59
- package/src/sandbox/routing.ts +160 -33
- package/src/sandbox/runtime-settings.ts +281 -0
- package/src/session-authorization.ts +262 -78
- package/src/site-session-origin.ts +22 -0
- package/src/transcription.ts +13 -1
- package/src/turn-surface.ts +45 -0
- package/src/user-presence.ts +134 -0
- package/dist/chunk-6WKPWE5S.js.map +0 -1
- package/dist/chunk-IBOEYG6N.js +0 -34
- package/dist/chunk-IBOEYG6N.js.map +0 -1
- package/dist/chunk-JJU6I5XD.js.map +0 -1
- package/dist/chunk-NYPMQ7NO.js.map +0 -1
- package/dist/domain/durable-learning-slack-publication.d.ts +0 -72
- package/dist/domain/packs.d.ts +0 -55
- package/src/domain/durable-learning-slack-publication.ts +0 -202
- package/src/domain/packs.ts +0 -556
|
@@ -16,12 +16,11 @@ import type {
|
|
|
16
16
|
WorkspaceInferenceControlRequest,
|
|
17
17
|
WorkspaceInferenceControlResponse,
|
|
18
18
|
} from "@opengeni/contracts";
|
|
19
|
+
import { DraftTimelineAnnotations } from "@opengeni/contracts";
|
|
20
|
+
import type { Settings } from "@opengeni/config";
|
|
21
|
+
import { HTTPException } from "hono/http-exception";
|
|
19
22
|
import {
|
|
20
|
-
|
|
21
|
-
latencyModeForMetadata,
|
|
22
|
-
reasoningEffortForMetadata,
|
|
23
|
-
} from "@opengeni/contracts";
|
|
24
|
-
import {
|
|
23
|
+
checkWorkspaceAllowance,
|
|
25
24
|
deleteSessionQueueItemInTransaction,
|
|
26
25
|
editQueuedTurnInTransaction,
|
|
27
26
|
getComposerDraftInTransaction,
|
|
@@ -29,9 +28,12 @@ import {
|
|
|
29
28
|
getSessionEvent,
|
|
30
29
|
getWorkspaceControlEvent,
|
|
31
30
|
getSessionQueueSnapshot,
|
|
31
|
+
frozenInitiatorForCommandActor,
|
|
32
|
+
isCodexBilledTurn,
|
|
32
33
|
moveQueuedTurnInTransaction,
|
|
33
34
|
mutateSessionControlInTransaction,
|
|
34
35
|
mutateWorkspaceControlInTransaction,
|
|
36
|
+
setWorkspacePauseTimerInTransaction,
|
|
35
37
|
projectEffectiveControlForRelatedAccess,
|
|
36
38
|
runIdempotentPersistenceTransaction,
|
|
37
39
|
saveComposerDraftInTransaction,
|
|
@@ -39,6 +41,7 @@ import {
|
|
|
39
41
|
serializeEffectiveSessionControl,
|
|
40
42
|
steerAgentSessionInTransaction,
|
|
41
43
|
steerQueuedTurnInTransaction,
|
|
44
|
+
workspaceControlRequestLockTimeoutMs,
|
|
42
45
|
withWorkspaceRls,
|
|
43
46
|
withWorkspaceSessionActivityRls,
|
|
44
47
|
withWorkspaceSubjectRls,
|
|
@@ -55,6 +58,9 @@ import {
|
|
|
55
58
|
import type { SessionWorkflowClient } from "../dependencies";
|
|
56
59
|
import { normalizeResources } from "../domain/resources";
|
|
57
60
|
import { validateDraftTimelineAnnotations } from "../domain/timeline-annotations";
|
|
61
|
+
import { initiatingHumanForAllowance } from "../domain/sessions";
|
|
62
|
+
import { modelFundingForAdmission } from "../billing/limits";
|
|
63
|
+
import { resolveWorkspaceCatalogSettings } from "../model-catalog";
|
|
58
64
|
import {
|
|
59
65
|
requireSessionAuthorization,
|
|
60
66
|
type ResolvedSessionAuthorization,
|
|
@@ -150,6 +156,51 @@ function agentActor(context: AgentSessionCommandContext) {
|
|
|
150
156
|
};
|
|
151
157
|
}
|
|
152
158
|
|
|
159
|
+
/**
|
|
160
|
+
* Called inside the command's exact live-attempt fence, after receipt recovery
|
|
161
|
+
* but before any fresh work or Steer interruption. Attribution comes from the
|
|
162
|
+
* caller's accepted turn, never the target creator or request subject.
|
|
163
|
+
*/
|
|
164
|
+
async function assertFreshAgentCommandAllowance(
|
|
165
|
+
tx: SessionActivityDatabase,
|
|
166
|
+
deps: { settings?: Settings },
|
|
167
|
+
context: AgentSessionCommandContext,
|
|
168
|
+
targetSessionId: string,
|
|
169
|
+
): Promise<void> {
|
|
170
|
+
const target = await getSession(tx, context.workspaceId, targetSessionId);
|
|
171
|
+
if (!target || target.accountId !== context.accountId) {
|
|
172
|
+
throw new HTTPException(404, { message: "Target session not found" });
|
|
173
|
+
}
|
|
174
|
+
if (deps.settings) {
|
|
175
|
+
const { settings } = await resolveWorkspaceCatalogSettings(tx, deps.settings, {
|
|
176
|
+
accountId: target.accountId,
|
|
177
|
+
workspaceId: context.workspaceId,
|
|
178
|
+
retainedProductModelId: target.model,
|
|
179
|
+
});
|
|
180
|
+
const codexBilled = await isCodexBilledTurn({
|
|
181
|
+
db: tx,
|
|
182
|
+
settings,
|
|
183
|
+
workspaceId: context.workspaceId,
|
|
184
|
+
model: target.model,
|
|
185
|
+
});
|
|
186
|
+
if (modelFundingForAdmission(settings, target.model, codexBilled).fundedWithoutCredits) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const frozen = await frozenInitiatorForCommandActor(tx, context.workspaceId, agentActor(context));
|
|
191
|
+
const refusal = await checkWorkspaceAllowance(tx, {
|
|
192
|
+
accountId: target.accountId,
|
|
193
|
+
workspaceId: context.workspaceId,
|
|
194
|
+
subjectId: initiatingHumanForAllowance(frozen),
|
|
195
|
+
});
|
|
196
|
+
if (refusal) {
|
|
197
|
+
throw new HTTPException(402, {
|
|
198
|
+
message: refusal.message,
|
|
199
|
+
cause: { allowed: false, ...refusal },
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
153
204
|
/**
|
|
154
205
|
* Retry only one operation-keyed session command transaction. Callers keep
|
|
155
206
|
* event publication and Temporal wake delivery after this returns, so a
|
|
@@ -185,18 +236,68 @@ async function runSessionCommandPersistenceTransaction<T>(
|
|
|
185
236
|
);
|
|
186
237
|
}
|
|
187
238
|
|
|
188
|
-
|
|
239
|
+
type SessionCommandPostCommitDeps = {
|
|
240
|
+
/** Historical name; now schedules replayable follow-up for every interactive session command. */
|
|
241
|
+
schedulePromptPostCommit?: ((task: () => Promise<void>) => void) | undefined;
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
type SessionCommandPostCommitStep = {
|
|
245
|
+
kind: "session_event_fanout" | "workspace_control_fanout" | "workflow_wake";
|
|
246
|
+
run: () => Promise<void>;
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* A committed interactive command must never wait for ephemeral fanout or an
|
|
251
|
+
* immediate Temporal nudge. Durable events and wake outboxes are the recovery
|
|
252
|
+
* contract; these steps only reduce propagation latency.
|
|
253
|
+
*/
|
|
254
|
+
function scheduleSessionCommandPostCommit(
|
|
255
|
+
deps: SessionCommandPostCommitDeps,
|
|
256
|
+
operation: string,
|
|
257
|
+
steps: SessionCommandPostCommitStep[],
|
|
258
|
+
): void {
|
|
259
|
+
const task = async () => {
|
|
260
|
+
await Promise.all(
|
|
261
|
+
steps.map(async (step) => {
|
|
262
|
+
try {
|
|
263
|
+
await step.run();
|
|
264
|
+
} catch {
|
|
265
|
+
console.warn("[session-commands] replayable post-commit step failed", {
|
|
266
|
+
errorClass: "SessionCommandPostCommitError",
|
|
267
|
+
errorCode: "session_command_post_commit_failed",
|
|
268
|
+
origin: "core",
|
|
269
|
+
operation,
|
|
270
|
+
step: step.kind,
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}),
|
|
274
|
+
);
|
|
275
|
+
};
|
|
276
|
+
try {
|
|
277
|
+
const schedule =
|
|
278
|
+
deps.schedulePromptPostCommit ??
|
|
279
|
+
((pending: () => Promise<void>) => {
|
|
280
|
+
void pending();
|
|
281
|
+
});
|
|
282
|
+
schedule(task);
|
|
283
|
+
} catch {
|
|
284
|
+
console.warn("[session-commands] post-commit scheduling failed", {
|
|
285
|
+
errorClass: "SessionCommandPostCommitScheduleError",
|
|
286
|
+
errorCode: "session_command_post_commit_schedule_failed",
|
|
287
|
+
origin: "core",
|
|
288
|
+
operation,
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
async function wakeSessionCommand(
|
|
189
294
|
deps: {
|
|
190
|
-
db: Database;
|
|
191
|
-
bus: EventBus;
|
|
192
295
|
workflowClient: Pick<SessionWorkflowClient, "wakeSessionWorkflow">;
|
|
193
|
-
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
194
296
|
},
|
|
195
297
|
input: {
|
|
196
298
|
accountId: string;
|
|
197
299
|
workspaceId: string;
|
|
198
300
|
sessionId: string;
|
|
199
|
-
eventIds: string[];
|
|
200
301
|
workflowId: string;
|
|
201
302
|
wakeRevision: number | null;
|
|
202
303
|
shouldSignal: boolean;
|
|
@@ -204,7 +305,6 @@ async function publishAndWakeAgentCommand(
|
|
|
204
305
|
controlRequested?: boolean;
|
|
205
306
|
},
|
|
206
307
|
): Promise<void> {
|
|
207
|
-
await publishSessionEventIds(deps, input.workspaceId, input.sessionId, input.eventIds);
|
|
208
308
|
if (!input.shouldSignal || input.wakeRevision === null) return;
|
|
209
309
|
try {
|
|
210
310
|
await deps.workflowClient.wakeSessionWorkflow({
|
|
@@ -218,14 +318,11 @@ async function publishAndWakeAgentCommand(
|
|
|
218
318
|
: {}),
|
|
219
319
|
});
|
|
220
320
|
} catch {
|
|
221
|
-
console.warn(
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
origin: "core",
|
|
227
|
-
},
|
|
228
|
-
);
|
|
321
|
+
console.warn("[session-commands] immediate command wake failed; durable outbox will retry", {
|
|
322
|
+
errorClass: "WorkflowWakeOperationError",
|
|
323
|
+
errorCode: "session_command_wake_failed",
|
|
324
|
+
origin: "core",
|
|
325
|
+
});
|
|
229
326
|
}
|
|
230
327
|
}
|
|
231
328
|
|
|
@@ -290,10 +387,11 @@ async function publishWorkspaceControlEvent(
|
|
|
290
387
|
export async function sendAgentSessionMessage(
|
|
291
388
|
deps: {
|
|
292
389
|
db: Database;
|
|
390
|
+
settings?: Settings;
|
|
293
391
|
bus: EventBus;
|
|
294
392
|
workflowClient: Pick<SessionWorkflowClient, "wakeSessionWorkflow">;
|
|
295
393
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
296
|
-
},
|
|
394
|
+
} & SessionCommandPostCommitDeps,
|
|
297
395
|
context: AgentSessionCommandContext,
|
|
298
396
|
input: { targetSessionId: string; text: string; idempotencyKey: string },
|
|
299
397
|
) {
|
|
@@ -312,30 +410,57 @@ export async function sendAgentSessionMessage(
|
|
|
312
410
|
actor: agentActor(context),
|
|
313
411
|
operationKey: input.idempotencyKey,
|
|
314
412
|
text: input.text,
|
|
413
|
+
assertFreshAdmission: (scoped) =>
|
|
414
|
+
assertFreshAgentCommandAllowance(scoped, deps, context, input.targetSessionId),
|
|
415
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
315
416
|
}),
|
|
316
417
|
},
|
|
317
418
|
);
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
419
|
+
scheduleSessionCommandPostCommit(deps, "agent_message", [
|
|
420
|
+
{
|
|
421
|
+
kind: "session_event_fanout",
|
|
422
|
+
run: async () =>
|
|
423
|
+
await publishSessionEventIds(
|
|
424
|
+
deps,
|
|
425
|
+
context.workspaceId,
|
|
426
|
+
input.targetSessionId,
|
|
427
|
+
result.eventIds,
|
|
428
|
+
),
|
|
429
|
+
},
|
|
430
|
+
{
|
|
431
|
+
kind: "workspace_control_fanout",
|
|
432
|
+
run: async () =>
|
|
433
|
+
await publishWorkspaceControlEvent(
|
|
434
|
+
deps,
|
|
435
|
+
context.workspaceId,
|
|
436
|
+
result.workspaceControlEventId,
|
|
437
|
+
),
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
kind: "workflow_wake",
|
|
441
|
+
run: async () =>
|
|
442
|
+
await wakeSessionCommand(deps, {
|
|
443
|
+
accountId: context.accountId,
|
|
444
|
+
workspaceId: context.workspaceId,
|
|
445
|
+
sessionId: input.targetSessionId,
|
|
446
|
+
workflowId: result.workflowId,
|
|
447
|
+
wakeRevision: result.wakeRevision,
|
|
448
|
+
shouldSignal: result.shouldSignal,
|
|
449
|
+
interruptionCount: 0,
|
|
450
|
+
}),
|
|
451
|
+
},
|
|
452
|
+
]);
|
|
329
453
|
return result;
|
|
330
454
|
}
|
|
331
455
|
|
|
332
456
|
export async function steerAgentSession(
|
|
333
457
|
deps: {
|
|
334
458
|
db: Database;
|
|
459
|
+
settings?: Settings;
|
|
335
460
|
bus: EventBus;
|
|
336
461
|
workflowClient: Pick<SessionWorkflowClient, "wakeSessionWorkflow">;
|
|
337
462
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
338
|
-
},
|
|
463
|
+
} & SessionCommandPostCommitDeps,
|
|
339
464
|
context: AgentSessionCommandContext,
|
|
340
465
|
input: {
|
|
341
466
|
targetSessionId: string;
|
|
@@ -358,21 +483,47 @@ export async function steerAgentSession(
|
|
|
358
483
|
actor: agentActor(context),
|
|
359
484
|
operationKey: input.idempotencyKey,
|
|
360
485
|
instruction: input.instruction,
|
|
486
|
+
assertFreshAdmission: (scoped) =>
|
|
487
|
+
assertFreshAgentCommandAllowance(scoped, deps, context, input.targetSessionId),
|
|
488
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
361
489
|
}),
|
|
362
490
|
},
|
|
363
491
|
);
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
492
|
+
scheduleSessionCommandPostCommit(deps, "agent_steer", [
|
|
493
|
+
{
|
|
494
|
+
kind: "session_event_fanout",
|
|
495
|
+
run: async () =>
|
|
496
|
+
await publishSessionEventIds(
|
|
497
|
+
deps,
|
|
498
|
+
context.workspaceId,
|
|
499
|
+
input.targetSessionId,
|
|
500
|
+
result.eventIds,
|
|
501
|
+
),
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
kind: "workspace_control_fanout",
|
|
505
|
+
run: async () =>
|
|
506
|
+
await publishWorkspaceControlEvent(
|
|
507
|
+
deps,
|
|
508
|
+
context.workspaceId,
|
|
509
|
+
result.workspaceControlEventId,
|
|
510
|
+
),
|
|
511
|
+
},
|
|
512
|
+
{
|
|
513
|
+
kind: "workflow_wake",
|
|
514
|
+
run: async () =>
|
|
515
|
+
await wakeSessionCommand(deps, {
|
|
516
|
+
accountId: context.accountId,
|
|
517
|
+
workspaceId: context.workspaceId,
|
|
518
|
+
sessionId: input.targetSessionId,
|
|
519
|
+
workflowId: result.workflowId,
|
|
520
|
+
wakeRevision: result.wakeRevision,
|
|
521
|
+
shouldSignal: result.shouldSignal,
|
|
522
|
+
interruptionCount: result.interruptionCount,
|
|
523
|
+
controlRequested: true,
|
|
524
|
+
}),
|
|
525
|
+
},
|
|
526
|
+
]);
|
|
376
527
|
return result;
|
|
377
528
|
}
|
|
378
529
|
|
|
@@ -380,9 +531,12 @@ export async function controlAgentSessionWorkstream(
|
|
|
380
531
|
deps: {
|
|
381
532
|
db: Database;
|
|
382
533
|
bus: EventBus;
|
|
383
|
-
workflowClient: Pick<
|
|
534
|
+
workflowClient: Pick<
|
|
535
|
+
SessionWorkflowClient,
|
|
536
|
+
"requestSessionWorkflowWakeDispatch" | "wakeSessionWorkflow"
|
|
537
|
+
>;
|
|
384
538
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
385
|
-
},
|
|
539
|
+
} & SessionCommandPostCommitDeps,
|
|
386
540
|
context: AgentSessionCommandContext,
|
|
387
541
|
input: {
|
|
388
542
|
targetSessionId: string;
|
|
@@ -412,14 +566,60 @@ export async function controlAgentSessionWorkstream(
|
|
|
412
566
|
operationKey: input.idempotencyKey,
|
|
413
567
|
action: input.action,
|
|
414
568
|
reason: input.reason ?? null,
|
|
569
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
415
570
|
}),
|
|
416
571
|
},
|
|
417
572
|
);
|
|
418
|
-
|
|
419
|
-
result.sessionControlEventId
|
|
573
|
+
scheduleSessionCommandPostCommit(deps, "agent_control", [
|
|
574
|
+
...(result.sessionControlEventId
|
|
575
|
+
? [
|
|
576
|
+
{
|
|
577
|
+
kind: "session_event_fanout" as const,
|
|
578
|
+
run: async () =>
|
|
579
|
+
await publishSessionEventIds(deps, context.workspaceId, input.targetSessionId, [
|
|
580
|
+
result.sessionControlEventId!,
|
|
581
|
+
]),
|
|
582
|
+
},
|
|
583
|
+
]
|
|
584
|
+
: []),
|
|
585
|
+
...(result.workspaceControlEventId
|
|
586
|
+
? [
|
|
587
|
+
{
|
|
588
|
+
kind: "workspace_control_fanout" as const,
|
|
589
|
+
run: async () =>
|
|
590
|
+
await publishWorkspaceControlEvent(
|
|
591
|
+
deps,
|
|
592
|
+
context.workspaceId,
|
|
593
|
+
result.workspaceControlEventId!,
|
|
594
|
+
),
|
|
595
|
+
},
|
|
596
|
+
]
|
|
597
|
+
: []),
|
|
598
|
+
...(result.wakeCount > 0
|
|
599
|
+
? [
|
|
600
|
+
{
|
|
601
|
+
kind: "workflow_wake" as const,
|
|
602
|
+
run: async () => await requestControlWakeDispatch(deps, result.wakeCount),
|
|
603
|
+
},
|
|
604
|
+
]
|
|
605
|
+
: []),
|
|
606
|
+
{
|
|
607
|
+
kind: "workflow_wake",
|
|
608
|
+
run: async () => {
|
|
609
|
+
if (!result.workflowWake) return;
|
|
610
|
+
await wakeSessionCommand(deps, {
|
|
611
|
+
accountId: result.workflowWake.accountId,
|
|
612
|
+
workspaceId: result.workflowWake.workspaceId,
|
|
613
|
+
sessionId: result.workflowWake.sessionId,
|
|
614
|
+
workflowId: result.workflowWake.temporalWorkflowId,
|
|
615
|
+
wakeRevision: result.workflowWake.wakeRevision,
|
|
616
|
+
shouldSignal: true,
|
|
617
|
+
interruptionCount: result.interruptionCount,
|
|
618
|
+
controlRequested: input.action === "pause",
|
|
619
|
+
});
|
|
620
|
+
},
|
|
621
|
+
},
|
|
420
622
|
]);
|
|
421
|
-
await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
|
|
422
|
-
await requestControlWakeDispatch(deps, result.wakeCount);
|
|
423
623
|
return { ...result, authorization };
|
|
424
624
|
}
|
|
425
625
|
|
|
@@ -479,7 +679,7 @@ export async function moveHumanQueuePrompt(
|
|
|
479
679
|
db: Database;
|
|
480
680
|
bus: EventBus;
|
|
481
681
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
482
|
-
},
|
|
682
|
+
} & SessionCommandPostCommitDeps,
|
|
483
683
|
context: HumanSessionCommandContext,
|
|
484
684
|
turnId: string,
|
|
485
685
|
input: MoveSessionQueueItemRequest,
|
|
@@ -499,6 +699,7 @@ export async function moveHumanQueuePrompt(
|
|
|
499
699
|
expectedQueueVersion: input.expectedQueueVersion,
|
|
500
700
|
actor: { type: "human", subjectId: context.subjectId },
|
|
501
701
|
operationKey: input.clientEventId,
|
|
702
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
502
703
|
}),
|
|
503
704
|
},
|
|
504
705
|
);
|
|
@@ -511,7 +712,13 @@ export async function moveHumanQueuePrompt(
|
|
|
511
712
|
authorization?.relatedSessionAccess ?? "root",
|
|
512
713
|
),
|
|
513
714
|
};
|
|
514
|
-
|
|
715
|
+
scheduleSessionCommandPostCommit(deps, "human_queue_move", [
|
|
716
|
+
{
|
|
717
|
+
kind: "session_event_fanout",
|
|
718
|
+
run: async () =>
|
|
719
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds),
|
|
720
|
+
},
|
|
721
|
+
]);
|
|
515
722
|
return response;
|
|
516
723
|
}
|
|
517
724
|
|
|
@@ -520,7 +727,7 @@ export async function deleteHumanQueuePrompt(
|
|
|
520
727
|
db: Database;
|
|
521
728
|
bus: EventBus;
|
|
522
729
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
523
|
-
},
|
|
730
|
+
} & SessionCommandPostCommitDeps,
|
|
524
731
|
context: HumanSessionCommandContext,
|
|
525
732
|
turnId: string,
|
|
526
733
|
input: DeleteSessionQueueItemRequest,
|
|
@@ -540,6 +747,7 @@ export async function deleteHumanQueuePrompt(
|
|
|
540
747
|
actor: { type: "human", subjectId: context.subjectId },
|
|
541
748
|
operationKey: input.clientEventId,
|
|
542
749
|
reason: input.reason ?? null,
|
|
750
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
543
751
|
}),
|
|
544
752
|
},
|
|
545
753
|
);
|
|
@@ -552,7 +760,13 @@ export async function deleteHumanQueuePrompt(
|
|
|
552
760
|
authorization?.relatedSessionAccess ?? "root",
|
|
553
761
|
),
|
|
554
762
|
};
|
|
555
|
-
|
|
763
|
+
scheduleSessionCommandPostCommit(deps, "human_queue_delete", [
|
|
764
|
+
{
|
|
765
|
+
kind: "session_event_fanout",
|
|
766
|
+
run: async () =>
|
|
767
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds),
|
|
768
|
+
},
|
|
769
|
+
]);
|
|
556
770
|
return response;
|
|
557
771
|
}
|
|
558
772
|
|
|
@@ -561,7 +775,7 @@ export async function editHumanQueuePrompt(
|
|
|
561
775
|
db: Database;
|
|
562
776
|
bus: EventBus;
|
|
563
777
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
564
|
-
},
|
|
778
|
+
} & SessionCommandPostCommitDeps,
|
|
565
779
|
context: HumanSessionCommandContext,
|
|
566
780
|
turnId: string,
|
|
567
781
|
input: EditSessionQueueItemRequest,
|
|
@@ -582,6 +796,7 @@ export async function editHumanQueuePrompt(
|
|
|
582
796
|
replaceDraft: input.replaceDraft,
|
|
583
797
|
actor: { type: "human", subjectId: context.subjectId },
|
|
584
798
|
operationKey: input.clientEventId,
|
|
799
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
585
800
|
}),
|
|
586
801
|
},
|
|
587
802
|
);
|
|
@@ -595,7 +810,13 @@ export async function editHumanQueuePrompt(
|
|
|
595
810
|
),
|
|
596
811
|
draft: composerDraft(result.draft)!,
|
|
597
812
|
};
|
|
598
|
-
|
|
813
|
+
scheduleSessionCommandPostCommit(deps, "human_queue_edit", [
|
|
814
|
+
{
|
|
815
|
+
kind: "session_event_fanout",
|
|
816
|
+
run: async () =>
|
|
817
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds),
|
|
818
|
+
},
|
|
819
|
+
]);
|
|
599
820
|
return response;
|
|
600
821
|
}
|
|
601
822
|
|
|
@@ -603,8 +824,9 @@ export async function steerHumanQueuePrompt(
|
|
|
603
824
|
deps: {
|
|
604
825
|
db: Database;
|
|
605
826
|
bus: EventBus;
|
|
827
|
+
workflowClient: Pick<SessionWorkflowClient, "wakeSessionWorkflow">;
|
|
606
828
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
607
|
-
},
|
|
829
|
+
} & SessionCommandPostCommitDeps,
|
|
608
830
|
context: HumanSessionCommandContext,
|
|
609
831
|
turnId: string,
|
|
610
832
|
input: SteerSessionQueueItemRequest,
|
|
@@ -624,6 +846,7 @@ export async function steerHumanQueuePrompt(
|
|
|
624
846
|
controlEtag: input.controlEtag ?? null,
|
|
625
847
|
actor: { type: "human", subjectId: context.subjectId },
|
|
626
848
|
operationKey: input.clientEventId,
|
|
849
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
627
850
|
}),
|
|
628
851
|
},
|
|
629
852
|
);
|
|
@@ -636,8 +859,36 @@ export async function steerHumanQueuePrompt(
|
|
|
636
859
|
authorization?.relatedSessionAccess ?? "root",
|
|
637
860
|
),
|
|
638
861
|
};
|
|
639
|
-
|
|
640
|
-
|
|
862
|
+
scheduleSessionCommandPostCommit(deps, "human_queue_steer", [
|
|
863
|
+
{
|
|
864
|
+
kind: "session_event_fanout",
|
|
865
|
+
run: async () =>
|
|
866
|
+
await publishSessionEventIds(deps, context.workspaceId, context.sessionId, result.eventIds),
|
|
867
|
+
},
|
|
868
|
+
{
|
|
869
|
+
kind: "workspace_control_fanout",
|
|
870
|
+
run: async () =>
|
|
871
|
+
await publishWorkspaceControlEvent(
|
|
872
|
+
deps,
|
|
873
|
+
context.workspaceId,
|
|
874
|
+
result.workspaceControlEventId,
|
|
875
|
+
),
|
|
876
|
+
},
|
|
877
|
+
{
|
|
878
|
+
kind: "workflow_wake",
|
|
879
|
+
run: async () =>
|
|
880
|
+
await wakeSessionCommand(deps, {
|
|
881
|
+
accountId: context.accountId,
|
|
882
|
+
workspaceId: context.workspaceId,
|
|
883
|
+
sessionId: context.sessionId,
|
|
884
|
+
workflowId: result.workflowId,
|
|
885
|
+
wakeRevision: result.wakeRevision,
|
|
886
|
+
shouldSignal: true,
|
|
887
|
+
interruptionCount: result.interruptionCount,
|
|
888
|
+
controlRequested: true,
|
|
889
|
+
}),
|
|
890
|
+
},
|
|
891
|
+
]);
|
|
641
892
|
return response;
|
|
642
893
|
}
|
|
643
894
|
|
|
@@ -645,12 +896,19 @@ export async function controlHumanSessionWorkstreamWithOutcome(
|
|
|
645
896
|
deps: {
|
|
646
897
|
db: Database;
|
|
647
898
|
bus: EventBus;
|
|
648
|
-
workflowClient: Pick<
|
|
899
|
+
workflowClient: Pick<
|
|
900
|
+
SessionWorkflowClient,
|
|
901
|
+
"requestSessionWorkflowWakeDispatch" | "wakeSessionWorkflow"
|
|
902
|
+
>;
|
|
649
903
|
sessionAuthorization?: SessionAuthorizationPort | null;
|
|
650
|
-
},
|
|
904
|
+
} & SessionCommandPostCommitDeps,
|
|
651
905
|
context: HumanSessionCommandContext,
|
|
652
906
|
input: SessionControlRequest,
|
|
653
|
-
): Promise<{
|
|
907
|
+
): Promise<{
|
|
908
|
+
response: SessionControlResponse;
|
|
909
|
+
outcome: "changed" | "unchanged" | "replayed";
|
|
910
|
+
replay: boolean;
|
|
911
|
+
}> {
|
|
654
912
|
const authorization = await authorizeHumanSessionCommand(deps, context, "session.control");
|
|
655
913
|
const result = await runSessionCommandPersistenceTransaction(
|
|
656
914
|
deps,
|
|
@@ -670,6 +928,7 @@ export async function controlHumanSessionWorkstreamWithOutcome(
|
|
|
670
928
|
action: input.action,
|
|
671
929
|
reason: input.reason ?? null,
|
|
672
930
|
expectedControlEtag: input.expectedControlEtag ?? null,
|
|
931
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
673
932
|
}),
|
|
674
933
|
},
|
|
675
934
|
);
|
|
@@ -685,12 +944,56 @@ export async function controlHumanSessionWorkstreamWithOutcome(
|
|
|
685
944
|
cancelledSessionCount: result.cancelledSessionCount,
|
|
686
945
|
cancelledTurnCount: result.cancelledTurnCount,
|
|
687
946
|
};
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
947
|
+
scheduleSessionCommandPostCommit(deps, "human_control", [
|
|
948
|
+
...result.affectedSessionEvents.map((affected) => ({
|
|
949
|
+
kind: "session_event_fanout" as const,
|
|
950
|
+
run: async () =>
|
|
951
|
+
await publishSessionEventIds(
|
|
952
|
+
deps,
|
|
953
|
+
context.workspaceId,
|
|
954
|
+
affected.sessionId,
|
|
955
|
+
affected.eventIds,
|
|
956
|
+
),
|
|
957
|
+
})),
|
|
958
|
+
...(result.workspaceControlEventId
|
|
959
|
+
? [
|
|
960
|
+
{
|
|
961
|
+
kind: "workspace_control_fanout" as const,
|
|
962
|
+
run: async () =>
|
|
963
|
+
await publishWorkspaceControlEvent(
|
|
964
|
+
deps,
|
|
965
|
+
context.workspaceId,
|
|
966
|
+
result.workspaceControlEventId!,
|
|
967
|
+
),
|
|
968
|
+
},
|
|
969
|
+
]
|
|
970
|
+
: []),
|
|
971
|
+
...(result.wakeCount > 0
|
|
972
|
+
? [
|
|
973
|
+
{
|
|
974
|
+
kind: "workflow_wake" as const,
|
|
975
|
+
run: async () => await requestControlWakeDispatch(deps, result.wakeCount),
|
|
976
|
+
},
|
|
977
|
+
]
|
|
978
|
+
: []),
|
|
979
|
+
{
|
|
980
|
+
kind: "workflow_wake",
|
|
981
|
+
run: async () => {
|
|
982
|
+
if (!result.workflowWake) return;
|
|
983
|
+
await wakeSessionCommand(deps, {
|
|
984
|
+
accountId: result.workflowWake.accountId,
|
|
985
|
+
workspaceId: result.workflowWake.workspaceId,
|
|
986
|
+
sessionId: result.workflowWake.sessionId,
|
|
987
|
+
workflowId: result.workflowWake.temporalWorkflowId,
|
|
988
|
+
wakeRevision: result.workflowWake.wakeRevision,
|
|
989
|
+
shouldSignal: true,
|
|
990
|
+
interruptionCount: result.interruptionCount,
|
|
991
|
+
controlRequested: input.action === "pause",
|
|
992
|
+
});
|
|
993
|
+
},
|
|
994
|
+
},
|
|
995
|
+
]);
|
|
996
|
+
return { response, outcome: result.outcome, replay: result.replay };
|
|
694
997
|
}
|
|
695
998
|
|
|
696
999
|
/** Backward-compatible response path used by the REST control route. */
|
|
@@ -707,7 +1010,7 @@ export async function controlHumanWorkspace(
|
|
|
707
1010
|
db: Database;
|
|
708
1011
|
bus: EventBus;
|
|
709
1012
|
workflowClient: Pick<SessionWorkflowClient, "requestSessionWorkflowWakeDispatch">;
|
|
710
|
-
},
|
|
1013
|
+
} & SessionCommandPostCommitDeps,
|
|
711
1014
|
context: Omit<HumanSessionCommandContext, "sessionId">,
|
|
712
1015
|
input: WorkspaceInferenceControlRequest,
|
|
713
1016
|
): Promise<WorkspaceInferenceControlResponse> {
|
|
@@ -721,6 +1024,7 @@ export async function controlHumanWorkspace(
|
|
|
721
1024
|
action: input.action,
|
|
722
1025
|
reason: input.reason ?? null,
|
|
723
1026
|
expectedRevision: input.expectedRevision ?? null,
|
|
1027
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
724
1028
|
}),
|
|
725
1029
|
),
|
|
726
1030
|
);
|
|
@@ -731,8 +1035,29 @@ export async function controlHumanWorkspace(
|
|
|
731
1035
|
interruptionCount: result.interruptionCount,
|
|
732
1036
|
wakeCount: result.wakeCount,
|
|
733
1037
|
};
|
|
734
|
-
|
|
735
|
-
|
|
1038
|
+
scheduleSessionCommandPostCommit(deps, "human_workspace_control", [
|
|
1039
|
+
...(result.workspaceControlEventId
|
|
1040
|
+
? [
|
|
1041
|
+
{
|
|
1042
|
+
kind: "workspace_control_fanout" as const,
|
|
1043
|
+
run: async () =>
|
|
1044
|
+
await publishWorkspaceControlEvent(
|
|
1045
|
+
deps,
|
|
1046
|
+
context.workspaceId,
|
|
1047
|
+
result.workspaceControlEventId!,
|
|
1048
|
+
),
|
|
1049
|
+
},
|
|
1050
|
+
]
|
|
1051
|
+
: []),
|
|
1052
|
+
...(result.wakeCount > 0
|
|
1053
|
+
? [
|
|
1054
|
+
{
|
|
1055
|
+
kind: "workflow_wake" as const,
|
|
1056
|
+
run: async () => await requestControlWakeDispatch(deps, result.wakeCount),
|
|
1057
|
+
},
|
|
1058
|
+
]
|
|
1059
|
+
: []),
|
|
1060
|
+
]);
|
|
736
1061
|
return response;
|
|
737
1062
|
}
|
|
738
1063
|
|
|
@@ -762,8 +1087,8 @@ export async function getHumanComposerDraft(
|
|
|
762
1087
|
annotations: [],
|
|
763
1088
|
resources: [],
|
|
764
1089
|
model: session.model,
|
|
765
|
-
reasoningEffort:
|
|
766
|
-
latencyMode:
|
|
1090
|
+
reasoningEffort: session.reasoningEffort,
|
|
1091
|
+
latencyMode: session.latencyMode,
|
|
767
1092
|
sourceTurnId: null,
|
|
768
1093
|
sourceTurnVersion: null,
|
|
769
1094
|
updatedAt: null,
|
|
@@ -794,8 +1119,40 @@ export async function saveHumanComposerDraft(
|
|
|
794
1119
|
annotations,
|
|
795
1120
|
resources: normalizeResources(input.resources),
|
|
796
1121
|
subjectId: context.subjectId,
|
|
1122
|
+
controlLockTimeoutMs: workspaceControlRequestLockTimeoutMs(),
|
|
797
1123
|
}),
|
|
798
1124
|
),
|
|
799
1125
|
);
|
|
800
1126
|
return composerDraft(row)!;
|
|
801
1127
|
}
|
|
1128
|
+
|
|
1129
|
+
export async function controlHumanWorkspaceTimer(
|
|
1130
|
+
deps: Parameters<typeof controlHumanWorkspace>[0],
|
|
1131
|
+
context: Parameters<typeof controlHumanWorkspace>[1],
|
|
1132
|
+
input: import("@opengeni/contracts").WorkspacePauseTimerRequest,
|
|
1133
|
+
): Promise<void> {
|
|
1134
|
+
const result = await withWorkspaceRls(deps.db, context.workspaceId, (scoped) =>
|
|
1135
|
+
scoped.transaction((tx) =>
|
|
1136
|
+
setWorkspacePauseTimerInTransaction(tx as unknown as Database, {
|
|
1137
|
+
...input,
|
|
1138
|
+
...context,
|
|
1139
|
+
}),
|
|
1140
|
+
),
|
|
1141
|
+
);
|
|
1142
|
+
scheduleSessionCommandPostCommit(deps, "human_workspace_timer", [
|
|
1143
|
+
...(result.workspaceControlEventId
|
|
1144
|
+
? [
|
|
1145
|
+
{
|
|
1146
|
+
kind: "workspace_control_fanout" as const,
|
|
1147
|
+
run: async () =>
|
|
1148
|
+
await publishWorkspaceControlEvent(
|
|
1149
|
+
deps,
|
|
1150
|
+
context.workspaceId,
|
|
1151
|
+
result.workspaceControlEventId!,
|
|
1152
|
+
),
|
|
1153
|
+
},
|
|
1154
|
+
]
|
|
1155
|
+
: []),
|
|
1156
|
+
{ kind: "workflow_wake" as const, run: async () => await requestControlWakeDispatch(deps, 1) },
|
|
1157
|
+
]);
|
|
1158
|
+
}
|