Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions backend/__tests__/unit/config/nativeAgents.modelRoute.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/**
* First-party native apps must name a model the deployment can actually serve.
*
* pod-summarizer, pod-welcomer and task-clerk kept the free OpenRouter
* nemotron route after its key expired on 2026-10-25. LiteLLM still declares
* that name, so nothing failed at boot; every run died on its first model call
* with HTTP 404 (6 of 8 pod-summarizer runs in the 48h before 2026-10-27).
* Declared is not the same as servable, so this pins both.
*/
const fs = require('fs');
const path = require('path');
const { FIRST_PARTY_APPS } = require('../../../config/native-agents/apps');

const litellmConfig = fs.readFileSync(path.join(__dirname,
'../../../../k8s/helm/commonly/templates/configmaps/litellm-config.yaml'), 'utf8');
const declaredModels = new Set(
[...litellmConfig.matchAll(/model_name:\s*(\S+)/g)].map((m) => m[1]),
);

describe('first-party native app model routes', () => {
test.each(FIRST_PARTY_APPS.map((app) => [app.agentName, app.model]))(
'%s names a model LiteLLM declares',
(_name, model) => {
expect(declaredModels.has(model)).toBe(true);
},
);

test.each(FIRST_PARTY_APPS.map((app) => [app.agentName, app.model]))(
'%s does not route through the expired OpenRouter free tier',
(_name, model) => {
expect(model).not.toMatch(/^openrouter\//);
expect(model).not.toMatch(/:free$/);
},
);
});
2 changes: 1 addition & 1 deletion backend/config/native-agents/pod-summarizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const podSummarizerApp = {
+ '- DO NOT call commonly_create_task. You are not here to create work.',
// See pod-welcomer.ts for the rationale — utility apps run on the
// OpenRouter free tier, not paid Codex.
model: 'openrouter/nvidia/nemotron-3-super-120b-a12b:free',
model: 'deepseek-v4-flash',
triggers: ['heartbeat'],
heartbeatIntervalMinutes: 360,
tools: [
Expand Down
2 changes: 1 addition & 1 deletion backend/config/native-agents/pod-welcomer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const podWelcomerApp = {
// burning it for these heavy-traffic event handlers exhausts dev agents'
// accounts. Same default community agents use; if quality drops, reach for
// gemini-2.5-flash (paid but cheap) before paid Codex.
model: 'openrouter/nvidia/nemotron-3-super-120b-a12b:free',
model: 'deepseek-v4-flash',
triggers: ['pod.join'],
tools: ['commonly_read_context', 'commonly_post_message'],
iconUrl: '',
Expand Down
2 changes: 1 addition & 1 deletion backend/config/native-agents/task-clerk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ export const taskClerkApp = {
+ '- Keep all replies under 2 lines. You are a clerk, not a conversationalist.',
// See pod-welcomer.ts for the rationale — utility apps run on the
// OpenRouter free tier, not paid Codex.
model: 'openrouter/nvidia/nemotron-3-super-120b-a12b:free',
model: 'deepseek-v4-flash',
triggers: ['mention'],
tools: [
'commonly_read_context',
Expand Down
Loading