inline-chat-kit 0.55.1 → 0.56.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.
- package/CHANGELOG.md +80 -0
- package/README.md +110 -2
- package/dist/Approval/Approval.d.ts +13 -2
- package/dist/Artifact/ArtifactPane.d.ts +1 -1
- package/dist/Attachments/Attachments.d.ts +2 -3
- package/dist/Branch/Branch.d.ts +2 -6
- package/dist/ChainOfThought/ChainOfThought.d.ts +2 -7
- package/dist/ChatExperience/ChatExperience.d.ts +47 -5
- package/dist/{ChatExperience-C2UXwrrI.js → ChatExperience-DCta8bv3.js} +2116 -1955
- package/dist/ChatExperience-DCta8bv3.js.map +1 -0
- package/dist/ChatInput/AddCardsOverlay.d.ts +20 -3
- package/dist/ChatInput/ChatInput.d.ts +10 -0
- package/dist/ChatTurnRow/ChatTurnRow.d.ts +36 -20
- package/dist/CodeBlock/CodeBlock.d.ts +3 -1
- package/dist/Context/Context.d.ts +2 -8
- package/dist/EmptyState/EmptyState.d.ts +1 -1
- package/dist/QuestionCard/QuestionCard.d.ts +2 -1
- package/dist/Reasoning/Reasoning.d.ts +2 -1
- package/dist/Sources/Sources.d.ts +2 -5
- package/dist/TaskList/TaskList.d.ts +2 -4
- package/dist/Tool/Tool.d.ts +2 -1
- package/dist/demo/ChatExperienceDemo.d.ts +4 -1
- package/dist/demo.js +4 -4
- package/dist/demo.js.map +1 -1
- package/dist/index.d.ts +6 -4
- package/dist/inline-chat-kit.css +1 -1
- package/dist/inline-chat-kit.js +8 -8
- package/dist/inline-chat-kit.js.map +1 -1
- package/dist/labels/labels.d.ts +254 -0
- package/dist/turnParts/turnParts.d.ts +29 -2
- package/dist/voice/useVoiceInput.d.ts +8 -1
- package/package.json +2 -2
- package/dist/ChatExperience-C2UXwrrI.js.map +0 -1
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Every word the kit says, in one place.
|
|
4
|
+
*
|
|
5
|
+
* The components each took a `labels` prop, and that was enough right up until
|
|
6
|
+
* somebody assembled them: `ChatExperience` and `ChatTurnRow` draw a dozen of
|
|
7
|
+
* them and passed none of it through, so a chat translated piece by piece still
|
|
8
|
+
* said "Copy", "Allow once" and "Thinking" in English. This is the one object
|
|
9
|
+
* that reaches all of them.
|
|
10
|
+
*
|
|
11
|
+
* Grouped by the component that says it, so a translator can find a string by
|
|
12
|
+
* looking at the screen. Every group is partial: what is left out stays the
|
|
13
|
+
* English default below. `{name}` in a value is filled in by the component —
|
|
14
|
+
* keep the placeholder, move it wherever the language wants it.
|
|
15
|
+
*
|
|
16
|
+
* What counts: text on screen, an `aria-label`, a `title`, a placeholder, text
|
|
17
|
+
* only a screen reader gets, and anything said through the live region.
|
|
18
|
+
* Everything a person sees or hears.
|
|
19
|
+
*/
|
|
20
|
+
export declare const defaultLabels: {
|
|
21
|
+
approval: {
|
|
22
|
+
once: string;
|
|
23
|
+
always: string;
|
|
24
|
+
deny: string;
|
|
25
|
+
allowedOnce: string;
|
|
26
|
+
allowedAlways: string;
|
|
27
|
+
wasDenied: string;
|
|
28
|
+
pending: string;
|
|
29
|
+
};
|
|
30
|
+
tool: {
|
|
31
|
+
input: string;
|
|
32
|
+
output: string;
|
|
33
|
+
error: string;
|
|
34
|
+
pending: string;
|
|
35
|
+
running: string;
|
|
36
|
+
done: string;
|
|
37
|
+
};
|
|
38
|
+
reasoning: {
|
|
39
|
+
thinking: string;
|
|
40
|
+
thought: string;
|
|
41
|
+
/** Followed by the duration: "Thought for 12s". */
|
|
42
|
+
thoughtFor: string;
|
|
43
|
+
};
|
|
44
|
+
chain: {
|
|
45
|
+
/** Followed by the count: "Thought through 4 steps". */
|
|
46
|
+
through: string;
|
|
47
|
+
step: string;
|
|
48
|
+
steps: string;
|
|
49
|
+
thinking: string;
|
|
50
|
+
};
|
|
51
|
+
tasks: {
|
|
52
|
+
pending: string;
|
|
53
|
+
running: string;
|
|
54
|
+
done: string;
|
|
55
|
+
error: string;
|
|
56
|
+
/** `{done}` and `{total}` are filled in. */
|
|
57
|
+
progress: string;
|
|
58
|
+
};
|
|
59
|
+
sources: {
|
|
60
|
+
title: string;
|
|
61
|
+
one: string;
|
|
62
|
+
many: string;
|
|
63
|
+
};
|
|
64
|
+
/** The marker in the prose, spoken as "Source 2: <title>". */
|
|
65
|
+
citation: {
|
|
66
|
+
cite: string;
|
|
67
|
+
};
|
|
68
|
+
answerActions: {
|
|
69
|
+
copy: string;
|
|
70
|
+
copied: string;
|
|
71
|
+
regenerate: string;
|
|
72
|
+
up: string;
|
|
73
|
+
down: string;
|
|
74
|
+
};
|
|
75
|
+
branch: {
|
|
76
|
+
previous: string;
|
|
77
|
+
next: string;
|
|
78
|
+
/** `{index}` and `{total}` are filled in. */
|
|
79
|
+
position: string;
|
|
80
|
+
};
|
|
81
|
+
context: {
|
|
82
|
+
name: string;
|
|
83
|
+
/** Between the two numbers: "128k of 1M". */
|
|
84
|
+
of: string;
|
|
85
|
+
tokens: string;
|
|
86
|
+
/** Said once it is past `warnAt`, and it should say what happens next. */
|
|
87
|
+
nearlyFull: string;
|
|
88
|
+
};
|
|
89
|
+
attachments: {
|
|
90
|
+
/** Followed by the file's name. */
|
|
91
|
+
remove: string;
|
|
92
|
+
};
|
|
93
|
+
question: {
|
|
94
|
+
next: string;
|
|
95
|
+
none: string;
|
|
96
|
+
edit: string;
|
|
97
|
+
/** The free-text row, when the question does not name its own. */
|
|
98
|
+
other: string;
|
|
99
|
+
/** The alphabet the options are lettered from, in order. */
|
|
100
|
+
letters: string;
|
|
101
|
+
};
|
|
102
|
+
questionGroup: {
|
|
103
|
+
/** After the count, in the folded row: "3 answers". */
|
|
104
|
+
answers: string;
|
|
105
|
+
};
|
|
106
|
+
/** The composer — the box you type in, and the bubble it becomes. */
|
|
107
|
+
input: {
|
|
108
|
+
placeholder: string;
|
|
109
|
+
send: string;
|
|
110
|
+
save: string;
|
|
111
|
+
stop: string;
|
|
112
|
+
cancelEdit: string;
|
|
113
|
+
/** The "+" that opens the menu. */
|
|
114
|
+
add: string;
|
|
115
|
+
closeMenu: string;
|
|
116
|
+
/** The three built-in menu entries. */
|
|
117
|
+
attach: string;
|
|
118
|
+
design: string;
|
|
119
|
+
connectors: string;
|
|
120
|
+
/** Under a sent message. */
|
|
121
|
+
copy: string;
|
|
122
|
+
edit: string;
|
|
123
|
+
readMore: string;
|
|
124
|
+
readLess: string;
|
|
125
|
+
/** The microphone, by what pressing it would do. */
|
|
126
|
+
dictate: string;
|
|
127
|
+
stopListening: string;
|
|
128
|
+
waitingForMicrophone: string;
|
|
129
|
+
cancelTranscription: string;
|
|
130
|
+
microphoneBlocked: string;
|
|
131
|
+
microphoneBlockedHelp: string;
|
|
132
|
+
};
|
|
133
|
+
/** Said through the live region while dictating, and shown when it fails. */
|
|
134
|
+
voice: {
|
|
135
|
+
listening: string;
|
|
136
|
+
stoppedListening: string;
|
|
137
|
+
transcribing: string;
|
|
138
|
+
nothingHeard: string;
|
|
139
|
+
transcriptAdded: string;
|
|
140
|
+
transcriptFailed: string;
|
|
141
|
+
refused: string;
|
|
142
|
+
notFound: string;
|
|
143
|
+
couldNotOpen: string;
|
|
144
|
+
};
|
|
145
|
+
header: {
|
|
146
|
+
back: string;
|
|
147
|
+
more: string;
|
|
148
|
+
};
|
|
149
|
+
highlighter: {
|
|
150
|
+
menu: string;
|
|
151
|
+
reply: string;
|
|
152
|
+
remove: string;
|
|
153
|
+
/** The invisible button per highlight, followed by its text. */
|
|
154
|
+
highlight: string;
|
|
155
|
+
/** `{count}` is filled in. */
|
|
156
|
+
countOne: string;
|
|
157
|
+
countMany: string;
|
|
158
|
+
/** Read when the answer takes focus: how to highlight without a pointer. */
|
|
159
|
+
keyboardHint: string;
|
|
160
|
+
};
|
|
161
|
+
thread: {
|
|
162
|
+
title: string;
|
|
163
|
+
save: string;
|
|
164
|
+
close: string;
|
|
165
|
+
/** Screen-reader only, before the quoted passage. */
|
|
166
|
+
on: string;
|
|
167
|
+
placeholder: string;
|
|
168
|
+
};
|
|
169
|
+
codeBlock: {
|
|
170
|
+
copy: string;
|
|
171
|
+
copyCode: string;
|
|
172
|
+
copied: string;
|
|
173
|
+
copiedAnnouncement: string;
|
|
174
|
+
};
|
|
175
|
+
pane: {
|
|
176
|
+
close: string;
|
|
177
|
+
expand: string;
|
|
178
|
+
collapse: string;
|
|
179
|
+
};
|
|
180
|
+
conversation: {
|
|
181
|
+
jump: string;
|
|
182
|
+
};
|
|
183
|
+
emptyState: {
|
|
184
|
+
suggestions: string;
|
|
185
|
+
};
|
|
186
|
+
/** What `ChatExperience` adds around the pieces. */
|
|
187
|
+
experience: {
|
|
188
|
+
title: string;
|
|
189
|
+
savedHighlights: string;
|
|
190
|
+
themeToLight: string;
|
|
191
|
+
themeToDark: string;
|
|
192
|
+
share: string;
|
|
193
|
+
selectionMode: string;
|
|
194
|
+
marker: string;
|
|
195
|
+
precise: string;
|
|
196
|
+
windowFull: string;
|
|
197
|
+
highlights: string;
|
|
198
|
+
close: string;
|
|
199
|
+
/** `{index}` is filled in. */
|
|
200
|
+
paragraph: string;
|
|
201
|
+
/** Said when a request starts. */
|
|
202
|
+
responding: string;
|
|
203
|
+
};
|
|
204
|
+
};
|
|
205
|
+
type Defaults = typeof defaultLabels;
|
|
206
|
+
/** Every string one component says, all required. */
|
|
207
|
+
export type LabelsOf<K extends keyof Defaults> = {
|
|
208
|
+
[S in keyof Defaults[K]]: string;
|
|
209
|
+
};
|
|
210
|
+
/**
|
|
211
|
+
* What a host passes: any component's group, any of its strings. The rest
|
|
212
|
+
* stay English.
|
|
213
|
+
*/
|
|
214
|
+
export type ChatLabels = {
|
|
215
|
+
[K in keyof Defaults]?: Partial<LabelsOf<K>>;
|
|
216
|
+
};
|
|
217
|
+
export type ApprovalLabels = LabelsOf<"approval">;
|
|
218
|
+
export type ToolLabels = LabelsOf<"tool">;
|
|
219
|
+
export type ReasoningLabels = LabelsOf<"reasoning">;
|
|
220
|
+
export type ChainLabels = LabelsOf<"chain">;
|
|
221
|
+
export type TaskListLabels = LabelsOf<"tasks">;
|
|
222
|
+
export type SourcesLabels = LabelsOf<"sources">;
|
|
223
|
+
export type AnswerActionsLabels = LabelsOf<"answerActions">;
|
|
224
|
+
export type BranchLabels = LabelsOf<"branch">;
|
|
225
|
+
export type ContextLabels = LabelsOf<"context">;
|
|
226
|
+
export type ChatInputLabels = LabelsOf<"input">;
|
|
227
|
+
export type VoiceLabels = LabelsOf<"voice">;
|
|
228
|
+
/**
|
|
229
|
+
* Hands a `ChatLabels` to every kit component beneath it.
|
|
230
|
+
*
|
|
231
|
+
* Through context rather than a prop on each row: `ChatTurnRow` is memoised,
|
|
232
|
+
* and a translation threaded through its props would be one more thing that
|
|
233
|
+
* had to stay referentially stable. It still has to be stable here — a new
|
|
234
|
+
* object in context re-renders every reader — so the value is keyed on the
|
|
235
|
+
* *contents*, and an object literal written inline in a host's render costs
|
|
236
|
+
* nothing after the first time.
|
|
237
|
+
*
|
|
238
|
+
* Nests: an inner provider overrides the outer one string by string.
|
|
239
|
+
*/
|
|
240
|
+
export declare function LabelsProvider({ labels, children, }: {
|
|
241
|
+
labels?: ChatLabels;
|
|
242
|
+
children?: ReactNode;
|
|
243
|
+
}): import("react").JSX.Element;
|
|
244
|
+
/**
|
|
245
|
+
* One component's strings: the English default, under whatever a
|
|
246
|
+
* `LabelsProvider` above says, under the component's own `labels` prop.
|
|
247
|
+
*
|
|
248
|
+
* The prop wins because it is the more specific of the two — somebody who
|
|
249
|
+
* wrote a string on one instance meant that instance.
|
|
250
|
+
*/
|
|
251
|
+
export declare function useLabels<K extends keyof Defaults>(group: K, local?: Partial<LabelsOf<K>>): LabelsOf<K>;
|
|
252
|
+
/** `"{done} of {total}"` → `"2 of 5"`. */
|
|
253
|
+
export declare function fill(template: string, values: Record<string, string | number>): string;
|
|
254
|
+
export {};
|
|
@@ -3,7 +3,7 @@ import { Thought } from '../ChainOfThought/ChainOfThought';
|
|
|
3
3
|
import { Source } from '../Sources/Sources';
|
|
4
4
|
import { Task } from '../TaskList/TaskList';
|
|
5
5
|
import { ToolState } from '../Tool/Tool';
|
|
6
|
-
import { Decision } from '../Approval/Approval';
|
|
6
|
+
import { ApprovalChoice, Decision } from '../Approval/Approval';
|
|
7
7
|
import { Answer, Question } from '../QuestionCard/types';
|
|
8
8
|
import { SystemTone } from '../SystemMessage/SystemMessage';
|
|
9
9
|
import { ArtifactKind, ArtifactState } from '../Artifact/ArtifactCard';
|
|
@@ -87,6 +87,12 @@ export type TurnPart = {
|
|
|
87
87
|
};
|
|
88
88
|
/** `null` or absent while it is still being asked. */
|
|
89
89
|
decision?: Decision | null;
|
|
90
|
+
/**
|
|
91
|
+
* Which answers are offered. All three when left out. Drop `"always"`
|
|
92
|
+
* where a standing permission means nothing — approving one edit to a
|
|
93
|
+
* plan, say — and "Allow once" stays the primary.
|
|
94
|
+
*/
|
|
95
|
+
choices?: ApprovalChoice[];
|
|
90
96
|
} | {
|
|
91
97
|
kind: "question";
|
|
92
98
|
id: string;
|
|
@@ -129,7 +135,28 @@ export type TurnPart = {
|
|
|
129
135
|
lang?: string;
|
|
130
136
|
content?: string;
|
|
131
137
|
state?: ArtifactState;
|
|
132
|
-
};
|
|
138
|
+
} | CustomPart;
|
|
139
|
+
/**
|
|
140
|
+
* A part the kit does not know how to draw, and the host does.
|
|
141
|
+
*
|
|
142
|
+
* Every other kind is a component in this package. This one is the host's:
|
|
143
|
+
* `type` says which of its own cards it is — `"plan-diff"`, `"send-request"` —
|
|
144
|
+
* and `data` is whatever that card needs. `<ChatTurnRow>` hands it to
|
|
145
|
+
* `renderPart` and draws what comes back, in its place among the other parts.
|
|
146
|
+
*
|
|
147
|
+
* Still data rather than JSX, for the reason the rest are: a stream can send
|
|
148
|
+
* `{ kind: "custom", id, type, data }` and cannot send a component. Merged by
|
|
149
|
+
* id like everything else, so `{ kind: "custom", id, data }` replaces `data`
|
|
150
|
+
* and leaves `type` alone.
|
|
151
|
+
*/
|
|
152
|
+
export interface CustomPart {
|
|
153
|
+
kind: "custom";
|
|
154
|
+
id: string;
|
|
155
|
+
/** Which of the host's cards this is. The kit never reads it. */
|
|
156
|
+
type: string;
|
|
157
|
+
/** Whatever that card needs. Replaced whole on an update, not merged. */
|
|
158
|
+
data?: unknown;
|
|
159
|
+
}
|
|
133
160
|
/**
|
|
134
161
|
* An update to a part, which is a part with everything optional but the two
|
|
135
162
|
* fields that say which one it is.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { RefObject } from 'react';
|
|
2
|
+
import { VoiceLabels } from '../labels/labels';
|
|
2
3
|
/**
|
|
3
4
|
* The microphone, and everything around turning it into text except the part
|
|
4
5
|
* that is a service.
|
|
@@ -63,6 +64,12 @@ export interface UseVoiceInputOptions {
|
|
|
63
64
|
* straight to the browser.
|
|
64
65
|
*/
|
|
65
66
|
meterRef?: RefObject<HTMLElement | null>;
|
|
67
|
+
/**
|
|
68
|
+
* What is said through the live region, and the errors it reports. English
|
|
69
|
+
* when left out. A hook cannot read a `LabelsProvider` the host renders
|
|
70
|
+
* below it, so `ChatInput` passes its own through here.
|
|
71
|
+
*/
|
|
72
|
+
labels?: Partial<VoiceLabels>;
|
|
66
73
|
}
|
|
67
74
|
export interface VoiceInput {
|
|
68
75
|
state: VoiceState;
|
|
@@ -76,4 +83,4 @@ export interface VoiceInput {
|
|
|
76
83
|
/** Forget a refusal, so the button can be offered again. */
|
|
77
84
|
reset: () => void;
|
|
78
85
|
}
|
|
79
|
-
export declare function useVoiceInput({ onTranscribe, onTranscript, onDone, meterRef, }: UseVoiceInputOptions): VoiceInput;
|
|
86
|
+
export declare function useVoiceInput({ onTranscribe, onTranscript, onDone, meterRef, labels, }: UseVoiceInputOptions): VoiceInput;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "inline-chat-kit",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "An inline AI chat experience for React. The input is the message: it morphs into the bubble, the answer streams beneath it, and the parts around it
|
|
3
|
+
"version": "0.56.0",
|
|
4
|
+
"description": "An inline AI chat experience for React. The input is the message: it morphs into the bubble, the answer streams beneath it, and the parts around it — tool calls, reasoning, questions, artifacts, dictation — come with it.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"react",
|
|
7
7
|
"chat",
|