@stndrds/schema 1.0.0-alpha.277 → 1.0.0-alpha.279

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/dist/{all-D-E8v5yo.d.mts → all-Bk8cRKsu.d.mts} +20 -3
  2. package/dist/{all-D5SkjRst.d.ts → all-C_tC90ZM.d.ts} +20 -3
  3. package/dist/{attributes-lBLiOIY3.d.mts → attributes--M1ifW8_.d.mts} +1 -1
  4. package/dist/{attributes-_b3Db8vT.d.ts → attributes-D8eHv5Kf.d.ts} +1 -1
  5. package/dist/{chunk-XQEDMB6B.mjs → chunk-5PLJHYSL.mjs} +24 -4
  6. package/dist/{chunk-KKR6I3YV.js → chunk-DEHBEFGO.js} +3 -3
  7. package/dist/{chunk-VVYIFBFQ.mjs → chunk-PQEOIDXD.mjs} +1 -1
  8. package/dist/{chunk-F32XOFSP.js → chunk-QMAVKX3Y.js} +55 -34
  9. package/dist/{chunk-PSCSTHUB.mjs → chunk-QUZ3PN36.mjs} +11 -14
  10. package/dist/{chunk-K4UER3DU.mjs → chunk-V2WJFUZW.mjs} +14 -2
  11. package/dist/{chunk-RYAQOR7M.js → chunk-ZBWTAKZO.js} +14 -2
  12. package/dist/{chunk-FMLZHHWB.js → chunk-ZEPGMHCK.js} +14 -16
  13. package/dist/exceptions.d.mts +14 -4
  14. package/dist/exceptions.d.ts +14 -4
  15. package/dist/exceptions.js +39 -39
  16. package/dist/exceptions.mjs +1 -1
  17. package/dist/{helpers-C1VVEAOO.d.mts → helpers-BiABdSxK.d.mts} +3 -3
  18. package/dist/{helpers-vQ6kp8ET.d.ts → helpers-DyoPqiSz.d.ts} +3 -3
  19. package/dist/index-C3P5Dnwt.d.mts +790 -0
  20. package/dist/index-SpFpkWVC.d.ts +790 -0
  21. package/dist/index.d.mts +2228 -393
  22. package/dist/index.d.ts +2228 -393
  23. package/dist/index.js +565 -324
  24. package/dist/index.mjs +358 -138
  25. package/dist/{migrations-DcuJZ8qO.d.ts → migrations-B1kkIhIX.d.ts} +1 -1
  26. package/dist/{migrations-BXd2ZGfM.d.mts → migrations-BNlQVzDC.d.mts} +1 -1
  27. package/dist/{objects-A1ED9af-.d.ts → objects-DgFojgwH.d.ts} +19 -3
  28. package/dist/{objects-BCaBw2ef.d.mts → objects-DmMqHn3L.d.mts} +19 -3
  29. package/dist/{types-DNz3ITS-.d.mts → types-DHqXzkgW.d.mts} +1 -1
  30. package/dist/{types-DqLi1tx1.d.ts → types-DYYFto8d.d.ts} +1 -1
  31. package/dist/validation/all.d.mts +7 -7
  32. package/dist/validation/all.d.ts +7 -7
  33. package/dist/validation/all.js +29 -29
  34. package/dist/validation/all.mjs +4 -4
  35. package/dist/validation/complex/currency.d.mts +2 -2
  36. package/dist/validation/complex/currency.d.ts +2 -2
  37. package/dist/validation/complex/location.d.mts +2 -2
  38. package/dist/validation/complex/location.d.ts +2 -2
  39. package/dist/validation/complex/phone.d.mts +2 -2
  40. package/dist/validation/complex/phone.d.ts +2 -2
  41. package/dist/validation/complex/relation.d.mts +2 -2
  42. package/dist/validation/complex/relation.d.ts +2 -2
  43. package/dist/validation/complex/richtext.d.mts +2 -2
  44. package/dist/validation/complex/richtext.d.ts +2 -2
  45. package/dist/validation/complex/select.d.mts +2 -2
  46. package/dist/validation/complex/select.d.ts +2 -2
  47. package/dist/validation/complex/user.d.mts +2 -2
  48. package/dist/validation/complex/user.d.ts +2 -2
  49. package/dist/validation/computed/formula.d.mts +2 -2
  50. package/dist/validation/computed/formula.d.ts +2 -2
  51. package/dist/validation/computed/rollup.d.mts +2 -2
  52. package/dist/validation/computed/rollup.d.ts +2 -2
  53. package/dist/validation/config/index.d.mts +4 -4
  54. package/dist/validation/config/index.d.ts +4 -4
  55. package/dist/validation/config/index.js +11 -11
  56. package/dist/validation/config/index.mjs +2 -2
  57. package/dist/validation/core/index.d.mts +3 -3
  58. package/dist/validation/core/index.d.ts +3 -3
  59. package/dist/validation/object/index.d.mts +5 -5
  60. package/dist/validation/object/index.d.ts +5 -5
  61. package/dist/validation/object/index.js +14 -14
  62. package/dist/validation/object/index.mjs +2 -2
  63. package/dist/validation/primitives/checkbox.d.mts +2 -2
  64. package/dist/validation/primitives/checkbox.d.ts +2 -2
  65. package/dist/validation/primitives/date.d.mts +2 -2
  66. package/dist/validation/primitives/date.d.ts +2 -2
  67. package/dist/validation/primitives/number.d.mts +2 -2
  68. package/dist/validation/primitives/number.d.ts +2 -2
  69. package/dist/validation/primitives/text.d.mts +2 -2
  70. package/dist/validation/primitives/text.d.ts +2 -2
  71. package/package.json +2 -2
  72. package/dist/index-AJeEKoy6.d.ts +0 -2203
  73. package/dist/index-ApHE8c1J.d.mts +0 -2203
package/dist/index.d.ts CHANGED
@@ -1,23 +1,23 @@
1
- import { S as SortRule, F as FilterState, V as ViewType, a as ViewConfig, C as ConfigOverrides, P as PermissionScope, A as Action, b as FilterOperator, c as SystemResource, d as ProviderName, M as ModelDefinition, e as AgentSchedule, f as AgentExecutionConfig, g as AgentApprovalPolicy, T as TriggerEventType, h as AgentTriggerBlueprint, i as AgentBlueprint, D as DetailViewConfig, j as DetailViewDefinition, k as SidePanelConfig, l as Field, m as AttributeGroupField, n as FieldGroup, R as RelationGroup, G as Group, o as TableTab, p as CreateMode, q as Tab, L as ListViewConfig, r as ListViewDefinition, s as ViewDefinition, t as ListViewTab, u as FilterValue, v as FilterRule, w as DynamicValue, x as RelativeDateValue } from './index-AJeEKoy6.js';
2
- export { y as AIAvailableModel, z as AIBatchAnswerValue, B as AIBatchQuestion, E as AIBatchQuestionAnswer, H as AIBatchQuestionOption, I as AIBatchQuestionType, J as AIChatMessage, K as AIChatMessagePart, N as AIChatMessagePartType, O as AIChatNotification, Q as AICompactionSummary, U as AIMemoryEntry, W as AIMemoryType, X as AIMessageRole, Y as AIProviderMetrics, Z as AIQuestion, _ as AIQuestionAnswer, $ as AIQuestionOption, a0 as AIQuestionType, a1 as AISubagentStatus, a2 as AITodoItem, a3 as AITodoList, a4 as AITodoStatus, a5 as AIToolCall, a6 as AIToolCallStatus, a7 as AIUsageMetrics, a8 as ALL_ACTIONS, a9 as AccessLevel, aa as ActivityTab, ab as AddAttributeInput, ac as AdvancedFilterState, ad as AgentConfig, ae as AgentDashboard, af as AgentDefinition, ag as AgentEvent, ah as AgentMessageAttachment, ai as AgentMessagePart, aj as AgentMission, ak as AgentMissionArtifact, al as AgentMissionPage, am as AgentMissionPolicy, an as AgentMissionRubric, ao as AgentMissionRubricCriterion, ap as AgentMissionStatus, aq as AgentMissionVerification, ar as AgentMissionView, as as AgentRequiredPermission, at as AgentRun, au as AgentRunStatus, av as AgentSession, aw as AgentSessionMessage, ax as AgentSessionMode, ay as AgentSessionStatus, az as AgentTodoPlan, aA as AgentTodoPlanStatus, aB as AgentTodoPlanView, aC as AgentToolCall, aD as AgentTriggerDefinition, aE as AgentTriggerType, aF as ApprovalMode, aG as AssignRoleInput, aH as CompactionStrategy, aI as CreateCustomObjectInput, aJ as CreatePermissionInput, aK as CreateRoleInput, aL as CreateViewInput, aM as CriticConfig, aN as CurrencyFilterValue, aO as CustomTab, aP as DEFAULT_APPROVAL_POLICY, aQ as DocumentsTab, aR as EdgeQuantifier, aS as EffectivePermissions, aT as EmailsTab, aU as ExtendedFilterRule, aV as FilterCombinator, aW as FilterGroup, aX as FormDensity, aY as FormSubmittedAgentEvent, aZ as FormTab, a_ as FormsTab, a$ as HumanRequestNeed, b0 as InverseSource, b1 as ListViewLayout, b2 as MAX_TODOS, b3 as MAX_TODO_DESCRIPTION_CHARS, b4 as MAX_TODO_ID_CHARS, b5 as MAX_TODO_RESULT_CHARS, b6 as MentionEntityType, b7 as MentionReference, b8 as MentionedContext, b9 as MentionedEntityContext, ba as NO_VALUE_OPERATORS, bb as NoValueOperator, bc as OPERATORS_BY_TYPE, bd as ObjectPermissions, be as Permission, bf as PhoneFilterValue, bg as QueryState, bh as ReasoningPartData, bi as RecordAgentEvent, bj as RelationOption, bk as RelationOptionsResponse, bl as RelationSource, bm as RetryPolicy, bn as RichtextTab, bo as Role, bp as SESSION_TERMINAL_STATUSES, bq as SessionApprovalMode, br as SortDirection, bs as StreamEventCompactionEnd, bt as StreamEventCompactionFailed, bu as StreamEventCompactionStart, bv as StreamEventMessagePersisted, bw as StreamEventMessageUpdated, bx as StreamEventMissionUpdate, by as StreamEventTodoPlanUpdate, bz as StreamEventUsage, bA as SystemPermissions, bB as TODO_PLAN_STATUSES, bC as TODO_STATUSES, bD as TabType, bE as TableSource, bF as TerminalSessionStatus, bG as TextPartData, bH as ThinkingPartData, bI as ToolImpact, bJ as ToolPartData, bK as ToolPartErrorCode, bL as ToolPartState, bM as UpdateObjectInput, bN as UpdateRoleInput, bO as UpdateViewInput, bP as UserRoleAssignment, bQ as ViewOverlay, bR as accessLevelToActions, bS as actionsToAccessLevel, bT as agentDisplayName, bU as getRollupFilterOperators, bV as isDetailView, bW as isFieldGroup, bX as isListView, bY as isNoValueOperator, bZ as isRelationGroup, b_ as isTerminalSessionStatus, b$ as multiselectOptionWriteSchema, c0 as parseAttributeConfig, c1 as parseAttributeConfigForCreate, c2 as parseAttributeConfigForUpdate, c3 as selectOptionWriteSchema, c4 as statusGroupSchema, c5 as statusOptionWriteSchema } from './index-AJeEKoy6.js';
3
- import { i as ComputedValueType, j as ComputedReturnType, f as AttributeType, k as ComputedOptionsSource, l as ComputedDependency, m as ComputedPlan, e as RollupAttribute, n as ComputedFormulaAstNode, A as Attribute, o as LocationGranularity, p as Location, F as FormulaAttribute, D as DateAttribute, q as DateRangeValue, r as DocumentAttribute, d as StatusAttribute, c as SelectAttribute, b as MultiselectAttribute, s as Phone, t as Currency, U as UserAttribute, T as TextAttribute, u as PropertySchema, g as CheckboxAttribute, C as CurrencyAttribute, v as TimeFormat, N as NumberAttribute, P as PhoneAttribute, O as Option, L as LocationAttribute, w as FormulaReturnType, R as RelationAttribute, B as BilateralConfig, S as SingleRelationAttribute, M as MultiRelationAttribute, x as RelationTarget, a as RichtextAttribute, y as RollupFunction, z as UserReferenceType } from './attributes-_b3Db8vT.js';
4
- export { E as AttributeGroup, G as BaseAttribute, h as ComputedAttributeState, H as ComputedFieldKind, I as ComputedFormulaBinaryNode, J as ComputedFormulaBinaryOperator, K as ComputedFormulaCallNode, Q as ComputedFormulaLiteralNode, V as ComputedFormulaParseError, W as ComputedFormulaPathNode, X as ComputedStateStatus, Y as DateFormat, Z as DateValue, _ as NumberUnit, $ as OptionPropertyAttribute, a0 as PropertyAttribute, a1 as PropertyType, a2 as RELATION_TARGET_ANY, a3 as RichTextAttribute, a4 as StatusGroup, a5 as hasOptions, a6 as inferInverseCardinality, a7 as isAttributeSortable, a8 as isBilateralRelation, a9 as isUniversalRelation, aa as parseComputedFormula, ab as resolvePropertyDefinitions } from './attributes-_b3Db8vT.js';
1
+ import { S as SortRule, F as FilterState, V as ViewType, a as ViewConfig, C as ConfigOverrides, b as FilterOperator, D as DetailViewConfig, c as DetailViewDefinition, d as SidePanelConfig, e as Field, A as AttributeGroupField, f as FieldGroup, R as RelationGroup, G as Group, T as TableTab, g as CreateMode, E as EmailsTab, M as MeetingsTab, h as Tab, L as ListViewConfig, i as ListViewDefinition, j as ViewDefinition, k as ListViewTab, l as FilterValue, m as FilterRule, n as DynamicValue, o as RelativeDateValue } from './index-SpFpkWVC.js';
2
+ export { p as ActivityTab, q as AddAttributeInput, r as AdvancedFilterState, s as CreateCustomObjectInput, t as CreateViewInput, u as CurrencyFilterValue, v as CustomTab, w as DayMonthValue, x as DocumentsTab, y as EdgeQuantifier, z as ExtendedFilterRule, B as FilterCombinator, H as FilterGroup, I as FormDensity, J as FormTab, K as FormsTab, N as InverseSource, O as ListViewLayout, P as NO_VALUE_OPERATORS, Q as NoValueOperator, U as OPERATORS_BY_TYPE, W as PhoneFilterValue, X as QueryState, Y as RelationOption, Z as RelationOptionsResponse, _ as RelationSource, $ as RichtextTab, a0 as SortDirection, a1 as TabType, a2 as TableSource, a3 as UpdateObjectInput, a4 as UpdateViewInput, a5 as ViewOverlay, a6 as getRollupFilterOperators, a7 as isDetailView, a8 as isFieldGroup, a9 as isListView, aa as isNoValueOperator, ab as isRelationGroup, ac as multiselectOptionWriteSchema, ad as parseAttributeConfig, ae as parseAttributeConfigForCreate, af as parseAttributeConfigForUpdate, ag as selectOptionWriteSchema, ah as statusGroupSchema, ai as statusOptionWriteSchema } from './index-SpFpkWVC.js';
3
+ import { i as ComputedValueType, j as ComputedReturnType, f as AttributeType, k as ComputedOptionsSource, l as ComputedDependency, m as ComputedPlan, e as RollupAttribute, n as ComputedFormulaAstNode, A as Attribute, o as LocationGranularity, p as Location, F as FormulaAttribute, D as DateAttribute, q as DateRangeValue, r as DocumentAttribute, d as StatusAttribute, c as SelectAttribute, b as MultiselectAttribute, s as Phone, t as Currency, U as UserAttribute, T as TextAttribute, u as PropertySchema, g as CheckboxAttribute, C as CurrencyAttribute, v as TimeFormat, w as PropertyAttribute, x as FormulaReturnType, L as LocationAttribute, O as Option, N as NumberAttribute, P as PhoneAttribute, R as RelationAttribute, B as BilateralConfig, S as SingleRelationAttribute, M as MultiRelationAttribute, y as RelationTarget, a as RichtextAttribute, z as RollupFunction, E as UserReferenceType } from './attributes-D8eHv5Kf.js';
4
+ export { G as AttributeGroup, H as BaseAttribute, h as ComputedAttributeState, I as ComputedFieldKind, J as ComputedFormulaBinaryNode, K as ComputedFormulaBinaryOperator, Q as ComputedFormulaCallNode, V as ComputedFormulaLiteralNode, W as ComputedFormulaParseError, X as ComputedFormulaPathNode, Y as ComputedStateStatus, Z as DateFormat, _ as DateValue, $ as NumberUnit, a0 as OptionPropertyAttribute, a1 as PropertyType, a2 as RELATION_TARGET_ANY, a3 as RichTextAttribute, a4 as StatusGroup, a5 as hasOptions, a6 as inferInverseCardinality, a7 as isAttributeSortable, a8 as isBilateralRelation, a9 as isUniversalRelation, aa as parseComputedFormula, ab as resolvePropertyDefinitions } from './attributes-D8eHv5Kf.js';
5
5
  import { IconName, MimeType, ColorId, CountryIso3, CurrencyCode } from '@stndrds/constants';
6
6
  import { Uuid, TenantId } from './utils.js';
7
7
  export { UserId, asTenantId, asUserId, deepEqual, generateId, indexBy } from './utils.js';
8
- import { a as ObjectRecord, D as DocumentLayout, T as Timestamps, R as ResourceVisibility, O as ObjectDefinition, L as ListViewTabVisibility } from './objects-A1ED9af-.js';
9
- export { b as DocumentLayoutVariant, F as FolderPreset, c as LIST_VIEW_TAB_VISIBILITIES, M as MAX_PRESET_DEPTH, d as ObjectAttribute, P as PresetNode, e as RESERVED_ATTRIBUTE_NAMES, f as RESERVED_OBJECT_NAMES, g as RESOURCE_VISIBILITIES, h as ReservedAttributeName, i as ReservedObjectName, S as SYSTEM_FIELD_NAMES, j as SystemFieldName } from './objects-A1ED9af-.js';
10
- import { M as MigrationDefinition } from './migrations-DcuJZ8qO.js';
11
- export { B as BuiltInTransform, S as SchemaOperation } from './migrations-DcuJZ8qO.js';
8
+ import { a as ObjectRecord, D as DocumentLayout, T as Timestamps, R as ResourceVisibility, O as ObjectDefinition, L as ListViewTabVisibility } from './objects-DgFojgwH.js';
9
+ export { b as DocumentLayoutVariant, F as FolderPreset, c as LIST_VIEW_TAB_VISIBILITIES, M as MAX_PRESET_DEPTH, d as ObjectAttribute, P as PresetNode, e as RESERVED_ATTRIBUTE_NAMES, f as RESERVED_OBJECT_NAMES, g as RESOURCE_VISIBILITIES, h as ReservedAttributeName, i as ReservedObjectName, S as SYSTEM_FIELD_NAMES, j as SystemFieldName, p as parseResourceVisibility } from './objects-DgFojgwH.js';
10
+ import { M as MigrationDefinition } from './migrations-B1kkIhIX.js';
11
+ export { B as BuiltInTransform, S as SchemaOperation } from './migrations-B1kkIhIX.js';
12
12
  import { ValidationError } from './exceptions.js';
13
13
  export { AccessDeniedError, AttributeInUseError, AttributeNotFoundError, AttributeUsage, ChangeTypeNotSupportedError, ConcurrentModificationError, DestructiveSyncNotAllowedError, DuplicateError, ForbiddenError, MemoryNotFoundError, MigrationTimeoutError, NotFoundError, NotImplementedError, ObjectNotFoundError, ObjectReferencedError, OrphanSystemAttributeError, ProtectedResourceError, ProtectedRoleError, RecordNotFoundError, RecordReference, RecordReferencedError, RepositoryError, RepositoryOperation, RoleNotFoundError, SchemaError, SchemaErrorCode, SchemaPlanNotFoundError, SearchBackendError, StorageError, StorageOperation, SyncCascadeError, SyncConflictError, SyncError, SystemEntityImmutableError, ValidationErrorDetail, isAttributeInUseError, isNotFoundError, isObjectReferencedError, isProtectedResourceError, isRecordReferencedError, isSchemaError, isValidationError } from './exceptions.js';
14
14
  import { StandardSchemaV1 } from '@standard-schema/spec';
15
15
  export { StandardSchemaV1 } from '@standard-schema/spec';
16
16
  import z, { z as z$1 } from 'zod';
17
- export { V as ValidationMessages } from './types-DqLi1tx1.js';
17
+ export { V as ValidationMessages } from './types-DYYFto8d.js';
18
18
  export { DEFAULT_VALIDATION_MESSAGES, formatZodErrors } from './validation/core/index.js';
19
- export { S as SCHEMA_LIMITS, c as colorIdSchema, d as detailTabSchema, a as detailViewConfigSchema, i as iconNameSchema, b as inverseSourceSchema, l as listViewConfigSchema, e as listViewTabSchema, p as parseViewConfig, r as relationSourceSchema, t as tableSourceSchema, v as viewConfigByTypeSchema, f as viewTypeSchema } from './all-D5SkjRst.js';
20
- export { a as createFormAttributeValidator, r as rejectUnknownAttributesOrThrow, b as validateDraft, d as validateDraftOrThrow, e as validateObject, f as validateObjectOrThrow } from './helpers-vQ6kp8ET.js';
19
+ export { S as SCHEMA_LIMITS, c as colorIdSchema, d as detailTabSchema, a as detailViewConfigSchema, i as iconNameSchema, b as inverseSourceSchema, l as listViewConfigSchema, e as listViewTabSchema, p as parseViewConfig, r as relationSourceSchema, t as tableSourceSchema, v as viewConfigByTypeSchema, f as viewTypeSchema } from './all-C_tC90ZM.js';
20
+ export { a as createFormAttributeValidator, r as rejectUnknownAttributesOrThrow, b as validateDraft, d as validateDraftOrThrow, e as validateObject, f as validateObjectOrThrow } from './helpers-DyoPqiSz.js';
21
21
  export { createCheckboxValidator } from './validation/primitives/checkbox.js';
22
22
  export { createDateValidator } from './validation/primitives/date.js';
23
23
  export { createNumberValidator } from './validation/primitives/number.js';
@@ -118,7 +118,25 @@ interface ListOptions {
118
118
  include?: string[];
119
119
  }
120
120
 
121
- type CountMode = "none" | "estimated" | "exact";
121
+ declare const COUNT_MODES: readonly ["none", "estimated", "exact"];
122
+ type CountMode = (typeof COUNT_MODES)[number];
123
+ /**
124
+ * Narrow an untrusted value from an edge (HTTP body, query string) to a
125
+ * {@link CountMode}, or reject it.
126
+ *
127
+ * It lives beside the union so whoever changes the union sees the one gate that
128
+ * admits values into it. A `countMode` typed as `CountMode` on a request body is
129
+ * a claim, not a check: the mailbox endpoints forwarded the raw value into
130
+ * `list_email_thread_summaries`, which raises SQLSTATE 22023 for anything
131
+ * outside the three — and 22023 is not a mapped state, so plain bad input came
132
+ * back as a 500.
133
+ *
134
+ * Throws {@link ValidationError} rather than a transport exception so it can be
135
+ * used below the controller layer; the HTTP filter maps its code to 400.
136
+ */
137
+ declare function parseCountMode(value: unknown): CountMode;
138
+ /** As {@link parseCountMode}, but absent stays absent rather than defaulting. */
139
+ declare function parseOptionalCountMode(value: unknown): CountMode | undefined;
122
140
  /**
123
141
  * Row cap for `countMode: "estimated"`.
124
142
  *
@@ -126,7 +144,9 @@ type CountMode = "none" | "estimated" | "exact";
126
144
  * tenant. Below the cap the count happens to be exact; at the cap it means "at
127
145
  * least this many", and `totalIsExact` is what tells the two apart.
128
146
  *
129
- * Mirrored in `list_filtered_object_records`; change both together.
147
+ * Mirrored in two SQL functions — `list_filtered_object_records` and
148
+ * `list_email_thread_summaries` (the mailbox toolbar's count) — each carrying
149
+ * the literal rather than reading this constant. Change all three together.
130
150
  */
131
151
  declare const ESTIMATED_COUNT_CAP = 10000;
132
152
  /** Canonical continuation metadata shared by collection and search responses. */
@@ -701,6 +721,245 @@ interface AssignActorRoleInput {
701
721
  assignedBy?: Uuid | null;
702
722
  }
703
723
 
724
+ /**
725
+ * Scope of a permission rule.
726
+ * - `object`: Controls access to an entire object type (business data)
727
+ * - `system`: Controls access to platform resources (people, workspace, API keys, etc.)
728
+ */
729
+ type PermissionScope = "object" | "system";
730
+ /**
731
+ * Actions that can be performed on a resource.
732
+ *
733
+ * `observe` is intentionally excluded from `ALL_ACTIONS` ("full" preset) — it
734
+ * is only meaningful for runnable resources (agent sessions) where it grants
735
+ * read-only visibility on the run timeline without implying CRUD.
736
+ */
737
+ type Action = "read" | "create" | "update" | "delete" | "manage" | "observe";
738
+ /**
739
+ * System resources that can be managed.
740
+ * - `people`: User profiles, invitations, roles and permissions
741
+ * - `workspace`: Tenant settings and workspace-level configuration
742
+ * - `architect`: Architect settings, templates, and configurations
743
+ */
744
+ type SystemResource = "people" | "workspace" | "architect" | "feature-flags" | "files" | "views" | "forms" | "documents" | "audit" | "api-keys" | "connectors" | "env-vars" | "session";
745
+ /**
746
+ * Preset access levels for simplified permission configuration.
747
+ * - `full`: All CRUD actions
748
+ * - `read-only`: Only read action
749
+ * - `none`: No actions
750
+ * - `custom`: Manual selection of individual actions
751
+ */
752
+ type AccessLevel = "full" | "read-only" | "none" | "custom";
753
+ declare const ALL_ACTIONS: Action[];
754
+ /**
755
+ * Derive an AccessLevel from a list of actions.
756
+ */
757
+ declare function actionsToAccessLevel(actions: Action[]): AccessLevel;
758
+ /**
759
+ * Convert an AccessLevel preset to its corresponding actions.
760
+ */
761
+ declare function accessLevelToActions(level: Exclude<AccessLevel, "custom">): Action[];
762
+ /**
763
+ * Role definition - Groups permissions together.
764
+ *
765
+ * Roles are tenant-scoped and can be system-defined (immutable) or custom.
766
+ *
767
+ * @example
768
+ * ```typescript
769
+ * const ownerRole: Role = {
770
+ * id: "role-123",
771
+ * tenantId: "tenant-456",
772
+ * name: "owner",
773
+ * label: "Owner",
774
+ * description: "Full access to all platform features and data",
775
+ * system: true,
776
+ * createdAt: new Date(),
777
+ * updatedAt: new Date(),
778
+ * };
779
+ * ```
780
+ */
781
+ interface Role extends Timestamps {
782
+ id: Uuid;
783
+ tenantId: Uuid;
784
+ /**
785
+ * Technical name (unique per tenant, used in code).
786
+ * Examples: "owner", "member", "sales_manager"
787
+ */
788
+ name: string;
789
+ /**
790
+ * Display name shown in UI.
791
+ */
792
+ label: string;
793
+ /**
794
+ * Optional description of the role's purpose.
795
+ */
796
+ description?: string;
797
+ /**
798
+ * If true, this role cannot be modified or deleted.
799
+ * Used for built-in roles like "owner".
800
+ */
801
+ system: boolean;
802
+ }
803
+ /**
804
+ * Permission definition - Grants specific actions on a target.
805
+ *
806
+ * A permission belongs to a role and defines what actions are allowed
807
+ * on a specific target (object or system resource).
808
+ *
809
+ * @example
810
+ * ```typescript
811
+ * // Allow read and update on companies object
812
+ * const permission: Permission = {
813
+ * id: "perm-123",
814
+ * roleId: "role-456",
815
+ * scope: "object",
816
+ * target: "companies",
817
+ * actions: ["read", "update"],
818
+ * createdAt: new Date(),
819
+ * };
820
+ *
821
+ * // Wildcard permission for all objects
822
+ * const wildcardPerm: Permission = {
823
+ * id: "perm-789",
824
+ * roleId: "role-456",
825
+ * scope: "object",
826
+ * target: "*",
827
+ * actions: ["read", "create", "update", "delete"],
828
+ * createdAt: new Date(),
829
+ * };
830
+ * ```
831
+ */
832
+ interface Permission {
833
+ id: Uuid;
834
+ roleId: Uuid;
835
+ /**
836
+ * Scope of this permission.
837
+ */
838
+ scope: PermissionScope;
839
+ /**
840
+ * Target of the permission.
841
+ * - For `object` scope: object name (e.g., "companies") or "*" for all
842
+ * - For `system` scope: system resource (e.g., "people", "workspace") or "*" for all
843
+ */
844
+ target: string;
845
+ /**
846
+ * Actions allowed on the target.
847
+ */
848
+ actions: Action[];
849
+ createdAt: Date;
850
+ }
851
+ /**
852
+ * Links a user profile to a role within a tenant.
853
+ *
854
+ * A user can have multiple roles, and their permissions are additive (union).
855
+ *
856
+ * Note: `userProfileId` references UserProfile.id from the user_profiles table,
857
+ * NOT the auth provider ID (authId). This keeps permissions tied to the
858
+ * application's user management, not the authentication layer.
859
+ */
860
+ interface UserRoleAssignment {
861
+ id: Uuid;
862
+ /**
863
+ * User profile ID (UserProfile.id from user_profiles table).
864
+ * This links to the application's user management system,
865
+ * not the auth provider's user ID.
866
+ */
867
+ userProfileId: Uuid;
868
+ roleId: Uuid;
869
+ tenantId: Uuid;
870
+ /**
871
+ * When the role was assigned.
872
+ */
873
+ assignedAt: Date;
874
+ /**
875
+ * Actor ID of who assigned this role (for audit trail).
876
+ */
877
+ assignedBy?: Uuid;
878
+ }
879
+ /**
880
+ * Computed permissions for a user.
881
+ *
882
+ * This is the merged result of all roles assigned to a user.
883
+ * Returned by the API for permission checks.
884
+ */
885
+ interface EffectivePermissions {
886
+ /**
887
+ * Object-level permissions.
888
+ * Key is the object name, value is array of allowed actions.
889
+ * Special key "*" means permission applies to all objects.
890
+ */
891
+ objectPermissions: Record<string, Action[]>;
892
+ /**
893
+ * System-level permissions.
894
+ * Key is the system resource (people, workspace), value is array of allowed actions.
895
+ * Special key "*" means permission applies to all system resources.
896
+ */
897
+ systemPermissions: Record<string, Action[]>;
898
+ }
899
+ /**
900
+ * Permissions for a specific object.
901
+ * Convenience type for frontend use.
902
+ */
903
+ interface ObjectPermissions {
904
+ canRead: boolean;
905
+ canCreate: boolean;
906
+ canUpdate: boolean;
907
+ canDelete: boolean;
908
+ canManage: boolean;
909
+ }
910
+ /**
911
+ * Permissions for a specific system resource.
912
+ * Convenience type for frontend use.
913
+ */
914
+ interface SystemPermissions {
915
+ canRead: boolean;
916
+ canCreate: boolean;
917
+ canUpdate: boolean;
918
+ canDelete: boolean;
919
+ canManage: boolean;
920
+ }
921
+ /**
922
+ * Input for creating a new role.
923
+ * TenantId is automatically set from TenantContext.
924
+ */
925
+ interface CreateRoleInput {
926
+ name: string;
927
+ label: string;
928
+ description?: string;
929
+ /** Framework-owned default roles are system:true (immutable, auto-assignable). Custom roles default false. */
930
+ system?: boolean;
931
+ }
932
+ /**
933
+ * Input for updating an existing role.
934
+ */
935
+ interface UpdateRoleInput {
936
+ label?: string;
937
+ description?: string;
938
+ }
939
+ /**
940
+ * Input for creating a permission.
941
+ */
942
+ interface CreatePermissionInput {
943
+ scope: PermissionScope;
944
+ target: string;
945
+ /**
946
+ * Actions allowed on the target.
947
+ */
948
+ actions: Action[];
949
+ }
950
+ /**
951
+ * Input for assigning a role to a user.
952
+ */
953
+ interface AssignRoleInput {
954
+ /**
955
+ * User profile ID (UserProfile.id).
956
+ */
957
+ userProfileId: Uuid;
958
+ roleId: Uuid;
959
+ tenantId: Uuid;
960
+ assignedBy?: Uuid;
961
+ }
962
+
704
963
  /**
705
964
  * Legacy permission payload stored with an API key.
706
965
  * Runtime authorization uses the API key actor's effective permissions.
@@ -778,6 +1037,54 @@ interface EnvVarEntry {
778
1037
  updatedAt: string;
779
1038
  }
780
1039
 
1040
+ /**
1041
+ * Type of mentionable entity
1042
+ */
1043
+ type MentionEntityType = "user" | "record" | (string & {});
1044
+ /**
1045
+ * A mention reference stored with a message
1046
+ */
1047
+ interface MentionReference {
1048
+ /** Unique ID for this mention instance */
1049
+ id: string;
1050
+ /** Entity type (user, record, or custom) */
1051
+ type: MentionEntityType;
1052
+ /** Entity ID (user ID or record ID) */
1053
+ entityId: string;
1054
+ /** Display label at time of mention (cached for display even if entity is deleted) */
1055
+ label: string;
1056
+ /** Object name for records, undefined for users */
1057
+ objectName?: string;
1058
+ /** Start position in the message text */
1059
+ startIndex: number;
1060
+ /** End position in the message text */
1061
+ endIndex: number;
1062
+ }
1063
+ /**
1064
+ * Context data for a mentioned entity (sent to AI)
1065
+ */
1066
+ interface MentionedEntityContext {
1067
+ /** Entity type */
1068
+ type: MentionEntityType;
1069
+ /** Entity ID */
1070
+ entityId: string;
1071
+ /** Display label */
1072
+ label: string;
1073
+ /** Object name for records */
1074
+ objectName?: string;
1075
+ /** Additional context data (record values, user details, etc.) */
1076
+ data?: Record<string, unknown>;
1077
+ }
1078
+ /**
1079
+ * Full mention context for AI
1080
+ */
1081
+ interface MentionedContext {
1082
+ /** All mentioned entities with their context data */
1083
+ entities: MentionedEntityContext[];
1084
+ /** Summary text for AI system prompt */
1085
+ summary: string;
1086
+ }
1087
+
781
1088
  declare const NOTIFICATION_KINDS: readonly ["fyi", "task", "question", "handoff", "system"];
782
1089
  type NotificationKind = (typeof NOTIFICATION_KINDS)[number];
783
1090
  declare const NOTIFICATION_PRIORITIES: readonly ["low", "normal", "high", "urgent"];
@@ -1054,113 +1361,1248 @@ interface FieldHistoryEntry {
1054
1361
  }
1055
1362
 
1056
1363
  /**
1057
- * The minimum every capability predicate in this file reads: the type, plus
1058
- * whatever else of a full `Attribute` the caller happens to hold. Exported so
1059
- * callers that only have a partial attribute a plan's proposed attribute, a
1060
- * schema snapshot row can ask the same questions as callers holding the real
1061
- * thing, instead of restating the rules.
1062
- */
1063
- type AttributeLike = Pick<Attribute, "type"> & Partial<Attribute>;
1064
- type AttributeLifecycleCapabilities = {
1065
- active: boolean;
1066
- deprecated: boolean;
1067
- visibleInArchitect: boolean;
1068
- visibleInRuntime: boolean;
1069
- warningWhenDeprecated: boolean;
1070
- };
1071
- type AttributeStorageMode = "value" | "edge" | "computed";
1072
- type AttributeCardinality = "one" | "many";
1073
- type AttributePolymorphicCapability = "none" | "code-only" | "internal";
1074
- type AttributeStorageCapabilities = {
1075
- mode: AttributeStorageMode;
1076
- cardinality: AttributeCardinality;
1077
- edgeBacked: boolean;
1078
- preservesExistingValues: boolean;
1079
- qualifiedProperties: boolean;
1080
- polymorphic: AttributePolymorphicCapability;
1081
- maxItems: boolean;
1082
- };
1083
- type AttributeRequiredCapability = "allowed" | "forbidden";
1084
- type AttributeDefaultValueCapability = "static" | "automatic" | "forbidden";
1085
- type AttributeAuthoringCapabilities = {
1086
- editable: boolean;
1087
- readOnly: boolean;
1088
- directEdit: boolean;
1089
- required: AttributeRequiredCapability;
1090
- defaultValue: AttributeDefaultValueCapability;
1091
- placeholder: boolean;
1092
- maxItems: boolean;
1093
- };
1094
- type AttributePresentationCapabilities = {
1095
- formField: boolean;
1096
- tableCell: boolean;
1097
- defaultColumn: boolean;
1098
- compactDisplay: boolean;
1099
- popoverEditor: boolean;
1100
- placeholder: boolean;
1101
- warningWhenDeprecated: boolean;
1102
- };
1103
- type AttributeQueryCapabilities = {
1104
- filterable: boolean;
1105
- searchable: boolean;
1106
- sortable: boolean;
1107
- groupable: boolean;
1108
- kanbanGroupable: boolean;
1109
- operators: readonly FilterOperator[];
1110
- };
1111
- type AttributeAgentCapabilities = {
1112
- readable: boolean;
1113
- writable: boolean;
1114
- compactReadable: boolean;
1115
- contentReadable: boolean;
1116
- requiresDedicatedTool: boolean;
1117
- };
1118
- type AttributeExchangeCapabilities = {
1119
- importable: boolean;
1120
- exportable: boolean;
1121
- schemaExportable: boolean;
1122
- metadataExportable: boolean;
1123
- };
1124
- type AttributeCapabilities = {
1125
- lifecycle: AttributeLifecycleCapabilities;
1126
- storage: AttributeStorageCapabilities;
1127
- authoring: AttributeAuthoringCapabilities;
1128
- presentation: AttributePresentationCapabilities;
1129
- query: AttributeQueryCapabilities;
1130
- agent: AttributeAgentCapabilities;
1131
- exchange: AttributeExchangeCapabilities;
1132
- };
1133
- declare const ATTRIBUTE_FILTER_OPERATORS: Readonly<Record<Exclude<AttributeType, "rollup">, readonly FilterOperator[]>>;
1134
- declare function getAttributeCapabilities(attribute: AttributeLike): AttributeCapabilities;
1135
- declare function getAttributeFilterOperators(attribute: AttributeLike): readonly FilterOperator[];
1136
- declare function isAttributeFilterable(attribute: AttributeLike): boolean;
1137
- declare function isAttributeSearchable(attribute: AttributeLike): boolean;
1138
- declare function isAttributeGroupable(attribute: AttributeLike): boolean;
1139
- declare function isAttributeKanbanGroupable(attribute: AttributeLike): boolean;
1364
+ * Outcome of a compaction pass: a no-op (context already small enough), an LLM
1365
+ * `summary`, or a degraded `truncation` (the summarizer failed/timed out/returned
1366
+ * empty, so older messages were dropped and a notice injected). Canonical home —
1367
+ * `runtime` re-exports this and `react` imports it; never duplicate the literals.
1368
+ */
1369
+ type CompactionStrategy = "no-op" | "summary" | "truncation";
1370
+ type AgentRunStatus = "pending" | "running" | "completed" | "failed" | "cancelled" | "paused";
1371
+ type AgentSessionStatus = "active" | "idle" | "completed" | "failed" | "cancelled" | "waiting_human" | "waiting_agents" | "timeout" | "expired";
1372
+ /**
1373
+ * The flat {@link AgentSessionStatus} word answers three independent questions
1374
+ * at once (is it running? what is it parked on? how did it end?) — which is
1375
+ * how `timeout`/`expired` once closed sessions the browser kept reconnecting
1376
+ * to. The structured form separates the axes so predicates become structural
1377
+ * (`phase === "terminal"`) and a new park reason can never be forgotten by a
1378
+ * hand-enumerated list.
1379
+ */
1380
+ type SessionPhase = "queued" | "running" | "parked" | "terminal";
1381
+ /** What a parked session waits on. Extensible: a new reason is a new value here, never a new predicate. */
1382
+ type SessionParkedOn = "human" | "agents";
1383
+ /** How a terminal session ended — the exact legacy words, unchanged. */
1384
+ type SessionOutcome = "completed" | "failed" | "cancelled" | "timeout" | "expired";
1385
+ /**
1386
+ * Structured session state. Illegal combinations are unrepresentable at the
1387
+ * database (CHECK constraints) and refused by the single runtime writer
1388
+ * (`resolveSessionState`, which throws instead of emitting):
1389
+ * - `parkedOn` present iff `phase === "parked"`;
1390
+ * - `humanRequestIds` present iff `parkedOn === "human"` the in-flight
1391
+ * request ids (AI SDK vocabulary verbatim: `approvalId` for approval-gated
1392
+ * calls, `toolCallId` for `ask_questions`) the UI must render;
1393
+ * - `outcome` present iff `phase === "terminal"`.
1394
+ */
1395
+ interface SessionState {
1396
+ phase: SessionPhase;
1397
+ parkedOn?: SessionParkedOn;
1398
+ humanRequestIds?: string[];
1399
+ outcome?: SessionOutcome;
1400
+ }
1401
+ /** Structural terminality — replaces membership tests against a hand-kept list. */
1402
+ declare function isTerminalState(state: SessionState): boolean;
1403
+ /**
1404
+ * The 1:1 legacy mapping, both directions. `sessionStateToLegacyStatus` is the
1405
+ * TS mirror of the migration's generated `status` column (byte-identical
1406
+ * words); `legacyStatusToSessionState` reads rows written before the
1407
+ * migration's backfill — which cannot know `humanRequestIds`, so a legacy
1408
+ * `waiting_human` maps to `parked`/`human` with an empty id list (the runtime
1409
+ * writer itself refuses to EMIT that shape; only legacy reads produce it).
1410
+ */
1411
+ declare function sessionStateToLegacyStatus(state: SessionState): AgentSessionStatus;
1412
+ declare function legacyStatusToSessionState(status: AgentSessionStatus): SessionState;
1413
+ /**
1414
+ * Statuses a session never leaves. Lives beside the union it partitions so
1415
+ * every consumer shares it — runtime orchestration decides whether to keep
1416
+ * working, and the React realtime lifecycle decides whether to stay connected.
1417
+ * Splitting them is how `timeout` and `expired` came to close a session on the
1418
+ * server while the browser kept reconnecting to it.
1419
+ */
1420
+ declare const SESSION_TERMINAL_STATUSES: readonly ["completed", "failed", "cancelled", "timeout", "expired"];
1421
+ type TerminalSessionStatus = (typeof SESSION_TERMINAL_STATUSES)[number];
1422
+ declare function isTerminalSessionStatus(status: AgentSessionStatus): status is TerminalSessionStatus;
1423
+ type AgentSessionMode = "interactive" | "autonomous";
1424
+ /** Whether a class of tool call is confirmed by a human or executed straight away. */
1425
+ type ApprovalMode = "ask" | "auto";
1426
+ /**
1427
+ * An agent's declared stance per risk class. Code-owned and versioned: there is
1428
+ * deliberately no policy table (see the `agent_execution_policies` guardrail).
1429
+ */
1430
+ interface AgentApprovalPolicy {
1431
+ mutation: ApprovalMode;
1432
+ destructive: ApprovalMode;
1433
+ outward: ApprovalMode;
1434
+ }
1435
+ declare const DEFAULT_APPROVAL_POLICY: AgentApprovalPolicy;
1436
+ /**
1437
+ * The switch shown at the bottom-left of the composer. `auto` relaxes
1438
+ * `mutation` only — deletions and outward sends keep asking.
1439
+ */
1440
+ type SessionApprovalMode = "manual" | "auto";
1441
+ /** What the agent may do: investigate/plan, or execute the approved work. */
1442
+ type AgentWorkMode = "execute" | "plan";
1443
+ declare const TODO_PLAN_STATUSES: readonly ["active", "completed", "abandoned"];
1444
+ type AgentTodoPlanStatus = (typeof TODO_PLAN_STATUSES)[number];
1445
+ type TriggerEventType = "record.created" | "record.updated" | "record.deleted" | "form.submitted" | "agent.completed" | "webhook" | "schedule";
1446
+ type AgentTriggerType = Extract<TriggerEventType, "record.created" | "record.updated" | "record.deleted">;
1447
+ type ProviderName = "anthropic" | "openai" | "google" | "mistral";
1448
+ interface ModelDefinition {
1449
+ provider: ProviderName;
1450
+ model: string;
1451
+ maxTokens?: number;
1452
+ /**
1453
+ * Total context window in tokens (e.g. 200000 for Claude Sonnet).
1454
+ * Required by the compaction subsystem when this model is used as the
1455
+ * summary model; optional otherwise.
1456
+ */
1457
+ contextWindow?: number;
1458
+ }
1459
+ interface RetryPolicy {
1460
+ maxRetries: number;
1461
+ backoffMs: number;
1462
+ backoffMultiplier: number;
1463
+ }
1464
+ interface AgentExecutionConfig {
1465
+ maxConcurrentRuns: number;
1466
+ retryPolicy: RetryPolicy;
1467
+ timeoutMs: number;
1468
+ costLimitUsd?: number;
1469
+ }
1470
+ /**
1471
+ * Shared base config used by AgentDefinition, inline runs, and AgentSession.
1472
+ */
1473
+ interface AgentConfig {
1474
+ systemPrompt: string;
1475
+ model: ModelDefinition;
1476
+ tools?: string[];
1477
+ /**
1478
+ * MCP servers whose tools mount into this agent's toolchain. Ids opt in
1479
+ * explicitly; `"all"` mounts every server the viewer can see. Absent means
1480
+ * none — so agents that predate this field are tool-identical.
1481
+ */
1482
+ mcpServers?: string[] | "all";
1483
+ timeoutMs?: number;
1484
+ costLimitUsd?: number | null;
1485
+ canDelegate: boolean;
1486
+ maxDepth: number;
1487
+ maxTreeCostUsd?: number;
1488
+ critic?: CriticConfig;
1489
+ }
1490
+ interface CriticConfig {
1491
+ enabled: boolean;
1492
+ model?: ModelDefinition;
1493
+ systemPrompt?: string;
1494
+ maxRetries?: number;
1495
+ }
1496
+ /**
1497
+ * Standalone trigger definition (replaces embedded AgentTrigger[]).
1498
+ * Triggers are now first-class entities with their own lifecycle.
1499
+ */
1500
+ interface AgentTriggerDefinition {
1501
+ id: string;
1502
+ tenantId: string;
1503
+ definitionId: string;
1504
+ name?: string;
1505
+ eventType: TriggerEventType;
1506
+ objectId?: string;
1507
+ watchedFields?: string[];
1508
+ formDefinitionId?: string;
1509
+ sourceAgentId?: string;
1510
+ webhookPath?: string;
1511
+ cronExpression?: string;
1512
+ timezone?: string;
1513
+ filter?: FilterState;
1514
+ inputBuilder?: string;
1515
+ debounceMs?: number;
1516
+ enabled: boolean;
1517
+ lastFiredAt?: Date;
1518
+ createdAt: Date;
1519
+ updatedAt: Date;
1520
+ }
1521
+ interface AgentSchedule {
1522
+ cron: string;
1523
+ timezone?: string;
1524
+ enabled: boolean;
1525
+ input?: Record<string, unknown>;
1526
+ inputBuilder?: string;
1527
+ }
1140
1528
  /**
1141
- * The type a filter on this attribute actually compares against. Identity for
1142
- * every ordinary attribute; for a rollup it unfolds the aggregation:
1143
- * `earliest`/`latest` compare dates, `original` compares the target attribute's
1144
- * own type, and every other function (count/sum/avg/min/max/…) compares numbers.
1145
- *
1146
- * This is the single place that knowledge lives: operator resolution and value
1147
- * canonicalization both read it, so a rollup can never be offered numeric
1148
- * operators while its value is canonicalized as something else.
1529
+ * Declarative trigger carried by an {@link AgentBlueprint}. The boot sync
1530
+ * reconciles the agent's AgentTriggerDefinition rows to match, using `name`
1531
+ * as the stable identity.
1149
1532
  */
1150
- declare function resolveEffectiveFilterType(attribute: AttributeLike): AttributeType;
1151
-
1152
1533
  /**
1153
- * Common configuration for all builders (Objects & Attributes)
1534
+ * System permission an actor must hold to see and use an agent. When
1535
+ * declared, the agent listing and session-creation gates hide/refuse the
1536
+ * agent for any actor lacking `action` on `resource` — checked via
1537
+ * `PermissionService.canAccessSystemByActor`. Absent by default: the
1538
+ * overwhelming majority of agents are visible to every actor.
1154
1539
  */
1155
- interface BuilderConfig {
1156
- /**
1157
- * Technical name (snake_case, kebab-case, camelCase)
1158
- * Used as identifier in database and API
1159
- */
1540
+ interface AgentRequiredPermission {
1541
+ resource: SystemResource;
1542
+ action: Action;
1543
+ }
1544
+ interface AgentTriggerBlueprint {
1545
+ name: string;
1546
+ eventType: TriggerEventType;
1547
+ objectId?: string;
1548
+ watchedFields?: string[];
1549
+ formDefinitionId?: string;
1550
+ sourceAgentId?: string;
1551
+ webhookPath?: string;
1552
+ cronExpression?: string;
1553
+ timezone?: string;
1554
+ filter?: FilterState;
1555
+ inputBuilder?: string;
1556
+ debounceMs?: number;
1557
+ enabled: boolean;
1558
+ }
1559
+ /**
1560
+ * Code-declared agent definition produced by the `agent()` builder.
1561
+ * Contains everything an AgentDefinition needs except runtime-assigned
1562
+ * fields (id, tenantId, createdBy, timestamps). `system: true` blueprints
1563
+ * are seeded/reconciled at boot and immutable through the public API.
1564
+ */
1565
+ interface AgentBlueprint {
1160
1566
  name: string;
1161
1567
  /**
1162
- * Human-readable label
1163
- * Used in UI
1568
+ * Display text shown wherever this agent's identity is rendered in the
1569
+ * UI `undefined` falls back to `name`. A separate concern from `name`
1570
+ * on purpose: `name` is the stable identity the boot sync matches rows
1571
+ * on (`system-agent-sync.service.ts`), so renaming the display text (or
1572
+ * translating it) must never require touching that identity.
1573
+ */
1574
+ label?: string;
1575
+ icon?: string;
1576
+ description?: string;
1577
+ systemPrompt: string;
1578
+ model: ModelDefinition;
1579
+ tools?: string[];
1580
+ schedule?: AgentSchedule;
1581
+ config: AgentExecutionConfig;
1582
+ canDelegate?: boolean;
1583
+ maxDepth?: number;
1584
+ maxTreeCostUsd?: number;
1585
+ /**
1586
+ * MCP servers this agent may use (see `AgentConfig.mcpServers`). Absent
1587
+ * means none — an agent that never declares this stays tool-identical to
1588
+ * one predating the field. Reconciled by the boot sync like the other
1589
+ * optional config fields (`SYNCED_FIELDS`).
1590
+ */
1591
+ mcpServers?: string[] | "all";
1592
+ system: boolean;
1593
+ /** Code-declared agents are workspace-visible; private is runtime-only. */
1594
+ visibility: ResourceVisibility;
1595
+ triggers: AgentTriggerBlueprint[];
1596
+ requiredPermission?: AgentRequiredPermission;
1597
+ approval?: AgentApprovalPolicy;
1598
+ }
1599
+ interface AgentMessageAttachment {
1600
+ id: string;
1601
+ name: string;
1602
+ mimeType: string;
1603
+ size: number;
1604
+ }
1605
+ /**
1606
+ * The text to show wherever an agent's identity is rendered — its `label`
1607
+ * when declared, else its technical `name` verbatim (never capitalised or
1608
+ * otherwise transformed here: every existing agent must keep rendering
1609
+ * exactly as it does today until it explicitly declares a `label`).
1610
+ */
1611
+ declare function agentDisplayName(agent: Pick<AgentBlueprint, "name" | "label">): string;
1612
+ /** A lightweight todo plan scoped to one agent session. */
1613
+ interface AgentTodoPlan {
1614
+ id: string;
1615
+ tenantId: string;
1616
+ sessionId: string;
1617
+ activationMessageId?: string;
1618
+ status: AgentTodoPlanStatus;
1619
+ todos: AITodoItem[];
1620
+ version: number;
1621
+ createdBy?: string;
1622
+ createdAt: Date;
1623
+ updatedAt: Date;
1624
+ completedAt?: Date;
1625
+ }
1626
+ /** UI-safe todo plan lifecycle snapshot returned by REST and realtime surfaces. */
1627
+ interface AgentTodoPlanView {
1628
+ id: string;
1629
+ sessionId: string;
1630
+ status: AgentTodoPlanStatus;
1631
+ todos: AITodoItem[];
1632
+ version: number;
1633
+ createdAt: string;
1634
+ updatedAt: string;
1635
+ completedAt?: string;
1636
+ }
1637
+ interface AgentDefinition {
1638
+ id: string;
1639
+ tenantId: string;
1640
+ name: string;
1641
+ /** Display text shown wherever this agent's identity is rendered — see `AgentBlueprint.label`. `undefined` falls back to `name`. */
1642
+ label?: string;
1643
+ icon?: string;
1644
+ description?: string;
1645
+ systemPrompt: string;
1646
+ model: ModelDefinition;
1647
+ tools?: string[];
1648
+ schedule?: AgentSchedule;
1649
+ config: AgentExecutionConfig;
1650
+ /**
1651
+ * MCP servers this definition may use (see `AgentConfig.mcpServers`).
1652
+ * Absent means none — a definition that predates this field is
1653
+ * tool-identical to one that never sets it. The opt-in is narrowed further
1654
+ * by the viewer's visibility at resolution time (`buildMcpToolset`); a
1655
+ * server id here that the viewer cannot see yields no tools from it.
1656
+ */
1657
+ mcpServers?: string[] | "all";
1658
+ /** Code-declared (immutable via public API); reconciled by the boot sync. */
1659
+ system: boolean;
1660
+ visibility: ResourceVisibility;
1661
+ ownedBy: string | null;
1662
+ createdBy: string;
1663
+ createdAt: Date;
1664
+ updatedAt: Date;
1665
+ deletedAt?: Date;
1666
+ canDelegate?: boolean;
1667
+ maxDepth?: number;
1668
+ maxTreeCostUsd?: number;
1669
+ critic?: CriticConfig;
1670
+ autoDecide?: boolean;
1671
+ requiredPermission?: AgentRequiredPermission;
1672
+ }
1673
+ interface AgentRun {
1674
+ id: string;
1675
+ definitionId?: string;
1676
+ parentRunId?: string;
1677
+ depth: number;
1678
+ inlineConfig?: AgentConfig;
1679
+ tenantId: string;
1680
+ createdBy?: string;
1681
+ status: AgentRunStatus;
1682
+ retryCount: number;
1683
+ input: Record<string, unknown>;
1684
+ output?: Record<string, unknown>;
1685
+ error?: string;
1686
+ tokenUsage?: {
1687
+ input: number;
1688
+ output: number;
1689
+ };
1690
+ costUsd?: number;
1691
+ startedAt?: Date;
1692
+ completedAt?: Date;
1693
+ createdAt: Date;
1694
+ sessionId?: string;
1695
+ rootRunId?: string;
1696
+ triggerId?: string;
1697
+ /** Source domain-event id that launched this run; used for redelivery idempotency. */
1698
+ sourceEventId?: string;
1699
+ treeCostUsd?: number;
1700
+ effectiveSystemPrompt?: string;
1701
+ /** Monotonic fencing token, incremented on each lease acquisition. */
1702
+ attemptId?: number;
1703
+ /** Worker id currently holding the execution lease (null when free). */
1704
+ leaseOwner?: string;
1705
+ /** When the current lease expires; a run is re-acquirable once past this. */
1706
+ leaseExpiresAt?: Date;
1707
+ }
1708
+ interface AgentSession {
1709
+ id: string;
1710
+ tenantId: string;
1711
+ mode: AgentSessionMode;
1712
+ /** Legacy flat word — read from the generated SQL column during the phase 1 transition; derived, never written directly. */
1713
+ status: AgentSessionStatus;
1714
+ /**
1715
+ * Structured state (phase 1) — the read model of the `phase` / `parked_on` /
1716
+ * `outcome` / `human_request_ids` columns. The single turn-end writer is
1717
+ * `resolveSessionState`; out-of-band terminalizations use
1718
+ * `terminalSessionState`. UI reads THIS, never the flat word.
1719
+ */
1720
+ state: SessionState;
1721
+ /**
1722
+ * D4's SECOND approval level: the human's per-conversation switch. The first
1723
+ * level is the agent's own code-declared {@link AgentApprovalPolicy}; both
1724
+ * are read together by `requiresApproval`, and this one relaxes the
1725
+ * `mutation` class ONLY.
1726
+ *
1727
+ * Required on read, not optional: the column is `NOT NULL DEFAULT 'auto'`,
1728
+ * so every read path yields a concrete posture. Writes may omit it — see
1729
+ * `AgentRepository.createSession`, whose input type drops it precisely
1730
+ * because the default lives in the database.
1731
+ */
1732
+ approvalMode: SessionApprovalMode;
1733
+ /** Orthogonal to approvalMode: Plan removes execution tools altogether. */
1734
+ workMode: AgentWorkMode;
1735
+ /** Monotonic CAS token for mode transitions and stale approval replay. */
1736
+ workModeVersion: number;
1737
+ /** On-demand tool groups already loaded for this session; stored truth, never inferred from history. */
1738
+ loadedToolsets: string[];
1739
+ definitionId?: string;
1740
+ inlineConfig?: AgentConfig;
1741
+ parentSessionId?: string;
1742
+ rootSessionId: string;
1743
+ depth: number;
1744
+ missionPrompt?: string;
1745
+ treeCostUsd: number;
1746
+ name?: string;
1747
+ metadata?: Record<string, unknown>;
1748
+ createdBy?: string;
1749
+ createdAt: Date;
1750
+ updatedAt: Date;
1751
+ completedAt?: Date;
1752
+ expiresAt?: Date;
1753
+ archivedAt?: Date;
1754
+ /** Per-actor read marker. Populated by list endpoints when the caller is known. */
1755
+ lastReadAt?: Date;
1756
+ /** Convenience flag: true when session has activity since `lastReadAt` (or never read). */
1757
+ isUnread?: boolean;
1758
+ }
1759
+ type ToolPartState = "streaming" | "running" | "completed" | "error";
1760
+ /**
1761
+ * Structured cause for a tool part that ended in `state: "error"` without the
1762
+ * tool having run. Lets the UI render a localized explanation instead of the
1763
+ * raw error string.
1764
+ */
1765
+ type ToolPartErrorCode = "output_limit_reached" | "interrupted";
1766
+ /**
1767
+ * Damage measured from a tool's input WITHOUT executing it — what a
1768
+ * confirmation card states so the human decides on numbers rather than on a
1769
+ * tool name (D3: "the confirmation quantifies the damage").
1770
+ *
1771
+ * Lives here, in the contracts package, because it is written to the message
1772
+ * part (see `approvalImpact` below) and therefore crosses runtime, adapters
1773
+ * and UI alike. The runtime's `ToolPreview`/`ToolRiskEntry` re-export it
1774
+ * rather than redefining it.
1775
+ */
1776
+ interface ToolImpact {
1777
+ /** One human sentence, used as the confirmation title. */
1778
+ label: string;
1779
+ /**
1780
+ * The authorization gate refused the call.
1781
+ *
1782
+ * A flag rather than a wording: the label is written server-side, where no
1783
+ * recipient locale is in reach, so a refusal used to read "Suppression
1784
+ * refusée" to every user in every language. The card renders its own copy
1785
+ * from this.
1786
+ */
1787
+ denied?: boolean;
1788
+ /**
1789
+ * What a delete preview is about to remove, as data rather than as a
1790
+ * sentence. The label is written server-side with no recipient locale in
1791
+ * reach, so "Supprimer 12 records" reached every user in every language —
1792
+ * and its thousands separator was pinned to `fr-FR` besides. The card
1793
+ * composes its own headline from this.
1794
+ */
1795
+ deletion?: {
1796
+ /** The record or document's own name; data, not copy. */
1797
+ target?: string;
1798
+ /** How many are going, when there is no single target to name. */
1799
+ count?: number;
1800
+ /** Days the deletion can still be undone, if it can. */
1801
+ restorableDays?: number;
1802
+ };
1803
+ /** Named counts, e.g. `{ records: 1284, brokenLinks: 63 }`. */
1804
+ counts?: Record<string, number>;
1805
+ warnings?: string[];
1806
+ }
1807
+ /**
1808
+ * LEGACY (chantier Q, 2026-08-09): the required-vs-optional split on human
1809
+ * requests was deleted — a question never blocks anything, and an
1810
+ * approval-family request always gates the turn, so nothing decides between
1811
+ * the two values anymore. The type and the `humanRequestNeed` part field
1812
+ * below survive only because persisted rows still carry the stamp; no reader
1813
+ * consults it.
1814
+ */
1815
+ type HumanRequestNeed = "required" | "optional";
1816
+ type AgentMessagePart = {
1817
+ type: "text";
1818
+ text: string;
1819
+ } | {
1820
+ type: "reasoning";
1821
+ text: string;
1822
+ } | {
1823
+ type: "error";
1824
+ error: string;
1825
+ errorClass?: string;
1826
+ } | {
1827
+ type: "tool";
1828
+ toolCallId: string;
1829
+ name: string;
1830
+ args: Record<string, unknown>;
1831
+ result?: unknown;
1832
+ error?: string;
1833
+ errorCode?: ToolPartErrorCode;
1834
+ state: ToolPartState;
1835
+ durationMs?: number;
1836
+ /**
1837
+ * Set when this call was suspended by the approval gate (a risky tool
1838
+ * awaiting a human decision — see `toolApproval` in the AI SDK config).
1839
+ * The part legitimately stays in its current state (`running`) with no
1840
+ * result/error while the human decides; presence of this id is what
1841
+ * distinguishes "waiting on a human" from "crashed mid-call" on resume,
1842
+ * for ANY tool name — unlike the HITL exemption, which is keyed on a
1843
+ * fixed set of tool names (`ask_questions`).
1844
+ */
1845
+ approvalId?: string;
1846
+ /**
1847
+ * What this suspended call would do, measured ONCE at suspension time
1848
+ * from the tool's declared `preview` (D13). Persisted next to
1849
+ * `approvalId` instead of being recomputed per reader: the same card is
1850
+ * rendered by three hosts (composer, notification queue, record
1851
+ * banner), and a queue of ten pending requests would otherwise fire ten
1852
+ * previews per host. The UI therefore shows it dated ("12 records · 4
1853
+ * min ago"), bounded by the 24h expiry.
1854
+ *
1855
+ * Absent when the tool declares no `preview` (a `mutation`-class tool
1856
+ * cannot have one, by construction of `ToolRiskEntry`) or when the
1857
+ * preview threw — a broken preview must never swallow the suspension.
1858
+ */
1859
+ approvalImpact?: ToolImpact;
1860
+ /**
1861
+ * The human's decision on `approvalId`: `true` approved, `false` refused.
1862
+ * Absent while the decision is still pending. The approver's identity is
1863
+ * carried by the audit trail, not this field.
1864
+ */
1865
+ approved?: boolean;
1866
+ /**
1867
+ * The human's optional rationale for `approved` (Finding 3, final
1868
+ * review): why they decided as they did. Purely informational — it
1869
+ * never changes what executes, only what the agent (and any audit
1870
+ * reader) is told about the decision.
1871
+ */
1872
+ approvalReason?: string;
1873
+ /**
1874
+ * LEGACY (chantier Q): the required-vs-optional split is gone — see
1875
+ * {@link HumanRequestNeed}. Approval suspensions still stamp
1876
+ * `"required"` (a statement of fact on the row), but no reader
1877
+ * consults the field anymore.
1878
+ */
1879
+ humanRequestNeed?: HumanRequestNeed;
1880
+ /**
1881
+ * Whether the session's `auto` mode would have let THIS call through —
1882
+ * i.e. whether offering "always allow this here" on its card would be
1883
+ * honest. Computed server-side at suspension by re-evaluating the one
1884
+ * owner of the decision (`requiresApproval`) with `sessionMode: "auto"`,
1885
+ * so it can never drift from the policy: it IS the policy, asked a
1886
+ * different question.
1887
+ *
1888
+ * It exists because the card cannot infer it. The tempting shortcut —
1889
+ * "no measured impact means `mutation`, since only `destructive` and
1890
+ * `outward` carry a `preview`" — is false: a preview that threw or timed
1891
+ * out also yields no impact, so a deletion would masquerade as a
1892
+ * mutation and the card would promise an ease the mode does not grant.
1893
+ *
1894
+ * Absent means "do not offer it", which is the fail-closed reading a
1895
+ * pre-migration row must produce.
1896
+ */
1897
+ approvalRelaxableByAuto?: boolean;
1898
+ } | {
1899
+ type: "file";
1900
+ fileId: string;
1901
+ name: string;
1902
+ mimeType: string;
1903
+ } | {
1904
+ type: "compaction";
1905
+ state: "in-progress";
1906
+ reason: "preflight_threshold" | "overflow_recovery";
1907
+ estimatedTokens?: number;
1908
+ reportedTokens?: number;
1909
+ } | {
1910
+ type: "compaction";
1911
+ state: "completed";
1912
+ tokensBefore: number;
1913
+ tokensAfter: number;
1914
+ tokensSaved: number;
1915
+ strategy: CompactionStrategy;
1916
+ durationMs: number;
1917
+ /**
1918
+ * Raw summary text produced by the summarizer LLM. Persisted so that
1919
+ * follow-up turns can reuse it instead of re-running the summarizer.
1920
+ */
1921
+ summary?: string;
1922
+ } | {
1923
+ type: "compaction";
1924
+ state: "failed";
1925
+ /** Human-readable reason from the CompactionImpossibleError. */
1926
+ reason: string;
1927
+ durationMs?: number;
1928
+ };
1929
+ /**
1930
+ * Persisted message in an agent session.
1931
+ * Unified type for both interactive and autonomous sessions.
1932
+ */
1933
+ interface AgentSessionMessage {
1934
+ id: string;
1935
+ sessionId: string;
1936
+ tenantId?: string;
1937
+ runId?: string;
1938
+ role: "user" | "assistant" | "system" | "tool";
1939
+ parts: AgentMessagePart[];
1940
+ attachments?: AgentMessageAttachment[];
1941
+ mentions?: MentionReference[];
1942
+ model?: ModelDefinition;
1943
+ tokenUsage?: {
1944
+ input: number;
1945
+ output: number;
1946
+ };
1947
+ metadata?: Record<string, unknown>;
1948
+ createdAt: Date;
1949
+ }
1950
+ interface AgentToolCall {
1951
+ id: string;
1952
+ name: string;
1953
+ arguments: Record<string, unknown>;
1954
+ result?: unknown;
1955
+ error?: string;
1956
+ durationMs?: number;
1957
+ /** Set by turn reconciliation when the tool call was cut off before completing. */
1958
+ errorCode?: ToolPartErrorCode;
1959
+ }
1960
+ interface RecordAgentEvent {
1961
+ type: AgentTriggerType;
1962
+ objectId: string;
1963
+ recordId: string;
1964
+ tenantId: string;
1965
+ data?: Record<string, unknown>;
1966
+ }
1967
+ interface FormSubmittedAgentEvent {
1968
+ type: "form.submitted";
1969
+ tenantId: string;
1970
+ formId: string;
1971
+ formName: string;
1972
+ submissionId: string;
1973
+ createdBy?: string;
1974
+ createdRecordIds: Record<string, string>;
1975
+ data: {
1976
+ formId: string;
1977
+ formName: string;
1978
+ submissionId: string;
1979
+ createdBy?: string;
1980
+ createdRecordIds: Record<string, string>;
1981
+ slotValues: Record<string, Record<string, unknown>>;
1982
+ stepValues: Record<string, Record<string, unknown>>;
1983
+ };
1984
+ }
1985
+ type AgentEvent = RecordAgentEvent | FormSubmittedAgentEvent;
1986
+ interface AgentDashboard {
1987
+ activeRuns: number;
1988
+ pendingRuns: number;
1989
+ failedToday: number;
1990
+ completedToday: number;
1991
+ totalCostToday: number;
1992
+ totalCostWeek: number;
1993
+ }
1994
+ /**
1995
+ * Message role in a conversation
1996
+ */
1997
+ type AIMessageRole = "user" | "assistant";
1998
+ /**
1999
+ * An AI model available for selection by the user.
2000
+ * Configured on the backend and exposed via GET /agent/models.
2001
+ */
2002
+ interface AIAvailableModel {
2003
+ /** Model identifier exposed to the UI (e.g. "claude-sonnet-4-6") */
2004
+ id: string;
2005
+ /**
2006
+ * Provider model ID sent to the underlying SDK. Defaults to `id` when omitted.
2007
+ * Use this to register multiple registry entries (different `contextWindow`,
2008
+ * `label`, etc.) that route to the same upstream model — e.g. a test entry
2009
+ * with a reduced context window for QA of the compaction system.
2010
+ */
2011
+ apiModelId?: string;
2012
+ /** Provider name (e.g. "anthropic", "google") */
2013
+ provider: string;
2014
+ /** Display label (e.g. "Claude 4.6 Sonnet") */
2015
+ label: string;
2016
+ /** Whether this is the default model */
2017
+ isDefault?: boolean;
2018
+ /**
2019
+ * Total context window in tokens. Optional — resolved from the vendored
2020
+ * models.dev snapshot when omitted. Set explicitly only for a deliberate cap
2021
+ * (e.g. a QA reduced-window entry).
2022
+ */
2023
+ contextWindow?: number;
2024
+ /**
2025
+ * Maximum output tokens. Optional — resolved from the models.dev snapshot when
2026
+ * omitted. Set explicitly only for a deliberate cap.
2027
+ */
2028
+ maxOutputTokens?: number;
2029
+ /**
2030
+ * Set true for a model newer than the models.dev snapshot. When true,
2031
+ * `contextWindow` and `maxOutputTokens` MUST be provided explicitly. Token
2032
+ * cost stays unknown (never developer-specified) until the snapshot lists it.
2033
+ */
2034
+ unverified?: boolean;
2035
+ /** If true, this model is used for generating compaction summaries */
2036
+ isCompactionModel?: boolean;
2037
+ /** If true, this model is used for fast utility generations (regex, formula, …) */
2038
+ isUtilityModel?: boolean;
2039
+ }
2040
+ /**
2041
+ * Tool call status during execution
2042
+ */
2043
+ type AIToolCallStatus = "pending" | "running" | "streaming" | "success" | "error";
2044
+ /**
2045
+ * Tool call information for chat UI
2046
+ */
2047
+ interface AIToolCall {
2048
+ /** Unique tool call ID */
2049
+ id: string;
2050
+ /** Tool name */
2051
+ name: string;
2052
+ /** Tool arguments */
2053
+ args?: Record<string, unknown>;
2054
+ /** Tool result (when complete) */
2055
+ result?: unknown;
2056
+ /** Error message if failed */
2057
+ error?: string;
2058
+ /** Execution status */
2059
+ status: AIToolCallStatus;
2060
+ }
2061
+ /**
2062
+ * Part type for message content
2063
+ */
2064
+ type AIChatMessagePartType = "text" | "attachment" | "tool" | "thinking" | "reasoning" | "todo" | "question" | "error" | "approval" | "record" | "search-results" | "compaction" | (string & {});
2065
+ /**
2066
+ * Data for text part
2067
+ */
2068
+ interface TextPartData {
2069
+ text: string;
2070
+ isStreaming?: boolean;
2071
+ /**
2072
+ * Mentions to paint as chips inside {@link text}, rather than leaving the
2073
+ * `@Label` the composer wrote as bare prose.
2074
+ *
2075
+ * Carried on the part and not on the message because the part registry hands a
2076
+ * component its `data` and nothing else — a message-level field would mean a
2077
+ * new context or a wider registry contract to deliver one string. Only user
2078
+ * messages have any: an assistant writes `@` as ordinary text.
2079
+ */
2080
+ mentions?: MentionReference[];
2081
+ }
2082
+ /**
2083
+ * Data for tool part (same as AIToolCall)
2084
+ */
2085
+ interface ToolPartData {
2086
+ id: string;
2087
+ name: string;
2088
+ args?: Record<string, unknown>;
2089
+ result?: unknown;
2090
+ error?: string;
2091
+ errorCode?: ToolPartErrorCode;
2092
+ status: AIToolCallStatus;
2093
+ /** Raw JSON string accumulating during tool-input streaming (cleared on tool_input_end) */
2094
+ partialInput?: string;
2095
+ /**
2096
+ * Set when this call is suspended pending a human approval decision — mirrors
2097
+ * `AgentMessagePart`'s `"tool"` variant so a reloaded conversation still shows
2098
+ * the call as awaiting a human rather than as a generic "running" state.
2099
+ */
2100
+ approvalId?: string;
2101
+ /**
2102
+ * What the suspended call would do, as measured ONCE at suspension time and
2103
+ * persisted on the part (D13) — never recomputed by the renderer. Because
2104
+ * the number is a snapshot of that moment and the request lives up to 24h,
2105
+ * the card must show it DATED ("3 records · il y a 4 min") rather than as a
2106
+ * live count. Absent when the tool declared no preview, or when the preview
2107
+ * threw: a degraded card, never a lost one.
2108
+ */
2109
+ approvalImpact?: ToolImpact;
2110
+ /**
2111
+ * The human's decision, once recorded: `true` approved, `false` refused,
2112
+ * `undefined` still pending. It has to reach the renderer, not just the
2113
+ * request: between the decision and the end of the re-execution the part
2114
+ * legitimately stays `running` WITH its `approvalId`, so a card keyed on
2115
+ * `approvalId` alone would come back offering two live buttons on a request
2116
+ * that is already settled.
2117
+ */
2118
+ approved?: boolean;
2119
+ /**
2120
+ * Whether the session's `auto` mode would have let this call through, so the
2121
+ * card knows if "always allow this here" is an honest offer. Mirrors
2122
+ * `AgentMessagePart`'s field of the same name — see it for why the card
2123
+ * cannot derive this itself. Absent means do not offer it.
2124
+ */
2125
+ approvalRelaxableByAuto?: boolean;
2126
+ }
2127
+ /**
2128
+ * Data for thinking part
2129
+ */
2130
+ interface ThinkingPartData {
2131
+ isStreaming: boolean;
2132
+ startTime?: number;
2133
+ }
2134
+ /**
2135
+ * Data for reasoning part (Extended Thinking content)
2136
+ */
2137
+ interface ReasoningPartData {
2138
+ /** Reasoning content (accumulated during streaming) */
2139
+ content: string;
2140
+ /** Whether reasoning is still streaming */
2141
+ isStreaming: boolean;
2142
+ /** Start timestamp for elapsed time display */
2143
+ startTime?: number;
2144
+ }
2145
+ /**
2146
+ * A part of a chat message.
2147
+ * Parts are ordered chronologically as they arrive from the stream.
2148
+ */
2149
+ interface AIChatMessagePart {
2150
+ /** Part type */
2151
+ type: AIChatMessagePartType;
2152
+ /** Unique part ID */
2153
+ id: string;
2154
+ /** Part-specific data */
2155
+ data: unknown;
2156
+ }
2157
+ /**
2158
+ * Terminal status of a dispatched subagent, mirrored onto the parent-visible
2159
+ * notification. `completed` reads as success; everything else reads as failure.
2160
+ */
2161
+ type AISubagentStatus = "completed" | "failed" | "cancelled" | "timeout" | "expired";
2162
+ /**
2163
+ * Narrow, UI-ready projection of an `agent-notification` message. Derived by the
2164
+ * react mapper from the raw `AgentSessionMessage.metadata` so the UI never has to
2165
+ * touch untrusted wrapper text: the title comes from {@link childName}/{@link status}
2166
+ * and {@link body} is the child's report already unwrapped from its `<subagent_result>`
2167
+ * envelope.
2168
+ */
2169
+ interface AIChatNotification {
2170
+ childSessionId: string;
2171
+ childName: string;
2172
+ status: AISubagentStatus;
2173
+ /** Child's report, unwrapped from the `<subagent_result>` envelope; rendered as markdown. */
2174
+ body: string;
2175
+ }
2176
+ /**
2177
+ * Chat message for runtime/streaming.
2178
+ *
2179
+ * All content is represented as ordered parts (text, tools, thinking, etc.)
2180
+ * Parts are in chronological order as they arrive from the stream.
2181
+ *
2182
+ * Used in:
2183
+ * - useAgentChat hook
2184
+ * - AI chat UI components
2185
+ * - Stream processing
2186
+ */
2187
+ interface AIChatMessage {
2188
+ /** Unique message ID */
2189
+ id: string;
2190
+ /** Message role */
2191
+ role: AIMessageRole;
2192
+ /** Ordered message parts (text, tools, thinking, etc.) */
2193
+ parts: AIChatMessagePart[];
2194
+ /** Whether the message is still streaming */
2195
+ isStreaming?: boolean;
2196
+ /** Message timestamp */
2197
+ timestamp?: Date;
2198
+ /** Error message if the message failed */
2199
+ error?: string;
2200
+ /**
2201
+ * Present only for subagent-completion notifications. When set, the UI renders
2202
+ * a compact collapsible callout in the agent flow instead of a user bubble, and
2203
+ * ignores {@link parts} (which still hold the raw wrapper text).
2204
+ */
2205
+ notification?: AIChatNotification;
2206
+ /**
2207
+ * Tokens reported by the provider after this message completed. The `input`
2208
+ * value reflects the size of the conversation Anthropic actually saw on
2209
+ * that turn — used by the chat composer to render a context-window
2210
+ * progress ring.
2211
+ */
2212
+ tokenUsage?: {
2213
+ input: number;
2214
+ output: number;
2215
+ };
2216
+ }
2217
+ /**
2218
+ * Question types supported by the agent
2219
+ */
2220
+ type AIQuestionType = "text" | "choice" | "confirm" | "multiselect";
2221
+ /**
2222
+ * Option for choice/multiselect questions
2223
+ */
2224
+ interface AIQuestionOption {
2225
+ value: string;
2226
+ label: string;
2227
+ description?: string;
2228
+ }
2229
+ /**
2230
+ * Question from the agent to the user
2231
+ */
2232
+ interface AIQuestion {
2233
+ /** Unique question ID */
2234
+ id: string;
2235
+ /** Question type */
2236
+ type: AIQuestionType;
2237
+ /** Question text */
2238
+ question: string;
2239
+ /** Options for choice/multiselect */
2240
+ options?: AIQuestionOption[];
2241
+ /** Placeholder for text input */
2242
+ placeholder?: string;
2243
+ /** Whether answer is required */
2244
+ required?: boolean;
2245
+ /** Min selections for multiselect */
2246
+ minSelections?: number;
2247
+ /** Max selections for multiselect */
2248
+ maxSelections?: number;
2249
+ }
2250
+ /**
2251
+ * Answer format for questions
2252
+ */
2253
+ type AIQuestionAnswer = {
2254
+ type: "text";
2255
+ value: string;
2256
+ } | {
2257
+ type: "choice";
2258
+ value: string;
2259
+ } | {
2260
+ type: "confirm";
2261
+ value: boolean;
2262
+ } | {
2263
+ type: "multiselect";
2264
+ value: string[];
2265
+ };
2266
+ /**
2267
+ * Option for batch questions
2268
+ */
2269
+ interface AIBatchQuestionOption {
2270
+ /** Value returned when selected */
2271
+ value: string;
2272
+ /** Display label */
2273
+ label: string;
2274
+ /**
2275
+ * What choosing this option means, or what it costs. Rendered under the
2276
+ * label, in the quiet weight: a batch of bare labels asks the human to
2277
+ * infer the trade-off the agent already knows.
2278
+ */
2279
+ description?: string;
2280
+ }
2281
+ /**
2282
+ * Kind of field a batch question is answered with.
2283
+ *
2284
+ * `record` (constraining the answer to a real `recordId`) is deliberately
2285
+ * absent: it needs a record selector, which is a feature of its own rather
2286
+ * than a field variant.
2287
+ */
2288
+ type AIBatchQuestionType = "choice" | "text" | "boolean";
2289
+ /**
2290
+ * Question in a batch (for ask_questions tool)
2291
+ */
2292
+ interface AIBatchQuestion {
2293
+ /** Unique question ID */
2294
+ id: string;
2295
+ /** Question text to display */
2296
+ question: string;
2297
+ /**
2298
+ * Kind of field to answer with. Optional for backwards compatibility: when
2299
+ * absent it is derived from the shape — `options` present means `choice`,
2300
+ * otherwise `text`. Only `boolean` cannot be derived, so it must be declared.
2301
+ */
2302
+ type?: AIBatchQuestionType;
2303
+ /** Predefined options (if provided, displayed as buttons) */
2304
+ options?: AIBatchQuestionOption[];
2305
+ /**
2306
+ * Several options may be chosen at once, and the answer comes back as an
2307
+ * array. Decided by the agent per question, because only it knows whether
2308
+ * the choices are mutually exclusive; a human forced to pick one of three
2309
+ * non-exclusive options answers a question nobody asked.
2310
+ */
2311
+ multiSelect?: boolean;
2312
+ /** Allow custom text input in addition to options */
2313
+ allowCustomAnswer?: boolean;
2314
+ /** Placeholder for custom input field */
2315
+ placeholder?: string;
2316
+ }
2317
+ /**
2318
+ * A single answer, in the type the question asked for. A `boolean` question
2319
+ * answered with the string `"true"` would leave the model re-parsing display
2320
+ * text — the same class of mistake as returning an option's label instead of
2321
+ * its value. A `multiSelect` question answers with the array for the same
2322
+ * reason: joining it into `"a, b"` would hand the model a string to split back
2323
+ * apart, and one whose separator can appear inside a value.
2324
+ */
2325
+ type AIBatchAnswerValue = string | boolean | string[];
2326
+ /**
2327
+ * Answer returned by the AgentQuestions widget
2328
+ */
2329
+ interface AIBatchQuestionAnswer {
2330
+ /** True if user skipped all questions */
2331
+ skipped: boolean;
2332
+ /** Map of question ID to the answer given, in the question's own type */
2333
+ answers: Record<string, AIBatchAnswerValue>;
2334
+ }
2335
+ /**
2336
+ * Todo item status
2337
+ */
2338
+ declare const TODO_STATUSES: readonly ["pending", "in_progress", "completed", "blocked"];
2339
+ type AITodoStatus = (typeof TODO_STATUSES)[number];
2340
+ /**
2341
+ * Todo item in a task list
2342
+ */
2343
+ interface AITodoItem {
2344
+ id: string;
2345
+ description: string;
2346
+ status: AITodoStatus;
2347
+ result?: string;
2348
+ updatedAt?: number;
2349
+ }
2350
+ /**
2351
+ * Persisted bounds on a todo, beside the type they constrain.
2352
+ *
2353
+ * Both sides of the wire enforce them: the runtime zod schema when it writes,
2354
+ * and the React projection parser when it reads an untrusted payload back.
2355
+ * React cannot import the runtime, which is why these numbers used to be
2356
+ * copied there under a "keep aligned with the canonical persisted schema"
2357
+ * comment — a synchronisation the compiler could not check.
2358
+ */
2359
+ declare const MAX_TODOS = 50;
2360
+ declare const MAX_TODO_ID_CHARS = 80;
2361
+ declare const MAX_TODO_DESCRIPTION_CHARS = 500;
2362
+ declare const MAX_TODO_RESULT_CHARS = 2000;
2363
+ /**
2364
+ * Todo list managed by the agent
2365
+ */
2366
+ interface AITodoList {
2367
+ items: AITodoItem[];
2368
+ progress: number;
2369
+ isComplete: boolean;
2370
+ }
2371
+ /**
2372
+ * AI Usage Metrics record
2373
+ */
2374
+ interface AIUsageMetrics {
2375
+ id: string;
2376
+ tenantId: string;
2377
+ date: Date;
2378
+ requestCount: number;
2379
+ totalTokens: number;
2380
+ totalCost: number;
2381
+ providerBreakdown: Record<string, AIProviderMetrics>;
2382
+ toolUsage: Record<string, number>;
2383
+ }
2384
+ /**
2385
+ * Provider-specific metrics
2386
+ */
2387
+ interface AIProviderMetrics {
2388
+ requests: number;
2389
+ tokens: number;
2390
+ cost: number;
2391
+ }
2392
+ /**
2393
+ * Memory type for categorization
2394
+ *
2395
+ * - `soul`: Tenant identity and persona (admin-managed)
2396
+ * - `user`: Per-user facts and preferences
2397
+ * - `daily`: Auto-generated daily summaries
2398
+ * - `session`: Auto-generated conversation summaries
2399
+ */
2400
+ type AIMemoryType = "soul" | "user" | "daily" | "session";
2401
+ /**
2402
+ * Advanced memory entry for OpenClaw-style memory system
2403
+ */
2404
+ interface AIMemoryEntry {
2405
+ id: string;
2406
+ tenantId: string;
2407
+ userId: string | null;
2408
+ conversationId: string | null;
2409
+ type: AIMemoryType;
2410
+ content: string;
2411
+ embedding: number[] | null;
2412
+ importance: number;
2413
+ source: string;
2414
+ createdAt: Date;
2415
+ updatedAt: Date;
2416
+ expiresAt: Date | null;
2417
+ }
2418
+ /**
2419
+ * Compaction summary for conversation history compression
2420
+ */
2421
+ interface AICompactionSummary {
2422
+ id: string;
2423
+ tenantId: string;
2424
+ userId: string;
2425
+ conversationId: string;
2426
+ summary: string;
2427
+ originalMessageCount: number;
2428
+ tokenCountBefore: number;
2429
+ tokenCountAfter: number;
2430
+ compactedAt: Date;
2431
+ }
2432
+
2433
+ declare const NATIVE_AGENT_UI_PART_IDS_METADATA_KEY = "__stndrdsNativeUiPartIds";
2434
+ declare const NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION: 1;
2435
+ type NativeAgentUIPartIds = Readonly<Record<string, string>>;
2436
+ interface NativeAgentUIPartIdsMetadata {
2437
+ readonly schemaVersion: typeof NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION;
2438
+ readonly partIds: NativeAgentUIPartIds;
2439
+ }
2440
+ /** Stable metadata key for a native AI SDK part in the durable message-wide part order. */
2441
+ declare function nativeAgentUIPartIdMetadataKey(part: AgentMessagePart, partIndex: number): string | undefined;
2442
+ /**
2443
+ * Validates the versioned client-visible native ID map against the durable
2444
+ * message shape. Legacy row-ID maps deliberately fail closed.
2445
+ */
2446
+ declare function parseNativeAgentUIPartIdsMetadata(message: Pick<AgentSessionMessage, "parts" | "metadata">): NativeAgentUIPartIds;
2447
+ /** Usage information rendered alongside an agent response. */
2448
+ interface AgentUsageView {
2449
+ inputTokens: number;
2450
+ outputTokens: number;
2451
+ totalTokens: number;
2452
+ cacheReadTokens?: number;
2453
+ cacheCreationTokens?: number;
2454
+ contextWindow: number;
2455
+ residentTokens: number;
2456
+ utilization: number;
2457
+ costUsd?: number;
2458
+ }
2459
+ /** Data payloads carried by the AI SDK UI message stream for agent sessions. */
2460
+ interface AgentUIDataTypes {
2461
+ "session-named": {
2462
+ name: string;
2463
+ };
2464
+ "compaction-start": {
2465
+ reason: "preflight_threshold" | "overflow_recovery";
2466
+ estimatedTokens?: number;
2467
+ reportedTokens?: number;
2468
+ };
2469
+ "compaction-end": {
2470
+ tokensBefore: number;
2471
+ tokensAfter: number;
2472
+ tokensSaved: number;
2473
+ strategy: CompactionStrategy;
2474
+ durationMs: number;
2475
+ summary?: string;
2476
+ };
2477
+ "compaction-failed": {
2478
+ reason: string;
2479
+ };
2480
+ usage: AgentUsageView;
2481
+ "message-persisted": {
2482
+ message: AgentSessionMessage;
2483
+ };
2484
+ "message-updated": {
2485
+ message: AgentSessionMessage;
2486
+ };
2487
+ "todo-plan-update": {
2488
+ plan: AgentTodoPlanView;
2489
+ };
2490
+ "approval-context": {
2491
+ approvalId: string;
2492
+ toolCallId: string;
2493
+ impact?: ToolImpact;
2494
+ relaxableByAuto?: boolean;
2495
+ };
2496
+ }
2497
+
2498
+ /**
2499
+ * The minimum every capability predicate in this file reads: the type, plus
2500
+ * whatever else of a full `Attribute` the caller happens to hold. Exported so
2501
+ * callers that only have a partial attribute — a plan's proposed attribute, a
2502
+ * schema snapshot row — can ask the same questions as callers holding the real
2503
+ * thing, instead of restating the rules.
2504
+ */
2505
+ type AttributeLike = Pick<Attribute, "type"> & Partial<Attribute>;
2506
+ type AttributeLifecycleCapabilities = {
2507
+ active: boolean;
2508
+ deprecated: boolean;
2509
+ visibleInArchitect: boolean;
2510
+ visibleInRuntime: boolean;
2511
+ warningWhenDeprecated: boolean;
2512
+ };
2513
+ type AttributeStorageMode = "value" | "edge" | "computed";
2514
+ type AttributeCardinality = "one" | "many";
2515
+ type AttributePolymorphicCapability = "none" | "code-only" | "internal";
2516
+ type AttributeStorageCapabilities = {
2517
+ mode: AttributeStorageMode;
2518
+ cardinality: AttributeCardinality;
2519
+ edgeBacked: boolean;
2520
+ preservesExistingValues: boolean;
2521
+ qualifiedProperties: boolean;
2522
+ polymorphic: AttributePolymorphicCapability;
2523
+ maxItems: boolean;
2524
+ };
2525
+ type AttributeRequiredCapability = "allowed" | "forbidden";
2526
+ type AttributeDefaultValueCapability = "static" | "automatic" | "forbidden";
2527
+ type AttributeAuthoringCapabilities = {
2528
+ editable: boolean;
2529
+ readOnly: boolean;
2530
+ directEdit: boolean;
2531
+ required: AttributeRequiredCapability;
2532
+ defaultValue: AttributeDefaultValueCapability;
2533
+ placeholder: boolean;
2534
+ maxItems: boolean;
2535
+ };
2536
+ type AttributePresentationCapabilities = {
2537
+ formField: boolean;
2538
+ tableCell: boolean;
2539
+ defaultColumn: boolean;
2540
+ compactDisplay: boolean;
2541
+ popoverEditor: boolean;
2542
+ placeholder: boolean;
2543
+ warningWhenDeprecated: boolean;
2544
+ };
2545
+ type AttributeQueryCapabilities = {
2546
+ filterable: boolean;
2547
+ searchable: boolean;
2548
+ sortable: boolean;
2549
+ groupable: boolean;
2550
+ kanbanGroupable: boolean;
2551
+ operators: readonly FilterOperator[];
2552
+ };
2553
+ type AttributeAgentCapabilities = {
2554
+ readable: boolean;
2555
+ writable: boolean;
2556
+ compactReadable: boolean;
2557
+ contentReadable: boolean;
2558
+ requiresDedicatedTool: boolean;
2559
+ };
2560
+ type AttributeExchangeCapabilities = {
2561
+ importable: boolean;
2562
+ exportable: boolean;
2563
+ schemaExportable: boolean;
2564
+ metadataExportable: boolean;
2565
+ };
2566
+ type AttributeCapabilities = {
2567
+ lifecycle: AttributeLifecycleCapabilities;
2568
+ storage: AttributeStorageCapabilities;
2569
+ authoring: AttributeAuthoringCapabilities;
2570
+ presentation: AttributePresentationCapabilities;
2571
+ query: AttributeQueryCapabilities;
2572
+ agent: AttributeAgentCapabilities;
2573
+ exchange: AttributeExchangeCapabilities;
2574
+ };
2575
+ declare const ATTRIBUTE_FILTER_OPERATORS: Readonly<Record<Exclude<AttributeType, "rollup">, readonly FilterOperator[]>>;
2576
+ declare function getAttributeCapabilities(attribute: AttributeLike): AttributeCapabilities;
2577
+ declare function getAttributeFilterOperators(attribute: AttributeLike): readonly FilterOperator[];
2578
+ declare function isAttributeFilterable(attribute: AttributeLike): boolean;
2579
+ declare function isAttributeSearchable(attribute: AttributeLike): boolean;
2580
+ declare function isAttributeGroupable(attribute: AttributeLike): boolean;
2581
+ declare function isAttributeKanbanGroupable(attribute: AttributeLike): boolean;
2582
+ /**
2583
+ * The type a filter on this attribute actually compares against. Identity for
2584
+ * every ordinary attribute; for a rollup it unfolds the aggregation:
2585
+ * `earliest`/`latest` compare dates, `original` compares the target attribute's
2586
+ * own type, and every other function (count/sum/avg/min/max/…) compares numbers.
2587
+ *
2588
+ * This is the single place that knowledge lives: operator resolution and value
2589
+ * canonicalization both read it, so a rollup can never be offered numeric
2590
+ * operators while its value is canonicalized as something else.
2591
+ */
2592
+ declare function resolveEffectiveFilterType(attribute: AttributeLike): AttributeType;
2593
+
2594
+ /**
2595
+ * Common configuration for all builders (Objects & Attributes)
2596
+ */
2597
+ interface BuilderConfig {
2598
+ /**
2599
+ * Technical name (snake_case, kebab-case, camelCase)
2600
+ * Used as identifier in database and API
2601
+ */
2602
+ name: string;
2603
+ /**
2604
+ * Human-readable label
2605
+ * Used in UI
1164
2606
  */
1165
2607
  label: string;
1166
2608
  }
@@ -1584,6 +3026,27 @@ interface FormFreeFieldRef {
1584
3026
  type FormFieldRef = FormSlotFieldRef | FormFreeFieldRef;
1585
3027
  declare function isFormSlotFieldRef(f: FormFieldRef): f is FormSlotFieldRef;
1586
3028
  declare function isFormFreeFieldRef(f: FormFieldRef): f is FormFreeFieldRef;
3029
+ /**
3030
+ * Whether a form field must be filled.
3031
+ *
3032
+ * An explicit `required` on the field always wins — dropping it from a field is
3033
+ * how a form makes it optional. Only when the field says nothing does the
3034
+ * underlying attribute's own `required` apply, and then for a `create` slot
3035
+ * alone: that is the one mode which always writes a record, so a `select`,
3036
+ * `optional`, or `create_if_not_empty` slot's object cannot bind the form.
3037
+ *
3038
+ * Lives here because both sides need the same answer. The interface used to
3039
+ * resolve it one way and `FormService` another, so the interface demanded
3040
+ * values the API accepted and the submission only failed later, at record
3041
+ * creation, naming an attribute rather than the field the user was looking at
3042
+ * (#1927). One function, imported by both, instead of a comment asking them to
3043
+ * agree.
3044
+ */
3045
+ declare function resolveFieldRequired(input: {
3046
+ fieldRequired: boolean | undefined;
3047
+ slotMode?: string;
3048
+ attributeRequired: boolean | undefined;
3049
+ }): boolean;
1587
3050
  /** All slot ids a slot field writes to: the primary followed by any additional slots. */
1588
3051
  declare function getSlotFieldTargets(field: FormSlotFieldRef): string[];
1589
3052
 
@@ -1996,9 +3459,21 @@ type CustomAttributeValue = Exclude<Attribute, FormulaAttribute | RollupAttribut
1996
3459
  * Adds support for custom attributes (added via UI) to a record type
1997
3460
  * Preserves autocompletion for known attributes while allowing additional properties
1998
3461
  */
1999
- type WithCustomAttributes$1<T> = T & {
3462
+ type WithCustomAttributes<T> = T & {
2000
3463
  [key: string]: CustomAttributeValue;
2001
3464
  };
3465
+ /**
3466
+ * The open custom-key index for a *stored record*, which carries metadata the
3467
+ * attribute value union does not describe.
3468
+ *
3469
+ * `WithCustomAttributes` alone cannot be intersected with {@link RecordMetadata}:
3470
+ * an index signature constrains every property of the literal, so `createdAt:
3471
+ * Date` and `metadata: Record<string, unknown>` are rejected by the very type
3472
+ * that requires them — leaving `ExtractRecord` inhabitable by nothing.
3473
+ */
3474
+ type WithCustomRecordAttributes<T> = T & {
3475
+ [key: string]: CustomAttributeValue | RecordMetadata[keyof RecordMetadata];
3476
+ };
2002
3477
  /**
2003
3478
  * Base metadata fields present on all records.
2004
3479
  * These are added by the system and always available.
@@ -2073,7 +3548,7 @@ type ExtractRecord<TBuilder> = TBuilder extends {
2073
3548
  _types: {
2074
3549
  record: infer R;
2075
3550
  };
2076
- } ? WithCustomAttributes$1<R> & RecordMetadata : never;
3551
+ } ? WithCustomRecordAttributes<R & RecordMetadata> : never;
2077
3552
  /**
2078
3553
  * Extract the record type without custom attributes (strict mode)
2079
3554
  * Use this when you only want the defined attributes
@@ -2093,7 +3568,7 @@ type ExtractRecordInput<TBuilder> = TBuilder extends {
2093
3568
  _types: {
2094
3569
  input: infer R;
2095
3570
  };
2096
- } ? WithoutSystemFields<WithCustomAttributes$1<R>> : never;
3571
+ } ? WithCustomAttributes<WithoutSystemFields<R>> : never;
2097
3572
  /**
2098
3573
  * Extract the input type without custom attributes (strict mode)
2099
3574
  * Omits system fields (id, createdAt, updatedAt) as they are managed automatically.
@@ -2112,7 +3587,7 @@ type ExtractRecordUpdate<TBuilder> = TBuilder extends {
2112
3587
  _types: {
2113
3588
  update: infer R;
2114
3589
  };
2115
- } ? WithoutSystemFields<WithCustomAttributes$1<R>> : never;
3590
+ } ? WithCustomAttributes<WithoutSystemFields<R>> : never;
2116
3591
  /**
2117
3592
  * Extract the update type without custom attributes (strict mode)
2118
3593
  * Omits system fields (id, createdAt, updatedAt) as they are managed automatically.
@@ -2345,6 +3820,10 @@ type UserStatus = "active" | "suspended";
2345
3820
  * Use in validators (e.g., `@IsIn(USER_STATUSES)`) to keep a single source of truth.
2346
3821
  */
2347
3822
  declare const USER_STATUSES: readonly UserStatus[];
3823
+ /** User preference applied only when a conversation has no session yet. */
3824
+ type UserWorkPosture = "plan" | "manual" | "auto";
3825
+ /** Canonical values accepted by profile transports and persistence. */
3826
+ declare const USER_WORK_POSTURES: readonly UserWorkPosture[];
2348
3827
  /**
2349
3828
  * User Profile - Represents application user data (authorization)
2350
3829
  *
@@ -2405,6 +3884,8 @@ interface UserProfile extends Timestamps {
2405
3884
  * - suspended: Temporarily blocked by admin
2406
3885
  */
2407
3886
  status: UserStatus;
3887
+ /** Explicit posture used to initialize each new conversation draft. */
3888
+ defaultWorkPosture: UserWorkPosture;
2408
3889
  /**
2409
3890
  * Last login timestamp (updated on each successful auth)
2410
3891
  */
@@ -2437,6 +3918,7 @@ interface UpdateUserProfile {
2437
3918
  avatarUrl?: string | null;
2438
3919
  status?: UserStatus;
2439
3920
  lastLoginAt?: Date;
3921
+ defaultWorkPosture?: UserWorkPosture;
2440
3922
  }
2441
3923
  /**
2442
3924
  * Data for inviting a new user by email.
@@ -2675,29 +4157,58 @@ declare const BYTE_UNIT_LABELS: readonly ["B", "KB", "MB", "GB", "TB"];
2675
4157
  declare function formatByteSize(bytes: number): string;
2676
4158
 
2677
4159
  /**
2678
- * The strictest reading of "no value": nullish, or the empty string.
2679
- *
2680
- * This is a SHAPE test, not a semantic one. It does not trim, does not recurse
2681
- * into objects, and does not treat `[]` as empty — callers that format a value,
2682
- * diff it, or decide whether to render a placeholder want exactly that, because
2683
- * `" "`, `[]` and `{ city: "" }` are all things a user can see.
4160
+ * Four emptiness predicates live in this codebase, and each answers a different
4161
+ * question. None of them is interchangeable with another, and every shape where
4162
+ * they disagree is asserted from both sides in `tests/lib/empty.test.ts`:
2684
4163
  *
2685
- * Three richer predicates deliberately live elsewhere and answer different
2686
- * questions; none of them is interchangeable with this one:
4164
+ * - `isNullishOrEmptyString` (below) nullish or the empty string, nothing
4165
+ * else. A shape test, for callers that format, diff, or decide whether to
4166
+ * render a placeholder.
4167
+ * - `isValuePresent` (below) — the single answer to "is a required field
4168
+ * satisfied?". Also trims, and treats `[]` as absent.
2687
4169
  * - `isEmptyValue` (validation/object/empty-value) also trims and treats an
2688
4170
  * all-empty object as empty. It gates `withEmptyToNull`, which lets an
2689
4171
  * optional attribute skip format validation when it is blank.
2690
- * - `isValuePresent` (validation/object/helpers) also trims, and backs
2691
- * `getMissingRequiredAttributes`.
2692
4172
  * - the filter operators' own `isEmpty` (filters/operators) also treats `[]` as
2693
4173
  * empty, because that is what `is_empty` means to a user writing a filter.
4174
+ */
4175
+ /**
4176
+ * The strictest reading of "no value": nullish, or the empty string.
4177
+ *
4178
+ * This is a SHAPE test, not a semantic one. It does not trim, does not recurse
4179
+ * into objects, and does not treat `[]` as empty — callers that format a value,
4180
+ * diff it, or decide whether to render a placeholder want exactly that, because
4181
+ * `" "`, `[]` and `{ city: "" }` are all things a user can see.
2694
4182
  *
2695
4183
  * Declared as a type guard rather than a plain boolean: it replaced inline
2696
4184
  * `x === null || x === undefined || x === ""` expressions, and TypeScript
2697
4185
  * narrows on those. A boolean-returning helper would have silently widened
2698
4186
  * every negative branch that used to be narrowed.
2699
4187
  */
2700
- declare function isNullishOrEmptyString(value: unknown): value is null | undefined | "";
4188
+ declare function isNullishOrEmptyString(value: unknown): value is null | undefined | "";
4189
+ /**
4190
+ * Whether a value satisfies a required field: it holds something a user would
4191
+ * see. Nullish, a whitespace-only string, and `[]` all count as absent. Every
4192
+ * required-field gate in the stack calls this.
4193
+ *
4194
+ * The semantics are the interface's, because they are what users are told. When
4195
+ * the gates disagreed the server was the looser one, so the UI refused a value
4196
+ * the API then accepted and the required error never cleared: a required `text`
4197
+ * took `" "` (#1813), a required `multiselect` took `[]`, a required
4198
+ * `richtext` took `" "` (#2167).
4199
+ *
4200
+ * Objects are deliberately out of scope: `{}` and `{ city: "" }` are present
4201
+ * here, so a required `location` holding an empty object still passes this
4202
+ * gate. Recursing into an object is `isEmptyValue`'s job — that is the
4203
+ * predicate carrying the all-empty-object branch — and widening required
4204
+ * satisfaction to match it is a separate decision about a different set of
4205
+ * types.
4206
+ *
4207
+ * Deliberately NOT a type guard: unlike `isNullishOrEmptyString` it has no
4208
+ * narrowable negative form (`" "` is still a `string`), and every caller
4209
+ * branches on it rather than narrowing through it.
4210
+ */
4211
+ declare function isValuePresent(value: unknown): boolean;
2701
4212
 
2702
4213
  /**
2703
4214
  * The one definition of what `format: email | url | slug` means.
@@ -2850,6 +4361,15 @@ declare function validateLabelExpression(expression: string): {
2850
4361
  * @returns The transformed string
2851
4362
  */
2852
4363
  declare function applyPipes(value: string, pipes: string[]): string;
4364
+ /**
4365
+ * Default fallback value when expression resolves to empty string.
4366
+ *
4367
+ * Exported because it is a sentinel, not a caption: the runtime writes it where
4368
+ * no user locale exists, and it is persisted and indexed. A reader that wants to
4369
+ * show a record's name in the reader's own language has to recognise this exact
4370
+ * value rather than guess at one — see `recordDisplayLabel` in `@stndrds/ui`.
4371
+ */
4372
+ declare const DEFAULT_LABEL_FALLBACK = "(Untitled)";
2853
4373
  /**
2854
4374
  * Render a label expression template with values
2855
4375
  *
@@ -2964,14 +4484,51 @@ interface UserLike {
2964
4484
  /**
2965
4485
  * Get user display name from firstName and lastName, falling back to email prefix.
2966
4486
  *
4487
+ * A name made only of whitespace is not a name: it falls back to the address
4488
+ * like an absent one, rather than drawing a person as a blank. That matters
4489
+ * beyond rendering now — this value is PERSISTED into `actors.display_name`
4490
+ * (#2214), where a row naming someone `" "` cannot be told apart from a real
4491
+ * one and nothing rewrites it afterwards.
4492
+ *
2967
4493
  * @param user - User object with optional firstName, lastName, and email
2968
4494
  * @returns Display name string
2969
4495
  *
2970
4496
  * @example
2971
4497
  * getUserDisplayName({ firstName: "John", lastName: "Doe" }) // "John Doe"
2972
4498
  * getUserDisplayName({ email: "admin@example.com" }) // "admin"
4499
+ * getUserDisplayName({ firstName: " ", email: "admin@example.com" }) // "admin"
2973
4500
  */
2974
4501
  declare function getUserDisplayName(user: UserLike): string;
4502
+ /**
4503
+ * Derive up to two initials from a label, for avatars and monograms.
4504
+ *
4505
+ * This is the single rule: every surface that draws a person derives its
4506
+ * initials here, so two views of the same actor cannot disagree (#2104 — the
4507
+ * activity feed and the sidebar showed different initials for one user).
4508
+ *
4509
+ * Two details are deliberate:
4510
+ *
4511
+ * - **Punctuation split only for a single word.** A label that is one word is
4512
+ * split again on `.`, `_` and `-`, so an e-mail local part like
4513
+ * `"marie.curie"` yields `"MC"` instead of `"M"`. Splitting on those
4514
+ * characters unconditionally would regress hyphenated names:
4515
+ * `"Jean-Paul Sartre"` must give `"JS"`, not `"JP"`.
4516
+ * - **First letter or digit, not first character.** A word may start with a
4517
+ * quote or other decoration, so `"'Marie Curie'"` still gives `"MC"` (#1928,
4518
+ * where decorated senders produced punctuation initials).
4519
+ *
4520
+ * @param label - Display name, e-mail local part, or any human label
4521
+ * @param fallback - Returned verbatim when no initial can be derived; may be
4522
+ * multiple characters (e.g. a monogram such as `"⚙"`)
4523
+ * @returns Up to two uppercase initials, or `fallback`
4524
+ *
4525
+ * @example
4526
+ * deriveInitials("Marie Curie", "?") // "MC"
4527
+ * deriveInitials("marie.curie", "?") // "MC"
4528
+ * deriveInitials("Jean-Paul Sartre", "?") // "JS"
4529
+ * deriveInitials("🔥", "?") // "?"
4530
+ */
4531
+ declare function deriveInitials(label: string | undefined, fallback: string): string;
2975
4532
 
2976
4533
  /**
2977
4534
  * Type guard for the { start, end } range shape stored on date attributes
@@ -3010,6 +4567,23 @@ declare const RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY = "__creatorRootActorId";
3010
4567
  */
3011
4568
  declare function getRecordCreatorPrincipalId(record: Pick<ObjectRecord, "createdBy" | "metadata">): string | undefined;
3012
4569
 
4570
+ /**
4571
+ * Does an action list grant `action`?
4572
+ *
4573
+ * `"*"` is a wildcard, not a literal action name — the contract published in
4574
+ * `content/docs/04-permissions.mdx`. Readers that compared literally shipped a
4575
+ * role granted `*` that listed every MCP tool and then returned an empty
4576
+ * schema: one reader honoured the wildcard, the next did not.
4577
+ *
4578
+ * It lives in `@stndrds/schema` rather than beside the permission service
4579
+ * because the browser needs it too, and `packages/ui` / `packages/react` do not
4580
+ * depend on `@stndrds/runtime`. That package boundary is why the sidebar and the
4581
+ * hooks each grew their own literal comparison instead of calling this.
4582
+ */
4583
+ declare function includesAction(actions: readonly string[] | undefined, action: Action): boolean;
4584
+ /** Capability flags every surface derives from one action list. */
4585
+ declare function buildPermissionFlags(actions: readonly string[]): ObjectPermissions;
4586
+
3013
4587
  /**
3014
4588
  * Attribute fields stored in dedicated database columns (not in config JSONB).
3015
4589
  * Used to determine which properties are extracted into the config column during sync.
@@ -3691,7 +5265,9 @@ interface RelationBuilderInitOptions {
3691
5265
  * Union of attribute builders allowed as qualified relation properties.
3692
5266
  * Matches PropertyType — excludes complex types (formula, rollup, relation, etc.)
3693
5267
  */
3694
- type PropertyAttributeBuilder = TextAttributeBuilder<string, boolean> | NumberAttributeBuilder<string, boolean> | CheckboxAttributeBuilder<string, boolean> | DateAttributeBuilder<string, boolean> | PhoneAttributeBuilder<string, boolean> | CurrencyAttributeBuilder<string, boolean> | StatusAttributeBuilder<string, readonly Option[], boolean> | SelectAttributeBuilder<string, readonly Option[], boolean> | MultiselectAttributeBuilder<string, readonly Option[], boolean> | LocationAttributeBuilder<string, boolean>;
5268
+ type PropertyAttributeBuilder = {
5269
+ build(): PropertyAttribute;
5270
+ };
3695
5271
  /**
3696
5272
  * Base builder for relation attributes (single and multi).
3697
5273
  * Carries shared methods: to(), toAny(), qualifyWith(), bilateral()
@@ -4233,31 +5809,54 @@ type ExtractBuilderInfo<T> = T extends {
4233
5809
  required: T["required"];
4234
5810
  } : never;
4235
5811
  /**
4236
- * Flatten and simplify an intersection type for better IDE display
4237
- */
4238
- type Flatten<T> = T extends object ? {
5812
+ * Collapse an intersection into a single object literal, for IDE display and to
5813
+ * keep the accumulator flat as `.attribute()` calls chain.
5814
+ *
5815
+ * This is the only mapped type applied to the *whole* accumulated record per
5816
+ * step, and that count is what sets the inference ceiling. (The per-attribute
5817
+ * `{ [K in TName]: ... }` below is a mapped type too, but it spans one key, not
5818
+ * the record.) The previous shape wrapped `Flatten` around an unconditional
5819
+ * `Omit` — itself a `Pick`, so a second whole-record mapped type — and paid two
5820
+ * per attribute.
5821
+ *
5822
+ * Measured with a uniform `text().required()` chain: the old shape was clean at
5823
+ * 49 attributes and raised TS2589 at 50; this one is clean at 98 and raises it
5824
+ * at 99. The CONTACT fixture in
5825
+ * `tests/builders/big-object-type-inference.test.ts` declares 67 attributes,
5826
+ * above the old ceiling — which is why its earliest-declared attributes silently
5827
+ * degraded to `any`. Real objects mix attribute types and cost more per step
5828
+ * than that uniform chain, so treat 98 as an upper bound, not a guarantee.
5829
+ */
5830
+ type Flatten<T> = {
4239
5831
  [K in keyof T]: T[K];
4240
- } : T;
5832
+ };
4241
5833
  /**
4242
- * Add a required attribute to the record type
5834
+ * Add a required attribute to the record type.
5835
+ *
5836
+ * `Omit` runs only when the name is already on the accumulator. That branch is
5837
+ * what makes the later declaration win a redeclaration — without it the two
5838
+ * declarations would intersect — while leaving the ordinary path, a name that
5839
+ * does not collide, at the single whole-record mapped type `Flatten` describes.
4243
5840
  */
4244
- type WithRequiredAttr<TRecord extends Record<string, unknown>, TName extends string, TValue> = Flatten<Omit<TRecord, TName> & {
5841
+ type WithRequiredAttr<TRecord extends Record<string, unknown>, TName extends string, TValue> = Flatten<(TName extends keyof TRecord ? Omit<TRecord, TName> : TRecord) & {
4245
5842
  [K in TName]: TValue;
4246
5843
  }>;
4247
5844
  /**
4248
- * Add an optional attribute to the record type
5845
+ * Add an optional attribute to the record type. See `WithRequiredAttr` for why
5846
+ * the `Omit` is conditional.
4249
5847
  */
4250
- type WithOptionalAttr<TRecord extends Record<string, unknown>, TName extends string, TValue> = Flatten<Omit<TRecord, TName> & {
5848
+ type WithOptionalAttr<TRecord extends Record<string, unknown>, TName extends string, TValue> = Flatten<(TName extends keyof TRecord ? Omit<TRecord, TName> : TRecord) & {
4251
5849
  [K in TName]?: TValue;
4252
5850
  }>;
4253
5851
  /**
4254
- * Add support for custom attributes (added via UI) to a record type
4255
- */
4256
- type WithCustomAttributes<T> = T & {
4257
- [key: string]: CustomAttributeValue;
4258
- };
4259
- /**
4260
- * Add an attribute to the accumulated record type
5852
+ * Add an attribute to the accumulated record type.
5853
+ *
5854
+ * Branch here, on `TRequired`, rather than folding the two aliases above into
5855
+ * one `Flatten<... & (TRequired extends true ? ... : ...)>`. The folded form
5856
+ * looks tidier and survives a uniform `text()` chain, but it was measured to
5857
+ * put the required/optional conditional *inside* the whole-record intersection,
5858
+ * which costs enough instantiation depth to drop the CONTACT fixture back below
5859
+ * the limit: 7 × TS2589 at 67 attributes, versus 0 in this shape.
4261
5860
  */
4262
5861
  type AddAttribute<TRecord extends Record<string, unknown>, TName extends string, TAttr extends Attribute, TRequired extends boolean> = TRequired extends true ? WithRequiredAttr<TRecord, TName, InferAttributeValue<TAttr>> : WithOptionalAttr<TRecord, TName, InferAttributeValue<TAttr>>;
4263
5862
  /**
@@ -4298,6 +5897,11 @@ type AddAttribute<TRecord extends Record<string, unknown>, TName extends string,
4298
5897
  * ```
4299
5898
  */
4300
5899
  declare class ObjectBuilder<TRecord extends Record<string, unknown> = {}> implements StandardSchemaV1<unknown, Record<string, unknown>> {
5900
+ /**
5901
+ * `attributes` and `name` are both seeded in the constructor and never
5902
+ * cleared, so they are pinned non-optional here rather than re-checked (or
5903
+ * defaulted) at every use site.
5904
+ */
4301
5905
  private obj;
4302
5906
  private _labelExpression?;
4303
5907
  private _embeddingExpression?;
@@ -4334,11 +5938,11 @@ declare class ObjectBuilder<TRecord extends Record<string, unknown> = {}> implem
4334
5938
  */
4335
5939
  readonly $infer: {
4336
5940
  /** Full record type with custom attributes and metadata (same as ExtractRecord) */
4337
- record: WithCustomAttributes<TRecord> & RecordMetadata;
5941
+ record: WithCustomRecordAttributes<TRecord & RecordMetadata>;
4338
5942
  /** Input type for creating records, omits system fields (same as ExtractRecordInput) */
4339
- create: WithoutSystemFields<WithCustomAttributes<TRecord>>;
5943
+ create: WithCustomAttributes<WithoutSystemFields<TRecord>>;
4340
5944
  /** Partial type for updating records, omits system fields (same as ExtractRecordUpdate) */
4341
- update: WithoutSystemFields<WithCustomAttributes<{
5945
+ update: WithCustomAttributes<WithoutSystemFields<{
4342
5946
  [K in keyof TRecord]?: TRecord[K];
4343
5947
  }>>;
4344
5948
  };
@@ -4418,6 +6022,7 @@ declare class ObjectBuilder<TRecord extends Record<string, unknown> = {}> implem
4418
6022
  * into the TRecord generic, enabling full inference.
4419
6023
  *
4420
6024
  * @param attr - Attribute definition or builder (auto-builds if builder)
6025
+ * @throws DuplicateError if the name is already declared on this object
4421
6026
  */
4422
6027
  attribute<TBuilder extends {
4423
6028
  _types: unknown;
@@ -4425,10 +6030,31 @@ declare class ObjectBuilder<TRecord extends Record<string, unknown> = {}> implem
4425
6030
  /**
4426
6031
  * Add multiple attributes at once
4427
6032
  * Note: For full type inference, prefer chaining .attribute() calls
6033
+ *
6034
+ * @throws DuplicateError if a name is declared twice, inside this batch or
6035
+ * against an attribute already declared on this object
4428
6036
  */
4429
6037
  attributes(attrs: Array<Attribute | {
4430
6038
  build: () => Attribute;
4431
6039
  }>): this;
6040
+ /**
6041
+ * Build any builders, reject duplicate names, then commit — the single push
6042
+ * path behind `attribute()` and `attributes()`, so both entry points share
6043
+ * one builder detection and one uniqueness guarantee.
6044
+ *
6045
+ * The check runs on the resulting array (already committed + incoming), so one
6046
+ * call catches both a collision inside a single `.attributes([...])` batch and
6047
+ * one spanning several calls.
6048
+ *
6049
+ * Names are compared with raw `===`. Postgres stores `attributes.name` as
6050
+ * plain `text` under a deterministic collation, so `x` and `X` are two
6051
+ * distinct attributes there; folding case here would reject a pair the
6052
+ * database accepts.
6053
+ *
6054
+ * @throws DuplicateError with `SchemaErrorCode.DUPLICATE_ATTRIBUTE`
6055
+ * @internal
6056
+ */
6057
+ private pushAttributes;
4432
6058
  /**
4433
6059
  * Set metadata. Merges with any previously set metadata (preserves keys
4434
6060
  * written by other builder methods like `.order()`).
@@ -4793,17 +6419,16 @@ declare class ActivityTabConfig {
4793
6419
  build(): DetailViewDefinition;
4794
6420
  }
4795
6421
  /**
4796
- * Builder for configuring emails tabs.
4797
- *
4798
- * @example
4799
- * .tab("emails", "Emails").emails().emailAttributes("email", "backup_email")
6422
+ * Shared builder for the tabs that associate provider data to a record by
6423
+ * matching address-bearing attributes: emails and meetings. Both carry exactly
6424
+ * the same configuration, so the terminal methods live here once.
4800
6425
  */
4801
- declare class EmailsTabConfig {
6426
+ declare abstract class AddressMatchedTabConfig<T extends EmailsTab | MeetingsTab> {
4802
6427
  private view;
4803
6428
  private tabData;
4804
6429
  /** @internal */
4805
- constructor(view: DetailViewBuilder, base: BaseTabConfig);
4806
- /** Set the text attributes whose values are matched against email participants. */
6430
+ constructor(view: DetailViewBuilder, base: BaseTabConfig, type: T["type"]);
6431
+ /** Set the text attributes whose values are matched against participants. */
4807
6432
  emailAttributes(...attributeIds: string[]): this;
4808
6433
  /**
4809
6434
  * Continue building with a new tab
@@ -4818,6 +6443,26 @@ declare class EmailsTabConfig {
4818
6443
  */
4819
6444
  build(): DetailViewDefinition;
4820
6445
  }
6446
+ /**
6447
+ * Builder for configuring emails tabs.
6448
+ *
6449
+ * @example
6450
+ * .tab("emails", "Emails").emails().emailAttributes("email", "backup_email")
6451
+ */
6452
+ declare class EmailsTabConfig extends AddressMatchedTabConfig<EmailsTab> {
6453
+ /** @internal */
6454
+ constructor(view: DetailViewBuilder, base: BaseTabConfig);
6455
+ }
6456
+ /**
6457
+ * Builder for configuring meetings tabs.
6458
+ *
6459
+ * @example
6460
+ * .tab("meetings", "Meetings").meetings().emailAttributes("email", "backup_email")
6461
+ */
6462
+ declare class MeetingsTabConfig extends AddressMatchedTabConfig<MeetingsTab> {
6463
+ /** @internal */
6464
+ constructor(view: DetailViewBuilder, base: BaseTabConfig);
6465
+ }
4821
6466
  /**
4822
6467
  * Builder for configuring documents tabs
4823
6468
  *
@@ -4941,6 +6586,11 @@ declare class TabBuilder {
4941
6586
  * @example .emails().emailAttributes("email", "backup_email")
4942
6587
  */
4943
6588
  emails(): EmailsTabConfig;
6589
+ /**
6590
+ * Create a meetings tab (query-time association via email-bearing attributes)
6591
+ * @example .meetings().emailAttributes("email", "backup_email")
6592
+ */
6593
+ meetings(): MeetingsTabConfig;
4944
6594
  /**
4945
6595
  * Create a forms tab to launch and track form instances linked to this record
4946
6596
  * @example .tab("forms", "Forms").forms()
@@ -6193,206 +7843,32 @@ declare function getActiveTab(config: ListViewConfig, tabId?: string): ListViewT
6193
7843
  * .field("client", "firstName")
6194
7844
  * .field("client", "email")
6195
7845
  * .build();
6196
- *
6197
- * formRegistry.register(ONBOARDING);
6198
- * ```
6199
- */
6200
- declare class FormRegistry {
6201
- private forms;
6202
- /**
6203
- * Register a form definition (or array of definitions).
6204
- * @throws Error if a form with the same name is already registered.
6205
- */
6206
- register(formOrForms: FormDefinition | FormDefinition[]): this;
6207
- /**
6208
- * Get a form definition by name.
6209
- */
6210
- get(name: string): FormDefinition | undefined;
6211
- /**
6212
- * Get all registered form definitions.
6213
- */
6214
- getAll(): FormDefinition[];
6215
- /**
6216
- * List all registered form names.
6217
- */
6218
- listNames(): string[];
6219
- }
6220
-
6221
- declare const formRegistry: FormRegistry;
6222
-
6223
- /**
6224
- * Event types emitted by write paths.
6225
- * New types are added as handlers are implemented.
6226
- */
6227
- type EventType = "record.created" | "record.updated" | "record.deleted" | "record.restored" | "record.purged" | "form.submitted" | "schema.attribute.created" | "schema.attribute.updated" | "schema.attribute.deleted" | "schema.object.created" | "schema.object.deleted" | "tenant.created" | "memory.retrieved" | "agent.session.completed";
6228
- /**
6229
- * Typed payload map — each event type has a specific data shape.
6230
- */
6231
- interface EventDataMap {
6232
- "record.created": {
6233
- objectId: string;
6234
- objectName: string;
6235
- recordId: string;
6236
- values: Record<string, unknown>;
6237
- };
6238
- "record.updated": {
6239
- objectId: string;
6240
- objectName: string;
6241
- recordId: string;
6242
- /** Only the names of fields that changed */
6243
- changedFields: string[];
6244
- /** Only the changed fields' previous values */
6245
- oldValues: Record<string, unknown>;
6246
- /** Only the changed fields' new values */
6247
- newValues: Record<string, unknown>;
6248
- };
6249
- "record.deleted": {
6250
- objectId: string;
6251
- objectName: string;
6252
- recordId: string;
6253
- /** Snapshot of record values at the moment of deletion */
6254
- values: Record<string, unknown>;
6255
- };
6256
- "record.restored": {
6257
- objectId: string;
6258
- objectName: string;
6259
- recordId: string;
6260
- };
6261
- "record.purged": {
6262
- objectId: string;
6263
- objectName: string;
6264
- recordId: string;
6265
- };
6266
- "form.submitted": {
6267
- formId: string;
6268
- formName: string;
6269
- submissionId: string;
6270
- createdBy: string | null;
6271
- createdRecordIds: Record<string, string>;
6272
- slotValues: Record<string, Record<string, unknown>>;
6273
- stepValues: Record<string, Record<string, unknown>>;
6274
- };
6275
- /**
6276
- * Emitted after a custom attribute is added to an object. Triggers the
6277
- * unified `SchemaSyncHandler` which converges the search index settings
6278
- * (filterable/sortable/searchable) to the live schema.
6279
- */
6280
- "schema.attribute.created": {
6281
- objectId: string;
6282
- attributeId: string;
6283
- };
6284
- /**
6285
- * Emitted after an attribute mutation (label/required/config). The
6286
- * `SchemaSyncHandler` reconciles index settings; downstream reindex is
6287
- * handled separately by `ObjectSchemaService.updateObject` when needed.
6288
- */
6289
- "schema.attribute.updated": {
6290
- objectId: string;
6291
- attributeId: string;
6292
- };
6293
- /**
6294
- * Emitted after a custom attribute is deleted from an object. Triggers
6295
- * the unified `SchemaSyncHandler` to drop the attribute from the index
6296
- * settings.
6297
- */
6298
- "schema.attribute.deleted": {
6299
- objectId: string;
6300
- attributeId: string;
6301
- };
6302
- /**
6303
- * Emitted after a custom object is created. Triggers the unified
6304
- * `SchemaSyncHandler` to provision per-tenant index settings.
6305
- */
6306
- "schema.object.created": {
6307
- objectId: string;
6308
- };
6309
- /**
6310
- * Emitted after a custom object is deleted. Triggers the unified
6311
- * `SchemaSyncHandler` so the search adapter can clean up dangling settings.
6312
- */
6313
- "schema.object.deleted": {
6314
- objectId: string;
6315
- };
6316
- /**
6317
- * Emitted on initial provisioning of a tenant. Triggers the unified
6318
- * `SchemaSyncHandler` to bootstrap the tenant's search index settings.
6319
- */
6320
- "tenant.created": {
6321
- /** The tenant identifier (mirrors the envelope `tenantId` for convenience). */
6322
- tenantId: string;
6323
- };
6324
- /**
6325
- * Emitted when memories are retrieved via search. Passive event for
6326
- * observability and downstream handlers (e.g. Task 8 container forwarding).
6327
- */
6328
- "memory.retrieved": {
6329
- memoryIds: string[];
6330
- query: string;
6331
- };
6332
- /**
6333
- * Emitted whenever an agent session reaches a terminal status (`completed`,
6334
- * `failed`, `cancelled`, `timeout`, `expired`). Consumed by the
6335
- * `AgentCompletionHandler` to notify parent sessions when a dispatched
6336
- * child session finishes.
6337
- */
6338
- "agent.session.completed": {
6339
- sessionId: string;
6340
- parentSessionId?: string;
6341
- rootSessionId: string;
6342
- status: "completed" | "failed" | "cancelled" | "timeout" | "expired";
6343
- mode: "interactive" | "autonomous";
6344
- /** Durable identity of this exact terminal transition. */
6345
- completionOccurrenceId: string;
6346
- /** Exact assistant message persisted by this turn, when one exists. */
6347
- childMessageId?: string;
6348
- };
6349
- }
6350
- /**
6351
- * A typed domain event.
6352
- * The generic parameter T narrows `data` to the correct payload shape.
6353
- */
6354
- interface DomainEvent<T extends EventType = EventType> {
6355
- id: string;
6356
- type: T;
6357
- tenantId: string;
6358
- userId: string | null;
6359
- timestamp: string;
6360
- data: EventDataMap[T];
6361
- /** Free-form metadata propagated from write-path callers (e.g. provenance for loop guards). */
6362
- metadata?: Record<string, unknown>;
6363
- }
6364
-
6365
- type LiveChannelKind = "workspace" | "object" | "record" | "view" | "agent" | "user" | "conversation";
6366
- type LiveChannel = {
6367
- kind: "workspace";
6368
- tenantId: string;
6369
- } | {
6370
- kind: "object";
6371
- objectId: string;
6372
- } | {
6373
- kind: "record";
6374
- objectId: string;
6375
- recordId: string;
6376
- } | {
6377
- kind: "view";
6378
- viewId: string;
6379
- } | {
6380
- kind: "agent";
6381
- tenantId: string;
6382
- } | {
6383
- kind: "user";
6384
- actorId: string;
6385
- } | {
6386
- kind: "conversation";
6387
- sessionId: string;
6388
- };
6389
- declare function liveChannelKey(channel: LiveChannel): string;
6390
- declare function parseLiveChannelKey(key: string): LiveChannel | null;
7846
+ *
7847
+ * formRegistry.register(ONBOARDING);
7848
+ * ```
7849
+ */
7850
+ declare class FormRegistry {
7851
+ private forms;
7852
+ /**
7853
+ * Register a form definition (or array of definitions).
7854
+ * @throws Error if a form with the same name is already registered.
7855
+ */
7856
+ register(formOrForms: FormDefinition | FormDefinition[]): this;
7857
+ /**
7858
+ * Get a form definition by name.
7859
+ */
7860
+ get(name: string): FormDefinition | undefined;
7861
+ /**
7862
+ * Get all registered form definitions.
7863
+ */
7864
+ getAll(): FormDefinition[];
7865
+ /**
7866
+ * List all registered form names.
7867
+ */
7868
+ listNames(): string[];
7869
+ }
6391
7870
 
6392
- declare const LIVE_STREAM_START_CURSOR = "0-0";
6393
- declare function isLiveStreamCursor(value: unknown): value is string;
6394
- declare function assertLiveStreamCursor(cursor: string | null, label?: string): asserts cursor is string | null;
6395
- declare function compareLiveStreamCursors(left: string, right: string): -1 | 0 | 1;
7871
+ declare const formRegistry: FormRegistry;
6396
7872
 
6397
7873
  type RecordFieldPatch = {
6398
7874
  fieldKey: string;
@@ -6583,6 +8059,269 @@ declare function isLiveEventType(value: unknown): value is LiveEventType;
6583
8059
  declare function isLiveEventPayload(payload: unknown): payload is LiveEventPayload;
6584
8060
  declare function isLiveEventPayloadForType(type: string, payload: unknown): payload is LiveEventPayload;
6585
8061
 
8062
+ /**
8063
+ * Event types emitted by write paths.
8064
+ * New types are added as handlers are implemented.
8065
+ */
8066
+ type EventType = "record.created" | "record.updated" | "record.deleted" | "record.restored" | "record.purged" | "form.submitted" | "schema.attribute.created" | "schema.attribute.updated" | "schema.attribute.deleted" | "schema.object.created" | "schema.object.deleted" | "tenant.created" | "memory.retrieved" | "realtime.publish" | "agent.session.completed" | "agent.session.turn.completed" | "calendar.meeting.ended" | "calendar.meeting.transcript.created";
8067
+ /** Announced once per meeting, by the sweep that watches for end times passing.
8068
+ * Nothing at the provider signals the end of a meeting, so this is derived. */
8069
+ interface CalendarMeetingEndedData {
8070
+ eventId: string;
8071
+ title: string | null;
8072
+ startsAt: string | null;
8073
+ endsAt: string | null;
8074
+ conferenceJoinUrl: string | null;
8075
+ /** Canonicalized addresses of everyone on the invite. */
8076
+ participantAddresses: string[];
8077
+ /** Records the meeting resolved to at the moment it ended. */
8078
+ linkedRecordIds: string[];
8079
+ }
8080
+ /** Announced once per meeting, when a bot's recording has been transcribed and
8081
+ * stored. Distinct from `calendar.meeting.ended`: a meeting ends whether or not
8082
+ * anything recorded it, and a transcript can arrive minutes later. */
8083
+ interface CalendarMeetingTranscriptCreatedData {
8084
+ transcriptId: string;
8085
+ eventId: string;
8086
+ provider: string;
8087
+ language: string | null;
8088
+ segmentCount: number;
8089
+ /** Recording length, or null when the provider reported no bounds. */
8090
+ durationMs: number | null;
8091
+ }
8092
+ /**
8093
+ * Typed payload map — each event type has a specific data shape.
8094
+ */
8095
+ interface EventDataMap {
8096
+ "realtime.publish": {
8097
+ channel: string;
8098
+ type: LiveEventPayload["type"];
8099
+ payload: LiveEventPayload;
8100
+ actorId: string | null;
8101
+ correlationId: string | null;
8102
+ occurredAt: string;
8103
+ schemaVersion: 1;
8104
+ };
8105
+ "record.created": {
8106
+ objectId: string;
8107
+ objectName: string;
8108
+ recordId: string;
8109
+ values: Record<string, unknown>;
8110
+ };
8111
+ "record.updated": {
8112
+ objectId: string;
8113
+ objectName: string;
8114
+ recordId: string;
8115
+ /** Only the names of fields that changed */
8116
+ changedFields: string[];
8117
+ /** Only the changed fields' previous values */
8118
+ oldValues: Record<string, unknown>;
8119
+ /** Only the changed fields' new values */
8120
+ newValues: Record<string, unknown>;
8121
+ /**
8122
+ * The record's WHOLE value set after the write, unchanged attributes
8123
+ * included — what `record.created` and `record.deleted` already carry.
8124
+ *
8125
+ * A consumer asking "does this record now match?" cannot answer from the
8126
+ * diff: an attribute absent from `newValues` is one the write did not
8127
+ * touch, not one the record lacks, and reading it as absent makes an
8128
+ * `is_empty` rule fire on a populated field (#1887).
8129
+ *
8130
+ * Optional because the event journal is durable: entries written before
8131
+ * this field existed still replay, and must fall back to the diff.
8132
+ *
8133
+ * Two things it is NOT. Computed attributes carry their pre-write value:
8134
+ * they are recalculated in a job after the write, so no payload assembled
8135
+ * at write time can hold their result. And the envelope is journaled inside
8136
+ * the write RPC, so a write that loses an optimistic-concurrency race and
8137
+ * replays still reports the values it read before the conflict. Treat it as
8138
+ * the state this write intended, which for every non-computed attribute
8139
+ * under no concurrent writer is the state it produced.
8140
+ */
8141
+ values?: Record<string, unknown>;
8142
+ };
8143
+ "record.deleted": {
8144
+ objectId: string;
8145
+ objectName: string;
8146
+ recordId: string;
8147
+ /** Snapshot of record values at the moment of deletion */
8148
+ values: Record<string, unknown>;
8149
+ };
8150
+ "record.restored": {
8151
+ objectId: string;
8152
+ objectName: string;
8153
+ recordId: string;
8154
+ };
8155
+ "record.purged": {
8156
+ objectId: string;
8157
+ objectName: string;
8158
+ recordId: string;
8159
+ };
8160
+ "form.submitted": {
8161
+ formId: string;
8162
+ formName: string;
8163
+ submissionId: string;
8164
+ createdBy: string | null;
8165
+ createdRecordIds: Record<string, string>;
8166
+ slotValues: Record<string, Record<string, unknown>>;
8167
+ stepValues: Record<string, Record<string, unknown>>;
8168
+ };
8169
+ /**
8170
+ * Emitted after a custom attribute is added to an object. Triggers the
8171
+ * unified `SchemaSyncHandler` which converges the search index settings
8172
+ * (filterable/sortable/searchable) to the live schema.
8173
+ */
8174
+ "schema.attribute.created": {
8175
+ objectId: string;
8176
+ attributeId: string;
8177
+ };
8178
+ /**
8179
+ * Emitted after an attribute mutation (label/required/config). The
8180
+ * `SchemaSyncHandler` reconciles index settings; downstream reindex is
8181
+ * handled separately by `ObjectSchemaService.updateObject` when needed.
8182
+ */
8183
+ "schema.attribute.updated": {
8184
+ objectId: string;
8185
+ attributeId: string;
8186
+ };
8187
+ /**
8188
+ * Emitted after a custom attribute is deleted from an object. Triggers
8189
+ * the unified `SchemaSyncHandler` to drop the attribute from the index
8190
+ * settings.
8191
+ */
8192
+ "schema.attribute.deleted": {
8193
+ objectId: string;
8194
+ attributeId: string;
8195
+ };
8196
+ /**
8197
+ * Emitted after a custom object is created. Triggers the unified
8198
+ * `SchemaSyncHandler` to provision per-tenant index settings.
8199
+ */
8200
+ "schema.object.created": {
8201
+ objectId: string;
8202
+ };
8203
+ /**
8204
+ * Emitted after a custom object is deleted. Triggers the unified
8205
+ * `SchemaSyncHandler` so the search adapter can clean up dangling settings.
8206
+ */
8207
+ "schema.object.deleted": {
8208
+ objectId: string;
8209
+ };
8210
+ /**
8211
+ * Emitted on initial provisioning of a tenant. Triggers the unified
8212
+ * `SchemaSyncHandler` to bootstrap the tenant's search index settings.
8213
+ */
8214
+ "tenant.created": {
8215
+ /** The tenant identifier (mirrors the envelope `tenantId` for convenience). */
8216
+ tenantId: string;
8217
+ };
8218
+ /**
8219
+ * Emitted when memories are retrieved via search. Passive event for
8220
+ * observability and downstream handlers (e.g. Task 8 container forwarding).
8221
+ */
8222
+ "memory.retrieved": {
8223
+ memoryIds: string[];
8224
+ query: string;
8225
+ };
8226
+ /**
8227
+ * Emitted whenever an agent session reaches a terminal status (`completed`,
8228
+ * `failed`, `cancelled`, `timeout`, `expired`). Consumed by the
8229
+ * `AgentCompletionHandler` to notify parent sessions when a dispatched
8230
+ * child session finishes.
8231
+ */
8232
+ "agent.session.completed": {
8233
+ sessionId: string;
8234
+ parentSessionId?: string;
8235
+ rootSessionId: string;
8236
+ status: "completed" | "failed" | "cancelled" | "timeout" | "expired";
8237
+ mode: "interactive" | "autonomous";
8238
+ /** Durable identity of this exact terminal transition. */
8239
+ completionOccurrenceId: string;
8240
+ /** Exact assistant message persisted by this turn, when one exists. */
8241
+ childMessageId?: string;
8242
+ };
8243
+ /**
8244
+ * Emitted after one successful agent turn commits its resumable or terminal
8245
+ * state. Unlike `agent.session.completed`, this is about a model turn, not
8246
+ * the lifetime of the conversation.
8247
+ */
8248
+ "agent.session.turn.completed": {
8249
+ sessionId: string;
8250
+ parentSessionId?: string;
8251
+ rootSessionId: string;
8252
+ /** Redundant with parentSessionId so older child rows still fail closed. */
8253
+ depth: number;
8254
+ status: "idle" | "completed";
8255
+ mode: "interactive" | "autonomous";
8256
+ };
8257
+ "calendar.meeting.ended": CalendarMeetingEndedData;
8258
+ "calendar.meeting.transcript.created": CalendarMeetingTranscriptCreatedData;
8259
+ }
8260
+ /**
8261
+ * A typed domain event.
8262
+ * The generic parameter T narrows `data` to the correct payload shape.
8263
+ */
8264
+ interface DomainEvent<T extends EventType = EventType> {
8265
+ id: string;
8266
+ type: T;
8267
+ tenantId: string;
8268
+ userId: string | null;
8269
+ timestamp: string;
8270
+ data: EventDataMap[T];
8271
+ /** Free-form metadata propagated from write-path callers (e.g. provenance for loop guards). */
8272
+ metadata?: Record<string, unknown>;
8273
+ }
8274
+
8275
+ declare const AGENT_UI_BATCH_MAX_BYTES = 204800;
8276
+ declare const AGENT_UI_BATCH_MAX_ITEMS = 256;
8277
+ type AgentUIMessageBatchItem<TChunk = unknown> = {
8278
+ sequence: number;
8279
+ content?: {
8280
+ kind: "text" | "reasoning";
8281
+ startOffset: number;
8282
+ endOffset: number;
8283
+ };
8284
+ chunk: TChunk;
8285
+ };
8286
+ type AgentUIMessageBatch<TChunk = unknown> = {
8287
+ schemaVersion: 1;
8288
+ batchId: string;
8289
+ tenantId: string;
8290
+ sessionId: string;
8291
+ streamId: string;
8292
+ sequenceStart: number;
8293
+ sequenceEnd: number;
8294
+ items: AgentUIMessageBatchItem<TChunk>[];
8295
+ };
8296
+ declare function isAgentUIMessageBatch(value: unknown): value is AgentUIMessageBatch;
8297
+
8298
+ type LiveChannelKind = "workspace" | "object" | "record" | "view" | "agent" | "user" | "conversation";
8299
+ type LiveChannel = {
8300
+ kind: "workspace";
8301
+ tenantId: string;
8302
+ } | {
8303
+ kind: "object";
8304
+ objectId: string;
8305
+ } | {
8306
+ kind: "record";
8307
+ objectId: string;
8308
+ recordId: string;
8309
+ } | {
8310
+ kind: "view";
8311
+ viewId: string;
8312
+ } | {
8313
+ kind: "agent";
8314
+ tenantId: string;
8315
+ } | {
8316
+ kind: "user";
8317
+ actorId: string;
8318
+ } | {
8319
+ kind: "conversation";
8320
+ sessionId: string;
8321
+ };
8322
+ declare function liveChannelKey(channel: LiveChannel): string;
8323
+ declare function parseLiveChannelKey(key: string): LiveChannel | null;
8324
+
6586
8325
  type UnknownRecord = Record<string, unknown>;
6587
8326
  type LiveEventEnvelope = {
6588
8327
  id: string;
@@ -6595,36 +8334,8 @@ type LiveEventEnvelope = {
6595
8334
  correlationId?: string | null;
6596
8335
  schemaVersion?: number;
6597
8336
  };
6598
- type LiveSubscribePayload = {
6599
- channel: string;
6600
- cursor: string | null;
6601
- };
6602
- type LiveUnsubscribePayload = {
6603
- channel?: string;
6604
- };
6605
- type LiveReplayCompletePayload = {
6606
- channel: string;
6607
- cursor: string | null;
6608
- };
6609
- type LiveGapPayload = {
6610
- channel: string;
6611
- requestedAfterId?: string | null;
6612
- oldestAvailableId?: string | null;
6613
- [key: string]: unknown;
6614
- };
6615
- type LiveErrorPayload = {
6616
- channel: string;
6617
- code?: string;
6618
- message?: string;
6619
- [key: string]: unknown;
6620
- };
6621
8337
  declare function getLiveProtocolPayloadChannel(payload: unknown): string | null;
6622
8338
  declare function isLiveEventEnvelope(payload: unknown): payload is LiveEventEnvelope;
6623
- declare function parseLiveSubscribePayload(payload: unknown): LiveSubscribePayload | null;
6624
- declare function parseLiveUnsubscribePayload(payload: unknown): LiveUnsubscribePayload | null;
6625
- declare function isLiveReplayCompletePayload(payload: unknown): payload is LiveReplayCompletePayload;
6626
- declare function isLiveGapPayload(payload: unknown): payload is LiveGapPayload;
6627
- declare function isLiveErrorPayload(payload: unknown): payload is LiveErrorPayload;
6628
8339
 
6629
8340
  interface OperatorSpec {
6630
8341
  /** Attribute types this operator applies to. Used by both UI and evaluators. */
@@ -6823,8 +8534,14 @@ declare function resolveUtcDayBounds(ms: number): IsWithinBounds | null;
6823
8534
  /** Format a UTC millisecond bound as the `YYYY-MM-DD` day string Postgres compares against. */
6824
8535
  declare function toUtcDayString(ms: number): string;
6825
8536
 
6826
- /** Built-in external connector providers (v1). */
6827
- type ConnectorProviderId = "gmail" | "outlook";
8537
+ /** Built-in external connector providers. Mirrors the runtime's
8538
+ * `ConnectorProvider`: mail and calendar are separate keys per vendor, because
8539
+ * the scopes differ and a user may connect one without the other. */
8540
+ type ConnectorProviderId = "gmail" | "outlook" | "google-calendar" | "outlook-calendar";
8541
+ /** Providers that sync a mailbox. */
8542
+ type EmailConnectorProviderId = Extract<ConnectorProviderId, "gmail" | "outlook">;
8543
+ /** Providers that sync a calendar. */
8544
+ type CalendarConnectorProviderId = Extract<ConnectorProviderId, "google-calendar" | "outlook-calendar">;
6828
8545
  /** Connection lifecycle status, mirrored from `connector_connections.status`. */
6829
8546
  type ConnectionStatusId = "active" | "reauth_required" | "error" | "disconnected";
6830
8547
  /**
@@ -6856,6 +8573,13 @@ interface StartConnectorAuthInput {
6856
8573
  interface StartConnectorAuthResult {
6857
8574
  authorizeUrl: string;
6858
8575
  }
8576
+ /**
8577
+ * Providers this deployment holds OAuth credentials for. A provider absent from
8578
+ * the list cannot start an authorization flow, so its card is not offered.
8579
+ */
8580
+ interface ConnectorProvidersResult {
8581
+ providers: ConnectorProviderId[];
8582
+ }
6859
8583
  /** Input to attach a Microsoft shared mailbox to an existing Outlook connection. */
6860
8584
  interface AddSharedMailboxInput {
6861
8585
  /** Shared mailbox SMTP address (e.g. contact@company.com). */
@@ -6928,7 +8652,14 @@ interface ConnectMcpServerInput {
6928
8652
  }
6929
8653
 
6930
8654
  type EmailProvider = "gmail" | "outlook";
6931
- type EmailVisibility = "shared" | "private";
8655
+ /**
8656
+ * How a connected mailbox is shared, NOT a record's visibility. Deliberately
8657
+ * distinct from `ResourceVisibility`: a connection is `shared` or `private`,
8658
+ * while the EMAILS it syncs carry `workspace | private` like every other
8659
+ * resource. Collapsing the two is what let email run a second visibility system
8660
+ * (#1907) — do not merge them back.
8661
+ */
8662
+ type MailboxAccountVisibility = "shared" | "private";
6932
8663
  type EmailDirection = "inbound" | "outbound";
6933
8664
  type MailboxReadState = "all" | "unread" | "read";
6934
8665
  type ConnectionStatus = "active" | "reauth_required" | "error" | "disconnected";
@@ -6949,7 +8680,8 @@ interface EmailAttachmentMeta {
6949
8680
  interface MailboxEmail {
6950
8681
  id: string;
6951
8682
  threadId: string;
6952
- connectionId: string;
8683
+ /** Null once the importing connection has been deleted — the email is kept, its origin is not. */
8684
+ connectionId: string | null;
6953
8685
  messageId: string;
6954
8686
  fromAddress: string;
6955
8687
  fromName: string;
@@ -6960,7 +8692,7 @@ interface MailboxEmail {
6960
8692
  hasRemoteContent: boolean;
6961
8693
  sentAt: string;
6962
8694
  direction: EmailDirection;
6963
- visibility: EmailVisibility;
8695
+ visibility: ResourceVisibility;
6964
8696
  isRead: boolean;
6965
8697
  labels: string[];
6966
8698
  attachments: EmailAttachmentMeta[];
@@ -6978,13 +8710,14 @@ interface MailboxThread {
6978
8710
  snippet: string;
6979
8711
  hasAttachments: boolean;
6980
8712
  participants: EmailParticipantRef[];
6981
- accountId: string;
8713
+ /** Null once the connection that imported the latest message has been deleted. */
8714
+ accountId: string | null;
6982
8715
  }
6983
8716
  interface MailboxAccount {
6984
8717
  id: string;
6985
8718
  provider: EmailProvider;
6986
8719
  externalAccountId: string;
6987
- visibility: EmailVisibility;
8720
+ visibility: MailboxAccountVisibility;
6988
8721
  status: ConnectionStatus;
6989
8722
  }
6990
8723
  interface MailboxCursor {
@@ -6997,10 +8730,30 @@ interface MailboxQuery {
6997
8730
  readState?: MailboxReadState;
6998
8731
  limit?: number;
6999
8732
  cursor?: MailboxCursor;
8733
+ /**
8734
+ * Whether the response carries {@link MailboxListResponse.total}, in the
8735
+ * records list's vocabulary. Defaults to `"exact"`: the thread-summary query
8736
+ * already aggregates the whole matching set before it slices a page, so the
8737
+ * count adds no scan it was not doing anyway. Pass `"none"` when the caller
8738
+ * has the number already — every page after the first of one infinite list.
8739
+ */
8740
+ countMode?: CountMode;
7000
8741
  }
7001
8742
  interface MailboxListResponse {
7002
8743
  threads: MailboxThread[];
7003
8744
  nextCursor?: MailboxCursor;
8745
+ /**
8746
+ * Threads matching the QUERY — account, search, read state — not the page.
8747
+ * `null` under `countMode: "none"`, which is "not counted" and never "zero".
8748
+ */
8749
+ total: number | null;
8750
+ /**
8751
+ * False when `total` is a lower bound rather than the real count, exactly as
8752
+ * on the records page: see `ContinuationPage.totalIsExact`. Absent when
8753
+ * nothing was counted. Derive it from the response, never from the requested
8754
+ * mode.
8755
+ */
8756
+ totalIsExact?: boolean;
7004
8757
  }
7005
8758
  interface MailboxThreadDetail {
7006
8759
  threadId: string;
@@ -7008,6 +8761,67 @@ interface MailboxThreadDetail {
7008
8761
  emails: MailboxEmail[];
7009
8762
  }
7010
8763
 
8764
+ /** Wire types for the meetings surface. Mirrors `types/emails.ts`: these are the
8765
+ * shapes the API returns and the UI renders, deliberately narrower than the
8766
+ * runtime's persisted `CalendarEvent`. */
8767
+ type MeetingStatus = "confirmed" | "tentative" | "cancelled";
8768
+ type MeetingParticipantRole = "organizer" | "required" | "optional";
8769
+ type MeetingResponseStatus = "accepted" | "declined" | "tentative" | "needs_action";
8770
+ interface MeetingParticipantRef {
8771
+ address: string;
8772
+ name?: string;
8773
+ role: MeetingParticipantRole;
8774
+ responseStatus?: MeetingResponseStatus;
8775
+ }
8776
+ /** A record a meeting was associated to at read time, by participant address.
8777
+ * There is no stored link — see the calendar design note. */
8778
+ interface MeetingLinkedRecord {
8779
+ recordId: string;
8780
+ objectId: string;
8781
+ objectName: string;
8782
+ /** Display label resolved from the record, when the API could resolve one. */
8783
+ label?: string;
8784
+ }
8785
+ interface Meeting {
8786
+ id: string;
8787
+ title: string | null;
8788
+ description: string | null;
8789
+ location: string | null;
8790
+ startsAt: string | null;
8791
+ endsAt: string | null;
8792
+ isAllDay: boolean;
8793
+ status: MeetingStatus;
8794
+ organizer: MeetingParticipantRef | null;
8795
+ conferenceProvider: string | null;
8796
+ conferenceJoinUrl: string | null;
8797
+ htmlLink: string | null;
8798
+ participants: MeetingParticipantRef[];
8799
+ linkedRecords: MeetingLinkedRecord[];
8800
+ }
8801
+ interface MeetingsQuery {
8802
+ /** Text match over title, description and location. */
8803
+ search?: string;
8804
+ /** Inclusive ISO lower bound on the start. */
8805
+ since?: string;
8806
+ /** Exclusive ISO upper bound on the start. */
8807
+ before?: string;
8808
+ /** Restrict to meetings involving one of these addresses. */
8809
+ addresses?: string[];
8810
+ /** Restrict to meetings linked to this record. */
8811
+ recordId?: string;
8812
+ /** Email attribute IDs to match on when filtering by recordId. */
8813
+ emailAttributeIds?: string[];
8814
+ /** `asc` lists what is coming next (the default view), `desc` reads history. */
8815
+ order?: "asc" | "desc";
8816
+ limit?: number;
8817
+ offset?: number;
8818
+ }
8819
+ interface MeetingsListResponse {
8820
+ meetings: Meeting[];
8821
+ /** Offset to request next, absent when the page was the last one. */
8822
+ nextOffset?: number;
8823
+ }
8824
+
7011
8825
  /**
7012
8826
  * Serializes a value into deterministic JSON: object keys are sorted
7013
8827
  * recursively, array order is preserved, `undefined` object entries are
@@ -7060,6 +8874,21 @@ declare function dateInTimezone(date: Date, timezone: string): string;
7060
8874
  */
7061
8875
  declare function resolveAttributeDefaultValue(attribute: Attribute, ctx: DefaultResolutionContext): unknown;
7062
8876
 
8877
+ /**
8878
+ * Build the stable title shown while an agent-generated title is unavailable.
8879
+ */
8880
+ declare function buildAgentFallbackTitle(message: string): string;
8881
+ interface ConversationDisplayTitleInput {
8882
+ readonly generated?: string;
8883
+ readonly firstUserText?: string;
8884
+ readonly emptyLabel: string;
8885
+ }
8886
+ /**
8887
+ * Resolve a conversation title monotonically from generated, optimistic, then
8888
+ * empty state without exposing storage placeholders such as `Session N`.
8889
+ */
8890
+ declare function conversationDisplayTitle(input: ConversationDisplayTitleInput): string;
8891
+
7063
8892
  /**
7064
8893
  * The subset of a view definition that participates in sync hashing.
7065
8894
  *
@@ -7473,9 +9302,13 @@ type SchemaPlanStatus = "proposed" | "applying" | "applied" | "failed" | "reject
7473
9302
  /**
7474
9303
  * What actually happened when a plan was applied.
7475
9304
  *
7476
- * `adapter.transaction()` is not a real SQL transaction on this platform
7477
- * (PostgREST has no transaction primitive), so a plan that fails midway
7478
- * leaves its already-applied entries in place. `applied` is persisted
9305
+ * `applied` was designed when `adapter.transaction()` was not a real SQL
9306
+ * transaction (PostgREST had no transaction primitive) and a plan that failed
9307
+ * midway genuinely left its already-applied entries in place. That is no
9308
+ * longer true — `adapter-postgres` is the only database adapter and its
9309
+ * transaction rolls back — so `applied` can name entries the rollback has
9310
+ * since undone (#2279). Treat it as "what apply believed it had done when it
9311
+ * stopped", not as a guarantee about the schema. `applied` is persisted
7479
9312
  * incrementally — after every step that lands, not only at the end — so a
7480
9313
  * process crash between two steps still leaves a readable record of exactly
7481
9314
  * what landed, even though `status` is then stuck at `"applying"` forever
@@ -7507,6 +9340,8 @@ interface SchemaPlanOutcome {
7507
9340
  */
7508
9341
  interface StoredSchemaPlan {
7509
9342
  id: Uuid;
9343
+ /** Conversation that proposed the plan; null/absent only for historical rows. */
9344
+ sourceSessionId?: Uuid | null;
7510
9345
  /**
7511
9346
  * The server-prepared payload, never the agent's raw proposal: `propose`
7512
9347
  * verifies each view target's `baselineToken` and converts the plan into
@@ -7973,4 +9808,4 @@ type SchemaPlanProposalInput = z$1.input<typeof structuralSchemaPlanSchema>;
7973
9808
  type ParsedSchemaPlanProposal = z$1.output<typeof schemaPlanSchema>;
7974
9809
  type ParsedPersistedSchemaPlan = z$1.output<typeof persistedSchemaPlanSchema>;
7975
9810
 
7976
- export { type AIGenerationInputMap, type AIGenerationResult, type AIGenerationType, type AIGenerationUsage, ALLOWED_PROPERTY_TYPES, ALL_SYSTEM_RESOURCES, ATTRIBUTE_FILTER_OPERATORS, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, type AcceptsCandidate, Action, ActivityTabConfig, type Actor, type ActorRoleAssignment, type ActorStatus, type ActorType, type AddSharedMailboxInput, AgentApprovalPolicy, AgentBlueprint, AgentBuilder, type AgentBuilderConfig, AgentExecutionConfig, AgentSchedule, type AgentSessionPatchLiveEvent, AgentTriggerBlueprint, type AgentUnreadPatchLiveEvent, type ApiKey, type ApiKeyAuthContext, type ApiKeyPermission, type ApiKeyWithSecret, type AssignActorRoleInput, Attribute, type AttributeAgentCapabilities, type AttributeAuthoringCapabilities, type AttributeCapabilities, type AttributeCardinality, type AttributeDefaultValueCapability, type AttributeExchangeCapabilities, AttributeGroupField, type AttributeLifecycleCapabilities, type AttributeLike, type AttributePolymorphicCapability, type AttributePresentationCapabilities, type AttributeQueryCapabilities, type AttributeRequiredCapability, type AttributeStorageCapabilities, type AttributeStorageMode, AttributeType, type AuditAction, type AuditActorType, type AuditChange, type AuditListOptions, type AuditLogEntry, type AuditResourceType, type AuditServiceOptions, type AuditSortField, type AuthorizedGlobalSearchResult, type AuthorizedRecordSearchResult, type AuthorizedSearchPage, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, BilateralConfig, type BoundingBox, type BrowserPreviewDescriptor, type BrowserPreviewStatus, type BrowserPreviewUpdatedLiveEvent, type BuilderConfig, type ByteMagnitude, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, type ChannelRevokedLiveEvent, CheckboxAttribute, type CollectionPage, type CollectionRequest, type CollectionResponse, type CompileComputedFormulaInput, type ComputedCompileAttribute, type ComputedCompileObject, type ComputedCompileSchema, ComputedDependency, type ComputedDependencyGraphNode, ComputedFormulaAstNode, ComputedFormulaCompileError, type ComputedFormulaResult, type ComputedFunctionCategory, type ComputedFunctionMetadata, type ComputedFunctionName, type ComputedFunctionSignature, ComputedOptionsSource, ComputedPlan, ComputedReturnType, ComputedValueType, ConfigOverrides, type ConnectMcpServerInput, type ConnectionStatus, type ConnectionStatusId, type ConnectionView, type ConnectorCallbackStatusValue, type ConnectorProviderId, type ConnectorScope, type ContinuationPage, type ConversationRenamedLiveEvent, type CountMode, type CreateActorInput, type CreateApiKeyInput, type CreateAuditLogInput, type CreateDBAttribute, type CreateDBForm, type CreateDBFormSubmission, type CreateDBObject, type CreateDBView, type CreateDBViewOverlay, type CreateDocument, type CreateDocumentLink, type CreateFile, CreateMode, type CreateNotificationInput, type CreateNotificationRecipientInput, type CreateObjectRecord, type CreateReflexInput, type CreateReflexVersionInput, type CreateUserProfile, Currency, CurrencyAttribute, type CustomAttributeValue, type CustomObjectInfo, CustomTabConfig, type DBAttribute, type DBForm, type DBFormSubmission, type DBObject, type DBView, type DBViewOverlay, type DBViewSyncResolution, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DateAttribute, DateRangeValue, type DefaultResolutionContext, type DefaultRoleName, type DeletedMode, DetailViewBuilder, DetailViewConfig, DetailViewDefinition, type Document, DocumentAttribute, type DocumentFile, type DocumentKind, DocumentLayout, type DocumentListOptions, type DocumentWithFiles, type DocumentWithSubCount, DocumentsTabConfig, type DomainEvent, type DriftAttributeInfo, DynamicValue, type DynamicValueResolver, EMPTY_VALUE_PLACEHOLDER, ESTIMATED_COUNT_CAP, type Eager, type EmailAttachmentMeta, type EmailDirection, type EmailParticipantRef, type EmailParticipantRole, type EmailProvider, type EmailVisibility, EmailsTabConfig, type EnvVarEntry, type EnvVarScope, type EventDataMap, type EventType, type ExtractRecord, type ExtractRecordInput, type ExtractRecordInputStrict, type ExtractRecordStrict, type ExtractRecordUpdate, type ExtractRecordUpdateStrict, FORM_FORBIDDEN_ATTRIBUTE_TYPES, type FeatureFlagDefinition, type FeatureFlagsConfig, type FeatureFlagsRepository, type FeatureGate, Field, FieldGroup, type FieldHistoryEntry, type File, type FileListOptions, type FileOcrStatus, FilterOperator, FilterRule, FilterState, FilterValue, type FlagLevel, type FlagOverride, FlagRegistry, type FlagResolutionContext, FlagService, type FlagValueType, FormBuilder, type FormDefinition, type FormFieldRef, type FormFieldsRow, type FormFreeFieldRef, type FormHeadingRow, FormRegistry, type FormRow, FormRowBuilder, type FormSeparatorRow, type FormSlot, type FormSlotFieldRef, type FormStatus, type FormStep, FormStepBuilder, type FormSubmission, type FormSubmissionStatus, type FormTextRow, FormulaAttribute, type FormulaGenerationAttribute, type FormulaGenerationInput, FormulaReturnType, type GeocodingAdapter, type GeocodingAutocompleteParams, type GeocodingParams, type GeocodingSuggestion, type GlobalSearchGroupedOptions, type GlobalSearchGroupedResult, type GlobalSearchOptions, type GlobalSearchResultItem, Group, GroupBuilder, IDENTITY_PROPERTIES, type InferAttributeValue, type InferQualifiedProps, type InviteUserInput, type IsWithinBounds, LIVE_EVENT_TYPES, LIVE_STREAM_START_CURSOR, type ListOptions, ListViewBuilder, ListViewConfig, ListViewDefinition, ListViewTab, ListViewTabConfigBuilder, ListViewTabVisibility, type LiveChannel, type LiveChannelKind, type LiveErrorPayload, type LiveEventEnvelope, type LiveEventPayload, type LiveEventType, type LiveGapPayload, type LiveNotification, type LiveNotificationRecipient, type LiveNotificationRecipientPatch, type LiveReplayCompletePayload, type LiveSubscribePayload, type LiveUnsubscribePayload, Location, LocationAttribute, LocationGranularity, MEMORY_LIST_VIEW, MEMORY_OBJECT, MEMORY_VIEW, type MailboxAccount, type MailboxCursor, type MailboxEmail, type MailboxListResponse, type MailboxQuery, type MailboxReadState, type MailboxThread, type MailboxThreadDetail, type McpCatalogEntry, type McpServerAuthInput, type McpServerAuthType, type McpServerStatus, type McpServerView, MigrationDefinition, ModelDefinition, MultiRelationAttribute, MultiselectAttribute, NOTIFICATION_INBOX_STATES, NOTIFICATION_KINDS, NOTIFICATION_PRIORITIES, NOTIFICATION_SENSITIVITIES, NOTIFICATION_TYPES_V1, NOTIFICATION_TYPE_AGENT_QUESTION_REQUESTED, NOTIFICATION_TYPE_AGENT_SESSION_COMPLETED, NOTIFICATION_TYPE_AGENT_SESSION_FAILED, NOTIFICATION_TYPE_AGENT_SESSION_TIMEOUT, NOTIFICATION_TYPE_AGENT_SESSION_WAITING_HUMAN, NOTIFICATION_TYPE_AGENT_TASK_ASSIGNED, NOTIFICATION_WORK_STATES, NoopGeocodingAdapter, type Notification, type NotificationCountPatchLiveEvent, type NotificationCounts, type NotificationCreatedLiveEvent, type NotificationInboxState, type NotificationKind, type NotificationListParams, type NotificationListResult, type NotificationPriority, type NotificationRecipient, type NotificationRecipientPatchLiveEvent, type NotificationSensitivity, type NotificationSubject, type NotificationType, type NotificationV1Type, type NotificationWithRecipient, type NotificationWorkState, NumberAttribute, OPERATOR_SPECS, ObjectBuilder, type ObjectConfig, ObjectDefinition, ObjectRecord, type OcrAdapter, type OcrInput, type OcrOptions, type OcrPage, type OcrResult, type OcrTextBlock, type OperatorSpec, Option, PRESENTATION_PROPERTIES, type PageInfo, type PageOptions, type PageResponse, type ParsedAttribute, type ParsedPersistedSchemaPlan, type ParsedSchemaPlanProposal, PermissionScope, type PersistedDefaultViewTarget, type PersistedSchemaPlan, type PersistedSchemaPlanAdditive, Phone, PhoneAttribute, type PlannedAttribute, type PlannedAttributeRemoval, type PlannedObject, type PlannedObjectRemoval, type PlannedRename, PropertySchema, type ProposedDefaultViewTarget, ProviderName, QUALIFIED_SEPARATOR, type QualifiedDocumentAttributeBuilder, type QualifiedDocumentBrand, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, REMOVED_OPERATOR_REPLACEMENTS, type RecordCreatedLiveEvent, type RecordDeletedLiveEvent, type RecordDocuments, type RecordFieldPatch, type RecordLiveSnapshot, type RecordMetadata, type RecordPatchLiveEvent, type RecordRemovedLiveEvent, type Reflex, type ReflexRun, type ReflexState, type ReflexVersion, type ReflexVersionStatus, type RegexGenerationInput, RelationAttribute, RelationGroup, RelationGroupBuilder, RelationTarget, RelativeDateValue, type ResolutionContext, type ResolvedFlag, ResourceVisibility, type ReverseGeocodingParams, RichtextAttribute, RichtextTabConfig, RollupAttribute, RollupFunction, type RunEffect, type RunMode, SCHEMA_PLAN_LIMITS, SKILL_LIST_VIEW, SKILL_OBJECT, SKILL_VIEW, STANDARD_SCHEMA_VENDOR, SYNONYM_ALIASES, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_FILTER_ATTRIBUTE_TYPES, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, type SchemaDriftResult, type SchemaPlan, type SchemaPlanAdditive, type SchemaPlanAdditiveBase, type SchemaPlanChangeSet, type SchemaPlanDestructive, type SchemaPlanDraft, type SchemaPlanDraftResponse, type SchemaPlanDraftState, type SchemaPlanDraftStatus, type SchemaPlanDraftWrite, type SchemaPlanImpact, type SchemaPlanImpactEntry, type SchemaPlanOutcome, type SchemaPlanProposalInput, type SchemaPlanSampleData, type SchemaPlanStatus, type SchemaPlanViewChanges, type SchemaState, type SearchOptions, SelectAttribute, SidePanelConfig, type SidebarExtraItem, SingleRelationAttribute, type SlotMode, SortRule, type StandardSchemaIssue, type StandardSchemaResult, type StartConnectorAuthInput, type StartConnectorAuthResult, type StaticFlagDefault, StatusAttribute, type StorageProvider, type StoredSchemaPlan, type SystemAttribute, type SystemAttributeI18nKey, type SystemFields, type SystemObjectDriftInfo, SystemResource, TEXT_FORMAT_PATTERNS, TODAY_DEFAULT, Tab, TabBuilder, TableTab, TableTabConfig, TenantId, type TenantSettings, TextAttribute, TimeFormat, Timestamps, TriggerEventType, USER_STATUSES, type UpdateActorInput, type UpdateDBAttribute, type UpdateDBForm, type UpdateDBFormSubmission, type UpdateDBObject, type UpdateDBView, type UpdateDBViewOverlay, type UpdateDocument, type UpdateFile, type UpdateUserProfile, type UpsertDBAttribute, type UpsertDBObject, type UpsertDBView, UserAttribute, type UserLike, type UserProfile, UserReferenceType, type UserStatus, Uuid, ValidationError, type ValueRef, type ViewBaselineOrigin, type ViewChange, ViewConfig, type ViewConfigDelta, ViewDefinition, type ViewProjectionStaleLiveEvent, type ViewStateEntry, type ViewStateResolution, type ViewSyncPayload, ViewType, type WithCustomAttributes$1 as WithCustomAttributes, type WithoutSystemFields, agent, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, assertLiveStreamCursor, booleanFlag, buildPropertySchema, buildQualifiedAttribute, canonicalStringify, canonicalizeFilterValue, checkbox, collectQualifiedRuleIssues, compareLiveStreamCursors, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, currentActor, date, dateInTimezone, dateValueStart, destructiveSchema, detailView, document, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractCurrencyFilterValue, extractFilterValue, extractValueRefs, flagRegistry, form, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getAttributeCapabilities, getAttributeFilterOperators, getErrorMessage, getLiveProtocolPayloadChannel, getOperatorPolarity, getRecordCreatorPrincipalId, getSlotFieldTargets, getSystemAttributeI18nKey, getSystemAttributeList, getUserDisplayName, group, hasDestructiveEntries, inferRollupReturnType, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isCheckboxEquality, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDocumentAttribute, isDynamicValue, isEmptyObject, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isLiveErrorPayload, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isLiveGapPayload, isLiveReplayCompletePayload, isLiveStreamCursor, isManagedSystemAttribute, isNotEmpty, isNullishOrEmptyString, isPlainRecord, isRelativeDateValue, isSetMembershipOperator, isStandardSchema, jsonFlag, listView, liveChannelKey, location, matchesAccepts, multiselect, normalizeDateValue, normalizeFilterRule, normalizeForEdgeRpc, normalizeOperator, now, number, numberFlag, object, parseLiveChannelKey, parseLiveSubscribePayload, parseLiveUnsubscribePayload, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, registry, relation, relationGroup, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolveEffectiveFilterType, resolveIsWithinBounds, resolveTextPattern, resolveUtcDayBounds, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, status, stringFlag, text, toMultiValueOperator, toUndefinedIfEmpty, toUtcDayString, today, user, validateAttributeName, validateLabelExpression, validateObjectName, validateQualifiedRule, validateViewName, viewRegistry, viewStateKey, viewSyncPayload };
9811
+ export { AGENT_UI_BATCH_MAX_BYTES, AGENT_UI_BATCH_MAX_ITEMS, type AIAvailableModel, type AIBatchAnswerValue, type AIBatchQuestion, type AIBatchQuestionAnswer, type AIBatchQuestionOption, type AIBatchQuestionType, type AIChatMessage, type AIChatMessagePart, type AIChatMessagePartType, type AIChatNotification, type AICompactionSummary, type AIGenerationInputMap, type AIGenerationResult, type AIGenerationType, type AIGenerationUsage, type AIMemoryEntry, type AIMemoryType, type AIMessageRole, type AIProviderMetrics, type AIQuestion, type AIQuestionAnswer, type AIQuestionOption, type AIQuestionType, type AISubagentStatus, type AITodoItem, type AITodoList, type AITodoStatus, type AIToolCall, type AIToolCallStatus, type AIUsageMetrics, ALLOWED_PROPERTY_TYPES, ALL_ACTIONS, ALL_SYSTEM_RESOURCES, ATTRIBUTE_FILTER_OPERATORS, AUDIT_ACTIONS, AUDIT_RESOURCE_TYPES, type AcceptsCandidate, type AccessLevel, type Action, ActivityTabConfig, type Actor, type ActorRoleAssignment, type ActorStatus, type ActorType, type AddSharedMailboxInput, type AgentApprovalPolicy, type AgentBlueprint, AgentBuilder, type AgentBuilderConfig, type AgentConfig, type AgentDashboard, type AgentDefinition, type AgentEvent, type AgentExecutionConfig, type AgentMessageAttachment, type AgentMessagePart, type AgentRequiredPermission, type AgentRun, type AgentRunStatus, type AgentSchedule, type AgentSession, type AgentSessionMessage, type AgentSessionMode, type AgentSessionPatchLiveEvent, type AgentSessionStatus, type AgentTodoPlan, type AgentTodoPlanStatus, type AgentTodoPlanView, type AgentToolCall, type AgentTriggerBlueprint, type AgentTriggerDefinition, type AgentTriggerType, type AgentUIDataTypes, type AgentUIMessageBatch, type AgentUIMessageBatchItem, type AgentUnreadPatchLiveEvent, type AgentUsageView, type AgentWorkMode, type ApiKey, type ApiKeyAuthContext, type ApiKeyPermission, type ApiKeyWithSecret, type ApprovalMode, type AssignActorRoleInput, type AssignRoleInput, Attribute, type AttributeAgentCapabilities, type AttributeAuthoringCapabilities, type AttributeCapabilities, type AttributeCardinality, type AttributeDefaultValueCapability, type AttributeExchangeCapabilities, AttributeGroupField, type AttributeLifecycleCapabilities, type AttributeLike, type AttributePolymorphicCapability, type AttributePresentationCapabilities, type AttributeQueryCapabilities, type AttributeRequiredCapability, type AttributeStorageCapabilities, type AttributeStorageMode, AttributeType, type AuditAction, type AuditActorType, type AuditChange, type AuditListOptions, type AuditLogEntry, type AuditResourceType, type AuditServiceOptions, type AuditSortField, type AuthorizedGlobalSearchResult, type AuthorizedRecordSearchResult, type AuthorizedSearchPage, BEHAVIOR_PROPERTIES, BROWSER_PREVIEW_STATUSES, BYTE_UNIT_LABELS, BilateralConfig, type BoundingBox, type BrowserPreviewDescriptor, type BrowserPreviewStatus, type BrowserPreviewUpdatedLiveEvent, type BuilderConfig, type ByteMagnitude, COMPUTED_FUNCTIONS, COMPUTED_FUNCTION_METADATA, COMPUTED_FUNCTION_NAMES, CONNECTOR_CALLBACK_PARAM, COUNT_MODES, type CalendarConnectorProviderId, type CalendarMeetingEndedData, type CalendarMeetingTranscriptCreatedData, type ChannelRevokedLiveEvent, CheckboxAttribute, type CollectionPage, type CollectionRequest, type CollectionResponse, type CompactionStrategy, type CompileComputedFormulaInput, type ComputedCompileAttribute, type ComputedCompileObject, type ComputedCompileSchema, ComputedDependency, type ComputedDependencyGraphNode, ComputedFormulaAstNode, ComputedFormulaCompileError, type ComputedFormulaResult, type ComputedFunctionCategory, type ComputedFunctionMetadata, type ComputedFunctionName, type ComputedFunctionSignature, ComputedOptionsSource, ComputedPlan, ComputedReturnType, ComputedValueType, ConfigOverrides, type ConnectMcpServerInput, type ConnectionStatus, type ConnectionStatusId, type ConnectionView, type ConnectorCallbackStatusValue, type ConnectorProviderId, type ConnectorProvidersResult, type ConnectorScope, type ContinuationPage, type ConversationDisplayTitleInput, type ConversationRenamedLiveEvent, type CountMode, type CreateActorInput, type CreateApiKeyInput, type CreateAuditLogInput, type CreateDBAttribute, type CreateDBForm, type CreateDBFormSubmission, type CreateDBObject, type CreateDBView, type CreateDBViewOverlay, type CreateDocument, type CreateDocumentLink, type CreateFile, CreateMode, type CreateNotificationInput, type CreateNotificationRecipientInput, type CreateObjectRecord, type CreatePermissionInput, type CreateReflexInput, type CreateReflexVersionInput, type CreateRoleInput, type CreateUserProfile, type CriticConfig, Currency, CurrencyAttribute, type CustomAttributeValue, type CustomObjectInfo, CustomTabConfig, type DBAttribute, type DBForm, type DBFormSubmission, type DBObject, type DBView, type DBViewOverlay, type DBViewSyncResolution, DB_COLUMN_FIELDS, DEFAULT_AGENT_EXECUTION_CONFIG, DEFAULT_APPROVAL_POLICY, DEFAULT_LABEL_FALLBACK, DEFAULT_ROLES, DEFAULT_ROLE_DESCRIPTIONS, DEFAULT_ROLE_LABELS, DEFAULT_ROLE_PERMISSIONS, DOCUMENT_SYSTEM_ATTRIBUTES, DateAttribute, DateRangeValue, type DefaultResolutionContext, type DefaultRoleName, type DeletedMode, DetailViewBuilder, DetailViewConfig, DetailViewDefinition, type Document, DocumentAttribute, type DocumentFile, type DocumentKind, DocumentLayout, type DocumentListOptions, type DocumentWithFiles, type DocumentWithSubCount, DocumentsTabConfig, type DomainEvent, type DriftAttributeInfo, DynamicValue, type DynamicValueResolver, EMPTY_VALUE_PLACEHOLDER, ESTIMATED_COUNT_CAP, type Eager, type EffectivePermissions, type EmailAttachmentMeta, type EmailConnectorProviderId, type EmailDirection, type EmailParticipantRef, type EmailParticipantRole, type EmailProvider, EmailsTab, EmailsTabConfig, type EnvVarEntry, type EnvVarScope, type EventDataMap, type EventType, type ExtractRecord, type ExtractRecordInput, type ExtractRecordInputStrict, type ExtractRecordStrict, type ExtractRecordUpdate, type ExtractRecordUpdateStrict, FORM_FORBIDDEN_ATTRIBUTE_TYPES, type FeatureFlagDefinition, type FeatureFlagsConfig, type FeatureFlagsRepository, type FeatureGate, Field, FieldGroup, type FieldHistoryEntry, type File, type FileListOptions, type FileOcrStatus, FilterOperator, FilterRule, FilterState, FilterValue, type FlagLevel, type FlagOverride, FlagRegistry, type FlagResolutionContext, FlagService, type FlagValueType, FormBuilder, type FormDefinition, type FormFieldRef, type FormFieldsRow, type FormFreeFieldRef, type FormHeadingRow, FormRegistry, type FormRow, FormRowBuilder, type FormSeparatorRow, type FormSlot, type FormSlotFieldRef, type FormStatus, type FormStep, FormStepBuilder, type FormSubmission, type FormSubmissionStatus, type FormSubmittedAgentEvent, type FormTextRow, FormulaAttribute, type FormulaGenerationAttribute, type FormulaGenerationInput, FormulaReturnType, type GeocodingAdapter, type GeocodingAutocompleteParams, type GeocodingParams, type GeocodingSuggestion, type GlobalSearchGroupedOptions, type GlobalSearchGroupedResult, type GlobalSearchOptions, type GlobalSearchResultItem, Group, GroupBuilder, type HumanRequestNeed, IDENTITY_PROPERTIES, type InferAttributeValue, type InferQualifiedProps, type InviteUserInput, type IsWithinBounds, LIVE_EVENT_TYPES, type ListOptions, ListViewBuilder, ListViewConfig, ListViewDefinition, ListViewTab, ListViewTabConfigBuilder, ListViewTabVisibility, type LiveChannel, type LiveChannelKind, type LiveEventEnvelope, type LiveEventPayload, type LiveEventType, type LiveNotification, type LiveNotificationRecipient, type LiveNotificationRecipientPatch, Location, LocationAttribute, LocationGranularity, MAX_TODOS, MAX_TODO_DESCRIPTION_CHARS, MAX_TODO_ID_CHARS, MAX_TODO_RESULT_CHARS, MEMORY_LIST_VIEW, MEMORY_OBJECT, MEMORY_VIEW, type MailboxAccount, type MailboxAccountVisibility, type MailboxCursor, type MailboxEmail, type MailboxListResponse, type MailboxQuery, type MailboxReadState, type MailboxThread, type MailboxThreadDetail, type McpCatalogEntry, type McpServerAuthInput, type McpServerAuthType, type McpServerStatus, type McpServerView, type Meeting, type MeetingLinkedRecord, type MeetingParticipantRef, type MeetingParticipantRole, type MeetingResponseStatus, type MeetingStatus, type MeetingsListResponse, type MeetingsQuery, MeetingsTab, MeetingsTabConfig, type MentionEntityType, type MentionReference, type MentionedContext, type MentionedEntityContext, MigrationDefinition, type ModelDefinition, MultiRelationAttribute, MultiselectAttribute, NATIVE_AGENT_UI_PART_IDS_METADATA_KEY, NATIVE_AGENT_UI_PART_IDS_METADATA_SCHEMA_VERSION, NOTIFICATION_INBOX_STATES, NOTIFICATION_KINDS, NOTIFICATION_PRIORITIES, NOTIFICATION_SENSITIVITIES, NOTIFICATION_TYPES_V1, NOTIFICATION_TYPE_AGENT_QUESTION_REQUESTED, NOTIFICATION_TYPE_AGENT_SESSION_COMPLETED, NOTIFICATION_TYPE_AGENT_SESSION_FAILED, NOTIFICATION_TYPE_AGENT_SESSION_TIMEOUT, NOTIFICATION_TYPE_AGENT_SESSION_WAITING_HUMAN, NOTIFICATION_TYPE_AGENT_TASK_ASSIGNED, NOTIFICATION_WORK_STATES, type NativeAgentUIPartIds, type NativeAgentUIPartIdsMetadata, NoopGeocodingAdapter, type Notification, type NotificationCountPatchLiveEvent, type NotificationCounts, type NotificationCreatedLiveEvent, type NotificationInboxState, type NotificationKind, type NotificationListParams, type NotificationListResult, type NotificationPriority, type NotificationRecipient, type NotificationRecipientPatchLiveEvent, type NotificationSensitivity, type NotificationSubject, type NotificationType, type NotificationV1Type, type NotificationWithRecipient, type NotificationWorkState, NumberAttribute, OPERATOR_SPECS, ObjectBuilder, type ObjectConfig, ObjectDefinition, type ObjectPermissions, ObjectRecord, type OcrAdapter, type OcrInput, type OcrOptions, type OcrPage, type OcrResult, type OcrTextBlock, type OperatorSpec, Option, PRESENTATION_PROPERTIES, type PageInfo, type PageOptions, type PageResponse, type ParsedAttribute, type ParsedPersistedSchemaPlan, type ParsedSchemaPlanProposal, type Permission, type PermissionScope, type PersistedDefaultViewTarget, type PersistedSchemaPlan, type PersistedSchemaPlanAdditive, Phone, PhoneAttribute, type PlannedAttribute, type PlannedAttributeRemoval, type PlannedObject, type PlannedObjectRemoval, type PlannedRename, PropertyAttribute, PropertySchema, type ProposedDefaultViewTarget, type ProviderName, QUALIFIED_SEPARATOR, type QualifiedDocumentAttributeBuilder, type QualifiedDocumentBrand, RECORD_CREATOR_ROOT_ACTOR_METADATA_KEY, REMOVED_OPERATOR_REPLACEMENTS, type ReasoningPartData, type RecordAgentEvent, type RecordCreatedLiveEvent, type RecordDeletedLiveEvent, type RecordDocuments, type RecordFieldPatch, type RecordLiveSnapshot, type RecordMetadata, type RecordPatchLiveEvent, type RecordRemovedLiveEvent, type Reflex, type ReflexRun, type ReflexState, type ReflexVersion, type ReflexVersionStatus, type RegexGenerationInput, RelationAttribute, RelationGroup, RelationGroupBuilder, RelationTarget, RelativeDateValue, type ResolutionContext, type ResolvedFlag, ResourceVisibility, type RetryPolicy, type ReverseGeocodingParams, RichtextAttribute, RichtextTabConfig, type Role, RollupAttribute, RollupFunction, type RunEffect, type RunMode, SCHEMA_PLAN_LIMITS, SESSION_TERMINAL_STATUSES, SKILL_LIST_VIEW, SKILL_OBJECT, SKILL_VIEW, STANDARD_SCHEMA_VENDOR, SYNONYM_ALIASES, SYSTEM_ATTRIBUTES, SYSTEM_ATTRIBUTE_I18N_KEYS, SYSTEM_FILTER_ATTRIBUTE_TYPES, SYSTEM_RESOURCES, SYSTEM_RESOURCE_LABELS, type SchemaDriftResult, type SchemaPlan, type SchemaPlanAdditive, type SchemaPlanAdditiveBase, type SchemaPlanChangeSet, type SchemaPlanDestructive, type SchemaPlanDraft, type SchemaPlanDraftResponse, type SchemaPlanDraftState, type SchemaPlanDraftStatus, type SchemaPlanDraftWrite, type SchemaPlanImpact, type SchemaPlanImpactEntry, type SchemaPlanOutcome, type SchemaPlanProposalInput, type SchemaPlanSampleData, type SchemaPlanStatus, type SchemaPlanViewChanges, type SchemaState, type SearchOptions, SelectAttribute, type SessionApprovalMode, type SessionOutcome, type SessionParkedOn, type SessionPhase, type SessionState, SidePanelConfig, type SidebarExtraItem, SingleRelationAttribute, type SlotMode, SortRule, type StandardSchemaIssue, type StandardSchemaResult, type StartConnectorAuthInput, type StartConnectorAuthResult, type StaticFlagDefault, StatusAttribute, type StorageProvider, type StoredSchemaPlan, type SystemAttribute, type SystemAttributeI18nKey, type SystemFields, type SystemObjectDriftInfo, type SystemPermissions, type SystemResource, TEXT_FORMAT_PATTERNS, TODAY_DEFAULT, TODO_PLAN_STATUSES, TODO_STATUSES, Tab, TabBuilder, TableTab, TableTabConfig, TenantId, type TenantSettings, type TerminalSessionStatus, TextAttribute, type TextPartData, type ThinkingPartData, TimeFormat, Timestamps, type ToolImpact, type ToolPartData, type ToolPartErrorCode, type ToolPartState, type TriggerEventType, USER_STATUSES, USER_WORK_POSTURES, type UpdateActorInput, type UpdateDBAttribute, type UpdateDBForm, type UpdateDBFormSubmission, type UpdateDBObject, type UpdateDBView, type UpdateDBViewOverlay, type UpdateDocument, type UpdateFile, type UpdateRoleInput, type UpdateUserProfile, type UpsertDBAttribute, type UpsertDBObject, type UpsertDBView, UserAttribute, type UserLike, type UserProfile, UserReferenceType, type UserRoleAssignment, type UserStatus, type UserWorkPosture, Uuid, ValidationError, type ValueRef, type ViewBaselineOrigin, type ViewChange, ViewConfig, type ViewConfigDelta, ViewDefinition, type ViewProjectionStaleLiveEvent, type ViewStateEntry, type ViewStateResolution, type ViewSyncPayload, ViewType, type WithCustomAttributes, type WithCustomRecordAttributes, type WithoutSystemFields, accessLevelToActions, actionsToAccessLevel, agent, agentDisplayName, applyPipes, applyRelationProps, assertAcyclicComputedDependencies, booleanFlag, buildAgentFallbackTitle, buildPermissionFlags, buildPropertySchema, buildQualifiedAttribute, canonicalStringify, canonicalizeFilterValue, checkbox, collectQualifiedRuleIssues, compileComputedFormula, compileRollupAttribute, computeByteMagnitude, conversationDisplayTitle, createFlagRegistry, createFlagService, createStandardSchemaProps, currency, currentActor, date, dateInTimezone, dateValueStart, deriveInitials, destructiveSchema, detailView, document, evaluateComputedAst, evaluateComputedFormula, evaluateComputedFormulaWithResult, evaluateFilterState, evaluateRecordFilterState, extractAttributeNames, extractCurrencyFilterValue, extractFilterValue, extractValueRefs, flagRegistry, form, formRegistry, formatAttributeValue, formatByteSize, formatComputedResult, formatLocationValue, formula, generateDefaultDetailView, generateDefaultListView, getActiveTab, getAttributeCapabilities, getAttributeFilterOperators, getErrorMessage, getLiveProtocolPayloadChannel, getOperatorPolarity, getRecordCreatorPrincipalId, getSlotFieldTargets, getSystemAttributeI18nKey, getSystemAttributeList, getUserDisplayName, group, hasDestructiveEntries, includesAction, inferRollupReturnType, isAgentUIMessageBatch, isAttributeFilterable, isAttributeGroupable, isAttributeKanbanGroupable, isAttributeSearchable, isCheckboxEquality, isComputedFunctionName, isDateRangeValue, isDefaultRole, isDocumentAttribute, isDynamicValue, isEmptyObject, isFormDefinition, isFormFieldsRow, isFormFreeFieldRef, isFormHeadingRow, isFormSeparatorRow, isFormSlotFieldRef, isFormTextRow, isLabelExpression, isLiveEventEnvelope, isLiveEventPayload, isLiveEventPayloadForType, isLiveEventType, isManagedSystemAttribute, isNotEmpty, isNullishOrEmptyString, isPlainRecord, isRelativeDateValue, isSetMembershipOperator, isStandardSchema, isTerminalSessionStatus, isTerminalState, isValuePresent, jsonFlag, legacyStatusToSessionState, listView, liveChannelKey, location, matchesAccepts, multiselect, nativeAgentUIPartIdMetadataKey, normalizeDateValue, normalizeFilterRule, normalizeForEdgeRpc, normalizeOperator, now, number, numberFlag, object, parseCountMode, parseLiveChannelKey, parseNativeAgentUIPartIdsMetadata, parseOptionalCountMode, parseQualifiedAttribute, persistedDefaultViewTargetSchema, persistedSchemaPlanSchema, phone, plannedAttributeSchema, plannedInlineAttributeSchema, plannedObjectSchema, proposedDefaultViewTargetSchema, registry, relation, relationGroup, relationPropertyDefs, renderLabelExpression, resetViewToDefault, resolveAttributeDefaultValue, resolveEffectiveFilterType, resolveFieldRequired, resolveIsWithinBounds, resolveTextPattern, resolveUtcDayBounds, richtext, rollup, rollupToFormulaExpression, schemaPlanSchema, select, sessionStateToLegacyStatus, status, stringFlag, text, toMultiValueOperator, toUndefinedIfEmpty, toUtcDayString, today, user, validateAttributeName, validateLabelExpression, validateObjectName, validateQualifiedRule, validateViewName, viewRegistry, viewStateKey, viewSyncPayload };