feat(models): manage team and local model profiles with explicit agent switching
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 4.8k
- Forks
- 342
- Avg merge
- 13h 48m
- Merged PRs (30d)
- 211
Description
Background
TeamAI already manages skills, rules, MCP, hooks, and environment resources across AI coding tools. Model endpoints are still configured separately in each tool, so users repeatedly edit Claude Code, Codex, OpenCode, CodeBuddy, and WorkBuddy configuration files by hand.
Issue #403 proposed applying a Git-backed model catalog during teamai pull. That design does not cover two important requirements:
- A team may publish a shared API endpoint and per-agent model mapping, while every member supplies their own API key locally.
- A user may create completely personal model profiles whose endpoint and API key never enter the team repository.
Model changes are invasive and may replace the active provider/model, so teamai pull must never switch models automatically. Applying a profile must be an explicit user action.
Goals
- Support both team-provided and personal model profiles.
- Keep every API key local; never commit or push it to Git.
- Let users switch one selected agent, multiple agents, or all installed compatible agents.
- Preserve user-owned provider definitions and restore the previous active model safely.
- Build a reusable local engine that a future TeamAI dashboard can call directly.
Sources
Team profiles
Team profiles live in models/models.yaml. They may contain a fixed shared endpoint or declare local input placeholders. Secret fields must always reference a declared secret input.
version: 1
profiles:
- id: company-gateway
name: Company Gateway
inputs:
COMPANY_API_KEY:
label: API Key
type: secret
required: true
endpoints:
anthropic:
protocol: anthropic
base_url: https://gateway.company.example/v1
api_key: ${COMPANY_API_KEY}
responses:
protocol: openai-responses
base_url: https://gateway.company.example/v1
api_key: ${COMPANY_API_KEY}
agents:
claude:
endpoint: anthropic
model: company-claude
codex:
endpoint: responses
model: company-coder
teamai pull updates this catalog only. It must not write any agent model configuration.
Local profiles
Users create personal profiles with teamai models add. Their endpoints, credentials, and model mappings remain in machine-local storage and are never added to the team repository.
Team and local profiles are separate namespaces. A collision is addressed explicitly as team:<id> or local:<id>; an unqualified id is accepted only when unique.
Protocols
Do not infer or append URL paths. Store the exact base URL supplied by the team or user.
Initial protocol identifiers:
anthropicopenai-responsesopenai-chat-completions
A profile may contain multiple endpoints because different agents can require different protocols. For example, Codex requires a Responses-compatible endpoint, while CodeBuddy or WorkBuddy may use Chat Completions.
CLI
teamai models list
teamai models show <profile>
teamai models add <id>
teamai models configure <profile>
teamai models switch <profile> [--agent <agent>...] [--all] [--dry-run]
teamai models remove local:<id>
teamai models restore [--agent <agent>...] [--all]
Semantics:
addcreates a personal local profile through an interactive wizard.configure team:<id>fills or updates only the local inputs declared by the team template.configure local:<id>edits the complete personal profile.configurenever changes an agent configuration.switchis the only command that installs and activates a profile in agent configuration files.- Without
--agentor--all, an interactive terminal asks the user to select detected agents; non-interactive use fails with an actionable message. - API keys are collected with hidden input,
--api-key-env <name>, or--api-key-stdin. Do not accept an API key as a normal argv value because argv may be recorded in shell history, process listings, CI output, or diagnostics.
Local storage
Suggested layout:
~/.teamai/models/profiles.yaml personal profiles
<dataHome>/models.local.yaml local values for the current team's templates
~/.teamai/models/secrets.json locally stored credentials, mode 0600
~/.teamai/managed-models.json global field ownership and restore state
Team-local inputs must be partitioned by the team repository identity so profiles with the same id in different teams never share credentials. The ownership manifest is global because the user-level Claude, Codex, OpenCode, CodeBuddy, and WorkBuddy files are global.
The first implementation may use another equivalent machine-local layout if it keeps the same isolation and security properties.
Reconcile and ownership rules
- Perform field-level or entry-level updates; never regenerate a shared configuration file from scratch.
- Do not overwrite an unmanaged provider/model entry with the same key.
- Save the previous active selection before the first TeamAI switch.
- Update or restore a field only while its current value still matches the hash last written by TeamAI.
- If the user edits a managed field manually, relinquish ownership and leave the new value untouched.
- Do not overwrite Codex official authentication state in
auth.json. - Return a per-agent result for
--all; partial success must be reported explicitly. - Show restart/reload requirements per agent.
- Unsupported protocols are skipped with an actionable reason.
Git safety
- A team profile
api_keymust be exactly a reference to a declaredsecretinput. - Secret inputs cannot define defaults.
- Validate model templates during list/pull and before push.
- Refuse to push a model template containing a literal credential.
- Never print secrets from
models list,models show, status, logs, or errors.
Dashboard compatibility
The parser, local store, preflight logic, ownership manifest, and agent writers must live below the CLI command layer. A future local dashboard should call the same APIs to:
- display read-only team profiles;
- configure the member's local values;
- create and edit personal profiles;
- select one or all agents;
- preview changes, switch, and restore.
Initial scope
- User-scope model configuration only.
- Team and personal profiles.
- Explicit switch only; no
autoApplysetting. - Claude Code, Codex, OpenCode, CodeBuddy, and WorkBuddy where their native configuration supports the requested operation.
- Native protocol configuration only; no resident proxy or protocol conversion.
Non-goals
- Storing or distributing API keys through Git.
- Automatically switching models during
teamai pullor session hooks. - A local protocol-conversion proxy.
- Pushing personal profiles to the team repository.
- Silently overriding user-owned configuration.
Implementation outline
- Extract the existing
apply_model_configparsing and CodeBuddy/WorkBuddy/Claude writers fromlocal-agent.tsinto a shared model configuration module. - Add the team template parser, local profile/input store, secret handling, and source-qualified profile resolution.
- Add safe Codex and OpenCode writers and the global ownership/restore manifest.
- Add the
teamai modelscommands and per-agent preflight/result reporting. - Add validation to prevent literal credentials in team templates.
- Add unit tests and fake-home end-to-end coverage, followed by real CLI verification for supported agents and Git providers.
- Update all affected English and translated documentation consistently.
Acceptance criteria
-
models/models.yamlprovides a secret-free team catalog. -
teamai pullnever modifies an agent's model configuration. - Members can configure local inputs for a team profile.
- Users can create, edit, and remove personal local profiles.
- Team and local profiles remain separate and collisions require a qualified name.
- Users can explicitly switch one, several, or all installed compatible agents.
- Literal API keys in team templates are rejected before push.
- Secrets are stored locally with restrictive permissions and never printed.
- User-owned entries and manual edits are preserved.
- Previous active selections can be safely restored while TeamAI still owns them.
- Codex official authentication is preserved.
- Tests cover team/local profiles, collisions, missing inputs, conflicts, partial success, restore, and secret redaction.
- CLI end-to-end verification covers Claude, Codex, CodeBuddy, WorkBuddy, and OpenCode where supported.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the existing apply_model_config parsing and CodeBuddy/WorkBuddy/Claude writers in local-agent.ts, then map the proposed models/models.yaml format and teamai models commands to the shared module boundary. Review the acceptance criteria and add unit, fake-home end-to-end, and CLI verification coverage for profile isolation, secret handling, ownership, switching, restoration, and partial results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- cli, security, tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100