v3.0: Add multi-provider Bedrock models, newborn milestones, Converse API
- Bedrock: Add 14 non-vendor model models (Amazon Nova, Meta Llama 4, DeepSeek R1/V3, Mistral Large 3, Cohere Command R+, AI21 Jamba) with verified AWS model IDs - Bedrock: Implement Converse API for non-Anthropic models (unified cross-model API), keep native Messages API for vendor model models (best performance) - Milestones: Add Newborn / 1 month developmental milestones (Gross Motor, Fine Motor, Language, Social/Emotional, Cognitive) — previously started at 2 months - Bump version to 3.0.0, docker-compose tag to v3.0
This commit is contained in:
parent
eb8c86f70e
commit
d2ed08cd46
6 changed files with 144 additions and 32 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
services:
|
services:
|
||||||
pediatric-scribe:
|
pediatric-scribe:
|
||||||
image: danielonyejesi/pediatric-ai-scribe-v3:v2.7
|
image: danielonyejesi/pediatric-ai-scribe-v3:v3.0
|
||||||
ports:
|
ports:
|
||||||
- "3552:3000"
|
- "3552:3000"
|
||||||
env_file:
|
env_file:
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "pediatric-ai-scribe",
|
"name": "pediatric-ai-scribe",
|
||||||
"version": "2.9.0",
|
"version": "3.0.0",
|
||||||
"description": "AI-powered pediatric clinical documentation platform",
|
"description": "AI-powered pediatric clinical documentation platform",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -1002,6 +1002,7 @@
|
||||||
<label>Age Group</label>
|
<label>Age Group</label>
|
||||||
<select id="ms-age-group">
|
<select id="ms-age-group">
|
||||||
<option value="">-- Select --</option>
|
<option value="">-- Select --</option>
|
||||||
|
<option value="Newborn / 1 month">Newborn / 1 Month</option>
|
||||||
<option value="2 months">2 Months</option>
|
<option value="2 months">2 Months</option>
|
||||||
<option value="4 months">4 Months</option>
|
<option value="4 months">4 Months</option>
|
||||||
<option value="6 months">6 Months</option>
|
<option value="6 months">6 Months</option>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,37 @@
|
||||||
|
|
||||||
var MILESTONES_DATA = {
|
var MILESTONES_DATA = {
|
||||||
|
|
||||||
|
"Newborn / 1 month": {
|
||||||
|
"Gross Motor": [
|
||||||
|
"Moves arms and legs equally",
|
||||||
|
"Lifts head briefly when on tummy (prone)",
|
||||||
|
"Strong flexion posture (arms and legs tucked)",
|
||||||
|
"Turns head side to side when lying on back"
|
||||||
|
],
|
||||||
|
"Fine Motor": [
|
||||||
|
"Hands mostly fisted",
|
||||||
|
"Strong grasp reflex when palm is touched",
|
||||||
|
"Brings hands near face"
|
||||||
|
],
|
||||||
|
"Language": [
|
||||||
|
"Cries to express needs",
|
||||||
|
"Startles or quiets to sounds",
|
||||||
|
"Makes brief throaty sounds"
|
||||||
|
],
|
||||||
|
"Social/Emotional": [
|
||||||
|
"Recognizes caregiver voice",
|
||||||
|
"Briefly fixates on faces at close range (8-12 inches)",
|
||||||
|
"Calms when held or hears familiar voice",
|
||||||
|
"Shows brief alert periods"
|
||||||
|
],
|
||||||
|
"Cognitive": [
|
||||||
|
"Focuses on faces briefly",
|
||||||
|
"Follows objects briefly to midline",
|
||||||
|
"Prefers black and white or high-contrast patterns",
|
||||||
|
"Responds to loud sounds (Moro reflex)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
"2 months": {
|
"2 months": {
|
||||||
"Gross Motor": [
|
"Gross Motor": [
|
||||||
"Lifts head when prone (45 degrees)",
|
"Lifts head when prone (45 degrees)",
|
||||||
|
|
|
||||||
|
|
@ -148,15 +148,15 @@ async function callAzure(messages, model, temperature, maxTokens) {
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
// CALL AWS BEDROCK
|
// CALL AWS BEDROCK
|
||||||
|
// Anthropic models use InvokeModel (Messages API)
|
||||||
|
// All other models use Converse API (unified cross-model API)
|
||||||
// ============================================================
|
// ============================================================
|
||||||
async function callBedrock(messages, model, temperature, maxTokens) {
|
async function callBedrock(messages, model, temperature, maxTokens) {
|
||||||
if (!bedrockClient) throw new Error('AWS Bedrock not configured');
|
if (!bedrockClient) throw new Error('AWS Bedrock not configured');
|
||||||
|
|
||||||
var BedrockModule = require('@aws-sdk/client-bedrock-runtime');
|
var BedrockModule = require('@aws-sdk/client-bedrock-runtime');
|
||||||
var InvokeModelCommand = BedrockModule.InvokeModelCommand;
|
|
||||||
|
|
||||||
// Map friendly model ID to Bedrock model ID
|
|
||||||
var modelId = getBedrockModelId(model);
|
var modelId = getBedrockModelId(model);
|
||||||
|
var isAnthropic = modelId.startsWith('anthropic.');
|
||||||
|
|
||||||
// Separate system message from chat messages
|
// Separate system message from chat messages
|
||||||
var systemMsg = '';
|
var systemMsg = '';
|
||||||
|
|
@ -169,35 +169,77 @@ async function callBedrock(messages, model, temperature, maxTokens) {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build request body (Anthropic Messages API format for Bedrock)
|
if (isAnthropic) {
|
||||||
var body = {
|
// Anthropic Messages API format (native, best performance)
|
||||||
anthropic_version: 'bedrock-2023-05-31',
|
var InvokeModelCommand = BedrockModule.InvokeModelCommand;
|
||||||
max_tokens: maxTokens,
|
var body = {
|
||||||
temperature: temperature,
|
anthropic_version: 'bedrock-2023-05-31',
|
||||||
messages: chatMessages
|
max_tokens: maxTokens,
|
||||||
};
|
temperature: temperature,
|
||||||
if (systemMsg) body.system = systemMsg;
|
messages: chatMessages
|
||||||
|
};
|
||||||
|
if (systemMsg) body.system = systemMsg;
|
||||||
|
|
||||||
var command = new InvokeModelCommand({
|
var command = new InvokeModelCommand({
|
||||||
modelId: modelId,
|
modelId: modelId,
|
||||||
contentType: 'application/json',
|
contentType: 'application/json',
|
||||||
accept: 'application/json',
|
accept: 'application/json',
|
||||||
body: JSON.stringify(body)
|
body: JSON.stringify(body)
|
||||||
});
|
});
|
||||||
|
|
||||||
var response = await bedrockClient.send(command);
|
var response = await bedrockClient.send(command);
|
||||||
var responseBody = JSON.parse(new TextDecoder().decode(response.body));
|
var responseBody = JSON.parse(new TextDecoder().decode(response.body));
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
content: responseBody.content[0].text,
|
content: responseBody.content[0].text,
|
||||||
model: modelId,
|
model: modelId,
|
||||||
provider: 'bedrock',
|
provider: 'bedrock',
|
||||||
usage: {
|
usage: {
|
||||||
prompt_tokens: responseBody.usage ? responseBody.usage.input_tokens : 0,
|
prompt_tokens: responseBody.usage ? responseBody.usage.input_tokens : 0,
|
||||||
completion_tokens: responseBody.usage ? responseBody.usage.output_tokens : 0
|
completion_tokens: responseBody.usage ? responseBody.usage.output_tokens : 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
// Converse API — unified API for all non-Anthropic Bedrock models
|
||||||
|
var ConverseCommand = BedrockModule.ConverseCommand;
|
||||||
|
|
||||||
|
var converseMessages = chatMessages.map(function(m) {
|
||||||
|
return { role: m.role, content: [{ text: m.content }] };
|
||||||
|
});
|
||||||
|
|
||||||
|
var converseParams = {
|
||||||
|
modelId: modelId,
|
||||||
|
messages: converseMessages,
|
||||||
|
inferenceConfig: {
|
||||||
|
maxTokens: maxTokens,
|
||||||
|
temperature: temperature
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if (systemMsg) {
|
||||||
|
converseParams.system = [{ text: systemMsg }];
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
var converseResponse = await bedrockClient.send(new ConverseCommand(converseParams));
|
||||||
|
|
||||||
|
var outputText = '';
|
||||||
|
if (converseResponse.output && converseResponse.output.message && converseResponse.output.message.content) {
|
||||||
|
converseResponse.output.message.content.forEach(function(block) {
|
||||||
|
if (block.text) outputText += block.text;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
content: outputText,
|
||||||
|
model: modelId,
|
||||||
|
provider: 'bedrock',
|
||||||
|
usage: {
|
||||||
|
prompt_tokens: converseResponse.usage ? converseResponse.usage.inputTokens : 0,
|
||||||
|
completion_tokens: converseResponse.usage ? converseResponse.usage.outputTokens : 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ============================================================
|
// ============================================================
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ var OPENROUTER_MODELS = [
|
||||||
];
|
];
|
||||||
|
|
||||||
var BEDROCK_MODELS = [
|
var BEDROCK_MODELS = [
|
||||||
// vendor model models only — verified IDs from AWS docs (models-supported.html)
|
// ── Anthropic vendor model — verified IDs from AWS docs (models-supported.html) ──
|
||||||
{ id: 'anthropic/vendor-model-opus-4-6', name: 'vendor model Opus 4.6', cost: '~$0.075', tag: 'BEST NUANCE', category: 'premium',
|
{ id: 'anthropic/vendor-model-opus-4-6', name: 'vendor model Opus 4.6', cost: '~$0.075', tag: 'BEST NUANCE', category: 'premium',
|
||||||
bedrockId: 'anthropic.agent-config-opus-4-6-v1' },
|
bedrockId: 'anthropic.agent-config-opus-4-6-v1' },
|
||||||
{ id: 'anthropic/vendor-model-opus-4-5', name: 'vendor model Opus 4.5', cost: '~$0.075', tag: 'OPUS', category: 'premium',
|
{ id: 'anthropic/vendor-model-opus-4-5', name: 'vendor model Opus 4.5', cost: '~$0.075', tag: 'OPUS', category: 'premium',
|
||||||
|
|
@ -41,7 +41,45 @@ var BEDROCK_MODELS = [
|
||||||
{ id: 'anthropic/vendor-model-haiku-4-5', name: 'vendor model Haiku 4.5', cost: '~$0.003', tag: 'FAST', category: 'smart',
|
{ id: 'anthropic/vendor-model-haiku-4-5', name: 'vendor model Haiku 4.5', cost: '~$0.003', tag: 'FAST', category: 'smart',
|
||||||
bedrockId: 'anthropic.agent-config-haiku-4-5-20251001-v1:0' },
|
bedrockId: 'anthropic.agent-config-haiku-4-5-20251001-v1:0' },
|
||||||
{ id: 'anthropic/vendor-model-3.5-haiku', name: 'vendor model 3.5 Haiku', cost: '~$0.002', tag: 'VALUE', category: 'smart',
|
{ id: 'anthropic/vendor-model-3.5-haiku', name: 'vendor model 3.5 Haiku', cost: '~$0.002', tag: 'VALUE', category: 'smart',
|
||||||
bedrockId: 'anthropic.agent-config-3-5-haiku-20241022-v1:0' }
|
bedrockId: 'anthropic.agent-config-3-5-haiku-20241022-v1:0' },
|
||||||
|
|
||||||
|
// ── Amazon Nova ──
|
||||||
|
{ id: 'amazon/nova-pro', name: 'Amazon Nova Pro', cost: '~$0.008', tag: 'SMART', category: 'smart',
|
||||||
|
bedrockId: 'amazon.nova-pro-v1:0' },
|
||||||
|
{ id: 'amazon/nova-lite', name: 'Amazon Nova Lite', cost: '~$0.001', tag: 'FAST', category: 'fast',
|
||||||
|
bedrockId: 'amazon.nova-lite-v1:0' },
|
||||||
|
{ id: 'amazon/nova-micro', name: 'Amazon Nova Micro', cost: '~$0.0004', tag: 'CHEAPEST', category: 'fast',
|
||||||
|
bedrockId: 'amazon.nova-micro-v1:0' },
|
||||||
|
{ id: 'amazon/nova-premier', name: 'Amazon Nova Premier', cost: '~$0.04', tag: 'BEST AMAZON', category: 'premium',
|
||||||
|
bedrockId: 'amazon.nova-premier-v1:0' },
|
||||||
|
|
||||||
|
// ── Meta Llama ──
|
||||||
|
{ id: 'meta/llama-4-maverick', name: 'Llama 4 Maverick', cost: '~$0.005', tag: 'NEW', category: 'smart',
|
||||||
|
bedrockId: 'meta.llama4-maverick-17b-instruct-v1:0' },
|
||||||
|
{ id: 'meta/llama-4-scout', name: 'Llama 4 Scout', cost: '~$0.004', tag: 'NEW', category: 'smart',
|
||||||
|
bedrockId: 'meta.llama4-scout-17b-instruct-v1:0' },
|
||||||
|
{ id: 'meta/llama-3.3-70b', name: 'Llama 3.3 70B', cost: '~$0.003', tag: 'GOOD', category: 'smart',
|
||||||
|
bedrockId: 'meta.llama3-3-70b-instruct-v1:0' },
|
||||||
|
|
||||||
|
// ── DeepSeek ──
|
||||||
|
{ id: 'deepseek/r1', name: 'DeepSeek R1', cost: '~$0.005', tag: 'REASONING', category: 'smart',
|
||||||
|
bedrockId: 'deepseek.r1-v1:0' },
|
||||||
|
{ id: 'deepseek/v3', name: 'DeepSeek V3', cost: '~$0.001', tag: 'CHEAP', category: 'fast',
|
||||||
|
bedrockId: 'deepseek.v3-v1:0' },
|
||||||
|
|
||||||
|
// ── Mistral AI ──
|
||||||
|
{ id: 'mistral/large-3', name: 'Mistral Large 3 (675B)', cost: '~$0.008', tag: 'PREMIUM', category: 'premium',
|
||||||
|
bedrockId: 'mistral.mistral-large-3-675b-instruct' },
|
||||||
|
{ id: 'mistral/mistral-large-2407', name: 'Mistral Large (24.07)', cost: '~$0.006', tag: 'GOOD', category: 'smart',
|
||||||
|
bedrockId: 'mistral.mistral-large-2407-v1:0' },
|
||||||
|
|
||||||
|
// ── Cohere ──
|
||||||
|
{ id: 'cohere/command-r-plus', name: 'Command R+', cost: '~$0.005', tag: 'GOOD', category: 'smart',
|
||||||
|
bedrockId: 'cohere.command-r-plus-v1:0' },
|
||||||
|
|
||||||
|
// ── AI21 Labs ──
|
||||||
|
{ id: 'ai21/jamba-1.5-large', name: 'Jamba 1.5 Large', cost: '~$0.005', tag: 'GOOD', category: 'smart',
|
||||||
|
bedrockId: 'ai21.jamba-1-5-large-v1:0' }
|
||||||
];
|
];
|
||||||
|
|
||||||
var AZURE_MODELS = [
|
var AZURE_MODELS = [
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue