feat(ai,coding-agent): add faux provider and ModelRegistry factories
This commit is contained in:
@@ -636,6 +636,92 @@ The library uses a registry of API implementations. Built-in APIs include:
|
||||
- **`azure-openai-responses`**: Azure OpenAI Responses API (`streamAzureOpenAIResponses`, `AzureOpenAIResponsesOptions`)
|
||||
- **`bedrock-converse-stream`**: Amazon Bedrock Converse API (`streamBedrock`, `BedrockOptions`)
|
||||
|
||||
### Faux provider for tests
|
||||
|
||||
`registerFauxProvider()` registers a temporary in-memory provider for tests and demos. It is opt-in and not part of the built-in provider set.
|
||||
|
||||
```typescript
|
||||
import {
|
||||
complete,
|
||||
fauxAssistantMessage,
|
||||
fauxText,
|
||||
fauxThinking,
|
||||
fauxToolCall,
|
||||
registerFauxProvider,
|
||||
stream,
|
||||
} from '@mariozechner/pi-ai';
|
||||
|
||||
const registration = registerFauxProvider({
|
||||
tokensPerSecond: 50 // optional
|
||||
});
|
||||
|
||||
const model = registration.getModel();
|
||||
const context = {
|
||||
messages: [{ role: 'user', content: 'Summarize package.json and then call echo', timestamp: Date.now() }]
|
||||
};
|
||||
|
||||
registration.setResponses([
|
||||
fauxAssistantMessage([
|
||||
fauxThinking('Need to inspect package metadata first.'),
|
||||
fauxToolCall('echo', { text: 'package.json' })
|
||||
], { stopReason: 'toolUse' })
|
||||
]);
|
||||
|
||||
const first = await complete(model, context, {
|
||||
sessionId: 'session-1',
|
||||
cacheRetention: 'short'
|
||||
});
|
||||
context.messages.push(first);
|
||||
|
||||
context.messages.push({
|
||||
role: 'toolResult',
|
||||
toolCallId: first.content.find((block) => block.type === 'toolCall')!.id,
|
||||
toolName: 'echo',
|
||||
content: [{ type: 'text', text: 'package.json contents here' }],
|
||||
isError: false,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
registration.setResponses([
|
||||
fauxAssistantMessage([
|
||||
fauxThinking('Now I can summarize the tool output.'),
|
||||
fauxText('Here is the summary.')
|
||||
])
|
||||
]);
|
||||
|
||||
const s = stream(model, context);
|
||||
for await (const event of s) {
|
||||
console.log(event.type);
|
||||
}
|
||||
|
||||
// Optional: register multiple faux models for model-switching tests
|
||||
const multiModel = registerFauxProvider({
|
||||
models: [
|
||||
{ id: 'faux-fast', reasoning: false },
|
||||
{ id: 'faux-thinker', reasoning: true }
|
||||
]
|
||||
});
|
||||
const thinker = multiModel.getModel('faux-thinker');
|
||||
|
||||
console.log(thinker?.reasoning);
|
||||
console.log(registration.getPendingResponseCount());
|
||||
console.log(registration.state.callCount);
|
||||
registration.unregister();
|
||||
multiModel.unregister();
|
||||
```
|
||||
|
||||
Notes:
|
||||
- Responses are consumed from a queue in request start order.
|
||||
- If the queue is empty, the faux provider returns an assistant error message with `errorMessage: "No more faux responses queued"`.
|
||||
- Use `registration.setResponses([...])` to replace the remaining queue and `registration.appendResponses([...])` to add more responses.
|
||||
- `registration.models` exposes all registered faux models. `registration.getModel()` returns the first one, and `registration.getModel(id)` returns a specific one.
|
||||
- Use `fauxAssistantMessage(...)` for scripted assistant replies. Use `fauxText(...)`, `fauxThinking(...)`, and `fauxToolCall(...)` to build content blocks without filling in low-level fields manually.
|
||||
- `registration.unregister()` removes the temporary provider from the global API registry.
|
||||
- Usage is estimated at roughly 1 token per 4 characters. When `sessionId` is present and `cacheRetention` is not `"none"`, prompt cache reads and writes are simulated automatically.
|
||||
- Tool call arguments stream incrementally via `toolcall_delta` chunks.
|
||||
- By default, each streamed chunk is emitted on its own microtask. Set `tokensPerSecond` to pace chunk delivery in real time.
|
||||
- The intended use is one deterministic scripted flow per registration. If you need independent concurrent flows, register separate faux providers.
|
||||
|
||||
### Providers and Models
|
||||
|
||||
A **provider** offers models through a specific API. For example:
|
||||
|
||||
Reference in New Issue
Block a user