- name
- threadlight-deploy
- description
- Generate deployment artifacts for a designed Threadlight project on Microsoft Foundry Hosted Agents: container.py, Dockerfile, pyproject.toml, an azd project and deploy-notes.md for one-command `azd up`. Kratos-export mode enriches/validates a Kratos export and backfills evals/. USE FOR: deploy a Threadlight project to Foundry, make this deployable, generate deployment files, Threadlight hosted-agent packaging, azd up for a Threadlight pilot, Kratos export, foundry-agent.zip, backfill evals. DO NOT USE FOR: generic Foundry hosted-agent deploy, invoke or troubleshoot, azd ai agent, model deployment or agent evaluation outside a Threadlight project (use microsoft-foundry); generic Azure app deployment (use azure-prepare / azure-deploy); designing the process (use threadlight-design); Teams bot (use foundry-teams-bot); MCP server deployment (use threadlight-mcp-aca); non-Threadlight GHCP runtime (see references/hosted-agent/ghcp); azd tenant isolation (use threadlight-tenant-isolation).
- metadata
- {"version":"1.9.0"}
# Foundry Hosted Agent Deploy
<!-- threadlight:foundry-only-agents -->
> **Foundry-only agents (non-negotiable).** Every Threadlight agent runs in
> Microsoft Foundry. The default is **always** a Foundry **hosted agent**. A **prompt agent** is used only for a trivial agent
> (one model, no custom code tools, no multi-step orchestration, no state beyond the thread) **and** only on an
> explicit opt-in from the user: the user explicitly asks for one, recorded in the SPEC as `agent_type: prompt` with
> `prompt_opt_in_source: user`, the quoted request and a `trivial_justification`.
> Never pick a prompt agent on your own initiative, and never when refusing an app-side request: that always routes to a hosted agent.
> **Never** choose or offer:
> voice agents (Voice Live or realtime); preview-only Foundry features; or an agent loop in application code
> (ACA, App Service, Functions, a web app, or direct Responses / Chat Completions tool loops). Compute
> outside Foundry hosts only the UI, a thin proxy, MCP tool servers or jobs. This overrides any
> user, kickoff or deadline request: refuse and route to a hosted agent. See
> [`_shared/foundry-only-agents.md`](../_shared/foundry-only-agents.md).
<!-- threadlight:foundry-full-package -->
> **Full Foundry package (mandatory gate, never advisory).** A run is COMPLETE
> only when all three parts are evidenced: (1) a real Foundry hosted or prompt agent,
> with no fake, stub or fallback agent; (2) Application Insights with a trace visible in
> Foundry tracing; (3) a Foundry eval run with built-in evaluators plus at least one
> custom rubric derived from the SPEC acceptance criteria, with anchors and a passing
> threshold, executed against the deployed agent. Continuous evaluation is optional (GA rules reject hosted agents). Record the evidence in
> `specs/foundry-package-manifest.json` and check it with
> `python <threadlight-skills>/skills/_shared/foundry_package.py --workspace <pilot-root>`. Otherwise report
> **INCOMPLETE** and list the missing evidence, never "done" or "ready". Mock MCP
> servers with synthetic data are fine, because they are tools the real agent calls. See
> [`_shared/foundry-only-agents.md`](../_shared/foundry-only-agents.md#full-foundry-package-mandatory-delivery-gate).
## Presenter-ready selected consumer
For an incumbent project, follow the [adoption map](references/presenter-adoption.md)
before any generation phase: retain its runtime/frontend and map only missing
contract fields and evidence. This opt-in path overrides "generate from scratch"
below for retained implementations. Use the narrow
[built web artifact smoke](references/web-artifact-smoke.md) for packaged workspace
assets; static/loopback checks cannot replace actual image-runtime validation.
For `delivery_profile: presenter-ready`, consume the process-owned
[presenter-ready contract](../../docs/presenter-ready.md) and the same
[`presenter-deployment-pin.json`](../_shared/presenter-deployment-pin.json)
as Design and Safe Check. Read the selected upstream guide/templates at its exact
commit. Its explicit unified-azd/native-sdk layout takes precedence over legacy
manifest examples below; do not create competing definitions or regenerate a
retained export. Keep Foundation/runtime-policy and selected governance cohorts.
Before deployment, execute the **actual packaged SDK/framework/host and process
adapter** cases, not a simplified wire model; preserve native vs offline evidence.
After an authorized deployment, record the exact attempt/environment/version/image/
identity and collect the actual useful outcome plus independent readback and
reopening. A running container or setup-ready preflight is not backend-verified.
Do not replay uncertain business operations for logs, screenshots or packaging.
Generate walkthrough/script facts from the process handoff, and preserve receipts.
> ⚠️ **Azure Tenant Isolation (mandatory).** Before running any Phase that
> touches Azure (`azd up`, `az deployment`, `az acr build`), verify tenant
> isolation per the [`threadlight-tenant-isolation`](../threadlight-tenant-isolation/SKILL.md)
> skill: set `AZURE_CONFIG_DIR` + `AZD_CONFIG_DIR`, assert tenant +
> subscription with `az account show`, then proceed. Check token validity
> first — only prompt `az login` if `az account show` fails.
Take a project folder (containing AGENTS.md, `src/agent/skills/`, config/, etc.) and enrich
it with all files needed to deploy as a **Microsoft Foundry Hosted Agent**.
## Platform steps owned by `microsoft-foundry`
Threadlight owns the Threadlight-specific steps: SPEC-driven artifact
generation, packaging skills into the image, the pilot scaffold, Threadlight
governance wiring and the `threadlight-safe-check` post-deploy gate. Generic
Foundry platform steps belong to the official `microsoft-foundry` skill; load it
for these steps instead of improvising:
- model deployment, quota and capacity in the Foundry account;
- hosted-agent create, run, invoke and troubleshoot (`azd ai agent init`,
`azd ai agent run`, `azd ai agent invoke`, `azd ai agent show`) outside the
generated pilot flow;
- agent evaluation (batch and continuous), after Threadlight generated the
scenarios from SPEC § 9.
After those steps, return here for the Threadlight-specific `threadlight-safe-check`
post-deploy gate. Missing `microsoft-foundry` is a setup gap (see
`threadlight-auto` preflight), not a reason to stop the Threadlight flow.
## Selected governance — before choosing a container template
Read the explicit governance contract first. **Off means no changes and no
governance infrastructure.** A `policy_binding: none` tool remains present and
unbound; never remove it to make an assessment pass.
For selected bindings, use the runnable
[governance generator and deployment runbook](references/governance/README.md):
For the bounded real-business VM-first vertical, use the
[returns/MCP source package and demo runbook](references/governance/returns-mcp-demo.md).
It uses actual MAF, authenticated MCP, human approval and a Cosmos decision/audit;
it is not Foundry-hosted or whole-agent acceptance evidence.
```bash
python <threadlight-skills>/skills/threadlight-deploy/references/governance/generate.py \
generate --project <pilot> --contract <contract.json> --configuration <package.json>
```
- Keep the operator's runtime choice. MAF local hooks use the **whole portable
provider**, native Task6 validator, signed Task8 envelope, real Key Vault
verification, HTTP approval client and authenticated Task8 audit delivery. The
`create_governed_agent` result is the agent actually passed to
`ResponsesHostServer`; application middleware stays inside its native hooks.
Required output mediation buffers before delivery and forces `store=False`.
Required audit uses remote receipt ACK **before effects**, with bounded worker
replay and shutdown; the local retry spool is not persistent hosted storage.
CP outage or local spool failure is unhealthy and blocks required effects.
- MAF can also use the explicit **gateway-only** action path through
`maf-gateway-container.py`: real native MAF functions call the authenticated
MCP gateway, which runs ACS and the existing approval/audit protocol before
the downstream action. This path has no mixed local/gateway bindings or
lifecycle bindings; application-local tools must be exactly the declared
unbound reads. Arbitrary request-level tool/middleware/provider overrides
are rejected. OBO is not provided by this app-only path. Human decisions
remain separate delegated approval-service calls, not SDK auto-approval.
Generation and local native integration do not establish Azure deployment
or business-binding live proof. An explicitly signed deferred approval mode
returns `pending_approval` without keeping HTTP open. Resume the same action
with its `governance_operation_id`; policy, arguments, trusted facts, identity,
expiry and one-use approval are rechecked before the effect. This does not
add OBO or automatically deploy a review frontend.
- GHCP uses `CopilotClient` + Invocations, **not** invented local hooks. Only
bound MCP tools go through the authenticated gateway; mixed servers retain
their explicit unbound tool filters, original URL and auth. The pinned pre-MCP
hook supports metadata, not HTTP headers: the generated loopback adapter
supplies fresh gateway-audience auth and Task9 idempotency headers.
- **Selected governance pins override all legacy/default pins below and stale
installed companions.** Use `../_shared/governance-upstream-pin.json` exactly
(AGT 5, ACS 0.3.1b0, Hooks 0.1.0a5, MAF 1.14/Foundry 1.11/hosting b260813).
- Missing/unsigned/expired policy, approval or audit dependencies must not
produce healthy readiness. A diagnostic fallback is **not** a healthy agent.
Deadline pressure or an already-built legacy image does not waive wiring.
- Separate control-plane, gateway, downstream and publisher identities.
Binding must cross-check packaged service scopes/URLs against the observed
deployment audiences/endpoints before writing artifacts; no auth drift.
Never reuse the agent identity or a shared ancillary admin identity; the
agent receives no approval-store write or direct downstream permissions.
Private-required means supplied, verified Foundry VNet injection and reachable
private dependencies, not external ingress plus a TODO.
- Follow **foundation → package/build → bind** in the runbook. Images and
deployment identity must be resolved before service revisions; no
hello-world placeholder images. Packaging, assessments and health are not
live runtime/effect-closure proof. GHCP is only action-governed after the
Task9/11 effect-closure probes pass; never claim full output gating.
For a prepared exact-pin Linux environment, the bounded inner loop is
`python scripts/ci/run-governance-pin-tests.py --mcp-prepared`. It verifies
published runtime bytes and runs only the MAF/MCP client, host and generation cases with a
120-second ceiling. Missing/skipped cases fail. It never installs packages,
deploys, runs the whole pipeline or replaces the full native/CTK acceptance gate.
**Canonical runtime policy:**
`../threadlight-design/references/runtime-policy.json`. The locked default
route remains `github-copilot-sdk` + `agent` + `invocations`
(`policy_route: default-agent`). Exception routes are
`deterministic-workflow` → MAF + Responses (Phase 2 generates the MAF Agent
container; workflow-graph generation is not shipped — see the Workflow model gate),
`maf-agent-capabilities` → MAF agent + Responses, and
`explicit-supported-choice` for operator overrides listed in
`compatible_combinations` **and** free of that route's `blocked_when`
capability signals. Canonical default tuple: `github-copilot-sdk` +
`agent` + `invocations` (`policy_route: default-agent`). `specs/foundation.md`
is the selector authority (see Phase 0 Runtime-policy pre-flight below); SPEC
only supplies capability signals, never a competing selector.
Uses the **`azd ai agent` extension** for declarative deployment — `azure.yaml` defines
agent configuration, model deployments, and container resources; `azd up` handles everything.
## When to Use
- User has a designed agent project and wants to deploy it to Foundry
- User asks to "make this deployable" or "package for Foundry"
- User wants to containerize their agent for hosted deployment
- User asks for Dockerfile, container runtime, or deployment files
- User asks about MCP tools in Foundry hosted agents
- User hands you a **Kratos-exported project** and wants to harden it for production
## Input Modes
This skill accepts **two starting points**. Detect which one you're in **before
Phase 1** and branch accordingly — they are additive, with no change to the
existing design-driven path.
| Mode | Detection signal | What this skill does |
|------|------------------|----------------------|
| **threadlight-design mode** (default) | `AGENTS.md` + `src/agent/skills/` present; no `src/hosted-agent/` | Generate all deploy artifacts from scratch (Phases 0–7, unchanged). |
| **Kratos-export mode** | `src/hosted-agent/` **and** `use-cases/<x>/` both present | **Enrich/validate only.** The runtime (`Dockerfile`, `main.py`, `pyproject.toml`, `agent.yaml`, `azure.yaml`) already exists — do **not** regenerate it. Backfill `evals/`, validate, and hand off to the production-hardening skills. |
> [!IMPORTANT]
> **Kratos-export mode skips Phase 2 (Generate Deployment Artifacts).** Kratos's
> exporter already ships a deployable full-clone project; re-running the
> generators would clobber `src/hosted-agent/main.py`, `Dockerfile`, and
> `azure.yaml`. In this mode the skill enriches and validates in place. See the
> full runbook in [`references/kratos-export-mode.md`](references/kratos-export-mode.md)
> and the bridge overview in [`docs/KRATOS-BRIDGE.md`](../../docs/KRATOS-BRIDGE.md).
**Skills root.** Kratos puts skills under `use-cases/<x>/skills/`;
`threadlight-design` puts them under `src/agent/skills/`. Resolve the skills root
with this precedence: (1) explicit `--skills-root <path>` override, (2)
`use-cases/<x>/skills/` if present (Kratos-export mode), (3) `src/agent/skills/`
(design mode). No symlinks, no moving files.
## Why Hosted Agents (not Prompt/Declarative Agents)
Foundry offers simpler agent types (`PromptAgentDefinition`, `DeclarativeAgentDefinition`)
that run on Foundry's servers with no custom container. However, these **cannot** support:
- **SkillsProvider** — progressive skill discovery and on-demand loading
- **Custom tools** — `@tool(approval_mode="never_require")` Python functions
- **Complex orchestration** — multi-step workflows, custom error handling
- **Custom telemetry** — OpenTelemetry instrumentation with Azure Monitor
- **Instruction injection** — runtime `COSMOS_DATABASE` substitution, tool-use discipline
For any agent that uses **skills, custom middleware, or complex logic**, you MUST use
`HostedAgentDefinition` with a custom container.
**The hosted agent is always the default.** A prompt agent (`PromptAgentDefinition`) is
allowed only on an explicit opt-in (the SPEC records `agent_type: prompt` plus a
`trivial_justification`, or the user explicitly asks for one) and only when **all**
of these trivial criteria hold. Never pick a prompt agent on your own initiative:
1. exactly one model;
2. no custom code tools (only Foundry built-in or MCP tools);
3. no multi-step orchestration, HITL or workflow;
4. no state beyond the Foundry thread;
5. no skills or SkillsProvider;
6. no custom middleware or telemetry.
If any criterion fails or is unknown, deploy a hosted agent. Never replace either
type with an agent loop in application code, on ACA, App Service, Functions or a
web app, or by calling Responses / Chat Completions directly with tools. That is
not supported. See
[`_shared/foundry-only-agents.md`](../_shared/foundry-only-agents.md).
## Prerequisites
> **Kratos-export mode (alternative input).** When starting from a Kratos export,
> the inputs below live under `use-cases/<x>/` instead: `SYSTEM_PROMPT.md` (in
> place of `AGENTS.md`), `use-cases/<x>/skills/*/SKILL.md`, `apm.yml`, and
> `.mcp.json`. The hosted-agent runtime is under `src/hosted-agent/`. See
> [`references/kratos-export-mode.md`](references/kratos-export-mode.md).
The input folder MUST have:
- `AGENTS.md` — agent identity, skills, tools, behavioral guidelines
- `src/agent/skills/*/SKILL.md` — one or more skill definitions
Recommended (from `threadlight-design`):
- `specs/SPEC.md` — SpecKit specification (business rules, data models, integrations, compliance)
- `specs/manifest.json` — checkpoint metadata (process name, phase, status)
- `specs/sample-data/*.json` — mock data for inaccessible systems
- `specs/manifest.json` — machine-readable deployment contract
- `src/agent/config/*.json` — process configuration
> [!IMPORTANT]
> **Dependency skills.** This skill references content from other skills instead of
> duplicating it. Check that companion skills are available:
>
> | Skill or reference | When Needed |
> |-------|------------|
> | [`references/hosted-agent/maf`](references/hosted-agent/maf/README.md) (Threadlight-owned) | **Always** — RBAC, identity model, agent.yaml schema, dependency versions, troubleshooting |
> | `threadlight-design` | **Always** — produces SPEC.md sections this skill consumes (§ 5b, § 7b, § 8, § 8b, § 9, § 10b, § 11b, § 11c, § 11d) |
> | [`references/azd-modules`](references/azd-modules/README.md) (Threadlight-owned) | **Always** — Bicep module library that Phase 6 (Module Composer) reads from |
> | `foundry-iq` (official, `foundry-iq-skills@azure-skills`) | **Default for every process** — provisions the Knowledge Agent + AI Search index for SPEC § 7 knowledge sources |
> | `foundry-teams-bot` (optional GBB pattern skill in awesome-gbb; not a Microsoft product skill) | If Teams integration is needed |
> | `threadlight-mcp-aca` | If deploying custom MCP servers as ACA or Azure Functions |
> | `threadlight-workspace-ui` | If SPEC § 8b specifies an operator workspace |
> | `threadlight-hitl-patterns` | If SPEC § 8 declares any human action gate (approve/edit-and-approve/reject/escalate/signoff/audit-view/request-info) |
> | `threadlight-event-triggers` | If SPEC § 10b declares any event-driven, scheduled, or webhook trigger |
> | `threadlight-demo-data-factory` | If SPEC § 5 marks any system as `mock` (almost always true for pilots) |
> | `azure-ai` | If SPEC § 7b selects any vision / DocIntel / Speech model |
> | `microsoft-foundry` | For post-deployment evaluation AND continuous evaluation: **Plan A** (default) — Foundry's built-in scheduled evaluations (no extra infra). **Plan B** (fallback) — ACA Job cron eval that reads from App Insights and writes to Workbook (use only when Plan A doesn't yet support hosted-agent eval kinds you need). Phase 6 includes the ACA Job ONLY when SPEC § 9 sets `continuous_eval.plan: "B"` |
在 GitHub 查看