Skip to content

feat(sessions): per-job provider routing — distribute across quota buckets#244

Open
brianjones-v4n wants to merge 1 commit into
JKHeadley:mainfrom
brianjones-v4n:feat/per-job-provider-routing
Open

feat(sessions): per-job provider routing — distribute across quota buckets#244
brianjones-v4n wants to merge 1 commit into
JKHeadley:mainfrom
brianjones-v4n:feat/per-job-provider-routing

Conversation

@brianjones-v4n
Copy link
Copy Markdown
Contributor

Summary

Today SessionManager.spawnSession launches config.claudePath for every session — interactive and scheduled. This adds optional per-job provider routing so background scheduler jobs can be routed through a cheaper local provider (e.g., an Ollama wrapper running claude against DeepSeek) while interactive Telegram-driven sessions stay on native Anthropic Claude. Operators get to balance work deliberately across two quota buckets.

API surface

// types.ts
export interface ProviderConfig {
  claudePath: string;
  env?: Record<string, string>;
  modelTiers?: Partial<Record<ModelTier, string>>;
}

// SessionManagerConfig
providers?: Record<string, ProviderConfig>;

// JobDefinition
provider?: string;   // key into SessionManagerConfig.providers

.instar/config.json:

"sessions": {
  "claudePath": "/usr/local/bin/claude",
  "providers": {
    "anthropic": {
      "claudePath": "/usr/local/bin/claude",
      "modelTiers": { "haiku": "claude-haiku-4-5", "sonnet": "claude-sonnet-4-6", "opus": "claude-opus-4-7" }
    },
    "ollama": {
      "claudePath": "/usr/local/bin/ollama-launch-claude",
      "env": { "ANTHROPIC_BASE_URL": "http://localhost:11434" },
      "modelTiers": { "haiku": "qwen2.5:7b", "sonnet": "deepseek-v4-pro:cloud" }
    }
  }
}

.instar/jobs.json entries gain "provider": "ollama" to opt in. Omitting provider keeps the existing behavior verbatim.

Backward compatibility

  • All new fields are optional.
  • Jobs without provider produce the same spawn command as before (same binary, same env, same --model flag).
  • Configs without a sessions.providers block work unchanged.
  • Existing jobs.json files without provider work unchanged.

Test plan

  • Static-analysis tests assert the new types and field signatures
  • Resolution test: provider name → provider's claudePath
  • Resolution test: no provider → global config.claudePath (unchanged)
  • Env merge: provider env overrides base env
  • Model tier translation: model: "sonnet" → provider's modelTiers.sonnet value
  • Model tier passthrough: tier not in modelTiers falls through to bare tier name
  • JobScheduler passes job.provider to SessionManager.spawnSession
  • npx tsc --noEmit — no new errors (9 pre-existing unchanged)
  • npm run build — pre-existing 9 tsc errors unchanged (build script exits non-zero on pre-existing errors that exist on main; tsc emits dist correctly with noEmitOnError unset)

Why tier semantics over provider-specific model names

Jobs stay portable. "model": "sonnet" in a job means "the medium-tier model on whatever provider runs you" — providers translate to their own identifier. Operators retune the translation table without touching any jobs.json.

🤖 Generated with Claude Code

…ckets

Today SessionManager.spawnSession launches config.claudePath for every
session — interactive and scheduled. This adds optional per-job
provider routing so background jobs can run on a cheaper local
provider (Ollama wrapper) while interactive sessions stay on native
Anthropic, letting operators balance work across two quota buckets.

- types.ts: new ProviderConfig (claudePath, env, modelTiers); add
  providers: Record<string, ProviderConfig> to SessionManagerConfig;
  add optional provider: string to JobDefinition
- SessionManager: spawnSession resolves claudePath, env, and the
  --model flag against the selected provider (or falls through to
  global config when no provider is set — full back-compat)
- JobScheduler: passes job.provider to spawnSession
- Config: loads sessions.providers from .instar/config.json

Tier semantics preserved: jobs.json still uses opus/sonnet/haiku;
each provider declares a modelTiers map translating those to its
actual model identifier (e.g., Anthropic haiku→claude-haiku-4-5,
Ollama haiku→qwen2.5:7b). Jobs that omit provider keep the
existing behavior verbatim.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 16, 2026

@brianjones-v4n is attempting to deploy a commit to the sagemind Team on Vercel.

A member of the Team first needs to authorize it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant