@opengeni/core 3.0.1 → 3.1.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 (257) hide show
  1. package/README.md +4 -4
  2. package/dist/access/index.d.ts +131 -7
  3. package/dist/access/service-initiator.d.ts +3 -0
  4. package/dist/application/archived-session-imports.d.ts +6 -0
  5. package/dist/application/composer-submit.d.ts +1 -1
  6. package/dist/application/connect-operation.d.ts +6 -0
  7. package/dist/application/external-workspace-members.d.ts +13 -1
  8. package/dist/application/modal-native-live-declaration-join.d.ts +37 -0
  9. package/dist/application/modal-native-original-configuration.d.ts +79 -0
  10. package/dist/application/modal-native-worker-host-transport.d.ts +297 -0
  11. package/dist/application/new-session-drafts.d.ts +29 -2
  12. package/dist/application/organization-privacy.d.ts +57 -0
  13. package/dist/application/prepared-mcp-connection.d.ts +31 -0
  14. package/dist/application/sandbox-recovery.d.ts +58 -0
  15. package/dist/application/session-commands.d.ts +3 -0
  16. package/dist/application/session-tenancy.d.ts +13 -4
  17. package/dist/billing/agent-run-admission.d.ts +21 -0
  18. package/dist/billing/limits.d.ts +27 -1
  19. package/dist/billing/model-call-admission.d.ts +34 -0
  20. package/dist/billing/model-usage-settlement.d.ts +112 -0
  21. package/dist/canonical-human-identities.js +1 -1
  22. package/dist/{chunk-VCZFFEPB.js → chunk-7T2SZ7BI.js} +16 -2
  23. package/dist/chunk-7T2SZ7BI.js.map +1 -0
  24. package/dist/{chunk-ZYCNLYGH.js → chunk-OMJFIIWK.js} +178 -12
  25. package/dist/chunk-OMJFIIWK.js.map +1 -0
  26. package/dist/{chunk-H7X52RI2.js → chunk-QI2M2B2K.js} +83 -8
  27. package/dist/chunk-QI2M2B2K.js.map +1 -0
  28. package/dist/{chunk-OF65T3PM.js → chunk-TTWTXQB2.js} +94 -6
  29. package/dist/chunk-TTWTXQB2.js.map +1 -0
  30. package/dist/codex-model-availability.d.ts +55 -0
  31. package/dist/default-session-model.d.ts +192 -0
  32. package/dist/dependencies.d.ts +41 -7
  33. package/dist/developer-setup-credential-ceiling.d.ts +10 -0
  34. package/dist/domain/agent-config-resolution.d.ts +49 -0
  35. package/dist/domain/automations.d.ts +8 -1
  36. package/dist/domain/capabilities.d.ts +112 -8
  37. package/dist/domain/connection-account-selection-error.d.ts +8 -0
  38. package/dist/domain/connector-tool-permissions.d.ts +62 -0
  39. package/dist/domain/direct-model-provider.d.ts +3 -0
  40. package/dist/domain/editable-artifacts/agent-application.d.ts +10 -1
  41. package/dist/domain/editable-artifacts/durable-export.d.ts +22 -1
  42. package/dist/domain/editable-artifacts/ports.d.ts +10 -0
  43. package/dist/domain/editable-artifacts/service.d.ts +3 -1
  44. package/dist/domain/editable-artifacts/types.d.ts +1 -1
  45. package/dist/domain/encryption-key.d.ts +12 -0
  46. package/dist/domain/insights-timing.d.ts +16 -0
  47. package/dist/domain/insights-usage.d.ts +27 -0
  48. package/dist/domain/insights.d.ts +21 -3
  49. package/dist/domain/knowledge-files.d.ts +1 -1
  50. package/dist/domain/knowledge-preparation.d.ts +10 -0
  51. package/dist/domain/knowledge-preparation.test.d.ts +1 -0
  52. package/dist/domain/knowledge-search.d.ts +15 -76
  53. package/dist/domain/mcp-account-bindings.d.ts +17 -0
  54. package/dist/domain/mcp-account-routes.d.ts +21 -0
  55. package/dist/domain/native-mcp-connection-admission.d.ts +3 -0
  56. package/dist/domain/organization-integration-catalog.d.ts +15 -0
  57. package/dist/domain/personal-connection-delegations.d.ts +73 -12
  58. package/dist/domain/pr-review.d.ts +121 -6
  59. package/dist/domain/realtime-voice-billing.d.ts +103 -0
  60. package/dist/domain/resources.d.ts +17 -1
  61. package/dist/domain/scheduled-task-access.d.ts +265 -0
  62. package/dist/domain/scheduled-task-account-audit.d.ts +27 -0
  63. package/dist/domain/scheduled-task-audience.d.ts +70 -0
  64. package/dist/domain/scheduled-tasks.d.ts +61 -18
  65. package/dist/domain/session-connection-accounts.d.ts +53 -0
  66. package/dist/domain/session-file-access.d.ts +4 -0
  67. package/dist/domain/session-native-connection-replacement.d.ts +14 -0
  68. package/dist/domain/session-start-timing.d.ts +7 -0
  69. package/dist/domain/session-tool-policy.d.ts +102 -4
  70. package/dist/domain/sessions.d.ts +179 -15
  71. package/dist/domain/site-audience.d.ts +52 -0
  72. package/dist/domain/skills.d.ts +29 -1
  73. package/dist/domain/slack-bot.d.ts +46 -1
  74. package/dist/domain/slack-publication-secret-safety.d.ts +1 -1
  75. package/dist/domain/vaults/index.d.ts +7 -0
  76. package/dist/domain/vaults/mapping.d.ts +25 -0
  77. package/dist/domain/vaults/provider-registry.d.ts +72 -0
  78. package/dist/domain/vaults/provider-sync.d.ts +176 -0
  79. package/dist/domain/vaults/provider-writes.d.ts +57 -0
  80. package/dist/domain/vaults/secret-resolver.d.ts +34 -0
  81. package/dist/domain/vaults/types.d.ts +24 -0
  82. package/dist/domain/vaults/vault-service.d.ts +35 -0
  83. package/dist/domain/voice-input-billing.d.ts +77 -0
  84. package/dist/domain/web-search-billing.d.ts +51 -0
  85. package/dist/domain/workspace-credits.d.ts +7 -0
  86. package/dist/editable-artifact-live/application.d.ts +2 -1
  87. package/dist/editable-artifact-live/server.d.ts +5 -1
  88. package/dist/editable-artifact-live/ticket.d.ts +2 -1
  89. package/dist/editable-artifact-live/types.d.ts +9 -0
  90. package/dist/editable-artifact-live.js +2 -2
  91. package/dist/editable-artifacts.js +10 -2
  92. package/dist/goal-admission.d.ts +627 -0
  93. package/dist/host-session-usage-limit.d.ts +15 -0
  94. package/dist/index.d.ts +43 -8
  95. package/dist/index.js +22682 -11743
  96. package/dist/index.js.map +1 -1
  97. package/dist/managed-session.d.ts +110 -7
  98. package/dist/model-call.d.ts +58 -0
  99. package/dist/model-catalog.d.ts +29 -3
  100. package/dist/model-provider-credentials.d.ts +43 -0
  101. package/dist/product-usage-metrics.d.ts +30 -0
  102. package/dist/rigs/index.d.ts +1 -13
  103. package/dist/sandbox/fleet.d.ts +58 -4
  104. package/dist/sandbox/routing.d.ts +42 -2
  105. package/dist/sandbox/runtime-settings.d.ts +27 -17
  106. package/dist/session-authorization.d.ts +10 -0
  107. package/dist/session-usage-limit-metrics.d.ts +60 -0
  108. package/dist/session-usage-limits.d.ts +89 -0
  109. package/dist/site-agent-clamp.d.ts +71 -0
  110. package/dist/site-session-origin.d.ts +39 -2
  111. package/dist/transcription.d.ts +120 -3
  112. package/dist/turn-surface.d.ts +20 -0
  113. package/dist/user-presence.d.ts +32 -0
  114. package/dist/workflow-wake-contract.d.ts +13 -1
  115. package/package.json +15 -22
  116. package/src/access/index.ts +961 -38
  117. package/src/access/service-initiator.ts +50 -0
  118. package/src/application/api-integration-servers.ts +9 -0
  119. package/src/application/archived-session-imports.ts +161 -0
  120. package/src/application/composer-submit.ts +3 -2
  121. package/src/application/connect-authority.ts +3 -3
  122. package/src/application/connect-operation.ts +37 -3
  123. package/src/application/external-continuation.ts +20 -3
  124. package/src/application/external-link-work-admission.ts +3 -0
  125. package/src/application/external-workspace-members.ts +51 -3
  126. package/src/application/modal-native-live-declaration-join.ts +196 -0
  127. package/src/application/modal-native-original-configuration.ts +261 -0
  128. package/src/application/modal-native-worker-host-transport.ts +263 -0
  129. package/src/application/new-session-drafts.ts +172 -55
  130. package/src/application/organization-privacy.ts +161 -0
  131. package/src/application/prepared-mcp-connection.ts +133 -0
  132. package/src/application/sandbox-recovery.ts +78 -0
  133. package/src/application/session-commands.ts +73 -1
  134. package/src/application/session-mcp-credential-rotation.ts +61 -18
  135. package/src/application/session-tenancy.ts +262 -44
  136. package/src/application/user-resource-grants.ts +1 -29
  137. package/src/billing/agent-run-admission.ts +117 -0
  138. package/src/billing/limits.ts +138 -14
  139. package/src/billing/model-call-admission.ts +118 -0
  140. package/src/billing/model-usage-settlement.ts +472 -0
  141. package/src/codex-model-availability.ts +264 -0
  142. package/src/default-session-model.ts +692 -0
  143. package/src/dependencies.ts +48 -6
  144. package/src/developer-setup-credential-ceiling.ts +60 -0
  145. package/src/domain/agent-config-resolution.ts +148 -0
  146. package/src/domain/automations.ts +76 -2
  147. package/src/domain/capabilities.ts +830 -181
  148. package/src/domain/connection-account-selection-error.ts +19 -0
  149. package/src/domain/connector-tool-permissions.ts +572 -0
  150. package/src/domain/direct-model-provider.ts +62 -0
  151. package/src/domain/editable-artifacts/agent-application.ts +44 -6
  152. package/src/domain/editable-artifacts/durable-export.ts +100 -5
  153. package/src/domain/editable-artifacts/in-memory.ts +6 -0
  154. package/src/domain/editable-artifacts/ports.ts +11 -0
  155. package/src/domain/editable-artifacts/service.ts +20 -0
  156. package/src/domain/editable-artifacts/types.ts +1 -1
  157. package/src/domain/encryption-key.ts +26 -0
  158. package/src/domain/file-owner.ts +16 -1
  159. package/src/domain/github-action-policies.ts +1 -1
  160. package/src/domain/github-skill-source.ts +3 -1
  161. package/src/domain/insights-timing.ts +95 -0
  162. package/src/domain/insights-usage.ts +67 -0
  163. package/src/domain/insights.ts +167 -43
  164. package/src/domain/knowledge-files.ts +10 -3
  165. package/src/domain/knowledge-messages.ts +1 -0
  166. package/src/domain/knowledge-preparation.test.ts +276 -0
  167. package/src/domain/knowledge-preparation.ts +147 -0
  168. package/src/domain/knowledge-search.test.ts +617 -5
  169. package/src/domain/knowledge-search.ts +240 -23
  170. package/src/domain/mcp-account-bindings.ts +169 -0
  171. package/src/domain/mcp-account-routes.ts +152 -0
  172. package/src/domain/native-mcp-connection-admission.ts +14 -0
  173. package/src/domain/organization-integration-catalog.ts +88 -0
  174. package/src/domain/personal-connection-delegations.ts +399 -257
  175. package/src/domain/pr-review.ts +24 -8
  176. package/src/domain/realtime-voice-billing.ts +425 -0
  177. package/src/domain/resources.ts +50 -4
  178. package/src/domain/scheduled-task-access.ts +1089 -0
  179. package/src/domain/scheduled-task-account-audit.ts +90 -0
  180. package/src/domain/scheduled-task-audience.ts +249 -0
  181. package/src/domain/scheduled-tasks.ts +1313 -374
  182. package/src/domain/session-connection-accounts.ts +239 -0
  183. package/src/domain/session-file-access.ts +47 -0
  184. package/src/domain/session-native-connection-replacement.ts +64 -0
  185. package/src/domain/session-start-timing.ts +60 -0
  186. package/src/domain/session-tool-policy.ts +489 -14
  187. package/src/domain/sessions.ts +2254 -717
  188. package/src/domain/site-audience.ts +130 -0
  189. package/src/domain/skills.ts +9 -0
  190. package/src/domain/slack-bot.ts +141 -4
  191. package/src/domain/slack-publication-secret-safety.ts +1 -1
  192. package/src/domain/vaults/index.ts +19 -0
  193. package/src/domain/vaults/mapping.ts +190 -0
  194. package/src/domain/vaults/provider-registry.ts +201 -0
  195. package/src/domain/vaults/provider-sync.ts +531 -0
  196. package/src/domain/vaults/provider-writes.ts +288 -0
  197. package/src/domain/vaults/secret-resolver.ts +464 -0
  198. package/src/domain/vaults/types.ts +26 -0
  199. package/src/domain/vaults/vault-service.ts +1316 -0
  200. package/src/domain/voice-input-billing.ts +330 -0
  201. package/src/domain/web-search-billing.ts +169 -0
  202. package/src/domain/workspace-credits.ts +13 -0
  203. package/src/editable-artifact-live/application.ts +8 -1
  204. package/src/editable-artifact-live/server.ts +154 -6
  205. package/src/editable-artifact-live/ticket.ts +86 -1
  206. package/src/editable-artifact-live/types.ts +10 -0
  207. package/src/goal-admission.ts +220 -0
  208. package/src/host-session-usage-limit.ts +25 -0
  209. package/src/index.ts +75 -11
  210. package/src/managed-session.ts +137 -6
  211. package/src/model-call.ts +79 -0
  212. package/src/model-catalog.ts +345 -91
  213. package/src/model-provider-credentials.ts +394 -0
  214. package/src/product-usage-metrics.ts +101 -0
  215. package/src/rigs/index.ts +23 -111
  216. package/src/sandbox/fleet.ts +253 -28
  217. package/src/sandbox/routing.ts +204 -43
  218. package/src/sandbox/runtime-settings.ts +159 -85
  219. package/src/session-authorization.ts +172 -23
  220. package/src/session-usage-limit-metrics.ts +95 -0
  221. package/src/session-usage-limits.ts +415 -0
  222. package/src/site-agent-clamp.ts +226 -0
  223. package/src/site-session-origin.ts +84 -5
  224. package/src/transcription.ts +123 -4
  225. package/src/turn-surface.ts +47 -0
  226. package/src/user-presence.ts +134 -0
  227. package/src/workflow-wake-contract.ts +14 -1
  228. package/dist/application/host-mcp-owner.d.ts +0 -6
  229. package/dist/application/host-mcp-resolvers.d.ts +0 -13
  230. package/dist/chunk-5WZYFL45.js +0 -266
  231. package/dist/chunk-5WZYFL45.js.map +0 -1
  232. package/dist/chunk-H7X52RI2.js.map +0 -1
  233. package/dist/chunk-OF65T3PM.js.map +0 -1
  234. package/dist/chunk-VCZFFEPB.js.map +0 -1
  235. package/dist/chunk-ZYCNLYGH.js.map +0 -1
  236. package/dist/domain/connection-authority.d.ts +0 -97
  237. package/dist/domain/connection-authority.js +0 -169
  238. package/dist/domain/connection-authority.js.map +0 -1
  239. package/dist/domain/environments.d.ts +0 -33
  240. package/dist/domain/host-mcp-authority-source-admission.d.ts +0 -10
  241. package/dist/domain/host-mcp-task-admission.d.ts +0 -18
  242. package/dist/domain/packs.d.ts +0 -59
  243. package/dist/domain/product-integration-pack.d.ts +0 -44
  244. package/dist/domain/product-integration-skill.gen.d.ts +0 -5
  245. package/dist/remote-mcp-credentials.d.ts +0 -23
  246. package/dist/remote-mcp-credentials.js +0 -11
  247. package/dist/remote-mcp-credentials.js.map +0 -1
  248. package/src/application/host-mcp-owner.ts +0 -41
  249. package/src/application/host-mcp-resolvers.ts +0 -84
  250. package/src/domain/connection-authority.ts +0 -329
  251. package/src/domain/environments.ts +0 -120
  252. package/src/domain/host-mcp-authority-source-admission.ts +0 -25
  253. package/src/domain/host-mcp-task-admission.ts +0 -121
  254. package/src/domain/packs.ts +0 -699
  255. package/src/domain/product-integration-pack.ts +0 -42
  256. package/src/domain/product-integration-skill.gen.ts +0 -52
  257. package/src/remote-mcp-credentials.ts +0 -361
@@ -0,0 +1,60 @@
1
+ import type { Observability } from "@opengeni/observability";
2
+ /**
3
+ * Content-free diagnostics for per-task usage limits. Every label is
4
+ * a closed set: where the decision was made and what it was. No workspace,
5
+ * session, subject, model, prompt or amount ever becomes a label, so the
6
+ * series count is bounded by these two lists.
7
+ */
8
+ export type SessionUsageLimitMetricsSink = Pick<Observability, "incrementCounter">;
9
+ export declare const SESSION_USAGE_LIMIT_METRIC_BOUNDARIES: readonly ["create", "child_create", "send", "steer", "goal", "claim", "between_calls", "single_call", "settlement", "write", "import"];
10
+ export type SessionUsageLimitMetricBoundary = (typeof SESSION_USAGE_LIMIT_METRIC_BOUNDARIES)[number];
11
+ export declare const SESSION_USAGE_LIMIT_METRIC_OUTCOMES: readonly [
12
+ /** Admission refused: observed settled usage reached the root limit. */
13
+ "reached",
14
+ /** The usage state could not be read or written; the request was blocked. */
15
+ "unavailable",
16
+ /** Settlement could not be recorded; the next dispatch waits for recovery. */
17
+ "accounting_failure",
18
+ /** A response had no known price: excluded from the total and disclosed. */
19
+ "unpriced",
20
+ /** A priced response was recorded once. */
21
+ "recorded",
22
+ /** An exact replay of an already recorded source. */
23
+ "duplicate",
24
+ /** A previously unpriced source gained its stored price. */
25
+ "filled",
26
+ /** A different amount was offered for an already recorded source. */
27
+ "source_conflict",
28
+ /** The session was deleted before its in-flight response settled. */
29
+ "source_gone",
30
+ /** A write lost its compare-and-set race. */
31
+ "cas_conflict",
32
+ /** A write targeted a root whose legacy history is still preparing. */
33
+ "preparing",
34
+ /** A write was refused for an agent, scoped bearer or other non-person actor. */
35
+ "forbidden",
36
+ /** A new non-null limit was refused because producers are disabled. */
37
+ "disabled",
38
+ /** A write was refused because the session is not the task root. */
39
+ "not_root",
40
+ /** An authorized write changed the limit. */
41
+ "set",
42
+ /** An authorized write removed the limit. */
43
+ "cleared",
44
+ /** An authorized write repeated an already applied request. */
45
+ "replayed",
46
+ /** Legacy import pages processed by maintenance. */
47
+ "imported",
48
+ /** Legacy import maintenance failed and will be retried. */
49
+ "import_failed",
50
+ /** A settled receipt could not be written yet and is held for a DB-only retry. */
51
+ "held",
52
+ /** An unfilled single-call custody marker passed its lost window; disclosed as unpriced. */
53
+ "lost_resolved"];
54
+ export type SessionUsageLimitMetricOutcome = (typeof SESSION_USAGE_LIMIT_METRIC_OUTCOMES)[number];
55
+ export declare const SESSION_USAGE_LIMIT_EVENTS_METRIC: {
56
+ readonly name: "opengeni_session_usage_limit_events_total";
57
+ readonly help: "Per-task usage limit decisions by boundary and outcome; labels are closed sets.";
58
+ };
59
+ /** Count one usage-limit decision. Never throws: telemetry cannot change the outcome. */
60
+ export declare function recordSessionUsageLimitEvent(sink: SessionUsageLimitMetricsSink | null | undefined, boundary: SessionUsageLimitMetricBoundary, outcome: SessionUsageLimitMetricOutcome, amount?: number): void;
@@ -0,0 +1,89 @@
1
+ import { HTTPException } from "hono/http-exception";
2
+ import { type Database, type SessionUsageLimitWriteActor } from "@opengeni/db";
3
+ import { type Session, type SessionUsageLimit, type SessionUsageLimitReachedRefusal, type SetSessionUsageLimitRequest } from "@opengeni/contracts";
4
+ import { type AccessGrantAuthorization } from "./access/index.js";
5
+ import { type SessionAuthorizationDependencies } from "./session-authorization.js";
6
+ import { type SessionUsageLimitMetricBoundary, type SessionUsageLimitMetricsSink } from "./session-usage-limit-metrics.js";
7
+ /**
8
+ * Producer flag for per-task usage limits. Off by default. When off, new
9
+ * non-null limits are rejected (`session_usage_limit_disabled`), but limits
10
+ * already persisted keep being enforced and clearing stays allowed, so turning
11
+ * the flag off is never a way to lift a limit or strand one.
12
+ */
13
+ export declare function sessionUsageLimitsProducerEnabled(settings: {
14
+ sessionUsageLimitsEnabled?: boolean | undefined;
15
+ }): boolean;
16
+ /** Typed route error with a stable `details.code`. */
17
+ export declare class SessionUsageLimitHttpError extends HTTPException {
18
+ readonly code: "session_usage_limit_conflict" | "session_usage_limit_not_root" | "session_usage_limit_preparing" | "session_usage_limit_disabled" | "session_usage_limit_forbidden" | "session_usage_limit_unavailable" | "session_not_found";
19
+ readonly details: Record<string, unknown>;
20
+ constructor(status: 403 | 404 | 409 | 422 | 503, code: "session_usage_limit_conflict" | "session_usage_limit_not_root" | "session_usage_limit_preparing" | "session_usage_limit_disabled" | "session_usage_limit_forbidden" | "session_usage_limit_unavailable" | "session_not_found", message: string, details?: Record<string, unknown>);
21
+ }
22
+ /**
23
+ * Who may change a task's usage limit: an authenticated person acting
24
+ * directly, or the trusted host's server key. Never an agent attempt, a
25
+ * delegated-human or admin-access agent (an OAuth/MCP dispatch acting as a
26
+ * person, or a personal API key), a service-delegated token or a session-scoped
27
+ * bearer. `principalKind` alone is not proof of a present person.
28
+ */
29
+ export declare function sessionUsageLimitWriteActorForAccess(access: AccessGrantAuthorization, request?: Request): SessionUsageLimitWriteActor;
30
+ /** Projection for a session whose usage state cannot be read right now. Never $0 or unlimited. */
31
+ export declare function unavailableSessionUsageLimit(session: Pick<Session, "id" | "rootSessionId">): SessionUsageLimit;
32
+ /**
33
+ * Read a session's usage projection for an already-authorized session read.
34
+ * A read failure yields the `unavailable` projection rather than failing the
35
+ * whole session read. `prepare` advances a pending historical import inline.
36
+ */
37
+ export declare function sessionUsageLimitForRead(db: Database, session: Pick<Session, "id" | "rootSessionId" | "accountId" | "workspaceId">, options?: {
38
+ prepare?: boolean;
39
+ subjectId?: string | null;
40
+ }): Promise<SessionUsageLimit | undefined>;
41
+ /** GET usage-limit: authorize a session read, then read (advancing a pending import). */
42
+ export declare function getSessionUsageLimitForAccess(deps: SessionAuthorizationDependencies, access: AccessGrantAuthorization, sessionId: string): Promise<SessionUsageLimit>;
43
+ /**
44
+ * PUT usage-limit: a person or trusted host compare-and-sets a ROOT task's
45
+ * limit. Appends `session.usage_limit.updated` on change. Never wakes or
46
+ * resumes work: a paused goal stays paused until someone resumes it.
47
+ */
48
+ export declare function setSessionUsageLimitForAccess(deps: SessionAuthorizationDependencies & {
49
+ settings: {
50
+ sessionUsageLimitsEnabled?: boolean | undefined;
51
+ };
52
+ observability?: SessionUsageLimitMetricsSink | undefined;
53
+ }, access: AccessGrantAuthorization, sessionId: string, request: SetSessionUsageLimitRequest, rawRequest?: Request): Promise<SessionUsageLimit>;
54
+ /**
55
+ * Apply a create-time limit inside the session-creating transaction, before
56
+ * the initial turn can be claimed. Only a person or trusted host may set it
57
+ * and only on a new root; children always share their root's limit.
58
+ */
59
+ export declare function applyInitialSessionUsageLimit(tx: Database, input: {
60
+ accountId: string;
61
+ workspaceId: string;
62
+ sessionId: string;
63
+ limitMicros: number;
64
+ actor: SessionUsageLimitWriteActor;
65
+ producerEnabled: boolean;
66
+ }): Promise<void>;
67
+ /**
68
+ * Edge admission for per-task usage limits. Called after an exact
69
+ * committed replay has been returned and before any queue, interrupt, draft or
70
+ * turn side effect, so a refused Send/Steer leaves nothing behind and the
71
+ * composer keeps its draft.
72
+ *
73
+ * - Reached: HTTP 402 whose cause is the typed refusal (`session_usage_limit_reached`).
74
+ * - Unreadable state: HTTP 503 (`session_usage_limit_unavailable`), never unlimited.
75
+ */
76
+ export declare function requireSessionUsageLimitAllows(db: Database, input: {
77
+ accountId: string;
78
+ workspaceId: string;
79
+ sessionId: string;
80
+ /** Server-internal admission for an authorized attempt: fail closed on a missing tree. */
81
+ runtime?: boolean;
82
+ /** Runtime only: open a durable custody marker for this single call when admitted. */
83
+ openSourceId?: string;
84
+ }, metrics?: {
85
+ sink: SessionUsageLimitMetricsSink | null | undefined;
86
+ boundary: SessionUsageLimitMetricBoundary;
87
+ }): Promise<void>;
88
+ /** True when this error is the typed edge refusal raised above. */
89
+ export declare function sessionUsageLimitRefusalFromError(error: unknown): SessionUsageLimitReachedRefusal | null;
@@ -0,0 +1,71 @@
1
+ import type { AccessGrant } from "@opengeni/contracts";
2
+ import { type Database } from "@opengeni/db";
3
+ /**
4
+ * Whether an agent acts for a Site page: its session, a spawning ancestor or
5
+ * its root session was started from a Site (a published Site or an inline or
6
+ * preview frame), or its current or a spawning ancestor turn arrived from one.
7
+ * The same evidence the Site Data agent clamp uses
8
+ * (apps/api/src/site-data/service.ts), plus frame origins without a
9
+ * published Site id.
10
+ */
11
+ export type SiteAgentClamp = {
12
+ clamped: boolean;
13
+ /** Published Sites in the lineage; empty for frames without a published Site. */
14
+ originSiteIds: string[];
15
+ };
16
+ /** Null when the grant is not an agent session. */
17
+ export declare function siteAgentClamp(db: Database, grant: AccessGrant): Promise<SiteAgentClamp | null>;
18
+ /**
19
+ * The Site clamp of an agent running in `sessionId` (and `turnId`, when
20
+ * known). A turn's clamp is computed once a minute at most per process: the
21
+ * evidence it reads (where the session, its ancestors and that turn came
22
+ * from) does not change during the turn. Without a turn id it is always
23
+ * read fresh.
24
+ */
25
+ export declare function siteSessionClamp(db: Database, scope: {
26
+ accountId: string;
27
+ workspaceId: string;
28
+ }, sessionId: string, turnId: string | null): Promise<SiteAgentClamp>;
29
+ /** What a Site-clamped agent may not create or change. */
30
+ export type SiteClampedResource = "schedules" | "automations" | "Site publications" | "workspace instructions" | "Skills" | "Knowledge" | "secrets" | "workspace members, connections or settings" | "the organization profile" | "Connected Machines" | "sandbox environments" | "browser or computer sessions" | "documents, spreadsheets or presentations the Site did not declare" | "workspace settings";
31
+ /** The refusal message for a Site-clamped agent. */
32
+ export declare function siteClampedAgentMessage(what: SiteClampedResource): string;
33
+ /**
34
+ * The refusal when a Site-clamped agent reaches for compute beyond its own
35
+ * session's: `run_on`, attaching, swapping or provisioning a sandbox, or
36
+ * starting a worker on a chosen machine or another session's sandbox.
37
+ */
38
+ export declare const SITE_AGENT_COMPUTE_MESSAGE = "An agent started from a Site page cannot run on, attach, provision or choose sandboxes or Connected Machines";
39
+ /**
40
+ * Refuse a Site-clamped agent's session create that chooses compute: a
41
+ * machine target, a self-hosted backend or another session's sandbox group.
42
+ * Its workers run in its own sandbox (shared) or a new managed one.
43
+ */
44
+ export declare function assertSiteAgentMayChooseCompute(db: Database, grant: AccessGrant, payload: {
45
+ sandbox?: unknown;
46
+ sandboxBackend?: unknown;
47
+ targetSandboxId?: unknown;
48
+ workingDir?: unknown;
49
+ }): Promise<void>;
50
+ /**
51
+ * Refuse a Site-clamped agent: an agent started from a Site page acts with
52
+ * that page's reach and cannot create or change schedules, automations, Site
53
+ * publications, workspace instructions, Skills, Knowledge, secrets,
54
+ * workspace members, connections and settings, the organization profile,
55
+ * Connected Machines, sandbox environments or other workspace settings.
56
+ */
57
+ export declare function assertNotSiteClampedAgent(db: Database, grant: AccessGrant, what: SiteClampedResource): Promise<void>;
58
+ /**
59
+ * Whether an agent running in `caller` may message, steer or control
60
+ * `targetSessionId`. An unclamped agent is not limited here. A Site-clamped
61
+ * agent reaches only sessions that act for the same Site: clamped themselves
62
+ * (its own lineage, or another session the Site started) and naming no
63
+ * published Site the caller does not.
64
+ */
65
+ export declare function siteAgentMayReachSession(db: Database, scope: {
66
+ accountId: string;
67
+ workspaceId: string;
68
+ }, caller: {
69
+ sessionId: string;
70
+ turnId: string | null;
71
+ }, targetSessionId: string): Promise<boolean>;
@@ -1,7 +1,44 @@
1
+ /**
2
+ * Which Site page a request came from. Provenance, plus the key the API uses
3
+ * to keep one Site's pages away from another Site's sessions.
4
+ *
5
+ * A published Site has a `siteId` (and `versionId` when the host pinned one).
6
+ * Inline HTML and Codemode preview frames have no published id: they record
7
+ * `siteId: null`, the `frame` kind and the host-minted `frameId` of the
8
+ * mounted page, so a frame reaches only the sessions it started itself.
9
+ */
1
10
  export type SiteSessionOrigin = {
2
- siteId: string;
11
+ siteId: string | null;
3
12
  title: string;
13
+ versionId?: string;
14
+ frame?: "inline" | "preview";
15
+ frameId?: string;
4
16
  };
5
- /** Request-local provenance, set only after the API validates a published Site version. */
17
+ export declare const SITE_ORIGIN_METADATA_KEY = "_opengeniSiteOrigin";
18
+ /**
19
+ * Request-local provenance, set only after the API validated the Site the
20
+ * request came from (a published Site version the caller can see, or a
21
+ * host-marked inline or preview frame).
22
+ */
6
23
  export declare function withSiteSessionOrigin<T>(origin: SiteSessionOrigin, run: () => T): T;
7
24
  export declare function sessionCreationMetadata(metadata: Record<string, unknown>): Record<string, unknown>;
25
+ /** The validated Site origin of the current request, if any. Provenance only. */
26
+ export declare function currentSiteSessionOrigin(): SiteSessionOrigin | undefined;
27
+ /**
28
+ * Replace any caller-supplied Site origin in `metadata` with `origin` (or drop
29
+ * it). Callers never choose their own provenance.
30
+ */
31
+ export declare function withSiteOriginMetadata(metadata: Record<string, unknown>, origin: SiteSessionOrigin | null | undefined): Record<string, unknown>;
32
+ /**
33
+ * Read the recorded Site origin from session (or schedule agent config)
34
+ * metadata. Any object under the key counts as a Site origin, so a malformed
35
+ * record still marks the session as Site-started (fail closed).
36
+ */
37
+ export declare function siteSessionOriginFromMetadata(metadata: Record<string, unknown> | null | undefined): SiteSessionOrigin | null;
38
+ /**
39
+ * Whether a request from the `requester` Site page may reach a session (or
40
+ * schedule) whose recorded origin is `target`. Same published Site, or, for
41
+ * frames without a published id, the same mounted frame. Anything without a
42
+ * Site origin is out of reach for a Site page.
43
+ */
44
+ export declare function siteOriginsMatch(requester: SiteSessionOrigin, target: SiteSessionOrigin | null | undefined): boolean;
@@ -1,9 +1,11 @@
1
+ import type { VoiceInputPricing, VoiceInputUsage } from "@opengeni/config";
1
2
  import type { TranscribeAudioResponse, VoiceInputErrorCode } from "@opengeni/contracts";
3
+ import type { CreditDebitAttribution } from "@opengeni/db";
2
4
  /**
3
5
  * Server-owned upstream budget for one provider attempt. Resumable recording
4
6
  * claims remain fenced for longer than this budget before another worker may
5
7
  * reclaim them. Provider adapters must honor the supplied AbortSignal and must
6
- * not return while their upstream request is still live; OpenGeni does not
8
+ * not return while their upstream request is still live; Opengeni does not
7
9
  * claim remote-side idempotency or cancellation for vendors that cannot meet
8
10
  * that adapter contract.
9
11
  */
@@ -31,21 +33,112 @@ export type TranscriptionRequest = {
31
33
  preferredProvider?: string | null | undefined;
32
34
  fallbackEnabled?: boolean | undefined;
33
35
  excludedProviders?: readonly string[] | undefined;
36
+ /**
37
+ * Credit settlement facts for a deployment-funded provider. Required when
38
+ * the selected provider is deployment-funded and credit billing is active;
39
+ * the service fails closed without it.
40
+ */
41
+ billing?: TranscriptionBillingContext | undefined;
42
+ /**
43
+ * Internal: return `settleBilling` instead of settling before returning, so
44
+ * a resumable segment's transcript commits before any billing write.
45
+ */
46
+ deferBillingSettlement?: boolean;
47
+ };
48
+ /**
49
+ * Trusted, server-built settlement identity for one transcription unit. The
50
+ * usage receipt and debit idempotency keys derive from `workspaceId` +
51
+ * `sourceId` (see `voiceInputSettlementKeys`), so a retry or a later
52
+ * reconciliation settles the same unit exactly once.
53
+ */
54
+ export type TranscriptionBillingContext = {
55
+ /**
56
+ * Server-derived unit identity. Never a client-chosen value: a reused id
57
+ * settles once, so a client-controlled id would make later calls free.
58
+ */
59
+ sourceId: string;
60
+ /** Trusted payer facts from the authenticated request boundary. */
61
+ attribution: CreditDebitAttribution;
62
+ /**
63
+ * Audio duration measured by the server from WAV bytes it produced (the
64
+ * resumable segment, or the normalized one-shot upload). Bills whenever the
65
+ * provider reports no usage this deployment has a price for.
66
+ */
67
+ trustedDurationSeconds?: number | undefined;
34
68
  };
35
69
  export type TranscriptionResult = TranscribeAudioResponse & {
36
70
  /** Server-private provider id for operational metrics only. Never returned to clients. */
37
71
  providerId: string;
38
72
  audioSeconds: number;
39
73
  latencyMs: number;
74
+ /** Opengeni credits charged for this call (0 for subscription/free providers). */
75
+ creditCostMicros?: number | undefined;
76
+ /**
77
+ * Server-only settlement callback; never serialized into a public response.
78
+ * Never rejects: a settlement failure after provider success is logged and
79
+ * retried, and the transcript is still delivered.
80
+ */
81
+ settleBilling?: () => Promise<void>;
82
+ };
83
+ export type TranscriptionBillingRefusalCode = "insufficient_credits" | "allowance_exhausted" | "monthly_model_cost_limit";
84
+ /**
85
+ * Pre-use refusal for deployment-funded transcription: 402 for credits and
86
+ * allowances (same codes as session admission), 429 for a static monthly cap.
87
+ */
88
+ export declare class TranscriptionBillingRefusedError extends Error {
89
+ readonly status: 402 | 429;
90
+ readonly code: TranscriptionBillingRefusalCode;
91
+ readonly details: {
92
+ scope?: string;
93
+ resetsAt?: string | null;
94
+ subjectId?: string;
95
+ };
96
+ constructor(input: {
97
+ code: TranscriptionBillingRefusalCode;
98
+ message: string;
99
+ details?: {
100
+ scope?: string;
101
+ resetsAt?: string | null;
102
+ subjectId?: string;
103
+ };
104
+ });
105
+ }
106
+ /**
107
+ * Credit admission and settlement for deployment-funded transcription.
108
+ * Subscription providers (Codex, SuperGrok) never reach this port.
109
+ */
110
+ export type TranscriptionBilling = {
111
+ /** Refuse before any audio is sent when the payer cannot fund the call. */
112
+ admit(input: {
113
+ accountId: string;
114
+ workspaceId: string;
115
+ attribution: CreditDebitAttribution;
116
+ }): Promise<void>;
117
+ /**
118
+ * Record usage and debit credits once per unit, after use. The usage receipt
119
+ * commits before the debit, so a failed debit leaves a durable receipt that
120
+ * `admit` reconciles on the workspace's next voice request.
121
+ */
122
+ settle(input: {
123
+ accountId: string;
124
+ workspaceId: string;
125
+ providerId: string;
126
+ model: string;
127
+ pricing: VoiceInputPricing;
128
+ usage: VoiceInputUsage | null;
129
+ billing: TranscriptionBillingContext;
130
+ }): Promise<{
131
+ creditCostMicros: number;
132
+ }>;
40
133
  };
41
134
  export declare class TranscriptionServiceError extends Error {
42
- readonly code: VoiceInputErrorCode;
135
+ readonly code: Exclude<VoiceInputErrorCode, TranscriptionBillingRefusalCode>;
43
136
  readonly status: number;
44
137
  readonly retryable: boolean;
45
138
  /** Explicit rejection before any transcription result; safe to try another provider. */
46
139
  readonly fallbackSafe: boolean;
47
140
  constructor(input: {
48
- code: VoiceInputErrorCode;
141
+ code: Exclude<VoiceInputErrorCode, TranscriptionBillingRefusalCode>;
49
142
  message: string;
50
143
  status?: number;
51
144
  retryable?: boolean;
@@ -73,6 +166,15 @@ export type TranscriptionProvider = {
73
166
  /** The adapter guarantees that its upstream transport honors AbortSignal. */
74
167
  readonly supportsServerDeadline: true;
75
168
  readonly experimental?: boolean | undefined;
169
+ /**
170
+ * Present when the deployment pays the upstream provider (OpenAI/Azure):
171
+ * the call is admitted against and settled in Opengeni credits. Absent for
172
+ * the workspace's own subscriptions, which are never charged.
173
+ */
174
+ readonly deploymentFunded?: {
175
+ readonly model: string;
176
+ readonly pricing: VoiceInputPricing | null;
177
+ } | undefined;
76
178
  /**
77
179
  * Deployment readiness when called without a workspace. When `workspaceId` is
78
180
  * provided, providers may require a workspace-attached credential (e.g. Codex).
@@ -90,14 +192,27 @@ export type TranscriptionProvider = {
90
192
  }): Promise<{
91
193
  text: string;
92
194
  languages: string[];
195
+ usage?: VoiceInputUsage | null | undefined;
93
196
  }>;
94
197
  };
95
198
  export type TranscriptionService = {
96
199
  limits(): TranscriptionLimits;
97
200
  /** True when at least one ready provider can serve requests. */
98
201
  available(context?: TranscriptionAvailabilityContext): boolean | Promise<boolean>;
202
+ availableProviderIds?(context: TranscriptionAvailabilityContext): Promise<string[]>;
99
203
  /** Select one provider before a durable segment attempt; retries pin this id. */
100
204
  selectProvider?(context: TranscriptionAvailabilityContext): string | null | Promise<string | null>;
205
+ /**
206
+ * Credit admission for an exact provider before durable work is claimed.
207
+ * Resolves for subscription providers; throws TranscriptionBillingRefusedError
208
+ * when a deployment-funded provider cannot be paid for.
209
+ */
210
+ admit?(input: {
211
+ providerId: string;
212
+ accountId: string;
213
+ workspaceId: string;
214
+ attribution: CreditDebitAttribution;
215
+ }): Promise<void>;
101
216
  transcribe(request: TranscriptionRequest): Promise<TranscriptionResult>;
102
217
  };
103
218
  export type PreparedTranscriptionSegment = {
@@ -113,6 +228,8 @@ export type TranscriptionSegmenter = {
113
228
  sourceMimeType: string;
114
229
  totalDurationMilliseconds: number;
115
230
  providerSegmentSeconds: number;
231
+ /** Hard decode ceiling (`ffmpeg -t`); audio past it is never decoded. */
232
+ maxDecodeSeconds?: number | undefined;
116
233
  chunks: AsyncIterable<Uint8Array>;
117
234
  signal?: AbortSignal | undefined;
118
235
  }): AsyncIterable<PreparedTranscriptionSegment>;
@@ -0,0 +1,20 @@
1
+ import type { AccessGrant, SessionTurnSurface } from "@opengeni/contracts";
2
+ import type { AccessGrantAuthorization } from "./access/index.js";
3
+ /**
4
+ * Resolve the content-free product surface a request entered through.
5
+ *
6
+ * The result is a label frozen on the accepted turn, mainly for analytics. It
7
+ * never grants access; the one place it affects authority is Site Data, where a
8
+ * `site` surface only narrows an agent to viewer reach
9
+ * (apps/api/src/site-data/service.ts). It reads trusted provenance only where
10
+ * it already exists: an explicit entry-point choice (Slack, automations, maintenance), the
11
+ * API-validated Site scope, and the access path the grant was resolved from.
12
+ * A grant whose path this function cannot place yields null rather than a
13
+ * guess.
14
+ */
15
+ export declare function resolveTurnSurface(input: {
16
+ grant: AccessGrant;
17
+ authorization?: AccessGrantAuthorization | null | undefined;
18
+ /** An entry point that knows its surface (for example Slack) passes it here. */
19
+ requested?: SessionTurnSurface | null | undefined;
20
+ }): SessionTurnSurface | null;
@@ -0,0 +1,32 @@
1
+ import { type Database } from "@opengeni/db";
2
+ import type { Observability } from "@opengeni/observability";
3
+ /**
4
+ * Throttled, batched server-side presence for managed humans.
5
+ *
6
+ * `touch` is called on the request path, so it only does an in-memory map
7
+ * check: each person is queued at most once per throttle window per process,
8
+ * and queued people are written in one batched database call after a short
9
+ * delay, never awaited by the request. API keys, services and embedded-host
10
+ * subjects are never passed here; anything outside the opaque `user:` shape is
11
+ * ignored. The database turns a new UTC day into the `user.active` lifecycle
12
+ * fact, and control workers read windowed counts for `opengeni_active_users`.
13
+ */
14
+ export type UserPresenceRecorder = {
15
+ /** Note authenticated activity for one managed human. Never throws. */
16
+ touch(subjectId: string): void;
17
+ /** Write everything queued now. Resolves even when the write fails. */
18
+ flush(): Promise<void>;
19
+ /** Flush and stop scheduling further writes. */
20
+ close(): Promise<void>;
21
+ };
22
+ export declare const USER_PRESENCE_THROTTLE_MS = 60000;
23
+ export declare const USER_PRESENCE_FLUSH_DELAY_MS = 5000;
24
+ export declare function createUserPresenceRecorder(options: {
25
+ db: Database;
26
+ observability?: Pick<Observability, "incrementCounter" | "warn"> | undefined;
27
+ throttleMs?: number;
28
+ flushDelayMs?: number;
29
+ maxTracked?: number;
30
+ now?: () => number;
31
+ record?: (db: Database, subjectIds: readonly string[]) => Promise<number>;
32
+ }): UserPresenceRecorder;
@@ -1,6 +1,18 @@
1
- /** One global Temporal Schedule owns bounded delivery of committed session wakes. */
1
+ /**
2
+ * Legacy id of the Temporal Schedule that used to start the dispatcher every
3
+ * period whether or not anything was due. Current control workers delete it at
4
+ * startup; older releases recreate it, so a rollback keeps its repair cadence.
5
+ */
2
6
  export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_SCHEDULE_ID = "opengeni-session-workflow-wake-dispatcher";
3
7
  export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_TYPE = "sessionWorkflowWakeDispatcherWorkflow";
8
+ /**
9
+ * The single dispatcher execution. Immediate triggers and the control
10
+ * worker's repair cadence signal-with-start this id, so a request that lands
11
+ * while a sweep is running buffers exactly one more sweep instead of starting
12
+ * a second execution.
13
+ */
14
+ export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_WORKFLOW_ID = "opengeni-session-workflow-wake-dispatcher";
15
+ export declare const SESSION_WORKFLOW_WAKE_DISPATCH_REQUESTED_SIGNAL = "dispatchRequested";
4
16
  export declare const SESSION_WORKFLOW_WAKE_DISPATCHER_PERIOD_MS = 10000;
5
17
  /**
6
18
  * Temporal delivers activity cancellation through heartbeats. Keep both the
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@opengeni/core",
3
- "version": "3.0.1",
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).",
3
+ "version": "3.1.2",
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": {
7
7
  "type": "git",
@@ -18,10 +18,6 @@
18
18
  "module": "./dist/index.js",
19
19
  "types": "./dist/index.d.ts",
20
20
  "exports": {
21
- "./remote-mcp-credentials": {
22
- "types": "./dist/remote-mcp-credentials.d.ts",
23
- "import": "./dist/remote-mcp-credentials.js"
24
- },
25
21
  ".": {
26
22
  "types": "./dist/index.d.ts",
27
23
  "import": "./dist/index.js"
@@ -41,10 +37,6 @@
41
37
  "./managed-auth-session-sets": {
42
38
  "types": "./dist/managed-auth-session-sets.d.ts",
43
39
  "import": "./dist/managed-auth-session-sets.js"
44
- },
45
- "./connection-authority": {
46
- "types": "./dist/domain/connection-authority.d.ts",
47
- "import": "./dist/domain/connection-authority.js"
48
40
  }
49
41
  },
50
42
  "publishConfig": {
@@ -53,22 +45,23 @@
53
45
  },
54
46
  "scripts": {
55
47
  "typecheck": "tsc --noEmit",
56
- "build": "bun ../../scripts/sync-product-integration-skill.ts --check && bun ../../scripts/build-typescript-package.ts",
48
+ "build": "bun ../../scripts/build-typescript-package.ts",
57
49
  "prepublishOnly": "bash ../../scripts/prepublish-guard"
58
50
  },
59
51
  "dependencies": {
60
52
  "@modelcontextprotocol/sdk": "^1.29.0",
61
- "@opengeni/capabilities": "^0.3.4",
62
- "@opengeni/codex": "^0.2.23",
63
- "@opengeni/config": "^1.2.2",
64
- "@opengeni/contracts": "^4.1.0",
65
- "@opengeni/db": "^5.0.1",
66
- "@opengeni/documents": "^0.8.30",
67
- "@opengeni/events": "^0.4.28",
68
- "@opengeni/network": "^0.3.1",
69
- "@opengeni/observability": "^0.8.29",
70
- "@opengeni/runtime": "^3.0.1",
71
- "@opengeni/storage": "^0.2.130",
53
+ "@opengeni/capabilities": "3.1.2",
54
+ "@opengeni/codex": "3.1.2",
55
+ "@opengeni/config": "3.1.2",
56
+ "@opengeni/contracts": "3.1.2",
57
+ "@opengeni/db": "3.1.2",
58
+ "@opengeni/documents": "3.1.2",
59
+ "@opengeni/events": "3.1.2",
60
+ "@opengeni/network": "3.1.2",
61
+ "@opengeni/observability": "3.1.2",
62
+ "@opengeni/runtime": "3.1.2",
63
+ "@opengeni/storage": "3.1.2",
64
+ "@opengeni/vaults": "3.1.2",
72
65
  "hono": "^4.12.18",
73
66
  "zod": "^4.2.1"
74
67
  },