@gravity-rail/sdk 0.17.0 → 0.18.1

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/dist/internal.js CHANGED
@@ -10,6 +10,18 @@ import {
10
10
  AccessGrantTrigger,
11
11
  AccessGrantsApi,
12
12
  AccessLevel,
13
+ ActivityActorKind,
14
+ ActivityAggregationKind,
15
+ ActivityCaptureState,
16
+ ActivityConfigAction,
17
+ ActivityConfigArea,
18
+ ActivityCoverageLimitation,
19
+ ActivityDirection,
20
+ ActivityEmptyReason,
21
+ ActivityEventType,
22
+ ActivityEventTypePreset,
23
+ ActivityGoalImpact,
24
+ ActivityTimelineProjection,
13
25
  AgentTasksApi,
14
26
  AgentsApi,
15
27
  ApiKeysApi,
@@ -56,6 +68,7 @@ import {
56
68
  FhirConnectionsApi,
57
69
  FhirVendor,
58
70
  FilesApi,
71
+ FormValueDisposition,
59
72
  GravityRailClient,
60
73
  HealthieApi,
61
74
  HubspotApi,
@@ -64,7 +77,6 @@ import {
64
77
  InvitationStatus,
65
78
  JobPosition,
66
79
  JourneysApi,
67
- LIMIT_ONLY_RESOURCES,
68
80
  MASKED_SECRET_SENTINEL,
69
81
  McpServerState,
70
82
  McpServersApi,
@@ -125,7 +137,8 @@ import {
125
137
  SMS_DELIVERY_FAILURE_STATUSES,
126
138
  STT_MODEL_DEEPGRAM_FLUX,
127
139
  STT_MODEL_DEEPGRAM_FLUX_MULTI,
128
- STT_MODEL_ELEVENLABS_SCRIBE,
140
+ STT_MODEL_DEEPGRAM_FLUX_MULTI_SELFHOST,
141
+ STT_MODEL_DEEPGRAM_FLUX_SELFHOST,
129
142
  SalesforceApi,
130
143
  Scope,
131
144
  ScopeCategory,
@@ -164,6 +177,7 @@ import {
164
177
  areDependenciesSatisfied,
165
178
  asIdentifiedMemberContactConflict,
166
179
  bindAccessGrantsMethods,
180
+ bindActivityTimelineMethods,
167
181
  bindAgentTasksMethods,
168
182
  bindAgentsMethods,
169
183
  bindAppsMethods,
@@ -187,6 +201,7 @@ import {
187
201
  bindOperatorMethods,
188
202
  bindOrgMethods,
189
203
  bindPersonasMethods,
204
+ bindProjectsMethods,
190
205
  bindPromptsMethods,
191
206
  bindPronunciationsMethods,
192
207
  bindQualificationsMethods,
@@ -209,8 +224,6 @@ import {
209
224
  formatAppContextAsMarkdown,
210
225
  getAllFeatures,
211
226
  getAllResourceSlugs,
212
- getApplicableResourceSlugs,
213
- getApplicableResources,
214
227
  getAvailableFeaturesForUpgrade,
215
228
  getFeature,
216
229
  getFeaturesByCategory,
@@ -218,7 +231,6 @@ import {
218
231
  getMissingDependencies,
219
232
  getResourceMetadata,
220
233
  getRevisionState,
221
- getScopeFromProductType,
222
234
  getTTSProvider,
223
235
  getVoiceModelId,
224
236
  initializeFeatures,
@@ -239,7 +251,7 @@ import {
239
251
  roleWorkflowAccess,
240
252
  usesBuiltinAssistant,
241
253
  validateFeatureDependencies
242
- } from "./chunk-CEFOCGYO.js";
254
+ } from "./chunk-PUIYXJSZ.js";
243
255
  import {
244
256
  AttendeeResponseStatus,
245
257
  AttendeeStatus,
@@ -262,6 +274,16 @@ import {
262
274
  parseOrgAuthChallenge
263
275
  } from "./chunk-PJFEGUHM.js";
264
276
 
277
+ // src/types/generated/addon.ts
278
+ var AddonMutationResponseScope = {
279
+ organization: "organization",
280
+ workspace: "workspace"
281
+ };
282
+ var OrganizationAddonResponseScope = {
283
+ organization: "organization",
284
+ workspace: "workspace"
285
+ };
286
+
265
287
  // src/types/generated/customer_activity.ts
266
288
  var CustomerActivityClassifierDetectorName = {
267
289
  assignment_chat_classifier: "assignment_chat_classifier",
@@ -418,6 +440,19 @@ export {
418
440
  AccessGrantTrigger,
419
441
  AccessGrantsApi,
420
442
  AccessLevel,
443
+ ActivityActorKind,
444
+ ActivityAggregationKind,
445
+ ActivityCaptureState,
446
+ ActivityConfigAction,
447
+ ActivityConfigArea,
448
+ ActivityCoverageLimitation,
449
+ ActivityDirection,
450
+ ActivityEmptyReason,
451
+ ActivityEventType,
452
+ ActivityEventTypePreset,
453
+ ActivityGoalImpact,
454
+ ActivityTimelineProjection,
455
+ AddonMutationResponseScope,
421
456
  AgentTasksApi,
422
457
  AgentsApi,
423
458
  ApiError,
@@ -485,6 +520,7 @@ export {
485
520
  FhirConnectionsApi,
486
521
  FhirVendor,
487
522
  FilesApi,
523
+ FormValueDisposition,
488
524
  GravityRailClient,
489
525
  HealthieApi,
490
526
  HubspotApi,
@@ -494,7 +530,6 @@ export {
494
530
  InvitationStatus,
495
531
  JobPosition,
496
532
  JourneysApi,
497
- LIMIT_ONLY_RESOURCES,
498
533
  MASKED_SECRET_SENTINEL,
499
534
  McpServerState,
500
535
  McpServersApi,
@@ -524,6 +559,7 @@ export {
524
559
  OperatorApi,
525
560
  OrgApi,
526
561
  OrgFeature,
562
+ OrganizationAddonResponseScope,
527
563
  PERMISSION_ADMIN,
528
564
  PERMISSION_CREATE,
529
565
  PERMISSION_DELETE,
@@ -570,7 +606,8 @@ export {
570
606
  SMS_DELIVERY_FAILURE_STATUSES,
571
607
  STT_MODEL_DEEPGRAM_FLUX,
572
608
  STT_MODEL_DEEPGRAM_FLUX_MULTI,
573
- STT_MODEL_ELEVENLABS_SCRIBE,
609
+ STT_MODEL_DEEPGRAM_FLUX_MULTI_SELFHOST,
610
+ STT_MODEL_DEEPGRAM_FLUX_SELFHOST,
574
611
  SalesforceApi,
575
612
  Scope,
576
613
  ScopeCategory,
@@ -610,6 +647,7 @@ export {
610
647
  areDependenciesSatisfied,
611
648
  asIdentifiedMemberContactConflict,
612
649
  bindAccessGrantsMethods,
650
+ bindActivityTimelineMethods,
613
651
  bindAgentTasksMethods,
614
652
  bindAgentsMethods,
615
653
  bindAppsMethods,
@@ -633,6 +671,7 @@ export {
633
671
  bindOperatorMethods,
634
672
  bindOrgMethods,
635
673
  bindPersonasMethods,
674
+ bindProjectsMethods,
636
675
  bindPromptsMethods,
637
676
  bindPronunciationsMethods,
638
677
  bindQualificationsMethods,
@@ -655,8 +694,6 @@ export {
655
694
  formatAppContextAsMarkdown,
656
695
  getAllFeatures,
657
696
  getAllResourceSlugs,
658
- getApplicableResourceSlugs,
659
- getApplicableResources,
660
697
  getAvailableFeaturesForUpgrade,
661
698
  getCookieValue,
662
699
  getFeature,
@@ -665,7 +702,6 @@ export {
665
702
  getMissingDependencies,
666
703
  getResourceMetadata,
667
704
  getRevisionState,
668
- getScopeFromProductType,
669
705
  getTTSProvider,
670
706
  getVoiceModelId,
671
707
  initializeFeatures,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types/generated/customer_activity.ts","../src/types/generated/phi_posture.ts","../src/types/generated/workspace.ts","../src/types/generated/metric.ts","../src/types/generated/pilot_program.ts"],"sourcesContent":["/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: customer_activity\n */\n\n\n/**\n * PHI-free aggregate over ALL rows matching the filters (not a page).\n *\n * Counts, ages in hours, thresholds and identifiers only — no titles, review\n * notes, classifier feedback, subject labels, member data or message content\n * is read or returned.\n */\nexport interface CustomerActivityBacklogSummaryResponse {\n generatedAt: string;\n queryVersion: string;\n filters: CustomerActivitySummaryFilters;\n totalCount: number;\n backlogCount: number;\n reviewedCount: number;\n unclassifiedCount?: number;\n oldestBacklogCreatedAt?: string | null;\n oldestBacklogAgeHours?: number | null;\n byStatus: CustomerActivityStatusBucket[];\n bySeverity: CustomerActivitySeverityBucket[];\n bySource: CustomerActivitySourceBucket[];\n throughput: CustomerActivityThroughputWindow[];\n sla: CustomerActivitySlaSummary;\n}\n\nexport interface CustomerActivityClassifierDefinitionResponse {\n detectorName: CustomerActivityClassifierDetectorName;\n subjectType: string;\n labels: CustomerActivityClassifierLabel[];\n}\n\nexport type CustomerActivityClassifierDetectorName = typeof CustomerActivityClassifierDetectorName[keyof typeof CustomerActivityClassifierDetectorName];\n\n\nexport const CustomerActivityClassifierDetectorName = {\n assignment_chat_classifier: 'assignment_chat_classifier',\n manager_chat_classifier: 'manager_chat_classifier',\n concierge_chat_classifier: 'concierge_chat_classifier',\n chat_review: 'chat_review',\n} as const;\n\nexport type CustomerActivityClassifierLabel = typeof CustomerActivityClassifierLabel[keyof typeof CustomerActivityClassifierLabel];\n\n\nexport const CustomerActivityClassifierLabel = {\n user_distress: 'user_distress',\n user_confusion: 'user_confusion',\n health_topic_mentioned: 'health_topic_mentioned',\n health_advice_given: 'health_advice_given',\n escalation_failure: 'escalation_failure',\n repeated_tool_failure: 'repeated_tool_failure',\n transcription_quality: 'transcription_quality',\n repetitive_loop: 'repetitive_loop',\n manager_no_response: 'manager_no_response',\n docs_or_skill_gap: 'docs_or_skill_gap',\n discovery_thrash: 'discovery_thrash',\n} as const;\n\nexport interface CustomerActivityClassifiersResponse {\n assignmentChatClassifier: CustomerActivityClassifierDefinitionResponse;\n managerChatClassifier: CustomerActivityClassifierDefinitionResponse;\n conciergeChatClassifier: CustomerActivityClassifierDefinitionResponse;\n}\n\nexport interface CustomerActivityEventListResponse {\n items: CustomerActivityEventResponse[];\n total: number;\n page: number;\n pageSize: number;\n totalPages: number;\n}\n\n/**\n * Admin/operator view of one customer-activity event.\n *\n * The list response remains free of operator-authored text. The single-event\n * detail response may include ``reviewNote`` and ``classifierFeedback`` for the\n * internal review workflow.\n */\nexport interface CustomerActivityEventResponse {\n id: number;\n uuid: string;\n accountId?: number | null;\n accountName?: string | null;\n organizationId?: number | null;\n organizationName?: string | null;\n workspaceId?: number | null;\n workspaceName?: string | null;\n subjectType: string;\n subjectRef: string;\n title?: string | null;\n labels: string[];\n severity: CustomerActivitySeverity;\n confidence?: number | null;\n score?: number | null;\n source: CustomerActivityEventSource;\n dedupeKey?: string | null;\n detectorName?: CustomerActivityClassifierDetectorName | null;\n detectorVersion?: string | null;\n modelId?: string | null;\n promptVersion?: string | null;\n status: CustomerActivityEventStatus;\n reviewOutcome?: CustomerActivityReviewOutcome | null;\n reviewNote?: string | null;\n classifierFeedback?: CustomerActivityEventResponseClassifierFeedback;\n linkUrl?: string | null;\n reviewedByAccountId?: number | null;\n reviewedByName?: string | null;\n reviewedAt?: string | null;\n supportRequestId?: number | null;\n resourceId?: number | null;\n workspaceUuid?: string | null;\n chatClassifierPrompt?: string | null;\n subjectTitle?: string | null;\n subjectSubtitle?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type CustomerActivityEventResponseClassifierFeedback = { [key: string]: unknown } | null;\n\nexport type CustomerActivityEventSource = typeof CustomerActivityEventSource[keyof typeof CustomerActivityEventSource];\n\n\nexport const CustomerActivityEventSource = {\n system: 'system',\n customer: 'customer',\n classifier: 'classifier',\n operator: 'operator',\n} as const;\n\nexport type CustomerActivityEventStatus = typeof CustomerActivityEventStatus[keyof typeof CustomerActivityEventStatus];\n\n\nexport const CustomerActivityEventStatus = {\n new: 'new',\n reviewed: 'reviewed',\n} as const;\n\nexport type CustomerActivityReviewOutcome = typeof CustomerActivityReviewOutcome[keyof typeof CustomerActivityReviewOutcome];\n\n\nexport const CustomerActivityReviewOutcome = {\n no_action_needed: 'no_action_needed',\n support_request_created: 'support_request_created',\n bug_filed: 'bug_filed',\n linked_existing_work: 'linked_existing_work',\n classifier_feedback: 'classifier_feedback',\n test_activity: 'test_activity',\n} as const;\n\nexport type CustomerActivitySeverity = typeof CustomerActivitySeverity[keyof typeof CustomerActivitySeverity];\n\n\nexport const CustomerActivitySeverity = {\n none: 'none',\n minimal: 'minimal',\n low: 'low',\n medium: 'medium',\n high: 'high',\n critical: 'critical',\n} as const;\n\nexport interface CustomerActivitySeverityBucket {\n severity: CustomerActivitySeverity;\n backlogCount: number;\n reviewedCount: number;\n oldestBacklogAgeHours?: number | null;\n}\n\n/**\n * Open (unreviewed) events at one severity past their review threshold.\n *\n * ``thresholdSource`` travels with the threshold it describes: a breach count\n * must never be readable without both the number that produced it and whether\n * that number is ratified policy or a provisional default.\n */\nexport interface CustomerActivitySlaBucket {\n severity: CustomerActivitySeverity;\n thresholdHours: number;\n thresholdSource: CustomerActivitySlaThresholdSource;\n breachCount: number;\n oldestBacklogAgeHours?: number | null;\n}\n\nexport interface CustomerActivitySlaSummary {\n buckets: CustomerActivitySlaBucket[];\n totalBreachCount: number;\n}\n\n/**\n * Where ONE severity's SLA threshold came from.\n *\n * ``default`` = the provisional in-repo default (see\n * ``lib/services/customer_activity_metrics.py``); ``request`` = the caller\n * supplied it. Tracked per severity rather than per response so that\n * overriding one threshold cannot make the other read as caller-supplied\n * policy when it is still an unratified default.\n */\nexport type CustomerActivitySlaThresholdSource = typeof CustomerActivitySlaThresholdSource[keyof typeof CustomerActivitySlaThresholdSource];\n\n\nexport const CustomerActivitySlaThresholdSource = {\n default: 'default',\n request: 'request',\n} as const;\n\nexport interface CustomerActivitySourceBucket {\n source: CustomerActivityEventSource;\n backlogCount: number;\n reviewedCount: number;\n}\n\nexport interface CustomerActivityStatusBucket {\n status: CustomerActivityEventStatus;\n count: number;\n}\n\n/**\n * Echo of the filters the aggregate was computed under.\n *\n * Identifiers, closed-vocabulary enums and the open-vocabulary\n * ``subjectType`` only — so an exported aggregate carries its own scope and\n * can never be mistaken for a whole-queue figure.\n */\nexport interface CustomerActivitySummaryFilters {\n status?: CustomerActivityEventStatus | null;\n subjectType?: string | null;\n source?: CustomerActivityEventSource | null;\n severity?: CustomerActivitySeverity | null;\n reviewOutcome?: CustomerActivityReviewOutcome | null;\n detectorName?: CustomerActivityClassifierDetectorName | null;\n workspaceId?: number | null;\n organizationId?: number | null;\n accountId?: number | null;\n}\n\n/**\n * Adjudication throughput over a trailing window.\n *\n * ``recordedCount`` counts events created in the window; ``reviewedCount``\n * counts events whose review verdict was recorded in it (``reviewed_at``).\n * Reopening an event clears ``reviewed_at``, so the pair reads as \"arrived vs\n * currently-adjudicated\", and arrival outpacing adjudication is exactly the\n * growing-backlog signal.\n */\nexport interface CustomerActivityThroughputWindow {\n windowHours: number;\n recordedCount: number;\n reviewedCount: number;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: phi_posture\n */\n\nimport type { DeclaredDataUse } from './organization';\nimport type { PhiDataPolicy, PhiPostureDecision, PhiPostureReasonCode } from './workspace';\n\nexport type PhiPolicyReason = typeof PhiPolicyReason[keyof typeof PhiPolicyReason];\n\n\nexport const PhiPolicyReason = {\n initial_classification: 'initial_classification',\n customer_confirmation: 'customer_confirmation',\n agreement_verified: 'agreement_verified',\n scope_change: 'scope_change',\n periodic_review: 'periodic_review',\n correction: 'correction',\n incident_response: 'incident_response',\n} as const;\n\nexport type PhiPolicySource = typeof PhiPolicySource[keyof typeof PhiPolicySource];\n\n\nexport const PhiPolicySource = {\n customer_attestation: 'customer_attestation',\n contract_review: 'contract_review',\n staff_review: 'staff_review',\n legacy_inventory: 'legacy_inventory',\n} as const;\n\nexport interface PhiPostureFinding {\n reasonCode: PhiPostureReasonCode;\n organizationId: number;\n workspaceId?: number | null;\n workspaceUuid?: string | null;\n decision: PhiPostureDecision;\n}\n\nexport interface PhiPostureReportResponse {\n generatedAt: string;\n organizationCount: number;\n workspaceCount: number;\n findingCount: number;\n offset: number;\n limit: number;\n nextOffset?: number | null;\n findings: PhiPostureFinding[];\n truncated: boolean;\n}\n\nexport interface PhiPostureTransitionResponse {\n targetType: PhiPostureTransitionResponseTargetType;\n organizationId: number;\n workspaceId?: number | null;\n workspaceUuid?: string | null;\n declaredDataUse?: DeclaredDataUse | null;\n phiDataPolicy?: PhiDataPolicy | null;\n decision?: PhiPostureDecision | null;\n reasonCode?: PhiPostureReasonCode | null;\n policyVersion: string;\n source: string;\n reason: string;\n reviewedAt: string;\n reviewedByAccountId: number;\n reviewDueAt: string;\n}\n\nexport type PhiPostureTransitionResponseTargetType = typeof PhiPostureTransitionResponseTargetType[keyof typeof PhiPostureTransitionResponseTargetType];\n\n\nexport const PhiPostureTransitionResponseTargetType = {\n organization: 'organization',\n workspace: 'workspace',\n} as const;\n\nexport interface UpdateOrganizationPhiPostureRequest {\n /**\n * @minLength 1\n * @maxLength 64\n */\n policyVersion: string;\n source: PhiPolicySource;\n reason: PhiPolicyReason;\n reviewDueAt: string;\n declaredDataUse: DeclaredDataUse;\n}\n\nexport interface UpdateWorkspacePhiPolicyRequest {\n /**\n * @minLength 1\n * @maxLength 64\n */\n policyVersion: string;\n source: PhiPolicySource;\n reason: PhiPolicyReason;\n reviewDueAt: string;\n phiDataPolicy: PhiDataPolicy;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: workspace\n */\n\nimport type { Query } from './ir';\n\n/**\n * Admin request to create a user's membership in a workspace.\n */\nexport interface AdminCreateWorkspaceMemberRequest {\n memberRoleId?: number | null;\n}\n\n/**\n * Request model for admin workspace operations.\n */\nexport interface AdminCreateWorkspaceRequest {\n organizationId: number;\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n resellerId?: number | null;\n templateWorkspaceUuid?: string | null;\n locale?: string | null;\n features?: string[] | null;\n chatClassifierPrompt?: string | null;\n subscriptionProductId?: number | null;\n}\n\n/**\n * Admin request to map a site to a workspace.\n */\nexport interface AdminMapSiteRequest {\n workspaceId?: number | null;\n siteUuid: string;\n name?: string | null;\n siteSlug?: string | null;\n externalDomain?: string | null;\n ownerId?: number | null;\n allowSignup?: boolean;\n}\n\n/**\n * Response model for site mappings.\n */\nexport interface AdminSiteMappingResponse {\n id: number;\n siteId: number;\n siteUuid: string;\n siteName: string;\n siteSlug: string;\n externalDomain?: string | null;\n workspaceId: number;\n workspaceUuid: string;\n workspaceName: string;\n workspaceSlug: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Admin request to update a user's membership in a workspace.\n */\nexport interface AdminUpdateWorkspaceMemberRequest {\n tosAccepted?: boolean | null;\n memberRoleId?: number | null;\n}\n\n/**\n * Request model for admin workspace operations.\n */\nexport interface AdminUpdateWorkspaceRequest {\n organizationId?: number | null;\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n resellerId?: number | null;\n creatorId?: number | null;\n features?: string[] | null;\n featuresOverride?: AdminUpdateWorkspaceRequestFeaturesOverride;\n themes?: string[] | null;\n locale?: string | null;\n timezone?: string | null;\n chatClassifierPrompt?: string | null;\n}\n\nexport type AdminUpdateWorkspaceRequestFeaturesOverride = {[key: string]: boolean} | null;\n\nexport interface AdminWorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n organizationId: number;\n organizationUuid?: string | null;\n organizationName?: string | null;\n organizationLogoUrl?: string | null;\n signupCode?: string | null;\n createdAt: string;\n userRole: string | null;\n isPublic?: boolean;\n allowSignup?: boolean;\n resellerId?: number | null;\n themes?: string[];\n features?: string[] | null;\n featureStatus?: AdminWorkspaceResponseFeatureStatus;\n signupRequestStatus?: string | null;\n status?: number | null;\n locale?: string | null;\n timezone?: string | null;\n creatorId?: number | null;\n creatorName?: string | null;\n dbId?: number | null;\n featuresOverride?: AdminWorkspaceResponseFeaturesOverride;\n billingOwnerId?: number | null;\n billingOwnerName?: string | null;\n subscriptionProductId?: number | null;\n subscriptionProductName?: string | null;\n chatClassifierPrompt?: string | null;\n phiDataPolicy?: PhiDataPolicy;\n phiPostureDecision?: PhiPostureDecision;\n phiPostureReasonCode?: PhiPostureReasonCode;\n phiPolicyVersion?: string | null;\n phiPolicySource?: string | null;\n phiPolicyReason?: string | null;\n phiPolicyReviewedAt?: string | null;\n phiPolicyReviewedByAccountId?: number | null;\n phiPolicyReviewDueAt?: string | null;\n}\n\nexport type AdminWorkspaceResponseFeatureStatus = {[key: string]: string} | null;\n\nexport type AdminWorkspaceResponseFeaturesOverride = {[key: string]: boolean} | null;\n\nexport interface BusinessHoursStatusResponse {\n isBusinessHours: boolean;\n}\n\n/**\n * Typed body for the CLI-facing ``change-org`` / ``change-org/preview``\n * admin endpoints.\n *\n * Typing ``targetOrganizationId`` / ``newCreatorId`` as ``int`` makes FastAPI\n * return 422 on a non-numeric body field instead of letting a string value\n * reach the DB driver. Mirrors the superuser\n * ``WorkspaceMigrationRequest`` model used by the sibling\n * ``POST /admin/org-migration/workspace`` endpoint.\n */\nexport interface ChangeWorkspaceOrgRequest {\n /**\n * ID of the target organization\n * @exclusiveMinimum 0\n */\n targetOrganizationId: number;\n /**\n * Account ID to set as the workspace creator (created or promoted to OWNER in the target org)\n * @exclusiveMinimum 0\n */\n newCreatorId: number;\n}\n\nexport interface ClassifyPhoneResponse {\n phoneType?: string | null;\n}\n\nexport interface CostInfo {\n score: number;\n budget: number;\n}\n\n/**\n * Request model for associating data records with assignments.\n */\nexport interface DataRecordAssociationRequest {\n id: number;\n accessMode?: number;\n}\n\nexport interface DeleteMembershipResponse {\n message: string;\n}\n\nexport interface DeleteWorkspaceResponse {\n status: string;\n}\n\nexport interface FirstRunState {\n mode?: string;\n statuses?: FirstRunStateStatuses;\n collapsed?: boolean | null;\n}\n\nexport type FirstRunStateStatuses = {[key: string]: string} | null;\n\n/**\n * Create request for org-scoped workspace creation.\n *\n * Only allows fields appropriate for org admins.\n * Does NOT allow: resellerId, features, featuresOverride, isPublic, allowSignup.\n */\nexport interface OrgCreateWorkspaceRequest {\n name: string;\n slug?: string | null;\n templateWorkspaceUuid?: string | null;\n productId: number;\n planPeriod?: string;\n}\n\n/**\n * Request to join a workspace as an org admin.\n */\nexport interface OrgJoinWorkspaceRequest {\n memberRoleId: number;\n}\n\n/**\n * Response after joining a workspace.\n */\nexport interface OrgJoinWorkspaceResponse {\n memberId: number;\n memberRoleId: number;\n message: string;\n}\n\n/**\n * Organization settings an **org admin** may change.\n *\n * Deliberately a separate model from :class:`UpdateOrganizationRequest`\n * rather than a subset enforced at the route: the privileged fields —\n * ``primary`` and ``enforceCreditLimit`` — are *absent from the schema*, so\n * an org admin cannot set them even by crafting the request body. Pydantic\n * ignores unknown keys, and there is no code path from here to those\n * columns.\n *\n * Both remain superuser-only, on ``PUT /api/v2/admin/organizations/{id}``\n * behind ``Depends(get_superuser)``:\n *\n * - ``primary`` designates the platform's own organization.\n * - ``enforceCreditLimit`` decides whether a customer is hard-blocked (402)\n * at zero credits or merely alerted, i.e. whether they can keep spending.\n *\n * SSO is not here either — it has its own admin-scoped endpoint\n * (``PUT /api/v2/o/{org_uuid}/sso``) with its own audit trail.\n */\nexport interface OrgSettingsUpdateRequest {\n name?: string | null;\n slug?: string | null;\n contactEmail?: string | null;\n contactPhone?: string | null;\n logoUrl?: string | null;\n}\n\n/**\n * Update request for org-scoped workspace updates.\n *\n * Only allows fields that org admins should be able to change.\n * Does NOT allow: features, featuresOverride, organizationId, resellerId,\n * creatorId, themes.\n */\nexport interface OrgUpdateWorkspaceRequest {\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n locale?: string | null;\n timezone?: string | null;\n}\n\n/**\n * Workspace response for org context.\n *\n * Similar to AdminWorkspaceResponse but without superuser-only fields\n * like dbId, featuresOverride, billingOwnerId, etc.\n */\nexport interface OrgWorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n organizationId: number;\n organizationUuid?: string | null;\n organizationName?: string | null;\n signupCode?: string | null;\n createdAt: string;\n isPublic?: boolean;\n allowSignup?: boolean;\n resellerId?: number | null;\n status: number;\n features?: string[] | null;\n featureStatus?: OrgWorkspaceResponseFeatureStatus;\n creatorId?: number | null;\n creatorName?: string | null;\n locale?: string | null;\n timezone?: string | null;\n isMember?: boolean;\n}\n\nexport type OrgWorkspaceResponseFeatureStatus = {[key: string]: string} | null;\n\n/**\n * One workspace card's expensive half: workspace-schema aggregates.\n *\n * ``myRoleName`` is about the requesting account and is returned to any org\n * member who belongs to the workspace. The counts are org-administrative\n * information and are populated only for ``org:read`` holders; everyone else\n * gets ``None`` (rendered as \"—\" rather than zero, so the UI never implies\n * an empty workspace when it simply may not look).\n *\n * ``schemaReady`` is False while the workspace is still provisioning — its\n * tables do not exist yet, so the counts are absent for a reason the card\n * can explain instead of showing a failure.\n */\nexport interface OrgWorkspaceStatsResponse {\n workspaceUuid: string;\n /** False while the workspace is still provisioning, or when its schema could not be read. The counts are absent in that case. */\n schemaReady?: boolean;\n /** The REQUESTING account's member-role name in this workspace. Null when they have no member row there. */\n myRoleName?: string | null;\n /** Non-archived members in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n memberCount?: number | null;\n /** Published and draft sites in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n siteCount?: number | null;\n /** Email inboxes in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n inboxCount?: number | null;\n /** Non-archived phone numbers in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n phoneNumberCount?: number | null;\n}\n\n/**\n * One workspace card's cheap half: identity plus a GLB-side count.\n *\n * ``orgMemberCount`` joins workspace membership to org membership. A separate\n * \"all accounts\" tally was tried and dropped: the\n * ``enforce_org_membership_before_workspace`` trigger refuses a workspace\n * membership for an account with no org membership, so the two numbers are\n * equal except in the transient state after an org membership is revoked —\n * a distinction no card was showing.\n */\nexport interface OrgWorkspaceSummaryResponse {\n uuid: string;\n name: string;\n slug: string;\n /** WorkspaceProvisionStatus. 2 = AVAILABLE; anything else means the workspace is still being provisioned. */\n status: number;\n createdAt: string;\n isPublic?: boolean;\n allowSignup?: boolean;\n /** Whether the requesting account has a workspace membership here. */\n isMember?: boolean;\n /** Accounts with access to this workspace who are also members of this organization. */\n orgMemberCount?: number;\n}\n\nexport type PhiDataPolicy = typeof PhiDataPolicy[keyof typeof PhiDataPolicy];\n\n\nexport const PhiDataPolicy = {\n unclassified: 'unclassified',\n phi_prohibited: 'phi_prohibited',\n phi_permitted: 'phi_permitted',\n} as const;\n\nexport type PhiPostureDecision = typeof PhiPostureDecision[keyof typeof PhiPostureDecision];\n\n\nexport const PhiPostureDecision = {\n allow_non_phi: 'allow_non_phi',\n warn_non_phi: 'warn_non_phi',\n review_required: 'review_required',\n authorization_required: 'authorization_required',\n conflict: 'conflict',\n} as const;\n\nexport type PhiPostureReasonCode = typeof PhiPostureReasonCode[keyof typeof PhiPostureReasonCode];\n\n\nexport const PhiPostureReasonCode = {\n org_unclassified: 'org_unclassified',\n workspace_unclassified: 'workspace_unclassified',\n non_phi_policy_aligned: 'non_phi_policy_aligned',\n phi_expected_workspace_prohibited: 'phi_expected_workspace_prohibited',\n phi_authorization_not_evaluated: 'phi_authorization_not_evaluated',\n phi_coverage_satisfied: 'phi_coverage_satisfied',\n phi_coverage_missing: 'phi_coverage_missing',\n phi_coverage_expired: 'phi_coverage_expired',\n non_phi_org_workspace_permitted: 'non_phi_org_workspace_permitted',\n phi_permitted_org_not_expected: 'phi_permitted_org_not_expected',\n organization_review_expired: 'organization_review_expired',\n workspace_review_expired: 'workspace_review_expired',\n invalid_state: 'invalid_state',\n} as const;\n\nexport interface PublicWorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n createdAt: string;\n allowSignup?: boolean;\n resellerId?: number | null;\n memberRole?: string | null;\n signupRequestStatus?: string | null;\n}\n\nexport interface QueryDataTypeInfo {\n id: number;\n slug: string;\n name: string;\n isCollection: boolean;\n recordFields: RecordFieldInfo[];\n}\n\n/**\n * A labeled choice for a field whose raw values are ids/codes.\n */\nexport interface QueryEnumOption {\n value: unknown;\n label: string;\n color?: string | null;\n}\n\nexport interface QueryFieldInfo {\n path: string;\n type: string;\n operators: string[];\n sortable?: boolean;\n selectable?: boolean;\n enumValues?: unknown[] | null;\n enumOptions?: QueryEnumOption[] | null;\n displayName?: string | null;\n category?: string | null;\n}\n\nexport interface QueryFieldsResponse {\n entities: QueryFieldsResponseEntities;\n aggregateSources: QueryFieldsResponseAggregateSources;\n dataTypes: QueryDataTypeInfo[];\n recordSystemFields: QueryFieldInfo[];\n relations?: QueryFieldsResponseRelations;\n aggregateSourceCategories?: QueryFieldsResponseAggregateSourceCategories;\n}\n\nexport type QueryFieldsResponseAggregateSourceCategories = {[key: string]: {[key: string]: string}};\n\nexport type QueryFieldsResponseAggregateSources = {[key: string]: string[]};\n\nexport type QueryFieldsResponseEntities = {[key: string]: QueryFieldInfo[]};\n\nexport type QueryFieldsResponseRelations = {[key: string]: {[key: string]: QueryFieldInfo[]}};\n\nexport interface RecordFieldInfo {\n slug: string;\n name: string;\n type: string;\n operators: string[];\n enumValues?: unknown[] | null;\n}\n\nexport interface RunQueryRequest {\n query: Query;\n mode?: RunQueryRequestMode;\n}\n\nexport type RunQueryRequestMode = typeof RunQueryRequestMode[keyof typeof RunQueryRequestMode] | null;\n\n\nexport const RunQueryRequestMode = {\n rows: 'rows',\n count: 'count',\n aggregate: 'aggregate',\n} as const;\n\nexport interface RunQueryResponse {\n mode: string;\n items?: RunQueryResponseItems;\n nextCursor?: string | null;\n count?: number | null;\n rows?: RunQueryResponseRows;\n warnings?: string[];\n cost?: CostInfo | null;\n}\n\nexport type RunQueryResponseItems = { [key: string]: unknown }[] | null;\n\nexport type RunQueryResponseRows = { [key: string]: unknown }[] | null;\n\n/**\n * Request model for associating child tasks (parent-child relationships).\n *\n * ``order`` is optional and backward-compatible: when omitted, callers\n * that build associations from a UI-style ``childTasks`` list keep the\n * historical array-index ordering. When provided (e.g. by the workspace\n * transfer importer), it preserves the authored routing order so that\n * automatic routing still selects the lower-order matching child after\n * transfer.\n */\nexport interface TaskAssociationRequest {\n taskId: number;\n autoNext: boolean;\n required: boolean;\n choicePrompt?: string | null;\n celCondition?: string | null;\n order?: number | null;\n}\n\n/**\n * Update workspace defaults.\n */\nexport interface UpdateWorkspaceDefaultsRequest {\n defaultPhoneNumberId?: number | null;\n defaultAgentId?: number | null;\n escalationBusinessHours?: string | null;\n escalationOnlineMessageTemplate?: string | null;\n escalationOfflineMessageTemplate?: string | null;\n escalationNotifiedMessageTemplate?: string | null;\n escalationPausedMessageTemplate?: string | null;\n emailFooter?: string | null;\n pauseOnEscalate?: boolean | null;\n enableAudioRecording?: boolean | null;\n enableVoicemailDetection?: boolean | null;\n shortenUrls?: boolean | null;\n transcriptionModel?: string | null;\n}\n\n/**\n * Update a workspace.\n */\nexport interface UpdateWorkspaceRequest {\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n locale?: string | null;\n timezone?: string | null;\n}\n\nexport interface ValidateQueryResponse {\n valid: boolean;\n cost: CostInfo;\n warnings?: string[];\n errors?: string[];\n}\n\n/**\n * Slim view of an OrgDomain for selection in workspace forms.\n *\n * Intentionally smaller than `OrgDomainResponse` — workspace members\n * don't need ownership tokens, DNS records, last-checked timestamps,\n * etc. Just enough to populate a dropdown, pass the uuid back as a\n * foreign reference (e.g. `orgDomainUuid` on inbox creation), and\n * let the UI mark non-verified entries as disabled with a reason.\n */\nexport interface WorkspaceAvailableDomain {\n uuid: string;\n domain: string;\n ownershipStatus: string;\n emailStatus?: string | null;\n siteStatus?: string | null;\n}\n\nexport interface WorkspaceAvailableDomainsResponse {\n items: WorkspaceAvailableDomain[];\n total: number;\n}\n\n/**\n * Response model for workspace counts.\n */\nexport interface WorkspaceCountsResponse {\n humans: number;\n agents: number;\n tasks: number;\n workflows: number;\n inboxes: number;\n phoneNumbers: number;\n chats: number;\n files: number;\n sites: number;\n forms: number;\n}\n\n/**\n * Request model for joining a workspace.\n */\nexport interface WorkspaceJoinRequest {\n memberRoleId: number;\n orgRole?: string | null;\n}\n\n/**\n * Response model for joining a workspace.\n */\nexport interface WorkspaceJoinResponse {\n success: boolean;\n memberUuid: string;\n memberId: number;\n workspaceUuid: string;\n workspaceName: string;\n memberRoleName: string;\n message: string;\n}\n\nexport interface WorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n organizationId: number;\n organizationUuid?: string | null;\n organizationName?: string | null;\n organizationLogoUrl?: string | null;\n signupCode?: string | null;\n createdAt: string;\n userRole: string | null;\n isPublic?: boolean;\n allowSignup?: boolean;\n resellerId?: number | null;\n themes?: string[];\n features?: string[] | null;\n featureStatus?: WorkspaceResponseFeatureStatus;\n signupRequestStatus?: string | null;\n status?: number | null;\n locale?: string | null;\n timezone?: string | null;\n}\n\nexport type WorkspaceResponseFeatureStatus = {[key: string]: string} | null;\n\n/**\n * Individual scope metadata.\n */\nexport interface WorkspaceScopeResponse {\n name: string;\n category: string;\n description: string;\n implies?: string[];\n dangerous?: boolean;\n}\n\n/**\n * Response containing all workspace-grantable scopes.\n */\nexport interface WorkspaceScopesListResponse {\n items: WorkspaceScopeResponse[];\n categories: string[];\n}\n\nexport interface WorkspaceSettingsResponse {\n id: number;\n slug: string;\n defaultPhoneNumberId: number | null;\n defaultAgentId: number | null;\n workspaceFolderId?: number | null;\n escalationBusinessHours: string | null;\n escalationOnlineMessageTemplate: string | null;\n escalationOfflineMessageTemplate: string | null;\n escalationNotifiedMessageTemplate: string | null;\n escalationPausedMessageTemplate: string | null;\n emailFooter: string | null;\n pauseOnEscalate: boolean;\n sesDomain: string;\n enableAudioRecording: boolean;\n enableVoicemailDetection: boolean;\n shortenUrls: boolean;\n shortenUrlsExampleUrl: string;\n shortenUrlsAvailable: boolean;\n transcriptionModel?: string | null;\n defaultChatModel: string;\n defaultRealtimeModel: string;\n defaultInferenceModel: string;\n defaultVoiceModel: string;\n firstRunMode?: string | null;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: metric\n */\n\n\n/**\n * On-demand compute of enabled chat-source metrics for one chat.\n */\nexport interface ComputeChatMetricsRequest {\n /**\n * Chat id to evaluate\n * @minimum 1\n */\n chatId: number;\n}\n\n/**\n * Result of an on-demand chat metrics compute.\n */\nexport interface ComputeChatMetricsResponse {\n chatId: number;\n observationCount: number;\n}\n\n/**\n * Create a workspace metric definition.\n */\nexport interface CreateMetricRequest {\n /**\n * @minLength 1\n * @maxLength 255\n */\n name: string;\n /** Stable identifier; auto-derived from name when omitted. */\n slug?: string | null;\n description?: string | null;\n metricType: MetricType;\n source?: MetricSource;\n kind?: MetricKind;\n unit?: MetricUnit;\n celExpression?: string | null;\n evaluationPrompt?: string | null;\n /**\n * @minimum 0\n * @maximum 1\n */\n passingThreshold?: number;\n sourceConfig?: MetricSourceConfig | null;\n denominator?: MetricDenominator;\n attributionWindowSeconds?: number | null;\n enabled?: boolean;\n chatType?: MetricChatType;\n /** Workflows this chat metric measures. Required for chat metrics — pass [] to mean every workflow, deliberately. Omitting it is an error, so a scope is never chosen by accident. */\n workflowIds?: number[] | null;\n /** Optional goal for this metric — 'reach this value'. */\n targetValue?: number | null;\n /** Optional due date for targetValue. */\n targetDate?: string | null;\n}\n\n/**\n * Which conversation surface a chat metric measures.\n *\n * One metric measures one surface, deliberately. An assignment chat, a\n * sidebar DM and a contributor-input chat are different populations with\n * different success conditions; averaging them yields a number that\n * describes nothing. Want resolution rate for DMs too? That is a second\n * metric, and the two are legitimately comparable side by side.\n *\n * ``manager`` is absent on purpose — workspace-management chats are the\n * operator talking to the product, never a customer outcome.\n */\nexport type MetricChatType = typeof MetricChatType[keyof typeof MetricChatType];\n\n\nexport const MetricChatType = {\n assignment: 'assignment',\n dm: 'dm',\n contributor: 'contributor',\n} as const;\n\n/**\n * Explicit rate denominator — stored on the definition, not a convention.\n *\n * Read it as \"count once per\": what the rate divides by.\n *\n * * ``OBSERVATIONS`` — each observation counts once. For every metric\n * that can exist today that is one per conversation, because a\n * conversation yields exactly one observation.\n * * ``UNIQUE_MEMBERS`` — each Member counts once no matter how many\n * chats they had in the window. Required by pilot agreements written\n * as \"unique clients who respond… multiple responses from the same\n * client count as a single engagement\": a member in a multi-touch\n * journey has several chats, so averaging over observations\n * double-counts them and produces a defensible number that is not the\n * number in the contract.\n *\n * There was briefly a third value, ``CHATS``, reserved so a future\n * message-sourced metric could distinguish \"per observation\" (per\n * message) from \"per conversation\". It computed an identical number to\n * ``OBSERVATIONS`` for every metric that can exist today, so it reached\n * the UI as two buttons producing the same result. Reintroduce it with\n * the ``CHAT_MESSAGE`` source (#22474), when the distinction is real.\n */\nexport type MetricDenominator = typeof MetricDenominator[keyof typeof MetricDenominator];\n\n\nexport const MetricDenominator = {\n observations: 'observations',\n unique_members: 'unique_members',\n} as const;\n\n/**\n * Aggregation semantics for stored values.\n *\n * * ``OBSERVATION`` — one row per subject (chat/message/member). Aggregate\n * with avg/sum/count over a window. Must not be last-valued.\n * * ``GAUGE`` — point-in-time count of matching rows. Last-value only;\n * must not be summed across a window. Computed by the ``member_filter``\n * source.\n */\nexport type MetricKind = typeof MetricKind[keyof typeof MetricKind];\n\n\nexport const MetricKind = {\n observation: 'observation',\n gauge: 'gauge',\n} as const;\n\n/**\n * One observation — reason may be PHI; gated by analytics scope.\n */\nexport interface MetricObservationResponse {\n id: number;\n uuid: string;\n metricId: number;\n value: number;\n observedAt: string;\n chatId: number | null;\n memberId: number | null;\n messageId: number | null;\n /** Rubric grader free text — PHI-bearing; omit from aggregate export */\n reason?: string | null;\n modelId?: string | null;\n modelVersion?: string | null;\n evaluationData?: MetricObservationResponseEvaluationData;\n createdAt: string;\n}\n\nexport type MetricObservationResponseEvaluationData = { [key: string]: unknown } | null;\n\n/**\n * API shape for a Metric definition.\n */\nexport interface MetricResponse {\n id: number;\n uuid: string;\n name: string;\n slug: string;\n description: string | null;\n metricType: string;\n source: string;\n kind: string;\n unit: string;\n celExpression: string | null;\n evaluationPrompt: string | null;\n passingThreshold: number;\n sourceConfig: MetricResponseSourceConfig;\n denominator: string;\n attributionWindowSeconds: number | null;\n chatType: string;\n workflowIds: number[];\n targetValue: number | null;\n targetDate: string | null;\n enabled: boolean;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type MetricResponseSourceConfig = { [key: string]: unknown } | null;\n\n/**\n * One time-bucket of aggregated observations.\n */\nexport interface MetricSeriesBucket {\n bucketStart: string;\n value: number | null;\n count: number;\n}\n\n/**\n * Time-series readout for a metric.\n */\nexport interface MetricSeriesResponse {\n metricId: number;\n metricUuid: string;\n metricName: string;\n unit: string;\n kind: string;\n denominator: string;\n aggregation: string;\n bucket: string;\n start: string;\n end: string;\n buckets: MetricSeriesBucket[];\n overallValue: number | null;\n overallCount: number;\n targetValue?: number | null;\n targetDate?: string | null;\n}\n\n/**\n * What triggers computation of a metric observation.\n *\n * * ``CHAT`` — rides ``ChatPostProcessingWorkflow`` after a chat goes quiet.\n * * ``MEMBER_FILTER`` — point-in-time count of Members matching a\n * :class:`~lib.models.workspace.member_filter.MemberFilter`. This is the\n * source that subsumed the former ``MilestoneGoal`` (a named target over a\n * Member cohort at a date); ``source_config`` carries\n * ``{\"member_filter_id\": <id>}``.\n *\n * Other sources are reserved for follow-on work.\n */\nexport type MetricSource = typeof MetricSource[keyof typeof MetricSource];\n\n\nexport const MetricSource = {\n chat: 'chat',\n member_filter: 'member_filter',\n} as const;\n\n/**\n * Per-source parameters for a metric definition.\n *\n * Typed rather than a bare ``dict[str, Any]`` because the values are\n * load-bearing at compute time and failure is silent. A chat metric whose\n * ``minMessages`` arrives as ``\"10\"`` was previously ignored outright —\n * ``metric_meets_min_messages`` only honours the key when it is already an\n * ``int`` — so the metric graded conversations the author meant to exclude\n * and nothing said so. ``extra=\"forbid\"`` gives the same treatment to a\n * typo'd key, which used to be stored and quietly do nothing.\n *\n * API keys are camelCase per the naming convention; the persisted JSONB\n * keeps snake_case because that is what ``metric_eval_service`` reads.\n * ``to_storage`` is the only place that translation happens.\n */\nexport interface MetricSourceConfig {\n memberFilterId?: number | null;\n minMessages?: number | null;\n}\n\n/**\n * How a metric value is computed.\n *\n * ``EXPRESSION`` is CEL-evaluated (synchronous, deterministic).\n * ``RUBRIC`` is LLM-evaluated (async, probabilistic). Those two mirror\n * :class:`~lib.models.workspace.qualification.CriterionType`.\n *\n * ``FILTER_COUNT`` has no authored expression at all — the value is the\n * number of rows matching a saved filter named in ``source_config``. It\n * pairs with ``source=member_filter`` + ``kind=gauge`` and is what the\n * retired MilestoneGoal computed.\n */\nexport type MetricType = typeof MetricType[keyof typeof MetricType];\n\n\nexport const MetricType = {\n expression: 'expression',\n rubric: 'rubric',\n filter_count: 'filter_count',\n} as const;\n\n/**\n * Display/aggregation hint for the metric's values.\n */\nexport type MetricUnit = typeof MetricUnit[keyof typeof MetricUnit];\n\n\nexport const MetricUnit = {\n rate: 'rate',\n score: 'score',\n count: 'count',\n custom: 'custom',\n} as const;\n\n/**\n * Partial update of a metric definition.\n *\n * ``metricType`` is immutable after create (same rule as ScenarioCriterion).\n */\nexport interface UpdateMetricRequest {\n name?: string | null;\n description?: string | null;\n unit?: MetricUnit | null;\n celExpression?: string | null;\n evaluationPrompt?: string | null;\n passingThreshold?: number | null;\n sourceConfig?: MetricSourceConfig | null;\n denominator?: MetricDenominator | null;\n attributionWindowSeconds?: number | null;\n enabled?: boolean | null;\n archived?: boolean | null;\n workflowIds?: number[] | null;\n targetValue?: number | null;\n targetDate?: string | null;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: pilot_program\n */\n\n\n/**\n * All pilot-program config rows the operator asked for.\n */\nexport interface PilotProgramListResponse {\n programs: PilotProgramResponse[];\n total: number;\n includesInactive: boolean;\n}\n\n/**\n * One ``pilot_programs`` config row.\n */\nexport interface PilotProgramResponse {\n id: number;\n uuid: string;\n label: string;\n customerId?: number | null;\n coveredWorkspaceIds: number[];\n relationshipType: PilotRelationshipType;\n lifecycleStage: PilotStage;\n stageEnteredAt: string;\n allocationMinutes?: number | null;\n allocationPeriodStart?: string | null;\n notifyThresholdPct: number;\n notifyContactLabel?: string | null;\n stalenessThresholdDays: number;\n active: boolean;\n createdAt?: string | null;\n updatedAt?: string | null;\n}\n\n/**\n * How this pilot relates to us commercially.\n *\n * Drives the staleness read: a ``DIRECT_PILOT`` is healthy when its own\n * workspaces are active; a ``PARTNER_CHANNEL`` (co-sale partner / reseller) is\n * healthy on deal + integration activity even with low own-workspace volume.\n */\nexport type PilotRelationshipType = typeof PilotRelationshipType[keyof typeof PilotRelationshipType];\n\n\nexport const PilotRelationshipType = {\n direct_pilot: 'direct_pilot',\n partner_channel: 'partner_channel',\n} as const;\n\n/**\n * The pilot funnel stage (distinct from the churn-risk\n * ``CustomerHealthLifecycleStage`` in the customer-health read model —\n * that answers \"how healthy?\", this answers \"how far through the pilot?\").\n *\n * ``SIGNED``/``LIVE``/``VALUE_EVIDENCED`` are the in-flight stages a staleness\n * watcher covers; ``ON_HOLD`` is a deliberate pause (never paged on); and\n * ``CONVERTED``/``CHURNED`` are terminal outcomes (no staleness signal).\n */\nexport type PilotStage = typeof PilotStage[keyof typeof PilotStage];\n\n\nexport const PilotStage = {\n signed: 'signed',\n live: 'live',\n value_evidenced: 'value_evidenced',\n converted: 'converted',\n on_hold: 'on_hold',\n churned: 'churned',\n} as const;\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCO,IAAM,yCAAyC;AAAA,EACpD,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,2BAA2B;AAAA,EAC3B,aAAa;AACf;AAKO,IAAM,kCAAkC;AAAA,EAC7C,eAAe;AAAA,EACf,gBAAgB;AAAA,EAChB,wBAAwB;AAAA,EACxB,qBAAqB;AAAA,EACrB,oBAAoB;AAAA,EACpB,uBAAuB;AAAA,EACvB,uBAAuB;AAAA,EACvB,iBAAiB;AAAA,EACjB,qBAAqB;AAAA,EACrB,mBAAmB;AAAA,EACnB,kBAAkB;AACpB;AAoEO,IAAM,8BAA8B;AAAA,EACzC,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,YAAY;AAAA,EACZ,UAAU;AACZ;AAKO,IAAM,8BAA8B;AAAA,EACzC,KAAK;AAAA,EACL,UAAU;AACZ;AAKO,IAAM,gCAAgC;AAAA,EAC3C,kBAAkB;AAAA,EAClB,yBAAyB;AAAA,EACzB,WAAW;AAAA,EACX,sBAAsB;AAAA,EACtB,qBAAqB;AAAA,EACrB,eAAe;AACjB;AAKO,IAAM,2BAA2B;AAAA,EACtC,MAAM;AAAA,EACN,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,UAAU;AACZ;AAyCO,IAAM,qCAAqC;AAAA,EAChD,SAAS;AAAA,EACT,SAAS;AACX;;;ACvMO,IAAM,kBAAkB;AAAA,EAC7B,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,oBAAoB;AAAA,EACpB,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,YAAY;AAAA,EACZ,mBAAmB;AACrB;AAKO,IAAM,kBAAkB;AAAA,EAC7B,sBAAsB;AAAA,EACtB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,kBAAkB;AACpB;AA0CO,IAAM,yCAAyC;AAAA,EACpD,cAAc;AAAA,EACd,WAAW;AACb;;;ACgSO,IAAM,gBAAgB;AAAA,EAC3B,cAAc;AAAA,EACd,gBAAgB;AAAA,EAChB,eAAe;AACjB;AAKO,IAAM,qBAAqB;AAAA,EAChC,eAAe;AAAA,EACf,cAAc;AAAA,EACd,iBAAiB;AAAA,EACjB,wBAAwB;AAAA,EACxB,UAAU;AACZ;AAKO,IAAM,uBAAuB;AAAA,EAClC,kBAAkB;AAAA,EAClB,wBAAwB;AAAA,EACxB,wBAAwB;AAAA,EACxB,mCAAmC;AAAA,EACnC,iCAAiC;AAAA,EACjC,wBAAwB;AAAA,EACxB,sBAAsB;AAAA,EACtB,sBAAsB;AAAA,EACtB,iCAAiC;AAAA,EACjC,gCAAgC;AAAA,EAChC,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,eAAe;AACjB;;;AChUO,IAAM,iBAAiB;AAAA,EAC5B,YAAY;AAAA,EACZ,IAAI;AAAA,EACJ,aAAa;AACf;AA4BO,IAAM,oBAAoB;AAAA,EAC/B,cAAc;AAAA,EACd,gBAAgB;AAClB;AAcO,IAAM,aAAa;AAAA,EACxB,aAAa;AAAA,EACb,OAAO;AACT;AAoGO,IAAM,eAAe;AAAA,EAC1B,MAAM;AAAA,EACN,eAAe;AACjB;AAqCO,IAAM,aAAa;AAAA,EACxB,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,cAAc;AAChB;AAQO,IAAM,aAAa;AAAA,EACxB,MAAM;AAAA,EACN,OAAO;AAAA,EACP,OAAO;AAAA,EACP,QAAQ;AACV;;;AC9OO,IAAM,wBAAwB;AAAA,EACnC,cAAc;AAAA,EACd,iBAAiB;AACnB;AAcO,IAAM,aAAa;AAAA,EACxB,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,iBAAiB;AAAA,EACjB,WAAW;AAAA,EACX,SAAS;AAAA,EACT,SAAS;AACX;","names":[]}
1
+ {"version":3,"sources":["../src/types/generated/addon.ts","../src/types/generated/customer_activity.ts","../src/types/generated/phi_posture.ts","../src/types/generated/workspace.ts","../src/types/generated/metric.ts","../src/types/generated/pilot_program.ts"],"sourcesContent":["/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: addon\n */\n\nimport type { PlanConfig } from './billing';\n\n/**\n * The result of one attach or detach.\n *\n * ``featuresSynced`` is reported rather than assumed: billing is the\n * durable half and the feature reconciliation is repairable, so a failed\n * resync must not roll back a completed purchase — but the client has to be\n * able to tell the difference.\n */\nexport interface AddonMutationResponse {\n productId: number;\n subscriptionItemId: number;\n scope: AddonMutationResponseScope;\n workspaceUuid?: string | null;\n providesFeatures: string[];\n featuresSynced: boolean;\n syncedWorkspaceUuids: string[];\n}\n\nexport type AddonMutationResponseScope = typeof AddonMutationResponseScope[keyof typeof AddonMutationResponseScope];\n\n\nexport const AddonMutationResponseScope = {\n organization: 'organization',\n workspace: 'workspace',\n} as const;\n\n/**\n * Buy one add-on for an organization, optionally scoped to a workspace.\n *\n * ``extra=\"forbid\"`` because this is a billing mutation: a misspelled field\n * that silently does nothing would charge the customer for a scope they did\n * not ask for.\n */\nexport interface AttachAddonRequest {\n /**\n * ID of the add-on product to attach\n * @exclusiveMinimum 0\n */\n productId: number;\n /** Workspace to scope the add-on to. Omit for an organization-wide add-on, which every workspace in the organization inherits. */\n workspaceUuid?: string | null;\n}\n\n/**\n * One add-on in an organization's catalogue, with its attachment state.\n */\nexport interface OrganizationAddonResponse {\n id: number;\n productId: number;\n name: string;\n tagline?: string | null;\n description: string;\n icon?: string | null;\n color?: string | null;\n providesFeatures: string[];\n requiresFeatures: string[];\n plans?: OrganizationAddonResponsePlans;\n priceCents?: number | null;\n /** Whether this add-on can be attached right now: self-service, not archived, and carrying a Stripe price for the organization's billing period. */\n purchasable: boolean;\n attached: boolean;\n scope?: OrganizationAddonResponseScope;\n workspaceUuid?: string | null;\n workspaceName?: string | null;\n subscriptionItemId?: number | null;\n}\n\nexport type OrganizationAddonResponsePlans = {[key: string]: PlanConfig} | null;\n\nexport type OrganizationAddonResponseScope = typeof OrganizationAddonResponseScope[keyof typeof OrganizationAddonResponseScope] | null;\n\n\nexport const OrganizationAddonResponseScope = {\n organization: 'organization',\n workspace: 'workspace',\n} as const;\n\n/**\n * The organization's add-on catalogue and what it currently owns.\n *\n * An ENVELOPE, never a bare list. ``canManage`` is why: it is the only way a\n * client can render a correct read-only state for a member who may see the\n * catalogue but not buy from it. A bare array would force the client to guess\n * at billing privilege and offer an attach button that 403s.\n */\nexport interface OrganizationAddonsResponse {\n organizationUuid: string;\n subscriptionId?: number | null;\n planPeriod?: string | null;\n canManage: boolean;\n canAttach: boolean;\n addons: OrganizationAddonResponse[];\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: customer_activity\n */\n\n\n/**\n * PHI-free aggregate over ALL rows matching the filters (not a page).\n *\n * Counts, ages in hours, thresholds and identifiers only — no titles, review\n * notes, classifier feedback, subject labels, member data or message content\n * is read or returned.\n */\nexport interface CustomerActivityBacklogSummaryResponse {\n generatedAt: string;\n queryVersion: string;\n filters: CustomerActivitySummaryFilters;\n totalCount: number;\n backlogCount: number;\n reviewedCount: number;\n unclassifiedCount?: number;\n oldestBacklogCreatedAt?: string | null;\n oldestBacklogAgeHours?: number | null;\n byStatus: CustomerActivityStatusBucket[];\n bySeverity: CustomerActivitySeverityBucket[];\n bySource: CustomerActivitySourceBucket[];\n throughput: CustomerActivityThroughputWindow[];\n sla: CustomerActivitySlaSummary;\n}\n\nexport interface CustomerActivityClassifierDefinitionResponse {\n detectorName: CustomerActivityClassifierDetectorName;\n subjectType: string;\n labels: CustomerActivityClassifierLabel[];\n}\n\nexport type CustomerActivityClassifierDetectorName = typeof CustomerActivityClassifierDetectorName[keyof typeof CustomerActivityClassifierDetectorName];\n\n\nexport const CustomerActivityClassifierDetectorName = {\n assignment_chat_classifier: 'assignment_chat_classifier',\n manager_chat_classifier: 'manager_chat_classifier',\n concierge_chat_classifier: 'concierge_chat_classifier',\n chat_review: 'chat_review',\n} as const;\n\nexport type CustomerActivityClassifierLabel = typeof CustomerActivityClassifierLabel[keyof typeof CustomerActivityClassifierLabel];\n\n\nexport const CustomerActivityClassifierLabel = {\n user_distress: 'user_distress',\n user_confusion: 'user_confusion',\n health_topic_mentioned: 'health_topic_mentioned',\n health_advice_given: 'health_advice_given',\n escalation_failure: 'escalation_failure',\n repeated_tool_failure: 'repeated_tool_failure',\n transcription_quality: 'transcription_quality',\n repetitive_loop: 'repetitive_loop',\n manager_no_response: 'manager_no_response',\n docs_or_skill_gap: 'docs_or_skill_gap',\n discovery_thrash: 'discovery_thrash',\n} as const;\n\nexport interface CustomerActivityClassifiersResponse {\n assignmentChatClassifier: CustomerActivityClassifierDefinitionResponse;\n managerChatClassifier: CustomerActivityClassifierDefinitionResponse;\n conciergeChatClassifier: CustomerActivityClassifierDefinitionResponse;\n}\n\nexport interface CustomerActivityEventListResponse {\n items: CustomerActivityEventResponse[];\n total: number;\n page: number;\n pageSize: number;\n totalPages: number;\n}\n\n/**\n * Admin/operator view of one customer-activity event.\n *\n * The list response remains free of operator-authored text. The single-event\n * detail response may include ``reviewNote`` and ``classifierFeedback`` for the\n * internal review workflow.\n */\nexport interface CustomerActivityEventResponse {\n id: number;\n uuid: string;\n accountId?: number | null;\n accountName?: string | null;\n organizationId?: number | null;\n organizationName?: string | null;\n workspaceId?: number | null;\n workspaceName?: string | null;\n subjectType: string;\n subjectRef: string;\n title?: string | null;\n labels: string[];\n severity: CustomerActivitySeverity;\n confidence?: number | null;\n score?: number | null;\n source: CustomerActivityEventSource;\n dedupeKey?: string | null;\n detectorName?: CustomerActivityClassifierDetectorName | null;\n detectorVersion?: string | null;\n modelId?: string | null;\n promptVersion?: string | null;\n status: CustomerActivityEventStatus;\n reviewOutcome?: CustomerActivityReviewOutcome | null;\n reviewNote?: string | null;\n classifierFeedback?: CustomerActivityEventResponseClassifierFeedback;\n linkUrl?: string | null;\n reviewedByAccountId?: number | null;\n reviewedByName?: string | null;\n reviewedAt?: string | null;\n supportRequestId?: number | null;\n resourceId?: number | null;\n workspaceUuid?: string | null;\n chatClassifierPrompt?: string | null;\n subjectTitle?: string | null;\n subjectSubtitle?: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type CustomerActivityEventResponseClassifierFeedback = { [key: string]: unknown } | null;\n\nexport type CustomerActivityEventSource = typeof CustomerActivityEventSource[keyof typeof CustomerActivityEventSource];\n\n\nexport const CustomerActivityEventSource = {\n system: 'system',\n customer: 'customer',\n classifier: 'classifier',\n operator: 'operator',\n} as const;\n\nexport type CustomerActivityEventStatus = typeof CustomerActivityEventStatus[keyof typeof CustomerActivityEventStatus];\n\n\nexport const CustomerActivityEventStatus = {\n new: 'new',\n reviewed: 'reviewed',\n} as const;\n\nexport type CustomerActivityReviewOutcome = typeof CustomerActivityReviewOutcome[keyof typeof CustomerActivityReviewOutcome];\n\n\nexport const CustomerActivityReviewOutcome = {\n no_action_needed: 'no_action_needed',\n support_request_created: 'support_request_created',\n bug_filed: 'bug_filed',\n linked_existing_work: 'linked_existing_work',\n classifier_feedback: 'classifier_feedback',\n test_activity: 'test_activity',\n} as const;\n\nexport type CustomerActivitySeverity = typeof CustomerActivitySeverity[keyof typeof CustomerActivitySeverity];\n\n\nexport const CustomerActivitySeverity = {\n none: 'none',\n minimal: 'minimal',\n low: 'low',\n medium: 'medium',\n high: 'high',\n critical: 'critical',\n} as const;\n\nexport interface CustomerActivitySeverityBucket {\n severity: CustomerActivitySeverity;\n backlogCount: number;\n reviewedCount: number;\n oldestBacklogAgeHours?: number | null;\n}\n\n/**\n * Open (unreviewed) events at one severity past their review threshold.\n *\n * ``thresholdSource`` travels with the threshold it describes: a breach count\n * must never be readable without both the number that produced it and whether\n * that number is ratified policy or a provisional default.\n */\nexport interface CustomerActivitySlaBucket {\n severity: CustomerActivitySeverity;\n thresholdHours: number;\n thresholdSource: CustomerActivitySlaThresholdSource;\n breachCount: number;\n oldestBacklogAgeHours?: number | null;\n}\n\nexport interface CustomerActivitySlaSummary {\n buckets: CustomerActivitySlaBucket[];\n totalBreachCount: number;\n}\n\n/**\n * Where ONE severity's SLA threshold came from.\n *\n * ``default`` = the provisional in-repo default (see\n * ``lib/services/customer_activity_metrics.py``); ``request`` = the caller\n * supplied it. Tracked per severity rather than per response so that\n * overriding one threshold cannot make the other read as caller-supplied\n * policy when it is still an unratified default.\n */\nexport type CustomerActivitySlaThresholdSource = typeof CustomerActivitySlaThresholdSource[keyof typeof CustomerActivitySlaThresholdSource];\n\n\nexport const CustomerActivitySlaThresholdSource = {\n default: 'default',\n request: 'request',\n} as const;\n\nexport interface CustomerActivitySourceBucket {\n source: CustomerActivityEventSource;\n backlogCount: number;\n reviewedCount: number;\n}\n\nexport interface CustomerActivityStatusBucket {\n status: CustomerActivityEventStatus;\n count: number;\n}\n\n/**\n * Echo of the filters the aggregate was computed under.\n *\n * Identifiers, closed-vocabulary enums and the open-vocabulary\n * ``subjectType`` only — so an exported aggregate carries its own scope and\n * can never be mistaken for a whole-queue figure.\n */\nexport interface CustomerActivitySummaryFilters {\n status?: CustomerActivityEventStatus | null;\n subjectType?: string | null;\n source?: CustomerActivityEventSource | null;\n severity?: CustomerActivitySeverity | null;\n reviewOutcome?: CustomerActivityReviewOutcome | null;\n detectorName?: CustomerActivityClassifierDetectorName | null;\n workspaceId?: number | null;\n organizationId?: number | null;\n accountId?: number | null;\n}\n\n/**\n * Adjudication throughput over a trailing window.\n *\n * ``recordedCount`` counts events created in the window; ``reviewedCount``\n * counts events whose review verdict was recorded in it (``reviewed_at``).\n * Reopening an event clears ``reviewed_at``, so the pair reads as \"arrived vs\n * currently-adjudicated\", and arrival outpacing adjudication is exactly the\n * growing-backlog signal.\n */\nexport interface CustomerActivityThroughputWindow {\n windowHours: number;\n recordedCount: number;\n reviewedCount: number;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: phi_posture\n */\n\nimport type { DeclaredDataUse } from './organization';\nimport type { PhiDataPolicy, PhiPostureDecision, PhiPostureReasonCode } from './workspace';\n\nexport type PhiPolicyReason = typeof PhiPolicyReason[keyof typeof PhiPolicyReason];\n\n\nexport const PhiPolicyReason = {\n initial_classification: 'initial_classification',\n customer_confirmation: 'customer_confirmation',\n agreement_verified: 'agreement_verified',\n scope_change: 'scope_change',\n periodic_review: 'periodic_review',\n correction: 'correction',\n incident_response: 'incident_response',\n} as const;\n\nexport type PhiPolicySource = typeof PhiPolicySource[keyof typeof PhiPolicySource];\n\n\nexport const PhiPolicySource = {\n customer_attestation: 'customer_attestation',\n contract_review: 'contract_review',\n staff_review: 'staff_review',\n legacy_inventory: 'legacy_inventory',\n} as const;\n\nexport interface PhiPostureFinding {\n reasonCode: PhiPostureReasonCode;\n organizationId: number;\n workspaceId?: number | null;\n workspaceUuid?: string | null;\n decision: PhiPostureDecision;\n}\n\nexport interface PhiPostureReportResponse {\n generatedAt: string;\n organizationCount: number;\n workspaceCount: number;\n findingCount: number;\n offset: number;\n limit: number;\n nextOffset?: number | null;\n findings: PhiPostureFinding[];\n truncated: boolean;\n}\n\nexport interface PhiPostureTransitionResponse {\n targetType: PhiPostureTransitionResponseTargetType;\n organizationId: number;\n workspaceId?: number | null;\n workspaceUuid?: string | null;\n declaredDataUse?: DeclaredDataUse | null;\n phiDataPolicy?: PhiDataPolicy | null;\n decision?: PhiPostureDecision | null;\n reasonCode?: PhiPostureReasonCode | null;\n policyVersion: string;\n source: string;\n reason: string;\n reviewedAt: string;\n reviewedByAccountId: number;\n reviewDueAt: string;\n}\n\nexport type PhiPostureTransitionResponseTargetType = typeof PhiPostureTransitionResponseTargetType[keyof typeof PhiPostureTransitionResponseTargetType];\n\n\nexport const PhiPostureTransitionResponseTargetType = {\n organization: 'organization',\n workspace: 'workspace',\n} as const;\n\nexport interface UpdateOrganizationPhiPostureRequest {\n /**\n * @minLength 1\n * @maxLength 64\n */\n policyVersion: string;\n source: PhiPolicySource;\n reason: PhiPolicyReason;\n reviewDueAt: string;\n declaredDataUse: DeclaredDataUse;\n}\n\nexport interface UpdateWorkspacePhiPolicyRequest {\n /**\n * @minLength 1\n * @maxLength 64\n */\n policyVersion: string;\n source: PhiPolicySource;\n reason: PhiPolicyReason;\n reviewDueAt: string;\n phiDataPolicy: PhiDataPolicy;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: workspace\n */\n\nimport type { Query } from './ir';\n\n/**\n * Admin request to create a user's membership in a workspace.\n */\nexport interface AdminCreateWorkspaceMemberRequest {\n memberRoleId?: number | null;\n}\n\n/**\n * Request model for admin workspace operations.\n */\nexport interface AdminCreateWorkspaceRequest {\n organizationId: number;\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n resellerId?: number | null;\n templateWorkspaceUuid?: string | null;\n locale?: string | null;\n features?: string[] | null;\n chatClassifierPrompt?: string | null;\n}\n\n/**\n * Admin request to map a site to a workspace.\n */\nexport interface AdminMapSiteRequest {\n workspaceId?: number | null;\n siteUuid: string;\n name?: string | null;\n siteSlug?: string | null;\n externalDomain?: string | null;\n ownerId?: number | null;\n allowSignup?: boolean;\n}\n\n/**\n * Response model for site mappings.\n */\nexport interface AdminSiteMappingResponse {\n id: number;\n siteId: number;\n siteUuid: string;\n siteName: string;\n siteSlug: string;\n externalDomain?: string | null;\n workspaceId: number;\n workspaceUuid: string;\n workspaceName: string;\n workspaceSlug: string;\n createdAt: string;\n updatedAt: string;\n}\n\n/**\n * Admin request to update a user's membership in a workspace.\n */\nexport interface AdminUpdateWorkspaceMemberRequest {\n tosAccepted?: boolean | null;\n memberRoleId?: number | null;\n}\n\n/**\n * Request model for admin workspace operations.\n */\nexport interface AdminUpdateWorkspaceRequest {\n organizationId?: number | null;\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n resellerId?: number | null;\n creatorId?: number | null;\n features?: string[] | null;\n featuresOverride?: AdminUpdateWorkspaceRequestFeaturesOverride;\n themes?: string[] | null;\n locale?: string | null;\n timezone?: string | null;\n chatClassifierPrompt?: string | null;\n}\n\nexport type AdminUpdateWorkspaceRequestFeaturesOverride = {[key: string]: boolean} | null;\n\nexport interface AdminWorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n organizationId: number;\n organizationUuid?: string | null;\n organizationName?: string | null;\n organizationLogoUrl?: string | null;\n signupCode?: string | null;\n createdAt: string;\n userRole: string | null;\n isPublic?: boolean;\n allowSignup?: boolean;\n resellerId?: number | null;\n themes?: string[];\n features?: string[] | null;\n featureStatus?: AdminWorkspaceResponseFeatureStatus;\n signupRequestStatus?: string | null;\n status?: number | null;\n locale?: string | null;\n timezone?: string | null;\n creatorId?: number | null;\n creatorName?: string | null;\n dbId?: number | null;\n featuresOverride?: AdminWorkspaceResponseFeaturesOverride;\n billingOwnerId?: number | null;\n billingOwnerName?: string | null;\n subscriptionProductId?: number | null;\n subscriptionProductName?: string | null;\n chatClassifierPrompt?: string | null;\n phiDataPolicy?: PhiDataPolicy;\n phiPostureDecision?: PhiPostureDecision;\n phiPostureReasonCode?: PhiPostureReasonCode;\n phiPolicyVersion?: string | null;\n phiPolicySource?: string | null;\n phiPolicyReason?: string | null;\n phiPolicyReviewedAt?: string | null;\n phiPolicyReviewedByAccountId?: number | null;\n phiPolicyReviewDueAt?: string | null;\n}\n\nexport type AdminWorkspaceResponseFeatureStatus = {[key: string]: string} | null;\n\nexport type AdminWorkspaceResponseFeaturesOverride = {[key: string]: boolean} | null;\n\nexport interface BusinessHoursStatusResponse {\n isBusinessHours: boolean;\n}\n\n/**\n * Typed body for the CLI-facing ``change-org`` / ``change-org/preview``\n * admin endpoints.\n *\n * Typing ``targetOrganizationId`` / ``newCreatorId`` as ``int`` makes FastAPI\n * return 422 on a non-numeric body field instead of letting a string value\n * reach the DB driver. Mirrors the superuser\n * ``WorkspaceMigrationRequest`` model used by the sibling\n * ``POST /admin/org-migration/workspace`` endpoint.\n */\nexport interface ChangeWorkspaceOrgRequest {\n /**\n * ID of the target organization\n * @exclusiveMinimum 0\n */\n targetOrganizationId: number;\n /**\n * Account ID to set as the workspace creator (created or promoted to OWNER in the target org)\n * @exclusiveMinimum 0\n */\n newCreatorId: number;\n}\n\nexport interface ClassifyPhoneResponse {\n phoneType?: string | null;\n}\n\nexport interface CostInfo {\n score: number;\n budget: number;\n}\n\n/**\n * Request model for associating data records with assignments.\n */\nexport interface DataRecordAssociationRequest {\n id: number;\n accessMode?: number;\n}\n\nexport interface DeleteMembershipResponse {\n message: string;\n}\n\nexport interface DeleteWorkspaceResponse {\n status: string;\n}\n\nexport interface FirstRunState {\n mode?: string;\n statuses?: FirstRunStateStatuses;\n collapsed?: boolean | null;\n}\n\nexport type FirstRunStateStatuses = {[key: string]: string} | null;\n\n/**\n * Create request for org-scoped workspace creation.\n *\n * Only allows fields appropriate for org admins.\n * Does NOT allow: resellerId, features, featuresOverride, isPublic, allowSignup.\n */\nexport interface OrgCreateWorkspaceRequest {\n /**\n * @minLength 1\n * @maxLength 200\n */\n name: string;\n slug?: string | null;\n templateWorkspaceUuid?: string | null;\n}\n\n/**\n * Request to join a workspace as an org admin.\n */\nexport interface OrgJoinWorkspaceRequest {\n memberRoleId: number;\n}\n\n/**\n * Response after joining a workspace.\n */\nexport interface OrgJoinWorkspaceResponse {\n memberId: number;\n memberRoleId: number;\n message: string;\n}\n\n/**\n * Organization settings an **org admin** may change.\n *\n * Deliberately a separate model from :class:`UpdateOrganizationRequest`\n * rather than a subset enforced at the route: the privileged field\n * ``enforceCreditLimit`` is *absent from the schema*, so an org admin\n * cannot set it even by crafting the request body. Pydantic ignores\n * unknown keys, and there is no code path from here to that column.\n *\n * It remains superuser-only, on ``PUT /api/v2/admin/organizations/{id}``\n * behind ``Depends(get_superuser)``: ``enforceCreditLimit`` decides whether\n * a customer is hard-blocked (402) at zero credits or merely alerted, i.e.\n * whether they can keep spending.\n *\n * SSO is not here either — it has its own admin-scoped endpoint\n * (``PUT /api/v2/o/{org_uuid}/sso``) with its own audit trail.\n */\nexport interface OrgSettingsUpdateRequest {\n name?: string | null;\n slug?: string | null;\n contactEmail?: string | null;\n contactPhone?: string | null;\n logoUrl?: string | null;\n}\n\n/**\n * Update request for org-scoped workspace updates.\n *\n * Only allows fields that org admins should be able to change.\n * Does NOT allow: features, featuresOverride, organizationId, resellerId,\n * creatorId, themes.\n */\nexport interface OrgUpdateWorkspaceRequest {\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n locale?: string | null;\n timezone?: string | null;\n}\n\n/**\n * Workspace response for org context.\n *\n * Similar to AdminWorkspaceResponse but without superuser-only fields\n * like dbId, featuresOverride, billingOwnerId, etc.\n */\nexport interface OrgWorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n organizationId: number;\n organizationUuid?: string | null;\n organizationName?: string | null;\n signupCode?: string | null;\n createdAt: string;\n isPublic?: boolean;\n allowSignup?: boolean;\n resellerId?: number | null;\n status: number;\n features?: string[] | null;\n featureStatus?: OrgWorkspaceResponseFeatureStatus;\n creatorId?: number | null;\n creatorName?: string | null;\n locale?: string | null;\n timezone?: string | null;\n isMember?: boolean;\n}\n\nexport type OrgWorkspaceResponseFeatureStatus = {[key: string]: string} | null;\n\n/**\n * One workspace card's expensive half: workspace-schema aggregates.\n *\n * ``myRoleName`` is about the requesting account and is returned to any org\n * member who belongs to the workspace. The counts are org-administrative\n * information and are populated only for ``org:read`` holders; everyone else\n * gets ``None`` (rendered as \"—\" rather than zero, so the UI never implies\n * an empty workspace when it simply may not look).\n *\n * ``schemaReady`` is False while the workspace is still provisioning — its\n * tables do not exist yet, so the counts are absent for a reason the card\n * can explain instead of showing a failure.\n */\nexport interface OrgWorkspaceStatsResponse {\n workspaceUuid: string;\n /** False while the workspace is still provisioning, or when its schema could not be read. The counts are absent in that case. */\n schemaReady?: boolean;\n /** The REQUESTING account's member-role name in this workspace. Null when they have no member row there. */\n myRoleName?: string | null;\n /** Non-archived members in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n memberCount?: number | null;\n /** Published and draft sites in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n siteCount?: number | null;\n /** Email inboxes in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n inboxCount?: number | null;\n /** Non-archived phone numbers in this workspace. NULL — not 0 — when the caller lacks org:read, or when the workspace schema is unreadable (schemaReady=false). Zero means the workspace really is empty. */\n phoneNumberCount?: number | null;\n}\n\n/**\n * One workspace card's cheap half: identity plus a GLB-side count.\n *\n * ``orgMemberCount`` joins workspace membership to org membership. A separate\n * \"all accounts\" tally was tried and dropped: the\n * ``enforce_org_membership_before_workspace`` trigger refuses a workspace\n * membership for an account with no org membership, so the two numbers are\n * equal except in the transient state after an org membership is revoked —\n * a distinction no card was showing.\n */\nexport interface OrgWorkspaceSummaryResponse {\n uuid: string;\n name: string;\n slug: string;\n /** WorkspaceProvisionStatus. 2 = AVAILABLE; anything else means the workspace is still being provisioned. */\n status: number;\n createdAt: string;\n isPublic?: boolean;\n allowSignup?: boolean;\n /** Whether the requesting account has a workspace membership here. */\n isMember?: boolean;\n /** Accounts with access to this workspace who are also members of this organization. */\n orgMemberCount?: number;\n}\n\nexport type PhiDataPolicy = typeof PhiDataPolicy[keyof typeof PhiDataPolicy];\n\n\nexport const PhiDataPolicy = {\n unclassified: 'unclassified',\n phi_prohibited: 'phi_prohibited',\n phi_permitted: 'phi_permitted',\n} as const;\n\nexport type PhiPostureDecision = typeof PhiPostureDecision[keyof typeof PhiPostureDecision];\n\n\nexport const PhiPostureDecision = {\n allow_non_phi: 'allow_non_phi',\n warn_non_phi: 'warn_non_phi',\n review_required: 'review_required',\n authorization_required: 'authorization_required',\n conflict: 'conflict',\n} as const;\n\nexport type PhiPostureReasonCode = typeof PhiPostureReasonCode[keyof typeof PhiPostureReasonCode];\n\n\nexport const PhiPostureReasonCode = {\n org_unclassified: 'org_unclassified',\n workspace_unclassified: 'workspace_unclassified',\n non_phi_policy_aligned: 'non_phi_policy_aligned',\n phi_expected_workspace_prohibited: 'phi_expected_workspace_prohibited',\n phi_authorization_not_evaluated: 'phi_authorization_not_evaluated',\n phi_coverage_satisfied: 'phi_coverage_satisfied',\n phi_coverage_missing: 'phi_coverage_missing',\n phi_coverage_expired: 'phi_coverage_expired',\n non_phi_org_workspace_permitted: 'non_phi_org_workspace_permitted',\n phi_permitted_org_not_expected: 'phi_permitted_org_not_expected',\n organization_review_expired: 'organization_review_expired',\n workspace_review_expired: 'workspace_review_expired',\n invalid_state: 'invalid_state',\n} as const;\n\nexport interface PublicWorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n createdAt: string;\n allowSignup?: boolean;\n resellerId?: number | null;\n memberRole?: string | null;\n signupRequestStatus?: string | null;\n}\n\nexport interface QueryDataTypeInfo {\n id: number;\n slug: string;\n name: string;\n isCollection: boolean;\n recordFields: RecordFieldInfo[];\n}\n\n/**\n * A labeled choice for a field whose raw values are ids/codes.\n */\nexport interface QueryEnumOption {\n value: unknown;\n label: string;\n color?: string | null;\n}\n\nexport interface QueryFieldInfo {\n path: string;\n type: string;\n operators: string[];\n sortable?: boolean;\n selectable?: boolean;\n enumValues?: unknown[] | null;\n enumOptions?: QueryEnumOption[] | null;\n displayName?: string | null;\n category?: string | null;\n}\n\nexport interface QueryFieldsResponse {\n entities: QueryFieldsResponseEntities;\n aggregateSources: QueryFieldsResponseAggregateSources;\n dataTypes: QueryDataTypeInfo[];\n recordSystemFields: QueryFieldInfo[];\n relations?: QueryFieldsResponseRelations;\n aggregateSourceCategories?: QueryFieldsResponseAggregateSourceCategories;\n}\n\nexport type QueryFieldsResponseAggregateSourceCategories = {[key: string]: {[key: string]: string}};\n\nexport type QueryFieldsResponseAggregateSources = {[key: string]: string[]};\n\nexport type QueryFieldsResponseEntities = {[key: string]: QueryFieldInfo[]};\n\nexport type QueryFieldsResponseRelations = {[key: string]: {[key: string]: QueryFieldInfo[]}};\n\nexport interface RecordFieldInfo {\n slug: string;\n name: string;\n type: string;\n operators: string[];\n enumValues?: unknown[] | null;\n}\n\nexport interface RunQueryRequest {\n query: Query;\n mode?: RunQueryRequestMode;\n}\n\nexport type RunQueryRequestMode = typeof RunQueryRequestMode[keyof typeof RunQueryRequestMode] | null;\n\n\nexport const RunQueryRequestMode = {\n rows: 'rows',\n count: 'count',\n aggregate: 'aggregate',\n} as const;\n\nexport interface RunQueryResponse {\n mode: string;\n items?: RunQueryResponseItems;\n nextCursor?: string | null;\n count?: number | null;\n rows?: RunQueryResponseRows;\n warnings?: string[];\n cost?: CostInfo | null;\n}\n\nexport type RunQueryResponseItems = { [key: string]: unknown }[] | null;\n\nexport type RunQueryResponseRows = { [key: string]: unknown }[] | null;\n\n/**\n * Request model for associating child tasks (parent-child relationships).\n *\n * ``order`` is optional and backward-compatible: when omitted, callers\n * that build associations from a UI-style ``childTasks`` list keep the\n * historical array-index ordering. When provided (e.g. by the workspace\n * transfer importer), it preserves the authored routing order so that\n * automatic routing still selects the lower-order matching child after\n * transfer.\n */\nexport interface TaskAssociationRequest {\n taskId: number;\n autoNext: boolean;\n required: boolean;\n choicePrompt?: string | null;\n celCondition?: string | null;\n order?: number | null;\n}\n\n/**\n * Update workspace defaults.\n */\nexport interface UpdateWorkspaceDefaultsRequest {\n defaultPhoneNumberId?: number | null;\n defaultAgentId?: number | null;\n escalationBusinessHours?: string | null;\n escalationOnlineMessageTemplate?: string | null;\n escalationOfflineMessageTemplate?: string | null;\n escalationNotifiedMessageTemplate?: string | null;\n escalationPausedMessageTemplate?: string | null;\n emailFooter?: string | null;\n pauseOnEscalate?: boolean | null;\n enableAudioRecording?: boolean | null;\n enableVoicemailDetection?: boolean | null;\n shortenUrls?: boolean | null;\n transcriptionModel?: string | null;\n}\n\n/**\n * Update a workspace.\n */\nexport interface UpdateWorkspaceRequest {\n name?: string | null;\n slug?: string | null;\n signupCode?: string | null;\n isPublic?: boolean | null;\n allowSignup?: boolean | null;\n locale?: string | null;\n timezone?: string | null;\n}\n\nexport interface ValidateQueryResponse {\n valid: boolean;\n cost: CostInfo;\n warnings?: string[];\n errors?: string[];\n}\n\n/**\n * Slim view of an OrgDomain for selection in workspace forms.\n *\n * Intentionally smaller than `OrgDomainResponse` — workspace members\n * don't need ownership tokens, DNS records, last-checked timestamps,\n * etc. Just enough to populate a dropdown, pass the uuid back as a\n * foreign reference (e.g. `orgDomainUuid` on inbox creation), and\n * let the UI mark non-verified entries as disabled with a reason.\n */\nexport interface WorkspaceAvailableDomain {\n uuid: string;\n domain: string;\n ownershipStatus: string;\n emailStatus?: string | null;\n siteStatus?: string | null;\n}\n\nexport interface WorkspaceAvailableDomainsResponse {\n items: WorkspaceAvailableDomain[];\n total: number;\n}\n\n/**\n * Response model for workspace counts.\n */\nexport interface WorkspaceCountsResponse {\n humans: number;\n agents: number;\n tasks: number;\n workflows: number;\n inboxes: number;\n phoneNumbers: number;\n chats: number;\n files: number;\n sites: number;\n forms: number;\n}\n\n/**\n * Request model for joining a workspace.\n */\nexport interface WorkspaceJoinRequest {\n memberRoleId: number;\n orgRole?: string | null;\n}\n\n/**\n * Response model for joining a workspace.\n */\nexport interface WorkspaceJoinResponse {\n success: boolean;\n memberUuid: string;\n memberId: number;\n workspaceUuid: string;\n workspaceName: string;\n memberRoleName: string;\n message: string;\n}\n\nexport interface WorkspaceResponse {\n id: number;\n uuid: string;\n slug: string;\n name: string;\n organizationId: number;\n organizationUuid?: string | null;\n organizationName?: string | null;\n organizationLogoUrl?: string | null;\n signupCode?: string | null;\n createdAt: string;\n userRole: string | null;\n isPublic?: boolean;\n allowSignup?: boolean;\n resellerId?: number | null;\n themes?: string[];\n features?: string[] | null;\n featureStatus?: WorkspaceResponseFeatureStatus;\n signupRequestStatus?: string | null;\n status?: number | null;\n locale?: string | null;\n timezone?: string | null;\n}\n\nexport type WorkspaceResponseFeatureStatus = {[key: string]: string} | null;\n\n/**\n * Individual scope metadata.\n */\nexport interface WorkspaceScopeResponse {\n name: string;\n category: string;\n description: string;\n implies?: string[];\n dangerous?: boolean;\n}\n\n/**\n * Response containing all workspace-grantable scopes.\n */\nexport interface WorkspaceScopesListResponse {\n items: WorkspaceScopeResponse[];\n categories: string[];\n}\n\nexport interface WorkspaceSettingsResponse {\n id: number;\n slug: string;\n defaultPhoneNumberId: number | null;\n defaultAgentId: number | null;\n workspaceFolderId?: number | null;\n escalationBusinessHours: string | null;\n escalationOnlineMessageTemplate: string | null;\n escalationOfflineMessageTemplate: string | null;\n escalationNotifiedMessageTemplate: string | null;\n escalationPausedMessageTemplate: string | null;\n emailFooter: string | null;\n pauseOnEscalate: boolean;\n sesDomain: string;\n enableAudioRecording: boolean;\n enableVoicemailDetection: boolean;\n shortenUrls: boolean;\n shortenUrlsExampleUrl: string;\n shortenUrlsAvailable: boolean;\n transcriptionModel?: string | null;\n defaultChatModel: string;\n defaultRealtimeModel: string;\n defaultInferenceModel: string;\n defaultVoiceModel: string;\n firstRunMode?: string | null;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: metric\n */\n\n\n/**\n * On-demand compute of enabled chat-source metrics for one chat.\n */\nexport interface ComputeChatMetricsRequest {\n /**\n * Chat id to evaluate\n * @minimum 1\n */\n chatId: number;\n}\n\n/**\n * Result of an on-demand chat metrics compute.\n */\nexport interface ComputeChatMetricsResponse {\n chatId: number;\n observationCount: number;\n}\n\n/**\n * Create a workspace metric definition.\n */\nexport interface CreateMetricRequest {\n /**\n * @minLength 1\n * @maxLength 255\n */\n name: string;\n /** Stable identifier; auto-derived from name when omitted. */\n slug?: string | null;\n description?: string | null;\n metricType: MetricType;\n source?: MetricSource;\n kind?: MetricKind;\n unit?: MetricUnit;\n celExpression?: string | null;\n evaluationPrompt?: string | null;\n /**\n * @minimum 0\n * @maximum 1\n */\n passingThreshold?: number;\n sourceConfig?: MetricSourceConfig | null;\n denominator?: MetricDenominator;\n attributionWindowSeconds?: number | null;\n enabled?: boolean;\n chatType?: MetricChatType;\n /** Workflows this chat metric measures. Required for chat metrics — pass [] to mean every workflow, deliberately. Omitting it is an error, so a scope is never chosen by accident. */\n workflowIds?: number[] | null;\n /** Optional goal for this metric — 'reach this value'. */\n targetValue?: number | null;\n /** Optional due date for targetValue. */\n targetDate?: string | null;\n}\n\n/**\n * Which conversation surface a chat metric measures.\n *\n * One metric measures one surface, deliberately. An assignment chat, a\n * sidebar DM and a contributor-input chat are different populations with\n * different success conditions; averaging them yields a number that\n * describes nothing. Want resolution rate for DMs too? That is a second\n * metric, and the two are legitimately comparable side by side.\n *\n * ``manager`` is absent on purpose — workspace-management chats are the\n * operator talking to the product, never a customer outcome.\n */\nexport type MetricChatType = typeof MetricChatType[keyof typeof MetricChatType];\n\n\nexport const MetricChatType = {\n assignment: 'assignment',\n dm: 'dm',\n contributor: 'contributor',\n} as const;\n\n/**\n * Explicit rate denominator — stored on the definition, not a convention.\n *\n * Read it as \"count once per\": what the rate divides by.\n *\n * * ``OBSERVATIONS`` — each observation counts once. For every metric\n * that can exist today that is one per conversation, because a\n * conversation yields exactly one observation.\n * * ``UNIQUE_MEMBERS`` — each Member counts once no matter how many\n * chats they had in the window. Required by pilot agreements written\n * as \"unique clients who respond… multiple responses from the same\n * client count as a single engagement\": a member in a multi-touch\n * journey has several chats, so averaging over observations\n * double-counts them and produces a defensible number that is not the\n * number in the contract.\n *\n * There was briefly a third value, ``CHATS``, reserved so a future\n * message-sourced metric could distinguish \"per observation\" (per\n * message) from \"per conversation\". It computed an identical number to\n * ``OBSERVATIONS`` for every metric that can exist today, so it reached\n * the UI as two buttons producing the same result. Reintroduce it with\n * the ``CHAT_MESSAGE`` source (#22474), when the distinction is real.\n */\nexport type MetricDenominator = typeof MetricDenominator[keyof typeof MetricDenominator];\n\n\nexport const MetricDenominator = {\n observations: 'observations',\n unique_members: 'unique_members',\n} as const;\n\n/**\n * Aggregation semantics for stored values.\n *\n * * ``OBSERVATION`` — one row per subject (chat/message/member). Aggregate\n * with avg/sum/count over a window. Must not be last-valued.\n * * ``GAUGE`` — point-in-time count of matching rows. Last-value only;\n * must not be summed across a window. Computed by the ``member_filter``\n * source.\n */\nexport type MetricKind = typeof MetricKind[keyof typeof MetricKind];\n\n\nexport const MetricKind = {\n observation: 'observation',\n gauge: 'gauge',\n} as const;\n\n/**\n * One observation — reason may be PHI; gated by analytics scope.\n */\nexport interface MetricObservationResponse {\n id: number;\n uuid: string;\n metricId: number;\n value: number;\n observedAt: string;\n chatId: number | null;\n memberId: number | null;\n messageId: number | null;\n /** Rubric grader free text — PHI-bearing; omit from aggregate export */\n reason?: string | null;\n modelId?: string | null;\n modelVersion?: string | null;\n evaluationData?: MetricObservationResponseEvaluationData;\n createdAt: string;\n}\n\nexport type MetricObservationResponseEvaluationData = { [key: string]: unknown } | null;\n\n/**\n * API shape for a Metric definition.\n */\nexport interface MetricResponse {\n id: number;\n uuid: string;\n name: string;\n slug: string;\n description: string | null;\n metricType: string;\n source: string;\n kind: string;\n unit: string;\n celExpression: string | null;\n evaluationPrompt: string | null;\n passingThreshold: number;\n sourceConfig: MetricResponseSourceConfig;\n denominator: string;\n attributionWindowSeconds: number | null;\n chatType: string;\n workflowIds: number[];\n targetValue: number | null;\n targetDate: string | null;\n enabled: boolean;\n archived: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type MetricResponseSourceConfig = { [key: string]: unknown } | null;\n\n/**\n * One time-bucket of aggregated observations.\n */\nexport interface MetricSeriesBucket {\n bucketStart: string;\n value: number | null;\n count: number;\n}\n\n/**\n * Time-series readout for a metric.\n */\nexport interface MetricSeriesResponse {\n metricId: number;\n metricUuid: string;\n metricName: string;\n unit: string;\n kind: string;\n denominator: string;\n aggregation: string;\n bucket: string;\n start: string;\n end: string;\n buckets: MetricSeriesBucket[];\n overallValue: number | null;\n overallCount: number;\n targetValue?: number | null;\n targetDate?: string | null;\n}\n\n/**\n * What triggers computation of a metric observation.\n *\n * * ``CHAT`` — rides ``ChatPostProcessingWorkflow`` after a chat goes quiet.\n * * ``MEMBER_FILTER`` — point-in-time count of Members matching a\n * :class:`~lib.models.workspace.member_filter.MemberFilter`. This is the\n * source that subsumed the former ``MilestoneGoal`` (a named target over a\n * Member cohort at a date); ``source_config`` carries\n * ``{\"member_filter_id\": <id>}``.\n *\n * Other sources are reserved for follow-on work.\n */\nexport type MetricSource = typeof MetricSource[keyof typeof MetricSource];\n\n\nexport const MetricSource = {\n chat: 'chat',\n member_filter: 'member_filter',\n} as const;\n\n/**\n * Per-source parameters for a metric definition.\n *\n * Typed rather than a bare ``dict[str, Any]`` because the values are\n * load-bearing at compute time and failure is silent. A chat metric whose\n * ``minMessages`` arrives as ``\"10\"`` was previously ignored outright —\n * ``metric_meets_min_messages`` only honours the key when it is already an\n * ``int`` — so the metric graded conversations the author meant to exclude\n * and nothing said so. ``extra=\"forbid\"`` gives the same treatment to a\n * typo'd key, which used to be stored and quietly do nothing.\n *\n * API keys are camelCase per the naming convention; the persisted JSONB\n * keeps snake_case because that is what ``metric_eval_service`` reads.\n * ``to_storage`` is the only place that translation happens.\n */\nexport interface MetricSourceConfig {\n memberFilterId?: number | null;\n minMessages?: number | null;\n}\n\n/**\n * How a metric value is computed.\n *\n * ``EXPRESSION`` is CEL-evaluated (synchronous, deterministic).\n * ``RUBRIC`` is LLM-evaluated (async, probabilistic). Those two mirror\n * :class:`~lib.models.workspace.qualification.CriterionType`.\n *\n * ``FILTER_COUNT`` has no authored expression at all — the value is the\n * number of rows matching a saved filter named in ``source_config``. It\n * pairs with ``source=member_filter`` + ``kind=gauge`` and is what the\n * retired MilestoneGoal computed.\n */\nexport type MetricType = typeof MetricType[keyof typeof MetricType];\n\n\nexport const MetricType = {\n expression: 'expression',\n rubric: 'rubric',\n filter_count: 'filter_count',\n} as const;\n\n/**\n * Display/aggregation hint for the metric's values.\n */\nexport type MetricUnit = typeof MetricUnit[keyof typeof MetricUnit];\n\n\nexport const MetricUnit = {\n rate: 'rate',\n score: 'score',\n count: 'count',\n custom: 'custom',\n} as const;\n\n/**\n * Partial update of a metric definition.\n *\n * ``metricType`` is immutable after create (same rule as ScenarioCriterion).\n */\nexport interface UpdateMetricRequest {\n name?: string | null;\n description?: string | null;\n unit?: MetricUnit | null;\n celExpression?: string | null;\n evaluationPrompt?: string | null;\n passingThreshold?: number | null;\n sourceConfig?: MetricSourceConfig | null;\n denominator?: MetricDenominator | null;\n attributionWindowSeconds?: number | null;\n enabled?: boolean | null;\n archived?: boolean | null;\n workflowIds?: number[] | null;\n targetValue?: number | null;\n targetDate?: string | null;\n}\n","/**\n * Generated by Orval, grouped by scripts/types-codegen/group_generated.ts\n * (group map from emit_openapi.py). Do not edit manually.\n * Group: pilot_program\n */\n\n\n/**\n * All pilot-program config rows the operator asked for.\n */\nexport interface PilotProgramListResponse {\n programs: PilotProgramResponse[];\n total: number;\n includesInactive: boolean;\n}\n\n/**\n * One ``pilot_programs`` config row.\n */\nexport interface PilotProgramResponse {\n id: number;\n uuid: string;\n label: string;\n customerId?: number | null;\n coveredWorkspaceIds: number[];\n relationshipType: PilotRelationshipType;\n lifecycleStage: PilotStage;\n stageEnteredAt: string;\n allocationMinutes?: number | null;\n allocationPeriodStart?: string | null;\n notifyThresholdPct: number;\n notifyContactLabel?: string | null;\n stalenessThresholdDays: number;\n active: boolean;\n createdAt?: string | null;\n updatedAt?: string | null;\n}\n\n/**\n * How this pilot relates to us commercially.\n *\n * Drives the staleness read: a ``DIRECT_PILOT`` is healthy when its own\n * workspaces are active; a ``PARTNER_CHANNEL`` (co-sale partner / reseller) is\n * healthy on deal + integration activity even with low own-workspace volume.\n */\nexport type PilotRelationshipType = typeof PilotRelationshipType[keyof typeof PilotRelationshipType];\n\n\nexport const PilotRelationshipType = {\n direct_pilot: 'direct_pilot',\n partner_channel: 'partner_channel',\n} as const;\n\n/**\n * The pilot funnel stage (distinct from the churn-risk\n * ``CustomerHealthLifecycleStage`` in the customer-health read model —\n * that answers \"how healthy?\", this answers \"how far through the pilot?\").\n *\n * ``SIGNED``/``LIVE``/``VALUE_EVIDENCED`` are the in-flight stages a staleness\n * watcher covers; ``ON_HOLD`` is a deliberate pause (never paged on); and\n * ``CONVERTED``/``CHURNED`` are terminal outcomes (no staleness signal).\n */\nexport type PilotStage = typeof PilotStage[keyof typeof PilotStage];\n\n\nexport const PilotStage = {\n signed: 'signed',\n live: 'live',\n value_evidenced: 'value_evidenced',\n converted: 'converted',\n on_hold: 'on_hold',\n churned: 'churned',\n} as const;\n"],"mappings":"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","names":[]}