@guuey/chat 0.4.0

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 (66) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +137 -0
  3. package/dist/history-inputs.d.ts +24 -0
  4. package/dist/history-inputs.d.ts.map +1 -0
  5. package/dist/history-inputs.js +34 -0
  6. package/dist/index.d.ts +19 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +17 -0
  9. package/dist/plan.d.ts +5 -0
  10. package/dist/plan.d.ts.map +1 -0
  11. package/dist/plan.js +629 -0
  12. package/dist/policy.d.ts +110 -0
  13. package/dist/policy.d.ts.map +1 -0
  14. package/dist/policy.js +75 -0
  15. package/dist/react/components.d.ts +87 -0
  16. package/dist/react/components.d.ts.map +1 -0
  17. package/dist/react/components.js +270 -0
  18. package/dist/react/guuey-chat.d.ts +84 -0
  19. package/dist/react/guuey-chat.d.ts.map +1 -0
  20. package/dist/react/guuey-chat.js +103 -0
  21. package/dist/react/markdown.d.ts +32 -0
  22. package/dist/react/markdown.d.ts.map +1 -0
  23. package/dist/react/markdown.js +40 -0
  24. package/dist/react/theme-css.d.ts +16 -0
  25. package/dist/react/theme-css.d.ts.map +1 -0
  26. package/dist/react/theme-css.js +37 -0
  27. package/dist/react/transcript.d.ts +42 -0
  28. package/dist/react/transcript.d.ts.map +1 -0
  29. package/dist/react/transcript.js +88 -0
  30. package/dist/react/use-transcript.d.ts +39 -0
  31. package/dist/react/use-transcript.d.ts.map +1 -0
  32. package/dist/react/use-transcript.js +201 -0
  33. package/dist/react.d.ts +21 -0
  34. package/dist/react.d.ts.map +1 -0
  35. package/dist/react.js +20 -0
  36. package/dist/strings.d.ts +74 -0
  37. package/dist/strings.d.ts.map +1 -0
  38. package/dist/strings.js +45 -0
  39. package/dist/theme.d.ts +99 -0
  40. package/dist/theme.d.ts.map +1 -0
  41. package/dist/theme.js +182 -0
  42. package/dist/types.d.ts +283 -0
  43. package/dist/types.d.ts.map +1 -0
  44. package/dist/types.js +1 -0
  45. package/package.json +87 -0
  46. package/src/corpus/README.md +40 -0
  47. package/src/corpus/__snapshots__/corpus.test.ts.snap +1590 -0
  48. package/src/corpus/capture.ts +67 -0
  49. package/src/corpus/captures/issue2627-render-capture.coalesced.sse.txt +173 -0
  50. package/src/corpus/drive.ts +184 -0
  51. package/src/corpus/fixtures.ts +338 -0
  52. package/src/history-inputs.ts +48 -0
  53. package/src/index.ts +58 -0
  54. package/src/plan.ts +740 -0
  55. package/src/policy.ts +146 -0
  56. package/src/react/components.tsx +655 -0
  57. package/src/react/guuey-chat.tsx +227 -0
  58. package/src/react/markdown.tsx +114 -0
  59. package/src/react/theme-css.ts +50 -0
  60. package/src/react/transcript.tsx +187 -0
  61. package/src/react/use-transcript.ts +274 -0
  62. package/src/react.tsx +51 -0
  63. package/src/strings.ts +144 -0
  64. package/src/theme.ts +195 -0
  65. package/src/types.ts +320 -0
  66. package/styles.css +514 -0
package/src/policy.ts ADDED
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Presets as complete policy bundles (spec §5): `calm` (end-user, THE
3
+ * default) and `debug` (builder) are exported policy VALUES, not modes
4
+ * scattered through components. Every §3 knob lives here; the factories
5
+ * take partial overrides so a builder tunes one knob without forfeiting the
6
+ * rest of the preset.
7
+ */
8
+ import { defaultChatStrings, humanizeToolName, type ChatStrings } from "./strings.js";
9
+
10
+ export interface TranscriptPolicy {
11
+ /** The i18n seam — override any string without forking components (§4.2). */
12
+ strings: ChatStrings;
13
+ /** Chrome locale (a view's own locale rides the wave-2 hostContext instead). */
14
+ locale: string;
15
+ /**
16
+ * The debug master switch: raw-state suffixes on the status line, the
17
+ * #192 recovered marker, verbatim wire errors, raw prompt payloads, and
18
+ * R15's full pretty-printed payload all key off it.
19
+ */
20
+ debugDetail: boolean;
21
+ /** R0. */
22
+ userMessage: { retryAffordance: boolean };
23
+ /** R1 (markdown sanitization itself is the 3b renderer's security surface). */
24
+ text: { markdown: boolean };
25
+ /** R2. */
26
+ reasoning: { show: boolean; expandedByDefault: boolean };
27
+ /** R3. */
28
+ tool: {
29
+ expandByDefault: boolean;
30
+ argsVisible: boolean;
31
+ humanizeTitle: (wireName: string) => string;
32
+ };
33
+ /** R4 — `false` disables grouping entirely (debug's default). */
34
+ toolGroup: { threshold: number | false };
35
+ /** R5. */
36
+ dataResult: {
37
+ capRem: number;
38
+ prettyPrint: boolean;
39
+ alwaysShowBytes: boolean;
40
+ /** Preview bound — the plan never carries a full giant payload (fixture 6). */
41
+ previewChars: number;
42
+ };
43
+ /** R6 (sandbox overrides pass through to `<GuueyView>` in 3b). */
44
+ view: { timeoutMs: number };
45
+ /** R7. */
46
+ media: { inlineImageCapRem: number; chipOnly: boolean };
47
+ /** R8. */
48
+ code: { capRem: number; wrap: boolean };
49
+ /** R9. */
50
+ citations: { style: "chips" | "list" };
51
+ /** R10. */
52
+ prompt: { placement: "inline" | "modal"; rawPayload: boolean };
53
+ /**
54
+ * R11. `copyByCode` is the specced per-code copy knob (the directive's
55
+ * `errorCopy`, nested here so it doesn't stutter as `error.errorCopy`):
56
+ * an exact wire-code → sentence map that wins over everything else.
57
+ * `verbatimCodes` renders the SOURCE message instead of family copy for
58
+ * the listed codes — or for every error (`"all"`, the widget's #162
59
+ * posture: pod refusal bodies are already written for a reader, and
60
+ * client-side identity copy arrives code-less). Precedence per error:
61
+ * `copyByCode[code]` → verbatim source message (when matched and
62
+ * non-empty) → family copy. `verbatim` stays the DEBUG formatting knob
63
+ * (code-prefixed raw line under the notice), independent of voice.
64
+ */
65
+ error: {
66
+ verbatim: boolean;
67
+ copyByCode: Readonly<Record<string, string>>;
68
+ verbatimCodes: readonly string[] | "all";
69
+ };
70
+ /** R12 — thresholds are chosen-not-measured (§10-F6; 3b validates vs #188 data). */
71
+ status: { wakingMs: number; longStartMs: number };
72
+ /** R14. */
73
+ compaction: { show: boolean };
74
+ /** R15. */
75
+ unknown: { show: boolean; raw: boolean };
76
+ }
77
+
78
+ /** Deep-ish merge for the one level of nesting policies actually have. */
79
+ function withOverrides(base: TranscriptPolicy, overrides?: Partial<TranscriptPolicy>): TranscriptPolicy {
80
+ if (!overrides) return base;
81
+ return {
82
+ ...base,
83
+ ...overrides,
84
+ strings: { ...base.strings, ...(overrides.strings ?? {}) },
85
+ userMessage: { ...base.userMessage, ...(overrides.userMessage ?? {}) },
86
+ text: { ...base.text, ...(overrides.text ?? {}) },
87
+ reasoning: { ...base.reasoning, ...(overrides.reasoning ?? {}) },
88
+ tool: { ...base.tool, ...(overrides.tool ?? {}) },
89
+ toolGroup: { ...base.toolGroup, ...(overrides.toolGroup ?? {}) },
90
+ dataResult: { ...base.dataResult, ...(overrides.dataResult ?? {}) },
91
+ view: { ...base.view, ...(overrides.view ?? {}) },
92
+ media: { ...base.media, ...(overrides.media ?? {}) },
93
+ code: { ...base.code, ...(overrides.code ?? {}) },
94
+ citations: { ...base.citations, ...(overrides.citations ?? {}) },
95
+ prompt: { ...base.prompt, ...(overrides.prompt ?? {}) },
96
+ error: { ...base.error, ...(overrides.error ?? {}) },
97
+ status: { ...base.status, ...(overrides.status ?? {}) },
98
+ compaction: { ...base.compaction, ...(overrides.compaction ?? {}) },
99
+ unknown: { ...base.unknown, ...(overrides.unknown ?? {}) },
100
+ };
101
+ }
102
+
103
+ function calmBase(): TranscriptPolicy {
104
+ return {
105
+ strings: defaultChatStrings,
106
+ locale: "en",
107
+ debugDetail: false,
108
+ userMessage: { retryAffordance: true },
109
+ text: { markdown: true },
110
+ reasoning: { show: true, expandedByDefault: false },
111
+ tool: { expandByDefault: false, argsVisible: false, humanizeTitle: humanizeToolName },
112
+ toolGroup: { threshold: 2 },
113
+ dataResult: { capRem: 16, prettyPrint: true, alwaysShowBytes: false, previewChars: 2048 },
114
+ view: { timeoutMs: 8000 },
115
+ media: { inlineImageCapRem: 20, chipOnly: false },
116
+ code: { capRem: 16, wrap: false },
117
+ citations: { style: "chips" },
118
+ prompt: { placement: "inline", rawPayload: false },
119
+ error: { verbatim: false, copyByCode: {}, verbatimCodes: [] },
120
+ status: { wakingMs: 2500, longStartMs: 15_000 },
121
+ compaction: { show: true },
122
+ unknown: { show: true, raw: false },
123
+ };
124
+ }
125
+
126
+ /** The `calm` preset — the end-user default (spec §5). */
127
+ export function calmPolicy(overrides?: Partial<TranscriptPolicy>): TranscriptPolicy {
128
+ return withOverrides(calmBase(), overrides);
129
+ }
130
+
131
+ /** The `debug` preset — the builder surface (Studio's test chat, spec §5). */
132
+ export function debugPolicy(overrides?: Partial<TranscriptPolicy>): TranscriptPolicy {
133
+ const base = calmBase();
134
+ const debug: TranscriptPolicy = {
135
+ ...base,
136
+ debugDetail: true,
137
+ reasoning: { ...base.reasoning, expandedByDefault: true },
138
+ tool: { ...base.tool, expandByDefault: true, argsVisible: true },
139
+ toolGroup: { threshold: false },
140
+ dataResult: { ...base.dataResult, capRem: 32, alwaysShowBytes: true },
141
+ prompt: { ...base.prompt, rawPayload: true },
142
+ error: { ...base.error, verbatim: true },
143
+ unknown: { ...base.unknown, raw: true },
144
+ };
145
+ return withOverrides(debug, overrides);
146
+ }