@hanzo/ui 8.27.3 → 8.27.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/backdrop/Backdrop.cjs +420 -0
  2. package/dist/backdrop/Backdrop.d.ts +53 -0
  3. package/dist/backdrop/Backdrop.d.ts.map +1 -0
  4. package/dist/backdrop/Backdrop.js +418 -0
  5. package/dist/backdrop/Backdrop.js.map +1 -0
  6. package/dist/backdrop/index.cjs +50 -0
  7. package/dist/backdrop/index.d.ts +29 -0
  8. package/dist/backdrop/index.d.ts.map +1 -0
  9. package/dist/backdrop/index.js +29 -0
  10. package/dist/backdrop/index.js.map +1 -0
  11. package/dist/backdrop/scene.cjs +439 -0
  12. package/dist/backdrop/scene.d.ts +235 -0
  13. package/dist/backdrop/scene.d.ts.map +1 -0
  14. package/dist/backdrop/scene.js +423 -0
  15. package/dist/backdrop/scene.js.map +1 -0
  16. package/dist/chat/Chat.cjs +23 -1
  17. package/dist/chat/Chat.d.ts +6 -3
  18. package/dist/chat/Chat.d.ts.map +1 -1
  19. package/dist/chat/Chat.js +23 -1
  20. package/dist/chat/Chat.js.map +1 -1
  21. package/dist/chat/Inspector.cjs +51 -0
  22. package/dist/chat/Inspector.d.ts +49 -0
  23. package/dist/chat/Inspector.d.ts.map +1 -0
  24. package/dist/chat/Inspector.js +49 -0
  25. package/dist/chat/Inspector.js.map +1 -0
  26. package/dist/chat/Message.cjs +3 -1
  27. package/dist/chat/Message.d.ts +3 -1
  28. package/dist/chat/Message.d.ts.map +1 -1
  29. package/dist/chat/Message.js +3 -1
  30. package/dist/chat/Message.js.map +1 -1
  31. package/dist/chat/Parts.cjs +159 -0
  32. package/dist/chat/Parts.d.ts +186 -0
  33. package/dist/chat/Parts.d.ts.map +1 -0
  34. package/dist/chat/Parts.js +153 -0
  35. package/dist/chat/Parts.js.map +1 -0
  36. package/dist/chat/Persona.cjs +34 -0
  37. package/dist/chat/Persona.d.ts +37 -0
  38. package/dist/chat/Persona.d.ts.map +1 -0
  39. package/dist/chat/Persona.js +30 -0
  40. package/dist/chat/Persona.js.map +1 -0
  41. package/dist/chat/Preview.cjs +42 -0
  42. package/dist/chat/Preview.d.ts +36 -0
  43. package/dist/chat/Preview.d.ts.map +1 -0
  44. package/dist/chat/Preview.js +40 -0
  45. package/dist/chat/Preview.js.map +1 -0
  46. package/dist/chat/directive.cjs +272 -0
  47. package/dist/chat/directive.d.ts +167 -0
  48. package/dist/chat/directive.d.ts.map +1 -0
  49. package/dist/chat/directive.js +266 -0
  50. package/dist/chat/directive.js.map +1 -0
  51. package/dist/chat/index.cjs +59 -4
  52. package/dist/chat/index.d.ts +31 -3
  53. package/dist/chat/index.d.ts.map +1 -1
  54. package/dist/chat/index.js +31 -3
  55. package/dist/chat/index.js.map +1 -1
  56. package/dist/gallery.html +4 -4
  57. package/dist/styles.css +3 -3
  58. package/dist/theme.css +3 -3
  59. package/package.json +7 -1
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Inspector — what the agent did, beside what it said.
3
+ *
4
+ * The thread carries the answer. This carries the evidence: a summary at the
5
+ * top, then the run's own regions underneath — what it was given, what it
6
+ * produced, what ran on the way. It is the pane a person reads to decide
7
+ * whether to believe the answer, which is why the summary is first and the
8
+ * detail is under it rather than the other way round.
9
+ *
10
+ * It is the CONTENTS of the right rail, not the rail. `Aside` is the column —
11
+ * the border, the width, the fact that it is a column at all — and this goes
12
+ * inside it. Two components because a surface hides the rail at narrow widths
13
+ * by not rendering it, and that decision has nothing to do with what is in it.
14
+ *
15
+ * ONE inspector, whatever the run was. A section carries `facts` (name to
16
+ * value) or `parts` (drawn by `Parts`), and `MessagePart` already covers every
17
+ * shape a run produces: tool calls and their results for a chat turn, files and
18
+ * console output for a coding run, `citation` for a research run's sources, an
19
+ * `artifact` for anything it made. A second panel per kind of run would be four
20
+ * copies of this file disagreeing about spacing.
21
+ *
22
+ * A section with nothing in it does not render, so a caller passes the same
23
+ * list every time and does not write the emptiness checks.
24
+ */
25
+ import { YStack } from '@hanzo/gui';
26
+ import type { ComponentProps, ReactNode } from 'react';
27
+ import type { Facts } from './directive.js';
28
+ import { type MessagePart, type PartActions } from './Parts.js';
29
+ /** One region of a run. Either half may be present; both is fine. */
30
+ export interface Section {
31
+ /** The heading. */
32
+ name: string;
33
+ /** Drawn as a table of name and value. */
34
+ facts?: Facts;
35
+ /** Drawn by `Parts` — steps, artifacts, sources, files. */
36
+ parts?: readonly MessagePart[];
37
+ }
38
+ export interface InspectorProps extends PartActions, Omit<ComponentProps<typeof YStack>, 'children'> {
39
+ /** The pane's own heading. */
40
+ title?: string;
41
+ /** One paragraph: what the run did. Absent, no summary block draws. */
42
+ summary?: string;
43
+ /** The regions, in order. Empty ones are skipped. */
44
+ sections?: readonly Section[];
45
+ /** Shown when there is no summary and every section is empty. */
46
+ placeholder?: ReactNode;
47
+ }
48
+ export declare function Inspector({ title, summary, sections, placeholder, prose, onRetry, onOpen, onSource, ...props }: InspectorProps): import("react").JSX.Element;
49
+ //# sourceMappingURL=Inspector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Inspector.d.ts","sourceRoot":"","sources":["../../src/chat/Inspector.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAmC,MAAM,EAAE,MAAM,YAAY,CAAA;AACpE,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGtD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,aAAa,CAAA;AAExC,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAA;AAEzE,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,KAAK,CAAC,EAAE,KAAK,CAAA;IACb,2DAA2D;IAC3D,KAAK,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;CAC/B;AAMD,MAAM,WAAW,cACf,SAAQ,WAAW,EACjB,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,CAAC;IACjD,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,qDAAqD;IACrD,QAAQ,CAAC,EAAE,SAAS,OAAO,EAAE,CAAA;IAC7B,iEAAiE;IACjE,WAAW,CAAC,EAAE,SAAS,CAAA;CACxB;AAED,wBAAgB,SAAS,CAAC,EACxB,KAAa,EACb,OAAO,EACP,QAAa,EACb,WAAW,EACX,KAAK,EACL,OAAO,EACP,MAAM,EACN,QAAQ,EACR,GAAG,KAAK,EACT,EAAE,cAAc,+BAyDhB"}
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ /**
4
+ * Inspector — what the agent did, beside what it said.
5
+ *
6
+ * The thread carries the answer. This carries the evidence: a summary at the
7
+ * top, then the run's own regions underneath — what it was given, what it
8
+ * produced, what ran on the way. It is the pane a person reads to decide
9
+ * whether to believe the answer, which is why the summary is first and the
10
+ * detail is under it rather than the other way round.
11
+ *
12
+ * It is the CONTENTS of the right rail, not the rail. `Aside` is the column —
13
+ * the border, the width, the fact that it is a column at all — and this goes
14
+ * inside it. Two components because a surface hides the rail at narrow widths
15
+ * by not rendering it, and that decision has nothing to do with what is in it.
16
+ *
17
+ * ONE inspector, whatever the run was. A section carries `facts` (name to
18
+ * value) or `parts` (drawn by `Parts`), and `MessagePart` already covers every
19
+ * shape a run produces: tool calls and their results for a chat turn, files and
20
+ * console output for a coding run, `citation` for a research run's sources, an
21
+ * `artifact` for anything it made. A second panel per kind of run would be four
22
+ * copies of this file disagreeing about spacing.
23
+ *
24
+ * A section with nothing in it does not render, so a caller passes the same
25
+ * list every time and does not write the emptiness checks.
26
+ */
27
+ import { ScrollView, SizableText, XStack, YStack } from '@hanzo/gui';
28
+ import { slot } from '../backends/gui/slot.js';
29
+ import { Code } from './Code.js';
30
+ import { Parts, show } from './Parts.js';
31
+ const filled = (section) => (section.facts != null && Object.keys(section.facts).length > 0) ||
32
+ (section.parts != null && section.parts.length > 0);
33
+ export function Inspector({ title = 'Run', summary, sections = [], placeholder, prose, onRetry, onOpen, onSource, ...props }) {
34
+ const shown = sections.filter(filled);
35
+ const bare = summary == null && shown.length === 0;
36
+ return (_jsxs(YStack, { ...slot('inspector'), flex: 1, minH: 0, width: "100%", ...props, children: [_jsx(XStack, { items: "center", px: "$1", pb: "$2", shrink: 0, children: _jsx(SizableText, { size: "$1", color: "$soft", fontWeight: "600", children: title }) }), _jsx(ScrollView, { flex: 1, showsVerticalScrollIndicator: false, children: _jsxs(YStack, { gap: "$4", pb: "$4", children: [summary ? (_jsx(YStack, { ...slot('inspector-summary'), p: "$3", gap: "$2", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", children: _jsx(SizableText, { size: "$2", color: "$ink", children: summary }) })) : null, shown.map((section) => (_jsxs(YStack, { ...slot('inspector-section'), gap: "$2", children: [_jsx(SizableText, { size: "$1", color: "$quiet", fontWeight: "600", children: section.name }), section.facts ? _jsx(Table, { facts: section.facts }) : null, section.parts?.length ? (_jsx(Parts, { parts: section.parts, prose: prose, onRetry: onRetry, onOpen: onOpen, onSource: onSource })) : null] }, section.name))), bare && placeholder != null ? (_jsx(SizableText, { size: "$2", color: "$soft", children: placeholder })) : null] }) })] }));
37
+ }
38
+ /**
39
+ * A record, as rows.
40
+ *
41
+ * A string is its own presentation; anything else goes through `Code`, because
42
+ * a nested object flattened into a line is unreadable and `show` already
43
+ * serialises one safely. That is the only rule here, and it is why this is a
44
+ * dozen lines rather than a formatting library.
45
+ */
46
+ function Table({ facts }) {
47
+ return (_jsx(YStack, { ...slot('inspector-facts'), rounded: "$4", borderWidth: 1, borderColor: "$borderColor", overflow: "hidden", children: Object.entries(facts).map(([name, value], i) => (_jsxs(YStack, { gap: "$1.5", px: "$3", py: "$2", borderTopWidth: i === 0 ? 0 : 1, borderColor: "$borderColor", children: [_jsx(SizableText, { size: "$1", color: "$quiet", children: name }), typeof value === 'string' ? (_jsx(SizableText, { size: "$2", color: "$ink", children: value })) : (_jsx(Code, { language: "json", children: show(value) }))] }, name))) }));
48
+ }
49
+ //# sourceMappingURL=Inspector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Inspector.js","sourceRoot":"","sources":["../../src/chat/Inspector.tsx"],"names":[],"mappings":"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"}
@@ -12,7 +12,9 @@ const jsx_runtime_1 = require("react/jsx-runtime");
12
12
  * turn is a muted aside. The contrast is what says who is speaking, so there is
13
13
  * no name and no timestamp, and `icon` is opt-in.
14
14
  *
15
- * Content is `children`: the markdown pipeline stays with the surface.
15
+ * Content is `children`: the markdown pipeline stays with the surface. A turn
16
+ * that arrived as a list of parts puts `<Parts>` there — `Chat` does exactly
17
+ * that — so this component keeps knowing nothing about the wire.
16
18
  */
17
19
  const gui_1 = require("@hanzo/gui");
18
20
  const ink_1 = require("../backends/gui/ink.cjs");
@@ -6,7 +6,9 @@
6
6
  * turn is a muted aside. The contrast is what says who is speaking, so there is
7
7
  * no name and no timestamp, and `icon` is opt-in.
8
8
  *
9
- * Content is `children`: the markdown pipeline stays with the surface.
9
+ * Content is `children`: the markdown pipeline stays with the surface. A turn
10
+ * that arrived as a list of parts puts `<Parts>` there — `Chat` does exactly
11
+ * that — so this component keeps knowing nothing about the wire.
10
12
  */
11
13
  import { XStack } from '@hanzo/gui';
12
14
  import type { ComponentProps, ReactNode } from 'react';
@@ -1 +1 @@
1
- {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;GASG;AACH,OAAO,EAAQ,MAAM,EAAU,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE3D;wDACwD;AACxD,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,CAAA;AAErE;;;;;;;GAOG;AACH,wBAAgB,KAAK,gCAEpB;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK;IACzC,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;6DACyD;IACzD,IAAI,CAAC,EAAE,KAAK,CAAA;CACb;AAED,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAY,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,YAAY,+BAyDd"}
1
+ {"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,OAAO,EAAQ,MAAM,EAAU,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAKtD;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAA;AAE3D;wDACwD;AACxD,KAAK,KAAK,GAAG,IAAI,CAAC,cAAc,CAAC,OAAO,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC,CAAA;AAErE;;;;;;;GAOG;AACH,wBAAgB,KAAK,gCAEpB;AAED,MAAM,WAAW,YAAa,SAAQ,KAAK;IACzC,IAAI,EAAE,IAAI,CAAA;IACV,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,SAAS,CAAA;IACnB,8DAA8D;IAC9D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,sEAAsE;IACtE,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB;6DACyD;IACzD,IAAI,CAAC,EAAE,KAAK,CAAA;CACb;AAED,wBAAgB,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAY,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACT,EAAE,YAAY,+BAyDd"}
@@ -8,7 +8,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  * turn is a muted aside. The contrast is what says who is speaking, so there is
9
9
  * no name and no timestamp, and `icon` is opt-in.
10
10
  *
11
- * Content is `children`: the markdown pipeline stays with the surface.
11
+ * Content is `children`: the markdown pipeline stays with the surface. A turn
12
+ * that arrived as a list of parts puts `<Parts>` there — `Chat` does exactly
13
+ * that — so this component keeps knowing nothing about the wire.
12
14
  */
13
15
  import { Text, XStack, YStack } from '@hanzo/gui';
14
16
  import { ink } from '../backends/gui/ink.js';
@@ -1 +1 @@
1
- {"version":3,"file":"Message.js","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;GASG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGjD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAsB3C;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,KAAC,MAAM,OAAK,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAC,MAAM,wBAAe,CAAA;AAC9F,CAAC;AAgBD,MAAM,UAAU,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAI,GAAG,KAAK,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACK;IACb,8EAA8E;IAC9E,4BAA4B;IAC5B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM;QACtC,OAAO,CACL,KAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eAIR,IAAI,EACf,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,QAAQ,EAChB,EAAE,EAAC,IAAI,KACH,KAAK,YAET,KAAC,IAAI,IAAC,QAAQ,EAAC,IAAI,EAAC,KAAK,EAAC,OAAO,EAAC,IAAI,EAAC,QAAQ,YAC5C,QAAQ,GACJ,GACA,CACV,CAAA;IAEH,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,CAAA;IAC5B,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eACR,IAAI,EACf,KAAK,EAAC,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,EACzC,GAAG,EAAC,IAAI;QACR,qEAAqE;QACrE,oDAAoD;QACpD,KAAK,WACD,KAAK,aAER,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,EAAE,EAAC,IAAI,YAAE,IAAI,GAAU,CAAC,CAAC,CAAC,IAAI,EACvD,MAAC,MAAM,OACD,IAAI,CAAC,cAAc,CAAC,iBACX,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACtC,GAAG,EAAC,IAAI;gBACR,yDAAyD;gBACzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAC3B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KACtB,CAAC,IAAI,IAAI;oBACX,EAAE,EAAE,QAAQ;oBACZ,OAAO,EAAE,IAAI;oBACb,EAAE,EAAE,IAAI;oBACR,EAAE,EAAE,IAAI;iBACT,CAAC,KACE,IAAI,aAEP,GAAG,CAAC,QAAQ,CAAC,EACb,IAAI,CAAC,CAAC,CAAC,KAAC,KAAK,KAAG,CAAC,CAAC,CAAC,IAAI,EACvB,OAAO,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,GAAG,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,YAAE,OAAO,GAAU,CAAC,CAAC,CAAC,IAAI,IAC7D,IACF,CACV,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"Message.js","sourceRoot":"","sources":["../../src/chat/Message.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;;;;;;;;GAWG;AACH,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAA;AAGjD,OAAO,EAAE,GAAG,EAAE,MAAM,qBAAqB,CAAA;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAA;AAsB3C;;;;;;;GAOG;AACH,MAAM,UAAU,KAAK;IACnB,OAAO,KAAC,MAAM,OAAK,IAAI,CAAC,OAAO,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,EAAE,EAAC,MAAM,wBAAe,CAAA;AAC9F,CAAC;AAgBD,MAAM,UAAU,OAAO,CAAC,EACtB,IAAI,EACJ,QAAQ,EACR,OAAO,EACP,IAAI,GAAG,KAAK,EACZ,IAAI,EACJ,IAAI,EACJ,GAAG,KAAK,EACK;IACb,8EAA8E;IAC9E,4BAA4B;IAC5B,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,MAAM;QACtC,OAAO,CACL,KAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eAIR,IAAI,EACf,KAAK,EAAC,MAAM,EACZ,OAAO,EAAC,QAAQ,EAChB,EAAE,EAAC,IAAI,KACH,KAAK,YAET,KAAC,IAAI,IAAC,QAAQ,EAAC,IAAI,EAAC,KAAK,EAAC,OAAO,EAAC,IAAI,EAAC,QAAQ,YAC5C,QAAQ,GACJ,GACA,CACV,CAAA;IAEH,MAAM,IAAI,GAAG,IAAI,KAAK,MAAM,CAAA;IAC5B,OAAO,CACL,MAAC,MAAM,OACD,IAAI,CAAC,SAAS,CAAC,eACR,IAAI,EACf,KAAK,EAAC,MAAM,EACZ,OAAO,EAAE,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,YAAY,EACzC,GAAG,EAAC,IAAI;QACR,qEAAqE;QACrE,oDAAoD;QACpD,KAAK,WACD,KAAK,aAER,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,EAAE,EAAC,IAAI,YAAE,IAAI,GAAU,CAAC,CAAC,CAAC,IAAI,EACvD,MAAC,MAAM,OACD,IAAI,CAAC,cAAc,CAAC,iBACX,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACtC,GAAG,EAAC,IAAI;gBACR,yDAAyD;gBACzD,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAC3B,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,KACtB,CAAC,IAAI,IAAI;oBACX,EAAE,EAAE,QAAQ;oBACZ,OAAO,EAAE,IAAI;oBACb,EAAE,EAAE,IAAI;oBACR,EAAE,EAAE,IAAI;iBACT,CAAC,KACE,IAAI,aAEP,GAAG,CAAC,QAAQ,CAAC,EACb,IAAI,CAAC,CAAC,CAAC,KAAC,KAAK,KAAG,CAAC,CAAC,CAAC,IAAI,EACvB,OAAO,CAAC,CAAC,CAAC,KAAC,MAAM,IAAC,GAAG,EAAC,IAAI,EAAC,KAAK,EAAC,QAAQ,YAAE,OAAO,GAAU,CAAC,CAAC,CAAC,IAAI,IAC7D,IACF,CACV,CAAA;AACH,CAAC"}
@@ -0,0 +1,159 @@
1
+ 'use client';"use strict";
2
+ 'use client';
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.show = void 0;
5
+ exports.join = join;
6
+ exports.Piece = Piece;
7
+ exports.Parts = Parts;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ /**
10
+ * Parts — a streamed turn, drawn by what each piece of it IS.
11
+ *
12
+ * A completion's content is a list of parts, and until now this package had one
13
+ * answer for all of them: `words` flattens the list to prose and DROPS every
14
+ * part that is not text. An image, a tool call, a citation, an artifact — all of
15
+ * it arrived on the wire and none of it reached the screen. Six surfaces wrote
16
+ * six switch statements over the same union to get it back.
17
+ *
18
+ * `MessagePart` is that union, closed, and `Parts` is the dispatcher over it.
19
+ * Closed is the decision: `words`'s `Part` stays OPEN because it reads the wire
20
+ * and must survive a type it has never heard of, while this one is the CANON —
21
+ * the set a surface can exhaustively handle, and the set this package promises
22
+ * to draw. A part whose `type` is outside it still contributes its text, exactly
23
+ * as `words` does, so an unknown part degrades to prose instead of vanishing.
24
+ *
25
+ * Nothing here is new furniture. Every branch dispatches to a piece this package
26
+ * already had: `Code` for a tool's arguments and its output, `Step` for the call
27
+ * itself, `Failure` for an error, `Sources` for citations, `ArtifactCard` for a
28
+ * produced thing. That is the whole reason a typed renderer belongs here rather
29
+ * than in each surface — the parts were already drawn, one per surface, with no
30
+ * agreement about which part got which drawing.
31
+ *
32
+ * MARKDOWN IS STILL NOT HERE. `prose` is where a surface's pipeline enters, and
33
+ * with none supplied the words render plainly. The plugin set is per-surface —
34
+ * nine plugins, one plugin, or a regex under a bundle ceiling that cannot afford
35
+ * a parser — so this package ships no parser and takes the rendered nodes.
36
+ */
37
+ const gui_1 = require("@hanzo/gui");
38
+ const lucide_icons_2_1 = require("@hanzogui/lucide-icons-2");
39
+ const Pane_1 = require("../agents/Pane.cjs");
40
+ const ink_1 = require("../backends/gui/ink.cjs");
41
+ const slot_1 = require("../backends/gui/slot.cjs");
42
+ const Code_1 = require("./Code.cjs");
43
+ const Failure_1 = require("./Failure.cjs");
44
+ const Preview_1 = require("./Preview.cjs");
45
+ const Sources_1 = require("./Sources.cjs");
46
+ const Step_1 = require("./Step.cjs");
47
+ /**
48
+ * Adjacent prose, put back together.
49
+ *
50
+ * The wire splits a sentence across parts — and mid-word, which is why `words`
51
+ * joins with no separator — so drawing each text part as its own block would
52
+ * break one paragraph into a dozen and hand a markdown parser fragments that are
53
+ * not markdown. Runs of `text` and runs of `reasoning` each collapse to one;
54
+ * everything else passes through untouched and in order.
55
+ *
56
+ * This is what makes `Parts` a strict improvement on `words` rather than a
57
+ * different-looking one: an all-text turn renders exactly the string `words`
58
+ * would have produced.
59
+ */
60
+ function join(parts) {
61
+ const out = [];
62
+ for (const part of parts) {
63
+ const last = out[out.length - 1];
64
+ if ((part.type === 'text' || part.type === 'reasoning') &&
65
+ last &&
66
+ last.type === part.type) {
67
+ out[out.length - 1] = { type: part.type, text: last.text + part.text };
68
+ continue;
69
+ }
70
+ out.push(part);
71
+ }
72
+ return out;
73
+ }
74
+ /**
75
+ * What a tool was asked, or answered, as text.
76
+ *
77
+ * The wire sends JSON, so a caller holding the parsed object should not have to
78
+ * re-serialise it at every call site — that is six copies of two lines. The
79
+ * fallback exists because this takes `unknown` and a value that cannot be
80
+ * serialised must not take the page down with it.
81
+ */
82
+ const show = (value) => {
83
+ if (value == null)
84
+ return '';
85
+ if (typeof value === 'string')
86
+ return value;
87
+ try {
88
+ return JSON.stringify(value, null, 2);
89
+ }
90
+ catch {
91
+ return String(value);
92
+ }
93
+ };
94
+ exports.show = show;
95
+ /** A size a person can read. Every surface writes this one; here it is once. */
96
+ const weigh = (bytes) => {
97
+ const units = ['B', 'KB', 'MB', 'GB'];
98
+ let n = bytes;
99
+ let i = 0;
100
+ while (n >= 1024 && i < units.length - 1) {
101
+ n /= 1024;
102
+ i += 1;
103
+ }
104
+ return `${i === 0 ? n : n.toFixed(1)} ${units[i]}`;
105
+ };
106
+ /**
107
+ * One part.
108
+ *
109
+ * It spreads no residual props and owns no box, which is the one place this
110
+ * package's house rule does not apply: a piece IS whichever component its type
111
+ * names, and giving it a wrapper of its own would put an anonymous div between
112
+ * every part and the column that spaces them. `Parts` is the box.
113
+ *
114
+ * Named `Piece` and not `Part` because `Part` is already the name of `words`'s
115
+ * open wire type on this barrel, and a module cannot export one name as both a
116
+ * type and a value.
117
+ */
118
+ function Piece({ part, prose, onRetry, onOpen, onSource }) {
119
+ switch (part.type) {
120
+ case 'text':
121
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: prose ? prose(part.text, part) : (0, ink_1.ink)(part.text) });
122
+ case 'reasoning':
123
+ // Dimmed rather than recoloured: a surface's markdown paints its own
124
+ // colours, and a token on the container would not reach inside them.
125
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('reasoning'), opacity: 0.72, children: prose ? prose(part.text, part) : (0, ink_1.ink)(part.text) }));
126
+ case 'toolCall':
127
+ return ((0, jsx_runtime_1.jsx)(Step_1.Step, { name: part.name, status: "running", detail: part.id, children: part.args == null ? undefined : (0, jsx_runtime_1.jsx)(Code_1.Code, { language: "json", children: (0, exports.show)(part.args) }) }));
128
+ case 'toolResult':
129
+ return ((0, jsx_runtime_1.jsx)(Step_1.Step, { name: part.name, status: part.status ?? 'done', detail: part.id, children: part.result == null ? undefined : (0, jsx_runtime_1.jsx)(Code_1.Code, { language: "json", children: (0, exports.show)(part.result) }) }));
130
+ case 'image':
131
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('image'), maxW: 420, rounded: "$4", overflow: "hidden", borderWidth: 1, borderColor: "$borderColor", children: (0, jsx_runtime_1.jsx)(gui_1.Image, { src: part.url, alt: part.alt ?? '', style: { width: '100%', height: 'auto', display: 'block' } }) }));
132
+ case 'file':
133
+ return ((0, jsx_runtime_1.jsxs)(gui_1.XStack, { ...(0, slot_1.slot)('file'), items: "center", gap: "$2", maxW: 420, px: "$2.5", py: "$2", rounded: "$4", borderWidth: 1, borderColor: "$borderColor", bg: "$panel", children: [(0, jsx_runtime_1.jsx)(lucide_icons_2_1.Paperclip, { size: 13, color: "$quiet" }), (0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$2", color: "$ink", numberOfLines: 1, flex: 1, children: part.name }), part.size == null ? null : ((0, jsx_runtime_1.jsx)(gui_1.SizableText, { size: "$1", color: "$quiet", children: weigh(part.size) }))] }));
134
+ case 'citation':
135
+ return (0, jsx_runtime_1.jsx)(Sources_1.Sources, { sources: part.sources, onOpen: onSource });
136
+ case 'artifact':
137
+ // Held, so shown. `Preview` renders it with scripting disabled, which is
138
+ // what makes drawing model-authored markup a different question from
139
+ // loading a `uiResource`'s url — see that arm, and `Preview`'s own note.
140
+ return part.markup ? ((0, jsx_runtime_1.jsx)(Preview_1.Preview, { title: part.title, markup: part.markup })) : ((0, jsx_runtime_1.jsx)(Pane_1.ArtifactCard, { title: part.title, kind: part.kind, onOpen: onOpen ? () => onOpen(part) : undefined }));
141
+ case 'uiResource':
142
+ return ((0, jsx_runtime_1.jsx)(Step_1.Step, { name: part.uri, detail: part.mime, children: part.text ? (0, jsx_runtime_1.jsx)(Code_1.Code, { language: part.mime ?? 'text', children: part.text }) : undefined }));
143
+ case 'error':
144
+ return (0, jsx_runtime_1.jsx)(Failure_1.Failure, { onRetry: onRetry, children: part.text });
145
+ default: {
146
+ // The union is closed and the WIRE is not, which is the one place those
147
+ // two facts have to meet. A part this does not know contributes its text
148
+ // and nothing else — the same answer `words` gives, so nothing a surface
149
+ // sends can go missing without also having been missing before.
150
+ const unknown = part;
151
+ return (0, jsx_runtime_1.jsx)(jsx_runtime_1.Fragment, { children: unknown.text ? (0, ink_1.ink)(unknown.text) : null });
152
+ }
153
+ }
154
+ }
155
+ /** A turn's parts, in order, spaced. Goes in a `Message`'s children — `Chat`
156
+ * puts it there for a turn whose content is a list. */
157
+ function Parts({ parts, prose, onRetry, onOpen, onSource, ...props }) {
158
+ return ((0, jsx_runtime_1.jsx)(gui_1.YStack, { ...(0, slot_1.slot)('parts'), width: "100%", gap: "$2", ...props, children: join(parts).map((part, i) => ((0, jsx_runtime_1.jsx)(Piece, { part: part, prose: prose, onRetry: onRetry, onOpen: onOpen, onSource: onSource }, `${part.type}-${i}`))) }));
159
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Parts — a streamed turn, drawn by what each piece of it IS.
3
+ *
4
+ * A completion's content is a list of parts, and until now this package had one
5
+ * answer for all of them: `words` flattens the list to prose and DROPS every
6
+ * part that is not text. An image, a tool call, a citation, an artifact — all of
7
+ * it arrived on the wire and none of it reached the screen. Six surfaces wrote
8
+ * six switch statements over the same union to get it back.
9
+ *
10
+ * `MessagePart` is that union, closed, and `Parts` is the dispatcher over it.
11
+ * Closed is the decision: `words`'s `Part` stays OPEN because it reads the wire
12
+ * and must survive a type it has never heard of, while this one is the CANON —
13
+ * the set a surface can exhaustively handle, and the set this package promises
14
+ * to draw. A part whose `type` is outside it still contributes its text, exactly
15
+ * as `words` does, so an unknown part degrades to prose instead of vanishing.
16
+ *
17
+ * Nothing here is new furniture. Every branch dispatches to a piece this package
18
+ * already had: `Code` for a tool's arguments and its output, `Step` for the call
19
+ * itself, `Failure` for an error, `Sources` for citations, `ArtifactCard` for a
20
+ * produced thing. That is the whole reason a typed renderer belongs here rather
21
+ * than in each surface — the parts were already drawn, one per surface, with no
22
+ * agreement about which part got which drawing.
23
+ *
24
+ * MARKDOWN IS STILL NOT HERE. `prose` is where a surface's pipeline enters, and
25
+ * with none supplied the words render plainly. The plugin set is per-surface —
26
+ * nine plugins, one plugin, or a regex under a bundle ceiling that cannot afford
27
+ * a parser — so this package ships no parser and takes the rendered nodes.
28
+ */
29
+ import { YStack } from '@hanzo/gui';
30
+ import type { ComponentProps, ReactNode } from 'react';
31
+ import { type ArtifactKind } from '../agents/Pane.js';
32
+ import { type Source } from './Sources.js';
33
+ import { type Ran } from './Step.js';
34
+ /**
35
+ * One piece of a turn — the canonical set.
36
+ *
37
+ * Every member carries `type` and an optional `text`, which is what keeps
38
+ * `MessagePart[]` assignable to `words`'s `Part[]`: the same list answers "what
39
+ * was said" and "what is on screen" with no conversion between them.
40
+ *
41
+ * `toolCall` and `toolResult` are two states of one thing, not two things that
42
+ * arrive together — a streaming turn UPDATES the part in place as the result
43
+ * lands. A surface that appends both instead will see two steps, which is an
44
+ * honest picture of what it appended.
45
+ */
46
+ export type MessagePart =
47
+ /** Prose. */
48
+ {
49
+ type: 'text';
50
+ text: string;
51
+ }
52
+ /** Prose the model wrote while working, shown quieter than the answer. */
53
+ | {
54
+ type: 'reasoning';
55
+ text: string;
56
+ }
57
+ /** A tool the model asked for, and what it asked with. */
58
+ | {
59
+ type: 'toolCall';
60
+ name: string;
61
+ id?: string;
62
+ args?: unknown;
63
+ text?: string;
64
+ }
65
+ /** What the tool answered. `status` says how it went; absent means it landed. */
66
+ | {
67
+ type: 'toolResult';
68
+ name: string;
69
+ id?: string;
70
+ status?: Ran;
71
+ result?: unknown;
72
+ text?: string;
73
+ } | {
74
+ type: 'image';
75
+ url: string;
76
+ alt?: string;
77
+ text?: string;
78
+ } | {
79
+ type: 'file';
80
+ name: string;
81
+ url?: string;
82
+ mime?: string;
83
+ size?: number;
84
+ text?: string;
85
+ }
86
+ /** What the answer was drawn from. */
87
+ | {
88
+ type: 'citation';
89
+ sources: Source[];
90
+ text?: string;
91
+ }
92
+ /**
93
+ * Something the turn produced and the surface can open.
94
+ *
95
+ * `markup` is the thing ITSELF — a self-contained HTML document the model
96
+ * wrote — and when it is there the part draws as a `Preview` rather than as a
97
+ * card, because a card offering to open a thing we are holding is a worse
98
+ * answer than showing it. Absent, the card is all there is to draw.
99
+ */
100
+ | {
101
+ type: 'artifact';
102
+ title: string;
103
+ kind: ArtifactKind;
104
+ id?: string;
105
+ markup?: string;
106
+ text?: string;
107
+ }
108
+ /**
109
+ * A resource the model offers as an interface.
110
+ *
111
+ * Named and shown as source, never RUN. Executing a remote document inside the
112
+ * host page is the whole of cross-site scripting, and a component library
113
+ * cannot make that call for its consumers — a surface with a sandbox to run it
114
+ * in renders it itself, which is a decision it takes where its policy lives.
115
+ */
116
+ | {
117
+ type: 'uiResource';
118
+ uri: string;
119
+ mime?: string;
120
+ text?: string;
121
+ }
122
+ /** The turn did not arrive. */
123
+ | {
124
+ type: 'error';
125
+ text: string;
126
+ };
127
+ /**
128
+ * Adjacent prose, put back together.
129
+ *
130
+ * The wire splits a sentence across parts — and mid-word, which is why `words`
131
+ * joins with no separator — so drawing each text part as its own block would
132
+ * break one paragraph into a dozen and hand a markdown parser fragments that are
133
+ * not markdown. Runs of `text` and runs of `reasoning` each collapse to one;
134
+ * everything else passes through untouched and in order.
135
+ *
136
+ * This is what makes `Parts` a strict improvement on `words` rather than a
137
+ * different-looking one: an all-text turn renders exactly the string `words`
138
+ * would have produced.
139
+ */
140
+ export declare function join(parts: readonly MessagePart[]): MessagePart[];
141
+ /**
142
+ * What a tool was asked, or answered, as text.
143
+ *
144
+ * The wire sends JSON, so a caller holding the parsed object should not have to
145
+ * re-serialise it at every call site — that is six copies of two lines. The
146
+ * fallback exists because this takes `unknown` and a value that cannot be
147
+ * serialised must not take the page down with it.
148
+ */
149
+ export declare const show: (value: unknown) => string;
150
+ /** The controls a part can offer. Callbacks-out, as everything here is: the part
151
+ * is data and knows nothing about what opening it means. */
152
+ export interface PartActions {
153
+ /** Render prose. Absent, the words render plainly. */
154
+ prose?: (text: string, part: MessagePart) => ReactNode;
155
+ /** Run the turn again — an `error` part's control. Absent, none renders. */
156
+ onRetry?: () => void;
157
+ /** Open an `artifact` part. */
158
+ onOpen?: (part: Extract<MessagePart, {
159
+ type: 'artifact';
160
+ }>) => void;
161
+ /** Open one of a `citation` part's sources. */
162
+ onSource?: (source: Source) => void;
163
+ }
164
+ export interface PieceProps extends PartActions {
165
+ part: MessagePart;
166
+ }
167
+ /**
168
+ * One part.
169
+ *
170
+ * It spreads no residual props and owns no box, which is the one place this
171
+ * package's house rule does not apply: a piece IS whichever component its type
172
+ * names, and giving it a wrapper of its own would put an anonymous div between
173
+ * every part and the column that spaces them. `Parts` is the box.
174
+ *
175
+ * Named `Piece` and not `Part` because `Part` is already the name of `words`'s
176
+ * open wire type on this barrel, and a module cannot export one name as both a
177
+ * type and a value.
178
+ */
179
+ export declare function Piece({ part, prose, onRetry, onOpen, onSource }: PieceProps): import("react").JSX.Element;
180
+ export interface PartsProps extends PartActions, Omit<ComponentProps<typeof YStack>, 'children'> {
181
+ parts: readonly MessagePart[];
182
+ }
183
+ /** A turn's parts, in order, spaced. Goes in a `Message`'s children — `Chat`
184
+ * puts it there for a turn whose content is a list. */
185
+ export declare function Parts({ parts, prose, onRetry, onOpen, onSource, ...props }: PartsProps): import("react").JSX.Element;
186
+ //# sourceMappingURL=Parts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Parts.d.ts","sourceRoot":"","sources":["../../src/chat/Parts.tsx"],"names":[],"mappings":"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"}