Provider-agnostic AI service layer for MDP Framework
npm install @mdp-framework/ai-servicesProvider-agnostic AI service layer for MDP Framework.
✅ IMPLEMENTED - Stream 1 Complete
See: Stream 1 Contract
TODO-STREAM-1: Ready for consumption by dependent streams (2, 4, 5)
Foundation layer providing AI capabilities to:
- Stream 2: AI-powered policy evaluation
- Stream 4: AOI specification generation
- Stream 5: Multi-agent orchestration
All interfaces in src/contracts/ are FROZEN per CONTRACTS-AI.md.
Changes require:
1. Major version bump
2. Cross-team review
3. Migration guide
src/providers/anthropic.ts - AnthropicProvider with structured outputsrc/registry.ts - Multi-provider registrysrc/providers/openai.ts - OpenAIProvider with embeddingssrc/providers/mock.ts - MockProvider for deterministic testingsrc/prompts/template.ts - Jinja2-like templating with validationsrc/cost-tracker.ts - Token counting & budget enforcement- ✅ Token cost estimation within 5%
- ✅ Embeddings <1s for 1KB text
- ✅ 100% test coverage
- ✅ All providers implement AIProvider interface
``typescript
import { AnthropicProvider, OpenAIProvider, MockProvider } from '@mdp-framework/ai-services';
// Initialize provider
const provider = new AnthropicProvider({
apiKey: process.env.ANTHROPIC_API_KEY
});
// Complete with structured output
const response = await provider.complete({
prompt: 'Evaluate this PR against policy...',
schema: {
type: 'object',
properties: {
violations: { type: 'array' }
}
},
temperature: 0.1
});
console.log(Cost: $${response.usage.cost_usd});`
console.log('Violations:', response.structured.violations);
`typescript
import { DefaultAIProviderRegistry, AnthropicProvider, OpenAIProvider } from '@mdp-framework/ai-services';
const registry = new DefaultAIProviderRegistry();
registry.register(new AnthropicProvider({ apiKey: process.env.ANTHROPIC_API_KEY }));
registry.register(new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY }));
// Use default provider
const provider = registry.getDefault();
const response = await provider.complete({ prompt: 'Hello!' });
// Switch providers
registry.setDefault('openai');
`
`typescript
import { PromptTemplateBuilder } from '@mdp-framework/ai-services';
const template = new PromptTemplateBuilder()
.setName('policy-eval')
.setTemplate('Evaluate: {{code}}\nPolicy: {{policy}}')
.addVariable('code', 'string', { required: true })
.addVariable('policy', 'string', { required: true })
.build();
const prompt = template.render({
code: 'console.log("test")',
policy: 'No console.log statements'
});
const response = await provider.complete({ prompt });
`
`typescript
import { CostTracker } from '@mdp-framework/ai-services';
const tracker = new CostTracker({
max_cost_per_day: 10.0,
alert_threshold_pct: 80
});
// Check budget before call
const estimate = provider.estimateTokens(prompt);
const check = tracker.wouldExceedBudget(estimate.cost_usd);
if (!check.exceeded) {
const response = await provider.complete({ prompt });
tracker.recordCost({
provider: provider.name,
model: response.model,
input_tokens: response.usage.input_tokens,
output_tokens: response.usage.output_tokens,
total_tokens: response.usage.total_tokens,
cost_usd: response.usage.cost_usd
});
}
// Get summary
const summary = tracker.getSummary();
console.log(Total spent: $${summary.total_cost_usd});`
`typescript
import { OpenAIProvider } from '@mdp-framework/ai-services';
const provider = new OpenAIProvider({ apiKey: process.env.OPENAI_API_KEY });
const embeddings = await provider.embed([
'First document',
'Second document',
'Third document'
]);
console.log(Embedding dimension: ${embeddings[0].vector.length});`
Consumed By:
- @mdp-framework/gateway (Stream 2, 4)@mdp-framework/agents` (Stream 5)
-
No Dependencies: Foundation layer
MIT