Parent Epic
Part of #19 - Hybrid ADK + AI SDK Migration
Objective
Refactor the ADK OpenRouter LLM adapter to use AI SDK internally instead of raw fetch calls, while maintaining the ADK BaseLlm interface.
Tasks
Current State
// Current: Raw fetch with manual format conversion
async *generateContentAsync(llmRequest: LlmRequest): AsyncGenerator<LlmResponse> {
const messages = geminiToOpenAI(llmRequest.contents, systemInstruction);
const response = await fetch(`${this.baseUrl}/chat/completions`, {
method: "POST",
headers: { ... },
body: JSON.stringify(requestBody),
});
// Manual retry logic, format conversion...
}
Target State
// Target: AI SDK with native features
async *generateContentAsync(llmRequest: LlmRequest): AsyncGenerator<LlmResponse> {
const { text, toolCalls, usage, reasoningText } = await generateText({
model: this.openrouter(modelId),
messages: this.convertToAISDKMessages(llmRequest.contents),
tools: this.convertToAISDKTools(llmRequest.config?.tools),
providerOptions: isThinkingModel ? {
openrouter: { reasoning: { effort: 'high' } }
} : undefined,
});
yield this.convertToGeminiResponse(text, toolCalls, usage, reasoningText);
}
Key Changes
1. Replace fetch with AI SDK
- Remove
geminiToOpenAI() manual conversion
- Use AI SDK's native message format
- Remove manual retry logic (AI SDK handles it)
2. Add Reasoning Token Support
usageMetadata: {
promptTokenCount: usage.promptTokens,
candidatesTokenCount: usage.completionTokens,
totalTokenCount: usage.totalTokens,
reasoningTokenCount: usage.reasoningTokens, // NEW
}
3. Support :thinking Variant
const isThinkingModel = modelId.includes(':thinking');
providerOptions: isThinkingModel ? {
openrouter: { reasoning: { effort: 'high' } }
} : undefined,
Files to Modify
src/holons/adk/openrouter-llm.ts - Main refactor
src/holons/adk/runner.ts - Update token extraction
src/holons/adk/agents.ts - Test model configurations
Bugs to Fix During Migration
| Bug |
Location |
Fix |
| Unstable tool_call_id |
Line 101 |
Use crypto.randomUUID() |
| Token format mismatch |
Lines 264-276 |
Support both Gemini and OpenAI formats |
| No streaming |
Line 268 |
Document as future enhancement |
Acceptance Criteria
Estimated Effort
2 days
Parent Epic
Part of #19 - Hybrid ADK + AI SDK Migration
Objective
Refactor the ADK OpenRouter LLM adapter to use AI SDK internally instead of raw fetch calls, while maintaining the ADK
BaseLlminterface.Tasks
openrouter-llm.tsto use AI SDKgenerateText()usageMetadatarunner.tstoken extraction for new formatCurrent State
Target State
Key Changes
1. Replace fetch with AI SDK
geminiToOpenAI()manual conversion2. Add Reasoning Token Support
3. Support :thinking Variant
Files to Modify
src/holons/adk/openrouter-llm.ts- Main refactorsrc/holons/adk/runner.ts- Update token extractionsrc/holons/adk/agents.ts- Test model configurationsBugs to Fix During Migration
Acceptance Criteria
Estimated Effort
2 days