Add runtime capability scaffolding and align docs
This commit is contained in:
parent
fb8b985049
commit
cbf212bb7b
19 changed files with 1048 additions and 71 deletions
|
|
@ -16,6 +16,12 @@ __all__ = ["VmManager", "run_ollama_tool_demo"]
|
|||
DEFAULT_OLLAMA_BASE_URL: Final[str] = "http://localhost:11434/v1"
|
||||
DEFAULT_OLLAMA_MODEL: Final[str] = "llama:3.2-3b"
|
||||
MAX_TOOL_ROUNDS: Final[int] = 12
|
||||
CLONE_TARGET_DIR: Final[str] = "hello-world"
|
||||
NETWORK_PROOF_COMMAND: Final[str] = (
|
||||
"rm -rf hello-world "
|
||||
"&& git clone --depth 1 https://github.com/octocat/Hello-World.git hello-world >/dev/null "
|
||||
"&& git -C hello-world rev-parse --is-inside-work-tree"
|
||||
)
|
||||
|
||||
TOOL_SPECS: Final[list[dict[str, Any]]] = [
|
||||
{
|
||||
|
|
@ -210,7 +216,7 @@ def _run_direct_lifecycle_fallback(manager: VmManager) -> dict[str, Any]:
|
|||
created = manager.create_vm(profile="debian-git", vcpu_count=1, mem_mib=512, ttl_seconds=600)
|
||||
vm_id = str(created["vm_id"])
|
||||
manager.start_vm(vm_id)
|
||||
return manager.exec_vm(vm_id, command="git --version", timeout_seconds=30)
|
||||
return manager.exec_vm(vm_id, command=NETWORK_PROOF_COMMAND, timeout_seconds=60)
|
||||
|
||||
|
||||
def _is_vm_id_placeholder(value: str) -> bool:
|
||||
|
|
@ -240,8 +246,10 @@ def _normalize_tool_arguments(
|
|||
return normalized_arguments, last_created_vm_id
|
||||
|
||||
|
||||
def _summarize_message_for_log(message: dict[str, Any]) -> str:
|
||||
def _summarize_message_for_log(message: dict[str, Any], *, verbose: bool) -> str:
|
||||
role = str(message.get("role", "unknown"))
|
||||
if not verbose:
|
||||
return role
|
||||
content = str(message.get("content") or "").strip()
|
||||
if content == "":
|
||||
return f"{role}: <empty>"
|
||||
|
|
@ -257,6 +265,7 @@ def run_ollama_tool_demo(
|
|||
model: str = DEFAULT_OLLAMA_MODEL,
|
||||
*,
|
||||
strict: bool = True,
|
||||
verbose: bool = False,
|
||||
log: Callable[[str], None] | None = None,
|
||||
) -> dict[str, Any]:
|
||||
"""Ask Ollama to run git version check in an ephemeral VM through lifecycle tools."""
|
||||
|
|
@ -267,10 +276,12 @@ def run_ollama_tool_demo(
|
|||
{
|
||||
"role": "user",
|
||||
"content": (
|
||||
"Use the lifecycle tools to run `git --version` in an ephemeral VM.\n"
|
||||
"Use the lifecycle tools to prove outbound internet access in an ephemeral VM.\n"
|
||||
"Required order: vm_list_profiles -> vm_create -> vm_start -> vm_exec.\n"
|
||||
"Use profile `debian-git`, choose adequate vCPU/memory, and pass the `vm_id` "
|
||||
"returned by vm_create into vm_start/vm_exec.\n"
|
||||
f"Run this exact command: `{NETWORK_PROOF_COMMAND}`.\n"
|
||||
f"Success means the clone completes and the command prints `true`.\n"
|
||||
"If a tool returns an error, fix arguments and retry."
|
||||
),
|
||||
}
|
||||
|
|
@ -280,7 +291,7 @@ def run_ollama_tool_demo(
|
|||
last_created_vm_id: str | None = None
|
||||
|
||||
for _round_index in range(1, MAX_TOOL_ROUNDS + 1):
|
||||
emit(f"[model] input {_summarize_message_for_log(messages[-1])}")
|
||||
emit(f"[model] input {_summarize_message_for_log(messages[-1], verbose=verbose)}")
|
||||
response = _post_chat_completion(
|
||||
base_url,
|
||||
{
|
||||
|
|
@ -292,7 +303,7 @@ def run_ollama_tool_demo(
|
|||
},
|
||||
)
|
||||
assistant_message = _extract_message(response)
|
||||
emit(f"[model] output {_summarize_message_for_log(assistant_message)}")
|
||||
emit(f"[model] output {_summarize_message_for_log(assistant_message, verbose=verbose)}")
|
||||
tool_calls = assistant_message.get("tool_calls")
|
||||
if not isinstance(tool_calls, list) or not tool_calls:
|
||||
final_response = str(assistant_message.get("content") or "")
|
||||
|
|
@ -320,15 +331,24 @@ def run_ollama_tool_demo(
|
|||
if not isinstance(tool_name, str):
|
||||
raise RuntimeError("tool call function name is invalid")
|
||||
arguments = _parse_tool_arguments(function.get("arguments"))
|
||||
emit(f"[model] tool_call {tool_name} args={arguments}")
|
||||
if verbose:
|
||||
emit(f"[model] tool_call {tool_name} args={arguments}")
|
||||
else:
|
||||
emit(f"[model] tool_call {tool_name}")
|
||||
arguments, normalized_vm_id = _normalize_tool_arguments(
|
||||
tool_name,
|
||||
arguments,
|
||||
last_created_vm_id=last_created_vm_id,
|
||||
)
|
||||
if normalized_vm_id is not None:
|
||||
emit(f"[tool] resolved vm_id placeholder to {normalized_vm_id}")
|
||||
emit(f"[tool] calling {tool_name} with args={arguments}")
|
||||
if verbose:
|
||||
emit(f"[tool] resolved vm_id placeholder to {normalized_vm_id}")
|
||||
else:
|
||||
emit("[tool] resolved vm_id placeholder")
|
||||
if verbose:
|
||||
emit(f"[tool] calling {tool_name} with args={arguments}")
|
||||
else:
|
||||
emit(f"[tool] calling {tool_name}")
|
||||
try:
|
||||
result = _dispatch_tool_call(manager, tool_name, arguments)
|
||||
success = True
|
||||
|
|
@ -341,7 +361,10 @@ def run_ollama_tool_demo(
|
|||
result = _format_tool_error(tool_name, arguments, exc)
|
||||
success = False
|
||||
emit(f"[tool] {tool_name} failed: {exc}")
|
||||
emit(f"[tool] result {tool_name} {_serialize_log_value(result)}")
|
||||
if verbose:
|
||||
emit(f"[tool] result {tool_name} {_serialize_log_value(result)}")
|
||||
else:
|
||||
emit(f"[tool] result {tool_name}")
|
||||
tool_events.append(
|
||||
{
|
||||
"tool_name": tool_name,
|
||||
|
|
@ -379,7 +402,7 @@ def run_ollama_tool_demo(
|
|||
tool_events.append(
|
||||
{
|
||||
"tool_name": "vm_exec_fallback",
|
||||
"arguments": {"command": "git --version"},
|
||||
"arguments": {"command": NETWORK_PROOF_COMMAND},
|
||||
"result": exec_result,
|
||||
"success": True,
|
||||
}
|
||||
|
|
@ -390,13 +413,13 @@ def run_ollama_tool_demo(
|
|||
raise RuntimeError("vm_exec result shape is invalid")
|
||||
if int(exec_result.get("exit_code", -1)) != 0:
|
||||
raise RuntimeError("vm_exec failed; expected exit_code=0")
|
||||
if "git version" not in str(exec_result.get("stdout", "")):
|
||||
raise RuntimeError("vm_exec output did not contain `git version`")
|
||||
if str(exec_result.get("stdout", "")).strip() != "true":
|
||||
raise RuntimeError("vm_exec output did not confirm repository clone success")
|
||||
emit("[done] command execution succeeded")
|
||||
|
||||
return {
|
||||
"model": model,
|
||||
"command": "git --version",
|
||||
"command": NETWORK_PROOF_COMMAND,
|
||||
"exec_result": exec_result,
|
||||
"tool_events": tool_events,
|
||||
"final_response": final_response,
|
||||
|
|
@ -408,6 +431,7 @@ def _build_parser() -> argparse.ArgumentParser:
|
|||
parser = argparse.ArgumentParser(description="Run Ollama tool-calling demo for ephemeral VMs.")
|
||||
parser.add_argument("--base-url", default=DEFAULT_OLLAMA_BASE_URL)
|
||||
parser.add_argument("--model", default=DEFAULT_OLLAMA_MODEL)
|
||||
parser.add_argument("-v", "--verbose", action="store_true")
|
||||
return parser
|
||||
|
||||
|
||||
|
|
@ -418,6 +442,7 @@ def main() -> None:
|
|||
result = run_ollama_tool_demo(
|
||||
base_url=args.base_url,
|
||||
model=args.model,
|
||||
verbose=args.verbose,
|
||||
log=lambda message: print(message, flush=True),
|
||||
)
|
||||
except Exception as exc: # noqa: BLE001
|
||||
|
|
@ -428,7 +453,9 @@ def main() -> None:
|
|||
raise RuntimeError("demo produced invalid execution result")
|
||||
print(
|
||||
f"[summary] exit_code={int(exec_result.get('exit_code', -1))} "
|
||||
f"fallback_used={bool(result.get('fallback_used'))}",
|
||||
f"fallback_used={bool(result.get('fallback_used'))} "
|
||||
f"execution_mode={str(exec_result.get('execution_mode', 'unknown'))}",
|
||||
flush=True,
|
||||
)
|
||||
print(f"[summary] stdout={str(exec_result.get('stdout', '')).strip()}", flush=True)
|
||||
if args.verbose:
|
||||
print(f"[summary] stdout={str(exec_result.get('stdout', '')).strip()}", flush=True)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue