@syncagent/react 0.1.6 → 0.1.7

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/dist/index.d.mts CHANGED
@@ -10,13 +10,16 @@ declare function SyncAgentProvider({ config, children, }: {
10
10
  declare function useSyncAgentClient(): SyncAgentClient;
11
11
 
12
12
  interface UseSyncAgentOptions {
13
- /** Pass a client directly instead of using the provider */
14
13
  client?: SyncAgentClient;
15
14
  }
16
15
  declare function useSyncAgent(options?: UseSyncAgentOptions): {
17
16
  messages: Message[];
18
17
  isLoading: boolean;
19
18
  error: Error | null;
19
+ status: {
20
+ step: string;
21
+ label: string;
22
+ } | null;
20
23
  sendMessage: (content: string) => Promise<void>;
21
24
  stop: () => void;
22
25
  reset: () => void;
package/dist/index.d.ts CHANGED
@@ -10,13 +10,16 @@ declare function SyncAgentProvider({ config, children, }: {
10
10
  declare function useSyncAgentClient(): SyncAgentClient;
11
11
 
12
12
  interface UseSyncAgentOptions {
13
- /** Pass a client directly instead of using the provider */
14
13
  client?: SyncAgentClient;
15
14
  }
16
15
  declare function useSyncAgent(options?: UseSyncAgentOptions): {
17
16
  messages: Message[];
18
17
  isLoading: boolean;
19
18
  error: Error | null;
19
+ status: {
20
+ step: string;
21
+ label: string;
22
+ } | null;
20
23
  sendMessage: (content: string) => Promise<void>;
21
24
  stop: () => void;
22
25
  reset: () => void;
package/dist/index.js CHANGED
@@ -63,6 +63,7 @@ function useSyncAgent(options = {}) {
63
63
  const [messages, setMessages] = (0, import_react2.useState)([]);
64
64
  const [isLoading, setIsLoading] = (0, import_react2.useState)(false);
65
65
  const [error, setError] = (0, import_react2.useState)(null);
66
+ const [status, setStatus] = (0, import_react2.useState)(null);
66
67
  const abortRef = (0, import_react2.useRef)(null);
67
68
  const sendMessage = (0, import_react2.useCallback)(
68
69
  async (content) => {
@@ -72,12 +73,14 @@ function useSyncAgent(options = {}) {
72
73
  setMessages(updated);
73
74
  setIsLoading(true);
74
75
  setError(null);
76
+ setStatus(null);
75
77
  const placeholder = { role: "assistant", content: "" };
76
78
  setMessages([...updated, placeholder]);
77
79
  abortRef.current = new AbortController();
78
80
  try {
79
81
  await client.chat(updated, {
80
82
  signal: abortRef.current.signal,
83
+ onStatus: (step, label) => setStatus({ step, label }),
81
84
  onToken: (token) => {
82
85
  placeholder.content += token;
83
86
  setMessages((prev) => {
@@ -87,6 +90,7 @@ function useSyncAgent(options = {}) {
87
90
  });
88
91
  },
89
92
  onComplete: (text) => {
93
+ setStatus(null);
90
94
  setMessages((prev) => {
91
95
  const next = [...prev];
92
96
  next[next.length - 1] = { role: "assistant", content: text };
@@ -105,6 +109,7 @@ function useSyncAgent(options = {}) {
105
109
  }
106
110
  } finally {
107
111
  setIsLoading(false);
112
+ setStatus(null);
108
113
  abortRef.current = null;
109
114
  }
110
115
  },
@@ -118,8 +123,9 @@ function useSyncAgent(options = {}) {
118
123
  setMessages([]);
119
124
  setError(null);
120
125
  setIsLoading(false);
126
+ setStatus(null);
121
127
  }, []);
122
- return { messages, isLoading, error, sendMessage, stop, reset };
128
+ return { messages, isLoading, error, status, sendMessage, stop, reset };
123
129
  }
124
130
 
125
131
  // src/chat.tsx
@@ -296,7 +302,7 @@ function ChatInner({
296
302
  style: customStyle,
297
303
  suggestions = ["Show all records", "Count total entries", "Show recent activity"]
298
304
  }) {
299
- const { messages, isLoading, error, sendMessage, stop, reset } = useSyncAgent();
305
+ const { messages, isLoading, error, status, sendMessage, stop, reset } = useSyncAgent();
300
306
  const [open, setOpen] = (0, import_react3.useState)(defaultOpen);
301
307
  const [input, setInput] = (0, import_react3.useState)("");
302
308
  const [ts] = (0, import_react3.useState)(() => /* @__PURE__ */ new Map());
@@ -365,7 +371,10 @@ function ChatInner({
365
371
  }, children: "\u2726" }),
366
372
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
367
373
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "white", fontWeight: 700, fontSize: 14, lineHeight: 1.2, letterSpacing: "-0.01em" }, children: title }),
368
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "rgba(255,255,255,.72)", fontSize: 11, marginTop: 1 }, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { animation: "sa-pulse 1.2s infinite" }, children: "\u25CF Thinking..." }) : subtitle })
374
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { color: "rgba(255,255,255,.72)", fontSize: 11, marginTop: 1 }, children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { animation: "sa-pulse 1.2s infinite" }, children: [
375
+ "\u25CF ",
376
+ status?.label || "Thinking..."
377
+ ] }) : subtitle })
369
378
  ] })
370
379
  ] }),
371
380
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: 4 }, children: [
@@ -457,6 +466,32 @@ function ChatInner({
457
466
  setInput(s);
458
467
  inputRef.current?.focus();
459
468
  }, accent: accentColor }),
469
+ isLoading && status && status.step !== "done" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
470
+ padding: "7px 14px",
471
+ borderTop: "1px solid #f0f4f8",
472
+ background: "#fafbfc",
473
+ display: "flex",
474
+ alignItems: "center",
475
+ gap: 8,
476
+ flexShrink: 0
477
+ }, children: [
478
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: { display: "flex", gap: 3 }, children: [0, 1, 2].map((i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { style: {
479
+ width: 5,
480
+ height: 5,
481
+ borderRadius: "50%",
482
+ background: accentColor,
483
+ animation: "sa-bounce 1.2s infinite",
484
+ animationDelay: `${i * 0.15}s`
485
+ } }, i)) }),
486
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { fontSize: 11.5, color: "#64748b", fontWeight: 500 }, children: [
487
+ status.step === "connecting" && "\u{1F50C} ",
488
+ status.step === "schema" && "\u{1F4CB} ",
489
+ status.step === "thinking" && "\u{1F9E0} ",
490
+ status.step === "querying" && "\u{1F50D} ",
491
+ status.step === "writing" && "\u270F\uFE0F ",
492
+ status.label
493
+ ] })
494
+ ] }),
460
495
  /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: {
461
496
  padding: "10px 12px 12px",
462
497
  borderTop: "1px solid #e8edf3",
package/dist/index.mjs CHANGED
@@ -34,6 +34,7 @@ function useSyncAgent(options = {}) {
34
34
  const [messages, setMessages] = useState([]);
35
35
  const [isLoading, setIsLoading] = useState(false);
36
36
  const [error, setError] = useState(null);
37
+ const [status, setStatus] = useState(null);
37
38
  const abortRef = useRef(null);
38
39
  const sendMessage = useCallback(
39
40
  async (content) => {
@@ -43,12 +44,14 @@ function useSyncAgent(options = {}) {
43
44
  setMessages(updated);
44
45
  setIsLoading(true);
45
46
  setError(null);
47
+ setStatus(null);
46
48
  const placeholder = { role: "assistant", content: "" };
47
49
  setMessages([...updated, placeholder]);
48
50
  abortRef.current = new AbortController();
49
51
  try {
50
52
  await client.chat(updated, {
51
53
  signal: abortRef.current.signal,
54
+ onStatus: (step, label) => setStatus({ step, label }),
52
55
  onToken: (token) => {
53
56
  placeholder.content += token;
54
57
  setMessages((prev) => {
@@ -58,6 +61,7 @@ function useSyncAgent(options = {}) {
58
61
  });
59
62
  },
60
63
  onComplete: (text) => {
64
+ setStatus(null);
61
65
  setMessages((prev) => {
62
66
  const next = [...prev];
63
67
  next[next.length - 1] = { role: "assistant", content: text };
@@ -76,6 +80,7 @@ function useSyncAgent(options = {}) {
76
80
  }
77
81
  } finally {
78
82
  setIsLoading(false);
83
+ setStatus(null);
79
84
  abortRef.current = null;
80
85
  }
81
86
  },
@@ -89,8 +94,9 @@ function useSyncAgent(options = {}) {
89
94
  setMessages([]);
90
95
  setError(null);
91
96
  setIsLoading(false);
97
+ setStatus(null);
92
98
  }, []);
93
- return { messages, isLoading, error, sendMessage, stop, reset };
99
+ return { messages, isLoading, error, status, sendMessage, stop, reset };
94
100
  }
95
101
 
96
102
  // src/chat.tsx
@@ -272,7 +278,7 @@ function ChatInner({
272
278
  style: customStyle,
273
279
  suggestions = ["Show all records", "Count total entries", "Show recent activity"]
274
280
  }) {
275
- const { messages, isLoading, error, sendMessage, stop, reset } = useSyncAgent();
281
+ const { messages, isLoading, error, status, sendMessage, stop, reset } = useSyncAgent();
276
282
  const [open, setOpen] = useState2(defaultOpen);
277
283
  const [input, setInput] = useState2("");
278
284
  const [ts] = useState2(() => /* @__PURE__ */ new Map());
@@ -341,7 +347,10 @@ function ChatInner({
341
347
  }, children: "\u2726" }),
342
348
  /* @__PURE__ */ jsxs("div", { children: [
343
349
  /* @__PURE__ */ jsx2("div", { style: { color: "white", fontWeight: 700, fontSize: 14, lineHeight: 1.2, letterSpacing: "-0.01em" }, children: title }),
344
- /* @__PURE__ */ jsx2("div", { style: { color: "rgba(255,255,255,.72)", fontSize: 11, marginTop: 1 }, children: isLoading ? /* @__PURE__ */ jsx2("span", { style: { animation: "sa-pulse 1.2s infinite" }, children: "\u25CF Thinking..." }) : subtitle })
350
+ /* @__PURE__ */ jsx2("div", { style: { color: "rgba(255,255,255,.72)", fontSize: 11, marginTop: 1 }, children: isLoading ? /* @__PURE__ */ jsxs("span", { style: { animation: "sa-pulse 1.2s infinite" }, children: [
351
+ "\u25CF ",
352
+ status?.label || "Thinking..."
353
+ ] }) : subtitle })
345
354
  ] })
346
355
  ] }),
347
356
  /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 4 }, children: [
@@ -433,6 +442,32 @@ function ChatInner({
433
442
  setInput(s);
434
443
  inputRef.current?.focus();
435
444
  }, accent: accentColor }),
445
+ isLoading && status && status.step !== "done" && /* @__PURE__ */ jsxs("div", { style: {
446
+ padding: "7px 14px",
447
+ borderTop: "1px solid #f0f4f8",
448
+ background: "#fafbfc",
449
+ display: "flex",
450
+ alignItems: "center",
451
+ gap: 8,
452
+ flexShrink: 0
453
+ }, children: [
454
+ /* @__PURE__ */ jsx2("div", { style: { display: "flex", gap: 3 }, children: [0, 1, 2].map((i) => /* @__PURE__ */ jsx2("div", { style: {
455
+ width: 5,
456
+ height: 5,
457
+ borderRadius: "50%",
458
+ background: accentColor,
459
+ animation: "sa-bounce 1.2s infinite",
460
+ animationDelay: `${i * 0.15}s`
461
+ } }, i)) }),
462
+ /* @__PURE__ */ jsxs("span", { style: { fontSize: 11.5, color: "#64748b", fontWeight: 500 }, children: [
463
+ status.step === "connecting" && "\u{1F50C} ",
464
+ status.step === "schema" && "\u{1F4CB} ",
465
+ status.step === "thinking" && "\u{1F9E0} ",
466
+ status.step === "querying" && "\u{1F50D} ",
467
+ status.step === "writing" && "\u270F\uFE0F ",
468
+ status.label
469
+ ] })
470
+ ] }),
436
471
  /* @__PURE__ */ jsxs("div", { style: {
437
472
  padding: "10px 12px 12px",
438
473
  borderTop: "1px solid #e8edf3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncagent/react",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "SyncAgent React SDK — AI database chat widget & hooks",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",