@foir/sdk 0.28.0 → 0.30.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/CHANGELOG.md +145 -0
- package/dist/ai/index.d.ts +190 -0
- package/dist/ai.js +566 -0
- package/dist/auth/auth.d.ts +29 -6
- package/dist/auth/code-flow.d.ts +97 -0
- package/dist/auth/grant-table.generated.d.ts +1 -1
- package/dist/auth/grants.d.ts +2 -1
- package/dist/auth/hosted.d.ts +14 -6
- package/dist/auth/index.d.ts +3 -1
- package/dist/auth/operations.d.ts +5 -0
- package/dist/auth/session-client.d.ts +1 -1
- package/dist/auth.js +189 -8
- package/dist/client/platform-client.d.ts +1 -1
- package/dist/data/agents.d.ts +104 -0
- package/dist/data/builtins.d.ts +182 -0
- package/dist/data/index.d.ts +5 -3
- package/dist/data/subjects.d.ts +45 -0
- package/dist/data/subscriptions.d.ts +38 -0
- package/dist/data/transport.d.ts +1 -0
- package/dist/data/ws-transport.d.ts +9 -0
- package/dist/data.js +213 -5
- package/dist/media/ProgressiveMedia.d.ts +27 -1
- package/dist/media.js +39 -10
- package/dist/next/session.d.ts +6 -2
- package/dist/next.js +4 -9
- package/dist/placement.js +8 -2
- package/dist/react/FoirFeedback.d.ts +18 -1
- package/dist/react/FoirProvider.d.ts +6 -2
- package/dist/react/SignIn.d.ts +2 -2
- package/dist/react/feedback-notes.d.ts +7 -0
- package/dist/react.js +267 -17
- package/dist/realtime/index.d.ts +6 -0
- package/dist/realtime.js +2 -1
- package/dist/server/webhook-helpers.d.ts +3 -1
- package/dist/server.js +84 -8
- package/package.json +11 -2
package/CHANGELOG.md
CHANGED
|
@@ -108,6 +108,131 @@ nobody asking for `@foir/sdk` gets it early. The push that carries the commit to
|
|
|
108
108
|
|
|
109
109
|
Changes on `dev` that have not been published to npm.
|
|
110
110
|
|
|
111
|
+
### Added
|
|
112
|
+
|
|
113
|
+
- **Tags in a message** (`@foir/sdk/ai`, `@foir/sdk/data`): a message can
|
|
114
|
+
point at a record, a field, a model, a person, a file, an operation, an
|
|
115
|
+
agent, a hook, a schedule, an organisation or a note, by id. The `useChat`
|
|
116
|
+
transport sends each `data-tag` part of the message as a tag, and
|
|
117
|
+
`startAgentRun` (and so `askAgent`) takes `tags`, typed `FoirMessageTag`.
|
|
118
|
+
The agent reads what a tag points at with its own tools, as the caller.
|
|
119
|
+
- **Images and PDFs in a message** (`@foir/sdk/ai`, `@foir/sdk/data`): the
|
|
120
|
+
`useChat` transport sends the files of `sendMessage({ text, files })`, and
|
|
121
|
+
`askAgent` takes `files`. Each is uploaded first with the new
|
|
122
|
+
`uploadAgentFile` (or the `createAgentAttachment` mutation) and sent by its
|
|
123
|
+
id in `startAgentRun`'s `attachmentIds`. `foirChatMessages` reads a sent
|
|
124
|
+
file back as a `file` part with a link that lasts an hour. An image (PNG,
|
|
125
|
+
JPEG, GIF or WebP) may be up to 5 MB and a PDF up to 10 MB, at most five a
|
|
126
|
+
message; a visitor may send images only, 20 a day.
|
|
127
|
+
- **Field marks** (`@foir/sdk/data`): `subjects.field(record, 'title', { label })`
|
|
128
|
+
returns `{ 'data-foir-field': token }` to spread onto the element that shows
|
|
129
|
+
that field, and `subjects.pointedAt(token)` reads it back as a
|
|
130
|
+
`FoirFieldMark`. The token is opaque, so the page prints none of the model,
|
|
131
|
+
record or field, and the same field gets the same token on the server and in
|
|
132
|
+
the browser.
|
|
133
|
+
- **`<FoirFeedback pointing>`** (`@foir/sdk/react`): the reader points at the
|
|
134
|
+
part of the page they mean, by clicking a marked field or by Tab and Enter,
|
|
135
|
+
and the note is filed against that record and names the field
|
|
136
|
+
(`anchorField`). A page showing two records files each comment against the
|
|
137
|
+
right one. A visitor may name a field they can read; the data API refuses
|
|
138
|
+
any other. Offered only while the page shows a marked field. `writeNote`
|
|
139
|
+
takes the anchor from this release of the data API; a client generated
|
|
140
|
+
before it needs `foir types` re-run before it can send one.
|
|
141
|
+
- **`<FoirFeedback launcher="bottom-right" | "bottom-left">`**: the button is
|
|
142
|
+
fixed in that corner of the viewport, and the inline panel opens above it.
|
|
143
|
+
- **`@foir/sdk/ai`**: `foirChatTransport({ client, agent })` puts a project's
|
|
144
|
+
agent behind the AI SDK's `useChat`, with no backend of the app's own. Text
|
|
145
|
+
and reasoning stream into their parts, each step the agent takes is a
|
|
146
|
+
`dynamic-tool` part, and an act held for the person is the AI SDK's
|
|
147
|
+
approval step, decided with `addToolApprovalResponse`. The chat keeps its
|
|
148
|
+
thread in the browser's storage; `foirChatMessages` reads a thread back as
|
|
149
|
+
`useChat`'s messages. `ai` (7.x) is an optional peer, which
|
|
150
|
+
`@foir/sdk/ai` needs. Data an agent sends the app arrives as `data-<name>`
|
|
151
|
+
parts.
|
|
152
|
+
- **Tools of the page** (`@foir/sdk/ai`): `foirChatTransport({ pageTools })`
|
|
153
|
+
defines the page's own tools, each with a `description`, an `inputSchema`
|
|
154
|
+
(a Zod schema, a Standard Schema or `jsonSchema()`) and an `execute`, as an
|
|
155
|
+
AI SDK `tool()` has. They are sent with every message to an agent that
|
|
156
|
+
allows the page's tools. When the agent calls one, the transport runs
|
|
157
|
+
`execute` and the run carries on in the same answer with what it returned;
|
|
158
|
+
what it throws is answered as `{ error }`. A tool with no `execute` is a
|
|
159
|
+
tool part the app answers with `addToolOutput`. `startAgentRun` takes
|
|
160
|
+
`pageTools`, typed `FoirPageToolOffer`.
|
|
161
|
+
- **Typed answers** (`@foir/sdk/data`): `askAgent` resolves with `output`, the
|
|
162
|
+
value a run of an agent with an output schema answers with. `FoirAgentRun`
|
|
163
|
+
carries `output`, and a run's events carry `DATA` (a data part sent to the
|
|
164
|
+
app) and the final `STATUS` event's `output`. A run's nodes can be
|
|
165
|
+
`PAGE_TOOL` (a tool the page offered, held until `answerPageTool`) and
|
|
166
|
+
`DATA`.
|
|
167
|
+
|
|
168
|
+
### Fixed
|
|
169
|
+
|
|
170
|
+
- **`CodeFlowConfig.issuer` names Foir's issuer as `https://api.foir.dev`** in
|
|
171
|
+
its description, where it said `https://api.foir.io`. The comments of
|
|
172
|
+
`@foir/sdk/auth` and `<SignIn>` call the hosted page hosted sign-in.
|
|
173
|
+
- **`foirChatTransport` and `foirChatMessages` take any client
|
|
174
|
+
`createFoirClient` returns**, typed by the project's schema or not, as
|
|
175
|
+
`askAgent` does. The documented example passed such a client and did not
|
|
176
|
+
typecheck. A client whose key runs no agent is refused when the first
|
|
177
|
+
message is sent, saying so.
|
|
178
|
+
- **A `useChat` answer that is cancelled stops following its run.** The
|
|
179
|
+
transport kept the run's subscription open and wrote each later event to a
|
|
180
|
+
stream nobody read, which threw. A page loaded again still picks the answer
|
|
181
|
+
up from the stored run with `resume`.
|
|
182
|
+
|
|
183
|
+
## [0.29.0] — 2026-10-21
|
|
184
|
+
|
|
185
|
+
### Added
|
|
186
|
+
|
|
187
|
+
- **Agents** (`@foir/sdk/data`): a project's agents through the data API.
|
|
188
|
+
`foir.ns.agents.startAgentRun`, `cancelAgentRun`, `agentRun`, `agentThreads`
|
|
189
|
+
and the approvals verbs are offered where the key runs some agent, and
|
|
190
|
+
`foir.ns.agents.onRun({ id })` follows a run as it is written, from its start
|
|
191
|
+
so nothing is missed. `askAgent(foir, { agent, message, threadId, onText })`
|
|
192
|
+
starts a run and resolves with the answer, the thread to go on with and how
|
|
193
|
+
the run ended; `visitorToken()` is a visitor's own secret, kept in the
|
|
194
|
+
browser, which makes a conversation theirs. Types: `FoirAgentRun`,
|
|
195
|
+
`FoirAgentRunEvent`, `FoirAgentRunNode`, `FoirAgentRunStatus`,
|
|
196
|
+
`FoirAgentThread`, `FoirAgentThreadMessage`, `FoirAgentApproval`,
|
|
197
|
+
`FoirMcpConnection`, `FoirStartAgentRunArgs`, `FoirAgentsClient`,
|
|
198
|
+
`AskAgentOptions`, `AgentReply`.
|
|
199
|
+
- **`AuthorizedApp` says whose app it is**: `clientLogoUrl`, `clientLogoAlt`
|
|
200
|
+
and `clientHomepageUrl`, where the app set them.
|
|
201
|
+
- **`beginSignIn` and `completeSignIn`** (`@foir/sdk/auth`): the OpenID Connect
|
|
202
|
+
code flow for a server app with no OpenID Connect library. `beginSignIn`
|
|
203
|
+
finds the issuer's endpoints from its discovery document and returns the
|
|
204
|
+
authorization URL, with a PKCE S256 challenge, a state and a nonce, and what
|
|
205
|
+
to keep until the person comes back. `completeSignIn` checks the callback
|
|
206
|
+
against it, redeems the code at the token endpoint and returns the tokens,
|
|
207
|
+
with the ID token's issuer, audience, nonce and expiry checked. A refusal is
|
|
208
|
+
a `CodeFlowError` naming the OAuth error. It uses `fetch` and Web Crypto
|
|
209
|
+
only, so it runs in Workers, Oxygen and Node 18 or later.
|
|
210
|
+
- **A link for somebody new** (`@foir/sdk/auth`): `hostedLoginUrl`,
|
|
211
|
+
`signInUrl` and `useFoir().hostedSignInUrl` take `{ signUp: true }`, which
|
|
212
|
+
opens the hosted sign-in at the login domain's `/signup`, on the project's
|
|
213
|
+
way in rather than the sign-in form: joining where sign-up is public, the
|
|
214
|
+
waitlist in waitlist mode, or the invitation-only or closed notice. For a
|
|
215
|
+
"Sign up" or "Join the waitlist" button. In the code flow,
|
|
216
|
+
`beginSignIn(config, { prompt: 'create' })` asks for the same.
|
|
217
|
+
- **`<ProgressiveMedia>` video props** (`@foir/sdk/media`):
|
|
218
|
+
- `objectPosition` keeps a focal point in view when the image, the video or
|
|
219
|
+
its thumbnail is cropped to fit;
|
|
220
|
+
- `controls` shows the browser's controls, which default to `!autoplay` as
|
|
221
|
+
before. A video with controls shows from the start, its poster standing
|
|
222
|
+
until it plays;
|
|
223
|
+
- `preload` sets how much the browser fetches before a video plays;
|
|
224
|
+
- `videoRef` hands over the `<video>` element, for your own play and pause
|
|
225
|
+
controls;
|
|
226
|
+
- `onVideoError` is called when a video's source cannot play.
|
|
227
|
+
|
|
228
|
+
### Fixed
|
|
229
|
+
|
|
230
|
+
- **A video that cannot play leaves its thumbnail**, labelled with `alt`, where
|
|
231
|
+
it left a blank box.
|
|
232
|
+
- **A video's `alt` labels the `<video>`**; it was dropped.
|
|
233
|
+
- **A video of unknown size takes its own shape** once its metadata loads,
|
|
234
|
+
where it was cropped to 16:10.
|
|
235
|
+
|
|
111
236
|
## [0.28.0] — 2026-10-20
|
|
112
237
|
|
|
113
238
|
### Added
|
|
@@ -152,6 +277,17 @@ Changes on `dev` that have not been published to npm.
|
|
|
152
277
|
|
|
153
278
|
### Added
|
|
154
279
|
|
|
280
|
+
- **`createCollabSession({ orgId })`** (`@foir/sdk/realtime`): the
|
|
281
|
+
organization the signed-in user stands at in the room, sent as the
|
|
282
|
+
connection's `org`. The user joins there only as a member of it; omitted,
|
|
283
|
+
the join stands at the project.
|
|
284
|
+
- **The subscription socket honours close codes 4402 and 4403.** On 4402,
|
|
285
|
+
the socket's credential is no longer honoured: the bearer is renewed through
|
|
286
|
+
`refreshBearer` and the socket reconnects at once, failing its subscriptions
|
|
287
|
+
with `FoirSessionExpiredError` when the session is over. On 4403, the
|
|
288
|
+
signed-in user is no member of the organization the client names: the
|
|
289
|
+
subscriptions fail rather than reconnecting into the same refusal.
|
|
290
|
+
|
|
155
291
|
- **`organizations.startPool({ movePeople, dryRun })`** (`@foir/sdk/app`):
|
|
156
292
|
starting the run's organization's own pool takes its people along when
|
|
157
293
|
asked. Somebody who stands only there moves whole, and somebody who also
|
|
@@ -195,6 +331,15 @@ Changes on `dev` that have not been published to npm.
|
|
|
195
331
|
|
|
196
332
|
### Changed
|
|
197
333
|
|
|
334
|
+
- **Breaking: signing up with a password proves the address first.**
|
|
335
|
+
`register()` answers `true` and `signUpWithPassword(env, vars)` answers
|
|
336
|
+
nothing, and neither signs anybody in: the address is mailed a code, and
|
|
337
|
+
`signInWithOTP` / `loginWithOTP` with it finishes the account and starts the
|
|
338
|
+
session, also where the project takes no code to sign in. The answer is the
|
|
339
|
+
same whether or not the address has an account already, or the project takes
|
|
340
|
+
nobody new; whoever holds the address is told by email. `signUpWithPassword`
|
|
341
|
+
no longer takes a session adapter, `useFoirAuth().register()` answers
|
|
342
|
+
nothing, and `foirRegisterWithPassword` takes no cookie store.
|
|
198
343
|
- **`<FoirFeedback>` writes a signed-in user's note through `writeNote`**, the
|
|
199
344
|
one note create, rather than `createMyNote`, its older name. The same note
|
|
200
345
|
on the same data API. A client whose generated module predates `writeNote`
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A Fóir agent behind the AI SDK's `useChat`.
|
|
3
|
+
*
|
|
4
|
+
* ```tsx
|
|
5
|
+
* import { useChat } from '@ai-sdk/react';
|
|
6
|
+
* import { lastAssistantMessageIsCompleteWithApprovalResponses } from 'ai';
|
|
7
|
+
* import { createFoirClient } from '@foir/sdk/data';
|
|
8
|
+
* import { foirChatTransport } from '@foir/sdk/ai';
|
|
9
|
+
*
|
|
10
|
+
* const foir = createFoirClient({ apiUrl, apiKey });
|
|
11
|
+
* const transport = foirChatTransport({ client: foir, agent: 'support' });
|
|
12
|
+
*
|
|
13
|
+
* const { messages, sendMessage, addToolApprovalResponse } = useChat({
|
|
14
|
+
* transport,
|
|
15
|
+
* sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses,
|
|
16
|
+
* });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* Each message starts a run of the agent on Fóir. Nothing runs in the app's
|
|
20
|
+
* own backend, and the app holds no model key. The run's events arrive as the
|
|
21
|
+
* message parts `useChat` renders: text and reasoning as they are written, and
|
|
22
|
+
* each step the agent takes as a tool part. An act the agent holds for the
|
|
23
|
+
* person's decision is the AI SDK's approval step: `addToolApprovalResponse`
|
|
24
|
+
* decides it, and the run carries on. An act held for the project's team shows
|
|
25
|
+
* as waiting, since the person cannot decide it.
|
|
26
|
+
*
|
|
27
|
+
* Data the agent sends the app's own components arrives as `data-<name>`
|
|
28
|
+
* parts. The page's own tools are defined once, in `pageTools`, and sent with
|
|
29
|
+
* each message to an agent that allows them:
|
|
30
|
+
*
|
|
31
|
+
* ```ts
|
|
32
|
+
* const transport = foirChatTransport({
|
|
33
|
+
* client: foir,
|
|
34
|
+
* agent: 'shop',
|
|
35
|
+
* pageTools: {
|
|
36
|
+
* show_product: {
|
|
37
|
+
* description: 'Open a product on the page.',
|
|
38
|
+
* inputSchema: z.object({ id: z.string() }),
|
|
39
|
+
* execute: ({ id }) => {
|
|
40
|
+
* router.push(`/products/${id}`);
|
|
41
|
+
* return { shown: id };
|
|
42
|
+
* },
|
|
43
|
+
* },
|
|
44
|
+
* },
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*
|
|
48
|
+
* The transport runs a tool's `execute` when the agent calls it, and the run
|
|
49
|
+
* carries on with what it returned. A tool with no `execute` is a tool part
|
|
50
|
+
* waiting for its output: answer it in `onToolCall` with `addToolOutput`.
|
|
51
|
+
*
|
|
52
|
+
* Fóir keeps the conversation. A chat goes on in its thread for as long as
|
|
53
|
+
* `threads` keeps the thread's id (the browser's storage by default), and a
|
|
54
|
+
* visitor's thread is theirs by the secret their browser keeps.
|
|
55
|
+
* `foirChatMessages` reads a thread back as `useChat`'s messages.
|
|
56
|
+
*/
|
|
57
|
+
import type { ChatTransport, FlexibleSchema, UIMessage, UIMessageChunk } from 'ai';
|
|
58
|
+
import type { FoirAgentAttachmentUpload, FoirAgentRun, FoirAgentRunNode, FoirAgentThread, FoirCreateAgentAttachmentArgs, FoirStartAgentRunArgs } from '../data/builtins';
|
|
59
|
+
import type { FoirAgentRunEvent, FoirAgentRunSubscribeOptions } from '../data/subscriptions';
|
|
60
|
+
import type { FoirSubscription } from '../data/ws-transport';
|
|
61
|
+
/** What the transport needs of a client: the agents namespace a key that runs an agent is given. */
|
|
62
|
+
export interface FoirChatClient {
|
|
63
|
+
ns: {
|
|
64
|
+
agents: {
|
|
65
|
+
startAgentRun(args: FoirStartAgentRunArgs): Promise<FoirAgentRun>;
|
|
66
|
+
onRun(options: FoirAgentRunSubscribeOptions): FoirSubscription;
|
|
67
|
+
decideAgentApproval(args: {
|
|
68
|
+
id: string;
|
|
69
|
+
approve: boolean;
|
|
70
|
+
reason?: string;
|
|
71
|
+
}): Promise<FoirAgentRunNode | null>;
|
|
72
|
+
answerPageTool(args: {
|
|
73
|
+
id: string;
|
|
74
|
+
output: unknown;
|
|
75
|
+
visitorToken?: string;
|
|
76
|
+
}): Promise<FoirAgentRunNode | null>;
|
|
77
|
+
agentThread(args: {
|
|
78
|
+
id: string;
|
|
79
|
+
visitorToken?: string;
|
|
80
|
+
}): Promise<FoirAgentThread | null>;
|
|
81
|
+
createAgentAttachment(args: FoirCreateAgentAttachmentArgs): Promise<FoirAgentAttachmentUpload>;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A tool of the app's own page, which the agent may call while it answers. An
|
|
87
|
+
* AI SDK `tool({ ... })` is one.
|
|
88
|
+
*/
|
|
89
|
+
export interface FoirPageTool<INPUT = any> {
|
|
90
|
+
/** What the tool does, as the model is told it. At most 1000 characters. */
|
|
91
|
+
description?: string;
|
|
92
|
+
/**
|
|
93
|
+
* The tool's input: a Zod schema, a Standard Schema, or a JSON Schema
|
|
94
|
+
* through the AI SDK's `jsonSchema()`. It must describe an object. Left
|
|
95
|
+
* out, the tool takes no input.
|
|
96
|
+
*/
|
|
97
|
+
inputSchema?: FlexibleSchema<INPUT>;
|
|
98
|
+
/**
|
|
99
|
+
* Does what the tool does on the page, and answers what it did: JSON, as
|
|
100
|
+
* the model is told it, at most 64 KB. What it throws is answered as
|
|
101
|
+
* `{ error }`. Left out, the call waits for `addToolOutput`.
|
|
102
|
+
*/
|
|
103
|
+
execute?(input: INPUT, options: {
|
|
104
|
+
toolCallId: string;
|
|
105
|
+
messages: unknown[];
|
|
106
|
+
abortSignal?: AbortSignal;
|
|
107
|
+
}): unknown;
|
|
108
|
+
}
|
|
109
|
+
/** Where a chat's thread id is kept between page loads. */
|
|
110
|
+
export type FoirThreadStore = Pick<Storage, 'getItem' | 'setItem'>;
|
|
111
|
+
export interface FoirChatTransportOptions {
|
|
112
|
+
/**
|
|
113
|
+
* A Fóir client whose key runs the agent: `createFoirClient`'s, typed by
|
|
114
|
+
* the project's schema or not. A client that offers no agents is refused
|
|
115
|
+
* when the first message is sent, saying so.
|
|
116
|
+
*/
|
|
117
|
+
client: FoirChatClient | {
|
|
118
|
+
readonly ns: object;
|
|
119
|
+
};
|
|
120
|
+
/** The agent's key. */
|
|
121
|
+
agent: string;
|
|
122
|
+
/**
|
|
123
|
+
* A visitor with nobody signed in: the secret their browser keeps. Defaults
|
|
124
|
+
* to the one `visitorToken()` keeps; pass `null` for a signed-in person.
|
|
125
|
+
*/
|
|
126
|
+
visitorToken?: string | null;
|
|
127
|
+
/** Where each chat's thread id is kept. The browser's storage by default; `null` keeps it for the page. */
|
|
128
|
+
threads?: FoirThreadStore | null;
|
|
129
|
+
/**
|
|
130
|
+
* The page's own tools, by name: lowercase letters, digits and _. Each is
|
|
131
|
+
* sent with every message, and the agent must allow the page's tools. At
|
|
132
|
+
* most 20.
|
|
133
|
+
*/
|
|
134
|
+
pageTools?: Record<string, FoirPageTool>;
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* One run's events as `useChat`'s chunks. A run outlives a stream: it stops
|
|
138
|
+
* for a decision and carries on once it is made, so what the person has
|
|
139
|
+
* already been shown (the steps, the last event) is kept per run, and each
|
|
140
|
+
* stream only opens and closes its own text.
|
|
141
|
+
*/
|
|
142
|
+
export declare class FoirRunChunks {
|
|
143
|
+
private readonly runId;
|
|
144
|
+
private readonly runs;
|
|
145
|
+
private readonly tools;
|
|
146
|
+
/** The last event shown, to follow the run again from. */
|
|
147
|
+
after: string;
|
|
148
|
+
private textId;
|
|
149
|
+
private reasoningId;
|
|
150
|
+
private opened;
|
|
151
|
+
/** The run stopped for this stream's followers: it ended, or holds an act. */
|
|
152
|
+
stopped: boolean;
|
|
153
|
+
/** Calls to the page's tools waiting for the app's `addToolOutput`. */
|
|
154
|
+
readonly pageCalls: Set<string>;
|
|
155
|
+
/** Calls to the page's tools the transport runs and answers itself, until the run hears them. */
|
|
156
|
+
readonly answering: Set<string>;
|
|
157
|
+
/** Calls the transport is to run: taken with `takeCalls`. */
|
|
158
|
+
private toRun;
|
|
159
|
+
/** Acts held for a decision, by anyone. */
|
|
160
|
+
private readonly held;
|
|
161
|
+
/** `runs` names the page's tools the transport runs itself. */
|
|
162
|
+
constructor(runId: string, runs?: (tool: string) => boolean);
|
|
163
|
+
/** The calls to the page's tools that arrived for the transport to run. */
|
|
164
|
+
takeCalls(): FoirAgentRunNode[];
|
|
165
|
+
/** Starts a new stream of the same run, as after a decision. */
|
|
166
|
+
resume(): void;
|
|
167
|
+
private open;
|
|
168
|
+
private closeText;
|
|
169
|
+
private closeReasoning;
|
|
170
|
+
/** The chunks an event makes. `fresh` is a stream that starts a new message. */
|
|
171
|
+
of(event: FoirAgentRunEvent, fresh?: boolean): UIMessageChunk[];
|
|
172
|
+
private toolChunks;
|
|
173
|
+
/**
|
|
174
|
+
* A call to one of the page's tools. The transport runs one it has an
|
|
175
|
+
* `execute` for and shows what it answered; any other waits for the app's
|
|
176
|
+
* `addToolOutput`. One the page did not answer in time is an error.
|
|
177
|
+
*/
|
|
178
|
+
private pageToolChunks;
|
|
179
|
+
}
|
|
180
|
+
/** The transport `useChat` sends through: each message is a run of a Fóir agent. */
|
|
181
|
+
export declare function foirChatTransport(options: FoirChatTransportOptions): ChatTransport<UIMessage>;
|
|
182
|
+
/**
|
|
183
|
+
* A thread read back as `useChat`'s messages, to open a chat where it was left.
|
|
184
|
+
* Fóir keeps each message's parts as the run wrote them.
|
|
185
|
+
*/
|
|
186
|
+
export declare function foirChatMessages(client: FoirChatClient | {
|
|
187
|
+
readonly ns: object;
|
|
188
|
+
}, threadId: string, options?: {
|
|
189
|
+
visitorToken?: string | null;
|
|
190
|
+
}): Promise<UIMessage[]>;
|