@aigentyc/chat-sdk 0.1.3 → 0.2.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.
Files changed (45) hide show
  1. package/AGENTS.md +189 -0
  2. package/bin/doctor.mjs +255 -0
  3. package/dist/ai-elements.cjs +119 -162
  4. package/dist/ai-elements.cjs.map +1 -1
  5. package/dist/ai-elements.js +5 -60
  6. package/dist/ai-elements.js.map +1 -1
  7. package/dist/{chunk-PKGD6CTD.js → chunk-2677FDTG.js} +107 -59
  8. package/dist/chunk-2677FDTG.js.map +1 -0
  9. package/dist/{chunk-42ARGQXE.js → chunk-7L4FS6G7.js} +7 -3
  10. package/dist/chunk-7L4FS6G7.js.map +1 -0
  11. package/dist/{chunk-VS3NZ7FX.js → chunk-A7PCSWIK.js} +60 -5
  12. package/dist/chunk-A7PCSWIK.js.map +1 -0
  13. package/dist/{chunk-WZLWAVSS.cjs → chunk-C24QG43M.cjs} +10 -2
  14. package/dist/chunk-C24QG43M.cjs.map +1 -0
  15. package/dist/{chunk-NW2ESHRV.js → chunk-KVEJAPWA.js} +4 -8
  16. package/dist/chunk-KVEJAPWA.js.map +1 -0
  17. package/dist/{chunk-X5YEOOPK.cjs → chunk-QDFPJJ5Y.cjs} +5 -13
  18. package/dist/chunk-QDFPJJ5Y.cjs.map +1 -0
  19. package/dist/{chunk-FQN6OBGN.cjs → chunk-RTVEBPAJ.cjs} +63 -4
  20. package/dist/chunk-RTVEBPAJ.cjs.map +1 -0
  21. package/dist/{chunk-IWIGM3RY.cjs → chunk-WQARQ2FJ.cjs} +109 -61
  22. package/dist/chunk-WQARQ2FJ.cjs.map +1 -0
  23. package/dist/components.cjs +14 -14
  24. package/dist/components.d.cts +5 -0
  25. package/dist/components.d.ts +5 -0
  26. package/dist/components.js +4 -4
  27. package/dist/index.cjs +14 -12
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.d.cts +8 -1
  30. package/dist/index.d.ts +8 -1
  31. package/dist/index.js +8 -6
  32. package/dist/index.js.map +1 -1
  33. package/dist/llms-full.txt +769 -0
  34. package/dist/ui.cjs +51 -51
  35. package/dist/ui.js +2 -2
  36. package/llms.txt +323 -0
  37. package/package.json +10 -2
  38. package/dist/chunk-42ARGQXE.js.map +0 -1
  39. package/dist/chunk-FQN6OBGN.cjs.map +0 -1
  40. package/dist/chunk-IWIGM3RY.cjs.map +0 -1
  41. package/dist/chunk-NW2ESHRV.js.map +0 -1
  42. package/dist/chunk-PKGD6CTD.js.map +0 -1
  43. package/dist/chunk-VS3NZ7FX.js.map +0 -1
  44. package/dist/chunk-WZLWAVSS.cjs.map +0 -1
  45. package/dist/chunk-X5YEOOPK.cjs.map +0 -1
package/AGENTS.md ADDED
@@ -0,0 +1,189 @@
1
+ # AGENTS.md — @aigentyc/chat-sdk
2
+
3
+ Guide for AI coding assistants (Claude Code, Cursor, Windsurf, v0, Lovable, Bolt) using or contributing to this SDK. Humans: read `README.md` first.
4
+
5
+ **Live docs (always current):** https://context7.com/llmstxt/unpkg_aigentyc_chat-sdk_0_1_5_llms_txt/llms.txt
6
+
7
+ ---
8
+
9
+ ## What this package is
10
+
11
+ React 19 SDK for embedding an AI chat UI backed by the Aigentyc platform. Ships as a set of subpath exports so consumers only pull what they need.
12
+
13
+ - Package name: `@aigentyc/chat-sdk`
14
+ - Peer deps (required): `react>=19`, `react-dom>=19`
15
+ - Bundled internally (no install needed): `@ai-sdk/react`, `ai`
16
+ - Peer deps (optional, install only for that feature): `socket.io-client` (live chat), `recharts` (viz), `@json-render/*` + `zod` (json-render)
17
+ - SSR: all client components emit `"use client"`; safe for Next.js App Router.
18
+
19
+ ---
20
+
21
+ ## Canonical install + usage (paste-ready)
22
+
23
+ **New project?** Use the scaffolder — it's the lowest-risk path:
24
+
25
+ ```bash
26
+ npm create aigentyc-chat@latest my-app -- --template=next --project-id=YOUR_ID
27
+ ```
28
+
29
+ **Adding to an existing app:**
30
+
31
+ ```bash
32
+ npm install @aigentyc/chat-sdk
33
+ ```
34
+
35
+ ```tsx
36
+ import { Chat } from "@aigentyc/chat-sdk"
37
+ import "@aigentyc/chat-sdk/theme/styles.css"
38
+
39
+ export default function Page() {
40
+ return (
41
+ <Chat
42
+ projectId="YOUR_PROJECT_ID"
43
+ apiEndpoint="https://api.aigentyc.com"
44
+ apiKey="YOUR_API_KEY"
45
+ />
46
+ )
47
+ }
48
+ ```
49
+
50
+ **Required:** the CSS import. Without it the chat renders unstyled.
51
+
52
+ ---
53
+
54
+ ## Decision tree: which API to use
55
+
56
+ ```
57
+ Need a full chat UI with zero config? → <Chat />
58
+ Need a floating bubble widget? → <ChatWidget />
59
+ Need to customize header/input/messages only? → <Chat slots={{...}} />
60
+ Need custom layout around the chat? → <ChatProvider> + <ChatInterface /> + <ChatInput />
61
+ Need your own UI entirely? → useAigentycChat() (headless)
62
+ Need to override one tool's rendering? → slots.tools[toolName]
63
+ ```
64
+
65
+ Don't reach for the headless hook just to change styling — use `theme` or `slots` first.
66
+
67
+ ---
68
+
69
+ ## Entry points (import from these, never from `dist/`)
70
+
71
+ | Import | What you get |
72
+ | --- | --- |
73
+ | `@aigentyc/chat-sdk` | `Chat`, `ChatWidget`, `ChatProvider` |
74
+ | `@aigentyc/chat-sdk/hooks` | `useAigentycChat`, other hooks |
75
+ | `@aigentyc/chat-sdk/components` | Granular composable chat pieces |
76
+ | `@aigentyc/chat-sdk/ai-elements` | `Message`, `Conversation` primitives |
77
+ | `@aigentyc/chat-sdk/tools` | `ToolRenderer`, `VisualizationRenderer` |
78
+ | `@aigentyc/chat-sdk/json-render` | json-render integration |
79
+ | `@aigentyc/chat-sdk/ui` | shadcn-style primitives |
80
+ | `@aigentyc/chat-sdk/theme` | `ThemeProvider`; CSS at `.../theme/styles.css` |
81
+ | `@aigentyc/chat-sdk/i18n` | `addLanguage`, built-in `en`, `he` |
82
+ | `@aigentyc/chat-sdk/core` | Types, transport, utilities |
83
+
84
+ ---
85
+
86
+ ## Slots
87
+
88
+ `slots` prop on `<Chat>` / `<ChatWidget>`:
89
+
90
+ - `header`, `welcome`, `message`, `input`, `footer`, `loader`, `suggestions`
91
+ - `tools`: `Record<toolName, ComponentType>` — override per-tool rendering
92
+
93
+ Each slot receives typed props — consult `.d.ts` of the entry points for exact signatures. Don't invent prop names.
94
+
95
+ ---
96
+
97
+ ## Tool rendering
98
+
99
+ Tool results come back from the backend with a `uiRenderMode`:
100
+
101
+ - `visualization` → recharts (requires `recharts` peer)
102
+ - `json_render` → `@json-render/shadcn` (requires `@json-render/*` + `zod` peers)
103
+ - `legacy` → HTML/CSS template from backend
104
+ - `preset` → built-in renderer
105
+
106
+ If a peer is missing, that tool's UI falls back; install the peer or override via `slots.tools[name]`.
107
+
108
+ ---
109
+
110
+ ## Theming
111
+
112
+ CSS variables scoped under `[data-aigentyc-chat]`. Two ways to customize:
113
+
114
+ ```tsx
115
+ <Chat theme={{ primaryColor: "#3b82f6" }} />
116
+ ```
117
+
118
+ or plain CSS targeting `[data-aigentyc-chat]`. Do **not** edit `dist/styles.css` directly.
119
+
120
+ ---
121
+
122
+ ## i18n
123
+
124
+ Built-in: `en`, `he`. Add more:
125
+
126
+ ```tsx
127
+ import { addLanguage } from "@aigentyc/chat-sdk/i18n"
128
+ addLanguage("fr", { welcomeTitle: "Bienvenue" })
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Live chat handoff
134
+
135
+ ```tsx
136
+ <Chat enableLiveChat chatServiceUrl="wss://..." />
137
+ ```
138
+
139
+ Requires `socket.io-client`. Omit both props for AI-only mode.
140
+
141
+ ---
142
+
143
+ ## Rules for agents editing consumer projects
144
+
145
+ **Do:**
146
+ - Use the canonical quick start above verbatim for first-time setup.
147
+ - Import CSS once, at the app root or layout file.
148
+ - Prefer `slots` + `theme` before going headless.
149
+ - Use React 19 features (Actions, `use`) — this SDK targets React 19.
150
+ - Check `.d.ts` files under the published package for exact prop types.
151
+
152
+ **Don't:**
153
+ - Don't install React 18 — peer is `>=19`. If the project is on React 18, warn the user and stop.
154
+ - Don't import from `@aigentyc/chat-sdk/dist/*` — those paths are not public API.
155
+ - Don't reimplement message rendering when `slots.message` exists.
156
+ - Don't call the Aigentyc API directly from the client — the SDK owns transport.
157
+ - Don't add `"use client"` to files that wrap the SDK unnecessarily; it's already inside.
158
+ - Don't commit `apiKey` to source control; use env vars (`NEXT_PUBLIC_*` only if the project is OK exposing it; otherwise proxy through a server route).
159
+
160
+ ---
161
+
162
+ ## Troubleshooting quick table
163
+
164
+ | Symptom | Likely cause |
165
+ | --- | --- |
166
+ | Unstyled / broken layout | Missing `import "@aigentyc/chat-sdk/theme/styles.css"` |
167
+ | "Cannot find module @ai-sdk/react" | Stale install — delete `node_modules` and reinstall (these are now bundled) |
168
+ | Tool renders blank | Peer for that `uiRenderMode` not installed |
169
+ | SSR hydration warning | Wrapping `<Chat>` in a non-client component — it's fine, the SDK handles `"use client"` internally; check for other client-only code in the tree |
170
+ | React version error | Upgrade to React 19 |
171
+
172
+ ---
173
+
174
+ ## Repository layout (for contributors)
175
+
176
+ - `src/` — source; barrel files per entry point
177
+ - `dist/` — build output (tsup); do not edit
178
+ - `stories/` — Storybook
179
+ - `demo/` — local demo app (standalone Vite)
180
+ - `src/styles/index.css` — Tailwind entry compiled to `dist/styles.css`
181
+
182
+ Scripts: `pnpm build`, `pnpm storybook`, `pnpm test`, `pnpm lint`.
183
+
184
+ ---
185
+
186
+ ## Versioning
187
+
188
+ - Current: `0.1.0` (pre-1.0 — API may shift).
189
+ - Pin exact versions in consumer projects until 1.0.
package/bin/doctor.mjs ADDED
@@ -0,0 +1,255 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * aigentyc doctor — diagnose Aigentyc Chat SDK install issues.
4
+ *
5
+ * Run inside a project that uses @aigentyc/chat-sdk:
6
+ * npx aigentyc doctor
7
+ *
8
+ * Checks (in order):
9
+ * 1. Node >= 18
10
+ * 2. React >= 19 installed
11
+ * 3. @aigentyc/chat-sdk installed + version
12
+ * 4. CSS imported somewhere in source
13
+ * 5. Env vars (PROJECT_ID, API_ENDPOINT) present
14
+ * 6. API endpoint reachable
15
+ * 7. API key (if present) authorized for project
16
+ * 8. CORS allowed-origins includes localhost dev URL (best-effort)
17
+ *
18
+ * Exit code: 0 on all-pass, 1 if any check failed.
19
+ */
20
+
21
+ import { readFile, readdir, stat } from "node:fs/promises";
22
+ import { existsSync } from "node:fs";
23
+ import { resolve, join } from "node:path";
24
+
25
+ const argv = process.argv.slice(2);
26
+ const sub = argv[0];
27
+ if (sub && sub !== "doctor") {
28
+ console.error(`Unknown command: ${sub}\nUsage: npx aigentyc doctor`);
29
+ process.exit(2);
30
+ }
31
+
32
+ const CWD = process.cwd();
33
+ const C = {
34
+ dim: (s) => `\x1b[2m${s}\x1b[0m`,
35
+ red: (s) => `\x1b[31m${s}\x1b[0m`,
36
+ green: (s) => `\x1b[32m${s}\x1b[0m`,
37
+ yellow: (s) => `\x1b[33m${s}\x1b[0m`,
38
+ bold: (s) => `\x1b[1m${s}\x1b[0m`,
39
+ };
40
+
41
+ const results = [];
42
+ function pass(msg, hint) { results.push({ status: "ok", msg, hint }); }
43
+ function warn(msg, hint) { results.push({ status: "warn", msg, hint }); }
44
+ function fail(msg, hint) { results.push({ status: "fail", msg, hint }); }
45
+
46
+ // ---------------------------------------------------------------------------
47
+ // Helpers
48
+ // ---------------------------------------------------------------------------
49
+
50
+ async function readJson(path) {
51
+ try { return JSON.parse(await readFile(path, "utf8")); } catch { return null; }
52
+ }
53
+
54
+ async function readEnv() {
55
+ const candidates = [".env.local", ".env", ".env.development"];
56
+ const out = {};
57
+ for (const f of candidates) {
58
+ const path = join(CWD, f);
59
+ if (!existsSync(path)) continue;
60
+ const raw = await readFile(path, "utf8").catch(() => "");
61
+ for (const line of raw.split("\n")) {
62
+ const m = line.match(/^\s*([A-Z0-9_]+)\s*=\s*(.*)\s*$/);
63
+ if (!m) continue;
64
+ let v = m[2].trim();
65
+ if ((v.startsWith('"') && v.endsWith('"')) || (v.startsWith("'") && v.endsWith("'"))) {
66
+ v = v.slice(1, -1);
67
+ }
68
+ if (out[m[1]] === undefined) out[m[1]] = v;
69
+ }
70
+ }
71
+ return out;
72
+ }
73
+
74
+ async function* walk(dir, depth = 0) {
75
+ if (depth > 4) return;
76
+ let entries;
77
+ try { entries = await readdir(dir); } catch { return; }
78
+ for (const name of entries) {
79
+ if (name === "node_modules" || name === ".next" || name === "dist" || name.startsWith(".")) continue;
80
+ const full = join(dir, name);
81
+ let s;
82
+ try { s = await stat(full); } catch { continue; }
83
+ if (s.isDirectory()) {
84
+ yield* walk(full, depth + 1);
85
+ } else if (/\.(tsx?|jsx?|mjs|cjs)$/.test(name)) {
86
+ yield full;
87
+ }
88
+ }
89
+ }
90
+
91
+ async function findCssImport() {
92
+ for await (const file of walk(CWD)) {
93
+ const src = await readFile(file, "utf8").catch(() => "");
94
+ if (/@aigentyc\/chat-sdk\/theme\/styles\.css/.test(src)) {
95
+ return file;
96
+ }
97
+ }
98
+ return null;
99
+ }
100
+
101
+ function semverMajor(v) {
102
+ if (!v) return 0;
103
+ const m = String(v).match(/(\d+)/);
104
+ return m ? Number(m[1]) : 0;
105
+ }
106
+
107
+ async function pingEndpoint(url) {
108
+ const ctrl = new AbortController();
109
+ const t = setTimeout(() => ctrl.abort(), 5000);
110
+ try {
111
+ const res = await fetch(url, { method: "GET", signal: ctrl.signal });
112
+ clearTimeout(t);
113
+ return { ok: res.ok || res.status < 500, status: res.status };
114
+ } catch (err) {
115
+ clearTimeout(t);
116
+ return { ok: false, error: String(err?.message || err) };
117
+ }
118
+ }
119
+
120
+ // ---------------------------------------------------------------------------
121
+ // Checks
122
+ // ---------------------------------------------------------------------------
123
+
124
+ async function run() {
125
+ console.log(C.bold("\n aigentyc doctor"));
126
+ console.log(C.dim(` cwd: ${CWD}\n`));
127
+
128
+ // 1. Node version
129
+ const nodeMajor = Number(process.versions.node.split(".")[0]);
130
+ if (nodeMajor >= 18) pass(`Node ${process.versions.node}`);
131
+ else fail(`Node ${process.versions.node} (need >= 18)`, "Update Node: https://nodejs.org");
132
+
133
+ // 2. package.json + React + SDK
134
+ const pkg = await readJson(join(CWD, "package.json"));
135
+ if (!pkg) {
136
+ fail("No package.json found in current directory.", `Run from your project root.`);
137
+ return finish();
138
+ }
139
+ const deps = { ...pkg.dependencies, ...pkg.devDependencies };
140
+
141
+ const reactV = deps.react;
142
+ if (!reactV) fail("`react` not in dependencies.", "npm install react@^19 react-dom@^19");
143
+ else if (semverMajor(reactV) < 19)
144
+ fail(`React ${reactV} (need >= 19)`, "npm install react@^19 react-dom@^19");
145
+ else pass(`React ${reactV}`);
146
+
147
+ const sdkV = deps["@aigentyc/chat-sdk"];
148
+ if (!sdkV) {
149
+ fail("`@aigentyc/chat-sdk` not in dependencies.", "npm install @aigentyc/chat-sdk");
150
+ } else {
151
+ pass(`@aigentyc/chat-sdk ${sdkV}`);
152
+ }
153
+
154
+ // 3. CSS import
155
+ const cssFile = await findCssImport();
156
+ if (cssFile) pass(`CSS imported in ${cssFile.replace(CWD + "/", "")}`);
157
+ else fail(
158
+ "Missing CSS import.",
159
+ `Add to your entry/layout file:\n import "@aigentyc/chat-sdk/theme/styles.css"`
160
+ );
161
+
162
+ // 4. Env vars
163
+ const env = await readEnv();
164
+ const isNext = !!deps.next;
165
+ const prefix = isNext ? "NEXT_PUBLIC_AIGENTYC" : "VITE_AIGENTYC";
166
+
167
+ const projectId = env[`${prefix}_PROJECT_ID`];
168
+ const apiEndpoint = env[`${prefix}_API_ENDPOINT`];
169
+ const apiKey = env[`${prefix}_API_KEY`];
170
+
171
+ if (!projectId || projectId === "replace-me") {
172
+ fail(
173
+ `${prefix}_PROJECT_ID missing or placeholder.`,
174
+ "Get your projectId from https://app.aigentyc.ai/dashboard"
175
+ );
176
+ } else if (!/^proj_/.test(projectId)) {
177
+ warn(
178
+ `${prefix}_PROJECT_ID does not look like a project slug (expected proj_...).`,
179
+ `Got: ${projectId}`
180
+ );
181
+ } else {
182
+ pass(`${prefix}_PROJECT_ID = ${projectId}`);
183
+ }
184
+
185
+ if (!apiEndpoint) {
186
+ fail(
187
+ `${prefix}_API_ENDPOINT missing.`,
188
+ `Add ${prefix}_API_ENDPOINT=https://app.aigentyc.ai`
189
+ );
190
+ } else {
191
+ pass(`${prefix}_API_ENDPOINT = ${apiEndpoint}`);
192
+ }
193
+
194
+ if (apiKey) {
195
+ if (!/^tyco_pk_/.test(apiKey)) {
196
+ warn(
197
+ `${prefix}_API_KEY does not look like an Aigentyc key (expected tyco_pk_...).`,
198
+ `Got: ${apiKey.slice(0, 12)}...`
199
+ );
200
+ } else {
201
+ pass(`${prefix}_API_KEY = ${apiKey.slice(0, 12)}...`);
202
+ }
203
+ } else {
204
+ warn(
205
+ `${prefix}_API_KEY not set.`,
206
+ "OK if your project is public; required otherwise. Create one at https://app.aigentyc.ai/dashboard/<projectId>/api-keys"
207
+ );
208
+ }
209
+
210
+ // 5. Endpoint reachable
211
+ if (apiEndpoint) {
212
+ const ping = await pingEndpoint(apiEndpoint);
213
+ if (ping.ok) pass(`Reachable: ${apiEndpoint} (HTTP ${ping.status})`);
214
+ else fail(
215
+ `Cannot reach ${apiEndpoint}`,
216
+ ping.error ? `Network error: ${ping.error}` : `HTTP ${ping.status}`
217
+ );
218
+ }
219
+
220
+ // 6. CORS hint
221
+ const dev = isNext ? "http://localhost:3000" : "http://localhost:5173";
222
+ warn(
223
+ "CORS",
224
+ `Make sure your API key allows origin: ${dev} (set in dashboard → API Keys → Allowed Origins)`
225
+ );
226
+
227
+ finish();
228
+ }
229
+
230
+ function finish() {
231
+ console.log("");
232
+ let failed = 0;
233
+ for (const r of results) {
234
+ const tag =
235
+ r.status === "ok" ? C.green("✓") :
236
+ r.status === "warn" ? C.yellow("⚠") :
237
+ C.red("✗");
238
+ console.log(` ${tag} ${r.msg}`);
239
+ if (r.hint && r.status !== "ok") {
240
+ console.log(` ${C.dim(r.hint)}`);
241
+ }
242
+ if (r.status === "fail") failed++;
243
+ }
244
+ console.log("");
245
+ if (failed === 0) {
246
+ console.log(C.green(" All checks passed."));
247
+ console.log(C.dim(" Run `npm run dev` and your chat should work.\n"));
248
+ process.exit(0);
249
+ } else {
250
+ console.log(C.red(` ${failed} check${failed === 1 ? "" : "s"} failed. Fix the items above and rerun.\n`));
251
+ process.exit(1);
252
+ }
253
+ }
254
+
255
+ run();