diff --git a/.changeset/activity-middleware-persistence.md b/.changeset/activity-middleware-persistence.md deleted file mode 100644 index e71dedcb47..0000000000 --- a/.changeset/activity-middleware-persistence.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai': patch ---- - -Apply `ACTIVITY_SNAPSHOT` and `ACTIVITY_DELTA` events that chat middleware adds to `ctx.activities`, so `withPersistence` saves them and `reconstructChat` restores their activity rows. A middleware that passes on an adapter activity event, or an exact copy of it, does not apply it twice. diff --git a/.changeset/ai-harness-cli.md b/.changeset/ai-harness-cli.md deleted file mode 100644 index 479bf06e29..0000000000 --- a/.changeset/ai-harness-cli.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@tanstack/ai-harness-cli': minor ---- - -Add `@tanstack/ai-harness-cli`: `runCli(harness)` runs a harness from the terminal. - -- Line mode reads one message or `/command` per line, hides a secret answer while the user types, and sends `@path` files. In a terminal, `/cancel` and a message typed while a turn runs act at once: the message joins the running turn. When a turn waits, each next line answers one wait: `y` or `n` for an approval (`once`, `always`, or `reject` for an approval of `permissions()`), and an answer read with the schema for a question. Pass `ui` to show your own screen on a session view instead. -- `-p "prompt"` runs one prompt for scripts and CI, and `--output ndjson` prints every AG-UI event. `-p` exits with code 3 (`EXIT.needsAction`) at the first wait of the turn: an approval, a question, or a sign-in. -- `--serve` serves the session protocol over HTTP behind a bearer token. It signs media URLs with its own key, never with the token: `--media-key` or `HARNESS_MEDIA_KEY` (at least 32 bytes), or a new random key at each start. Without a set key, signed media URLs stop working after a restart. On a host without `access`, it also passes `openAccess`: the `user` of `runCli`, or `true` without one. So each request with the token runs as the user of the CLI. -- `--acp` and `--mcp` load `@tanstack/ai-acp` and `@tanstack/ai-mcp` only when you use the flag. A missing package, or one without harness support, fails that flag with a clear message. Any other error while the package loads is reported, not hidden. -- In every mode, the first SIGINT or SIGTERM cancels the running turn. A second one, or one while no turn runs, stops the CLI, and `runCli` resolves to 130 (SIGINT) or 143 (SIGTERM). The CLI closes a host that it made with `recoverable: true`, or releases its session handle on your own host and does not wait for a turn that ignores the cancel. The `signals` option takes another signal source, for example an `EventEmitter` in a test. -- `host` and `user` options let the CLI use your durable host and run as your user. Every mode opens its sessions as that user. On a host with `access`, `--serve` reads the user of each request with `getUser`, and `--mcp` does not start, because stdio has no login. diff --git a/.changeset/ai-harness-core.md b/.changeset/ai-harness-core.md deleted file mode 100644 index e255d176de..0000000000 --- a/.changeset/ai-harness-core.md +++ /dev/null @@ -1,169 +0,0 @@ ---- -'@tanstack/ai-harness': minor ---- - -Add `@tanstack/ai-harness`: build an agent harness on TanStack AI. A harness keeps one conversation open across many turns. - -- `defineHarness()` names an agent: its adapter, tools, system prompts, middleware, agents, subagents, routing, plugins, turn hooks, and durability options. -- `createHarnessHost()` opens sessions. Each `host.open` gives its own handle to the live session of the thread. `session.close()`, or `await using`, releases the handle. A dropped handle is released by the garbage collector, with one warning. After `close()`, each call on the handle throws. When the session closes under a handle that is not released (its log failed, or a delete ran), the next call on the handle opens it again. -- `lifecycle` on `createHarnessHost()` sets how sessions live. A session that no handle holds closes after it was idle for `closeIdleSessionsAfterMs` (default 60 000). `maxOpenSessions` (default 500) first closes the least recently used idle sessions. A session is not idle while a background job of this host runs. `retention` (`keepSettledOperations`, `keepSettledAgentRuns`, `maxEventBytesInMemory`) bounds the settled operations, agent runs, receipts, events, and log tail that each session keeps in memory. The log keeps the `MESSAGES_SNAPSHOT` that core sends when a run pauses at an interrupt, so a rejoin from the log rebuilds the paused run. `host.close({ recoverable })` stops the work of every session and refuses later opens. With `recoverable: true`, the host gives each log that has work back with a wake, so a worker takes it at once. -- `host.observe(harness, { threadId, user })` reads a thread with no session: its events, transcript, snapshot, media, usage, and entry. It sets up no plugins, writes nothing, and never takes the log, so a read works while another host owns the thread. Its snapshot follows the same rules as `session.snapshot()`, without what only an open session knows (a running turn, operations, queues). `view.logState()` reads the `durability.logState` fold. -- `host.sessions.delete` closes the sessions of a thread and of its child threads. Then it deletes the log of the session tree (with the settings, config, plugin state, interrupted turn, runs, interrupts, usage, revert data, and the inputs that wait), the index entries, the uploaded media, and the generated artifacts. The first-party plugins also end the thread: `workspaceTools()` closes an owned sandbox with `'closed'`, and `snapshots()` removes the shadow repository. This needs the index entry, and the harness on that host: a host that opened it, or one with it in the `harnesses` option of `createHarnessHost()`. Else the host warns. A child thread is ended in the log of its root. While the delete runs, an open of the thread throws. With `access`, a thread with no index entry throws `AccessDeniedError`. -- A session takes `send` (a prompt, a steer into the running turn, a follow-up, or a message to an agent run with `to`), `continueWithoutMessage`, `reset`, `resolve`, `cancel`, and `moveToolCallToBackground` inputs. Each returns an operation with a receipt, and the session streams typed events. `host.isOpen(harness, { threadId })` says whether this host holds that session open. -- The session methods take one object: `cancelInput({ inputId, user? })`, `revert({ messageId, user? })`, `background({ toolCallId?, user? })`, `getMedia({ id })`, `mediaUrl({ id })`, and `agentTranscript({ subagentRunId })` or `agentTranscript({ runId })`. `AgentRun.subagentRunId` and `AgentRunInfo.subagentRunId` name the child id of an agent run, so the transcript of a run that code or a background call starts is found too. -- `session.appendRecords({ records, inputId?, user? })` returns a `Receipt`. A second append with the same `inputId` writes nothing. Without `inputId`, the append gets a new input id, and the log keeps it as an input. The `harness.revert` record keeps the user of `revert`, and the `harness.job` record keeps the user of `background`. -- `createHarnessHost({ access })` decides who can use each session. `getUser({ request })` reads the user of a request, and `isAllowed({ user, action, session, run })` decides each action. The user type comes from what `getUser` returns. The host keeps each tenant apart, needs a `user` on each call, and `host.open` returns a handle that acts only as its user. A refused action throws `AccessDeniedError`. The operations and the agent runs that a handle returns check access too. A child thread is checked through its root, also on `host.open`, so a stranger does not learn its root. When one user answers the turn of another user, the rest of the turn runs as the user who sent it. Without `access`, one user runs the host, with no checks. With `access`, keyed adapters and provider keys read env vars only when `access.allowServerEnvKeys` is `true`. -- `membersOnly()` gives ready access rules with the roles owner, member, operator, and viewer. `access` is `{ getUser, rules, getGuestUser?, allowServerEnvKeys? }`, and `membersOnly()` returns rules: `{ getUser, rules: membersOnly() }`. Rules are `{ isAllowed, filterSessionList?, members? }`: `filterSessionList` is the store filter of `host.sessions.list`, and `members` turns on `host.sessions.share` and `unshare` (`members.fork` sets the members of a fork). Your own rules are `rules: { isAllowed }`. `host.sessions.share` and `host.sessions.unshare` change the members, and `host.sessions.fork` takes `members: 'self' | 'all'`. The owner is the member with the role `owner`. For apps with their own access tables, `host.revoke` takes the access of a user to a thread, and returns a `Promise`. `host.revoke` and `unshare` cancel the running and queued work of the user on every host, and remove the schedules of the user at once. When that work cannot be stopped, they reject, and the access is gone already. A running `events()` read of a handle or a view ends with `AccessDeniedError`, and later view calls throw. `host.getUserOfRequest` reads the user of a request for your own routes. Each `host.sessions` method takes one object. -- A user with a `tenantId` keeps its sessions in its tenant: one thread id in two tenants is two sessions, with two index entries and two logs. `logIdOf({ tenantId, logId })` gives the id of a log in the store. -- Every run has a run context with its user, and that user's credentials and provider keys: `ctx.context.run` in tools and middleware (type them with `HarnessRunContext`), `ctx.turn.run` in a turn plugin, and `run` in a command. The `ctx.credentials` and `ctx.keys` of a session plugin have no user, so each call throws. `ctx.agents.start(agent, input, { user })` starts an agent for a user. `AgentRun.send` takes `user?`, and the `send` and `cancel` of a run act as the user of the run. `session.agents..run` honors `user`. The log keeps the sender of every input. The run context also has `epoch`, the ownership epoch of the log, and `idempotencyKey(step, scope?)`, a key for one side effect that is the same when the run runs again on any host. -- `definePlugin()` adds tools, prompts, middleware, agents, commands, config options, state, and extension points to a session or to one turn. With `lifetime: 'host'`, the host sets a plugin object up once per harness and shares it with every session that uses the same object. It is cleaned up when the last session that uses it closes, or at `host.close()`. A prompt with `placement: 'context'` goes in one system prompt after all the others, made again at each model call, so text that changes often (the todo list, the goal status, plan mode) leaves the system prompts before it in the provider prompt cache. The default `placement: 'system'` keeps a prompt in the system prompts. `prepareTools` gets `run`. `onTurnStart(turn)` runs once at the start of each turn, before the prompts, so a plugin can refresh the state that its prompts read. A plugin's `ctx.session.send` and `note` take `user?`, and default to the session owner. A thread that removes a plugin cannot run the agents of that plugin by name. -- `routing.router` sends a turn to a root agent. The log keeps the active agent, and the router reads it as `activeAgent`. A router that returns `undefined` gives the turn to the active agent, else to the main model. One agent name makes that agent active, `'main'` clears it, and `{ handoff, note }` is a handoff from the router. `routing.afterAgentsAnswer: 'end-turn' | 'main-answers'` (default `'end-turn'`) says whether the main model answers after the routed agents. -- Handoffs move a conversation to another root agent, and the target answers in the same turn. With `routing`, the main model and each root agent get a `handoff` tool. Code hands off with `ctx.harness.handoff({ to, note })` in a root agent, and with `ctx.context.run.handoff(...)` (`RunContext.handoff`) in a tool of the main model. Each handoff writes a `harness.handoff` record and streams a `harness.handoff` event (`from`, `to`, `note`, `by`, `runId`). A message that an agent writes has `metadata.harness.agent`. A turn hands off 10 times at most. An app tool named `handoff` fails the turn. `routing.giveModelsHandoffTool: false` gives no model the `handoff` tool, and the router and code can still hand off. A handoff stops only the chat that made it. When the part that handed off also stops for interrupts, the resolve turn runs the target (or pauses for a person). The router writes a handoff to the main model once when the active agent is gone. A handoff from the router or from code adds a `handoff` tool call and its result to the transcript before the target answers, so the target sees why it got the conversation. With `routing.giveModelsHandoffTool: false`, it adds one assistant note. -- With `routing.allowHandoffToHuman: true`, a handoff to `{ human: true }` opens a `human` wait with no default expiry, and the turn ends `interrupted`. User messages during the pause go in the transcript, and no model answers them. `session.send(text, { as: 'operator' })` adds an operator reply. It needs the `operator` access action, and it is rejected with `no_human_wait` when no handoff to a person is open. The operator ends the pause with an answer to the `human` wait: `{ resume: true }` or `{ handBack: '' | 'main' }`, also to a root agent of a turn plugin. When the `human` wait ends in any other way (a resolve, a cancel, an expiry), the agent from before the handoff answers again. An operator reply with files keeps its text in the assistant message, and the files in a user message after it with `metadata.harness.operatorAttachment`. A view shows the files with the reply, live and after a reload. -- `host.transfer({ from, to, envelope, user, transferId })` moves a conversation to another thread, also of another harness, in the same tenant. Only the envelope moves: a note, then no message, a summary that the source model writes, or the settled transcript with its media. The user needs `transfer` on the source and `send` on a target that exists. A new target has the user as its only owner. Both logs get a `harness.transferred` record, the index entries link the threads in `metadata`, `host.events()` yields a `transferred` event, and a retry with the same `transferId` is safe. A source thread that does not exist throws. A fork stays in its harness: `host.fork` with a thread of another harness throws. -- Agents run from code with `session.agents..run()` and `.start()`. `agentRun.receipt` resolves. In agent code, `ctx.harness` gives `step.do()` (a finished step returns its stored value when the run runs again), `step.sleep({ name, ms })`, `agents`, `state`, and `handoff` (in a root agent). `ctx.harness` is optional: a run that a plain `chat()` starts has none. -- `ctx.harness.agents` in agent code and `ctx.agents` in a plugin have one type, `AgentActions`: `start(agent, input, options?)`, `run(agent, input, options?)`, and `group({ concurrency, onFailure, key }, (g) => [g.start(...)])`. The input type comes from the input schema of the agent, and the result type from its output. `group` resolves to the results in order. With `onFailure: 'collect'`, each entry is an `AgentSettled` (`{ ok, value }` or `{ ok, error }`). The children of a group over its `concurrency` wait as `queued`. -- Each start takes `key`, `limits: { timeoutMs, maxAttempts }`, `budget: { maxTokens, maxCost }`, and `onModelError`. A run over its budget fails with the code `budget`, after the first model call over it. A run that runs again after a host stop counts the model use of the runs before. A run past `limits.timeoutMs` fails with the code `timeout`. A child never has more budget than its parent has left. `onModelError` is asked when a model call fails before it streams, and `'retry'` calls only that model call again (at most 3 calls). As data, `onModelError: { retries: 1 | 2, transientOnly? }` retries up to `retries` times (by default only a transient error), and the log keeps it, so a run that another host takes over or resumes retries too. A function is not in the log, so a run that another host takes over runs without it. A `ctx.agents` start in a plugin tool that an agent run calls is a child of that run, so it takes no `maxConcurrent` slot and the run can await it. `parent: ctx.context.run` names the run, and `parent: null` starts a root run. A `parent` that names no running agent run of this session throws, so a mistake does not start a root run. A running turn of the session gives a root run. -- The log keeps every run of a session as a `RunNode` of one run tree (`turn`, `agent`, `tool`, or `command`), with its parent, its user, its limits, its budget, and its result. `agentRuns()` reads the tree, and `AgentRunInfo` has `runId`, `kind`, `budget`, `result`, and `error`. Each `harness.usage` record has the `runId` of its run, and an agent run that ends keeps the usage of the run and its children. -- `maxDepth` and `maxCalls` count per tree, and `maxConcurrent` counts the root agent runs of the session. Over `maxConcurrent`, a root start waits as `queued`. The log keeps the counts, so a restart does not reset them. A `queued` start survives a host stop: the next host starts it with the same run id, in order, when a slot is free. -- A child run gets the user, the keys, and the signal of its parent: a cancel, a timeout, or a budget stop of the parent stops the child. A cancel of a turn also cancels the background runs that it started. A background run that a turn starts keeps the turn plugins until it settles. An agent that the model calls as a tool, and a routed agent, get `ctx.harness` too. -- A run with `runAgainAfterCrash: true` that runs again after a host stop gets the children that it started before, with their stored results, and starts only the rest. A background child that the model starts (`background: true`) runs again after a host stop as a run with `runAgainAfterCrash: true`, with the same `subagentRunId`. `durability.resumeBackgroundAgents: false` fails it instead. -- `ctx.harness.state({ key, initial })` gives the agents of a session a shared state by key, with `get` and `update`. The log keeps it, and a fork copies it. `STATE_SNAPSHOT` has `{ plugins, shared }`. -- A routed agent takes steers at its next model call, and late joins in the same turn, and `turn.beforeFinish` and `turn.onModelError` run for it. -- Every host keeps each session tree in one log, `stores.log` from `@tanstack/ai-persistence`. `memoryPersistence()` has a memory log, and a host with no `persistence` uses it. The log holds the inputs, events, transcripts, runs, interrupts, settings, config, plugin state, agent results, schedules, and tool steps, and the host folds them when a thread opens. A root thread and its child threads (agent runs and subagents) write to the log of the root. `session.logState()` reads the `durability.logState` fold of the whole tree. A harness with another `durability.addRecordsToModelContext` or `durability.logState` than the one that folds an open log throws when it opens that log. With a log store that survives a restart, the next host recovers a turn that a crash stopped. -- One host owns a log at a time: the first write takes it, one timer per host renews it, and a host that loses it stops its work on it. A host gives a log back when it has no work. Another host recovers the work of a log only after its ownership expires. A read never takes the log. An input that reaches another host waits in the input lane of the log, and the owner runs it (receipt `queued`) with its JSON overrides (`model`, `modelOptions`, `reasoning`, and `promptCache`). A command that reaches another host ends as it ends on the owner: with its result, its error, or `InputRejectedError`. An input to a thread that was deleted is refused: the receipt is `rejected` with the reason `deleted`, and an awaited operation rejects with `InputRejectedError` ("The thread was deleted."). `ownership: { expiresAfterMs, renewEveryMs }` sets the timing. `renewEveryMs` must be less than `expiresAfterMs`, else `createHarnessHost` throws a `RangeError`. With only `expiresAfterMs`, `renewEveryMs` is a third of it. -- When the owner refuses an offered input (busy, or an id that the log has with another payload), `session.settled()` on the host that offered it rejects with `InputRejectedError`. The log gets a `harness.offer.rejected` record. An offer that comes while the owner appends is not missed. -- A host that does not own a thread opens it while the owner runs a background job. Settings, config values, and the interrupted turn follow the changes of other hosts. `updateThreadSettings` merges into the latest stored settings. -- The owner writes a snapshot of the folded log to the log store after `log.saveSnapshotAfter.bytes` of new records (default 1 000 000) or `log.saveSnapshotAfter.ms` (default 300 000), and a new host opens from it. With `lifecycle.retention.keepLogRecords: 'since-snapshot'` (default `'all'`), the owner truncates the records before each snapshot. A reader whose cursor is in the dropped part gets one `harness.gap` event (`EventGap`), then the stream goes on. With `'since-snapshot'`, a thread whose snapshot the host cannot use (a changed `reduce` version or `project`) cannot open, and rejects with `LogTruncatedError`. `session.revert()` works with `'since-snapshot'`: the snapshot keeps the last 500 file steps. A plugin sets which of its records the snapshot keeps with `keepRecords: { [type]: count }` on its definition, and reads them, oldest first, with `ctx.session.keptRecords(type)`. The fold keeps the last 100 ended runs, run nodes, interrupts, and agent results, and drops the turn overrides of a settled input, so a long thread does not grow its fold and its snapshot with each turn. -- `host.submit` stores an input for a thread and runs nothing. `session.schedule({ at, input, scheduleId, user })` runs an input later, and `session.cancelSchedule({ scheduleId })` stops it. `createHarnessWorker({ host, harnesses, concurrency, signal, pollMs })` runs the threads that have work and no live host, and returns `{ stop }`. `host.resumePending` does one sweep. A swept thread that fails to open goes back with a wake in 30 s. A worker skips a thread that fails to open for a time that doubles after each failure in a row, up to 5 minutes, so the other threads still run. `host.submit` throws for a thread of another harness, and a later offer never changes the harness of a log. -- `durableTool()` keeps the result of each step. A crash can cut a step, and then it runs again, so `step.do` passes `{ idempotencyKey, epoch }` to `fn`. Give the key to your system, so it refuses the second side effect. `step.ask({ name, message, schema })` asks the user: the log keeps the question, any host can take the answer, and a run again after a stop returns the logged answer. A `step.do` value must be JSON: a `Date`, a `Map`, or a class instance is a type error. `step.sleep({ name, ms })` waits in the process, and the log keeps the wake time, so a worker continues the call after a stop. A sleep longer than 30 s on a thread that only a worker runs gives the thread back with the wake, so it keeps no worker slot. `durability.truncatedToolResult` sets the text of a tool call cut at the output limit. Without it, a cut answer ends the turn. -- `turn.onModelError`, `retryTransientErrors()`, `turn.beforeFinish`, and `turn.canJoin` control how a turn retries, continues, and ends. -- Every approval, question, sign-in, client tool, and human takeover that a run waits for is a `Wait` in the session log (`waitId`, `kind`, `runId`, `schema`, `expiresAt`, `message`). `WaitKind` is `approval`, `question`, `sign-in`, `client-tool`, or `human`. `waitKind`, `isApproval`, `waitFromInterrupt`, and `waitFromQuestion` come from the root and from `./view`. `snapshot().pendingWaits` lists the open waits: each one with its `interrupt` when a chat run stopped for it, and `turn: true` for a wait of the stopped turn. It is the one wait view of a snapshot. and `session.waitForRun({ runId, signal })` resolves with the next one. A wait ends `answered`, `cancelled`, or `expired`. A wait with `expiresAt` expires on time. Only `sign-in` has a default limit: 15 minutes. -- A wait that only the log holds keeps no host busy: the session goes idle, and an answer on any host continues the run. `resolve` answers the waits with an `interrupt`: of a stopped turn, or of one background agent run per call. `answer` answers the waits with no `interrupt` (a `step.ask` question, an MCP question, the `human` wait of a handoff), checks the answer against the JSON Schema of the wait, and keeps a secret out of the log. A `resolve` of such a wait is refused with `use_answer`, and a second answer to a wait that one answer ends is refused. `host.submit` checks an answer against the wait that it answers. -- A run waits for a person only at fixed points: `permissions()` before a tool call, the `question` tool, `step.ask` in a durable tool, a command (`CommandContext.step`), or an agent run, and the live waits of MCP elicitation and OAuth sign-in. `ctx.session.ask` throws anywhere else, with an error that names `step.ask`, the `question` tool, and `PermissionResources`. A command that called `step.ask` runs again from the top after a host stop. `Question` takes `expiresAt` and `signal`. -- A background agent run stops with status `waiting` on a wait, for example an approval of `permissions()`, and continues after the answer, also after a restart. An agent that the model calls as a tool inside a turn waits with the turn: its approvals, questions, sign-ins, app interrupts, client tools, and `ctx.harness.step.ask` questions are waits of the turn in `snapshot().pendingWaits`, with `agent` and `subagentRunId`. After the resolve, also on another host or after a restart, the agent goes on from where it stopped, and its result goes to the model as the tool result. Its `ctx.harness.step.do` values are in the log. With `durability.agentToolWaits: false`, the agent does not wait: a call of it that needs an approval is refused. -- The `operator` access action answers a `human` wait of any run, also with a resolve. A `human` wait takes only `operator`. `membersOnly()` gives it only to the role `operator`, so the user who waits for a person cannot act as that person. `membersOnly({ operator: { roles } })` sets the roles that have it. `isAllowed` gets the `wait` (`waitId`, `kind`) of an `answer` or `operator` action. -- `session.settled({ inputId, signal })` takes one object. `signal` stops the wait for the settlement. -- `session.onQuestion`, `session.onAuthRequired`, `session.onMedia`, and `session.onUsage` call a listener for the events that a user answers or sees, with a typed value. -- Sessions also have thread settings, fork and revert, usage totals, media files, the transcript of each child agent (`session.agentTranscript`), and `harnessText()` / `harnessAgent()` to use a harness as a text adapter or an agent. In a session, a `harnessAgent` child is a child run in the log of the root, with the user, keys, limits, and budget of the run that calls it. Its usage and its waits show in the parent session, on every host and in `host.observe`. An answer on another host goes to the host that runs the child. The base64 cache of media files is shared by all the sessions of a host. -- `harnessText()` uses the user of each call. The inner thread is `/inner/` on every host, and `host.open` refuses that id from app code. When a host with access runs the outer thread too, the inner session is checked through the outer thread, so every user of a shared outer thread can use it. The index entry of the inner thread keeps the link to its outer thread. An abort on a remote harness sends a cancel. The usage of the inner run reaches the outer `RUN_FINISHED`. Its SSE reader takes multi-line `data:` and CRLF. `harnessText()` and `harnessAgent()` forward events on one shared path. -- `createHarnessHost({ observability: { tracer, onOperation } })` traces runs. `tracer` takes an OpenTelemetry `Tracer`. `@opentelemetry/api` is an optional peer dependency: the host loads it only when it has a tracer. The host writes `harness.operation` spans (turns, agent runs, commands), and `harness.recovery`, `harness.wait`, and `harness.transfer` spans. A child run on the same host is a child span: the host passes `trace.setSpan(context.active(), parent)` as the third argument of `startSpan`. A tracer that throws is logged and fails no run. `SendOptions.traceparent` stores a W3C `traceparent` with the input, and the run span on the host that runs it gets a link to it. -- `onOperation` gets a `started` report and a `settled` report (`OperationReport`) for each operation that this host runs, with `status`, `durationMs`, `error`, and `usage`. A listener that throws gets a `harness.plugin.warning` event, and the work goes on. -- More lifecycle events in the session stream: `harness.input.queued`, `harness.ownership.changed` (`reason: 'taken_over'` when the store says that the old owner expired, else `'acquired'`), `harness.stranded`, `harness.transferred`, `harness.wait.opened`, and `harness.wait.settled`. `HarnessEventValues` maps each `harness.*` event name to the type of its value. -- `onEvent`, `onQuestion`, `onUsage`, and `onMedia` also get the events that another host writes to the log of the session. An event fires once. The status of `host.events()` counts that work too, for the sessions that are open on the host. -- The router gets `model`: `model.chat({ adapter, options, label })` in `routing.router` (`HarnessRouterContext.model`) calls a model with the keys of the sender, and a cancel of the turn stops it. -- `session.usage()` has `bySource`: the model calls that are not a turn or an agent run, keyed by `plugin:`, `router`, or `transfer`. Each `UsageCall` and `harness.usage` event of such a call has `source`, and `label` when the call has one. The summary of `host.transfer` with `messages: 'summary'` counts in the source thread under `transfer`, with the label `summary`, and stops after 2 minutes. - -Add first-party plugins. `@tanstack/ai-harness/plugins` loads no Node module. The plugins that read files are in the Node entry `@tanstack/ai-harness/plugins/node`. - -- `permissions()`: rules for tools, paths, and commands, and the `default`, `plan`, `acceptEdits`, and `bypass` modes. It decides every call of a model message before the calls run, and opens one approval wait for each call that asks, so the turn stops and no process waits. An answer is `true` or `false`, `'once'`, `'always'`, or `'reject'`, or `{ answer, message? }`. It also has saved "always" rules with `/permissions` and `/permissions forget `, and `listSavedPermissions` / `deleteSavedPermission` for server code. The rules apply in subagent runs too. It decides in `onGuardToolCall`, on the final checked arguments. -- `agents()` (in `plugins/node`): agent profiles with their own prompt, tools, model, rules, and step limit, in code or in Markdown files, `/agent` to switch the primary agent, and the built-in `build`, `plan`, `general`, and `explore` agents. A subagent run uses the tools and the model of the turn that started it. A run whose turn is not in the memory of this host fails with a clear error. A run that code starts needs a profile `model`. -- `question()`: a `question` tool for the lead turn. Each question is a wait of the turn, answered with `resolve`. Agent runs do not get the tool. -- `todos()`, `title()`, `modelPicker()`, `compact()`, and `usage()` (with your own prices for calls that have no provider cost). -- `goal()` runs each turn as the user who set the goal. -- `projectInstructions()`, `fileCommands()`, and `boundToolOutput()`, in `plugins/node`. - -A plugin runs agents with `ctx.agents.start`, `ctx.agents.run`, and `ctx.agents.group({ concurrency }, (g) => [g.start(agent, input)])`, with the same types as `ctx.harness.agents` in agent code. - -`PermissionRules`, `PermissionResources`, `PermissionDecisionCapability`, and `decidePermission` are also exported from the package root. They load no Node module, so an edge-safe plugin can read the permission rules. - -`ctx.model.chat({ adapter, options, label, run, timeoutMs })` calls a model from a plugin, for example a judge or a title. It uses the keys of the user of the run, the budget of the run applies, and it stops when the run stops or after `timeoutMs` (default 2 minutes). Its usage counts in the session under `plugin:` in `session.usage().bySource`. `goal()`, `title()`, and `compact()` call their models this way, with the labels `judge`, `title`, and `compact`. - -Serve a harness session to clients. - -- `createHarnessHandler()` from `@tanstack/ai-harness/server` serves a session over HTTP, as the user that the host `access` reads from each request. `POST run` is standard AG-UI, so `useChat` with `fetchServerSentEvents` works on a harness, with approvals, client tools, and a reload that joins the running turn. `POST control`, `GET events`, `GET transcript`, `GET agent-transcript` (the messages of a child agent run), `GET snapshot`, and `GET describe` cover one session. `sessions` (with the `share` and `unshare` ops), `GET host-events`, and the media routes cover the rest. A `host.events()` reader listens from the call, and one that falls more than 1 000 changes behind stops, and reads again for the current statuses. A refused action answers 403. A read of a thread that does not exist answers 404 and starts no session. A signed media URL still needs a user: `getUser` reads the user of the request, and that user needs `read` on the thread, in the tenant of the URL. For a request with no login, `access.getGuestUser({ tenantId })` can give a guest, and `isAllowed` decides `read` for it. The guest exists only on the signed media route. `requestUsers` from `@tanstack/ai-harness/server` gives the user of each request with the same rule, for your own server. The read routes read a thread with `host.observe`, so they set up no plugins. `GET describe` opens the session. -- `handleHarnessSocket()`, from the same entry, serves the same session over a WebSocket. It takes the upgrade `request` and reads the user from it. It handles the frames of one connection in order. -- A `command` or an `agent` input over HTTP or the socket runs once for one `inputId`, and the `inputId` of its receipt is the id of the client. -- `expose` on `defineHarness()` names the agents, settings, config keys, and commands that a client can use. Any other input of those kinds gets `rejected` with `not_exposed`. -- `createHarnessClient()` from `@tanstack/ai-harness/client` is a typed, browser-safe client. It sends inputs, reads the session, and streams events that resume from a cursor. Without `from`, `client.events()` starts at the newest event (the cursor of the snapshot), so it does not send the whole history first. This is the default: a reader that needs the history (to rebuild a transcript, for example) must pass `from: '0'` or a saved cursor. When the snapshot answer has no string `cursor`, `client.events()` throws and does not retry. `client.events()` connects again after `idleTimeoutMs` (default 60 000) with no bytes. The `prompt` input of the protocol and `client.send` take `as: 'operator'` for the reply of an operator after a handoff to a person. -- The client methods take one object: `cancelInput`, `revert`, `agentTranscript`, `mediaUrl`, `appendRecords`, and `putMedia`. `client.sessions.list`, `rename`, `delete`, `update`, `fork`, `share`, and `unshare` manage the sessions. `HarnessErrorCode`, the type of `HarnessProtocolError.code`, comes from the main, `/client`, and `/server` entries. -- `oauthConnector()` and the OAuth helpers from `@tanstack/ai-harness/oauth` (`loopbackLogin`, `deviceLogin`, `exchangeCode`, `refreshCredential`, and more) keep a credential per user. A tool calls `token({ run: ctx.context.run })` for the token of the user of its run. `token({ run, wait: true })` stops the turn with an `auth_required` interrupt until the user signs in. `deviceLogin`, `loopbackLogin`, `startLoopbackReceiver`, `exchangeCode`, and `refreshCredential(config, credential, { fetch, signal })` stop at once when their `signal` aborts, so a cancel or a session close stops a running `/connect`. `OAuthConfig.issuer` makes `loopbackLogin` refuse a code from another issuer (RFC 9207). The loopback deadline (`timeoutMs`) does not keep the process alive. -- `run.credentials.refresh(id, update, { signal })` refreshes a saved credential once for all callers on a host, keyed by tenant, user, and id. It saves with `setIf` when the store has `getVersioned` and `setIf`, and uses the other host's token on a conflict. Without that pair, it does a plain `set`. It saves to the scope where it found the credential, so a tenant token stays the tenant's. `update` gets a signal that only `host.close()` aborts. An abort of `signal` rejects only that call. `oauthConnector` refreshes this way, and `refreshCredential` keeps the `client` of the old credential. -- The session stream speaks protocol version 2 on every transport: `GET events`, the socket, and the stdio worker. Each event is an AG-UI wire chunk in a `harness.event` frame, with `cursor`, `threadId`, and `operationId`. The AG-UI `RUN_STARTED` of a child agent run has `parentRunId`, so a client can rebuild the run tree. -- The first frame of a stream is `harness.hello` with the version `v`. A client asks for a version with `?v=` or with `v` in `harness.subscribe`. Another version gets a `harness.error` frame with the code `unsupported_version`, and the stream closes (socket code 4400). -- A `harness.error` frame has a `code` (`unauthorized`, `forbidden`, `invalid_frame`, `unsupported_version`, `slow_consumer`, or `internal`) and a `requestId`. On the socket and the stdio worker, the `requestId` is the id of the frame that failed. Every answer of the handler has an `X-Request-Id` header: the id that the client sent when it is a short safe id, else a new UUID. -- Streams stay open and protect the server. SSE streams send a `: ping` comment and the socket sends a `harness.ping` frame when idle. SSE reads the log only as fast as the client reads, and the socket waits while its `bufferedAmount` is over the limit. A client that does not read in time gets a `slow_consumer` error frame, and the stream closes (socket code 4408). A slow client loses no events: it connects again from its last cursor. `createHarnessClient` does this in `events()` and `hostEvents()`, and ends the read with a `HarnessProtocolError` (with its `code`) for any other error frame. -- `presence: { onConnect, onDisconnect }` on `createHarnessHost` reports each client stream of `GET events` and of the socket (after its subscribe), as a `PresenceEvent` with a new `connectionId`, the user, the thread, the transport, and `resumed`. `onDisconnect` runs once per stream, with the reason `closed`, `revoked`, or `error`. The host does not wait for a hook, and a hook that fails only warns. -- `stream: { heartbeatMs, slowConsumerMs, sseQueueBytes, socketBufferBytes }` on `createHarnessHandler` and `handleHarnessSocket` changes these values. The defaults are 20 s, 30 s, 1 MiB, and 8 MiB. A value that is not a finite number above 0 throws at the start. `HarnessStreamOptions` is the type. -- A reader whose events are gone gets one `harness.gap` event, with `reason: 'truncated'` (a truncate of the log) or `'evicted'` (the memory feed of a session dropped them). The stream then goes on from `resumeAt`. -- A W3C `traceparent` goes with a message: as the `traceparent` header of `POST control` and `POST run`, or as the `traceparent` field of a `harness.input` frame. `ClientSendOptions.traceparent` makes `client.send` send the header. -- A `cancel` input stops a turn from any host that reads the same log, so `client.cancel({ operationId })` works behind a load balancer. A closed connection still never cancels work. To stop a `useChat` turn, call `client.cancel` with the `runId` of `useChat` in the stop handler. - -Add `createSessionView()` in `@tanstack/ai-harness/view`. It turns a session (local, or remote through `createHarnessClient()`) into one live TanStack Store state that works with any UI library. - -- The state: messages with their parts, tool calls, approvals, client tools, other interrupts, questions, sign-ins, `waits` (every open wait, with its kind), child agents with their results and a `status` of `running` or `waiting`, media with signed URLs, waiting inputs, usage, models, settings, commands, and plugin state. -- The waits of background agent runs show in `approvals`, `clientTools`, and `interrupts`. The view answers each one at once: with `resolve`, or with `answer` for a `human` wait that no turn holds. -- Actions: `send` (a prompt, a steer, or a `/command`), `followUp`, `continueWithoutMessage`, `putMedia`, `cancel`, `cancelInput`, `changeInputDelivery`, `updateThreadSettings`, `reset`, `revert`, `loadAgent`, and the answers to approvals (with edited arguments), client tools, interrupts, and questions. `cancelInput`, `revert`, `approve({ id, ...options })`, `reject({ id, payload? })`, `notice({ text })`, and `putMedia` take one object, and so does the `reject({ payload? })` of an approval item. -- Typed events: `view.on('approval' | 'interrupt' | 'turnEnd' | ..., handler)` and plugin events. -- In a harness with `routing`, an assistant message has `agent`, the root agent that wrote it. After a handoff, the next agent writes a new message in the same turn. -- `view.send(text, { as: 'operator' })` sends the reply of an operator while a handoff to a person is open. The reply shows in each open view at once. -- A view that opens while a turn runs shows the turn from its start. After a reload, each child agent shows its card, and `view.loadAgent({ id })` fills it with its own messages. -- When the stream sends a `harness.gap` event, the view stops its read, loads the snapshot and the transcript again, then reads on from the new cursor. No turn shows twice. - -Mark `createSessionView`, `SessionViewState`, and `SessionViewEvents` as `@experimental`. Document that event cursors are opaque strings: positions in the session log. - -Add the `goal({ judge, maxRounds })` plugin to `@tanstack/ai-harness/plugins`. `/goal ` sets a goal and starts a turn. After each turn, the judge model checks the goal, and the plugin starts the next turn until the goal is met, the round limit is reached, a turn waits for approval or fails, or the user sends a message. `/goal`, `/goal stop`, and `/goal resume` show and control it. The `GoalMet` event fires when the goal is met, and `selectGoal(session.snapshot())` reads the goal for a UI. - -Add the `providerKeys({ providers })` plugin to `@tanstack/ai-harness/plugins`. Users of a shipped harness connect their own model provider in the app, with no `.env` file. It adds `/connect:`, `/disconnect:`, and `/keys`. `/connect:` runs the provider's `signIn` when it has one, else it opens `keyUrl` when set and asks the user to paste the key with `step.ask` and `secret: true`. The log keeps the question as a wait, so a user on any host can answer it, and the log never keeps the key. The key is saved in the credential store of the user, and a `keyedAdapter(...)` for that provider uses it. `/keys` shows where each key of the user comes from: a saved key (the last 4 characters only), the env var, or no key. The plugin state shows only the env vars that the session reads, as every member of the thread reads it. On a host with access without `allowServerEnvKeys`, no env var counts. - -Add coding tools in the new Node entry `@tanstack/ai-harness/plugins/coding`: - -- `workspaceTools({ root })` gives `read_file` (text pages, images, PDFs), `write_file`, `edit_file` or `patch` (`editStyle`), `list_files`, `grep`, `bash` (with `background`), `webfetch`, and `websearch` (with a `SearchProvider`). With `permissions()`, edits, `bash`, and `webfetch` ask first, and the rules also apply to the real path of a link. `outside: 'ask'` makes a path outside `root` need an approval. `permissions()` decides outside paths and the real paths of links before the call runs, so a tool never asks while it runs. The `cwd` thread setting gives each thread its own working folder. -- `workspaceTools({ workspace: { bind, reattach? } })` gives each thread its own workspace. The root of the workspace is the boundary of every tool. The session log keeps where the workspace is (`harness.workspace.bound`). On another host, `reattach` gives the workspace back (for example a resumed sandbox), or `'pinned'` or `'gone'`. A gone workspace sends `tanstack/workspace-tools:stranded`. With this plugin first, `snapshots()` and `formatter()` use the workspace of each thread, and their `root` is optional. -- `createHarnessHost({ ownership: { hostId } })` gives a host a stable id. Then a thread that uses a folder on that host is pinned to it, and other hosts refuse its tool calls. Without `hostId`, threads are not pinned. A host with `hostId` sends a heartbeat to the log store, and its pins lapse when no heartbeat came for `ownership.expiresAfterMs`: then another host reattaches its threads. `host.unpin({ harness, threadId })` unpins a thread from a host that does not come back, once its ownership expired. -- `workspaceRoot(base, ...parts)` gives a folder in `base` for a tenant and a thread id. It encodes each part, so a thread id from a client cannot leave `base` or reach another thread. -- Commands, `rg`, `git`, and the formatters get only a short list of variables of the server process, plus the `env` of the backend call. Git runs without the hooks and the `fsmonitor` of the project. -- The tools resolve links with `realpath` under the file lock, and fail when a backend cannot resolve a path. A write fails when the file changed after the tool read it in the same chat run, so a lead and its subagents do not lose each other's edits. The file locks are shared by the sessions of a host, by the sandbox (or host) and the real path of the file. -- Background jobs: at most 8 per session (`maxJobs`), the newest 1 MiB of output per job, and the events `tanstack/workspace-tools:job-started`, `job-output`, and `job-ended`. A running command that `session.moveToolCallToBackground()` moves counts as a job, and its process id goes to the log. A job that an earlier host left running is stopped at the next tool call, with a note to the model. When the backend cannot check the job (for example with no `ps`), the log keeps it, and the note says that it can still run. The wake turn of a job runs as the user who started it. `session.jobs()` and `jobs()` of a `host.observe` view list the jobs that did not end (`JobInfo`: the job id, the thread, the command or tool name, who moved it, when it started, and `running` on this host). The `bash` spill file has `[redacted]` in place of each secret of the session. -- `read_file` sends images and PDFs up to 256 KB. `webfetch` gives the model the first 256 KB of a page. -- A `WorkspaceBackend` runs the tools. `hostBackend` is the default. `realpath` is required. `spawn` can give a `jobId`, `exec` can give one with `onStart`, and `killJob`, `binding`, and `close` are optional. `killJob` rejects when it cannot check that the process is the job. On Windows, commands do not run a program from the working folder by its name. -- `snapshots()` adds `/undo` and `/redo`, which restore only the files of the turn (git 2.26 or newer), file restore for `session.revert()`, and a diff for each model step. Each thread of each tenant has its own shadow repository, which never stores `.env` files. A step keeps only the files of its own run. The steps and the undo point are in the session log, so another host with the same repository can undo. A revert uses the last 500 steps. `host.sessions.delete` removes the repository of the thread, and `purgeSnapshots()` does it from your own code. A failed snapshot sends `tanstack/snapshots:failed`. -- `formatter()` formats each written file with the formatter of the project. With `permissions()`, the rules decide the formatter with the call that writes, before that call runs: one approval covers both, and the formatter runs after the write. An `always` answer is tied to a hash of the formatter config files. A write of a formatter config below the root, or under `node_modules`, asks each time, and an `always` answer saves no rule for that formatter run. -- `WorkspaceHooks` lets other plugins run code after a read or a write. - -`@vscode/ripgrep` and `turndown` are optional peer dependencies. - -`@tanstack/ai-harness/build` and `@tanstack/ai-harness/worker`: `buildHarness` bundles a harness with Bun into a worker artifact (`harness.js` and a `harness.manifest.json` with the sha256 digest), and can also build a single executable. `artifactText(dir)` checks the digest and uses the artifact as the model of a `chat()` call, with one worker process per thread. `runHarnessWorker` runs a harness on stdin and stdout with the session frames of the harness protocol. - -`definePlugin` refuses a `setup()` contribution, such as `adapter` or `tools`, at the top level of a definition, where it would be ignored. Return it from `setup()`. - -`write_file`, `edit_file`, and `patch` send `FileChanged` (`tanstack/workspace-tools:file-changed`) with a unified patch and its line counts for each file that they change. At the end of each model step, `snapshots()` sends it for the files that other tools, like `bash`, changed: at most 100 for each step. `/undo`, `/redo`, `session.revert()`, and `session.unrevert()` also send it for each file that they put back. - -Any server instance that reads the same log store can serve a run. - -- `POST run` sends the log cursor of each event as its SSE `id`. A client that is cut off sends the same request with `Last-Event-ID`, and any instance continues the stream from there. The turn does not run again. -- `GET run?runId=&threadId=` finds a turn that another instance runs. It streams the turn from the log of `threadId`, from its start or from `Last-Event-ID`, until the turn ends. It reads the log from the start of the turn, not from the start of the log. A turn rebuilt after a restart (a retried `POST run`) also streams from its start. Without `threadId`, only the instance that runs the turn finds it, and another instance answers `400`. The join request of a `ChatClient` sends only the run id, so put `threadId` in the URL of the connection. -- `GET run?threadId=` shows a turn that another instance runs as `activeRun`, so a reloaded `useChat` joins it. - -A host that folds a `harness.*` log record type it does not know (a newer harness wrote it, for example during a rolling deploy) reads the log but refuses to write it, with `LogVersionError`. A log snapshot from a newer harness is not used. - -`createHarnessHost({ logger })` takes a `Logger` from `@tanstack/ai` for the warnings and errors of the harness and its `chat()` calls (default: `ConsoleLogger`). Plugins get it as `ctx.logger`, and a logger that throws does not stop the harness. - -`PermissionCallCapability` gives a plugin that runs tool calls itself, like code mode, the decision that `permissions()` makes for one call: `allow`, `deny` with the error that the model gets, or `ask` with the approval question. It uses the current mode, the saved `always` answers, and the resources of the call args, and `settle(reply)` applies the user's answer as a direct approval does. - -Keep the secrets of a session out of what it keeps and sends. - -- Each session replaces every secret that it gave out with `[redacted]`. These are the values of `run.keys` (also from env vars) and `run.credentials`, connector credentials and OAuth tokens, and secret answers (each string field of an answer with fields). It scrubs log records, feed events, plugin state (also in a `Map` or a `Set`), notes, the model context, and tool results, also after the own middleware of an agent run. It also scrubs the error frames of the HTTP handler, the WebSocket, and the stdio worker. It finds the raw, JSON-escaped, and URL-encoded forms, and skips values shorter than 6 characters. A secret split across two streaming deltas stays in those two events, and a secret that is JSON-escaped two times is not found. -- `scrubSecrets` from `@tanstack/ai-harness` is the one from `@tanstack/ai/byok`. -- A `step.do` value that holds a secret of the session throws, on the first run and on a replay, so the log never keeps a secret. Read the secret outside `step.do`. -- A retry of an input with a secret in it is a duplicate, not a conflict: the check compares the input without the secrets, as the log keeps it. -- The log keeps the final result of each tool call: the result after every `onAfterToolCall` hook (also the agent's own middleware in an agent run), scrubbed. A replacement from a hook wins, also on an error. Recovery after a crash gives the model that result. -- An answer to a `secret: true` question that reaches a host that does not own the log goes through the `credentials` store of the host, as a one-time reference with the credential type `secret_answer` and an `expiresAt` 24 hours later. Only the reference goes into the input lane, and the owner reads and deletes it. The references that nobody read go when the question ends. A kept answer for a run again goes when the run ends. Without `createHarnessHost({ credentials })`, the answer is rejected with `secret_answer_needs_credentials`. A used, expired, or unknown reference is rejected with `unknown_secret_answer`. `credentials.list` does not show the `secret_answer` type. - -Make the transport defaults safe for a server with many instances. - -- `createHarnessHandler` and `handleHarnessSocket` read the user of each request with the host `access`. On a host without `access`, pass `openAccess: true` (no user) or `openAccess: { user }` (one local user), else they throw at the start. So a server never serves every thread to everyone by mistake. -- `media: { secret }` signs the media URLs of `createHarnessHandler`. Set the same secret on every instance, so a media URL that one instance signs works on every instance. Without it, the handler signs with a random key of its own, and a URL works only on that instance. A host with `ownership` options needs `media`, else the handler throws at the start. On another host without `media`, the first handler logs one warning. A signed URL names its harness and its user, and the handler checks that user again when it serves the file. A URL of a deleted thread answers 404. -- `media: { keys: [newKey, oldKey] }` rotates the key: the first key signs, and every key checks. Each key must be at least 32 bytes, else the handler throws at the start. -- `oauthConnector` needs `login`. Use `'device'` on a server, and `'loopback'` only for a harness on the user's own machine, such as a CLI. - -How a turn takes steers, settings, and plugin removals, and the size limit of client requests. - -- A steer that arrives during a `session.runTool()` turn waits, and then runs as its own turn. -- A turn keeps the config values that it started with. A config change while it runs, for example `/mode bypass`, applies from the next turn. -- `configure({ settings: { plugins: { remove } } })` removes everything that those plugins give the thread: also their agents, subagents, commands, agent and generation middleware, and the items that they add for other plugins (for example the permission rules of `agents()`). A remove that leaves a plugin (of any lifetime) or a harness middleware without a capability that it needs is rejected. -- When two plugins give a tool with the same name from `discoverTools`, the first one stays, and clients get one `harness.plugin.warning` event that names both plugins. -- `createHarnessHandler` reads each JSON body up to `media.maxBodyBytes` (default 32 MiB). A bigger body answers 413. `handleHarnessSocket` closes the socket with code 1009 on a bigger frame. The WebSocket server reads the whole frame first, so also set its own frame limit (for example `maxPayload` of `ws`). -- Client media is checked part by part before any part is stored, so a refused input stores nothing. A retried input with the same `inputId` stores its media no second time, and gets the first receipt. -- A client input with a provider file handle (`source.type: 'file'`) is refused with `media_url_not_allowed` unless the harness sets `media.allowProviderFiles: true`. Server code can still send file handles. -- `POST run` moves the inline bytes of the last user message to the media store, as `POST control` does, so the transcript keeps a `harness-media:` reference. A refused part answers 413 (`media_too_large`), 415 (`media_not_allowed`), or 400 (`media_invalid`, `media_url_not_allowed`). diff --git a/.changeset/ai-mcp-extension-setup.md b/.changeset/ai-mcp-extension-setup.md deleted file mode 100644 index 59ae4670fc..0000000000 --- a/.changeset/ai-mcp-extension-setup.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-mcp': minor ---- - -Serve and call MCP extensions. `createMCPServer` takes a `setup` function. It gets each SDK `McpServer` before it connects, so a server can declare an extension in `capabilities.extensions` and add handlers for its methods. `MCPClient.request` sends any request with the SDK `Client.request`, including the methods of an extension. diff --git a/.changeset/ai-mcp-harness.md b/.changeset/ai-mcp-harness.md deleted file mode 100644 index 38e67ecbc9..0000000000 --- a/.changeset/ai-mcp-harness.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@tanstack/ai-mcp': minor ---- - -Use MCP in a TanStack AI harness. - -- `@tanstack/ai-mcp/harness` adds `createHarnessMcpServer`. It serves a harness as an MCP server, so Claude Code, Claude Desktop, Cursor, or another agent can use it. The tools are `chat`, `steer`, `cancel`, `approve`, `reject`, `resolve`, `answer`, and `status`, plus `agent_` for each exposed agent and `command_` for each exposed command. Every tool takes an optional `threadId`. With `approvals: 'ask'` (the default), the client asks the user about each approval when it supports elicitation. Otherwise the approvals come back in the result. `approvals: 'auto'` approves every tool call. `resolve` answers every interrupt of a stopped turn in one call, or the waits of one background agent run. It finds the wait in the log, so it also answers a wait that another server, or a server before a restart, opened. A question takes `answer`. Every result lists the open waits of its work in `waits`, each with a `kind` from `waitKind` (`approval`, `question`, `sign-in`, `client-tool`, or `human`). The `status` tool lists every wait, and each background agent with `status: 'running'` or `'waiting'`. -- On a host with `access`, `createHarnessMcpServer` reads the user of each HTTP request with `getUser`. The host checks each tool call of that user. A host without `access` needs `openAccess: true` (no user) or `openAccess: { user }` (one local user), else the server throws at the start. It uses `requestUsers`, the same rule as the HTTP handler. Each tool call releases its session handle when it ends, so the session closes on idle. The `status` tool and the media reads read the thread with `host.observe`, so they set up no plugins. The server forgets a wait when its operation settles. -- `@tanstack/ai-mcp/harness` also adds the `mcp()` harness plugin. It connects stdio and HTTP servers by name, gives the model their tools as `_`, and adds a `/mcp` status command. A stdio server starts once per host for each `mcp()` object, and every session that uses that object shares it. `oauth: true` signs in to a server with `/connect `, for each user. -- `mcp()` connects again with backoff when a server closes, and lists the tools again on `list_changed`. A server that fails its first connect also tries again with backoff. `mcpConnector` and `oauth: true` servers connect again at the next turn, and list their tools again. Each server takes `needsApproval` and `toolName`. The backoff starts again only after a connection stayed open for 30 s, so a server that crashes right after it connects waits longer each time. When two servers give a tool with the same name, `mcp()` warns once. With `onDuplicateTool: 'error'`, the later server fails instead, with an error that names both servers and the tool. -- `@tanstack/ai-mcp/connector` adds `mcpConnector`: one OAuth MCP server as a harness plugin, with `needsApproval`, `prefix`, `scopes`, and `clientName`. The sign-in passes the `iss` of the callback on (RFC 9207). A cancel or a session close stops a running sign-in at once: the loopback stops listening, and the OAuth requests abort. When the MCP SDK refreshes a token, the connector saves it with `credentials.refresh` of the harness: to the scope of the sign-in, and with compare-and-set when the store has it. Each session still sends its own refresh request. When the server refuses a token, the connector deletes the saved sign-in only if it is the token that this session used. When the user signs out while the SDK refreshes, the connector saves no new token, and the call asks for a sign-in. -- `mcp()` and `mcpConnector` answer the `elicitation/create` requests of MCP spec 2025 servers, and the input requests of spec 2026-07-28 servers, as session questions. One tool call can ask up to 5 times. Each question is a live wait of the run that made the tool call: it ends `cancelled` when that run stops. `mcp()` tracks the live questions for each server, so each question goes to the run that called the tool. A spec 2025 request goes to the user only when all the running calls of that server belong to one run. Else the server gets `decline`. - -`@tanstack/ai-harness` is an optional peer dependency. Only the `./harness` and `./connector` entries need it. diff --git a/.changeset/ai-mcp-param-headers.md b/.changeset/ai-mcp-param-headers.md deleted file mode 100644 index b7a19e21ce..0000000000 --- a/.changeset/ai-mcp-param-headers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-mcp': patch ---- - -Send the `Mcp-Param-*` headers on spec 2026-07-28 tool calls. A tool argument marked with `x-mcp-header` in the input schema is now copied to its header, so strict servers such as GitHub's remote MCP server accept the call. Spec 2026 calls now go through the SDK `Client.callTool`, and use the SDK timeout, abort, and progress handling. diff --git a/.changeset/ai-mcp-prior-discover.md b/.changeset/ai-mcp-prior-discover.md deleted file mode 100644 index 8bc6be379c..0000000000 --- a/.changeset/ai-mcp-prior-discover.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-mcp': minor ---- - -Reuse a protocol `2026-07-28` `server/discover` result. `MCPClient.getDiscoverResult()` returns the result of the connection, or the adopted prior. `createMCPClient({ prior })` passes a saved one to the SDK `Client.connect`, so the client skips the `server/discover` request. `DiscoverResult` and `PriorDiscovery` are exported as types. diff --git a/.changeset/ai-mcp-setup-context.md b/.changeset/ai-mcp-setup-context.md deleted file mode 100644 index de7f3d4c86..0000000000 --- a/.changeset/ai-mcp-setup-context.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-mcp': minor ---- - -`createMCPServer({ setup })` gets the `handle` context of the request as its second argument, so an extension handler or an instrumentation hook can read the caller. A spec 2025 session with `sessions: 'memory'` gets the context of the request that opened it. diff --git a/.changeset/ai-sandbox-harness.md b/.changeset/ai-sandbox-harness.md deleted file mode 100644 index a837603ec3..0000000000 --- a/.changeset/ai-sandbox-harness.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@tanstack/ai-sandbox': minor ---- - -Add `@tanstack/ai-sandbox/harness` for `@tanstack/ai-harness`: - -- `codingAgents({ sandbox, agents, workspace? })` is a harness plugin. The lead model gets one tool per coding agent (Claude Code, Codex, Grok Build, or any ACP agent). Each agent works in the sandbox, keeps its own session per thread (also after a restart), and starts read-only in the `plan` mode of `permissions()`. `/fresh [agent]` starts a new session. `workspace: 'shared'` (default) runs the agents of a thread one at a time in one sandbox. `'per-agent'` gives each agent its own sandbox. -- `codingAgents` runs agents only on the host that owns the log of the thread, so `'shared'` runs one agent at a time also with many hosts. -- `sandboxWorkspaceBackend(sandbox, { owned? })` runs the coding tools of `@tanstack/ai-harness/plugins/coding` (`workspaceTools()`, `snapshots()`, `formatter()`) in a sandbox. It resolves links in the sandbox, reads one page of a file in the sandbox, and stops background jobs by their id (the pid and its start time), also from another host. It never stops another process that got the pid of a job. `binding()` gives the provider and the sandbox id, so another host can resume the sandbox. `close()` stops the jobs of the backend. A session close closes it with `'moved'`, so an owned sandbox stays for the next host. `host.sessions.delete` closes it with `'closed'`, and with `owned: true` that destroys the sandbox. - -`@tanstack/ai-harness` is an optional peer dependency. diff --git a/.changeset/ai-utils-command-env.md b/.changeset/ai-utils-command-env.md deleted file mode 100644 index 86516cd423..0000000000 --- a/.changeset/ai-utils-command-env.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-utils': minor ---- - -Add `commandEnv(env, platform, passEnv?)`, the short env of a command that a process starts (no provider keys or other secrets of the server), and `createOutputTail(maxBytes)`, the newest output of a command. `@tanstack/ai-harness`, `@tanstack/ai-sandbox`, and `@tanstack/ai-sandbox-local-process` use them. diff --git a/.changeset/anthropic-refusal-fallback.md b/.changeset/anthropic-refusal-fallback.md deleted file mode 100644 index 0216e30c35..0000000000 --- a/.changeset/anthropic-refusal-fallback.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@tanstack/ai-anthropic': minor ---- - -Add the `fallbacks` model option for Anthropic server-side refusal fallback. Set `modelOptions: { fallbacks: 'default' }` on `claude-fable-5`, `claude-fable-5-1`, `claude-opus-5`, `claude-opus-5-5` or `claude-sonnet-5-5`. When a safety classifier declines the request, the API answers with another model in the same call. The adapter sends the `server-side-fallback-2026-07-01` beta header for you. - -A response with `stop_reason: "refusal"` now finishes with `finishReason: 'content_filter'`. Before, it finished with `'stop'`. The refusal `stop_details` (`category`, `explanation`) is on the `RUN_FINISHED` event as `rawEvent`. diff --git a/.changeset/anthropic-stream-failure-usage.md b/.changeset/anthropic-stream-failure-usage.md deleted file mode 100644 index 6c95a603cd..0000000000 --- a/.changeset/anthropic-stream-failure-usage.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-anthropic': patch ---- - -Report the input token usage when a streamed response fails after its first event. A dropped connection or an Anthropic `error` event in the stream ended in a `RUN_ERROR` with no `usage`. Anthropic bills the input tokens of that call, so this `RUN_ERROR` now carries the `usage` that `message_start` reported. The output count is the one from `message_start`, so it can be lower than the real output count. diff --git a/.changeset/calm-dolphins-buffer.md b/.changeset/calm-dolphins-buffer.md deleted file mode 100644 index dfbf559bc3..0000000000 --- a/.changeset/calm-dolphins-buffer.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-opencode': patch ---- - -fix(ai-opencode): bound memory while buffering parts before their message role is known diff --git a/.changeset/client-reconnect-backoff.md b/.changeset/client-reconnect-backoff.md deleted file mode 100644 index 9b0c100c76..0000000000 --- a/.changeset/client-reconnect-backoff.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-client': minor ---- - -Reconnects of a durable run can ride out a server restart. The wait between reconnects now doubles from `initialDelayMs` (default 250) up to `maxDelayMs` (default 5000), with jitter. Set `budgetMs` to keep reconnecting for a total time instead of a fixed number of attempts. A reconnect answered 408, 429, 502, 503, or 504 is retried, and a `Retry-After` header sets the wait. `delayMs` still works as the old name of `initialDelayMs`. diff --git a/.changeset/cloudflare-binding-headers.md b/.changeset/cloudflare-binding-headers.md deleted file mode 100644 index 39efe98bda..0000000000 --- a/.changeset/cloudflare-binding-headers.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-cloudflare': minor ---- - -Add `defaultHeaders` to the binding config. Every binding run sends them as the Workers AI `extraHeaders` option, next to `gateway`, so you can set `x-session-affinity` for prompt caching when you use `{ binding: env.AI }`. diff --git a/.changeset/code-mode-harness.md b/.changeset/code-mode-harness.md deleted file mode 100644 index d4d780073b..0000000000 --- a/.changeset/code-mode-harness.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@tanstack/ai-code-mode': minor ---- - -Add `@tanstack/ai-code-mode/harness` with `codeMode({ driver })`: a harness plugin that gives the model one `execute_typescript` tool. The model writes a program that calls several tools, and the program runs in the isolate of any `@tanstack/ai-isolate-*` driver. - -- By default, only tools that are safe to run without a question move into code mode. These are server tools with no `needsApproval` and no permission resources, which the permission rules allow in plan mode. A safe tool with `metadata.codeMode: true` always moves. -- `include` picks more tools, also tools with permission checks, such as the coding tools `read_file`, `write_file`, `edit_file`, `patch`, `list_files`, `grep`, `bash`, and `webfetch`. Each call of such a tool in a program gets the same decision from `permissions()` as a direct call. The call runs, or it throws an error with the reason, or the program waits for the user to approve it. The approval is a question wait that `session.answer` answers with `once`, `always`, or `reject`. A program that can wait gets a timeout of 10 minutes by default. -- The session log keeps the result of each checked call. After a stop, the next host runs the program again, and a call that finished before the stop does not run twice. A call that the stop cut, and that is not safe to run again, throws in the program. -- `include` never moves a tool that needs approval, or a tool that the rules deny in the current permission mode. The rules decide again at each turn, so in plan mode the tools that edit stay normal tool calls. -- `directCalls: 'keep'` keeps the moved tools in the model's tool list too. The session setting `directCalls` changes it while the session runs. -- `lazy: true` lists only the tool names and adds `discover_tools`. A tool name that is not a JavaScript identifier gets a safe name inside the program. - -`@tanstack/ai-harness` is an optional peer dependency. diff --git a/.changeset/code-mode-result-shape.md b/.changeset/code-mode-result-shape.md deleted file mode 100644 index 98673986c6..0000000000 --- a/.changeset/code-mode-result-shape.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-code-mode': patch ---- - -The `execute_typescript` tool description and the code-mode system prompt now tell the model that the tool returns `{ success, result, logs, error }`, where `result` is the value its code returned. diff --git a/.changeset/computer-use-harness.md b/.changeset/computer-use-harness.md deleted file mode 100644 index e283670bcb..0000000000 --- a/.changeset/computer-use-harness.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -'@tanstack/ai-computer-use': minor -'@tanstack/ai-harness': minor ---- - -Add `computerUse()` in `@tanstack/ai-computer-use/harness`: computer use as a harness plugin. - -- Each screenshot goes to the media store of the session. The transcript and the log keep a small `harness-media:` reference. -- The model gets only the newest `keepScreenshots` screenshots (3 by default). An older one goes to the model as a 1x1 image. -- A call with OpenAI safety checks asks the user through `permissions()`, each time. Without `permissions()`, the call is refused. -- The `plan` mode of `permissions()` refuses the `computer` tool. - -`@tanstack/ai-harness` is an optional peer dependency of `@tanstack/ai-computer-use`. - -A plugin can now store a file with `ctx.session.putMedia(upload)`, and put `mediaPart(record)` in a tool result. diff --git a/.changeset/conformance-skip-reporting.md b/.changeset/conformance-skip-reporting.md deleted file mode 100644 index b5d778b9c4..0000000000 --- a/.changeset/conformance-skip-reporting.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-persistence': patch ---- - -Report the conformance cases of an omitted `generationRuns`, `artifacts`, or `blobs` store as skipped. These cases reported a pass when the store was declared in `skip`. diff --git a/.changeset/docker-local-source.md b/.changeset/docker-local-source.md deleted file mode 100644 index 38e9db057d..0000000000 --- a/.changeset/docker-local-source.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-sandbox-docker': minor ---- - -`dockerSandbox()` now copies a `localSource(dir)` folder into a new container: the files that git lists, their uncommitted changes, and the history of the current branch. The folder must be a Git repository, and the image must have git (for example `node:24`). diff --git a/.changeset/docker-resume-errors.md b/.changeset/docker-resume-errors.md deleted file mode 100644 index 354b453875..0000000000 --- a/.changeset/docker-resume-errors.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-sandbox-docker': patch ---- - -`resume()` of `dockerSandbox()` gives `null` only for a container that Docker does not have. Any other error, such as Docker not running, now goes to the caller, so a user sees "Docker is not running" and not "the workspace is gone". diff --git a/.changeset/elevenlabs-sound-v3.md b/.changeset/elevenlabs-sound-v3.md deleted file mode 100644 index 659c1aab53..0000000000 --- a/.changeset/elevenlabs-sound-v3.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-elevenlabs': patch ---- - -The audio adapter accepts `eleven_text_to_sound_v3`, a sound model that the ElevenLabs SDK types do not list yet. diff --git a/.changeset/evaluate-http-status.md b/.changeset/evaluate-http-status.md deleted file mode 100644 index 918e7b1593..0000000000 --- a/.changeset/evaluate-http-status.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@tanstack/ai-typesafe': minor -'@tanstack/ai-ollaya': minor -'@tanstack/ai-openrouter': minor -'@tanstack/ai-vercel-gateway': minor ---- - -The TypeSafe, Ollaya, OpenRouter and Vercel Gateway evaluate adapters now set `status` on the error they throw for an error response. `status` is the HTTP status code, so you can tell a rate limit (429) from a bad key (401) without parsing the message. The message does not change. - -```ts -if (error instanceof Error && 'status' in error && error.status === 429) { - // wait, then call decide() again -} -``` diff --git a/.changeset/evaluate-refusal-error.md b/.changeset/evaluate-refusal-error.md deleted file mode 100644 index b9d6187486..0000000000 --- a/.changeset/evaluate-refusal-error.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -'@tanstack/ai': minor -'@tanstack/ai-openai': minor ---- - -Add `EvaluateError`, a typed error an evaluate adapter throws when the provider answered but the call cannot become a result. `@tanstack/ai` and `@tanstack/ai/adapters` export the class, the `isEvaluateError()` type guard, the `EvaluateErrorInit` type and `EVALUATE_REFUSAL_CODE`. The error keeps what the provider sent back: - -- `code`: a stable code to branch on. A refused question uses `EVALUATE_REFUSAL_CODE` (`'refusal'`). -- `usage`: the tokens the call used. -- `model`: the model that answered. -- `answers`: the raw wire answers that came back, before `decide()` maps them. A `choice()` answer has `choice` (for example `{ type: 'choice', choice: 'billing', ... }`), and a `boolean()` answer is `{ type: 'noul', noul: 0.9 }`, not `{ value }`. The refused question has no key. - -When OpenAI refuses to answer a question, `decide()` now throws an `EvaluateError` with `code: 'refusal'` instead of a plain `Error`. If more than one question is refused, the message names the first one. - -Use `isEvaluateError(error)` to narrow a caught error. It checks `name` and `code`, not `instanceof`, so it still works when the app installs more than one copy of `@tanstack/ai`. - -When an adapter throws an `EvaluateError` that carries `usage`, `decide()` reports that usage through the `evaluate:usage` event and the middleware `onUsage` hook, then runs `onError` and rethrows the same error. `onFinish` does not run. - -```ts -try { - await decide({ adapter, state, questions }) -} catch (error) { - if (isEvaluateError(error) && error.code === EVALUATE_REFUSAL_CODE) { - console.log(error.usage, error.answers) - } - throw error -} -``` - -The message text does not change. The error is still an `Error`, but its `name` is now `'EvaluateError'`, so logs and the OpenTelemetry `error.type` show that name instead of `'Error'`. diff --git a/.changeset/harness-acp-agent.md b/.changeset/harness-acp-agent.md deleted file mode 100644 index e8684a7229..0000000000 --- a/.changeset/harness-acp-agent.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@tanstack/ai-acp': minor ---- - -`@tanstack/ai-acp/agent` adds `createAcpAgent` and `serveAcp`, which serve a harness as an ACP v2 agent (experimental, like the draft protocol). Each wait of a turn goes to the editor by its kind: an approval becomes a permission request (with `allow_always` only when the answer schema takes `always`), a question or a `human` wait becomes a form elicitation, and a sign-in becomes a URL elicitation, when the editor declares them in `initialize`. A wait that the editor cannot answer is cancelled. Cancel cancels the running turn, and image, audio, and embedded file blocks go to the media store of the session. A prompt takes its place in the queue before its media is saved, and gives the place back when the session is idle. `session/list` lists the sessions of the harness from the session index of the host. The `user` option is the user of the editor: each session opens as that user, and the list shows the sessions of that user. It is required on a host with `access`. The agent holds one session handle per ACP session. `session/close` releases it, and the close of the connection releases them all (a session whose prompt runs keeps its handle until that prompt ends), so the host closes each session on idle. `@tanstack/ai-acp` now uses `@agentclientprotocol/sdk` 1.8, pinned to `~1.8.0` because the agent uses its experimental v2 entry point. The existing ACP client adapters keep working. - -One agent app serves one connection, and reads the editor capabilities from that connection. A second connection gets a clear error. For more connections, make one app for each: `new AcpServer({ createAgent: () => createAcpAgent(options) })`. A session that the agent made or opened in its connection takes prompts after the agent released its handle, also on a host with no `stores.sessions`. diff --git a/.changeset/harness-anonymous-input.md b/.changeset/harness-anonymous-input.md deleted file mode 100644 index d4b5e37b79..0000000000 --- a/.changeset/harness-anonymous-input.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-harness': patch ---- - -An input with no user no longer runs as the user who opened the session that owns the thread. A host with access refuses that input. diff --git a/.changeset/harness-credentials-option.md b/.changeset/harness-credentials-option.md deleted file mode 100644 index 4e0ddb7ef9..0000000000 --- a/.changeset/harness-credentials-option.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@tanstack/ai-harness': minor -'@tanstack/ai-harness-cli': minor ---- - -`createHarnessHost({ credentials })` takes the `CredentialStore` (from `@tanstack/ai/byok`) where users' API keys and OAuth sign-ins are saved. Without it, credentials stay in memory until the process stops. `runCli` takes the same `credentials` option. diff --git a/.changeset/harness-plugin-logger.md b/.changeset/harness-plugin-logger.md deleted file mode 100644 index 5ed7539ea9..0000000000 --- a/.changeset/harness-plugin-logger.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@tanstack/ai-mcp': patch -'@tanstack/ai-code-mode': patch -'@tanstack/ai-skills': patch ---- - -The `mcp()`, `codeMode()`, and `skills()` harness plugins send their warnings to the logger of the host (`createHarnessHost({ logger })`). diff --git a/.changeset/harness-round5-fixes.md b/.changeset/harness-round5-fixes.md deleted file mode 100644 index 0829bfd354..0000000000 --- a/.changeset/harness-round5-fixes.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -'@tanstack/ai': patch -'@tanstack/ai-anthropic': patch -'@tanstack/ai-client': patch -'@tanstack/ai-cloudflare': patch -'@tanstack/ai-compaction': patch -'@tanstack/ai-event-client': patch -'@tanstack/ai-harness': patch -'@tanstack/ai-persistence': patch -'@tanstack/ai-sandbox': patch -'@tanstack/ai-sandbox-blaxel': patch -'@tanstack/ai-sandbox-boxd': patch -'@tanstack/ai-sandbox-cloudflare': patch -'@tanstack/ai-sandbox-daytona': patch -'@tanstack/ai-sandbox-docker': patch -'@tanstack/ai-sandbox-e2b': patch -'@tanstack/ai-sandbox-local-process': patch -'@tanstack/ai-sandbox-railway': patch -'@tanstack/ai-sandbox-sprites': patch -'@tanstack/ai-sandbox-upstash-box': patch -'@tanstack/ai-sandbox-vercel': patch -'@tanstack/openai-base': patch ---- - -Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. - -- Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. -- Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. -- Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). -- Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. -- The duplicate-input check no longer depends on the key order of the stored input. -- `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. -- New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. -- Plugin model calls (`ctx.model.chat`) run the harness middleware. -- Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. -- Compaction drops a background summary that another model prepared. -- Sandbox file calls take an optional `{ signal }`. -- Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. -- OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. -- Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. -- Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. -- `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. -- The persistence conformance suite no longer fails a correct store on a slow runner. diff --git a/.changeset/harness-skills.md b/.changeset/harness-skills.md deleted file mode 100644 index 365b90e0c1..0000000000 --- a/.changeset/harness-skills.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-skills': minor ---- - -`@tanstack/ai-skills/harness`: the new `skills({ dirs })` plugin gives the harness model the skills of a list of folders, and makes each skill a `/` command that starts a turn with that skill. A skill with the name of another command is `/skill:`, and `/skills` lists them. The plugin watches the folders, so a skill that you add or remove while the session runs changes the commands at once. The watcher lives as long as the host, every session that uses the same `skills()` object shares it, and a change makes each session read the folders again. A skill that does not load gets a fallback message. diff --git a/.changeset/llmgateway-catalog-models.md b/.changeset/llmgateway-catalog-models.md deleted file mode 100644 index 884b50f1fa..0000000000 --- a/.changeset/llmgateway-catalog-models.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-llmgateway': minor ---- - -Generate the LLM Gateway chat model list from the gateway catalog, including input kinds and reasoning levels. diff --git a/.changeset/mcp-events.md b/.changeset/mcp-events.md deleted file mode 100644 index 10ca3d49b4..0000000000 --- a/.changeset/mcp-events.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@tanstack/ai-mcp': minor ---- - -Add experimental MCP Events (SEP-3415) webhook support. - -- `createMCPClient({ experimental_events: { store } | { adapter } })` adds `client.experimental_events` with `list`, `subscribe`, `refresh` and `unsubscribe` (direct) or adapter-delegated operations (managed). -- New `@tanstack/ai-mcp/events` subpath: `createMCPEventWebhook`, `inMemoryMCPEventStore`, `createMCPEventSecret`, `signMCPEventPayload`. diff --git a/.changeset/mid-conversation-exact-optional.md b/.changeset/mid-conversation-exact-optional.md deleted file mode 100644 index c49f40d399..0000000000 --- a/.changeset/mid-conversation-exact-optional.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai': patch ---- - -Accept a missing `midConversationChannels` value on text adapters when `exactOptionalPropertyTypes` is on. `chat()` can take `fakeText()` and the provider text adapters again. diff --git a/.changeset/neon-adapter.md b/.changeset/neon-adapter.md deleted file mode 100644 index 26c914c98f..0000000000 --- a/.changeset/neon-adapter.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@tanstack/ai': patch -'@tanstack/ai-neon': minor -'@tanstack/openai-base': patch ---- - -Add `@tanstack/ai-neon` for the Neon AI Gateway: `neonText` sends Claude to the Anthropic Messages route, codex and `*-pro` models to the Responses route, and every other model to Chat Completions, with `neonEmbedding` and `neonSummarize`. `@tanstack/openai-base` gets a `streamOptions(model)` hook, so a Chat Completions backend that rejects `stream_options` can leave it out. diff --git a/.changeset/openai-base-length-tool-call.md b/.changeset/openai-base-length-tool-call.md deleted file mode 100644 index f9738677a8..0000000000 --- a/.changeset/openai-base-length-tool-call.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/openai-base': patch ---- - -Keep `finishReason: "length"` when Chat Completions cuts off a tool call. The run no longer reports `tool_calls` or sends the unfinished arguments back to the model. diff --git a/.changeset/openai-gpt6-sampling.md b/.changeset/openai-gpt6-sampling.md deleted file mode 100644 index d9bf923f1f..0000000000 --- a/.changeset/openai-gpt6-sampling.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-openai': patch ---- - -Drop `temperature`, `top_p`, and `top_logprobs` on GPT-6 reasoning models, and request encrypted reasoning for those models. OpenAI returns 400 when these fields are sent. They are kept when reasoning effort is `none`, which OpenAI accepts. diff --git a/.changeset/opencode-stream-parts.md b/.changeset/opencode-stream-parts.md deleted file mode 100644 index a437b79ad2..0000000000 --- a/.changeset/opencode-stream-parts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-opencode': patch ---- - -Only translate assistant message parts and wait for OpenCode to provide tool input before emitting a tool call. diff --git a/.changeset/persist-activities-on-stop.md b/.changeset/persist-activities-on-stop.md deleted file mode 100644 index 812f8041fe..0000000000 --- a/.changeset/persist-activities-on-stop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-persistence': patch ---- - -`withPersistence` now saves activity rows when a run is stopped or fails, so `reconstructChat` restores them after a reload. A plain disconnect on a detachable or interrupted run still writes nothing. diff --git a/.changeset/persistence-batch-hint-metadata.md b/.changeset/persistence-batch-hint-metadata.md deleted file mode 100644 index 6f16e66c44..0000000000 --- a/.changeset/persistence-batch-hint-metadata.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@tanstack/ai': patch -'@tanstack/ai-persistence': patch ---- - -Middleware can read `ctx.callMetadata`, the `metadata.tanstack` of the current model call. Each assistant message of the call gets a copy of it. - -With `snapshotStreaming`, `withPersistence` now stores `ctx.callMetadata` on snapshot rows, so a stopped or failed row has the same metadata as a finished one. A stopped or failed row no longer stores other chunk metadata, such as the durability batch hint of `ctx.emitCustomEvent(name, value, { batch: true })`. diff --git a/.changeset/persistence-child-resume.md b/.changeset/persistence-child-resume.md deleted file mode 100644 index 6940c3e31f..0000000000 --- a/.changeset/persistence-child-resume.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@tanstack/ai': minor -'@tanstack/ai-persistence': patch ---- - -Fix `withPersistence` failing to resume an interrupt of a subagent tool call with `Tool is unavailable for interrupt .` The parent run now leaves interrupts its child answers to the child, using the new `ctx.childResumeIds` on the middleware context, and still commits them once the run succeeds. - -With `withPersistence`, the resume of a child is server-authoritative: - -- The stored interrupt records decide which interrupts a child owns. A resume whose subagent cards claim other interrupts fails with `InterruptResumeValidationError`. -- The child resumes from its stored messages, not from the card the client sent back. `LoadChild` results get an optional `pending` field for this. A middleware that provides `loadChild` must set `pending` for a waiting child, or the agent tool does not resume it. diff --git a/.changeset/persistence-routed-host-after-tool-call.md b/.changeset/persistence-routed-host-after-tool-call.md deleted file mode 100644 index b176911c9b..0000000000 --- a/.changeset/persistence-routed-host-after-tool-call.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-persistence': patch ---- - -Keep the answer of a routed agent in its own message when the turn resumes after an interrupt and a finished tool call (for example a handoff) comes before that answer. Before, the stored answer moved onto the message of the tool call. diff --git a/.changeset/persistence-session-stores.md b/.changeset/persistence-session-stores.md deleted file mode 100644 index 470f8f1c16..0000000000 --- a/.changeset/persistence-session-stores.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@tanstack/ai-persistence': minor ---- - -Add opt-in session stores. The chat and generation middleware work as before without them. - -- `log` (`LogStore`): an append-only log for each session tree, with 15 methods, each with one object argument. Records: `append`, `read`, and `subscribe`. Ownership: `acquireOwnership`, `renewOwnership`, `releaseOwnership`, `pinToWorkers`, `markHostAlive`, and `listLogsWithoutOwner`. A pin (`pinToWorkers`) counts only while its host is alive: `acquireOwnership` and `listLogsWithoutOwner` ignore the affinity of a host with no live `heartbeat({ hostId, ttlMs })`, so the logs of a host that stopped go to other hosts. A host that is alive keeps its pins, also on the logs that it released. The input lane: `offerInput` and `listOfferedInputs`, consumed in the same write with `append({ consumes })`. The owner or the first offer names the harness of a log for `listLogsWithoutOwner`: a later offer does not change it. Snapshots and lifecycle: `getSnapshot`, `putSnapshot`, `truncate`, and `deleteLog`. `acquireOwnership` returns `expired: true` when it takes the log from another owner whose ownership expired with no release. Each fenced write carries the epoch from `acquireOwnership`, and a write with an old epoch rejects with `OwnershipLostError`. A writer that never calls `acquireOwnership` appends with `NO_OWNER_EPOCH`. `pinToWorkers`, `putSnapshot`, and `truncate` need the owner, so they refuse `NO_OWNER_EPOCH`. After `deleteLog`, every fenced write fails until the next `acquireOwnership`, and `offerInput` returns the new `OfferResult` `'deleted'` and stores nothing, so a late write or input cannot bring a deleted log back. `append` rejects with `LogConflictError` when another writer took the position, and `read` rejects with `LogTruncatedError` before the truncation point. `memoryLogStore()` is the reference store. `memoryLogStore({ state })` with one `memoryLogState()` lets two store instances share one log. The conformance kit needs `twin`, a second store set with a new log store instance on the same backend, for the `log` cases across instances. -- `sessions` (`SessionIndexStore`): one index entry per tenant and thread. The key is `{ tenantId?, threadId }` (`SessionIndexKey`), so one thread id in two tenants is two entries. An entry has `members` (`SessionMember`, with the role `owner`, `member`, `viewer`, or `operator`). The owner is the member with the role `owner`. The store has `get(key)`, `getVersioned(key)`, `upsert(entry)`, `upsertIf({ entry, revision })` for compare-and-set writes, `list`, and `delete(key)`, a hard delete. `list` reads one tenant, filters by member, parent thread, title `search`, `harness` name, and exact `metadata` values, and pages with a cursor. - -`defineLogStore` and `defineSessionIndexStore` type an adapter. `memoryPersistence()` now also has `log` and `sessions`. `runPersistenceConformance` runs the cases of each session store when the store is present, so an existing backend needs no `skip` entry. - -With `stores.sessions`, `withPersistence` writes one index entry for each subagent child (`subagent:`), in the tenant of its `tenantId` option. The entry has the parent thread, the tool call, and the `harness` name of the parent entry. It has no members: access to a child goes through its top-level thread. - -`loadChildTranscript(messages, subagentRunId, threadId)` reads the stored messages of a child agent run for a UI. It returns `undefined` for a child of another thread. diff --git a/.changeset/persistence-subagent-interrupts.md b/.changeset/persistence-subagent-interrupts.md deleted file mode 100644 index 7af790d480..0000000000 --- a/.changeset/persistence-subagent-interrupts.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-persistence': patch ---- - -`withPersistence` lets a subagent that a tool call started check the answers to its own interrupts. The parent run does not check them against its own tools and batch, so a child client tool, and two children that wait at once, resume. diff --git a/.changeset/quiet-tools-split.md b/.changeset/quiet-tools-split.md deleted file mode 100644 index 41352e3c66..0000000000 --- a/.changeset/quiet-tools-split.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/openai-base': patch ---- - -Parallel tool calls stay separate when the provider leaves out `index` on the streamed deltas (Gemini's OpenAI-compatible endpoint, for example). Before, they merged into one call with joined arguments. A different id starts the next call once the current call has an id. A different name does so when the delta has no id, or when the current call still has no id. Any other delta without an index continues the latest call. A repeated name stays on that call. diff --git a/.changeset/remove-retired-models.md b/.changeset/remove-retired-models.md deleted file mode 100644 index 10994686ef..0000000000 --- a/.changeset/remove-retired-models.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -'@tanstack/ai': patch -'@tanstack/ai-anthropic': patch -'@tanstack/ai-gemini': patch -'@tanstack/ai-groq': patch -'@tanstack/ai-mistral': patch -'@tanstack/ai-openai': patch -'@tanstack/openai-base': patch ---- - -Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. - -- Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. -- Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. -- OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. -- Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. -- Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. - -Types and helpers that only served those models are removed: - -- `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. -- `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. -- `@tanstack/ai-openai`: the dall-e option and size types. diff --git a/.changeset/responses-text-before-calls.md b/.changeset/responses-text-before-calls.md deleted file mode 100644 index fd7a0db46f..0000000000 --- a/.changeset/responses-text-before-calls.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/openai-base': patch ---- - -Responses replay no longer puts an assistant's text between a `function_call` and its `function_call_output`. The text now goes before the calls. DeepSeek rejected the old order with `No tool output found for function call`. diff --git a/.changeset/run-error-provider-details.md b/.changeset/run-error-provider-details.md deleted file mode 100644 index 6f88d237ec..0000000000 --- a/.changeset/run-error-provider-details.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@tanstack/ai': minor -'@tanstack/ai-anthropic': minor -'@tanstack/openai-base': minor ---- - -Put the provider error type and the request id on `RUN_ERROR`. The Anthropic adapter and the adapters built on `@tanstack/openai-base` set `errorType` (for example `overloaded_error`) and `requestId` (from the SDK error or the `request-id` / `x-request-id` header). `chat()` moves both to `metadata.tanstack`, so the client gets them too. `code` stays the HTTP status. Adapter authors can read both values with `toRunErrorDetails` from `@tanstack/ai/adapter-internals`. diff --git a/.changeset/sandbox-local-process-env.md b/.changeset/sandbox-local-process-env.md deleted file mode 100644 index ca17bde66c..0000000000 --- a/.changeset/sandbox-local-process-env.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@tanstack/ai-sandbox-local-process': minor ---- - -A command in `localProcessSandbox` gets only a few variables of the host process: `PATH`, `HOME`, `LANG`, `LC_ALL`, `TMPDIR`, `TEMP`, `TMP`, and on Windows `SystemRoot`, `ComSpec`, `PATHEXT`, `WINDIR`, and `USERPROFILE`. The workspace secrets and the env of the call still reach it. Provider keys and other secrets of the server do not. If a command needs another variable of the host, set it as a workspace secret or in the env of the call. `passEnv` names more variables of the host for each command, for example `HTTPS_PROXY` or `CLAUDE_CONFIG_DIR`. `scrubEnv` still removes a variable from the env of each command. diff --git a/.changeset/sync-models.md b/.changeset/sync-models.md deleted file mode 100644 index cf6ce271d7..0000000000 --- a/.changeset/sync-models.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -'@tanstack/ai-elevenlabs': patch -'@tanstack/ai-gemini': patch -'@tanstack/ai-llmgateway': patch -'@tanstack/ai-openrouter': patch -'@tanstack/ai-vercel-gateway': patch ---- - -Update model metadata from OpenRouter API diff --git a/.changeset/tau-core.md b/.changeset/tau-core.md deleted file mode 100644 index e9047ea2ce..0000000000 --- a/.changeset/tau-core.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -'@tanstack/ai': minor -'@tanstack/ai-compaction': minor -'@tanstack/ai-harness': minor -'@tanstack/ai-mcp': minor -'@tanstack/ai-persistence': minor -'@tanstack/ai-sandbox': minor ---- - -Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. - -Add the harness asks from the fifth findings list. - -- `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. -- `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. -- A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. -- Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. -- `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. -- A plugin `adapter()` pick with `override: true` wins over the stored thread model. -- `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. -- Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. -- `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. -- `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. -- `HarnessRecord` is exported, for a typed `LogStore` wrapper. -- Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. -- `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. - -Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. - -- `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model - turn, for example from a schedule or a webhook. The call goes through the - same middleware, input check, and `permissions()` rules as a model call, and - the call and its result join the transcript. A tool that asks for approval - stops the turn with an interrupt. While interrupts wait, the call is refused - with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom - event. `args` is typed from the input schema of a harness tool. -- `expose.tools` lists the harness tools a client may run with a - `{ op: 'tool', name, args?, meta? }` input, or with the new - `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness - `tools`, and `defineHarness` throws for a name that is not in `tools`. Any - other tool is refused with `not_exposed`. The capabilities document marks - each tool with `exposed`. -- `expose.records` lists the host record types a client may add with an - `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. - A record of another type, or with a `thread` field, is refused with - `not_exposed`. The session log keeps the records. -- `createHarnessMcpServer` adds a `tool_` tool for each tool in - `expose.tools`, and an `append` tool when `expose.records` has types. A tool - input with its own `threadId` field throws when the server is created, - because MCP uses `threadId` to pick the thread. -- `session.send(message, { systemPreamble })` prepends per-run, server-only - system prompts ahead of the harness's own system prompts (for example - host-provided memory). A client input cannot set them. -- A tool call in a harness turn gets `threadId` and `runId` in its execution - context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional - fields for a host to set. - -A host can add fields to the `ctx` an agent's `run` gets. - -- `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. -- `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. - -Add `interrupts` to `SubagentBinding`. - -- A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. -- The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. -- A child's `ctx.chat({ subagents })` passes the definitions on to its own children. -- A plain `chat()` call does not get them. - -Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. - -Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. - -An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. - -Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. - -Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. - -- It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. -- The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. -- Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. -- It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. -- The new `GuardToolCallDecision` type is exported. - -BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: - -- `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. -- `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. -- `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. -- `memoryCredentialStore()`: a store in memory, for development and tests. -- `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. -- `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. - -`CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. - -Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. - -`scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. - -`Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. - -Approved edits to tool arguments stay raw until the final input check. - -- `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. -- `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. - -A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. - -`chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. - -`WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. diff --git a/.changeset/v1-release.md b/.changeset/v1-release.md deleted file mode 100644 index 3fa6440d11..0000000000 --- a/.changeset/v1-release.md +++ /dev/null @@ -1,96 +0,0 @@ ---- -'@tanstack/ai-acp': major -'@tanstack/ai-angular': major -'@tanstack/ai-anthropic': major -'@tanstack/ai-bedrock': major -'@tanstack/ai-byteplus': major -'@tanstack/ai-claude-code': major -'@tanstack/ai-client': major -'@tanstack/ai-cloudflare': major -'@tanstack/ai-code-mode-snippets': major -'@tanstack/ai-code-mode': major -'@tanstack/ai-codex': major -'@tanstack/ai-cohere': major -'@tanstack/ai-compaction': major -'@tanstack/ai-computer-local': major -'@tanstack/ai-computer-playwright': major -'@tanstack/ai-computer-sandbox': major -'@tanstack/ai-computer-use': major -'@tanstack/ai-devtools-core': major -'@tanstack/ai-durable-stream': major -'@tanstack/ai-elevenlabs': major -'@tanstack/ai-event-client': major -'@tanstack/ai-fal': major -'@tanstack/ai-gemini': major -'@tanstack/ai-grok-build': major -'@tanstack/ai-grok': major -'@tanstack/ai-groq': major -'@tanstack/ai-isolate-cloudflare': major -'@tanstack/ai-isolate-daytona': major -'@tanstack/ai-isolate-e2b': major -'@tanstack/ai-isolate-node': major -'@tanstack/ai-isolate-quickjs-bun': major -'@tanstack/ai-isolate-quickjs': major -'@tanstack/ai-llmgateway': major -'@tanstack/ai-lovable': major -'@tanstack/ai-mcp': major -'@tanstack/ai-memory': major -'@tanstack/ai-mistral': major -'@tanstack/ai-octane': major -'@tanstack/ai-ollama': major -'@tanstack/ai-ollaya': major -'@tanstack/ai-openai': major -'@tanstack/ai-opencode': major -'@tanstack/ai-openrouter': major -'@tanstack/ai-perplexity': major -'@tanstack/ai-persistence': major -'@tanstack/ai-preact': major -'@tanstack/ai-react': major -'@tanstack/ai-reactor': major -'@tanstack/ai-remix': major -'@tanstack/ai-sandbox-blaxel': major -'@tanstack/ai-sandbox-boxd': major -'@tanstack/ai-sandbox-cloudflare': major -'@tanstack/ai-sandbox-daytona': major -'@tanstack/ai-sandbox-docker': major -'@tanstack/ai-sandbox-e2b': major -'@tanstack/ai-sandbox-local-process': major -'@tanstack/ai-sandbox-railway': major -'@tanstack/ai-sandbox-sprites': major -'@tanstack/ai-sandbox-upstash-box': major -'@tanstack/ai-sandbox-vercel': major -'@tanstack/ai-sandbox': major -'@tanstack/ai-skills': major -'@tanstack/ai-solid': major -'@tanstack/ai-svelte': major -'@tanstack/ai-typesafe': major -'@tanstack/ai-utils': major -'@tanstack/ai-vercel-gateway': major -'@tanstack/ai-vertex': major -'@tanstack/ai-vue': major -'@tanstack/ai-worldlabs': major -'@tanstack/ai': major -'@tanstack/openai-base': major -'@tanstack/preact-ai-devtools': major -'@tanstack/react-ai-devtools': major -'@tanstack/solid-ai-devtools': major -'@tanstack/svelte-ai-devtools': major ---- - -TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 - -- Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. -- Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. -- Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. -- Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. -- `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. -- The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. -- A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. -- `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. -- `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. -- `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. -- A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. -- `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. -- Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). -- Removed provider models that are shut down. -- `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. diff --git a/.changeset/vercel-gateway-usage-cost.md b/.changeset/vercel-gateway-usage-cost.md deleted file mode 100644 index e749979cc4..0000000000 --- a/.changeset/vercel-gateway-usage-cost.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@tanstack/ai-vercel-gateway': patch -'@tanstack/openai-base': patch ---- - -Surface Vercel AI Gateway request cost on `usage.cost`, with the market price in `usage.costDetails.upstreamCost`. diff --git a/examples/ag-ui/CHANGELOG.md b/examples/ag-ui/CHANGELOG.md index 5bef40703f..66ac48a13f 100644 --- a/examples/ag-ui/CHANGELOG.md +++ b/examples/ag-ui/CHANGELOG.md @@ -1,5 +1,13 @@ # ag-ui +## 0.0.41 + +### Patch Changes + +- Updated dependencies [[`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-client@1.0.0 + - @tanstack/ai-react@1.0.0 + ## 0.0.40 ### Patch Changes diff --git a/examples/ag-ui/package.json b/examples/ag-ui/package.json index 0481e15f98..50cb9909d4 100644 --- a/examples/ag-ui/package.json +++ b/examples/ag-ui/package.json @@ -2,7 +2,7 @@ "name": "ag-ui", "private": true, "type": "module", - "version": "0.0.40", + "version": "0.0.41", "scripts": { "detect-servers": "node scripts/detect-servers.mjs", "predev": "node scripts/detect-servers.mjs", diff --git a/packages/ai-acp/CHANGELOG.md b/packages/ai-acp/CHANGELOG.md index b7956d6e1c..c595a95636 100644 --- a/packages/ai-acp/CHANGELOG.md +++ b/packages/ai-acp/CHANGELOG.md @@ -1,5 +1,39 @@ # @tanstack/ai-acp +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `@tanstack/ai-acp/agent` adds `createAcpAgent` and `serveAcp`, which serve a harness as an ACP v2 agent (experimental, like the draft protocol). Each wait of a turn goes to the editor by its kind: an approval becomes a permission request (with `allow_always` only when the answer schema takes `always`), a question or a `human` wait becomes a form elicitation, and a sign-in becomes a URL elicitation, when the editor declares them in `initialize`. A wait that the editor cannot answer is cancelled. Cancel cancels the running turn, and image, audio, and embedded file blocks go to the media store of the session. A prompt takes its place in the queue before its media is saved, and gives the place back when the session is idle. `session/list` lists the sessions of the harness from the session index of the host. The `user` option is the user of the editor: each session opens as that user, and the list shows the sessions of that user. It is required on a host with `access`. The agent holds one session handle per ACP session. `session/close` releases it, and the close of the connection releases them all (a session whose prompt runs keeps its handle until that prompt ends), so the host closes each session on idle. `@tanstack/ai-acp` now uses `@agentclientprotocol/sdk` 1.8, pinned to `~1.8.0` because the agent uses its experimental v2 entry point. The existing ACP client adapters keep working. + + One agent app serves one connection, and reads the editor capabilities from that connection. A second connection gets a clear error. For more connections, make one app for each: `new AcpServer({ createAgent: () => createAcpAgent(options) })`. A session that the agent made or opened in its connection takes prompts after the agent released its handle, also on a host with no `stores.sessions`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + - @tanstack/ai-sandbox@1.0.0 + ## 0.3.27 ### Patch Changes diff --git a/packages/ai-acp/package.json b/packages/ai-acp/package.json index 7a5ae3fd99..3604832dd2 100644 --- a/packages/ai-acp/package.json +++ b/packages/ai-acp/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-acp", - "version": "0.3.27", + "version": "1.0.0", "description": "Shared Agent Client Protocol (ACP) transport, session, and AG-UI translation for TanStack AI harness adapters.", "author": "", "license": "MIT", diff --git a/packages/ai-angular/CHANGELOG.md b/packages/ai-angular/CHANGELOG.md index 4a8fda6058..4e609e0aae 100644 --- a/packages/ai-angular/CHANGELOG.md +++ b/packages/ai-angular/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-angular +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.14.1 ### Patch Changes diff --git a/packages/ai-angular/package.json b/packages/ai-angular/package.json index 8daada07ea..08aa0037d4 100644 --- a/packages/ai-angular/package.json +++ b/packages/ai-angular/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-angular", - "version": "0.14.1", + "version": "1.0.0", "description": "Angular signals integration for TanStack AI streaming chat, structured outputs, and media generation.", "author": "", "license": "MIT", diff --git a/packages/ai-anthropic/CHANGELOG.md b/packages/ai-anthropic/CHANGELOG.md index 5445c4c3d4..4cbcb20dbf 100644 --- a/packages/ai-anthropic/CHANGELOG.md +++ b/packages/ai-anthropic/CHANGELOG.md @@ -1,5 +1,73 @@ # @tanstack/ai-anthropic +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1835](https://github.com/TanStack/ai/pull/1835) [`ec9023e`](https://github.com/TanStack/ai/commit/ec9023e9be665fbd0ffea3e639280c2216edc16c) - Add the `fallbacks` model option for Anthropic server-side refusal fallback. Set `modelOptions: { fallbacks: 'default' }` on `claude-fable-5`, `claude-fable-5-1`, `claude-opus-5`, `claude-opus-5-5` or `claude-sonnet-5-5`. When a safety classifier declines the request, the API answers with another model in the same call. The adapter sends the `server-side-fallback-2026-07-01` beta header for you. + + A response with `stop_reason: "refusal"` now finishes with `finishReason: 'content_filter'`. Before, it finished with `'stop'`. The refusal `stop_details` (`category`, `explanation`) is on the `RUN_FINISHED` event as `rawEvent`. + +- [#1880](https://github.com/TanStack/ai/pull/1880) [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f) - Put the provider error type and the request id on `RUN_ERROR`. The Anthropic adapter and the adapters built on `@tanstack/openai-base` set `errorType` (for example `overloaded_error`) and `requestId` (from the SDK error or the `request-id` / `x-request-id` header). `chat()` moves both to `metadata.tanstack`, so the client gets them too. `code` stays the HTTP status. Adapter authors can read both values with `toRunErrorDetails` from `@tanstack/ai/adapter-internals`. + +### Patch Changes + +- [#1793](https://github.com/TanStack/ai/pull/1793) [`9f1bdd6`](https://github.com/TanStack/ai/commit/9f1bdd61b4df1d16c23a6ce300fa0424ab824d6a) - Report the input token usage when a streamed response fails after its first event. A dropped connection or an Anthropic `error` event in the stream ended in a `RUN_ERROR` with no `usage`. Anthropic bills the input tokens of that call, so this `RUN_ERROR` now carries the `usage` that `message_start` reported. The output count is the one from `message_start`, so it can be lower than the real output count. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.23.0 ### Minor Changes diff --git a/packages/ai-anthropic/package.json b/packages/ai-anthropic/package.json index aa79348862..2da0ae69e9 100644 --- a/packages/ai-anthropic/package.json +++ b/packages/ai-anthropic/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-anthropic", - "version": "0.23.0", + "version": "1.0.0", "description": "Anthropic Claude adapter for TanStack AI chat, tool calling, thinking, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-bedrock/CHANGELOG.md b/packages/ai-bedrock/CHANGELOG.md index c74e747141..d5b8b0c1fd 100644 --- a/packages/ai-bedrock/CHANGELOG.md +++ b/packages/ai-bedrock/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-bedrock +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.6.2 ### Patch Changes diff --git a/packages/ai-bedrock/package.json b/packages/ai-bedrock/package.json index d84efd371b..8a3969898d 100644 --- a/packages/ai-bedrock/package.json +++ b/packages/ai-bedrock/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-bedrock", - "version": "0.6.2", + "version": "1.0.0", "type": "module", "description": "Amazon Bedrock adapter for TanStack AI — OpenAI-compatible chat, responses, tools, and reasoning.", "author": "", diff --git a/packages/ai-byteplus/CHANGELOG.md b/packages/ai-byteplus/CHANGELOG.md index 13951dd01c..f350862da7 100644 --- a/packages/ai-byteplus/CHANGELOG.md +++ b/packages/ai-byteplus/CHANGELOG.md @@ -1,5 +1,33 @@ # @tanstack/ai-byteplus +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.7.2 ### Patch Changes diff --git a/packages/ai-byteplus/package.json b/packages/ai-byteplus/package.json index 7dd853019a..1dc5e8b6ff 100644 --- a/packages/ai-byteplus/package.json +++ b/packages/ai-byteplus/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-byteplus", - "version": "0.7.2", + "version": "1.0.0", "description": "BytePlus ModelArk adapter for TanStack AI: Seed LLM chat, Seedance video, Seedream image, and Seed Speech TTS/ASR.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-claude-code/CHANGELOG.md b/packages/ai-claude-code/CHANGELOG.md index e4eb58e043..7c3fb65a14 100644 --- a/packages/ai-claude-code/CHANGELOG.md +++ b/packages/ai-claude-code/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-claude-code +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-sandbox@1.0.0 + ## 0.9.2 ### Patch Changes diff --git a/packages/ai-claude-code/package.json b/packages/ai-claude-code/package.json index f94e0e7c34..40322efb55 100644 --- a/packages/ai-claude-code/package.json +++ b/packages/ai-claude-code/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-claude-code", - "version": "0.9.2", + "version": "1.0.0", "description": "Claude Code harness adapter for TanStack AI — run Claude Code as a chat backend with local tool execution and stateful sessions.", "author": "", "license": "MIT", diff --git a/packages/ai-client/CHANGELOG.md b/packages/ai-client/CHANGELOG.md index 198ba79276..cdd129e3df 100644 --- a/packages/ai-client/CHANGELOG.md +++ b/packages/ai-client/CHANGELOG.md @@ -1,5 +1,56 @@ # @tanstack/ai-client +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1881](https://github.com/TanStack/ai/pull/1881) [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787) - Reconnects of a durable run can ride out a server restart. The wait between reconnects now doubles from `initialDelayMs` (default 250) up to `maxDelayMs` (default 5000), with jitter. Set `budgetMs` to keep reconnecting for a total time instead of a fixed number of attempts. A reconnect answered 408, 429, 502, 503, or 504 is retried, and a `Retry-After` header sets the wait. `delayMs` still works as the old name of `initialDelayMs`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/ai-event-client@1.0.0 + ## 0.40.1 ### Patch Changes diff --git a/packages/ai-client/package.json b/packages/ai-client/package.json index 39608a00ab..95b5331547 100644 --- a/packages/ai-client/package.json +++ b/packages/ai-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-client", - "version": "0.40.1", + "version": "1.0.0", "description": "Framework-agnostic headless client for TanStack AI chat, realtime sessions, streaming transports, and media generations.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-cloudflare/CHANGELOG.md b/packages/ai-cloudflare/CHANGELOG.md index 22bfb434c1..1ae7bd3a19 100644 --- a/packages/ai-cloudflare/CHANGELOG.md +++ b/packages/ai-cloudflare/CHANGELOG.md @@ -1,5 +1,56 @@ # @tanstack/ai-cloudflare +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1568](https://github.com/TanStack/ai/pull/1568) [`56edf43`](https://github.com/TanStack/ai/commit/56edf43c94a926566591e20c5739680eacb1515d) - Add `defaultHeaders` to the binding config. Every binding run sends them as the Workers AI `extraHeaders` option, next to `gateway`, so you can set `x-session-affinity` for prompt caching when you use `{ binding: env.AI }`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.3.2 ### Patch Changes diff --git a/packages/ai-cloudflare/package.json b/packages/ai-cloudflare/package.json index bb49f5680a..c197987cfe 100644 --- a/packages/ai-cloudflare/package.json +++ b/packages/ai-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-cloudflare", - "version": "0.3.2", + "version": "1.0.0", "description": "Cloudflare adapter for TanStack AI — Workers AI chat, embeddings, images, speech, transcription, and summarization over the AI binding or REST, with AI Gateway routing for any provider.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-code-mode-snippets/CHANGELOG.md b/packages/ai-code-mode-snippets/CHANGELOG.md index 9621360849..8c6c32639b 100644 --- a/packages/ai-code-mode-snippets/CHANGELOG.md +++ b/packages/ai-code-mode-snippets/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-code-mode-snippets +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-code-mode@1.0.0 + ## 0.4.27 ### Patch Changes diff --git a/packages/ai-code-mode-snippets/package.json b/packages/ai-code-mode-snippets/package.json index 684bc85ad8..5d4ff5098b 100644 --- a/packages/ai-code-mode-snippets/package.json +++ b/packages/ai-code-mode-snippets/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-code-mode-snippets", - "version": "0.4.27", + "version": "1.0.0", "description": "Persistent runtime snippet library for TanStack AI Code Mode agents and sandboxed tool orchestration.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-code-mode/CHANGELOG.md b/packages/ai-code-mode/CHANGELOG.md index b6cd83f612..a0866ccc58 100644 --- a/packages/ai-code-mode/CHANGELOG.md +++ b/packages/ai-code-mode/CHANGELOG.md @@ -1,5 +1,48 @@ # @tanstack/ai-code-mode +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `@tanstack/ai-code-mode/harness` with `codeMode({ driver })`: a harness plugin that gives the model one `execute_typescript` tool. The model writes a program that calls several tools, and the program runs in the isolate of any `@tanstack/ai-isolate-*` driver. + - By default, only tools that are safe to run without a question move into code mode. These are server tools with no `needsApproval` and no permission resources, which the permission rules allow in plan mode. A safe tool with `metadata.codeMode: true` always moves. + - `include` picks more tools, also tools with permission checks, such as the coding tools `read_file`, `write_file`, `edit_file`, `patch`, `list_files`, `grep`, `bash`, and `webfetch`. Each call of such a tool in a program gets the same decision from `permissions()` as a direct call. The call runs, or it throws an error with the reason, or the program waits for the user to approve it. The approval is a question wait that `session.answer` answers with `once`, `always`, or `reject`. A program that can wait gets a timeout of 10 minutes by default. + - The session log keeps the result of each checked call. After a stop, the next host runs the program again, and a call that finished before the stop does not run twice. A call that the stop cut, and that is not safe to run again, throws in the program. + - `include` never moves a tool that needs approval, or a tool that the rules deny in the current permission mode. The rules decide again at each turn, so in plan mode the tools that edit stay normal tool calls. + - `directCalls: 'keep'` keeps the moved tools in the model's tool list too. The session setting `directCalls` changes it while the session runs. + - `lazy: true` lists only the tool names and adds `discover_tools`. A tool name that is not a JavaScript identifier gets a safe name inside the program. + + `@tanstack/ai-harness` is an optional peer dependency. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - The `execute_typescript` tool description and the code-mode system prompt now tell the model that the tool returns `{ success, result, logs, error }`, where `result` is the value its code returned. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - The `mcp()`, `codeMode()`, and `skills()` harness plugins send their warnings to the logger of the host (`createHarnessHost({ logger })`). + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + ## 0.5.5 ### Patch Changes diff --git a/packages/ai-code-mode/package.json b/packages/ai-code-mode/package.json index 8c66f5d221..2f7a8186a6 100644 --- a/packages/ai-code-mode/package.json +++ b/packages/ai-code-mode/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-code-mode", - "version": "0.5.5", + "version": "1.0.0", "description": "Secure TypeScript Code Mode for TanStack AI agents to execute sandboxed tool orchestration programs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-codex/CHANGELOG.md b/packages/ai-codex/CHANGELOG.md index 280bba119a..8ff8220f1a 100644 --- a/packages/ai-codex/CHANGELOG.md +++ b/packages/ai-codex/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-codex +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-sandbox@1.0.0 + ## 0.6.2 ### Patch Changes diff --git a/packages/ai-codex/package.json b/packages/ai-codex/package.json index 029c505e5f..5d747d059d 100644 --- a/packages/ai-codex/package.json +++ b/packages/ai-codex/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-codex", - "version": "0.6.2", + "version": "1.0.0", "description": "Codex harness adapter for TanStack AI — run OpenAI Codex as a chat backend with local tool execution and stateful sessions.", "author": "", "license": "MIT", diff --git a/packages/ai-cohere/CHANGELOG.md b/packages/ai-cohere/CHANGELOG.md index 850f1591d5..835b8539dd 100644 --- a/packages/ai-cohere/CHANGELOG.md +++ b/packages/ai-cohere/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-cohere +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.4.19 ### Patch Changes diff --git a/packages/ai-cohere/package.json b/packages/ai-cohere/package.json index 79efeaed77..b15445e8d1 100644 --- a/packages/ai-cohere/package.json +++ b/packages/ai-cohere/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-cohere", - "version": "0.4.19", + "version": "1.0.0", "description": "Cohere adapter for TanStack AI — multimodal embeddings and document reranking.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-compaction/CHANGELOG.md b/packages/ai-compaction/CHANGELOG.md index aa8c650d5d..64c8c1554a 100644 --- a/packages/ai-compaction/CHANGELOG.md +++ b/packages/ai-compaction/CHANGELOG.md @@ -1,5 +1,149 @@ # @tanstack/ai-compaction +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1883](https://github.com/TanStack/ai/pull/1883) [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3) - Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. + + Add the harness asks from the fifth findings list. + - `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. + - `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. + - A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. + - Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. + - `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. + - A plugin `adapter()` pick with `override: true` wins over the stored thread model. + - `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. + - Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. + - `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. + - `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. + - `HarnessRecord` is exported, for a typed `LogStore` wrapper. + - Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. + - `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. + + Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. + - `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model + turn, for example from a schedule or a webhook. The call goes through the + same middleware, input check, and `permissions()` rules as a model call, and + the call and its result join the transcript. A tool that asks for approval + stops the turn with an interrupt. While interrupts wait, the call is refused + with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom + event. `args` is typed from the input schema of a harness tool. + - `expose.tools` lists the harness tools a client may run with a + `{ op: 'tool', name, args?, meta? }` input, or with the new + `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness + `tools`, and `defineHarness` throws for a name that is not in `tools`. Any + other tool is refused with `not_exposed`. The capabilities document marks + each tool with `exposed`. + - `expose.records` lists the host record types a client may add with an + `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. + A record of another type, or with a `thread` field, is refused with + `not_exposed`. The session log keeps the records. + - `createHarnessMcpServer` adds a `tool_` tool for each tool in + `expose.tools`, and an `append` tool when `expose.records` has types. A tool + input with its own `threadId` field throws when the server is created, + because MCP uses `threadId` to pick the thread. + - `session.send(message, { systemPreamble })` prepends per-run, server-only + system prompts ahead of the harness's own system prompts (for example + host-provided memory). A client input cannot set them. + - A tool call in a harness turn gets `threadId` and `runId` in its execution + context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional + fields for a host to set. + + A host can add fields to the `ctx` an agent's `run` gets. + - `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. + - `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. + + Add `interrupts` to `SubagentBinding`. + - A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. + - The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. + - A child's `ctx.chat({ subagents })` passes the definitions on to its own children. + - A plain `chat()` call does not get them. + + Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. + + Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. + + An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. + + Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. + + Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. + - It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. + - The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. + - Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. + - It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. + - The new `GuardToolCallDecision` type is exported. + + BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: + - `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. + - `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. + - `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. + - `memoryCredentialStore()`: a store in memory, for development and tests. + - `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. + - `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. + + `CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. + + Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. + + `scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. + + `Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. + + Approved edits to tool arguments stay raw until the final input check. + - `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. + - `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. + + A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. + + `chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. + + `WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + ## 0.3.1 ### Patch Changes diff --git a/packages/ai-compaction/package.json b/packages/ai-compaction/package.json index 5421f30476..d1c5150fd6 100644 --- a/packages/ai-compaction/package.json +++ b/packages/ai-compaction/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-compaction", - "version": "0.3.1", + "version": "1.0.0", "description": "Context-window compaction middleware for TanStack AI chat()", "author": "", "license": "MIT", diff --git a/packages/ai-computer-local/CHANGELOG.md b/packages/ai-computer-local/CHANGELOG.md index 3ed198c6fa..87e7dc2269 100644 --- a/packages/ai-computer-local/CHANGELOG.md +++ b/packages/ai-computer-local/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-computer-local +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-computer-use@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/ai-computer-local/package.json b/packages/ai-computer-local/package.json index ac973f70b5..61f5fd62bb 100644 --- a/packages/ai-computer-local/package.json +++ b/packages/ai-computer-local/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-computer-local", - "version": "0.1.0", + "version": "1.0.0", "description": "Local computer driver for TanStack AI computer use. The model controls the mouse, keyboard, and screen of the machine that runs the server.", "author": "", "license": "MIT", diff --git a/packages/ai-computer-playwright/CHANGELOG.md b/packages/ai-computer-playwright/CHANGELOG.md index e7f5fe093b..317b863361 100644 --- a/packages/ai-computer-playwright/CHANGELOG.md +++ b/packages/ai-computer-playwright/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-computer-playwright +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-computer-use@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/ai-computer-playwright/package.json b/packages/ai-computer-playwright/package.json index 8d58c9f421..da71044635 100644 --- a/packages/ai-computer-playwright/package.json +++ b/packages/ai-computer-playwright/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-computer-playwright", - "version": "0.1.0", + "version": "1.0.0", "description": "Playwright browser driver for TanStack AI computer use.", "author": "", "license": "MIT", diff --git a/packages/ai-computer-sandbox/CHANGELOG.md b/packages/ai-computer-sandbox/CHANGELOG.md index a8547a4c22..4d3889438e 100644 --- a/packages/ai-computer-sandbox/CHANGELOG.md +++ b/packages/ai-computer-sandbox/CHANGELOG.md @@ -1,5 +1,33 @@ # @tanstack/ai-computer-sandbox +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/ai-computer-use@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/ai-computer-sandbox/package.json b/packages/ai-computer-sandbox/package.json index d3764fdeab..8d83ac39c5 100644 --- a/packages/ai-computer-sandbox/package.json +++ b/packages/ai-computer-sandbox/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-computer-sandbox", - "version": "0.1.0", + "version": "1.0.0", "description": "Sandbox desktop driver for TanStack AI computer use. Works with any @tanstack/ai-sandbox provider.", "author": "", "license": "MIT", diff --git a/packages/ai-computer-use/CHANGELOG.md b/packages/ai-computer-use/CHANGELOG.md index 19c4a6d87d..641c7e96de 100644 --- a/packages/ai-computer-use/CHANGELOG.md +++ b/packages/ai-computer-use/CHANGELOG.md @@ -1,5 +1,45 @@ # @tanstack/ai-computer-use +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `computerUse()` in `@tanstack/ai-computer-use/harness`: computer use as a harness plugin. + - Each screenshot goes to the media store of the session. The transcript and the log keep a small `harness-media:` reference. + - The model gets only the newest `keepScreenshots` screenshots (3 by default). An older one goes to the model as a 1x1 image. + - A call with OpenAI safety checks asks the user through `permissions()`, each time. Without `permissions()`, the call is refused. + - The `plan` mode of `permissions()` refuses the `computer` tool. + + `@tanstack/ai-harness` is an optional peer dependency of `@tanstack/ai-computer-use`. + + A plugin can now store a file with `ctx.session.putMedia(upload)`, and put `mediaPart(record)` in a tool result. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + - @tanstack/ai-utils@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/ai-computer-use/package.json b/packages/ai-computer-use/package.json index 5310f9b821..e620311ddc 100644 --- a/packages/ai-computer-use/package.json +++ b/packages/ai-computer-use/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-computer-use", - "version": "0.1.0", + "version": "1.0.0", "description": "Provider-agnostic computer use for TanStack AI.", "author": "", "license": "MIT", diff --git a/packages/ai-devtools/CHANGELOG.md b/packages/ai-devtools/CHANGELOG.md index a2dd662ebf..2d74d61d89 100644 --- a/packages/ai-devtools/CHANGELOG.md +++ b/packages/ai-devtools/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-devtools-core +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-event-client@1.0.0 + ## 0.5.30 ### Patch Changes diff --git a/packages/ai-devtools/package.json b/packages/ai-devtools/package.json index 06bb2f0133..bda02517d2 100644 --- a/packages/ai-devtools/package.json +++ b/packages/ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-devtools-core", - "version": "0.5.30", + "version": "1.0.0", "description": "Core TanStack AI Devtools plugin for inspecting chat messages, tool calls, streams, and errors.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-durable-stream/CHANGELOG.md b/packages/ai-durable-stream/CHANGELOG.md index 68387b3eb9..b3b3167ed3 100644 --- a/packages/ai-durable-stream/CHANGELOG.md +++ b/packages/ai-durable-stream/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-durable-stream +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + ## 0.1.29 ### Patch Changes diff --git a/packages/ai-durable-stream/package.json b/packages/ai-durable-stream/package.json index f06d340cde..5805979f05 100644 --- a/packages/ai-durable-stream/package.json +++ b/packages/ai-durable-stream/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-durable-stream", - "version": "0.1.29", + "version": "1.0.0", "description": "Delivery durability for TanStack AI over the durable-streams HTTP protocol — a resumable StreamDurability transport sink (append/read/resume) that stores zero delivery events itself.", "author": "", "license": "MIT", diff --git a/packages/ai-elevenlabs/CHANGELOG.md b/packages/ai-elevenlabs/CHANGELOG.md index 397f32e54e..c5b6cba698 100644 --- a/packages/ai-elevenlabs/CHANGELOG.md +++ b/packages/ai-elevenlabs/CHANGELOG.md @@ -1,5 +1,36 @@ # @tanstack/ai-elevenlabs +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - The audio adapter accepts `eleven_text_to_sound_v3`, a sound model that the ElevenLabs SDK types do not list yet. + +- [#1882](https://github.com/TanStack/ai/pull/1882) [`456bdc4`](https://github.com/TanStack/ai/commit/456bdc4fa5dba2d01889d5073ffe2c418078ea07) - Update model metadata from OpenRouter API + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.6.14 ### Patch Changes diff --git a/packages/ai-elevenlabs/package.json b/packages/ai-elevenlabs/package.json index 2785454af2..9e3bd78b2c 100644 --- a/packages/ai-elevenlabs/package.json +++ b/packages/ai-elevenlabs/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-elevenlabs", - "version": "0.6.14", + "version": "1.0.0", "description": "ElevenLabs adapter for TanStack AI realtime voice, text-to-speech, transcription, music, and sound effects.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-event-client/CHANGELOG.md b/packages/ai-event-client/CHANGELOG.md index 9a98455cc1..1580b40f99 100644 --- a/packages/ai-event-client/CHANGELOG.md +++ b/packages/ai-event-client/CHANGELOG.md @@ -1,5 +1,47 @@ # @tanstack/ai-event-client +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + ## 0.13.1 ### Patch Changes diff --git a/packages/ai-event-client/package.json b/packages/ai-event-client/package.json index cc2f9b0ebe..41ca9d411b 100644 --- a/packages/ai-event-client/package.json +++ b/packages/ai-event-client/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-event-client", - "version": "0.13.1", + "version": "1.0.0", "description": "Typed event client for TanStack AI devtools, observability, and streamed runtime events.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-fal/CHANGELOG.md b/packages/ai-fal/CHANGELOG.md index 29ffba633d..4fc147daaa 100644 --- a/packages/ai-fal/CHANGELOG.md +++ b/packages/ai-fal/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-fal +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.16.6 ### Patch Changes diff --git a/packages/ai-fal/package.json b/packages/ai-fal/package.json index 409150cdab..92b3ba3ec2 100644 --- a/packages/ai-fal/package.json +++ b/packages/ai-fal/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-fal", - "version": "0.16.6", + "version": "1.0.0", "description": "fal.ai adapter for TanStack AI image, video, live, audio, speech, and transcription generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-gemini/CHANGELOG.md b/packages/ai-gemini/CHANGELOG.md index 51a2f71b65..9c0aee095c 100644 --- a/packages/ai-gemini/CHANGELOG.md +++ b/packages/ai-gemini/CHANGELOG.md @@ -1,5 +1,46 @@ # @tanstack/ai-gemini +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- [#1882](https://github.com/TanStack/ai/pull/1882) [`456bdc4`](https://github.com/TanStack/ai/commit/456bdc4fa5dba2d01889d5073ffe2c418078ea07) - Update model metadata from OpenRouter API + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.38.2 ### Patch Changes diff --git a/packages/ai-gemini/package.json b/packages/ai-gemini/package.json index c6974937fe..3fdf580a7c 100644 --- a/packages/ai-gemini/package.json +++ b/packages/ai-gemini/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-gemini", - "version": "0.38.2", + "version": "1.0.0", "description": "Google Gemini adapter for TanStack AI chat, images, speech, audio generation, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-grok-build/CHANGELOG.md b/packages/ai-grok-build/CHANGELOG.md index 8363c732f3..10b5390752 100644 --- a/packages/ai-grok-build/CHANGELOG.md +++ b/packages/ai-grok-build/CHANGELOG.md @@ -1,5 +1,33 @@ # @tanstack/ai-grok-build +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-sandbox@1.0.0 + - @tanstack/ai-acp@1.0.0 + ## 0.5.22 ### Patch Changes diff --git a/packages/ai-grok-build/package.json b/packages/ai-grok-build/package.json index 1acd71305e..009684820a 100644 --- a/packages/ai-grok-build/package.json +++ b/packages/ai-grok-build/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-grok-build", - "version": "0.5.22", + "version": "1.0.0", "description": "Grok Build harness adapter for TanStack AI — run Grok Build as a chat backend with local tool execution and stateful sessions.", "author": "", "license": "MIT", diff --git a/packages/ai-grok/CHANGELOG.md b/packages/ai-grok/CHANGELOG.md index 77881ac795..77f281a3c0 100644 --- a/packages/ai-grok/CHANGELOG.md +++ b/packages/ai-grok/CHANGELOG.md @@ -1,5 +1,33 @@ # @tanstack/ai-grok +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.22.2 ### Patch Changes diff --git a/packages/ai-grok/package.json b/packages/ai-grok/package.json index 87701a07b5..dd1ebef36a 100644 --- a/packages/ai-grok/package.json +++ b/packages/ai-grok/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-grok", - "version": "0.22.2", + "version": "1.0.0", "description": "xAI Grok adapter for TanStack AI chat, image generation, realtime, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-groq/CHANGELOG.md b/packages/ai-groq/CHANGELOG.md index 3a36e7b660..13c4b593bc 100644 --- a/packages/ai-groq/CHANGELOG.md +++ b/packages/ai-groq/CHANGELOG.md @@ -1,5 +1,45 @@ # @tanstack/ai-groq +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.10.1 ### Patch Changes diff --git a/packages/ai-groq/package.json b/packages/ai-groq/package.json index 2e25d80ab0..e793ccc034 100644 --- a/packages/ai-groq/package.json +++ b/packages/ai-groq/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-groq", - "version": "0.10.1", + "version": "1.0.0", "description": "Groq adapter for TanStack AI low-latency chat, tool calling, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-harness-cli/CHANGELOG.md b/packages/ai-harness-cli/CHANGELOG.md new file mode 100644 index 0000000000..de89a4f51a --- /dev/null +++ b/packages/ai-harness-cli/CHANGELOG.md @@ -0,0 +1,23 @@ +# @tanstack/ai-harness-cli + +## 0.1.0 + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `@tanstack/ai-harness-cli`: `runCli(harness)` runs a harness from the terminal. + - Line mode reads one message or `/command` per line, hides a secret answer while the user types, and sends `@path` files. In a terminal, `/cancel` and a message typed while a turn runs act at once: the message joins the running turn. When a turn waits, each next line answers one wait: `y` or `n` for an approval (`once`, `always`, or `reject` for an approval of `permissions()`), and an answer read with the schema for a question. Pass `ui` to show your own screen on a session view instead. + - `-p "prompt"` runs one prompt for scripts and CI, and `--output ndjson` prints every AG-UI event. `-p` exits with code 3 (`EXIT.needsAction`) at the first wait of the turn: an approval, a question, or a sign-in. + - `--serve` serves the session protocol over HTTP behind a bearer token. It signs media URLs with its own key, never with the token: `--media-key` or `HARNESS_MEDIA_KEY` (at least 32 bytes), or a new random key at each start. Without a set key, signed media URLs stop working after a restart. On a host without `access`, it also passes `openAccess`: the `user` of `runCli`, or `true` without one. So each request with the token runs as the user of the CLI. + - `--acp` and `--mcp` load `@tanstack/ai-acp` and `@tanstack/ai-mcp` only when you use the flag. A missing package, or one without harness support, fails that flag with a clear message. Any other error while the package loads is reported, not hidden. + - In every mode, the first SIGINT or SIGTERM cancels the running turn. A second one, or one while no turn runs, stops the CLI, and `runCli` resolves to 130 (SIGINT) or 143 (SIGTERM). The CLI closes a host that it made with `recoverable: true`, or releases its session handle on your own host and does not wait for a turn that ignores the cancel. The `signals` option takes another signal source, for example an `EventEmitter` in a test. + - `host` and `user` options let the CLI use your durable host and run as your user. Every mode opens its sessions as that user. On a host with `access`, `--serve` reads the user of each request with `getUser`, and `--mcp` does not start, because stdio has no login. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `createHarnessHost({ credentials })` takes the `CredentialStore` (from `@tanstack/ai/byok`) where users' API keys and OAuth sign-ins are saved. Without it, credentials stay in memory until the process stops. `runCli` takes the same `credentials` option. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`e3b2885`](https://github.com/TanStack/ai/commit/e3b28853f7aed75389ef48fcabedaf9286d478bc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`d980ce1`](https://github.com/TanStack/ai/commit/d980ce153371404d71b6d4ceac37b0c8293df1d8), [`52cb02d`](https://github.com/TanStack/ai/commit/52cb02de60a9b6df8ed5ced4fe07f4321a8d4c9c), [`a99204a`](https://github.com/TanStack/ai/commit/a99204a08178cc47bdeb5053793c20123aa3d106), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`3e84606`](https://github.com/TanStack/ai/commit/3e84606afb2d0550520d3f2a4cb8ea88b0a9cdf8), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + - @tanstack/ai-mcp@1.0.0 + - @tanstack/ai-acp@1.0.0 diff --git a/packages/ai-harness-cli/package.json b/packages/ai-harness-cli/package.json index 76c4920ab6..799358abca 100644 --- a/packages/ai-harness-cli/package.json +++ b/packages/ai-harness-cli/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-harness-cli", - "version": "0.0.0", + "version": "0.1.0", "description": "Run a TanStack AI harness from the terminal: line mode or your own screen, print mode, NDJSON, ACP, MCP, and an HTTP server", "author": "", "license": "MIT", diff --git a/packages/ai-harness/CHANGELOG.md b/packages/ai-harness/CHANGELOG.md new file mode 100644 index 0000000000..7f87f5473e --- /dev/null +++ b/packages/ai-harness/CHANGELOG.md @@ -0,0 +1,299 @@ +# @tanstack/ai-harness + +## 0.1.0 + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `@tanstack/ai-harness`: build an agent harness on TanStack AI. A harness keeps one conversation open across many turns. + - `defineHarness()` names an agent: its adapter, tools, system prompts, middleware, agents, subagents, routing, plugins, turn hooks, and durability options. + - `createHarnessHost()` opens sessions. Each `host.open` gives its own handle to the live session of the thread. `session.close()`, or `await using`, releases the handle. A dropped handle is released by the garbage collector, with one warning. After `close()`, each call on the handle throws. When the session closes under a handle that is not released (its log failed, or a delete ran), the next call on the handle opens it again. + - `lifecycle` on `createHarnessHost()` sets how sessions live. A session that no handle holds closes after it was idle for `closeIdleSessionsAfterMs` (default 60 000). `maxOpenSessions` (default 500) first closes the least recently used idle sessions. A session is not idle while a background job of this host runs. `retention` (`keepSettledOperations`, `keepSettledAgentRuns`, `maxEventBytesInMemory`) bounds the settled operations, agent runs, receipts, events, and log tail that each session keeps in memory. The log keeps the `MESSAGES_SNAPSHOT` that core sends when a run pauses at an interrupt, so a rejoin from the log rebuilds the paused run. `host.close({ recoverable })` stops the work of every session and refuses later opens. With `recoverable: true`, the host gives each log that has work back with a wake, so a worker takes it at once. + - `host.observe(harness, { threadId, user })` reads a thread with no session: its events, transcript, snapshot, media, usage, and entry. It sets up no plugins, writes nothing, and never takes the log, so a read works while another host owns the thread. Its snapshot follows the same rules as `session.snapshot()`, without what only an open session knows (a running turn, operations, queues). `view.logState()` reads the `durability.logState` fold. + - `host.sessions.delete` closes the sessions of a thread and of its child threads. Then it deletes the log of the session tree (with the settings, config, plugin state, interrupted turn, runs, interrupts, usage, revert data, and the inputs that wait), the index entries, the uploaded media, and the generated artifacts. The first-party plugins also end the thread: `workspaceTools()` closes an owned sandbox with `'closed'`, and `snapshots()` removes the shadow repository. This needs the index entry, and the harness on that host: a host that opened it, or one with it in the `harnesses` option of `createHarnessHost()`. Else the host warns. A child thread is ended in the log of its root. While the delete runs, an open of the thread throws. With `access`, a thread with no index entry throws `AccessDeniedError`. + - A session takes `send` (a prompt, a steer into the running turn, a follow-up, or a message to an agent run with `to`), `continueWithoutMessage`, `reset`, `resolve`, `cancel`, and `moveToolCallToBackground` inputs. Each returns an operation with a receipt, and the session streams typed events. `host.isOpen(harness, { threadId })` says whether this host holds that session open. + - The session methods take one object: `cancelInput({ inputId, user? })`, `revert({ messageId, user? })`, `background({ toolCallId?, user? })`, `getMedia({ id })`, `mediaUrl({ id })`, and `agentTranscript({ subagentRunId })` or `agentTranscript({ runId })`. `AgentRun.subagentRunId` and `AgentRunInfo.subagentRunId` name the child id of an agent run, so the transcript of a run that code or a background call starts is found too. + - `session.appendRecords({ records, inputId?, user? })` returns a `Receipt`. A second append with the same `inputId` writes nothing. Without `inputId`, the append gets a new input id, and the log keeps it as an input. The `harness.revert` record keeps the user of `revert`, and the `harness.job` record keeps the user of `background`. + - `createHarnessHost({ access })` decides who can use each session. `getUser({ request })` reads the user of a request, and `isAllowed({ user, action, session, run })` decides each action. The user type comes from what `getUser` returns. The host keeps each tenant apart, needs a `user` on each call, and `host.open` returns a handle that acts only as its user. A refused action throws `AccessDeniedError`. The operations and the agent runs that a handle returns check access too. A child thread is checked through its root, also on `host.open`, so a stranger does not learn its root. When one user answers the turn of another user, the rest of the turn runs as the user who sent it. Without `access`, one user runs the host, with no checks. With `access`, keyed adapters and provider keys read env vars only when `access.allowServerEnvKeys` is `true`. + - `membersOnly()` gives ready access rules with the roles owner, member, operator, and viewer. `access` is `{ getUser, rules, getGuestUser?, allowServerEnvKeys? }`, and `membersOnly()` returns rules: `{ getUser, rules: membersOnly() }`. Rules are `{ isAllowed, filterSessionList?, members? }`: `filterSessionList` is the store filter of `host.sessions.list`, and `members` turns on `host.sessions.share` and `unshare` (`members.fork` sets the members of a fork). Your own rules are `rules: { isAllowed }`. `host.sessions.share` and `host.sessions.unshare` change the members, and `host.sessions.fork` takes `members: 'self' | 'all'`. The owner is the member with the role `owner`. For apps with their own access tables, `host.revoke` takes the access of a user to a thread, and returns a `Promise`. `host.revoke` and `unshare` cancel the running and queued work of the user on every host, and remove the schedules of the user at once. When that work cannot be stopped, they reject, and the access is gone already. A running `events()` read of a handle or a view ends with `AccessDeniedError`, and later view calls throw. `host.getUserOfRequest` reads the user of a request for your own routes. Each `host.sessions` method takes one object. + - A user with a `tenantId` keeps its sessions in its tenant: one thread id in two tenants is two sessions, with two index entries and two logs. `logIdOf({ tenantId, logId })` gives the id of a log in the store. + - Every run has a run context with its user, and that user's credentials and provider keys: `ctx.context.run` in tools and middleware (type them with `HarnessRunContext`), `ctx.turn.run` in a turn plugin, and `run` in a command. The `ctx.credentials` and `ctx.keys` of a session plugin have no user, so each call throws. `ctx.agents.start(agent, input, { user })` starts an agent for a user. `AgentRun.send` takes `user?`, and the `send` and `cancel` of a run act as the user of the run. `session.agents..run` honors `user`. The log keeps the sender of every input. The run context also has `epoch`, the ownership epoch of the log, and `idempotencyKey(step, scope?)`, a key for one side effect that is the same when the run runs again on any host. + - `definePlugin()` adds tools, prompts, middleware, agents, commands, config options, state, and extension points to a session or to one turn. With `lifetime: 'host'`, the host sets a plugin object up once per harness and shares it with every session that uses the same object. It is cleaned up when the last session that uses it closes, or at `host.close()`. A prompt with `placement: 'context'` goes in one system prompt after all the others, made again at each model call, so text that changes often (the todo list, the goal status, plan mode) leaves the system prompts before it in the provider prompt cache. The default `placement: 'system'` keeps a prompt in the system prompts. `prepareTools` gets `run`. `onTurnStart(turn)` runs once at the start of each turn, before the prompts, so a plugin can refresh the state that its prompts read. A plugin's `ctx.session.send` and `note` take `user?`, and default to the session owner. A thread that removes a plugin cannot run the agents of that plugin by name. + - `routing.router` sends a turn to a root agent. The log keeps the active agent, and the router reads it as `activeAgent`. A router that returns `undefined` gives the turn to the active agent, else to the main model. One agent name makes that agent active, `'main'` clears it, and `{ handoff, note }` is a handoff from the router. `routing.afterAgentsAnswer: 'end-turn' | 'main-answers'` (default `'end-turn'`) says whether the main model answers after the routed agents. + - Handoffs move a conversation to another root agent, and the target answers in the same turn. With `routing`, the main model and each root agent get a `handoff` tool. Code hands off with `ctx.harness.handoff({ to, note })` in a root agent, and with `ctx.context.run.handoff(...)` (`RunContext.handoff`) in a tool of the main model. Each handoff writes a `harness.handoff` record and streams a `harness.handoff` event (`from`, `to`, `note`, `by`, `runId`). A message that an agent writes has `metadata.harness.agent`. A turn hands off 10 times at most. An app tool named `handoff` fails the turn. `routing.giveModelsHandoffTool: false` gives no model the `handoff` tool, and the router and code can still hand off. A handoff stops only the chat that made it. When the part that handed off also stops for interrupts, the resolve turn runs the target (or pauses for a person). The router writes a handoff to the main model once when the active agent is gone. A handoff from the router or from code adds a `handoff` tool call and its result to the transcript before the target answers, so the target sees why it got the conversation. With `routing.giveModelsHandoffTool: false`, it adds one assistant note. + - With `routing.allowHandoffToHuman: true`, a handoff to `{ human: true }` opens a `human` wait with no default expiry, and the turn ends `interrupted`. User messages during the pause go in the transcript, and no model answers them. `session.send(text, { as: 'operator' })` adds an operator reply. It needs the `operator` access action, and it is rejected with `no_human_wait` when no handoff to a person is open. The operator ends the pause with an answer to the `human` wait: `{ resume: true }` or `{ handBack: '' | 'main' }`, also to a root agent of a turn plugin. When the `human` wait ends in any other way (a resolve, a cancel, an expiry), the agent from before the handoff answers again. An operator reply with files keeps its text in the assistant message, and the files in a user message after it with `metadata.harness.operatorAttachment`. A view shows the files with the reply, live and after a reload. + - `host.transfer({ from, to, envelope, user, transferId })` moves a conversation to another thread, also of another harness, in the same tenant. Only the envelope moves: a note, then no message, a summary that the source model writes, or the settled transcript with its media. The user needs `transfer` on the source and `send` on a target that exists. A new target has the user as its only owner. Both logs get a `harness.transferred` record, the index entries link the threads in `metadata`, `host.events()` yields a `transferred` event, and a retry with the same `transferId` is safe. A source thread that does not exist throws. A fork stays in its harness: `host.fork` with a thread of another harness throws. + - Agents run from code with `session.agents..run()` and `.start()`. `agentRun.receipt` resolves. In agent code, `ctx.harness` gives `step.do()` (a finished step returns its stored value when the run runs again), `step.sleep({ name, ms })`, `agents`, `state`, and `handoff` (in a root agent). `ctx.harness` is optional: a run that a plain `chat()` starts has none. + - `ctx.harness.agents` in agent code and `ctx.agents` in a plugin have one type, `AgentActions`: `start(agent, input, options?)`, `run(agent, input, options?)`, and `group({ concurrency, onFailure, key }, (g) => [g.start(...)])`. The input type comes from the input schema of the agent, and the result type from its output. `group` resolves to the results in order. With `onFailure: 'collect'`, each entry is an `AgentSettled` (`{ ok, value }` or `{ ok, error }`). The children of a group over its `concurrency` wait as `queued`. + - Each start takes `key`, `limits: { timeoutMs, maxAttempts }`, `budget: { maxTokens, maxCost }`, and `onModelError`. A run over its budget fails with the code `budget`, after the first model call over it. A run that runs again after a host stop counts the model use of the runs before. A run past `limits.timeoutMs` fails with the code `timeout`. A child never has more budget than its parent has left. `onModelError` is asked when a model call fails before it streams, and `'retry'` calls only that model call again (at most 3 calls). As data, `onModelError: { retries: 1 | 2, transientOnly? }` retries up to `retries` times (by default only a transient error), and the log keeps it, so a run that another host takes over or resumes retries too. A function is not in the log, so a run that another host takes over runs without it. A `ctx.agents` start in a plugin tool that an agent run calls is a child of that run, so it takes no `maxConcurrent` slot and the run can await it. `parent: ctx.context.run` names the run, and `parent: null` starts a root run. A `parent` that names no running agent run of this session throws, so a mistake does not start a root run. A running turn of the session gives a root run. + - The log keeps every run of a session as a `RunNode` of one run tree (`turn`, `agent`, `tool`, or `command`), with its parent, its user, its limits, its budget, and its result. `agentRuns()` reads the tree, and `AgentRunInfo` has `runId`, `kind`, `budget`, `result`, and `error`. Each `harness.usage` record has the `runId` of its run, and an agent run that ends keeps the usage of the run and its children. + - `maxDepth` and `maxCalls` count per tree, and `maxConcurrent` counts the root agent runs of the session. Over `maxConcurrent`, a root start waits as `queued`. The log keeps the counts, so a restart does not reset them. A `queued` start survives a host stop: the next host starts it with the same run id, in order, when a slot is free. + - A child run gets the user, the keys, and the signal of its parent: a cancel, a timeout, or a budget stop of the parent stops the child. A cancel of a turn also cancels the background runs that it started. A background run that a turn starts keeps the turn plugins until it settles. An agent that the model calls as a tool, and a routed agent, get `ctx.harness` too. + - A run with `runAgainAfterCrash: true` that runs again after a host stop gets the children that it started before, with their stored results, and starts only the rest. A background child that the model starts (`background: true`) runs again after a host stop as a run with `runAgainAfterCrash: true`, with the same `subagentRunId`. `durability.resumeBackgroundAgents: false` fails it instead. + - `ctx.harness.state({ key, initial })` gives the agents of a session a shared state by key, with `get` and `update`. The log keeps it, and a fork copies it. `STATE_SNAPSHOT` has `{ plugins, shared }`. + - A routed agent takes steers at its next model call, and late joins in the same turn, and `turn.beforeFinish` and `turn.onModelError` run for it. + - Every host keeps each session tree in one log, `stores.log` from `@tanstack/ai-persistence`. `memoryPersistence()` has a memory log, and a host with no `persistence` uses it. The log holds the inputs, events, transcripts, runs, interrupts, settings, config, plugin state, agent results, schedules, and tool steps, and the host folds them when a thread opens. A root thread and its child threads (agent runs and subagents) write to the log of the root. `session.logState()` reads the `durability.logState` fold of the whole tree. A harness with another `durability.addRecordsToModelContext` or `durability.logState` than the one that folds an open log throws when it opens that log. With a log store that survives a restart, the next host recovers a turn that a crash stopped. + - One host owns a log at a time: the first write takes it, one timer per host renews it, and a host that loses it stops its work on it. A host gives a log back when it has no work. Another host recovers the work of a log only after its ownership expires. A read never takes the log. An input that reaches another host waits in the input lane of the log, and the owner runs it (receipt `queued`) with its JSON overrides (`model`, `modelOptions`, `reasoning`, and `promptCache`). A command that reaches another host ends as it ends on the owner: with its result, its error, or `InputRejectedError`. An input to a thread that was deleted is refused: the receipt is `rejected` with the reason `deleted`, and an awaited operation rejects with `InputRejectedError` ("The thread was deleted."). `ownership: { expiresAfterMs, renewEveryMs }` sets the timing. `renewEveryMs` must be less than `expiresAfterMs`, else `createHarnessHost` throws a `RangeError`. With only `expiresAfterMs`, `renewEveryMs` is a third of it. + - When the owner refuses an offered input (busy, or an id that the log has with another payload), `session.settled()` on the host that offered it rejects with `InputRejectedError`. The log gets a `harness.offer.rejected` record. An offer that comes while the owner appends is not missed. + - A host that does not own a thread opens it while the owner runs a background job. Settings, config values, and the interrupted turn follow the changes of other hosts. `updateThreadSettings` merges into the latest stored settings. + - The owner writes a snapshot of the folded log to the log store after `log.saveSnapshotAfter.bytes` of new records (default 1 000 000) or `log.saveSnapshotAfter.ms` (default 300 000), and a new host opens from it. With `lifecycle.retention.keepLogRecords: 'since-snapshot'` (default `'all'`), the owner truncates the records before each snapshot. A reader whose cursor is in the dropped part gets one `harness.gap` event (`EventGap`), then the stream goes on. With `'since-snapshot'`, a thread whose snapshot the host cannot use (a changed `reduce` version or `project`) cannot open, and rejects with `LogTruncatedError`. `session.revert()` works with `'since-snapshot'`: the snapshot keeps the last 500 file steps. A plugin sets which of its records the snapshot keeps with `keepRecords: { [type]: count }` on its definition, and reads them, oldest first, with `ctx.session.keptRecords(type)`. The fold keeps the last 100 ended runs, run nodes, interrupts, and agent results, and drops the turn overrides of a settled input, so a long thread does not grow its fold and its snapshot with each turn. + - `host.submit` stores an input for a thread and runs nothing. `session.schedule({ at, input, scheduleId, user })` runs an input later, and `session.cancelSchedule({ scheduleId })` stops it. `createHarnessWorker({ host, harnesses, concurrency, signal, pollMs })` runs the threads that have work and no live host, and returns `{ stop }`. `host.resumePending` does one sweep. A swept thread that fails to open goes back with a wake in 30 s. A worker skips a thread that fails to open for a time that doubles after each failure in a row, up to 5 minutes, so the other threads still run. `host.submit` throws for a thread of another harness, and a later offer never changes the harness of a log. + - `durableTool()` keeps the result of each step. A crash can cut a step, and then it runs again, so `step.do` passes `{ idempotencyKey, epoch }` to `fn`. Give the key to your system, so it refuses the second side effect. `step.ask({ name, message, schema })` asks the user: the log keeps the question, any host can take the answer, and a run again after a stop returns the logged answer. A `step.do` value must be JSON: a `Date`, a `Map`, or a class instance is a type error. `step.sleep({ name, ms })` waits in the process, and the log keeps the wake time, so a worker continues the call after a stop. A sleep longer than 30 s on a thread that only a worker runs gives the thread back with the wake, so it keeps no worker slot. `durability.truncatedToolResult` sets the text of a tool call cut at the output limit. Without it, a cut answer ends the turn. + - `turn.onModelError`, `retryTransientErrors()`, `turn.beforeFinish`, and `turn.canJoin` control how a turn retries, continues, and ends. + - Every approval, question, sign-in, client tool, and human takeover that a run waits for is a `Wait` in the session log (`waitId`, `kind`, `runId`, `schema`, `expiresAt`, `message`). `WaitKind` is `approval`, `question`, `sign-in`, `client-tool`, or `human`. `waitKind`, `isApproval`, `waitFromInterrupt`, and `waitFromQuestion` come from the root and from `./view`. `snapshot().pendingWaits` lists the open waits: each one with its `interrupt` when a chat run stopped for it, and `turn: true` for a wait of the stopped turn. It is the one wait view of a snapshot. and `session.waitForRun({ runId, signal })` resolves with the next one. A wait ends `answered`, `cancelled`, or `expired`. A wait with `expiresAt` expires on time. Only `sign-in` has a default limit: 15 minutes. + - A wait that only the log holds keeps no host busy: the session goes idle, and an answer on any host continues the run. `resolve` answers the waits with an `interrupt`: of a stopped turn, or of one background agent run per call. `answer` answers the waits with no `interrupt` (a `step.ask` question, an MCP question, the `human` wait of a handoff), checks the answer against the JSON Schema of the wait, and keeps a secret out of the log. A `resolve` of such a wait is refused with `use_answer`, and a second answer to a wait that one answer ends is refused. `host.submit` checks an answer against the wait that it answers. + - A run waits for a person only at fixed points: `permissions()` before a tool call, the `question` tool, `step.ask` in a durable tool, a command (`CommandContext.step`), or an agent run, and the live waits of MCP elicitation and OAuth sign-in. `ctx.session.ask` throws anywhere else, with an error that names `step.ask`, the `question` tool, and `PermissionResources`. A command that called `step.ask` runs again from the top after a host stop. `Question` takes `expiresAt` and `signal`. + - A background agent run stops with status `waiting` on a wait, for example an approval of `permissions()`, and continues after the answer, also after a restart. An agent that the model calls as a tool inside a turn waits with the turn: its approvals, questions, sign-ins, app interrupts, client tools, and `ctx.harness.step.ask` questions are waits of the turn in `snapshot().pendingWaits`, with `agent` and `subagentRunId`. After the resolve, also on another host or after a restart, the agent goes on from where it stopped, and its result goes to the model as the tool result. Its `ctx.harness.step.do` values are in the log. With `durability.agentToolWaits: false`, the agent does not wait: a call of it that needs an approval is refused. + - The `operator` access action answers a `human` wait of any run, also with a resolve. A `human` wait takes only `operator`. `membersOnly()` gives it only to the role `operator`, so the user who waits for a person cannot act as that person. `membersOnly({ operator: { roles } })` sets the roles that have it. `isAllowed` gets the `wait` (`waitId`, `kind`) of an `answer` or `operator` action. + - `session.settled({ inputId, signal })` takes one object. `signal` stops the wait for the settlement. + - `session.onQuestion`, `session.onAuthRequired`, `session.onMedia`, and `session.onUsage` call a listener for the events that a user answers or sees, with a typed value. + - Sessions also have thread settings, fork and revert, usage totals, media files, the transcript of each child agent (`session.agentTranscript`), and `harnessText()` / `harnessAgent()` to use a harness as a text adapter or an agent. In a session, a `harnessAgent` child is a child run in the log of the root, with the user, keys, limits, and budget of the run that calls it. Its usage and its waits show in the parent session, on every host and in `host.observe`. An answer on another host goes to the host that runs the child. The base64 cache of media files is shared by all the sessions of a host. + - `harnessText()` uses the user of each call. The inner thread is `/inner/` on every host, and `host.open` refuses that id from app code. When a host with access runs the outer thread too, the inner session is checked through the outer thread, so every user of a shared outer thread can use it. The index entry of the inner thread keeps the link to its outer thread. An abort on a remote harness sends a cancel. The usage of the inner run reaches the outer `RUN_FINISHED`. Its SSE reader takes multi-line `data:` and CRLF. `harnessText()` and `harnessAgent()` forward events on one shared path. + - `createHarnessHost({ observability: { tracer, onOperation } })` traces runs. `tracer` takes an OpenTelemetry `Tracer`. `@opentelemetry/api` is an optional peer dependency: the host loads it only when it has a tracer. The host writes `harness.operation` spans (turns, agent runs, commands), and `harness.recovery`, `harness.wait`, and `harness.transfer` spans. A child run on the same host is a child span: the host passes `trace.setSpan(context.active(), parent)` as the third argument of `startSpan`. A tracer that throws is logged and fails no run. `SendOptions.traceparent` stores a W3C `traceparent` with the input, and the run span on the host that runs it gets a link to it. + - `onOperation` gets a `started` report and a `settled` report (`OperationReport`) for each operation that this host runs, with `status`, `durationMs`, `error`, and `usage`. A listener that throws gets a `harness.plugin.warning` event, and the work goes on. + - More lifecycle events in the session stream: `harness.input.queued`, `harness.ownership.changed` (`reason: 'taken_over'` when the store says that the old owner expired, else `'acquired'`), `harness.stranded`, `harness.transferred`, `harness.wait.opened`, and `harness.wait.settled`. `HarnessEventValues` maps each `harness.*` event name to the type of its value. + - `onEvent`, `onQuestion`, `onUsage`, and `onMedia` also get the events that another host writes to the log of the session. An event fires once. The status of `host.events()` counts that work too, for the sessions that are open on the host. + - The router gets `model`: `model.chat({ adapter, options, label })` in `routing.router` (`HarnessRouterContext.model`) calls a model with the keys of the sender, and a cancel of the turn stops it. + - `session.usage()` has `bySource`: the model calls that are not a turn or an agent run, keyed by `plugin:`, `router`, or `transfer`. Each `UsageCall` and `harness.usage` event of such a call has `source`, and `label` when the call has one. The summary of `host.transfer` with `messages: 'summary'` counts in the source thread under `transfer`, with the label `summary`, and stops after 2 minutes. + + Add first-party plugins. `@tanstack/ai-harness/plugins` loads no Node module. The plugins that read files are in the Node entry `@tanstack/ai-harness/plugins/node`. + - `permissions()`: rules for tools, paths, and commands, and the `default`, `plan`, `acceptEdits`, and `bypass` modes. It decides every call of a model message before the calls run, and opens one approval wait for each call that asks, so the turn stops and no process waits. An answer is `true` or `false`, `'once'`, `'always'`, or `'reject'`, or `{ answer, message? }`. It also has saved "always" rules with `/permissions` and `/permissions forget `, and `listSavedPermissions` / `deleteSavedPermission` for server code. The rules apply in subagent runs too. It decides in `onGuardToolCall`, on the final checked arguments. + - `agents()` (in `plugins/node`): agent profiles with their own prompt, tools, model, rules, and step limit, in code or in Markdown files, `/agent` to switch the primary agent, and the built-in `build`, `plan`, `general`, and `explore` agents. A subagent run uses the tools and the model of the turn that started it. A run whose turn is not in the memory of this host fails with a clear error. A run that code starts needs a profile `model`. + - `question()`: a `question` tool for the lead turn. Each question is a wait of the turn, answered with `resolve`. Agent runs do not get the tool. + - `todos()`, `title()`, `modelPicker()`, `compact()`, and `usage()` (with your own prices for calls that have no provider cost). + - `goal()` runs each turn as the user who set the goal. + - `projectInstructions()`, `fileCommands()`, and `boundToolOutput()`, in `plugins/node`. + + A plugin runs agents with `ctx.agents.start`, `ctx.agents.run`, and `ctx.agents.group({ concurrency }, (g) => [g.start(agent, input)])`, with the same types as `ctx.harness.agents` in agent code. + + `PermissionRules`, `PermissionResources`, `PermissionDecisionCapability`, and `decidePermission` are also exported from the package root. They load no Node module, so an edge-safe plugin can read the permission rules. + + `ctx.model.chat({ adapter, options, label, run, timeoutMs })` calls a model from a plugin, for example a judge or a title. It uses the keys of the user of the run, the budget of the run applies, and it stops when the run stops or after `timeoutMs` (default 2 minutes). Its usage counts in the session under `plugin:` in `session.usage().bySource`. `goal()`, `title()`, and `compact()` call their models this way, with the labels `judge`, `title`, and `compact`. + + Serve a harness session to clients. + - `createHarnessHandler()` from `@tanstack/ai-harness/server` serves a session over HTTP, as the user that the host `access` reads from each request. `POST run` is standard AG-UI, so `useChat` with `fetchServerSentEvents` works on a harness, with approvals, client tools, and a reload that joins the running turn. `POST control`, `GET events`, `GET transcript`, `GET agent-transcript` (the messages of a child agent run), `GET snapshot`, and `GET describe` cover one session. `sessions` (with the `share` and `unshare` ops), `GET host-events`, and the media routes cover the rest. A `host.events()` reader listens from the call, and one that falls more than 1 000 changes behind stops, and reads again for the current statuses. A refused action answers 403. A read of a thread that does not exist answers 404 and starts no session. A signed media URL still needs a user: `getUser` reads the user of the request, and that user needs `read` on the thread, in the tenant of the URL. For a request with no login, `access.getGuestUser({ tenantId })` can give a guest, and `isAllowed` decides `read` for it. The guest exists only on the signed media route. `requestUsers` from `@tanstack/ai-harness/server` gives the user of each request with the same rule, for your own server. The read routes read a thread with `host.observe`, so they set up no plugins. `GET describe` opens the session. + - `handleHarnessSocket()`, from the same entry, serves the same session over a WebSocket. It takes the upgrade `request` and reads the user from it. It handles the frames of one connection in order. + - A `command` or an `agent` input over HTTP or the socket runs once for one `inputId`, and the `inputId` of its receipt is the id of the client. + - `expose` on `defineHarness()` names the agents, settings, config keys, and commands that a client can use. Any other input of those kinds gets `rejected` with `not_exposed`. + - `createHarnessClient()` from `@tanstack/ai-harness/client` is a typed, browser-safe client. It sends inputs, reads the session, and streams events that resume from a cursor. Without `from`, `client.events()` starts at the newest event (the cursor of the snapshot), so it does not send the whole history first. This is the default: a reader that needs the history (to rebuild a transcript, for example) must pass `from: '0'` or a saved cursor. When the snapshot answer has no string `cursor`, `client.events()` throws and does not retry. `client.events()` connects again after `idleTimeoutMs` (default 60 000) with no bytes. The `prompt` input of the protocol and `client.send` take `as: 'operator'` for the reply of an operator after a handoff to a person. + - The client methods take one object: `cancelInput`, `revert`, `agentTranscript`, `mediaUrl`, `appendRecords`, and `putMedia`. `client.sessions.list`, `rename`, `delete`, `update`, `fork`, `share`, and `unshare` manage the sessions. `HarnessErrorCode`, the type of `HarnessProtocolError.code`, comes from the main, `/client`, and `/server` entries. + - `oauthConnector()` and the OAuth helpers from `@tanstack/ai-harness/oauth` (`loopbackLogin`, `deviceLogin`, `exchangeCode`, `refreshCredential`, and more) keep a credential per user. A tool calls `token({ run: ctx.context.run })` for the token of the user of its run. `token({ run, wait: true })` stops the turn with an `auth_required` interrupt until the user signs in. `deviceLogin`, `loopbackLogin`, `startLoopbackReceiver`, `exchangeCode`, and `refreshCredential(config, credential, { fetch, signal })` stop at once when their `signal` aborts, so a cancel or a session close stops a running `/connect`. `OAuthConfig.issuer` makes `loopbackLogin` refuse a code from another issuer (RFC 9207). The loopback deadline (`timeoutMs`) does not keep the process alive. + - `run.credentials.refresh(id, update, { signal })` refreshes a saved credential once for all callers on a host, keyed by tenant, user, and id. It saves with `setIf` when the store has `getVersioned` and `setIf`, and uses the other host's token on a conflict. Without that pair, it does a plain `set`. It saves to the scope where it found the credential, so a tenant token stays the tenant's. `update` gets a signal that only `host.close()` aborts. An abort of `signal` rejects only that call. `oauthConnector` refreshes this way, and `refreshCredential` keeps the `client` of the old credential. + - The session stream speaks protocol version 2 on every transport: `GET events`, the socket, and the stdio worker. Each event is an AG-UI wire chunk in a `harness.event` frame, with `cursor`, `threadId`, and `operationId`. The AG-UI `RUN_STARTED` of a child agent run has `parentRunId`, so a client can rebuild the run tree. + - The first frame of a stream is `harness.hello` with the version `v`. A client asks for a version with `?v=` or with `v` in `harness.subscribe`. Another version gets a `harness.error` frame with the code `unsupported_version`, and the stream closes (socket code 4400). + - A `harness.error` frame has a `code` (`unauthorized`, `forbidden`, `invalid_frame`, `unsupported_version`, `slow_consumer`, or `internal`) and a `requestId`. On the socket and the stdio worker, the `requestId` is the id of the frame that failed. Every answer of the handler has an `X-Request-Id` header: the id that the client sent when it is a short safe id, else a new UUID. + - Streams stay open and protect the server. SSE streams send a `: ping` comment and the socket sends a `harness.ping` frame when idle. SSE reads the log only as fast as the client reads, and the socket waits while its `bufferedAmount` is over the limit. A client that does not read in time gets a `slow_consumer` error frame, and the stream closes (socket code 4408). A slow client loses no events: it connects again from its last cursor. `createHarnessClient` does this in `events()` and `hostEvents()`, and ends the read with a `HarnessProtocolError` (with its `code`) for any other error frame. + - `presence: { onConnect, onDisconnect }` on `createHarnessHost` reports each client stream of `GET events` and of the socket (after its subscribe), as a `PresenceEvent` with a new `connectionId`, the user, the thread, the transport, and `resumed`. `onDisconnect` runs once per stream, with the reason `closed`, `revoked`, or `error`. The host does not wait for a hook, and a hook that fails only warns. + - `stream: { heartbeatMs, slowConsumerMs, sseQueueBytes, socketBufferBytes }` on `createHarnessHandler` and `handleHarnessSocket` changes these values. The defaults are 20 s, 30 s, 1 MiB, and 8 MiB. A value that is not a finite number above 0 throws at the start. `HarnessStreamOptions` is the type. + - A reader whose events are gone gets one `harness.gap` event, with `reason: 'truncated'` (a truncate of the log) or `'evicted'` (the memory feed of a session dropped them). The stream then goes on from `resumeAt`. + - A W3C `traceparent` goes with a message: as the `traceparent` header of `POST control` and `POST run`, or as the `traceparent` field of a `harness.input` frame. `ClientSendOptions.traceparent` makes `client.send` send the header. + - A `cancel` input stops a turn from any host that reads the same log, so `client.cancel({ operationId })` works behind a load balancer. A closed connection still never cancels work. To stop a `useChat` turn, call `client.cancel` with the `runId` of `useChat` in the stop handler. + + Add `createSessionView()` in `@tanstack/ai-harness/view`. It turns a session (local, or remote through `createHarnessClient()`) into one live TanStack Store state that works with any UI library. + - The state: messages with their parts, tool calls, approvals, client tools, other interrupts, questions, sign-ins, `waits` (every open wait, with its kind), child agents with their results and a `status` of `running` or `waiting`, media with signed URLs, waiting inputs, usage, models, settings, commands, and plugin state. + - The waits of background agent runs show in `approvals`, `clientTools`, and `interrupts`. The view answers each one at once: with `resolve`, or with `answer` for a `human` wait that no turn holds. + - Actions: `send` (a prompt, a steer, or a `/command`), `followUp`, `continueWithoutMessage`, `putMedia`, `cancel`, `cancelInput`, `changeInputDelivery`, `updateThreadSettings`, `reset`, `revert`, `loadAgent`, and the answers to approvals (with edited arguments), client tools, interrupts, and questions. `cancelInput`, `revert`, `approve({ id, ...options })`, `reject({ id, payload? })`, `notice({ text })`, and `putMedia` take one object, and so does the `reject({ payload? })` of an approval item. + - Typed events: `view.on('approval' | 'interrupt' | 'turnEnd' | ..., handler)` and plugin events. + - In a harness with `routing`, an assistant message has `agent`, the root agent that wrote it. After a handoff, the next agent writes a new message in the same turn. + - `view.send(text, { as: 'operator' })` sends the reply of an operator while a handoff to a person is open. The reply shows in each open view at once. + - A view that opens while a turn runs shows the turn from its start. After a reload, each child agent shows its card, and `view.loadAgent({ id })` fills it with its own messages. + - When the stream sends a `harness.gap` event, the view stops its read, loads the snapshot and the transcript again, then reads on from the new cursor. No turn shows twice. + + Mark `createSessionView`, `SessionViewState`, and `SessionViewEvents` as `@experimental`. Document that event cursors are opaque strings: positions in the session log. + + Add the `goal({ judge, maxRounds })` plugin to `@tanstack/ai-harness/plugins`. `/goal ` sets a goal and starts a turn. After each turn, the judge model checks the goal, and the plugin starts the next turn until the goal is met, the round limit is reached, a turn waits for approval or fails, or the user sends a message. `/goal`, `/goal stop`, and `/goal resume` show and control it. The `GoalMet` event fires when the goal is met, and `selectGoal(session.snapshot())` reads the goal for a UI. + + Add the `providerKeys({ providers })` plugin to `@tanstack/ai-harness/plugins`. Users of a shipped harness connect their own model provider in the app, with no `.env` file. It adds `/connect:`, `/disconnect:`, and `/keys`. `/connect:` runs the provider's `signIn` when it has one, else it opens `keyUrl` when set and asks the user to paste the key with `step.ask` and `secret: true`. The log keeps the question as a wait, so a user on any host can answer it, and the log never keeps the key. The key is saved in the credential store of the user, and a `keyedAdapter(...)` for that provider uses it. `/keys` shows where each key of the user comes from: a saved key (the last 4 characters only), the env var, or no key. The plugin state shows only the env vars that the session reads, as every member of the thread reads it. On a host with access without `allowServerEnvKeys`, no env var counts. + + Add coding tools in the new Node entry `@tanstack/ai-harness/plugins/coding`: + - `workspaceTools({ root })` gives `read_file` (text pages, images, PDFs), `write_file`, `edit_file` or `patch` (`editStyle`), `list_files`, `grep`, `bash` (with `background`), `webfetch`, and `websearch` (with a `SearchProvider`). With `permissions()`, edits, `bash`, and `webfetch` ask first, and the rules also apply to the real path of a link. `outside: 'ask'` makes a path outside `root` need an approval. `permissions()` decides outside paths and the real paths of links before the call runs, so a tool never asks while it runs. The `cwd` thread setting gives each thread its own working folder. + - `workspaceTools({ workspace: { bind, reattach? } })` gives each thread its own workspace. The root of the workspace is the boundary of every tool. The session log keeps where the workspace is (`harness.workspace.bound`). On another host, `reattach` gives the workspace back (for example a resumed sandbox), or `'pinned'` or `'gone'`. A gone workspace sends `tanstack/workspace-tools:stranded`. With this plugin first, `snapshots()` and `formatter()` use the workspace of each thread, and their `root` is optional. + - `createHarnessHost({ ownership: { hostId } })` gives a host a stable id. Then a thread that uses a folder on that host is pinned to it, and other hosts refuse its tool calls. Without `hostId`, threads are not pinned. A host with `hostId` sends a heartbeat to the log store, and its pins lapse when no heartbeat came for `ownership.expiresAfterMs`: then another host reattaches its threads. `host.unpin({ harness, threadId })` unpins a thread from a host that does not come back, once its ownership expired. + - `workspaceRoot(base, ...parts)` gives a folder in `base` for a tenant and a thread id. It encodes each part, so a thread id from a client cannot leave `base` or reach another thread. + - Commands, `rg`, `git`, and the formatters get only a short list of variables of the server process, plus the `env` of the backend call. Git runs without the hooks and the `fsmonitor` of the project. + - The tools resolve links with `realpath` under the file lock, and fail when a backend cannot resolve a path. A write fails when the file changed after the tool read it in the same chat run, so a lead and its subagents do not lose each other's edits. The file locks are shared by the sessions of a host, by the sandbox (or host) and the real path of the file. + - Background jobs: at most 8 per session (`maxJobs`), the newest 1 MiB of output per job, and the events `tanstack/workspace-tools:job-started`, `job-output`, and `job-ended`. A running command that `session.moveToolCallToBackground()` moves counts as a job, and its process id goes to the log. A job that an earlier host left running is stopped at the next tool call, with a note to the model. When the backend cannot check the job (for example with no `ps`), the log keeps it, and the note says that it can still run. The wake turn of a job runs as the user who started it. `session.jobs()` and `jobs()` of a `host.observe` view list the jobs that did not end (`JobInfo`: the job id, the thread, the command or tool name, who moved it, when it started, and `running` on this host). The `bash` spill file has `[redacted]` in place of each secret of the session. + - `read_file` sends images and PDFs up to 256 KB. `webfetch` gives the model the first 256 KB of a page. + - A `WorkspaceBackend` runs the tools. `hostBackend` is the default. `realpath` is required. `spawn` can give a `jobId`, `exec` can give one with `onStart`, and `killJob`, `binding`, and `close` are optional. `killJob` rejects when it cannot check that the process is the job. On Windows, commands do not run a program from the working folder by its name. + - `snapshots()` adds `/undo` and `/redo`, which restore only the files of the turn (git 2.26 or newer), file restore for `session.revert()`, and a diff for each model step. Each thread of each tenant has its own shadow repository, which never stores `.env` files. A step keeps only the files of its own run. The steps and the undo point are in the session log, so another host with the same repository can undo. A revert uses the last 500 steps. `host.sessions.delete` removes the repository of the thread, and `purgeSnapshots()` does it from your own code. A failed snapshot sends `tanstack/snapshots:failed`. + - `formatter()` formats each written file with the formatter of the project. With `permissions()`, the rules decide the formatter with the call that writes, before that call runs: one approval covers both, and the formatter runs after the write. An `always` answer is tied to a hash of the formatter config files. A write of a formatter config below the root, or under `node_modules`, asks each time, and an `always` answer saves no rule for that formatter run. + - `WorkspaceHooks` lets other plugins run code after a read or a write. + + `@vscode/ripgrep` and `turndown` are optional peer dependencies. + + `@tanstack/ai-harness/build` and `@tanstack/ai-harness/worker`: `buildHarness` bundles a harness with Bun into a worker artifact (`harness.js` and a `harness.manifest.json` with the sha256 digest), and can also build a single executable. `artifactText(dir)` checks the digest and uses the artifact as the model of a `chat()` call, with one worker process per thread. `runHarnessWorker` runs a harness on stdin and stdout with the session frames of the harness protocol. + + `definePlugin` refuses a `setup()` contribution, such as `adapter` or `tools`, at the top level of a definition, where it would be ignored. Return it from `setup()`. + + `write_file`, `edit_file`, and `patch` send `FileChanged` (`tanstack/workspace-tools:file-changed`) with a unified patch and its line counts for each file that they change. At the end of each model step, `snapshots()` sends it for the files that other tools, like `bash`, changed: at most 100 for each step. `/undo`, `/redo`, `session.revert()`, and `session.unrevert()` also send it for each file that they put back. + + Any server instance that reads the same log store can serve a run. + - `POST run` sends the log cursor of each event as its SSE `id`. A client that is cut off sends the same request with `Last-Event-ID`, and any instance continues the stream from there. The turn does not run again. + - `GET run?runId=&threadId=` finds a turn that another instance runs. It streams the turn from the log of `threadId`, from its start or from `Last-Event-ID`, until the turn ends. It reads the log from the start of the turn, not from the start of the log. A turn rebuilt after a restart (a retried `POST run`) also streams from its start. Without `threadId`, only the instance that runs the turn finds it, and another instance answers `400`. The join request of a `ChatClient` sends only the run id, so put `threadId` in the URL of the connection. + - `GET run?threadId=` shows a turn that another instance runs as `activeRun`, so a reloaded `useChat` joins it. + + A host that folds a `harness.*` log record type it does not know (a newer harness wrote it, for example during a rolling deploy) reads the log but refuses to write it, with `LogVersionError`. A log snapshot from a newer harness is not used. + + `createHarnessHost({ logger })` takes a `Logger` from `@tanstack/ai` for the warnings and errors of the harness and its `chat()` calls (default: `ConsoleLogger`). Plugins get it as `ctx.logger`, and a logger that throws does not stop the harness. + + `PermissionCallCapability` gives a plugin that runs tool calls itself, like code mode, the decision that `permissions()` makes for one call: `allow`, `deny` with the error that the model gets, or `ask` with the approval question. It uses the current mode, the saved `always` answers, and the resources of the call args, and `settle(reply)` applies the user's answer as a direct approval does. + + Keep the secrets of a session out of what it keeps and sends. + - Each session replaces every secret that it gave out with `[redacted]`. These are the values of `run.keys` (also from env vars) and `run.credentials`, connector credentials and OAuth tokens, and secret answers (each string field of an answer with fields). It scrubs log records, feed events, plugin state (also in a `Map` or a `Set`), notes, the model context, and tool results, also after the own middleware of an agent run. It also scrubs the error frames of the HTTP handler, the WebSocket, and the stdio worker. It finds the raw, JSON-escaped, and URL-encoded forms, and skips values shorter than 6 characters. A secret split across two streaming deltas stays in those two events, and a secret that is JSON-escaped two times is not found. + - `scrubSecrets` from `@tanstack/ai-harness` is the one from `@tanstack/ai/byok`. + - A `step.do` value that holds a secret of the session throws, on the first run and on a replay, so the log never keeps a secret. Read the secret outside `step.do`. + - A retry of an input with a secret in it is a duplicate, not a conflict: the check compares the input without the secrets, as the log keeps it. + - The log keeps the final result of each tool call: the result after every `onAfterToolCall` hook (also the agent's own middleware in an agent run), scrubbed. A replacement from a hook wins, also on an error. Recovery after a crash gives the model that result. + - An answer to a `secret: true` question that reaches a host that does not own the log goes through the `credentials` store of the host, as a one-time reference with the credential type `secret_answer` and an `expiresAt` 24 hours later. Only the reference goes into the input lane, and the owner reads and deletes it. The references that nobody read go when the question ends. A kept answer for a run again goes when the run ends. Without `createHarnessHost({ credentials })`, the answer is rejected with `secret_answer_needs_credentials`. A used, expired, or unknown reference is rejected with `unknown_secret_answer`. `credentials.list` does not show the `secret_answer` type. + + Make the transport defaults safe for a server with many instances. + - `createHarnessHandler` and `handleHarnessSocket` read the user of each request with the host `access`. On a host without `access`, pass `openAccess: true` (no user) or `openAccess: { user }` (one local user), else they throw at the start. So a server never serves every thread to everyone by mistake. + - `media: { secret }` signs the media URLs of `createHarnessHandler`. Set the same secret on every instance, so a media URL that one instance signs works on every instance. Without it, the handler signs with a random key of its own, and a URL works only on that instance. A host with `ownership` options needs `media`, else the handler throws at the start. On another host without `media`, the first handler logs one warning. A signed URL names its harness and its user, and the handler checks that user again when it serves the file. A URL of a deleted thread answers 404. + - `media: { keys: [newKey, oldKey] }` rotates the key: the first key signs, and every key checks. Each key must be at least 32 bytes, else the handler throws at the start. + - `oauthConnector` needs `login`. Use `'device'` on a server, and `'loopback'` only for a harness on the user's own machine, such as a CLI. + + How a turn takes steers, settings, and plugin removals, and the size limit of client requests. + - A steer that arrives during a `session.runTool()` turn waits, and then runs as its own turn. + - A turn keeps the config values that it started with. A config change while it runs, for example `/mode bypass`, applies from the next turn. + - `configure({ settings: { plugins: { remove } } })` removes everything that those plugins give the thread: also their agents, subagents, commands, agent and generation middleware, and the items that they add for other plugins (for example the permission rules of `agents()`). A remove that leaves a plugin (of any lifetime) or a harness middleware without a capability that it needs is rejected. + - When two plugins give a tool with the same name from `discoverTools`, the first one stays, and clients get one `harness.plugin.warning` event that names both plugins. + - `createHarnessHandler` reads each JSON body up to `media.maxBodyBytes` (default 32 MiB). A bigger body answers 413. `handleHarnessSocket` closes the socket with code 1009 on a bigger frame. The WebSocket server reads the whole frame first, so also set its own frame limit (for example `maxPayload` of `ws`). + - Client media is checked part by part before any part is stored, so a refused input stores nothing. A retried input with the same `inputId` stores its media no second time, and gets the first receipt. + - A client input with a provider file handle (`source.type: 'file'`) is refused with `media_url_not_allowed` unless the harness sets `media.allowProviderFiles: true`. Server code can still send file handles. + - `POST run` moves the inline bytes of the last user message to the media store, as `POST control` does, so the transcript keeps a `harness-media:` reference. A refused part answers 413 (`media_too_large`), 415 (`media_not_allowed`), or 400 (`media_invalid`, `media_url_not_allowed`). + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `computerUse()` in `@tanstack/ai-computer-use/harness`: computer use as a harness plugin. + - Each screenshot goes to the media store of the session. The transcript and the log keep a small `harness-media:` reference. + - The model gets only the newest `keepScreenshots` screenshots (3 by default). An older one goes to the model as a 1x1 image. + - A call with OpenAI safety checks asks the user through `permissions()`, each time. Without `permissions()`, the call is refused. + - The `plan` mode of `permissions()` refuses the `computer` tool. + + `@tanstack/ai-harness` is an optional peer dependency of `@tanstack/ai-computer-use`. + + A plugin can now store a file with `ctx.session.putMedia(upload)`, and put `mediaPart(record)` in a tool result. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `createHarnessHost({ credentials })` takes the `CredentialStore` (from `@tanstack/ai/byok`) where users' API keys and OAuth sign-ins are saved. Without it, credentials stay in memory until the process stops. `runCli` takes the same `credentials` option. + +- [#1883](https://github.com/TanStack/ai/pull/1883) [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3) - Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. + + Add the harness asks from the fifth findings list. + - `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. + - `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. + - A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. + - Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. + - `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. + - A plugin `adapter()` pick with `override: true` wins over the stored thread model. + - `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. + - Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. + - `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. + - `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. + - `HarnessRecord` is exported, for a typed `LogStore` wrapper. + - Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. + - `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. + + Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. + - `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model + turn, for example from a schedule or a webhook. The call goes through the + same middleware, input check, and `permissions()` rules as a model call, and + the call and its result join the transcript. A tool that asks for approval + stops the turn with an interrupt. While interrupts wait, the call is refused + with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom + event. `args` is typed from the input schema of a harness tool. + - `expose.tools` lists the harness tools a client may run with a + `{ op: 'tool', name, args?, meta? }` input, or with the new + `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness + `tools`, and `defineHarness` throws for a name that is not in `tools`. Any + other tool is refused with `not_exposed`. The capabilities document marks + each tool with `exposed`. + - `expose.records` lists the host record types a client may add with an + `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. + A record of another type, or with a `thread` field, is refused with + `not_exposed`. The session log keeps the records. + - `createHarnessMcpServer` adds a `tool_` tool for each tool in + `expose.tools`, and an `append` tool when `expose.records` has types. A tool + input with its own `threadId` field throws when the server is created, + because MCP uses `threadId` to pick the thread. + - `session.send(message, { systemPreamble })` prepends per-run, server-only + system prompts ahead of the harness's own system prompts (for example + host-provided memory). A client input cannot set them. + - A tool call in a harness turn gets `threadId` and `runId` in its execution + context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional + fields for a host to set. + + A host can add fields to the `ctx` an agent's `run` gets. + - `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. + - `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. + + Add `interrupts` to `SubagentBinding`. + - A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. + - The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. + - A child's `ctx.chat({ subagents })` passes the definitions on to its own children. + - A plain `chat()` call does not get them. + + Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. + + Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. + + An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. + + Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. + + Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. + - It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. + - The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. + - Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. + - It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. + - The new `GuardToolCallDecision` type is exported. + + BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: + - `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. + - `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. + - `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. + - `memoryCredentialStore()`: a store in memory, for development and tests. + - `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. + - `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. + + `CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. + + Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. + + `scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. + + `Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. + + Approved edits to tool arguments stay raw until the final input check. + - `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. + - `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. + + A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. + + `chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. + + `WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. + +### Patch Changes + +- [#1876](https://github.com/TanStack/ai/pull/1876) [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc) - An input with no user no longer runs as the user who opened the session that owns the thread. A host with access refuses that input. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`d3b4cd4`](https://github.com/TanStack/ai/commit/d3b4cd4965552f35273b9c96823ad657af1fe0b5), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`f6a27bc`](https://github.com/TanStack/ai/commit/f6a27bc33198bff58415dfe8d107f1d5b9525e83), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/ai-persistence@1.0.0 diff --git a/packages/ai-harness/package.json b/packages/ai-harness/package.json index 9e66d8adb3..46867f6859 100644 --- a/packages/ai-harness/package.json +++ b/packages/ai-harness/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-harness", - "version": "0.0.0", + "version": "0.1.0", "description": "Build agent harnesses on TanStack AI: long-lived sessions, typed agents, and plugins", "keywords": [ "agent", diff --git a/packages/ai-isolate-cloudflare/CHANGELOG.md b/packages/ai-isolate-cloudflare/CHANGELOG.md index 849e133c3c..b75d01bb87 100644 --- a/packages/ai-isolate-cloudflare/CHANGELOG.md +++ b/packages/ai-isolate-cloudflare/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-isolate-cloudflare +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-code-mode@1.0.0 + ## 0.2.43 ### Patch Changes diff --git a/packages/ai-isolate-cloudflare/package.json b/packages/ai-isolate-cloudflare/package.json index 5d7aa22a4c..2625e2bbc7 100644 --- a/packages/ai-isolate-cloudflare/package.json +++ b/packages/ai-isolate-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-cloudflare", - "version": "0.2.43", + "version": "1.0.0", "description": "Cloudflare Workers sandbox driver for TanStack AI Code Mode TypeScript execution at the edge.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-isolate-daytona/CHANGELOG.md b/packages/ai-isolate-daytona/CHANGELOG.md index f2e0e03142..923d583c67 100644 --- a/packages/ai-isolate-daytona/CHANGELOG.md +++ b/packages/ai-isolate-daytona/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-isolate-daytona +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-code-mode@1.0.0 + ## 0.1.3 ### Patch Changes diff --git a/packages/ai-isolate-daytona/package.json b/packages/ai-isolate-daytona/package.json index 1643ed0697..b70627853d 100644 --- a/packages/ai-isolate-daytona/package.json +++ b/packages/ai-isolate-daytona/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-daytona", - "version": "0.1.3", + "version": "1.0.0", "description": "Daytona sandbox driver for TanStack AI Code Mode TypeScript execution.", "author": "", "license": "MIT", diff --git a/packages/ai-isolate-e2b/CHANGELOG.md b/packages/ai-isolate-e2b/CHANGELOG.md index 349b3be602..1b1d3128dc 100644 --- a/packages/ai-isolate-e2b/CHANGELOG.md +++ b/packages/ai-isolate-e2b/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-isolate-e2b +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-code-mode@1.0.0 + ## 0.1.1 ### Patch Changes diff --git a/packages/ai-isolate-e2b/package.json b/packages/ai-isolate-e2b/package.json index 4e81a2fc86..0e07c5cf34 100644 --- a/packages/ai-isolate-e2b/package.json +++ b/packages/ai-isolate-e2b/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-e2b", - "version": "0.1.1", + "version": "1.0.0", "description": "E2B sandbox driver for TanStack AI Code Mode TypeScript execution.", "author": "", "license": "MIT", diff --git a/packages/ai-isolate-node/CHANGELOG.md b/packages/ai-isolate-node/CHANGELOG.md index 84461b50a9..3aa8c2fc29 100644 --- a/packages/ai-isolate-node/CHANGELOG.md +++ b/packages/ai-isolate-node/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-isolate-node +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-code-mode@1.0.0 + ## 0.1.52 ### Patch Changes diff --git a/packages/ai-isolate-node/package.json b/packages/ai-isolate-node/package.json index 4f422c4b89..2af8d07a68 100644 --- a/packages/ai-isolate-node/package.json +++ b/packages/ai-isolate-node/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-node", - "version": "0.1.52", + "version": "1.0.0", "description": "Node.js isolated-vm sandbox driver for TanStack AI Code Mode TypeScript execution.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-isolate-quickjs-bun/CHANGELOG.md b/packages/ai-isolate-quickjs-bun/CHANGELOG.md index d7678c21ec..877bd5b251 100644 --- a/packages/ai-isolate-quickjs-bun/CHANGELOG.md +++ b/packages/ai-isolate-quickjs-bun/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-isolate-quickjs-bun +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-code-mode@1.0.0 + ## 0.1.2 ### Patch Changes diff --git a/packages/ai-isolate-quickjs-bun/package.json b/packages/ai-isolate-quickjs-bun/package.json index 99dc9a9442..8f4627b62d 100644 --- a/packages/ai-isolate-quickjs-bun/package.json +++ b/packages/ai-isolate-quickjs-bun/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-quickjs-bun", - "version": "0.1.2", + "version": "1.0.0", "description": "Native QuickJS sandbox driver for TanStack AI Code Mode TypeScript execution on Bun via bun:ffi.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-isolate-quickjs/CHANGELOG.md b/packages/ai-isolate-quickjs/CHANGELOG.md index 8e6dd6b76b..d52d33fdfb 100644 --- a/packages/ai-isolate-quickjs/CHANGELOG.md +++ b/packages/ai-isolate-quickjs/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-isolate-quickjs +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-code-mode@1.0.0 + ## 0.3.2 ### Patch Changes diff --git a/packages/ai-isolate-quickjs/package.json b/packages/ai-isolate-quickjs/package.json index 93857ee5b4..4be89d5ea4 100644 --- a/packages/ai-isolate-quickjs/package.json +++ b/packages/ai-isolate-quickjs/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-isolate-quickjs", - "version": "0.3.2", + "version": "1.0.0", "description": "QuickJS WASM sandbox driver for TanStack AI Code Mode TypeScript execution across runtimes.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-llmgateway/CHANGELOG.md b/packages/ai-llmgateway/CHANGELOG.md index bd7c6dc1c7..9b3c3ed460 100644 --- a/packages/ai-llmgateway/CHANGELOG.md +++ b/packages/ai-llmgateway/CHANGELOG.md @@ -1,5 +1,39 @@ # @tanstack/ai-llmgateway +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1866](https://github.com/TanStack/ai/pull/1866) [`6af47a2`](https://github.com/TanStack/ai/commit/6af47a2a7792129d4ef25ff6409afcde212130af) - Generate the LLM Gateway chat model list from the gateway catalog, including input kinds and reasoning levels. + +### Patch Changes + +- [#1882](https://github.com/TanStack/ai/pull/1882) [`456bdc4`](https://github.com/TanStack/ai/commit/456bdc4fa5dba2d01889d5073ffe2c418078ea07) - Update model metadata from OpenRouter API + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.3.2 ### Patch Changes diff --git a/packages/ai-llmgateway/package.json b/packages/ai-llmgateway/package.json index e01e35981b..48b8c2d5fa 100644 --- a/packages/ai-llmgateway/package.json +++ b/packages/ai-llmgateway/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-llmgateway", - "version": "0.3.2", + "version": "1.0.0", "description": "LLM Gateway adapter for TanStack AI — one OpenAI-compatible endpoint for chat, tool calling, and structured outputs across many providers and models.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-lovable/CHANGELOG.md b/packages/ai-lovable/CHANGELOG.md index 27bc91218c..c064c059c9 100644 --- a/packages/ai-lovable/CHANGELOG.md +++ b/packages/ai-lovable/CHANGELOG.md @@ -1,5 +1,33 @@ # @tanstack/ai-lovable +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.6.2 ### Patch Changes diff --git a/packages/ai-lovable/package.json b/packages/ai-lovable/package.json index ec49914f97..fad86b93af 100644 --- a/packages/ai-lovable/package.json +++ b/packages/ai-lovable/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-lovable", - "version": "0.6.2", + "version": "1.0.0", "description": "Lovable AI Gateway adapter for TanStack AI chat, embeddings, image, video, speech, and transcription.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-mcp/CHANGELOG.md b/packages/ai-mcp/CHANGELOG.md index 7c030f64a9..f115178875 100644 --- a/packages/ai-mcp/CHANGELOG.md +++ b/packages/ai-mcp/CHANGELOG.md @@ -1,5 +1,155 @@ # @tanstack/ai-mcp +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1848](https://github.com/TanStack/ai/pull/1848) [`e3b2885`](https://github.com/TanStack/ai/commit/e3b28853f7aed75389ef48fcabedaf9286d478bc) - Serve and call MCP extensions. `createMCPServer` takes a `setup` function. It gets each SDK `McpServer` before it connects, so a server can declare an extension in `capabilities.extensions` and add handlers for its methods. `MCPClient.request` sends any request with the SDK `Client.request`, including the methods of an extension. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Use MCP in a TanStack AI harness. + - `@tanstack/ai-mcp/harness` adds `createHarnessMcpServer`. It serves a harness as an MCP server, so Claude Code, Claude Desktop, Cursor, or another agent can use it. The tools are `chat`, `steer`, `cancel`, `approve`, `reject`, `resolve`, `answer`, and `status`, plus `agent_` for each exposed agent and `command_` for each exposed command. Every tool takes an optional `threadId`. With `approvals: 'ask'` (the default), the client asks the user about each approval when it supports elicitation. Otherwise the approvals come back in the result. `approvals: 'auto'` approves every tool call. `resolve` answers every interrupt of a stopped turn in one call, or the waits of one background agent run. It finds the wait in the log, so it also answers a wait that another server, or a server before a restart, opened. A question takes `answer`. Every result lists the open waits of its work in `waits`, each with a `kind` from `waitKind` (`approval`, `question`, `sign-in`, `client-tool`, or `human`). The `status` tool lists every wait, and each background agent with `status: 'running'` or `'waiting'`. + - On a host with `access`, `createHarnessMcpServer` reads the user of each HTTP request with `getUser`. The host checks each tool call of that user. A host without `access` needs `openAccess: true` (no user) or `openAccess: { user }` (one local user), else the server throws at the start. It uses `requestUsers`, the same rule as the HTTP handler. Each tool call releases its session handle when it ends, so the session closes on idle. The `status` tool and the media reads read the thread with `host.observe`, so they set up no plugins. The server forgets a wait when its operation settles. + - `@tanstack/ai-mcp/harness` also adds the `mcp()` harness plugin. It connects stdio and HTTP servers by name, gives the model their tools as `_`, and adds a `/mcp` status command. A stdio server starts once per host for each `mcp()` object, and every session that uses that object shares it. `oauth: true` signs in to a server with `/connect `, for each user. + - `mcp()` connects again with backoff when a server closes, and lists the tools again on `list_changed`. A server that fails its first connect also tries again with backoff. `mcpConnector` and `oauth: true` servers connect again at the next turn, and list their tools again. Each server takes `needsApproval` and `toolName`. The backoff starts again only after a connection stayed open for 30 s, so a server that crashes right after it connects waits longer each time. When two servers give a tool with the same name, `mcp()` warns once. With `onDuplicateTool: 'error'`, the later server fails instead, with an error that names both servers and the tool. + - `@tanstack/ai-mcp/connector` adds `mcpConnector`: one OAuth MCP server as a harness plugin, with `needsApproval`, `prefix`, `scopes`, and `clientName`. The sign-in passes the `iss` of the callback on (RFC 9207). A cancel or a session close stops a running sign-in at once: the loopback stops listening, and the OAuth requests abort. When the MCP SDK refreshes a token, the connector saves it with `credentials.refresh` of the harness: to the scope of the sign-in, and with compare-and-set when the store has it. Each session still sends its own refresh request. When the server refuses a token, the connector deletes the saved sign-in only if it is the token that this session used. When the user signs out while the SDK refreshes, the connector saves no new token, and the call asks for a sign-in. + - `mcp()` and `mcpConnector` answer the `elicitation/create` requests of MCP spec 2025 servers, and the input requests of spec 2026-07-28 servers, as session questions. One tool call can ask up to 5 times. Each question is a live wait of the run that made the tool call: it ends `cancelled` when that run stops. `mcp()` tracks the live questions for each server, so each question goes to the run that called the tool. A spec 2025 request goes to the user only when all the running calls of that server belong to one run. Else the server gets `decline`. + + `@tanstack/ai-harness` is an optional peer dependency. Only the `./harness` and `./connector` entries need it. + +- [#1850](https://github.com/TanStack/ai/pull/1850) [`52cb02d`](https://github.com/TanStack/ai/commit/52cb02de60a9b6df8ed5ced4fe07f4321a8d4c9c) - Reuse a protocol `2026-07-28` `server/discover` result. `MCPClient.getDiscoverResult()` returns the result of the connection, or the adopted prior. `createMCPClient({ prior })` passes a saved one to the SDK `Client.connect`, so the client skips the `server/discover` request. `DiscoverResult` and `PriorDiscovery` are exported as types. + +- [#1849](https://github.com/TanStack/ai/pull/1849) [`a99204a`](https://github.com/TanStack/ai/commit/a99204a08178cc47bdeb5053793c20123aa3d106) - `createMCPServer({ setup })` gets the `handle` context of the request as its second argument, so an extension handler or an instrumentation hook can read the caller. A spec 2025 session with `sessions: 'memory'` gets the context of the request that opened it. + +- [#1816](https://github.com/TanStack/ai/pull/1816) [`3e84606`](https://github.com/TanStack/ai/commit/3e84606afb2d0550520d3f2a4cb8ea88b0a9cdf8) - Add experimental MCP Events (SEP-3415) webhook support. + - `createMCPClient({ experimental_events: { store } | { adapter } })` adds `client.experimental_events` with `list`, `subscribe`, `refresh` and `unsubscribe` (direct) or adapter-delegated operations (managed). + - New `@tanstack/ai-mcp/events` subpath: `createMCPEventWebhook`, `inMemoryMCPEventStore`, `createMCPEventSecret`, `signMCPEventPayload`. + +- [#1883](https://github.com/TanStack/ai/pull/1883) [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3) - Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. + + Add the harness asks from the fifth findings list. + - `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. + - `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. + - A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. + - Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. + - `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. + - A plugin `adapter()` pick with `override: true` wins over the stored thread model. + - `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. + - Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. + - `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. + - `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. + - `HarnessRecord` is exported, for a typed `LogStore` wrapper. + - Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. + - `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. + + Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. + - `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model + turn, for example from a schedule or a webhook. The call goes through the + same middleware, input check, and `permissions()` rules as a model call, and + the call and its result join the transcript. A tool that asks for approval + stops the turn with an interrupt. While interrupts wait, the call is refused + with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom + event. `args` is typed from the input schema of a harness tool. + - `expose.tools` lists the harness tools a client may run with a + `{ op: 'tool', name, args?, meta? }` input, or with the new + `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness + `tools`, and `defineHarness` throws for a name that is not in `tools`. Any + other tool is refused with `not_exposed`. The capabilities document marks + each tool with `exposed`. + - `expose.records` lists the host record types a client may add with an + `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. + A record of another type, or with a `thread` field, is refused with + `not_exposed`. The session log keeps the records. + - `createHarnessMcpServer` adds a `tool_` tool for each tool in + `expose.tools`, and an `append` tool when `expose.records` has types. A tool + input with its own `threadId` field throws when the server is created, + because MCP uses `threadId` to pick the thread. + - `session.send(message, { systemPreamble })` prepends per-run, server-only + system prompts ahead of the harness's own system prompts (for example + host-provided memory). A client input cannot set them. + - A tool call in a harness turn gets `threadId` and `runId` in its execution + context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional + fields for a host to set. + + A host can add fields to the `ctx` an agent's `run` gets. + - `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. + - `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. + + Add `interrupts` to `SubagentBinding`. + - A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. + - The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. + - A child's `ctx.chat({ subagents })` passes the definitions on to its own children. + - A plain `chat()` call does not get them. + + Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. + + Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. + + An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. + + Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. + + Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. + - It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. + - The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. + - Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. + - It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. + - The new `GuardToolCallDecision` type is exported. + + BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: + - `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. + - `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. + - `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. + - `memoryCredentialStore()`: a store in memory, for development and tests. + - `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. + - `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. + + `CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. + + Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. + + `scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. + + `Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. + + Approved edits to tool arguments stay raw until the final input check. + - `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. + - `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. + + A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. + + `chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. + + `WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. + +### Patch Changes + +- [#1871](https://github.com/TanStack/ai/pull/1871) [`d980ce1`](https://github.com/TanStack/ai/commit/d980ce153371404d71b6d4ceac37b0c8293df1d8) - Send the `Mcp-Param-*` headers on spec 2026-07-28 tool calls. A tool argument marked with `x-mcp-header` in the input schema is now copied to its header, so strict servers such as GitHub's remote MCP server accept the call. Spec 2026 calls now go through the SDK `Client.callTool`, and use the SDK timeout, abort, and progress handling. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - The `mcp()`, `codeMode()`, and `skills()` harness plugins send their warnings to the logger of the host (`createHarnessHost({ logger })`). + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + ## 0.9.2 ### Patch Changes diff --git a/packages/ai-mcp/package.json b/packages/ai-mcp/package.json index c453b0e0b0..fca382af0b 100644 --- a/packages/ai-mcp/package.json +++ b/packages/ai-mcp/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-mcp", - "version": "0.9.2", + "version": "1.0.0", "description": "Host-side Model Context Protocol client for TanStack AI: discover and run MCP server tools, resources, and prompts in any adapter's chat() loop, with generated end-to-end types.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-memory/CHANGELOG.md b/packages/ai-memory/CHANGELOG.md index 9b661b61f4..017312e1fe 100644 --- a/packages/ai-memory/CHANGELOG.md +++ b/packages/ai-memory/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-memory +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-event-client@1.0.0 + ## 0.2.16 ### Patch Changes diff --git a/packages/ai-memory/package.json b/packages/ai-memory/package.json index a4e9bf4984..a6512b1916 100644 --- a/packages/ai-memory/package.json +++ b/packages/ai-memory/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-memory", - "version": "0.2.16", + "version": "1.0.0", "description": "Pluggable memory adapters for TanStack AI memoryMiddleware", "author": "", "license": "MIT", diff --git a/packages/ai-mistral/CHANGELOG.md b/packages/ai-mistral/CHANGELOG.md index 14310106a4..9450226a96 100644 --- a/packages/ai-mistral/CHANGELOG.md +++ b/packages/ai-mistral/CHANGELOG.md @@ -1,5 +1,44 @@ # @tanstack/ai-mistral +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.7.2 ### Patch Changes diff --git a/packages/ai-mistral/package.json b/packages/ai-mistral/package.json index 261e04c662..790545f845 100644 --- a/packages/ai-mistral/package.json +++ b/packages/ai-mistral/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-mistral", - "version": "0.7.2", + "version": "1.0.0", "type": "module", "description": "Mistral adapter for TanStack AI", "author": "", diff --git a/packages/ai-neon/CHANGELOG.md b/packages/ai-neon/CHANGELOG.md new file mode 100644 index 0000000000..8feade8409 --- /dev/null +++ b/packages/ai-neon/CHANGELOG.md @@ -0,0 +1,15 @@ +# @tanstack/ai-neon + +## 0.1.0 + +### Minor Changes + +- [#1851](https://github.com/TanStack/ai/pull/1851) [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d) - Add `@tanstack/ai-neon` for the Neon AI Gateway: `neonText` sends Claude to the Anthropic Messages route, codex and `*-pro` models to the Responses route, and every other model to Chat Completions, with `neonEmbedding` and `neonSummarize`. `@tanstack/openai-base` gets a `streamOptions(model)` hook, so a Chat Completions backend that rejects `stream_options` can leave it out. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`ec9023e`](https://github.com/TanStack/ai/commit/ec9023e9be665fbd0ffea3e639280c2216edc16c), [`9f1bdd6`](https://github.com/TanStack/ai/commit/9f1bdd61b4df1d16c23a6ce300fa0424ab824d6a), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/ai-anthropic@1.0.0 + - @tanstack/openai-base@1.0.0 diff --git a/packages/ai-neon/package.json b/packages/ai-neon/package.json index d60a07e5f0..11ccf2d5a0 100644 --- a/packages/ai-neon/package.json +++ b/packages/ai-neon/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-neon", - "version": "0.0.1", + "version": "0.1.0", "description": "Neon AI Gateway adapter for TanStack AI chat, embeddings, and summarization.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-octane/CHANGELOG.md b/packages/ai-octane/CHANGELOG.md index cdd1f1da60..15fdb6c120 100644 --- a/packages/ai-octane/CHANGELOG.md +++ b/packages/ai-octane/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-octane +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.9.1 ### Patch Changes diff --git a/packages/ai-octane/package.json b/packages/ai-octane/package.json index a903961248..ea23ac8e42 100644 --- a/packages/ai-octane/package.json +++ b/packages/ai-octane/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-octane", - "version": "0.9.1", + "version": "1.0.0", "description": "Octane bindings for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Dominic Gannaway", "license": "MIT", diff --git a/packages/ai-ollama/CHANGELOG.md b/packages/ai-ollama/CHANGELOG.md index e88bd14a24..43e4d7c417 100644 --- a/packages/ai-ollama/CHANGELOG.md +++ b/packages/ai-ollama/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-ollama +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.12.2 ### Patch Changes diff --git a/packages/ai-ollama/package.json b/packages/ai-ollama/package.json index 5154c12ed1..522111e3b3 100644 --- a/packages/ai-ollama/package.json +++ b/packages/ai-ollama/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-ollama", - "version": "0.12.2", + "version": "1.0.0", "description": "Ollama adapter for TanStack AI local LLM chat, tool calling, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-ollaya/CHANGELOG.md b/packages/ai-ollaya/CHANGELOG.md index aa50144e5f..71764236f3 100644 --- a/packages/ai-ollaya/CHANGELOG.md +++ b/packages/ai-ollaya/CHANGELOG.md @@ -1,5 +1,41 @@ # @tanstack/ai-ollaya +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1747](https://github.com/TanStack/ai/pull/1747) [`0e44e95`](https://github.com/TanStack/ai/commit/0e44e95a8dba1572295b505c398739147e111fa9) - The TypeSafe, Ollaya, OpenRouter and Vercel Gateway evaluate adapters now set `status` on the error they throw for an error response. `status` is the HTTP status code, so you can tell a rate limit (429) from a bad key (401) without parsing the message. The message does not change. + + ```ts + if (error instanceof Error && 'status' in error && error.status === 429) { + // wait, then call decide() again + } + ``` + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + ## 0.2.7 ### Patch Changes diff --git a/packages/ai-ollaya/package.json b/packages/ai-ollaya/package.json index 75a8df488b..038838d41d 100644 --- a/packages/ai-ollaya/package.json +++ b/packages/ai-ollaya/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-ollaya", - "version": "0.2.7", + "version": "1.0.0", "description": "Ollaya adapter for TanStack AI — typed evaluate decisions against a local Ollaya / laya decision server.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-openai/CHANGELOG.md b/packages/ai-openai/CHANGELOG.md index aa092f0233..549c62f789 100644 --- a/packages/ai-openai/CHANGELOG.md +++ b/packages/ai-openai/CHANGELOG.md @@ -1,5 +1,74 @@ # @tanstack/ai-openai +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1743](https://github.com/TanStack/ai/pull/1743) [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27) - Add `EvaluateError`, a typed error an evaluate adapter throws when the provider answered but the call cannot become a result. `@tanstack/ai` and `@tanstack/ai/adapters` export the class, the `isEvaluateError()` type guard, the `EvaluateErrorInit` type and `EVALUATE_REFUSAL_CODE`. The error keeps what the provider sent back: + - `code`: a stable code to branch on. A refused question uses `EVALUATE_REFUSAL_CODE` (`'refusal'`). + - `usage`: the tokens the call used. + - `model`: the model that answered. + - `answers`: the raw wire answers that came back, before `decide()` maps them. A `choice()` answer has `choice` (for example `{ type: 'choice', choice: 'billing', ... }`), and a `boolean()` answer is `{ type: 'noul', noul: 0.9 }`, not `{ value }`. The refused question has no key. + + When OpenAI refuses to answer a question, `decide()` now throws an `EvaluateError` with `code: 'refusal'` instead of a plain `Error`. If more than one question is refused, the message names the first one. + + Use `isEvaluateError(error)` to narrow a caught error. It checks `name` and `code`, not `instanceof`, so it still works when the app installs more than one copy of `@tanstack/ai`. + + When an adapter throws an `EvaluateError` that carries `usage`, `decide()` reports that usage through the `evaluate:usage` event and the middleware `onUsage` hook, then runs `onError` and rethrows the same error. `onFinish` does not run. + + ```ts + try { + await decide({ adapter, state, questions }) + } catch (error) { + if (isEvaluateError(error) && error.code === EVALUATE_REFUSAL_CODE) { + console.log(error.usage, error.answers) + } + throw error + } + ``` + + The message text does not change. The error is still an `Error`, but its `name` is now `'EvaluateError'`, so logs and the OpenTelemetry `error.type` show that name instead of `'Error'`. + +### Patch Changes + +- [#1857](https://github.com/TanStack/ai/pull/1857) [`483f59a`](https://github.com/TanStack/ai/commit/483f59ac202cf913c6737a379abfb0953afebe56) - Drop `temperature`, `top_p`, and `top_logprobs` on GPT-6 reasoning models, and request encrypted reasoning for those models. OpenAI returns 400 when these fields are sent. They are kept when reasoning effort is `none`, which OpenAI accepts. + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.31.0 ### Minor Changes diff --git a/packages/ai-openai/package.json b/packages/ai-openai/package.json index f35c9d1e1e..c9cc3d4840 100644 --- a/packages/ai-openai/package.json +++ b/packages/ai-openai/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-openai", - "version": "0.31.0", + "version": "1.0.0", "description": "OpenAI adapter for TanStack AI chat, tools, images, video, speech, transcription, realtime, and structured outputs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-opencode/CHANGELOG.md b/packages/ai-opencode/CHANGELOG.md index f0acc9e03d..523ed1cbb9 100644 --- a/packages/ai-opencode/CHANGELOG.md +++ b/packages/ai-opencode/CHANGELOG.md @@ -1,5 +1,36 @@ # @tanstack/ai-opencode +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1862](https://github.com/TanStack/ai/pull/1862) [`460e506`](https://github.com/TanStack/ai/commit/460e50689522848e918521a1ebf3dcc3cf79cd07) - fix(ai-opencode): bound memory while buffering parts before their message role is known + +- [#1858](https://github.com/TanStack/ai/pull/1858) [`647b06f`](https://github.com/TanStack/ai/commit/647b06fa2aea4e5e5b7fd8a0a8e11478c3f780da) - Only translate assistant message parts and wait for OpenCode to provide tool input before emitting a tool call. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-sandbox@1.0.0 + ## 0.5.2 ### Patch Changes diff --git a/packages/ai-opencode/package.json b/packages/ai-opencode/package.json index f693624c12..57a67539c4 100644 --- a/packages/ai-opencode/package.json +++ b/packages/ai-opencode/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-opencode", - "version": "0.5.2", + "version": "1.0.0", "description": "OpenCode harness adapter for TanStack AI — run OpenCode as a chat backend with local tool execution and stateful sessions.", "author": "", "license": "MIT", diff --git a/packages/ai-openrouter/CHANGELOG.md b/packages/ai-openrouter/CHANGELOG.md index 113c105024..37259f9345 100644 --- a/packages/ai-openrouter/CHANGELOG.md +++ b/packages/ai-openrouter/CHANGELOG.md @@ -1,5 +1,44 @@ # @tanstack/ai-openrouter +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1747](https://github.com/TanStack/ai/pull/1747) [`0e44e95`](https://github.com/TanStack/ai/commit/0e44e95a8dba1572295b505c398739147e111fa9) - The TypeSafe, Ollaya, OpenRouter and Vercel Gateway evaluate adapters now set `status` on the error they throw for an error response. `status` is the HTTP status code, so you can tell a rate limit (429) from a bad key (401) without parsing the message. The message does not change. + + ```ts + if (error instanceof Error && 'status' in error && error.status === 429) { + // wait, then call decide() again + } + ``` + +### Patch Changes + +- [#1882](https://github.com/TanStack/ai/pull/1882) [`456bdc4`](https://github.com/TanStack/ai/commit/456bdc4fa5dba2d01889d5073ffe2c418078ea07) - Update model metadata from OpenRouter API + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.23.1 ### Patch Changes diff --git a/packages/ai-openrouter/package.json b/packages/ai-openrouter/package.json index d7e4e50f2d..441d1eeedb 100644 --- a/packages/ai-openrouter/package.json +++ b/packages/ai-openrouter/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-openrouter", - "version": "0.23.1", + "version": "1.0.0", "description": "TanStack AI adapter for OpenRouter chat, provider tools, structured outputs, and access to hundreds of LLMs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-perplexity/CHANGELOG.md b/packages/ai-perplexity/CHANGELOG.md index 38e9af84f0..d883789c35 100644 --- a/packages/ai-perplexity/CHANGELOG.md +++ b/packages/ai-perplexity/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/ai-perplexity +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + ## 0.2.27 ### Patch Changes diff --git a/packages/ai-perplexity/package.json b/packages/ai-perplexity/package.json index e28ab02f91..7c0694ec6e 100644 --- a/packages/ai-perplexity/package.json +++ b/packages/ai-perplexity/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-perplexity", - "version": "0.2.27", + "version": "1.0.0", "description": "Perplexity Search API client and tool for TanStack AI", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-persistence/CHANGELOG.md b/packages/ai-persistence/CHANGELOG.md index 2893ed8bcb..5a50356613 100644 --- a/packages/ai-persistence/CHANGELOG.md +++ b/packages/ai-persistence/CHANGELOG.md @@ -1,5 +1,178 @@ # @tanstack/ai-persistence +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add opt-in session stores. The chat and generation middleware work as before without them. + - `log` (`LogStore`): an append-only log for each session tree, with 15 methods, each with one object argument. Records: `append`, `read`, and `subscribe`. Ownership: `acquireOwnership`, `renewOwnership`, `releaseOwnership`, `pinToWorkers`, `markHostAlive`, and `listLogsWithoutOwner`. A pin (`pinToWorkers`) counts only while its host is alive: `acquireOwnership` and `listLogsWithoutOwner` ignore the affinity of a host with no live `heartbeat({ hostId, ttlMs })`, so the logs of a host that stopped go to other hosts. A host that is alive keeps its pins, also on the logs that it released. The input lane: `offerInput` and `listOfferedInputs`, consumed in the same write with `append({ consumes })`. The owner or the first offer names the harness of a log for `listLogsWithoutOwner`: a later offer does not change it. Snapshots and lifecycle: `getSnapshot`, `putSnapshot`, `truncate`, and `deleteLog`. `acquireOwnership` returns `expired: true` when it takes the log from another owner whose ownership expired with no release. Each fenced write carries the epoch from `acquireOwnership`, and a write with an old epoch rejects with `OwnershipLostError`. A writer that never calls `acquireOwnership` appends with `NO_OWNER_EPOCH`. `pinToWorkers`, `putSnapshot`, and `truncate` need the owner, so they refuse `NO_OWNER_EPOCH`. After `deleteLog`, every fenced write fails until the next `acquireOwnership`, and `offerInput` returns the new `OfferResult` `'deleted'` and stores nothing, so a late write or input cannot bring a deleted log back. `append` rejects with `LogConflictError` when another writer took the position, and `read` rejects with `LogTruncatedError` before the truncation point. `memoryLogStore()` is the reference store. `memoryLogStore({ state })` with one `memoryLogState()` lets two store instances share one log. The conformance kit needs `twin`, a second store set with a new log store instance on the same backend, for the `log` cases across instances. + - `sessions` (`SessionIndexStore`): one index entry per tenant and thread. The key is `{ tenantId?, threadId }` (`SessionIndexKey`), so one thread id in two tenants is two entries. An entry has `members` (`SessionMember`, with the role `owner`, `member`, `viewer`, or `operator`). The owner is the member with the role `owner`. The store has `get(key)`, `getVersioned(key)`, `upsert(entry)`, `upsertIf({ entry, revision })` for compare-and-set writes, `list`, and `delete(key)`, a hard delete. `list` reads one tenant, filters by member, parent thread, title `search`, `harness` name, and exact `metadata` values, and pages with a cursor. + + `defineLogStore` and `defineSessionIndexStore` type an adapter. `memoryPersistence()` now also has `log` and `sessions`. `runPersistenceConformance` runs the cases of each session store when the store is present, so an existing backend needs no `skip` entry. + + With `stores.sessions`, `withPersistence` writes one index entry for each subagent child (`subagent:`), in the tenant of its `tenantId` option. The entry has the parent thread, the tool call, and the `harness` name of the parent entry. It has no members: access to a child goes through its top-level thread. + + `loadChildTranscript(messages, subagentRunId, threadId)` reads the stored messages of a child agent run for a UI. It returns `undefined` for a child of another thread. + +- [#1883](https://github.com/TanStack/ai/pull/1883) [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3) - Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. + + Add the harness asks from the fifth findings list. + - `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. + - `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. + - A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. + - Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. + - `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. + - A plugin `adapter()` pick with `override: true` wins over the stored thread model. + - `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. + - Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. + - `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. + - `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. + - `HarnessRecord` is exported, for a typed `LogStore` wrapper. + - Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. + - `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. + + Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. + - `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model + turn, for example from a schedule or a webhook. The call goes through the + same middleware, input check, and `permissions()` rules as a model call, and + the call and its result join the transcript. A tool that asks for approval + stops the turn with an interrupt. While interrupts wait, the call is refused + with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom + event. `args` is typed from the input schema of a harness tool. + - `expose.tools` lists the harness tools a client may run with a + `{ op: 'tool', name, args?, meta? }` input, or with the new + `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness + `tools`, and `defineHarness` throws for a name that is not in `tools`. Any + other tool is refused with `not_exposed`. The capabilities document marks + each tool with `exposed`. + - `expose.records` lists the host record types a client may add with an + `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. + A record of another type, or with a `thread` field, is refused with + `not_exposed`. The session log keeps the records. + - `createHarnessMcpServer` adds a `tool_` tool for each tool in + `expose.tools`, and an `append` tool when `expose.records` has types. A tool + input with its own `threadId` field throws when the server is created, + because MCP uses `threadId` to pick the thread. + - `session.send(message, { systemPreamble })` prepends per-run, server-only + system prompts ahead of the harness's own system prompts (for example + host-provided memory). A client input cannot set them. + - A tool call in a harness turn gets `threadId` and `runId` in its execution + context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional + fields for a host to set. + + A host can add fields to the `ctx` an agent's `run` gets. + - `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. + - `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. + + Add `interrupts` to `SubagentBinding`. + - A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. + - The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. + - A child's `ctx.chat({ subagents })` passes the definitions on to its own children. + - A plain `chat()` call does not get them. + + Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. + + Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. + + An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. + + Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. + + Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. + - It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. + - The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. + - Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. + - It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. + - The new `GuardToolCallDecision` type is exported. + + BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: + - `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. + - `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. + - `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. + - `memoryCredentialStore()`: a store in memory, for development and tests. + - `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. + - `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. + + `CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. + + Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. + + `scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. + + `Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. + + Approved edits to tool arguments stay raw until the final input check. + - `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. + - `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. + + A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. + + `chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. + + `WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. + +### Patch Changes + +- [#1847](https://github.com/TanStack/ai/pull/1847) [`d3b4cd4`](https://github.com/TanStack/ai/commit/d3b4cd4965552f35273b9c96823ad657af1fe0b5) - Report the conformance cases of an omitted `generationRuns`, `artifacts`, or `blobs` store as skipped. These cases reported a pass when the store was declared in `skip`. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- [#1875](https://github.com/TanStack/ai/pull/1875) [`f6a27bc`](https://github.com/TanStack/ai/commit/f6a27bc33198bff58415dfe8d107f1d5b9525e83) - `withPersistence` now saves activity rows when a run is stopped or fails, so `reconstructChat` restores them after a reload. A plain disconnect on a detachable or interrupted run still writes nothing. + +- [#1805](https://github.com/TanStack/ai/pull/1805) [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31) - Middleware can read `ctx.callMetadata`, the `metadata.tanstack` of the current model call. Each assistant message of the call gets a copy of it. + + With `snapshotStreaming`, `withPersistence` now stores `ctx.callMetadata` on snapshot rows, so a stopped or failed row has the same metadata as a finished one. A stopped or failed row no longer stores other chunk metadata, such as the durability batch hint of `ctx.emitCustomEvent(name, value, { batch: true })`. + +- [#1806](https://github.com/TanStack/ai/pull/1806) [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2) - Fix `withPersistence` failing to resume an interrupt of a subagent tool call with `Tool is unavailable for interrupt .` The parent run now leaves interrupts its child answers to the child, using the new `ctx.childResumeIds` on the middleware context, and still commits them once the run succeeds. + + With `withPersistence`, the resume of a child is server-authoritative: + - The stored interrupt records decide which interrupts a child owns. A resume whose subagent cards claim other interrupts fails with `InterruptResumeValidationError`. + - The child resumes from its stored messages, not from the card the client sent back. `LoadChild` results get an optional `pending` field for this. A middleware that provides `loadChild` must set `pending` for a waiting child, or the agent tool does not resume it. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Keep the answer of a routed agent in its own message when the turn resumes after an interrupt and a finished tool call (for example a handoff) comes before that answer. Before, the stored answer moved onto the message of the tool call. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `withPersistence` lets a subagent that a tool call started check the answers to its own interrupts. The parent run does not check them against its own tools and batch, so a child client tool, and two children that wait at once, resume. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.10.1 ### Patch Changes diff --git a/packages/ai-persistence/package.json b/packages/ai-persistence/package.json index ba972502ac..6e9e841f26 100644 --- a/packages/ai-persistence/package.json +++ b/packages/ai-persistence/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-persistence", - "version": "0.10.1", + "version": "1.0.0", "description": "Composable state persistence for TanStack AI messages, runs, interrupts, metadata, and locks.", "author": "", "license": "MIT", diff --git a/packages/ai-preact/CHANGELOG.md b/packages/ai-preact/CHANGELOG.md index 0c1221f3b4..084851aa66 100644 --- a/packages/ai-preact/CHANGELOG.md +++ b/packages/ai-preact/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-preact +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.21.1 ### Patch Changes diff --git a/packages/ai-preact/package.json b/packages/ai-preact/package.json index 0002f722e7..5cd7f24939 100644 --- a/packages/ai-preact/package.json +++ b/packages/ai-preact/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-preact", - "version": "0.21.1", + "version": "1.0.0", "description": "Preact hooks for TanStack AI streaming chat and typed messages.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-react/CHANGELOG.md b/packages/ai-react/CHANGELOG.md index b0c8b3fce2..dca36accb0 100644 --- a/packages/ai-react/CHANGELOG.md +++ b/packages/ai-react/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-react +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.31.1 ### Patch Changes diff --git a/packages/ai-react/package.json b/packages/ai-react/package.json index 053b03587a..1f94406cfe 100644 --- a/packages/ai-react/package.json +++ b/packages/ai-react/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-react", - "version": "0.31.1", + "version": "1.0.0", "description": "React hooks for TanStack AI streaming chat, realtime voice, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-reactor/CHANGELOG.md b/packages/ai-reactor/CHANGELOG.md index 9ffe10f1e4..767e0820ab 100644 --- a/packages/ai-reactor/CHANGELOG.md +++ b/packages/ai-reactor/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-reactor +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.2.17 ### Patch Changes diff --git a/packages/ai-reactor/package.json b/packages/ai-reactor/package.json index 3d18d13b97..5e7e3eec25 100644 --- a/packages/ai-reactor/package.json +++ b/packages/ai-reactor/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-reactor", - "version": "0.2.17", + "version": "1.0.0", "description": "Reactor adapter for TanStack AI live world and video generation (Orbis, Happy Oyster, LingBot, Helios, FastH3).", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-remix/CHANGELOG.md b/packages/ai-remix/CHANGELOG.md index a2307c1173..d1a616133d 100644 --- a/packages/ai-remix/CHANGELOG.md +++ b/packages/ai-remix/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-remix +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.7.1 ### Patch Changes diff --git a/packages/ai-remix/package.json b/packages/ai-remix/package.json index 722ae4a370..be1483f7bc 100644 --- a/packages/ai-remix/package.json +++ b/packages/ai-remix/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-remix", - "version": "0.7.1", + "version": "1.0.0", "description": "Remix 3 bindings for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-sandbox-blaxel/CHANGELOG.md b/packages/ai-sandbox-blaxel/CHANGELOG.md index 113d623e64..443bb3879f 100644 --- a/packages/ai-sandbox-blaxel/CHANGELOG.md +++ b/packages/ai-sandbox-blaxel/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-blaxel +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.3.1 ### Patch Changes diff --git a/packages/ai-sandbox-blaxel/package.json b/packages/ai-sandbox-blaxel/package.json index 128312e4d6..328b530335 100644 --- a/packages/ai-sandbox-blaxel/package.json +++ b/packages/ai-sandbox-blaxel/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-blaxel", - "version": "0.3.1", + "version": "1.0.0", "description": "Blaxel sandbox provider for TanStack AI — run harness adapters inside isolated Blaxel cloud sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-boxd/CHANGELOG.md b/packages/ai-sandbox-boxd/CHANGELOG.md index 02981d013d..1e31981115 100644 --- a/packages/ai-sandbox-boxd/CHANGELOG.md +++ b/packages/ai-sandbox-boxd/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-boxd +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.2.1 ### Patch Changes diff --git a/packages/ai-sandbox-boxd/package.json b/packages/ai-sandbox-boxd/package.json index aa4689796c..a556ffdb47 100644 --- a/packages/ai-sandbox-boxd/package.json +++ b/packages/ai-sandbox-boxd/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-boxd", - "version": "0.2.1", + "version": "1.0.0", "description": "boxd sandbox provider for TanStack AI — run harness adapters inside isolated boxd KVM microVMs through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-cloudflare/CHANGELOG.md b/packages/ai-sandbox-cloudflare/CHANGELOG.md index 04919a3c52..b09a36b693 100644 --- a/packages/ai-sandbox-cloudflare/CHANGELOG.md +++ b/packages/ai-sandbox-cloudflare/CHANGELOG.md @@ -1,5 +1,52 @@ # @tanstack/ai-sandbox-cloudflare +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-sandbox@1.0.0 + - @tanstack/ai-sandbox-local-process@1.0.0 + ## 0.4.17 ### Patch Changes diff --git a/packages/ai-sandbox-cloudflare/package.json b/packages/ai-sandbox-cloudflare/package.json index d193c368ec..34a29cc2ff 100644 --- a/packages/ai-sandbox-cloudflare/package.json +++ b/packages/ai-sandbox-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-cloudflare", - "version": "0.4.17", + "version": "1.0.0", "description": "Cloudflare sandbox provider for TanStack AI — run harness adapters inside Cloudflare Containers (edge) through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-daytona/CHANGELOG.md b/packages/ai-sandbox-daytona/CHANGELOG.md index 71caa96a3a..4317a0f6f4 100644 --- a/packages/ai-sandbox-daytona/CHANGELOG.md +++ b/packages/ai-sandbox-daytona/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-daytona +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.3.5 ### Patch Changes diff --git a/packages/ai-sandbox-daytona/package.json b/packages/ai-sandbox-daytona/package.json index 5c141b53c7..2bd3434d2d 100644 --- a/packages/ai-sandbox-daytona/package.json +++ b/packages/ai-sandbox-daytona/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-daytona", - "version": "0.3.5", + "version": "1.0.0", "description": "Daytona sandbox provider for TanStack AI — run harness adapters inside isolated Daytona cloud sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-docker/CHANGELOG.md b/packages/ai-sandbox-docker/CHANGELOG.md index bba1b9b790..8a9c0c8da1 100644 --- a/packages/ai-sandbox-docker/CHANGELOG.md +++ b/packages/ai-sandbox-docker/CHANGELOG.md @@ -1,5 +1,56 @@ # @tanstack/ai-sandbox-docker +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `dockerSandbox()` now copies a `localSource(dir)` folder into a new container: the files that git lists, their uncommitted changes, and the history of the current branch. The folder must be a Git repository, and the image must have git (for example `node:24`). + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `resume()` of `dockerSandbox()` gives `null` only for a container that Docker does not have. Any other error, such as Docker not running, now goes to the caller, so a user sees "Docker is not running" and not "the workspace is gone". + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.3.2 ### Patch Changes diff --git a/packages/ai-sandbox-docker/package.json b/packages/ai-sandbox-docker/package.json index f93578aa61..ba231b39d0 100644 --- a/packages/ai-sandbox-docker/package.json +++ b/packages/ai-sandbox-docker/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-docker", - "version": "0.3.2", + "version": "1.0.0", "description": "Docker sandbox providers for TanStack AI — dockerSandbox() runs a container; sbxSandbox() runs a Docker Sandboxes microVM.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-e2b/CHANGELOG.md b/packages/ai-sandbox-e2b/CHANGELOG.md index bd5c17ed28..9cafed7282 100644 --- a/packages/ai-sandbox-e2b/CHANGELOG.md +++ b/packages/ai-sandbox-e2b/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-e2b +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/ai-sandbox-e2b/package.json b/packages/ai-sandbox-e2b/package.json index b1f5c33efd..524a0e0916 100644 --- a/packages/ai-sandbox-e2b/package.json +++ b/packages/ai-sandbox-e2b/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-e2b", - "version": "0.1.0", + "version": "1.0.0", "description": "E2B sandbox provider for TanStack AI — run harness adapters inside isolated E2B cloud sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-local-process/CHANGELOG.md b/packages/ai-sandbox-local-process/CHANGELOG.md index fc84a4c9ea..6aba446f04 100644 --- a/packages/ai-sandbox-local-process/CHANGELOG.md +++ b/packages/ai-sandbox-local-process/CHANGELOG.md @@ -1,5 +1,55 @@ # @tanstack/ai-sandbox-local-process +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - A command in `localProcessSandbox` gets only a few variables of the host process: `PATH`, `HOME`, `LANG`, `LC_ALL`, `TMPDIR`, `TEMP`, `TMP`, and on Windows `SystemRoot`, `ComSpec`, `PATHEXT`, `WINDIR`, and `USERPROFILE`. The workspace secrets and the env of the call still reach it. Provider keys and other secrets of the server do not. If a command needs another variable of the host, set it as a workspace secret or in the env of the call. `passEnv` names more variables of the host for each command, for example `HTTPS_PROXY` or `CLAUDE_CONFIG_DIR`. `scrubEnv` still removes a variable from the env of each command. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.2.6 ### Patch Changes diff --git a/packages/ai-sandbox-local-process/package.json b/packages/ai-sandbox-local-process/package.json index f47989a778..7797cb1502 100644 --- a/packages/ai-sandbox-local-process/package.json +++ b/packages/ai-sandbox-local-process/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-local-process", - "version": "0.2.6", + "version": "1.0.0", "description": "Local-process sandbox provider for TanStack AI — runs the agent directly on the host through the uniform SandboxHandle (no isolation; trusted/dev use).", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-railway/CHANGELOG.md b/packages/ai-sandbox-railway/CHANGELOG.md index 942def0767..8e0410e15c 100644 --- a/packages/ai-sandbox-railway/CHANGELOG.md +++ b/packages/ai-sandbox-railway/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-railway +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/ai-sandbox-railway/package.json b/packages/ai-sandbox-railway/package.json index a9231f0b43..2b722fe282 100644 --- a/packages/ai-sandbox-railway/package.json +++ b/packages/ai-sandbox-railway/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-railway", - "version": "0.1.0", + "version": "1.0.0", "description": "Railway sandbox provider for TanStack AI — run harness adapters inside Railway sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-sprites/CHANGELOG.md b/packages/ai-sandbox-sprites/CHANGELOG.md index ed6d0956d5..a3c1cb6e3e 100644 --- a/packages/ai-sandbox-sprites/CHANGELOG.md +++ b/packages/ai-sandbox-sprites/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-sprites +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.2.5 ### Patch Changes diff --git a/packages/ai-sandbox-sprites/package.json b/packages/ai-sandbox-sprites/package.json index 2016b299d3..b0543c478e 100644 --- a/packages/ai-sandbox-sprites/package.json +++ b/packages/ai-sandbox-sprites/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-sprites", - "version": "0.2.5", + "version": "1.0.0", "description": "Sprites sandbox provider for TanStack AI — run harness adapters inside isolated Fly.io Sprite stateful sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-upstash-box/CHANGELOG.md b/packages/ai-sandbox-upstash-box/CHANGELOG.md index 892d3dc6a9..78b83a88de 100644 --- a/packages/ai-sandbox-upstash-box/CHANGELOG.md +++ b/packages/ai-sandbox-upstash-box/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-upstash-box +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.2.0 ### Minor Changes diff --git a/packages/ai-sandbox-upstash-box/package.json b/packages/ai-sandbox-upstash-box/package.json index 07408695da..5c54d0fe91 100644 --- a/packages/ai-sandbox-upstash-box/package.json +++ b/packages/ai-sandbox-upstash-box/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-upstash-box", - "version": "0.2.0", + "version": "1.0.0", "description": "Upstash Box sandbox provider for TanStack AI — run harness adapters inside isolated Upstash Box cloud sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox-vercel/CHANGELOG.md b/packages/ai-sandbox-vercel/CHANGELOG.md index 9426c4ec7c..bffcb9569b 100644 --- a/packages/ai-sandbox-vercel/CHANGELOG.md +++ b/packages/ai-sandbox-vercel/CHANGELOG.md @@ -1,5 +1,50 @@ # @tanstack/ai-sandbox-vercel +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-sandbox@1.0.0 + ## 0.2.5 ### Patch Changes diff --git a/packages/ai-sandbox-vercel/package.json b/packages/ai-sandbox-vercel/package.json index 0040a3137d..430cef17be 100644 --- a/packages/ai-sandbox-vercel/package.json +++ b/packages/ai-sandbox-vercel/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox-vercel", - "version": "0.2.5", + "version": "1.0.0", "description": "Vercel Sandbox provider for TanStack AI — run harness adapters inside isolated Vercel microVM sandboxes through the uniform SandboxHandle.", "author": "", "license": "MIT", diff --git a/packages/ai-sandbox/CHANGELOG.md b/packages/ai-sandbox/CHANGELOG.md index e1ad980508..1b1aae5dcf 100644 --- a/packages/ai-sandbox/CHANGELOG.md +++ b/packages/ai-sandbox/CHANGELOG.md @@ -1,5 +1,160 @@ # @tanstack/ai-sandbox +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `@tanstack/ai-sandbox/harness` for `@tanstack/ai-harness`: + - `codingAgents({ sandbox, agents, workspace? })` is a harness plugin. The lead model gets one tool per coding agent (Claude Code, Codex, Grok Build, or any ACP agent). Each agent works in the sandbox, keeps its own session per thread (also after a restart), and starts read-only in the `plan` mode of `permissions()`. `/fresh [agent]` starts a new session. `workspace: 'shared'` (default) runs the agents of a thread one at a time in one sandbox. `'per-agent'` gives each agent its own sandbox. + - `codingAgents` runs agents only on the host that owns the log of the thread, so `'shared'` runs one agent at a time also with many hosts. + - `sandboxWorkspaceBackend(sandbox, { owned? })` runs the coding tools of `@tanstack/ai-harness/plugins/coding` (`workspaceTools()`, `snapshots()`, `formatter()`) in a sandbox. It resolves links in the sandbox, reads one page of a file in the sandbox, and stops background jobs by their id (the pid and its start time), also from another host. It never stops another process that got the pid of a job. `binding()` gives the provider and the sandbox id, so another host can resume the sandbox. `close()` stops the jobs of the backend. A session close closes it with `'moved'`, so an owned sandbox stays for the next host. `host.sessions.delete` closes it with `'closed'`, and with `owned: true` that destroys the sandbox. + + `@tanstack/ai-harness` is an optional peer dependency. + +- [#1883](https://github.com/TanStack/ai/pull/1883) [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3) - Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. + + Add the harness asks from the fifth findings list. + - `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. + - `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. + - A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. + - Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. + - `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. + - A plugin `adapter()` pick with `override: true` wins over the stored thread model. + - `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. + - Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. + - `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. + - `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. + - `HarnessRecord` is exported, for a typed `LogStore` wrapper. + - Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. + - `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. + + Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. + - `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model + turn, for example from a schedule or a webhook. The call goes through the + same middleware, input check, and `permissions()` rules as a model call, and + the call and its result join the transcript. A tool that asks for approval + stops the turn with an interrupt. While interrupts wait, the call is refused + with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom + event. `args` is typed from the input schema of a harness tool. + - `expose.tools` lists the harness tools a client may run with a + `{ op: 'tool', name, args?, meta? }` input, or with the new + `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness + `tools`, and `defineHarness` throws for a name that is not in `tools`. Any + other tool is refused with `not_exposed`. The capabilities document marks + each tool with `exposed`. + - `expose.records` lists the host record types a client may add with an + `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. + A record of another type, or with a `thread` field, is refused with + `not_exposed`. The session log keeps the records. + - `createHarnessMcpServer` adds a `tool_` tool for each tool in + `expose.tools`, and an `append` tool when `expose.records` has types. A tool + input with its own `threadId` field throws when the server is created, + because MCP uses `threadId` to pick the thread. + - `session.send(message, { systemPreamble })` prepends per-run, server-only + system prompts ahead of the harness's own system prompts (for example + host-provided memory). A client input cannot set them. + - A tool call in a harness turn gets `threadId` and `runId` in its execution + context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional + fields for a host to set. + + A host can add fields to the `ctx` an agent's `run` gets. + - `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. + - `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. + + Add `interrupts` to `SubagentBinding`. + - A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. + - The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. + - A child's `ctx.chat({ subagents })` passes the definitions on to its own children. + - A plain `chat()` call does not get them. + + Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. + + Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. + + An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. + + Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. + + Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. + - It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. + - The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. + - Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. + - It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. + - The new `GuardToolCallDecision` type is exported. + + BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: + - `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. + - `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. + - `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. + - `memoryCredentialStore()`: a store in memory, for development and tests. + - `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. + - `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. + + `CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. + + Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. + + `scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. + + `Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. + + Approved edits to tool arguments stay raw until the final input check. + - `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. + - `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. + + A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. + + `chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. + + `WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`d3b4cd4`](https://github.com/TanStack/ai/commit/d3b4cd4965552f35273b9c96823ad657af1fe0b5), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`f6a27bc`](https://github.com/TanStack/ai/commit/f6a27bc33198bff58415dfe8d107f1d5b9525e83), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/ai-persistence@1.0.0 + - @tanstack/ai-skills@1.0.0 + ## 0.5.25 ### Patch Changes diff --git a/packages/ai-sandbox/package.json b/packages/ai-sandbox/package.json index 6d5f53986f..57a6dca4a4 100644 --- a/packages/ai-sandbox/package.json +++ b/packages/ai-sandbox/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-sandbox", - "version": "0.5.25", + "version": "1.0.0", "description": "Provider-agnostic sandbox layer for TanStack AI — run harness adapters inside isolated sandboxes (defineSandbox, defineWorkspace, withSandbox) with a uniform SandboxHandle, workspace bootstrap, policy, and resumable lifecycle.", "author": "", "license": "MIT", diff --git a/packages/ai-skills/CHANGELOG.md b/packages/ai-skills/CHANGELOG.md index 85e6b7f2a9..ffad3ee94f 100644 --- a/packages/ai-skills/CHANGELOG.md +++ b/packages/ai-skills/CHANGELOG.md @@ -1,5 +1,38 @@ # @tanstack/ai-skills +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - `@tanstack/ai-skills/harness`: the new `skills({ dirs })` plugin gives the harness model the skills of a list of folders, and makes each skill a `/` command that starts a turn with that skill. A skill with the name of another command is `/skill:`, and `/skills` lists them. The plugin watches the folders, so a skill that you add or remove while the session runs changes the commands at once. The watcher lives as long as the host, every session that uses the same `skills()` object shares it, and a change makes each session read the folders again. A skill that does not load gets a fallback message. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - The `mcp()`, `codeMode()`, and `skills()` harness plugins send their warnings to the logger of the host (`createHarnessHost({ logger })`). + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`a5c2af3`](https://github.com/TanStack/ai/commit/a5c2af3e93b8359209ea3c44856e4c06599387dc), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-harness@0.1.0 + ## 0.1.21 ### Patch Changes diff --git a/packages/ai-skills/package.json b/packages/ai-skills/package.json index 63347425fe..f46c8709fd 100644 --- a/packages/ai-skills/package.json +++ b/packages/ai-skills/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-skills", - "version": "0.1.21", + "version": "1.0.0", "description": "Portable Agent Skills (SKILL.md) as a first-class chat() middleware for TanStack AI.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-solid/CHANGELOG.md b/packages/ai-solid/CHANGELOG.md index 8b9a126900..1c7b495d30 100644 --- a/packages/ai-solid/CHANGELOG.md +++ b/packages/ai-solid/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-solid +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.27.1 ### Patch Changes diff --git a/packages/ai-solid/package.json b/packages/ai-solid/package.json index a4d659d90c..e69af4c6be 100644 --- a/packages/ai-solid/package.json +++ b/packages/ai-solid/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-solid", - "version": "0.27.1", + "version": "1.0.0", "description": "Solid hooks for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-svelte/CHANGELOG.md b/packages/ai-svelte/CHANGELOG.md index 00aeff9438..198fd882de 100644 --- a/packages/ai-svelte/CHANGELOG.md +++ b/packages/ai-svelte/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-svelte +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.26.1 ### Patch Changes diff --git a/packages/ai-svelte/package.json b/packages/ai-svelte/package.json index 73c95d4b1a..c24c689fbd 100644 --- a/packages/ai-svelte/package.json +++ b/packages/ai-svelte/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-svelte", - "version": "0.26.1", + "version": "1.0.0", "description": "Svelte 5 bindings for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-typesafe/CHANGELOG.md b/packages/ai-typesafe/CHANGELOG.md index ac1921596a..e1ac4f17be 100644 --- a/packages/ai-typesafe/CHANGELOG.md +++ b/packages/ai-typesafe/CHANGELOG.md @@ -1,5 +1,42 @@ # @tanstack/ai-typesafe +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1747](https://github.com/TanStack/ai/pull/1747) [`0e44e95`](https://github.com/TanStack/ai/commit/0e44e95a8dba1572295b505c398739147e111fa9) - The TypeSafe, Ollaya, OpenRouter and Vercel Gateway evaluate adapters now set `status` on the error they throw for an error response. `status` is the HTTP status code, so you can tell a rate limit (429) from a bad key (401) without parsing the message. The message does not change. + + ```ts + if (error instanceof Error && 'status' in error && error.status === 429) { + // wait, then call decide() again + } + ``` + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.1.14 ### Patch Changes diff --git a/packages/ai-typesafe/package.json b/packages/ai-typesafe/package.json index f249a0f6ea..3ebc8e5566 100644 --- a/packages/ai-typesafe/package.json +++ b/packages/ai-typesafe/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-typesafe", - "version": "0.1.14", + "version": "1.0.0", "description": "TypeSafe Jev adapter for TanStack AI — typed evaluate decisions over HTTP.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-utils/CHANGELOG.md b/packages/ai-utils/CHANGELOG.md index 6e4fed09ff..5eacb8411d 100644 --- a/packages/ai-utils/CHANGELOG.md +++ b/packages/ai-utils/CHANGELOG.md @@ -1,5 +1,30 @@ # @tanstack/ai-utils +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Add `commandEnv(env, platform, passEnv?)`, the short env of a command that a process starts (no provider keys or other secrets of the server), and `createOutputTail(maxBytes)`, the newest output of a command. `@tanstack/ai-harness`, `@tanstack/ai-sandbox`, and `@tanstack/ai-sandbox-local-process` use them. + ## 0.5.0 ### Minor Changes diff --git a/packages/ai-utils/package.json b/packages/ai-utils/package.json index ce4946d803..30bd601540 100644 --- a/packages/ai-utils/package.json +++ b/packages/ai-utils/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-utils", - "version": "0.5.0", + "version": "1.0.0", "description": "Shared TypeScript utilities for TanStack AI provider adapters and runtime packages.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-vercel-gateway/CHANGELOG.md b/packages/ai-vercel-gateway/CHANGELOG.md index a7e40452b7..efb4bc400e 100644 --- a/packages/ai-vercel-gateway/CHANGELOG.md +++ b/packages/ai-vercel-gateway/CHANGELOG.md @@ -1,5 +1,47 @@ # @tanstack/ai-vercel-gateway +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1747](https://github.com/TanStack/ai/pull/1747) [`0e44e95`](https://github.com/TanStack/ai/commit/0e44e95a8dba1572295b505c398739147e111fa9) - The TypeSafe, Ollaya, OpenRouter and Vercel Gateway evaluate adapters now set `status` on the error they throw for an error response. `status` is the HTTP status code, so you can tell a rate limit (429) from a bad key (401) without parsing the message. The message does not change. + + ```ts + if (error instanceof Error && 'status' in error && error.status === 429) { + // wait, then call decide() again + } + ``` + +### Patch Changes + +- [#1882](https://github.com/TanStack/ai/pull/1882) [`456bdc4`](https://github.com/TanStack/ai/commit/456bdc4fa5dba2d01889d5073ffe2c418078ea07) - Update model metadata from OpenRouter API + +- [#1873](https://github.com/TanStack/ai/pull/1873) [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32) - Surface Vercel AI Gateway request cost on `usage.cost`, with the market price in `usage.costDetails.upstreamCost`. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e), [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + - @tanstack/openai-base@1.0.0 + ## 0.4.2 ### Patch Changes diff --git a/packages/ai-vercel-gateway/package.json b/packages/ai-vercel-gateway/package.json index f6f1fb0a54..8632edd103 100644 --- a/packages/ai-vercel-gateway/package.json +++ b/packages/ai-vercel-gateway/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-vercel-gateway", - "version": "0.4.2", + "version": "1.0.0", "description": "Vercel AI Gateway adapter for TanStack AI chat, embeddings, and image generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-vertex/CHANGELOG.md b/packages/ai-vertex/CHANGELOG.md index e14ae31d94..2e68614b98 100644 --- a/packages/ai-vertex/CHANGELOG.md +++ b/packages/ai-vertex/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-vertex +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`456bdc4`](https://github.com/TanStack/ai/commit/456bdc4fa5dba2d01889d5073ffe2c418078ea07), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-gemini@1.0.0 + ## 0.2.31 ### Patch Changes diff --git a/packages/ai-vertex/package.json b/packages/ai-vertex/package.json index f57ffd119a..ed91417518 100644 --- a/packages/ai-vertex/package.json +++ b/packages/ai-vertex/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-vertex", - "version": "0.2.31", + "version": "1.0.0", "description": "Google Vertex AI adapter for TanStack AI. Runs Gemini models on Vertex with regional endpoints and Google Cloud credentials.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-vue/CHANGELOG.md b/packages/ai-vue/CHANGELOG.md index bc16da21ea..711f13bc7e 100644 --- a/packages/ai-vue/CHANGELOG.md +++ b/packages/ai-vue/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-vue +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`9f5a18a`](https://github.com/TanStack/ai/commit/9f5a18a1837d54cc5dcb009837e23c16b4f55787), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-client@1.0.0 + ## 0.27.1 ### Patch Changes diff --git a/packages/ai-vue/package.json b/packages/ai-vue/package.json index a9f208aab3..8c2a0a1b3c 100644 --- a/packages/ai-vue/package.json +++ b/packages/ai-vue/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-vue", - "version": "0.27.1", + "version": "1.0.0", "description": "Vue composables for TanStack AI streaming chat, structured outputs, and media generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai-worldlabs/CHANGELOG.md b/packages/ai-worldlabs/CHANGELOG.md index bc302c010d..4f8361889e 100644 --- a/packages/ai-worldlabs/CHANGELOG.md +++ b/packages/ai-worldlabs/CHANGELOG.md @@ -1,5 +1,32 @@ # @tanstack/ai-worldlabs +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.1.10 ### Patch Changes diff --git a/packages/ai-worldlabs/package.json b/packages/ai-worldlabs/package.json index 89ed7da490..1deff9ba8a 100644 --- a/packages/ai-worldlabs/package.json +++ b/packages/ai-worldlabs/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai-worldlabs", - "version": "0.1.10", + "version": "1.0.0", "description": "World Labs adapter for TanStack AI world generation (Marble).", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/ai/CHANGELOG.md b/packages/ai/CHANGELOG.md index 1386ff10d0..a705c8438c 100644 --- a/packages/ai/CHANGELOG.md +++ b/packages/ai/CHANGELOG.md @@ -1,5 +1,205 @@ # @tanstack/ai +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1743](https://github.com/TanStack/ai/pull/1743) [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27) - Add `EvaluateError`, a typed error an evaluate adapter throws when the provider answered but the call cannot become a result. `@tanstack/ai` and `@tanstack/ai/adapters` export the class, the `isEvaluateError()` type guard, the `EvaluateErrorInit` type and `EVALUATE_REFUSAL_CODE`. The error keeps what the provider sent back: + - `code`: a stable code to branch on. A refused question uses `EVALUATE_REFUSAL_CODE` (`'refusal'`). + - `usage`: the tokens the call used. + - `model`: the model that answered. + - `answers`: the raw wire answers that came back, before `decide()` maps them. A `choice()` answer has `choice` (for example `{ type: 'choice', choice: 'billing', ... }`), and a `boolean()` answer is `{ type: 'noul', noul: 0.9 }`, not `{ value }`. The refused question has no key. + + When OpenAI refuses to answer a question, `decide()` now throws an `EvaluateError` with `code: 'refusal'` instead of a plain `Error`. If more than one question is refused, the message names the first one. + + Use `isEvaluateError(error)` to narrow a caught error. It checks `name` and `code`, not `instanceof`, so it still works when the app installs more than one copy of `@tanstack/ai`. + + When an adapter throws an `EvaluateError` that carries `usage`, `decide()` reports that usage through the `evaluate:usage` event and the middleware `onUsage` hook, then runs `onError` and rethrows the same error. `onFinish` does not run. + + ```ts + try { + await decide({ adapter, state, questions }) + } catch (error) { + if (isEvaluateError(error) && error.code === EVALUATE_REFUSAL_CODE) { + console.log(error.usage, error.answers) + } + throw error + } + ``` + + The message text does not change. The error is still an `Error`, but its `name` is now `'EvaluateError'`, so logs and the OpenTelemetry `error.type` show that name instead of `'Error'`. + +- [#1806](https://github.com/TanStack/ai/pull/1806) [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2) - Fix `withPersistence` failing to resume an interrupt of a subagent tool call with `Tool is unavailable for interrupt .` The parent run now leaves interrupts its child answers to the child, using the new `ctx.childResumeIds` on the middleware context, and still commits them once the run succeeds. + + With `withPersistence`, the resume of a child is server-authoritative: + - The stored interrupt records decide which interrupts a child owns. A resume whose subagent cards claim other interrupts fails with `InterruptResumeValidationError`. + - The child resumes from its stored messages, not from the card the client sent back. `LoadChild` results get an optional `pending` field for this. A middleware that provides `loadChild` must set `pending` for a waiting child, or the agent tool does not resume it. + +- [#1880](https://github.com/TanStack/ai/pull/1880) [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f) - Put the provider error type and the request id on `RUN_ERROR`. The Anthropic adapter and the adapters built on `@tanstack/openai-base` set `errorType` (for example `overloaded_error`) and `requestId` (from the SDK error or the `request-id` / `x-request-id` header). `chat()` moves both to `metadata.tanstack`, so the client gets them too. `code` stays the HTTP status. Adapter authors can read both values with `toRunErrorDetails` from `@tanstack/ai/adapter-internals`. + +- [#1883](https://github.com/TanStack/ai/pull/1883) [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3) - Core support for the harness: subagent binding options, the `onGuardToolCall` hook, server-side BYOK keys, harness tool runs, checked streamed `outputSchema` results, and resume fixes. + + Add the harness asks from the fifth findings list. + - `chat({ outputSchema, stream: true })` now checks the full result against a Standard Schema. A failure ends with `RUN_ERROR` `structured-output-validation-failed`, with the model text in `metadata.tanstack.rawText`. + - `session.send(prompt, { outputSchema })` gives the turn a typed `structured` value. It is per send only, and the HTTP handler does not take it. + - A server tool reads run capabilities with `context.get(capability)` and `context.getOptional(capability)`, for example the sandbox under `withSandbox`. + - Readers keep the full history after a durable compaction. `session.transcript()`, `GET transcript`, and the chat hydration show every message. The model still gets the compacted context. + - `createHarnessHost({ acceptInput })` sees each input after the access check and before the log keeps it. It can change the input or refuse it. + - A plugin `adapter()` pick with `override: true` wins over the stored thread model. + - `onModelError` can return `{ retry: true, adapter }` to retry on another model. `ModelErrorContext` has `adapter` and `model`. + - Middleware reads `ctx.context.run.source` and `label` to tell a turn call from a plugin, router, or transfer call. + - `host.sessions.archive()` and `unarchive()`. Lists hide archived threads unless you pass `withArchived: true`. + - `host.sessions.eraseUser({ harness, threadId, userId, replies })` replaces one person's messages with `[removed]`, deletes their media, and cuts the log before a new snapshot. The new `erase` access action guards it. + - `HarnessRecord` is exported, for a typed `LogStore` wrapper. + - Coding-tool file calls pass their abort signal through `WorkspaceBackend` to the sandbox. + - `withCompaction` limits (`maxTokens`, `contextWindow`, `background.atTokens`) can be a function of `{ model }`. + + Run a harness tool with no model turn, add host records from a client, and add a per-run system preamble. + - `session.runTool({ name, args?, meta?, inputId?, user? })` runs one harness tool with no model + turn, for example from a schedule or a webhook. The call goes through the + same middleware, input check, and `permissions()` rules as a model call, and + the call and its result join the transcript. A tool that asks for approval + stops the turn with an interrupt. While interrupts wait, the call is refused + with `pending_interrupts`. `meta` is echoed as a `tanstack.injection` custom + event. `args` is typed from the input schema of a harness tool. + - `expose.tools` lists the harness tools a client may run with a + `{ op: 'tool', name, args?, meta? }` input, or with the new + `client.runTool({ name, args?, meta?, inputId? })`. The list is typed from the harness + `tools`, and `defineHarness` throws for a name that is not in `tools`. Any + other tool is refused with `not_exposed`. The capabilities document marks + each tool with `exposed`. + - `expose.records` lists the host record types a client may add with an + `{ op: 'append', records }` input, or with the new `client.appendRecords({ records })`. + A record of another type, or with a `thread` field, is refused with + `not_exposed`. The session log keeps the records. + - `createHarnessMcpServer` adds a `tool_` tool for each tool in + `expose.tools`, and an `append` tool when `expose.records` has types. A tool + input with its own `threadId` field throws when the server is created, + because MCP uses `threadId` to pick the thread. + - `session.send(message, { systemPreamble })` prepends per-run, server-only + system prompts ahead of the harness's own system prompts (for example + host-provided memory). A client input cannot set them. + - A tool call in a harness turn gets `threadId` and `runId` in its execution + context. `ToolExecutionContext` in `@tanstack/ai` has the two new optional + fields for a host to set. + + A host can add fields to the `ctx` an agent's `run` gets. + - `subagents.binding.extend(ctx)` returns the fields to add. A child's `ctx.chat({ subagents })` passes it down, so the fields reach nested children too. + - `SubagentContextExtension` is an empty interface that `SubagentRunContext` includes. A package augments it to type its fields, for example `ctx.harness` from `@tanstack/ai-harness`. Make each field optional, because a run that a plain `chat()` starts has no host. + + Add `interrupts` to `SubagentBinding`. + - A host sets `binding.interrupts` to give interrupt definitions to every `ctx.chat` call of an agent run. Then the host middleware in `chatMiddleware` can stop the child with these interrupts. + - The own `interrupts` of the call win. When a host definition has the same id as one of the call, the host definition is not added. + - A child's `ctx.chat({ subagents })` passes the definitions on to its own children. + - A plain `chat()` call does not get them. + + Add `lastChatMiddleware` to `SubagentBinding`. It runs after the own middleware of each `ctx.chat` call of an agent run, so it sees the final model context and tool results. A child's `ctx.chat({ subagents })` passes it on, after the child's own. + + Add `validateJsonSchema(schema, value)`. It checks a value against a JSON Schema with `@cfworker/json-schema`, as a tool input is checked, but with no repair. The result has the Standard Schema shape: `{ value }` or `{ issues }`. The root also exports the `StandardSchemaV1` and `StandardJSONSchemaV1` types. + + An agent `run` that throws the shape of `MCPInputRequiredError` (`name`, `kind`, `request`) stops the child as `suspended`, as a tool does, and the parent run stops with its interrupt. The interrupt has a generic binding and no tool call. Its id is the `interruptId` of the thrown value, else `mcp_input_`, and its message is the error message. The resume runs the child again, and `ctx.resume` has the answer. + + Add `SubagentBinding.debug`, the `debug` option for the model calls of child agents that set no `debug` of their own. + + Add the `onGuardToolCall` middleware hook for checks that must always run, such as permissions. + - It runs for every tool call, after all `onBeforeToolCall` hooks and after the `inputSchema` check. `hookCtx.args` holds the final checked arguments that the tool gets. + - The guard of every middleware runs, in order, until one returns a decision. An earlier `onBeforeToolCall` decision does not skip it. + - Return `{ type: 'skip', result }` to deny the call. The tool does not run, and the model gets `result`, the same as an `onBeforeToolCall` skip. Return `{ type: 'abort', reason }` to abort the run. + - It runs before a server tool runs and before a client tool goes to the client. A guard cannot change the arguments. + - The new `GuardToolCallDecision` type is exported. + + BYOK keys can now live on the server. `@tanstack/ai/byok` exports the `CredentialStore` contract, the `Credential` and `CredentialScope` types, and `defineCredentialStore`. A `CredentialScope` has `tenantId` and `userId`. Its `threadId` is optional, and a store ignores it. `@tanstack/ai/byok/server` adds: + - `storedProviderKeys(store, scope)`: provider keys from the `api_key` credentials of a user, then of the tenant, then the provider's `env` names. Pass `keys.adapter(...)` to `chat()` and `keys.get` to `subagents.keys`. + - `readCredential(store, scope, id)`: one credential, the user's own first, then the tenant's. A user with no tenant reads only their own. + - `tenantScopeOf(scope)`: the tenant scope of a user scope, or `undefined` when the scope has no user or no tenant. + - `memoryCredentialStore()`: a store in memory, for development and tests. + - `envKeyEntry(provider)`: the first `provider.env` name that is set, with its value. + - `readCredentialEntry(store, scope, id)`: reads a credential like `readCredential`. It also tells you which scope had the credential (the user or the tenant), and gives its revision when the store has `getVersioned`. + + `CredentialStore` has two optional methods for compare-and-set writes, `getVersioned` and `setIf`, with the same shape as the pair on `MetadataStore`. A store without them still works. `memoryCredentialStore` has both. + + Keep the store in your own database or in a secrets manager, and encrypt the secrets at rest. An `oauth` credential can keep the OAuth `client` it was issued to. `list` never returns secret values. + + `scrubSecrets` from `@tanstack/ai/byok` now also removes the JSON-escaped and URL-encoded forms of each secret. It skips a secret that is shorter than 6 characters, so a short value does not remove common words. + + `Credential` has a new type, `secret_answer` (`{ value, expiresAt }`). The harness keeps a secret answer to a question there for a short time and deletes it once read. Leave this type out of a list of connected accounts. `memoryCredentialStore().list` returns its `expiresAt`. + + Approved edits to tool arguments stay raw until the final input check. + - `@tanstack/ai`: a resume no longer rejects approved `editedArgs` that do not fit the tool's `inputSchema`. The edit goes through `onBeforeToolCall` and the final input check, like the model's arguments. If it still does not fit, the approval is used, the tool does not run, and the model gets the input error as the tool result. The transcript keeps the approved edit as it was sent, but only when the call passed the check. + - `@tanstack/ai-persistence`: `withPersistence` binds the client-tool phase of an approved tool call to its approval. After a restart, the client result resumes with the approval that came before it, and a stale or missing approval fails the resume. + + A nested subagent that waits on an interrupt now continues after the resume under `withPersistence`. Before, it ran again from its prompt. Core rebuilds the card of the nested child from the store and takes only its id from the client card. `LoadChild` takes an optional `parentSubagentRunId`, and returns `interruptIds` and `parentToolCallId`. + + `chat()` asks the middleware `onShouldContinue` after it runs the pending tool calls of a resume, before the next model call. A middleware that returns `false` there ends the run with no more model calls. The loop strategy is not asked at that point. + + `WebSocketLike` has an optional `bufferedAmount`. A server can read it to stop sending to a slow socket. A socket without it works as before. + +### Patch Changes + +- [#1846](https://github.com/TanStack/ai/pull/1846) [`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9) - Apply `ACTIVITY_SNAPSHOT` and `ACTIVITY_DELTA` events that chat middleware adds to `ctx.activities`, so `withPersistence` saves them and `reconstructChat` restores their activity rows. A middleware that passes on an adapter activity event, or an exact copy of it, does not apply it twice. + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- [#1869](https://github.com/TanStack/ai/pull/1869) [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7) - Accept a missing `midConversationChannels` value on text adapters when `exactOptionalPropertyTypes` is on. `chat()` can take `fakeText()` and the provider text adapters again. + +- [#1851](https://github.com/TanStack/ai/pull/1851) [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d) - Add `@tanstack/ai-neon` for the Neon AI Gateway: `neonText` sends Claude to the Anthropic Messages route, codex and `*-pro` models to the Responses route, and every other model to Chat Completions, with `neonEmbedding` and `neonSummarize`. `@tanstack/openai-base` gets a `streamOptions(model)` hook, so a Chat Completions backend that rejects `stream_options` can leave it out. + +- [#1805](https://github.com/TanStack/ai/pull/1805) [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31) - Middleware can read `ctx.callMetadata`, the `metadata.tanstack` of the current model call. Each assistant message of the call gets a copy of it. + + With `snapshotStreaming`, `withPersistence` now stores `ctx.callMetadata` on snapshot rows, so a stopped or failed row has the same metadata as a finished one. A stopped or failed row no longer stores other chunk metadata, such as the durability batch hint of `ctx.emitCustomEvent(name, value, { batch: true })`. + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- Updated dependencies [[`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-utils@1.0.0 + - @tanstack/ai-event-client@1.0.0 + ## 0.71.0 ### Minor Changes diff --git a/packages/ai/package.json b/packages/ai/package.json index 25c0b269ba..80c82bd70f 100644 --- a/packages/ai/package.json +++ b/packages/ai/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/ai", - "version": "0.71.0", + "version": "1.0.0", "description": "Type-safe TypeScript AI SDK for streaming chat, tool calling, agents, structured outputs, and multimodal generation.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/openai-base/CHANGELOG.md b/packages/openai-base/CHANGELOG.md index 0c2db2f6c4..364f422612 100644 --- a/packages/openai-base/CHANGELOG.md +++ b/packages/openai-base/CHANGELOG.md @@ -1,5 +1,77 @@ # @tanstack/openai-base +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Minor Changes + +- [#1880](https://github.com/TanStack/ai/pull/1880) [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f) - Put the provider error type and the request id on `RUN_ERROR`. The Anthropic adapter and the adapters built on `@tanstack/openai-base` set `errorType` (for example `overloaded_error`) and `requestId` (from the SDK error or the `request-id` / `x-request-id` header). `chat()` moves both to `metadata.tanstack`, so the client gets them too. `code` stays the HTTP status. Adapter authors can read both values with `toRunErrorDetails` from `@tanstack/ai/adapter-internals`. + +### Patch Changes + +- [#1755](https://github.com/TanStack/ai/pull/1755) [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983) - Fix recovery, cancel, steer, and provider bugs, and fill small harness gaps. + - Recovery: a resolve that another host recovers runs its continuation. Before, it settled `completed` with no answer. + - Approvals: a tool that a middleware adds in `onConfig` can now be approved. `chat()` checks a durable resume after the whole `onConfig` chain. + - Cancel: a cancelled turn keeps the text it streamed, and ends with `TEXT_MESSAGE_END` and `RUN_FINISHED` (`outcome: cancelled`). A turn that times out ends with `RUN_ERROR` (`code: 'timeout'`). + - Steer: a steer from another sender gets a `queued` receipt with its own operation. `host.events()` shows `idle` after a turn that a steer joined. + - The duplicate-input check no longer depends on the key order of the stored input. + - `TurnInfo` has `model`, `attempt`, and `sender`. The log keeps the sender's `name`. `harness.input.accepted` carries the message. The chat hydration has `pendingWaits`. `ObservedSession.settled()` reads a settlement with no open session. Another host's `snapshot().plugins` shows the saved plugin state. + - New options: `subagents.background: false`, `media.urlTtlMs`, `conversationSummarizer({ middleware })`, and the `beforeWrite` workspace hook, which can refuse a write. + - Plugin model calls (`ctx.model.chat`) run the harness middleware. + - Exports: `SHUTDOWN_REASON`, `BUDGET_REASON`, and `RUN_CANCEL_REASON` from `@tanstack/ai-harness`, `HARNESS_EVENTS` from `@tanstack/ai-harness/client`, and `ChatHydrateOptions` and `ChatHydrationResult` from `@tanstack/ai-client`. + - Compaction drops a background summary that another model prepared. + - Sandbox file calls take an optional `{ signal }`. + - Anthropic: `outputSchema` moves keywords that Anthropic rejects into `description`, usage reports 1-hour cache writes as `cacheWrite1hTokens` again, and `reasoning` on a model with no reasoning entry warns once. + - OpenAI Responses: a message whose model call sent a reasoning item is marked with `metadata.tanstack.reasoningItem`. A replay of that message without its reasoning item no longer sends its `msg_` and `fc_` ids. + - Cloudflare: a `data:` line with no `choices` no longer throws, and the SSE fix-up accepts `data:` with no space, CRLF line ends, and any case in the content type. + - Structured output: a schema failure carries `rawText`, and a parse failure has the code `structured-output-parse-failed`. + - `ChatClient.addToolResult` answers the interrupt when the tool's schemas differ, so the result is sent. + - The persistence conformance suite no longer fails a correct store on a slow runner. + +- [#1851](https://github.com/TanStack/ai/pull/1851) [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d) - Add `@tanstack/ai-neon` for the Neon AI Gateway: `neonText` sends Claude to the Anthropic Messages route, codex and `*-pro` models to the Responses route, and every other model to Chat Completions, with `neonEmbedding` and `neonSummarize`. `@tanstack/openai-base` gets a `streamOptions(model)` hook, so a Chat Completions backend that rejects `stream_options` can leave it out. + +- [#1874](https://github.com/TanStack/ai/pull/1874) [`028f30f`](https://github.com/TanStack/ai/commit/028f30f948181188f00fa33d3ed423b86e47774e) - Keep `finishReason: "length"` when Chat Completions cuts off a tool call. The run no longer reports `tool_calls` or sends the unfinished arguments back to the model. + +- [#1839](https://github.com/TanStack/ai/pull/1839) [`36eab88`](https://github.com/TanStack/ai/commit/36eab8835f2e7718b2d52a2c0e6e5797830041c7) - Parallel tool calls stay separate when the provider leaves out `index` on the streamed deltas (Gemini's OpenAI-compatible endpoint, for example). Before, they merged into one call with joined arguments. A different id starts the next call once the current call has an id. A different name does so when the delta has no id, or when the current call still has no id. Any other delta without an index continues the latest call. A repeated name stays on that call. + +- [#1868](https://github.com/TanStack/ai/pull/1868) [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a) - Remove model ids that providers have retired. Each one now fails on the provider's API, so the types no longer accept it. + - Groq: `llama-3.3-70b-versatile`, `llama-3.1-8b-instant`, `meta-llama/llama-4-maverick-17b-128e-instruct`, `meta-llama/llama-4-scout-17b-16e-instruct`, `meta-llama/llama-guard-4-12b`, `moonshotai/kimi-k2-instruct-0905`, `qwen/qwen3-32b`. Adds `qwen/qwen3.8-27b`. + - Mistral: `pixtral-large-latest`, `pixtral-12b-2409`, `open-mistral-nemo`. + - OpenAI: `chatgpt-4o-latest`, `codex-mini-latest`, `gpt-4o-audio`, `gpt-4o-mini-audio`, `gpt-5.6`, `dall-e-2`, `dall-e-3`, `computer-use-preview`. The speech model `gpt-4o-audio-preview` is replaced by `gpt-4o-mini-tts`. + - Anthropic: `claude-opus-4-1`, `claude-opus-5-fast`. + - Gemini: `imagen-4.0-generate-001`, `imagen-4.0-ultra-generate-001`, `imagen-4.0-fast-generate-001`. + + Types and helpers that only served those models are removed: + - `@tanstack/ai-gemini`: `GeminiImageProviderOptions`, `GeminiAnyImageProviderOptions`, `GeminiAspectRatio`, `PersonGeneration`, `SafetyFilterLevel`, `ImagePromptLanguage`, `GEMINI_NATIVE_IMAGE_MODELS`, `isGeminiNativeImageModel`. Every Gemini image model uses `GeminiNativeImageProviderOptions`. + - `@tanstack/openai-base`: `OpenAIComputerToolName`. `resolveComputerUseTool(tool)` no longer takes a model. + - `@tanstack/ai-openai`: the dall-e option and size types. + +- [#1870](https://github.com/TanStack/ai/pull/1870) [`85204ea`](https://github.com/TanStack/ai/commit/85204eaf1a02ec4bbebc9f8390233221a81bc21c) - Responses replay no longer puts an assistant's text between a `function_call` and its `function_call_output`. The text now goes before the calls. DeepSeek rejected the old order with `No tool output found for function call`. + +- [#1873](https://github.com/TanStack/ai/pull/1873) [`49dbcf9`](https://github.com/TanStack/ai/commit/49dbcf92e80f20b98707d800dcf30e90b2e20d32) - Surface Vercel AI Gateway request cost on `usage.cost`, with the market price in `usage.costDetails.upstreamCost`. + +- Updated dependencies [[`fcbd199`](https://github.com/TanStack/ai/commit/fcbd199a66b553acef0b81bc76c4b4acd7fde6a9), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`959f43e`](https://github.com/TanStack/ai/commit/959f43e4b11112f2c097f642bdec34d8d0f83e27), [`39c1c79`](https://github.com/TanStack/ai/commit/39c1c79dc9b6c21329f659d9b4ba6968e9496983), [`fa2a291`](https://github.com/TanStack/ai/commit/fa2a291f5526f6dec9a91fe5b71de15dfaf59ec7), [`f7e7cce`](https://github.com/TanStack/ai/commit/f7e7cce8f2d543a7480b626b7985417e054bfd8d), [`7a0a48b`](https://github.com/TanStack/ai/commit/7a0a48bac8b531a90e768c87cb645da2fc8d3f31), [`468063c`](https://github.com/TanStack/ai/commit/468063c07cd904be97b154b415163c23510834b2), [`fe83aa0`](https://github.com/TanStack/ai/commit/fe83aa05fe2346c50693664d4a4896d4fc1fea5a), [`781a3a8`](https://github.com/TanStack/ai/commit/781a3a82c870e246deff23c7aca32094e9aaaf2f), [`39abb7e`](https://github.com/TanStack/ai/commit/39abb7ed172b4357bc04a39fc6cf7c3577f77cf3), [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai@1.0.0 + - @tanstack/ai-utils@1.0.0 + ## 0.16.0 ### Minor Changes diff --git a/packages/openai-base/package.json b/packages/openai-base/package.json index 05f85dcb62..b2c1097e37 100644 --- a/packages/openai-base/package.json +++ b/packages/openai-base/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/openai-base", - "version": "0.16.0", + "version": "1.0.0", "description": "Shared OpenAI SDK base adapters for TanStack AI providers using Chat Completions and Responses APIs.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/preact-ai-devtools/CHANGELOG.md b/packages/preact-ai-devtools/CHANGELOG.md index 96fb9cfac7..27e86b8a0f 100644 --- a/packages/preact-ai-devtools/CHANGELOG.md +++ b/packages/preact-ai-devtools/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/preact-ai-devtools +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-devtools-core@1.0.0 + ## 0.1.72 ### Patch Changes diff --git a/packages/preact-ai-devtools/package.json b/packages/preact-ai-devtools/package.json index 07d59ec657..fbfc8553e0 100644 --- a/packages/preact-ai-devtools/package.json +++ b/packages/preact-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/preact-ai-devtools", - "version": "0.1.72", + "version": "1.0.0", "description": "Preact Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/react-ai-devtools/CHANGELOG.md b/packages/react-ai-devtools/CHANGELOG.md index d72f398839..48ed1590e0 100644 --- a/packages/react-ai-devtools/CHANGELOG.md +++ b/packages/react-ai-devtools/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/react-ai-devtools +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-devtools-core@1.0.0 + ## 0.2.71 ### Patch Changes diff --git a/packages/react-ai-devtools/package.json b/packages/react-ai-devtools/package.json index eb8cd89ac0..93bdabef7f 100644 --- a/packages/react-ai-devtools/package.json +++ b/packages/react-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/react-ai-devtools", - "version": "0.2.71", + "version": "1.0.0", "description": "React Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "tannerlinsley", "license": "MIT", diff --git a/packages/solid-ai-devtools/CHANGELOG.md b/packages/solid-ai-devtools/CHANGELOG.md index 395d2f7598..0f777f426e 100644 --- a/packages/solid-ai-devtools/CHANGELOG.md +++ b/packages/solid-ai-devtools/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/solid-ai-devtools +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-devtools-core@1.0.0 + ## 0.2.71 ### Patch Changes diff --git a/packages/solid-ai-devtools/package.json b/packages/solid-ai-devtools/package.json index 14f9b9521c..e0a81d6ee9 100644 --- a/packages/solid-ai-devtools/package.json +++ b/packages/solid-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/solid-ai-devtools", - "version": "0.2.71", + "version": "1.0.0", "description": "Solid Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "Tanner Linsley", "license": "MIT", diff --git a/packages/svelte-ai-devtools/CHANGELOG.md b/packages/svelte-ai-devtools/CHANGELOG.md index 6547c6e3b4..fb4acae97d 100644 --- a/packages/svelte-ai-devtools/CHANGELOG.md +++ b/packages/svelte-ai-devtools/CHANGELOG.md @@ -1,5 +1,31 @@ # @tanstack/svelte-ai-devtools +## 1.0.0 + +### Major Changes + +- [#1840](https://github.com/TanStack/ai/pull/1840) [`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e) - TanStack AI 1.0.0. This release removes every API that was deprecated in 0.x. Read the upgrade guide before you upgrade: https://tanstack.com/ai/latest/docs/migration/v1 + - Removed all `@deprecated` exports, options, fields, and type aliases. Each one has a replacement that already shipped in 0.x. + - Removed `addToolApprovalResponse()` from `ChatClient` and every chat hook. Resolve the bound `tool-approval` interrupt with `resolveInterrupt` instead. The devtools event `tools:approval:responded` is also removed. + - Removed the old wire formats: the CUSTOM `approval-requested` and `tool-input-available` events, the `[DONE]` SSE line, the `data` copy of `forwardedProps`, pre-binding interrupt descriptors and their `approval_required` and `client_tool_input` reasons, and the STEP events that adapters sent next to `REASONING_*` events. Use a 1.0 client with a 1.0 server. + - Removed the `toolName` alias from `TOOL_CALL_START` chunks. Read `toolCallName` instead. + - `threadId` is now required on `useChat` and every other chat hook, `ChatClient`, the generation hooks and clients, `chat()`, `summarize()`, the generation functions, `codeModeWithSnippets()`, `selectRelevantSnippets()`, `CompactionContext`, and `SummarizeInput`. TanStack AI no longer makes a thread id for you. Pass a stable id for each conversation. `createChatHook` factory options no longer take `threadId`: pass it on each hook call. Octane generation hooks take `threadId` instead of `id`. `@tanstack/ai-sandbox` removes `resolveDurableThreadId` and `DurableThreadIdRequiredError`. + - The published `@tanstack/ai-octane/ui` types are now strict. `UI.Messages`, `UI.Message`, `UI.Part`, and `UI.Interrupts` type their render children. `ToolProps` types `part.input` and `part.output` for the named tool. `toolsComponents` and `interruptsComponents` are required when the chat options declare tools or named interrupts. Code that relied on the old loose types can fail to compile. + - A connection adapter's `connect()` and `send()` need the run context (with `threadId`) as their fourth argument. `ChatClient` and the generation clients pass it. + - `@tanstack/ai-sandbox`: `createToolBridgeCore()`, `startHostToolBridge()`, a `ToolBridgeProvisioner`, and `executeHostTool()` take a required `threadId`. Bridged tools get it in their context. + - `@tanstack/ai-sandbox`: the harness tool bridge and `executeHostTool()` refuse a tool with `needsApproval`. Before, the tool ran with no approval. Remove `needsApproval`, or run the tool with an HTTP adapter. + - `stream()` and `rpcStream()` pass the AG-UI `RunAgentInput` for the run as the fourth factory argument, the same body the HTTP adapters send. Read it on the server with `chatParamsFromRequestBody()` or `generationParamsFromBody()`, so `threadId`, `runId`, and interrupt `resume` reach a server function. `RunAgentInput` is exported from `@tanstack/ai/client`. + - A generation `fetcher` gets `threadId` and `runId` in its second argument, next to `signal` and `headers`. Pass them to the server generation call. + - `generationParamsFromBody()` and `generationParamsFromRequest()` read the generation input from `forwardedProps`. A server that reads `body.data` gets `undefined`. Read `body.forwardedProps` instead. They also require `threadId` and `runId` and return them as strings, the same as `chatParamsFromRequestBody()` and the AG-UI `RunAgentInput`. A body that holds only the input is rejected. + - Removed the readers for data saved in old 0.x formats (old Cloudflare run-log records, a bare `UIMessage[]` from client persistence, artifact records without `blobKey`). + - Removed provider models that are shut down. + - `@tanstack/ai-react-ui`, `@tanstack/ai-solid-ui`, and `@tanstack/ai-vue-ui` get no 1.0 release. Import from `@tanstack/ai-react/ui`, `@tanstack/ai-solid/ui`, or `@tanstack/ai-vue/ui`. + +### Patch Changes + +- Updated dependencies [[`f1b3f65`](https://github.com/TanStack/ai/commit/f1b3f65a59fb75116bd52abbb162cab8c763d10e)]: + - @tanstack/ai-devtools-core@1.0.0 + ## 0.1.0 ### Minor Changes diff --git a/packages/svelte-ai-devtools/package.json b/packages/svelte-ai-devtools/package.json index a5f243487b..59b313503e 100644 --- a/packages/svelte-ai-devtools/package.json +++ b/packages/svelte-ai-devtools/package.json @@ -1,6 +1,6 @@ { "name": "@tanstack/svelte-ai-devtools", - "version": "0.1.0", + "version": "1.0.0", "description": "Svelte Devtools plugin for inspecting TanStack AI chat messages, tool calls, streams, and errors.", "author": "Tanner Linsley", "license": "MIT",