@opengeni/sdk 3.3.2 → 3.5.1-canary.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.
Files changed (58) hide show
  1. package/README.md +15 -2
  2. package/dist/artifact-client.d.ts +2 -1
  3. package/dist/artifacts.d.ts +1 -1
  4. package/dist/artifacts.js +6 -6
  5. package/dist/browser.d.ts +3 -2
  6. package/dist/browser.js +6 -4
  7. package/dist/{chunk-QT3KFVDP.js → chunk-3VIQGNRX.js} +2 -2
  8. package/dist/chunk-3VIQGNRX.js.map +1 -0
  9. package/dist/{chunk-C2H7HBNP.js → chunk-7S2MZ65L.js} +6 -6
  10. package/dist/{chunk-TRNI7KEO.js → chunk-GXC4RESV.js} +164 -15
  11. package/dist/chunk-GXC4RESV.js.map +1 -0
  12. package/dist/{chunk-JUS2UYRP.js → chunk-HILHQEZD.js} +1 -1
  13. package/dist/chunk-HILHQEZD.js.map +1 -0
  14. package/dist/{chunk-C4DJPZRU.js → chunk-OO5LPTO7.js} +14 -1
  15. package/dist/chunk-OO5LPTO7.js.map +1 -0
  16. package/dist/{chunk-YXQX7RQT.js → chunk-PPWKSUDS.js} +2 -2
  17. package/dist/{chunk-KKRO2VCP.js → chunk-QTBAMHEF.js} +2 -2
  18. package/dist/client.d.ts +43 -4
  19. package/dist/codex-realtime-controller.js +2 -2
  20. package/dist/core.d.ts +3 -2
  21. package/dist/core.js +9 -7
  22. package/dist/document-authority.js +5 -5
  23. package/dist/editable-artifacts.js +4 -4
  24. package/dist/errors.d.ts +12 -0
  25. package/dist/github-repositories.d.ts +10 -0
  26. package/dist/github-repositories.js +36 -0
  27. package/dist/github-repositories.js.map +1 -0
  28. package/dist/index.d.ts +6 -5
  29. package/dist/index.js +62 -52
  30. package/dist/index.js.map +1 -1
  31. package/dist/interaction.js +2 -2
  32. package/dist/model-picker-order.d.ts +1 -0
  33. package/dist/model-picker-order.js +10 -0
  34. package/dist/model-picker-order.js.map +1 -0
  35. package/dist/realtime.js +2 -2
  36. package/dist/session-titles.d.ts +2 -28
  37. package/dist/stream.d.ts +2 -0
  38. package/dist/types.d.ts +121 -3
  39. package/package.json +10 -2
  40. package/src/artifact-client.ts +2 -1
  41. package/src/artifacts.ts +1 -0
  42. package/src/browser.ts +3 -0
  43. package/src/client.ts +261 -15
  44. package/src/core.ts +3 -0
  45. package/src/errors.ts +23 -0
  46. package/src/github-repositories.ts +60 -0
  47. package/src/index.ts +27 -1
  48. package/src/model-picker-order.ts +6 -0
  49. package/src/session-titles.ts +8 -82
  50. package/src/stream.ts +29 -8
  51. package/src/types.ts +147 -4
  52. package/dist/chunk-C4DJPZRU.js.map +0 -1
  53. package/dist/chunk-JUS2UYRP.js.map +0 -1
  54. package/dist/chunk-QT3KFVDP.js.map +0 -1
  55. package/dist/chunk-TRNI7KEO.js.map +0 -1
  56. /package/dist/{chunk-C2H7HBNP.js.map → chunk-7S2MZ65L.js.map} +0 -0
  57. /package/dist/{chunk-YXQX7RQT.js.map → chunk-PPWKSUDS.js.map} +0 -0
  58. /package/dist/{chunk-KKRO2VCP.js.map → chunk-QTBAMHEF.js.map} +0 -0
@@ -1,84 +1,10 @@
1
- import {
1
+ export {
2
2
  AUTOMATIC_SESSION_TITLE_FALLBACK,
3
- boundAutomaticSessionTitle,
4
- containsSensitiveAutomaticSessionTitleValue,
3
+ deriveAutomaticSessionTitlePreview,
4
+ deriveSessionDisplayTitle,
5
+ sessionTitleIsPending,
6
+ } from "@opengeni/contracts/session-titles";
7
+ export type {
8
+ SessionDisplayTitleInput,
9
+ SessionDisplayTitleOptions,
5
10
  } from "@opengeni/contracts/session-titles";
6
- import type { Session } from "./types";
7
-
8
- export { AUTOMATIC_SESSION_TITLE_FALLBACK };
9
-
10
- // Session creation accepts a body far larger than a navigation label. Bound
11
- // the source before any replace/split/normalization so a persisted large prompt
12
- // cannot amplify memory or CPU on every browser render.
13
- const PROMPT_PREVIEW_SCAN_MAX_CODE_UNITS = 4_096;
14
-
15
- function deriveOpeningPromptPreview(value: unknown): string | null {
16
- if (typeof value !== "string") return null;
17
-
18
- const firstLine = value
19
- .slice(0, PROMPT_PREVIEW_SCAN_MAX_CODE_UNITS)
20
- .replace(/[\u0000-\u001f\u007f-\u009f]+/gu, "\n")
21
- .split(/\n+/u)
22
- .map((line) => line.trim())
23
- .find(Boolean);
24
- if (!firstLine) return null;
25
- if (containsSensitiveAutomaticSessionTitleValue(firstLine)) return null;
26
-
27
- const preview = boundAutomaticSessionTitle(firstLine.replace(/\s+/gu, " "))
28
- .replace(/[\s.!?,;:\-–—]+$/u, "")
29
- .trim();
30
- if (!preview) return null;
31
- return preview;
32
- }
33
-
34
- export type SessionDisplayTitleInput = {
35
- title?: Session["title"] | undefined;
36
- titleSource?: Session["titleSource"] | undefined;
37
- initialMessage?: Session["initialMessage"] | null | undefined;
38
- metadata?: Readonly<Record<string, unknown>> | undefined;
39
- };
40
-
41
- export type SessionDisplayTitleOptions = {
42
- /** Optional metadata fields to try before the opening-prompt preview. */
43
- metadataKeys?: readonly string[] | undefined;
44
- };
45
-
46
- /**
47
- * Whether the durable title still represents the automatic-title pending state.
48
- * A user-authored title always wins, even when its literal value is the fallback.
49
- */
50
- export function sessionTitleIsPending(input: SessionDisplayTitleInput): boolean {
51
- const title = input.title?.trim() ?? "";
52
- return input.titleSource !== "user" && (!title || title === AUTOMATIC_SESSION_TITLE_FALLBACK);
53
- }
54
-
55
- /**
56
- * Derive the title a client should display for a session.
57
- *
58
- * A semantic agent title or human rename wins. While automatic naming is still
59
- * pending, clients show a short, sensitive-safe preview of the opening prompt;
60
- * the preview is never persisted as title metadata and is replaced naturally
61
- * when `session.title_set` arrives. Obvious credential-, URL-, or identifier-
62
- * shaped prompt prefixes retain the generic fallback.
63
- */
64
- export function deriveSessionDisplayTitle(
65
- input: SessionDisplayTitleInput,
66
- options: SessionDisplayTitleOptions = {},
67
- ): string {
68
- const title = input.title?.trim() ?? "";
69
- if (input.titleSource === "user") {
70
- return title || AUTOMATIC_SESSION_TITLE_FALLBACK;
71
- }
72
- if (title && !sessionTitleIsPending(input)) {
73
- return title;
74
- }
75
-
76
- for (const key of options.metadataKeys ?? []) {
77
- const value = input.metadata?.[key];
78
- if (typeof value === "string" && value.trim().length > 0) {
79
- return value.trim();
80
- }
81
- }
82
-
83
- return deriveOpeningPromptPreview(input.initialMessage) ?? AUTOMATIC_SESSION_TITLE_FALLBACK;
84
- }
package/src/stream.ts CHANGED
@@ -2,6 +2,10 @@ import { isAbortError, isRetryableStreamError, OpenGeniStreamError } from "./err
2
2
  import { parseSseStream } from "./sse";
3
3
  import type { SessionEvent } from "./types";
4
4
 
5
+ const SESSION_EVENT_STREAM_COVERAGE = Symbol.for(
6
+ "@opengeni/sdk/session-event-stream-covered-through",
7
+ );
8
+
5
9
  /**
6
10
  * Transport boundary for the streaming core. The client implements it with
7
11
  * `fetch`; unit tests script it directly.
@@ -111,7 +115,8 @@ export async function* streamSessionEvents(
111
115
  if (!event) {
112
116
  continue;
113
117
  }
114
- const coveredSequence = eventResumeSequence(event);
118
+ const coveredSequence = trustedSseSequence(message.id, event.sequence);
119
+ markSessionEventStreamCoverage(event, coveredSequence);
115
120
  if (coveredSequence <= cursor) continue;
116
121
  if (event.sequence > cursor + 1) {
117
122
  for await (const missed of backfillEvents(transport, cursor, event.sequence - 1)) {
@@ -283,13 +288,29 @@ function parseSessionEvent(data: string): SessionEvent | null {
283
288
  return parsed as SessionEvent;
284
289
  }
285
290
 
286
- /** Raw durable cursor covered by a compact SSE event. */
287
- function eventResumeSequence(event: SessionEvent): number {
288
- if (!event.payload || typeof event.payload !== "object" || Array.isArray(event.payload)) {
289
- return event.sequence;
290
- }
291
- const covered = Number((event.payload as Record<string, unknown>).coalescedUntil);
292
- return Math.max(event.sequence, Number.isFinite(covered) ? Math.floor(covered) : event.sequence);
291
+ /** Trusted SSE coverage attached non-enumerably to a streamed event. */
292
+ export function sessionEventStreamCoveredThrough(event: SessionEvent): number | null {
293
+ const covered = (event as SessionEvent & { [SESSION_EVENT_STREAM_COVERAGE]?: unknown })[
294
+ SESSION_EVENT_STREAM_COVERAGE
295
+ ];
296
+ return typeof covered === "number" && Number.isSafeInteger(covered) && covered >= event.sequence
297
+ ? covered
298
+ : null;
299
+ }
300
+
301
+ function trustedSseSequence(id: string | undefined, sequence: number): number {
302
+ if (id === undefined || !/^\d+$/.test(id)) return sequence;
303
+ const covered = Number(id);
304
+ return Number.isSafeInteger(covered) && covered >= sequence ? covered : sequence;
305
+ }
306
+
307
+ function markSessionEventStreamCoverage(event: SessionEvent, covered: number): void {
308
+ Object.defineProperty(event, SESSION_EVENT_STREAM_COVERAGE, {
309
+ value: covered,
310
+ enumerable: false,
311
+ configurable: false,
312
+ writable: false,
313
+ });
293
314
  }
294
315
 
295
316
  async function sleep(delayMs: number, signal: AbortSignal | undefined): Promise<void> {
package/src/types.ts CHANGED
@@ -610,6 +610,7 @@ export type McpConnectionAuthoritySelection = {
610
610
 
611
611
  export type McpServerConnectionRef = {
612
612
  connectionId?: string | undefined;
613
+ authoritySource?: "host" | undefined;
613
614
  provider?: string | undefined;
614
615
  providerDomain: string;
615
616
  kind?: ConnectionKind | undefined;
@@ -671,6 +672,7 @@ export type CreateConnectionRequest = {
671
672
  grantedScopes?: string[] | undefined;
672
673
  expiresAt?: string | null | undefined;
673
674
  metadata?: Record<string, unknown> | undefined;
675
+ operationId?: string | undefined;
674
676
  };
675
677
 
676
678
  export type PersonalGitHubConnectionMetadata = {
@@ -1072,6 +1074,8 @@ export type UpdateConnectionRequest = {
1072
1074
  grantedScopes?: string[] | undefined;
1073
1075
  expiresAt?: string | null | undefined;
1074
1076
  metadata?: Record<string, unknown> | undefined;
1077
+ expectedVersion?: number | undefined;
1078
+ operationId?: string | undefined;
1075
1079
  };
1076
1080
 
1077
1081
  export type ConnectionResponse = {
@@ -1850,6 +1854,8 @@ export type SessionEvent = {
1850
1854
  sessionId: string;
1851
1855
  /** Per-session sequence number: positive, contiguous, strictly increasing. */
1852
1856
  sequence: number;
1857
+ /** Server-owned durable high-water mark for a synthetic compact event. */
1858
+ coveredThrough?: number | undefined;
1853
1859
  type: SessionEventType;
1854
1860
  payload: unknown;
1855
1861
  occurredAt: string;
@@ -1983,6 +1989,7 @@ export type ToolAuthNeededPayload = {
1983
1989
  providerDomain: string;
1984
1990
  provider?: string | undefined;
1985
1991
  connectionId?: string | null | undefined;
1992
+ authoritySource?: "host" | undefined;
1986
1993
  reason:
1987
1994
  | "missing_connection"
1988
1995
  | "expired"
@@ -1991,6 +1998,15 @@ export type ToolAuthNeededPayload = {
1991
1998
  | "personal_authority_unavailable"
1992
1999
  | "unsupported_auth"
1993
2000
  | "resource_scope_unavailable";
2001
+ hostReason?:
2002
+ | "missing_connection"
2003
+ | "expired"
2004
+ | "insufficient_scope"
2005
+ | "refresh_failed"
2006
+ | "personal_authority_unavailable"
2007
+ | "unsupported_auth"
2008
+ | "resource_scope_unavailable"
2009
+ | undefined;
1994
2010
  scopes?: string[] | undefined;
1995
2011
  resource?: string | undefined;
1996
2012
  selectedResources?: Array<{ id: string; kind: "repository" }> | undefined;
@@ -2722,6 +2738,8 @@ export type CreateSessionRequest = {
2722
2738
  resources?: ResourceRef[] | undefined;
2723
2739
  /** Inline skills fixed onto this session; omitted children inherit them. */
2724
2740
  skills?: SessionSkill[] | undefined;
2741
+ /** Installed session-selected Skill identities to freeze onto this session at creation. */
2742
+ installedSkillIds?: string[] | undefined;
2725
2743
  tools?: ToolRef[] | undefined;
2726
2744
  metadata?: Record<string, unknown> | undefined;
2727
2745
  model?: string | undefined;
@@ -3023,16 +3041,20 @@ export type ModelCapabilitiesV1 = {
3023
3041
  export type ModelCredentialSourceV1 =
3024
3042
  | { kind: "deployment"; mechanism: "api_key" | "azure_ad_bearer" }
3025
3043
  | { kind: "connected_subscription"; provider: "codex" | "xai" }
3026
- | { kind: "workspace_connection"; mechanism: "api_key" };
3044
+ | { kind: "workspace_connection"; mechanism: "api_key" }
3045
+ | { kind: "organization_connection"; mechanism: "api_key" };
3027
3046
 
3028
3047
  export type ModelBillingAttributionV1 = {
3029
- upstreamPayer: "deployment" | "workspace" | "connected_subscription";
3048
+ upstreamPayer: "deployment" | "workspace" | "organization" | "connected_subscription";
3030
3049
  metering: "opengeni_credits" | "external";
3031
3050
  };
3032
3051
 
3052
+ export type ModelCostClassV1 = "free" | "credits" | "subscription" | "workspace" | "organization";
3053
+
3033
3054
  export type ModelPricingV1 = {
3034
3055
  inputMicrosPerMillionTokens: number;
3035
3056
  cachedInputMicrosPerMillionTokens?: number | undefined;
3057
+ cacheWriteMicrosPerMillionTokens?: number | undefined;
3036
3058
  outputMicrosPerMillionTokens: number;
3037
3059
  marginBps?: number | undefined;
3038
3060
  };
@@ -3062,7 +3084,7 @@ export type ClientModel = {
3062
3084
  provider: string;
3063
3085
  providerLabel: string;
3064
3086
  api: "responses" | "chat";
3065
- source?: "opengeni" | "codex" | "supergrok" | "workspace_gateway" | undefined;
3087
+ source?: "opengeni" | "codex" | "supergrok" | "workspace_gateway" | "openrouter" | undefined;
3066
3088
  contextWindowTokens?: number | undefined;
3067
3089
  schemaVersion?: 1 | undefined;
3068
3090
  aliases?: string[] | undefined;
@@ -3082,6 +3104,7 @@ export type ClientModel = {
3082
3104
  | undefined;
3083
3105
  credentialSource?: ModelCredentialSourceV1 | undefined;
3084
3106
  billing?: ModelBillingAttributionV1 | undefined;
3107
+ cost?: ModelCostClassV1 | undefined;
3085
3108
  capabilities?: ModelCapabilitiesV1 | undefined;
3086
3109
  pricing?: ModelPricingScheduleV1 | undefined;
3087
3110
  definitionVersion?: string | undefined;
@@ -3126,6 +3149,68 @@ export type WorkspaceModelCatalogResponse = {
3126
3149
  models: WorkspaceModelCatalogModel[];
3127
3150
  };
3128
3151
 
3152
+ export type WorkspaceGatewayCustomModel = {
3153
+ id: string;
3154
+ upstreamModelId: string;
3155
+ label: string | null;
3156
+ version: number;
3157
+ createdAt: string;
3158
+ updatedAt: string;
3159
+ };
3160
+
3161
+ export type WorkspaceGatewayCustomModelsResponse = {
3162
+ models: WorkspaceGatewayCustomModel[];
3163
+ };
3164
+
3165
+ export type CreateWorkspaceGatewayCustomModelRequest = {
3166
+ operationId: string;
3167
+ upstreamModelId: string;
3168
+ label?: string | undefined;
3169
+ };
3170
+
3171
+ export type DeleteWorkspaceGatewayCustomModelRequest = {
3172
+ expectedVersion: number;
3173
+ operationId: string;
3174
+ };
3175
+
3176
+ export type WorkspaceOpenRouterCustomModel = WorkspaceGatewayCustomModel;
3177
+
3178
+ export type WorkspaceOpenRouterCustomModelsResponse = {
3179
+ models: WorkspaceOpenRouterCustomModel[];
3180
+ };
3181
+
3182
+ export type CreateWorkspaceOpenRouterCustomModelRequest = CreateWorkspaceGatewayCustomModelRequest;
3183
+
3184
+ export type DeleteWorkspaceOpenRouterCustomModelRequest = DeleteWorkspaceGatewayCustomModelRequest;
3185
+
3186
+ export type OrganizationModelProviderKind = "vercel_gateway" | "openrouter";
3187
+
3188
+ export type OrganizationModelProviderConnection = {
3189
+ providerKind: OrganizationModelProviderKind;
3190
+ status: "active" | "revoked";
3191
+ version: number;
3192
+ createdAt: string;
3193
+ updatedAt: string;
3194
+ };
3195
+
3196
+ export type UpsertOrganizationModelProviderConnectionRequest = {
3197
+ operationId: string;
3198
+ expectedVersion?: number | undefined;
3199
+ apiKey: string;
3200
+ };
3201
+
3202
+ export type RevokeOrganizationModelProviderConnectionRequest = {
3203
+ operationId: string;
3204
+ expectedVersion: number;
3205
+ };
3206
+
3207
+ export type OrganizationProviderCustomModel = WorkspaceGatewayCustomModel;
3208
+ export type OrganizationProviderCustomModelsResponse = {
3209
+ models: OrganizationProviderCustomModel[];
3210
+ };
3211
+ export type CreateOrganizationProviderCustomModelRequest = CreateWorkspaceGatewayCustomModelRequest;
3212
+ export type DeleteOrganizationProviderCustomModelRequest = DeleteWorkspaceGatewayCustomModelRequest;
3213
+
3129
3214
  /**
3130
3215
  * The workspace's hard model/provider allowlist. `null` means unrestricted for
3131
3216
  * that dimension; an empty array is an explicit total block.
@@ -3938,6 +4023,16 @@ export type CreateOrganizationResponse = {
3938
4023
  organization: OrganizationSummary;
3939
4024
  workspaceId: string;
3940
4025
  };
4026
+ export type CreateAdditionalOrganizationRequest = {
4027
+ name: string;
4028
+ workspaceName: string;
4029
+ operationId: string;
4030
+ };
4031
+ export type CreateAdditionalOrganizationResponse = {
4032
+ organization: OrganizationSummary;
4033
+ workspaceId: string;
4034
+ personalWorkspaceId: string;
4035
+ };
3941
4036
  export type UpdateOrganizationNameRequest = {
3942
4037
  name: string;
3943
4038
  expectedUpdatedAt: string;
@@ -5959,10 +6054,12 @@ export type CapabilityPackSkillFile = {
5959
6054
  export type CapabilityPackSkill = {
5960
6055
  name: string;
5961
6056
  description?: string | undefined;
6057
+ /** Omitted means workspace-wide; session_selected requires explicit session attachment. */
6058
+ activationMode?: "workspace_managed" | "session_selected" | undefined;
5962
6059
  files: CapabilityPackSkillFile[];
5963
6060
  };
5964
6061
 
5965
- export type SessionSkill = CapabilityPackSkill;
6062
+ export type SessionSkill = Omit<CapabilityPackSkill, "activationMode">;
5966
6063
 
5967
6064
  export type CapabilityPackVariableSetSpec = {
5968
6065
  description: string;
@@ -6056,6 +6153,7 @@ export type RegisterCapabilityPackRequest = {
6056
6153
  | {
6057
6154
  name: string;
6058
6155
  description?: string | undefined;
6156
+ activationMode?: "workspace_managed" | "session_selected" | undefined;
6059
6157
  files: CapabilityPackSkillFile[];
6060
6158
  }[]
6061
6159
  | undefined;
@@ -6507,6 +6605,7 @@ export type CapabilityCatalogItem = {
6507
6605
  /** The connection backing this enabled installation, or null when none is involved. */
6508
6606
  connectionRef: {
6509
6607
  connectionId?: string | undefined;
6608
+ authoritySource?: "host" | undefined;
6510
6609
  providerDomain: string;
6511
6610
  kind: string;
6512
6611
  subjectScope?: "subject" | "workspace" | undefined;
@@ -7129,6 +7228,37 @@ export type GitHubRepositoriesResponse = {
7129
7228
  repositories: GitHubRepository[];
7130
7229
  };
7131
7230
 
7231
+ export type VerifyPublicGitHubRepositoryRefRequest = {
7232
+ url: string;
7233
+ ref: string;
7234
+ };
7235
+
7236
+ export type VerifyPublicGitHubRepositoryRefResponse = {
7237
+ owner: string;
7238
+ name: string;
7239
+ fullName: string;
7240
+ canonicalUrl: string;
7241
+ cloneUrl: string;
7242
+ defaultBranch: string;
7243
+ ref: string;
7244
+ commitSha: string;
7245
+ };
7246
+
7247
+ export type GitHubRepositoryBranch = {
7248
+ name: string;
7249
+ isDefault: boolean;
7250
+ };
7251
+
7252
+ export type ListGitHubRepositoryBranchesOptions = {
7253
+ cursor?: number | undefined;
7254
+ limit?: number | undefined;
7255
+ };
7256
+
7257
+ export type GitHubRepositoryBranchesResponse = {
7258
+ branches: GitHubRepositoryBranch[];
7259
+ nextCursor: number | null;
7260
+ };
7261
+
7132
7262
  export type CreateGitHubAppManifestRequest = {
7133
7263
  appName?: string | undefined;
7134
7264
  organization?: string | undefined;
@@ -7234,6 +7364,8 @@ export type InsightsModelUsageRow = {
7234
7364
  creditUsd: number;
7235
7365
  estimatedProviderUsd: number;
7236
7366
  estimatedProviderCostKnownCalls: number;
7367
+ equivalentCreditUsd: number;
7368
+ equivalentCreditCostKnownCalls: number;
7237
7369
  };
7238
7370
 
7239
7371
  export type InsightsSeriesPoint = {
@@ -7241,6 +7373,8 @@ export type InsightsSeriesPoint = {
7241
7373
  modelCostUsd: number;
7242
7374
  estimatedProviderUsd: number;
7243
7375
  estimatedProviderCostKnownCalls: number;
7376
+ equivalentCreditUsd: number;
7377
+ equivalentCreditCostKnownCalls: number;
7244
7378
  warmSeconds: number;
7245
7379
  inputTokens: number;
7246
7380
  outputTokens: number;
@@ -7272,6 +7406,8 @@ export type InsightsSpendDriver = {
7272
7406
  creditUsd: number;
7273
7407
  estimatedProviderUsd: number;
7274
7408
  estimatedProviderCostKnownCalls: number;
7409
+ equivalentCreditUsd: number;
7410
+ equivalentCreditCostKnownCalls: number;
7275
7411
  tokens: number;
7276
7412
  cacheHitPct: number;
7277
7413
  pctOfCreditUsd: number;
@@ -7317,6 +7453,8 @@ export type InsightsScheduleRow = {
7317
7453
  creditUsd: number | null;
7318
7454
  estimatedProviderUsd: number | null;
7319
7455
  estimatedProviderCostKnownCalls: number | null;
7456
+ equivalentCreditUsd: number | null;
7457
+ equivalentCreditCostKnownCalls: number | null;
7320
7458
  tokens: number | null;
7321
7459
  cacheHitPct: number | null;
7322
7460
  billing: InsightsBillingPath | null;
@@ -7341,6 +7479,7 @@ export type InsightsModelCallRow = {
7341
7479
  totalTokens: number | null;
7342
7480
  creditUsd: number;
7343
7481
  estimatedProviderUsd: number | null;
7482
+ equivalentCreditUsd: number | null;
7344
7483
  pricingSource: InsightsPricingSource | null;
7345
7484
  };
7346
7485
 
@@ -7401,6 +7540,10 @@ export type WorkspaceInsightsSnapshot = {
7401
7540
  priorEstimatedProviderUsd: number;
7402
7541
  estimatedProviderCostKnownCalls: number;
7403
7542
  priorEstimatedProviderCostKnownCalls: number;
7543
+ equivalentCreditUsd: number;
7544
+ priorEquivalentCreditUsd: number;
7545
+ equivalentCreditCostKnownCalls: number;
7546
+ priorEquivalentCreditCostKnownCalls: number;
7404
7547
  modelCalls: number;
7405
7548
  priorInputTokens: number;
7406
7549
  priorTotalTokens: number;
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/errors.ts"],"sourcesContent":["/** Error for a non-2xx OpenGeni API response. */\nexport class OpenGeniApiError extends Error {\n readonly status: number;\n readonly code: string | undefined;\n readonly retryable: boolean;\n readonly correlationId: string | undefined;\n /** True only when an uncontrolled transport failed after a mutation may have been accepted. */\n readonly outcomeUnknown: boolean;\n readonly body: string;\n readonly details: Record<string, unknown> | undefined;\n\n constructor(\n status: number,\n body: string,\n options: {\n code?: string | undefined;\n retryable?: boolean | undefined;\n correlationId?: string | undefined;\n outcomeUnknown?: boolean | undefined;\n displayMessage?: string | undefined;\n mutation?: boolean | undefined;\n } = {},\n ) {\n const decoded = decodeApiErrorBody(body);\n const correlationId = decoded?.requestId ?? boundedCorrelationId(options.correlationId);\n const gatewayFailure = status >= 502 && status <= 504;\n const fromResponse = options.mutation !== undefined;\n const message = decoded?.message ?? (fromResponse ? \"Request failed.\" : body || \"(empty body)\");\n const displayMessage =\n options.displayMessage ??\n (gatewayFailure && fromResponse\n ? (decoded?.message ?? \"OpenGeni is temporarily unavailable — retry.\")\n : `OpenGeni API ${status}: ${message}`);\n super(correlationId ? `${displayMessage} Reference: ${correlationId}.` : displayMessage);\n this.name = \"OpenGeniApiError\";\n this.status = status;\n this.code =\n options.code ??\n decoded?.code ??\n (gatewayFailure && fromResponse ? \"upstream_unavailable\" : undefined);\n this.retryable = options.retryable ?? decoded?.retryable ?? retryableApiStatus(status);\n this.correlationId = correlationId;\n this.outcomeUnknown =\n options.outcomeUnknown ??\n decoded?.outcomeUnknown ??\n (gatewayFailure && !!options.mutation && !decoded);\n this.body = !fromResponse || decoded ? body : \"\";\n this.details = decoded?.details;\n }\n}\n\nfunction decodeApiErrorBody(body: string): {\n code: string | undefined;\n message: string | undefined;\n requestId: string | undefined;\n retryable: boolean | undefined;\n outcomeUnknown: boolean | undefined;\n details: Record<string, unknown> | undefined;\n} | null {\n if (!body) return null;\n try {\n const decoded: unknown = JSON.parse(body);\n if (!decoded || typeof decoded !== \"object\" || Array.isArray(decoded)) return null;\n const record = decoded as Record<string, unknown>;\n const nested =\n record.error && typeof record.error === \"object\" && !Array.isArray(record.error)\n ? (record.error as Record<string, unknown>)\n : record;\n const code = boundedApiField(nested.code);\n const message = boundedApiField(nested.message);\n const requestId = boundedCorrelationId(nested.requestId);\n const retryable = typeof nested.retryable === \"boolean\" ? nested.retryable : undefined;\n const outcomeUnknown =\n typeof nested.outcomeUnknown === \"boolean\" ? nested.outcomeUnknown : undefined;\n const details = boundedApiDetails(nested.details);\n if (\n !code &&\n !message &&\n !requestId &&\n retryable === undefined &&\n outcomeUnknown === undefined &&\n !details\n )\n return null;\n return {\n code,\n message,\n requestId,\n retryable,\n outcomeUnknown,\n details,\n };\n } catch {\n return null;\n }\n}\n\nfunction boundedApiDetails(value: unknown): Record<string, unknown> | undefined {\n if (!value || typeof value !== \"object\" || Array.isArray(value)) return;\n const entries = Object.entries(value as Record<string, unknown>).slice(0, 16);\n const details: Record<string, unknown> = {};\n for (const [key, entry] of entries) {\n if (!/^[a-zA-Z][\\w.-]{0,63}$/.test(key)) continue;\n if (typeof entry === \"string\") {\n const bounded = boundedApiField(entry);\n if (bounded !== undefined) details[key] = bounded;\n } else if (typeof entry === \"number\" || typeof entry === \"boolean\" || entry === null) {\n details[key] = entry;\n }\n }\n return Object.keys(details).length > 0 ? details : undefined;\n}\n\nfunction boundedApiField(value: unknown): string | undefined {\n if (typeof value !== \"string\") return;\n const bytes = new TextEncoder().encode(value);\n return bytes.byteLength <= 512 ? value : new TextDecoder().decode(bytes.slice(0, 512));\n}\n\nfunction retryableApiStatus(status: number): boolean {\n return status === 408 || status === 409 || status === 425 || status === 429 || status >= 500;\n}\n\nfunction boundedCorrelationId(value: unknown): string | undefined {\n if (typeof value !== \"string\" || value.length > 128 || !/^[\\w.:-]+$/.test(value)) {\n return;\n }\n return value;\n}\n\n/** A legacy short-lived session-list snapshot cursor can no longer be continued. */\nexport class OpenGeniSessionListCursorError extends OpenGeniApiError {}\n\n/** The browser bundle and API disagree about their state-changing wire contract. */\nexport class OpenGeniApiContractMismatchError extends Error {\n readonly expected: string;\n readonly actual: string;\n\n constructor(expected: string, actual: string) {\n super(`OpenGeni API contract mismatch: client expects ${expected}, API serves ${actual}`);\n this.name = \"OpenGeniApiContractMismatchError\";\n this.expected = expected;\n this.actual = actual;\n }\n}\n\n/** Error for an unrecoverable event-stream condition (not a transient drop). */\nexport class OpenGeniStreamError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenGeniStreamError\";\n }\n}\n\nexport function isAbortError(error: unknown): boolean {\n return (\n (error instanceof DOMException && error.name === \"AbortError\") ||\n (error instanceof Error && error.name === \"AbortError\")\n );\n}\n\n/**\n * Transient conditions worth a reconnect: network-level failures (`fetch`\n * rejects with `TypeError`) and HTTP statuses that signal a temporary server\n * or contention condition. Auth/validation failures (401/403/404/...) are\n * permanent and surface to the caller instead.\n */\nexport function isRetryableStreamError(error: unknown): boolean {\n if (error instanceof OpenGeniApiError) return error.retryable;\n return error instanceof TypeError;\n}\n"],"mappings":";AACO,IAAM,mBAAN,cAA+B,MAAM;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YACE,QACA,MACA,UAOI,CAAC,GACL;AACA,UAAM,UAAU,mBAAmB,IAAI;AACvC,UAAM,gBAAgB,SAAS,aAAa,qBAAqB,QAAQ,aAAa;AACtF,UAAM,iBAAiB,UAAU,OAAO,UAAU;AAClD,UAAM,eAAe,QAAQ,aAAa;AAC1C,UAAM,UAAU,SAAS,YAAY,eAAe,oBAAoB,QAAQ;AAChF,UAAM,iBACJ,QAAQ,mBACP,kBAAkB,eACd,SAAS,WAAW,sDACrB,gBAAgB,MAAM,KAAK,OAAO;AACxC,UAAM,gBAAgB,GAAG,cAAc,eAAe,aAAa,MAAM,cAAc;AACvF,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OACH,QAAQ,QACR,SAAS,SACR,kBAAkB,eAAe,yBAAyB;AAC7D,SAAK,YAAY,QAAQ,aAAa,SAAS,aAAa,mBAAmB,MAAM;AACrF,SAAK,gBAAgB;AACrB,SAAK,iBACH,QAAQ,kBACR,SAAS,mBACR,kBAAkB,CAAC,CAAC,QAAQ,YAAY,CAAC;AAC5C,SAAK,OAAO,CAAC,gBAAgB,UAAU,OAAO;AAC9C,SAAK,UAAU,SAAS;AAAA,EAC1B;AACF;AAEA,SAAS,mBAAmB,MAOnB;AACP,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI;AACF,UAAM,UAAmB,KAAK,MAAM,IAAI;AACxC,QAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,EAAG,QAAO;AAC9E,UAAM,SAAS;AACf,UAAM,SACJ,OAAO,SAAS,OAAO,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,OAAO,KAAK,IAC1E,OAAO,QACR;AACN,UAAM,OAAO,gBAAgB,OAAO,IAAI;AACxC,UAAM,UAAU,gBAAgB,OAAO,OAAO;AAC9C,UAAM,YAAY,qBAAqB,OAAO,SAAS;AACvD,UAAM,YAAY,OAAO,OAAO,cAAc,YAAY,OAAO,YAAY;AAC7E,UAAM,iBACJ,OAAO,OAAO,mBAAmB,YAAY,OAAO,iBAAiB;AACvE,UAAM,UAAU,kBAAkB,OAAO,OAAO;AAChD,QACE,CAAC,QACD,CAAC,WACD,CAAC,aACD,cAAc,UACd,mBAAmB,UACnB,CAAC;AAED,aAAO;AACT,WAAO;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAAA,EACF,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,SAAS,kBAAkB,OAAqD;AAC9E,MAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,EAAG;AACjE,QAAM,UAAU,OAAO,QAAQ,KAAgC,EAAE,MAAM,GAAG,EAAE;AAC5E,QAAM,UAAmC,CAAC;AAC1C,aAAW,CAAC,KAAK,KAAK,KAAK,SAAS;AAClC,QAAI,CAAC,yBAAyB,KAAK,GAAG,EAAG;AACzC,QAAI,OAAO,UAAU,UAAU;AAC7B,YAAM,UAAU,gBAAgB,KAAK;AACrC,UAAI,YAAY,OAAW,SAAQ,GAAG,IAAI;AAAA,IAC5C,WAAW,OAAO,UAAU,YAAY,OAAO,UAAU,aAAa,UAAU,MAAM;AACpF,cAAQ,GAAG,IAAI;AAAA,IACjB;AAAA,EACF;AACA,SAAO,OAAO,KAAK,OAAO,EAAE,SAAS,IAAI,UAAU;AACrD;AAEA,SAAS,gBAAgB,OAAoC;AAC3D,MAAI,OAAO,UAAU,SAAU;AAC/B,QAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,KAAK;AAC5C,SAAO,MAAM,cAAc,MAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,MAAM,MAAM,GAAG,GAAG,CAAC;AACvF;AAEA,SAAS,mBAAmB,QAAyB;AACnD,SAAO,WAAW,OAAO,WAAW,OAAO,WAAW,OAAO,WAAW,OAAO,UAAU;AAC3F;AAEA,SAAS,qBAAqB,OAAoC;AAChE,MAAI,OAAO,UAAU,YAAY,MAAM,SAAS,OAAO,CAAC,aAAa,KAAK,KAAK,GAAG;AAChF;AAAA,EACF;AACA,SAAO;AACT;AAGO,IAAM,iCAAN,cAA6C,iBAAiB;AAAC;AAG/D,IAAM,mCAAN,cAA+C,MAAM;AAAA,EACjD;AAAA,EACA;AAAA,EAET,YAAY,UAAkB,QAAgB;AAC5C,UAAM,kDAAkD,QAAQ,gBAAgB,MAAM,EAAE;AACxF,SAAK,OAAO;AACZ,SAAK,WAAW;AAChB,SAAK,SAAS;AAAA,EAChB;AACF;AAGO,IAAM,sBAAN,cAAkC,MAAM;AAAA,EAC7C,YAAY,SAAiB;AAC3B,UAAM,OAAO;AACb,SAAK,OAAO;AAAA,EACd;AACF;AAEO,SAAS,aAAa,OAAyB;AACpD,SACG,iBAAiB,gBAAgB,MAAM,SAAS,gBAChD,iBAAiB,SAAS,MAAM,SAAS;AAE9C;AAQO,SAAS,uBAAuB,OAAyB;AAC9D,MAAI,iBAAiB,iBAAkB,QAAO,MAAM;AACpD,SAAO,iBAAiB;AAC1B;","names":[]}