@xano-sdk/chatbot 1.0.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.
- package/AGENTS.md +437 -0
- package/LICENSE +21 -0
- package/README.md +697 -0
- package/dist/index.d.ts +1811 -0
- package/dist/index.js +1128 -0
- package/llms.txt +487 -0
- package/package.json +88 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1811 @@
|
|
|
1
|
+
import * as _xano_sdk from '@xano/sdk';
|
|
2
|
+
import { TableDef, LlmSettings, ToolsetToolEntry, InferRow, Xano, InferInput, InferResponse } from '@xano/sdk';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* The public configuration surface, plus the resolver that turns a caller's
|
|
6
|
+
* partial options into the fully-defaulted `ResolvedOptions` every def factory
|
|
7
|
+
* reads.
|
|
8
|
+
*
|
|
9
|
+
* Everything in this package is a **factory** rather than a module singleton,
|
|
10
|
+
* and `authTable` is why. `f.tableRef` resolves its target's guid eagerly, at
|
|
11
|
+
* column-construction time (core's `src/fields/catalog.ts` — `resolveRef("dbo",
|
|
12
|
+
* table)` runs inside the field builder), so a module-level `conversation` def
|
|
13
|
+
* would bake in one particular user reference the moment this module evaluated
|
|
14
|
+
* and could never be re-pointed by a later `registerChatbot` call.
|
|
15
|
+
*
|
|
16
|
+
* That divergence from `@xano-sdk/auth`'s layout costs the
|
|
17
|
+
* `import { conversationTable }` cherry-pick, and buys two things back. The
|
|
18
|
+
* obvious one is a configurable auth table. The subtler one is that the ~100
|
|
19
|
+
* lines of conflict guards in `@xano-sdk/auth`'s `register.ts` have no analogue
|
|
20
|
+
* here: those exist because `authenticationGroup` is a process-wide singleton a
|
|
21
|
+
* second `registerAuth` could silently retarget. Fresh defs per call cannot have
|
|
22
|
+
* that bug, so this package needs no cross-call agreement checks.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* The auth table, as this package accepts it: a `table()` def handle or a bare
|
|
27
|
+
* table name.
|
|
28
|
+
*
|
|
29
|
+
* Deliberately NARROWER than core's `AuthRef`, which also allows a raw numeric
|
|
30
|
+
* `dbo.id`. That escape hatch is unusable here: the same table is both the
|
|
31
|
+
* endpoints' `auth` (which takes a number happily) and the target of
|
|
32
|
+
* `conversation.user_id`, and `f.tableRef` resolves through `ObjectRef` —
|
|
33
|
+
* `string | { name, guid? }` — which has no numeric form. Accepting a number
|
|
34
|
+
* would mean silently dropping the foreign key or demanding a second option
|
|
35
|
+
* naming the same table twice, so it is refused at the type level instead.
|
|
36
|
+
*/
|
|
37
|
+
type ChatbotAuthTable = TableDef | string;
|
|
38
|
+
/**
|
|
39
|
+
* The LLM settings a caller may supply: core's `LlmSettings` with the run prompt
|
|
40
|
+
* removed from every member of the union.
|
|
41
|
+
*
|
|
42
|
+
* Distributive on purpose — a plain `Omit<LlmSettings, …>` on a union collapses it
|
|
43
|
+
* to the keys all members share, which would erase every provider-specific field
|
|
44
|
+
* and make `{ type: "anthropic", thinkingTokens }` a type error.
|
|
45
|
+
*
|
|
46
|
+
* The removal makes `llm.prompt` a COMPILE error rather than only a runtime one.
|
|
47
|
+
* `resolveOptions` still throws, because a JS caller (or options read from untyped
|
|
48
|
+
* config) reaches neither check — but a TypeScript author finds out at the call
|
|
49
|
+
* site, which is the whole point of the package being typed.
|
|
50
|
+
*
|
|
51
|
+
* ⚠ The two banned keys are re-declared as `?: never` rather than merely
|
|
52
|
+
* `Omit`ted. Omission alone makes the rejection an EXCESS-PROPERTY check, which
|
|
53
|
+
* fires for a direct object-literal assignment and silently stops firing the
|
|
54
|
+
* moment the argument is inferred into a generic type parameter — as it now is,
|
|
55
|
+
* so `createChatbot`/`registerChatbot` can tell which endpoint families a given
|
|
56
|
+
* options object produces. `?: never` is a real assignability failure and
|
|
57
|
+
* survives that inference.
|
|
58
|
+
*/
|
|
59
|
+
type ChatbotLlmOptions = LlmSettings extends infer U ? U extends unknown ? Partial<Omit<U, "prompt" | "messages">> & {
|
|
60
|
+
prompt?: never;
|
|
61
|
+
messages?: never;
|
|
62
|
+
} : never : never;
|
|
63
|
+
/**
|
|
64
|
+
* Per-caller rate limiting on the endpoints that invoke the model.
|
|
65
|
+
*
|
|
66
|
+
* ON by default, because the guest family is **public and every send costs an
|
|
67
|
+
* LLM call** — an unauthenticated, metered endpoint with no ceiling is the one
|
|
68
|
+
* configuration a turnkey package should never ship. Same reasoning as request
|
|
69
|
+
* history being off by default.
|
|
70
|
+
*
|
|
71
|
+
* Applied to the two `send` endpoints and to `guest/conversations/create` (the
|
|
72
|
+
* only unauthenticated write). Reads are not limited: they are cheap and
|
|
73
|
+
* limiting them mostly breaks legitimate UIs.
|
|
74
|
+
*
|
|
75
|
+
* Keys are per caller and per install:
|
|
76
|
+
*
|
|
77
|
+
* - authenticated → `auth("id")`, a real identity;
|
|
78
|
+
* - guest → `sys.remoteIp()`, because `auth()` is null on a public endpoint and
|
|
79
|
+
* every caller would otherwise share ONE bucket — core warns about exactly
|
|
80
|
+
* this collapse.
|
|
81
|
+
*
|
|
82
|
+
* ⚠ An IP key is the best available signal on a public endpoint, not a strong
|
|
83
|
+
* one: callers behind one NAT share a bucket, and a distributed source gets a
|
|
84
|
+
* fresh bucket per address. Treat it as a cost ceiling, not an anti-abuse
|
|
85
|
+
* control.
|
|
86
|
+
*
|
|
87
|
+
* Pass `false` to remove it entirely.
|
|
88
|
+
*/
|
|
89
|
+
interface ChatbotRateLimit {
|
|
90
|
+
/** Requests per window, per caller. Default {@link DEFAULT_RATE_LIMIT_MAX}. */
|
|
91
|
+
max?: number;
|
|
92
|
+
/** Window length in seconds. Default {@link DEFAULT_RATE_LIMIT_TTL}. */
|
|
93
|
+
ttl?: number;
|
|
94
|
+
/** Message returned when the limit is hit. */
|
|
95
|
+
error?: string;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The default system prompt — deliberately bland, meant to be replaced.
|
|
99
|
+
*
|
|
100
|
+
* The markdown sentence is the one part that is not filler. Replies read far
|
|
101
|
+
* better in a chat UI when the frontend renders them as markdown, and that only
|
|
102
|
+
* works if the model is actually told to produce it, so the shipped default and
|
|
103
|
+
* the rendering advice in README.md are two halves of one decision.
|
|
104
|
+
*
|
|
105
|
+
* **Light** markdown on purpose. A model told simply to "use markdown" reaches
|
|
106
|
+
* for headings and tables in a two-line answer, which reads worse than prose in a
|
|
107
|
+
* chat bubble — and every element it uses is one more thing a frontend has to
|
|
108
|
+
* style. Emphasis, lists and code spans cover what a conversational reply needs.
|
|
109
|
+
*
|
|
110
|
+
* If your frontend renders replies as PLAIN TEXT, override this: unrendered
|
|
111
|
+
* markdown shows the reader literal `**asterisks**`, which is worse than the
|
|
112
|
+
* prose it replaced. Pass your own `llm.systemPrompt` — that is the field this
|
|
113
|
+
* package expects most installs to set.
|
|
114
|
+
*/
|
|
115
|
+
declare const DEFAULT_SYSTEM_PROMPT: string;
|
|
116
|
+
/**
|
|
117
|
+
* Appended to the system prompt when — and only when — `tools` are configured.
|
|
118
|
+
*
|
|
119
|
+
* Two clauses, each earning its place from observed behaviour:
|
|
120
|
+
*
|
|
121
|
+
* 1. **"call the tool rather than saying you do not know."** Verified live: with
|
|
122
|
+
* a correctly wired tool but no mention of it in the prompt, the model
|
|
123
|
+
* answered "I do not know the secret word" and never called it — the default
|
|
124
|
+
* prompt's own "if you do not know something, say so rather than guessing"
|
|
125
|
+
* steers it away from trying. Asked by name it called the tool immediately.
|
|
126
|
+
* 2. **"answer in your own words, never paste the raw tool response."** A tool
|
|
127
|
+
* result arrives wrapped in an engine envelope
|
|
128
|
+
* (`{"<tool>_response": {"content": …, "name": …}}`), and the model will
|
|
129
|
+
* happily paste that verbatim into `reply` — which then renders as a JSON
|
|
130
|
+
* blob in the UI. Observed exactly that before this clause existed.
|
|
131
|
+
*
|
|
132
|
+
* Kept to two sentences so it composes with a caller's own `systemPrompt`
|
|
133
|
+
* instead of arguing with it.
|
|
134
|
+
*/
|
|
135
|
+
declare const TOOLS_SYSTEM_PROMPT: string;
|
|
136
|
+
/** How many prior turns the send endpoint replays into the model. */
|
|
137
|
+
declare const DEFAULT_HISTORY_LIMIT = 20;
|
|
138
|
+
/** How many conversations the list endpoint returns. */
|
|
139
|
+
declare const DEFAULT_LIST_LIMIT = 100;
|
|
140
|
+
/** How many messages a transcript endpoint returns. */
|
|
141
|
+
declare const DEFAULT_TRANSCRIPT_LIMIT = 200;
|
|
142
|
+
/** Default stored-object names. */
|
|
143
|
+
declare const DEFAULT_NAMES: {
|
|
144
|
+
readonly conversation: "conversation";
|
|
145
|
+
readonly message: "conversation_message";
|
|
146
|
+
readonly replyFn: "chatbot/generate_reply";
|
|
147
|
+
readonly agent: "chatbot_agent";
|
|
148
|
+
readonly apiGroup: "Chatbot";
|
|
149
|
+
};
|
|
150
|
+
/** Overridable stored-object names — see {@link ChatbotOptions.names}. */
|
|
151
|
+
interface ChatbotNames {
|
|
152
|
+
/** The conversation table. Default `"conversation"`. */
|
|
153
|
+
conversation?: string;
|
|
154
|
+
/**
|
|
155
|
+
* The message table. Default `"conversation_message"` rather than the more
|
|
156
|
+
* obvious `"message"`: a bare `message` is a name a realtime or notification
|
|
157
|
+
* workspace plausibly already holds, and a collision surfaces as a duplicate
|
|
158
|
+
* -guid throw at export rather than anything self-explanatory.
|
|
159
|
+
*/
|
|
160
|
+
message?: string;
|
|
161
|
+
/** The shared reply function. Default `"chatbot/generate_reply"`. */
|
|
162
|
+
replyFn?: string;
|
|
163
|
+
/** The agent. Default `"chatbot_agent"`. */
|
|
164
|
+
agent?: string;
|
|
165
|
+
/** The API group. Default `"Chatbot"`. */
|
|
166
|
+
apiGroup?: string;
|
|
167
|
+
}
|
|
168
|
+
/** Options for `createChatbot` / `registerChatbot`. */
|
|
169
|
+
interface ChatbotOptions {
|
|
170
|
+
/**
|
|
171
|
+
* The table conversations belong to, and the table the authenticated
|
|
172
|
+
* endpoints authenticate against. Required whenever `authenticated` is on
|
|
173
|
+
* (the default).
|
|
174
|
+
*
|
|
175
|
+
* Takes a `table()` def handle or a bare table name (see
|
|
176
|
+
* {@link ChatbotAuthTable} for why a numeric `dbo.id` is not accepted).
|
|
177
|
+
* **Nothing in this package imports `@xano-sdk/auth`**; handing it that
|
|
178
|
+
* package's `userTable` is just the documented happy path:
|
|
179
|
+
*
|
|
180
|
+
* ```ts
|
|
181
|
+
* import { userTable } from "@xano-sdk/auth";
|
|
182
|
+
* registerChatbot(xano, { authTable: userTable });
|
|
183
|
+
* ```
|
|
184
|
+
*
|
|
185
|
+
* Your own table works identically. `table({ auth: true })` is the convention,
|
|
186
|
+
* not a mechanism: the engine gates a request by comparing the token's `dbo`
|
|
187
|
+
* against the endpoint's configured `dbo` **by name**, and mints a token for
|
|
188
|
+
* any table by name — neither side reads the flag, which is only an editor
|
|
189
|
+
* concern (see core's `src/refs/auth.ts`). So a table without `auth: true`
|
|
190
|
+
* authenticates fine; core merely warns at export.
|
|
191
|
+
*
|
|
192
|
+
* Prefer the **handle** over a bare name. A name carries no schema, so core
|
|
193
|
+
* cannot check the referenced primary-key type against the `user_id` column —
|
|
194
|
+
* an int/uuid mismatch then surfaces as a Xano import failure instead of an
|
|
195
|
+
* author-time throw. Pass `{ userIdType: "uuid" }` alongside a uuid-keyed
|
|
196
|
+
* table referenced by name.
|
|
197
|
+
*/
|
|
198
|
+
authTable?: ChatbotAuthTable;
|
|
199
|
+
/**
|
|
200
|
+
* The primary-key type of `authTable`, and so the type of
|
|
201
|
+
* `conversation.user_id`. Default `"int"`.
|
|
202
|
+
*
|
|
203
|
+
* Only needed when `authTable` is a bare **name** — a name carries no schema.
|
|
204
|
+
* With a handle, core reads the target's `idType` and throws on a mismatch by
|
|
205
|
+
* itself, so this option is redundant there (but still checked for agreement).
|
|
206
|
+
*/
|
|
207
|
+
userIdType?: "int" | "uuid";
|
|
208
|
+
/**
|
|
209
|
+
* Register the token-authenticated endpoint family (`chat/*`), scoped by
|
|
210
|
+
* `auth("id")`. Default `true`.
|
|
211
|
+
*
|
|
212
|
+
* Set `false` for a purely anonymous bot, in which case `authTable` may be
|
|
213
|
+
* omitted entirely and `user_id` is dropped from the conversation table.
|
|
214
|
+
*/
|
|
215
|
+
authenticated?: boolean;
|
|
216
|
+
/**
|
|
217
|
+
* Register the public guest endpoint family (`chat/guest/*`), scoped by an
|
|
218
|
+
* unguessable `session_token`. Default `false`.
|
|
219
|
+
*
|
|
220
|
+
* Two families rather than one because a Xano endpoint's `auth` is **binary**
|
|
221
|
+
* and there is no optional-auth flag: an authenticated endpoint returns 401
|
|
222
|
+
* without a token, and referencing `auth()` inside a *public* stack raises
|
|
223
|
+
* `ACCESS_DENIED` outright (verified against a live instance — see
|
|
224
|
+
* AGENTS.md). One endpoint therefore cannot serve both callers, so each family
|
|
225
|
+
* gets its own, and each has exactly one authorization rule to audit.
|
|
226
|
+
*
|
|
227
|
+
* ⚠ A guest conversation is protected by a bearer capability, not a login.
|
|
228
|
+
* See the security notes in README.md before enabling this on a public site.
|
|
229
|
+
*/
|
|
230
|
+
guest?: boolean;
|
|
231
|
+
/**
|
|
232
|
+
* The agent's LLM settings, passed through to core's `agent({ llm })`.
|
|
233
|
+
*
|
|
234
|
+
* Defaults to `{ type: "xano-free" }` — Xano's keyless provider, so a fresh
|
|
235
|
+
* install answers a message without any credential wiring.
|
|
236
|
+
*
|
|
237
|
+
* `systemPrompt` defaults to {@link DEFAULT_SYSTEM_PROMPT} and is the one
|
|
238
|
+
* field most installs will set. The **run prompt is not yours to set**: this
|
|
239
|
+
* package owns it, because the conversation transcript is delivered through
|
|
240
|
+
* it. Passing `prompt` or `messages` throws rather than silently losing the
|
|
241
|
+
* history (core stores one prompt behind a `prompt_type` discriminator, so a
|
|
242
|
+
* caller-supplied one would replace the transcript, not add to it).
|
|
243
|
+
*/
|
|
244
|
+
llm?: ChatbotLlmOptions;
|
|
245
|
+
/**
|
|
246
|
+
* How many prior messages to replay into the model on each send. Default
|
|
247
|
+
* {@link DEFAULT_HISTORY_LIMIT}. Must be a positive integer.
|
|
248
|
+
*
|
|
249
|
+
* The window is applied in the database (`db.query` + `sort` + `paging`), so a
|
|
250
|
+
* long conversation costs a bounded read and a bounded context, not a growing
|
|
251
|
+
* one. Raising it raises per-message token spend on every turn.
|
|
252
|
+
*/
|
|
253
|
+
/**
|
|
254
|
+
* How many messages of the thread are replayed to the model on each send.
|
|
255
|
+
* Default {@link DEFAULT_HISTORY_LIMIT}.
|
|
256
|
+
*
|
|
257
|
+
* ⚠ A count of **messages (rows), including the turn being sent** — not of
|
|
258
|
+
* exchanges. The user's message is written before the history is read, so the
|
|
259
|
+
* usable memory is `historyLimit - 1` PRIOR messages, and a user+assistant
|
|
260
|
+
* exchange costs two.
|
|
261
|
+
*
|
|
262
|
+
* Verified live: at `historyLimit: 2` the model is given
|
|
263
|
+
* `[previous assistant reply, current user message]` — the user's own previous
|
|
264
|
+
* statement is already outside the window, so "the codeword is X" followed by
|
|
265
|
+
* "what was the codeword?" cannot be answered. The default of 20 is ~10
|
|
266
|
+
* exchanges; treat anything below ~6 as effectively memoryless.
|
|
267
|
+
*
|
|
268
|
+
* Independent of `transcriptLimit`, so a user can see a message on screen that
|
|
269
|
+
* the model was never shown.
|
|
270
|
+
*/
|
|
271
|
+
historyLimit?: number;
|
|
272
|
+
/**
|
|
273
|
+
* How many conversations `GET chat/conversations` returns, newest-active first.
|
|
274
|
+
* Default {@link DEFAULT_LIST_LIMIT}. Must be a positive integer.
|
|
275
|
+
*
|
|
276
|
+
* A fixed cap rather than caller-supplied paging: input-bound paging would let
|
|
277
|
+
* an omitted `per_page` reach the engine as null, and a chat sidebar is not the
|
|
278
|
+
* surface where that trade is worth making. A consumer who needs real paging
|
|
279
|
+
* registers their own list endpoint over the same table.
|
|
280
|
+
*/
|
|
281
|
+
listLimit?: number;
|
|
282
|
+
/**
|
|
283
|
+
* Per-caller rate limiting on the model-invoking endpoints. Defaults to
|
|
284
|
+
* `{ max: 20, ttl: 60 }`; pass `false` to disable. See {@link ChatbotRateLimit}.
|
|
285
|
+
*/
|
|
286
|
+
rateLimit?: false | ChatbotRateLimit;
|
|
287
|
+
/**
|
|
288
|
+
* Tools the chat agent may call — a `tool()` def handle, its name, or a
|
|
289
|
+
* `{ tool, enabled?, auth? }` wrapper.
|
|
290
|
+
*
|
|
291
|
+
* Empty by default: a tool-less assistant is the right shape for a plain
|
|
292
|
+
* chatbot, and a tool the model can call is a capability, not a decoration.
|
|
293
|
+
*
|
|
294
|
+
* ⚠ **This package references your tools; it never registers them.** Same rule
|
|
295
|
+
* as `authTable`. Register them yourself:
|
|
296
|
+
*
|
|
297
|
+
* ```ts
|
|
298
|
+
* const lookupOrder = tool({ name: "lookup_order", … });
|
|
299
|
+
*
|
|
300
|
+
* const bot = registerChatbot(xano, { authTable: userTable, tools: [lookupOrder] });
|
|
301
|
+
* bot.xano.registerTools([lookupOrder]);
|
|
302
|
+
* ```
|
|
303
|
+
*
|
|
304
|
+
* A reference resolves to a name-derived guid with no registry lookup, so a
|
|
305
|
+
* tool you forget to register is caught at **export**, which THROWS naming the
|
|
306
|
+
* tool and the fix — deliberately, since a mistyped name would otherwise
|
|
307
|
+
* produce a valid-looking guid that only fails once the import has begun.
|
|
308
|
+
*
|
|
309
|
+
* Two things follow from adding tools:
|
|
310
|
+
*
|
|
311
|
+
* - **`llm.maxSteps` starts to matter.** It bounds reasoning/tool steps and
|
|
312
|
+
* defaults to 5; a chain needing more calls than that stops early.
|
|
313
|
+
* - **A tool runs with the caller's request context.** If it reads data, scope
|
|
314
|
+
* it yourself — the agent will call it whenever the model decides to, on
|
|
315
|
+
* behalf of whoever is chatting, including an anonymous guest when the guest
|
|
316
|
+
* family is enabled.
|
|
317
|
+
*
|
|
318
|
+
* ## Per-tool auth is applied for you
|
|
319
|
+
*
|
|
320
|
+
* A toolset entry carries its own `auth`, and the engine's default is
|
|
321
|
+
* `auth: false` — a **public** tool stack. `auth("id")` inside a public stack
|
|
322
|
+
* does not resolve to null: it raises `ERROR_CODE_ACCESS_DENIED` on the first
|
|
323
|
+
* statement that reads it. The agent swallows that throw, so the model still
|
|
324
|
+
* answers "I saved your note" and nothing is written — no 500, no error in the
|
|
325
|
+
* reply, no export warning (a live failure, recorded in AGENTS.md).
|
|
326
|
+
*
|
|
327
|
+
* So when {@link ChatbotOptions.authTable} is set, every entry that does not
|
|
328
|
+
* name an `auth` of its own is given **that table**:
|
|
329
|
+
*
|
|
330
|
+
* ```ts
|
|
331
|
+
* tools: [saveNote] // → { tool: saveNote, auth: userTable }
|
|
332
|
+
* tools: [{ tool: saveNote }] // → { tool: saveNote, auth: userTable }
|
|
333
|
+
* tools: [{ tool: ping, auth: false }] // → left public, the explicit opt-out
|
|
334
|
+
* tools: [{ tool: saveNote, auth: other }] // → left alone
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* The tools belong to a bot whose endpoints are already token-gated, so a
|
|
338
|
+
* public tool is almost never the intent. `{ tool, auth: false }` remains the
|
|
339
|
+
* way to say it deliberately — and such a tool must not call `auth()`.
|
|
340
|
+
*
|
|
341
|
+
* ⚠ A **guest-only** install (`{ authenticated: false, guest: true }`) has no
|
|
342
|
+
* auth table, so nothing is defaulted and every tool is public. A tool reached
|
|
343
|
+
* from the guest family has no caller identity: do not write `auth()` in it,
|
|
344
|
+
* and scope what it reads by the arguments the model supplies instead.
|
|
345
|
+
*/
|
|
346
|
+
tools?: ToolsetToolEntry[];
|
|
347
|
+
/**
|
|
348
|
+
* How many messages the transcript endpoints return, oldest-first within the
|
|
349
|
+
* window. Default {@link DEFAULT_TRANSCRIPT_LIMIT}. Must be a positive integer.
|
|
350
|
+
*
|
|
351
|
+
* The window takes the NEWEST messages, so a thread longer than this loses its
|
|
352
|
+
* oldest turns from the response — the right end to drop for a UI that renders
|
|
353
|
+
* from the bottom. Independent of `historyLimit`: what a human reads back and
|
|
354
|
+
* what the model is given are different budgets.
|
|
355
|
+
*/
|
|
356
|
+
transcriptLimit?: number;
|
|
357
|
+
/**
|
|
358
|
+
* Pin the API group's canonical — the `<canonical>` in
|
|
359
|
+
* `/api:<canonical>/chat/conversations`.
|
|
360
|
+
*
|
|
361
|
+
* Omitted, identity comes from the consumer's `xano.lock` (or, with no lock, a
|
|
362
|
+
* random segment assigned at import) and a bare `getPath()` throws. Pinning it
|
|
363
|
+
* lets a browser resolve `getPath()` with no lock file. Must match
|
|
364
|
+
* `[A-Za-z0-9_-]+`, and must be unique across the instance's API groups —
|
|
365
|
+
* which this package cannot check, so a collision surfaces at Xano import.
|
|
366
|
+
*/
|
|
367
|
+
canonical?: string;
|
|
368
|
+
/**
|
|
369
|
+
* Request-history capture for the API group the endpoints inherit from.
|
|
370
|
+
* Default `false`.
|
|
371
|
+
*
|
|
372
|
+
* `false` rather than the engine's inherit-on for the same reason
|
|
373
|
+
* `@xano-sdk/auth` overrides it: request history records the request body, and
|
|
374
|
+
* on this package that body is the user's message text plus — on the guest
|
|
375
|
+
* family — the `session_token` that grants access to the whole thread. A
|
|
376
|
+
* turnkey install should not persist either into the workspace's history
|
|
377
|
+
* store. `true` opts back in at the engine's default depth; a positive integer
|
|
378
|
+
* sets the capture depth; `"all"` is unlimited.
|
|
379
|
+
*/
|
|
380
|
+
history?: boolean | number | "all";
|
|
381
|
+
/**
|
|
382
|
+
* The leading path segment of every endpoint — `chat` in
|
|
383
|
+
* `chat/conversations/{id}/send`. Default {@link DEFAULT_ROUTE_PREFIX}.
|
|
384
|
+
*
|
|
385
|
+
* This is the second half of running TWO chatbots in one workspace. `names`
|
|
386
|
+
* renames the stored objects, but a query's identity derives from its **route
|
|
387
|
+
* name**, so a second install also needs its own prefix or every endpoint
|
|
388
|
+
* collides on guid. Slashes are allowed (`"support/chat"`); braces are not,
|
|
389
|
+
* since a prefix is not a place for a path param.
|
|
390
|
+
*/
|
|
391
|
+
routePrefix?: string;
|
|
392
|
+
/** Override the stored object names — see {@link ChatbotNames}. */
|
|
393
|
+
names?: ChatbotNames;
|
|
394
|
+
/** Tags applied to every def this package creates. Default `["xano:chatbot"]`. */
|
|
395
|
+
tags?: string[];
|
|
396
|
+
}
|
|
397
|
+
/** Fully-defaulted options, as the def factories consume them. */
|
|
398
|
+
interface ResolvedOptions {
|
|
399
|
+
/** `undefined` exactly when the authenticated family is off. */
|
|
400
|
+
authTable: ChatbotAuthTable | undefined;
|
|
401
|
+
userIdType: "int" | "uuid";
|
|
402
|
+
authenticated: boolean;
|
|
403
|
+
guest: boolean;
|
|
404
|
+
llm: LlmSettings;
|
|
405
|
+
historyLimit: number;
|
|
406
|
+
listLimit: number;
|
|
407
|
+
/** Resolved rate limit, or `false` when disabled. */
|
|
408
|
+
rateLimit: false | {
|
|
409
|
+
max: number;
|
|
410
|
+
ttl: number;
|
|
411
|
+
error: string;
|
|
412
|
+
};
|
|
413
|
+
/**
|
|
414
|
+
* Tools the agent may call. Empty unless the caller supplied some.
|
|
415
|
+
*
|
|
416
|
+
* Normalized, not verbatim: with an auth table, every entry that named no
|
|
417
|
+
* `auth` of its own is now `{ tool, auth: <authTable> }` — see
|
|
418
|
+
* {@link ChatbotOptions.tools}. An explicit `auth: false` survives.
|
|
419
|
+
*/
|
|
420
|
+
tools: ToolsetToolEntry[];
|
|
421
|
+
transcriptLimit: number;
|
|
422
|
+
canonical: string | undefined;
|
|
423
|
+
history: boolean | number | "all";
|
|
424
|
+
routePrefix: string;
|
|
425
|
+
names: Required<ChatbotNames>;
|
|
426
|
+
tags: string[];
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Resolve and validate options. Every check lives here, before any def is
|
|
430
|
+
* built, so a bad call produces one clear error rather than a half-built
|
|
431
|
+
* workspace or an opaque throw from deep inside core's encoder.
|
|
432
|
+
*/
|
|
433
|
+
declare function resolveOptions(opts?: ChatbotOptions): ResolvedOptions;
|
|
434
|
+
/**
|
|
435
|
+
* The agent's run prompt: the whole conversation, as a rendered `messages`
|
|
436
|
+
* template. See `src/agent/chat-agent.ts` for the verification behind it.
|
|
437
|
+
*/
|
|
438
|
+
declare const MESSAGES_TEMPLATE = "{{ $args.messages }}";
|
|
439
|
+
|
|
440
|
+
/** Build the `conversation` def for the given resolved options. */
|
|
441
|
+
declare function conversationTable(opts: ResolvedOptions): _xano_sdk.TableDef<_xano_sdk.SchemaCols<{
|
|
442
|
+
title: _xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<string, {
|
|
443
|
+
readonly methods: readonly ["trim"];
|
|
444
|
+
readonly description: "Human-readable thread title. Seeded from the first user message.";
|
|
445
|
+
}, "text">;
|
|
446
|
+
last_message_at: _xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<number, {
|
|
447
|
+
readonly nullable: true;
|
|
448
|
+
readonly description: "When the most recent message was appended. Null until the first send.";
|
|
449
|
+
}, "epochms">;
|
|
450
|
+
session_token?: (_xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<string, {
|
|
451
|
+
readonly access: "internal";
|
|
452
|
+
readonly description: "Opaque bearer capability for guest access to this thread. Treat it like a password.";
|
|
453
|
+
}, "text">) | undefined;
|
|
454
|
+
user_id?: (_xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<number, {
|
|
455
|
+
readonly description: "The user this conversation belongs to. Null until a guest thread is claimed.";
|
|
456
|
+
readonly nullable?: true | undefined;
|
|
457
|
+
readonly type: "int" | "uuid";
|
|
458
|
+
}, "int" | "uuid">) | undefined;
|
|
459
|
+
}>, {
|
|
460
|
+
id: number;
|
|
461
|
+
created_at: number;
|
|
462
|
+
title: string;
|
|
463
|
+
last_message_at: number | null;
|
|
464
|
+
session_token?: unknown;
|
|
465
|
+
user_id?: unknown;
|
|
466
|
+
}, never>;
|
|
467
|
+
/** The `conversation` def type, for consumers naming it explicitly. */
|
|
468
|
+
type ConversationTable = ReturnType<typeof conversationTable>;
|
|
469
|
+
/**
|
|
470
|
+
* A `conversation` row.
|
|
471
|
+
*
|
|
472
|
+
* Declared rather than `InferRow`-derived off a factory result, because which
|
|
473
|
+
* columns exist depends on the options passed — an inferred type would be
|
|
474
|
+
* per-call and unnameable. `user_id` and `session_token` are therefore optional
|
|
475
|
+
* here: present in the store exactly when their family is enabled.
|
|
476
|
+
*/
|
|
477
|
+
interface Conversation {
|
|
478
|
+
id: number;
|
|
479
|
+
created_at: number;
|
|
480
|
+
/** Present when the authenticated family is enabled; null on an unclaimed guest thread. */
|
|
481
|
+
user_id?: number | string | null;
|
|
482
|
+
/** Present when the guest family is enabled. `internal` access — never returned by this package's endpoints. */
|
|
483
|
+
session_token?: string;
|
|
484
|
+
title: string;
|
|
485
|
+
last_message_at: number | null;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* The columns this package's endpoints return for a conversation — the single
|
|
489
|
+
* source of truth for their `output` lists and for {@link PublicConversation},
|
|
490
|
+
* so the two cannot drift.
|
|
491
|
+
*
|
|
492
|
+
* `session_token` is deliberately absent: it is the guest bearer capability and
|
|
493
|
+
* is handed back exactly once, by the create endpoint that mints it, from that
|
|
494
|
+
* statement's own binding — never re-read and re-served afterwards.
|
|
495
|
+
*/
|
|
496
|
+
declare const PUBLIC_CONVERSATION_FIELDS: readonly ["id", "created_at", "title", "last_message_at"];
|
|
497
|
+
/** The conversation projection this package's endpoints hand back. */
|
|
498
|
+
type PublicConversation = Pick<Conversation, (typeof PUBLIC_CONVERSATION_FIELDS)[number]>;
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* The roles the engine accepts in a decoded `messages` array. Exported because
|
|
502
|
+
* it is simultaneously the column's enum, the {@link MessageRole} type, and the
|
|
503
|
+
* set the reply function is allowed to write — one reviewed list, not three.
|
|
504
|
+
*/
|
|
505
|
+
declare const MESSAGE_ROLES: readonly ["user", "assistant", "system"];
|
|
506
|
+
/** A stored message's role. */
|
|
507
|
+
type MessageRole = (typeof MESSAGE_ROLES)[number];
|
|
508
|
+
/** Build the `conversation_message` def for the given resolved options. */
|
|
509
|
+
declare function messageTable(opts: ResolvedOptions, conversation: ConversationTable): _xano_sdk.TableDef<_xano_sdk.SchemaCols<{
|
|
510
|
+
conversation_id: _xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<number, {
|
|
511
|
+
readonly required: true;
|
|
512
|
+
readonly description: "The thread this message belongs to.";
|
|
513
|
+
}, "int">;
|
|
514
|
+
role: _xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<"system" | "user" | "assistant", {
|
|
515
|
+
readonly required: true;
|
|
516
|
+
readonly description: "Who produced this turn. The engine rejects any other value when replaying it.";
|
|
517
|
+
}, "enum">;
|
|
518
|
+
content: _xano_sdk.FieldDescriptor & _xano_sdk.TypeBrand<string, {
|
|
519
|
+
readonly required: true;
|
|
520
|
+
readonly methods: readonly ["min:1"];
|
|
521
|
+
readonly description: "The message text. Must be non-empty — a blank turn makes the model confabulate.";
|
|
522
|
+
}, "text">;
|
|
523
|
+
}>, {
|
|
524
|
+
id: number;
|
|
525
|
+
created_at: number;
|
|
526
|
+
conversation_id: number;
|
|
527
|
+
role: "system" | "user" | "assistant";
|
|
528
|
+
content: string;
|
|
529
|
+
}, never>;
|
|
530
|
+
/** The `conversation_message` def type. */
|
|
531
|
+
type MessageTable = ReturnType<typeof messageTable>;
|
|
532
|
+
/** A `conversation_message` row. */
|
|
533
|
+
type Message = InferRow<ReturnType<typeof messageTable>>;
|
|
534
|
+
/**
|
|
535
|
+
* The columns this package's endpoints return for a message — the single source
|
|
536
|
+
* of truth for their `output` lists and for {@link PublicMessage}.
|
|
537
|
+
*/
|
|
538
|
+
declare const PUBLIC_MESSAGE_FIELDS: readonly ["id", "created_at", "conversation_id", "role", "content"];
|
|
539
|
+
/** The message projection this package's endpoints hand back. */
|
|
540
|
+
interface PublicMessage {
|
|
541
|
+
id: number;
|
|
542
|
+
created_at: number;
|
|
543
|
+
conversation_id: number;
|
|
544
|
+
role: MessageRole;
|
|
545
|
+
content: string;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* Build the agent def.
|
|
550
|
+
*
|
|
551
|
+
* `llm` arrives already merged and validated by `resolveOptions`, which also
|
|
552
|
+
* pins `messages` to the template and refuses a caller-supplied `prompt` /
|
|
553
|
+
* `messages` — see `src/options.ts`.
|
|
554
|
+
*
|
|
555
|
+
* `tools` comes from `opts.tools` and is empty by default — a tool-less agent is
|
|
556
|
+
* the right shape for a plain conversational assistant. When a consumer supplies
|
|
557
|
+
* tools, this package REFERENCES them and never registers them, exactly as it
|
|
558
|
+
* treats `authTable`; see `ChatbotOptions.tools`.
|
|
559
|
+
*
|
|
560
|
+
* No `output` schema, and that one is not configurable. `ChatReply.reply` is
|
|
561
|
+
* declared `string` and the send endpoints hand `run.result` straight back, so a
|
|
562
|
+
* structured-output schema would make `.result` an object where every consumer's
|
|
563
|
+
* type — and every markdown renderer — expects text. A caller who wants
|
|
564
|
+
* structured data should give the agent a TOOL that writes it, and keep the
|
|
565
|
+
* reply itself free text.
|
|
566
|
+
*/
|
|
567
|
+
declare function chatAgent(opts: ResolvedOptions): _xano_sdk.AgentHandle<{
|
|
568
|
+
readonly name: string;
|
|
569
|
+
readonly description: "Conversational assistant. Receives the thread's recent turns as decoded LLM messages and returns the next one.";
|
|
570
|
+
readonly tags: string[];
|
|
571
|
+
readonly tools: _xano_sdk.ToolsetToolEntry[];
|
|
572
|
+
readonly llm: _xano_sdk.LlmSettings;
|
|
573
|
+
}>;
|
|
574
|
+
/** The agent def type. */
|
|
575
|
+
type ChatAgent = ReturnType<typeof chatAgent>;
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Response shapes this package hand-declares.
|
|
579
|
+
*
|
|
580
|
+
* Only one, and only because core's static walk genuinely cannot see it. Every
|
|
581
|
+
* other endpoint's response IS derived — a projection off a `db.query`, a
|
|
582
|
+
* `db.add`, or a `db.edit`, all of which the walk can read off the table schema
|
|
583
|
+
* and the `output` list. Those stay underived on purpose, so editing a
|
|
584
|
+
* `PUBLIC_*_FIELDS` array moves the consumer's type with it.
|
|
585
|
+
*/
|
|
586
|
+
|
|
587
|
+
/**
|
|
588
|
+
* What the send endpoints (and the reply function) hand back.
|
|
589
|
+
*
|
|
590
|
+
* Declared rather than derived because `reply` is `ref("run.result")` — the
|
|
591
|
+
* completion from `s.ai.agent.run`. The agent carries no `output.schema` (a chat
|
|
592
|
+
* reply is free text), so core resolves the run envelope's `.result` to `unknown`,
|
|
593
|
+
* and `unknown` propagating into every consumer's send call is the one place a
|
|
594
|
+
* declaration earns itself here.
|
|
595
|
+
*
|
|
596
|
+
* `string` is an assumption about the provider's completion, not something core
|
|
597
|
+
* pins — the same class of hand-maintained contract as `@xano-sdk/auth`'s
|
|
598
|
+
* `authToken: string`. The type tests pin the declared *keys* against the keys the
|
|
599
|
+
* walk does see, which is the part that can drift silently.
|
|
600
|
+
*/
|
|
601
|
+
interface ChatReply {
|
|
602
|
+
/** The thread the turn was appended to — echoed back for client-side routing. */
|
|
603
|
+
conversation_id: number;
|
|
604
|
+
/**
|
|
605
|
+
* The assistant's reply.
|
|
606
|
+
*
|
|
607
|
+
* **Markdown.** The default system prompt asks for light markdown, because a
|
|
608
|
+
* chat reply reads better rendered than as a wall of plain text. Render it with
|
|
609
|
+
* a markdown component rather than dropping it into a text node — otherwise the
|
|
610
|
+
* reader sees literal `**asterisks**`. (Using a plain-text UI? Override
|
|
611
|
+
* `llm.systemPrompt` so the model stops emitting markup at all.)
|
|
612
|
+
*
|
|
613
|
+
* ⚠ **Render it as untrusted input.** This string is model output shaped by
|
|
614
|
+
* whatever the user typed, so a prompt-injection attempt can try to steer it
|
|
615
|
+
* into `<script>` or a `javascript:` link. Use a renderer with raw HTML
|
|
616
|
+
* disabled (the default in `react-markdown` and `marked`), or sanitize before
|
|
617
|
+
* `dangerouslySetInnerHTML`. The default prompt says not to emit raw HTML,
|
|
618
|
+
* which is a nudge to a model, not a guarantee — the renderer is the control.
|
|
619
|
+
*/
|
|
620
|
+
reply: string;
|
|
621
|
+
/** The primary key of the stored assistant message. */
|
|
622
|
+
message_id: number;
|
|
623
|
+
/**
|
|
624
|
+
* The NAMES of the tools the agent executed on this turn, in call order —
|
|
625
|
+
* `[]` when the model answered directly, and `[]` on every turn of a
|
|
626
|
+
* tool-less install.
|
|
627
|
+
*
|
|
628
|
+
* Names only, and deliberately. A tool call also carries the arguments the
|
|
629
|
+
* model produced and whatever the tool returned; both are model-shaped, and a
|
|
630
|
+
* tool that reads data would put that data on the wire for a client that only
|
|
631
|
+
* asked "did anything run?". The name answers that and leaks nothing.
|
|
632
|
+
*
|
|
633
|
+
* ⚠ **Not an audit log.** A tool that THREW still appears here or does not,
|
|
634
|
+
* according to what the engine records for the run — the field says which
|
|
635
|
+
* tools the model reached for, not which of them succeeded. Read the rows a
|
|
636
|
+
* tool should have written if you need to know it worked.
|
|
637
|
+
*/
|
|
638
|
+
tool_calls: string[];
|
|
639
|
+
}
|
|
640
|
+
|
|
641
|
+
/** How many characters of the first message become the auto-generated title. */
|
|
642
|
+
declare const TITLE_LENGTH = 60;
|
|
643
|
+
declare function generateReplyFn(opts: ResolvedOptions, conversation: ConversationTable, message: MessageTable, chatAgent: ChatAgent): _xano_sdk.FunctionDef<{
|
|
644
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
645
|
+
readonly required: true;
|
|
646
|
+
readonly description: "The thread to append to. NOT authorized here — the caller must have checked ownership.";
|
|
647
|
+
}, "int">;
|
|
648
|
+
readonly content: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
649
|
+
readonly required: true;
|
|
650
|
+
readonly description: "The user's message text. Must be non-empty.";
|
|
651
|
+
}, "text">;
|
|
652
|
+
}, ChatReply, {
|
|
653
|
+
conversation_id: _xano_sdk.InpValue<"conversation_id">;
|
|
654
|
+
reply: _xano_sdk.RefValue<"run.result">;
|
|
655
|
+
message_id: _xano_sdk.RefValue<"assistant_message.id">;
|
|
656
|
+
tool_calls: _xano_sdk.ConstValue<readonly []> | (_xano_sdk.TaggedValue & {
|
|
657
|
+
readonly __filtered: true;
|
|
658
|
+
readonly __base?: _xano_sdk.RefValue<"tool_call_names"> | undefined;
|
|
659
|
+
readonly __chain?: [_xano_sdk.FilterXdo<"filter_null">] | undefined;
|
|
660
|
+
});
|
|
661
|
+
}, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"user_message", {
|
|
662
|
+
id: number;
|
|
663
|
+
created_at: number;
|
|
664
|
+
conversation_id: number;
|
|
665
|
+
role: "system" | "user" | "assistant";
|
|
666
|
+
content: string;
|
|
667
|
+
}>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
668
|
+
id: number;
|
|
669
|
+
created_at: number;
|
|
670
|
+
conversation_id: number;
|
|
671
|
+
role: "system" | "user" | "assistant";
|
|
672
|
+
content: string;
|
|
673
|
+
}, "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"turns", _xano_sdk.ArrayMapShape<_xano_sdk.TaggedValue & {
|
|
674
|
+
readonly __filtered: true;
|
|
675
|
+
readonly __base?: _xano_sdk.RefValue<"recent"> | undefined;
|
|
676
|
+
readonly __chain?: [_xano_sdk.FilterXdo<"reverse">] | undefined;
|
|
677
|
+
}, {
|
|
678
|
+
readonly role: _xano_sdk.RefValue<"$this.role">;
|
|
679
|
+
readonly content: _xano_sdk.RefValue<"$this.content">;
|
|
680
|
+
}>>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages_json", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"run", _xano_sdk.AgentRunResult<string>>, ...((_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"run_steps", unknown>) | (_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"tool_call_names", readonly []>) | (_xano_sdk.Statement & _xano_sdk.MaybeBodyBrand<readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"step_calls", unknown>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"step_names", _xano_sdk.ArrayMapShape<_xano_sdk.RefValue<"step_calls">, _xano_sdk.TaggedValue & {
|
|
681
|
+
readonly __filtered: true;
|
|
682
|
+
readonly __base?: _xano_sdk.RefValue<"$this.toolName"> | undefined;
|
|
683
|
+
readonly __chain?: [_xano_sdk.FilterXdo<"first_notnull">, _xano_sdk.FilterXdo<"first_notnull">] | undefined;
|
|
684
|
+
}>>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"tool_call_names", unknown>]>))[], _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"assistant_message", {
|
|
685
|
+
id: number;
|
|
686
|
+
created_at: number;
|
|
687
|
+
conversation_id: number;
|
|
688
|
+
role: "system" | "user" | "assistant";
|
|
689
|
+
content: string;
|
|
690
|
+
}>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
691
|
+
id: number;
|
|
692
|
+
created_at: number;
|
|
693
|
+
title: string;
|
|
694
|
+
last_message_at: number | null;
|
|
695
|
+
session_token?: unknown;
|
|
696
|
+
user_id?: unknown;
|
|
697
|
+
}, "id" | "title"> | null>, _xano_sdk.Statement & _xano_sdk.MaybeBodyBrand<[_xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, {
|
|
698
|
+
id: number;
|
|
699
|
+
created_at: number;
|
|
700
|
+
title: string;
|
|
701
|
+
last_message_at: number | null;
|
|
702
|
+
session_token?: unknown;
|
|
703
|
+
user_id?: unknown;
|
|
704
|
+
}>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, {
|
|
705
|
+
id: number;
|
|
706
|
+
created_at: number;
|
|
707
|
+
title: string;
|
|
708
|
+
last_message_at: number | null;
|
|
709
|
+
session_token?: unknown;
|
|
710
|
+
user_id?: unknown;
|
|
711
|
+
}>]> & _xano_sdk.BranchesBrand<[readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, {
|
|
712
|
+
id: number;
|
|
713
|
+
created_at: number;
|
|
714
|
+
title: string;
|
|
715
|
+
last_message_at: number | null;
|
|
716
|
+
session_token?: unknown;
|
|
717
|
+
user_id?: unknown;
|
|
718
|
+
}>], readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, {
|
|
719
|
+
id: number;
|
|
720
|
+
created_at: number;
|
|
721
|
+
title: string;
|
|
722
|
+
last_message_at: number | null;
|
|
723
|
+
session_token?: unknown;
|
|
724
|
+
user_id?: unknown;
|
|
725
|
+
}>]]>]>;
|
|
726
|
+
/** The reply function's def type. */
|
|
727
|
+
type GenerateReplyFn = ReturnType<typeof generateReplyFn>;
|
|
728
|
+
|
|
729
|
+
declare function chatbotGroup(opts: ResolvedOptions): _xano_sdk.ApiGroupDef;
|
|
730
|
+
/** The API group def type. */
|
|
731
|
+
type ChatbotGroup = ReturnType<typeof chatbotGroup>;
|
|
732
|
+
|
|
733
|
+
declare function authenticatedQueries(opts: ResolvedOptions, group: ChatbotGroup, conversation: ConversationTable, message: MessageTable, replyFn: GenerateReplyFn): {
|
|
734
|
+
createConversation: _xano_sdk.QueryDef<{
|
|
735
|
+
readonly title: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
736
|
+
readonly methods: readonly ["trim"];
|
|
737
|
+
readonly description: "Optional thread title. Left blank, the first message's opening words become the title.";
|
|
738
|
+
}, "text">;
|
|
739
|
+
}, never, _xano_sdk.RefValue<"conversation">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"session_token", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
740
|
+
id: number;
|
|
741
|
+
created_at: number;
|
|
742
|
+
title: string;
|
|
743
|
+
last_message_at: number | null;
|
|
744
|
+
session_token?: unknown;
|
|
745
|
+
user_id?: unknown;
|
|
746
|
+
}, "id" | "title" | "last_message_at" | "created_at">>] | readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
747
|
+
id: number;
|
|
748
|
+
created_at: number;
|
|
749
|
+
title: string;
|
|
750
|
+
last_message_at: number | null;
|
|
751
|
+
session_token?: unknown;
|
|
752
|
+
user_id?: unknown;
|
|
753
|
+
}, "id" | "title" | "last_message_at" | "created_at">>], `${string}/conversations/create`, "POST"> & {
|
|
754
|
+
getPath: (opts?: {
|
|
755
|
+
canonical?: string;
|
|
756
|
+
}) => string;
|
|
757
|
+
toSearchParams: {
|
|
758
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
759
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
760
|
+
};
|
|
761
|
+
} & {
|
|
762
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
763
|
+
};
|
|
764
|
+
listConversations: _xano_sdk.QueryDef<{}, never, _xano_sdk.RefValue<"conversations">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversations", Pick<{
|
|
765
|
+
id: number;
|
|
766
|
+
created_at: number;
|
|
767
|
+
title: string;
|
|
768
|
+
last_message_at: number | null;
|
|
769
|
+
session_token?: unknown;
|
|
770
|
+
user_id?: unknown;
|
|
771
|
+
}, "id" | "title" | "last_message_at" | "created_at">[]>], `${string}/conversations`, "GET"> & {
|
|
772
|
+
getPath: (opts?: {
|
|
773
|
+
canonical?: string;
|
|
774
|
+
}) => string;
|
|
775
|
+
toSearchParams: {
|
|
776
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
777
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
778
|
+
};
|
|
779
|
+
} & {
|
|
780
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
781
|
+
};
|
|
782
|
+
listMessages: _xano_sdk.QueryDef<{
|
|
783
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
784
|
+
readonly required: true;
|
|
785
|
+
}, "int">;
|
|
786
|
+
}, PublicMessage[], _xano_sdk.RefValue<"messages">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
787
|
+
id: number;
|
|
788
|
+
created_at: number;
|
|
789
|
+
title: string;
|
|
790
|
+
last_message_at: number | null;
|
|
791
|
+
session_token?: unknown;
|
|
792
|
+
user_id?: unknown;
|
|
793
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
794
|
+
id: number;
|
|
795
|
+
created_at: number;
|
|
796
|
+
conversation_id: number;
|
|
797
|
+
role: "system" | "user" | "assistant";
|
|
798
|
+
content: string;
|
|
799
|
+
}, "id" | "created_at" | "conversation_id" | "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages", unknown>], `${string}/conversations/{conversation_id}/messages`, "GET"> & {
|
|
800
|
+
getPath: (opts: {
|
|
801
|
+
canonical?: string;
|
|
802
|
+
params: {
|
|
803
|
+
conversation_id: string | number;
|
|
804
|
+
};
|
|
805
|
+
}) => string;
|
|
806
|
+
toSearchParams: {
|
|
807
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
808
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
809
|
+
};
|
|
810
|
+
} & {
|
|
811
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
812
|
+
};
|
|
813
|
+
sendMessage: _xano_sdk.QueryDef<{
|
|
814
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
815
|
+
readonly required: true;
|
|
816
|
+
}, "int">;
|
|
817
|
+
readonly content: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
818
|
+
readonly required: false;
|
|
819
|
+
readonly methods: readonly ["trim"];
|
|
820
|
+
readonly description: "The user's message. Must be non-empty after trimming.";
|
|
821
|
+
}, "text">;
|
|
822
|
+
readonly message: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
823
|
+
readonly required: false;
|
|
824
|
+
readonly methods: readonly ["trim"];
|
|
825
|
+
readonly description: "Alias for `content`.";
|
|
826
|
+
}, "text">;
|
|
827
|
+
readonly prompt: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
828
|
+
readonly required: false;
|
|
829
|
+
readonly methods: readonly ["trim"];
|
|
830
|
+
readonly description: "Alias for `content`.";
|
|
831
|
+
}, "text">;
|
|
832
|
+
}, ChatReply, _xano_sdk.RefValue<"reply">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
833
|
+
id: number;
|
|
834
|
+
created_at: number;
|
|
835
|
+
title: string;
|
|
836
|
+
last_message_at: number | null;
|
|
837
|
+
session_token?: unknown;
|
|
838
|
+
user_id?: unknown;
|
|
839
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
840
|
+
id: number;
|
|
841
|
+
created_at: number;
|
|
842
|
+
title: string;
|
|
843
|
+
last_message_at: number | null;
|
|
844
|
+
session_token?: unknown;
|
|
845
|
+
user_id?: unknown;
|
|
846
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>], `${string}/conversations/{conversation_id}/send`, "POST"> & {
|
|
847
|
+
getPath: (opts: {
|
|
848
|
+
canonical?: string;
|
|
849
|
+
params: {
|
|
850
|
+
conversation_id: string | number;
|
|
851
|
+
};
|
|
852
|
+
}) => string;
|
|
853
|
+
toSearchParams: {
|
|
854
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
855
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
856
|
+
};
|
|
857
|
+
} & {
|
|
858
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
859
|
+
};
|
|
860
|
+
deleteConversation: _xano_sdk.QueryDef<{
|
|
861
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
862
|
+
readonly required: true;
|
|
863
|
+
}, "int">;
|
|
864
|
+
}, never, _xano_sdk.ConstValue<null>, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
865
|
+
id: number;
|
|
866
|
+
created_at: number;
|
|
867
|
+
title: string;
|
|
868
|
+
last_message_at: number | null;
|
|
869
|
+
session_token?: unknown;
|
|
870
|
+
user_id?: unknown;
|
|
871
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, number>, _xano_sdk.Statement], `${string}/conversations/{conversation_id}`, "DELETE"> & {
|
|
872
|
+
getPath: (opts: {
|
|
873
|
+
canonical?: string;
|
|
874
|
+
params: {
|
|
875
|
+
conversation_id: string | number;
|
|
876
|
+
};
|
|
877
|
+
}) => string;
|
|
878
|
+
toSearchParams: {
|
|
879
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
880
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
881
|
+
};
|
|
882
|
+
} & {
|
|
883
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
884
|
+
};
|
|
885
|
+
/** `undefined` unless the guest family is also enabled — see above. */
|
|
886
|
+
claimConversation: (_xano_sdk.QueryDef<{
|
|
887
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
888
|
+
readonly required: true;
|
|
889
|
+
}, "int">;
|
|
890
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
891
|
+
readonly required: true;
|
|
892
|
+
readonly description: "The guest session token the thread was created with.";
|
|
893
|
+
}, "text">;
|
|
894
|
+
}, never, _xano_sdk.RefValue<"claimed">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
895
|
+
id: number;
|
|
896
|
+
created_at: number;
|
|
897
|
+
title: string;
|
|
898
|
+
last_message_at: number | null;
|
|
899
|
+
session_token?: unknown;
|
|
900
|
+
user_id?: unknown;
|
|
901
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"claimed", Pick<{
|
|
902
|
+
id: number;
|
|
903
|
+
created_at: number;
|
|
904
|
+
title: string;
|
|
905
|
+
last_message_at: number | null;
|
|
906
|
+
session_token?: unknown;
|
|
907
|
+
user_id?: unknown;
|
|
908
|
+
}, "id" | "title" | "last_message_at" | "created_at">>], `${string}/conversations/{conversation_id}/claim`, "POST"> & {
|
|
909
|
+
getPath: (opts: {
|
|
910
|
+
canonical?: string;
|
|
911
|
+
params: {
|
|
912
|
+
conversation_id: string | number;
|
|
913
|
+
};
|
|
914
|
+
}) => string;
|
|
915
|
+
toSearchParams: {
|
|
916
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
917
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
918
|
+
};
|
|
919
|
+
} & {
|
|
920
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
921
|
+
}) | undefined;
|
|
922
|
+
/**
|
|
923
|
+
* Every def above that actually exists, ready to register. Built as one array
|
|
924
|
+
* literal rather than a `push`, so the element type is the union of the
|
|
925
|
+
* handles rather than the first one's — each `query()` handle carries its own
|
|
926
|
+
* literal `name` in its type, so a mutable array would fix that type to
|
|
927
|
+
* whichever def happened to be first.
|
|
928
|
+
*/
|
|
929
|
+
all: ((_xano_sdk.QueryDef<{
|
|
930
|
+
readonly title: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
931
|
+
readonly methods: readonly ["trim"];
|
|
932
|
+
readonly description: "Optional thread title. Left blank, the first message's opening words become the title.";
|
|
933
|
+
}, "text">;
|
|
934
|
+
}, never, _xano_sdk.RefValue<"conversation">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"session_token", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
935
|
+
id: number;
|
|
936
|
+
created_at: number;
|
|
937
|
+
title: string;
|
|
938
|
+
last_message_at: number | null;
|
|
939
|
+
session_token?: unknown;
|
|
940
|
+
user_id?: unknown;
|
|
941
|
+
}, "id" | "title" | "last_message_at" | "created_at">>] | readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
942
|
+
id: number;
|
|
943
|
+
created_at: number;
|
|
944
|
+
title: string;
|
|
945
|
+
last_message_at: number | null;
|
|
946
|
+
session_token?: unknown;
|
|
947
|
+
user_id?: unknown;
|
|
948
|
+
}, "id" | "title" | "last_message_at" | "created_at">>], `${string}/conversations/create`, "POST"> & {
|
|
949
|
+
getPath: (opts?: {
|
|
950
|
+
canonical?: string;
|
|
951
|
+
}) => string;
|
|
952
|
+
toSearchParams: {
|
|
953
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
954
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
955
|
+
};
|
|
956
|
+
} & {
|
|
957
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
958
|
+
}) | (_xano_sdk.QueryDef<{}, never, _xano_sdk.RefValue<"conversations">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversations", Pick<{
|
|
959
|
+
id: number;
|
|
960
|
+
created_at: number;
|
|
961
|
+
title: string;
|
|
962
|
+
last_message_at: number | null;
|
|
963
|
+
session_token?: unknown;
|
|
964
|
+
user_id?: unknown;
|
|
965
|
+
}, "id" | "title" | "last_message_at" | "created_at">[]>], `${string}/conversations`, "GET"> & {
|
|
966
|
+
getPath: (opts?: {
|
|
967
|
+
canonical?: string;
|
|
968
|
+
}) => string;
|
|
969
|
+
toSearchParams: {
|
|
970
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
971
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
972
|
+
};
|
|
973
|
+
} & {
|
|
974
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
975
|
+
}) | (_xano_sdk.QueryDef<{
|
|
976
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
977
|
+
readonly required: true;
|
|
978
|
+
}, "int">;
|
|
979
|
+
}, PublicMessage[], _xano_sdk.RefValue<"messages">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
980
|
+
id: number;
|
|
981
|
+
created_at: number;
|
|
982
|
+
title: string;
|
|
983
|
+
last_message_at: number | null;
|
|
984
|
+
session_token?: unknown;
|
|
985
|
+
user_id?: unknown;
|
|
986
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
987
|
+
id: number;
|
|
988
|
+
created_at: number;
|
|
989
|
+
conversation_id: number;
|
|
990
|
+
role: "system" | "user" | "assistant";
|
|
991
|
+
content: string;
|
|
992
|
+
}, "id" | "created_at" | "conversation_id" | "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages", unknown>], `${string}/conversations/{conversation_id}/messages`, "GET"> & {
|
|
993
|
+
getPath: (opts: {
|
|
994
|
+
canonical?: string;
|
|
995
|
+
params: {
|
|
996
|
+
conversation_id: string | number;
|
|
997
|
+
};
|
|
998
|
+
}) => string;
|
|
999
|
+
toSearchParams: {
|
|
1000
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1001
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1002
|
+
};
|
|
1003
|
+
} & {
|
|
1004
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
1005
|
+
}) | (_xano_sdk.QueryDef<{
|
|
1006
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1007
|
+
readonly required: true;
|
|
1008
|
+
}, "int">;
|
|
1009
|
+
readonly content: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1010
|
+
readonly required: false;
|
|
1011
|
+
readonly methods: readonly ["trim"];
|
|
1012
|
+
readonly description: "The user's message. Must be non-empty after trimming.";
|
|
1013
|
+
}, "text">;
|
|
1014
|
+
readonly message: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1015
|
+
readonly required: false;
|
|
1016
|
+
readonly methods: readonly ["trim"];
|
|
1017
|
+
readonly description: "Alias for `content`.";
|
|
1018
|
+
}, "text">;
|
|
1019
|
+
readonly prompt: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1020
|
+
readonly required: false;
|
|
1021
|
+
readonly methods: readonly ["trim"];
|
|
1022
|
+
readonly description: "Alias for `content`.";
|
|
1023
|
+
}, "text">;
|
|
1024
|
+
}, ChatReply, _xano_sdk.RefValue<"reply">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1025
|
+
id: number;
|
|
1026
|
+
created_at: number;
|
|
1027
|
+
title: string;
|
|
1028
|
+
last_message_at: number | null;
|
|
1029
|
+
session_token?: unknown;
|
|
1030
|
+
user_id?: unknown;
|
|
1031
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1032
|
+
id: number;
|
|
1033
|
+
created_at: number;
|
|
1034
|
+
title: string;
|
|
1035
|
+
last_message_at: number | null;
|
|
1036
|
+
session_token?: unknown;
|
|
1037
|
+
user_id?: unknown;
|
|
1038
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>], `${string}/conversations/{conversation_id}/send`, "POST"> & {
|
|
1039
|
+
getPath: (opts: {
|
|
1040
|
+
canonical?: string;
|
|
1041
|
+
params: {
|
|
1042
|
+
conversation_id: string | number;
|
|
1043
|
+
};
|
|
1044
|
+
}) => string;
|
|
1045
|
+
toSearchParams: {
|
|
1046
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1047
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1048
|
+
};
|
|
1049
|
+
} & {
|
|
1050
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
1051
|
+
}) | (_xano_sdk.QueryDef<{
|
|
1052
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1053
|
+
readonly required: true;
|
|
1054
|
+
}, "int">;
|
|
1055
|
+
}, never, _xano_sdk.ConstValue<null>, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1056
|
+
id: number;
|
|
1057
|
+
created_at: number;
|
|
1058
|
+
title: string;
|
|
1059
|
+
last_message_at: number | null;
|
|
1060
|
+
session_token?: unknown;
|
|
1061
|
+
user_id?: unknown;
|
|
1062
|
+
}, "id" | "user_id"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, number>, _xano_sdk.Statement], `${string}/conversations/{conversation_id}`, "DELETE"> & {
|
|
1063
|
+
getPath: (opts: {
|
|
1064
|
+
canonical?: string;
|
|
1065
|
+
params: {
|
|
1066
|
+
conversation_id: string | number;
|
|
1067
|
+
};
|
|
1068
|
+
}) => string;
|
|
1069
|
+
toSearchParams: {
|
|
1070
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1071
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1072
|
+
};
|
|
1073
|
+
} & {
|
|
1074
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
1075
|
+
}) | (_xano_sdk.QueryDef<{
|
|
1076
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1077
|
+
readonly required: true;
|
|
1078
|
+
}, "int">;
|
|
1079
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1080
|
+
readonly required: true;
|
|
1081
|
+
readonly description: "The guest session token the thread was created with.";
|
|
1082
|
+
}, "text">;
|
|
1083
|
+
}, never, _xano_sdk.RefValue<"claimed">, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1084
|
+
id: number;
|
|
1085
|
+
created_at: number;
|
|
1086
|
+
title: string;
|
|
1087
|
+
last_message_at: number | null;
|
|
1088
|
+
session_token?: unknown;
|
|
1089
|
+
user_id?: unknown;
|
|
1090
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"claimed", Pick<{
|
|
1091
|
+
id: number;
|
|
1092
|
+
created_at: number;
|
|
1093
|
+
title: string;
|
|
1094
|
+
last_message_at: number | null;
|
|
1095
|
+
session_token?: unknown;
|
|
1096
|
+
user_id?: unknown;
|
|
1097
|
+
}, "id" | "title" | "last_message_at" | "created_at">>], `${string}/conversations/{conversation_id}/claim`, "POST"> & {
|
|
1098
|
+
getPath: (opts: {
|
|
1099
|
+
canonical?: string;
|
|
1100
|
+
params: {
|
|
1101
|
+
conversation_id: string | number;
|
|
1102
|
+
};
|
|
1103
|
+
}) => string;
|
|
1104
|
+
toSearchParams: {
|
|
1105
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1106
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1107
|
+
};
|
|
1108
|
+
} & {
|
|
1109
|
+
auth?: string | _xano_sdk.TableDef<string, unknown, string> | undefined;
|
|
1110
|
+
}))[];
|
|
1111
|
+
};
|
|
1112
|
+
|
|
1113
|
+
declare function guestQueries(opts: ResolvedOptions, group: ChatbotGroup, conversation: ConversationTable, message: MessageTable, replyFn: GenerateReplyFn): {
|
|
1114
|
+
createConversation: _xano_sdk.QueryDef<{
|
|
1115
|
+
readonly title: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1116
|
+
readonly methods: readonly ["trim"];
|
|
1117
|
+
readonly description: "Optional thread title. Left blank, the first message's opening words become the title.";
|
|
1118
|
+
}, "text">;
|
|
1119
|
+
}, never, {
|
|
1120
|
+
id: _xano_sdk.RefValue<"conversation.id">;
|
|
1121
|
+
created_at: _xano_sdk.RefValue<"conversation.created_at">;
|
|
1122
|
+
title: _xano_sdk.RefValue<"conversation.title">;
|
|
1123
|
+
last_message_at: _xano_sdk.RefValue<"conversation.last_message_at">;
|
|
1124
|
+
session_token: _xano_sdk.RefValue<"session_token">;
|
|
1125
|
+
}, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"session_token", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1126
|
+
id: number;
|
|
1127
|
+
created_at: number;
|
|
1128
|
+
title: string;
|
|
1129
|
+
last_message_at: number | null;
|
|
1130
|
+
session_token?: unknown;
|
|
1131
|
+
user_id?: unknown;
|
|
1132
|
+
}, "id" | "title" | "last_message_at" | "created_at">>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"session_token", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1133
|
+
id: number;
|
|
1134
|
+
created_at: number;
|
|
1135
|
+
title: string;
|
|
1136
|
+
last_message_at: number | null;
|
|
1137
|
+
session_token?: unknown;
|
|
1138
|
+
user_id?: unknown;
|
|
1139
|
+
}, "id" | "title" | "last_message_at" | "created_at">>], `${string}/guest/conversations/create`, "POST"> & {
|
|
1140
|
+
getPath: (opts?: {
|
|
1141
|
+
canonical?: string;
|
|
1142
|
+
}) => string;
|
|
1143
|
+
toSearchParams: {
|
|
1144
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1145
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1146
|
+
};
|
|
1147
|
+
} & {
|
|
1148
|
+
auth?: unknown;
|
|
1149
|
+
};
|
|
1150
|
+
listMessages: _xano_sdk.QueryDef<{
|
|
1151
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1152
|
+
readonly required: true;
|
|
1153
|
+
}, "int">;
|
|
1154
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1155
|
+
readonly required: true;
|
|
1156
|
+
readonly description: "The token returned when the conversation was created.";
|
|
1157
|
+
}, "text">;
|
|
1158
|
+
}, PublicMessage[], _xano_sdk.RefValue<"messages">, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1159
|
+
id: number;
|
|
1160
|
+
created_at: number;
|
|
1161
|
+
title: string;
|
|
1162
|
+
last_message_at: number | null;
|
|
1163
|
+
session_token?: unknown;
|
|
1164
|
+
user_id?: unknown;
|
|
1165
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
1166
|
+
id: number;
|
|
1167
|
+
created_at: number;
|
|
1168
|
+
conversation_id: number;
|
|
1169
|
+
role: "system" | "user" | "assistant";
|
|
1170
|
+
content: string;
|
|
1171
|
+
}, "id" | "created_at" | "conversation_id" | "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages", unknown>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1172
|
+
id: number;
|
|
1173
|
+
created_at: number;
|
|
1174
|
+
title: string;
|
|
1175
|
+
last_message_at: number | null;
|
|
1176
|
+
session_token?: unknown;
|
|
1177
|
+
user_id?: unknown;
|
|
1178
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
1179
|
+
id: number;
|
|
1180
|
+
created_at: number;
|
|
1181
|
+
conversation_id: number;
|
|
1182
|
+
role: "system" | "user" | "assistant";
|
|
1183
|
+
content: string;
|
|
1184
|
+
}, "id" | "created_at" | "conversation_id" | "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages", unknown>], `${string}/guest/conversations/{conversation_id}/messages`, "GET"> & {
|
|
1185
|
+
getPath: (opts: {
|
|
1186
|
+
canonical?: string;
|
|
1187
|
+
params: {
|
|
1188
|
+
conversation_id: string | number;
|
|
1189
|
+
};
|
|
1190
|
+
}) => string;
|
|
1191
|
+
toSearchParams: {
|
|
1192
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1193
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1194
|
+
};
|
|
1195
|
+
} & {
|
|
1196
|
+
auth?: unknown;
|
|
1197
|
+
};
|
|
1198
|
+
sendMessage: _xano_sdk.QueryDef<{
|
|
1199
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1200
|
+
readonly required: true;
|
|
1201
|
+
}, "int">;
|
|
1202
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1203
|
+
readonly required: true;
|
|
1204
|
+
}, "text">;
|
|
1205
|
+
readonly content: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1206
|
+
readonly required: false;
|
|
1207
|
+
readonly methods: readonly ["trim"];
|
|
1208
|
+
readonly description: "The user's message. Must be non-empty after trimming.";
|
|
1209
|
+
}, "text">;
|
|
1210
|
+
readonly message: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1211
|
+
readonly required: false;
|
|
1212
|
+
readonly methods: readonly ["trim"];
|
|
1213
|
+
readonly description: "Alias for `content`.";
|
|
1214
|
+
}, "text">;
|
|
1215
|
+
readonly prompt: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1216
|
+
readonly required: false;
|
|
1217
|
+
readonly methods: readonly ["trim"];
|
|
1218
|
+
readonly description: "Alias for `content`.";
|
|
1219
|
+
}, "text">;
|
|
1220
|
+
}, ChatReply, _xano_sdk.RefValue<"reply">, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1221
|
+
id: number;
|
|
1222
|
+
created_at: number;
|
|
1223
|
+
title: string;
|
|
1224
|
+
last_message_at: number | null;
|
|
1225
|
+
session_token?: unknown;
|
|
1226
|
+
user_id?: unknown;
|
|
1227
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1228
|
+
id: number;
|
|
1229
|
+
created_at: number;
|
|
1230
|
+
title: string;
|
|
1231
|
+
last_message_at: number | null;
|
|
1232
|
+
session_token?: unknown;
|
|
1233
|
+
user_id?: unknown;
|
|
1234
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1235
|
+
id: number;
|
|
1236
|
+
created_at: number;
|
|
1237
|
+
title: string;
|
|
1238
|
+
last_message_at: number | null;
|
|
1239
|
+
session_token?: unknown;
|
|
1240
|
+
user_id?: unknown;
|
|
1241
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1242
|
+
id: number;
|
|
1243
|
+
created_at: number;
|
|
1244
|
+
title: string;
|
|
1245
|
+
last_message_at: number | null;
|
|
1246
|
+
session_token?: unknown;
|
|
1247
|
+
user_id?: unknown;
|
|
1248
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>], `${string}/guest/conversations/{conversation_id}/send`, "POST"> & {
|
|
1249
|
+
getPath: (opts: {
|
|
1250
|
+
canonical?: string;
|
|
1251
|
+
params: {
|
|
1252
|
+
conversation_id: string | number;
|
|
1253
|
+
};
|
|
1254
|
+
}) => string;
|
|
1255
|
+
toSearchParams: {
|
|
1256
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1257
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1258
|
+
};
|
|
1259
|
+
} & {
|
|
1260
|
+
auth?: unknown;
|
|
1261
|
+
};
|
|
1262
|
+
deleteConversation: _xano_sdk.QueryDef<{
|
|
1263
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1264
|
+
readonly required: true;
|
|
1265
|
+
}, "int">;
|
|
1266
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1267
|
+
readonly required: true;
|
|
1268
|
+
}, "text">;
|
|
1269
|
+
}, never, _xano_sdk.ConstValue<null>, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1270
|
+
id: number;
|
|
1271
|
+
created_at: number;
|
|
1272
|
+
title: string;
|
|
1273
|
+
last_message_at: number | null;
|
|
1274
|
+
session_token?: unknown;
|
|
1275
|
+
user_id?: unknown;
|
|
1276
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, number>, _xano_sdk.Statement] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1277
|
+
id: number;
|
|
1278
|
+
created_at: number;
|
|
1279
|
+
title: string;
|
|
1280
|
+
last_message_at: number | null;
|
|
1281
|
+
session_token?: unknown;
|
|
1282
|
+
user_id?: unknown;
|
|
1283
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, number>, _xano_sdk.Statement], `${string}/guest/conversations/{conversation_id}/delete`, "POST"> & {
|
|
1284
|
+
getPath: (opts: {
|
|
1285
|
+
canonical?: string;
|
|
1286
|
+
params: {
|
|
1287
|
+
conversation_id: string | number;
|
|
1288
|
+
};
|
|
1289
|
+
}) => string;
|
|
1290
|
+
toSearchParams: {
|
|
1291
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1292
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1293
|
+
};
|
|
1294
|
+
} & {
|
|
1295
|
+
auth?: unknown;
|
|
1296
|
+
};
|
|
1297
|
+
all: ((_xano_sdk.QueryDef<{
|
|
1298
|
+
readonly title: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1299
|
+
readonly methods: readonly ["trim"];
|
|
1300
|
+
readonly description: "Optional thread title. Left blank, the first message's opening words become the title.";
|
|
1301
|
+
}, "text">;
|
|
1302
|
+
}, never, {
|
|
1303
|
+
id: _xano_sdk.RefValue<"conversation.id">;
|
|
1304
|
+
created_at: _xano_sdk.RefValue<"conversation.created_at">;
|
|
1305
|
+
title: _xano_sdk.RefValue<"conversation.title">;
|
|
1306
|
+
last_message_at: _xano_sdk.RefValue<"conversation.last_message_at">;
|
|
1307
|
+
session_token: _xano_sdk.RefValue<"session_token">;
|
|
1308
|
+
}, readonly [_xano_sdk.Statement & _xano_sdk.AsShapeBrand<"session_token", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1309
|
+
id: number;
|
|
1310
|
+
created_at: number;
|
|
1311
|
+
title: string;
|
|
1312
|
+
last_message_at: number | null;
|
|
1313
|
+
session_token?: unknown;
|
|
1314
|
+
user_id?: unknown;
|
|
1315
|
+
}, "id" | "title" | "last_message_at" | "created_at">>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"session_token", string>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1316
|
+
id: number;
|
|
1317
|
+
created_at: number;
|
|
1318
|
+
title: string;
|
|
1319
|
+
last_message_at: number | null;
|
|
1320
|
+
session_token?: unknown;
|
|
1321
|
+
user_id?: unknown;
|
|
1322
|
+
}, "id" | "title" | "last_message_at" | "created_at">>], `${string}/guest/conversations/create`, "POST"> & {
|
|
1323
|
+
getPath: (opts?: {
|
|
1324
|
+
canonical?: string;
|
|
1325
|
+
}) => string;
|
|
1326
|
+
toSearchParams: {
|
|
1327
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1328
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1329
|
+
};
|
|
1330
|
+
} & {
|
|
1331
|
+
auth?: unknown;
|
|
1332
|
+
}) | (_xano_sdk.QueryDef<{
|
|
1333
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1334
|
+
readonly required: true;
|
|
1335
|
+
}, "int">;
|
|
1336
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1337
|
+
readonly required: true;
|
|
1338
|
+
readonly description: "The token returned when the conversation was created.";
|
|
1339
|
+
}, "text">;
|
|
1340
|
+
}, PublicMessage[], _xano_sdk.RefValue<"messages">, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1341
|
+
id: number;
|
|
1342
|
+
created_at: number;
|
|
1343
|
+
title: string;
|
|
1344
|
+
last_message_at: number | null;
|
|
1345
|
+
session_token?: unknown;
|
|
1346
|
+
user_id?: unknown;
|
|
1347
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
1348
|
+
id: number;
|
|
1349
|
+
created_at: number;
|
|
1350
|
+
conversation_id: number;
|
|
1351
|
+
role: "system" | "user" | "assistant";
|
|
1352
|
+
content: string;
|
|
1353
|
+
}, "id" | "created_at" | "conversation_id" | "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages", unknown>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1354
|
+
id: number;
|
|
1355
|
+
created_at: number;
|
|
1356
|
+
title: string;
|
|
1357
|
+
last_message_at: number | null;
|
|
1358
|
+
session_token?: unknown;
|
|
1359
|
+
user_id?: unknown;
|
|
1360
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"recent", Pick<{
|
|
1361
|
+
id: number;
|
|
1362
|
+
created_at: number;
|
|
1363
|
+
conversation_id: number;
|
|
1364
|
+
role: "system" | "user" | "assistant";
|
|
1365
|
+
content: string;
|
|
1366
|
+
}, "id" | "created_at" | "conversation_id" | "role" | "content">[]>, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"messages", unknown>], `${string}/guest/conversations/{conversation_id}/messages`, "GET"> & {
|
|
1367
|
+
getPath: (opts: {
|
|
1368
|
+
canonical?: string;
|
|
1369
|
+
params: {
|
|
1370
|
+
conversation_id: string | number;
|
|
1371
|
+
};
|
|
1372
|
+
}) => string;
|
|
1373
|
+
toSearchParams: {
|
|
1374
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1375
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1376
|
+
};
|
|
1377
|
+
} & {
|
|
1378
|
+
auth?: unknown;
|
|
1379
|
+
}) | (_xano_sdk.QueryDef<{
|
|
1380
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1381
|
+
readonly required: true;
|
|
1382
|
+
}, "int">;
|
|
1383
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1384
|
+
readonly required: true;
|
|
1385
|
+
}, "text">;
|
|
1386
|
+
readonly content: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1387
|
+
readonly required: false;
|
|
1388
|
+
readonly methods: readonly ["trim"];
|
|
1389
|
+
readonly description: "The user's message. Must be non-empty after trimming.";
|
|
1390
|
+
}, "text">;
|
|
1391
|
+
readonly message: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1392
|
+
readonly required: false;
|
|
1393
|
+
readonly methods: readonly ["trim"];
|
|
1394
|
+
readonly description: "Alias for `content`.";
|
|
1395
|
+
}, "text">;
|
|
1396
|
+
readonly prompt: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1397
|
+
readonly required: false;
|
|
1398
|
+
readonly methods: readonly ["trim"];
|
|
1399
|
+
readonly description: "Alias for `content`.";
|
|
1400
|
+
}, "text">;
|
|
1401
|
+
}, ChatReply, _xano_sdk.RefValue<"reply">, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1402
|
+
id: number;
|
|
1403
|
+
created_at: number;
|
|
1404
|
+
title: string;
|
|
1405
|
+
last_message_at: number | null;
|
|
1406
|
+
session_token?: unknown;
|
|
1407
|
+
user_id?: unknown;
|
|
1408
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1409
|
+
id: number;
|
|
1410
|
+
created_at: number;
|
|
1411
|
+
title: string;
|
|
1412
|
+
last_message_at: number | null;
|
|
1413
|
+
session_token?: unknown;
|
|
1414
|
+
user_id?: unknown;
|
|
1415
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1416
|
+
id: number;
|
|
1417
|
+
created_at: number;
|
|
1418
|
+
title: string;
|
|
1419
|
+
last_message_at: number | null;
|
|
1420
|
+
session_token?: unknown;
|
|
1421
|
+
user_id?: unknown;
|
|
1422
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>] | readonly [_xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1423
|
+
id: number;
|
|
1424
|
+
created_at: number;
|
|
1425
|
+
title: string;
|
|
1426
|
+
last_message_at: number | null;
|
|
1427
|
+
session_token?: unknown;
|
|
1428
|
+
user_id?: unknown;
|
|
1429
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"resolved_turn_content", unknown>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"reply", ChatReply>], `${string}/guest/conversations/{conversation_id}/send`, "POST"> & {
|
|
1430
|
+
getPath: (opts: {
|
|
1431
|
+
canonical?: string;
|
|
1432
|
+
params: {
|
|
1433
|
+
conversation_id: string | number;
|
|
1434
|
+
};
|
|
1435
|
+
}) => string;
|
|
1436
|
+
toSearchParams: {
|
|
1437
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1438
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1439
|
+
};
|
|
1440
|
+
} & {
|
|
1441
|
+
auth?: unknown;
|
|
1442
|
+
}) | (_xano_sdk.QueryDef<{
|
|
1443
|
+
readonly conversation_id: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<number, {
|
|
1444
|
+
readonly required: true;
|
|
1445
|
+
}, "int">;
|
|
1446
|
+
readonly session_token: _xano_sdk.InputDescriptor & _xano_sdk.TypeBrand<string, {
|
|
1447
|
+
readonly required: true;
|
|
1448
|
+
}, "text">;
|
|
1449
|
+
}, never, _xano_sdk.ConstValue<null>, readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1450
|
+
id: number;
|
|
1451
|
+
created_at: number;
|
|
1452
|
+
title: string;
|
|
1453
|
+
last_message_at: number | null;
|
|
1454
|
+
session_token?: unknown;
|
|
1455
|
+
user_id?: unknown;
|
|
1456
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, number>, _xano_sdk.Statement] | readonly [_xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<"conversation", Pick<{
|
|
1457
|
+
id: number;
|
|
1458
|
+
created_at: number;
|
|
1459
|
+
title: string;
|
|
1460
|
+
last_message_at: number | null;
|
|
1461
|
+
session_token?: unknown;
|
|
1462
|
+
user_id?: unknown;
|
|
1463
|
+
}, "id" | "user_id" | "session_token"> | null>, _xano_sdk.Statement, _xano_sdk.Statement & _xano_sdk.AsShapeBrand<string, number>, _xano_sdk.Statement], `${string}/guest/conversations/{conversation_id}/delete`, "POST"> & {
|
|
1464
|
+
getPath: (opts: {
|
|
1465
|
+
canonical?: string;
|
|
1466
|
+
params: {
|
|
1467
|
+
conversation_id: string | number;
|
|
1468
|
+
};
|
|
1469
|
+
}) => string;
|
|
1470
|
+
toSearchParams: {
|
|
1471
|
+
(input: Record<string, _xano_sdk.SearchParamValue>): _xano_sdk.SearchParams;
|
|
1472
|
+
(input: Record<string, unknown>): _xano_sdk.SearchParams;
|
|
1473
|
+
};
|
|
1474
|
+
} & {
|
|
1475
|
+
auth?: unknown;
|
|
1476
|
+
}))[];
|
|
1477
|
+
};
|
|
1478
|
+
|
|
1479
|
+
/**
|
|
1480
|
+
* `createChatbot(opts)` — build every def for one configuration.
|
|
1481
|
+
* `registerChatbot(xano, opts)` — build them and register them in one call.
|
|
1482
|
+
*
|
|
1483
|
+
* There is **no cross-call agreement checking** here, unlike `@xano-sdk/auth`'s
|
|
1484
|
+
* `registerAuth`. Auth needs it because its `authenticationGroup` is a
|
|
1485
|
+
* process-wide module singleton: a second `registerAuth` could silently retarget
|
|
1486
|
+
* the first workspace's group, and omitting an option could make one workspace
|
|
1487
|
+
* inherit another's canonical. Every def here is minted fresh per
|
|
1488
|
+
* `createChatbot` call, so two calls simply produce two independent sets and
|
|
1489
|
+
* there is nothing to reconcile.
|
|
1490
|
+
*
|
|
1491
|
+
* There IS an idempotency guard, for a different reason. Core's own duplicate-def
|
|
1492
|
+
* guard compares def **identity**, and two `createChatbot` calls produce distinct
|
|
1493
|
+
* objects that merely share names — so a second `registerChatbot` on one instance
|
|
1494
|
+
* slips past it and fails much later at `export()` with
|
|
1495
|
+
*
|
|
1496
|
+
* Duplicate object guid (82dcb96…) shared by "dbo/conversation" and "dbo/conversation"
|
|
1497
|
+
*
|
|
1498
|
+
* which names one guid, the same label twice, and neither call. The WeakSet below
|
|
1499
|
+
* reports it at the call that made it.
|
|
1500
|
+
*/
|
|
1501
|
+
|
|
1502
|
+
/** The token-authenticated endpoint family. */
|
|
1503
|
+
type AuthenticatedFamily = ReturnType<typeof authenticatedQueries>;
|
|
1504
|
+
/** The public guest endpoint family. */
|
|
1505
|
+
type GuestFamily = ReturnType<typeof guestQueries>;
|
|
1506
|
+
/**
|
|
1507
|
+
* Which families a given options object produces, decided at the type level.
|
|
1508
|
+
*
|
|
1509
|
+
* `authenticated` defaults to **true** and `guest` to **false**, so for the
|
|
1510
|
+
* overwhelmingly common call — `registerChatbot(xano, { authTable })` — these
|
|
1511
|
+
* resolve to a present `authenticated` and an absent `guest`, and a consumer
|
|
1512
|
+
* writes `bot.authenticated.sendMessage` with no `!`. Typing both as
|
|
1513
|
+
* `| undefined` unconditionally made every caller pay for a configuration
|
|
1514
|
+
* almost none of them use.
|
|
1515
|
+
*
|
|
1516
|
+
* A non-literal flag (`{ guest: someBoolean }`) is genuinely unknowable at
|
|
1517
|
+
* compile time, so it widens back to `… | undefined` — correct, and the only
|
|
1518
|
+
* case that still needs a check.
|
|
1519
|
+
*
|
|
1520
|
+
* ⚠ Written as structural `O extends { authenticated: … }` checks rather than the
|
|
1521
|
+
* shorter indexed access `O["authenticated"]`. When the key is ABSENT from `O`,
|
|
1522
|
+
* an indexed access falls back to the CONSTRAINT — `boolean | undefined` — so
|
|
1523
|
+
* every default install looked like a runtime boolean and stayed nullable, which
|
|
1524
|
+
* is the exact papercut this exists to remove. `extends` detects the missing key.
|
|
1525
|
+
*/
|
|
1526
|
+
type AuthenticatedOf<O extends ChatbotOptions> = O extends {
|
|
1527
|
+
authenticated: false;
|
|
1528
|
+
} ? undefined : O extends {
|
|
1529
|
+
authenticated: true;
|
|
1530
|
+
} ? AuthenticatedFamily : O extends {
|
|
1531
|
+
authenticated: boolean;
|
|
1532
|
+
} ? AuthenticatedFamily | undefined : AuthenticatedFamily;
|
|
1533
|
+
/** @see {@link AuthenticatedOf} — the same rule, inverted (guest is off by default). */
|
|
1534
|
+
type GuestOf<O extends ChatbotOptions> = O extends {
|
|
1535
|
+
guest: true;
|
|
1536
|
+
} ? GuestFamily : O extends {
|
|
1537
|
+
guest: false;
|
|
1538
|
+
} ? undefined : O extends {
|
|
1539
|
+
guest: boolean;
|
|
1540
|
+
} ? GuestFamily | undefined : undefined;
|
|
1541
|
+
/**
|
|
1542
|
+
* Everything one `createChatbot` call produces.
|
|
1543
|
+
*
|
|
1544
|
+
* Parameterized by the options it was built from, so `authenticated` and `guest`
|
|
1545
|
+
* are present or absent according to those options rather than always nullable.
|
|
1546
|
+
* The bare `Chatbot` (no type argument) keeps both nullable — it describes *any*
|
|
1547
|
+
* configuration, which is what a variable annotated by hand should mean.
|
|
1548
|
+
*/
|
|
1549
|
+
interface Chatbot<O extends ChatbotOptions = ChatbotOptions> {
|
|
1550
|
+
/** The resolved, fully-defaulted options these defs were built from. */
|
|
1551
|
+
options: ResolvedOptions;
|
|
1552
|
+
conversation: ReturnType<typeof conversationTable>;
|
|
1553
|
+
message: ReturnType<typeof messageTable>;
|
|
1554
|
+
agent: ReturnType<typeof chatAgent>;
|
|
1555
|
+
replyFn: ReturnType<typeof generateReplyFn>;
|
|
1556
|
+
group: ReturnType<typeof chatbotGroup>;
|
|
1557
|
+
/** The authenticated family. Absent only with `{ authenticated: false }`. */
|
|
1558
|
+
authenticated: AuthenticatedOf<O>;
|
|
1559
|
+
/** The guest family. Present only with `{ guest: true }`. */
|
|
1560
|
+
guest: GuestOf<O>;
|
|
1561
|
+
/** Every query def across both enabled families, ready for `registerQueries`. */
|
|
1562
|
+
queries: (AuthenticatedFamily["all"][number] | GuestFamily["all"][number])[];
|
|
1563
|
+
}
|
|
1564
|
+
/**
|
|
1565
|
+
* Build the full def set without registering anything.
|
|
1566
|
+
*
|
|
1567
|
+
* Reach for this over `registerChatbot` when you want to cherry-pick, reorder
|
|
1568
|
+
* registration around your own defs, or reference a def (the agent, the message
|
|
1569
|
+
* table) from a stack of your own. This is the cherry-pick path — a factory
|
|
1570
|
+
* package has no module-level def to import.
|
|
1571
|
+
*
|
|
1572
|
+
* ```ts
|
|
1573
|
+
* const bot = createChatbot({ authTable: userTable });
|
|
1574
|
+
* xano.registerTables([bot.conversation, bot.message]);
|
|
1575
|
+
* // …register only the endpoints you want
|
|
1576
|
+
* xano.registerQueries([bot.authenticated.sendMessage]);
|
|
1577
|
+
* ```
|
|
1578
|
+
*
|
|
1579
|
+
* Dependencies travel together: the queries need both tables, the reply function
|
|
1580
|
+
* and the agent; the reply function needs both tables and the agent. Registering
|
|
1581
|
+
* a query without them exports a reference to an object the workspace does not
|
|
1582
|
+
* hold, which fails the export.
|
|
1583
|
+
*/
|
|
1584
|
+
declare function createChatbot<const O extends ChatbotOptions = Record<string, never>>(opts?: O): Chatbot<O>;
|
|
1585
|
+
/** What {@link registerChatbot} hands back: the def set, plus the instance it was registered on. */
|
|
1586
|
+
interface RegisteredChatbot<X extends Xano, O extends ChatbotOptions = ChatbotOptions> extends Chatbot<O> {
|
|
1587
|
+
/**
|
|
1588
|
+
* The instance the defs were registered on — the same object that was passed
|
|
1589
|
+
* in, for `export default`.
|
|
1590
|
+
*/
|
|
1591
|
+
xano: X;
|
|
1592
|
+
}
|
|
1593
|
+
/**
|
|
1594
|
+
* Build and register the full set on the given instance.
|
|
1595
|
+
*
|
|
1596
|
+
* ```ts
|
|
1597
|
+
* import { workspace } from "@xano/sdk";
|
|
1598
|
+
* import { registerAuth, userTable } from "@xano-sdk/auth";
|
|
1599
|
+
* import { registerChatbot } from "@xano-sdk/chatbot";
|
|
1600
|
+
*
|
|
1601
|
+
* const xano = registerAuth(workspace("my-app"));
|
|
1602
|
+
* export const bot = registerChatbot(xano, { authTable: userTable });
|
|
1603
|
+
*
|
|
1604
|
+
* export default bot.xano; // the default export must be the Xano registry
|
|
1605
|
+
* ```
|
|
1606
|
+
*
|
|
1607
|
+
* **Why this returns the defs and not the instance.** The defs are factories, so
|
|
1608
|
+
* a consumer has no `import { sendMessage }` to point `InferInput<typeof …>` at —
|
|
1609
|
+
* the handle returned here is the only route to the real, registered defs.
|
|
1610
|
+
* Returning the bare instance made the turnkey path structurally un-typeable and
|
|
1611
|
+
* pushed frontends into calling {@link createChatbot} a second time at runtime,
|
|
1612
|
+
* which drags the whole statement graph into the browser bundle to obtain a type
|
|
1613
|
+
* that erases. Exporting `bot` and importing it with `import type` costs nothing:
|
|
1614
|
+
*
|
|
1615
|
+
* ```ts
|
|
1616
|
+
* // frontend — erases completely at build time
|
|
1617
|
+
* import type { bot } from "../xano/index.js";
|
|
1618
|
+
* type Send = typeof bot.authenticated.sendMessage;
|
|
1619
|
+
* ```
|
|
1620
|
+
*
|
|
1621
|
+
* For the common shapes there is no need to drill at all — `SendMessageBody`,
|
|
1622
|
+
* `ChatReply`, `ListConversationsResponse` and friends are exported directly.
|
|
1623
|
+
*
|
|
1624
|
+
* Note what the example does *not* do: this package never registers the auth
|
|
1625
|
+
* table. It only references it, and a reference resolves through the same
|
|
1626
|
+
* name-derived guid the table itself emits, so registration order does not matter
|
|
1627
|
+
* — and a consumer whose auth table is already registered by `registerAuth` (or by
|
|
1628
|
+
* hand) does not get a duplicate.
|
|
1629
|
+
*
|
|
1630
|
+
* Use {@link createChatbot} when you want the defs *without* registering them —
|
|
1631
|
+
* to cherry-pick a subset, or to reference one from a stack of your own.
|
|
1632
|
+
*/
|
|
1633
|
+
declare function registerChatbot<X extends Xano, const O extends ChatbotOptions = Record<string, never>>(xano: X, opts?: O): RegisteredChatbot<X, O>;
|
|
1634
|
+
|
|
1635
|
+
/**
|
|
1636
|
+
* Request and response types for every endpoint — what a client sends and gets
|
|
1637
|
+
* back, and **where each input travels**.
|
|
1638
|
+
*
|
|
1639
|
+
* These exist because the defs are **factories** (see `register.ts`), so there is
|
|
1640
|
+
* no module-level `sendMessage` to write `InferInput<typeof sendMessage>`
|
|
1641
|
+
* against. Reaching the handles through the factory's return type is a type-level
|
|
1642
|
+
* operation — nothing is built, nothing is evaluated — so a browser importing
|
|
1643
|
+
* these pulls in no statement stack and no SDK runtime.
|
|
1644
|
+
*
|
|
1645
|
+
* ## The naming rule
|
|
1646
|
+
*
|
|
1647
|
+
* Every name is `<HandleName><Part>`, where the handle name is exactly the
|
|
1648
|
+
* property on `bot.authenticated` / `bot.guest` (`sendMessage` →
|
|
1649
|
+
* `SendMessage…`). One vocabulary for the def, the type, and the endpoint map.
|
|
1650
|
+
*
|
|
1651
|
+
* | part | is | goes |
|
|
1652
|
+
* |---|---|---|
|
|
1653
|
+
* | `…Params` | path parameters | interpolated into the URL |
|
|
1654
|
+
* | `…Query` | query-string parameters | `?a=b` |
|
|
1655
|
+
* | `…Body` | the JSON body | the request body |
|
|
1656
|
+
* | `…Input` | everything core derives — all three at once | — |
|
|
1657
|
+
* | `…Response` | what comes back | — |
|
|
1658
|
+
*
|
|
1659
|
+
* A part that an endpoint does not have is simply not exported for it, so the
|
|
1660
|
+
* presence of a name is itself the answer to "does this take a body?".
|
|
1661
|
+
*
|
|
1662
|
+
* **Why the split matters.** `…Input` alone is not enough to write a request:
|
|
1663
|
+
* `SendMessageInput` contains `conversation_id`, but that is read off the URL,
|
|
1664
|
+
* so `JSON.stringify(input)` sends a field the endpoint ignores while the type
|
|
1665
|
+
* still demands it. That forced `Partial<…>` on every call and threw away the
|
|
1666
|
+
* check on the field you *do* have to send. It is security-relevant on the guest
|
|
1667
|
+
* family too: `session_token` is a bearer credential, and whether it belongs in
|
|
1668
|
+
* the query string or the body is exactly the distinction
|
|
1669
|
+
* `GuestListMessagesQuery` vs `GuestSendMessageBody` encodes.
|
|
1670
|
+
*/
|
|
1671
|
+
|
|
1672
|
+
/** The authenticated family's handles, as types. Builds nothing. */
|
|
1673
|
+
type Auth = ReturnType<typeof authenticatedQueries>;
|
|
1674
|
+
/** The guest family's handles, as types. Builds nothing. */
|
|
1675
|
+
type Guest = ReturnType<typeof guestQueries>;
|
|
1676
|
+
/** The path parameter every per-thread route carries. */
|
|
1677
|
+
type Thread = "conversation_id";
|
|
1678
|
+
/** `POST {prefix}/conversations/create` */
|
|
1679
|
+
type CreateConversationInput = InferInput<Auth["createConversation"]>;
|
|
1680
|
+
/** `POST {prefix}/conversations/create` — the JSON body (`{}` is valid). */
|
|
1681
|
+
type CreateConversationBody = CreateConversationInput;
|
|
1682
|
+
/** `POST {prefix}/conversations/create` */
|
|
1683
|
+
type CreateConversationResponse = InferResponse<Auth["createConversation"]>;
|
|
1684
|
+
/** `GET {prefix}/conversations` — takes nothing. */
|
|
1685
|
+
type ListConversationsResponse = InferResponse<Auth["listConversations"]>;
|
|
1686
|
+
/** `GET {prefix}/conversations/{conversation_id}/messages` */
|
|
1687
|
+
type ListMessagesInput = InferInput<Auth["listMessages"]>;
|
|
1688
|
+
/** `GET {prefix}/conversations/{conversation_id}/messages` — path parameters. */
|
|
1689
|
+
type ListMessagesParams = Pick<ListMessagesInput, Thread>;
|
|
1690
|
+
/** `GET {prefix}/conversations/{conversation_id}/messages` — oldest message first. */
|
|
1691
|
+
type ListMessagesResponse = InferResponse<Auth["listMessages"]>;
|
|
1692
|
+
/** `POST {prefix}/conversations/{conversation_id}/send` */
|
|
1693
|
+
type SendMessageInput = InferInput<Auth["sendMessage"]>;
|
|
1694
|
+
/** `POST {prefix}/conversations/{conversation_id}/send` — path parameters. */
|
|
1695
|
+
type SendMessageParams = Pick<SendMessageInput, Thread>;
|
|
1696
|
+
/** `POST {prefix}/conversations/{conversation_id}/send` — the JSON body. */
|
|
1697
|
+
type SendMessageBody = Omit<SendMessageInput, Thread>;
|
|
1698
|
+
/** `POST {prefix}/conversations/{conversation_id}/send` — this is `ChatReply`. */
|
|
1699
|
+
type SendMessageResponse = InferResponse<Auth["sendMessage"]>;
|
|
1700
|
+
/** `DELETE {prefix}/conversations/{conversation_id}` */
|
|
1701
|
+
type DeleteConversationInput = InferInput<Auth["deleteConversation"]>;
|
|
1702
|
+
/** `DELETE {prefix}/conversations/{conversation_id}` — path parameters. */
|
|
1703
|
+
type DeleteConversationParams = Pick<DeleteConversationInput, Thread>;
|
|
1704
|
+
/** `DELETE {prefix}/conversations/{conversation_id}` — returns `null`. */
|
|
1705
|
+
type DeleteConversationResponse = InferResponse<Auth["deleteConversation"]>;
|
|
1706
|
+
/** `POST {prefix}/conversations/{conversation_id}/claim` — only with `{ guest: true }`. */
|
|
1707
|
+
type ClaimConversationInput = InferInput<NonNullable<Auth["claimConversation"]>>;
|
|
1708
|
+
/** `POST {prefix}/conversations/{conversation_id}/claim` — path parameters. */
|
|
1709
|
+
type ClaimConversationParams = Pick<ClaimConversationInput, Thread>;
|
|
1710
|
+
/** `POST {prefix}/conversations/{conversation_id}/claim` — the JSON body (carries the guest token). */
|
|
1711
|
+
type ClaimConversationBody = Omit<ClaimConversationInput, Thread>;
|
|
1712
|
+
/** `POST {prefix}/conversations/{conversation_id}/claim` */
|
|
1713
|
+
type ClaimConversationResponse = InferResponse<NonNullable<Auth["claimConversation"]>>;
|
|
1714
|
+
/** `POST {prefix}/guest/conversations/create` */
|
|
1715
|
+
type GuestCreateConversationInput = InferInput<Guest["createConversation"]>;
|
|
1716
|
+
/** `POST {prefix}/guest/conversations/create` — the JSON body (`{}` is valid). */
|
|
1717
|
+
type GuestCreateConversationBody = GuestCreateConversationInput;
|
|
1718
|
+
/**
|
|
1719
|
+
* `POST {prefix}/guest/conversations/create`
|
|
1720
|
+
*
|
|
1721
|
+
* ⚠ The only response that ever carries `session_token`. Store it as a
|
|
1722
|
+
* credential; anyone holding it owns the thread until it is claimed.
|
|
1723
|
+
*/
|
|
1724
|
+
type GuestCreateConversationResponse = InferResponse<Guest["createConversation"]>;
|
|
1725
|
+
/** `GET {prefix}/guest/conversations/{conversation_id}/messages` */
|
|
1726
|
+
type GuestListMessagesInput = InferInput<Guest["listMessages"]>;
|
|
1727
|
+
/** `GET {prefix}/guest/conversations/{conversation_id}/messages` — path parameters. */
|
|
1728
|
+
type GuestListMessagesParams = Pick<GuestListMessagesInput, Thread>;
|
|
1729
|
+
/**
|
|
1730
|
+
* `GET {prefix}/guest/conversations/{conversation_id}/messages` — query string.
|
|
1731
|
+
*
|
|
1732
|
+
* ⚠ A `GET` has no body, so the token rides in the URL here and will reach
|
|
1733
|
+
* access logs, proxies and `Referer` headers. That is why the *delete* endpoint
|
|
1734
|
+
* is a `POST` instead — see {@link GuestDeleteConversationBody}.
|
|
1735
|
+
*/
|
|
1736
|
+
type GuestListMessagesQuery = Omit<GuestListMessagesInput, Thread>;
|
|
1737
|
+
/** `GET {prefix}/guest/conversations/{conversation_id}/messages` */
|
|
1738
|
+
type GuestListMessagesResponse = InferResponse<Guest["listMessages"]>;
|
|
1739
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/send` */
|
|
1740
|
+
type GuestSendMessageInput = InferInput<Guest["sendMessage"]>;
|
|
1741
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/send` — path parameters. */
|
|
1742
|
+
type GuestSendMessageParams = Pick<GuestSendMessageInput, Thread>;
|
|
1743
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/send` — the JSON body, token included. */
|
|
1744
|
+
type GuestSendMessageBody = Omit<GuestSendMessageInput, Thread>;
|
|
1745
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/send` */
|
|
1746
|
+
type GuestSendMessageResponse = InferResponse<Guest["sendMessage"]>;
|
|
1747
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/delete` */
|
|
1748
|
+
type GuestDeleteConversationInput = InferInput<Guest["deleteConversation"]>;
|
|
1749
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/delete` — path parameters. */
|
|
1750
|
+
type GuestDeleteConversationParams = Pick<GuestDeleteConversationInput, Thread>;
|
|
1751
|
+
/**
|
|
1752
|
+
* `POST {prefix}/guest/conversations/{conversation_id}/delete` — the JSON body.
|
|
1753
|
+
*
|
|
1754
|
+
* A `POST` rather than a `DELETE` on purpose: a `DELETE` would have to carry the
|
|
1755
|
+
* token in the query string, and a URL travels into access logs, proxies and
|
|
1756
|
+
* `Referer` headers. The body keeps the credential out of it.
|
|
1757
|
+
*/
|
|
1758
|
+
type GuestDeleteConversationBody = Omit<GuestDeleteConversationInput, Thread>;
|
|
1759
|
+
/** `POST {prefix}/guest/conversations/{conversation_id}/delete` — returns `null`. */
|
|
1760
|
+
type GuestDeleteConversationResponse = InferResponse<Guest["deleteConversation"]>;
|
|
1761
|
+
/** One endpoint's complete wire contract. `never` marks a part it does not take. */
|
|
1762
|
+
interface ChatbotEndpoint<Verb extends string, Route extends string, Auth, Params, Query, Body, Response> {
|
|
1763
|
+
/** HTTP method. */
|
|
1764
|
+
verb: Verb;
|
|
1765
|
+
/** Route template, **relative to `routePrefix`** (default `"chat"`). */
|
|
1766
|
+
route: Route;
|
|
1767
|
+
/** `"token"` = `Authorization: Bearer` for `authTable`; `"session_token"` = the guest capability; `"none"` = public. */
|
|
1768
|
+
auth: Auth;
|
|
1769
|
+
/** Path parameters, interpolated into the URL. */
|
|
1770
|
+
params: Params;
|
|
1771
|
+
/** Query-string parameters. */
|
|
1772
|
+
query: Query;
|
|
1773
|
+
/** The JSON request body. */
|
|
1774
|
+
body: Body;
|
|
1775
|
+
/** The parsed JSON response. */
|
|
1776
|
+
response: Response;
|
|
1777
|
+
}
|
|
1778
|
+
/**
|
|
1779
|
+
* Every endpoint, keyed by the **same name as the def handle** — so
|
|
1780
|
+
* `bot.authenticated.sendMessage` and `ChatbotEndpoints["sendMessage"]` describe
|
|
1781
|
+
* one thing, and a client can be written or generated from this map alone.
|
|
1782
|
+
*
|
|
1783
|
+
* ```ts
|
|
1784
|
+
* type Send = ChatbotEndpoints["sendMessage"];
|
|
1785
|
+
* // Send["verb"] → "POST"
|
|
1786
|
+
* // Send["params"] → { conversation_id: number }
|
|
1787
|
+
* // Send["body"] → { content: string }
|
|
1788
|
+
* // Send["response"] → ChatReply
|
|
1789
|
+
* ```
|
|
1790
|
+
*
|
|
1791
|
+
* Routes are relative to `routePrefix`, and the public URL is
|
|
1792
|
+
* `/api:<canonical>/<routePrefix>/<route>`. Get the resolved path from
|
|
1793
|
+
* `xanosdk routes <entry> --emit xano/routes.gen.ts` rather than concatenating it
|
|
1794
|
+
* by hand.
|
|
1795
|
+
*/
|
|
1796
|
+
interface ChatbotEndpoints {
|
|
1797
|
+
createConversation: ChatbotEndpoint<"POST", "conversations/create", "token", never, never, CreateConversationBody, CreateConversationResponse>;
|
|
1798
|
+
listConversations: ChatbotEndpoint<"GET", "conversations", "token", never, never, never, ListConversationsResponse>;
|
|
1799
|
+
listMessages: ChatbotEndpoint<"GET", "conversations/{conversation_id}/messages", "token", ListMessagesParams, never, never, ListMessagesResponse>;
|
|
1800
|
+
sendMessage: ChatbotEndpoint<"POST", "conversations/{conversation_id}/send", "token", SendMessageParams, never, SendMessageBody, SendMessageResponse>;
|
|
1801
|
+
deleteConversation: ChatbotEndpoint<"DELETE", "conversations/{conversation_id}", "token", DeleteConversationParams, never, never, DeleteConversationResponse>;
|
|
1802
|
+
claimConversation: ChatbotEndpoint<"POST", "conversations/{conversation_id}/claim", "token", ClaimConversationParams, never, ClaimConversationBody, ClaimConversationResponse>;
|
|
1803
|
+
guestCreateConversation: ChatbotEndpoint<"POST", "guest/conversations/create", "none", never, never, GuestCreateConversationBody, GuestCreateConversationResponse>;
|
|
1804
|
+
guestListMessages: ChatbotEndpoint<"GET", "guest/conversations/{conversation_id}/messages", "session_token", GuestListMessagesParams, GuestListMessagesQuery, never, GuestListMessagesResponse>;
|
|
1805
|
+
guestSendMessage: ChatbotEndpoint<"POST", "guest/conversations/{conversation_id}/send", "session_token", GuestSendMessageParams, never, GuestSendMessageBody, GuestSendMessageResponse>;
|
|
1806
|
+
guestDeleteConversation: ChatbotEndpoint<"POST", "guest/conversations/{conversation_id}/delete", "session_token", GuestDeleteConversationParams, never, GuestDeleteConversationBody, GuestDeleteConversationResponse>;
|
|
1807
|
+
}
|
|
1808
|
+
/** Every endpoint name in {@link ChatbotEndpoints}. */
|
|
1809
|
+
type ChatbotEndpointName = keyof ChatbotEndpoints;
|
|
1810
|
+
|
|
1811
|
+
export { type ChatAgent, type ChatReply, type Chatbot, type ChatbotAuthTable, type ChatbotEndpoint, type ChatbotEndpointName, type ChatbotEndpoints, type ChatbotGroup, type ChatbotLlmOptions, type ChatbotNames, type ChatbotOptions, type ClaimConversationBody, type ClaimConversationInput, type ClaimConversationParams, type ClaimConversationResponse, type Conversation, type ConversationTable, type CreateConversationBody, type CreateConversationInput, type CreateConversationResponse, DEFAULT_HISTORY_LIMIT, DEFAULT_LIST_LIMIT, DEFAULT_NAMES, DEFAULT_SYSTEM_PROMPT, DEFAULT_TRANSCRIPT_LIMIT, type DeleteConversationInput, type DeleteConversationParams, type DeleteConversationResponse, type GenerateReplyFn, type GuestCreateConversationBody, type GuestCreateConversationInput, type GuestCreateConversationResponse, type GuestDeleteConversationBody, type GuestDeleteConversationInput, type GuestDeleteConversationParams, type GuestDeleteConversationResponse, type GuestListMessagesInput, type GuestListMessagesParams, type GuestListMessagesQuery, type GuestListMessagesResponse, type GuestSendMessageBody, type GuestSendMessageInput, type GuestSendMessageParams, type GuestSendMessageResponse, type ListConversationsResponse, type ListMessagesInput, type ListMessagesParams, type ListMessagesResponse, MESSAGES_TEMPLATE, MESSAGE_ROLES, type Message, type MessageRole, type MessageTable, PUBLIC_CONVERSATION_FIELDS, PUBLIC_MESSAGE_FIELDS, type PublicConversation, type PublicMessage, type RegisteredChatbot, type ResolvedOptions, type SendMessageBody, type SendMessageInput, type SendMessageParams, type SendMessageResponse, TITLE_LENGTH, TOOLS_SYSTEM_PROMPT, authenticatedQueries, chatAgent, chatbotGroup, conversationTable, createChatbot, generateReplyFn, guestQueries, messageTable, registerChatbot, resolveOptions };
|