Tencent / Tencent/teamai-cli

feat(models): manage team and local model profiles with explicit agent switching

Open
#632 2 comments 0 reactions 0 assignees View on GitHub

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:

  1. A team may publish a shared API endpoint and per-agent model mapping, while every member supplies their own API key locally.
  2. 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:

  • anthropic
  • openai-responses
  • openai-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:

  • add creates 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.
  • configure never changes an agent configuration.
  • switch is the only command that installs and activates a profile in agent configuration files.
  • Without --agent or --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_key must be exactly a reference to a declared secret input.
  • 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 autoApply setting.
  • 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 pull or session hooks.
  • A local protocol-conversion proxy.
  • Pushing personal profiles to the team repository.
  • Silently overriding user-owned configuration.

Implementation outline

  1. Extract the existing apply_model_config parsing and CodeBuddy/WorkBuddy/Claude writers from local-agent.ts into a shared model configuration module.
  2. Add the team template parser, local profile/input store, secret handling, and source-qualified profile resolution.
  3. Add safe Codex and OpenCode writers and the global ownership/restore manifest.
  4. Add the teamai models commands and per-agent preflight/result reporting.
  5. Add validation to prevent literal credentials in team templates.
  6. Add unit tests and fake-home end-to-end coverage, followed by real CLI verification for supported agents and Git providers.
  7. Update all affected English and translated documentation consistently.

Acceptance criteria

  • models/models.yaml provides a secret-free team catalog.
  • teamai pull never 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.