@eidentic/nextjs 0.1.4 → 0.1.6

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/README.md CHANGED
@@ -43,12 +43,15 @@ export const POST = withEidentic(agent);
43
43
  ```
44
44
 
45
45
  ```tsx
46
- // Any React component
47
- import { useChat } from "ai/react";
46
+ // Client component — Vercel AI SDK v5+
47
+ import { useChat } from "@ai-sdk/react";
48
48
 
49
49
  export function Chat() {
50
- const { messages, input, handleInputChange, handleSubmit } = useChat({ api: "/api/chat" });
51
- return (/* render messages and input */);
50
+ // `useChat` POSTs `{ messages: [...] }`; `withEidentic` reads the newest user message out of the
51
+ // box no `prepareSendMessagesRequest` / request transform needed. Pass a stable `sessionId`
52
+ // (via the transport body) so the agent persists and recalls the conversation across reloads.
53
+ const { messages, sendMessage } = useChat();
54
+ return null; // render `messages`; send with `sendMessage({ text })`
52
55
  }
53
56
  ```
54
57
 
package/dist/index.cjs CHANGED
@@ -29,6 +29,20 @@ function toHeaders(h) {
29
29
  if (h instanceof Headers) return h;
30
30
  return new Headers(h);
31
31
  }
32
+ function lastUserMessageText(messages) {
33
+ if (!Array.isArray(messages)) return void 0;
34
+ for (let i = messages.length - 1; i >= 0; i--) {
35
+ const m = messages[i];
36
+ if (!m || m.role !== void 0 && m.role !== "user") continue;
37
+ if (typeof m.content === "string" && m.content.trim() !== "") return m.content;
38
+ if (Array.isArray(m.parts)) {
39
+ const text = m.parts.filter((p) => p?.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
40
+ if (text.trim() !== "") return text;
41
+ }
42
+ return void 0;
43
+ }
44
+ return void 0;
45
+ }
32
46
  var DEFAULT_MAX_BODY_BYTES = 1048576;
33
47
  function withEidentic(agent, opts = {}) {
34
48
  const protocol = opts.protocol ?? "ai-sdk-ui";
@@ -93,10 +107,10 @@ function withEidentic(agent, opts = {}) {
93
107
  { status: 400, headers: { "Content-Type": "application/json" } }
94
108
  );
95
109
  }
96
- const input = body.input ?? body.message;
110
+ const input = body.input ?? body.message ?? lastUserMessageText(body.messages);
97
111
  if (typeof input !== "string" || input.trim() === "") {
98
112
  return new Response(
99
- JSON.stringify({ error: "Missing or invalid 'input' (or 'message') field" }),
113
+ JSON.stringify({ error: "Missing or invalid input \u2014 provide 'input', 'message', or a 'messages' array" }),
100
114
  { status: 400, headers: { "Content-Type": "application/json" } }
101
115
  );
102
116
  }
package/dist/index.d.cts CHANGED
@@ -143,14 +143,18 @@ interface WithEidenticOptions {
143
143
  *
144
144
  * ### Request body (JSON)
145
145
  *
146
- * | Field | Type | Required | Description |
147
- * |-------------|----------|----------|------------------------------------------|
148
- * | `input` | `string` | yes* | The user message |
149
- * | `message` | `string` | yes* | Alias for `input` (useChat default name) |
150
- * | `sessionId` | `string` | no | Resume an existing session |
151
- * | `userId` | `string` | no | User ID for memory scoping (see WARNING) |
152
- *
153
- * *One of `input` or `message` must be present and non-empty.
146
+ * | Field | Type | Required | Description |
147
+ * |-------------|----------------|----------|------------------------------------------------------|
148
+ * | `input` | `string` | yes* | The user message |
149
+ * | `message` | `string` | yes* | Alias for `input` |
150
+ * | `messages` | `UIMessage[]` | yes* | A `useChat` history — the newest user message is used |
151
+ * | `sessionId` | `string` | no | Resume an existing session |
152
+ * | `userId` | `string` | no | User ID for memory scoping (see WARNING) |
153
+ *
154
+ * *One of `input`, `message`, or a non-empty `messages` array must be present. The `messages`
155
+ * form is what Vercel's `useChat` POSTs by default, so the route works with `useChat` out of the
156
+ * box — no client-side request transform (e.g. `prepareSendMessagesRequest`) is needed. The agent
157
+ * reloads prior turns from the store via `sessionId`, so only the newest user message is read.
154
158
  *
155
159
  * WARNING: `userId` and `sessionId` in the request body are caller-controlled.
156
160
  * Always derive identity server-side via the `identify` option in multi-tenant
package/dist/index.d.ts CHANGED
@@ -143,14 +143,18 @@ interface WithEidenticOptions {
143
143
  *
144
144
  * ### Request body (JSON)
145
145
  *
146
- * | Field | Type | Required | Description |
147
- * |-------------|----------|----------|------------------------------------------|
148
- * | `input` | `string` | yes* | The user message |
149
- * | `message` | `string` | yes* | Alias for `input` (useChat default name) |
150
- * | `sessionId` | `string` | no | Resume an existing session |
151
- * | `userId` | `string` | no | User ID for memory scoping (see WARNING) |
152
- *
153
- * *One of `input` or `message` must be present and non-empty.
146
+ * | Field | Type | Required | Description |
147
+ * |-------------|----------------|----------|------------------------------------------------------|
148
+ * | `input` | `string` | yes* | The user message |
149
+ * | `message` | `string` | yes* | Alias for `input` |
150
+ * | `messages` | `UIMessage[]` | yes* | A `useChat` history — the newest user message is used |
151
+ * | `sessionId` | `string` | no | Resume an existing session |
152
+ * | `userId` | `string` | no | User ID for memory scoping (see WARNING) |
153
+ *
154
+ * *One of `input`, `message`, or a non-empty `messages` array must be present. The `messages`
155
+ * form is what Vercel's `useChat` POSTs by default, so the route works with `useChat` out of the
156
+ * box — no client-side request transform (e.g. `prepareSendMessagesRequest`) is needed. The agent
157
+ * reloads prior turns from the store via `sessionId`, so only the newest user message is read.
154
158
  *
155
159
  * WARNING: `userId` and `sessionId` in the request body are caller-controlled.
156
160
  * Always derive identity server-side via the `identify` option in multi-tenant
package/dist/index.js CHANGED
@@ -6,6 +6,20 @@ function toHeaders(h) {
6
6
  if (h instanceof Headers) return h;
7
7
  return new Headers(h);
8
8
  }
9
+ function lastUserMessageText(messages) {
10
+ if (!Array.isArray(messages)) return void 0;
11
+ for (let i = messages.length - 1; i >= 0; i--) {
12
+ const m = messages[i];
13
+ if (!m || m.role !== void 0 && m.role !== "user") continue;
14
+ if (typeof m.content === "string" && m.content.trim() !== "") return m.content;
15
+ if (Array.isArray(m.parts)) {
16
+ const text = m.parts.filter((p) => p?.type === "text" && typeof p.text === "string").map((p) => p.text).join("");
17
+ if (text.trim() !== "") return text;
18
+ }
19
+ return void 0;
20
+ }
21
+ return void 0;
22
+ }
9
23
  var DEFAULT_MAX_BODY_BYTES = 1048576;
10
24
  function withEidentic(agent, opts = {}) {
11
25
  const protocol = opts.protocol ?? "ai-sdk-ui";
@@ -70,10 +84,10 @@ function withEidentic(agent, opts = {}) {
70
84
  { status: 400, headers: { "Content-Type": "application/json" } }
71
85
  );
72
86
  }
73
- const input = body.input ?? body.message;
87
+ const input = body.input ?? body.message ?? lastUserMessageText(body.messages);
74
88
  if (typeof input !== "string" || input.trim() === "") {
75
89
  return new Response(
76
- JSON.stringify({ error: "Missing or invalid 'input' (or 'message') field" }),
90
+ JSON.stringify({ error: "Missing or invalid input \u2014 provide 'input', 'message', or a 'messages' array" }),
77
91
  { status: 400, headers: { "Content-Type": "application/json" } }
78
92
  );
79
93
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eidentic/nextjs",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "publishConfig": {
@@ -28,9 +28,9 @@
28
28
  "README.md"
29
29
  ],
30
30
  "dependencies": {
31
- "@eidentic/types": "0.2.1",
32
31
  "@eidentic/core": "0.2.2",
33
- "@eidentic/server": "0.2.2"
32
+ "@eidentic/types": "0.2.1",
33
+ "@eidentic/server": "0.2.3"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "next": ">=14"