Commit graph

9 commits

Author SHA1 Message Date
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
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
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
9aa7a1e2be feat: add Zod v3 schema support via zod-to-json-schema
- Import zod-to-json-schema from esm.sh
- Add Strategy 3: detect Zod schemas via _def property
- Convert Zod v3/v4 schemas to JSON Schema
- Update error message to mention Zod v3 support
- Fixes firecrawl-aisdk tool schema extraction
2025-12-04 09:49:39 +10:00
Ajax Davis
ec27965ab4 feat: add fallback schema extraction with Zod v4 support
- Try Zod v4 toJSONSchema() or jsonSchema() first
- Fall back to AI SDK jsonSchema.schema property
- Fail gracefully with detailed debug info
- Supports both Zod-based and jsonSchema-based tools
2025-12-04 09:42:53 +10:00
Ajax Davis
956f9fdbae debug: add logging for inputSchema structure inspection 2025-12-04 09:33:09 +10:00
Ajax Davis
bb672edf15 fix: extract and serialize JSON Schema from AI SDK v6 tools correctly
THE BREAKTHROUGH: AI SDK v6 tools use jsonSchema() which wraps plain JSON Schema objects, NOT Zod schemas. JSON Schema is fully serializable.

Changes:
1. Railway server: Extract raw JSON Schema from toolModule.inputSchema?.schema
2. Playground loader: Wrap received JSON Schema with { type: 'json_schema', schema: ... }
3. This matches AI SDK v6 format exactly - no Zod serialization needed

How it works:
- Tools define inputSchema: jsonSchema({ type: 'object', properties: {...} })
- AI SDK stores it as { type: 'json_schema', schema: {...} }
- Railway extracts the plain JSON Schema (.schema property)
- Sends it as plain JSON (fully serializable)
- Playground wraps it back in AI SDK format
- OpenAI receives valid JSON Schema for function calling

This fixes both errors:
 No more "def.shape is not a function" (not using Zod)
 No more "Invalid schema type None" (proper JSON Schema provided)

Note: Tools using Zod instead of jsonSchema() will need to migrate.
TPMJS standard: All tools MUST use jsonSchema() with plain JSON Schema.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-12-04 09:00:00 +10:00
Ajax Davis
287d9b97c9 docs: document Zod schema serialization problem for external consultation 2025-12-04 08:53:26 +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