@opengeni/api-router 0.5.3 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/app.d.ts +9 -1
- package/dist/app.js +7 -1
- package/dist/{chunk-3HIA43CC.js → chunk-HBEJMWD3.js} +5470 -2223
- package/dist/chunk-HBEJMWD3.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +279 -55
- package/dist/index.js.map +1 -1
- package/package.json +20 -20
- package/src/app.ts +583 -166
- package/src/auth/managed-auth.ts +32 -16
- package/src/http/auth.ts +8 -1
- package/src/http/common.ts +6 -2
- package/src/http/sse.ts +84 -8
- package/src/index.ts +178 -75
- package/src/integrations/oauth-client.ts +403 -120
- package/src/integrations/provider-domain.ts +4 -1
- package/src/mcp/documents.ts +173 -94
- package/src/mcp/server.ts +1600 -693
- package/src/mcp/session-view.ts +8 -2
- package/src/mcp/toolspace.ts +175 -84
- package/src/observability.ts +7 -1
- package/src/routes/api-keys.ts +39 -23
- package/src/routes/billing.ts +180 -65
- package/src/routes/capabilities.ts +17 -8
- package/src/routes/catalog-assets.ts +5 -2
- package/src/routes/codex.ts +244 -63
- package/src/routes/connections.ts +71 -33
- package/src/routes/documents.ts +242 -92
- package/src/routes/enrollments.ts +100 -70
- package/src/routes/environments.ts +205 -136
- package/src/routes/files.ts +164 -39
- package/src/routes/github.ts +123 -50
- package/src/routes/install.ts +9 -2
- package/src/routes/machines.ts +9 -8
- package/src/routes/packs.ts +141 -89
- package/src/routes/rigs.ts +189 -0
- package/src/routes/scheduled-tasks.ts +51 -9
- package/src/routes/sessions.ts +870 -328
- package/src/routes/social.ts +50 -38
- package/src/routes/workspace-capture.ts +238 -0
- package/src/routes/workspaces.ts +146 -13
- package/src/sandbox/access.ts +11 -3
- package/src/sandbox/auth-callout.ts +5 -1
- package/src/sandbox/channel-a.ts +104 -27
- package/src/sandbox/enrollment.ts +13 -3
- package/src/sandbox/machines.ts +68 -59
- package/src/sandbox/metrics-ingestion.ts +238 -17
- package/src/sandbox/viewer.ts +172 -46
- package/dist/chunk-3HIA43CC.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getSettings } from '@opengeni/config';
|
|
2
2
|
import { ScheduledTaskOverlapPolicy, ScheduledTaskScheduleSpec } from '@opengeni/contracts';
|
|
3
|
+
import { Database } from '@opengeni/db';
|
|
3
4
|
import { ScheduleOverlapPolicy, ScheduleSpec } from '@temporalio/client';
|
|
4
5
|
import { SessionWorkflowClient, DocumentIndexClient } from '@opengeni/core';
|
|
5
6
|
|
|
6
|
-
declare function createTemporalWorkflowClient(settings: ReturnType<typeof getSettings
|
|
7
|
+
declare function createTemporalWorkflowClient(settings: ReturnType<typeof getSettings>, db: Database): Promise<{
|
|
7
8
|
client: SessionWorkflowClient;
|
|
8
9
|
documentIndexer: DocumentIndexClient;
|
|
9
10
|
close: () => Promise<void>;
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
import {
|
|
2
2
|
createApp
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-HBEJMWD3.js";
|
|
4
4
|
|
|
5
5
|
// src/index.ts
|
|
6
|
-
import {
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
dbSearchPath,
|
|
8
|
+
getSettings,
|
|
9
|
+
resolveNatsCalloutConfig,
|
|
10
|
+
resolveNatsControlPlaneAuth,
|
|
11
|
+
retryStartupDependency,
|
|
12
|
+
startupRetryOptions
|
|
13
|
+
} from "@opengeni/config";
|
|
14
|
+
import { createDb, markSessionWorkflowWakeDelivered } from "@opengeni/db";
|
|
8
15
|
import { createNatsEventBus } from "@opengeni/events";
|
|
9
16
|
import { createObservability, logStartupDependencyRetry } from "@opengeni/observability";
|
|
10
|
-
import {
|
|
17
|
+
import { SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID } from "@opengeni/core";
|
|
18
|
+
import {
|
|
19
|
+
Connection,
|
|
20
|
+
Client as TemporalClient,
|
|
21
|
+
ScheduleNotFoundError,
|
|
22
|
+
ScheduleOverlapPolicy,
|
|
23
|
+
WorkflowExecutionAlreadyStartedError
|
|
24
|
+
} from "@temporalio/client";
|
|
11
25
|
|
|
12
26
|
// src/observability.ts
|
|
13
27
|
function observabilityEventLogger(observability) {
|
|
@@ -38,7 +52,9 @@ function eventAttributeValue(value) {
|
|
|
38
52
|
}
|
|
39
53
|
|
|
40
54
|
// src/sandbox/auth-callout.ts
|
|
41
|
-
import {
|
|
55
|
+
import {
|
|
56
|
+
resolveEnrollmentSigningSecret
|
|
57
|
+
} from "@opengeni/config";
|
|
42
58
|
import { verifyEnrollmentBearer } from "@opengeni/contracts";
|
|
43
59
|
import { getEnrollment } from "@opengeni/db";
|
|
44
60
|
import {
|
|
@@ -135,12 +151,22 @@ async function startAuthCalloutResponder(deps, natsUrl) {
|
|
|
135
151
|
|
|
136
152
|
// src/sandbox/metrics-ingestion.ts
|
|
137
153
|
import {
|
|
154
|
+
clearEnrollmentWentOffline,
|
|
138
155
|
getEnrollment as getEnrollment2,
|
|
139
156
|
ingestMachineMetricsSample,
|
|
157
|
+
sessionsWithActiveOpOnEnrollment,
|
|
140
158
|
setEnrollmentDisplayState,
|
|
159
|
+
setEnrollmentOpStreamState,
|
|
160
|
+
setEnrollmentWentOffline,
|
|
141
161
|
touchEnrollmentLastSeen
|
|
142
162
|
} from "@opengeni/db";
|
|
143
|
-
import {
|
|
163
|
+
import { appendAndPublishEvents } from "@opengeni/events";
|
|
164
|
+
import {
|
|
165
|
+
AgentEvent,
|
|
166
|
+
GoingOfflineReason,
|
|
167
|
+
Hello,
|
|
168
|
+
goingOfflineReasonToJSON
|
|
169
|
+
} from "@opengeni/agent-proto";
|
|
144
170
|
var AGENT_EVENTS_SUBJECT = "agent.*.*.events";
|
|
145
171
|
var AGENT_HELLO_SUBJECT = "agent.*.*.hello";
|
|
146
172
|
function parseAgentSubject(subject, tail) {
|
|
@@ -196,7 +222,27 @@ async function ingestHeartbeat(db, input) {
|
|
|
196
222
|
});
|
|
197
223
|
return { ingested: true, seriesAppended: result.seriesAppended };
|
|
198
224
|
}
|
|
199
|
-
async function
|
|
225
|
+
async function fanOutMachineLinkEvents(db, bus, observability, workspaceId, enrollmentId, build) {
|
|
226
|
+
const sessions = await sessionsWithActiveOpOnEnrollment(db, { workspaceId, enrollmentId });
|
|
227
|
+
for (const session of sessions) {
|
|
228
|
+
try {
|
|
229
|
+
await appendAndPublishEvents(
|
|
230
|
+
db,
|
|
231
|
+
bus,
|
|
232
|
+
workspaceId,
|
|
233
|
+
session.sessionId,
|
|
234
|
+
build(session.activeTurnId)
|
|
235
|
+
);
|
|
236
|
+
} catch (error) {
|
|
237
|
+
observability?.warn?.("Failed to fan out a machine-link event to a session", {
|
|
238
|
+
workspaceId,
|
|
239
|
+
sessionId: session.sessionId,
|
|
240
|
+
error: error instanceof Error ? error.message : String(error)
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
async function handleAgentEventPayload(db, observability, payload, subject, bus) {
|
|
200
246
|
const ids = parseAgentEventSubject(subject);
|
|
201
247
|
if (!ids) {
|
|
202
248
|
return;
|
|
@@ -211,6 +257,54 @@ async function handleAgentEventPayload(db, observability, payload, subject) {
|
|
|
211
257
|
});
|
|
212
258
|
return;
|
|
213
259
|
}
|
|
260
|
+
if (event.event?.$case === "goingOffline") {
|
|
261
|
+
const reason = goingOfflineReasonToJSON(event.event.goingOffline.reason);
|
|
262
|
+
observability?.incrementCounter({
|
|
263
|
+
name: "opengeni_machine_going_offline_total",
|
|
264
|
+
help: "Total Connected Machine clean GoingOffline signals by typed reason.",
|
|
265
|
+
labels: { reason }
|
|
266
|
+
});
|
|
267
|
+
try {
|
|
268
|
+
const enrollment = await getEnrollment2(db, ids.workspaceId, ids.agentId);
|
|
269
|
+
if (enrollment) {
|
|
270
|
+
await setEnrollmentWentOffline(db, {
|
|
271
|
+
accountId: enrollment.accountId,
|
|
272
|
+
workspaceId: ids.workspaceId,
|
|
273
|
+
enrollmentId: ids.agentId,
|
|
274
|
+
reason
|
|
275
|
+
});
|
|
276
|
+
if (bus) {
|
|
277
|
+
const isSelfUpdate = event.event.goingOffline.reason === GoingOfflineReason.GOING_OFFLINE_REASON_UPDATE;
|
|
278
|
+
await fanOutMachineLinkEvents(
|
|
279
|
+
db,
|
|
280
|
+
bus,
|
|
281
|
+
observability,
|
|
282
|
+
ids.workspaceId,
|
|
283
|
+
ids.agentId,
|
|
284
|
+
(activeTurnId) => {
|
|
285
|
+
const events = [
|
|
286
|
+
{ type: "machine.link.lost", turnId: activeTurnId, payload: { reason } }
|
|
287
|
+
];
|
|
288
|
+
if (isSelfUpdate) {
|
|
289
|
+
events.push({
|
|
290
|
+
type: "machine.runner.restarted",
|
|
291
|
+
turnId: activeTurnId,
|
|
292
|
+
payload: {}
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
return events;
|
|
296
|
+
}
|
|
297
|
+
);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
} catch (error) {
|
|
301
|
+
observability?.warn?.("Failed to record a machine clean going-offline", {
|
|
302
|
+
subject,
|
|
303
|
+
error: error instanceof Error ? error.message : String(error)
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
return;
|
|
307
|
+
}
|
|
214
308
|
if (event.event?.$case !== "heartbeat") {
|
|
215
309
|
return;
|
|
216
310
|
}
|
|
@@ -219,7 +313,11 @@ async function handleAgentEventPayload(db, observability, payload, subject) {
|
|
|
219
313
|
return;
|
|
220
314
|
}
|
|
221
315
|
try {
|
|
222
|
-
await ingestHeartbeat(db, {
|
|
316
|
+
await ingestHeartbeat(db, {
|
|
317
|
+
workspaceId: ids.workspaceId,
|
|
318
|
+
agentId: ids.agentId,
|
|
319
|
+
sample: metrics
|
|
320
|
+
});
|
|
223
321
|
} catch (error) {
|
|
224
322
|
observability?.warn?.("Failed to ingest a machine metrics heartbeat", {
|
|
225
323
|
subject,
|
|
@@ -230,7 +328,7 @@ async function handleAgentEventPayload(db, observability, payload, subject) {
|
|
|
230
328
|
function startMetricsIngestion(deps) {
|
|
231
329
|
return deps.bus.subscribeAgentEvents(
|
|
232
330
|
AGENT_EVENTS_SUBJECT,
|
|
233
|
-
(payload, subject) => handleAgentEventPayload(deps.db, deps.observability, payload, subject)
|
|
331
|
+
(payload, subject) => handleAgentEventPayload(deps.db, deps.observability, payload, subject, deps.bus)
|
|
234
332
|
);
|
|
235
333
|
}
|
|
236
334
|
function helloReportsDisplay(hello) {
|
|
@@ -247,6 +345,9 @@ function helloDesktopUnavailableReason(hello) {
|
|
|
247
345
|
const reason = hello.capabilities?.desktopUnavailableReason;
|
|
248
346
|
return reason ? reason : null;
|
|
249
347
|
}
|
|
348
|
+
function helloReportsOpStream(hello) {
|
|
349
|
+
return hello.capabilities?.opStream === true;
|
|
350
|
+
}
|
|
250
351
|
async function refreshEnrollmentDisplay(db, input) {
|
|
251
352
|
const desktopUnavailableReason = input.desktopUnavailableReason ?? null;
|
|
252
353
|
const enrollment = await getEnrollment2(db, input.workspaceId, input.agentId);
|
|
@@ -264,7 +365,22 @@ async function refreshEnrollmentDisplay(db, input) {
|
|
|
264
365
|
desktopUnavailableReason
|
|
265
366
|
});
|
|
266
367
|
}
|
|
267
|
-
async function
|
|
368
|
+
async function refreshEnrollmentOpStream(db, input) {
|
|
369
|
+
const enrollment = await getEnrollment2(db, input.workspaceId, input.agentId);
|
|
370
|
+
if (!enrollment) {
|
|
371
|
+
return { updated: false };
|
|
372
|
+
}
|
|
373
|
+
if (enrollment.opStream === input.opStream) {
|
|
374
|
+
return { updated: false };
|
|
375
|
+
}
|
|
376
|
+
return await setEnrollmentOpStreamState(db, {
|
|
377
|
+
accountId: enrollment.accountId,
|
|
378
|
+
workspaceId: input.workspaceId,
|
|
379
|
+
enrollmentId: input.agentId,
|
|
380
|
+
opStream: input.opStream
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
async function handleHelloPayload(db, observability, payload, subject, bus) {
|
|
268
384
|
const ids = parseAgentHelloSubject(subject);
|
|
269
385
|
if (!ids) {
|
|
270
386
|
return;
|
|
@@ -286,8 +402,38 @@ async function handleHelloPayload(db, observability, payload, subject) {
|
|
|
286
402
|
hasDisplay: helloReportsDisplay(hello),
|
|
287
403
|
desktopUnavailableReason: helloDesktopUnavailableReason(hello)
|
|
288
404
|
});
|
|
405
|
+
await refreshEnrollmentOpStream(db, {
|
|
406
|
+
workspaceId: ids.workspaceId,
|
|
407
|
+
agentId: ids.agentId,
|
|
408
|
+
opStream: helloReportsOpStream(hello)
|
|
409
|
+
});
|
|
289
410
|
} catch (error) {
|
|
290
|
-
observability?.warn?.("Failed to refresh an enrollment's
|
|
411
|
+
observability?.warn?.("Failed to refresh an enrollment's capabilities from a Hello", {
|
|
412
|
+
subject,
|
|
413
|
+
error: error instanceof Error ? error.message : String(error)
|
|
414
|
+
});
|
|
415
|
+
}
|
|
416
|
+
try {
|
|
417
|
+
const enrollment = await getEnrollment2(db, ids.workspaceId, ids.agentId);
|
|
418
|
+
if (enrollment) {
|
|
419
|
+
const { cleared } = await clearEnrollmentWentOffline(db, {
|
|
420
|
+
accountId: enrollment.accountId,
|
|
421
|
+
workspaceId: ids.workspaceId,
|
|
422
|
+
enrollmentId: ids.agentId
|
|
423
|
+
});
|
|
424
|
+
if (cleared && bus) {
|
|
425
|
+
await fanOutMachineLinkEvents(
|
|
426
|
+
db,
|
|
427
|
+
bus,
|
|
428
|
+
observability,
|
|
429
|
+
ids.workspaceId,
|
|
430
|
+
ids.agentId,
|
|
431
|
+
(activeTurnId) => [{ type: "machine.link.restored", turnId: activeTurnId, payload: {} }]
|
|
432
|
+
);
|
|
433
|
+
}
|
|
434
|
+
}
|
|
435
|
+
} catch (error) {
|
|
436
|
+
observability?.warn?.("Failed to clear a machine going-offline marker on a Hello", {
|
|
291
437
|
subject,
|
|
292
438
|
error: error instanceof Error ? error.message : String(error)
|
|
293
439
|
});
|
|
@@ -296,7 +442,7 @@ async function handleHelloPayload(db, observability, payload, subject) {
|
|
|
296
442
|
function startHelloIngestion(deps) {
|
|
297
443
|
return deps.bus.subscribeAgentEvents(
|
|
298
444
|
AGENT_HELLO_SUBJECT,
|
|
299
|
-
(payload, subject) => handleHelloPayload(deps.db, deps.observability, payload, subject)
|
|
445
|
+
(payload, subject) => handleHelloPayload(deps.db, deps.observability, payload, subject, deps.bus)
|
|
300
446
|
);
|
|
301
447
|
}
|
|
302
448
|
|
|
@@ -318,7 +464,7 @@ var TEMPORAL_MONTHS = [
|
|
|
318
464
|
"NOVEMBER",
|
|
319
465
|
"DECEMBER"
|
|
320
466
|
];
|
|
321
|
-
async function createTemporalWorkflowClient(settings) {
|
|
467
|
+
async function createTemporalWorkflowClient(settings, db) {
|
|
322
468
|
const connection = await Connection.connect({ address: settings.temporalHost });
|
|
323
469
|
const temporal = new TemporalClient({
|
|
324
470
|
connection,
|
|
@@ -328,27 +474,79 @@ async function createTemporalWorkflowClient(settings) {
|
|
|
328
474
|
signalUserMessage: async ({ eventId, workflowId }) => {
|
|
329
475
|
await temporal.workflow.getHandle(workflowId).signal("userMessage", eventId);
|
|
330
476
|
},
|
|
331
|
-
wakeSessionWorkflow: async ({
|
|
477
|
+
wakeSessionWorkflow: async ({
|
|
478
|
+
accountId,
|
|
479
|
+
workspaceId,
|
|
480
|
+
sessionId,
|
|
481
|
+
workflowId,
|
|
482
|
+
wakeRevision,
|
|
483
|
+
interruptionRequested
|
|
484
|
+
}) => {
|
|
332
485
|
await temporal.workflow.signalWithStart("sessionWorkflow", {
|
|
333
486
|
taskQueue: settings.temporalTaskQueue,
|
|
334
487
|
workflowId,
|
|
335
488
|
workflowIdReusePolicy: "ALLOW_DUPLICATE",
|
|
336
489
|
args: [{ accountId, workspaceId, sessionId }],
|
|
337
|
-
signal: "queueChanged"
|
|
490
|
+
signal: interruptionRequested ? "sessionControl" : "queueChanged"
|
|
491
|
+
});
|
|
492
|
+
await markSessionWorkflowWakeDelivered(db, {
|
|
493
|
+
accountId,
|
|
494
|
+
workspaceId,
|
|
495
|
+
sessionId,
|
|
496
|
+
temporalWorkflowId: workflowId,
|
|
497
|
+
wakeRevision
|
|
338
498
|
});
|
|
339
499
|
},
|
|
340
|
-
|
|
341
|
-
await temporal.
|
|
500
|
+
requestSessionWorkflowWakeDispatch: async () => {
|
|
501
|
+
await temporal.schedule.getHandle(SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID).trigger(ScheduleOverlapPolicy.BUFFER_ONE);
|
|
342
502
|
},
|
|
343
|
-
|
|
503
|
+
signalCodexCapacity: async ({
|
|
504
|
+
accountId,
|
|
505
|
+
workspaceId,
|
|
506
|
+
sessionId,
|
|
507
|
+
workflowId,
|
|
508
|
+
wakeRevision,
|
|
509
|
+
workflowWakeRevision
|
|
510
|
+
}) => {
|
|
344
511
|
await temporal.workflow.signalWithStart("sessionWorkflow", {
|
|
345
512
|
taskQueue: settings.temporalTaskQueue,
|
|
346
513
|
workflowId,
|
|
347
514
|
workflowIdReusePolicy: "ALLOW_DUPLICATE",
|
|
348
515
|
args: [{ accountId, workspaceId, sessionId }],
|
|
349
|
-
signal: "
|
|
516
|
+
signal: "codexCapacityChanged",
|
|
517
|
+
signalArgs: [wakeRevision]
|
|
518
|
+
});
|
|
519
|
+
await markSessionWorkflowWakeDelivered(db, {
|
|
520
|
+
accountId,
|
|
521
|
+
workspaceId,
|
|
522
|
+
sessionId,
|
|
523
|
+
temporalWorkflowId: workflowId,
|
|
524
|
+
wakeRevision: workflowWakeRevision
|
|
525
|
+
});
|
|
526
|
+
},
|
|
527
|
+
signalApprovalDecision: async ({
|
|
528
|
+
accountId,
|
|
529
|
+
workspaceId,
|
|
530
|
+
sessionId,
|
|
531
|
+
eventId,
|
|
532
|
+
workflowId,
|
|
533
|
+
workflowWakeRevision
|
|
534
|
+
}) => {
|
|
535
|
+
await temporal.workflow.signalWithStart("sessionWorkflow", {
|
|
536
|
+
taskQueue: settings.temporalTaskQueue,
|
|
537
|
+
workflowId,
|
|
538
|
+
workflowIdReusePolicy: "ALLOW_DUPLICATE",
|
|
539
|
+
args: [{ accountId, workspaceId, sessionId }],
|
|
540
|
+
signal: "approvalDecision",
|
|
350
541
|
signalArgs: [eventId]
|
|
351
542
|
});
|
|
543
|
+
await markSessionWorkflowWakeDelivered(db, {
|
|
544
|
+
accountId,
|
|
545
|
+
workspaceId,
|
|
546
|
+
sessionId,
|
|
547
|
+
temporalWorkflowId: workflowId,
|
|
548
|
+
wakeRevision: workflowWakeRevision
|
|
549
|
+
});
|
|
352
550
|
},
|
|
353
551
|
syncScheduledTask: async ({ task }) => {
|
|
354
552
|
const schedule = temporal.schedule.getHandle(task.temporalScheduleId);
|
|
@@ -372,13 +570,15 @@ async function createTemporalWorkflowClient(settings) {
|
|
|
372
570
|
taskQueue: settings.temporalTaskQueue,
|
|
373
571
|
workflowId,
|
|
374
572
|
workflowIdReusePolicy: "REJECT_DUPLICATE",
|
|
375
|
-
args: [
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
573
|
+
args: [
|
|
574
|
+
{
|
|
575
|
+
accountId: task.accountId,
|
|
576
|
+
workspaceId: task.workspaceId,
|
|
577
|
+
taskId: task.id,
|
|
578
|
+
triggerType: "manual",
|
|
579
|
+
agentRunUsageIdempotencyKey
|
|
580
|
+
}
|
|
581
|
+
]
|
|
382
582
|
});
|
|
383
583
|
} catch (error) {
|
|
384
584
|
if (isWorkflowAlreadyStarted(error)) {
|
|
@@ -387,6 +587,24 @@ async function createTemporalWorkflowClient(settings) {
|
|
|
387
587
|
throw error;
|
|
388
588
|
}
|
|
389
589
|
},
|
|
590
|
+
startRigVerification: async ({ workspaceId, changeId, versionId, workflowId }) => {
|
|
591
|
+
const targetId = changeId ?? versionId;
|
|
592
|
+
if (!targetId) {
|
|
593
|
+
throw new Error("rig verification requires changeId or versionId");
|
|
594
|
+
}
|
|
595
|
+
await temporal.workflow.start("rigVerificationWorkflow", {
|
|
596
|
+
taskQueue: settings.temporalTaskQueue,
|
|
597
|
+
workflowId: workflowId ?? `rig-verification-${targetId}-${crypto.randomUUID()}`,
|
|
598
|
+
workflowIdReusePolicy: "ALLOW_DUPLICATE",
|
|
599
|
+
args: [
|
|
600
|
+
{
|
|
601
|
+
workspaceId,
|
|
602
|
+
...changeId ? { changeId } : {},
|
|
603
|
+
...versionId ? { versionId } : {}
|
|
604
|
+
}
|
|
605
|
+
]
|
|
606
|
+
});
|
|
607
|
+
},
|
|
390
608
|
check: async () => {
|
|
391
609
|
await connection.workflowService.getSystemInfo({});
|
|
392
610
|
}
|
|
@@ -435,16 +653,16 @@ async function startApi() {
|
|
|
435
653
|
onRetry
|
|
436
654
|
}
|
|
437
655
|
);
|
|
438
|
-
workflowClient = await retryStartupDependency(
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
656
|
+
workflowClient = await retryStartupDependency(
|
|
657
|
+
"Temporal",
|
|
658
|
+
() => createTemporalWorkflowClient(settings, dbClient.db),
|
|
659
|
+
{
|
|
660
|
+
...retryOptions,
|
|
661
|
+
onRetry
|
|
662
|
+
}
|
|
663
|
+
);
|
|
442
664
|
} catch (error) {
|
|
443
|
-
await Promise.allSettled([
|
|
444
|
-
bus?.close(),
|
|
445
|
-
workflowClient?.close(),
|
|
446
|
-
dbClient.close()
|
|
447
|
-
]);
|
|
665
|
+
await Promise.allSettled([bus?.close(), workflowClient?.close(), dbClient.close()]);
|
|
448
666
|
throw error;
|
|
449
667
|
}
|
|
450
668
|
if (!bus || !workflowClient) {
|
|
@@ -535,25 +753,29 @@ function temporalScheduleSpec(schedule) {
|
|
|
535
753
|
}
|
|
536
754
|
if (schedule.type === "calendar") {
|
|
537
755
|
return {
|
|
538
|
-
calendars: [
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
756
|
+
calendars: [
|
|
757
|
+
{
|
|
758
|
+
hour: schedule.hour,
|
|
759
|
+
minute: schedule.minute,
|
|
760
|
+
second: 0,
|
|
761
|
+
...schedule.daysOfWeek ? { dayOfWeek: schedule.daysOfWeek } : {}
|
|
762
|
+
}
|
|
763
|
+
],
|
|
544
764
|
timezone: schedule.timeZone
|
|
545
765
|
};
|
|
546
766
|
}
|
|
547
767
|
const runAt = new Date(schedule.runAt);
|
|
548
768
|
return {
|
|
549
|
-
calendars: [
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
769
|
+
calendars: [
|
|
770
|
+
{
|
|
771
|
+
year: runAt.getUTCFullYear(),
|
|
772
|
+
month: temporalMonth(runAt.getUTCMonth()),
|
|
773
|
+
dayOfMonth: runAt.getUTCDate(),
|
|
774
|
+
hour: runAt.getUTCHours(),
|
|
775
|
+
minute: runAt.getUTCMinutes(),
|
|
776
|
+
second: runAt.getUTCSeconds()
|
|
777
|
+
}
|
|
778
|
+
],
|
|
557
779
|
timezone: "UTC"
|
|
558
780
|
};
|
|
559
781
|
}
|
|
@@ -568,12 +790,14 @@ function temporalScheduleOptions(task, taskQueue) {
|
|
|
568
790
|
type: "startWorkflow",
|
|
569
791
|
workflowType: "scheduledTaskFireWorkflow",
|
|
570
792
|
taskQueue,
|
|
571
|
-
args: [
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
793
|
+
args: [
|
|
794
|
+
{
|
|
795
|
+
accountId: task.accountId,
|
|
796
|
+
workspaceId: task.workspaceId,
|
|
797
|
+
taskId: task.id,
|
|
798
|
+
triggerType: "scheduled"
|
|
799
|
+
}
|
|
800
|
+
]
|
|
577
801
|
},
|
|
578
802
|
policies: {
|
|
579
803
|
overlap: temporalOverlapPolicy(task.overlapPolicy),
|