a92d2ce989
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.
247 lines
9.0 KiB
Plaintext
247 lines
9.0 KiB
Plaintext
if (!globalThis.__omp_js_prelude_loaded__) {
|
|
globalThis.__omp_js_prelude_loaded__ = true;
|
|
|
|
const isPlainObject = value => value !== null && typeof value === "object" && !Array.isArray(value);
|
|
const optionsArg = (name, value, rest, example) => {
|
|
if (rest.length > 0) {
|
|
throw new TypeError(
|
|
`${name}() takes options as a single trailing object literal, not positional arguments (got ${rest.length + 1} extra args). Pass them as ${name}(..., ${example}).`,
|
|
);
|
|
}
|
|
if (value === undefined || value === null) return {};
|
|
if (!isPlainObject(value)) {
|
|
const kind = Array.isArray(value) ? "an array" : typeof value;
|
|
throw new TypeError(
|
|
`${name}() options must be a trailing object literal like ${example}, not ${kind}. JS helpers never take positional options.`,
|
|
);
|
|
}
|
|
return value;
|
|
};
|
|
const callHelper = (name, ...args) => globalThis.__omp_helpers__[name](...args);
|
|
|
|
const read = (path, opts, ...rest) => callHelper("read", path, optionsArg("read", opts, rest, "{ offset, limit }"));
|
|
const write = async (path, data) => callHelper("writeFile", path, data);
|
|
const append = (path, content) => callHelper("append", path, content);
|
|
const sort = (text, opts, ...rest) => callHelper("sortText", text, optionsArg("sort", opts, rest, "{ reverse, unique }"));
|
|
const uniq = (text, opts, ...rest) => callHelper("uniqText", text, optionsArg("uniq", opts, rest, "{ count }"));
|
|
const counter = (items, opts, ...rest) =>
|
|
callHelper("counter", items, optionsArg("counter", opts, rest, "{ limit, reverse }"));
|
|
const diff = (a, b) => callHelper("diff", a, b);
|
|
const tree = (path = ".", opts, ...rest) => callHelper("tree", path, optionsArg("tree", opts, rest, "{ maxDepth, showHidden }"));
|
|
const env = (key, value) => callHelper("env", key, value);
|
|
|
|
const tool = new Proxy(
|
|
{},
|
|
{
|
|
get(_target, prop) {
|
|
if (typeof prop !== "string") return undefined;
|
|
return async args => globalThis.__omp_call_tool__(prop, args ?? {});
|
|
},
|
|
},
|
|
);
|
|
|
|
const output = async (...args) => {
|
|
let opts = {};
|
|
let ids = args;
|
|
if (args.length > 0) {
|
|
const last = args.at(-1);
|
|
if (last && typeof last === "object" && !Array.isArray(last)) {
|
|
opts = last;
|
|
ids = args.slice(0, -1);
|
|
}
|
|
}
|
|
const reads = ids.map(id => tool.read({ path: `agent://${id}`, ...opts }));
|
|
const values = await Promise.all(reads);
|
|
return values.length === 1 ? values[0] : values;
|
|
};
|
|
|
|
const hasOwn = (object, key) => Object.prototype.hasOwnProperty.call(object, key);
|
|
|
|
const completion = async (prompt, opts, ...rest) => {
|
|
const o = optionsArg("completion", opts, rest, "{ model, system, schema }");
|
|
const res = await globalThis.__omp_call_tool__("__completion__", { prompt, ...o });
|
|
const text = res && typeof res === "object" ? res.text : res;
|
|
return hasOwn(o, "schema") ? JSON.parse(text) : text;
|
|
};
|
|
|
|
const agent = async (prompt, opts, ...rest) => {
|
|
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;
|
|
};
|
|
|
|
// Pool ceiling mirrors the task tool's `task.maxConcurrency` setting so an
|
|
// eval fan-out runs as wide as a `task` batch would. 0 (and any non-finite
|
|
// reply) means unbounded — run every item at once.
|
|
const __concurrencyLimit = async () => {
|
|
try {
|
|
const r = await globalThis.__omp_call_tool__("__concurrency__", {});
|
|
const n = Math.trunc(Number(r && typeof r === "object" ? r.limit : r));
|
|
return Number.isFinite(n) && n > 0 ? n : 0;
|
|
} catch {
|
|
return 0;
|
|
}
|
|
};
|
|
|
|
const __pool = async (items, fn) => {
|
|
const list = Array.from(items ?? []);
|
|
if (list.length === 0) return [];
|
|
const limit = await __concurrencyLimit();
|
|
const concurrency = limit > 0 ? Math.min(limit, list.length) : list.length;
|
|
const results = new Array(list.length);
|
|
// Barrier semantics (mirrors the Python _pool_map): every item settles
|
|
// before we return or throw, then the lowest-index error propagates.
|
|
// Early-rejecting would orphan in-flight thunks (e.g. live agent()
|
|
// subagents) whose worker-side promises would never be observed.
|
|
const errors = new Map();
|
|
let next = 0;
|
|
const worker = async () => {
|
|
while (true) {
|
|
const index = next++;
|
|
if (index >= list.length) return;
|
|
try {
|
|
results[index] = await fn(list[index], index);
|
|
} catch (error) {
|
|
errors.set(index, error);
|
|
}
|
|
}
|
|
};
|
|
await Promise.all(Array.from({ length: concurrency }, () => worker()));
|
|
if (errors.size > 0) throw errors.get(Math.min(...errors.keys()));
|
|
return results;
|
|
};
|
|
|
|
const parallel = async thunks =>
|
|
__pool(thunks, (thunk, index) => {
|
|
if (typeof thunk !== "function") throw new TypeError("parallel() expects an iterable of functions");
|
|
return thunk(index);
|
|
});
|
|
|
|
const pipeline = async (items, ...stages) => {
|
|
let current = Array.from(items ?? []);
|
|
for (const stage of stages) {
|
|
if (typeof stage !== "function") throw new TypeError("pipeline() stages must be functions");
|
|
current = await __pool(current, stage);
|
|
}
|
|
return current;
|
|
};
|
|
|
|
const log = message => globalThis.__omp_emit_status__("log", { message: String(message) });
|
|
|
|
const phase = title => {
|
|
globalThis.__omp_phase__ = String(title);
|
|
globalThis.__omp_emit_status__("phase", { title: String(title) });
|
|
};
|
|
|
|
const __budgetSnap = async () => {
|
|
const r = await globalThis.__omp_call_tool__("__budget__", {});
|
|
return r && typeof r === "object" ? r : {};
|
|
};
|
|
|
|
const budget = {
|
|
total: async () => {
|
|
const s = await __budgetSnap();
|
|
return s.total ?? null;
|
|
},
|
|
spent: async () => Number((await __budgetSnap()).spent ?? 0),
|
|
remaining: async () => {
|
|
const s = await __budgetSnap();
|
|
return s.total == null ? Infinity : Math.max(0, Number(s.total) - Number(s.spent ?? 0));
|
|
},
|
|
hard: async () => Boolean((await __budgetSnap()).hard),
|
|
};
|
|
|
|
const display = value => {
|
|
globalThis.__omp_display__(value);
|
|
};
|
|
|
|
const formatArgs = args => args.map(arg => (typeof arg === "string" ? arg : arg));
|
|
|
|
const consoleTimers = new Map();
|
|
const consoleCounts = new Map();
|
|
const consoleBridge = {
|
|
log: (...args) => globalThis.__omp_log__("log", ...formatArgs(args)),
|
|
info: (...args) => globalThis.__omp_log__("info", ...formatArgs(args)),
|
|
warn: (...args) => globalThis.__omp_log__("warn", ...formatArgs(args)),
|
|
error: (...args) => globalThis.__omp_log__("error", ...formatArgs(args)),
|
|
debug: (...args) => globalThis.__omp_log__("debug", ...formatArgs(args)),
|
|
table: (data, columns) =>
|
|
columns === undefined
|
|
? globalThis.__omp_table__(data)
|
|
: globalThis.__omp_table__(data, columns),
|
|
dir: (value, _options) => globalThis.__omp_log__("log", value),
|
|
dirxml: (...args) => globalThis.__omp_log__("log", ...formatArgs(args)),
|
|
trace: (...args) => {
|
|
const stack = (new Error().stack ?? "").split("\n").slice(2).join("\n");
|
|
globalThis.__omp_log__("log", args.length > 0 ? `Trace: ${formatArgs(args).join(" ")}` : "Trace", `\n${stack}`);
|
|
},
|
|
assert: (condition, ...args) => {
|
|
if (condition) return;
|
|
if (args.length > 0) globalThis.__omp_log__("error", "Assertion failed:", ...formatArgs(args));
|
|
else globalThis.__omp_log__("error", "Assertion failed");
|
|
},
|
|
group: (...args) => {
|
|
if (args.length > 0) globalThis.__omp_log__("log", ...formatArgs(args));
|
|
},
|
|
groupCollapsed: (...args) => {
|
|
if (args.length > 0) globalThis.__omp_log__("log", ...formatArgs(args));
|
|
},
|
|
groupEnd: () => {},
|
|
time: label => {
|
|
consoleTimers.set(String(label ?? "default"), Date.now());
|
|
},
|
|
timeLog: (label, ...args) => {
|
|
const key = String(label ?? "default");
|
|
const start = consoleTimers.get(key);
|
|
if (start === undefined) {
|
|
globalThis.__omp_log__("warn", `Timer '${key}' does not exist`);
|
|
return;
|
|
}
|
|
globalThis.__omp_log__("log", `${key}: ${Date.now() - start}ms`, ...formatArgs(args));
|
|
},
|
|
timeEnd: label => {
|
|
const key = String(label ?? "default");
|
|
const start = consoleTimers.get(key);
|
|
if (start === undefined) {
|
|
globalThis.__omp_log__("warn", `Timer '${key}' does not exist`);
|
|
return;
|
|
}
|
|
consoleTimers.delete(key);
|
|
globalThis.__omp_log__("log", `${key}: ${Date.now() - start}ms`);
|
|
},
|
|
count: label => {
|
|
const key = String(label ?? "default");
|
|
const next = (consoleCounts.get(key) ?? 0) + 1;
|
|
consoleCounts.set(key, next);
|
|
globalThis.__omp_log__("log", `${key}: ${next}`);
|
|
},
|
|
countReset: label => {
|
|
consoleCounts.delete(String(label ?? "default"));
|
|
},
|
|
};
|
|
|
|
globalThis.console = consoleBridge;
|
|
globalThis.print = consoleBridge.log;
|
|
globalThis.display = display;
|
|
globalThis.tool = tool;
|
|
globalThis.completion = completion;
|
|
globalThis.output = output;
|
|
globalThis.agent = agent;
|
|
globalThis.parallel = parallel;
|
|
globalThis.pipeline = pipeline;
|
|
globalThis.log = log;
|
|
globalThis.phase = phase;
|
|
globalThis.budget = budget;
|
|
globalThis.__pool = __pool;
|
|
globalThis.read = read;
|
|
globalThis.write = write;
|
|
globalThis.append = append;
|
|
globalThis.sort = sort;
|
|
globalThis.uniq = uniq;
|
|
globalThis.counter = counter;
|
|
globalThis.diff = diff;
|
|
globalThis.tree = tree;
|
|
globalThis.env = env;
|
|
}
|