Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/content/docs/framework/agent/runtime.en.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ agent = Agent(

The deployed [Harness server](/en/docs/cli/harness-cli) exposes the same switch:
the harness spec's `runtime` field, and the `--runtime` option on
`veadk agentkit harness add/invoke` (`adk` or `codex`).
`veadk harness add/invoke` (`adk` or `codex`).

## Adding a custom runtime

Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/framework/agent/runtime.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ agent = Agent(

## 在 Harness Server 中使用

部署的 [Harness server](/cn/docs/cli/harness-cli) 也暴露了运行时开关:harness 规格的 `runtime` 字段,以及 `veadk agentkit harness add/invoke` 的 `--runtime` 选项(`adk` 或 `codex`)。
部署的 [Harness server](/cn/docs/cli/harness-cli) 也暴露了运行时开关:harness 规格的 `runtime` 字段,以及 `veadk harness add/invoke` 的 `--runtime` 选项(`adk` 或 `codex`)。

## 扩展自定义运行时

Expand Down
72 changes: 0 additions & 72 deletions tests/cli/test_cli_agentkit_harness_contract.py

This file was deleted.

131 changes: 0 additions & 131 deletions veadk/cli/cli_agentkit.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

import json

import click
from agentkit.toolkit.cli.cli import app as agentkit_typer_app
from typer.main import get_command
Expand All @@ -30,132 +28,3 @@ def agentkit():
if isinstance(agentkit_commands, click.Group):
for cmd_name, cmd in agentkit_commands.commands.items():
agentkit.add_command(cmd, name=cmd_name)


# --- Harness server client -------------------------------------------------
# A thin HTTP client for a deployed Harness server (veadk/cloud/harness_app),
# which exposes `/harness/invoke`. Lives under a dedicated `harness` subgroup so
# it does not shadow the external AgentKit `invoke`.


def _harness_request(url: str, path: str, key: str | None, body: dict) -> dict:
"""POST ``body`` to ``url + path`` with optional Bearer auth; return JSON."""
import os

import httpx

headers = {"Content-Type": "application/json"}
if key:
headers["Authorization"] = f"Bearer {key}"

# Tool/skill-driven agent runs can take minutes; allow a generous, tunable
# client timeout (HARNESS_TIMEOUT seconds, default 600).
timeout = float(os.getenv("HARNESS_TIMEOUT", "600"))
resp = httpx.post(
url.rstrip("/") + path, json=body, headers=headers, timeout=timeout
)
if resp.status_code != 200:
raise click.ClickException(
f"{path} failed: HTTP {resp.status_code} - {resp.text}"
)
return resp.json()


@click.group()
def harness() -> None:
"""Manage and invoke harnesses on a deployed Harness server."""
pass


@harness.command("invoke")
@click.argument("message")
@click.option(
"--harness", "harness_name", required=True, help="Harness name to invoke."
)
@click.option(
"--model-name",
"model_name",
default=None,
help="Override the model for this call (creates a one-time harness).",
)
@click.option(
"--system-prompt",
"system_prompt",
default=None,
help="Override the system prompt for this call (creates a one-time harness).",
)
@click.option(
"--tools",
default=None,
help="Override tools for this call, comma-separated (creates a one-time harness).",
)
@click.option(
"--skills",
default=None,
help="Override skills for this call, comma-separated (creates a one-time harness).",
)
@click.option(
"--runtime",
default=None,
type=click.Choice(["adk", "codex"]),
help="Override the runtime for this call (creates a one-time harness).",
)
@click.option(
"--user-id", "user_id", default="cli-user", help="User id for the session."
)
@click.option(
"--session-id", "session_id", default="cli-session", help="Session id for the call."
)
@click.option(
"--url",
required=True,
envvar="HARNESS_URL",
help="Harness server base URL (or set HARNESS_URL).",
)
@click.option(
"--key",
default=None,
envvar="HARNESS_KEY",
help="Gateway API key for Bearer auth (or set HARNESS_KEY).",
)
def harness_invoke(
message,
harness_name,
model_name,
system_prompt,
tools,
skills,
runtime,
user_id,
session_id,
url,
key,
) -> None:
"""Invoke a harness with MESSAGE and print its output."""
body: dict = {
"prompt": message,
"harness_name": harness_name,
"run_agent_request": {"user_id": user_id, "session_id": session_id},
}
# Any of --model-name/--system-prompt/--tools/--skills/--runtime builds a
# one-time harness that overrides the stored one for this single call (the
# server replaces the whole agent). tools/skills are passed through as
# comma-separated strings; the server splits them.
once: dict = {}
if model_name:
once["model_name"] = model_name
if system_prompt:
once["system_prompt"] = system_prompt
if tools:
once["tools"] = tools
if skills:
once["skills"] = skills
if runtime:
once["runtime"] = runtime
if once:
body["harness"] = once
result = _harness_request(url, "/harness/invoke", key, body)
click.echo(result.get("output", json.dumps(result, ensure_ascii=False)))


agentkit.add_command(harness, name="harness")
25 changes: 23 additions & 2 deletions veadk/cli/cli_harness.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,29 @@ def _build_agentkit_config(
}


def _harness_request(url: str, path: str, key: str | None, body: dict) -> dict:
"""POST ``body`` to ``url + path`` with optional Bearer auth; return JSON."""
import os

import httpx

headers = {"Content-Type": "application/json"}
if key:
headers["Authorization"] = f"Bearer {key}"

# Tool/skill-driven agent runs can take minutes; allow a generous, tunable
# client timeout (HARNESS_TIMEOUT seconds, default 600).
timeout = float(os.getenv("HARNESS_TIMEOUT", "600"))
resp = httpx.post(
url.rstrip("/") + path, json=body, headers=headers, timeout=timeout
)
if resp.status_code != 200:
raise click.ClickException(
f"{path} failed: HTTP {resp.status_code} - {resp.text}"
)
return resp.json()


def _harness_json_path(directory: str) -> Path:
return Path(directory).resolve() / "harness.json"

Expand Down Expand Up @@ -808,8 +831,6 @@ def invoke(
deployed agent for this single call; memory and the knowledge base are never
overridable.
"""
from veadk.cli.cli_agentkit import _harness_request

message = message_opt or message_arg
if not message:
raise click.ClickException("Provide a prompt (MESSAGE argument or --message).")
Expand Down
Loading