Commit graph

19 commits

Author SHA1 Message Date
Ajax Davis
f8740fb7ff fix: add biome-ignore comments and config overrides for lint issues
- Add ToolSearchResult interface with biome-ignore for dynamic tool types
- Add biome-ignore comments for UIMessage.parts type casting
- Add biome config overrides for complexity warnings in MessageBubble.tsx
- Add biome config override for MobileMenu.tsx a11y rule
- Add biome config override for railway-executor complexity
- Fix unused template literal in railway-executor
- All lint tasks now pass with 0 errors

🤖 Generated with [Claude Code](https://claude.ai/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-01-02 01:51:46 +10:00
Ajax Davis
9855425be4 chore: upgrade AI SDK from beta to stable v6
- ai: 6.0.0-beta.124 → 6.0.3
- @ai-sdk/openai: 3.0.0-beta.74 → 3.0.1
- @ai-sdk/react: 3.0.0-beta.131 → 3.0.3

Breaking changes addressed:
- CoreMessage renamed to ModelMessage
- convertToModelMessages is now async (added await)
2025-12-28 16:17:41 +10:00
Ajax Davis
e84eda7525 refactor: rename exportName to name across entire codebase
- Database: Migrate column export_name to name in tools table
- Prisma schema: Update Tool model to use name field
- Sync routes: Update keyword and changes sync to use name
- Railway executor: Update API endpoints to use name parameter
- API routes: Update all tool routes to use name field
- Web app: Update all pages and components
- Playground: Update tool loader and sidebar
- create-basic-tools: Update types and generators
- Scripts: Update sync and test scripts

Database migration was done via direct SQL:
  ALTER TABLE tools RENAME COLUMN export_name TO name;

The unique constraint remains on (package_id, name).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-17 17:19:21 +10:00
Ajax Davis
0e5d4d6e3b feat: add Vercel Analytics to web and playground apps
- Install @vercel/analytics in both apps
- Add <Analytics /> component to root layouts
- Enables automatic page view tracking on Vercel
2025-12-17 11:04:02 +10:00
Ajax Davis
4413ac00f6 feat(playground): load all tools and add hide broken toggle
- Paginate through all tools from registry API (was limited to 20)
- Add 'Hide broken tools' checkbox (enabled by default)
- Filter out tools with BROKEN import or execution health
2025-12-12 12:28:02 +10:00
Ajax Davis
e09596a7fa fix(executor): pass execution context with abortSignal to tool execute()
Some AI SDK tools (like @parallel-web/ai-sdk-tools) expect execute(params, context)
where context contains { abortSignal, messages, toolCallId }. Previously we only
passed params which caused 'Cannot destructure abortSignal' errors.

Also:
- Improved playground system prompt for better tool execution
- Playground /api/tools now proxies to web app with response transformation
- Added broken-tools.md documenting tool failure categories

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-12 04:43:20 +10:00
Ajax Davis
1bd484797f fix: add 120s timeout per tool and increase route maxDuration to 300s
- Add AbortController timeout (120s) to Railway fetch requests
- Gracefully handle timeout errors and report to health check system
- Increase /api/chat maxDuration from 60s to 300s (5 minutes)
- Prevents entire chat from timing out when one tool has large dependencies
- Tools that timeout are logged and skipped, allowing others to load

Fixes issue where tools like ctx-zip with many dependencies would
cause the entire chat request to timeout after 60 seconds.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 00:43:13 +10:00
Ajax Davis
b02c464960 fix: add CSS variables for status colors to playground
Added error, warning, success, and info color CSS variables to
playground globals.css so that Badge component variants display
with correct colors. The error variant will now show red as expected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 19:47:24 +10:00
Ajax Davis
6e7c75dd14 fix: use function body in DefaultChatTransport to send latest env vars
PROBLEM:
DefaultChatTransport body is cloned ONCE on mount, so env vars
were always empty {} even after localStorage loaded them.

SOLUTION:
Use a function for body instead of an object. AI SDK v6 calls
body() on each request, ensuring latest env vars are sent.

Changes:
- useChat.ts: body: { env } → body: () => ({ env: buildEnvObject() })
- buildEnvObject() is called fresh on each request
- Env vars now sent correctly to /api/chat

Credit: ChatGPT for identifying the exact AI SDK v6 pattern

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:25:59 +10:00
Ajax Davis
377f90989d fix: properly pass env vars to cached tools and add extensive logging
PROBLEM:
- Tool wrappers cached env vars in closure, so cached tools used stale env
- Client env vars weren't reaching Railway executor even when provided
- No visibility into env var flow through the system

SOLUTION:
1. Store env vars per conversation in conversationEnv Map
2. Tool execute functions look up latest env from Map (not closure)
3. Chat API calls setConversationEnv() on each request
4. Added logging at every step

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:18:32 +10:00
Ajax Davis
1bf7879c1e feat: implement BM25 search with context from last 3 user messages
- Implement proper BM25 scoring algorithm in /api/tools/search
  - Term frequency with saturation (k1 = 1.5)
  - Length normalization (b = 0.75)
  - Inverse document frequency (IDF)
- Accept recent messages via 'messages' query param for better context
- Update search-registry tool to:
  - Use /api/tools/search endpoint (not /api/tools)
  - Pass last 3 user messages for contextual search
  - Include recentMessages in tool input schema
- Update chat API to extract and pass last 3 user messages to search

BM25 formula: Σ IDF(qi) * (tf * (k1 + 1)) / (tf + k1 * (1 - b + b * |D| / avgdl))

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:59:22 +10:00
Ajax Davis
9e863fe181 fix: make OPENAI_API_KEY optional for playground to allow client-provided keys
- Make OPENAI_API_KEY optional in env validation
- Move OpenAI client initialization from module level to runtime
- Accept API key from client UI (Settings sidebar) or server env
- Return clear error message if no API key is provided
- Fixes Vercel build failure due to missing env var at build time

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:22:23 +10:00
Ajax Davis
3aef5bb2bb fix: migrate playground to AI SDK v6 beta and resolve TypeScript errors
- Update @ai-sdk/react to v3.0.0-beta.131 for compatibility with AI SDK v6
- Fix tool execute method calls with type assertions in API routes
- Update chat components to use UIMessage types from AI SDK
- Move body option into DefaultChatTransport constructor
- Remove deprecated onResponse option from useChat hook
- Remove unused isCoreTool type guard function
- Fix Button variant from 'primary' to 'default'

Resolves all TypeScript compilation errors and build passes successfully.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:15:21 +10:00
Ajax Davis
323c7496f0 fix: add non-null assertion for searchTpmjsToolsTool.execute
TypeScript was complaining that execute might be undefined, but tools created
with tool() from AI SDK always have an execute method. Added non-null assertion
with biome-ignore comment to fix the TypeScript build error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 12:38:39 +10:00
Ajax Davis
8454452476 fix: use inputSchema instead of parameters for AI SDK v6 tool
Changed debug logging to access inputSchema property which exists on AI SDK v6 tools,
instead of parameters which doesn't exist. This fixes the TypeScript build error.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 12:34:32 +10:00
Ajax Davis
cd2cfe25cf fix: remove unused NextResponse import in playground chat route
Removed unused NextResponse import that was causing TypeScript build error.
The error handler already uses native Response constructor directly.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 12:31:11 +10:00
Ajax Davis
1c949f6a11 feat: add playground sidebars with dynamic tools and env var management
Left Sidebar:
- Create /api/tools endpoint to fetch tools from registry
- Update ToolsSidebar to fetch and display tools dynamically
- Add filter input for searching tools by name/description/category
- Fix interface to use packageName/exportName from search registry

Right Sidebar:
- Create SettingsSidebar with environment variable management
- Add localStorage persistence for env vars
- Implement password masking for values
- Export useEnvVars() hook for accessing env vars

Environment Variable Forwarding:
- Update useChat hook to read and forward env vars to API
- Update chat route to extract env vars from request body
- Update dynamic-tool-loader to accept and forward env vars
- Update Railway executor to inject env vars into Deno environment
- Complete chain: localStorage → client → chat → Railway → Deno.env

Bug Fixes:
- Fix undefined property errors in tool detail page
- Add optional chaining for npmDownloadsLastMonth and qualityScore

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 11:00:20 +10:00
Ajax Davis
d597a71eb4 feat: add dynamic tool loading system with Railway executor
Implements a complete dynamic tool loading system that allows the playground to discover and load tools from the TPMJS registry at runtime.

**Architecture:**
- Search tool package (@tpmjs/search-registry) - Searches registry for tools
- Search API endpoint (/api/tools/search) - Text-based search with scoring
- Pre-flight tool loading - Automatically searches and loads tools on every message
- Railway executor service (Deno) - Loads tools from esm.sh via HTTP imports
- Dynamic tool loader - Calls Railway to load and execute tools remotely

**Key Components:**

1. Railway Executor (apps/railway-executor/)
   - Deno-based service that natively supports HTTP imports
   - Endpoints: /load-and-describe, /execute-tool, /cache/stats, /cache/clear
   - Deploys to Railway with deno run --allow-net --allow-env server.ts

2. Search Tool Package (packages/tools/search-registry/)
   - AI SDK v6 tool for searching TPMJS registry
   - Uses jsonSchema + inputSchema pattern
   - Searches /api/tools/search endpoint

3. Search API (apps/web/src/app/api/tools/search/)
   - Text-based search with composite scoring
   - Scores: text relevance + quality boost + download boost
   - Returns tool metadata with importUrl for dynamic loading

4. Dynamic Tool Loader (apps/playground/src/lib/dynamic-tool-loader.ts)
   - Calls Railway service to load tools from esm.sh
   - Creates tool wrappers that execute remotely
   - Process-level module cache + per-conversation tracking

5. Pre-flight Loading (apps/playground/src/app/api/chat/route.ts)
   - Automatically searches for tools on every user message
   - Loads top 5 matching tools before agent processes request
   - Merges with static tools for seamless experience

**Technical Decisions:**
- Deno over Node.js: Native HTTP import support without flags
- Remote execution: Tools run in Railway sandbox, not Vercel
- Pre-flight loading: Better UX than two-turn search pattern
- Text search: BM25 had dependency issues, simple scoring works well

**Environment Variables:**
- RAILWAY_SERVICE_URL: https://endearing-commitment-production.up.railway.app

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 08:25:53 +10:00
Ajax Davis
0658aea425 feat: implement playground app with AI SDK v6 tool execution
- Create new Next.js app at apps/playground for testing TPMJS tools
- Implement AI SDK v6 patterns with DefaultChatTransport and UIMessage format
- Create template tool package at packages/tools/hello with hello-world and hello-name tools
- Use tool() and jsonSchema() helpers to avoid Zod 4 conversion issues with OpenAI
- Add static tool loading system with switch statement (Next.js/webpack compatible)
- Implement chat interface with tool call visualization showing inputs/outputs
- Support multi-step tool execution with stepCountIs(5)
- Stream responses with toUIMessageStreamResponse() for full tool support
- Add sidebar showing available tools (static list)
- Use parts-based message rendering for text and tool calls
- Integrate firecrawl-aisdk tools (scrape, crawl, search)
- Add theme toggle in header (defaults to light mode)
- Fix responsive layout with max-width for message bubbles
- Use biome-ignore comments for legitimate any types in tool loading

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 02:51:02 +10:00