@opengeni/core 0.18.0 → 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.0",
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.0",
39
- "@opengeni/contracts": "^0.31.0",
40
- "@opengeni/db": "^0.22.1",
41
- "@opengeni/documents": "^0.2.69",
42
- "@opengeni/events": "^0.3.59",
43
- "@opengeni/observability": "^0.4.3",
44
- "@opengeni/runtime": "^0.17.0",
45
- "@opengeni/storage": "^0.2.53",
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;
@@ -4,6 +4,7 @@ import {
4
4
  configuredAllowedModels,
5
5
  policyProviderIdForModel,
6
6
  resolveTurnExecutionPolicyV1,
7
+ WORKSPACE_GATEWAY_MODEL_ID_PREFIX,
7
8
  type Settings,
8
9
  } from "@opengeni/config";
9
10
  import {
@@ -513,6 +514,8 @@ export async function createAndStartSession(input: {
513
514
  accountId: string;
514
515
  workspaceId: string;
515
516
  initialMessage: string;
517
+ /** Create the session shell without an initial user event/agent turn. */
518
+ deferInitialTurn?: boolean;
516
519
  turnInstructions?: string | null;
517
520
  resources: ResourceRef[];
518
521
  skills?: SessionSkill[];
@@ -545,6 +548,9 @@ export async function createAndStartSession(input: {
545
548
  // workspace agentInstructions at turn time; never emitted as a timeline event.
546
549
  // Null/omitted ⇒ the session carries none.
547
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;
548
554
  // Validated against the creating grant before this is called.
549
555
  firstPartyMcpPermissions?: Permission[] | null;
550
556
  // Model-visible first-party tool names. Authorization remains controlled by
@@ -625,6 +631,7 @@ export async function createAndStartSession(input: {
625
631
  firstPartyMcpPermissions: input.firstPartyMcpPermissions ?? null,
626
632
  firstPartyMcpTools: input.firstPartyMcpTools,
627
633
  instructions: input.instructions ?? null,
634
+ policyRole: input.policyRole ?? null,
628
635
  parentSessionId: input.parentSessionId ?? null,
629
636
  createIdempotencyKey: input.createIdempotencyKey,
630
637
  sandboxGroupId: input.sandboxGroupId ?? null,
@@ -671,6 +678,7 @@ export async function createAndStartSession(input: {
671
678
  firstPartyMcpPermissions: input.firstPartyMcpPermissions ?? null,
672
679
  firstPartyMcpTools: input.firstPartyMcpTools,
673
680
  instructions: input.instructions ?? null,
681
+ policyRole: input.policyRole ?? null,
674
682
  parentSessionId: input.parentSessionId ?? null,
675
683
  sandboxGroupId: input.sandboxGroupId ?? null,
676
684
  ...(input.sandboxOs ? { sandboxOs: input.sandboxOs } : {}),
@@ -701,6 +709,7 @@ async function finishStartSession(
701
709
  bus: EventBus;
702
710
  workflowClient: SessionWorkflowClient;
703
711
  initialMessage: string;
712
+ deferInitialTurn?: boolean;
704
713
  turnInstructions?: string | null;
705
714
  resources: ResourceRef[];
706
715
  tools: ToolRef[];
@@ -780,6 +789,7 @@ async function finishStartSession(
780
789
  }
781
790
  : null,
782
791
  consumeNewSessionDraft: input.consumeNewSessionDraft ?? null,
792
+ deferInitialTurn: input.deferInitialTurn === true,
783
793
  });
784
794
  await publishDurableSessionEvents(input.bus, session.workspaceId, session.id, started.events);
785
795
  if (started.workflowWakeRevision !== null) {
@@ -839,6 +849,9 @@ export function canonicalConfiguredModel(
839
849
  if (settings.codexSubscriptionEnabled && canonicalModel.startsWith(CODEX_MODEL_ID_PREFIX)) {
840
850
  return canonicalModel;
841
851
  }
852
+ if (canonicalModel.startsWith(WORKSPACE_GATEWAY_MODEL_ID_PREFIX)) {
853
+ return canonicalModel;
854
+ }
842
855
  throw new HTTPException(422, { message: `model is not available: ${model}` });
843
856
  }
844
857
 
@@ -1251,9 +1264,10 @@ export async function createSessionForRequest(
1251
1264
  payload.variableSetId,
1252
1265
  )
1253
1266
  : null;
1254
- // RIG BINDING (M3). Resolve the rig this session rides — the EXPLICIT payload
1255
- // rigId when given, else the workspace default rig (workspaces.default_rig_id)
1256
- // — 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.
1257
1271
  // The session then rides that exact version for its whole life; a later
1258
1272
  // promote never moves it. Rig-less (both null) when neither resolves, which is
1259
1273
  // byte-for-byte today's behavior (zero extra work, zero row change).
@@ -1261,7 +1275,8 @@ export async function createSessionForRequest(
1261
1275
  // - A stale workspace-default rig (deleted → FK-nulled, or somehow with no
1262
1276
  // active version) degrades SILENTLY to rig-less: an operator-side default
1263
1277
  // must never brick every create in the workspace.
1264
- const requestedRigId = payload.rigId ?? (await getWorkspaceDefaultRigId(db, workspaceId));
1278
+ const requestedRigId =
1279
+ payload.rigId === undefined ? await getWorkspaceDefaultRigId(db, workspaceId) : payload.rigId;
1265
1280
  let frozenRigId: string | null = null;
1266
1281
  let frozenRigVersionId: string | null = null;
1267
1282
  if (requestedRigId) {
@@ -1594,13 +1609,15 @@ export async function createSessionForRequest(
1594
1609
  }
1595
1610
  }
1596
1611
  }
1597
- await requireLimit(deps, {
1598
- accountId: grant.accountId,
1599
- workspaceId,
1600
- action: "agent_run:create",
1601
- quantity: 1,
1602
- model,
1603
- });
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
+ }
1604
1621
  const creationInitiator = creationInitiatorForGrant(grant);
1605
1622
  let session: CreateSessionResponse;
1606
1623
  try {
@@ -1611,7 +1628,8 @@ export async function createSessionForRequest(
1611
1628
  workflowClient,
1612
1629
  accountId: grant.accountId,
1613
1630
  workspaceId,
1614
- initialMessage: payload.initialMessage,
1631
+ initialMessage: payload.initialMessage ?? "",
1632
+ deferInitialTurn: payload.startMode === "realtime",
1615
1633
  turnInstructions: payload.turnInstructions ?? null,
1616
1634
  resources,
1617
1635
  skills,
@@ -1647,6 +1665,7 @@ export async function createSessionForRequest(
1647
1665
  // contracts schema). Persisted on the row; composed system-level at turn
1648
1666
  // time. Not surfaced as an event.
1649
1667
  instructions: payload.instructions ?? null,
1668
+ policyRole: payload.policyRole ?? null,
1650
1669
  firstPartyMcpPermissions,
1651
1670
  firstPartyMcpTools,
1652
1671
  mcpServers: sessionMcpServers.dbServers,
@@ -1683,21 +1702,23 @@ export async function createSessionForRequest(
1683
1702
  }
1684
1703
  throw error;
1685
1704
  }
1686
- await recordWorkspaceUsage(deps, {
1687
- accountId: grant.accountId,
1688
- workspaceId,
1689
- subjectId: grant.subjectId,
1690
- eventType: "agent_run.created",
1691
- quantity: 1,
1692
- unit: "run",
1693
- sourceResourceType: "session",
1694
- sourceResourceId: session.id,
1695
- sessionId: session.id,
1696
- initiator: session.createdBy,
1697
- initiatorContext: session.createdByContext,
1698
- origin: creationInitiator.actor ? "system" : "user",
1699
- idempotencyKey: `agent_run.created:${workspaceId}:${session.id}`,
1700
- });
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
+ }
1701
1722
  return session;
1702
1723
  }
1703
1724