runs and deployment: first slice

uhh
This commit is contained in:
lda
2026-06-01 02:53:52 +07:00 Verified
parent 3cd7f529e9
commit d4ab0e6912
7 changed files with 1042 additions and 3 deletions
+29
View File
@@ -1,9 +1,38 @@
from __future__ import annotations
import asyncio
from typing import Annotated
import typer
from wf_cli.context import config_path_from_context, load_cli_context
from wf_cli.io import emit_json
app = typer.Typer(
name="deploy",
help="Save, inspect, validate, and delete workflow deployments.",
no_args_is_help=True,
)
@app.command("validate")
def validate_deployment(
ctx: typer.Context,
deployment_id: Annotated[str, typer.Argument(help="Deployment id to validate.")],
live: Annotated[
bool,
typer.Option(
"--live",
help="Also perform opt-in upstream liveness checks.",
),
] = False,
) -> None:
"""Validate one saved workflow deployment."""
context = load_cli_context(config_path_from_context(ctx))
payload = asyncio.run(
context.handlers.validate_deployment(
deployment_id=deployment_id,
live_check=live,
)
)
emit_json(payload)
+92
View File
@@ -1,9 +1,101 @@
from __future__ import annotations
import asyncio
from pathlib import Path
from typing import Annotated
import typer
from wf_cli.context import config_path_from_context, load_cli_context
from wf_cli.io import CliInputError, emit_json, parse_json_input
from wf_mcp.workflow_surface import TraceRange
app = typer.Typer(
name="run",
help="Run workflow deployments and inspect durable runs.",
no_args_is_help=True,
)
@app.command("start")
def start_run(
ctx: typer.Context,
deployment_id: Annotated[str, typer.Argument(help="Deployment id to run.")],
input_json: Annotated[
str | None,
typer.Option("--input", help="Workflow input JSON object."),
] = None,
input_file: Annotated[
Path | None,
typer.Option("--input-file", help="Path to workflow input JSON object."),
] = None,
trace_from: Annotated[
int | None,
typer.Option("--trace-from", min=0, help="Optional trace slice start."),
] = None,
trace_limit: Annotated[
int | None,
typer.Option(
"--trace-limit", min=1, max=100, help="Optional trace slice limit."
),
] = None,
) -> None:
"""Start one workflow deployment."""
try:
workflow_input = parse_json_input(input_json=input_json, input_file=input_file)
except CliInputError as exc:
raise typer.BadParameter(str(exc)) from exc
context = load_cli_context(config_path_from_context(ctx))
trace_range = _optional_trace_range(start=trace_from, limit=trace_limit)
payload = asyncio.run(
context.handlers.run_deployment(
deployment_id=deployment_id,
workflow_input=workflow_input,
trace_range=trace_range,
)
)
emit_json(payload)
@app.command("inspect")
def inspect_run(
ctx: typer.Context,
run_id: Annotated[str, typer.Argument(help="Durable run id to inspect.")],
) -> None:
"""Inspect a durable run without trace entries."""
context = load_cli_context(config_path_from_context(ctx))
emit_json(asyncio.run(context.handlers.inspect_run(run_id=run_id)))
@app.command("trace")
def trace_run(
ctx: typer.Context,
run_id: Annotated[str, typer.Argument(help="Durable run id to trace.")],
trace_from: Annotated[
int,
typer.Option("--from", min=0, help="Zero-based trace start offset."),
] = 0,
limit: Annotated[
int,
typer.Option("--limit", min=1, max=100, help="Maximum trace entries."),
] = 25,
) -> None:
"""Read a bounded debug trace slice."""
context = load_cli_context(config_path_from_context(ctx))
payload = asyncio.run(
context.handlers.read_run_trace(
run_id=run_id,
trace_range=TraceRange(start=trace_from, limit=limit),
)
)
emit_json(payload)
def _optional_trace_range(*, start: int | None, limit: int | None) -> TraceRange | None:
"""Build a trace range only when the caller requested trace detail."""
if start is None and limit is None:
return None
return TraceRange(
start=start if start is not None else 0,
limit=limit if limit is not None else 25,
)