Upgrade the runtime and native plugin API to OpenCode 2.0.24. Restore session-scoped learning, credential renewal, typed project queries and controlled frontend actions from the legacy Agent. Replace host Shell execution with an approved Landlock/seccomp executor and persistent per-session workspaces. Add typed Bocha search and Tianditu geocoding bridges using the owning session credential. Require a working kernel sandbox before startup and persist workspace files in deployments. Validation completed before this commit: TypeScript checks, 150 Bun tests, Docker build and UID 10001 sandbox execution, native Shell approval and session recovery. Tianditu succeeded; Bocha currently reports exhausted account quota. Unrelated investigation-report contract work is excluded.
43 lines
2.8 KiB
TypeScript
43 lines
2.8 KiB
TypeScript
import { tool } from "../tool.js";
|
|
import { getInternalBridgeConfig } from "../internalBridge.js";
|
|
import { newExecutionPlanSchema } from "../../src/routes/executionPlan.js";
|
|
|
|
export default tool({
|
|
description: "Publish the current full execution plan and progress to TJWater Server. Plans may be updated multiple times during investigation; a plan-only publish is intermediate and does not finish the task unless it explicitly records Agent failure. Publish the relevant plan node before proposing an action, then republish the plan with the returned action_id before the final report. Preserve stable node IDs and completed evidence. A running or completed node may only depend on completed or skipped predecessors. Edges are dependencies or labeled conditional branches, never guessed from list order. Human actions stay waiting until externally confirmed. Evidence must identify synthetic inputs, tool results or human confirmation accurately. This records a plan, it does not execute actions.",
|
|
args: {
|
|
request_id: tool.schema.string().describe("Stable UUID idempotency key for this plan revision"),
|
|
schema: tool.schema.enum(["execution-plan@2"]),
|
|
title: tool.schema.string(),
|
|
reason: tool.schema.string().describe("Why the plan or node status changed"),
|
|
nodes: tool.schema.array(tool.schema.object({
|
|
id: tool.schema.string(), title: tool.schema.string(),
|
|
status: tool.schema.enum(["pending", "running", "waiting", "completed", "failed", "skipped", "cancelled"]),
|
|
owner: tool.schema.enum(["agent", "human"]),
|
|
detail: tool.schema.string(), evidence: tool.schema.array(tool.schema.string()),
|
|
action_refs: tool.schema.array(tool.schema.string()).optional(),
|
|
kind: tool.schema.enum(["activity", "decision", "parallel_split", "parallel_join", "gate"]).optional(),
|
|
selected_edge_id: tool.schema.string().nullable().optional(),
|
|
gate_ref: tool.schema.string().nullable().optional(),
|
|
revisits_node_id: tool.schema.string().nullable().optional(),
|
|
})),
|
|
edges: tool.schema.array(tool.schema.object({ id: tool.schema.string().optional(), from: tool.schema.string(), to: tool.schema.string(), label: tool.schema.string() })),
|
|
},
|
|
async execute(args, context) {
|
|
const { request_id, ...input } = args;
|
|
const plan = newExecutionPlanSchema.parse(input);
|
|
const { baseUrl, internalToken } = getInternalBridgeConfig();
|
|
const response = await fetch(`${baseUrl}/internal/operational-task/artifacts`, {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json", "x-agent-internal-token": internalToken },
|
|
body: JSON.stringify({
|
|
session_id: context.sessionID,
|
|
request_id,
|
|
execution_plan: plan,
|
|
}),
|
|
});
|
|
const text = await response.text();
|
|
if (!response.ok) throw new Error(`task plan publish failed (${response.status}): ${text}`);
|
|
return text;
|
|
},
|
|
});
|