@opengeni/core 0.18.1 → 0.19.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opengeni/core",
3
- "version": "0.18.1",
3
+ "version": "0.19.0",
4
4
  "description": "OpenGeni framework-agnostic core: the domain, access, and billing layers (neutral access, off-HTTP V2 surface). Behavior-preserving extraction from apps/api — keeps Hono's HTTPException for error throwing (typed-errors cleanup deferred).",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -34,15 +34,15 @@
34
34
  },
35
35
  "dependencies": {
36
36
  "@modelcontextprotocol/sdk": "^1.29.0",
37
- "@opengeni/codex": "^0.2.9",
38
- "@opengeni/config": "^0.10.1",
39
- "@opengeni/contracts": "^0.31.1",
40
- "@opengeni/db": "^0.22.2",
41
- "@opengeni/documents": "^0.2.70",
42
- "@opengeni/events": "^0.3.60",
43
- "@opengeni/observability": "^0.4.4",
44
- "@opengeni/runtime": "^0.17.1",
45
- "@opengeni/storage": "^0.2.54",
37
+ "@opengeni/codex": "^0.2.10",
38
+ "@opengeni/config": "^0.10.3",
39
+ "@opengeni/contracts": "^0.32.0",
40
+ "@opengeni/db": "^0.23.0",
41
+ "@opengeni/documents": "^0.2.72",
42
+ "@opengeni/events": "^0.3.62",
43
+ "@opengeni/observability": "^0.4.6",
44
+ "@opengeni/runtime": "^0.18.0",
45
+ "@opengeni/storage": "^0.2.56",
46
46
  "hono": "^4.12.18"
47
47
  },
48
48
  "engines": {
@@ -595,10 +595,12 @@ export async function controlHumanSessionWorkstream(
595
595
  ),
596
596
  interruptionCount: result.interruptionCount,
597
597
  wakeCount: result.wakeCount,
598
+ cancelledSessionCount: result.cancelledSessionCount,
599
+ cancelledTurnCount: result.cancelledTurnCount,
598
600
  };
599
- await publishSessionEventIds(deps, context.workspaceId, context.sessionId, [
600
- result.sessionControlEventId,
601
- ]);
601
+ for (const affected of result.affectedSessionEvents) {
602
+ await publishSessionEventIds(deps, context.workspaceId, affected.sessionId, affected.eventIds);
603
+ }
602
604
  await publishWorkspaceControlEvent(deps, context.workspaceId, result.workspaceControlEventId);
603
605
  await requestControlWakeDispatch(deps, result.wakeCount);
604
606
  return response;
@@ -514,6 +514,8 @@ export async function createAndStartSession(input: {
514
514
  accountId: string;
515
515
  workspaceId: string;
516
516
  initialMessage: string;
517
+ /** Create the session shell without an initial user event/agent turn. */
518
+ deferInitialTurn?: boolean;
517
519
  turnInstructions?: string | null;
518
520
  resources: ResourceRef[];
519
521
  skills?: SessionSkill[];
@@ -546,6 +548,9 @@ export async function createAndStartSession(input: {
546
548
  // workspace agentInstructions at turn time; never emitted as a timeline event.
547
549
  // Null/omitted ⇒ the session carries none.
548
550
  instructions?: string | null;
551
+ // Immutable normalized prompt-policy role. This never derives from a
552
+ // workspace membership role; null retains the bounded metadata.role fallback.
553
+ policyRole?: string | null;
549
554
  // Validated against the creating grant before this is called.
550
555
  firstPartyMcpPermissions?: Permission[] | null;
551
556
  // Model-visible first-party tool names. Authorization remains controlled by
@@ -626,6 +631,7 @@ export async function createAndStartSession(input: {
626
631
  firstPartyMcpPermissions: input.firstPartyMcpPermissions ?? null,
627
632
  firstPartyMcpTools: input.firstPartyMcpTools,
628
633
  instructions: input.instructions ?? null,
634
+ policyRole: input.policyRole ?? null,
629
635
  parentSessionId: input.parentSessionId ?? null,
630
636
  createIdempotencyKey: input.createIdempotencyKey,
631
637
  sandboxGroupId: input.sandboxGroupId ?? null,
@@ -672,6 +678,7 @@ export async function createAndStartSession(input: {
672
678
  firstPartyMcpPermissions: input.firstPartyMcpPermissions ?? null,
673
679
  firstPartyMcpTools: input.firstPartyMcpTools,
674
680
  instructions: input.instructions ?? null,
681
+ policyRole: input.policyRole ?? null,
675
682
  parentSessionId: input.parentSessionId ?? null,
676
683
  sandboxGroupId: input.sandboxGroupId ?? null,
677
684
  ...(input.sandboxOs ? { sandboxOs: input.sandboxOs } : {}),
@@ -702,6 +709,7 @@ async function finishStartSession(
702
709
  bus: EventBus;
703
710
  workflowClient: SessionWorkflowClient;
704
711
  initialMessage: string;
712
+ deferInitialTurn?: boolean;
705
713
  turnInstructions?: string | null;
706
714
  resources: ResourceRef[];
707
715
  tools: ToolRef[];
@@ -781,6 +789,7 @@ async function finishStartSession(
781
789
  }
782
790
  : null,
783
791
  consumeNewSessionDraft: input.consumeNewSessionDraft ?? null,
792
+ deferInitialTurn: input.deferInitialTurn === true,
784
793
  });
785
794
  await publishDurableSessionEvents(input.bus, session.workspaceId, session.id, started.events);
786
795
  if (started.workflowWakeRevision !== null) {
@@ -1255,9 +1264,10 @@ export async function createSessionForRequest(
1255
1264
  payload.variableSetId,
1256
1265
  )
1257
1266
  : null;
1258
- // RIG BINDING (M3). Resolve the rig this session rides — the EXPLICIT payload
1259
- // rigId when given, else the workspace default rig (workspaces.default_rig_id)
1260
- // — and FREEZE both the rig id and its currently-ACTIVE version onto the row.
1267
+ // RIG BINDING (M3). Resolve the rig this session rides — a UUID binds that
1268
+ // rig, null explicitly opts out, and omission inherits the workspace default
1269
+ // (workspaces.default_rig_id) then FREEZE both the rig id and its currently-
1270
+ // ACTIVE version onto the row.
1261
1271
  // The session then rides that exact version for its whole life; a later
1262
1272
  // promote never moves it. Rig-less (both null) when neither resolves, which is
1263
1273
  // byte-for-byte today's behavior (zero extra work, zero row change).
@@ -1265,7 +1275,8 @@ export async function createSessionForRequest(
1265
1275
  // - A stale workspace-default rig (deleted → FK-nulled, or somehow with no
1266
1276
  // active version) degrades SILENTLY to rig-less: an operator-side default
1267
1277
  // must never brick every create in the workspace.
1268
- const requestedRigId = payload.rigId ?? (await getWorkspaceDefaultRigId(db, workspaceId));
1278
+ const requestedRigId =
1279
+ payload.rigId === undefined ? await getWorkspaceDefaultRigId(db, workspaceId) : payload.rigId;
1269
1280
  let frozenRigId: string | null = null;
1270
1281
  let frozenRigVersionId: string | null = null;
1271
1282
  if (requestedRigId) {
@@ -1598,13 +1609,15 @@ export async function createSessionForRequest(
1598
1609
  }
1599
1610
  }
1600
1611
  }
1601
- await requireLimit(deps, {
1602
- accountId: grant.accountId,
1603
- workspaceId,
1604
- action: "agent_run:create",
1605
- quantity: 1,
1606
- model,
1607
- });
1612
+ if (payload.startMode !== "realtime") {
1613
+ await requireLimit(deps, {
1614
+ accountId: grant.accountId,
1615
+ workspaceId,
1616
+ action: "agent_run:create",
1617
+ quantity: 1,
1618
+ model,
1619
+ });
1620
+ }
1608
1621
  const creationInitiator = creationInitiatorForGrant(grant);
1609
1622
  let session: CreateSessionResponse;
1610
1623
  try {
@@ -1615,7 +1628,8 @@ export async function createSessionForRequest(
1615
1628
  workflowClient,
1616
1629
  accountId: grant.accountId,
1617
1630
  workspaceId,
1618
- initialMessage: payload.initialMessage,
1631
+ initialMessage: payload.initialMessage ?? "",
1632
+ deferInitialTurn: payload.startMode === "realtime",
1619
1633
  turnInstructions: payload.turnInstructions ?? null,
1620
1634
  resources,
1621
1635
  skills,
@@ -1651,6 +1665,7 @@ export async function createSessionForRequest(
1651
1665
  // contracts schema). Persisted on the row; composed system-level at turn
1652
1666
  // time. Not surfaced as an event.
1653
1667
  instructions: payload.instructions ?? null,
1668
+ policyRole: payload.policyRole ?? null,
1654
1669
  firstPartyMcpPermissions,
1655
1670
  firstPartyMcpTools,
1656
1671
  mcpServers: sessionMcpServers.dbServers,
@@ -1687,21 +1702,23 @@ export async function createSessionForRequest(
1687
1702
  }
1688
1703
  throw error;
1689
1704
  }
1690
- await recordWorkspaceUsage(deps, {
1691
- accountId: grant.accountId,
1692
- workspaceId,
1693
- subjectId: grant.subjectId,
1694
- eventType: "agent_run.created",
1695
- quantity: 1,
1696
- unit: "run",
1697
- sourceResourceType: "session",
1698
- sourceResourceId: session.id,
1699
- sessionId: session.id,
1700
- initiator: session.createdBy,
1701
- initiatorContext: session.createdByContext,
1702
- origin: creationInitiator.actor ? "system" : "user",
1703
- idempotencyKey: `agent_run.created:${workspaceId}:${session.id}`,
1704
- });
1705
+ if (payload.startMode !== "realtime") {
1706
+ await recordWorkspaceUsage(deps, {
1707
+ accountId: grant.accountId,
1708
+ workspaceId,
1709
+ subjectId: grant.subjectId,
1710
+ eventType: "agent_run.created",
1711
+ quantity: 1,
1712
+ unit: "run",
1713
+ sourceResourceType: "session",
1714
+ sourceResourceId: session.id,
1715
+ sessionId: session.id,
1716
+ initiator: session.createdBy,
1717
+ initiatorContext: session.createdByContext,
1718
+ origin: creationInitiator.actor ? "system" : "user",
1719
+ idempotencyKey: `agent_run.created:${workspaceId}:${session.id}`,
1720
+ });
1721
+ }
1705
1722
  return session;
1706
1723
  }
1707
1724