@stainless-api/docs-ai-chat 0.1.0-beta.6 → 0.1.0-beta.60
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 +264 -33
- package/ambient.d.ts +6 -0
- package/eslint.config.ts +2 -0
- package/package.json +8 -17
- package/plugin.tsx +2 -2
- package/src/DocsChat.tsx +60 -0
- package/src/api/client-id.ts +11 -0
- package/src/api/index.ts +72 -6
- package/src/api/schemas.ts +15 -0
- package/src/hook.ts +106 -75
- package/tsconfig.json +1 -1
- package/eslint.config.js +0 -2
- package/src/AiChat.module.css +0 -221
- package/src/AiChat.tsx +0 -84
- package/src/Trigger.tsx +0 -135
- package/src/components/ChatLog.tsx +0 -42
- package/src/components/ChatMessage.tsx +0 -43
- package/src/components/CodeBlock.tsx +0 -29
- package/src/components/ToolCall.tsx +0 -36
- package/src/components/hljs-github.css +0 -81
package/CHANGELOG.md
CHANGED
|
@@ -1,61 +1,292 @@
|
|
|
1
1
|
# @stainless-api/docs-ai-chat
|
|
2
2
|
|
|
3
|
-
## 0.1.0-beta.
|
|
3
|
+
## 0.1.0-beta.60
|
|
4
4
|
|
|
5
5
|
### Patch Changes
|
|
6
6
|
|
|
7
|
-
- Updated dependencies
|
|
8
|
-
- @stainless-api/docs@0.1.0-beta.
|
|
7
|
+
- Updated dependencies [005419c]
|
|
8
|
+
- @stainless-api/docs-ui@0.1.0-beta.89
|
|
9
9
|
|
|
10
|
-
## 0.1.0-beta.
|
|
10
|
+
## 0.1.0-beta.59
|
|
11
11
|
|
|
12
12
|
### Patch Changes
|
|
13
13
|
|
|
14
|
-
- Updated dependencies [
|
|
15
|
-
-
|
|
16
|
-
- @stainless-api/docs@0.1.0-beta.63
|
|
17
|
-
- @stainless-api/ui-primitives@0.1.0-beta.39
|
|
18
|
-
- @stainless-api/docs-ui@0.1.0-beta.52
|
|
14
|
+
- Updated dependencies [af5a5d7]
|
|
15
|
+
- @stainless-api/docs-ui@0.1.0-beta.88
|
|
19
16
|
|
|
20
|
-
## 0.1.0-beta.
|
|
17
|
+
## 0.1.0-beta.58
|
|
18
|
+
|
|
19
|
+
### Minor Changes
|
|
20
|
+
|
|
21
|
+
- f22893c: Add interactive examples to ai chat
|
|
22
|
+
|
|
23
|
+
### Patch Changes
|
|
24
|
+
|
|
25
|
+
- Updated dependencies [f22893c]
|
|
26
|
+
- @stainless-api/ai-chat@0.1.0-beta.13
|
|
27
|
+
|
|
28
|
+
## 0.1.0-beta.57
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [7701d8f]
|
|
33
|
+
- Updated dependencies [5460e81]
|
|
34
|
+
- @stainless-api/docs-ui@0.1.0-beta.87
|
|
35
|
+
|
|
36
|
+
## 0.1.0-beta.56
|
|
37
|
+
|
|
38
|
+
### Patch Changes
|
|
39
|
+
|
|
40
|
+
- Updated dependencies [d096f7d]
|
|
41
|
+
- @stainless-api/ai-chat@0.1.0-beta.12
|
|
42
|
+
|
|
43
|
+
## 0.1.0-beta.55
|
|
44
|
+
|
|
45
|
+
### Patch Changes
|
|
46
|
+
|
|
47
|
+
- Updated dependencies [848cff4]
|
|
48
|
+
- Updated dependencies [ea2b90c]
|
|
49
|
+
- @stainless-api/docs-ui@0.1.0-beta.86
|
|
50
|
+
- @stainless-api/ai-chat@0.1.0-beta.11
|
|
51
|
+
|
|
52
|
+
## 0.1.0-beta.54
|
|
53
|
+
|
|
54
|
+
### Patch Changes
|
|
55
|
+
|
|
56
|
+
- Updated dependencies [93a3767]
|
|
57
|
+
- @stainless-api/docs-ui@0.1.0-beta.85
|
|
58
|
+
|
|
59
|
+
## 0.1.0-beta.53
|
|
60
|
+
|
|
61
|
+
### Patch Changes
|
|
62
|
+
|
|
63
|
+
- Updated dependencies [438a593]
|
|
64
|
+
- @stainless-api/docs-ui@0.1.0-beta.84
|
|
65
|
+
|
|
66
|
+
## 0.1.0-beta.52
|
|
67
|
+
|
|
68
|
+
### Patch Changes
|
|
69
|
+
|
|
70
|
+
- Updated dependencies [1c38511]
|
|
71
|
+
- @stainless-api/docs-ui@0.1.0-beta.83
|
|
72
|
+
|
|
73
|
+
## 0.1.0-beta.51
|
|
21
74
|
|
|
22
75
|
### Patch Changes
|
|
23
76
|
|
|
24
|
-
- Updated dependencies [
|
|
25
|
-
-
|
|
26
|
-
- Updated dependencies [aa9d333]
|
|
27
|
-
- Updated dependencies [07a2c87]
|
|
28
|
-
- @stainless-api/docs@0.1.0-beta.62
|
|
29
|
-
- @stainless-api/docs-ui@0.1.0-beta.51
|
|
30
|
-
- @stainless-api/ui-primitives@0.1.0-beta.38
|
|
77
|
+
- Updated dependencies [37cc2ac]
|
|
78
|
+
- @stainless-api/docs-ui@0.1.0-beta.82
|
|
31
79
|
|
|
32
|
-
## 0.1.0-beta.
|
|
80
|
+
## 0.1.0-beta.50
|
|
33
81
|
|
|
34
82
|
### Patch Changes
|
|
35
83
|
|
|
36
|
-
-
|
|
84
|
+
- Updated dependencies [134885b]
|
|
85
|
+
- Updated dependencies [5ba9135]
|
|
86
|
+
- Updated dependencies [df0c958]
|
|
87
|
+
- Updated dependencies [e641d33]
|
|
88
|
+
- @stainless-api/docs-ui@0.1.0-beta.81
|
|
37
89
|
|
|
38
|
-
## 0.1.0-beta.
|
|
90
|
+
## 0.1.0-beta.49
|
|
39
91
|
|
|
40
92
|
### Patch Changes
|
|
41
93
|
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
- Updated dependencies [2a79bae]
|
|
45
|
-
- Updated dependencies [88a9894]
|
|
46
|
-
- @stainless-api/ui-primitives@0.1.0-beta.38
|
|
47
|
-
- @stainless-api/docs@0.1.0-beta.61
|
|
48
|
-
- @stainless-api/docs-ui@0.1.0-beta.51
|
|
94
|
+
- Updated dependencies [05cd046]
|
|
95
|
+
- @stainless-api/docs-ui@0.1.0-beta.80
|
|
49
96
|
|
|
50
|
-
## 0.1.0-beta.
|
|
97
|
+
## 0.1.0-beta.48
|
|
98
|
+
|
|
99
|
+
### Patch Changes
|
|
100
|
+
|
|
101
|
+
- 8838d9f: remember presentation when window shrinks
|
|
102
|
+
- Updated dependencies [8838d9f]
|
|
103
|
+
- @stainless-api/ai-chat@0.1.0-beta.10
|
|
104
|
+
|
|
105
|
+
## 0.1.0-beta.47
|
|
106
|
+
|
|
107
|
+
### Minor Changes
|
|
108
|
+
|
|
109
|
+
- a8ed299: Adds the ability for AI chat to move into a sidebar “panel” position.
|
|
110
|
+
|
|
111
|
+
### Patch Changes
|
|
112
|
+
|
|
113
|
+
- Updated dependencies [5b3b798]
|
|
114
|
+
- Updated dependencies [a8ed299]
|
|
115
|
+
- @stainless-api/ai-chat@0.1.0-beta.9
|
|
116
|
+
|
|
117
|
+
## 0.1.0-beta.46
|
|
51
118
|
|
|
52
119
|
### Minor Changes
|
|
53
120
|
|
|
54
|
-
-
|
|
121
|
+
- 9d24589: Steelie empty state
|
|
122
|
+
- 5263b85: Loading state for ai chat
|
|
123
|
+
|
|
124
|
+
### Patch Changes
|
|
125
|
+
|
|
126
|
+
- 9d24589: Various steelie UI fixes
|
|
127
|
+
- Updated dependencies [9d24589]
|
|
128
|
+
- Updated dependencies [9d24589]
|
|
129
|
+
- Updated dependencies [5263b85]
|
|
130
|
+
- @stainless-api/ai-chat@0.1.0-beta.8
|
|
131
|
+
|
|
132
|
+
## 0.1.0-beta.45
|
|
133
|
+
|
|
134
|
+
### Patch Changes
|
|
135
|
+
|
|
136
|
+
- Updated dependencies [6d9933d]
|
|
137
|
+
- @stainless-api/docs-ui@0.1.0-beta.79
|
|
138
|
+
- @stainless-api/ai-chat@0.1.0-beta.7
|
|
139
|
+
|
|
140
|
+
## 0.1.0-beta.44
|
|
141
|
+
|
|
142
|
+
### Patch Changes
|
|
143
|
+
|
|
144
|
+
- Updated dependencies [54add64]
|
|
145
|
+
- @stainless-api/docs-ui@0.1.0-beta.78
|
|
146
|
+
|
|
147
|
+
## 0.1.0-beta.43
|
|
148
|
+
|
|
149
|
+
### Patch Changes
|
|
150
|
+
|
|
151
|
+
- Updated dependencies [21e50d3]
|
|
152
|
+
- @stainless-api/docs-ui@0.1.0-beta.77
|
|
153
|
+
|
|
154
|
+
## 0.1.0-beta.42
|
|
155
|
+
|
|
156
|
+
### Patch Changes
|
|
157
|
+
|
|
158
|
+
- Updated dependencies [95fe66c]
|
|
159
|
+
- Updated dependencies [5701494]
|
|
160
|
+
- @stainless-api/docs-ui@0.1.0-beta.76
|
|
161
|
+
- @stainless-api/ai-chat@0.1.0-beta.6
|
|
162
|
+
|
|
163
|
+
## 0.1.0-beta.41
|
|
164
|
+
|
|
165
|
+
### Patch Changes
|
|
166
|
+
|
|
167
|
+
- 6e762e2: fix steelie for multi-turn conversations
|
|
168
|
+
|
|
169
|
+
## 0.1.0-beta.40
|
|
170
|
+
|
|
171
|
+
### Patch Changes
|
|
172
|
+
|
|
173
|
+
- Updated dependencies [2919b0a]
|
|
174
|
+
- Updated dependencies [e005e5c]
|
|
175
|
+
- @stainless-api/docs-ui@0.1.0-beta.75
|
|
176
|
+
|
|
177
|
+
## 0.1.0-beta.39
|
|
178
|
+
|
|
179
|
+
### Patch Changes
|
|
180
|
+
|
|
181
|
+
- Updated dependencies [415629f]
|
|
182
|
+
- @stainless-api/docs-ui@0.1.0-beta.74
|
|
183
|
+
|
|
184
|
+
## 0.1.0-beta.38
|
|
185
|
+
|
|
186
|
+
### Patch Changes
|
|
187
|
+
|
|
188
|
+
- Updated dependencies [5c36876]
|
|
189
|
+
- @stainless-api/docs-ui@0.1.0-beta.73
|
|
190
|
+
|
|
191
|
+
## 0.1.0-beta.37
|
|
192
|
+
|
|
193
|
+
### Patch Changes
|
|
194
|
+
|
|
195
|
+
- Updated dependencies [6b86a8b]
|
|
196
|
+
- @stainless-api/docs-ui@0.1.0-beta.72
|
|
197
|
+
|
|
198
|
+
## 0.1.0-beta.36
|
|
199
|
+
|
|
200
|
+
### Patch Changes
|
|
201
|
+
|
|
202
|
+
- Updated dependencies [cd578b7]
|
|
203
|
+
- @stainless-api/docs-ui@0.1.0-beta.71
|
|
204
|
+
|
|
205
|
+
## 0.1.0-beta.35
|
|
206
|
+
|
|
207
|
+
### Patch Changes
|
|
208
|
+
|
|
209
|
+
- Updated dependencies [93c8f94]
|
|
210
|
+
- @stainless-api/docs-ui@0.1.0-beta.70
|
|
211
|
+
|
|
212
|
+
## 0.1.0-beta.34
|
|
213
|
+
|
|
214
|
+
### Patch Changes
|
|
215
|
+
|
|
216
|
+
- Updated dependencies [61ba36f]
|
|
217
|
+
- @stainless-api/docs-ui@0.1.0-beta.69
|
|
218
|
+
|
|
219
|
+
## 0.1.0-beta.33
|
|
220
|
+
|
|
221
|
+
### Patch Changes
|
|
222
|
+
|
|
223
|
+
- Updated dependencies [a3f1ede]
|
|
224
|
+
- @stainless-api/docs-ui@0.1.0-beta.68
|
|
225
|
+
|
|
226
|
+
## 0.1.0-beta.32
|
|
227
|
+
|
|
228
|
+
### Patch Changes
|
|
229
|
+
|
|
230
|
+
- @stainless-api/ai-chat@0.1.0-beta.5
|
|
231
|
+
- @stainless-api/docs-ui@0.1.0-beta.67
|
|
232
|
+
|
|
233
|
+
## 0.1.0-beta.31
|
|
234
|
+
|
|
235
|
+
### Patch Changes
|
|
236
|
+
|
|
237
|
+
- Updated dependencies [65a1c9b]
|
|
238
|
+
- Updated dependencies [4f1cee7]
|
|
239
|
+
- Updated dependencies [4c72a83]
|
|
240
|
+
- Updated dependencies [068469b]
|
|
241
|
+
- @stainless-api/docs-ui@0.1.0-beta.66
|
|
242
|
+
|
|
243
|
+
## 0.1.0-beta.30
|
|
244
|
+
|
|
245
|
+
### Patch Changes
|
|
246
|
+
|
|
247
|
+
- Updated dependencies [b62eb05]
|
|
248
|
+
- @stainless-api/docs-ui@0.1.0-beta.65
|
|
249
|
+
- @stainless-api/ai-chat@0.1.0-beta.4
|
|
250
|
+
|
|
251
|
+
## 0.1.0-beta.29
|
|
252
|
+
|
|
253
|
+
### Patch Changes
|
|
254
|
+
|
|
255
|
+
- Updated dependencies [52ece13]
|
|
256
|
+
- Updated dependencies [3411ffe]
|
|
257
|
+
- Updated dependencies [7439be7]
|
|
258
|
+
- @stainless-api/ai-chat@0.1.0-beta.3
|
|
259
|
+
- @stainless-api/docs-ui@0.1.0-beta.64
|
|
260
|
+
|
|
261
|
+
## 0.1.0-beta.28
|
|
262
|
+
|
|
263
|
+
### Patch Changes
|
|
264
|
+
|
|
265
|
+
- Updated dependencies [274cefc]
|
|
266
|
+
- @stainless-api/docs-ui@0.1.0-beta.63
|
|
267
|
+
|
|
268
|
+
## 0.1.0-beta.27
|
|
269
|
+
|
|
270
|
+
### Patch Changes
|
|
271
|
+
|
|
272
|
+
- Updated dependencies [6ef241e]
|
|
273
|
+
- Updated dependencies [d3a85b5]
|
|
274
|
+
- Updated dependencies [d3a85b5]
|
|
275
|
+
- Updated dependencies [2dcb5fb]
|
|
276
|
+
- @stainless-api/docs-ui@0.1.0-beta.62
|
|
277
|
+
|
|
278
|
+
## 0.1.0-beta.26
|
|
279
|
+
|
|
280
|
+
### Patch Changes
|
|
281
|
+
|
|
282
|
+
- Updated dependencies [7155fae]
|
|
283
|
+
- @stainless-api/ai-chat@0.1.0-beta.2
|
|
284
|
+
- @stainless-api/docs-ui@0.1.0-beta.61
|
|
285
|
+
|
|
286
|
+
## 0.1.0-beta.25
|
|
55
287
|
|
|
56
288
|
### Patch Changes
|
|
57
289
|
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
- @stainless-api/
|
|
61
|
-
- @stainless-api/ui-primitives@0.1.0-beta.37
|
|
290
|
+
- 5c257e2: separate steelie into separate packages
|
|
291
|
+
- Updated dependencies [9dda4cf]
|
|
292
|
+
- @stainless-api/ai-chat@0.1.0-beta.1
|
package/ambient.d.ts
CHANGED
|
@@ -2,3 +2,9 @@ declare module '*.module.css' {
|
|
|
2
2
|
const classes: { [key: string]: string };
|
|
3
3
|
export default classes;
|
|
4
4
|
}
|
|
5
|
+
|
|
6
|
+
declare module 'virtual:stl-docs-ai-chat-examples' {
|
|
7
|
+
import type { ExamplePrompt } from '@stainless-api/ai-chat/src/types';
|
|
8
|
+
|
|
9
|
+
export const examples: ExamplePrompt[] | undefined;
|
|
10
|
+
}
|
package/eslint.config.ts
ADDED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stainless-api/docs-ai-chat",
|
|
3
|
-
"version": "0.1.0-beta.
|
|
3
|
+
"version": "0.1.0-beta.60",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -8,25 +8,16 @@
|
|
|
8
8
|
"peerDependencies": {
|
|
9
9
|
"react": ">=19.0.0",
|
|
10
10
|
"react-dom": ">=19.0.0",
|
|
11
|
-
"@stainless-api/docs": "0.1.0-beta.
|
|
12
|
-
"@stainless-api/docs-ui": "0.1.0-beta.52",
|
|
13
|
-
"@stainless-api/ui-primitives": "0.1.0-beta.39"
|
|
11
|
+
"@stainless-api/docs-ui": "0.1.0-beta.89"
|
|
14
12
|
},
|
|
15
13
|
"dependencies": {
|
|
16
14
|
"@streamparser/json-whatwg": "^0.0.22",
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"motion": "^12.23.25",
|
|
20
|
-
"react": "^19.2.3",
|
|
21
|
-
"react-markdown": "^10.1.0",
|
|
22
|
-
"react-syntax-highlighter": "^16.1.0",
|
|
23
|
-
"remend": "^1.0.1",
|
|
24
|
-
"zod": "^4.1.13"
|
|
15
|
+
"zod": "^4.3.6",
|
|
16
|
+
"@stainless-api/ai-chat": "0.1.0-beta.13"
|
|
25
17
|
},
|
|
26
18
|
"devDependencies": {
|
|
27
|
-
"@types/react": "19.2.
|
|
19
|
+
"@types/react": "19.2.14",
|
|
28
20
|
"@types/react-dom": "^19.2.3",
|
|
29
|
-
"@types/react-syntax-highlighter": "^15.5.13",
|
|
30
21
|
"typescript": "5.9.3",
|
|
31
22
|
"@stainless/eslint-config": "0.1.0-beta.1"
|
|
32
23
|
},
|
|
@@ -34,12 +25,12 @@
|
|
|
34
25
|
"./plugin": {
|
|
35
26
|
"import": "./plugin.tsx"
|
|
36
27
|
},
|
|
37
|
-
"./src/
|
|
38
|
-
"import": "./src/
|
|
28
|
+
"./src/DocsChat.tsx": {
|
|
29
|
+
"import": "./src/DocsChat.tsx"
|
|
39
30
|
}
|
|
40
31
|
},
|
|
41
32
|
"scripts": {
|
|
42
|
-
"lint": "eslint .",
|
|
33
|
+
"lint": "eslint --flag unstable_native_nodejs_ts_config .",
|
|
43
34
|
"check:types": "tsc --noEmit"
|
|
44
35
|
}
|
|
45
36
|
}
|
package/plugin.tsx
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export default function
|
|
2
|
-
return { chatComponentPath: '@stainless-api/docs-ai-chat/src/
|
|
1
|
+
export default function docsChatPlugin() {
|
|
2
|
+
return { chatComponentPath: '@stainless-api/docs-ai-chat/src/DocsChat.tsx' };
|
|
3
3
|
}
|
package/src/DocsChat.tsx
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import AiChat from '@stainless-api/ai-chat/src/AiChat.tsx';
|
|
2
|
+
import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
3
|
+
import { setResponseMetadata, submitResponseFeedback } from './api';
|
|
4
|
+
import { useSyncExternalStore } from 'react';
|
|
5
|
+
import { useChat } from './hook';
|
|
6
|
+
|
|
7
|
+
const examplesPromise = import('virtual:stl-docs-ai-chat-examples')
|
|
8
|
+
.then((mod) => mod.examples)
|
|
9
|
+
.catch(() => undefined);
|
|
10
|
+
|
|
11
|
+
function onCopyMessage(spanId: string) {
|
|
12
|
+
setResponseMetadata(spanId, { copied_to_clipboard: 'true' }).catch(() => {});
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
async function rateMessage(spanId: string, rating: 'up' | 'down'): Promise<boolean> {
|
|
16
|
+
try {
|
|
17
|
+
const { success } = await submitResponseFeedback(spanId, { up: 1 as const, down: 0 as const }[rating]);
|
|
18
|
+
return success;
|
|
19
|
+
} catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export default function DocsChat({
|
|
25
|
+
projectId,
|
|
26
|
+
language,
|
|
27
|
+
siteTitle,
|
|
28
|
+
}: {
|
|
29
|
+
projectId: string;
|
|
30
|
+
language: DocsLanguage | undefined;
|
|
31
|
+
siteTitle: string | undefined;
|
|
32
|
+
}) {
|
|
33
|
+
const { chatMessages, sendMessage } = useChat({
|
|
34
|
+
projectId,
|
|
35
|
+
language: language ?? 'http',
|
|
36
|
+
siteTitle,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// panel mode is supported only on larger viewports
|
|
40
|
+
const supportsPanel = useSyncExternalStore(
|
|
41
|
+
(cb) => {
|
|
42
|
+
window.addEventListener('resize', cb);
|
|
43
|
+
return () => window.removeEventListener('resize', cb);
|
|
44
|
+
},
|
|
45
|
+
() => window.innerWidth >= 968,
|
|
46
|
+
() => false,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
return (
|
|
50
|
+
<AiChat
|
|
51
|
+
chatMessages={chatMessages}
|
|
52
|
+
sendMessage={sendMessage}
|
|
53
|
+
rateMessage={rateMessage}
|
|
54
|
+
onCopyMessage={onCopyMessage}
|
|
55
|
+
siteTitle={siteTitle}
|
|
56
|
+
promptExamples={examplesPromise}
|
|
57
|
+
supportsPanel={supportsPanel}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Identifier for tracking unique users in braintrust
|
|
3
|
+
*/
|
|
4
|
+
export function getClientId() {
|
|
5
|
+
let clientId = localStorage.getItem('stainless-client-id');
|
|
6
|
+
if (!clientId) {
|
|
7
|
+
clientId = crypto.randomUUID();
|
|
8
|
+
localStorage.setItem('stainless-client-id', clientId);
|
|
9
|
+
}
|
|
10
|
+
return clientId;
|
|
11
|
+
}
|
package/src/api/index.ts
CHANGED
|
@@ -1,9 +1,37 @@
|
|
|
1
1
|
import type { DocsLanguage } from '@stainless-api/docs-ui/routing';
|
|
2
2
|
import { JSONParser } from '@streamparser/json-whatwg';
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
type RequestBody,
|
|
5
|
+
responseChunk,
|
|
6
|
+
type FeedbackRequestBody,
|
|
7
|
+
feedbackResponseBody,
|
|
8
|
+
type MetadataRequestBody,
|
|
9
|
+
metadataResponseBody,
|
|
10
|
+
} from './schemas';
|
|
4
11
|
import { streamAsyncIterator } from './util';
|
|
12
|
+
import { getClientId } from './client-id';
|
|
5
13
|
|
|
6
|
-
export const
|
|
14
|
+
export const API_URL = new URL('https://app.stainless.com/api/');
|
|
15
|
+
export const CHAT_ENDPOINT = new URL('ai/get-agentic-help', API_URL);
|
|
16
|
+
|
|
17
|
+
export const FEEDBACK_ENDPOINT = (spanId: string) => new URL(`ai/agentic-help/${spanId}/score`, API_URL);
|
|
18
|
+
export const METADATA_ENDPOINT = (spanId: string) => new URL(`ai/agentic-help/${spanId}/metadata`, API_URL);
|
|
19
|
+
|
|
20
|
+
/** Context on what the user is currently viewing to pass to the agent */
|
|
21
|
+
function getPageContext({ siteTitle }: { siteTitle: string | undefined }) {
|
|
22
|
+
const { href } = window.location;
|
|
23
|
+
const markdownUrl = `${href.replace(/\/$/, '')}/index.md`;
|
|
24
|
+
const pageTitle = document.querySelector('h1')?.textContent;
|
|
25
|
+
return [
|
|
26
|
+
`The user is viewing a documentation page${siteTitle ? ` for ${siteTitle}` : ''}.`,
|
|
27
|
+
`- Content URL: ${markdownUrl}`,
|
|
28
|
+
pageTitle && `- Page title: “${pageTitle}”`,
|
|
29
|
+
// TODO: include stainless path here? does the agent know how to use it?
|
|
30
|
+
// TODO: pass more of the page content into context without the agent having to retrieve it
|
|
31
|
+
]
|
|
32
|
+
.filter(Boolean)
|
|
33
|
+
.join('\n');
|
|
34
|
+
}
|
|
7
35
|
|
|
8
36
|
/**
|
|
9
37
|
* Stream chat response from the server
|
|
@@ -14,15 +42,17 @@ export async function* getChatResponse(
|
|
|
14
42
|
project,
|
|
15
43
|
language,
|
|
16
44
|
priorMessages,
|
|
45
|
+
siteTitle,
|
|
17
46
|
}: {
|
|
18
47
|
query: string;
|
|
19
48
|
project: string;
|
|
20
49
|
language: DocsLanguage;
|
|
21
50
|
priorMessages: NonNullable<RequestBody['additionalContext']>['prior_messages'];
|
|
51
|
+
siteTitle: string | undefined;
|
|
22
52
|
},
|
|
23
53
|
abortSignal: AbortSignal,
|
|
24
54
|
) {
|
|
25
|
-
const
|
|
55
|
+
const res = await fetch(CHAT_ENDPOINT, {
|
|
26
56
|
method: 'POST',
|
|
27
57
|
headers: {
|
|
28
58
|
'Content-Type': 'application/json',
|
|
@@ -31,17 +61,53 @@ export async function* getChatResponse(
|
|
|
31
61
|
query,
|
|
32
62
|
sdk: { project, language },
|
|
33
63
|
stream: true,
|
|
34
|
-
additionalContext: {
|
|
64
|
+
additionalContext: {
|
|
65
|
+
prior_messages: priorMessages,
|
|
66
|
+
intent: getPageContext({ siteTitle }),
|
|
67
|
+
},
|
|
68
|
+
browser_id: getClientId(),
|
|
35
69
|
} satisfies RequestBody),
|
|
36
70
|
|
|
37
71
|
signal: abortSignal,
|
|
38
72
|
});
|
|
39
73
|
|
|
40
|
-
if (!
|
|
74
|
+
if (!res.ok || !res.body) throw new Error(`Chat request failed with status ${res.status}`);
|
|
41
75
|
|
|
42
76
|
const parser = new JSONParser({ separator: '\n', paths: ['$'] });
|
|
43
|
-
for await (const chunk of streamAsyncIterator(
|
|
77
|
+
for await (const chunk of streamAsyncIterator(res.body.pipeThrough(parser))) {
|
|
44
78
|
const chunkParsed = responseChunk.safeParse(chunk.value);
|
|
45
79
|
if (chunkParsed.success) yield chunkParsed.data;
|
|
46
80
|
}
|
|
47
81
|
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Attach a score to a response
|
|
85
|
+
*/
|
|
86
|
+
export async function submitResponseFeedback(spanId: string, score: 0 | 1) {
|
|
87
|
+
const res = await fetch(FEEDBACK_ENDPOINT(spanId), {
|
|
88
|
+
method: 'PUT',
|
|
89
|
+
headers: {
|
|
90
|
+
'Content-Type': 'application/json',
|
|
91
|
+
},
|
|
92
|
+
body: JSON.stringify({ score } satisfies FeedbackRequestBody),
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
if (!res.ok) throw new Error(`Feedback request failed with status ${res.status}`);
|
|
96
|
+
return feedbackResponseBody.parse(await res.json());
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Attach a score to a response
|
|
101
|
+
*/
|
|
102
|
+
export async function setResponseMetadata(spanId: string, metadata: Record<string, string>) {
|
|
103
|
+
const res = await fetch(METADATA_ENDPOINT(spanId), {
|
|
104
|
+
method: 'PUT',
|
|
105
|
+
headers: {
|
|
106
|
+
'Content-Type': 'application/json',
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify({ metadata } satisfies MetadataRequestBody),
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
if (!res.ok) throw new Error(`Metadata request failed with status ${res.status}`);
|
|
112
|
+
return metadataResponseBody.parse(await res.json());
|
|
113
|
+
}
|
package/src/api/schemas.ts
CHANGED
|
@@ -14,6 +14,7 @@ export const requestBody = z.object({
|
|
|
14
14
|
maxTokens: z.number().optional(),
|
|
15
15
|
})
|
|
16
16
|
.optional(),
|
|
17
|
+
session_id: z.string().optional(),
|
|
17
18
|
additionalContext: z
|
|
18
19
|
.object({
|
|
19
20
|
prior_messages: z.array(
|
|
@@ -28,6 +29,7 @@ export const requestBody = z.object({
|
|
|
28
29
|
errors: z.string().optional(),
|
|
29
30
|
})
|
|
30
31
|
.optional(),
|
|
32
|
+
browser_id: z.string().optional(),
|
|
31
33
|
});
|
|
32
34
|
export type RequestBody = z.input<typeof requestBody>;
|
|
33
35
|
|
|
@@ -48,6 +50,19 @@ export const responseChunk = z.discriminatedUnion('type', [
|
|
|
48
50
|
}),
|
|
49
51
|
z.object({
|
|
50
52
|
type: z.literal('done'),
|
|
53
|
+
span_id: z.string(),
|
|
54
|
+
}),
|
|
55
|
+
z.object({
|
|
56
|
+
type: z.literal('start_session'),
|
|
57
|
+
session_id: z.string(),
|
|
51
58
|
}),
|
|
52
59
|
]);
|
|
53
60
|
export type ResponseChunk = z.infer<typeof responseChunk>;
|
|
61
|
+
|
|
62
|
+
export const feedbackRequestBody = z.object({ score: z.number().min(0).max(1) });
|
|
63
|
+
export type FeedbackRequestBody = z.infer<typeof feedbackRequestBody>;
|
|
64
|
+
export const feedbackResponseBody = z.object({ success: z.boolean() });
|
|
65
|
+
|
|
66
|
+
export const metadataRequestBody = z.object({ metadata: z.record(z.string(), z.string()) });
|
|
67
|
+
export type MetadataRequestBody = z.infer<typeof metadataRequestBody>;
|
|
68
|
+
export const metadataResponseBody = z.object({ success: z.boolean() });
|