Commit graph

694 commits

Author SHA1 Message Date
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
e3b6ff6d25 fix: make Prisma import lazy in playground to prevent module initialization failures
- Remove top-level Prisma import from dynamic-tool-loader.ts
- Use dynamic import in reportToolFailure function instead
- Prevents entire module from failing if DATABASE_URL is missing
- Fixes API route timeout issue caused by module initialization failure

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-05 00:27:16 +10:00
Ajax Davis
e6c1be6a53 chore: release emoji-magic v0.2.0 and create-basic-tools v1.0.4 2025-12-05 00:10:18 +10:00
Ajax Davis
3219da5a03 feat: simplify interactive CLI to only ask for package name
- Removed all prompts except package name
- Auto-generate description from package name
- Use sensible defaults: 2 example tools, ai-ml category, MIT license
- Generate exampleTool and anotherTool that users can customize
- Much faster UX - no more 10+ prompts for basic usage
- Updated README with simplified flow example
- Bumped version to 1.0.3

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 23:55:54 +10:00
Ajax Davis
83afeef2dc feat: add @tpmjs/create-basic-tools generator promotion to website
- Add prominent callout box on homepage in 'Publish Your Tool' section
- Add featured generator section on /publish page with full documentation link
- Include command example and links to GitHub README and NPM
- Highlight key features: 2-3 tools, complete setup, production-ready

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 23:48:36 +10:00
Ajax Davis
0d1fa3e292 fix: remove duplicate shebang from source file
- tsup banner already adds shebang, no need in source
- bump version to 1.0.2
- fixes CLI execution errors

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 23:43:03 +10:00
Ajax Davis
38c85bd904 feat: add @tpmjs/create-basic-tools CLI generator
- Interactive CLI generator for scaffolding TPMJS tool packages
- Generates packages with minimum 2 tools (ideally 2-3)
- Zod 4 schemas - uses Zod directly (not jsonSchema wrapper)
- One file per tool in src/tools/<toolName>.ts
- TPMJS validated against official schemas from @tpmjs/types
- Complete package generation ready to publish to npm
- Works both standalone and in monorepo packages/ folders

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 23:34:37 +10:00
Ajax Davis
8b000cf0ca feat: add beta experimental section for dynamic tool loading to how-it-works page
- Add comprehensive section explaining BM25 search with context awareness
- Show comparison of traditional vs dynamic tool loading approaches
- Document Deno sandboxed execution environment on Railway
- Preview future collections feature for tool organization
- Include call-to-action to try the playground
2025-12-04 20:26:38 +10:00
Ajax Davis
129f45353a test: mock react-syntax-highlighter to fix ESM compatibility in CodeBlock tests 2025-12-04 20:21:14 +10:00
Ajax Davis
0a37ca5aa7 test: mock react-syntax-highlighter to fix ESM compatibility in CodeBlock tests 2025-12-04 20:06:41 +10:00
Ajax Davis
5c2cc529ef test: update form input tests to expect bg-surface instead of bg-background 2025-12-04 20:02:55 +10:00
Ajax Davis
c751a056a9 feat: add How It Works documentation page
- Create comprehensive /how-it-works page explaining TPMJS architecture
- Add detailed sections on developer workflow, AI agent integration, and system internals
- Include quality scoring formula, health checks, and data flow diagrams
- Add navigation link to AppHeader between Tools and Playground
- Style consistently with existing pages (Publish, Playground)
- Fix: remove debug console.log from ToolsSidebar

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 19:58:54 +10:00
Ajax Davis
cbcb1e49c7 fix: don't mark tools as broken for missing environment variables
Tools that fail due to missing environment variables (API keys, etc.)
are not actually broken - they just need configuration. Added detection
for common env var error patterns and mark these tools as HEALTHY
instead of BROKEN.

Error patterns detected:
- 'is required'
- 'is not set'
- 'missing environment'
- 'API key required/not provided'
- etc.

This fixes false positives where tools like @superagent-ai/ai-sdk
were marked as broken when they just need SUPERAGENT_API_KEY configured.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 19:52:22 +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
4ba39e07f8 fix: add health fields to /api/tools/search response
The search endpoint was missing importHealth, executionHealth,
healthCheckError, and lastHealthCheck fields in the response. This caused
the playground (which uses search-registry tool) to not receive health
data for displaying broken tool badges.

Added all four health fields to the tool mapping in the search response.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 19:41:50 +10:00
Ajax Davis
9f1c3fb383 fix: update footer links - correct GitHub URL and contact email
- Change GitHub URL to github.com/tpmjs/tpmjs
- Update contact email to thomasalwyndavis@gmail.com
2025-12-04 19:18:46 +10:00
Ajax Davis
a9e91c02d1 feat: add reusable ToolHealthBadge and ToolHealthBanner components
- Create ToolHealthBadge component in @tpmjs/ui for broken tool indicator
- Create ToolHealthBanner component in @tpmjs/ui for detailed health warnings
- Integrate both components into playground ToolsSidebar:
  - Badge shows in tool cards in left sidebar
  - Banner shows in tool detail modal
- Update search-registry to include health fields in API responses
- Add package.json exports for new health components

These components provide consistent UI for displaying broken tool status
across the application (tool search, tool detail pages, playground).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 19:12:07 +10:00
Ajax Davis
54ee6439cb fix: display environment variable names correctly in tool modal
Previously env vars were stored as an array but component used Object.entries(),
causing array indices (0, 1, 2...) to appear as variable names instead of actual
names like 'EXA_API_KEY'.

Updated component to:
- Reflect correct array structure in Tool interface
- Iterate directly over array with .map() instead of Object.entries()
- Access envVar.name field for display
- Added support for displaying default values if present

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:56:31 +10:00
Ajax Davis
97db95243a fix: use lighter background for tool detail modal
- Change modal from bg-background to bg-white/dark:bg-gray-900
- Makes modal stand out clearly from the app background
- Provides better visual hierarchy

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:49:59 +10:00
Ajax Davis
e437f69333 fix: use theme-aware colors for tool detail modal
- Change modal background from bg-surface to bg-background for proper dark mode support
- Use bg-surface for nested elements (env vars, code blocks) to create subtle contrast
- Ensures modal respects the application's dark theme

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:43:44 +10:00
Ajax Davis
f59a22dbad feat: add package names and tool detail modal to playground sidebar
- Display package name as secondary text below tool name
- Add clickable tool cards that open detailed modal
- Modal shows comprehensive tool info: description, frameworks, env vars, import URL, tool ID
- Improve modal click handling to only close on backdrop clicks
- Fix accessibility: add type="button" to close button
- Full keyboard support with Escape key and proper ARIA labels

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:34:22 +10:00
Ajax Davis
e0c5ca9969 feat(playground): enhance tool list UI with package names and detail modal
Add two major UX improvements to the ToolsSidebar:

1. Package Name Display
   - Show package name as secondary label below tool name
   - Improves tool identification at a glance

2. Tool Detail Modal
   - Click any tool card to open detailed modal
   - Shows comprehensive information:
     * Tool name, package, version, category
     * Quality score (if available)
     * Full description
     * Supported frameworks (badges)
     * Environment variables (with required flag)
     * Import URL (for manual integration)
     * Tool ID (for debugging)
   - Modal features:
     * Backdrop blur effect
     * Click outside or press Escape to close
     * Close button (X icon) with SVG title
     * Responsive layout (max-w-2xl)
     * Scrollable content (max-h-90vh)
     * Full keyboard accessibility (ARIA labels, tabIndex, Escape key)

3. Enhanced Tool Interface
   - Added optional fields: toolId, qualityScore, frameworks, env, importUrl
   - Maintains backward compatibility with existing API

This gives users full visibility into tool metadata and helps them
understand what each tool does before using it in conversations.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:20:33 +10:00
Ajax Davis
89564af030 fix: sanitize invalid JSON schemas with type 'None' to valid object schemas
Add sanitizeJsonSchema() function to fix common schema issues:
- Replaces invalid type 'None' (common in Python tools) with 'object'
- Ensures all schemas have a valid type field
- Recursively sanitizes nested schemas in properties, items, anyOf/oneOf/allOf
- Prevents OpenAI API errors from malformed tool schemas

This fixes the error with @superagent-ai/ai-sdk guard tool which
returns type: 'None' instead of a valid JSON Schema type.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 18:02:10 +10:00
Ajax Davis
6676f01a2d Revert "feat: add Node.js compatibility layer to Railway executor"
This reverts commit 8562eb5b38.
2025-12-04 17:55:25 +10:00
Ajax Davis
63bab53b0e fix: use eval instead of regex for TypeScript parsing 2025-12-04 17:50:26 +10:00
Ajax Davis
2a989c5527 fix: use variable for multi-line commit message 2025-12-04 17:47:03 +10:00
Ajax Davis
b41382f365 fix: use heredoc for multi-line commit message in workflow 2025-12-04 17:45:56 +10:00
Ajax Davis
ac22733cfc fix: support AI SDK jsonSchema() with .jsonSchema property
Added Strategy 2.5 to schema extraction to handle AI SDK v6's
jsonSchema() wrapper which uses `.jsonSchema` property instead
of `.schema`.

This fixes schema validation errors for @tpmjs/hello and other
packages that use jsonSchema() wrapper.

Error was: "No valid schema found" with keys ["_type", "jsonSchema", "validate"]
Fix: Check for inputSchema.jsonSchema as an object property

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 17:44:26 +10:00
Ajax Davis
f9dfc67de4 feat: add automated Vercel AI registry sync with OpenAI
Add hourly GitHub Action that syncs tools from Vercel's AI SDK registry:

Features:
- Fetches Vercel AI registry from their GitHub
- Uses OpenAI GPT-4 to intelligently convert tool metadata
- Handles multi-export packages (multiple tools per npm package)
- Automatically commits new tools to manual-tools.ts
- Sends Discord notifications with detailed stats
- Extensive logging at every step

Files added:
- sync-vercel-registry.ts - Main sync script with AI conversion
- .github/workflows/sync-vercel-registry.yml - Hourly GitHub Action
- docs/vercel-registry-sync.md - Complete documentation

Requires OPENAI_API_KEY secret in GitHub repository settings.
2025-12-04 17:43:17 +10:00
Ajax Davis
dd8fceb0d5 fix: set env vars in both Deno.env and process.env for Node.js compat
The Node.js compatibility layer (npm: specifier) broke environment
variable passing because tools imported via npm: expect process.env,
not Deno.env.

Root cause: Recent commit added npm: specifier for Node compatibility,
but env injection code only set Deno.env.set(), not process.env.

Fix: Set environment variables in BOTH locations:
- Deno.env.set() for esm.sh imports
- globalThis.process.env for npm: imports

This restores functionality for tools like Firecrawl that require
API keys via environment variables.

Fixes regression from commit 8562eb5.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 17:29:42 +10:00
Ajax Davis
46c3bcbff7 perf: only type-check changed packages in pre-commit hook
Use Turborepo's --filter='...[HEAD]' to only type-check packages
with staged changes instead of all 21 packages. This reduces
pre-commit hook time from ~30s to ~3s for single-package changes.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 17:16:42 +10:00
Ajax Davis
b9269c5574 fix: handle undefined npmKeywords in tool detail page
Add null check before accessing npmKeywords.length to prevent
runtime TypeError when npmKeywords is undefined.

Fixes: Cannot read properties of undefined (reading 'length')

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 17:14:20 +10:00
Ajax Davis
77e7eedbe0 fix: handle undefined githubStars in tool detail page
Use loose equality (!=) instead of strict equality (!==) to check for
both null and undefined values. This prevents runtime TypeError when
githubStars is undefined.

Fixes: Cannot read properties of undefined (reading 'toLocaleString')

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 17:03:58 +10:00
Ajax Davis
f6514314c0 feat: add collated error reporting to batch tool loading
Improve visibility when multiple tools fail during batch loading:

- Track success/failure status for each tool in batch
- Log consolidated summary with counts ( Successful: X/Y,  Failed: Y/Z)
- List all failed tools together with automatic health check confirmation
- Provide guidance to check individual error logs for detailed reasons

Also fix linting issues:
- Remove non-null assertions for safer code
- Fix template literals that don't need interpolation
- Add biome-ignore comments for AI SDK any types

This addresses error collation when multiple Railway tools fail,
making it easier to see the big picture while maintaining detailed
individual error logs and health check triggers.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:59:12 +10:00
Ajax Davis
4556213a1c feat: add automatic health check updates on Railway tool failures
Add real-time health status updates when tools fail to load or execute:

- Add @tpmjs/db dependency to playground package
- Create reportToolFailure() function to update health status on errors
- Trigger health check updates for:
  1. Import failures (Railway load-and-describe errors)
  2. Execution failures (Railway execute-tool errors)
- Updates are non-blocking and run in background
- Each tool failure now logs:
  - 🏥 Triggering health check for {package}/{export}
  -  Health status updated for {package}/{export}

This complements the proactive health checking (daily cron + manual recheck)
with reactive health updates from actual tool usage errors.

Handles multiple errors in batch loading - each error triggers its own
health check update independently and asynchronously.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:51:27 +10:00
Ajax Davis
958697f788 feat: add GitHub Action for daily health check cron and backfill script
- Create .github/workflows/health-check.yml to run daily at 2am UTC
- Add scripts/backfill-health-checks.ts to populate health data for existing tools
- Remove health-check from vercel.json crons (now using GitHub Actions)

The GitHub Action workflow follows the same pattern as other sync operations
and calls the /api/sync/health-check endpoint with proper authentication.

The backfill script:
- Fetches all tools from database
- Runs batch health checks with concurrency control (5 tools at a time)
- Shows detailed progress and summary statistics
- Lists broken tools with error details

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:36:55 +10:00
Ajax Davis
64a05482e4 feat: add health status UI to search and detail pages
Add comprehensive health status visibility across tool browsing:

Search Page (/tool/tool-search):
- Add health filter dropdown (All/Healthy Only/Broken Only)
- Show "Broken" badges on tool cards when import or execution fails
- Include health filter in Clear Filters button logic
- Update Tool interface with health fields

Detail Page (/tool/[...slug]):
- Add prominent warning banner for broken tools
- Display specific failure types (Import Failed / Execution Failed)
- Show health check error messages in code blocks
- Add manual "Recheck health" button with loading state
- Display last health check timestamp

Phase 3 of health check system implementation complete.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:30:04 +10:00
Ajax Davis
e18ebb9282 feat: add broken tools page at /tool/broken
Create dedicated page to display all tools with failed health checks.

Features:
- Lists all tools with importHealth='BROKEN' OR executionHealth='BROKEN'
- Displays health status badges for both import and execution
- Shows error messages in code blocks for debugging
- Includes last checked timestamp
- Links to tool detail pages for manual recheck
- Shows empty state with checkmark when all tools are healthy
- Warning banner showing total broken tool count

UI Components:
- Card layout with red borders for broken tools
- Health status icons (check/x) for visual status
- Category badges and version info
- Direct links to tool detail pages

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:20:47 +10:00
Ajax Davis
b51060d9e7 feat: trigger health checks automatically when tools are synced
Add non-blocking health check calls to both sync endpoints:
- /api/sync/changes: Triggers health checks after tool upsert from changes feed
- /api/sync/keyword: Triggers health checks after tool upsert from keyword search

Health checks run asynchronously with 'sync' trigger source, ensuring:
- New/updated tools are validated immediately after sync
- Sync operations don't wait for health check completion
- Errors are logged but don't fail the sync

This completes Phase 2 of the health check system implementation.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:16:30 +10:00
Ajax Davis
c2b5284da4 feat: add manual health check endpoint and health filtering
API Endpoints (Phase 2 - Part 2):

1. Manual Health Check Endpoint
   - POST /api/tools/[...slug]
   - Added POST handler to existing tool detail route
   - Extracts slug parsing into shared parseSlug() helper
   - 5-minute rate limit per tool
   - Returns full health check results
   - Validates that export name is provided (can't check whole package)

2. Health Filtering in /api/tools
   - Add query params: ?importHealth=HEALTHY|BROKEN|UNKNOWN
   - Add query params: ?executionHealth=HEALTHY|BROKEN|UNKNOWN
   - Add shorthand: ?broken=true (at least one health check failed)
   - Health filters applied as AND conditions with search/category filters
   - Refactored to reduce complexity:
     - Extract buildHealthFilters() helper
     - Extract buildPackageFilter() helper
     - Extract buildWhereClause() helper

3. Code Quality Improvements
   - Extract parseSlug() helper to reduce duplication (DRY)
   - Remove useless else clauses (biome lint fix)
   - Reduce cognitive complexity (GET: 16->8, POST: simplified)

RESTful Design:
- GET /api/tools/@tpmjs/hello/hello -> Fetch tool data
- POST /api/tools/@tpmjs/hello/hello -> Trigger health check

Query Examples:
- /api/tools?broken=true (all broken tools)
- /api/tools?importHealth=HEALTHY&executionHealth=HEALTHY (fully healthy)
- /api/tools?q=text&broken=true (search "text" in broken tools)

Rate Limiting:
- Manual recheck cooldown: 5 minutes per tool
- Returns 429 with retryAfter seconds on rate limit

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:12:40 +10:00
Ajax Davis
e2af4cfd6a feat: implement health check system (Phase 1 & 2)
Add comprehensive health monitoring for TPMJS tools that tracks both
import and execution health via Railway executor service.

## Database Schema

- Add HealthStatus enum (UNKNOWN, HEALTHY, BROKEN)
- Add HealthCheckType enum (IMPORT, EXECUTION, FULL)
- Add health fields to Tool model:
  - importHealth: tracks if tool can be loaded
  - executionHealth: tracks if tool can execute
  - lastHealthCheck: timestamp of last check
  - healthCheckError: stores error message
- Add HealthCheck audit table for full history

## Core Service

Create health-check-service.ts with 5 functions:
1. checkImportHealth() - Tests tool loading via /load-and-describe
2. checkExecutionHealth() - Tests execution via /execute-tool
3. generateTestParameters() - Creates minimal test params by type
4. performHealthCheck() - Full check with database updates
5. performBatchHealthCheck() - Processes tools in batches

Features:
- 30-second timeout per check
- Skips execution if import fails
- Batch processing (5 concurrent, 1s delays)
- Full audit trail in HealthCheck table

## API Endpoints

/api/sync/health-check (POST):
- Daily cron job at 2am UTC
- Checks all tools in database
- Requires CRON_SECRET auth
- Logs results to SyncLog table
- Max duration: 5 minutes

/api/tools/broken (GET):
- Lists all tools with broken health status
- Filters by importHealth='BROKEN' OR executionHealth='BROKEN'
- Includes package metadata
- Orders by lastHealthCheck DESC

## Configuration

- Add RAILWAY_EXECUTOR_URL to env.ts
- Add daily cron job to vercel.json
- Use db:push for schema changes (existing production data)

Next: Manual trigger endpoint + health filtering + UI components

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 16:03:21 +10:00
Ajax Davis
cf10a73e5a feat: add Node.js compatibility layer to Railway executor
Add multi-strategy import system to support Node.js packages in Deno:

1. Primary: Use npm: specifier for Node.js compatibility mode
2. Fallback: Use esm.sh with explicit esnext target

This allows packages like ai-sdk-tool-code-execution that depend on
Node.js built-ins (node:sqlite, undici) to work in the Deno runtime.

Also added deno.json with nodeModulesDir and BYONM support.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 15:18:38 +10:00
Ajax Davis
1d8b9a0f31 fix: check for errorText field in tool error rendering
AI SDK streams use "errorText" field for tool errors, not "error".
Updated MessageBubble to check both errorText and error for compatibility.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 15:04:54 +10:00
Ajax Davis
4cb7555c49 feat: display tool execution errors in chat UI
Add error message rendering to MessageBubble component so users can see
detailed error messages when tools fail (e.g., missing API keys).

Previously only showed "output-error" badge without the actual error text.
Now displays the error message in a red-tinted box below the tool call.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:59:34 +10:00
Ajax Davis
9b9f0f0859 feat: add factory function support to Railway tool executor
Detects and handles tools exported as factory functions that require
configuration before returning the actual AI SDK tool object.

Supports multiple factory patterns:
1. No-args factory: toolName()
2. Config object: toolName({ apiKey: 'xxx' })
3. Single-arg: toolName('api-key-value')

For config objects, tries multiple key name variations:
- Raw env vars: { VALYU_API_KEY: 'xxx' }
- Normalized apiKey: { apiKey: 'xxx' }
- Normalized key: { key: 'xxx' }

This enables dynamic loading of tools like @valyu/ai-sdk paperSearch
that use factory patterns instead of direct tool exports.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:52:47 +10:00
Ajax Davis
9fc4339d52 fix: read env vars directly from localStorage to avoid React closure issue
The previous approach using useEnvVars() hook had a closure problem:
- envVars started as [] on first render
- buildEnvObject captured this empty array
- Even with function body, the transport memoized the old buildEnvObject

Solution: Read directly from localStorage inside the body function
- Bypasses React state entirely
- Gets fresh values on each request
- No closure issues

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 14:36:51 +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
8441b5fc70 fix: use deployed /api/tools endpoint with client-side filtering and streamline git hooks
- Change search-registry to use /api/tools instead of /api/tools/search (not deployed yet)
- Add client-side filtering for search queries since deployed API doesn't support search
- Handle both deployed (/api/tools) and local dev (/api/tools/search) response formats
- Remove lint from pre-commit hooks to speed up commits (keep format + type-check)
- Fixes 404 errors when playground tries to search tools in production

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 13:43:19 +10:00