@opengeni/worker-bundle 0.29.0-canary.0 → 0.29.0-canary.2

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.
Files changed (49) hide show
  1. package/dist/activities/agent-turn/knowledge-source-tools.d.ts +9 -0
  2. package/dist/activities/agent-turn/knowledge-sources.d.ts +20 -0
  3. package/dist/activities/agent-turn/stream-attempt.d.ts +1 -0
  4. package/dist/activities/agent-turn/tool-environment.d.ts +1 -0
  5. package/dist/activities/knowledge-indexing.d.ts +10 -0
  6. package/dist/activities/run-input.d.ts +1 -0
  7. package/dist/activities/types.d.ts +10 -3
  8. package/dist/{activities-control-MKGEOBXT.js → activities-control-HMFGSKC5.js} +331 -3381
  9. package/dist/activities-control-HMFGSKC5.js.map +1 -0
  10. package/dist/activities-control.d.ts +12 -0
  11. package/dist/{activities-turn-5MZZ6HQA.js → activities-turn-AP67JADS.js} +1296 -1021
  12. package/dist/activities-turn-AP67JADS.js.map +1 -0
  13. package/dist/activities.d.ts +12 -0
  14. package/dist/{chunk-OA5CSY5N.js → chunk-CYITU5UH.js} +3348 -174
  15. package/dist/chunk-CYITU5UH.js.map +1 -0
  16. package/dist/index.d.ts +13 -0
  17. package/dist/index.js +48 -1
  18. package/dist/index.js.map +1 -1
  19. package/dist/workflow-bundle.js +65 -35
  20. package/dist/workflows/knowledge-indexing.d.ts +2 -0
  21. package/dist/workflows.d.ts +1 -0
  22. package/package.json +19 -18
  23. package/src/activities/agent-turn/knowledge-source-tools.ts +98 -0
  24. package/src/activities/agent-turn/knowledge-sources.ts +86 -0
  25. package/src/activities/agent-turn/run.ts +1244 -1112
  26. package/src/activities/agent-turn/skill-install.ts +1 -1
  27. package/src/activities/agent-turn/skill-save.ts +1 -1
  28. package/src/activities/agent-turn/skill-selection.ts +2 -0
  29. package/src/activities/agent-turn/skill-tools.ts +5 -12
  30. package/src/activities/agent-turn/stream-attempt.ts +3 -0
  31. package/src/activities/agent-turn/tool-environment.ts +24 -0
  32. package/src/activities/codex-image-generation.ts +1 -2
  33. package/src/activities/documents.ts +17 -52
  34. package/src/activities/knowledge-indexing.ts +130 -0
  35. package/src/activities/knowledge-source-sync.ts +120 -16
  36. package/src/activities/mcp-credentials.ts +2 -0
  37. package/src/activities/run-input.ts +2 -0
  38. package/src/activities/scheduled-tasks.ts +25 -62
  39. package/src/activities/types.ts +8 -2
  40. package/src/activities/video-generation-reconciliation.ts +8 -1
  41. package/src/activities-control.ts +2 -0
  42. package/src/activities.ts +1 -0
  43. package/src/index.ts +49 -0
  44. package/src/pr-review-credentials.ts +2 -2
  45. package/src/workflows/knowledge-indexing.ts +12 -0
  46. package/src/workflows.ts +1 -0
  47. package/dist/activities-control-MKGEOBXT.js.map +0 -1
  48. package/dist/activities-turn-5MZZ6HQA.js.map +0 -1
  49. package/dist/chunk-OA5CSY5N.js.map +0 -1
@@ -81,6 +81,7 @@ export type TurnInputOptions = {
81
81
  unavailableSandboxFilesNote?: string;
82
82
  runCredentialsNote?: string;
83
83
  mcpAvailabilityNote?: string;
84
+ knowledgeSourcePreparationNote?: string;
84
85
  providerApi: HistoryProviderApi;
85
86
  projectCanonicalHistory?: ModelHistoryAttachmentProjector;
86
87
  materializeModelHistory?: ModelHistoryAttachmentProjector;
@@ -509,6 +510,7 @@ export async function turnInput(
509
510
  options.unavailableSandboxFilesNote,
510
511
  options.runCredentialsNote,
511
512
  options.mcpAvailabilityNote,
513
+ options.knowledgeSourcePreparationNote,
512
514
  );
513
515
  if (trigger.type === "user.message") {
514
516
  const payload = trigger.payload as {
@@ -41,7 +41,6 @@ import {
41
41
  getScheduledTaskRunAcceptedExecution,
42
42
  getScheduledTaskRunByProducerKey,
43
43
  getScheduledTargetSessionExecution,
44
- ensureKnowledgeSourceSyncState,
45
44
  getScheduledTaskPersonalConnectionDelegations,
46
45
  getScheduledTaskRunPersonalResourceAuthority,
47
46
  getScheduledTaskPersonalResourceAuthoritySubject,
@@ -62,14 +61,12 @@ import {
62
61
  listInstalledApiIntegrationServerIdsForDelegations,
63
62
  markScheduledTaskRunFailedIfQueued,
64
63
  markScheduledTaskRunSkippedIfQueued,
65
- recordKnowledgeSourceSyncWake,
66
64
  recordUsageEvent,
67
65
  requireScheduledTaskIncidentAuthorityInTransaction,
68
66
  requireSession,
69
67
  requireWorkspace,
70
68
  settleScheduledTaskRunInTransaction,
71
69
  SessionSpawnDeniedDbError,
72
- updateScheduledTaskRun,
73
70
  updateSessionTitleWithEvent,
74
71
  upsertScheduledSessionGoalForRun,
75
72
  withSessionActivityRlsContext,
@@ -364,69 +361,15 @@ export function createScheduledTaskActivities(services: () => Promise<ControlAct
364
361
  if (!task) {
365
362
  return { action: "deleted" };
366
363
  }
367
- if (task.action.kind === "knowledge_source_sync") {
368
- if (knowledgeSourceSyncEffectivelyPaused(task)) {
369
- return { action: "blocked", reason: "knowledge_source_paused" };
370
- }
371
- const run = await createScheduledTaskRun(db, {
372
- workspaceId: task.workspaceId,
373
- taskId: task.id,
374
- taskAuthorityRevision: task.authorityRevision,
375
- taskExecutionDigest: task.executionDigest,
376
- triggerType: input.triggerType,
377
- producerKey: stableProducerKey,
378
- scheduledAt: null,
379
- });
380
- await ensureKnowledgeSourceSyncState(db, task);
381
- await recordKnowledgeSourceSyncWake(db, {
382
- accountId: task.accountId,
383
- workspaceId: task.workspaceId,
384
- sourceId: task.action.sourceId,
385
- scheduledTaskId: task.id,
386
- scheduledTaskRunId: run.id,
387
- cause: input.triggerType,
388
- producerKey: stableProducerKey,
389
- sourceConfigGeneration: task.action.sourceConfigGeneration,
390
- sourceLifecycleGeneration: task.action.sourceLifecycleGeneration,
391
- });
392
- await recordUsageEvent(db, {
393
- accountId: task.accountId,
394
- workspaceId: task.workspaceId,
395
- eventType: "knowledge_source_sync.fired",
396
- quantity: 1,
397
- unit: "run",
398
- sourceResourceType: "scheduled_task_run",
399
- sourceResourceId: run.id,
400
- initiator: input.initiator ?? {
401
- kind: "service",
402
- subjectId: "scheduler",
403
- },
404
- initiatorContext: {
405
- scheduledTaskId: task.id,
406
- scheduledTaskRunId: run.id,
407
- },
408
- origin: "scheduled_task",
409
- idempotencyKey: `usage:knowledge_source_sync.fired:${run.id}`,
410
- });
411
- if (run.status === "queued") {
412
- await updateScheduledTaskRun(db, task.workspaceId, run.id, {
413
- status: "dispatched",
414
- actionKind: "knowledge_source_sync",
415
- });
416
- }
417
- return {
418
- action: "knowledge_source_sync",
419
- accountId: task.accountId,
420
- workspaceId: task.workspaceId,
421
- taskId: task.id,
422
- scheduledTaskRunId: run.id,
423
- sourceId: task.action.sourceId,
424
- overlapPolicy: task.overlapPolicy as "skip" | "buffer_one",
425
- };
364
+ if (task.action.kind !== "agent_turn") {
365
+ return { action: "blocked", reason: "legacy_source_schedule_requires_migration" };
426
366
  }
427
367
  if (task.status !== "active") {
428
368
  return { action: "blocked", reason: "scheduled_task_paused" };
429
369
  }
370
+ if (task.agentConfig.knowledgeSource && knowledgeSourceSyncEffectivelyPaused(task)) {
371
+ return { action: "blocked", reason: "knowledge_source_paused" };
372
+ }
430
373
  const structuredAlertOccurrence = scheduledAlertOccurrenceIdentity({
431
374
  workspaceId: task.workspaceId,
432
375
  scheduledTaskId: task.id,
@@ -778,6 +721,14 @@ export function createScheduledTaskActivities(services: () => Promise<ControlAct
778
721
  throw new Error("scheduled authority classes have different causal humans");
779
722
  }
780
723
  const causalHumanSubjectId = taskAuthoritySubjectId ?? xaiAuthoritySubjectId;
724
+ if (
725
+ task.agentConfig.knowledgeSource &&
726
+ causalHumanSubjectId !== task.agentConfig.knowledgeSource.initiatingSubjectId
727
+ ) {
728
+ throw new Error(
729
+ "Source schedule requires its connection owner's current human authorization; update the source schedule to authorize it",
730
+ );
731
+ }
781
732
  // Workspace/organization Variable Sets and Rigs run through ordinary
782
733
  // workspace authority; only a user-owned resource needs the exact frozen
783
734
  // human, and the database admission fence re-proves the same rule for
@@ -1084,6 +1035,12 @@ export function createScheduledTaskActivities(services: () => Promise<ControlAct
1084
1035
  firstPartyMcpTools,
1085
1036
  firstPartyMcpPermissions,
1086
1037
  ...creatorSessionPolicy,
1038
+ ...(task.agentConfig.knowledgeSource?.destination.kind === "personal"
1039
+ ? {
1040
+ visibility: "user_private" as const,
1041
+ scheduledSourceRunId: run.id,
1042
+ }
1043
+ : {}),
1087
1044
  metadata: {
1088
1045
  ...taskMetadata,
1089
1046
  model,
@@ -2110,6 +2067,12 @@ async function recoverBoundScheduledTaskDispatch(input: {
2110
2067
  firstPartyMcpTools: input.acceptedExecution.resolvedFirstPartyMcpTools,
2111
2068
  firstPartyMcpPermissions: input.acceptedExecution.resolvedFirstPartyMcpPermissions,
2112
2069
  ...scheduledCreatorSessionPolicyInput(recoveredCreatorPolicy?.sessionPolicy ?? null),
2070
+ ...(task.agentConfig.knowledgeSource?.destination.kind === "personal"
2071
+ ? {
2072
+ visibility: "user_private" as const,
2073
+ scheduledSourceRunId: input.run.id,
2074
+ }
2075
+ : {}),
2113
2076
  metadata: {
2114
2077
  ...taskMetadata,
2115
2078
  model: input.acceptedExecution.resolvedModel,
@@ -3,6 +3,7 @@ import type {
3
3
  ConnectionCredentialsPort,
4
4
  DocumentAuthorityKind,
5
5
  EntitlementsPort,
6
+ KnowledgeSourceSyncRunSummary,
6
7
  ScheduledTaskTriggerType,
7
8
  TurnInitiator,
8
9
  } from "@opengeni/contracts";
@@ -434,6 +435,7 @@ export type DispatchScheduledTaskRunResult =
434
435
  | "scheduled_run_terminal"
435
436
  | "scheduled_execution_unrepresentable"
436
437
  | "knowledge_source_paused"
438
+ | "legacy_source_schedule_requires_migration"
437
439
  | "incident_preflight_metadata_missing"
438
440
  | "incident_responder_under_capable"
439
441
  | "incident_data_source_unsuitable";
@@ -458,6 +460,9 @@ export type DispatchScheduledTaskRunResult =
458
460
  };
459
461
 
460
462
  export type RunKnowledgeSourceSyncBatchInput = {
463
+ /** Host-bound attempt only. Legacy control workflow inputs have none and cannot fetch. */
464
+ agent?: Extract<import("@opengeni/db").KnowledgeActor, { kind: "agent" }>;
465
+
461
466
  accountId: string;
462
467
  workspaceId: string;
463
468
  taskId: string;
@@ -479,7 +484,7 @@ export type DispatchAutomationRunResult =
479
484
  | { action: "failed"; reason: string }
480
485
  | { action: "not_found" };
481
486
 
482
- export type RunKnowledgeSourceSyncBatchResult =
487
+ export type RunKnowledgeSourceSyncBatchResult = (
483
488
  | { action: "continue" }
484
489
  | {
485
490
  action: "complete";
@@ -491,7 +496,8 @@ export type RunKnowledgeSourceSyncBatchResult =
491
496
  action: "failed";
492
497
  bufferedWake: boolean;
493
498
  bufferedScheduledTaskRunId?: string | null;
494
- };
499
+ }
500
+ ) & { summary?: KnowledgeSourceSyncRunSummary; errorCode?: string };
495
501
 
496
502
  type DocumentIndexIdentity = {
497
503
  accountId: string;
@@ -17,6 +17,7 @@ import {
17
17
  markVideoGenerationTerminalUpdate,
18
18
  markVideoGenerationTerminalUpdateInTransaction,
19
19
  mediaGenerationResultForStoredOperation,
20
+ withSessionRlsActorContext,
20
21
  rescheduleVideoGenerationOperation,
21
22
  settleVideoGenerationFailure,
22
23
  settleVideoGenerationReady,
@@ -497,7 +498,13 @@ async function terminalPayload(
497
498
  service: TurnActivityServices,
498
499
  operation: VideoGenerationOperationWithReferences,
499
500
  ): Promise<MediaGenerationResult> {
500
- return await mediaGenerationResultForStoredOperation(service.db, operation);
501
+ return withSessionRlsActorContext(
502
+ {
503
+ subjectId: "service:video-generation-reconciliation",
504
+ privateFileOwnerSubjectId: operation.privateFileOwnerSubjectId ?? null,
505
+ },
506
+ () => mediaGenerationResultForStoredOperation(service.db, operation),
507
+ );
501
508
  }
502
509
 
503
510
  async function requireOperation(
@@ -1,3 +1,4 @@
1
+ import { createKnowledgeIndexingActivities } from "./activities/knowledge-indexing";
1
2
  import { createSharedActivityServices } from "./activity-services";
2
3
  import { createCodexCapacityActivities } from "./activities/codex-capacity";
3
4
  import { createBrowserStateArtifactMaintenanceActivities } from "./activities/browser-state-artifact-reaper";
@@ -29,6 +30,7 @@ export function createControlActivitiesFromServices(
29
30
  return {
30
31
  ...createAutomationActivities(services),
31
32
  ...createDocumentActivities(services, resolveDocumentServices),
33
+ ...createKnowledgeIndexingActivities(services, resolveDocumentServices),
32
34
  ...createKnowledgeSourceSyncActivities(services, resolveDocumentServices),
33
35
  ...createSessionStateActivities(services),
34
36
  ...createScheduledTaskActivities(services),
package/src/activities.ts CHANGED
@@ -92,6 +92,7 @@ export const runAgentTurn = defaultTurnActivities.runAgentTurn;
92
92
  export const reconcileVideoGenerationOperation =
93
93
  defaultTurnActivities.reconcileVideoGenerationOperation;
94
94
  export const indexDocument = defaultControlActivities.indexDocument;
95
+ export const indexKnowledge = defaultControlActivities.indexKnowledge;
95
96
  export const failSessionAttempt = defaultControlActivities.failSessionAttempt;
96
97
  export const settleSessionInterruptions = defaultControlActivities.settleSessionInterruptions;
97
98
  export const persistSessionAttemptQuiescence =
package/src/index.ts CHANGED
@@ -118,6 +118,8 @@ export {
118
118
  // no-op — so the Schedule is registered EXACTLY ONCE per deployment regardless
119
119
  // of replica count.
120
120
  const SANDBOX_REAPER_SCHEDULE_ID = "opengeni-sandbox-lease-reaper";
121
+ export const KNOWLEDGE_INDEXING_SCHEDULE_ID = "opengeni-knowledge-indexing";
122
+ export const KNOWLEDGE_INDEXING_PERIOD_MS = 15_000;
121
123
  export const FILE_UPLOAD_REAPER_SCHEDULE_ID = "opengeni-file-upload-reaper";
122
124
  export const FILE_UPLOAD_REAPER_PERIOD_MS = 15 * 60 * 1_000;
123
125
  export const SITE_AUTH_MAINTENANCE_SCHEDULE_ID = "opengeni-site-auth-maintenance";
@@ -615,6 +617,46 @@ export async function registerSandboxReaperSchedule(
615
617
  }
616
618
  }
617
619
 
620
+ /** Register the deployment-wide worker for rebuildable Knowledge search projections. */
621
+ export async function registerKnowledgeIndexingSchedule(
622
+ settings: Settings,
623
+ observability: Observability,
624
+ ): Promise<{ registered: boolean; close: () => Promise<void> }> {
625
+ const connection = await Connection.connect(temporalConnectionOptions(settings));
626
+ const temporal = new TemporalClient({ connection, namespace: settings.temporalNamespace });
627
+ try {
628
+ await temporal.schedule.create({
629
+ scheduleId: KNOWLEDGE_INDEXING_SCHEDULE_ID,
630
+ spec: { intervals: [{ every: KNOWLEDGE_INDEXING_PERIOD_MS }] },
631
+ action: {
632
+ type: "startWorkflow",
633
+ workflowType: "knowledgeIndexingWorkflow",
634
+ taskQueue: settings.temporalTaskQueue,
635
+ args: [],
636
+ },
637
+ policies: {
638
+ overlap: ScheduleOverlapPolicy.SKIP,
639
+ catchupWindow: "1m",
640
+ pauseOnFailure: false,
641
+ },
642
+ });
643
+ observability.info("Registered the global Knowledge indexer Schedule", {
644
+ scheduleId: KNOWLEDGE_INDEXING_SCHEDULE_ID,
645
+ indexingPeriodMs: KNOWLEDGE_INDEXING_PERIOD_MS,
646
+ });
647
+ return { registered: true, close: async () => connection.close() };
648
+ } catch (error) {
649
+ if (error instanceof ScheduleAlreadyRunning) {
650
+ observability.info("Global Knowledge indexer Schedule already registered", {
651
+ scheduleId: KNOWLEDGE_INDEXING_SCHEDULE_ID,
652
+ });
653
+ return { registered: false, close: async () => connection.close() };
654
+ }
655
+ await connection.close().catch(() => undefined);
656
+ throw error;
657
+ }
658
+ }
659
+
618
660
  /**
619
661
  * Register the one provider-neutral expired direct-upload cleanup Schedule.
620
662
  * Unlike sandbox GC this is always registered: file uploads can be enabled in
@@ -913,6 +955,13 @@ export async function createOpenGeniWorkerService(
913
955
  { ...retryOptions, onRetry },
914
956
  ),
915
957
  );
958
+ schedules.push(
959
+ await retryStartupDependency(
960
+ "Temporal schedule (Knowledge indexing)",
961
+ () => registerKnowledgeIndexingSchedule(settings, observability),
962
+ { ...retryOptions, onRetry },
963
+ ),
964
+ );
916
965
  schedules.push(
917
966
  await retryStartupDependency(
918
967
  "Temporal schedule (file upload reaper)",
@@ -5,7 +5,7 @@ import type {
5
5
  GitCredentialsRequest,
6
6
  } from "@opengeni/contracts";
7
7
  import { prReviewRegistrationIdFromCredentialBinding } from "@opengeni/core";
8
- import { createRemoteMcpCredentialsPort } from "@opengeni/core/remote-mcp-credentials";
8
+ import { createNativeRemoteMcpCredentialsPort } from "@opengeni/core/remote-mcp-credentials";
9
9
  import { decryptVariableSetValue, resolvePrReviewGitCredential, type Database } from "@opengeni/db";
10
10
  import {
11
11
  createGitHubAppInstallationTokenWithExpiry,
@@ -19,7 +19,7 @@ export function createStandaloneConnectionCredentialsPort(
19
19
  db: Database,
20
20
  ): ConnectionCredentialsPort {
21
21
  return {
22
- ...createRemoteMcpCredentialsPort(settings),
22
+ ...createNativeRemoteMcpCredentialsPort(settings, db),
23
23
  gitCredentials: async (request) => await resolveStandaloneGitCredentials(settings, db, request),
24
24
  };
25
25
  }
@@ -0,0 +1,12 @@
1
+ import { proxyActivities } from "@temporalio/workflow";
2
+ import type * as activities from "../activities";
3
+
4
+ const indexing = proxyActivities<Pick<typeof activities, "indexKnowledge">>({
5
+ startToCloseTimeout: "5 minutes",
6
+ retry: { maximumAttempts: 1 },
7
+ });
8
+
9
+ /** Rebuild derived search projections; this is not a source-ingestion task. */
10
+ export async function knowledgeIndexingWorkflow(): Promise<void> {
11
+ await indexing.indexKnowledge();
12
+ }
package/src/workflows.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { knowledgeIndexingWorkflow } from "./workflows/knowledge-indexing";
1
2
  export { documentIndexWorkflow, type DocumentIndexWorkflowInput } from "./workflows/document-index";
2
3
  export {
3
4
  approvalDecision,