feat(coding-agent): removed context argument from eval agent() spawn

Shared background now flows through a '/Users/can/.omp/agent/sessions/-Projects-.tree-pi-commit/2026-06-10T15-36-32-782Z_019eb22d-970e-7000-8964-72c98becf3e8/local' file referenced in each prompt instead of a context string forwarded into the subagent's system prompt. The JS and Python preludes drop the context kwarg from agent(), the subagent system prompt drops the {{#if context}} block and the conversation-context file pointer, and runEvalAgent no longer writes a per-call conversation context file. AgentSession sheds the now-unused formatCompactContext() helper that supplied the file's body, and ToolSession.getCompactContext is removed alongside it.
This commit is contained in:
can1357
2026-06-10 17:49:01 +02:00
parent fcb8663de8
commit a92d2ce989
10 changed files with 19 additions and 113 deletions
@@ -178,7 +178,7 @@ describe("runEvalAgent", () => {
expect(runSpy).not.toHaveBeenCalled();
});
it("passes the parent execution context and only sets outputSchema when schema is supplied", async () => {
it("passes parent execution options and only sets outputSchema when schema is supplied", async () => {
mockAgents();
const runSpy = vi.spyOn(taskExecutor, "runSubprocess").mockImplementation(async options => singleResult(options));
const abortController = new AbortController();
@@ -186,7 +186,7 @@ describe("runEvalAgent", () => {
const session = makeSession({ depth: 2, activeModel: "p/current", modelString: "p/fallback" });
await runEvalAgent(
{ prompt: " hello ", context: " context ", label: "My Agent", model: "p/override", schema },
{ prompt: " hello ", label: "My Agent", model: "p/override", schema },
{ session, signal: abortController.signal },
);
await runEvalAgent({ prompt: "plain" }, { session });
@@ -199,7 +199,6 @@ describe("runEvalAgent", () => {
expect(firstOptions.parentActiveModelPattern).toBe("p/current");
expect(firstOptions.outputSchema).toBe(schema);
expect(firstOptions.assignment).toBe("hello");
expect(firstOptions.context).toBe("context");
expect(firstOptions.description).toBe("My Agent");
expect(firstOptions.modelOverride).toEqual(["p/override"]);
expect(secondOptions.outputSchema).toBeUndefined();
+2 -15
View File
@@ -34,7 +34,6 @@ const agentArgsSchema = z.object({
prompt: z.string().min(1, "prompt must be a non-empty string"),
agentType: z.string().min(1).optional(),
model: z.union([z.string().min(1), z.array(z.string().min(1)).min(1)]).optional(),
context: z.string().optional(),
label: z.string().optional(),
schema: z.unknown().optional(),
});
@@ -43,7 +42,6 @@ interface EvalAgentArgs {
prompt: string;
agentType?: string;
model?: string | string[];
context?: string;
label?: string;
schema?: unknown;
}
@@ -135,20 +133,12 @@ function getOutputManager(session: ToolSession): AgentOutputManager {
async function getArtifacts(session: ToolSession): Promise<{
sessionFile: string | null;
artifactsDir: string;
contextFile?: string;
}> {
const sessionFile = session.getSessionFile();
const sessionArtifactsDir = sessionFile ? sessionFile.slice(0, -6) : null;
const artifactsDir = sessionArtifactsDir ?? path.join(os.tmpdir(), `omp-eval-agent-${Snowflake.next()}`);
await fs.mkdir(artifactsDir, { recursive: true });
const shouldWriteConversationContext = session.settings.get("irc.enabled") !== true;
const compactContext = shouldWriteConversationContext ? session.getCompactContext?.() : undefined;
if (!compactContext) return { sessionFile, artifactsDir };
const contextFile = path.join(artifactsDir, "context.md");
await Bun.write(contextFile, compactContext);
return { sessionFile, artifactsDir, contextFile };
return { sessionFile, artifactsDir };
}
function emitProgressStatus(emitStatus: ((event: JsStatusEvent) => void) | undefined, progress: AgentProgress): void {
@@ -246,11 +236,10 @@ export async function runEvalAgent(args: unknown, options: EvalAgentBridgeOption
};
const parentArtifactManager = options.session.getArtifactManager?.() ?? undefined;
const mcpManager = options.session.mcpManager ?? MCPManager.instance();
const { sessionFile, artifactsDir, contextFile } = await getArtifacts(options.session);
const { sessionFile, artifactsDir } = await getArtifacts(options.session);
const outputManager = getOutputManager(options.session);
const id = await outputManager.allocate(outputIdBase(parsed.label, agentName));
const assignment = parsed.prompt.trim();
const context = trimToUndefined(parsed.context);
// Suspend eval timeout accounting while the subagent owns control. The
// timeout clock restarts once the bridge returns to the cell runtime.
const result = await withBridgeTimeoutPause(options.emitStatus, () =>
@@ -259,7 +248,6 @@ export async function runEvalAgent(args: unknown, options: EvalAgentBridgeOption
agent: effectiveAgent,
task: renderSubagentPrompt(assignment),
assignment,
context,
description: trimToUndefined(parsed.label),
index: 0,
id,
@@ -271,7 +259,6 @@ export async function runEvalAgent(args: unknown, options: EvalAgentBridgeOption
sessionFile,
persistArtifacts: Boolean(sessionFile),
artifactsDir,
contextFile,
// Eval `agent()` subagents are short-lived programmatic helpers (data
// collection, structured output, parallel() fan-out). LSP server
// cold-start costs tens of seconds and is pure overhead here, so it is
@@ -65,7 +65,7 @@ if (!globalThis.__omp_js_prelude_loaded__) {
};
const agent = async (prompt, opts, ...rest) => {
const o = optionsArg("agent", opts, rest, "{ agentType, model, context, label, schema }");
const o = optionsArg("agent", opts, rest, "{ agentType, model, label, schema }");
const res = await globalThis.__omp_call_tool__("__agent__", { prompt, ...o });
const text = res && typeof res === "object" ? res.text : res;
return hasOwn(o, "schema") ? JSON.parse(text) : text;
+5 -6
View File
@@ -519,21 +519,20 @@ if "__omp_prelude_loaded__" not in globals():
text = res.get("text") if isinstance(res, dict) else res
return json.loads(text) if schema is not None else text
def agent(prompt, *, agent_type="task", model=None, context=None, label=None, schema=None):
def agent(prompt, *, agent_type="task", model=None, label=None, schema=None):
"""Run a subagent and return its final output.
`agent_type` selects the subagent definition (default "task"). Pass
`model` to override that agent's model, `context` for shared background,
`label` for the output artifact id, and `schema` to request structured
JSON output; when `schema` is supplied the parsed object is returned.
`model` to override that agent's model, `label` for the output artifact
id, and `schema` to request structured JSON output; when `schema` is
supplied the parsed object is returned. Share background by writing a
local:// file and referencing it in the prompt.
"""
args = {"prompt": prompt}
if agent_type is not None:
args["agentType"] = agent_type
if model is not None:
args["model"] = model
if context is not None:
args["context"] = context
if label is not None:
args["label"] = label
if schema is not None: