simple-ai-sdk 1.0.47 → 1.1.3

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.
@@ -1 +1 @@
1
- {"version":3,"file":"useChatSession.d.ts","sourceRoot":"","sources":["../../src/client/useChatSession.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAIrB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAiKtB"}
1
+ {"version":3,"file":"useChatSession.d.ts","sourceRoot":"","sources":["../../src/client/useChatSession.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,qBAAqB,EACrB,oBAAoB,EAIrB,MAAM,YAAY,CAAC;AAKpB,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,qBAAqB,GAC7B,oBAAoB,CAgMtB"}
@@ -1,4 +1,5 @@
1
- import { useEffect, useSyncExternalStore, useCallback, useRef } from "react";
1
+ import { useEffect, useSyncExternalStore, useCallback, useRef, useMemo, } from "react";
2
+ import { ChatError } from "../shared/index.js";
2
3
  import { useAIStreamManager } from "./context.js";
3
4
  import { generateMessageId } from "../shared/generate-id.js";
4
5
  export function useChatSession(sessionId, options) {
@@ -108,6 +109,32 @@ export function useChatSession(sessionId, options) {
108
109
  const setMessages = useCallback((messages, options) => {
109
110
  manager.setMessages(sessionId, messages, options);
110
111
  }, [manager, sessionId]);
112
+ const lastMessage = session.messages.at(-1);
113
+ const lastMessageRole = lastMessage?.role;
114
+ const isLastMessageEmpty = !lastMessage?.content;
115
+ const error = useMemo(() => {
116
+ if (session.finishedReason === "content_filter") {
117
+ return new ChatError("content_filter");
118
+ }
119
+ if (session.status === "aborted") {
120
+ return new ChatError("aborted");
121
+ }
122
+ // 何らかの理由で readyなのに assistant の応答がないまま止まっている
123
+ if (session.status === "ready") {
124
+ if (!lastMessageRole ||
125
+ lastMessageRole === "user" ||
126
+ isLastMessageEmpty) {
127
+ return new ChatError("no_response");
128
+ }
129
+ }
130
+ return session.error;
131
+ }, [
132
+ session.error,
133
+ session.finishedReason,
134
+ session.status,
135
+ lastMessageRole,
136
+ isLastMessageEmpty,
137
+ ]);
111
138
  return {
112
139
  messages: session.messages,
113
140
  metadata: session.metadata ?? [],
@@ -115,7 +142,7 @@ export function useChatSession(sessionId, options) {
115
142
  finishedReason: session.finishedReason ?? null,
116
143
  messagesVersion: session.messagesVersion ?? 0,
117
144
  status: session.status,
118
- error: session.error,
145
+ error,
119
146
  setMessages,
120
147
  sendMessage,
121
148
  reload,
@@ -1,2 +1,12 @@
1
1
  export declare function isAbortError(e: unknown): boolean;
2
+ /**
3
+ * - `content_filter`: The content was filtered by the content filter.
4
+ * - `aborted`: The request was aborted, likely by the user.
5
+ * - `no_response`: The model did not return a response. (not loading or streaming && last message is by the user)
6
+ */
7
+ export type ChatErrorCode = "content_filter" | "aborted" | "no_response";
8
+ export declare class ChatError extends Error {
9
+ readonly code: ChatErrorCode;
10
+ constructor(code: ChatErrorCode, message?: string);
11
+ }
2
12
  //# sourceMappingURL=error-utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../../src/shared/error-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAYhD"}
1
+ {"version":3,"file":"error-utils.d.ts","sourceRoot":"","sources":["../../src/shared/error-utils.ts"],"names":[],"mappings":"AAAA,wBAAgB,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAYhD;AAED;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,gBAAgB,GAAG,SAAS,GAAG,aAAa,CAAC;AAEzE,qBAAa,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAC,IAAI,EAAE,aAAa,CAAC;gBAEjB,IAAI,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,MAAM;CAKlD"}
@@ -9,3 +9,11 @@ export function isAbortError(e) {
9
9
  "code" in e &&
10
10
  e.code === "ABORT_ERR"));
11
11
  }
12
+ export class ChatError extends Error {
13
+ code;
14
+ constructor(code, message) {
15
+ super(message ?? code);
16
+ this.code = code;
17
+ this.name = "ChatError";
18
+ }
19
+ }
@@ -1,4 +1,5 @@
1
1
  export * from "./types.js";
2
2
  export * from "./wire.js";
3
3
  export * from "./generate-id.js";
4
+ export { isAbortError, ChatError, type ChatErrorCode } from "./error-utils.js";
4
5
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,WAAW,CAAC;AAC1B,cAAc,kBAAkB,CAAC;AACjC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAC"}
@@ -1,3 +1,4 @@
1
1
  export * from "./types.js";
2
2
  export * from "./wire.js";
3
3
  export * from "./generate-id.js";
4
+ export { isAbortError, ChatError } from "./error-utils.js";
package/dist/spec.md CHANGED
@@ -396,6 +396,10 @@ type UseChatSessionReturn = {
396
396
  */
397
397
  messagesVersion: number
398
398
  status: ChatStatus
399
+ /**
400
+ * 既知ケースでは ChatError が入る(Error のサブクラス)。
401
+ * - code: "content_filter" | "aborted" | "no_response"
402
+ */
399
403
  error: Error | null
400
404
  /**
401
405
  * API を呼ばずに現在のセッションの messages を即時上書きする。
@@ -451,6 +455,7 @@ await Promise.all([
451
455
  - 複数購読時の優先: 同一 `sessionId` を複数コンポーネントが使用する場合、最後に登録された `onFinish` が有効です。
452
456
  - `onError` は per-call: `sendMessage`/`reload` 呼び出し時に渡されたハンドラが呼ばれます(最新保持は行いません)。
453
457
 
458
+
454
459
  ### ページ遷移前のセッション事前準備(`usePrefetchChatSession`)
455
460
 
456
461
  ページ遷移前にセッションを事前に初期化し、オプションでストリーミングを開始することで、遷移後の応答時間を短縮できます。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "simple-ai-sdk",
3
- "version": "1.0.47",
3
+ "version": "1.1.3",
4
4
  "private": false,
5
5
  "description": "Simple AI SDK for Hono / React19+ / OpenAI",
6
6
  "type": "module",
@@ -59,7 +59,9 @@
59
59
  "dev": "tsc --watch",
60
60
  "typecheck": "tsc --noEmit",
61
61
  "lint": "eslint .",
62
+ "pretest": "pnpm build",
62
63
  "test": "node --test test/**/*.test.mjs",
64
+ "test:types": "tsc --project test-types/tsconfig.json --noEmit",
63
65
  "publish-sdk": "npm version patch --no-git-tag-version && pnpm build && pnpm publish --no-git-checks --access public"
64
66
  }
65
67
  }