Skip to content

feat(ui): route chat deploy intent through the template catalog - #281

Open
zjy365 wants to merge 1 commit into
mainfrom
feat/chat-deploy-intent-routing
Open

feat(ui): route chat deploy intent through the template catalog#281
zjy365 wants to merge 1 commit into
mainfrom
feat/chat-deploy-intent-routing

Conversation

@zjy365

@zjy365 zjy365 commented Aug 19, 2026

Copy link
Copy Markdown
Collaborator

Asked to "部署 glpi", the Assistant invented a Docker image instead of using the curated GLPI template that already exists in the Sealos catalog.

Three causes, all engineering:

  1. No catalog discovery. createDeployTask accepts a template source but nothing let the model learn a valid templateName, so it fell back to the one source it could fully specify from its own knowledge.
  2. No routing guidance. CHAT_BASE_SYSTEM_PROMPT covered AP/DB/Project/bash and said nothing about choosing a Deployment Source.
  3. GitHub was hard-blocked in chat, and the error text pointed at a UI pane the model cannot operate — so it fell back to Docker.

Changes

Catalog discovery — new searchDeployCatalog, shaped like loadSkill (ranked index query, detail on demand), backed by the already-cached listTemplateCatalog. Returns the exact templateName plus required args. Returns a tool-level error instead of throwing when the provider is unreachable, so the turn degrades to a prompt source rather than dying.

Routing prompt — explicit source preference: template → github → prompt → docker, with docker only when the user names an image. Requires asking the user for a template's required args instead of inventing secrets (GLPI needs admin_password).

Unbound GitHub tasks (ADR-0062) — chat can now create GitHub tasks, and a task no longer requires a Deployment Credential Binding. The runner already treated the token as optional at every use site; a single throw required it. An unbound task clones a public repo anonymously and deploys an already-published image.

Two guards keep that honest:

  • Creation fast-fails a repository GitHub positively refuses (404, or 403 with budget left). It fails open on rate limits — anonymous GitHub reads are 60/hr per egress IP, so inability to ask must not block a deploy.
  • The managed gateway prompt tells the agent it has no registry credential and must fail with github-credential-required rather than attempt a push — turning a failure that used to land after a full image build into one at detection time.

Verification

bun typecheck and bun check clean.

Suite Result
chat-deploy-catalog-tool.test.ts 9 pass
chat-deploy-task-tool.test.ts 6 pass
repo-public-access.test.ts 6 pass
runner-credential-binding.test.ts 4 pass
gateway-prompt.test.ts 4 pass
deploy-tasks/route.test.ts 14 pass
engine/engine.test.ts 42 pass

Ranking also validated against the live 215-template catalog: glpi, GLPI helpdesk, and the repo URL all rank the glpi template first and surface admin_password. wiki correctly returns nothing (no wiki template exists), falling through to the github/prompt path.

Two route tests changed meaning rather than breaking: they encoded the old "connection required" rule and now assert unbound creation plus private-repo rejection.

Notes for review

  • Load-bearing assumption: unbound value depends on "public repo + already-published image" covering most requests. No data behind that yet — the share of tasks ending in github-credential-required is the signal. If most need a source build, the answer is lowering GitHub-connect friction, not more unbound work.
  • The create path now makes a live GitHub API call for unbound tasks. Cached 1h, fails open.
  • Deliberately not included: the 64k-row repo crawler DB. It has no deployability signal and would push the agent toward deploying libraries and awesome-lists.

🤖 Generated with Claude Code

The Assistant had no way to discover the 215 curated Sealos templates: it
could emit a `template` source but not learn a valid `templateName`, and the
system prompt said nothing about choosing a Deployment Source. Asked to
deploy GLPI — which ships a curated template — it invented a Docker image
instead.

Add `searchDeployCatalog`, shaped like `loadSkill` (ranked index query, detail
on demand) and backed by the already-cached `listTemplateCatalog`. It degrades
to a tool-level error when the provider is unreachable so the turn survives.
Give the system prompt an explicit source-preference order and forbid
inventing an image name.

Unblock GitHub deployment from chat, and let a GitHub task exist without a
Deployment Credential Binding (ADR-0062). The runner already treated the
token as optional everywhere; only one throw required it. An unbound task
clones a public repository anonymously and deploys an already-published
image, which is the common case. Creation fast-fails a repository GitHub
positively refuses, and fails open on rate limits. The managed gateway prompt
tells the agent it cannot push, so an unsupported source build fails at
detection rather than after the image is built.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant