Skip to content

tan model: the Python port dispatches build only -- the eight lifecycle subcommands exist solely as Rust forwarders to an alp_cli that no longer has them #674

Description

@hkngln

tan model accepts one subcommand. The VS Code Models panel shells nine. The other eight exist only as Rust forwarders on a draft PR, and their forwarding target no longer exists either.

Measured against the shipped binary

tan 0.5.1 (the version alp-sdk-vscode pins as SUPPORTED_CLI_VERSION):

 Usage: tan model [OPTIONS] [SUBCOMMAND]

╭─ Arguments ──────────────────────────────────────────────────────────────────╮
│   SUBCOMMAND      <str>  build.                                              │
╰──────────────────────────────────────────────────────────────────────────────╯

python/tan/commands/model_cmd.py:518 is where that comes from — if subcommand != "build": → one issue, exit 1:

{"command":"model","ok":false,"exitCode":1,"project":{"root":null,"boardYaml":null},
 "data":{"schemaVersion":"1","sku":null,"built":[]},
 "issues":[{"code":"model.unknown-subcommand","severity":"error",
 "message":"Unknown model subcommand: list. Available: build."}]}

Probed individually, list, doctor, check, prep, run, ab, zoo and add all return exactly this, only the name changing. build is the one that dispatches — outside a project it fails on environment instead, a different code and a different exit status (model.sdk-root-unresolved, exitCode: 2), which is how you can tell dispatch from implementation.

Why this is worth a separate issue from #253

#253 covers tan model build: oracle parity, test coverage, what it should do when the vendor NPU toolchain is absent. It is about the one subcommand that exists. This is about the eight that do not, and the reason they do not is structural rather than deferred polish:

PR #58 (integration/model-edge-ai, draft) implements the lifecycle surface — ModelSub::{Build, List, Check, Zoo, Add, Prep, Doctor, Run, Ab} — in crates/tan-cli/src/commands/model.rs, +689 lines. Its nine changed files are crates/…, README.md, CHANGELOG.md and a plan doc. Not one file under python/. So the whole surface sits in the tree the v0.7.0 milestone deletes ("Retire the oracle. crates/ deleted…").

And the Rust implementation is a thin argv forwarder — each arm builds a python -m alp_cli model <sub> … invocation. That target is gone too: alp-sdk v0.15.0's scripts/alp_cli/model.py is 56 lines and registers exactly one command, @model_group.command(name="build") at line 31. There is no alp_cli model list|check|zoo|add|prep|doctor|run|ab to forward to.

The Python port already walked away from that architecture deliberately. model_cmd.py's own module docstring:

This is a REAL implementation, not a forward: it never spawns python -m alp_cli, so alp_cli stops being load-bearing for tan model (the point of this port -- see crates/tan-cli/src/commands/sdk_cli.rs's module doc for what it is replacing).

So porting the eight is not a translation of PR #58. #58's design — forward to alp_cli — is the design the port exists to replace, and the thing it forwards to doesn't implement them anyway. Whoever picks this up needs a decision about where the work actually lives (a driver script under the SDK's Python like build uses, new alp_cli subcommands upstream, or something else) before any code.

Consumer

alp-sdk-vscode's Models / edge-AI panel (alplabai/alp-sdk-vscode#366, also open-but-not-for-merge, also integration/model-edge-ai). src/models/panel.ts shells list (:103), doctor (:104), zoo (:118), add (:141), check (:164), prep (:193), run (:236), ab (:267), build (:326-327).

The refresh path is model list + model doctor, which is what runs when the panel opens. Against every shipped tan, that panel opens with an empty list and one error, and Build is its only working entry point. That is the gate on landing the panel, and it lives here, not there.

One thing that is already right and should stay that way: because the CLI answers with a well-formed envelope rather than dying, the panel surfaces the real cause (Unknown model subcommand: list. Available: build.) instead of a canned "update tan" message. Whatever shape the eight take, keeping unknown-subcommand a coded issue rather than a crash is what makes the consumer's failure text honest.

Scope

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestenvelope-contractThe {command,ok,exitCode,project,data,issues} contract consumed by alp-sdk-vscodepython-portRust-to-Python port of the tan command surface

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions