@tangle-network/agent-app 0.45.53 → 0.45.55
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/README.md +1 -1
- package/dist/alerting/index.d.ts +5 -175
- package/dist/alerting/slack.d.ts +176 -0
- package/dist/app-auth/index.d.ts +14 -17
- package/dist/assets/index.d.ts +2 -504
- package/dist/assets/schema.d.ts +264 -0
- package/dist/assets/types.d.ts +237 -0
- package/dist/assistant/AssistantDock.d.ts +56 -0
- package/dist/assistant/AssistantHistory.d.ts +41 -0
- package/dist/assistant/AssistantPanel.d.ts +84 -0
- package/dist/assistant/ProposalCard.d.ts +41 -0
- package/dist/assistant/ResizeHandle.d.ts +19 -0
- package/dist/assistant/client-context.d.ts +20 -0
- package/dist/assistant/client.d.ts +117 -0
- package/dist/assistant/index.d.ts +19 -848
- package/dist/assistant/launcher.d.ts +23 -0
- package/dist/assistant/persistence.d.ts +26 -0
- package/dist/assistant/presentation.d.ts +99 -0
- package/dist/assistant/provider-label.d.ts +7 -0
- package/dist/assistant/reducer.d.ts +130 -0
- package/dist/assistant/sse.d.ts +24 -0
- package/dist/assistant/time-ago.d.ts +6 -0
- package/dist/assistant/transcript.d.ts +97 -0
- package/dist/assistant/types.d.ts +291 -0
- package/dist/assistant/use-stick-to-bottom.d.ts +28 -0
- package/dist/assistant/useAssistantChat.d.ts +63 -0
- package/dist/assistant/useAssistantModels.d.ts +22 -0
- package/dist/assistant/useAssistantThreads.d.ts +47 -0
- package/dist/assistant/usePanelPrefs.d.ts +55 -0
- package/dist/billing/index.d.ts +19 -21
- package/dist/brand/index.d.ts +16 -10
- package/dist/brand-extraction/extract.d.ts +34 -0
- package/dist/brand-extraction/index.d.ts +12 -214
- package/dist/brand-extraction/map.d.ts +58 -0
- package/dist/brand-extraction/types.d.ts +119 -0
- package/dist/catalog/index.d.ts +11 -101
- package/dist/chat-react/composer-mode-controls.d.ts +14 -0
- package/dist/chat-react/entry-composer.d.ts +92 -0
- package/dist/chat-react/index.d.ts +22 -118
- package/dist/chat-react/types.d.ts +11 -0
- package/dist/chat-routes/attachment-store.d.ts +84 -0
- package/dist/chat-routes/attachment-upload.d.ts +84 -0
- package/dist/chat-routes/attachment-validation.d.ts +95 -0
- package/dist/chat-routes/binary-sniff.d.ts +45 -0
- package/dist/chat-routes/completed-sandbox-turn.d.ts +25 -0
- package/dist/chat-routes/detached-turn.d.ts +197 -0
- package/dist/chat-routes/dispatch-parts.d.ts +101 -0
- package/dist/chat-routes/draft-persistence.d.ts +189 -0
- package/dist/chat-routes/durable-projection.d.ts +18 -0
- package/dist/chat-routes/file-index.d.ts +115 -0
- package/dist/chat-routes/index.d.ts +25 -1840
- package/dist/chat-routes/model-failover-stream.d.ts +206 -0
- package/dist/chat-routes/promote-file-part.d.ts +84 -0
- package/dist/chat-routes/resolve-attachments.d.ts +72 -0
- package/dist/chat-routes/sandbox-producer.d.ts +146 -0
- package/dist/chat-routes/sandbox-turn-usage.d.ts +4 -0
- package/dist/{stale-turn-lock-DucQzvXu.d.ts → chat-routes/stale-turn-lock.d.ts} +7 -9
- package/dist/chat-routes/turn-routes.d.ts +540 -0
- package/dist/chat-routes/upload.d.ts +84 -0
- package/dist/{wire-DOZ-O6hD.d.ts → chat-routes/wire.d.ts} +41 -44
- package/dist/chat-store/core.d.ts +19 -0
- package/dist/chat-store/index.d.ts +22 -322
- package/dist/{parts-BqIHMdyu.d.ts → chat-store/parts.d.ts} +49 -47
- package/dist/chat-store/schema.d.ts +157 -0
- package/dist/chat-store/store.d.ts +177 -0
- package/dist/config/index.d.ts +13 -18
- package/dist/crypto/index.d.ts +10 -12
- package/dist/crypto/web-token.d.ts +22 -0
- package/dist/design-canvas/apply.d.ts +70 -0
- package/dist/design-canvas/drizzle-store.d.ts +29 -0
- package/dist/design-canvas/drizzle.d.ts +7 -575
- package/dist/{export-presets-mgVulRaV.d.ts → design-canvas/export-presets.d.ts} +18 -22
- package/dist/design-canvas/index.d.ts +22 -268
- package/dist/design-canvas/mcp-entry.d.ts +15 -0
- package/dist/design-canvas/mcp-handler.d.ts +34 -0
- package/dist/design-canvas/mcp-tools.d.ts +30 -0
- package/dist/{model-DnfO_PdJ.d.ts → design-canvas/model.d.ts} +33 -35
- package/dist/{operations-ByJ6yXOW.d.ts → design-canvas/operations.d.ts} +21 -25
- package/dist/design-canvas/schema.d.ts +558 -0
- package/dist/{store-CqfDtnPQ.d.ts → design-canvas/store.d.ts} +8 -12
- package/dist/design-canvas/templates.d.ts +72 -0
- package/dist/design-canvas/validate.d.ts +32 -0
- package/dist/design-canvas-react/components/BleedTrimOverlay.d.ts +22 -0
- package/dist/design-canvas-react/components/BrandKnot.d.ts +11 -0
- package/dist/design-canvas-react/components/CanvasEmptyState.d.ts +32 -0
- package/dist/design-canvas-react/components/CanvasInsertPanel.d.ts +53 -0
- package/dist/{lazy-DrkVyDpe.d.ts → design-canvas-react/components/DesignCanvas.d.ts} +27 -20
- package/dist/design-canvas-react/components/DesignCanvasEditor.d.ts +23 -0
- package/dist/design-canvas-react/components/ElementNode.d.ts +51 -0
- package/dist/design-canvas-react/components/ExportControl.d.ts +21 -0
- package/dist/design-canvas-react/components/GridLayer.d.ts +47 -0
- package/dist/design-canvas-react/components/InlineTextEditor.d.ts +25 -0
- package/dist/design-canvas-react/components/LayersPanel.d.ts +20 -0
- package/dist/design-canvas-react/components/PagesStrip.d.ts +34 -0
- package/dist/design-canvas-react/components/Rulers.d.ts +31 -0
- package/dist/design-canvas-react/components/SelectionLayer.d.ts +51 -0
- package/dist/design-canvas-react/components/SnapGuidesOverlay.d.ts +25 -0
- package/dist/design-canvas-react/components/Toolbar.d.ts +64 -0
- package/dist/design-canvas-react/components/Workspace.d.ts +92 -0
- package/dist/design-canvas-react/components/ZoomControls.d.ts +14 -0
- package/dist/design-canvas-react/components/glyphs.d.ts +46 -0
- package/dist/design-canvas-react/components/icon-button.d.ts +22 -0
- package/dist/design-canvas-react/components/index.d.ts +27 -0
- package/dist/design-canvas-react/components/layer-tree.d.ts +34 -0
- package/dist/design-canvas-react/components/ruler-math.d.ts +78 -0
- package/dist/design-canvas-react/components/transform-math.d.ts +168 -0
- package/dist/{command-stack-TNPWJCzW.d.ts → design-canvas-react/contracts.d.ts} +16 -63
- package/dist/design-canvas-react/engine/command-stack.d.ts +43 -0
- package/dist/design-canvas-react/engine/commands.d.ts +154 -0
- package/dist/design-canvas-react/engine/selection.d.ts +48 -0
- package/dist/design-canvas-react/engine/snap.d.ts +24 -0
- package/dist/design-canvas-react/engine/zoom-pan.d.ts +18 -0
- package/dist/design-canvas-react/engine.d.ts +21 -399
- package/dist/design-canvas-react/export-math.d.ts +104 -0
- package/dist/design-canvas-react/export.d.ts +89 -0
- package/dist/design-canvas-react/index.d.ts +16 -586
- package/dist/design-canvas-react/insert-builders.d.ts +61 -0
- package/dist/design-canvas-react/lazy.d.ts +21 -6
- package/dist/documents/docx.d.ts +50 -0
- package/dist/documents/extract.d.ts +87 -0
- package/dist/documents/index.d.ts +26 -232
- package/dist/documents/media-type.d.ts +33 -0
- package/dist/documents/pdf-inspector.d.ts +5 -9
- package/dist/{types-DrBidf3O.d.ts → documents/types.d.ts} +13 -15
- package/dist/documents/zip.d.ts +56 -0
- package/dist/eval/calibration.d.ts +106 -0
- package/dist/eval/index.d.ts +8 -116
- package/dist/eval-campaign/index.d.ts +11 -12
- package/dist/{trust-gate-Dcm5xSva.d.ts → eval-campaign/trust-gate.d.ts} +5 -9
- package/dist/forms/blank.d.ts +48 -0
- package/dist/forms/fill.d.ts +105 -0
- package/dist/forms/index.d.ts +58 -332
- package/dist/forms/registry.d.ts +115 -0
- package/dist/forms/verify.d.ts +58 -0
- package/dist/harness/index.d.ts +21 -19
- package/dist/intakes/api.d.ts +5 -11
- package/dist/{completion-CvcNUz07.d.ts → intakes/completion.d.ts} +7 -11
- package/dist/intakes/context-sufficiency.d.ts +113 -0
- package/dist/intakes/drizzle/schema.d.ts +338 -0
- package/dist/intakes/drizzle/store.d.ts +75 -0
- package/dist/intakes/drizzle.d.ts +12 -391
- package/dist/intakes/index.d.ts +23 -113
- package/dist/{model-C8U0HZxL.d.ts → intakes/model.d.ts} +15 -17
- package/dist/intakes-react/components/BrandMark.d.ts +10 -0
- package/dist/intakes-react/components/IntakeInterview.d.ts +15 -0
- package/dist/intakes-react/components/index.d.ts +1 -0
- package/dist/intakes-react/contracts.d.ts +42 -0
- package/dist/intakes-react/index.d.ts +12 -47
- package/dist/intakes-react/lazy.d.ts +9 -8
- package/dist/integrations/index.d.ts +10 -12
- package/dist/{contract-OxG_jVMx.d.ts → interactions/contract.d.ts} +40 -42
- package/dist/interactions/index.d.ts +16 -256
- package/dist/interactions/route.d.ts +151 -0
- package/dist/interactions/sidecar.d.ts +100 -0
- package/dist/knowledge/index.d.ts +7 -11
- package/dist/knowledge-loop/index.d.ts +13 -20
- package/dist/legibility/checks/empty-state.d.ts +59 -0
- package/dist/legibility/checks/reachability.d.ts +103 -0
- package/dist/legibility/checks/silent-failure.d.ts +57 -0
- package/dist/legibility/checks/success.d.ts +38 -0
- package/dist/legibility/checks/vocabulary.d.ts +65 -0
- package/dist/legibility/cli-args.d.ts +30 -0
- package/dist/legibility/cli.d.ts +25 -0
- package/dist/legibility/index.d.ts +10 -530
- package/dist/legibility/report.d.ts +22 -0
- package/dist/legibility/scan.d.ts +29 -0
- package/dist/legibility/source.d.ts +132 -0
- package/dist/legibility/suppress.d.ts +36 -0
- package/dist/legibility/types.d.ts +168 -0
- package/dist/legibility/walk-sources.d.ts +21 -0
- package/dist/{agent-activity-C8ZG0F0M.d.ts → missions/agent-activity.d.ts} +3 -5
- package/dist/missions/engine.d.ts +251 -0
- package/dist/missions/events.d.ts +195 -0
- package/dist/missions/index.d.ts +12 -765
- package/dist/missions/plan-parse.d.ts +50 -0
- package/dist/missions/service.d.ts +265 -0
- package/dist/{failover-D-3UXXTb.d.ts → model-resolution/failover.d.ts} +10 -12
- package/dist/model-resolution/index.d.ts +15 -18
- package/dist/object-store/index.d.ts +15 -17
- package/dist/openui/action.d.ts +54 -0
- package/dist/openui/authoring.d.ts +25 -0
- package/dist/openui/index.d.ts +24 -206
- package/dist/openui/route.d.ts +124 -0
- package/dist/openui/segments.d.ts +71 -0
- package/dist/openui/values.d.ts +82 -0
- package/dist/openui-react/index.d.ts +9 -13
- package/dist/peer-floors/check.d.ts +9 -190
- package/dist/peer-floors/cli.d.ts +2 -3
- package/dist/peer-floors/dependency-source.d.ts +178 -0
- package/dist/plans/index.d.ts +13 -14
- package/dist/{billing-BuNlaKlE.d.ts → platform/billing.d.ts} +28 -32
- package/dist/platform/guards.d.ts +79 -0
- package/dist/platform/hub.d.ts +107 -0
- package/dist/platform/index.d.ts +7 -112
- package/dist/{sso-Cm00S61u.d.ts → platform/sso.d.ts} +15 -97
- package/dist/preflight/cli.d.ts +3 -6
- package/dist/preflight/index.d.ts +16 -18
- package/dist/preset-cloudflare/headers.d.ts +12 -0
- package/dist/preset-cloudflare/index.d.ts +22 -74
- package/dist/preset-cloudflare/workflow-instance.d.ts +35 -0
- package/dist/profile/budget.d.ts +72 -0
- package/dist/profile/fingerprint.d.ts +65 -0
- package/dist/profile/index.d.ts +27 -19
- package/dist/prompt/index.d.ts +3 -5
- package/dist/record/drizzle/schema.d.ts +488 -0
- package/dist/record/drizzle/store.d.ts +224 -0
- package/dist/record/drizzle.d.ts +10 -679
- package/dist/record/fold.d.ts +99 -0
- package/dist/record/index.d.ts +13 -13
- package/dist/{fold-DACU7gtf.d.ts → record/model.d.ts} +22 -124
- package/dist/record/ulid.d.ts +12 -0
- package/dist/redact/index.d.ts +14 -16
- package/dist/run/index.d.ts +11 -16
- package/dist/runtime/agent.d.ts +23 -0
- package/dist/runtime/certified-delivery.d.ts +57 -0
- package/dist/runtime/index.d.ts +17 -367
- package/dist/runtime/loop.d.ts +58 -0
- package/dist/runtime/model-catalog.d.ts +103 -0
- package/dist/{model-CdCDfBA9.d.ts → runtime/model.d.ts} +25 -27
- package/dist/runtime/openai-stream.d.ts +126 -0
- package/dist/runtime/surface-profile.d.ts +115 -0
- package/dist/sandbox/binary-read.d.ts +63 -0
- package/dist/sandbox/diagnostics.d.ts +69 -0
- package/dist/sandbox/index.d.ts +103 -1085
- package/dist/sandbox/model.d.ts +179 -0
- package/dist/sandbox/outcome.d.ts +10 -0
- package/dist/sandbox/prewarm-claim-d1.d.ts +80 -0
- package/dist/sandbox/prewarm.d.ts +193 -0
- package/dist/sandbox/recovery.d.ts +216 -0
- package/dist/sandbox/terminal-connection.d.ts +145 -0
- package/dist/sandbox/workspace-sandbox-manager.d.ts +44 -0
- package/dist/sequences/apply.d.ts +54 -0
- package/dist/sequences/captions.d.ts +91 -0
- package/dist/sequences/drizzle-store.d.ts +36 -0
- package/dist/sequences/drizzle.d.ts +7 -1252
- package/dist/sequences/exports.d.ts +138 -0
- package/dist/sequences/index.d.ts +19 -340
- package/dist/sequences/mcp-entry.d.ts +15 -0
- package/dist/sequences/mcp-handler.d.ts +39 -0
- package/dist/sequences/mcp-tools.d.ts +47 -0
- package/dist/{store-B7LLlk9p.d.ts → sequences/model.d.ts} +26 -110
- package/dist/sequences/operations.d.ts +126 -0
- package/dist/sequences/schema.d.ts +1231 -0
- package/dist/sequences/store.d.ts +81 -0
- package/dist/sequences/validate.d.ts +98 -0
- package/dist/sequences-react/components/BrandMark.d.ts +10 -0
- package/dist/sequences-react/components/PreviewCanvas.d.ts +26 -0
- package/dist/sequences-react/components/SnapIndicatorLine.d.ts +11 -0
- package/dist/sequences-react/components/TimelineClipChip.d.ts +80 -0
- package/dist/sequences-react/components/TimelineEditor.d.ts +44 -0
- package/dist/sequences-react/components/TimelineEmptyState.d.ts +21 -0
- package/dist/sequences-react/components/TimelineGhostLanes.d.ts +14 -0
- package/dist/sequences-react/components/TimelinePlayhead.d.ts +11 -0
- package/dist/sequences-react/components/TimelineRuler.d.ts +16 -0
- package/dist/sequences-react/components/TimelineSmallScreenGate.d.ts +12 -0
- package/dist/sequences-react/components/TimelineTrackRow.d.ts +51 -0
- package/dist/sequences-react/components/ZoomControl.d.ts +15 -0
- package/dist/sequences-react/components/composite-command.d.ts +8 -0
- package/dist/sequences-react/components/glyphs.d.ts +26 -0
- package/dist/sequences-react/components/index.d.ts +31 -0
- package/dist/sequences-react/components/interaction-math.d.ts +103 -0
- package/dist/sequences-react/contracts.d.ts +187 -0
- package/dist/sequences-react/engine/command-stack.d.ts +18 -0
- package/dist/sequences-react/engine/commands.d.ts +146 -0
- package/dist/sequences-react/engine/playback.d.ts +18 -0
- package/dist/sequences-react/engine/snap.d.ts +29 -0
- package/dist/sequences-react/engine/zoom.d.ts +29 -0
- package/dist/sequences-react/index.d.ts +20 -880
- package/dist/sequences-react/lazy.d.ts +8 -0
- package/dist/sequences-react/media/frame-provider.d.ts +70 -0
- package/dist/sequences-react/media/transcription.d.ts +33 -0
- package/dist/sequences-react/media/waveform.d.ts +34 -0
- package/dist/session-shell/index.d.ts +31 -204
- package/dist/session-shell/nav-guard.d.ts +170 -0
- package/dist/session-shell/path.d.ts +19 -0
- package/dist/signoff/cli.d.ts +4 -7
- package/dist/signoff/config.d.ts +12 -0
- package/dist/signoff/exec.d.ts +44 -0
- package/dist/signoff/index.d.ts +56 -14
- package/dist/signoff/invoked-as-script.d.ts +25 -0
- package/dist/signoff/node-version.d.ts +50 -0
- package/dist/signoff/proof-attach.d.ts +88 -0
- package/dist/signoff/proof-cli.d.ts +1 -0
- package/dist/signoff/proof-fixture.d.ts +13 -0
- package/dist/signoff/proof-from-report.d.ts +22 -0
- package/dist/signoff/proof-git.d.ts +57 -0
- package/dist/signoff/proof-record.d.ts +202 -0
- package/dist/signoff/proof-verify.d.ts +103 -0
- package/dist/signoff/proof.d.ts +35 -310
- package/dist/signoff/report.d.ts +7 -0
- package/dist/{run-D80hoLKh.d.ts → signoff/run.d.ts} +3 -6
- package/dist/signoff/schedule.d.ts +55 -0
- package/dist/signoff/seeds.d.ts +50 -0
- package/dist/signoff/store.d.ts +22 -0
- package/dist/{types-Bd6uW9vQ.d.ts → signoff/types.d.ts} +15 -17
- package/dist/signoff/workflow-pin.d.ts +56 -0
- package/dist/signoff/workspace.d.ts +40 -0
- package/dist/skills/index.d.ts +28 -32
- package/dist/skills-placement/index.d.ts +7 -11
- package/dist/spend/budget.d.ts +123 -0
- package/dist/spend/ceiling.d.ts +51 -0
- package/dist/spend/cli-args.d.ts +20 -0
- package/dist/spend/cli.d.ts +1 -0
- package/dist/spend/fixtures/incident-parked-time.d.ts +55 -0
- package/dist/spend/index.d.ts +38 -1144
- package/dist/spend/liveness.d.ts +131 -0
- package/dist/spend/ownership.d.ts +87 -0
- package/dist/spend/reconcile.d.ts +109 -0
- package/dist/spend/reference.d.ts +42 -0
- package/dist/spend/report.d.ts +12 -0
- package/dist/spend/store.d.ts +123 -0
- package/dist/spend/types.d.ts +466 -0
- package/dist/store/index.d.ts +10 -12
- package/dist/stories/app-shell/fixtures.d.ts +43 -0
- package/dist/stories/app-shell/shell.d.ts +81 -0
- package/dist/stories/assistant/fixtures.d.ts +73 -0
- package/dist/stories/chat/fixtures.d.ts +70 -0
- package/dist/stories/chat/markdown.d.ts +11 -0
- package/dist/stories/chat/run-drill-in.d.ts +19 -0
- package/dist/stories/chat-controls/fixtures.d.ts +116 -0
- package/dist/stories/design-canvas/fixtures.d.ts +57 -0
- package/dist/stories/fixtures/canvas.d.ts +10 -0
- package/dist/stories/fixtures/catalog.d.ts +7 -0
- package/dist/stories/fixtures/chat.d.ts +39 -0
- package/dist/stories/fixtures/index.d.ts +4 -0
- package/dist/stories/fixtures/sequences.d.ts +17 -0
- package/dist/stories/panels/fixtures.d.ts +63 -0
- package/dist/stories/sequences/fixtures.d.ts +30 -0
- package/dist/stories/studio/fixtures.d.ts +22 -0
- package/dist/stream/index.d.ts +10 -56
- package/dist/{stream-normalizer-DKRxyVlZ.d.ts → stream/stream-normalizer.d.ts} +23 -26
- package/dist/{turn-buffer-COMQUwO2.d.ts → stream/turn-buffer.d.ts} +21 -23
- package/dist/stream/turn-identity.d.ts +49 -0
- package/dist/studio/generation.d.ts +179 -0
- package/dist/studio/index.d.ts +12 -181
- package/dist/studio-react/avatar-composer.d.ts +8 -0
- package/dist/studio-react/composer-hero.d.ts +12 -0
- package/dist/studio-react/composer-shell.d.ts +18 -0
- package/dist/studio-react/generation-card.d.ts +9 -0
- package/dist/studio-react/generation-detail-modal.d.ts +11 -0
- package/dist/studio-react/generation-detail.d.ts +6 -0
- package/dist/studio-react/generation-grid.d.ts +15 -0
- package/dist/studio-react/image-composer.d.ts +8 -0
- package/dist/studio-react/index.d.ts +32 -245
- package/dist/studio-react/library-drawer.d.ts +12 -0
- package/dist/studio-react/library-panel.d.ts +15 -0
- package/dist/studio-react/publish-package-composer.d.ts +18 -0
- package/dist/studio-react/result-canvas.d.ts +6 -0
- package/dist/studio-react/speech-composer.d.ts +4 -0
- package/dist/studio-react/studio-header.d.ts +5 -0
- package/dist/studio-react/studio-sheet.d.ts +12 -0
- package/dist/studio-react/studio-workspace.d.ts +23 -0
- package/dist/studio-react/transcription-composer.d.ts +12 -0
- package/dist/studio-react/type-config.d.ts +11 -0
- package/dist/studio-react/use-studio-generations.d.ts +20 -0
- package/dist/studio-react/video-composer.d.ts +10 -0
- package/dist/tangle/index.d.ts +7 -9
- package/dist/teams/drizzle/access.d.ts +82 -0
- package/dist/{invitations-schema-_fI7HkJP.d.ts → teams/drizzle/invitations-schema.d.ts} +39 -27
- package/dist/teams/drizzle/personal-organization.d.ts +41 -0
- package/dist/{access-490O6aOU.d.ts → teams/drizzle/schema.d.ts} +57 -122
- package/dist/teams/drizzle.d.ts +12 -44
- package/dist/teams/index.d.ts +20 -44
- package/dist/teams/invitations-api.d.ts +17 -21
- package/dist/{invitations-DoYMvXea.d.ts → teams/invitations.d.ts} +14 -18
- package/dist/teams/invite.d.ts +42 -0
- package/dist/teams/members-api.d.ts +12 -16
- package/dist/teams/resend.d.ts +3 -13
- package/dist/{roles-B4nU3jDi.d.ts → teams/roles.d.ts} +18 -20
- package/dist/teams-react/components/BrandMark.d.ts +10 -0
- package/dist/teams-react/components/InvitationsPanel.d.ts +13 -0
- package/dist/teams-react/components/InviteAcceptPage.d.ts +10 -0
- package/dist/teams-react/components/MembersPanel.d.ts +14 -0
- package/dist/teams-react/components/RoleSelect.d.ts +17 -0
- package/dist/teams-react/components/index.d.ts +3 -0
- package/dist/teams-react/contracts.d.ts +134 -0
- package/dist/teams-react/index.d.ts +12 -143
- package/dist/teams-react/lazy.d.ts +11 -11
- package/dist/test-setup.d.ts +1 -0
- package/dist/theme/index.d.ts +6 -104
- package/dist/theme/tailwind-preset.d.ts +1 -2
- package/dist/theme/theme.d.ts +106 -0
- package/dist/theme-contract/cli.d.ts +21 -0
- package/dist/theme-contract/index.d.ts +4 -6
- package/dist/{auth-BYtiazA4.d.ts → tools/auth.d.ts} +8 -11
- package/dist/tools/capability.d.ts +54 -0
- package/dist/tools/dispatch.d.ts +37 -0
- package/dist/tools/errors.d.ts +8 -0
- package/dist/tools/gating.d.ts +62 -0
- package/dist/tools/http.d.ts +27 -0
- package/dist/tools/index.d.ts +12 -217
- package/dist/{mcp-rpc-DYwPlYbZ.d.ts → tools/mcp-rpc.d.ts} +7 -9
- package/dist/{mcp-xxoZZfor.d.ts → tools/mcp.d.ts} +14 -16
- package/dist/tools/openai.d.ts +28 -0
- package/dist/tools/registry.d.ts +39 -0
- package/dist/tools/runtime.d.ts +22 -0
- package/dist/{types-B25Mib1r.d.ts → tools/types.d.ts} +15 -83
- package/dist/{flow-types-CJxEmaRy.d.ts → trace/flow-types.d.ts} +2 -4
- package/dist/trace/index.d.ts +11 -148
- package/dist/trace/mission-flow.d.ts +82 -0
- package/dist/trace/mission-trace.d.ts +52 -0
- package/dist/turn-health/classify.d.ts +207 -0
- package/dist/turn-health/index.d.ts +29 -637
- package/dist/turn-health/lifecycle.d.ts +75 -0
- package/dist/turn-health/sink.d.ts +122 -0
- package/dist/turn-health/sweep.d.ts +245 -0
- package/dist/turn-stream/adapters.d.ts +257 -0
- package/dist/turn-stream/core.d.ts +293 -0
- package/dist/turn-stream/do.d.ts +144 -0
- package/dist/turn-stream/index.d.ts +62 -738
- package/dist/turn-stream/memory.d.ts +41 -0
- package/dist/vault/ConfirmDialog.d.ts +22 -0
- package/dist/vault/VaultPane.d.ts +15 -0
- package/dist/{VaultPane-BDP6SB_K.d.ts → vault/contracts.d.ts} +15 -22
- package/dist/vault/index.d.ts +15 -22
- package/dist/vault/lazy.d.ts +9 -7
- package/dist/vault/server.d.ts +8 -10
- package/dist/web/free-route-limit.d.ts +187 -0
- package/dist/web/index.d.ts +15 -207
- package/dist/{rate-limit-BOVmJRXZ.d.ts → web/rate-limit.d.ts} +3 -5
- package/dist/web-react/agent-session-controls.d.ts +105 -0
- package/dist/web-react/async/async-view.d.ts +69 -0
- package/dist/web-react/async/index.d.ts +13 -305
- package/dist/web-react/async/state.d.ts +107 -0
- package/dist/web-react/async/use-async-resource.d.ts +41 -0
- package/dist/web-react/async/use-confirmed-mutation.d.ts +90 -0
- package/dist/web-react/brand-mark.d.ts +11 -0
- package/dist/web-react/chat-attachments.d.ts +21 -0
- package/dist/web-react/chat-composer.d.ts +174 -0
- package/dist/web-react/chat-interactions.d.ts +1 -0
- package/dist/web-react/chat-mentions.d.ts +48 -0
- package/dist/web-react/chat-stream.d.ts +106 -0
- package/dist/web-react/class-names.d.ts +10 -0
- package/dist/web-react/controls.d.ts +265 -0
- package/dist/web-react/durable-chat-cards.d.ts +40 -0
- package/dist/web-react/durable-interaction-submit.d.ts +22 -0
- package/dist/web-react/durable-plan-card.d.ts +13 -0
- package/dist/web-react/durable-plan-flow.d.ts +77 -0
- package/dist/web-react/harness-glyphs.d.ts +28 -0
- package/dist/web-react/index.d.ts +80 -2347
- package/dist/web-react/inert.d.ts +39 -0
- package/dist/web-react/insight-card.d.ts +203 -0
- package/dist/web-react/interaction-card-support.d.ts +115 -0
- package/dist/web-react/interaction-plan-card.d.ts +39 -0
- package/dist/web-react/interaction-question-card.d.ts +100 -0
- package/dist/web-react/message-attachments.d.ts +56 -0
- package/dist/web-react/mission-activity.d.ts +96 -0
- package/dist/web-react/motion.d.ts +43 -0
- package/dist/web-react/provenance-model.d.ts +195 -0
- package/dist/web-react/provenance.d.ts +82 -0
- package/dist/web-react/provider-logo.d.ts +14 -0
- package/dist/web-react/record-grid-model.d.ts +257 -0
- package/dist/web-react/record-grid.d.ts +108 -0
- package/dist/web-react/sandbox-terminal.d.ts +90 -0
- package/dist/web-react/seat-paywall.d.ts +47 -0
- package/dist/web-react/session-history.d.ts +196 -0
- package/dist/web-react/smooth-text.d.ts +29 -0
- package/dist/web-react/sparkline.d.ts +150 -0
- package/dist/web-react/terminal.d.ts +1 -92
- package/dist/web-react/use-chat-interactions.d.ts +78 -0
- package/dist/web-react/use-composer-attachments.d.ts +111 -0
- package/dist/web-react/use-file-mentions.d.ts +94 -0
- package/dist/web-react/work-product.d.ts +105 -0
- package/dist/work-product/claim-support.d.ts +288 -0
- package/dist/work-product/index.d.ts +16 -849
- package/dist/work-product/provenance.d.ts +61 -0
- package/dist/{queue-VTBA5ONX.d.ts → work-product/queue.d.ts} +10 -12
- package/dist/work-product/quote.d.ts +139 -0
- package/dist/work-product/route.d.ts +88 -0
- package/dist/work-product/service.d.ts +123 -0
- package/dist/work-product/tools.d.ts +144 -0
- package/dist/{types-CCeYywdS.d.ts → work-product/types.d.ts} +29 -31
- package/dist/work-product-react/index.d.ts +19 -8
- package/dist/workspace-react/index.d.ts +8 -11
- package/package.json +5 -4
- package/dist/agent-session-controls-CmlXwp_H.d.ts +0 -384
- package/dist/apply-6wlMOLf8.d.ts +0 -280
- package/dist/attachment-validation-BfJDBU1g.d.ts +0 -261
- package/dist/budget-BOucfcb_.d.ts +0 -142
- package/dist/values-C7RidJuI.d.ts +0 -156
|
@@ -1,2342 +1,77 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ReactNode, RefObject, ReactElement, CSSProperties } from 'react';
|
|
3
|
-
import { ToolPart } from '@tangle-network/ui/types';
|
|
4
|
-
import { C as ChatInteractionField, I as InteractionAnswers, a as ChatInteractionStatus, b as ChatInteraction, c as InteractionCancelData, d as ChatSelectField, e as InteractionRequestWire } from '../contract-OxG_jVMx.js';
|
|
5
|
-
export { f as ChatFreeTextField, g as ComposerAnswerDelivery, h as INTERACTION_CANCEL_EVENT, i as INTERACTION_EVENT, j as INTERACTION_RESOLVED_EVENT, k as InteractionAnswerValue, l as InteractionPersistedPart, N as NoticeKind, m as NoticePersistedPart, P as ParseInteractionAnswersResult, n as ParseInteractionResult, o as canTransitionInteractionStatus, p as cancelStatusFor, q as composerAnswerData, r as composerAnswerDeliveries, s as dedupeQuestionInteractionsByContent, t as fieldAcceptsFreeText, u as interactionFromWireRequest, v as interactionPartKey, w as interactionToPersistedPart, x as isRenderableInteractionKind, y as isSafeInteractionFieldKey, z as isTerminalInteractionStatus, A as noticePart, B as noticePartKey, D as parseInteractionAnswers, E as parseInteractionCancel, F as parseInteractionRequest, G as persistedPartToInteraction, H as questionInteractionContentSignature, J as stampInteractionAnswers } from '../contract-OxG_jVMx.js';
|
|
6
|
-
import { ChatPlan } from '../plans/index.js';
|
|
7
|
-
import { InteractionData } from '@tangle-network/agent-interface';
|
|
8
|
-
export { InteractionData, InteractionOutcome, InteractionRequest } from '@tangle-network/agent-interface';
|
|
9
|
-
import { e as ChatMentionPart, a as ChatAttachmentPart } from '../parts-BqIHMdyu.js';
|
|
10
|
-
export { s as attachmentInputToPart, t as attachmentKindForMime, u as attachmentPartsFromMessageParts, x as isChatAttachmentPart, H as mentionInputToPart, I as mentionPartsFromMessageParts } from '../parts-BqIHMdyu.js';
|
|
11
|
-
import { E as EvidenceEntry, g as ExceptionEntry, b as WorkProductProvenance, P as ProfileBacktestSummary, Q as QualityCheck, W as WorkProductPersistedPart, h as WorkProductStatus } from '../types-CCeYywdS.js';
|
|
12
|
-
export { a as AgentSessionControls, A as AgentSessionControlsProps, C as ComposerMentionProp, D as DEFAULT_EFFORT_LEVELS, b as DEFAULT_MENTION_EMPTY_TEXT, c as DEFAULT_MENTION_LIMIT, E as EFFORT_METER_SEGMENTS, d as EffortLevel, e as EffortMeter, f as EffortPicker, g as EffortPickerProps, I as INDEX_REFRESH_AFTER_MS, M as MentionItem, h as ModelPicker, i as ModelPickerProps, O as OVERLAY_SHADOW, P as POPOVER_SURFACE_ATTR, j as PopoverSurface, k as PopoverSurfaceProps, l as UseFileMentionsOptions, U as UseFileMentionsResult, m as effortLevelLabel, n as effortLevelsFromIds, o as effortMeterFill, r as rankFileMentions, p as reconcileEffortLevels, u as useFileMentions, q as usePending, s as usePopover } from '../agent-session-controls-CmlXwp_H.js';
|
|
13
|
-
import { a as ChatAttachmentKind, b as ChatAttachmentInput } from '../wire-DOZ-O6hD.js';
|
|
14
|
-
export { C as ChatMentionKind, e as ChatTurnFilePartInput, d as ChatTurnPartInput, c as ChatTurnRequestPayload, D as DISPATCH_MAX_MEDIA_PARTS, i as DISPATCH_MAX_PARTS, j as DISPATCH_REQUEST_MAX_BYTES, k as DISPATCH_STRUCTURAL_RESERVE_BYTES, F as FileMention, P as ProducerErrorEvent, m as ProducerNoticeEvent, n as ProducerPassthroughEvent, o as ProducerPassthroughEventType, p as ProducerReasoningEvent, q as ProducerTextEvent, r as ProducerToolCallEvent, s as ProducerToolResultEvent, t as ProducerUsageEvent, u as ProducerWireEvent, w as base64WireLen, x as buildMentionPromptBlock, y as chatTurnRequestInit, z as fileMentionsToParts, B as mediaTypeForMentionPath, E as mentionKindForPath } from '../wire-DOZ-O6hD.js';
|
|
15
|
-
import { Harness } from '../harness/index.js';
|
|
16
|
-
import { S as StepAgentActivity } from '../agent-activity-C8ZG0F0M.js';
|
|
17
|
-
import { F as FlowTrace } from '../flow-types-CJxEmaRy.js';
|
|
18
|
-
import { a as ReviewQueueItem, c as ReviewQueueState } from '../queue-VTBA5ONX.js';
|
|
19
|
-
export { p as parseReviewQueueItem } from '../queue-VTBA5ONX.js';
|
|
20
|
-
export { SandboxTerminalConnection, SandboxTerminalConnectionResponse, UseSandboxTerminalConnectionOptions, UseSandboxTerminalConnectionResult, tabTerminalConnectionId, useSandboxTerminalConnection } from './terminal.js';
|
|
21
|
-
import { i as ProductSeatOffer } from '../billing-BuNlaKlE.js';
|
|
22
|
-
import { SessionSort, SessionPage, SessionSummary, SessionRailAction } from '../session-shell/index.js';
|
|
23
|
-
import { AsyncResourceState, AsyncEmptySpec } from './async/index.js';
|
|
24
|
-
import { CatalogModel } from '../catalog/index.js';
|
|
25
|
-
export { a as ATTACHMENT_ACCEPT, e as FileIndexReadyResponse, f as FileIndexResponse, g as FileIndexWarmingResponse } from '../attachment-validation-BfJDBU1g.js';
|
|
26
|
-
export { a as attachmentPartKey } from '../stream-normalizer-DKRxyVlZ.js';
|
|
27
|
-
import '../billing/index.js';
|
|
28
|
-
|
|
29
|
-
/** Represent durable plan decisions as either approved or rejected */
|
|
30
|
-
type DurablePlanDecision = 'approved' | 'rejected';
|
|
31
|
-
/** Stable authority receipt for the follow-up turn dispatched by a plan
|
|
32
|
-
* decision. Consumers must make `attachFollowUp` idempotent by `receiptId`;
|
|
33
|
-
* reload and retry deliberately invoke it again. */
|
|
34
|
-
interface DurablePlanFollowUpReceipt {
|
|
35
|
-
receiptId: string;
|
|
36
|
-
planId: string;
|
|
37
|
-
revision: number;
|
|
38
|
-
turnId: string;
|
|
39
|
-
state: string;
|
|
40
|
-
}
|
|
41
|
-
/** Describe the result of a durable plan decision including plan details and pending statuses */
|
|
42
|
-
interface DurablePlanDecisionResult {
|
|
43
|
-
plan: ChatPlan;
|
|
44
|
-
followUp?: DurablePlanFollowUpReceipt;
|
|
45
|
-
idempotent: boolean;
|
|
46
|
-
projectionPending?: boolean;
|
|
47
|
-
effectPending?: boolean;
|
|
48
|
-
}
|
|
49
|
-
/** Define input parameters for making a durable plan decision including optional feedback */
|
|
50
|
-
interface DurablePlanDecisionInput {
|
|
51
|
-
planId: string;
|
|
52
|
-
revision: number;
|
|
53
|
-
decision: DurablePlanDecision;
|
|
54
|
-
feedback?: string;
|
|
55
|
-
}
|
|
56
|
-
/** Define input parameters for retrieving the current durable plan including optional revision number */
|
|
57
|
-
interface DurablePlanCurrentInput {
|
|
58
|
-
planId: string;
|
|
59
|
-
revision?: number;
|
|
60
|
-
}
|
|
61
|
-
/** Define methods to obtain and decide durable plan decisions asynchronously */
|
|
62
|
-
interface DurablePlanDecisionClient {
|
|
63
|
-
current: (input: DurablePlanCurrentInput) => Promise<DurablePlanDecisionResult>;
|
|
64
|
-
decide: (input: DurablePlanDecisionInput) => Promise<DurablePlanDecisionResult>;
|
|
65
|
-
}
|
|
66
|
-
/** Represent errors from DurablePlanClient operations including status, code, and current plan details */
|
|
67
|
-
declare class DurablePlanClientError extends Error {
|
|
68
|
-
readonly status: number;
|
|
69
|
-
readonly code?: string | undefined;
|
|
70
|
-
readonly currentPlan?: ChatPlan | undefined;
|
|
71
|
-
constructor(message: string, status: number, code?: string | undefined, currentPlan?: ChatPlan | undefined);
|
|
72
|
-
}
|
|
73
|
-
/** Define configuration options for creating a durable plan decision client */
|
|
74
|
-
interface DurablePlanDecisionClientOptions {
|
|
75
|
-
url: string | ((input: DurablePlanCurrentInput | DurablePlanDecisionInput) => string);
|
|
76
|
-
body?: Record<string, unknown> | ((input: DurablePlanDecisionInput) => Record<string, unknown>);
|
|
77
|
-
fetchImpl?: typeof fetch;
|
|
78
|
-
}
|
|
79
|
-
/** Browser client for the shared durable-plan route. The route URL and all
|
|
80
|
-
* product routing fields are injected; workspace/session identity is still
|
|
81
|
-
* resolved and authorized on the server. */
|
|
82
|
-
declare function createDurablePlanDecisionClient(options: DurablePlanDecisionClientOptions): DurablePlanDecisionClient;
|
|
83
|
-
/** Define options to configure durable plan flow with plan, client, and optional callbacks */
|
|
84
|
-
interface UseDurablePlanFlowOptions {
|
|
85
|
-
plan: ChatPlan;
|
|
86
|
-
client: DurablePlanDecisionClient;
|
|
87
|
-
/** Must be idempotent by receipt.receiptId. */
|
|
88
|
-
attachFollowUp?: (receipt: DurablePlanFollowUpReceipt) => Promise<void> | void;
|
|
89
|
-
onUpdated?: (plan: ChatPlan) => void;
|
|
90
|
-
}
|
|
91
|
-
/** Define the result and actions for managing a durable plan flow including decisions, restoration, and error handling */
|
|
92
|
-
interface UseDurablePlanFlowResult {
|
|
93
|
-
plan: ChatPlan;
|
|
94
|
-
deciding: DurablePlanDecision | null;
|
|
95
|
-
restoring: boolean;
|
|
96
|
-
error: string | null;
|
|
97
|
-
decide: (decision: DurablePlanDecision, feedback?: string) => Promise<DurablePlanDecisionResult | null>;
|
|
98
|
-
restore: () => Promise<DurablePlanDecisionResult | null>;
|
|
99
|
-
clearError: () => void;
|
|
100
|
-
}
|
|
101
|
-
/** Shared plan decision controller. It coalesces only concurrent attachment
|
|
102
|
-
* attempts; a later retry/restore calls the consumer's idempotent transport
|
|
103
|
-
* again so a lost response cannot strand an already-dispatched follow-up. */
|
|
104
|
-
declare function useDurablePlanFlow(options: UseDurablePlanFlowOptions): UseDurablePlanFlowResult;
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Shared answer-building + submit plumbing for the interaction cards
|
|
108
|
-
* (question, plan). Client-safe, no React: cards own their state, this owns
|
|
109
|
-
* the wire. Lifted from the gtm-agent fork (the most fix-absorbed of the three
|
|
110
|
-
* product copies), including the 30s submit timeout that keeps a dead route
|
|
111
|
-
* from wedging a card in "Submitting…".
|
|
112
|
-
*/
|
|
113
|
-
|
|
114
|
-
/** Status-badge labels for an interaction card. `cancelled`/`expired` read the
|
|
115
|
-
* same across cards; each card supplies its own verbs for the other states
|
|
116
|
-
* (a question is answered/declined; a plan is approved/rejected). */
|
|
117
|
-
declare function interactionStatusLabels(labels: {
|
|
118
|
-
pending: string;
|
|
119
|
-
answered: string;
|
|
120
|
-
declined: string;
|
|
121
|
-
}): Record<ChatInteractionStatus, string>;
|
|
122
|
-
/** Terminal-state notes for an interaction card. The expiry/withdrawal lines
|
|
123
|
-
* share one shape around the card's noun ("question"/"plan"); any extra notes
|
|
124
|
-
* (e.g. a plan's `declined` revision line) merge on top. */
|
|
125
|
-
declare function interactionTerminalNotes(noun: string, extra?: Partial<Record<ChatInteractionStatus, string>>): Partial<Record<ChatInteractionStatus, string>>;
|
|
126
|
-
/** Define a record mapping field names to objects with optional selected, text, and custom string arrays or values */
|
|
127
|
-
type FieldValues = Record<string, {
|
|
128
|
-
selected?: string[];
|
|
129
|
-
text?: string;
|
|
130
|
-
custom?: string;
|
|
131
|
-
}>;
|
|
132
|
-
/** Converts acknowledged, persisted answers back into the local field state
|
|
133
|
-
* consumed by the shared cards. Persisted values are authoritative: this is
|
|
134
|
-
* intentionally used only when an interaction carries `answers`, never to
|
|
135
|
-
* guess an answer from the absence of an outstanding sidecar ask. */
|
|
136
|
-
declare function fieldValuesFromAnswers(fields: ChatInteractionField[], answers: InteractionAnswers | undefined): FieldValues;
|
|
137
|
-
/** The submitted value for one field, or null when it has no answer yet.
|
|
138
|
-
*
|
|
139
|
-
* Returns `InteractionAnswers[string]`, not the wider `InteractionData[string]`:
|
|
140
|
-
* a card reads its value out of a rendered control, so every branch below
|
|
141
|
-
* yields a plain scalar or string array. `InteractionData` also admits a
|
|
142
|
-
* one-use `secret_handle` reference, which no control here can produce and
|
|
143
|
-
* which `onResolved` must never receive — that path persists into the visible
|
|
144
|
-
* transcript. Declaring the narrow type keeps the handle out by construction
|
|
145
|
-
* rather than by review. */
|
|
146
|
-
declare function fieldAnswer(field: ChatInteractionField, values: FieldValues): InteractionAnswers[string] | null;
|
|
147
|
-
/** All required fields answered → the respond payload; else null (not
|
|
148
|
-
* submittable yet). Optional unanswered fields are omitted. */
|
|
149
|
-
declare function buildAnswerData(fields: ChatInteractionField[], values: FieldValues): InteractionAnswers | null;
|
|
150
|
-
/** Determine if a status is late answerable by checking if it is expired or cancelled */
|
|
151
|
-
declare function isLateAnswerableStatus(status: ChatInteractionStatus): boolean;
|
|
152
|
-
/** Secrets must never leave the sidecar answer channel for the visible chat
|
|
153
|
-
* transcript, so a secret-bearing ask cannot be late-answered. */
|
|
154
|
-
declare function hasSecretField(fields: ChatInteractionField[]): boolean;
|
|
155
|
-
/** Renders the late answer as a self-contained chat message: the original
|
|
156
|
-
* question, its context, and the user's answer(s). */
|
|
157
|
-
declare function lateAnswerMessage(interaction: ChatInteraction, data: InteractionData): string;
|
|
158
|
-
/** Define the timeout duration in milliseconds for submitting an interaction */
|
|
159
|
-
declare const INTERACTION_SUBMIT_TIMEOUT_MS = 30000;
|
|
160
|
-
/** Provide the timeout message displayed when the agent cannot be reached during interaction submission */
|
|
161
|
-
declare const INTERACTION_SUBMIT_TIMEOUT_MESSAGE = "Could not reach the agent. Try again.";
|
|
162
|
-
/** One card submission: which ask, resolved how, with what answers. */
|
|
163
|
-
interface InteractionAnswerSubmission {
|
|
164
|
-
id: string;
|
|
165
|
-
outcome: 'accepted' | 'declined';
|
|
166
|
-
data?: InteractionData;
|
|
167
|
-
}
|
|
168
|
-
/** Resolve the result of an interaction submission indicating success or failure with details */
|
|
169
|
-
type InteractionSubmitResult = {
|
|
170
|
-
ok: true;
|
|
171
|
-
} | {
|
|
172
|
-
ok: false;
|
|
173
|
-
expired: boolean;
|
|
174
|
-
message: string;
|
|
175
|
-
};
|
|
176
|
-
/** The cards' only side-effect seam: POST one resolution, report the normalized
|
|
177
|
-
* outcome. Products bind their route URL + routing fields (workspaceId,
|
|
178
|
-
* threadId, session path param) via `createInteractionAnswerSubmitter` or a
|
|
179
|
-
* hand-rolled implementation. */
|
|
180
|
-
type SubmitInteractionAnswer = (submission: InteractionAnswerSubmission) => Promise<InteractionSubmitResult>;
|
|
181
|
-
/** Extracts the most specific error message a route returned. */
|
|
182
|
-
declare function responseErrorMessage(res: Response): Promise<{
|
|
183
|
-
code?: string;
|
|
184
|
-
message: string;
|
|
185
|
-
}>;
|
|
186
|
-
/** Define options for submitting interaction answers including URL, body, timeout, and fetch implementation */
|
|
187
|
-
interface InteractionAnswerSubmitterOptions {
|
|
188
|
-
/** The product's answer route (the POST half of `createInteractionAnswerRoute`).
|
|
189
|
-
* A function when the URL carries the session (e.g. `/api/sessions/${id}/interactions`). */
|
|
190
|
-
url: string | ((submission: InteractionAnswerSubmission) => string);
|
|
191
|
-
/** Extra routing fields merged into the POST body (e.g. workspaceId, threadId). */
|
|
192
|
-
body?: Record<string, unknown> | ((submission: InteractionAnswerSubmission) => Record<string, unknown>);
|
|
193
|
-
timeoutMs?: number;
|
|
194
|
-
fetchImpl?: typeof fetch;
|
|
195
|
-
}
|
|
196
|
-
/**
|
|
197
|
-
* Runs a host-supplied submitter under the CARD's own deadline, and always
|
|
198
|
-
* resolves.
|
|
199
|
-
*
|
|
200
|
-
* `createInteractionAnswerSubmitter` aborts its own fetch, but a product may
|
|
201
|
-
* pass any `SubmitInteractionAnswer` — commonly one wrapping an untimed
|
|
202
|
-
* `fetch`. The deadline cannot live only in the submitter, because what gets
|
|
203
|
-
* stuck is the card: its in-flight guard is cleared by the awaited promise
|
|
204
|
-
* settling, so a submitter that never settles leaves that guard set for the
|
|
205
|
-
* life of the instance — "Submitting…" forever, and no answer can be sent
|
|
206
|
-
* again. A submitter with its own shorter timeout simply wins the race.
|
|
207
|
-
*
|
|
208
|
-
* Rejection is normalized too: a submitter that throws would otherwise escape
|
|
209
|
-
* the click handler as an unhandled rejection, leaving the user with a card
|
|
210
|
-
* that silently did nothing. It becomes a visible, retryable message instead.
|
|
211
|
-
*/
|
|
212
|
-
declare function settleInteractionSubmit(run: () => Promise<InteractionSubmitResult>, timeoutMs?: number): Promise<InteractionSubmitResult>;
|
|
213
|
-
/**
|
|
214
|
-
* Builds the `SubmitInteractionAnswer` the cards consume: POSTs
|
|
215
|
-
* `{ ...routingFields, id, outcome, data? }` with an abortable timeout and
|
|
216
|
-
* normalizes the outcome. `expired` is the 410 path — the ask is gone
|
|
217
|
-
* (answered elsewhere, timed out, or the session moved on) and the card must
|
|
218
|
-
* flip to the same dead state a cancel event produces.
|
|
219
|
-
*/
|
|
220
|
-
declare function createInteractionAnswerSubmitter(options: InteractionAnswerSubmitterOptions): SubmitInteractionAnswer;
|
|
221
|
-
|
|
222
|
-
type DurableChatCard = {
|
|
223
|
-
kind: 'plan';
|
|
224
|
-
key: string;
|
|
225
|
-
plan: ChatPlan;
|
|
226
|
-
} | {
|
|
227
|
-
kind: 'interaction';
|
|
228
|
-
key: string;
|
|
229
|
-
interaction: ChatInteraction;
|
|
230
|
-
};
|
|
231
|
-
/** Converts persisted/live parts to canonical cards. Legacy interaction-plan
|
|
232
|
-
* cards are suppressed only when their raw part carries an explicit planId and
|
|
233
|
-
* revision matching a durable plan. Identical markdown alone is never proof. */
|
|
234
|
-
declare function durableChatCardsFromParts(parts: Array<Record<string, unknown>>): DurableChatCard[];
|
|
235
|
-
interface DurableChatCardsProps {
|
|
236
|
-
parts: Array<Record<string, unknown>>;
|
|
237
|
-
canWrite: boolean;
|
|
238
|
-
submitInteraction: SubmitInteractionAnswer;
|
|
239
|
-
decidePlan: (plan: ChatPlan, decision: DurablePlanDecision, feedback?: string) => Promise<DurablePlanDecisionResult | null>;
|
|
240
|
-
decidingPlan?: (plan: ChatPlan) => DurablePlanDecision | null;
|
|
241
|
-
planError?: (plan: ChatPlan) => string | null;
|
|
242
|
-
onInteractionResolved?: (id: string, status: Exclude<ChatInteraction['status'], 'pending'>, answers?: InteractionAnswers) => void;
|
|
243
|
-
onLateAnswer?: (message: string) => boolean | void | Promise<boolean | void>;
|
|
244
|
-
/** Fired when the user asks the agent to re-submit an expired/withdrawn
|
|
245
|
-
* plan card as a new chat turn; receives that card's interaction. Omit to
|
|
246
|
-
* hide the affordance entirely. */
|
|
247
|
-
onReRequest?: (interaction: ChatInteraction) => boolean | void | Promise<boolean | void>;
|
|
248
|
-
/** Overrides the default re-request button label. */
|
|
249
|
-
reRequestLabel?: string;
|
|
250
|
-
renderMarkdown?: (markdown: string) => ReactNode;
|
|
251
|
-
className?: string;
|
|
252
|
-
}
|
|
253
|
-
/** Ready-to-embed canonical question/plan card lane for persisted assistant
|
|
254
|
-
* parts. Apps inject transport and styling callbacks instead of rebuilding the
|
|
255
|
-
* lifecycle/render switch. */
|
|
256
|
-
declare function DurableChatCards({ parts, canWrite, submitInteraction, decidePlan, decidingPlan, planError, onInteractionResolved, onLateAnswer, onReRequest, reRequestLabel, renderMarkdown, className, }: DurableChatCardsProps): react.JSX.Element | null;
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* Client-side chat-stream consumption — the NDJSON parse loop every agent
|
|
260
|
-
* app's chat UI hand-rolls (and breaks). Normalizes the three line shapes the
|
|
261
|
-
* agent-app chat routes emit:
|
|
262
|
-
*
|
|
263
|
-
* {kind:'event', event:{type:'text'|'reasoning'|'tool_call'|'usage'|'notice'|'error', ...}}
|
|
264
|
-
* {kind:'tool_result', toolCallId, toolName, label, outcome}
|
|
265
|
-
* {type:'turn'|'metadata'|'error'|'turn_status', ...} (route-level)
|
|
266
|
-
* {type:'interaction', data:{request}} (sidecar ask)
|
|
267
|
-
*
|
|
268
|
-
* Replayed lines carry an extra `seq` — transparently ignored. Works for
|
|
269
|
-
* router-backed and sandbox-backed chats alike: anything producing these
|
|
270
|
-
* lines (live pump, queued follow, resume replay) feeds the same callbacks.
|
|
271
|
-
*/
|
|
272
|
-
|
|
273
|
-
/** Define the structure for a chat tool call including optional ID, name, and arguments object */
|
|
274
|
-
interface ChatStreamToolCall {
|
|
275
|
-
toolCallId?: string;
|
|
276
|
-
toolName: string;
|
|
277
|
-
args: Record<string, unknown>;
|
|
278
|
-
}
|
|
279
|
-
/** Describe the result of a chat stream tool including its outcome and optional metadata fields */
|
|
280
|
-
interface ChatStreamToolResult {
|
|
281
|
-
toolCallId?: string;
|
|
282
|
-
toolName?: string;
|
|
283
|
-
label?: string;
|
|
284
|
-
outcome: {
|
|
285
|
-
ok: boolean;
|
|
286
|
-
result?: unknown;
|
|
287
|
-
code?: string;
|
|
288
|
-
message?: string;
|
|
289
|
-
};
|
|
290
|
-
}
|
|
291
|
-
/** Define callbacks to handle events and data during a chat streaming session */
|
|
292
|
-
interface ChatStreamCallbacks {
|
|
293
|
-
onTurnId?: (turnId: string) => void;
|
|
294
|
-
onText?: (delta: string) => void;
|
|
295
|
-
onReasoning?: (delta: string) => void;
|
|
296
|
-
onToolCall?: (call: ChatStreamToolCall) => void;
|
|
297
|
-
onToolResult?: (result: ChatStreamToolResult) => void;
|
|
298
|
-
onUsage?: (usage: {
|
|
299
|
-
promptTokens: number;
|
|
300
|
-
completionTokens: number;
|
|
301
|
-
}) => void;
|
|
302
|
-
onNotice?: (notice: {
|
|
303
|
-
id: string;
|
|
304
|
-
noticeKind: 'warning' | 'auto-declined';
|
|
305
|
-
text: string;
|
|
306
|
-
}) => void;
|
|
307
|
-
onMetadata?: (data: Record<string, unknown>) => void;
|
|
308
|
-
/** Structured detail from a loop-level error event. Fired alongside the
|
|
309
|
-
* legacy string-only `onErrorEvent` callback. */
|
|
310
|
-
onErrorEventDetail?: (detail: {
|
|
311
|
-
message: string;
|
|
312
|
-
code?: string;
|
|
313
|
-
details?: Record<string, unknown>;
|
|
314
|
-
}) => void;
|
|
315
|
-
/** A loop-level error event (the turn failed server-side). Optional, but the
|
|
316
|
-
* error never vanishes: when omitted, the message is synthesized into the
|
|
317
|
-
* transcript via `onText` (rendered by ChatMessages as a text segment) and
|
|
318
|
-
* logged with `console.error`. */
|
|
319
|
-
onErrorEvent?: (message: string) => void;
|
|
320
|
-
/** A sidecar interaction ask (kind: "question"/"plan"/…). The run is BLOCKED
|
|
321
|
-
* in the broker until the user answers; a pending ask is "waiting on the
|
|
322
|
-
* user", not "model working". Optional — a consumer that doesn't wire it
|
|
323
|
-
* parses the same stream unchanged. */
|
|
324
|
-
onInteraction?: (interaction: ChatInteraction) => void;
|
|
325
|
-
/** A terminal withdrawal/timeout for a previously emitted interaction. */
|
|
326
|
-
onInteractionCancel?: (cancel: InteractionCancelData) => void;
|
|
327
|
-
/** A durable-plan snapshot from any plan lifecycle event. */
|
|
328
|
-
onPlan?: (plan: ChatPlan) => void;
|
|
329
|
-
}
|
|
330
|
-
/** Represent the result of consuming a chat stream including turn ID and content reception status */
|
|
331
|
-
interface ConsumeChatStreamResult {
|
|
332
|
-
turnId: string | null;
|
|
333
|
-
/** True when any text/reasoning/tool activity was received. */
|
|
334
|
-
receivedContent: boolean;
|
|
335
|
-
}
|
|
336
|
-
/** Parse one NDJSON line into the callbacks. Exposed for tests. */
|
|
337
|
-
declare function dispatchChatStreamLine(line: string, cb: ChatStreamCallbacks): {
|
|
338
|
-
turnId?: string;
|
|
339
|
-
receivedContent: boolean;
|
|
340
|
-
};
|
|
341
|
-
/** Drain one NDJSON body into the callbacks. Throws on transport failure
|
|
342
|
-
* (caller decides whether to resume). */
|
|
343
|
-
declare function consumeChatStream(body: ReadableStream<Uint8Array>, cb: ChatStreamCallbacks): Promise<ConsumeChatStreamResult>;
|
|
344
|
-
/** Define options for managing and resuming streaming chat interactions with callbacks */
|
|
345
|
-
interface StreamChatOptions {
|
|
346
|
-
/** Start the turn (POST the chat request); must return a streaming Response. */
|
|
347
|
-
start: () => Promise<Response>;
|
|
348
|
-
/** Re-attach to a turn after a transport drop (GET the resume route). */
|
|
349
|
-
resume?: (turnId: string, fromSeq: number) => Promise<Response>;
|
|
350
|
-
callbacks: ChatStreamCallbacks;
|
|
351
|
-
/** Called before a resume replays from 0 so the UI can reset accumulated
|
|
352
|
-
* turn state (text, reasoning, tool chips). */
|
|
353
|
-
onResetForResume?: () => void;
|
|
354
|
-
}
|
|
355
|
-
/**
|
|
356
|
-
* Run one chat turn with automatic single-shot resume: if the transport drops
|
|
357
|
-
* mid-turn and the server announced a turnId, reset and replay the buffered
|
|
358
|
-
* turn. Server-side the turn keeps running either way (queued runner).
|
|
359
|
-
*/
|
|
360
|
-
declare function streamChatTurn(opts: StreamChatOptions): Promise<ConsumeChatStreamResult>;
|
|
361
|
-
|
|
362
|
-
/** Prompt-part descriptor an uploaded file carries (the upload route's
|
|
363
|
-
* `UploadedChatFile.part`), echoed back in the turn body on send. Mirrors
|
|
364
|
-
* `/chat-routes`' wire shape structurally — no server import here. */
|
|
365
|
-
interface ComposerFilePart {
|
|
366
|
-
type: 'image' | 'file';
|
|
367
|
-
filename?: string;
|
|
368
|
-
mediaType?: string;
|
|
369
|
-
url?: string;
|
|
370
|
-
path?: string;
|
|
371
|
-
content?: string;
|
|
372
|
-
}
|
|
373
|
-
interface ComposerFile {
|
|
374
|
-
id: string;
|
|
375
|
-
name: string;
|
|
376
|
-
size?: number;
|
|
377
|
-
kind: 'file' | 'folder';
|
|
378
|
-
/** Number of files inside, for a folder chip. */
|
|
379
|
-
fileCount?: number;
|
|
380
|
-
status: 'pending' | 'uploading' | 'ready' | 'error';
|
|
381
|
-
/** Uploaded part descriptor; set once the upload route returns. Only
|
|
382
|
-
* `status: 'ready'` files with a part travel on a parts-aware send. */
|
|
383
|
-
part?: ComposerFilePart;
|
|
384
|
-
}
|
|
385
|
-
/** A send the host refused. `error` is shown verbatim in the composer's notice;
|
|
386
|
-
* omit it for the generic copy. */
|
|
387
|
-
interface ComposerSendRejected {
|
|
388
|
-
ok: false;
|
|
389
|
-
error?: string;
|
|
390
|
-
}
|
|
391
|
-
/**
|
|
392
|
-
* What a send handler reports back. `void` — what every handler returned before
|
|
393
|
-
* this existed — reads as accepted, so wiring stays unchanged; a thrown error, a
|
|
394
|
-
* rejected promise, or `{ ok: false }` is the rejection that restores the draft.
|
|
395
|
-
* A handler that resolves only when the whole turn finishes still reports
|
|
396
|
-
* correctly: the input already cleared on dispatch, so the answer only decides
|
|
397
|
-
* whether the draft comes back.
|
|
398
|
-
*/
|
|
399
|
-
type ComposerSendOutcome = void | {
|
|
400
|
-
ok: true;
|
|
401
|
-
} | ComposerSendRejected;
|
|
402
|
-
type ComposerSendResult = ComposerSendOutcome | Promise<ComposerSendOutcome>;
|
|
403
|
-
/**
|
|
404
|
-
* A send handler, typed as a UNION with the legacy `=> void` signature rather
|
|
405
|
-
* than as `(…) => ComposerSendResult` alone.
|
|
406
|
-
*
|
|
407
|
-
* TypeScript's return-type-`void` rule accepts a function returning ANYTHING
|
|
408
|
-
* where a `=> void` is expected, and that rule fires only when the target's
|
|
409
|
-
* return type is exactly `void` — not when it is a union that contains `void`.
|
|
410
|
-
* So narrowing this prop to `ComposerSendResult` would reject handler shapes
|
|
411
|
-
* that compiled against the shipped `onSend?: (message: string) => void`:
|
|
412
|
-
* `onSend={(m) => rows.push(m)}` (returns `number`) and
|
|
413
|
-
* `onSend={(m) => append({ role: 'user', content: m })}` (an ai-sdk append
|
|
414
|
-
* returns `Promise<string | null | undefined>`) both stop compiling, on a
|
|
415
|
-
* package whose pinned consumers must never need a source edit to take a minor.
|
|
416
|
-
*
|
|
417
|
-
* The union keeps both: a legacy handler lands on the first member, and a
|
|
418
|
-
* handler that reports an outcome lands on the second. A call through it
|
|
419
|
-
* resolves to `void | ComposerSendResult`, which IS `ComposerSendResult`, so
|
|
420
|
-
* the composer reads the outcome exactly as before.
|
|
421
|
-
*/
|
|
422
|
-
type ComposerSendHandler = ((message: string) => void) | ((message: string) => ComposerSendResult);
|
|
423
|
-
/** @see ComposerSendHandler — the parts-aware arity, same union for the same reason. */
|
|
424
|
-
type ComposerSendPartsHandler = ((message: string, parts: ComposerFilePart[]) => void) | ((message: string, parts: ComposerFilePart[]) => ComposerSendResult);
|
|
425
|
-
/** The rejected send, handed to `onSendFailed` so the host can undo whatever it
|
|
426
|
-
* cleared optimistically — most importantly the staged attachments, which the
|
|
427
|
-
* composer does not own (`pendingFiles` is a prop). */
|
|
428
|
-
interface ComposerSendFailure {
|
|
429
|
-
/** The reason as the composer renders it. */
|
|
430
|
-
message: string;
|
|
431
|
-
/** The user's exact draft, untrimmed. */
|
|
432
|
-
text: string;
|
|
433
|
-
/** The parts the rejected send carried. */
|
|
434
|
-
parts: ComposerFilePart[];
|
|
435
|
-
/** Whatever the handler threw / rejected with, or the `{ ok: false }` value. */
|
|
436
|
-
error: unknown;
|
|
437
|
-
/** True when the draft was put back in the textarea (the box was empty).
|
|
438
|
-
* False means the user had typed a replacement, so the unsent text is held in
|
|
439
|
-
* the notice instead. */
|
|
440
|
-
restored: boolean;
|
|
441
|
-
}
|
|
442
|
-
interface ChatComposerProps {
|
|
443
|
-
/** Send the trimmed, non-empty message. Attached files travel separately via
|
|
444
|
-
* `onAttach` + `pendingFiles` (the host consumes and clears them on send).
|
|
445
|
-
* Optional when `onSendParts` is wired.
|
|
446
|
-
*
|
|
447
|
-
* Report a refused send by throwing, rejecting, or returning `{ ok: false }`
|
|
448
|
-
* — the composer restores the draft rather than losing it. */
|
|
449
|
-
onSend?: ComposerSendHandler;
|
|
450
|
-
/** Parts-aware send: receives the trimmed message plus the `part`
|
|
451
|
-
* descriptors of every `ready` pending file. Takes precedence over
|
|
452
|
-
* `onSend`; enables file-only sends (empty text, ≥1 ready part).
|
|
453
|
-
*
|
|
454
|
-
* Same rejection contract as `onSend`. */
|
|
455
|
-
onSendParts?: ComposerSendPartsHandler;
|
|
456
|
-
/** Notified when a send is rejected, after the composer has restored what it
|
|
457
|
-
* owns. The host uses it to put back the `pendingFiles` it consumed. */
|
|
458
|
-
onSendFailed?: (failure: ComposerSendFailure) => void;
|
|
459
|
-
/** Notice copy when the handler names no reason of its own. */
|
|
460
|
-
sendFailureMessage?: string;
|
|
461
|
-
/** Stop the in-flight turn; shown in place of Send while `isStreaming`. */
|
|
462
|
-
onCancel?: () => void;
|
|
463
|
-
isStreaming?: boolean;
|
|
464
|
-
/** Block input + send (e.g. while restoring). Distinct from `isStreaming`,
|
|
465
|
-
* which keeps the textarea editable so the next turn can be composed. */
|
|
466
|
-
disabled?: boolean;
|
|
467
|
-
placeholder?: string;
|
|
468
|
-
/** Controlled value. Omit for self-managed internal state (cleared on send). */
|
|
469
|
-
value?: string;
|
|
470
|
-
onValueChange?: (value: string) => void;
|
|
471
|
-
/** Initial text in uncontrolled mode; ignored when `value` is provided. */
|
|
472
|
-
initialValue?: string;
|
|
473
|
-
/** One-shot external prefill: when this becomes a non-null string the
|
|
474
|
-
* composer adopts it as the draft (replacing any current draft), focuses the
|
|
475
|
-
* input with the caret at the end, and reports consumption via
|
|
476
|
-
* `onSeedApplied` so the host can clear its seed state. */
|
|
477
|
-
seed?: string | null;
|
|
478
|
-
onSeedApplied?: () => void;
|
|
479
|
-
/** Inline controls (e.g. `<ModelPicker/>` + `<EffortPicker/>` or
|
|
480
|
-
* `<AgentSessionControls/>`). */
|
|
481
|
-
controls?: ReactNode;
|
|
482
|
-
/**
|
|
483
|
-
* Where {@link controls} sit. `inline` (default) puts them on the card's own
|
|
484
|
-
* action row, beside attach and Send — the model a turn will use reads as
|
|
485
|
-
* part of the input rather than as a separate widget floating above it.
|
|
486
|
-
* `above` keeps them outside the card, for a host that wants the input to be
|
|
487
|
-
* nothing but the input.
|
|
488
|
-
*/
|
|
489
|
-
controlsPlacement?: 'above' | 'inline';
|
|
490
|
-
/** Attachments are opt-in: pass `onAttach` to show the attach button, accept
|
|
491
|
-
* drag-and-drop onto the input, and render `pendingFiles` chips. */
|
|
492
|
-
onAttach?: (files: FileList) => void;
|
|
493
|
-
onAttachFolder?: (files: FileList) => void;
|
|
494
|
-
pendingFiles?: ComposerFile[];
|
|
495
|
-
onRemoveFile?: (id: string) => void;
|
|
496
|
-
accept?: string;
|
|
497
|
-
dropTitle?: string;
|
|
498
|
-
dropDescription?: string;
|
|
499
|
-
/** Cmd/Ctrl+L focuses the input and shows the hint. Default true. */
|
|
500
|
-
focusShortcut?: boolean;
|
|
501
|
-
/** Float the card on a soft two-layer foreground-tinted shadow (opt-in).
|
|
502
|
-
* Elevation only — radius, ring, and control layout are unchanged. */
|
|
503
|
-
floating?: boolean;
|
|
504
|
-
/** Send button label. Default "Send". */
|
|
505
|
-
sendLabel?: string;
|
|
506
|
-
className?: string;
|
|
507
|
-
}
|
|
508
|
-
declare function ChatComposer({ onSend, onSendParts, onSendFailed, sendFailureMessage, onCancel, isStreaming, disabled, placeholder, value, onValueChange, initialValue, seed, onSeedApplied, controls, controlsPlacement, onAttach, onAttachFolder, pendingFiles, onRemoveFile, accept, dropTitle, dropDescription, focusShortcut, floating, sendLabel, className, }: ChatComposerProps): react.JSX.Element;
|
|
509
|
-
|
|
510
|
-
type InteractionBadgeVariant = 'outline' | 'default' | 'destructive';
|
|
511
|
-
declare function InteractionBadge({ variant, children }: {
|
|
512
|
-
variant: InteractionBadgeVariant;
|
|
513
|
-
children: string;
|
|
514
|
-
}): react.JSX.Element;
|
|
515
|
-
declare function InteractionActionButton({ variant, onClick, disabled, children, }: {
|
|
516
|
-
variant?: 'primary' | 'outline';
|
|
517
|
-
onClick: () => void;
|
|
518
|
-
disabled?: boolean;
|
|
519
|
-
children: string;
|
|
520
|
-
}): react.JSX.Element;
|
|
521
|
-
interface QuestionOptionListProps {
|
|
522
|
-
/** Radio/checkbox group name — unique per field so selection is isolated. */
|
|
523
|
-
groupName: string;
|
|
524
|
-
/** Stable prefix for per-option input ids (label htmlFor pairing). */
|
|
525
|
-
idPrefix: string;
|
|
526
|
-
options: ChatSelectField['options'];
|
|
527
|
-
/** Checkbox (multi-select) vs radio (single). */
|
|
528
|
-
multi: boolean;
|
|
529
|
-
selectedValues: string[];
|
|
530
|
-
disabled: boolean;
|
|
531
|
-
onToggle: (value: string) => void;
|
|
532
|
-
/** Terminal answered state: the selected rows highlight (primary edge, tint,
|
|
533
|
-
* trailing check) so the card shows WHAT was answered, not just that it was. */
|
|
534
|
-
answered?: boolean;
|
|
535
|
-
}
|
|
536
|
-
/** The radio/checkbox option rows for a select field. Renders a fragment of
|
|
537
|
-
* option `<label>` rows so a card keeps its own wrapping layout and appends
|
|
538
|
-
* its own write-in input.
|
|
539
|
-
*
|
|
540
|
-
* The rows arrive as a SEQUENCE (`.agent-arrive` + `--stagger-index`), which
|
|
541
|
-
* is the difference between reading a list and being shown one: the eye is
|
|
542
|
-
* told there are N choices and in what order before it has read any of them.
|
|
543
|
-
* The index is safe to take straight from the map because an option list does
|
|
544
|
-
* not re-sort under a mounted card — a different set of options is a
|
|
545
|
-
* different `key`, and a different ask resets the card wholesale. */
|
|
546
|
-
declare function QuestionOptionList({ groupName, idPrefix, options, multi, selectedValues, disabled, onToggle, answered, }: QuestionOptionListProps): react.JSX.Element;
|
|
547
|
-
interface InteractionQuestionCardProps {
|
|
548
|
-
interaction: ChatInteraction;
|
|
549
|
-
/** Viewer-vs-editor gate: false renders everything read-only. */
|
|
550
|
-
canWrite: boolean;
|
|
551
|
-
/** POST one resolution to the product's answer route (see
|
|
552
|
-
* `createInteractionAnswerSubmitter`). Never called for late answers. */
|
|
553
|
-
submitAnswer: SubmitInteractionAnswer;
|
|
554
|
-
/** Fired when this card resolves locally (answered, or discovered expired
|
|
555
|
-
* via a 410) so the stream/route state stays in sync. */
|
|
556
|
-
onResolved?: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>, answers?: ChatInteraction['answers']) => void;
|
|
557
|
-
/** Delivers a late answer (the ask expired/was withdrawn) as a fresh chat
|
|
558
|
-
* turn. Return/resolve `false` when the send was rejected so the card stays
|
|
559
|
-
* retryable. Omit to hide the late-answer affordance entirely. */
|
|
560
|
-
onLateAnswer?: (message: string) => boolean | void | Promise<boolean | void>;
|
|
561
|
-
/** Overrides the kind badge ("Question"). */
|
|
562
|
-
kindLabel?: string;
|
|
563
|
-
/** What happens if nobody answers, rendered beside the submit action.
|
|
564
|
-
*
|
|
565
|
-
* The caller owns both the clock and the copy: this card holds no timer, so a
|
|
566
|
-
* deadline that counts down re-renders on the caller's cadence rather than
|
|
567
|
-
* driving one of its own — and the consequence of silence ("the default is
|
|
568
|
-
* taken", "the run fails") is the host's policy to state, not this card's to
|
|
569
|
-
* infer. */
|
|
570
|
-
timeoutNote?: ReactNode;
|
|
571
|
-
/** Renders `body` as markdown. Omitted, `body` renders as plain text — so a
|
|
572
|
-
* host that passes authored markdown without this shows its syntax raw.
|
|
573
|
-
*
|
|
574
|
-
* `body` ONLY. `title` and every `field.label` stay plain strings: a label is
|
|
575
|
-
* also the input's accessible name (`aria-label`), which has to be text, and
|
|
576
|
-
* rendering one as nodes would either break that or silently disagree with
|
|
577
|
-
* what a screen reader announces. Put prose in `body`.
|
|
578
|
-
*
|
|
579
|
-
* `interaction.body` is untrusted: it arrives off the wire, written by an
|
|
580
|
-
* agent or whoever authored the ask. This card never injects HTML, but a
|
|
581
|
-
* renderer that does is an XSS sink — so return React elements, and sanitize
|
|
582
|
-
* (DOMPurify or equivalent) if you must produce HTML. */
|
|
583
|
-
renderMarkdown?: (markdown: string) => ReactNode;
|
|
584
|
-
className?: string;
|
|
585
|
-
}
|
|
586
|
-
declare function InteractionQuestionCard({ interaction, canWrite, submitAnswer, onResolved, onLateAnswer, kindLabel, timeoutNote, renderMarkdown, className, }: InteractionQuestionCardProps): react.JSX.Element;
|
|
587
|
-
|
|
588
|
-
interface InteractionPlanCardProps {
|
|
589
|
-
interaction: ChatInteraction;
|
|
590
|
-
/** Viewer-vs-editor gate: false renders everything read-only. */
|
|
591
|
-
canWrite: boolean;
|
|
592
|
-
/** POST one resolution to the product's answer route (see
|
|
593
|
-
* `createInteractionAnswerSubmitter`). */
|
|
594
|
-
submitAnswer: SubmitInteractionAnswer;
|
|
595
|
-
/** Fired when this card resolves locally (approved/rejected, or discovered
|
|
596
|
-
* expired via a 410) so the stream/route state stays in sync. */
|
|
597
|
-
onResolved?: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>) => void;
|
|
598
|
-
/** Fired when the user asks the agent to re-submit an expired/withdrawn plan
|
|
599
|
-
* as a new chat turn. Receives the interaction so a callback shared across
|
|
600
|
-
* cards (e.g. via DurableChatCards) knows which plan fired. Return/resolve
|
|
601
|
-
* `false` (or throw) to report the send failed and keep the affordance
|
|
602
|
-
* retryable. Omit to hide it entirely. */
|
|
603
|
-
onReRequest?: (interaction: ChatInteraction) => boolean | void | Promise<boolean | void>;
|
|
604
|
-
/** Overrides the default re-request button label
|
|
605
|
-
* ("Ask agent to re-submit the plan" — gtm's exact current copy). */
|
|
606
|
-
reRequestLabel?: string;
|
|
607
|
-
/** Renders the plan body (markdown). Falls back to pre-wrapped plain text. */
|
|
608
|
-
renderMarkdown?: (markdown: string) => ReactNode;
|
|
609
|
-
className?: string;
|
|
610
|
-
}
|
|
611
|
-
declare function InteractionPlanCard({ interaction, canWrite, submitAnswer, onResolved, onReRequest, reRequestLabel, renderMarkdown, className, }: InteractionPlanCardProps): react.JSX.Element;
|
|
612
|
-
|
|
613
|
-
interface DurablePlanCardProps {
|
|
614
|
-
plan: ChatPlan;
|
|
615
|
-
canWrite: boolean;
|
|
616
|
-
decide: (decision: DurablePlanDecision, feedback?: string) => Promise<DurablePlanDecisionResult | null>;
|
|
617
|
-
deciding?: DurablePlanDecision | null;
|
|
618
|
-
error?: string | null;
|
|
619
|
-
renderMarkdown?: (markdown: string) => ReactNode;
|
|
620
|
-
className?: string;
|
|
621
|
-
}
|
|
622
|
-
declare function DurablePlanCard({ plan, canWrite, decide, deciding, error, renderMarkdown, className, }: DurablePlanCardProps): react.JSX.Element;
|
|
623
|
-
|
|
624
|
-
/** Manage storage and retrieval of interaction attempt keys by interaction and submission identifiers */
|
|
625
|
-
interface InteractionAttemptStore {
|
|
626
|
-
get(interactionId: string, submissionSignature: string): string | null;
|
|
627
|
-
set(interactionId: string, submissionSignature: string, attemptKey: string): void;
|
|
628
|
-
delete(interactionId: string, submissionSignature: string): void;
|
|
629
|
-
}
|
|
630
|
-
/** Create a session-based store to manage interaction attempts using provided storage and optional namespace */
|
|
631
|
-
declare function createSessionInteractionAttemptStore(storage: Pick<Storage, 'getItem' | 'setItem' | 'removeItem'>, namespace?: string): InteractionAttemptStore;
|
|
632
|
-
/** Create an in-memory store to manage interaction attempts keyed by ID and signature */
|
|
633
|
-
declare function createMemoryInteractionAttemptStore(): InteractionAttemptStore;
|
|
634
|
-
/** Generate a stable string signature from an interaction answer submission */
|
|
635
|
-
declare function interactionSubmissionSignature(submission: InteractionAnswerSubmission): string;
|
|
636
|
-
/** Define options for submitting durable interaction answers with attempt tracking and optional key creation */
|
|
637
|
-
interface DurableInteractionAnswerSubmitterOptions extends InteractionAnswerSubmitterOptions {
|
|
638
|
-
attempts: InteractionAttemptStore;
|
|
639
|
-
createAttemptKey?: () => string;
|
|
640
|
-
}
|
|
641
|
-
/** Answer submitter for a durable interaction route. One opaque attempt key is
|
|
642
|
-
* retained for an ambiguous transport/5xx result and reused after reload. A
|
|
643
|
-
* changed answer has a different signature and therefore a new attempt. */
|
|
644
|
-
declare function createDurableInteractionAnswerSubmitter(options: DurableInteractionAnswerSubmitterOptions): SubmitInteractionAnswer;
|
|
645
|
-
|
|
646
|
-
/**
|
|
647
|
-
* useChatInteractions — the interaction-state wiring every consumer of
|
|
648
|
-
* `ChatStreamCallbacks.onInteraction` re-implements: an id-keyed,
|
|
649
|
-
* insertion-ordered list with
|
|
650
|
-
*
|
|
651
|
-
* - forward-only status transitions (a replayed/stale `pending` never
|
|
652
|
-
* resurrects a resolved card),
|
|
653
|
-
* - pending-question content dedupe (a re-emitted duplicate ask never renders
|
|
654
|
-
* a second card),
|
|
655
|
-
* - cancel-event application (`interaction.cancel` → cancelled/expired),
|
|
656
|
-
* - local resolution marking (the card's `onResolved`),
|
|
657
|
-
* - reload restore from the answer route's GET list (sidecar registry is the
|
|
658
|
-
* source of truth after a reload),
|
|
659
|
-
* - turn-end settling (client mirror of the server's finalize pass: a turn
|
|
660
|
-
* that completed without a cancel was answered; a failed turn can make no
|
|
661
|
-
* such claim).
|
|
662
|
-
*
|
|
663
|
-
* The reducer functions are pure and exported for non-React consumers/tests;
|
|
664
|
-
* the hook is a thin `useState` shell over them.
|
|
665
|
-
*/
|
|
666
|
-
|
|
667
|
-
/** Insert or update one interaction. A terminal existing entry wins over any
|
|
668
|
-
* incoming state for the same id; a new pending ask that duplicates another
|
|
669
|
-
* pending ask's content is dropped. Returns the same array when unchanged. */
|
|
670
|
-
declare function upsertChatInteraction(list: ChatInteraction[], interaction: ChatInteraction): ChatInteraction[];
|
|
671
|
-
/** Applies an `interaction.cancel` event: only a pending ask moves, to
|
|
672
|
-
* `expired` (reason:"timeout") or `cancelled`. */
|
|
673
|
-
declare function cancelChatInteraction(list: ChatInteraction[], cancel: InteractionCancelData): ChatInteraction[];
|
|
674
|
-
/** Marks one ask resolved locally (the card's `onResolved`). Forward-only. */
|
|
675
|
-
declare function resolveChatInteraction(list: ChatInteraction[], id: string, status: Exclude<ChatInteractionStatus, 'pending'>, answers?: InteractionAnswers): ChatInteraction[];
|
|
676
|
-
/** Settles every still-pending ask when the turn ends: `answered` for a turn
|
|
677
|
-
* that completed cleanly, `expired` for one that failed. */
|
|
678
|
-
declare function terminalizePendingChatInteractions(list: ChatInteraction[], status: Extract<ChatInteractionStatus, 'answered' | 'expired'>): ChatInteraction[];
|
|
679
|
-
/** Define modes for restoring chat interactions with legacy or durable strategies */
|
|
680
|
-
type ChatInteractionRestoreMode = 'legacy' | 'durable';
|
|
681
|
-
/** Define options to control how chat interactions are restored during the restore process */
|
|
682
|
-
interface RestoreChatInteractionsOptions {
|
|
683
|
-
/**
|
|
684
|
-
* `legacy` settles pending asks absent from the sidecar list as answered,
|
|
685
|
-
* preserving the pre-durable restore contract. `durable` leaves them
|
|
686
|
-
* pending because absence is ambiguous until `hydrateChatInteractions`
|
|
687
|
-
* applies the durable projection.
|
|
688
|
-
*/
|
|
689
|
-
mode?: ChatInteractionRestoreMode;
|
|
690
|
-
}
|
|
691
|
-
/** Reload restore from the answer route's GET list. Legacy consumers retain
|
|
692
|
-
* the historical absence→answered behavior; durable consumers opt into the
|
|
693
|
-
* ambiguity-preserving mode and apply terminal parts through `hydrate`. */
|
|
694
|
-
declare function restoreChatInteractions(list: ChatInteraction[], outstanding: InteractionRequestWire[], options?: RestoreChatInteractionsOptions): ChatInteraction[];
|
|
695
|
-
/** Applies transcript/state-store projections after reload. Terminal state and
|
|
696
|
-
* acknowledged answer values enrich an existing pending card without relying
|
|
697
|
-
* on the sidecar's outstanding-list absence. */
|
|
698
|
-
declare function hydrateChatInteractions(list: ChatInteraction[], persisted: ChatInteraction[]): ChatInteraction[];
|
|
699
|
-
/** Resolve and manage chat interactions with methods to update, cancel, mark resolved, and restore state */
|
|
700
|
-
interface UseChatInteractionsResult {
|
|
701
|
-
/** All known interactions, insertion-ordered. */
|
|
702
|
-
interactions: ChatInteraction[];
|
|
703
|
-
/** The asks currently blocking the run (waiting on the user). */
|
|
704
|
-
pending: ChatInteraction[];
|
|
705
|
-
/** Wire to `ChatStreamCallbacks.onInteraction` (and persisted-part replay). */
|
|
706
|
-
upsert: (interaction: ChatInteraction) => void;
|
|
707
|
-
/** Wire to `interaction.cancel` events. */
|
|
708
|
-
applyCancel: (cancel: InteractionCancelData) => void;
|
|
709
|
-
/** Wire to the cards' `onResolved`. */
|
|
710
|
-
markResolved: (id: string, status: Exclude<ChatInteractionStatus, 'pending'>, answers?: InteractionAnswers) => void;
|
|
711
|
-
/** Wire to the answer route's GET list after a reload/reconnect. */
|
|
712
|
-
restore: (outstanding: InteractionRequestWire[], options?: RestoreChatInteractionsOptions) => void;
|
|
713
|
-
/** Apply durable transcript/state projections after a reload. */
|
|
714
|
-
hydrate: (persisted: ChatInteraction[]) => void;
|
|
715
|
-
/** Settle still-pending asks when the turn ends. */
|
|
716
|
-
terminalizePending: (status: Extract<ChatInteractionStatus, 'answered' | 'expired'>) => void;
|
|
717
|
-
/** Drop everything (thread switch). */
|
|
718
|
-
reset: () => void;
|
|
719
|
-
}
|
|
720
|
-
/** Resolve options for restoring chat interactions from previous sessions */
|
|
721
|
-
type UseChatInteractionsOptions = RestoreChatInteractionsOptions;
|
|
722
|
-
/** Manage chat interactions state with upsert, cancel, resolve, and restore capabilities */
|
|
723
|
-
declare function useChatInteractions(options?: UseChatInteractionsOptions): UseChatInteractionsResult;
|
|
724
|
-
|
|
725
|
-
/**
|
|
726
|
-
* Transcript-side counterpart to the composer's `@`-mention primitive
|
|
727
|
-
* (sandbox-ui#184). The composer serializes a picked file into the message
|
|
728
|
-
* text as `@<path>`; this module is the exact inverse — it finds those tokens
|
|
729
|
-
* again in a PERSISTED message and splits the text so a renderer can draw a
|
|
730
|
-
* pill where the user typed one and leave the rest as prose.
|
|
731
|
-
*
|
|
732
|
-
* Pure and product-agnostic: no React, no fetch, no DOM. The only input beyond
|
|
733
|
-
* the text is the message's OWN mention parts, so one message can never render
|
|
734
|
-
* a pill for a path another message mentioned.
|
|
735
|
-
*
|
|
736
|
-
* `ChatMentionPart` and the runtime helpers `mentionInputToPart` /
|
|
737
|
-
* `mentionPartsFromMessageParts` are re-exported here from `../chat-store/parts`
|
|
738
|
-
* directly (not the `/chat-store` barrel), so a browser bundle gets the mention
|
|
739
|
-
* vocabulary and its converters without importing `/chat-store`, whose barrel
|
|
740
|
-
* pulls the drizzle peer.
|
|
741
|
-
*/
|
|
742
|
-
|
|
743
|
-
/** One run of a segmented message: literal prose, or a matched mention with
|
|
744
|
-
* the part that produced it. `text` for a mention segment is the token as it
|
|
745
|
-
* appears in the message (`@<path>`), so a renderer that ignores `part` still
|
|
746
|
-
* reproduces the original string exactly. */
|
|
747
|
-
interface MentionTextSegment {
|
|
748
|
-
type: 'text' | 'mention';
|
|
749
|
-
text: string;
|
|
750
|
-
part?: ChatMentionPart;
|
|
751
|
-
}
|
|
752
|
-
/**
|
|
753
|
-
* Split a message's text into plain-text and mention segments by matching
|
|
754
|
-
* `@<path>` runs against that message's own mention parts.
|
|
755
|
-
*
|
|
756
|
-
* Only a part whose exact `@<path>` token appears in `content`, at a token
|
|
757
|
-
* boundary on both sides, counts as a match; everything else — including
|
|
758
|
-
* unrelated `@` text — passes through as plain text untouched. When two parts'
|
|
759
|
-
* tokens both match at the same position (one path a prefix of another), the
|
|
760
|
-
* LONGEST token wins, so nested-looking paths split at the right boundary.
|
|
761
|
-
*
|
|
762
|
-
* Returns the matched parts alongside the segments: a caller that also renders
|
|
763
|
-
* a fallback chip row can drop the chip for anything now shown inline and keep
|
|
764
|
-
* it only for mentions the text does not actually contain (a restored draft, a
|
|
765
|
-
* queued message whose text was edited).
|
|
766
|
-
*/
|
|
767
|
-
declare function segmentMentionContent(content: string, parts: ReadonlyArray<ChatMentionPart>): {
|
|
768
|
-
segments: MentionTextSegment[];
|
|
769
|
-
matched: Set<ChatMentionPart>;
|
|
770
|
-
};
|
|
771
|
-
|
|
772
|
-
/**
|
|
773
|
-
* Renders a message's attachment parts (images + files) as thumbnails and
|
|
774
|
-
* download chips — the transcript-side counterpart to `ChatComposer`'s
|
|
775
|
-
* staged-upload chips. Ported from gtm-agent's `chat-attachment-parts.tsx`
|
|
776
|
-
* onto agent-app's RAW-BYTES download contract: the host supplies
|
|
777
|
-
* `resolveFileUrl(part)`, a URL that serves the attachment's raw bytes
|
|
778
|
-
* directly, so this module never parses a JSON `{file:{blobUrl,body}}`
|
|
779
|
-
* envelope or decodes a `[base64]` marker the way gtm's vault route did.
|
|
780
|
-
*
|
|
781
|
-
* No icon-library or primitives dependency (`ChatComposer`'s house style):
|
|
782
|
-
* the loading skeleton is an inline `animate-pulse` span and the few glyphs
|
|
783
|
-
* are inline SVGs.
|
|
784
|
-
*/
|
|
785
|
-
|
|
786
|
-
/** Typed outcome of fetching one attachment's raw bytes. Callers must check
|
|
787
|
-
* `ok` before touching `blob` — a failed fetch never produces a blank
|
|
788
|
-
* render, it produces a visible error state. */
|
|
789
|
-
type AttachmentFileResult = {
|
|
790
|
-
ok: true;
|
|
791
|
-
blob: Blob;
|
|
792
|
-
} | {
|
|
793
|
-
ok: false;
|
|
794
|
-
message: string;
|
|
795
|
-
};
|
|
796
|
-
declare function __resetAttachmentFileCacheForTests(): void;
|
|
797
|
-
/** Fetches (and caches) the raw bytes behind one attachment url. Concurrent
|
|
798
|
-
* callers for the SAME url dedupe to one in-flight fetch. Only a successful
|
|
799
|
-
* settlement stays cached — evicting failures means a remount or click-retry
|
|
800
|
-
* after a transient error issues a fresh fetch. */
|
|
801
|
-
declare function loadAttachmentFile(url: string, fetchFile?: (url: string) => Promise<Response>): Promise<AttachmentFileResult>;
|
|
802
|
-
/** Drives an anchor-click download from an already-resolved blob. Returns a
|
|
803
|
-
* typed outcome rather than throwing — a chip that fails to synthesize the
|
|
804
|
-
* download must show the failure, not silently no-op. */
|
|
805
|
-
declare function triggerAttachmentDownload(name: string, blob: Blob): {
|
|
806
|
-
ok: true;
|
|
807
|
-
} | {
|
|
808
|
-
ok: false;
|
|
809
|
-
message: string;
|
|
810
|
-
};
|
|
811
|
-
interface MessageAttachmentsProps {
|
|
812
|
-
parts: ChatAttachmentPart[];
|
|
813
|
-
/** URL serving the attachment's RAW bytes. */
|
|
814
|
-
resolveFileUrl: (part: ChatAttachmentPart) => string;
|
|
815
|
-
/** Row alignment — a user-bubble attachment row is right-aligned by
|
|
816
|
-
* default; pass `"start"` for an assistant-turn attachment, which sits
|
|
817
|
-
* inline with the rest of the transcript. */
|
|
818
|
-
justify?: 'start' | 'end';
|
|
819
|
-
/** Override the fetch used to load an attachment's bytes. Default:
|
|
820
|
-
* `fetch(url, { credentials: 'same-origin' })`. */
|
|
821
|
-
fetchFile?: (url: string) => Promise<Response>;
|
|
822
|
-
}
|
|
823
|
-
/** Renders a message's attachment parts as a row of image thumbnails and file
|
|
824
|
-
* chips. `null` when there are none, so callers can render unconditionally
|
|
825
|
-
* without an extra length check. */
|
|
826
|
-
declare function MessageAttachments({ parts, resolveFileUrl, justify, fetchFile }: MessageAttachmentsProps): ReactNode;
|
|
827
|
-
|
|
828
|
-
/**
|
|
829
|
-
* `useComposerAttachments` — the composer's staged-upload lifecycle: validate
|
|
830
|
-
* selected/dropped/pasted files against the shared limits (the SAME
|
|
831
|
-
* `sniffBinary`/`checkAttachmentType`/size-cap vocabulary the store-backed
|
|
832
|
-
* upload route enforces server-side, `../chat-routes/attachment-validation`
|
|
833
|
-
* + `../chat-routes/binary-sniff`), upload each accepted file with one POST
|
|
834
|
-
* request per file (so a single failure never poisons the batch), and track
|
|
835
|
-
* every file's status so a host composer can render chips and gate sending.
|
|
836
|
-
*
|
|
837
|
-
* Ported from gtm-agent's `src/components/composer-attachments.tsx`
|
|
838
|
-
* (gtm#584/#592/#593 hardened the sniff gate and batch semantics this leans
|
|
839
|
-
* on), de-gtm-ified:
|
|
840
|
-
* - the hardcoded `/api/vault/upload?workspaceId=` URL becomes
|
|
841
|
-
* `uploadUrl`/`buildUploadRequest` (the latter wins — it hands back both
|
|
842
|
-
* the URL and a `RequestInit` override, e.g. an auth header);
|
|
843
|
-
* - `sonner` toasts become `onReject` (client pre-validation, never hits the
|
|
844
|
-
* network) and `onError` (a request that reached the server and failed);
|
|
845
|
-
* - the sandbox-ui `validateComposerFiles` import becomes a small
|
|
846
|
-
* accept-list matcher re-implemented locally (`isAcceptedFileType`,
|
|
847
|
-
* mirroring its `accept`-string matching byte-for-byte) — this module
|
|
848
|
-
* stays free of the sandbox-ui peer;
|
|
849
|
-
* - the response is expected to be `{ files: ChatAttachmentInput[] }` (full
|
|
850
|
-
* server-authoritative descriptors — size/mediaType/kind — not gtm's
|
|
851
|
-
* `{path, name}`), so `references` is a verbatim pass-through with no
|
|
852
|
-
* client recompute;
|
|
853
|
-
* - `workspaceId`'s truthiness gate becomes `enabled` (default `true`).
|
|
854
|
-
*
|
|
855
|
-
* Import-free beyond React + the browser-safe `/chat-routes` validation core:
|
|
856
|
-
* this module ships through `/web-react` into client bundles
|
|
857
|
-
* (`tests/browser-safe-subpaths.test.ts` walks the graph), so nothing here
|
|
858
|
-
* may reach a Node builtin, `sandbox-ui`, or an engine package.
|
|
859
|
-
*/
|
|
860
|
-
|
|
861
|
-
/** Define options for configuring file upload behavior and handling in a composer component */
|
|
862
|
-
interface UseComposerAttachmentsOptions {
|
|
863
|
-
/** Simple upload target: every file POSTs here. Ignored when
|
|
864
|
-
* `buildUploadRequest` is provided. */
|
|
865
|
-
uploadUrl?: string;
|
|
866
|
-
/** Full request-building seam (auth headers, per-file routing, …) — wins
|
|
867
|
-
* over `uploadUrl` when both are set. */
|
|
868
|
-
buildUploadRequest?: (args: {
|
|
869
|
-
file: File;
|
|
870
|
-
name: string;
|
|
871
|
-
form: FormData;
|
|
872
|
-
}) => {
|
|
873
|
-
url: string;
|
|
874
|
-
init?: Omit<RequestInit, 'body' | 'signal'>;
|
|
875
|
-
};
|
|
876
|
-
/** Client pre-validation rejections — a file that never reaches the
|
|
877
|
-
* network (bad type, over a size cap, over count, disallowed kind). */
|
|
878
|
-
onReject?: (reason: string, file?: File) => void;
|
|
879
|
-
/** A file that reached the upload endpoint and failed (HTTP error,
|
|
880
|
-
* transport error, malformed response). */
|
|
881
|
-
onError?: (reason: string) => void;
|
|
882
|
-
limits?: {
|
|
883
|
-
maxCount?: number;
|
|
884
|
-
maxBinaryBytes?: number;
|
|
885
|
-
maxTextBytes?: number;
|
|
886
|
-
maxTotalBytes?: number;
|
|
887
|
-
};
|
|
888
|
-
/** Attachment kinds accepted, checked against the sniffed content's
|
|
889
|
-
* mime. Default: both (`['image', 'file']` — i.e. no restriction). */
|
|
890
|
-
allowedKinds?: ChatAttachmentKind[];
|
|
891
|
-
/** `<input accept>`-style gate for the file picker/drop/paste path.
|
|
892
|
-
* Default {@link ATTACHMENT_ACCEPT}. */
|
|
893
|
-
accept?: string;
|
|
894
|
-
/** When `false`, `addFiles` rejects every call via `onReject` (and
|
|
895
|
-
* `blockReason` explains why) instead of staging anything — the
|
|
896
|
-
* replacement for gtm's `workspaceId`-truthiness gate (e.g. no workspace
|
|
897
|
-
* loaded yet). Default `true`. */
|
|
898
|
-
enabled?: boolean;
|
|
899
|
-
}
|
|
900
|
-
/** Provide staged file chips, ready attachments, and methods to add, retry, or drop composer files */
|
|
901
|
-
interface UseComposerAttachmentsResult {
|
|
902
|
-
/** Chip models for `ChatComposer`'s `pendingFiles` prop, one per staged
|
|
903
|
-
* file — `kind` is always `'file'` (agent-app's `ComposerFile.kind`
|
|
904
|
-
* discriminates file-vs-folder chips, not attachment media type). */
|
|
905
|
-
composerFiles: ComposerFile[];
|
|
906
|
-
/** Ready-to-send attachment descriptors — only files whose upload
|
|
907
|
-
* succeeded, straight from the server's response (no recompute). Feed
|
|
908
|
-
* this into `ChatTurnRequestPayload.attachments`. */
|
|
909
|
-
references: ChatAttachmentInput[];
|
|
910
|
-
/** Validate + stage + upload the given files, one request per file. */
|
|
911
|
-
addFiles: (files: File[] | FileList) => Promise<void>;
|
|
912
|
-
/** Re-upload a failed entry using its retained `File`. */
|
|
913
|
-
retry: (id: string) => void;
|
|
914
|
-
/** Drop one staged entry, aborting its upload and revoking its preview. */
|
|
915
|
-
removeAttachment: (id: string) => void;
|
|
916
|
-
/** Forget every staged entry (call after a successful send). */
|
|
917
|
-
clear: () => void;
|
|
918
|
-
/** True while any file is still pending or uploading. */
|
|
919
|
-
hasPending: boolean;
|
|
920
|
-
/** True while any file failed to upload. */
|
|
921
|
-
hasError: boolean;
|
|
922
|
-
/** Why a send is blocked, or `null` when the queue is clean. */
|
|
923
|
-
blockReason: string | null;
|
|
924
|
-
}
|
|
925
|
-
/**
|
|
926
|
-
* Owns the composer's attachment lifecycle: validate selected/dropped/pasted
|
|
927
|
-
* files against the shared limits, upload each accepted file to the
|
|
928
|
-
* product's store (one request per file), and track every file's status so
|
|
929
|
-
* the composer can render chips and gate sending.
|
|
930
|
-
*
|
|
931
|
-
* Failures surface loud — a rejected file calls `onReject` and is never
|
|
932
|
-
* uploaded; a failed upload calls `onError` and leaves an error chip the user
|
|
933
|
-
* can retry or remove. `references` only ever contains files whose upload the
|
|
934
|
-
* server actually confirmed.
|
|
935
|
-
*/
|
|
936
|
-
declare function useComposerAttachments(options: UseComposerAttachmentsOptions): UseComposerAttachmentsResult;
|
|
937
|
-
|
|
938
|
-
/**
|
|
939
|
-
* Provider brand marks — real logo path data (simple-icons / SVG Logos, both
|
|
940
|
-
* CC0) inlined so the picker shows actual provider identity instead of
|
|
941
|
-
* colored-initial monograms. Providers without a usable mark fall back to a
|
|
942
|
-
* tinted monogram chip. Aliases (z-ai/zai, moonshot/moonshotai, deepseek_ai)
|
|
943
|
-
* normalize to one entry.
|
|
944
|
-
*/
|
|
945
|
-
|
|
946
|
-
interface ProviderLogoProps {
|
|
947
|
-
provider?: string;
|
|
948
|
-
size?: number;
|
|
949
|
-
}
|
|
950
|
-
/** Real brand mark when we have one; tinted monogram otherwise. */
|
|
951
|
-
declare function ProviderLogo({ provider, size }: ProviderLogoProps): ReactNode;
|
|
952
|
-
|
|
953
|
-
/**
|
|
954
|
-
* Per-harness brand marks for the canonical pickers — the same marks the
|
|
955
|
-
* legacy sandbox-ui harness picker (`dashboard/harness-logo.tsx`) shipped,
|
|
956
|
-
* vendored as inline SVG so `/web-react` stays dependency-free beyond React:
|
|
957
|
-
* sandbox-ui (and its `@lobehub/icons-static-svg` bundle) is an OPTIONAL peer
|
|
958
|
-
* the canonical pickers must not force on a consumer. Geometry is the lobehub
|
|
959
|
-
* single-color artwork, rendered in `currentColor` exactly as the legacy
|
|
960
|
-
* component painted it (a foreground-filled CSS mask), so every mark tracks
|
|
961
|
-
* the theme. Harnesses with no published brand mark get an honest inline
|
|
962
|
-
* lucide glyph — bot / plug / terminal, the same fallbacks the legacy picker
|
|
963
|
-
* used — and an unknown id falls back to the neutral bot. Data-record
|
|
964
|
-
* structure mirrors `./provider-logo`.
|
|
965
|
-
*/
|
|
966
|
-
|
|
967
|
-
interface HarnessGlyphProps {
|
|
968
|
-
/** Harness to mark. Typed as the canonical union; an out-of-union runtime
|
|
969
|
-
* value still renders — it gets the neutral fallback glyph. */
|
|
970
|
-
harness: Harness;
|
|
971
|
-
className?: string;
|
|
972
|
-
}
|
|
973
|
-
/**
|
|
974
|
-
* Brand mark for a harness — size it from the call site (`className="h-4
|
|
975
|
-
* w-4"`). Unknown ids render the neutral bot, never an invented logo.
|
|
976
|
-
* `data-glyph` names the resolved mark so tests and stories can assert
|
|
977
|
-
* brand-vs-fallback without snapshotting path data.
|
|
978
|
-
*/
|
|
979
|
-
declare function HarnessGlyph({ harness, className }: HarnessGlyphProps): ReactNode;
|
|
980
|
-
|
|
981
|
-
/**
|
|
982
|
-
* Smooth text reveal — turns chunky network deltas into a continuous
|
|
983
|
-
* typewriter paint. Streamed turns arrive in 100-500ms slabs (model burst,
|
|
984
|
-
* flush windows, replay polls); revealing characters at an adaptive rate
|
|
985
|
-
* makes the same bytes read as top-tier streaming. The rate scales with the
|
|
986
|
-
* backlog so the reveal never falls behind the stream — it crawls when caught
|
|
987
|
-
* up and sprints when a burst lands (e.g. a reasoning summary arriving all at
|
|
988
|
-
* once still *types out* instead of popping in).
|
|
989
|
-
*/
|
|
990
|
-
/** Define configuration options for controlling smooth text reveal animation rates */
|
|
991
|
-
interface SmoothRevealOptions {
|
|
992
|
-
/** Baseline reveal rate when nearly caught up. Default 90 chars/s. */
|
|
993
|
-
baseCharsPerSecond?: number;
|
|
994
|
-
/** Extra chars/s per backlog character — the catch-up pressure. Default 5. */
|
|
995
|
-
catchUpPerChar?: number;
|
|
996
|
-
/** Hard ceiling so giant bursts still animate. Default 2400 chars/s. */
|
|
997
|
-
maxCharsPerSecond?: number;
|
|
998
|
-
}
|
|
999
|
-
/** Pure reveal step: how many characters should be visible after `dtMs`.
|
|
1000
|
-
* Exposed for tests; the hook is a thin rAF wrapper around it. */
|
|
1001
|
-
declare function nextRevealCount(shown: number, targetLength: number, dtMs: number, opts?: SmoothRevealOptions): number;
|
|
1002
|
-
/**
|
|
1003
|
-
* Animate `target` text into view. While `enabled`, the returned string grows
|
|
1004
|
-
* smoothly toward `target` (which may itself keep growing); when `enabled` is
|
|
1005
|
-
* false the full text returns immediately (history, completed turns). A
|
|
1006
|
-
* target that is not an extension of the revealed prefix (new message) resets
|
|
1007
|
-
* the reveal.
|
|
1008
|
-
*/
|
|
1009
|
-
declare function useSmoothText(target: string, enabled: boolean, opts?: SmoothRevealOptions): string;
|
|
1010
|
-
|
|
1011
|
-
type ActivityTone = 'live' | 'ok' | 'error' | 'neutral';
|
|
1012
|
-
/** Map a delegation status (free-form string on the wire) to a render tone. */
|
|
1013
|
-
declare function activityTone(status: string): ActivityTone;
|
|
1014
|
-
/** "$0.4000" under a cent shows 4 decimals; null when unknown/zero. */
|
|
1015
|
-
declare function formatActivityCost(costUsd?: number): string | null;
|
|
1016
|
-
/** "8s" / "2m 05s" / "1h 12m"; null when unknown. */
|
|
1017
|
-
declare function formatActivityDuration(durationMs?: number): string | null;
|
|
1018
|
-
/** A delegation record on the cross-context surface; `missionRef` links a
|
|
1019
|
-
* promoted delegation back to the mission/step that spawned it. */
|
|
1020
|
-
interface AgentActivityRecord extends StepAgentActivity {
|
|
1021
|
-
missionRef?: {
|
|
1022
|
-
missionId: string;
|
|
1023
|
-
stepId?: string;
|
|
1024
|
-
label?: string;
|
|
1025
|
-
};
|
|
1026
|
-
}
|
|
1027
|
-
interface AgentActivityPage {
|
|
1028
|
-
items: AgentActivityRecord[];
|
|
1029
|
-
/** Opaque continuation token; absent ⇒ no further pages. */
|
|
1030
|
-
nextCursor?: string;
|
|
1031
|
-
}
|
|
1032
|
-
/**
|
|
1033
|
-
* Fold a fetched page into the held rows: dedupe by `taskId` with the
|
|
1034
|
-
* incoming row winning (a refresh re-fetches the head page, so newer
|
|
1035
|
-
* snapshots of in-flight runs replace stale ones), newest `startedAt` first.
|
|
1036
|
-
*/
|
|
1037
|
-
declare function mergeActivityPages(existing: AgentActivityRecord[], incoming: AgentActivityRecord[]): AgentActivityRecord[];
|
|
1038
|
-
interface WaterfallRow {
|
|
1039
|
-
name: string;
|
|
1040
|
-
kind: 'pipeline' | 'model' | 'tool';
|
|
1041
|
-
/** Bar geometry as percentages of the trace's total span. */
|
|
1042
|
-
offsetPct: number;
|
|
1043
|
-
widthPct: number;
|
|
1044
|
-
durationLabel: string;
|
|
1045
|
-
approx: boolean;
|
|
1046
|
-
/** False only when the span's meta carries an explicit failure. */
|
|
1047
|
-
ok: boolean;
|
|
1048
|
-
}
|
|
1049
|
-
/** Project a FlowTrace into proportional bar geometry for {@link FlowWaterfall}. */
|
|
1050
|
-
declare function waterfallLayout(trace: FlowTrace): WaterfallRow[];
|
|
1051
|
-
interface FlowWaterfallProps {
|
|
1052
|
-
trace: FlowTrace;
|
|
1053
|
-
}
|
|
1054
|
-
/** Compact proportional waterfall over a FlowTrace — span name, bar, duration
|
|
1055
|
-
* per row; total + cost in the footer. */
|
|
1056
|
-
declare function FlowWaterfall({ trace }: FlowWaterfallProps): react.JSX.Element | null;
|
|
1057
|
-
interface MissionActivityLaneProps {
|
|
1058
|
-
/** The step's delegated-run snapshot (`MissionStepState.agentActivity`). */
|
|
1059
|
-
activity: StepAgentActivity[];
|
|
1060
|
-
/** Epoch ms origin for the expanded waterfall — usually the step start. */
|
|
1061
|
-
startedAt?: number;
|
|
1062
|
-
/** Wall clock for extending in-flight runs on the waterfall. */
|
|
1063
|
-
nowMs?: number;
|
|
1064
|
-
}
|
|
1065
|
-
/**
|
|
1066
|
-
* Collapsed sub-rows under a mission step — one row per delegated run —
|
|
1067
|
-
* expanding to the step's waterfall. Renders nothing for an empty lane.
|
|
1068
|
-
*
|
|
1069
|
-
* A sub-row appears because a delegated run STARTED or FINISHED, which is the
|
|
1070
|
-
* one kind of list change worth choreographing: it arrives, and the group
|
|
1071
|
-
* arrives as a sequence. Keying on `taskId` is what keeps the rest still — the
|
|
1072
|
-
* snapshot re-renders every poll, and a row whose status merely advanced holds
|
|
1073
|
-
* the DOM node it already had.
|
|
1074
|
-
*/
|
|
1075
|
-
declare function MissionActivityLane({ activity, startedAt, nowMs }: MissionActivityLaneProps): react.JSX.Element | null;
|
|
1076
|
-
interface AgentActivityPanelProps {
|
|
1077
|
-
/** Data port — page through the product's delegation records. Called with
|
|
1078
|
-
* no cursor on mount/refresh, with `nextCursor` for older pages. */
|
|
1079
|
-
fetchActivity: (cursor?: string) => Promise<AgentActivityPage>;
|
|
1080
|
-
/** Render the mission link for a promoted delegation (chip, anchor, router
|
|
1081
|
-
* Link — the product's routing, not ours). */
|
|
1082
|
-
renderMissionRef?: (ref: NonNullable<AgentActivityRecord['missionRef']>, record: AgentActivityRecord) => ReactNode;
|
|
1083
|
-
title?: string;
|
|
1084
|
-
emptyLabel?: string;
|
|
1085
|
-
}
|
|
1086
|
-
declare function AgentActivityPanel({ fetchActivity, renderMissionRef, title, emptyLabel }: AgentActivityPanelProps): react.JSX.Element;
|
|
1087
|
-
|
|
1088
|
-
/** Human label for a queue state. */
|
|
1089
|
-
declare function reviewQueueStateLabel(state: ReviewQueueState): string;
|
|
1090
|
-
/** Human label for a work-product status. */
|
|
1091
|
-
declare function workProductStatusLabel(status: WorkProductStatus): string;
|
|
1092
|
-
/** Every persisted work-product anchor on one message, re-validated. */
|
|
1093
|
-
declare function workProductPartsFromMessageParts(parts: ReadonlyArray<Record<string, unknown>> | null | undefined): WorkProductPersistedPart[];
|
|
1094
|
-
/** Properties for the transcript anchor card rendered in chat */
|
|
1095
|
-
interface WorkProductCardProps {
|
|
1096
|
-
part: WorkProductPersistedPart;
|
|
1097
|
-
/** Open the work product (queue detail / pane) — the card's only action. */
|
|
1098
|
-
onOpen?: (part: WorkProductPersistedPart) => void;
|
|
1099
|
-
className?: string;
|
|
1100
|
-
}
|
|
1101
|
-
/** The chat transcript anchor card for one work-product version — a compact,
|
|
1102
|
-
* system-authored pointer, not a parallel review surface. */
|
|
1103
|
-
declare function WorkProductCard({ part, onOpen, className }: WorkProductCardProps): react.JSX.Element;
|
|
1104
|
-
/** One fetched page of queue items with an optional continuation cursor */
|
|
1105
|
-
interface ReviewQueuePage {
|
|
1106
|
-
items: ReviewQueueItem[];
|
|
1107
|
-
/** Opaque continuation token; absent ⇒ no further pages. */
|
|
1108
|
-
nextCursor?: string;
|
|
1109
|
-
}
|
|
1110
|
-
/** Properties for the review queue panel over a fetch data port */
|
|
1111
|
-
interface ReviewQueuePanelProps {
|
|
1112
|
-
/** Data port — fetch one page of queue items (the projection's output,
|
|
1113
|
-
* re-validated here at the JSON boundary). */
|
|
1114
|
-
fetchQueue: (cursor?: string) => Promise<ReviewQueuePage>;
|
|
1115
|
-
/** Open one queue item (navigate to its thread / detail pane). */
|
|
1116
|
-
onSelect?: (item: ReviewQueueItem) => void;
|
|
1117
|
-
title?: string;
|
|
1118
|
-
emptyLabel?: string;
|
|
1119
|
-
className?: string;
|
|
1120
|
-
}
|
|
1121
|
-
/** Merge a fetched page into held rows: dedupe by scopeKey, incoming wins,
|
|
1122
|
-
* newest updatedAt first. Exported for tests. */
|
|
1123
|
-
declare function mergeReviewQueuePages(existing: ReviewQueueItem[], incoming: ReviewQueueItem[]): ReviewQueueItem[];
|
|
1124
|
-
/** The workspace review queue — cursor-paged, refreshable, selection via
|
|
1125
|
-
* callback. States, counts, and provenance render from the projection; the
|
|
1126
|
-
* panel holds no domain logic. */
|
|
1127
|
-
declare function ReviewQueuePanel({ fetchQueue, onSelect, title, emptyLabel, className, }: ReviewQueuePanelProps): react.JSX.Element;
|
|
1128
|
-
/** Properties for the evidence lineage table with source click-through */
|
|
1129
|
-
interface EvidenceLineageTableProps {
|
|
1130
|
-
evidence: readonly EvidenceEntry[];
|
|
1131
|
-
/** Resolve one entry's source document to an openable URL (signed
|
|
1132
|
-
* object-store/vault download) — the `resolveFileUrl` pattern. Absent →
|
|
1133
|
-
* sources render as plain refs without links. */
|
|
1134
|
-
resolveSourceUrl?: (entry: EvidenceEntry) => string;
|
|
1135
|
-
className?: string;
|
|
1136
|
-
}
|
|
1137
|
-
/** Target → claim → source lineage rows: the "every material value traceable
|
|
1138
|
-
* to source evidence" surface. Each row names the artifact target, the
|
|
1139
|
-
* claim, and the source document location supporting it. */
|
|
1140
|
-
declare function EvidenceLineageTable({ evidence, resolveSourceUrl, className }: EvidenceLineageTableProps): react.JSX.Element;
|
|
1141
|
-
/** Properties for the severity-badged exception list */
|
|
1142
|
-
interface ExceptionListProps {
|
|
1143
|
-
exceptions: readonly ExceptionEntry[];
|
|
1144
|
-
className?: string;
|
|
1145
|
-
}
|
|
1146
|
-
/** Severity-badged exception rows with resolution state. */
|
|
1147
|
-
declare function ExceptionList({ exceptions, className }: ExceptionListProps): react.JSX.Element;
|
|
1148
|
-
/** Properties for the pass/fail quality check list */
|
|
1149
|
-
interface QualityCheckListProps {
|
|
1150
|
-
checks: readonly QualityCheck[];
|
|
1151
|
-
className?: string;
|
|
1152
|
-
}
|
|
1153
|
-
/** Pass/fail quality-check rows tagged with their source (agent self-report,
|
|
1154
|
-
* platform gate, judge ensemble). */
|
|
1155
|
-
declare function QualityCheckList({ checks, className }: QualityCheckListProps): react.JSX.Element;
|
|
1156
|
-
/** Properties for the provenance stamp with the optional backtest slot */
|
|
1157
|
-
interface ProvenanceStampProps {
|
|
1158
|
-
provenance: Pick<WorkProductProvenance, 'profileHash' | 'runId' | 'servingModels'> & Partial<Pick<WorkProductProvenance, 'costUsd' | 'producedAt'>>;
|
|
1159
|
-
/** The product-resolved backtest summary for this profile hash. When its
|
|
1160
|
-
* trust gate failed, the composite renders as "quality: unverified" —
|
|
1161
|
-
* never a naked number. */
|
|
1162
|
-
backtest?: ProfileBacktestSummary;
|
|
1163
|
-
className?: string;
|
|
1164
|
-
}
|
|
1165
|
-
/** The audit line a reviewer approves against: which configuration produced
|
|
1166
|
-
* this document, what served it, and how that configuration measured on its
|
|
1167
|
-
* backtest. */
|
|
1168
|
-
declare function ProvenanceStamp({ provenance, backtest, className }: ProvenanceStampProps): react.JSX.Element;
|
|
1169
|
-
|
|
1170
|
-
/**
|
|
1171
|
-
* The pure half of the provenance affordance: what kind of claim a value is,
|
|
1172
|
-
* what a reader should DO about it, and what has to be SAID when its origin
|
|
1173
|
-
* cannot be shown.
|
|
1174
|
-
*
|
|
1175
|
-
* Zero React, zero DOM — a loader or a worker can decide a value's standing
|
|
1176
|
-
* before it reaches a screen, and `./provenance`'s `ProvenanceValue` renders
|
|
1177
|
-
* exactly what these functions decide.
|
|
1178
|
-
*
|
|
1179
|
-
* The distinction the module exists to hold: a person typing a number, a
|
|
1180
|
-
* document carrying it, a formula producing it, and a model claiming it are
|
|
1181
|
-
* four different kinds of evidence. Rendered as one grey caption they are
|
|
1182
|
-
* indistinguishable, which is how an unverified model assertion reads to a
|
|
1183
|
-
* reviewer as a transcribed fact.
|
|
1184
|
-
*
|
|
1185
|
-
* Every domain word is a caller parameter: no field names, no document kinds,
|
|
1186
|
-
* and no confidence policy beyond a default the product overrides.
|
|
1187
|
-
*/
|
|
1188
|
-
/**
|
|
1189
|
-
* How a value came to exist. Four kinds, never interchangeable:
|
|
1190
|
-
*
|
|
1191
|
-
* - `extracted` — read out of a document or message the product can open.
|
|
1192
|
-
* - `entered` — a person typed or confirmed it.
|
|
1193
|
-
* - `computed` — produced from other values, each carrying its own provenance.
|
|
1194
|
-
* - `asserted` — the agent stated it, with nothing outside the model behind it.
|
|
1195
|
-
*/
|
|
1196
|
-
type ProvenanceBasis = 'extracted' | 'entered' | 'computed' | 'asserted';
|
|
1197
|
-
/** Every basis, in the order a legend should list them. */
|
|
1198
|
-
declare const PROVENANCE_BASES: readonly ProvenanceBasis[];
|
|
1199
|
-
/** The words one basis is rendered and announced with. */
|
|
1200
|
-
interface ProvenanceBasisMeta {
|
|
1201
|
-
/** Marker text next to the value — short, and never only a colour. */
|
|
1202
|
-
label: string;
|
|
1203
|
-
/** One plain sentence naming what kind of claim this is. */
|
|
1204
|
-
meaning: string;
|
|
1205
|
-
/** What a reader can hold the value against, or `null` when nothing outside
|
|
1206
|
-
* the model can. `null` is what makes an `asserted` value uncertifiable at
|
|
1207
|
-
* any confidence. */
|
|
1208
|
-
checkableAgainst: string | null;
|
|
1209
|
-
}
|
|
1210
|
-
/** Words for one basis. */
|
|
1211
|
-
declare function provenanceBasisMeta(basis: ProvenanceBasis): ProvenanceBasisMeta;
|
|
1212
|
-
/** Whether a source could be resolved. `ready` is the default for a source that
|
|
1213
|
-
* says nothing. */
|
|
1214
|
-
type ProvenanceSourceStatus = 'ready' | 'loading' | 'unavailable';
|
|
1215
|
-
/** One thing a value came from. A `label` is mandatory because an unnamed
|
|
1216
|
-
* source is the same as no source. */
|
|
1217
|
-
interface ProvenanceSource {
|
|
1218
|
-
/** What the source IS, in the reader's words: "Form W-2 (Acme Corp)",
|
|
1219
|
-
* "Dana Whitfield", "Engagement letter". */
|
|
1220
|
-
label: string;
|
|
1221
|
-
/** The text in the source that carries the value. */
|
|
1222
|
-
quote?: string;
|
|
1223
|
-
/** Position inside the source — a page, a line, a span, a timestamp. The
|
|
1224
|
-
* caller's words; nothing here parses it. */
|
|
1225
|
-
locator?: string;
|
|
1226
|
-
/** Click-through target. Absent → the source is named but not openable. */
|
|
1227
|
-
href?: string;
|
|
1228
|
-
/** Defaults to `ready`. */
|
|
1229
|
-
status?: ProvenanceSourceStatus;
|
|
1230
|
-
/** Why an `unavailable` source cannot be opened, in one sentence. */
|
|
1231
|
-
unavailableReason?: string;
|
|
1232
|
-
}
|
|
1233
|
-
/**
|
|
1234
|
-
* What the reader should DO about a value — the only form confidence takes on
|
|
1235
|
-
* screen. "89% confidence" names no next move; these three do.
|
|
1236
|
-
*
|
|
1237
|
-
* - `settled` — nothing to do.
|
|
1238
|
-
* - `check` — open the source and confirm before relying on it.
|
|
1239
|
-
* - `confirm` — a person has to confirm the value before it is used.
|
|
1240
|
-
*/
|
|
1241
|
-
type ProvenanceStanding = 'settled' | 'check' | 'confirm';
|
|
1242
|
-
/** The words one standing is rendered and announced with. */
|
|
1243
|
-
interface ProvenanceStandingMeta {
|
|
1244
|
-
/** Short state label. */
|
|
1245
|
-
label: string;
|
|
1246
|
-
/** The next move, as a sentence a person can follow. */
|
|
1247
|
-
action: string;
|
|
1248
|
-
}
|
|
1249
|
-
/** Words for one standing. */
|
|
1250
|
-
declare function provenanceStandingMeta(standing: ProvenanceStanding): ProvenanceStandingMeta;
|
|
1251
|
-
/** The weaker of two standings — `confirm` beats `check` beats `settled`. */
|
|
1252
|
-
declare function weakerProvenanceStanding(a: ProvenanceStanding, b: ProvenanceStanding): ProvenanceStanding;
|
|
1253
|
-
/**
|
|
1254
|
-
* Where a product draws its confidence lines. These are a POLICY, not a truth:
|
|
1255
|
-
* a number a model reports about itself means different things per surface, so
|
|
1256
|
-
* the thresholds are a parameter and the number itself never reaches the screen.
|
|
1257
|
-
*/
|
|
1258
|
-
interface ProvenanceConfidencePolicy {
|
|
1259
|
-
/** At or above this, a value is `settled`. */
|
|
1260
|
-
settledAtOrAbove: number;
|
|
1261
|
-
/** At or above this (and below `settledAtOrAbove`), a value is `check`.
|
|
1262
|
-
* Below it, `confirm`. */
|
|
1263
|
-
checkAtOrAbove: number;
|
|
1264
|
-
}
|
|
1265
|
-
/** The starting policy. Products with a different tolerance pass their own. */
|
|
1266
|
-
declare const DEFAULT_PROVENANCE_CONFIDENCE_POLICY: ProvenanceConfidencePolicy;
|
|
1267
|
-
/** A value, where it came from, and — when it was computed — the provenanced
|
|
1268
|
-
* values it came from. The `inputs` field is what makes the shape compose:
|
|
1269
|
-
* a computed value's provenance IS its inputs. */
|
|
1270
|
-
interface ProvenanceRecord {
|
|
1271
|
-
/** The value as the reader should see it, already formatted. An empty string
|
|
1272
|
-
* is a missing value and renders as one, never as blank space. */
|
|
1273
|
-
display: string;
|
|
1274
|
-
/** What the value IS ("Wages", "Filing deadline"). Optional at the top level,
|
|
1275
|
-
* where the surface around it usually says; rendered for every composed
|
|
1276
|
-
* input, where nothing else names them. */
|
|
1277
|
-
label?: string;
|
|
1278
|
-
basis: ProvenanceBasis;
|
|
1279
|
-
/** Where it came from. An `extracted` value without one is a gap, not a
|
|
1280
|
-
* detail. */
|
|
1281
|
-
sources?: readonly ProvenanceSource[];
|
|
1282
|
-
/** The provenanced values a `computed` value was produced from. */
|
|
1283
|
-
inputs?: readonly ProvenanceRecord[];
|
|
1284
|
-
/** How the inputs combine, in the caller's words ("wages + interest"). */
|
|
1285
|
-
derivation?: string;
|
|
1286
|
-
/** 0–1. Never rendered as a number — it selects a standing. */
|
|
1287
|
-
confidence?: number;
|
|
1288
|
-
/** Overrides the standing confidence and basis would produce — a reviewer
|
|
1289
|
-
* approved it, a gate failed. It can only make a value WEAKER: the
|
|
1290
|
-
* structural floors below still apply, so a product cannot mark a value
|
|
1291
|
-
* settled that has no origin on file. */
|
|
1292
|
-
standing?: ProvenanceStanding;
|
|
1293
|
-
}
|
|
1294
|
-
/** The standing a bare confidence maps to under a policy. */
|
|
1295
|
-
declare function standingFromConfidence(confidence: number, policy?: ProvenanceConfidencePolicy): ProvenanceStanding;
|
|
1296
|
-
/** Something missing that the reader has to be TOLD about, because the value
|
|
1297
|
-
* renders either way and a bare number reads as a fact. */
|
|
1298
|
-
type ProvenanceGapKind = 'no-source' | 'no-inputs' | 'unavailable-source';
|
|
1299
|
-
/** One stated gap. `message` is rendered verbatim. */
|
|
1300
|
-
interface ProvenanceGap {
|
|
1301
|
-
kind: ProvenanceGapKind;
|
|
1302
|
-
message: string;
|
|
1303
|
-
/** The source that could not be resolved (`unavailable-source` only). */
|
|
1304
|
-
source?: ProvenanceSource;
|
|
1305
|
-
}
|
|
1306
|
-
/** The sentence for a source that is not `ready`, or `null` when it is. One
|
|
1307
|
-
* source of this copy, so the row and the gap list never disagree. */
|
|
1308
|
-
declare function describeProvenanceSourceStatus(source: ProvenanceSource): string | null;
|
|
1309
|
-
/**
|
|
1310
|
-
* What this record cannot show, at its own level. Inputs are not walked: every
|
|
1311
|
-
* composed input renders its own gaps next to its own value, where a reader can
|
|
1312
|
-
* act on them.
|
|
1313
|
-
*/
|
|
1314
|
-
declare function provenanceGaps(record: ProvenanceRecord): ProvenanceGap[];
|
|
1315
|
-
/** The sources still resolving — rendered as their own state, never as an
|
|
1316
|
-
* absence. A load in flight is not a missing source. */
|
|
1317
|
-
declare function loadingProvenanceSources(record: ProvenanceRecord): ProvenanceSource[];
|
|
1318
1
|
/**
|
|
1319
|
-
*
|
|
1320
|
-
*
|
|
1321
|
-
*
|
|
1322
|
-
*
|
|
1323
|
-
*
|
|
1324
|
-
*
|
|
1325
|
-
*
|
|
1326
|
-
*
|
|
1327
|
-
*
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1330
|
-
*
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
*
|
|
1335
|
-
*
|
|
1336
|
-
*
|
|
1337
|
-
*
|
|
1338
|
-
*
|
|
1339
|
-
* one
|
|
1340
|
-
*
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
*
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
*
|
|
1352
|
-
*
|
|
1353
|
-
*
|
|
1354
|
-
*
|
|
1355
|
-
*
|
|
1356
|
-
*
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
*
|
|
1361
|
-
*
|
|
1362
|
-
*
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
* without a retry control, never swallowed. */
|
|
1380
|
-
onRetrySource?: (source: ProvenanceSource, record: ProvenanceRecord) => void;
|
|
1381
|
-
/** Where this product draws its confidence lines. */
|
|
1382
|
-
confidencePolicy?: ProvenanceConfidencePolicy;
|
|
1383
|
-
/**
|
|
1384
|
-
* How many levels of composed inputs stay expandable. Past it an input still
|
|
1385
|
-
* renders its value, its basis and its origin sentence — it just stops
|
|
1386
|
-
* carrying its own disclosure, so a deep tree cannot run away and a record
|
|
1387
|
-
* that reaches itself cannot recurse forever. Default 2.
|
|
1388
|
-
*/
|
|
1389
|
-
maxDepth?: number;
|
|
1390
|
-
/** Open the disclosure on first render — for a review surface where the
|
|
1391
|
-
* trail is the point. Several of these coexist: only a reader opening a
|
|
1392
|
-
* trail closes another one. */
|
|
1393
|
-
defaultOpen?: boolean;
|
|
1394
|
-
/** What an empty `display` renders as. A blank cell is the defect this
|
|
1395
|
-
* component exists to remove. */
|
|
1396
|
-
missingValueLabel?: string;
|
|
1397
|
-
className?: string;
|
|
1398
|
-
}
|
|
1399
|
-
/**
|
|
1400
|
-
* A value, its origin marker, and the disclosure that shows where it came
|
|
1401
|
-
* from. The marker states the basis in words and, whenever there is something
|
|
1402
|
-
* to do about the value, the next move — so the standing is legible at rest
|
|
1403
|
-
* and does not depend on anyone opening the panel.
|
|
1404
|
-
*/
|
|
1405
|
-
declare function ProvenanceValue({ record, onOpenSource, onRetrySource, confidencePolicy, maxDepth, defaultOpen, missingValueLabel, className, }: ProvenanceValueProps): react.JSX.Element;
|
|
1406
|
-
/** Properties for the basis legend. */
|
|
1407
|
-
interface ProvenanceLegendProps {
|
|
1408
|
-
/** Only the bases present on screen. Passing all four when only two appear
|
|
1409
|
-
* teaches distinctions the reader cannot use. */
|
|
1410
|
-
bases: readonly ProvenanceBasis[];
|
|
1411
|
-
className?: string;
|
|
1412
|
-
}
|
|
1413
|
-
/** The marker key for a surface that renders several bases at once — a review
|
|
1414
|
-
* pane, a grid, a return. Each row is the same glyph, tone and words the
|
|
1415
|
-
* markers use, plus what the basis MEANS. */
|
|
1416
|
-
declare function ProvenanceLegend({ bases, className }: ProvenanceLegendProps): react.JSX.Element | null;
|
|
1417
|
-
|
|
1418
|
-
/**
|
|
1419
|
-
* `SeatPaywall` — the shared "unlock this product" screen every agent app
|
|
1420
|
-
* shows when a user has no active seat and has spent past the free tier.
|
|
1421
|
-
*
|
|
1422
|
-
* Copy contract (design §6.8): the included monthly AI usage is framed as a
|
|
1423
|
-
* BENEFIT the buyer receives — never the ratio, never the word "margin", never
|
|
1424
|
-
* "we debit 50%". Surface the allowance, hide the economics.
|
|
1425
|
-
*
|
|
1426
|
-
* Styling contract matches the rest of `web-react`: Tailwind classes over the
|
|
1427
|
-
* shared design tokens (`bg-card`, `border-border`, `text-muted-foreground`,
|
|
1428
|
-
* `bg-primary`, …); glyphs are inline SVGs; no icon or UI library.
|
|
1429
|
-
*/
|
|
1430
|
-
|
|
1431
|
-
interface SeatPaywallProps {
|
|
1432
|
-
/** Human product name shown in the headline, e.g. "Creative". */
|
|
1433
|
-
product: string;
|
|
1434
|
-
/** Fired when the user clicks the unlock CTA — route them to checkout. When
|
|
1435
|
-
* it returns a promise the button shows a pending state and ignores repeat
|
|
1436
|
-
* clicks until it settles (no double-charge on a slow checkout open). */
|
|
1437
|
-
onCheckout: () => void | Promise<void>;
|
|
1438
|
-
/** Monthly seat price in whole dollars. Default 100. */
|
|
1439
|
-
priceUsd?: number;
|
|
1440
|
-
/** Included monthly AI usage in whole dollars. Default 50. */
|
|
1441
|
-
includedUsageUsd?: number;
|
|
1442
|
-
/** Platform catalog terms. When present, these override the legacy dollar
|
|
1443
|
-
* props and show any introductory period without product-local price copy. */
|
|
1444
|
-
offer?: ProductSeatOffer;
|
|
1445
|
-
/** Optional one-line value prop under the headline. */
|
|
1446
|
-
tagline?: string;
|
|
1447
|
-
/** CTA label. Default "Continue to checkout". */
|
|
1448
|
-
ctaLabel?: string;
|
|
1449
|
-
/** Value-prop bullets. Default = product/usage-derived only; pass your own to
|
|
1450
|
-
* supply product-specific value props (the shell bakes no GTM copy). */
|
|
1451
|
-
benefits?: ReactNode[];
|
|
1452
|
-
/** Optional fine print under the CTA (e.g. "Cancel anytime."). Omitted by default. */
|
|
1453
|
-
footnote?: ReactNode;
|
|
1454
|
-
}
|
|
1455
|
-
/**
|
|
1456
|
-
* Centered card paywall. The price line reads
|
|
1457
|
-
* "$100/mo · includes $50/mo of AI usage" so the included allowance anchors the
|
|
1458
|
-
* value without ever exposing the ratio — and says it ONCE: the default
|
|
1459
|
-
* benefits don't restate the usage line the subline already carries, and the
|
|
1460
|
-
* CTA is the next step ("Continue to checkout"), not a third repeat of the
|
|
1461
|
-
* eyebrow + headline's "Unlock {product}".
|
|
1462
|
-
*/
|
|
1463
|
-
declare function SeatPaywall({ product, onCheckout, priceUsd, includedUsageUsd, offer, tagline, ctaLabel, benefits, footnote, }: SeatPaywallProps): ReactNode;
|
|
1464
|
-
|
|
1465
|
-
interface UseInfiniteScrollOptions {
|
|
1466
|
-
/** Only fire `onLoadMore` while true (a next page exists, none in flight). */
|
|
1467
|
-
enabled: boolean;
|
|
1468
|
-
/** Scroll container the sentinel lives in. Defaults to the viewport. */
|
|
1469
|
-
root?: RefObject<HTMLElement | null>;
|
|
1470
|
-
/** Prefetch distance before the sentinel is actually reached. */
|
|
1471
|
-
rootMargin?: string;
|
|
1472
|
-
}
|
|
1473
|
-
/**
|
|
1474
|
-
* Fires `onLoadMore` when a sentinel element scrolls into view. Returns a ref
|
|
1475
|
-
* callback for that sentinel (typically the last element in a list).
|
|
1476
|
-
*
|
|
1477
|
-
* The observer is re-created whenever `enabled` flips, so a short first page
|
|
1478
|
-
* that leaves the sentinel on-screen keeps loading: when a load finishes and
|
|
1479
|
-
* `enabled` returns to true, the fresh observer re-reads the current
|
|
1480
|
-
* intersection state and fires again until the sentinel is pushed off-screen.
|
|
1481
|
-
*/
|
|
1482
|
-
declare function useInfiniteScroll(onLoadMore: () => void, { enabled, root, rootMargin }: UseInfiniteScrollOptions): (node: HTMLElement | null) => void;
|
|
1483
|
-
interface SessionPageQuery {
|
|
1484
|
-
/** Trimmed search term; empty string means no filter. */
|
|
1485
|
-
q: string;
|
|
1486
|
-
sort: SessionSort;
|
|
1487
|
-
/** `null` for the first page. */
|
|
1488
|
-
cursor: string | null;
|
|
1489
|
-
/** Aborted when the view changes or the component unmounts. */
|
|
1490
|
-
signal: AbortSignal;
|
|
1491
|
-
}
|
|
1492
|
-
/** Data port — one page of sessions for the current view. */
|
|
1493
|
-
type FetchSessionPage = (query: SessionPageQuery) => Promise<SessionPage>;
|
|
1494
|
-
interface UseSessionHistoryOptions {
|
|
1495
|
-
fetchPage: FetchSessionPage;
|
|
1496
|
-
/** Trimmed search term driving the fetch. */
|
|
1497
|
-
q: string;
|
|
1498
|
-
sort: SessionSort;
|
|
1499
|
-
/** SSR page 1 of the default view, so the first paint costs no request. */
|
|
1500
|
-
initialPage: SessionPage;
|
|
1501
|
-
/** The sort `initialPage` was rendered for. Default `'newest'`. */
|
|
1502
|
-
defaultSort?: SessionSort;
|
|
1503
|
-
}
|
|
1504
|
-
interface SessionHistoryState {
|
|
1505
|
-
items: SessionSummary[];
|
|
1506
|
-
hasMore: boolean;
|
|
1507
|
-
isLoadingFirst: boolean;
|
|
1508
|
-
isLoadingMore: boolean;
|
|
1509
|
-
isError: boolean;
|
|
1510
|
-
loadMore: () => void;
|
|
1511
|
-
/** Re-run whichever load failed. */
|
|
1512
|
-
retry: () => void;
|
|
1513
|
-
/** Refetch page 1 — call after a client-side mutation (e.g. a delete). */
|
|
1514
|
-
reload: () => void;
|
|
1515
|
-
}
|
|
1516
|
-
/**
|
|
1517
|
-
* Infinite-scroll data source for the history view. Seeds from `initialPage`
|
|
1518
|
-
* for the default view (no fetch) and otherwise fetches page 1 for the current
|
|
1519
|
-
* search/sort; `loadMore` appends the next cursor page.
|
|
1520
|
-
*
|
|
1521
|
-
* Raw promises + `AbortController` rather than a router fetcher, so a filter
|
|
1522
|
-
* change cancels in-flight requests, pages accumulate, and a late response from
|
|
1523
|
-
* a superseded view is dropped by the monotonic `seq` guard.
|
|
1524
|
-
*/
|
|
1525
|
-
declare function useSessionHistory({ fetchPage, q, sort, initialPage, defaultSort, }: UseSessionHistoryOptions): SessionHistoryState;
|
|
1526
|
-
interface SessionActionsOptions {
|
|
1527
|
-
/** Persist a new title. Reject to surface the error in the dialog. */
|
|
1528
|
-
renameSession: (sessionId: string, title: string) => Promise<void>;
|
|
1529
|
-
deleteSession: (sessionId: string) => Promise<void>;
|
|
1530
|
-
/** Called after a successful rename/delete — revalidate the rail here. */
|
|
1531
|
-
onChanged?: () => void;
|
|
1532
|
-
/** Called after deleting the session the user is currently viewing, so the
|
|
1533
|
-
* product can navigate away from a route that no longer resolves. */
|
|
1534
|
-
onDeletedCurrent?: () => void;
|
|
1535
|
-
/** The open session, compared against the delete target. */
|
|
1536
|
-
currentSessionId?: string | null;
|
|
1537
|
-
/** Product toast/log seam. Errors also render inside the dialog. */
|
|
1538
|
-
notify?: (level: 'success' | 'error', message: string) => void;
|
|
1539
|
-
labels?: Partial<SessionActionLabels>;
|
|
1540
|
-
}
|
|
1541
|
-
interface SessionActionLabels {
|
|
1542
|
-
renameTitle: string;
|
|
1543
|
-
renameField: string;
|
|
1544
|
-
renameSubmit: string;
|
|
1545
|
-
deleteTitle: string;
|
|
1546
|
-
deleteBody: (title: string) => string;
|
|
1547
|
-
deleteSubmit: string;
|
|
1548
|
-
cancel: string;
|
|
1549
|
-
renamed: string;
|
|
1550
|
-
deleted: string;
|
|
1551
|
-
renameFailed: string;
|
|
1552
|
-
deleteFailed: string;
|
|
1553
|
-
}
|
|
1554
|
-
interface SessionActions {
|
|
1555
|
-
openRename: (session: SessionSummary) => void;
|
|
1556
|
-
openDelete: (session: SessionSummary) => void;
|
|
1557
|
-
/** Render once, anywhere that survives navigation (the layout). */
|
|
1558
|
-
dialogs: ReactNode;
|
|
1559
|
-
busy: boolean;
|
|
1560
|
-
}
|
|
1561
|
-
/**
|
|
1562
|
-
* Rename + delete for one session, shared by the rail kebab and the history
|
|
1563
|
-
* row menu so both drive the same dialogs and the same product mutations.
|
|
1564
|
-
*
|
|
1565
|
-
* Dialogs are owned here rather than returned as raw state: two surfaces
|
|
1566
|
-
* needing the same confirm step is exactly how a product ends up with two
|
|
1567
|
-
* subtly different delete confirmations.
|
|
1568
|
-
*/
|
|
1569
|
-
declare function useSessionActions({ renameSession, deleteSession, onChanged, onDeletedCurrent, currentSessionId, notify, labels, }: SessionActionsOptions): SessionActions;
|
|
1570
|
-
interface SessionHistoryPanelProps {
|
|
1571
|
-
history: SessionHistoryState;
|
|
1572
|
-
/** Whether the workspace has any sessions at all — decided by the SSR page,
|
|
1573
|
-
* independent of the active search, so filtering to zero shows "no matches"
|
|
1574
|
-
* rather than the first-run empty state. */
|
|
1575
|
-
hasAnySessions: boolean;
|
|
1576
|
-
query: string;
|
|
1577
|
-
onQueryChange: (value: string) => void;
|
|
1578
|
-
sort: SessionSort;
|
|
1579
|
-
onSortChange: (value: SessionSort) => void;
|
|
1580
|
-
/** Product route for one session row. */
|
|
1581
|
-
hrefForSession: (sessionId: string) => string;
|
|
1582
|
-
/** Rendered as the row link. Defaults to an `<a>`; pass a router Link to keep
|
|
1583
|
-
* client-side navigation. */
|
|
1584
|
-
linkComponent?: LinkLikeComponent;
|
|
1585
|
-
/** Ids currently mid-turn — renders the responding treatment. */
|
|
1586
|
-
respondingSessionIds?: ReadonlySet<string>;
|
|
1587
|
-
onRename?: (session: SessionSummary) => void;
|
|
1588
|
-
onDelete?: (session: SessionSummary) => void;
|
|
1589
|
-
/** Product-owned mutation for selected rows or a workspace-wide age range. */
|
|
1590
|
-
onBulkAction?: (action: SessionBulkAction) => Promise<void>;
|
|
1591
|
-
/** Menu wording, so this surface and the rail name the same act the same way
|
|
1592
|
-
* — a product whose delete is really an archive says so in both places. */
|
|
1593
|
-
renameLabel?: string;
|
|
1594
|
-
deleteLabel?: string;
|
|
1595
|
-
/**
|
|
1596
|
-
* Row actions this shell has no opinion about — pin, categorise, share.
|
|
1597
|
-
* Same seam and same ordering as the rail's `SessionRowActions.extraActions`:
|
|
1598
|
-
* evaluated per session, placed between rename and delete. This menu is
|
|
1599
|
-
* text-only, so `icon` is ignored here and honoured on the rail.
|
|
1600
|
-
*/
|
|
1601
|
-
extraActions?: (session: SessionSummary) => SessionRailAction[];
|
|
1602
|
-
/** New-session destination for the header action. Omitted ⇒ no button. */
|
|
1603
|
-
newSessionHref?: string;
|
|
1604
|
-
title?: string;
|
|
1605
|
-
untitledLabel?: string;
|
|
1606
|
-
emptyTitle?: string;
|
|
1607
|
-
emptyDescription?: string;
|
|
1608
|
-
/** Absolute → relative timestamp. Defaults to a compact built-in. */
|
|
1609
|
-
formatTimestamp?: (isoDate: string | null) => string;
|
|
1610
|
-
/** Max width of the reading column. `'full'` opts out for a product whose
|
|
1611
|
-
* surface really is a wide table. Default keeps title and timestamp inside
|
|
1612
|
-
* one scannable line rather than at opposite edges of a 1440px viewport. */
|
|
1613
|
-
contentWidth?: 'reading' | 'full';
|
|
1614
|
-
className?: string;
|
|
1615
|
-
}
|
|
1616
|
-
type SessionBulkAction = {
|
|
1617
|
-
kind: 'selected';
|
|
1618
|
-
ids: string[];
|
|
1619
|
-
} | {
|
|
1620
|
-
kind: 'older-than';
|
|
1621
|
-
days: number;
|
|
1622
|
-
} | {
|
|
1623
|
-
kind: 'newer-than';
|
|
1624
|
-
days: number;
|
|
1625
|
-
};
|
|
1626
|
-
interface LinkLikeProps {
|
|
1627
|
-
to: string;
|
|
1628
|
-
className?: string;
|
|
1629
|
-
children?: ReactNode;
|
|
1630
|
-
}
|
|
1631
|
-
type LinkLikeComponent = (props: LinkLikeProps) => ReactNode;
|
|
1632
|
-
/** Compact relative time. Overridable — a product with its own i18n passes
|
|
1633
|
-
* `formatTimestamp` rather than this being the only option. */
|
|
1634
|
-
declare function formatSessionTimestamp(isoDate: string | null): string;
|
|
1635
|
-
/**
|
|
1636
|
-
* The full session history: search, sort, cursor-paged rows with per-row
|
|
1637
|
-
* actions, and the states in between (first-run empty, loading, no matches,
|
|
1638
|
-
* error + retry).
|
|
1639
|
-
*
|
|
1640
|
-
* This is the surface the rail's capped list overflows into — the reason the
|
|
1641
|
-
* rail can stay short without hiding the user's work.
|
|
1642
|
-
*/
|
|
1643
|
-
declare function SessionHistoryPanel({ history, hasAnySessions, query, onQueryChange, sort, onSortChange, hrefForSession, linkComponent: Link, respondingSessionIds, onRename, onDelete, onBulkAction, renameLabel, deleteLabel, extraActions, newSessionHref, title, untitledLabel, emptyTitle, emptyDescription, formatTimestamp, contentWidth, className, }: SessionHistoryPanelProps): react.JSX.Element;
|
|
1644
|
-
|
|
1645
|
-
/**
|
|
1646
|
-
* The pure half of the editable record grid: the typed column vocabulary, the
|
|
1647
|
-
* per-cell parse/validate rules, display + editor formatting, and the
|
|
1648
|
-
* optimistic overlay a caller's rows are projected through.
|
|
1649
|
-
*
|
|
1650
|
-
* Zero React, zero DOM — a product can validate a row on a worker before it
|
|
1651
|
-
* ever reaches storage, and the component in `./record-grid` renders exactly
|
|
1652
|
-
* what these functions decide.
|
|
1653
|
-
*
|
|
1654
|
-
* Every domain word is a caller parameter: the module knows no column names,
|
|
1655
|
-
* no currencies, no option sets. What it owns is the mechanism four verticals
|
|
1656
|
-
* each re-derived — typed cells, an error a person can act on, and an
|
|
1657
|
-
* optimistic edit that can be taken back.
|
|
1658
|
-
*/
|
|
1659
|
-
|
|
1660
|
-
/** The value one cell can hold. `null` is "no value on file". */
|
|
1661
|
-
type RecordGridValue = string | number | boolean | null;
|
|
1662
|
-
/** Typed outcome for one cell. Callers MUST inspect `succeeded` before reading
|
|
1663
|
-
* `value`; nothing here throws. */
|
|
1664
|
-
type RecordGridCellOutcome = {
|
|
1665
|
-
succeeded: true;
|
|
1666
|
-
value: RecordGridValue;
|
|
1667
|
-
} | {
|
|
1668
|
-
succeeded: false;
|
|
1669
|
-
error: string;
|
|
1670
|
-
};
|
|
1671
|
-
/** Typed outcome for a whole row of inputs (the add form). `cellErrors` is
|
|
1672
|
-
* keyed by column id so each control can render its own message. */
|
|
1673
|
-
type RecordGridRowOutcome = {
|
|
1674
|
-
succeeded: true;
|
|
1675
|
-
value: Record<string, RecordGridValue>;
|
|
1676
|
-
} | {
|
|
1677
|
-
succeeded: false;
|
|
1678
|
-
error: string;
|
|
1679
|
-
cellErrors: Readonly<Record<string, string>>;
|
|
1680
|
-
};
|
|
1681
|
-
/** Build a cell success outcome. */
|
|
1682
|
-
declare function recordGridOk(value: RecordGridValue): RecordGridCellOutcome;
|
|
1683
|
-
/** Build a cell failure outcome carrying the message shown next to the cell. */
|
|
1684
|
-
declare function recordGridFail(error: string): RecordGridCellOutcome;
|
|
1685
|
-
/**
|
|
1686
|
-
* How a value came to sit in a cell. Rendered as the provenance tone.
|
|
1687
|
-
*
|
|
1688
|
-
* A type alias of `./provenance-model`'s `ProvenanceBasis`, not a lookalike:
|
|
1689
|
-
* two vocabularies for the same concept — a grid cell's origin — shipped one
|
|
1690
|
-
* day apart and would have drifted the moment either one added a value. The
|
|
1691
|
-
* grid gains `asserted` for free (a cell an agent claimed with nothing behind
|
|
1692
|
-
* it), where the caller previously had no way to say that.
|
|
1693
|
-
*/
|
|
1694
|
-
type RecordGridSourceBasis = ProvenanceBasis;
|
|
1695
|
-
/**
|
|
1696
|
-
* Where one cell's value came from. Optional on every row — a grid over data
|
|
1697
|
-
* with no lineage renders identically without it.
|
|
1698
|
-
*/
|
|
1699
|
-
interface RecordGridCellSource {
|
|
1700
|
-
/** The text in the source that supports this value. */
|
|
1701
|
-
quote?: string;
|
|
1702
|
-
/** Human name of the source document, message, or system. */
|
|
1703
|
-
label?: string;
|
|
1704
|
-
/** Click-through to the source. */
|
|
1705
|
-
href?: string;
|
|
1706
|
-
/** Position inside the source: a page, a line, a span — the caller's words. */
|
|
1707
|
-
locator?: string;
|
|
1708
|
-
/** How the value got here. Absent renders as `asserted` — the weakest claim
|
|
1709
|
-
* in the union — because a caller that stated no basis has established
|
|
1710
|
-
* nothing about a document, and an omission must never read as one. */
|
|
1711
|
-
basis?: RecordGridSourceBasis;
|
|
1712
|
-
}
|
|
1713
|
-
/** One option of a `select` column. */
|
|
1714
|
-
interface RecordGridSelectOption {
|
|
1715
|
-
value: string;
|
|
1716
|
-
label: string;
|
|
1717
|
-
}
|
|
1718
|
-
/** A cell is only editable, rendered, and validated when the column it depends
|
|
1719
|
-
* on holds `equals`. This is how a nested sub-form (a vesting schedule behind
|
|
1720
|
-
* a "has vesting" toggle) stays a set of flat, individually-typed columns. */
|
|
1721
|
-
interface RecordGridDependency {
|
|
1722
|
-
column: string;
|
|
1723
|
-
equals: RecordGridValue;
|
|
1724
|
-
}
|
|
1725
|
-
/** Fields every column kind carries. */
|
|
1726
|
-
interface RecordGridColumnBase {
|
|
1727
|
-
/** Key into a row's `values` bag. */
|
|
1728
|
-
id: string;
|
|
1729
|
-
/** Column heading, and the accessible name of every control in the column. */
|
|
1730
|
-
header: string;
|
|
1731
|
-
/** Short hint rendered under the control in the add form. */
|
|
1732
|
-
hint?: string;
|
|
1733
|
-
/** An empty cell is rejected. */
|
|
1734
|
-
required?: boolean;
|
|
1735
|
-
/** Cells are editable unless this is `false`. */
|
|
1736
|
-
editable?: boolean;
|
|
1737
|
-
/** Cell alignment. Numeric kinds default to `right`. */
|
|
1738
|
-
align?: 'left' | 'right';
|
|
1739
|
-
/** Groups this column under a labelled sub-form in the add form. */
|
|
1740
|
-
group?: string;
|
|
1741
|
-
/** Only applicable when another column holds a given value. */
|
|
1742
|
-
dependsOn?: RecordGridDependency;
|
|
1743
|
-
/** Extra rule, run after the kind's own checks pass. Return the message to
|
|
1744
|
-
* reject with, or `null` to accept. */
|
|
1745
|
-
validate?: (value: RecordGridValue) => string | null;
|
|
1746
|
-
/** Column summary rendered in the footer row. */
|
|
1747
|
-
footerValue?: (rows: readonly RecordGridRow[]) => RecordGridValue;
|
|
1748
|
-
}
|
|
1749
|
-
/** Free text, optionally length- or pattern-constrained. */
|
|
1750
|
-
interface RecordGridTextColumn extends RecordGridColumnBase {
|
|
1751
|
-
kind: 'text';
|
|
1752
|
-
minLength?: number;
|
|
1753
|
-
maxLength?: number;
|
|
1754
|
-
pattern?: RegExp;
|
|
1755
|
-
/** Message when `pattern` rejects. Without it the pattern source is shown. */
|
|
1756
|
-
patternMessage?: string;
|
|
1757
|
-
/** Render a textarea instead of a single-line input. */
|
|
1758
|
-
multiline?: boolean;
|
|
1759
|
-
}
|
|
1760
|
-
/** A plain number. */
|
|
1761
|
-
interface RecordGridNumberColumn extends RecordGridColumnBase {
|
|
1762
|
-
kind: 'number';
|
|
1763
|
-
min?: number;
|
|
1764
|
-
max?: number;
|
|
1765
|
-
integer?: boolean;
|
|
1766
|
-
/** Passed through to the editor's `step`. */
|
|
1767
|
-
step?: number;
|
|
1768
|
-
}
|
|
1769
|
-
/** A money amount. The currency is a caller parameter — this module bakes no
|
|
1770
|
-
* domain value, so a product with two currencies declares two columns. */
|
|
1771
|
-
interface RecordGridCurrencyColumn extends RecordGridColumnBase {
|
|
1772
|
-
kind: 'currency';
|
|
1773
|
-
/** ISO 4217 code, e.g. `USD`. */
|
|
1774
|
-
currency: string;
|
|
1775
|
-
min?: number;
|
|
1776
|
-
max?: number;
|
|
1777
|
-
/** Fraction digits for display. Defaults to the currency's own. */
|
|
1778
|
-
fractionDigits?: number;
|
|
1779
|
-
}
|
|
1780
|
-
/** A calendar date held as `YYYY-MM-DD`; no time, no zone. */
|
|
1781
|
-
interface RecordGridDateColumn extends RecordGridColumnBase {
|
|
1782
|
-
kind: 'date';
|
|
1783
|
-
/** Earliest accepted date, `YYYY-MM-DD`. */
|
|
1784
|
-
min?: string;
|
|
1785
|
-
/** Latest accepted date, `YYYY-MM-DD`. */
|
|
1786
|
-
max?: string;
|
|
1787
|
-
}
|
|
1788
|
-
/** One of a closed set of values. */
|
|
1789
|
-
interface RecordGridSelectColumn extends RecordGridColumnBase {
|
|
1790
|
-
kind: 'select';
|
|
1791
|
-
options: readonly RecordGridSelectOption[];
|
|
1792
|
-
}
|
|
1793
|
-
/** A checkbox. */
|
|
1794
|
-
interface RecordGridBooleanColumn extends RecordGridColumnBase {
|
|
1795
|
-
kind: 'boolean';
|
|
1796
|
-
/** Label for `true`. Defaults to `Yes`. */
|
|
1797
|
-
trueLabel?: string;
|
|
1798
|
-
/** Label for `false`. Defaults to `No`. */
|
|
1799
|
-
falseLabel?: string;
|
|
1800
|
-
}
|
|
1801
|
-
/** Every column shape the grid renders. */
|
|
1802
|
-
type RecordGridColumn = RecordGridTextColumn | RecordGridNumberColumn | RecordGridCurrencyColumn | RecordGridDateColumn | RecordGridSelectColumn | RecordGridBooleanColumn;
|
|
1803
|
-
/** One row: an id, a flat value bag keyed by column id, and optional per-cell
|
|
1804
|
-
* provenance. A record-backed product maps its fold output straight onto
|
|
1805
|
-
* this — one entry per cell, its quote and link in `sources`. */
|
|
1806
|
-
interface RecordGridRow {
|
|
1807
|
-
id: string;
|
|
1808
|
-
values: Readonly<Record<string, RecordGridValue>>;
|
|
1809
|
-
/** Per-cell provenance, keyed by column id. */
|
|
1810
|
-
sources?: Readonly<Record<string, RecordGridCellSource>>;
|
|
1811
|
-
/** No cell in this row may be edited or deleted. */
|
|
1812
|
-
readOnly?: boolean;
|
|
1813
|
-
/** Accessible name for the row's own controls. Falls back to the first text
|
|
1814
|
-
* or select column's value, then the row id. */
|
|
1815
|
-
label?: string;
|
|
1816
|
-
}
|
|
1817
|
-
/** True when the column's dependency (if any) is satisfied by the row's other
|
|
1818
|
-
* values. An inapplicable cell is never required, never validated, and never
|
|
1819
|
-
* editable. */
|
|
1820
|
-
declare function isRecordGridCellApplicable(column: RecordGridColumn, values: Readonly<Record<string, RecordGridValue>>): boolean;
|
|
1821
|
-
/** Value equality across the grid's value union, treating `undefined` as
|
|
1822
|
-
* `null` so an absent key and an explicit null never read as a change. */
|
|
1823
|
-
declare function sameRecordGridValue(a: RecordGridValue | undefined, b: RecordGridValue | undefined): boolean;
|
|
1824
|
-
/**
|
|
1825
|
-
* Turn what an editor control produced into a typed value. Syntax only —
|
|
1826
|
-
* range, length, and membership are {@link validateRecordGridCell}'s job.
|
|
1827
|
-
*/
|
|
1828
|
-
declare function parseRecordGridInput(column: RecordGridColumn, raw: string): RecordGridCellOutcome;
|
|
1829
|
-
/**
|
|
1830
|
-
* Check one already-typed value against its column. Returns the value the grid
|
|
1831
|
-
* should store (empty text normalizes to `null`) or the message a person can
|
|
1832
|
-
* act on.
|
|
1833
|
-
*/
|
|
1834
|
-
declare function validateRecordGridCell(column: RecordGridColumn, value: RecordGridValue): RecordGridCellOutcome;
|
|
1835
|
-
/** Parse editor text and validate it in one step — what a committing cell
|
|
1836
|
-
* editor calls. */
|
|
1837
|
-
declare function readRecordGridCell(column: RecordGridColumn, raw: string): RecordGridCellOutcome;
|
|
1838
|
-
/**
|
|
1839
|
-
* Validate a whole value bag against the columns. Inapplicable cells (an
|
|
1840
|
-
* unsatisfied `dependsOn`) are forced to `null` rather than carried, so a
|
|
1841
|
-
* sub-form the user turned off cannot smuggle stale values into a write.
|
|
1842
|
-
*/
|
|
1843
|
-
declare function validateRecordGridRow(columns: readonly RecordGridColumn[], values: Readonly<Record<string, RecordGridValue>>): RecordGridRowOutcome;
|
|
1844
|
-
/** Display text for a cell. `null` renders as the empty string; the component
|
|
1845
|
-
* decides what a missing value looks like. */
|
|
1846
|
-
declare function formatRecordGridValue(column: RecordGridColumn, value: RecordGridValue, locale?: string): string;
|
|
1847
|
-
/** The text an editor control starts with — the raw value, never the formatted
|
|
1848
|
-
* one, so committing an untouched cell is a no-op. */
|
|
1849
|
-
declare function recordGridEditorText(column: RecordGridColumn, value: RecordGridValue): string;
|
|
1850
|
-
/** Accessible name for a row's own controls. */
|
|
1851
|
-
declare function recordGridRowLabel(columns: readonly RecordGridColumn[], row: RecordGridRow): string;
|
|
1852
|
-
/** Sum a numeric column over the rows that hold a number. Rows with no value
|
|
1853
|
-
* are absent from the sum, not zero — a total over three of five filled cells
|
|
1854
|
-
* is the total of what is on file. */
|
|
1855
|
-
declare function sumRecordGridColumn(rows: readonly RecordGridRow[], columnId: string): number;
|
|
1856
|
-
/**
|
|
1857
|
-
* Edits the grid has applied locally but the caller's `rows` prop has not yet
|
|
1858
|
-
* caught up with. Every field is what rollback removes: drop the entry and the
|
|
1859
|
-
* caller's own data shows through again.
|
|
1860
|
-
*/
|
|
1861
|
-
interface RecordGridOverlay {
|
|
1862
|
-
/** rowId → columnId → optimistic value. */
|
|
1863
|
-
updates: Readonly<Record<string, Readonly<Record<string, RecordGridValue>>>>;
|
|
1864
|
-
/** Rows created locally, in insertion order. */
|
|
1865
|
-
created: readonly RecordGridRow[];
|
|
1866
|
-
/** Row ids removed locally. */
|
|
1867
|
-
removed: readonly string[];
|
|
1868
|
-
}
|
|
1869
|
-
/** An overlay holding nothing. */
|
|
1870
|
-
declare const EMPTY_RECORD_GRID_OVERLAY: RecordGridOverlay;
|
|
1871
|
-
/** The rows to render: caller rows minus local deletes, with local cell edits
|
|
1872
|
-
* applied, then locally-created rows. */
|
|
1873
|
-
declare function projectRecordGridRows(rows: readonly RecordGridRow[], overlay: RecordGridOverlay): RecordGridRow[];
|
|
1874
|
-
/** Record one optimistic cell edit. */
|
|
1875
|
-
declare function withRecordGridUpdate(overlay: RecordGridOverlay, rowId: string, columnId: string, value: RecordGridValue): RecordGridOverlay;
|
|
1876
|
-
/** Take back one optimistic cell edit — the rollback path. */
|
|
1877
|
-
declare function withoutRecordGridUpdate(overlay: RecordGridOverlay, rowId: string, columnId: string): RecordGridOverlay;
|
|
1878
|
-
/** Adopt a row the writer returned as canonical: for a locally-created row it
|
|
1879
|
-
* replaces the draft; for an existing row it replaces the optimistic cells.
|
|
1880
|
-
* Either way the draft's pending cell edits go with it — the canonical row IS
|
|
1881
|
-
* the answer, and leaving an edit layered over it is how a grid keeps showing
|
|
1882
|
-
* a value the server normalized away. */
|
|
1883
|
-
declare function withRecordGridServerRow(overlay: RecordGridOverlay, draftId: string, row: RecordGridRow): RecordGridOverlay;
|
|
1884
|
-
/** Record an optimistic create. */
|
|
1885
|
-
declare function withRecordGridCreated(overlay: RecordGridOverlay, row: RecordGridRow): RecordGridOverlay;
|
|
1886
|
-
/** Take back an optimistic create — the rollback path. Cell edits made against
|
|
1887
|
-
* the draft go with it; the row they applied to no longer exists anywhere. */
|
|
1888
|
-
declare function withoutRecordGridCreated(overlay: RecordGridOverlay, rowId: string): RecordGridOverlay;
|
|
1889
|
-
/** Record an optimistic delete. */
|
|
1890
|
-
declare function withRecordGridRemoved(overlay: RecordGridOverlay, rowId: string): RecordGridOverlay;
|
|
1891
|
-
/** Take back an optimistic delete — the rollback path. */
|
|
1892
|
-
declare function withoutRecordGridRemoved(overlay: RecordGridOverlay, rowId: string): RecordGridOverlay;
|
|
1893
|
-
/**
|
|
1894
|
-
* Drop the overlay entries the caller's own rows have caught up with: a cell
|
|
1895
|
-
* whose value now matches, a created row now present, a removed row now gone.
|
|
1896
|
-
* Without this an overlay would mask every later refresh of the same cell.
|
|
1897
|
-
*
|
|
1898
|
-
* Returns the SAME overlay object when nothing settled, so a caller can prune
|
|
1899
|
-
* on every render without looping.
|
|
1900
|
-
*/
|
|
1901
|
-
declare function pruneRecordGridOverlay(rows: readonly RecordGridRow[], overlay: RecordGridOverlay): RecordGridOverlay;
|
|
1902
|
-
|
|
1903
|
-
/** One committed cell edit, handed to `onUpdate`. */
|
|
1904
|
-
interface RecordGridCellChange {
|
|
1905
|
-
/** The row as it was BEFORE the edit — what rollback restores. */
|
|
1906
|
-
row: RecordGridRow;
|
|
1907
|
-
columnId: string;
|
|
1908
|
-
value: RecordGridValue;
|
|
1909
|
-
/** The full value bag after the edit: what a whole-row write would send. */
|
|
1910
|
-
values: Readonly<Record<string, RecordGridValue>>;
|
|
1911
|
-
}
|
|
1912
|
-
/** Outcome of an update or a delete. `value` optionally carries the server's
|
|
1913
|
-
* canonical row, which replaces the optimistic one. */
|
|
1914
|
-
type RecordGridWriteOutcome = {
|
|
1915
|
-
succeeded: true;
|
|
1916
|
-
value?: RecordGridRow;
|
|
1917
|
-
} | {
|
|
1918
|
-
succeeded: false;
|
|
1919
|
-
error: string;
|
|
1920
|
-
};
|
|
1921
|
-
/** Outcome of a create. The row is REQUIRED on success: a create that does not
|
|
1922
|
-
* name the row it wrote leaves the grid unable to address it. */
|
|
1923
|
-
type RecordGridCreateOutcome = {
|
|
1924
|
-
succeeded: true;
|
|
1925
|
-
value: RecordGridRow;
|
|
1926
|
-
} | {
|
|
1927
|
-
succeeded: false;
|
|
1928
|
-
error: string;
|
|
1929
|
-
};
|
|
1930
|
-
/** Properties for the editable, provenance-aware record grid. */
|
|
1931
|
-
interface RecordGridProps {
|
|
1932
|
-
/** Column definitions, in render order. */
|
|
1933
|
-
columns: readonly RecordGridColumn[];
|
|
1934
|
-
/** Fetch state over the caller's rows — `web-react/async`'s
|
|
1935
|
-
* `AsyncResourceState`, the same three-state contract every other screen
|
|
1936
|
-
* in the shell fetches through. `ready`/`empty`'s value is the base rows;
|
|
1937
|
-
* optimistic edits are layered over it and dropped as a later value
|
|
1938
|
-
* catches up. `error` always carries `retry` — there is no way to render a
|
|
1939
|
-
* failed fetch with no recovery action, by construction. */
|
|
1940
|
-
state: AsyncResourceState<readonly RecordGridRow[]>;
|
|
1941
|
-
/** Accessible name for the grid. Required — an unnamed grid is unusable with
|
|
1942
|
-
* a screen reader. */
|
|
1943
|
-
caption: string;
|
|
1944
|
-
/** What the empty state says, and what it offers next — `web-react/async`'s
|
|
1945
|
-
* `AsyncEmptySpec`, so an empty grid reads in the same words as an empty
|
|
1946
|
-
* list or panel elsewhere in the product. */
|
|
1947
|
-
empty: AsyncEmptySpec;
|
|
1948
|
-
/** Persist one created row. Absent → no add affordance. */
|
|
1949
|
-
onCreate?: (values: Readonly<Record<string, RecordGridValue>>) => Promise<RecordGridCreateOutcome>;
|
|
1950
|
-
/** Persist one cell edit. Absent → every cell renders read-only. */
|
|
1951
|
-
onUpdate?: (change: RecordGridCellChange) => Promise<RecordGridWriteOutcome>;
|
|
1952
|
-
/** Delete one row. Absent → no delete affordance. */
|
|
1953
|
-
onDelete?: (row: RecordGridRow) => Promise<RecordGridWriteOutcome>;
|
|
1954
|
-
/** Starting values for the add form. */
|
|
1955
|
-
newRowDefaults?: Readonly<Record<string, RecordGridValue>>;
|
|
1956
|
-
/** Label of the add control and of the add form. Defaults to `Add row`. */
|
|
1957
|
-
addLabel?: string;
|
|
1958
|
-
/** BCP-47 locale for number, currency, and date display. */
|
|
1959
|
-
locale?: string;
|
|
1960
|
-
/** Rendered above the grid — filters, counts, a product action row. */
|
|
1961
|
-
toolbar?: ReactNode;
|
|
1962
|
-
/** Skeleton rows in the loading state. Defaults to 3. */
|
|
1963
|
-
loadingRowCount?: number;
|
|
1964
|
-
className?: string;
|
|
1965
|
-
}
|
|
1966
|
-
/**
|
|
1967
|
-
* The shared editable record table. A row is a flat value bag keyed by column
|
|
1968
|
-
* id, so a record store's fold output maps straight on: one cell per entry,
|
|
1969
|
-
* its quote and link in `sources`.
|
|
1970
|
-
*/
|
|
1971
|
-
declare function RecordGrid({ columns, caption, state, empty, onCreate, onUpdate, onDelete, newRowDefaults, addLabel, locale, toolbar, loadingRowCount, className, }: RecordGridProps): react.JSX.Element;
|
|
1972
|
-
|
|
1973
|
-
/**
|
|
1974
|
-
* `Sparkline` — the series behind a number, as inline SVG.
|
|
1975
|
-
*
|
|
1976
|
-
* `/spend`, `/missions` and the eval lanes all produce a number for today, and
|
|
1977
|
-
* every product renders it as text. Text cannot separate "$41, up from $38"
|
|
1978
|
-
* from "$41, up from $4" — the same sentence, two different situations — so the
|
|
1979
|
-
* reader opens a second surface to find out which one they are in. The series
|
|
1980
|
-
* next to the number answers it in one glance.
|
|
1981
|
-
*
|
|
1982
|
-
* No chart dependency: this subpath is react + `@tangle-network/ui` only, and a
|
|
1983
|
-
* polyline is not worth a bundle. What a chart library would give us here is
|
|
1984
|
-
* axes, ticks and a tooltip, none of which belong on a 96×24 glyph.
|
|
1985
|
-
*
|
|
1986
|
-
* The three shapes a hand-rolled sparkline gets wrong, each handled here rather
|
|
1987
|
-
* than left to the caller:
|
|
1988
|
-
*
|
|
1989
|
-
* - **no readings** renders an explicit empty label, never a line. A line
|
|
1990
|
-
* along the baseline is a claim — "this metric sat at zero" — and a series
|
|
1991
|
-
* nobody has measured yet did not sit anywhere.
|
|
1992
|
-
* - **one reading** renders a point. A line needs two coordinates; drawing one
|
|
1993
|
-
* from a single reading invents the segment before it.
|
|
1994
|
-
* - **equal readings** render flat at MID height. The obvious normalisation
|
|
1995
|
-
* divides by `max - min`, which is `0` for a perfectly stable metric, and
|
|
1996
|
-
* the resulting `NaN` lands in the `points` attribute — SVG drops the whole
|
|
1997
|
-
* polyline, so the metric that never moved is the one that disappears.
|
|
1998
|
-
* - **a missing reading renders as a GAP, and the accessible name says so.**
|
|
1999
|
-
* A `null` from a hole in a series and a `NaN` from a producer's unguarded
|
|
2000
|
-
* division are not smaller series — they are readings nobody has. Deleting
|
|
2001
|
-
* them closed the line straight across the hole and announced a count that
|
|
2002
|
-
* was short by the number deleted: measured on `[1, NaN, 3]`, one continuous
|
|
2003
|
-
* two-point line labelled "2 readings, rising from 1 to 3", with nothing
|
|
2004
|
-
* anywhere saying a reading was unreadable. The card's figure slot already
|
|
2005
|
-
* refuses to let a non-measurement look measured; the series one line below
|
|
2006
|
-
* it holds the same rule. The x axis is the SAMPLE index, so the hole keeps
|
|
2007
|
-
* its width, the line breaks at it, and the label carries "N not available".
|
|
2008
|
-
*
|
|
2009
|
-
* Accessibility: `role="img"` with an `aria-label` naming the metric, its range
|
|
2010
|
-
* and its direction. A sparkline with no accessible name is decoration a screen
|
|
2011
|
-
* reader cannot report, which would leave the shape — the entire reason the
|
|
2012
|
-
* component exists — visible to exactly one kind of reader.
|
|
2013
|
-
*
|
|
2014
|
-
* Deliberately not animated. `docs/product-surfaces.md` Pattern 4 lists chart
|
|
2015
|
-
* draw-on under what this package does not animate: the shape IS the answer,
|
|
2016
|
-
* and easing it in taxes every read of a surface people sit in for hours. The
|
|
2017
|
-
* card around it arrives (`.agent-arrive`); the line does not draw itself.
|
|
2018
|
-
*/
|
|
2019
|
-
|
|
2020
|
-
/** Where a series ended relative to where it started. */
|
|
2021
|
-
type SparklineDirection = 'rising' | 'falling' | 'flat';
|
|
2022
|
-
interface SparklinePoint {
|
|
2023
|
-
readonly x: number;
|
|
2024
|
-
readonly y: number;
|
|
2025
|
-
}
|
|
2026
|
-
interface SparklineGeometry {
|
|
2027
|
-
/** The finite readings, in order — what was actually plotted. */
|
|
2028
|
-
readonly readings: readonly number[];
|
|
2029
|
-
/** Every plotted point, in order. Positions are on the SAMPLE axis, so a
|
|
2030
|
-
* missing reading leaves its width behind rather than closing up. */
|
|
2031
|
-
readonly points: readonly SparklinePoint[];
|
|
2032
|
-
/** The points split into runs of CONSECUTIVE samples. One run is one stroke:
|
|
2033
|
-
* a line drawn across a missing reading states a movement nobody measured. */
|
|
2034
|
-
readonly segments: readonly (readonly SparklinePoint[])[];
|
|
2035
|
-
/** Samples that carried no usable reading — a `null`, a `NaN`, an infinity.
|
|
2036
|
-
* Counted rather than discarded, because the accessible name has to state
|
|
2037
|
-
* them: a shorter series announced as a complete one is the silent loss. */
|
|
2038
|
-
readonly gaps: number;
|
|
2039
|
-
readonly min: number;
|
|
2040
|
-
readonly max: number;
|
|
2041
|
-
readonly first: number;
|
|
2042
|
-
readonly last: number;
|
|
2043
|
-
readonly direction: SparklineDirection;
|
|
2044
|
-
}
|
|
2045
|
-
interface SparklineGeometryOptions {
|
|
2046
|
-
width?: number;
|
|
2047
|
-
height?: number;
|
|
2048
|
-
/** Keeps the stroke and the end dot inside the viewBox instead of clipping
|
|
2049
|
-
* them at the extremes, where the interesting readings always are. */
|
|
2050
|
-
inset?: number;
|
|
2051
|
-
}
|
|
2052
|
-
declare const DEFAULT_SPARKLINE_WIDTH = 96;
|
|
2053
|
-
declare const DEFAULT_SPARKLINE_HEIGHT = 24;
|
|
2054
|
-
/** Only a name, never a metric: it exists so the accessible label is never
|
|
2055
|
-
* empty. Every caller in this package passes the metric's own title. */
|
|
2056
|
-
declare const DEFAULT_SPARKLINE_LABEL = "Trend";
|
|
2057
|
-
declare const DEFAULT_SPARKLINE_EMPTY_LABEL = "No history yet";
|
|
2058
|
-
/** Nothing was measurable, which is not the same as nothing was measured yet —
|
|
2059
|
-
* and "No history yet" over a series that arrived full of `NaN` reads as the
|
|
2060
|
-
* metric being new when the producer is broken. */
|
|
2061
|
-
declare const DEFAULT_SPARKLINE_UNAVAILABLE_LABEL = "No readings available";
|
|
2062
|
-
/** The package's default number rendering, pinned to `en-US` so a card and its
|
|
2063
|
-
* series read the same on every host — a series formatted by the server's
|
|
2064
|
-
* locale and a value formatted by the browser's is a defect nobody sees until
|
|
2065
|
-
* the decimal separators disagree. */
|
|
2066
|
-
declare function formatSparklineValue(value: number): string;
|
|
2067
|
-
/**
|
|
2068
|
-
* The readings that can be plotted.
|
|
2069
|
-
*
|
|
2070
|
-
* A `null` from a gap in a series, or a `NaN` from a division a producer did
|
|
2071
|
-
* not guard, is not plotted rather than coerced to `0`: plotting a missing
|
|
2072
|
-
* reading at the baseline draws a cliff that never happened.
|
|
2073
|
-
*
|
|
2074
|
-
* This returns the readings ALONE, so it cannot tell a caller how many are
|
|
2075
|
-
* missing. That is what {@link SparklineGeometry.gaps} is for, and what the
|
|
2076
|
-
* accessible name reports — dropping a sample and then announcing the shorter
|
|
2077
|
-
* count as the whole series is the defect, not the filter.
|
|
2078
|
-
*/
|
|
2079
|
-
declare function sparklineReadings(values: readonly number[]): number[];
|
|
2080
|
-
/**
|
|
2081
|
-
* Plots the series into the viewBox.
|
|
2082
|
-
*
|
|
2083
|
-
* Pure and exported so the cases that produce a broken chart — nothing, one
|
|
2084
|
-
* reading, a flat series, negatives — are unit-testable without a DOM.
|
|
2085
|
-
*/
|
|
2086
|
-
declare function sparklineGeometry(values: readonly number[], { width, height, inset }?: SparklineGeometryOptions): SparklineGeometry;
|
|
2087
|
-
/** `"2,14 48,3 94,21"` — the `points` attribute of the polyline. */
|
|
2088
|
-
declare function sparklinePointsAttribute(points: readonly SparklinePoint[]): string;
|
|
2089
|
-
interface SparklineLabelOptions {
|
|
2090
|
-
label?: string;
|
|
2091
|
-
format?: (value: number) => string;
|
|
2092
|
-
}
|
|
2093
|
-
/**
|
|
2094
|
-
* The accessible name: metric, how many readings, how many are missing, the
|
|
2095
|
-
* range, and the direction.
|
|
2096
|
-
*
|
|
2097
|
-
* All of it is load-bearing. The range without the direction describes a shape
|
|
2098
|
-
* that could have been walked in either order; the direction without the range
|
|
2099
|
-
* says "rising" about a metric that moved by a rounding error; and the count
|
|
2100
|
-
* without the gaps is the number of readings that SURVIVED announced as the
|
|
2101
|
-
* number that were taken — the shape a reader cannot see is exactly the one
|
|
2102
|
-
* this sentence exists to carry.
|
|
2103
|
-
*/
|
|
2104
|
-
declare function sparklineLabel(values: readonly number[], { label, format }?: SparklineLabelOptions): string;
|
|
2105
|
-
interface SparklineProps {
|
|
2106
|
-
values: readonly number[];
|
|
2107
|
-
/** Names the metric in the accessible label. */
|
|
2108
|
-
label?: string;
|
|
2109
|
-
/** Renders a reading in that label; defaults to the package number format. */
|
|
2110
|
-
format?: (value: number) => string;
|
|
2111
|
-
width?: number;
|
|
2112
|
-
height?: number;
|
|
2113
|
-
/** Shown instead of a line when the metric has no history yet. */
|
|
2114
|
-
emptyLabel?: string;
|
|
2115
|
-
/** Shown instead of a line when every sample arrived unreadable — a different
|
|
2116
|
-
* state from "no history yet", and one the reader has to be able to tell
|
|
2117
|
-
* apart, because one is a new metric and the other is a broken producer. */
|
|
2118
|
-
unavailableLabel?: string;
|
|
2119
|
-
className?: string;
|
|
2120
|
-
}
|
|
2121
|
-
/** The series glyph. Strokes in `currentColor`, so tone is the caller's. */
|
|
2122
|
-
declare function Sparkline({ values, label, format, width, height, emptyLabel, unavailableLabel, className, }: SparklineProps): ReactElement;
|
|
2123
|
-
|
|
2124
|
-
/**
|
|
2125
|
-
* `InsightCard` + `InsightDeck` — the number that moved, and the paged deck of
|
|
2126
|
-
* them.
|
|
2127
|
-
*
|
|
2128
|
-
* Every product on this shell computes insights already: `/spend` knows today's
|
|
2129
|
-
* burn against yesterday's, `/missions` knows how many runs landed, the eval
|
|
2130
|
-
* lanes know a pass rate per release. All of it renders as a line of text, so
|
|
2131
|
-
* the reader does the comparison in their head and the series behind the number
|
|
2132
|
-
* never reaches the screen at all.
|
|
2133
|
-
*
|
|
2134
|
-
* Two rules this surface exists to hold:
|
|
2135
|
-
*
|
|
2136
|
-
* - **A delta needs a baseline.** `previous` absent means no delta is drawn —
|
|
2137
|
-
* not a green `+0%`, which is the specific fabrication a hand-rolled card
|
|
2138
|
-
* produces when it defaults its baseline to zero, and which reads as "we
|
|
2139
|
-
* measured, nothing changed" when the truth is "we have nothing to compare
|
|
2140
|
-
* against". {@link insightDelta} returns `null` rather than a zero.
|
|
2141
|
-
* - **Direction is not sentiment.** Spend going up and missions going up are
|
|
2142
|
-
* the same arrow and opposite news, so tone is a caller declaration
|
|
2143
|
-
* (`polarity`), and the default is neutral. A card that paints every rise
|
|
2144
|
-
* green teaches the reader to stop reading the label.
|
|
2145
|
-
*
|
|
2146
|
-
* The deck is built on `web-react/async` rather than a loading boolean, so it
|
|
2147
|
-
* inherits that module's invariant instead of restating it: `AsyncView` renders
|
|
2148
|
-
* `error` with its message and retry, and `empty` is reachable only from a load
|
|
2149
|
-
* that resolved — a failed fetch can never paint "No insights yet"
|
|
2150
|
-
* (`docs/async-state-module.md`).
|
|
2151
|
-
*
|
|
2152
|
-
* Motion: cards arrive with `.agent-arrive`, staggered by `--stagger-index`
|
|
2153
|
-
* from the deck, and a page TURN remounts them so the next page arrives as a
|
|
2154
|
-
* sequence instead of swapping text under cards that never moved. A REFRESH is
|
|
2155
|
-
* the opposite case and gets the opposite treatment — see the deck's own note.
|
|
2156
|
-
* Every piece of that is decoration, carries no `data-motion`, and collapses
|
|
2157
|
-
* under `prefers-reduced-motion` — the live label included.
|
|
2158
|
-
*
|
|
2159
|
-
* The live label does NOT opt out, and the reasoning is worth stating because
|
|
2160
|
-
* the opposite reads plausible. What tells the reader a figure is still being
|
|
2161
|
-
* computed is the WORD (`liveLabel`, "Updating"): it is rendered only while
|
|
2162
|
-
* `live`, and a settled card does not render it at all. The sweep through its
|
|
2163
|
-
* glyphs is emphasis on a signal that is already there, not the signal. So a
|
|
2164
|
-
* reader who asked for less motion still sees the word — static, in the
|
|
2165
|
-
* shimmer's resting gradient, still legible, and still disappearing the moment
|
|
2166
|
-
* the figure is final. Nothing here overrides a request the reader made.
|
|
2167
|
-
*/
|
|
2168
|
-
|
|
2169
|
-
type InsightDirection = 'up' | 'down' | 'flat';
|
|
2170
|
-
/** Which way is good news for THIS metric. `neutral` is the default because it
|
|
2171
|
-
* is the only answer that is true for every metric. */
|
|
2172
|
-
type InsightPolarity = 'higher-is-better' | 'lower-is-better' | 'neutral';
|
|
2173
|
-
type InsightTone = 'positive' | 'negative' | 'neutral';
|
|
2174
|
-
interface InsightDelta {
|
|
2175
|
-
/** The baseline the move is measured against — rendered, so the delta is
|
|
2176
|
-
* never a number floating free of what produced it. */
|
|
2177
|
-
readonly previous: number;
|
|
2178
|
-
readonly absolute: number;
|
|
2179
|
-
/** `null` when the baseline is `0`: a share of nothing is undefined, and
|
|
2180
|
-
* "+∞%" or a silently-dropped percentage are both worse than the absolute. */
|
|
2181
|
-
readonly percent: number | null;
|
|
2182
|
-
readonly direction: InsightDirection;
|
|
2183
|
-
}
|
|
2184
|
-
/**
|
|
2185
|
-
* The move, or `null` when there is no honest one to state.
|
|
2186
|
-
*
|
|
2187
|
-
* `unknown` inputs on purpose: these arrive from a fetched payload, and the
|
|
2188
|
-
* cases that must not produce a delta — a missing baseline, a `null` from a
|
|
2189
|
-
* first-ever reading, a `NaN` from a producer's division — are exactly the ones
|
|
2190
|
-
* a narrower signature would let through as `0`.
|
|
2191
|
-
*/
|
|
2192
|
-
declare function insightDelta(value: unknown, previous: unknown): InsightDelta | null;
|
|
2193
|
-
/** Maps a direction onto good/bad news, which only the caller knows. */
|
|
2194
|
-
declare function insightDeltaTone(direction: InsightDirection, polarity?: InsightPolarity): InsightTone;
|
|
2195
|
-
/**
|
|
2196
|
-
* The delta as words: direction, magnitude, and the baseline it is measured
|
|
2197
|
-
* against. Words rather than an arrow plus a bare number, because the arrow is
|
|
2198
|
-
* `aria-hidden` and a reader hearing "12%" learns nothing about which way.
|
|
2199
|
-
*/
|
|
2200
|
-
declare function formatInsightDelta(delta: InsightDelta, format?: (value: number) => string): string;
|
|
2201
|
-
interface InsightAction {
|
|
2202
|
-
label: string;
|
|
2203
|
-
onClick: () => void;
|
|
2204
|
-
}
|
|
2205
|
-
interface InsightCardProps {
|
|
2206
|
-
/** What was measured, in the reader's words ("Spend today"). */
|
|
2207
|
-
title: string;
|
|
2208
|
-
/** The number that moved. A `string` renders verbatim — a total the caller
|
|
2209
|
-
* already formatted with its own currency — and takes no delta, because
|
|
2210
|
-
* there is nothing to subtract. A non-finite number is not a measurement and
|
|
2211
|
-
* renders as {@link INSIGHT_UNAVAILABLE_GLYPH}, never as "NaN" or "∞". */
|
|
2212
|
-
value: number | string;
|
|
2213
|
-
/** "USD", "runs", "%" — the unit the number is in, beside it rather than
|
|
2214
|
-
* glued into it, so the figure stays scannable. */
|
|
2215
|
-
unit?: string;
|
|
2216
|
-
/** The baseline. Absent ⇒ the card renders the value and no delta. */
|
|
2217
|
-
previous?: number;
|
|
2218
|
-
polarity?: InsightPolarity;
|
|
2219
|
-
/** One number format for the value, the delta and the series, so the three
|
|
2220
|
-
* cannot disagree about decimals on the same card. */
|
|
2221
|
-
format?: (value: number) => string;
|
|
2222
|
-
series?: readonly number[];
|
|
2223
|
-
/** Names the series in its accessible label; defaults to the card's title. */
|
|
2224
|
-
seriesLabel?: string;
|
|
2225
|
-
/** One line of context under the number — what the window is, what is
|
|
2226
|
-
* excluded. Not a restatement of the title. */
|
|
2227
|
-
description?: string;
|
|
2228
|
-
/** The next action for this insight. An element renders as supplied (a link,
|
|
2229
|
-
* a dialog trigger); the object form renders the standard button. */
|
|
2230
|
-
action?: InsightAction | ReactElement;
|
|
2231
|
-
/** The number is still being computed. The label's PRESENCE is the signal, so
|
|
2232
|
-
* it reads the same with motion collapsed — see the module note. */
|
|
2233
|
-
live?: boolean;
|
|
2234
|
-
liveLabel?: string;
|
|
2235
|
-
className?: string;
|
|
2236
|
-
style?: CSSProperties;
|
|
2237
|
-
}
|
|
2238
|
-
declare function InsightCard({ title, value, unit, previous, polarity, format, series, seriesLabel, description, action, live, liveLabel, className, style, }: InsightCardProps): ReactElement;
|
|
2239
|
-
interface Insight extends InsightCardProps {
|
|
2240
|
-
/** Stable across refreshes: it keys the card. Paired with the deck holding
|
|
2241
|
-
* the last loaded page across a reload, a stable id is what lets a settled
|
|
2242
|
-
* card keep its own DOM node — and therefore not replay its arrival — when
|
|
2243
|
-
* a poll returns the same insight. */
|
|
2244
|
-
readonly id: string;
|
|
2245
|
-
}
|
|
2246
|
-
declare const DEFAULT_INSIGHT_PAGE_SIZE = 3;
|
|
2247
|
-
/**
|
|
2248
|
-
* The page size — ONE definition, read by the count and by the slice.
|
|
2249
|
-
*
|
|
2250
|
-
* Two definitions is how a deck hides an insight with no error at all: a count
|
|
2251
|
-
* that divides by the raw `2.5` claims two pages of a five-card deck, a slice
|
|
2252
|
-
* that floors it puts two cards on each, and the fifth card is on no page the
|
|
2253
|
-
* reader can reach. Nothing renders wrong; a card is simply gone.
|
|
2254
|
-
*
|
|
2255
|
-
* A page size is a count of cards, so a fraction, a zero and a negative are not
|
|
2256
|
-
* smaller decks — they are caller mistakes, and this normalises them back to the
|
|
2257
|
-
* default and says so once per offending value. Normalised rather than thrown
|
|
2258
|
-
* because the value is often computed from a measured viewport, where the first
|
|
2259
|
-
* paint legitimately produces a `0`: a deck that pages in threes is a far
|
|
2260
|
-
* smaller failure than a dashboard that throws during render.
|
|
2261
|
-
*/
|
|
2262
|
-
declare function insightPageSize(pageSize?: number): number;
|
|
2263
|
-
/** Always at least one page, so "Page 1 of 0" cannot be rendered. */
|
|
2264
|
-
declare function insightPageCount(total: number, pageSize?: number): number;
|
|
2265
|
-
/** The items on `page`, with the page clamped into range — a deck whose list
|
|
2266
|
-
* shrank under the reader shows the last page that exists, never a blank one. */
|
|
2267
|
-
declare function insightPageSlice<T>(items: readonly T[], page: number, pageSize?: number): readonly T[];
|
|
2268
|
-
interface InsightDeckProps {
|
|
2269
|
-
/** The same five-state contract every other screen fetches through. */
|
|
2270
|
-
state: AsyncResourceState<readonly Insight[]>;
|
|
2271
|
-
/** Required by `AsyncView`: an empty deck must say what is missing and what
|
|
2272
|
-
* to do about it. */
|
|
2273
|
-
empty: AsyncEmptySpec | ReactElement;
|
|
2274
|
-
/** Names the region for assistive tech and titles nothing visually — the
|
|
2275
|
-
* cards carry their own headings. */
|
|
2276
|
-
label?: string;
|
|
2277
|
-
pageSize?: number;
|
|
2278
|
-
loadingLabel?: string;
|
|
2279
|
-
retryLabel?: string;
|
|
2280
|
-
className?: string;
|
|
2281
|
-
/**
|
|
2282
|
-
* The page the reader is ON, whatever moved them there.
|
|
2283
|
-
*
|
|
2284
|
-
* That includes the render-time clamp: a list that shrinks under a reader
|
|
2285
|
-
* standing on page 3 leaves them on the last page that exists, and a parent
|
|
2286
|
-
* persisting this to a URL or to storage would otherwise keep writing a page
|
|
2287
|
-
* number nothing can reach. Reported once per effective page, never twice for
|
|
2288
|
-
* the same one.
|
|
2289
|
-
*/
|
|
2290
|
-
onPageChange?: (page: number) => void;
|
|
2291
|
-
}
|
|
2292
|
-
/**
|
|
2293
|
-
* The paged deck.
|
|
2294
|
-
*
|
|
2295
|
-
* `AsyncView` owns the non-`ready` branches, which is what makes the invariant
|
|
2296
|
-
* structural here: the cards are rendered from one branch of that component,
|
|
2297
|
-
* and no branch of this one could paint the empty copy over a failure.
|
|
2298
|
-
*
|
|
2299
|
-
* **A REFRESH DOES NOT REPLACE WHAT IS ON SCREEN.** `useAsyncResource` re-enters
|
|
2300
|
-
* `loading` with no value held on every reload, and handing that straight to
|
|
2301
|
-
* `AsyncView` swaps the ready subtree for the busy block — which destroys the
|
|
2302
|
-
* DOM the reader is standing in. Measured, on a real reload: `document.
|
|
2303
|
-
* activeElement` fell to `document.body`, so a keyboard reader mid-page lost
|
|
2304
|
-
* their place on every automatic poll; and every settled card was a NEW node, so
|
|
2305
|
-
* `.agent-arrive` replayed across the whole visible page — the exact flash this
|
|
2306
|
-
* surface's motion rules exist to prevent. Holding the page NUMBER above the
|
|
2307
|
-
* boundary fixed the counter and none of that, because the subtree under it was
|
|
2308
|
-
* still being torn down.
|
|
2309
|
-
*
|
|
2310
|
-
* So the deck holds the last insights it rendered and keeps handing them to the
|
|
2311
|
-
* SAME `AsyncView` branch while a reload is in flight: same element, same
|
|
2312
|
-
* position, same keys — React reuses the nodes, focus stays where the reader put
|
|
2313
|
-
* it, and nothing re-animates. `aria-busy` on the region is the signal that a
|
|
2314
|
-
* load is in flight; a per-card one is `live` on the card.
|
|
2315
|
-
*
|
|
2316
|
-
* The bridge is only ever over a WAIT. `error` and `empty` are answers about the
|
|
2317
|
-
* resource, so they drop what was held and render their own branch — a failed
|
|
2318
|
-
* fetch still cannot paint stale numbers, and the async module's invariant is
|
|
2319
|
-
* untouched.
|
|
2320
|
-
*
|
|
2321
|
-
* It bridges one resource, not one component: if the SUBJECT changes (a
|
|
2322
|
-
* different workspace, a different window), give the deck a `key` so it remounts
|
|
2323
|
-
* rather than showing the previous subject's numbers while the new ones load.
|
|
2324
|
-
*/
|
|
2325
|
-
declare function InsightDeck({ state, empty, label, pageSize, loadingLabel, retryLabel, className, onPageChange, }: InsightDeckProps): ReactElement;
|
|
2326
|
-
|
|
2
|
+
* `@tangle-network/agent-app/web-react` — the shared chat-shell components
|
|
3
|
+
* every agent app's web UI hand-rolls: a model picker over the runtime's
|
|
4
|
+
* model catalogue, a reasoning-effort selector, and a message thread with
|
|
5
|
+
* User/Agent identity, per-message model + cost + tokens/sec metrics,
|
|
6
|
+
* canonical tool rows, and a collapsible thinking section.
|
|
7
|
+
*
|
|
8
|
+
* Works for BOTH chat shapes: router-backed copilots (LoopEvents from
|
|
9
|
+
* `runtime/openai-stream`) and sandbox-backed chats — the thread renders
|
|
10
|
+
* `ChatUiMessage`s; how they're produced is the app's business.
|
|
11
|
+
*
|
|
12
|
+
* Styling contract: Tailwind classes against the shared design tokens
|
|
13
|
+
* (`bg-card`, `border-border`, `text-muted-foreground`, `bg-primary`, …) that
|
|
14
|
+
* Tangle app shells define. No icon library of its own — the few local glyphs
|
|
15
|
+
* are inline SVGs. Markdown and provider logos are injected (`renderMarkdown`,
|
|
16
|
+
* `renderProviderBadge`).
|
|
17
|
+
*
|
|
18
|
+
* Tool rows compose the canonical run-row grammar from `@tangle-network/ui`
|
|
19
|
+
* (`InlineToolItem` over `RunRowShell`): `chatToolCallPart` adapts each
|
|
20
|
+
* `ChatToolCallInfo` to ui's `ToolPart` (the same adapter pattern ui's own
|
|
21
|
+
* `ToolCallStep` uses), so the chat surface and every other Tangle run view
|
|
22
|
+
* share one row implementation instead of drifting. That makes
|
|
23
|
+
* `@tangle-network/ui` a peer of this subpath.
|
|
24
|
+
*/
|
|
25
|
+
import { type ReactNode } from 'react';
|
|
26
|
+
import type { ToolPart } from '@tangle-network/ui/types';
|
|
27
|
+
import { type DurableChatCardsProps } from './durable-chat-cards';
|
|
28
|
+
import { type ChatAttachmentPart } from './chat-attachments';
|
|
29
|
+
import type { WorkProductPersistedPart } from '../work-product/types';
|
|
30
|
+
export * from './chat-stream';
|
|
31
|
+
export * from './chat-interactions';
|
|
32
|
+
export * from './chat-composer';
|
|
33
|
+
export * from './interaction-card-support';
|
|
34
|
+
export * from './interaction-question-card';
|
|
35
|
+
export * from './interaction-plan-card';
|
|
36
|
+
export * from './durable-plan-flow';
|
|
37
|
+
export * from './durable-plan-card';
|
|
38
|
+
export * from './durable-chat-cards';
|
|
39
|
+
export * from './durable-interaction-submit';
|
|
40
|
+
export * from './use-chat-interactions';
|
|
41
|
+
export * from './use-file-mentions';
|
|
42
|
+
export * from './chat-mentions';
|
|
43
|
+
export * from './chat-attachments';
|
|
44
|
+
export * from './message-attachments';
|
|
45
|
+
export * from './use-composer-attachments';
|
|
46
|
+
export * from './provider-logo';
|
|
47
|
+
export * from './harness-glyphs';
|
|
48
|
+
export * from './smooth-text';
|
|
49
|
+
export * from './mission-activity';
|
|
50
|
+
export * from './work-product';
|
|
51
|
+
export * from './provenance';
|
|
52
|
+
export * from './sandbox-terminal';
|
|
53
|
+
export * from './seat-paywall';
|
|
54
|
+
export * from './session-history';
|
|
55
|
+
export * from './record-grid';
|
|
56
|
+
export * from './sparkline';
|
|
57
|
+
export * from './insight-card';
|
|
58
|
+
export { usePopover, usePending, PopoverSurface, POPOVER_SURFACE_ATTR, ModelPicker, EffortPicker, EffortMeter, effortMeterFill, effortLevelLabel, effortLevelsFromIds, reconcileEffortLevels, DEFAULT_EFFORT_LEVELS, EFFORT_METER_SEGMENTS, OVERLAY_SHADOW, type ModelPickerProps, type EffortPickerProps, type EffortLevel, type PopoverSurfaceProps, } from './controls';
|
|
59
|
+
export { AgentSessionControls, type AgentSessionControlsProps, } from './agent-session-controls';
|
|
60
|
+
import type { CatalogModel } from '../runtime/model-catalog';
|
|
61
|
+
export type { CatalogModel } from '../runtime/model-catalog';
|
|
2327
62
|
/** Describe metrics related to a chat message including model, token counts, and duration */
|
|
2328
|
-
interface ChatMessageMetrics {
|
|
63
|
+
export interface ChatMessageMetrics {
|
|
2329
64
|
modelUsed?: string;
|
|
2330
65
|
promptTokens?: number;
|
|
2331
66
|
completionTokens?: number;
|
|
2332
67
|
durationMs?: number;
|
|
2333
68
|
}
|
|
2334
69
|
/** "$0.0042" from token counts × catalogue per-token pricing; null when unknown. */
|
|
2335
|
-
declare function formatModelCost(msg: ChatMessageMetrics, models: CatalogModel[]): string | null;
|
|
70
|
+
export declare function formatModelCost(msg: ChatMessageMetrics, models: CatalogModel[]): string | null;
|
|
2336
71
|
/** "38 tok/s" from completion tokens over first-token→end duration; null when unknown. */
|
|
2337
|
-
declare function formatTokensPerSecond(msg: ChatMessageMetrics): string | null;
|
|
72
|
+
export declare function formatTokensPerSecond(msg: ChatMessageMetrics): string | null;
|
|
2338
73
|
/** One step of a retained tool run (e.g. a sandbox command + its output). */
|
|
2339
|
-
interface ToolRunStep {
|
|
74
|
+
export interface ToolRunStep {
|
|
2340
75
|
at: string;
|
|
2341
76
|
label: string;
|
|
2342
77
|
detail?: string;
|
|
@@ -2345,7 +80,7 @@ interface ToolRunStep {
|
|
|
2345
80
|
/** A retained tool run keyed by the parent message's toolCallId. The product
|
|
2346
81
|
* persists these server-side (fail-closed: only ids its own loop created)
|
|
2347
82
|
* and serves them to the drill-in panel. */
|
|
2348
|
-
interface ToolRunRecord {
|
|
83
|
+
export interface ToolRunRecord {
|
|
2349
84
|
toolCallId: string;
|
|
2350
85
|
toolName: string;
|
|
2351
86
|
title: string;
|
|
@@ -2353,7 +88,7 @@ interface ToolRunRecord {
|
|
|
2353
88
|
steps: ToolRunStep[];
|
|
2354
89
|
}
|
|
2355
90
|
/** Define properties required to run a drill and handle its closure event */
|
|
2356
|
-
interface RunDrillInProps {
|
|
91
|
+
export interface RunDrillInProps {
|
|
2357
92
|
run: ToolRunRecord;
|
|
2358
93
|
onClose: () => void;
|
|
2359
94
|
}
|
|
@@ -2362,9 +97,9 @@ interface RunDrillInProps {
|
|
|
2362
97
|
* "drill into what the sandbox actually did" view. Follow-ups happen in the
|
|
2363
98
|
* main chat, never here.
|
|
2364
99
|
*/
|
|
2365
|
-
declare function RunDrillIn({ run, onClose }: RunDrillInProps): react.JSX.Element;
|
|
100
|
+
export declare function RunDrillIn({ run, onClose }: RunDrillInProps): import("react").JSX.Element;
|
|
2366
101
|
/** Describe the structure and state of a tool call within a chat interaction */
|
|
2367
|
-
interface ChatToolCallInfo {
|
|
102
|
+
export interface ChatToolCallInfo {
|
|
2368
103
|
id: string;
|
|
2369
104
|
name: string;
|
|
2370
105
|
status: 'running' | 'done' | 'error';
|
|
@@ -2377,7 +112,7 @@ interface ChatToolCallInfo {
|
|
|
2377
112
|
}
|
|
2378
113
|
/** Extract `{proposalId, status}` from a tool outcome when it is a proposal
|
|
2379
114
|
* awaiting human approval; null otherwise. */
|
|
2380
|
-
declare function pendingApprovalOf(call: ChatToolCallInfo): {
|
|
115
|
+
export declare function pendingApprovalOf(call: ChatToolCallInfo): {
|
|
2381
116
|
proposalId: string;
|
|
2382
117
|
} | null;
|
|
2383
118
|
/** One ordered piece of an assistant turn: a run of answer text, or a tool
|
|
@@ -2385,7 +120,7 @@ declare function pendingApprovalOf(call: ChatToolCallInfo): {
|
|
|
2385
120
|
* is rendered in order — interleaving text and tool rows — so the agent's
|
|
2386
121
|
* pre- and post-tool reasoning reads chronologically instead of as one text
|
|
2387
122
|
* blob with the tool rows collected after it. */
|
|
2388
|
-
type ChatMessageSegment = {
|
|
123
|
+
export type ChatMessageSegment = {
|
|
2389
124
|
kind: 'text';
|
|
2390
125
|
content: string;
|
|
2391
126
|
} | {
|
|
@@ -2393,7 +128,7 @@ type ChatMessageSegment = {
|
|
|
2393
128
|
call: ChatToolCallInfo;
|
|
2394
129
|
};
|
|
2395
130
|
/** Describe the structure and properties of a chat message with roles, content, and optional metadata */
|
|
2396
|
-
interface ChatUiMessage extends ChatMessageMetrics {
|
|
131
|
+
export interface ChatUiMessage extends ChatMessageMetrics {
|
|
2397
132
|
id: string;
|
|
2398
133
|
role: 'user' | 'assistant' | 'system';
|
|
2399
134
|
content: string;
|
|
@@ -2408,7 +143,7 @@ interface ChatUiMessage extends ChatMessageMetrics {
|
|
|
2408
143
|
parts?: Array<Record<string, unknown>>;
|
|
2409
144
|
}
|
|
2410
145
|
/** Define properties for rendering chat messages with optional models, markdown, extras, and durable cards */
|
|
2411
|
-
interface ChatMessagesProps {
|
|
146
|
+
export interface ChatMessagesProps {
|
|
2412
147
|
messages: ChatUiMessage[];
|
|
2413
148
|
/** Shared reading scale for both user and assistant prose. Defaults to 16px
|
|
2414
149
|
* at a 1.6 line height; `large` uses 17px at the same leading without
|
|
@@ -2477,7 +212,7 @@ interface ChatMessagesProps {
|
|
|
2477
212
|
}
|
|
2478
213
|
/** One starting "door" in the chat first-run state — a concrete, labeled action
|
|
2479
214
|
* (start from a template, do it by hand, ask the agent), not a placeholder. */
|
|
2480
|
-
interface ChatEmptyDoor {
|
|
215
|
+
export interface ChatEmptyDoor {
|
|
2481
216
|
label: string;
|
|
2482
217
|
description?: string;
|
|
2483
218
|
onSelect: () => void;
|
|
@@ -2485,7 +220,7 @@ interface ChatEmptyDoor {
|
|
|
2485
220
|
icon?: ReactNode;
|
|
2486
221
|
}
|
|
2487
222
|
/** Define properties for rendering the chat empty state with customizable text and starting doors */
|
|
2488
|
-
interface ChatEmptyStateProps {
|
|
223
|
+
export interface ChatEmptyStateProps {
|
|
2489
224
|
/** Product name shown next to the Tangle mark. Default "Agent". */
|
|
2490
225
|
productName?: string;
|
|
2491
226
|
/** Headline. Default frames delegation, not messaging. */
|
|
@@ -2500,15 +235,15 @@ interface ChatEmptyStateProps {
|
|
|
2500
235
|
* up to three concrete doors. Replaces the blank thread that read as "empty or
|
|
2501
236
|
* broken". Concrete + actionable — never a "coming soon" placeholder.
|
|
2502
237
|
*/
|
|
2503
|
-
declare function ChatEmptyState({ productName, headline, subline, doors, }: ChatEmptyStateProps): react.JSX.Element;
|
|
238
|
+
export declare function ChatEmptyState({ productName, headline, subline, doors, }: ChatEmptyStateProps): import("react").JSX.Element;
|
|
2504
239
|
/** Handle approval and rejection actions for proposals with asynchronous support */
|
|
2505
|
-
interface ProposalApprovalHandlers {
|
|
240
|
+
export interface ProposalApprovalHandlers {
|
|
2506
241
|
onApprove: (proposalId: string, toolCallId: string) => void | Promise<void>;
|
|
2507
242
|
onReject: (proposalId: string, toolCallId: string) => void | Promise<void>;
|
|
2508
243
|
}
|
|
2509
244
|
/** Per-tool custom detail renderers for the expanded card body — keyed by
|
|
2510
245
|
* tool name. Return null to fall back to the generic detail view. */
|
|
2511
|
-
type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: ChatUiMessage) => ReactNode>;
|
|
246
|
+
export type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: ChatUiMessage) => ReactNode>;
|
|
2512
247
|
/**
|
|
2513
248
|
* Adapt a chat tool call to the canonical `@tangle-network/ui` `ToolPart`, so
|
|
2514
249
|
* the row renders through ui's `InlineToolItem` — one run-row grammar shared
|
|
@@ -2518,12 +253,12 @@ type ToolDetailRenderers = Record<string, (call: ChatToolCallInfo, message: Chat
|
|
|
2518
253
|
* every other tool keeps its real name. agent-app carries no per-call timings,
|
|
2519
254
|
* so `state.time` stays unset and the row shows no duration.
|
|
2520
255
|
*/
|
|
2521
|
-
declare function chatToolCallPart(call: ChatToolCallInfo): ToolPart;
|
|
256
|
+
export declare function chatToolCallPart(call: ChatToolCallInfo): ToolPart;
|
|
2522
257
|
/** Whole seconds elapsed while `active`, ticking once a second. Powers the live
|
|
2523
258
|
* "thinking" timers (the pre-first-token row and the reasoning box) so a long
|
|
2524
259
|
* thinking gap shows progress instead of a frozen label. Counts from when
|
|
2525
260
|
* `active` first turns true; freezes when it clears. */
|
|
2526
|
-
declare function useThinkingSeconds(active: boolean): number;
|
|
261
|
+
export declare function useThinkingSeconds(active: boolean): number;
|
|
2527
262
|
/**
|
|
2528
263
|
* The message thread: one centered column; user messages are right-aligned
|
|
2529
264
|
* bubbles with a User label; agent messages carry an Agent meta line with
|
|
@@ -2531,6 +266,4 @@ declare function useThinkingSeconds(active: boolean): number;
|
|
|
2531
266
|
* tool rows. `chrome="quiet"` opts into the label-free variant: the
|
|
2532
267
|
* label/meta row becomes a hover-revealed meta lane under each row.
|
|
2533
268
|
*/
|
|
2534
|
-
declare function ChatMessages({ messages, messageSize, chrome, models, renderMarkdown, renderExtras, durableCards, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, error, onRetry, renderEmpty, emptyState, header, resolveAttachmentUrl, workProductCards, }: ChatMessagesProps): react.JSX.Element;
|
|
2535
|
-
|
|
2536
|
-
export { type ActivityTone, type AgentActivityPage, AgentActivityPanel, type AgentActivityPanelProps, type AgentActivityRecord, type AttachmentFileResult, CatalogModel, ChatAttachmentInput, ChatAttachmentKind, ChatAttachmentPart, ChatComposer, type ChatComposerProps, type ChatEmptyDoor, ChatEmptyState, type ChatEmptyStateProps, ChatInteraction, ChatInteractionField, type ChatInteractionRestoreMode, ChatInteractionStatus, ChatMentionPart, type ChatMessageMetrics, type ChatMessageSegment, ChatMessages, type ChatMessagesProps, ChatSelectField, type ChatStreamCallbacks, type ChatStreamToolCall, type ChatStreamToolResult, type ChatToolCallInfo, type ChatUiMessage, type ComposerFile, type ComposerFilePart, type ComposerSendFailure, type ComposerSendHandler, type ComposerSendOutcome, type ComposerSendPartsHandler, type ComposerSendRejected, type ComposerSendResult, type ConsumeChatStreamResult, DEFAULT_INSIGHT_PAGE_SIZE, DEFAULT_PROVENANCE_CONFIDENCE_POLICY, DEFAULT_SPARKLINE_EMPTY_LABEL, DEFAULT_SPARKLINE_HEIGHT, DEFAULT_SPARKLINE_LABEL, DEFAULT_SPARKLINE_UNAVAILABLE_LABEL, DEFAULT_SPARKLINE_WIDTH, type DurableChatCard, DurableChatCards, type DurableChatCardsProps, type DurableInteractionAnswerSubmitterOptions, DurablePlanCard, type DurablePlanCardProps, DurablePlanClientError, type DurablePlanCurrentInput, type DurablePlanDecision, type DurablePlanDecisionClient, type DurablePlanDecisionClientOptions, type DurablePlanDecisionInput, type DurablePlanDecisionResult, type DurablePlanFollowUpReceipt, EMPTY_RECORD_GRID_OVERLAY, EvidenceLineageTable, type EvidenceLineageTableProps, ExceptionList, type ExceptionListProps, type FetchSessionPage, type FieldValues, FlowWaterfall, type FlowWaterfallProps, HarnessGlyph, type HarnessGlyphProps, INTERACTION_SUBMIT_TIMEOUT_MESSAGE, INTERACTION_SUBMIT_TIMEOUT_MS, type Insight, type InsightAction, InsightCard, type InsightCardProps, InsightDeck, type InsightDeckProps, type InsightDelta, type InsightDirection, type InsightPolarity, type InsightTone, InteractionActionButton, type InteractionAnswerSubmission, type InteractionAnswerSubmitterOptions, InteractionAnswers, type InteractionAttemptStore, InteractionBadge, type InteractionBadgeVariant, InteractionCancelData, InteractionPlanCard, type InteractionPlanCardProps, InteractionQuestionCard, type InteractionQuestionCardProps, InteractionRequestWire, type InteractionSubmitResult, type LinkLikeComponent, type LinkLikeProps, type MentionTextSegment, MessageAttachments, type MessageAttachmentsProps, MissionActivityLane, type MissionActivityLaneProps, PROVENANCE_BASES, type ProposalApprovalHandlers, type ProvenanceBasis, type ProvenanceBasisMeta, type ProvenanceConfidencePolicy, type ProvenanceGap, type ProvenanceGapKind, ProvenanceLegend, type ProvenanceLegendProps, type ProvenanceRecord, type ProvenanceSource, type ProvenanceSourceStatus, ProvenanceStamp, type ProvenanceStampProps, type ProvenanceStanding, type ProvenanceStandingMeta, ProvenanceValue, type ProvenanceValueProps, ProviderLogo, type ProviderLogoProps, QualityCheckList, type QualityCheckListProps, QuestionOptionList, type QuestionOptionListProps, RecordGrid, type RecordGridBooleanColumn, type RecordGridCellChange, type RecordGridCellOutcome, type RecordGridCellSource, type RecordGridColumn, type RecordGridColumnBase, type RecordGridCreateOutcome, type RecordGridCurrencyColumn, type RecordGridDateColumn, type RecordGridDependency, type RecordGridNumberColumn, type RecordGridOverlay, type RecordGridProps, type RecordGridRow, type RecordGridRowOutcome, type RecordGridSelectColumn, type RecordGridSelectOption, type RecordGridSourceBasis, type RecordGridTextColumn, type RecordGridValue, type RecordGridWriteOutcome, type RestoreChatInteractionsOptions, ReviewQueueItem, type ReviewQueuePage, ReviewQueuePanel, type ReviewQueuePanelProps, ReviewQueueState, RunDrillIn, type RunDrillInProps, SeatPaywall, type SeatPaywallProps, type SessionActionLabels, type SessionActions, type SessionActionsOptions, type SessionBulkAction, SessionHistoryPanel, type SessionHistoryPanelProps, type SessionHistoryState, type SessionPageQuery, type SmoothRevealOptions, Sparkline, type SparklineDirection, type SparklineGeometry, type SparklineGeometryOptions, type SparklineLabelOptions, type SparklinePoint, type SparklineProps, type StreamChatOptions, type SubmitInteractionAnswer, type ToolDetailRenderers, type ToolRunRecord, type ToolRunStep, type UseChatInteractionsOptions, type UseChatInteractionsResult, type UseComposerAttachmentsOptions, type UseComposerAttachmentsResult, type UseDurablePlanFlowOptions, type UseDurablePlanFlowResult, type UseInfiniteScrollOptions, type UseSessionHistoryOptions, type WaterfallRow, WorkProductCard, type WorkProductCardProps, __resetAttachmentFileCacheForTests, activityTone, buildAnswerData, cancelChatInteraction, chatToolCallPart, consumeChatStream, createDurableInteractionAnswerSubmitter, createDurablePlanDecisionClient, createInteractionAnswerSubmitter, createMemoryInteractionAttemptStore, createSessionInteractionAttemptStore, describeProvenance, describeProvenanceSourceStatus, dispatchChatStreamLine, durableChatCardsFromParts, fieldAnswer, fieldValuesFromAnswers, formatActivityCost, formatActivityDuration, formatInsightDelta, formatModelCost, formatRecordGridValue, formatSessionTimestamp, formatSparklineValue, formatTokensPerSecond, hasSecretField, hydrateChatInteractions, insightDelta, insightDeltaTone, insightPageCount, insightPageSize, insightPageSlice, interactionStatusLabels, interactionSubmissionSignature, interactionTerminalNotes, isLateAnswerableStatus, isRecordGridCellApplicable, lateAnswerMessage, loadAttachmentFile, loadingProvenanceSources, mergeActivityPages, mergeReviewQueuePages, nextRevealCount, parseRecordGridInput, pendingApprovalOf, projectRecordGridRows, provenanceBasisMeta, provenanceGaps, provenanceNextMove, provenanceStandingMeta, provenanceTriggerLabel, pruneRecordGridOverlay, readRecordGridCell, recordGridEditorText, recordGridFail, recordGridOk, recordGridRowLabel, resolveChatInteraction, resolveProvenanceStanding, responseErrorMessage, restoreChatInteractions, reviewQueueStateLabel, rollUpProvenanceStanding, sameRecordGridValue, segmentMentionContent, settleInteractionSubmit, sparklineGeometry, sparklineLabel, sparklinePointsAttribute, sparklineReadings, standingFromConfidence, streamChatTurn, sumRecordGridColumn, terminalizePendingChatInteractions, triggerAttachmentDownload, upsertChatInteraction, useChatInteractions, useComposerAttachments, useDurablePlanFlow, useInfiniteScroll, useSessionActions, useSessionHistory, useSmoothText, useThinkingSeconds, validateRecordGridCell, validateRecordGridRow, waterfallLayout, weakerProvenanceStanding, withRecordGridCreated, withRecordGridRemoved, withRecordGridServerRow, withRecordGridUpdate, withoutRecordGridCreated, withoutRecordGridRemoved, withoutRecordGridUpdate, workProductPartsFromMessageParts, workProductStatusLabel };
|
|
269
|
+
export declare function ChatMessages({ messages, messageSize, chrome, models, renderMarkdown, renderExtras, durableCards, userLabel, agentLabel, loading, approval, onToolCallClick, toolRenderers, error, onRetry, renderEmpty, emptyState, header, resolveAttachmentUrl, workProductCards, }: ChatMessagesProps): import("react").JSX.Element;
|