diff --git a/README.md b/README.md
index 6626f1f..b61c4e8 100644
--- a/README.md
+++ b/README.md
@@ -149,7 +149,7 @@ Beta testers can install `@openagentpack/cli@beta`; see the [release guide](./do
| MCP Server | native | native | native | native |
| Memory Store | unsupported | native | unsupported | native |
| Multi-Agent | unsupported | unsupported | native | native |
-| Deployment | emulated | emulated | native | emulated |
+| Deployment | emulated | native | native | emulated |
| Session | native | native | native | native |
The full capability matrix and per-provider differences live in the [Provider reference](./docs/reference/providers.md).
diff --git a/README.zh-CN.md b/README.zh-CN.md
index b2314b8..78078e8 100644
--- a/README.zh-CN.md
+++ b/README.zh-CN.md
@@ -149,7 +149,7 @@ Beta 用户可以安装 `@openagentpack/cli@beta`;固定版本及切回稳定
| MCP Server | native | native | native | native |
| Memory Store | unsupported | native | unsupported | native |
| Multi-Agent | unsupported | unsupported | native | native |
-| Deployment | emulated | emulated | native | emulated |
+| Deployment | emulated | native | native | emulated |
| Session | native | native | native | native |
完整能力矩阵与各 Provider 差异见 [Provider 参考](./docs/reference/providers.zh-CN.md)。
diff --git a/docs/architecture/how-it-works.md b/docs/architecture/how-it-works.md
index afbb75c..0c76937 100644
--- a/docs/architecture/how-it-works.md
+++ b/docs/architecture/how-it-works.md
@@ -63,4 +63,4 @@ agents state import
Resources (agents, environments, skills…) are **infrastructure** — long-lived, managed by `plan`/`apply`. A **session** is a **runtime** conversation started from an agent. Sessions are managed separately with `agents session` and are not part of the plan/apply lifecycle.
-Deployments sit between the two: they are declared as resources but produce runs. On Claude they schedule server-side; on Bailian, Qoder, and Volcengine Ark a `deployment run` expands into a session.
+Deployments sit between the two: they are declared as resources but produce runs. On Qoder and Claude they schedule server-side; on Bailian and Volcengine Ark a `deployment run` expands into a session.
diff --git a/docs/concepts/agents-as-code.md b/docs/concepts/agents-as-code.md
index 909215d..ec64d9a 100644
--- a/docs/concepts/agents-as-code.md
+++ b/docs/concepts/agents-as-code.md
@@ -19,7 +19,7 @@ Because the declaration is a file, it gets everything a file gets: code review,
- The **agent harness** is the provider-managed layer that wraps a model into an agent: knowledge base, skills, MCP wiring, prompt/instructions, vault, deployment, multi-agent orchestration. These are the customer's portable assets.
- The **agent infra** is the interchangeable execution substrate beneath the harness — the specific provider (Bailian, Qoder, Claude, Volcengine Ark) that runs the agent.
-OpenAgentPack's portability claim is that the same harness declaration can target different agent infra. Portability means the *core declaration* is portable and the per-provider **capability contract** is explicit — unsupported facets degrade gracefully (for example, an emulated `Deployment` on Bailian/Qoder/Volcengine Ark) — not that every feature is identical on every provider.
+OpenAgentPack's portability claim is that the same harness declaration can target different agent infra. Portability means the *core declaration* is portable and the per-provider **capability contract** is explicit — unsupported facets degrade gracefully (for example, an emulated `Deployment` on Bailian/Volcengine Ark) — not that every feature is identical on every provider.
## What this enables
diff --git a/docs/concepts/sessions-and-deployments.md b/docs/concepts/sessions-and-deployments.md
index 7c8befb..d8597d7 100644
--- a/docs/concepts/sessions-and-deployments.md
+++ b/docs/concepts/sessions-and-deployments.md
@@ -23,7 +23,8 @@ How a deployment *runs* depends on the provider's capability tier:
| Provider | Deployment tier | What `agents deployment run` does |
|----------|:--------------:|------------------------------------|
| Claude | native | schedules server-side through the deployments API |
-| Qoder, Bailian, Ark | emulated | expands into a one-shot session at run time |
+| Qoder | native | creates a deployment run and associated session |
+| Bailian, Ark | emulated | expands into a one-shot session at run time |
On the emulated providers, scheduling and outcome rubrics are **not** enforced server-side — use external cron/CI for always-on or scheduled runs.
diff --git a/docs/examples.md b/docs/examples.md
index e352cb6..fbeffa5 100644
--- a/docs/examples.md
+++ b/docs/examples.md
@@ -52,7 +52,7 @@ agents destroy
| MCP Server | native | native | native | native |
| Memory Store | unsupported | native | unsupported | native |
| Multi-Agent | unsupported | unsupported | native | native |
-| Deployment | emulated | emulated | native | emulated |
+| Deployment | emulated | native | native | emulated |
| Session | native | native | native | native |
See [Provider reference](./reference/providers.md) for per-provider configuration and notes.
diff --git a/docs/guides/configure-an-agent.zh-CN.md b/docs/guides/configure-an-agent.zh-CN.md
index f1d4072..d027351 100644
--- a/docs/guides/configure-an-agent.zh-CN.md
+++ b/docs/guides/configure-an-agent.zh-CN.md
@@ -460,7 +460,7 @@ Deployment 是介于「定义」与「运行」之间的声明式中间层。它
- **部署层**(Deployment):声明「用哪个 Agent、带哪些绑定、以什么初始事件和调度运行」。
- **运行层**(Session):一次具体的执行实例。
-> Provider 差异:Claude 原生支持 Deployment(对应平台的 deployments API,可服务端调度);百炼、Qoder、火山方舟为**模拟**实现——`apply` 只写本地状态(`remote_id` 为 `null`),`agents deployment run` 时展开为一个 Session。详见 [Provider 参考](../reference/providers.zh-CN.md#模拟emulated资源的能力降级)。
+> Provider 差异:Qoder 和 Claude 原生支持 Deployment(对应平台的 deployments API,可服务端调度);百炼、火山方舟为**模拟**实现——`apply` 只写本地状态(`remote_id` 为 `null`),`agents deployment run` 时展开为一个 Session。详见 [Provider 参考](../reference/providers.zh-CN.md#模拟emulated资源的能力降级)。
### 定义 Deployment
@@ -498,7 +498,7 @@ deployments:
- `agent` 必填,引用顶层 `agents` 中定义的 Agent。
- 未声明 `environment` / `vaults` / `memory_stores` 时,**继承所引用 Agent 的声明**;显式声明则覆盖。
-- `schedule.expression` 为 cron 表达式;`timezone` 为必填的 IANA 时区标识。仅 Claude 在服务端执行调度,百炼、Qoder、火山方舟需用外部 cron/CI 触发。
+- `schedule.expression` 为 cron 表达式;`timezone` 为必填的 IANA 时区标识。Qoder 和 Claude 在服务端执行调度,百炼、火山方舟需用外部 cron/CI 触发。
- `initial_events` **必填**(1–50 条),在 Deployment 运行时按顺序投递给 Agent。
### 初始事件(initial_events)
@@ -507,7 +507,7 @@ deployments:
|---------|------|------|
| `user.message` | `content` | 以用户身份发送的消息 |
| `system.message` | `content` | 系统提示(Qoder 上展平为 `user.message`) |
-| `user.define_outcome` | `description` / `rubric` / `rubric_file` / `max_iterations` | 定义结果评分目标(仅 Claude 服务端执行评分) |
+| `user.define_outcome` | `description` / `rubric` / `rubric_file` / `max_iterations` | 定义结果评分目标(Qoder 和 Claude 服务端执行评分) |
### 资源(resources)
@@ -515,9 +515,9 @@ Deployment 运行时可挂载的资源:
| 资源类型 | 字段 | 说明 |
|---------|------|------|
-| `file` | `file_id` / `source` / `mount_path` | 文件资源;`file_id` 引用已上传文件;`source` 为本地路径,Claude 在 `apply` 时上传、Qoder 在 `run` 时上传 |
+| `file` | `file_id` / `source` / `mount_path` | 文件资源;`file_id` 引用已上传文件;`source` 为本地路径,Qoder 和 Claude 在 `apply` 时上传 |
| `memory_store` | `memory_store` / `access` / `instructions` | 引用 Memory Store;`access` 为 `read_write`(默认)或 `read_only` |
-| `github_repository` | `url` / `checkout` / `mount_path` / `authorization_token` | 检出 Git 仓库(仅 Claude) |
+| `github_repository` | `url` / `checkout` / `mount_path` / `authorization_token` | 检出 Git 仓库(Qoder 和 Claude) |
### 运行与查看
@@ -669,7 +669,7 @@ Session 的架构遵循 Serverless Framework 模式:**定义管理**(`plan/a
| `memory_stores` | string[] | 否 | 覆盖 Agent 的 Memory Store |
| `resources` | array | 否 | 运行时挂载的资源(file / memory_store / github_repository) |
| `initial_events` | array | 是 | 运行时投递的初始事件(user.message / system.message / user.define_outcome),1–50 条 |
-| `schedule` | object | 否 | cron 调度(`expression` + 必填 `timezone`),仅 Claude 服务端执行 |
+| `schedule` | object | 否 | cron 调度(`expression` + 必填 `timezone`),Qoder 和 Claude 服务端执行 |
| `description` | string | 否 | 描述 |
| `provider` | string | 否 | 指定 Provider,覆盖 defaults |
| `metadata` | Record | 否 | 自定义元数据 |
diff --git a/docs/guides/deploy-to-qoder.md b/docs/guides/deploy-to-qoder.md
index 97f0261..99120b0 100644
--- a/docs/guides/deploy-to-qoder.md
+++ b/docs/guides/deploy-to-qoder.md
@@ -1,6 +1,6 @@
# Deploy to Qoder
-Qoder is a managed-agent platform with native **memory stores** but no multi-agent or server-side deployment primitive.
+Qoder is a managed-agent platform with native **memory stores** and **deployments**, but no multi-agent primitive.
## Provider configuration
@@ -20,11 +20,10 @@ providers:
| Feature | Tier |
|---------|:----:|
-| Environment, Vault, Skill, Agent, MCP Server, Memory Store, Session | native |
+| Environment, Vault, Skill, Agent, MCP Server, Memory Store, Deployment, Session | native |
| Multi-Agent | unsupported |
-| Deployment | emulated |
-A `deployment run` on Qoder expands into a one-shot session at run time; scheduling and outcome rubrics are not enforced server-side — use external cron/CI for scheduled runs.
+A `deployment run` on Qoder creates a native Deployment Run and associated Session. Cron schedules run server-side.
## Tool naming
diff --git a/docs/guides/manage-deployments.md b/docs/guides/manage-deployments.md
index 6774953..c67f9c6 100644
--- a/docs/guides/manage-deployments.md
+++ b/docs/guides/manage-deployments.md
@@ -67,12 +67,13 @@ agents deployment run # trigger a run
| Provider | Deployment tier | What `deployment run` does |
|----------|:--------------:|----------------------------|
| Claude | native | schedules server-side through the deployments API |
-| Qoder, Bailian, Ark | emulated | expands into a one-shot session at run time |
+| Qoder | native | creates a deployment run and associated session |
+| Bailian, Ark | emulated | expands into a one-shot session at run time |
On the emulated providers, scheduling and outcome rubrics are **not** enforced server-side — use external cron/CI for always-on or scheduled runs.
## Examples
- Native deployment + outcome rubric: [`examples/claude/deployment/`](../../examples/claude/deployment/)
-- Emulated deployment + memory store: [`examples/qoder/deployment/`](../../examples/qoder/deployment/)
+- Native deployment + memory store: [`examples/qoder/deployment/`](../../examples/qoder/deployment/)
- Emulated deployment + file resources: [`examples/bailian/deployment/`](../../examples/bailian/deployment/) and [`examples/ark/deployment/`](../../examples/ark/deployment/)
diff --git a/docs/reference/cli.md b/docs/reference/cli.md
index f449fba..bda61bd 100644
--- a/docs/reference/cli.md
+++ b/docs/reference/cli.md
@@ -120,7 +120,7 @@ Manage scheduled / triggered deployments.
|------------|-------------|
| `deployment list` | List deployments tracked in state. |
| `deployment get ` | Show a deployment's status and resolved bindings. |
-| `deployment run ` | Trigger a deployment run (native on Claude, emulated as a session on Bailian/Qoder/Volcengine Ark). |
+| `deployment run ` | Trigger a deployment run (native on Qoder/Claude, emulated as a session on Bailian/Volcengine Ark). |
## `agents models`
diff --git a/docs/reference/providers.md b/docs/reference/providers.md
index d8be961..f0be425 100644
--- a/docs/reference/providers.md
+++ b/docs/reference/providers.md
@@ -15,7 +15,7 @@ OpenAgentPack targets multiple agent platforms behind one declarative config. Ea
| MCP Server | native | native | native | native | Bailian uses official managed servers referenced by name. |
| Memory Store | unsupported | native | unsupported | native | Qoder and Ark are implemented. Claude's upstream API now has Memory Stores, but its OpenAgentPack adapter does not yet. |
| Multi-Agent | unsupported | unsupported | native | native | Coordinator topology is available on Claude and Volcengine Ark. |
-| Deployment | emulated | emulated | native | emulated | Non-Claude providers expand a deployment into a session at `run` time. |
+| Deployment | emulated | native | native | emulated | Qoder and Claude use native deployments; Bailian and Ark expand a deployment into a session at `run` time. |
| Session | native | native | native | native | Runtime sessions are native on every provider. |
- **native** — the provider supports the feature directly.
@@ -47,7 +47,7 @@ The resource matrix above answers whether a declaration can be applied. The tabl
### Notable provider-specific behavior
- **Bailian:** skill upload uses the Files API and supports scan-status polling; agent updates create provider-side versions. Official MCP servers are referenced by name.
-- **Qoder:** tool names are translated from the lowercase config vocabulary to PascalCase. Session sends return a cursor, enabling resumable event consumption. `system.message` is flattened to `user.message` when running an emulated deployment.
+- **Qoder:** tool names are translated from the lowercase config vocabulary to PascalCase. Session sends return a cursor, enabling resumable event consumption. Deployments are native and support manual or scheduled runs.
- **Claude:** deployments are native, including their server-side lifecycle. It is currently the only adapter that downloads remote skill packages during `sync`.
- **Volcengine Ark:** skills are create + get + attach only in the API behavior verified by this project. Updates re-upload a new skill; list and in-place update are unavailable; deletion is best-effort. Deployment is emulated as a session.
diff --git a/docs/reference/providers.zh-CN.md b/docs/reference/providers.zh-CN.md
index 1e16016..2a7558f 100644
--- a/docs/reference/providers.zh-CN.md
+++ b/docs/reference/providers.zh-CN.md
@@ -34,7 +34,7 @@ OpenAgentPack 通过 Provider 适配器与不同的 AI Agent 平台交互。每
| MCP Server | native | native | native | native | 通过 Agent 的 MCP 配置挂载 |
| Memory Store | unsupported | native | unsupported | native | Qoder、方舟已接入;Claude 上游已有 Memory Store,但 OpenAgentPack Adapter 尚未实现 |
| Multi-Agent | unsupported | unsupported | native | native | Claude 与 火山方舟 支持 coordinator |
-| Deployment | emulated | emulated | native | emulated | 非 Claude Provider 在 `run` 时展开为 Session |
+| Deployment | emulated | native | native | emulated | Qoder 和 Claude 使用原生 Deployment;百炼和火山方舟在 `run` 时展开为 Session |
| Session | native | native | native | native | 四者均原生支持 |
### Adapter 实现能力对照表
@@ -60,7 +60,7 @@ OpenAgentPack 通过 Provider 适配器与不同的 AI Agent 平台交互。每
#### Provider 特有实现与限制
- **百炼**:Skill 通过 Files API 上传并支持扫描状态轮询;Agent 更新会生成平台侧版本;官方 MCP Server 按名称引用。
-- **Qoder**:配置中的小写工具名会转换为 PascalCase;Session 发送返回游标,可恢复事件消费;模拟 Deployment 中的 `system.message` 会展平为 `user.message`。
+- **Qoder**:配置中的小写工具名会转换为 PascalCase;Session 发送返回游标,可恢复事件消费;Deployment 为原生资源,支持手动或定时运行。
- **Claude**:Deployment 是原生资源,具有服务端生命周期;当前只有 Claude Adapter 会在 `sync` 时下载远端 Skill 包。
- **火山方舟**:经本项目验证的 Skill API 行为仅支持创建、按 ID 查询和挂载。更新会重新上传,无法枚举和原地更新,删除为 best-effort;Deployment 由 Session 模拟。
@@ -113,7 +113,7 @@ OpenAgentPack 通过 Provider 适配器与不同的 AI Agent 平台交互。每
| Skill | existence | existence | existence | existence | 可发现缺失/删除,不比较包内容 |
| Vault | existence | existence | existence | existence | 凭证内容通常不可读回,不比较内容 |
| Memory Store | unsupported | existence | unsupported | existence | 可发现资源缺失 |
-| Deployment | unsupported | unsupported | native 路径待验证 | unsupported | emulated Deployment 为本地记录 |
+| Deployment | unsupported | native | native 路径待验证 | unsupported | 百炼和火山方舟的 emulated Deployment 为本地记录 |
Claude 的 drift detection 接口路径已预留;本仓库中的 live baseline 因 Anthropic API 账号余额不足未完成 Agent 创建验证。
@@ -139,7 +139,7 @@ qoder.multiagent.unsupported:
### 模拟(emulated)资源的能力降级
-`emulated` 等级表示 Provider 没有对应的原生原语,OpenAgentPack 通过其他原语间接实现。Deployment 在 百炼、Qoder、火山方舟 上为模拟实现:`apply` 时**不调用**部署 API(状态记录的 `remote_id` 为 `null`),而是在 `agents deployment run` 时展开为一个 Session 并回放 `initial_events`。
+`emulated` 等级表示 Provider 没有对应的原生原语,OpenAgentPack 通过其他原语间接实现。Deployment 在百炼和火山方舟上为模拟实现:`apply` 时**不调用**部署 API(状态记录的 `remote_id` 为 `null`),而是在 `agents deployment run` 时展开为一个 Session 并回放 `initial_events`。
部分子特性在 emulated Provider 上无法在服务端执行。`plan`/`apply` 阶段会输出**警告**(不阻断部署),`run` 时尽力降级:
@@ -150,17 +150,15 @@ qoder.multiagent.unsupported:
| `resources` 中的 `github_repository` | 不自动检出仓库 | 在 Session 内克隆仓库 |
| `resources` 中 `memory_store` 的 `access` / `instructions` | 忽略,按默认访问挂载 | — |
-此外,`system.message` 事件在 Qoder 上会被展平为 `user.message`(Qoder 仅支持 `user.message` 作为出站事件),其内容仍会送达 Agent。
-
示例诊断输出:
```
-⚠ qoder.deployment.schedule_unsupported
- Resource: deployment.daily-report (qoder)
+⚠ bailian.deployment.schedule_unsupported
+ Resource: deployment.daily-report (bailian)
Schedules are not enforced server-side on this provider; trigger runs via external cron/CI.
-⚠ qoder.deployment.define_outcome_unsupported
- Resource: deployment.daily-report (qoder)
+⚠ bailian.deployment.define_outcome_unsupported
+ Resource: deployment.daily-report (bailian)
Outcome rubrics (user.define_outcome) are not enforced server-side on this provider; the run executes without rubric grading.
```
diff --git a/examples/README.md b/examples/README.md
index 7c15550..496a2cc 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -32,7 +32,7 @@ examples/
│ ├── with-vault/ vault only
│ ├── vault-only/ vault-only project
│ ├── multi-provider/ same agent on both Claude + Qoder
-│ ├── deployment/ schedule + memory_store (emulated)
+│ ├── deployment/ schedule + memory_store (native)
│ ├── bailian-cli/ Bailian CLI integration
│ └── full/ Qoder full-feature stack
├── ark/ Volcengine Ark provider (Managed Agents, doubao)
@@ -59,7 +59,7 @@ examples/
| MCP Server | native | native | native | native | Bailian uses official managed servers referenced by name. |
| Memory Store | unsupported | native | unsupported | native | Qoder and Volcengine Ark. |
| Multi-Agent | unsupported | unsupported | native | native | Claude and Volcengine Ark support coordinator. |
-| Deployment | emulated | emulated | native | emulated | Claude schedules server-side; others expand into a session at `run` time. |
+| Deployment | emulated | native | native | emulated | Qoder and Claude schedule server-side; Bailian and Ark expand into a session at `run` time. |
| Session | native | native | native | native | All four support runtime sessions. |
## Tool naming differences
diff --git a/examples/qoder/deployment/agents.yaml b/examples/qoder/deployment/agents.yaml
index 69a5df2..bc1d360 100644
--- a/examples/qoder/deployment/agents.yaml
+++ b/examples/qoder/deployment/agents.yaml
@@ -36,14 +36,14 @@ agents:
builtin: [Read, Glob, Grep, WebSearch]
memory_stores: [project-kb]
-# Deployment is emulated on Qoder: `apply` only records local state
-# (remote_id = null); `agents deployment run` materializes it into a Session.
+# Deployment is native on Qoder: `apply` creates a remote Deployment, and
+# `agents deployment run` creates a Deployment Run with an associated Session.
# The schedule, define_outcome rubric, and memory_store access modifier below
# are not enforced server-side and will surface warning diagnostics on plan.
deployments:
daily-report:
agent: reporter
- description: "Daily report (emulated -> Session on run)"
+ description: "Daily report (native Deployment Run)"
schedule:
expression: "0 9 * * *"
timezone: UTC
diff --git a/packages/sdk/src/internal/providers/qoder/adapter.ts b/packages/sdk/src/internal/providers/qoder/adapter.ts
index 5287d2c..00e4cf3 100644
--- a/packages/sdk/src/internal/providers/qoder/adapter.ts
+++ b/packages/sdk/src/internal/providers/qoder/adapter.ts
@@ -55,7 +55,7 @@ import {
fileToDecl,
mapAgent,
mapCredential,
- mapDeploymentToSession,
+ mapDeployment,
mapEnvironment,
mapMemoryStore,
mapSendMessage,
@@ -358,77 +358,76 @@ export class QoderAdapter implements ProviderAdapter {
}
async createDeployment(
- _name: string,
- _decl: DeploymentDecl,
- _refs: ResolvedDeploymentRefs,
- _basePath: string,
+ name: string,
+ decl: DeploymentDecl,
+ refs: ResolvedDeploymentRefs,
+ basePath: string,
): Promise {
- // Emulated: Qoder has no deployments endpoint. The deployment is recorded in
- // state with remote_id = null and materialized into a session at run time.
- return { id: null, type: "deployment" };
+ const uploaded = await this.uploadDeploymentFiles(decl, basePath);
+ const body = mapDeployment(name, decl, refs, this.projectName, uploaded);
+ const res = (await this.client.post("/deployments", body)) as Record;
+ return toRemoteResource(res);
}
async updateDeployment(
- _id: string,
- _name: string,
- _decl: DeploymentDecl,
- _refs: ResolvedDeploymentRefs,
- _basePath: string,
+ id: string,
+ name: string,
+ decl: DeploymentDecl,
+ refs: ResolvedDeploymentRefs,
+ basePath: string,
): Promise {
- return { id: null, type: "deployment" };
+ const uploaded = await this.uploadDeploymentFiles(decl, basePath);
+ const body = mapDeployment(name, decl, refs, this.projectName, uploaded);
+ const res = (await this.client.post(`/deployments/${id}`, body)) as Record;
+ return toRemoteResource(res);
}
- async deleteDeployment(_id: string): Promise {
- // Emulated: no remote object to delete.
+ async deleteDeployment(id: string): Promise {
+ await this.client.post(`/deployments/${id}/archive`, {});
}
async runDeployment(ctx: DeploymentContext): Promise {
- // Emulated run: upload file resources, create a session bound to the
- // deployment's agent/environment/vault/memory_stores, then replay messages.
- const fileIds: string[] = [];
- for (const r of ctx.decl.resources ?? []) {
- if (r.type === "file") {
- if (r.file_id) {
- fileIds.push(r.file_id);
- } else if (r.source) {
- fileIds.push(await this.uploadSessionFile(r.source, ctx.basePath));
- }
- }
- }
-
- const body = mapDeploymentToSession(ctx.decl, ctx.refs, fileIds);
- const sessionRes = (await this.client.post("/sessions", body)) as Record;
- const sessionId = sessionRes.id as string;
-
- // Qoder only supports `user.message` as an outbound event, so a
- // system.message is delivered as a user.message (its content still reaches
- // the agent). define_outcome events are dropped (warned at plan time).
- const events = ctx.decl.initial_events
- .filter((e) => e.type === "user.message" || e.type === "system.message")
- .map((e) => ({
- type: "user.message",
- content: [{ type: "text", text: (e as { content: string }).content }],
- }));
-
- if (events.length) {
- await this.client.post(`/sessions/${sessionId}/events`, { events });
+ if (!ctx.id) {
+ throw new UserError(`Deployment '${ctx.name}' has no remote id; run \`agents apply\` first.`);
}
-
- return { session_id: sessionId };
+ const res = (await this.client.post(`/deployments/${ctx.id}/run`, {})) as Record;
+ return {
+ run_id: res.id as string | undefined,
+ session_id: (res.session_id as string | null) ?? null,
+ error: (res.error as { type: string; message: string } | null | undefined) ?? undefined,
+ };
}
async getDeployment(ctx: DeploymentContext): Promise {
- // Emulated: no remote object. Report the local record and the session that
- // `run` would materialize.
- const plan = mapDeploymentToSession(ctx.decl, ctx.refs, []);
+ if (!ctx.id) {
+ throw new UserError(`Deployment '${ctx.name}' has no remote id; run \`agents apply\` first.`);
+ }
+ const res = (await this.client.get(`/deployments/${ctx.id}`)) as Record;
+ const sched = res.schedule as Record | null | undefined;
return {
- id: ctx.id,
- status: "emulated (local)",
- schedule: ctx.decl.schedule,
- attributes: { materialization_plan: plan },
+ id: res.id as string,
+ status: (res.status as string) ?? "unknown",
+ paused_reason: res.paused_reason as { type: string; error?: { type: string } } | undefined,
+ schedule: sched
+ ? {
+ expression: sched.expression as string,
+ timezone: sched.timezone as string,
+ }
+ : undefined,
+ attributes: res,
};
}
+ private async uploadDeploymentFiles(decl: DeploymentDecl, basePath: string): Promise