Add multi-provider AI support (Claude and Mistral)
- Update runRound() to dynamically select correct AI client based on session.aiProvider - Modify POST /api/collaborate to accept and validate aiProvider parameter - Add aiProvider field to session creation response - Add AI provider selector dropdown to frontend (Mistral Large 2411 vs Claude 3.5 Sonnet) - Update collaboration store to pass aiProvider parameter through API Users can now choose between Mistral and Claude AI for their collaborative sessions. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
60fdc9a66f
commit
130e21c867
@ -10,7 +10,7 @@ const router = express.Router()
|
|||||||
*/
|
*/
|
||||||
router.post('/', async (req, res) => {
|
router.post('/', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const { prompt, documentFormat = 'md', agentCount = 7 } = req.body
|
const { prompt, documentFormat = 'md', agentCount = 7, aiProvider = 'mistral' } = req.body
|
||||||
|
|
||||||
if (!prompt || prompt.trim().length === 0) {
|
if (!prompt || prompt.trim().length === 0) {
|
||||||
return res.status(400).json({ error: 'Prompt is required' })
|
return res.status(400).json({ error: 'Prompt is required' })
|
||||||
@ -20,13 +20,18 @@ router.post('/', async (req, res) => {
|
|||||||
return res.status(400).json({ error: 'Document format must be "md" or "txt"' })
|
return res.status(400).json({ error: 'Document format must be "md" or "txt"' })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!['mistral', 'claude'].includes(aiProvider)) {
|
||||||
|
return res.status(400).json({ error: 'AI provider must be "mistral" or "claude"' })
|
||||||
|
}
|
||||||
|
|
||||||
// Validate agent count
|
// Validate agent count
|
||||||
const validAgentCount = Math.min(Math.max(agentCount, 3), 50)
|
const validAgentCount = Math.min(Math.max(agentCount, 3), 50)
|
||||||
|
|
||||||
const sessionId = collaborativeOrchestrator.createSession(
|
const sessionId = collaborativeOrchestrator.createSession(
|
||||||
prompt,
|
prompt,
|
||||||
documentFormat,
|
documentFormat,
|
||||||
validAgentCount
|
validAgentCount,
|
||||||
|
aiProvider
|
||||||
)
|
)
|
||||||
|
|
||||||
const sessionInfo = collaborativeOrchestrator.getSessionInfo(sessionId)
|
const sessionInfo = collaborativeOrchestrator.getSessionInfo(sessionId)
|
||||||
@ -36,6 +41,7 @@ router.post('/', async (req, res) => {
|
|||||||
prompt,
|
prompt,
|
||||||
documentFormat,
|
documentFormat,
|
||||||
agentCount: validAgentCount,
|
agentCount: validAgentCount,
|
||||||
|
aiProvider,
|
||||||
status: 'created',
|
status: 'created',
|
||||||
agents: sessionInfo.agents,
|
agents: sessionInfo.agents,
|
||||||
message: 'Collaborative session created. Start the session to begin collaboration.'
|
message: 'Collaborative session created. Start the session to begin collaboration.'
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import db from '../db/schema.js'
|
import db from '../db/schema.js'
|
||||||
import { generateAgentResponseSync, extractSection, extractThinking } from './mistralClient.js'
|
import * as mistralClient from './mistralClient.js'
|
||||||
|
import * as claudeClient from './claudeClient.js'
|
||||||
import { getRandomNames } from './nameGenerator.js'
|
import { getRandomNames } from './nameGenerator.js'
|
||||||
|
|
||||||
class CollaborativeOrchestrator {
|
class CollaborativeOrchestrator {
|
||||||
@ -44,13 +45,13 @@ class CollaborativeOrchestrator {
|
|||||||
/**
|
/**
|
||||||
* Create a new collaborative session with N random-named agents
|
* Create a new collaborative session with N random-named agents
|
||||||
*/
|
*/
|
||||||
createSession(initialPrompt, documentFormat = 'md', agentCount = 7) {
|
createSession(initialPrompt, documentFormat = 'md', agentCount = 7, aiProvider = 'mistral') {
|
||||||
const stmt = db.prepare(
|
const stmt = db.prepare(
|
||||||
'INSERT INTO collaborative_sessions (initial_prompt, document_format, status) VALUES (?, ?, ?)'
|
'INSERT INTO collaborative_sessions (initial_prompt, document_format, status) VALUES (?, ?, ?)'
|
||||||
)
|
)
|
||||||
const result = stmt.run(initialPrompt, documentFormat, 'created')
|
const result = stmt.run(initialPrompt, documentFormat, 'created')
|
||||||
const sessionId = result.lastInsertRowid
|
const sessionId = result.lastInsertRowid
|
||||||
console.log(`[Session ${sessionId}] Created with ${agentCount} agents, format: ${documentFormat}`)
|
console.log(`[Session ${sessionId}] Created with ${agentCount} agents, format: ${documentFormat}, provider: ${aiProvider}`)
|
||||||
|
|
||||||
// Generate random names for agents
|
// Generate random names for agents
|
||||||
const agentNames = getRandomNames(Math.min(agentCount, 50))
|
const agentNames = getRandomNames(Math.min(agentCount, 50))
|
||||||
@ -59,6 +60,7 @@ class CollaborativeOrchestrator {
|
|||||||
id: sessionId,
|
id: sessionId,
|
||||||
initialPrompt,
|
initialPrompt,
|
||||||
documentFormat,
|
documentFormat,
|
||||||
|
aiProvider, // Claude or Mistral
|
||||||
agents: agentNames, // Array of agent names
|
agents: agentNames, // Array of agent names
|
||||||
agentCount,
|
agentCount,
|
||||||
currentAgentIndex: 0,
|
currentAgentIndex: 0,
|
||||||
@ -179,14 +181,15 @@ class CollaborativeOrchestrator {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
console.log(`[Session ${sessionId}] ${agentName} analyzing and generating response...`)
|
console.log(`[Session ${sessionId}] ${agentName} analyzing and generating response...`)
|
||||||
const response = await generateAgentResponseSync(
|
const client = session.aiProvider === 'claude' ? claudeClient : mistralClient
|
||||||
|
const response = await client.generateAgentResponseSync(
|
||||||
agentName,
|
agentName,
|
||||||
session.initialPrompt,
|
session.initialPrompt,
|
||||||
session.currentDocument // <-- This is always the latest version
|
session.currentDocument // <-- This is always the latest version
|
||||||
)
|
)
|
||||||
|
|
||||||
const thinking = extractThinking(response)
|
const thinking = client.extractThinking(response)
|
||||||
const section = extractSection(response)
|
const section = client.extractSection(response)
|
||||||
|
|
||||||
console.log(`[Session ${sessionId}] ${agentName} response received (${response.length} chars)`)
|
console.log(`[Session ${sessionId}] ${agentName} response received (${response.length} chars)`)
|
||||||
console.log(`[Session ${sessionId}] --- THINKING (${agentName}) ---`)
|
console.log(`[Session ${sessionId}] --- THINKING (${agentName}) ---`)
|
||||||
|
|||||||
@ -9,6 +9,7 @@ const collaborationStore = useCollaborationStore()
|
|||||||
const prompt = ref('')
|
const prompt = ref('')
|
||||||
const contextFile = ref(null)
|
const contextFile = ref(null)
|
||||||
const agentCount = ref(7)
|
const agentCount = ref(7)
|
||||||
|
const aiProvider = ref('mistral')
|
||||||
const isCreating = ref(false)
|
const isCreating = ref(false)
|
||||||
const previousSessions = ref([])
|
const previousSessions = ref([])
|
||||||
const loadingPreviousSessions = ref(false)
|
const loadingPreviousSessions = ref(false)
|
||||||
@ -108,7 +109,8 @@ const handleCreateSession = async () => {
|
|||||||
const session = await collaborationStore.createSession(
|
const session = await collaborationStore.createSession(
|
||||||
finalPrompt,
|
finalPrompt,
|
||||||
'md',
|
'md',
|
||||||
agentCount.value
|
agentCount.value,
|
||||||
|
aiProvider.value
|
||||||
)
|
)
|
||||||
|
|
||||||
emit('session-created', session)
|
emit('session-created', session)
|
||||||
@ -117,6 +119,7 @@ const handleCreateSession = async () => {
|
|||||||
prompt.value = ''
|
prompt.value = ''
|
||||||
contextFile.value = null
|
contextFile.value = null
|
||||||
agentCount.value = 7
|
agentCount.value = 7
|
||||||
|
aiProvider.value = 'mistral'
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
alert(`Error creating session: ${collaborationStore.error}`)
|
alert(`Error creating session: ${collaborationStore.error}`)
|
||||||
} finally {
|
} finally {
|
||||||
@ -290,7 +293,7 @@ const removeFile = () => {
|
|||||||
<p class="hint">Optional: Provide existing documentation or requirements to guide the design.</p>
|
<p class="hint">Optional: Provide existing documentation or requirements to guide the design.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Agent Count Selection -->
|
<!-- Agent Count and AI Provider Selection -->
|
||||||
<div class="form-grid">
|
<div class="form-grid">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="agents" class="label">Number of AI Specialists</label>
|
<label for="agents" class="label">Number of AI Specialists</label>
|
||||||
@ -301,6 +304,14 @@ const removeFile = () => {
|
|||||||
</select>
|
</select>
|
||||||
<p class="hint">More agents = more diverse perspectives.</p>
|
<p class="hint">More agents = more diverse perspectives.</p>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="provider" class="label">AI Provider</label>
|
||||||
|
<select v-model="aiProvider" id="provider" class="select">
|
||||||
|
<option value="mistral">Mistral (Large 2411)</option>
|
||||||
|
<option value="claude">Claude (3.5 Sonnet)</option>
|
||||||
|
</select>
|
||||||
|
<p class="hint">Choose the AI model for specialists.</p>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Info Box -->
|
<!-- Info Box -->
|
||||||
|
|||||||
@ -15,7 +15,7 @@ export const useCollaborationStore = defineStore('collaboration', () => {
|
|||||||
/**
|
/**
|
||||||
* Create a new collaborative session
|
* Create a new collaborative session
|
||||||
*/
|
*/
|
||||||
async function createSession(prompt, documentFormat = 'md', agentCount = 7) {
|
async function createSession(prompt, documentFormat = 'md', agentCount = 7, aiProvider = 'mistral') {
|
||||||
loading.value = true
|
loading.value = true
|
||||||
error.value = null
|
error.value = null
|
||||||
|
|
||||||
@ -28,7 +28,8 @@ export const useCollaborationStore = defineStore('collaboration', () => {
|
|||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
prompt,
|
prompt,
|
||||||
documentFormat,
|
documentFormat,
|
||||||
agentCount
|
agentCount,
|
||||||
|
aiProvider
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user