@pikku/assistant-ui 0.12.1 → 0.12.2

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 CHANGED
@@ -1,5 +1,11 @@
1
1
  # @pikku/assistant-ui
2
2
 
3
+ ## 0.12.2
4
+
5
+ ### Patch Changes
6
+
7
+ - cc4a8e0: Show friendly error messages in agent chat instead of silently failing with a loading spinner
8
+
3
9
  ## 0.12.1
4
10
 
5
11
  ### Patch Changes
@@ -295,22 +295,51 @@ function createPikkuStreamingAdapter(optionsRef, pendingApprovalsRef, approvalDe
295
295
  }
296
296
  }
297
297
  }
298
- const response = yield __await(fetch(`${opts.api}/${opts.agentName}/stream`, {
299
- method: 'POST',
300
- headers: Object.assign({ 'Content-Type': 'application/json' }, opts.headers),
301
- body: JSON.stringify({
302
- agentName: opts.agentName,
303
- message: messageText,
304
- threadId: opts.threadId,
305
- resourceId: opts.resourceId,
306
- model: opts.model,
307
- temperature: opts.temperature,
308
- }),
309
- signal: abortSignal,
310
- credentials: opts.credentials,
311
- }));
298
+ let response;
299
+ try {
300
+ response = yield __await(fetch(`${opts.api}/${opts.agentName}/stream`, {
301
+ method: 'POST',
302
+ headers: Object.assign({ 'Content-Type': 'application/json' }, opts.headers),
303
+ body: JSON.stringify({
304
+ agentName: opts.agentName,
305
+ message: messageText,
306
+ threadId: opts.threadId,
307
+ resourceId: opts.resourceId,
308
+ model: opts.model,
309
+ temperature: opts.temperature,
310
+ }),
311
+ signal: abortSignal,
312
+ credentials: opts.credentials,
313
+ }));
314
+ }
315
+ catch (e) {
316
+ const msg = (e === null || e === void 0 ? void 0 : e.message) || 'Unknown error';
317
+ let errorText = 'Failed to connect to the agent.';
318
+ if (msg.includes('Failed to fetch') || msg.includes('NetworkError') || msg.includes('CORS')) {
319
+ errorText = 'Unable to reach the agent server. The deployment may be down or the URL may be incorrect.';
320
+ }
321
+ else if (msg.includes('abort')) {
322
+ return yield __await(void 0);
323
+ }
324
+ yield yield __await({ content: [{ type: 'text', text: `⚠️ ${errorText}` }] });
325
+ return yield __await(void 0);
326
+ }
312
327
  if (!response.ok || !response.body) {
313
- throw new Error(`Agent stream failed: ${response.status}`);
328
+ let errorText = `Request failed (${response.status}).`;
329
+ if (response.status === 401 || response.status === 403) {
330
+ errorText = 'Authentication error.';
331
+ }
332
+ else if (response.status === 404) {
333
+ errorText = 'Agent not found — the agent may not be configured for this project.';
334
+ }
335
+ else if (response.status === 502 || response.status === 503) {
336
+ errorText = 'The agent server is currently unavailable. Try again in a moment.';
337
+ }
338
+ else if (response.status === 429) {
339
+ errorText = 'Rate limited — too many requests. Please wait a moment.';
340
+ }
341
+ yield yield __await({ content: [{ type: 'text', text: `⚠️ ${errorText}` }] });
342
+ return yield __await(void 0);
314
343
  }
315
344
  const text = { value: '' };
316
345
  const toolCalls = [];
@@ -243,22 +243,51 @@ function createPikkuStreamingAdapter(optionsRef, pendingApprovalsRef, approvalDe
243
243
  }
244
244
  }
245
245
  }
246
- const response = await fetch(`${opts.api}/${opts.agentName}/stream`, {
247
- method: 'POST',
248
- headers: { 'Content-Type': 'application/json', ...opts.headers },
249
- body: JSON.stringify({
250
- agentName: opts.agentName,
251
- message: messageText,
252
- threadId: opts.threadId,
253
- resourceId: opts.resourceId,
254
- model: opts.model,
255
- temperature: opts.temperature,
256
- }),
257
- signal: abortSignal,
258
- credentials: opts.credentials,
259
- });
246
+ let response;
247
+ try {
248
+ response = await fetch(`${opts.api}/${opts.agentName}/stream`, {
249
+ method: 'POST',
250
+ headers: { 'Content-Type': 'application/json', ...opts.headers },
251
+ body: JSON.stringify({
252
+ agentName: opts.agentName,
253
+ message: messageText,
254
+ threadId: opts.threadId,
255
+ resourceId: opts.resourceId,
256
+ model: opts.model,
257
+ temperature: opts.temperature,
258
+ }),
259
+ signal: abortSignal,
260
+ credentials: opts.credentials,
261
+ });
262
+ }
263
+ catch (e) {
264
+ const msg = e?.message || 'Unknown error';
265
+ let errorText = 'Failed to connect to the agent.';
266
+ if (msg.includes('Failed to fetch') || msg.includes('NetworkError') || msg.includes('CORS')) {
267
+ errorText = 'Unable to reach the agent server. The deployment may be down or the URL may be incorrect.';
268
+ }
269
+ else if (msg.includes('abort')) {
270
+ return;
271
+ }
272
+ yield { content: [{ type: 'text', text: `⚠️ ${errorText}` }] };
273
+ return;
274
+ }
260
275
  if (!response.ok || !response.body) {
261
- throw new Error(`Agent stream failed: ${response.status}`);
276
+ let errorText = `Request failed (${response.status}).`;
277
+ if (response.status === 401 || response.status === 403) {
278
+ errorText = 'Authentication error.';
279
+ }
280
+ else if (response.status === 404) {
281
+ errorText = 'Agent not found — the agent may not be configured for this project.';
282
+ }
283
+ else if (response.status === 502 || response.status === 503) {
284
+ errorText = 'The agent server is currently unavailable. Try again in a moment.';
285
+ }
286
+ else if (response.status === 429) {
287
+ errorText = 'Rate limited — too many requests. Please wait a moment.';
288
+ }
289
+ yield { content: [{ type: 'text', text: `⚠️ ${errorText}` }] };
290
+ return;
262
291
  }
263
292
  const text = { value: '' };
264
293
  const toolCalls = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pikku/assistant-ui",
3
- "version": "0.12.1",
3
+ "version": "0.12.2",
4
4
  "author": "yasser.fadl@gmail.com",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -16,7 +16,8 @@
16
16
  "tsc": "tsc",
17
17
  "build:esm": "tsc -b && echo '{\"type\": \"module\"}' > dist/esm/package.json",
18
18
  "build:cjs": "tsc -b tsconfig.cjs.json && echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json",
19
- "build": "yarn build:esm && yarn build:cjs"
19
+ "build": "yarn build:esm && yarn build:cjs",
20
+ "prepublishOnly": "yarn build"
20
21
  },
21
22
  "dependencies": {
22
23
  "@assistant-ui/react": "^0.12.12",
@@ -351,23 +351,47 @@ function createPikkuStreamingAdapter(
351
351
  }
352
352
  }
353
353
 
354
- const response = await fetch(`${opts.api}/${opts.agentName}/stream`, {
355
- method: 'POST',
356
- headers: { 'Content-Type': 'application/json', ...opts.headers },
357
- body: JSON.stringify({
358
- agentName: opts.agentName,
359
- message: messageText,
360
- threadId: opts.threadId,
361
- resourceId: opts.resourceId,
362
- model: opts.model,
363
- temperature: opts.temperature,
364
- }),
365
- signal: abortSignal,
366
- credentials: opts.credentials,
367
- })
354
+ let response: Response
355
+ try {
356
+ response = await fetch(`${opts.api}/${opts.agentName}/stream`, {
357
+ method: 'POST',
358
+ headers: { 'Content-Type': 'application/json', ...opts.headers },
359
+ body: JSON.stringify({
360
+ agentName: opts.agentName,
361
+ message: messageText,
362
+ threadId: opts.threadId,
363
+ resourceId: opts.resourceId,
364
+ model: opts.model,
365
+ temperature: opts.temperature,
366
+ }),
367
+ signal: abortSignal,
368
+ credentials: opts.credentials,
369
+ })
370
+ } catch (e: any) {
371
+ const msg = e?.message || 'Unknown error'
372
+ let errorText = 'Failed to connect to the agent.'
373
+ if (msg.includes('Failed to fetch') || msg.includes('NetworkError') || msg.includes('CORS')) {
374
+ errorText = 'Unable to reach the agent server. The deployment may be down or the URL may be incorrect.'
375
+ } else if (msg.includes('abort')) {
376
+ return
377
+ }
378
+ yield { content: [{ type: 'text' as const, text: `⚠️ ${errorText}` }] }
379
+ return
380
+ }
368
381
 
369
382
  if (!response.ok || !response.body) {
370
- throw new Error(`Agent stream failed: ${response.status}`)
383
+ let errorText = `Request failed (${response.status}).`
384
+ if (response.status === 401 || response.status === 403) {
385
+ errorText = 'Authentication error.'
386
+ } else if (response.status === 404) {
387
+ errorText = 'Agent not found — the agent may not be configured for this project.'
388
+ } else if (response.status === 502 || response.status === 503) {
389
+ errorText = 'The agent server is currently unavailable. Try again in a moment.'
390
+ } else if (response.status === 429) {
391
+ errorText = 'Rate limited — too many requests. Please wait a moment.'
392
+ }
393
+ yield { content: [{ type: 'text' as const, text: `⚠️ ${errorText}` }] }
394
+ return
371
395
  }
372
396
 
373
397
  const text = { value: '' }