Description
The goal of this task is to ensure the following:
- conventional specifiers (ex:
openai/gpt-4o-mini
) for AI models work - lazy specifiers (ex:
gpt-4o-mini
,groq
) work - backward-compatibility is preserved
General AI Architecture
For this task it may be helpful to know the general structure of the AI providers. AI providers are actually individual Puter driver implementations, but they register with AIChatService - a parent driver implementation that delegates to each provider.
Coercion in puter.js
The puter.js AI module already does coercion for specific cases, but backend can handle this in a more generalized way which will also ensure that the SDK and API are consistent.
When we call await puter.ai.chat("Hello", { model: 'gpt-4o-mini' })
, a request is made to the API that's equivalent to this fetch call:
await fetch('https://api.puter.local/drivers/call', {
method: 'POST',
headers: {
Authorization: `Bearer ${puter.authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
interface: 'puter-chat-completion',
driver: 'openai-completion',
method: 'complete',
args: {
messages: [{ content: 'Hi Hello' }],
model: 'gpt-4o-mini'
}
})
});
The ai-chat
driver
Every AI service (openai-completion
, xai
, groq
, openrouter
, etc) registers itself as a provider to AIChatService. When all services are initialized (this phase is called consolidation) the AIChatService will register itself as an alias of each AI provider to DriverService so that everything goes through AIChatService as a central controller.
Right now we don't allow calling ai-chat
directly because we use the "intended service" (the one that was requested, that ai-chat
aliased itself as) to determine which AI provider is handling the request. Part of this task will be to remove this guard and have ai-chat
always infer a provider from the model specifier.
Requests that should work but don't work yet
Specifying ai-chat
as the driver
await fetch('https://api.puter.local/drivers/call', {
method: 'POST',
headers: {
Authorization: `Bearer ${puter.authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
interface: 'puter-chat-completion',
driver: 'ai-chat',
method: 'complete',
args: {
messages: [{ content: 'Hi Hello' }],
model: 'gpt-4o-mini'
}
})
});
specifying vendor name without supplier name when calling openrouter
await fetch('https://api.puter.local/drivers/call', {
method: 'POST',
headers: {
Authorization: `Bearer ${puter.authToken}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
interface: 'puter-chat-completion',
driver: 'openrouter',
method: 'complete',
args: {
messages: [{ content: 'Hi Hello' }],
model: 'openai/gpt-4o-mini'
}
})
});