Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .changeset/tanstack-ai-adapter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
"@simplepdf/embed": minor
"@simplepdf/react-embed-pdf": minor
---

Add a TanStack AI adapter (the `/tanstack-ai` subpath) for client-side tool calling, alongside the existing Vercel AI SDK (`/ai-sdk`) adapter. Both wrap the same generated tool registry + bridge router, so the editor is drivable from either SDK with no duplicated logic.

- `@simplepdf/embed/tanstack-ai`: `simplePDFToolDefinitions()` (server, for `chat({ tools })`) and `createSimplePDFTools({ embed })` (browser `.client()` tools for `clientTools(...)` then `useChat({ tools })`).
- `@simplepdf/react-embed-pdf/tanstack-ai`: `useEmbedTools(embedRef)`, the editor-bound client tools. Server definitions stay in the React-free core `@simplepdf/embed/tanstack-ai`, so a server route never pulls React in.
- `@tanstack/ai` is a new optional peer, pulled only by the `/tanstack-ai` subpath; the package roots stay free of it (and of `zod`).
- **Public exports trimmed to the strict minimum.** These are breaking removals, but the only consumer is copilot (migrated in lockstep), so they ship as a minor rather than a major:
- `@simplepdf/embed` root drops the internal helpers `buildEditorDomain`, `encodeContext`, `isBridgeResultLike`.
- `@simplepdf/embed/protocol` drops the internal `INTERNAL_PROTOCOL` / `InternalProtocolType` (used only by the bridge).
- `@simplepdf/react-embed-pdf` root no longer re-exports the whole `@simplepdf/embed` core or the wire-protocol vocabulary; import those from `@simplepdf/embed` / `@simplepdf/embed/protocol` directly.
- `@simplepdf/react-embed-pdf/ai-sdk` no longer re-exports `simplePDFToolDefinitions` (import it from `@simplepdf/embed/ai-sdk`); the browser-side `createSimplePDFExecutor` stays. Server tool-definitions now live only in the React-free core, so a server route never pulls React in.
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# API Extractor emits CRLF; keep the committed API-surface reports LF so they don't trip
# git's whitespace gate or churn across platforms. api-extractor's report comparison is
# line-ending agnostic, so this does not affect `check:api`.
*.api.md text eol=lf
12 changes: 12 additions & 0 deletions .github/workflows/embed.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,18 @@ on:
- main
paths:
- embed/**
- scripts/**
- package.json
- package-lock.json
- .github/workflows/embed.yaml
pull_request:
branches:
- main
paths:
- embed/**
- scripts/**
- package.json
- package-lock.json
- .github/workflows/embed.yaml

jobs:
Expand Down Expand Up @@ -39,3 +45,9 @@ jobs:

- name: Bundle size budgets
run: npm run --workspace @simplepdf/embed check:size

- name: Export load
run: npm run --workspace @simplepdf/embed check:exports

- name: API surface
run: npm run --workspace @simplepdf/embed check:api
15 changes: 15 additions & 0 deletions .github/workflows/react.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ on:
paths:
- react/**
- embed/**
- scripts/**
- package.json
- package-lock.json
- .github/workflows/react.yaml
pull_request:
branches:
- main
paths:
- react/**
- embed/**
- scripts/**
- package.json
- package-lock.json
- .github/workflows/react.yaml

jobs:
Expand All @@ -38,6 +44,9 @@ jobs:
- name: Build the core
run: npm run --workspace @simplepdf/embed build

- name: Build react-embed-pdf
run: npm run --workspace @simplepdf/react-embed-pdf build

- name: Formatting
run: npm run --workspace @simplepdf/react-embed-pdf test:format

Expand All @@ -46,3 +55,9 @@ jobs:

- name: Tests
run: npm run --workspace @simplepdf/react-embed-pdf test

- name: Export load
run: npm run --workspace @simplepdf/react-embed-pdf check:exports

- name: API surface
run: npm run --workspace @simplepdf/react-embed-pdf check:api
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,7 @@ chrome-extension/release.zip
.claude/
.wrangler/

coverage
coverage

# api-extractor working files (committed API reports live in <pkg>/etc/)
tmp/
13 changes: 4 additions & 9 deletions copilot/src/components/chat/chat_pane.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { useChat } from '@ai-sdk/react'
import {
OVERLAY_TOOL_TYPES,
type BridgeResult,
type DocumentContentPage,
type DocumentContentResult,
type EmbedActions,
type FieldRecord,
} from '@simplepdf/react-embed-pdf'
import { type EmbedTools, type SimplePDFToolName } from '@simplepdf/react-embed-pdf/ai-sdk'
import type { BridgeResult, DocumentContentPage, DocumentContentResult, FieldRecord } from '@simplepdf/embed'
import { OVERLAY_TOOL_TYPES } from '@simplepdf/embed/protocol'
import type { EmbedActions } from '@simplepdf/react-embed-pdf'
import type { EmbedTools, SimplePDFToolName } from '@simplepdf/react-embed-pdf/ai-sdk'
import { getRouteApi } from '@tanstack/react-router'
import { DefaultChatTransport, lastAssistantMessageIsCompleteWithToolCalls, type UIMessage } from 'ai'
import { ArrowUp, Mic, X } from 'lucide-react'
Expand Down
2 changes: 1 addition & 1 deletion copilot/src/lib/tools/definitions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { simplePDFToolDefinitions, type SimplePDFToolName } from '@simplepdf/react-embed-pdf/ai-sdk'
import { type SimplePDFToolName, simplePDFToolDefinitions } from '@simplepdf/embed/ai-sdk'
import type { FinalisationAction } from '../../server/tools'
import { IS_DEMO_MODE } from '../mode'

Expand Down
16 changes: 15 additions & 1 deletion embed/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,26 @@ const execute = createSimplePDFExecutor({ embed })

`@simplepdf/embed/tools` exposes the same registry SDK-agnostically (`routeToolCall`, `isSimplePDFToolName`). In React, `@simplepdf/react-embed-pdf/ai-sdk`'s `useEmbedTools(embedRef)` is the same registry pre-bound to the live editor.

For TanStack AI, the same registry is exposed via `@simplepdf/embed/tanstack-ai`:

```ts
// server: execute-less definitions so the model is aware of the tools
import { simplePDFToolDefinitions } from '@simplepdf/embed/tanstack-ai'
chat({ adapter, messages, tools: simplePDFToolDefinitions() })

// browser: the same definitions bound to the live editor via .client()
import { clientTools } from '@tanstack/ai-react'
import { createSimplePDFTools } from '@simplepdf/embed/tanstack-ai'
useChat({ connection, tools: clientTools(...createSimplePDFTools({ embed })) })
```

## Install

```bash
npm install @simplepdf/embed
```

Zero runtime dependencies at the root. `zod` is an optional peer, needed only by the `/schemas`, `/tools`, and `/ai-sdk` subpaths. `/ai-sdk` produces values for the Vercel AI SDK but never imports `ai`; bring your own.
Zero runtime dependencies at the root. `zod` is an optional peer, needed by the `/schemas`, `/tools`, `/ai-sdk`, and `/tanstack-ai` subpaths. `/ai-sdk` produces values for the Vercel AI SDK without importing `ai` (bring your own); `/tanstack-ai` uses `@tanstack/ai`'s `toolDefinition` (also an optional peer, pulled only by that subpath).

## Subpaths

Expand All @@ -66,6 +79,7 @@ Zero runtime dependencies at the root. `zod` is an optional peer, needed only by
| `@simplepdf/embed/schemas` | zod schema for every operation input | `zod` |
| `@simplepdf/embed/tools` | SDK-agnostic agentic tool registry + `routeToolCall` + `isSimplePDFToolName` | `zod` |
| `@simplepdf/embed/ai-sdk` | `simplePDFToolDefinitions()` (server) + `createSimplePDFExecutor({ embed })` (browser) for the Vercel AI SDK | `zod` |
| `@simplepdf/embed/tanstack-ai` | `simplePDFToolDefinitions()` (server) + `createSimplePDFTools({ embed })` (browser) for TanStack AI | `zod`, `@tanstack/ai` |

## Where the editor goes

Expand Down
31 changes: 31 additions & 0 deletions embed/etc/ai-sdk.api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
## API Report File for "@simplepdf/embed"

> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).

```ts

import * as zod from 'zod';
import * as zod_v4_core from 'zod/v4/core';

// Warning: (ae-forgotten-export) The symbol "BridgeResult" needs to be exported by the entry point ai-sdk.d.ts
//
// @public (undocumented)
export const createSimplePDFExecutor: (input: {
embed: Embed;
}) => ((toolName: string, input: unknown) => Promise<BridgeResult<unknown>>);

// Warning: (ae-forgotten-export) The symbol "TOOL_DEFINITIONS" needs to be exported by the entry point ai-sdk.d.ts
//
// @public (undocumented)
export const simplePDFToolDefinitions: () => typeof TOOL_DEFINITIONS;

// @public (undocumented)
export type SimplePDFToolName = keyof typeof TOOL_DEFINITIONS;

// Warnings were encountered during analysis:
//
// dist/ai-sdk.d.ts:10:5 - (ae-forgotten-export) The symbol "Embed" needs to be exported by the entry point ai-sdk.d.ts

// (No @packageDocumentation comment for this package)

```
Loading
Loading