react-semaphor 0.1.545 → 0.1.546
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/analytics-protocol/index.js +405 -442
- package/dist/assistant-context/index.js +1 -1
- package/dist/assistant-protocol/index.js +100 -76
- package/dist/brand-studio/index.js +4 -4
- package/dist/briefings/index.js +6 -6
- package/dist/chunks/{add-to-dashboard-BuAqfA2Y.js → add-to-dashboard-BQRAAnc3.js} +55 -33
- package/dist/chunks/{analytics-base-schemas-BFAoRlkU.js → analytics-base-schemas-BKs3flFS.js} +2 -2
- package/dist/chunks/{assistant-chat-D7sWTypJ.js → assistant-chat-BPXhulAx.js} +2826 -2595
- package/dist/chunks/{bookmark-state-CXw7lZ50.js → bookmark-state-C4vetoa0.js} +7 -8
- package/dist/chunks/column-catalog-BYnochWQ.js +3363 -0
- package/dist/chunks/comparison-window-caption-C2xF-eWw.js +1433 -0
- package/dist/chunks/{context-ClREvqCZ.js → context-BerEBuFR.js} +11 -6
- package/dist/chunks/custom-visual-inputs-CkJW9pBS.js +295 -0
- package/dist/chunks/{dashboard-B1tMju0u.js → dashboard-C3CoKbGY.js} +1 -1
- package/dist/chunks/dashboard-briefing-launcher-Be4h-7My.js +3734 -0
- package/dist/chunks/dashboard-controls-bxPrlSyp.js +2307 -0
- package/dist/chunks/{dashboard-json-CoYRPqxx.js → dashboard-json-BrjxIiRt.js} +5 -5
- package/dist/chunks/{document-dashboard-inputs-BesAHZvB.js → document-dashboard-inputs-CRVHpIHp.js} +872 -974
- package/dist/chunks/{edit-dashboard-visual-JPtNfJRb.js → edit-dashboard-visual-DYYYDjY6.js} +2361 -2447
- package/dist/chunks/{filter-value-text-ff7osJr7.js → filter-value-text-Ddf55Ku1.js} +9 -9
- package/dist/chunks/global-date-filter-utils-9d6m9-FE.js +11859 -0
- package/dist/chunks/index-CtoK1Lgu.js +586 -0
- package/dist/chunks/{index-DRWiuqyd.js → index-DkQkMKa1.js} +80 -79
- package/dist/chunks/list-filter-DsaTbM3J.js +15 -0
- package/dist/chunks/matrix-analytical-definition-B9vW-osb.js +717 -0
- package/dist/chunks/{matrix-card-DjwWcCo8.js → matrix-card-LiMEipvq.js} +3 -3
- package/dist/chunks/{matrix-formatter-DnCyRXJE.js → matrix-formatter-DWEeC0_c.js} +44 -44
- package/dist/chunks/{matrix-member-presentation-CQGdVks6.js → matrix-member-presentation-DqzG-UhQ.js} +1 -1
- package/dist/chunks/{matrix-operation-contract-8OIO4gob.js → matrix-operation-contract-D6vYkZK4.js} +72 -72
- package/dist/chunks/{metric-comparison-DEwi9uc2.js → metric-comparison-zpGw4lD6.js} +2 -2
- package/dist/chunks/normalize-dashboard-for-dirty-check-XKgH3GFX.js +119 -0
- package/dist/chunks/{pivot-header-presentation-DHcx1XGQ.js → pivot-header-presentation-CQnIDtUv.js} +1 -1
- package/dist/chunks/{pivot-result-identity-DJhXXcns.js → pivot-result-identity-C-Q1j1Wb.js} +1 -1
- package/dist/chunks/{pivot-result-lifecycle-DM4CyGKs.js → pivot-result-lifecycle-pwq3b7LC.js} +571 -380
- package/dist/chunks/{raw-temporal-contract-C51YG48G.js → raw-temporal-contract-WuXA8jBP.js} +1 -1
- package/dist/chunks/{raw-temporal-presentation-C3mUgnEx.js → raw-temporal-presentation-CBzrDOjM.js} +8 -8
- package/dist/chunks/{report-preferences-dialog-DUtuUL_5.js → report-preferences-dialog-4QEZWe5U.js} +111 -112
- package/dist/chunks/{report-runtime-context-Dq8XyODK.js → report-runtime-context-hWiTCzFV.js} +2 -2
- package/dist/chunks/resolve-dashboard-input-context-UpK_LBpL.js +5677 -0
- package/dist/chunks/{saved-dashboard-context-LrF_kW0l.js → saved-dashboard-context-D_I3Lxk0.js} +34 -34
- package/dist/chunks/{selection-reducer-Dj_8xD69.js → selection-reducer-CJzkTZio.js} +15 -15
- package/dist/chunks/{semaphor-ready-indicator-BxF96Yhv.js → semaphor-ready-indicator-4zpRHE-X.js} +45823 -47304
- package/dist/chunks/{shelf-drop-preview-context-CNaM_Gmh.js → shelf-drop-preview-context-Cfw7TRAx.js} +84 -84
- package/dist/chunks/{source-entity-resolution-BYn9giz3.js → source-entity-resolution-BIGRvtbG.js} +13 -13
- package/dist/chunks/{switch-uDtPgQlQ.js → switch-CEBOR4n7.js} +3 -3
- package/dist/chunks/{table-export-sheet-YzMioA7Y.js → table-export-sheet-4X9mAG3V.js} +1 -1
- package/dist/chunks/table-settings-CunhoDUi.js +605 -0
- package/dist/chunks/{temporal-bucket-D7NBrrtL.js → temporal-bucket-CQOSbv9-.js} +26 -26
- package/dist/chunks/{token-types-DBbZVQsm.js → token-types-BMqRmT-C.js} +1 -1
- package/dist/chunks/{use-create-flow-overlay-state-CjB7ig1o.js → use-create-flow-overlay-state-DZBZiiD-.js} +101 -101
- package/dist/chunks/{validators-DMHTpf7a.js → validators-C-aOQlTB.js} +713 -658
- package/dist/chunks/{relative-date-label-Bk2j94pA.js → zoned-wall-clock-MulfA26h.js} +64 -21
- package/dist/dashboard/index.js +2 -2
- package/dist/dashboard-authoring/index.js +1802 -1149
- package/dist/data-app-sdk/index.js +6 -6
- package/dist/data-app-sdk-adapters/index.js +3 -3
- package/dist/data-app-sdk-validation/index.js +14 -14
- package/dist/format-utils/index.js +133 -133
- package/dist/index.js +192 -186
- package/dist/layouts/index.js +5 -242
- package/dist/report-runtime-context/index.js +2 -2
- package/dist/shared/index.js +4 -5
- package/dist/style.css +1 -1
- package/dist/surfboard/index.js +2 -2
- package/dist/types/components/index.d.ts +2 -0
- package/dist/types/components/surfboard/arrange-layout-button.d.ts +8 -0
- package/dist/types/components/surfboard/screen-size-preview-button.d.ts +7 -0
- package/dist/types/index.js +6 -6
- package/dist/types/lib/charts/table-chart-types.d.ts +4 -0
- package/dist/types/lib/charts/types.d.ts +2 -2
- package/dist/types/lib/dashboard-inputs/dashboard-input-values.d.ts +6 -0
- package/dist/types/lib/dashboard-inputs/filter-settings.d.ts +2 -0
- package/dist/types/lib/dashboard-inputs/prepare-loaded-dashboard.d.ts +15 -0
- package/dist/types/lib/matrix-table/matrix-editor.d.ts +52 -0
- package/dist/types/lib/query-context/dashboard-filter-mapping-resolution.d.ts +69 -0
- package/dist/types/lib/stores/dashboard-store.d.ts +125 -6
- package/dist/types/lib/types/common-types.d.ts +8 -0
- package/dist/types/lib/types/explorer-types.d.ts +10 -0
- package/dist/types/lib/types/semantic-types.d.ts +84 -0
- package/dist/types/lib/utils/build-saved-editor-card.d.ts +20 -0
- package/dist/types/lib/utils/card-type-change.d.ts +16 -0
- package/dist/types/lib/utils/field-availability-context.d.ts +25 -0
- package/dist/types/lib/utils/field-placement.d.ts +96 -0
- package/dist/types/lib/utils/field-state-calculator.d.ts +161 -0
- package/dist/types/lib/utils/qualified-entity-name.d.ts +2 -0
- package/dist/types/shared/analytics-protocol/field-provenance.d.ts +89 -0
- package/dist/types/shared/analytics-protocol/index.d.ts +2 -0
- package/dist/types/shared/analytics-protocol/query-policies.d.ts +52 -0
- package/dist/types/shared/analytics-protocol/time-window-schema.d.ts +1 -1
- package/dist/types/shared/analytics-protocol/time-window.d.ts +40 -1
- package/dist/types/shared/assistant-context/saved-dashboard-context.d.ts +4 -1
- package/dist/types/shared/assistant-protocol/answer-text.d.ts +20 -0
- package/dist/types/shared/assistant-protocol/context.d.ts +21 -21
- package/dist/types/shared/assistant-protocol/index.d.ts +1 -0
- package/dist/types/shared/assistant-protocol/limits.d.ts +6 -1
- package/dist/types/shared/assistant-protocol/parts.d.ts +43 -3
- package/dist/types/shared/assistant-protocol/request.d.ts +14 -2
- package/dist/types/shared/dashboard-authoring/calculated-field-identity.d.ts +3 -0
- package/dist/types/shared/dashboard-authoring/changes/card-query-part.d.ts +487 -0
- package/dist/types/shared/dashboard-authoring/changes/card-types.d.ts +34 -0
- package/dist/types/shared/dashboard-authoring/changes/dashboard-change.d.ts +7886 -0
- package/dist/types/shared/dashboard-authoring/changes/diagnostics.d.ts +43 -0
- package/dist/types/shared/dashboard-authoring/changes/read-card-query.d.ts +54 -0
- package/dist/types/shared/dashboard-authoring/changes/resolve-dashboard-changes.d.ts +89 -0
- package/dist/types/shared/dashboard-authoring/column-catalog.d.ts +32 -0
- package/dist/types/shared/dashboard-authoring/contracts.d.ts +0 -55
- package/dist/types/shared/dashboard-authoring/control-execution-contract.d.ts +24 -14
- package/dist/types/shared/dashboard-authoring/dashboard-card-source-index.d.ts +9 -1
- package/dist/types/shared/dashboard-authoring/dashboard-input-scope.d.ts +26 -0
- package/dist/types/shared/dashboard-authoring/filter-applicability.d.ts +75 -0
- package/dist/types/shared/dashboard-authoring/index.d.ts +18 -2
- package/dist/types/shared/dashboard-authoring/operations/apply-dashboard-operations.d.ts +10 -37
- package/dist/types/shared/dashboard-authoring/operations/operation-types.d.ts +189 -0
- package/dist/types/shared/dashboard-authoring/outline/outline-dashboard.d.ts +94 -0
- package/dist/types/shared/dashboard-authoring/outline/outline-filters.d.ts +78 -0
- package/dist/types/shared/dashboard-authoring/validators.d.ts +1 -2
- package/dist/types/shared/layouts/engine/grid.d.ts +25 -0
- package/dist/types/shared/layouts/engine/index.d.ts +4 -0
- package/dist/types/shared/layouts/engine/sheet-layout.d.ts +7 -0
- package/dist/types/shared/layouts/engine/types.d.ts +125 -0
- package/dist/types/shared/layouts/index.d.ts +1 -2
- package/package.json +2 -2
- package/dist/chunks/apply-dashboard-operations-CZEMsx8E.js +0 -2080
- package/dist/chunks/calendar-day-equality-dvoQp1xW.js +0 -410
- package/dist/chunks/comparison-window-caption-D4E6IHPD.js +0 -1624
- package/dist/chunks/custom-visual-inputs-DLCD9Y5V.js +0 -329
- package/dist/chunks/dashboard-briefing-launcher-CePgIu0Z.js +0 -3720
- package/dist/chunks/dashboard-controls-Cq05n3e0.js +0 -2315
- package/dist/chunks/dashboard-filter-value-compatibility-CwQ_iSNb.js +0 -108
- package/dist/chunks/matrix-analytical-definition-C7Gb0e12.js +0 -117
- package/dist/chunks/normalize-dashboard-for-dirty-check-Bk3VYv_q.js +0 -67
- package/dist/chunks/numeric-presentation-7X_IrD58.js +0 -5226
- package/dist/chunks/resolve-dashboard-input-context-DJ2tICwz.js +0 -9415
- package/dist/chunks/stable-serialize-CfqXeiBP.js +0 -6
- package/dist/chunks/table-settings-CLZocegs.js +0 -501
- package/dist/chunks/use-debounced-dirty-check-BwAbnX_5.js +0 -59
- package/dist/chunks/zoned-wall-clock-BkxV9jS2.js +0 -46
- package/dist/types/shared/dashboard-authoring/change-compiler.d.ts +0 -7
- package/dist/types/shared/dashboard-authoring/layout-compiler.d.ts +0 -2
- package/dist/types/shared/layouts/create-frame-layouts.d.ts +0 -27
- package/dist/types/shared/layouts/frame-layouts.d.ts +0 -23
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { TCard } from '../types/common-types.js';
|
|
2
|
+
import { AutoJoinMetadata } from '../types/query-types.js';
|
|
3
|
+
import { JoinabilityMapResponse } from '../types/semantic-types.js';
|
|
4
|
+
import { FieldStateContext } from './field-state-calculator.js';
|
|
5
|
+
/**
|
|
6
|
+
* Everything `calculateFieldState` needs about a visual, except the
|
|
7
|
+
* selected fields (which differ per call). Built by ONE function so the
|
|
8
|
+
* field list, the click gate, the drop gate, and the matrix editor judge
|
|
9
|
+
* the same card from the same facts: the same join plan (the authored
|
|
10
|
+
* one, which is also right for matrix cards), the same auto-resolved
|
|
11
|
+
* base, the same relationship map, aliases, labels, mode, and data-source
|
|
12
|
+
* anchor. A caller that assembles these by hand will eventually disagree
|
|
13
|
+
* with the others; do not.
|
|
14
|
+
*/
|
|
15
|
+
export type FieldAvailabilityContext = Omit<FieldStateContext, 'selectedFields'> & {
|
|
16
|
+
/** The semantic domain the card reads, when any. */
|
|
17
|
+
semanticDomainId?: string;
|
|
18
|
+
};
|
|
19
|
+
export declare function buildFieldAvailabilityContext(input: {
|
|
20
|
+
card: Pick<TCard, 'type' | 'config' | 'dataSource'> | null | undefined;
|
|
21
|
+
joinabilityData?: JoinabilityMapResponse | null;
|
|
22
|
+
autoJoinMetadata?: AutoJoinMetadata;
|
|
23
|
+
/** Labels the caller knows from elsewhere (entity groups); catalog labels win. */
|
|
24
|
+
extraDatasetLabels?: Record<string, string>;
|
|
25
|
+
}): FieldAvailabilityContext;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { TCard, TCardPreferences } from '../types/common-types.js';
|
|
2
|
+
import { CardConfig, ContainerId, Field } from '../types/explorer-types.js';
|
|
3
|
+
import { MatrixCardCatalog } from '../matrix-table/matrix-card-adapter.js';
|
|
4
|
+
import { MatrixEditorChange } from '../matrix-table/matrix-editor.js';
|
|
5
|
+
import { FieldAvailabilityContext } from './field-availability-context.js';
|
|
6
|
+
import { FieldStateResult } from './field-state-calculator.js';
|
|
7
|
+
/**
|
|
8
|
+
* Field placement: the one rule for putting a field on a shelf.
|
|
9
|
+
*
|
|
10
|
+
* Every entry point (drop, move, reorder, click) and the drag preview call
|
|
11
|
+
* `evaluateFieldPlacement`; only `placeField` in `useFieldManagement` commits
|
|
12
|
+
* its outcome. The rules restate today's drag behavior per placement kind; see
|
|
13
|
+
* docs/implementation-plans/shelf-drop-placement/PLAN.md, "Placement rules".
|
|
14
|
+
*
|
|
15
|
+
* Evaluation is side-effect-free during the call: no id minting, store access,
|
|
16
|
+
* notifications, clock or random reads. New ids arrive in the context.
|
|
17
|
+
*/
|
|
18
|
+
export type ShelfZone = Exclude<ContainerId, 'source'>;
|
|
19
|
+
export declare const SHELF_ZONES: readonly ShelfZone[];
|
|
20
|
+
export type FieldPlacement = {
|
|
21
|
+
/** The field-list field, or the pill being moved. */
|
|
22
|
+
field: Field;
|
|
23
|
+
/** 'source' is the field list. */
|
|
24
|
+
from: ContainerId;
|
|
25
|
+
to: ShelfZone;
|
|
26
|
+
/** Pill to insert in front of; absent means the end. */
|
|
27
|
+
beforeId?: string;
|
|
28
|
+
};
|
|
29
|
+
export type FieldPlacementKind = 'add' | 'move' | 'copy-to-sort' | 'reorder';
|
|
30
|
+
export type FieldPlacementNotice = {
|
|
31
|
+
kind: 'join-required';
|
|
32
|
+
fieldState?: FieldStateResult;
|
|
33
|
+
} | {
|
|
34
|
+
kind: 'invalid-field-type';
|
|
35
|
+
reason: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: 'already-on-shelf';
|
|
38
|
+
zone: ShelfZone;
|
|
39
|
+
} | {
|
|
40
|
+
kind: 'sort-needs-shelf-field';
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'cannot-sort-from-pivot';
|
|
43
|
+
} | {
|
|
44
|
+
kind: 'matrix-refused';
|
|
45
|
+
message: string;
|
|
46
|
+
};
|
|
47
|
+
export type FieldPlacementCommit = {
|
|
48
|
+
cardKind: 'standard';
|
|
49
|
+
config: CardConfig;
|
|
50
|
+
/** null leaves the card's preferences untouched. */
|
|
51
|
+
preferences: TCardPreferences | null;
|
|
52
|
+
} | {
|
|
53
|
+
cardKind: 'matrix';
|
|
54
|
+
change: MatrixEditorChange;
|
|
55
|
+
};
|
|
56
|
+
export type FieldPlacementOutcome = {
|
|
57
|
+
kind: 'placed';
|
|
58
|
+
commit: FieldPlacementCommit;
|
|
59
|
+
}
|
|
60
|
+
/** A standard reorder onto its own slot. */
|
|
61
|
+
| {
|
|
62
|
+
kind: 'unchanged';
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'refused';
|
|
65
|
+
notice: FieldPlacementNotice;
|
|
66
|
+
};
|
|
67
|
+
export type FieldPlacementContext = {
|
|
68
|
+
availability: FieldAvailabilityContext;
|
|
69
|
+
/** Ignored for standard cards. */
|
|
70
|
+
matrixCatalog: MatrixCardCatalog;
|
|
71
|
+
/** A string exactly when `needsNewFieldId` is true. */
|
|
72
|
+
newFieldId: string | null;
|
|
73
|
+
};
|
|
74
|
+
/** Reserved id for standard-card previews. Never matches a minted id and never reaches the store. */
|
|
75
|
+
export declare const PLACEMENT_PREVIEW_FIELD_ID = "__placement-preview__";
|
|
76
|
+
/**
|
|
77
|
+
* Reserved id for Matrix previews. The Matrix spec validates instance ids as
|
|
78
|
+
* UUIDs, so the preview needs one; minted ids are random v4 UUIDs and never
|
|
79
|
+
* equal this fixed value. Never reaches the store.
|
|
80
|
+
*/
|
|
81
|
+
export declare const MATRIX_PLACEMENT_PREVIEW_ID = "00000000-0000-4000-8000-000000000000";
|
|
82
|
+
/** The preview id for a card type. */
|
|
83
|
+
export declare function placementPreviewId(cardType: TCard['type'] | undefined): string;
|
|
84
|
+
export declare function classifyFieldPlacement(placement: Pick<FieldPlacement, 'from' | 'to'>): FieldPlacementKind;
|
|
85
|
+
/** Standard cards: every kind except reorder. Matrix: only from the field list. */
|
|
86
|
+
export declare function needsNewFieldId(cardType: TCard['type'] | undefined, placement: Pick<FieldPlacement, 'from' | 'to'>): boolean;
|
|
87
|
+
/**
|
|
88
|
+
* A standard card's shelf as the editor shows it: stored fields with their
|
|
89
|
+
* shelf identity resolved and a label defaulted from the name.
|
|
90
|
+
*/
|
|
91
|
+
export declare function readStandardShelf(config: CardConfig | undefined, zone: ContainerId): Field[];
|
|
92
|
+
export declare function evaluateStandardPlacement(card: TCard, placement: FieldPlacement, context: FieldPlacementContext): FieldPlacementOutcome;
|
|
93
|
+
/** The one evaluation. Dispatches on card type. Side-effect-free. */
|
|
94
|
+
export declare function evaluateFieldPlacement(card: TCard, placement: FieldPlacement, context: FieldPlacementContext): FieldPlacementOutcome;
|
|
95
|
+
/** Preview text for the shelf header while a field hovers it. */
|
|
96
|
+
export declare function placementNoticeReason(notice: FieldPlacementNotice, shelfLabel: string): string;
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
import { Field, JoinPlan } from '../types/explorer-types.js';
|
|
2
|
+
import { JoinabilityMap } from '../types/semantic-types.js';
|
|
3
|
+
import { AutoJoinMetadata } from '../types/query-types.js';
|
|
4
|
+
import { resolveFieldDatasetDependencies, FieldDatasetDependency } from './field-dependencies.js';
|
|
5
|
+
import { getQualifiedEntityName } from './qualified-entity-name.js';
|
|
6
|
+
export interface DatasetIdentityAlias {
|
|
7
|
+
name: string;
|
|
8
|
+
table?: string | null;
|
|
9
|
+
catalog?: string | null;
|
|
10
|
+
schema?: string | null;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Field draggability states for the query builder
|
|
14
|
+
*
|
|
15
|
+
* - **base**: Field is from the base dataset (first dataset selected)
|
|
16
|
+
* - **draggable**: Field has a direct relationship to base dataset (1-hop)
|
|
17
|
+
* - **indirect**: Field requires a multi-hop join (2-hop via intermediate dataset)
|
|
18
|
+
* - **setup**: A relationship exists but the engine will not use it on its
|
|
19
|
+
* own (not set to auto-join). The user can fix this; until then the field
|
|
20
|
+
* is blocked exactly like `unreachable`.
|
|
21
|
+
* - **unreachable**: No relationship path exists to this field's dataset
|
|
22
|
+
*
|
|
23
|
+
* Calculated fields take the worst state among the datasets they read from.
|
|
24
|
+
*/
|
|
25
|
+
export type FieldDraggableState = 'base' | 'draggable' | 'indirect' | 'setup' | 'unreachable'
|
|
26
|
+
/**
|
|
27
|
+
* Nothing is on the shelves and the dataset is not one of the chart's
|
|
28
|
+
* data-source datasets. Not a fault to fix: the customer chose their
|
|
29
|
+
* datasets and this field reads another one. Blocked, with the path to
|
|
30
|
+
* using it (add the dataset) offered as information.
|
|
31
|
+
*/
|
|
32
|
+
| 'absent';
|
|
33
|
+
/** Per-dataset availability, attached to calculated-field results. */
|
|
34
|
+
export interface FieldDependencyState {
|
|
35
|
+
/** Catalog dataset name. */
|
|
36
|
+
entityName: string;
|
|
37
|
+
/** Customer-facing dataset label. */
|
|
38
|
+
label: string;
|
|
39
|
+
state: FieldDraggableState;
|
|
40
|
+
/** Customer-facing sentence when the dataset is not simply available. */
|
|
41
|
+
reason?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Result of field state calculation
|
|
45
|
+
*/
|
|
46
|
+
export interface FieldStateResult {
|
|
47
|
+
/** The calculated draggability state */
|
|
48
|
+
state: FieldDraggableState;
|
|
49
|
+
/** For indirect joins: the path through intermediate datasets */
|
|
50
|
+
joinPath?: string[];
|
|
51
|
+
/** `joinPath` as readers see it: dataset labels, in path order. */
|
|
52
|
+
joinPathLabels?: string[];
|
|
53
|
+
/** Short tooltip text explaining the state (row `title`). */
|
|
54
|
+
tooltip?: string;
|
|
55
|
+
/**
|
|
56
|
+
* Customer-facing explanation when the field cannot be added as-is.
|
|
57
|
+
* Precise: names the dataset and the actual problem.
|
|
58
|
+
*/
|
|
59
|
+
reason?: string;
|
|
60
|
+
/** The one thing the user can do about `reason`, when there is one. */
|
|
61
|
+
action?: string;
|
|
62
|
+
/**
|
|
63
|
+
* Dataset labels that `reason` mentions, so the UI can set them off from
|
|
64
|
+
* the surrounding sentence (a chip) without parsing the text.
|
|
65
|
+
*/
|
|
66
|
+
mentions?: string[];
|
|
67
|
+
/**
|
|
68
|
+
* Non-blocking caution from governed catalog metadata, for example a
|
|
69
|
+
* one-to-many join that can repeat an aggregate. Shown in the preview.
|
|
70
|
+
*/
|
|
71
|
+
warning?: string;
|
|
72
|
+
/**
|
|
73
|
+
* Datasets a calculated field reads from, each with its own state.
|
|
74
|
+
* Undefined for base fields (their dataset is their group).
|
|
75
|
+
*/
|
|
76
|
+
dependencies?: FieldDependencyState[];
|
|
77
|
+
/**
|
|
78
|
+
* False when availability could not be checked (relationship map still
|
|
79
|
+
* loading, or a dependency could not be traced). UI must not present
|
|
80
|
+
* such a field as verified-ready.
|
|
81
|
+
*/
|
|
82
|
+
verified?: boolean;
|
|
83
|
+
/** Indicates if this field is already selected/in the query */
|
|
84
|
+
isSelected?: boolean;
|
|
85
|
+
}
|
|
86
|
+
/** States that block adding the field to the query. */
|
|
87
|
+
export declare function isBlockedFieldState(state: FieldDraggableState | undefined): boolean;
|
|
88
|
+
export interface FieldStateContext {
|
|
89
|
+
joinabilityMap: JoinabilityMap | null;
|
|
90
|
+
selectedFields: Field[];
|
|
91
|
+
joinPlan?: JoinPlan;
|
|
92
|
+
autoJoinMetadata?: AutoJoinMetadata;
|
|
93
|
+
baseEntityName?: string;
|
|
94
|
+
datasetAliases?: DatasetIdentityAlias[];
|
|
95
|
+
/**
|
|
96
|
+
* Whether the card reads from a semantic domain. Drives the fallback when
|
|
97
|
+
* `joinabilityMap` is null:
|
|
98
|
+
* - true -> the map is still loading: report `verified: false`.
|
|
99
|
+
* - false -> physical datasets: reachability comes from the join plan.
|
|
100
|
+
* - undefined (legacy callers) -> everything draggable, as before.
|
|
101
|
+
*/
|
|
102
|
+
hasSemanticDomain?: boolean;
|
|
103
|
+
/** Customer-facing dataset labels keyed by dataset name. */
|
|
104
|
+
datasetLabels?: Record<string, string>;
|
|
105
|
+
/**
|
|
106
|
+
* The datasets the chart's data source lists (`DataSource.selectedEntities`),
|
|
107
|
+
* in order. When nothing is on the shelves yet, these ARE the chart's
|
|
108
|
+
* datasets: a calculated field's dependencies are judged against them,
|
|
109
|
+
* so the card talks about the dataset the customer actually picked
|
|
110
|
+
* instead of the calculation's own first input.
|
|
111
|
+
*/
|
|
112
|
+
dataSourceEntities?: DatasetAnchorRef[];
|
|
113
|
+
}
|
|
114
|
+
/** Minimal entity reference the calculator needs to identify a dataset. */
|
|
115
|
+
export type DatasetAnchorRef = Parameters<typeof getQualifiedEntityName>[0];
|
|
116
|
+
/**
|
|
117
|
+
* Customer-facing words for a state, in one place. The row tag under a
|
|
118
|
+
* dependency and the title of the refusal toast both read from here.
|
|
119
|
+
*/
|
|
120
|
+
export declare function getFieldStateCopy(state: FieldDraggableState | undefined): {
|
|
121
|
+
/** Short tag beside a blocking dependency; null when nothing blocks. */
|
|
122
|
+
tag: string | null;
|
|
123
|
+
/** Title of the refusal toast. */
|
|
124
|
+
toastTitle: string;
|
|
125
|
+
};
|
|
126
|
+
/**
|
|
127
|
+
* Calculate the draggability state for a field in the query builder
|
|
128
|
+
*
|
|
129
|
+
* This determines whether a field can be dragged based on:
|
|
130
|
+
* - Current selected fields (what's already in the query)
|
|
131
|
+
* - Joinability map (what relationships exist between datasets)
|
|
132
|
+
* - For calculated fields: the datasets their inputs read from
|
|
133
|
+
*
|
|
134
|
+
* **Fallback behavior**:
|
|
135
|
+
* - No joinability map and no `hasSemanticDomain` flag: all fields draggable
|
|
136
|
+
* (legacy callers, no restrictions)
|
|
137
|
+
* - No fields selected yet: base fields are draggable (first selection
|
|
138
|
+
* establishes the base dataset); calculated fields are judged against the
|
|
139
|
+
* data source's datasets when there are any, else against their own first
|
|
140
|
+
* dataset
|
|
141
|
+
*/
|
|
142
|
+
export declare function calculateFieldState(field: Field, context: FieldStateContext): FieldStateResult;
|
|
143
|
+
/** One data-source dataset's connection to the visual's base, for the Datasets panel. */
|
|
144
|
+
export interface DataSourceConnection {
|
|
145
|
+
/** Dataset identity (name in semantic mode, qualified table in physical). */
|
|
146
|
+
entityName: string;
|
|
147
|
+
label: string;
|
|
148
|
+
state: FieldDraggableState;
|
|
149
|
+
reason?: string;
|
|
150
|
+
action?: string;
|
|
151
|
+
mentions?: string[];
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* How each selected dataset connects to the visual's base dataset, using
|
|
155
|
+
* the same identity, base cascade, and per-dataset evaluation as the field
|
|
156
|
+
* list. The Datasets panel shows this at selection time so the customer
|
|
157
|
+
* learns about an unconnected dataset before the first drag. Order and
|
|
158
|
+
* verdicts match `calculateFieldState` for a field of that dataset.
|
|
159
|
+
*/
|
|
160
|
+
export declare function describeDataSourceConnections(context: FieldStateContext): DataSourceConnection[];
|
|
161
|
+
export { resolveFieldDatasetDependencies, type FieldDatasetDependency };
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A column's aggregate and label, written with what they record about where
|
|
3
|
+
* they came from, in one place (MCP dashboard editing, ledger V-18). Every
|
|
4
|
+
* producer writes through here (the editor's aggregate menu and rename, the
|
|
5
|
+
* governed compiler, the MCP's stated labels) and every reader asks here, so
|
|
6
|
+
* the value and its provenance always tell one story. Before, the editor's
|
|
7
|
+
* aggregate menu changed `aggregate` and `aggregateOrigin` but left the
|
|
8
|
+
* compiler's record (`effectiveAggregate`, `aggregateSource`) stale, and the
|
|
9
|
+
* compiler copied a catalog `aggregateOrigin: "default"` onto an aggregate the
|
|
10
|
+
* caller chose.
|
|
11
|
+
*/
|
|
12
|
+
export type MetricAggregateSource = 'semantic_model' | 'caller_override' | 'default_sum';
|
|
13
|
+
/** A measure's aggregate and its provenance, as a saved column carries them (structural: any field type fits). */
|
|
14
|
+
export type MetricAggregateProvenance<A extends string = string> = {
|
|
15
|
+
aggregate?: A;
|
|
16
|
+
aggregateOrigin?: 'default' | 'explicit';
|
|
17
|
+
semanticAggregate?: A;
|
|
18
|
+
effectiveAggregate?: A;
|
|
19
|
+
aggregateSource?: MetricAggregateSource;
|
|
20
|
+
/** The field's type, which decides the default aggregate (`defaultMetricAggregate`). */
|
|
21
|
+
dataType?: string;
|
|
22
|
+
};
|
|
23
|
+
/** A column's label and its provenance. */
|
|
24
|
+
export type LabelProvenance = {
|
|
25
|
+
label?: string;
|
|
26
|
+
labelOrigin?: 'semantic' | 'override';
|
|
27
|
+
derivedLabel?: string;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* The aggregate a measure gets when nobody chooses one, the one rule the
|
|
31
|
+
* editor (a field dropped on the measures), the governed compiler and every
|
|
32
|
+
* reader share: the semantic model's, else SUM for a number (or a type not
|
|
33
|
+
* known) and COUNT for anything else.
|
|
34
|
+
*/
|
|
35
|
+
export declare function defaultMetricAggregate<A extends string>(semanticAggregate: A | undefined, dataType?: string): A | 'SUM' | 'COUNT';
|
|
36
|
+
/**
|
|
37
|
+
* The compiler's record of a measure's aggregate: the aggregate it runs, and
|
|
38
|
+
* whether that is the default or an override. Asking for SUM on a SUM measure
|
|
39
|
+
* is not an override (Analytics MCP focus 1.4b).
|
|
40
|
+
*/
|
|
41
|
+
export declare function metricAggregateRecord<A extends string>(input: {
|
|
42
|
+
aggregate: A;
|
|
43
|
+
semanticAggregate?: A;
|
|
44
|
+
dataType?: string;
|
|
45
|
+
}): {
|
|
46
|
+
effectiveAggregate: A;
|
|
47
|
+
aggregateSource: MetricAggregateSource;
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* What to set on a measure for a new aggregate: the aggregate, whether
|
|
51
|
+
* someone chose it (`aggregateOrigin`), and, when the column carries the
|
|
52
|
+
* compiler's record, that record refreshed. A patch, for the editor's column
|
|
53
|
+
* updates; `withMetricAggregate` applies it.
|
|
54
|
+
*/
|
|
55
|
+
export declare function metricAggregatePatch<A extends string>(column: Pick<MetricAggregateProvenance<A>, 'semanticAggregate' | 'effectiveAggregate' | 'aggregateSource' | 'dataType'>, aggregate: A, origin: 'default' | 'explicit'): MetricAggregateProvenance<A>;
|
|
56
|
+
/** A measure with a new aggregate and its provenance (`metricAggregatePatch`). */
|
|
57
|
+
export declare function withMetricAggregate<T extends MetricAggregateProvenance>(column: T, aggregate: NonNullable<T['aggregate']>, origin: 'default' | 'explicit'): T;
|
|
58
|
+
/**
|
|
59
|
+
* The aggregate a measure runs: `aggregate`, which the query builder reads;
|
|
60
|
+
* the compiler's record only when it is all the column has. Readers ask here,
|
|
61
|
+
* so a column saved with a stale record is still read as it runs.
|
|
62
|
+
*/
|
|
63
|
+
export declare function metricColumnAggregate<A extends string>(column: Pick<MetricAggregateProvenance<A>, 'aggregate' | 'effectiveAggregate'>): A | undefined;
|
|
64
|
+
/**
|
|
65
|
+
* Whether someone chose a measure's aggregate rather than it being the
|
|
66
|
+
* default: the one reading of every stored shape. A column written here says
|
|
67
|
+
* so in `aggregateOrigin`; one saved before carries either the editor's mark,
|
|
68
|
+
* the compiler's record (an override, or a default the aggregate no longer
|
|
69
|
+
* equals because an editor change left the record stale), or neither (read as
|
|
70
|
+
* chosen, so a query states it).
|
|
71
|
+
*/
|
|
72
|
+
export declare function isMetricAggregateChosen(column: MetricAggregateProvenance): boolean;
|
|
73
|
+
/** The keys an authored label sets together. */
|
|
74
|
+
export declare const AUTHORED_LABEL_KEYS: readonly string[];
|
|
75
|
+
/**
|
|
76
|
+
* What to set for a label someone wrote: an override, which the editor never
|
|
77
|
+
* refreshes as a generated label, and no `derivedLabel`, so the field display
|
|
78
|
+
* rule reads it as authored even when it repeats the synthesized text. A
|
|
79
|
+
* patch for the editor's column updates (`derivedLabel: undefined` drops it
|
|
80
|
+
* when saved); `withAuthoredLabel` applies it to a column.
|
|
81
|
+
*/
|
|
82
|
+
export declare function authoredLabelPatch(label: string): LabelProvenance;
|
|
83
|
+
/** A column with a label someone wrote (`authoredLabelPatch`). */
|
|
84
|
+
export declare function withAuthoredLabel<T extends LabelProvenance>(column: T, label: string): T;
|
|
85
|
+
/**
|
|
86
|
+
* What to set for a generated label (an aggregate's "Average of Sales"): the
|
|
87
|
+
* label as a refreshable semantic hint, unless someone wrote the label.
|
|
88
|
+
*/
|
|
89
|
+
export declare function generatedLabelPatch(column: Pick<LabelProvenance, 'labelOrigin'>, label: string): LabelProvenance;
|
|
@@ -28,6 +28,8 @@ export * from './relative-date-label.js';
|
|
|
28
28
|
export * from './operation-temporal-state.js';
|
|
29
29
|
export * from './aggregate-expression.js';
|
|
30
30
|
export * from './measure-aggregation-profile.js';
|
|
31
|
+
export * from './field-provenance.js';
|
|
32
|
+
export * from './query-policies.js';
|
|
31
33
|
export * from './analytics-refusal.js';
|
|
32
34
|
export * from './visual-choice.js';
|
|
33
35
|
/**
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Small pure policies of how a query runs, shared by the governed compiler
|
|
3
|
+
* and the query builder (semaphor-app) and by whatever reads a saved card
|
|
4
|
+
* back (MCP dashboard editing, ledger V-19). Each was written once on the
|
|
5
|
+
* compiling side and again, inverted, on the reading side; a change to one
|
|
6
|
+
* copy would have broken the other silently. Grounding and SQL generation
|
|
7
|
+
* stay app-owned: these are the string and ordering rules only.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The sort a query gets when it states none: the grouped date ascending;
|
|
11
|
+
* else, when something is grouped, the primary measure (the first when none
|
|
12
|
+
* is named) descending; else none.
|
|
13
|
+
*/
|
|
14
|
+
export declare function defaultQuerySort<T>(parts: {
|
|
15
|
+
groupedDate?: T;
|
|
16
|
+
measures: readonly T[];
|
|
17
|
+
grouped: boolean;
|
|
18
|
+
primaryMeasure?: T;
|
|
19
|
+
}): {
|
|
20
|
+
target: T;
|
|
21
|
+
direction: 'asc' | 'desc';
|
|
22
|
+
} | undefined;
|
|
23
|
+
/** The saved condition operators that run a LIKE pattern. */
|
|
24
|
+
export type SavedPatternOperator = 'contains' | 'startsWith' | 'endsWith' | 'like' | 'not like';
|
|
25
|
+
export declare const SAVED_PATTERN_OPERATORS: ReadonlySet<string>;
|
|
26
|
+
/** A LIKE wildcard: `%` or `_`. */
|
|
27
|
+
export declare function hasLikeWildcard(value: string): boolean;
|
|
28
|
+
/**
|
|
29
|
+
* The LIKE pattern a saved condition runs (the query builder's rule):
|
|
30
|
+
* `contains` matches anywhere, `startsWith` and `endsWith` at one end, and
|
|
31
|
+
* `like` and `not like` run the value as written.
|
|
32
|
+
*/
|
|
33
|
+
export declare function savedConditionPattern(operator: SavedPatternOperator, value: string): {
|
|
34
|
+
pattern: string;
|
|
35
|
+
negate: boolean;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The pattern a public `contains` filter runs (the compiler's rule): the
|
|
39
|
+
* value wrapped in `%...%`, unless it already holds a wildcard.
|
|
40
|
+
*/
|
|
41
|
+
export declare function containsFilterPattern(value: string): string;
|
|
42
|
+
/**
|
|
43
|
+
* A saved pattern condition as the public `contains` / `not_contains` filter
|
|
44
|
+
* that runs the same pattern again, or undefined when none does (a pattern
|
|
45
|
+
* without a wildcard matches a value exactly). Checked against
|
|
46
|
+
* `containsFilterPattern` itself, so the reading can never drift from the
|
|
47
|
+
* compiler.
|
|
48
|
+
*/
|
|
49
|
+
export declare function statedPatternFilter(operator: SavedPatternOperator, value: string): {
|
|
50
|
+
operator: 'contains' | 'not_contains';
|
|
51
|
+
value: string;
|
|
52
|
+
} | undefined;
|
|
@@ -160,7 +160,7 @@ export declare function semaphorTimeWindowSchemas(options?: {
|
|
|
160
160
|
start: string;
|
|
161
161
|
end: string;
|
|
162
162
|
}>;
|
|
163
|
-
timeWindow: z.ZodUnion<[z.ZodEffects<z.ZodObject<{
|
|
163
|
+
timeWindow: z.ZodUnion<readonly [z.ZodEffects<z.ZodObject<{
|
|
164
164
|
kind: z.ZodOptional<z.ZodLiteral<"relative">>;
|
|
165
165
|
unit: z.ZodEnum<["second", "minute", "hour", "day", "week", "month", "quarter", "year"]>;
|
|
166
166
|
value: z.ZodNumber;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { SemaphorRelativeTimeWindow, SemaphorTimeGrain } from './contracts.js';
|
|
1
|
+
import { SemaphorCalendarTimeWindow, SemaphorRelativeTimeWindow, SemaphorTimeGrain, SemaphorTimeWindow } from './contracts.js';
|
|
2
|
+
import { RelativeDateFilter } from './relative-date-filter.js';
|
|
2
3
|
/** Units a calendar window ("this month", "previous quarter") can name. */
|
|
3
4
|
export declare const SEMAPHOR_CALENDAR_TIME_WINDOW_UNITS: readonly ["day", "week", "month", "quarter", "year"];
|
|
4
5
|
export declare const SEMAPHOR_CALENDAR_TIME_WINDOW_PERIODS: readonly ["this", "previous"];
|
|
@@ -11,3 +12,41 @@ export declare const SEMAPHOR_TIME_WINDOW_MAX_VALUE: Readonly<Record<SemaphorTim
|
|
|
11
12
|
* latest available data; a saved card that should keep rolling states "now".
|
|
12
13
|
*/
|
|
13
14
|
export declare function resolveTimeWindowAnchor(timeWindow: Pick<SemaphorRelativeTimeWindow, 'anchor'>): 'now' | 'latest_available';
|
|
15
|
+
/** A rolling "last N units" window (`kind` "relative" or omitted). */
|
|
16
|
+
export declare function isRelativeTimeWindow(timeWindow: SemaphorTimeWindow | null | undefined): timeWindow is SemaphorRelativeTimeWindow;
|
|
17
|
+
/** A whole calendar period, such as this month or the previous quarter. */
|
|
18
|
+
export declare function isCalendarTimeWindow(timeWindow: SemaphorTimeWindow | null | undefined): timeWindow is SemaphorCalendarTimeWindow;
|
|
19
|
+
/**
|
|
20
|
+
* A window as a dashboard filter's default. Filter defaults run to now (the
|
|
21
|
+
* editor's presets and the filter runtime have no latest-data anchor), so a
|
|
22
|
+
* rolling window without an anchor is anchored at now, and one anchored to
|
|
23
|
+
* the latest available data is not a filter default (null), never quietly
|
|
24
|
+
* moved to now. The one conversion every writer and checker of a filter
|
|
25
|
+
* default uses.
|
|
26
|
+
*/
|
|
27
|
+
export declare function timeWindowToFilterDefault(timeWindow: SemaphorTimeWindow): RelativeDateFilter | null;
|
|
28
|
+
/** A rolling week, month, quarter or year that includes the current, partial one: no filter preset holds it. */
|
|
29
|
+
export declare function isPartialRollingPeriod(timeWindow: SemaphorTimeWindow): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* The time window a filter default states, the inverse of
|
|
32
|
+
* `timeWindowToFilterDefault`, so what an agent reads back is what it would
|
|
33
|
+
* write: the last N days with today (`between` days from 1-N to 0), complete
|
|
34
|
+
* periods, this or the previous period; a rolling window saved before is
|
|
35
|
+
* read as rolling. Null for any other stored default, such as `between` on
|
|
36
|
+
* whole weeks or months, which no time window states.
|
|
37
|
+
*/
|
|
38
|
+
export declare function filterDefaultToTimeWindow(meta: RelativeDateFilter): SemaphorTimeWindow | null;
|
|
39
|
+
/**
|
|
40
|
+
* The relative date an agent time window persists as (plan D10, amended by
|
|
41
|
+
* analytics kernel K11), or null when it can't stay relative: absolute
|
|
42
|
+
* windows, second units, and complete minute or hour periods. A window
|
|
43
|
+
* anchored to the latest available data (an omitted anchor included) counts
|
|
44
|
+
* back from its own field's data anchor (`relativeTo: 'latest_data'`).
|
|
45
|
+
* `completeness` is the completeness the run used, when it was inferred.
|
|
46
|
+
* Moved from semaphor-app's query-spec-filters so a card's date window and a
|
|
47
|
+
* dashboard filter's default period convert through one owner (MCP dashboard
|
|
48
|
+
* editing, ledger P3-04).
|
|
49
|
+
*/
|
|
50
|
+
export declare function timeWindowToRelativeDateFilter(timeWindow: SemaphorTimeWindow, options?: {
|
|
51
|
+
completeness?: 'include_partial' | 'complete_periods';
|
|
52
|
+
}): RelativeDateFilter | null;
|
|
@@ -35,7 +35,9 @@ export declare function projectSavedDashboardContext(input: {
|
|
|
35
35
|
/**
|
|
36
36
|
* What a browser opening the saved dashboard at `place` sends with a message:
|
|
37
37
|
* the context and, for an asked-about card, its replay fields, both from the
|
|
38
|
-
* one snapshot (ledger P3-92)
|
|
38
|
+
* one snapshot (ledger P3-92), and the dashboard it projected, which a person
|
|
39
|
+
* who may change it sends as `openDashboard` (Phase 7, D7-29). The regression
|
|
40
|
+
* set sends exactly this.
|
|
39
41
|
*/
|
|
40
42
|
export declare function projectSavedDashboardTurn(input: {
|
|
41
43
|
dashboard: TDashboard;
|
|
@@ -45,6 +47,7 @@ export declare function projectSavedDashboardTurn(input: {
|
|
|
45
47
|
}): {
|
|
46
48
|
context: AssistantContext;
|
|
47
49
|
cardReplay?: AssistantCardReplayFields;
|
|
50
|
+
openDashboard: TDashboard;
|
|
48
51
|
};
|
|
49
52
|
/** The turn request's fields for an asked-about card: its request, or why it has none. */
|
|
50
53
|
export type AssistantCardReplayFields = {
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AssistantPart } from './parts.js';
|
|
2
|
+
/**
|
|
3
|
+
* Which of an answer's text is the answer (analytics agent Plan 1, P7-23):
|
|
4
|
+
* its last run of text, the text after the last step that more text follows.
|
|
5
|
+
* Text the model wrote before such a step ("Need the domain and fields.") is
|
|
6
|
+
* a working note: the transcript shows it while the assistant works, and not
|
|
7
|
+
* as the answer once more text follows a later step. An answer followed by a
|
|
8
|
+
* last query and nothing after it keeps its text, so no answer that wrote
|
|
9
|
+
* anything comes out empty. A step is a stage that reads data (a query, a
|
|
10
|
+
* lookup); a change to the dashboard, showing a result or asking the person a
|
|
11
|
+
* question is not one, so an answer written before its change stays the
|
|
12
|
+
* answer (P7-45). One rule for the transcript, the turn record and the eval.
|
|
13
|
+
*/
|
|
14
|
+
export type AnswerPartKind = 'text' | 'step' | 'other';
|
|
15
|
+
/** The parts that are working notes: text before the last step that comes before the answer's last text. */
|
|
16
|
+
export declare function workingNotesOf<T>(parts: readonly T[], kindOf: (part: T) => AnswerPartKind): ReadonlySet<T>;
|
|
17
|
+
/** A stored part's kind for `workingNotesOf`. */
|
|
18
|
+
export declare function storedPartKind(part: AssistantPart): AnswerPartKind;
|
|
19
|
+
/** A stored answer's text: its text parts after the last step, a paragraph each. */
|
|
20
|
+
export declare function answerTextOf(parts: readonly AssistantPart[]): string;
|