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:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user