Skip to content

Conversation

@Davaakhatan
Copy link

@Davaakhatan Davaakhatan commented Dec 13, 2025

Summary

Migrates conversational chat from Go/Anthropic SDK to Next.js/Vercel AI SDK while maintaining all existing functionality.

Changes

  • Frontend: Migrated from @anthropic-ai/sdk to Vercel AI SDK for streaming chat
  • Backend: New Next.js API route (/api/chat/conversational) handles LLM requests
  • Worker: Go worker now calls Next.js route instead of using Anthropic SDK directly
  • Real-time: Preserved Centrifugo streaming for live updates
  • Security: Added dedicated INTERNAL_API_TOKEN for worker authentication

What's Working

Streaming chat responses with real-time updates
Tool calling (latest_subchart_version, latest_kubernetes_version)
Context injection (chart structure, relevant files, chat history)
System prompts and instructions
All existing tests passing (10/10)

Bug Fixes

  • Fixed 404/500 error handling for missing messages
  • Prevented response duplication on job retry
  • Fixed buffered chunks application on message load
  • Fixed Chart.yaml/values.yaml guaranteed inclusion
  • Fixed worker timeout alignment (5min route + 6min HTTP timeout)
  • Removed hardcoded subchart version placeholder

Testing

Tested end-to-end with conversational chat flow - messages stream correctly without page refresh.

Replace direct Anthropic SDK usage in the Next.js frontend with Vercel
AI SDK. This migration:

- Migrates prompt-type.ts to use AI SDK Core's generateText()
- Removes @anthropic-ai/sdk dependency (saves 22 packages)
- Adds ai and @ai-sdk/anthropic packages
- Maintains exact same functionality for intent detection
- Keeps Go worker's Anthropic SDK usage unchanged

The Go worker continues to handle main LLM processing with Anthropic
SDK Go and Centrifugo streaming. This migration only affects the
Next.js frontend where @anthropic-ai/sdk was used for intent detection.

All existing features continue to work with no behavior changes.
- Documents completed Phase 1: frontend dependency migration
- Outlines remaining work for full migration
- Analyzes architectural challenges (Go worker vs Next.js)
- Provides recommendations for hybrid approach
- Estimates 1-2 weeks for complete migration

Also includes:
- Fix for node-fetch import (use Next.js built-in fetch)
- Monaco error suppression utility
This commit completes the migration from direct Anthropic SDK usage to
Vercel AI SDK for conversational chat functionality.

Changes:
- Created Next.js API route with Vercel AI SDK streamText()
- Implemented database helpers for chat persistence
- Added Centrifugo publishing for real-time updates
- Ported context retrieval (chart structure, relevant files, chat history)
- Implemented tool calling (latest_subchart_version, latest_kubernetes_version)
- Added Go worker listener for new_ai_sdk_chat events
- Updated work queue to use new_ai_sdk_chat
- Added comprehensive implementation guide

New files:
- chartsmith-app/app/api/chat/conversational/route.ts
- chartsmith-app/lib/workspace/chat-helpers.ts
- chartsmith-app/lib/workspace/context.ts
- chartsmith-app/lib/realtime/centrifugo-publish.ts
- chartsmith-app/lib/workspace/actions/process-ai-chat.ts
- pkg/listener/ai-sdk-chat.go
- IMPLEMENTATION_GUIDE.md

Modified files:
- chartsmith-app/package.json (added ai, @ai-sdk/anthropic, zod)
- chartsmith-app/lib/workspace/workspace.ts (enqueue new_ai_sdk_chat)
- pkg/listener/start.go (added new_ai_sdk_chat handler)

Testing: Next.js compiles successfully, Go worker builds without errors
…b APIs

Ported the getLatestSubchartVersion implementation from pkg/recommendations/subchart.go
to TypeScript. The implementation includes:

- Artifact Hub API search for Helm chart versions
- GitHub API integration for Replicated SDK version lookup
- Version caching with 45-minute TTL for Replicated charts
- Pinned version override map for specific subcharts
- Error handling that returns 'unknown' on failure

Updated the latest_subchart_version tool in the Vercel AI SDK API route to use
the actual implementation instead of placeholder "1.0.0".
Fixed pre-existing TypeScript error in archive.ts where native fetch() returns
a Web ReadableStream that doesn't have .pipe() method. Now using Readable.fromWeb()
to convert Web ReadableStream to Node.js Readable stream for compatibility with
tar extraction pipeline.
- Replace direct Anthropic SDK with @ai-sdk/anthropic
- Use streamText() for chat streaming with real-time updates
- Add Centrifugo WebSocket support for streaming chunks
- Maintain all existing functionality: system prompts, tools, context
- Enable easy AI provider switching
- All unit tests passing (10/10)
1. Use system parameter for system prompts
   - System prompts should use streamText's system parameter, not assistant messages
   - Ensures model interprets them as system instructions, not prior responses

2. Fix invalid model name
   - Change claude-3-7-sonnet-20250219 to claude-3-5-sonnet-20241022
   - The 3-7 model doesn't exist in Anthropic's model family

3. Remove incorrect authentication check
   - Removed userIdFromExtensionToken import (unused)
   - Route is called by trusted Go worker via Bearer token
   - Middleware already handles authentication for this route
- Warn when Centrifugo chunk arrives for unknown message
- Helps identify potential race conditions in practice
Bug replicatedhq#1: Add missing message_from_persona to getChatMessage SELECT
- Persona information was silently dropped from fetched messages

Bug replicatedhq#2: Add authentication validation to conversational API route
- Validate Bearer token matches ANTHROPIC_API_KEY
- Prevents unauthorized LLM calls and data exposure

Bug replicatedhq#3: Remove forced NON_PLAN intent for established workspaces
- Allow intent classification to work properly
- Users can now create plans in workspaces with existing files

Bug replicatedhq#4: Fix concurrent chunk append race condition
- Use row-level locking (FOR UPDATE) in appendChatMessageResponse
- Prevents overlapping onChunk updates from dropping text

Bug replicatedhq#5: Fix pgvector query parameter casting
- Cast embeddings parameter to ::vector type
- Prevents query failures and relevance selection fallback
Bug replicatedhq#6: AI chat auth token source mismatch
- Changed process-ai-chat.ts to use process.env.ANTHROPIC_API_KEY
- Matches what API route validates against
- Prevents 401s in production when key sources differ

Bug replicatedhq#7: Streaming chunks dropped for unknown message
- Added pendingChunksRef buffer in useCentrifugo
- Buffers chunks that arrive before message is in state
- Applies buffered chunks when message loads
- Prevents permanent loss of streamed content on reconnect
Bug replicatedhq#8: Buffered chunks can duplicate message response
- Removed pending chunk application on chunk arrival
- Pending chunks are cleared when message enters state
- Database response already contains persisted chunks

Bug replicatedhq#9: Anthropic key reused as endpoint auth token
- Created dedicated INTERNAL_API_TOKEN for worker->Next.js auth
- Separates internal auth from third-party API credentials
- Prevents Anthropic key leakage via request headers

Bug replicatedhq#10: Worker may call chat route unauthenticated
- Made INTERNAL_API_TOKEN required in both Go worker and Next.js
- Prevents 401 errors when ANTHROPIC_API_KEY unavailable
- Ensures consistent authentication across environments

BREAKING CHANGE: Requires INTERNAL_API_TOKEN environment variable
- Add to .env.local: INTERNAL_API_TOKEN=your-secret-token
- Add to worker environment when starting
Bug replicatedhq#11: Buffered chunks lose completion state
- Changed pendingChunksRef to store both chunks and isComplete
- Preserves completion state when chunks arrive before message loads
- Prevents messages from remaining incomplete after stream finishes

Bug replicatedhq#12: Empty userId breaks Centrifugo channel
- Added validation to reject chat messages with missing userId
- Prevents publishing to invalid channels (workspaceId#)
- Ensures clients receive streaming updates

Bug replicatedhq#13: Chart.yaml lookup misses nested chart paths
- Changed queries to match nested paths using LIKE '%/Chart.yaml'
- Ensures Chart.yaml and values.yaml are included in context
- Fixes missing chart context for extracted archives/subcharts
Bug replicatedhq#14: New dependency implicitly requires Node 20
- ai@5.0.113 depends on @vercel/oidc@3.0.5 which requires Node 20+
- Added engines field to package.json to make requirement explicit
- Prevents runtime errors in Node 18 environments
- Helps CI/CD systems detect incompatibility early

BREAKING CHANGE: Requires Node.js 20 or higher
- Add 6-minute HTTP timeout to worker chat requests
- Match Next.js route maxDuration (5 minutes)
- Remove dummy subchart-name placeholder from override map
- Prevent worker from blocking indefinitely
- Fix hardcoded subchart version override
- Skip overwriting pre-inserted Chart.yaml/values.yaml entries
- Extend similarity boost to nested paths (*/Chart.yaml)
- Preserve similarity 1.0 for guaranteed files
Bug replicatedhq#1: getChatMessage returns null for 404 instead of 500
- Change return type to ChatMessage | null
- Return null when no rows found instead of throwing
- API route now properly returns 404 for missing messages

Bug replicatedhq#2: Clear response before streaming to prevent duplication
- Add clearChatMessageResponse() helper
- Clear existing response at start of API route
- Prevents mixed/duplicated output on retry

Bug replicatedhq#3: Apply buffered chunks when messages load
- Buffered chunks now applied in handleRevisionCreated
- Prevents losing early chunks when message not yet in state
- Properly cleans up buffer map after applying chunks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant