@tangle-network/agent-app 0.45.49 → 0.45.51

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.
@@ -522,7 +522,8 @@
522
522
 
523
523
  /* The waiting label. `background-clip: text` over a moving gradient, so the
524
524
  shimmer runs THROUGH the glyphs rather than behind them. Marked essential:
525
- it is the only signal that work is still in flight. */
525
+ it is the only signal that work is still in flight. Its reduced-motion
526
+ answer is at the bottom of this file, with the floor it opts out of. */
526
527
  .agent-shimmer {
527
528
  background: linear-gradient(
528
529
  90deg,
@@ -583,6 +584,13 @@
583
584
  * out by declaring `data-motion="essential"`; the exclusion covers that element
584
585
  * and its subtree, and `:where()` keeps the selector at zero specificity so a
585
586
  * consumer's own `!important` can still win.
587
+ *
588
+ * `essential` is an exemption from the BLANKET rule, not a licence to keep
589
+ * running. It exists because collapsing a meaning-carrying animation to a 1ms
590
+ * flash destroys the meaning, so the element gets to answer for itself — and it
591
+ * then OWES that answer. An element with no end condition owes it most, which
592
+ * is why `.agent-shimmer` states its own below: the sweep stops, and what it
593
+ * was saying is re-stated as a static difference the reader can still see.
586
594
  */
587
595
  @media (prefers-reduced-motion: reduce) {
588
596
  :root {
@@ -603,6 +611,42 @@
603
611
  transition-duration: 1ms !important;
604
612
  }
605
613
 
614
+ /* The waiting label's own answer. It is `data-motion="essential"` because the
615
+ sweep is the ONLY thing separating an agent that is working from one that
616
+ is stuck, so the floor above must not collapse it — but an INFINITE
617
+ animation is exactly what someone asking for reduced motion is asking to be
618
+ rid of, and running it anyway because the element declared itself essential
619
+ is the override this file calls a defect.
620
+
621
+ So the meaning is carried without the motion. The sweep stops and the
622
+ gradient comes off (it exists only to be moved), which puts the glyphs back
623
+ under `color` instead of leaving them transparent windows onto it.
624
+
625
+ The DOTTED RULE is the discriminator, and it is the only one. Measured in
626
+ Chromium under `prefers-reduced-motion: reduce`, light and dark: the live
627
+ label computes `text-decoration: underline dotted` where a settled label
628
+ beside it computes `none`, and the two resolve to the SAME color and the
629
+ same weight. That is by construction — `color: inherit` hands the label
630
+ whatever its context already uses, and the settled label shares that
631
+ context. In `mission-activity`'s lane both tool names read rgb(12,12,21)
632
+ light / rgb(236,236,241) dark; in the chat trace toggle "Thinking · 12s"
633
+ and "Thought for 12s" both read rgb(96,96,99) light / rgb(158,158,160)
634
+ dark, because that button is `text-muted-foreground`. So the reader tells
635
+ in-flight from done by the rule under the word, from a still frame — not by
636
+ tone and not by weight.
637
+
638
+ Not `content: '…'` or any other generated text: this element's text is read
639
+ by a screen reader, and adding pseudo-content changes what is announced. */
640
+ .agent-shimmer {
641
+ animation: none;
642
+ background: none;
643
+ background-clip: border-box;
644
+ -webkit-background-clip: border-box;
645
+ color: inherit;
646
+ text-decoration: underline dotted currentColor;
647
+ text-underline-offset: 3px;
648
+ }
649
+
606
650
  html {
607
651
  scroll-behavior: auto !important;
608
652
  }
@@ -1,5 +1,5 @@
1
1
  import * as react from 'react';
2
- import { ReactNode, RefObject } from 'react';
2
+ import { ReactNode, RefObject, ReactElement, CSSProperties } from 'react';
3
3
  import { ToolPart } from '@tangle-network/ui/types';
4
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
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';
@@ -527,7 +527,14 @@ interface QuestionOptionListProps {
527
527
  }
528
528
  /** The radio/checkbox option rows for a select field. Renders a fragment of
529
529
  * option `<label>` rows so a card keeps its own wrapping layout and appends
530
- * its own write-in input. */
530
+ * its own write-in input.
531
+ *
532
+ * The rows arrive as a SEQUENCE (`.agent-arrive` + `--stagger-index`), which
533
+ * is the difference between reading a list and being shown one: the eye is
534
+ * told there are N choices and in what order before it has read any of them.
535
+ * The index is safe to take straight from the map because an option list does
536
+ * not re-sort under a mounted card — a different set of options is a
537
+ * different `key`, and a different ask resets the card wholesale. */
531
538
  declare function QuestionOptionList({ groupName, idPrefix, options, multi, selectedValues, disabled, onToggle, answered, }: QuestionOptionListProps): react.JSX.Element;
532
539
  interface InteractionQuestionCardProps {
533
540
  interaction: ChatInteraction;
@@ -1050,6 +1057,12 @@ interface MissionActivityLaneProps {
1050
1057
  /**
1051
1058
  * Collapsed sub-rows under a mission step — one row per delegated run —
1052
1059
  * expanding to the step's waterfall. Renders nothing for an empty lane.
1060
+ *
1061
+ * A sub-row appears because a delegated run STARTED or FINISHED, which is the
1062
+ * one kind of list change worth choreographing: it arrives, and the group
1063
+ * arrives as a sequence. Keying on `taskId` is what keeps the rest still — the
1064
+ * snapshot re-renders every poll, and a row whose status merely advanced holds
1065
+ * the DOM node it already had.
1053
1066
  */
1054
1067
  declare function MissionActivityLane({ activity, startedAt, nowMs }: MissionActivityLaneProps): react.JSX.Element | null;
1055
1068
  interface AgentActivityPanelProps {
@@ -1949,6 +1962,360 @@ interface RecordGridProps {
1949
1962
  */
1950
1963
  declare function RecordGrid({ columns, caption, state, empty, onCreate, onUpdate, onDelete, newRowDefaults, addLabel, locale, toolbar, loadingRowCount, className, }: RecordGridProps): react.JSX.Element;
1951
1964
 
1965
+ /**
1966
+ * `Sparkline` — the series behind a number, as inline SVG.
1967
+ *
1968
+ * `/spend`, `/missions` and the eval lanes all produce a number for today, and
1969
+ * every product renders it as text. Text cannot separate "$41, up from $38"
1970
+ * from "$41, up from $4" — the same sentence, two different situations — so the
1971
+ * reader opens a second surface to find out which one they are in. The series
1972
+ * next to the number answers it in one glance.
1973
+ *
1974
+ * No chart dependency: this subpath is react + `@tangle-network/ui` only, and a
1975
+ * polyline is not worth a bundle. What a chart library would give us here is
1976
+ * axes, ticks and a tooltip, none of which belong on a 96×24 glyph.
1977
+ *
1978
+ * The three shapes a hand-rolled sparkline gets wrong, each handled here rather
1979
+ * than left to the caller:
1980
+ *
1981
+ * - **no readings** renders an explicit empty label, never a line. A line
1982
+ * along the baseline is a claim — "this metric sat at zero" — and a series
1983
+ * nobody has measured yet did not sit anywhere.
1984
+ * - **one reading** renders a point. A line needs two coordinates; drawing one
1985
+ * from a single reading invents the segment before it.
1986
+ * - **equal readings** render flat at MID height. The obvious normalisation
1987
+ * divides by `max - min`, which is `0` for a perfectly stable metric, and
1988
+ * the resulting `NaN` lands in the `points` attribute — SVG drops the whole
1989
+ * polyline, so the metric that never moved is the one that disappears.
1990
+ * - **a missing reading renders as a GAP, and the accessible name says so.**
1991
+ * A `null` from a hole in a series and a `NaN` from a producer's unguarded
1992
+ * division are not smaller series — they are readings nobody has. Deleting
1993
+ * them closed the line straight across the hole and announced a count that
1994
+ * was short by the number deleted: measured on `[1, NaN, 3]`, one continuous
1995
+ * two-point line labelled "2 readings, rising from 1 to 3", with nothing
1996
+ * anywhere saying a reading was unreadable. The card's figure slot already
1997
+ * refuses to let a non-measurement look measured; the series one line below
1998
+ * it holds the same rule. The x axis is the SAMPLE index, so the hole keeps
1999
+ * its width, the line breaks at it, and the label carries "N not available".
2000
+ *
2001
+ * Accessibility: `role="img"` with an `aria-label` naming the metric, its range
2002
+ * and its direction. A sparkline with no accessible name is decoration a screen
2003
+ * reader cannot report, which would leave the shape — the entire reason the
2004
+ * component exists — visible to exactly one kind of reader.
2005
+ *
2006
+ * Deliberately not animated. `docs/product-surfaces.md` Pattern 4 lists chart
2007
+ * draw-on under what this package does not animate: the shape IS the answer,
2008
+ * and easing it in taxes every read of a surface people sit in for hours. The
2009
+ * card around it arrives (`.agent-arrive`); the line does not draw itself.
2010
+ */
2011
+
2012
+ /** Where a series ended relative to where it started. */
2013
+ type SparklineDirection = 'rising' | 'falling' | 'flat';
2014
+ interface SparklinePoint {
2015
+ readonly x: number;
2016
+ readonly y: number;
2017
+ }
2018
+ interface SparklineGeometry {
2019
+ /** The finite readings, in order — what was actually plotted. */
2020
+ readonly readings: readonly number[];
2021
+ /** Every plotted point, in order. Positions are on the SAMPLE axis, so a
2022
+ * missing reading leaves its width behind rather than closing up. */
2023
+ readonly points: readonly SparklinePoint[];
2024
+ /** The points split into runs of CONSECUTIVE samples. One run is one stroke:
2025
+ * a line drawn across a missing reading states a movement nobody measured. */
2026
+ readonly segments: readonly (readonly SparklinePoint[])[];
2027
+ /** Samples that carried no usable reading — a `null`, a `NaN`, an infinity.
2028
+ * Counted rather than discarded, because the accessible name has to state
2029
+ * them: a shorter series announced as a complete one is the silent loss. */
2030
+ readonly gaps: number;
2031
+ readonly min: number;
2032
+ readonly max: number;
2033
+ readonly first: number;
2034
+ readonly last: number;
2035
+ readonly direction: SparklineDirection;
2036
+ }
2037
+ interface SparklineGeometryOptions {
2038
+ width?: number;
2039
+ height?: number;
2040
+ /** Keeps the stroke and the end dot inside the viewBox instead of clipping
2041
+ * them at the extremes, where the interesting readings always are. */
2042
+ inset?: number;
2043
+ }
2044
+ declare const DEFAULT_SPARKLINE_WIDTH = 96;
2045
+ declare const DEFAULT_SPARKLINE_HEIGHT = 24;
2046
+ /** Only a name, never a metric: it exists so the accessible label is never
2047
+ * empty. Every caller in this package passes the metric's own title. */
2048
+ declare const DEFAULT_SPARKLINE_LABEL = "Trend";
2049
+ declare const DEFAULT_SPARKLINE_EMPTY_LABEL = "No history yet";
2050
+ /** Nothing was measurable, which is not the same as nothing was measured yet —
2051
+ * and "No history yet" over a series that arrived full of `NaN` reads as the
2052
+ * metric being new when the producer is broken. */
2053
+ declare const DEFAULT_SPARKLINE_UNAVAILABLE_LABEL = "No readings available";
2054
+ /** The package's default number rendering, pinned to `en-US` so a card and its
2055
+ * series read the same on every host — a series formatted by the server's
2056
+ * locale and a value formatted by the browser's is a defect nobody sees until
2057
+ * the decimal separators disagree. */
2058
+ declare function formatSparklineValue(value: number): string;
2059
+ /**
2060
+ * The readings that can be plotted.
2061
+ *
2062
+ * A `null` from a gap in a series, or a `NaN` from a division a producer did
2063
+ * not guard, is not plotted rather than coerced to `0`: plotting a missing
2064
+ * reading at the baseline draws a cliff that never happened.
2065
+ *
2066
+ * This returns the readings ALONE, so it cannot tell a caller how many are
2067
+ * missing. That is what {@link SparklineGeometry.gaps} is for, and what the
2068
+ * accessible name reports — dropping a sample and then announcing the shorter
2069
+ * count as the whole series is the defect, not the filter.
2070
+ */
2071
+ declare function sparklineReadings(values: readonly number[]): number[];
2072
+ /**
2073
+ * Plots the series into the viewBox.
2074
+ *
2075
+ * Pure and exported so the cases that produce a broken chart — nothing, one
2076
+ * reading, a flat series, negatives — are unit-testable without a DOM.
2077
+ */
2078
+ declare function sparklineGeometry(values: readonly number[], { width, height, inset }?: SparklineGeometryOptions): SparklineGeometry;
2079
+ /** `"2,14 48,3 94,21"` — the `points` attribute of the polyline. */
2080
+ declare function sparklinePointsAttribute(points: readonly SparklinePoint[]): string;
2081
+ interface SparklineLabelOptions {
2082
+ label?: string;
2083
+ format?: (value: number) => string;
2084
+ }
2085
+ /**
2086
+ * The accessible name: metric, how many readings, how many are missing, the
2087
+ * range, and the direction.
2088
+ *
2089
+ * All of it is load-bearing. The range without the direction describes a shape
2090
+ * that could have been walked in either order; the direction without the range
2091
+ * says "rising" about a metric that moved by a rounding error; and the count
2092
+ * without the gaps is the number of readings that SURVIVED announced as the
2093
+ * number that were taken — the shape a reader cannot see is exactly the one
2094
+ * this sentence exists to carry.
2095
+ */
2096
+ declare function sparklineLabel(values: readonly number[], { label, format }?: SparklineLabelOptions): string;
2097
+ interface SparklineProps {
2098
+ values: readonly number[];
2099
+ /** Names the metric in the accessible label. */
2100
+ label?: string;
2101
+ /** Renders a reading in that label; defaults to the package number format. */
2102
+ format?: (value: number) => string;
2103
+ width?: number;
2104
+ height?: number;
2105
+ /** Shown instead of a line when the metric has no history yet. */
2106
+ emptyLabel?: string;
2107
+ /** Shown instead of a line when every sample arrived unreadable — a different
2108
+ * state from "no history yet", and one the reader has to be able to tell
2109
+ * apart, because one is a new metric and the other is a broken producer. */
2110
+ unavailableLabel?: string;
2111
+ className?: string;
2112
+ }
2113
+ /** The series glyph. Strokes in `currentColor`, so tone is the caller's. */
2114
+ declare function Sparkline({ values, label, format, width, height, emptyLabel, unavailableLabel, className, }: SparklineProps): ReactElement;
2115
+
2116
+ /**
2117
+ * `InsightCard` + `InsightDeck` — the number that moved, and the paged deck of
2118
+ * them.
2119
+ *
2120
+ * Every product on this shell computes insights already: `/spend` knows today's
2121
+ * burn against yesterday's, `/missions` knows how many runs landed, the eval
2122
+ * lanes know a pass rate per release. All of it renders as a line of text, so
2123
+ * the reader does the comparison in their head and the series behind the number
2124
+ * never reaches the screen at all.
2125
+ *
2126
+ * Two rules this surface exists to hold:
2127
+ *
2128
+ * - **A delta needs a baseline.** `previous` absent means no delta is drawn —
2129
+ * not a green `+0%`, which is the specific fabrication a hand-rolled card
2130
+ * produces when it defaults its baseline to zero, and which reads as "we
2131
+ * measured, nothing changed" when the truth is "we have nothing to compare
2132
+ * against". {@link insightDelta} returns `null` rather than a zero.
2133
+ * - **Direction is not sentiment.** Spend going up and missions going up are
2134
+ * the same arrow and opposite news, so tone is a caller declaration
2135
+ * (`polarity`), and the default is neutral. A card that paints every rise
2136
+ * green teaches the reader to stop reading the label.
2137
+ *
2138
+ * The deck is built on `web-react/async` rather than a loading boolean, so it
2139
+ * inherits that module's invariant instead of restating it: `AsyncView` renders
2140
+ * `error` with its message and retry, and `empty` is reachable only from a load
2141
+ * that resolved — a failed fetch can never paint "No insights yet"
2142
+ * (`docs/async-state-module.md`).
2143
+ *
2144
+ * Motion: cards arrive with `.agent-arrive`, staggered by `--stagger-index`
2145
+ * from the deck, and a page TURN remounts them so the next page arrives as a
2146
+ * sequence instead of swapping text under cards that never moved. A REFRESH is
2147
+ * the opposite case and gets the opposite treatment — see the deck's own note.
2148
+ * Every piece of that is decoration, carries no `data-motion`, and collapses
2149
+ * under `prefers-reduced-motion` — the live label included.
2150
+ *
2151
+ * The live label does NOT opt out, and the reasoning is worth stating because
2152
+ * the opposite reads plausible. What tells the reader a figure is still being
2153
+ * computed is the WORD (`liveLabel`, "Updating"): it is rendered only while
2154
+ * `live`, and a settled card does not render it at all. The sweep through its
2155
+ * glyphs is emphasis on a signal that is already there, not the signal. So a
2156
+ * reader who asked for less motion still sees the word — static, in the
2157
+ * shimmer's resting gradient, still legible, and still disappearing the moment
2158
+ * the figure is final. Nothing here overrides a request the reader made.
2159
+ */
2160
+
2161
+ type InsightDirection = 'up' | 'down' | 'flat';
2162
+ /** Which way is good news for THIS metric. `neutral` is the default because it
2163
+ * is the only answer that is true for every metric. */
2164
+ type InsightPolarity = 'higher-is-better' | 'lower-is-better' | 'neutral';
2165
+ type InsightTone = 'positive' | 'negative' | 'neutral';
2166
+ interface InsightDelta {
2167
+ /** The baseline the move is measured against — rendered, so the delta is
2168
+ * never a number floating free of what produced it. */
2169
+ readonly previous: number;
2170
+ readonly absolute: number;
2171
+ /** `null` when the baseline is `0`: a share of nothing is undefined, and
2172
+ * "+∞%" or a silently-dropped percentage are both worse than the absolute. */
2173
+ readonly percent: number | null;
2174
+ readonly direction: InsightDirection;
2175
+ }
2176
+ /**
2177
+ * The move, or `null` when there is no honest one to state.
2178
+ *
2179
+ * `unknown` inputs on purpose: these arrive from a fetched payload, and the
2180
+ * cases that must not produce a delta — a missing baseline, a `null` from a
2181
+ * first-ever reading, a `NaN` from a producer's division — are exactly the ones
2182
+ * a narrower signature would let through as `0`.
2183
+ */
2184
+ declare function insightDelta(value: unknown, previous: unknown): InsightDelta | null;
2185
+ /** Maps a direction onto good/bad news, which only the caller knows. */
2186
+ declare function insightDeltaTone(direction: InsightDirection, polarity?: InsightPolarity): InsightTone;
2187
+ /**
2188
+ * The delta as words: direction, magnitude, and the baseline it is measured
2189
+ * against. Words rather than an arrow plus a bare number, because the arrow is
2190
+ * `aria-hidden` and a reader hearing "12%" learns nothing about which way.
2191
+ */
2192
+ declare function formatInsightDelta(delta: InsightDelta, format?: (value: number) => string): string;
2193
+ interface InsightAction {
2194
+ label: string;
2195
+ onClick: () => void;
2196
+ }
2197
+ interface InsightCardProps {
2198
+ /** What was measured, in the reader's words ("Spend today"). */
2199
+ title: string;
2200
+ /** The number that moved. A `string` renders verbatim — a total the caller
2201
+ * already formatted with its own currency — and takes no delta, because
2202
+ * there is nothing to subtract. A non-finite number is not a measurement and
2203
+ * renders as {@link INSIGHT_UNAVAILABLE_GLYPH}, never as "NaN" or "∞". */
2204
+ value: number | string;
2205
+ /** "USD", "runs", "%" — the unit the number is in, beside it rather than
2206
+ * glued into it, so the figure stays scannable. */
2207
+ unit?: string;
2208
+ /** The baseline. Absent ⇒ the card renders the value and no delta. */
2209
+ previous?: number;
2210
+ polarity?: InsightPolarity;
2211
+ /** One number format for the value, the delta and the series, so the three
2212
+ * cannot disagree about decimals on the same card. */
2213
+ format?: (value: number) => string;
2214
+ series?: readonly number[];
2215
+ /** Names the series in its accessible label; defaults to the card's title. */
2216
+ seriesLabel?: string;
2217
+ /** One line of context under the number — what the window is, what is
2218
+ * excluded. Not a restatement of the title. */
2219
+ description?: string;
2220
+ /** The next action for this insight. An element renders as supplied (a link,
2221
+ * a dialog trigger); the object form renders the standard button. */
2222
+ action?: InsightAction | ReactElement;
2223
+ /** The number is still being computed. The label's PRESENCE is the signal, so
2224
+ * it reads the same with motion collapsed — see the module note. */
2225
+ live?: boolean;
2226
+ liveLabel?: string;
2227
+ className?: string;
2228
+ style?: CSSProperties;
2229
+ }
2230
+ declare function InsightCard({ title, value, unit, previous, polarity, format, series, seriesLabel, description, action, live, liveLabel, className, style, }: InsightCardProps): ReactElement;
2231
+ interface Insight extends InsightCardProps {
2232
+ /** Stable across refreshes: it keys the card. Paired with the deck holding
2233
+ * the last loaded page across a reload, a stable id is what lets a settled
2234
+ * card keep its own DOM node — and therefore not replay its arrival — when
2235
+ * a poll returns the same insight. */
2236
+ readonly id: string;
2237
+ }
2238
+ declare const DEFAULT_INSIGHT_PAGE_SIZE = 3;
2239
+ /**
2240
+ * The page size — ONE definition, read by the count and by the slice.
2241
+ *
2242
+ * Two definitions is how a deck hides an insight with no error at all: a count
2243
+ * that divides by the raw `2.5` claims two pages of a five-card deck, a slice
2244
+ * that floors it puts two cards on each, and the fifth card is on no page the
2245
+ * reader can reach. Nothing renders wrong; a card is simply gone.
2246
+ *
2247
+ * A page size is a count of cards, so a fraction, a zero and a negative are not
2248
+ * smaller decks — they are caller mistakes, and this normalises them back to the
2249
+ * default and says so once per offending value. Normalised rather than thrown
2250
+ * because the value is often computed from a measured viewport, where the first
2251
+ * paint legitimately produces a `0`: a deck that pages in threes is a far
2252
+ * smaller failure than a dashboard that throws during render.
2253
+ */
2254
+ declare function insightPageSize(pageSize?: number): number;
2255
+ /** Always at least one page, so "Page 1 of 0" cannot be rendered. */
2256
+ declare function insightPageCount(total: number, pageSize?: number): number;
2257
+ /** The items on `page`, with the page clamped into range — a deck whose list
2258
+ * shrank under the reader shows the last page that exists, never a blank one. */
2259
+ declare function insightPageSlice<T>(items: readonly T[], page: number, pageSize?: number): readonly T[];
2260
+ interface InsightDeckProps {
2261
+ /** The same five-state contract every other screen fetches through. */
2262
+ state: AsyncResourceState<readonly Insight[]>;
2263
+ /** Required by `AsyncView`: an empty deck must say what is missing and what
2264
+ * to do about it. */
2265
+ empty: AsyncEmptySpec | ReactElement;
2266
+ /** Names the region for assistive tech and titles nothing visually — the
2267
+ * cards carry their own headings. */
2268
+ label?: string;
2269
+ pageSize?: number;
2270
+ loadingLabel?: string;
2271
+ retryLabel?: string;
2272
+ className?: string;
2273
+ /**
2274
+ * The page the reader is ON, whatever moved them there.
2275
+ *
2276
+ * That includes the render-time clamp: a list that shrinks under a reader
2277
+ * standing on page 3 leaves them on the last page that exists, and a parent
2278
+ * persisting this to a URL or to storage would otherwise keep writing a page
2279
+ * number nothing can reach. Reported once per effective page, never twice for
2280
+ * the same one.
2281
+ */
2282
+ onPageChange?: (page: number) => void;
2283
+ }
2284
+ /**
2285
+ * The paged deck.
2286
+ *
2287
+ * `AsyncView` owns the non-`ready` branches, which is what makes the invariant
2288
+ * structural here: the cards are rendered from one branch of that component,
2289
+ * and no branch of this one could paint the empty copy over a failure.
2290
+ *
2291
+ * **A REFRESH DOES NOT REPLACE WHAT IS ON SCREEN.** `useAsyncResource` re-enters
2292
+ * `loading` with no value held on every reload, and handing that straight to
2293
+ * `AsyncView` swaps the ready subtree for the busy block — which destroys the
2294
+ * DOM the reader is standing in. Measured, on a real reload: `document.
2295
+ * activeElement` fell to `document.body`, so a keyboard reader mid-page lost
2296
+ * their place on every automatic poll; and every settled card was a NEW node, so
2297
+ * `.agent-arrive` replayed across the whole visible page — the exact flash this
2298
+ * surface's motion rules exist to prevent. Holding the page NUMBER above the
2299
+ * boundary fixed the counter and none of that, because the subtree under it was
2300
+ * still being torn down.
2301
+ *
2302
+ * So the deck holds the last insights it rendered and keeps handing them to the
2303
+ * SAME `AsyncView` branch while a reload is in flight: same element, same
2304
+ * position, same keys — React reuses the nodes, focus stays where the reader put
2305
+ * it, and nothing re-animates. `aria-busy` on the region is the signal that a
2306
+ * load is in flight; a per-card one is `live` on the card.
2307
+ *
2308
+ * The bridge is only ever over a WAIT. `error` and `empty` are answers about the
2309
+ * resource, so they drop what was held and render their own branch — a failed
2310
+ * fetch still cannot paint stale numbers, and the async module's invariant is
2311
+ * untouched.
2312
+ *
2313
+ * It bridges one resource, not one component: if the SUBJECT changes (a
2314
+ * different workspace, a different window), give the deck a `key` so it remounts
2315
+ * rather than showing the previous subject's numbers while the new ones load.
2316
+ */
2317
+ declare function InsightDeck({ state, empty, label, pageSize, loadingLabel, retryLabel, className, onPageChange, }: InsightDeckProps): ReactElement;
2318
+
1952
2319
  /** Describe metrics related to a chat message including model, token counts, and duration */
1953
2320
  interface ChatMessageMetrics {
1954
2321
  modelUsed?: string;
@@ -2158,4 +2525,4 @@ declare function useThinkingSeconds(active: boolean): number;
2158
2525
  */
2159
2526
  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;
2160
2527
 
2161
- 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_PROVENANCE_CONFIDENCE_POLICY, 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, 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, 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, formatModelCost, formatRecordGridValue, formatSessionTimestamp, formatTokensPerSecond, hasSecretField, hydrateChatInteractions, 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, 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 };
2528
+ 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 };
@@ -3,9 +3,15 @@ import {
3
3
  ChatComposer,
4
4
  ChatEmptyState,
5
5
  ChatMessages,
6
+ DEFAULT_INSIGHT_PAGE_SIZE,
6
7
  DEFAULT_MENTION_EMPTY_TEXT,
7
8
  DEFAULT_MENTION_LIMIT,
8
9
  DEFAULT_PROVENANCE_CONFIDENCE_POLICY,
10
+ DEFAULT_SPARKLINE_EMPTY_LABEL,
11
+ DEFAULT_SPARKLINE_HEIGHT,
12
+ DEFAULT_SPARKLINE_LABEL,
13
+ DEFAULT_SPARKLINE_UNAVAILABLE_LABEL,
14
+ DEFAULT_SPARKLINE_WIDTH,
9
15
  DurableChatCards,
10
16
  DurablePlanCard,
11
17
  DurablePlanClientError,
@@ -14,6 +20,8 @@ import {
14
20
  INDEX_REFRESH_AFTER_MS,
15
21
  INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
16
22
  INTERACTION_SUBMIT_TIMEOUT_MS,
23
+ InsightCard,
24
+ InsightDeck,
17
25
  InteractionActionButton,
18
26
  InteractionBadge,
19
27
  InteractionPlanCard,
@@ -28,6 +36,7 @@ import {
28
36
  RunDrillIn,
29
37
  SeatPaywall,
30
38
  SessionHistoryPanel,
39
+ Sparkline,
31
40
  __resetAttachmentFileCacheForTests,
32
41
  activityTone,
33
42
  buildAnswerData,
@@ -47,12 +56,19 @@ import {
47
56
  fieldValuesFromAnswers,
48
57
  formatActivityCost,
49
58
  formatActivityDuration,
59
+ formatInsightDelta,
50
60
  formatModelCost,
51
61
  formatRecordGridValue,
52
62
  formatSessionTimestamp,
63
+ formatSparklineValue,
53
64
  formatTokensPerSecond,
54
65
  hasSecretField,
55
66
  hydrateChatInteractions,
67
+ insightDelta,
68
+ insightDeltaTone,
69
+ insightPageCount,
70
+ insightPageSize,
71
+ insightPageSlice,
56
72
  interactionStatusLabels,
57
73
  interactionSubmissionSignature,
58
74
  interactionTerminalNotes,
@@ -86,6 +102,10 @@ import {
86
102
  sameRecordGridValue,
87
103
  segmentMentionContent,
88
104
  settleInteractionSubmit,
105
+ sparklineGeometry,
106
+ sparklineLabel,
107
+ sparklinePointsAttribute,
108
+ sparklineReadings,
89
109
  standingFromConfidence,
90
110
  streamChatTurn,
91
111
  sumRecordGridColumn,
@@ -111,7 +131,7 @@ import {
111
131
  withoutRecordGridCreated,
112
132
  withoutRecordGridRemoved,
113
133
  withoutRecordGridUpdate
114
- } from "../chunk-ZAKKG6WI.js";
134
+ } from "../chunk-CXPWUCXC.js";
115
135
  import "../chunk-FBVLEGEG.js";
116
136
  import {
117
137
  EvidenceLineageTable,
@@ -154,6 +174,7 @@ import {
154
174
  tabTerminalConnectionId,
155
175
  useSandboxTerminalConnection
156
176
  } from "../chunk-BATKJP3P.js";
177
+ import "../chunk-3UBAO3N5.js";
157
178
  import "../chunk-PC2WYTK7.js";
158
179
  import "../chunk-QY4BRKRJ.js";
159
180
  import {
@@ -218,9 +239,15 @@ export {
218
239
  ChatEmptyState,
219
240
  ChatMessages,
220
241
  DEFAULT_EFFORT_LEVELS,
242
+ DEFAULT_INSIGHT_PAGE_SIZE,
221
243
  DEFAULT_MENTION_EMPTY_TEXT,
222
244
  DEFAULT_MENTION_LIMIT,
223
245
  DEFAULT_PROVENANCE_CONFIDENCE_POLICY,
246
+ DEFAULT_SPARKLINE_EMPTY_LABEL,
247
+ DEFAULT_SPARKLINE_HEIGHT,
248
+ DEFAULT_SPARKLINE_LABEL,
249
+ DEFAULT_SPARKLINE_UNAVAILABLE_LABEL,
250
+ DEFAULT_SPARKLINE_WIDTH,
224
251
  DISPATCH_MAX_MEDIA_PARTS,
225
252
  DISPATCH_MAX_PARTS,
226
253
  DISPATCH_REQUEST_MAX_BYTES,
@@ -242,6 +269,8 @@ export {
242
269
  INTERACTION_RESOLVED_EVENT,
243
270
  INTERACTION_SUBMIT_TIMEOUT_MESSAGE,
244
271
  INTERACTION_SUBMIT_TIMEOUT_MS,
272
+ InsightCard,
273
+ InsightDeck,
245
274
  InteractionActionButton,
246
275
  InteractionBadge,
247
276
  InteractionPlanCard,
@@ -264,6 +293,7 @@ export {
264
293
  RunDrillIn,
265
294
  SeatPaywall,
266
295
  SessionHistoryPanel,
296
+ Sparkline,
267
297
  WorkProductCard,
268
298
  __resetAttachmentFileCacheForTests,
269
299
  activityTone,
@@ -301,12 +331,19 @@ export {
301
331
  fileMentionsToParts,
302
332
  formatActivityCost,
303
333
  formatActivityDuration,
334
+ formatInsightDelta,
304
335
  formatModelCost,
305
336
  formatRecordGridValue,
306
337
  formatSessionTimestamp,
338
+ formatSparklineValue,
307
339
  formatTokensPerSecond,
308
340
  hasSecretField,
309
341
  hydrateChatInteractions,
342
+ insightDelta,
343
+ insightDeltaTone,
344
+ insightPageCount,
345
+ insightPageSize,
346
+ insightPageSlice,
310
347
  interactionFromWireRequest,
311
348
  interactionPartKey,
312
349
  interactionStatusLabels,
@@ -362,6 +399,10 @@ export {
362
399
  sameRecordGridValue,
363
400
  segmentMentionContent,
364
401
  settleInteractionSubmit,
402
+ sparklineGeometry,
403
+ sparklineLabel,
404
+ sparklinePointsAttribute,
405
+ sparklineReadings,
365
406
  stampInteractionAnswers,
366
407
  standingFromConfidence,
367
408
  streamChatTurn,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/agent-app",
3
- "version": "0.45.49",
3
+ "version": "0.45.51",
4
4
  "packageManager": "pnpm@11.17.0",
5
5
  "description": "Build agent applications with typed chat, tools, sandboxes, integrations, billing, and evaluation.",
6
6
  "keywords": [