@sema-agent/core 1.449.0 → 1.451.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -892,6 +892,7 @@ export async function prepareTask(spec, deps, sessions, resume, _memorySelector,
|
|
|
892
892
|
parentModel: () => harnessRef.current?.getModel(),
|
|
893
893
|
...(spec.getApiKeyAndHeaders !== undefined ? { parentGetApiKeyAndHeaders: spec.getApiKeyAndHeaders } : {}),
|
|
894
894
|
principal: spec.principal,
|
|
895
|
+
oneShot: spec.oneShot,
|
|
895
896
|
workflowDepth: internals?.workflowDepth,
|
|
896
897
|
parentCwd: taskRootPath,
|
|
897
898
|
parentThinking: () => harnessRef.current?.getThinkingLevel() ?? thinking,
|
package/dist/core/types.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export interface RunWorkflowToolDeps {
|
|
|
78
78
|
sizeGuideline?: WorkflowSizeGuideline;
|
|
79
79
|
sourceTaskId?: string;
|
|
80
80
|
principal?: string;
|
|
81
|
+
oneShot?: boolean;
|
|
81
82
|
workflowDepth?: number;
|
|
82
83
|
parentCwd?: string;
|
|
83
84
|
parentThinking?: () => import("../core/types.js").TaskSpec["thinking"];
|
|
@@ -524,10 +524,16 @@ export async function createRunWorkflowTool(d) {
|
|
|
524
524
|
...(persistedScriptPath !== undefined ? { scriptPath: persistedScriptPath } : {}),
|
|
525
525
|
note: (() => {
|
|
526
526
|
const pollExpr = d.taskRegistry ? `TaskOutput({ task_id: "${runId}" })` : undefined;
|
|
527
|
+
const blockingPollExpr = d.taskRegistry ? `TaskOutput({ task_id: "${runId}", block: true })` : undefined;
|
|
527
528
|
const journalRef = d.journalStore?.locator?.(runId, taskScope ?? d.scope ?? "");
|
|
528
529
|
const carries = pollExpr
|
|
529
530
|
? ` A terminal ${pollExpr} reply carries its result AND per-agent rows — read them${journalRef !== undefined ? ` (full journal: ${journalRef})` : ""} before assuming an empty or unexpected result.`
|
|
530
531
|
: "";
|
|
532
|
+
if (d.oneShot === true) {
|
|
533
|
+
return blockingPollExpr
|
|
534
|
+
? `This is a ONE-SHOT submission (e.g. headless \`-p\`) — there is no later turn for a background notification to land in, so do NOT end your turn expecting one. Actively wait instead: ${blockingPollExpr}. If it is still running after the wait, wait again (bounded) rather than ending the turn, or write out your best available answer now if you are near your own time budget.${carries}`
|
|
535
|
+
: "This is a one-shot submission (e.g. headless `-p`) and no poll path is available — the workflow's outcome may not be recoverable after this turn ends.";
|
|
536
|
+
}
|
|
531
537
|
if (d.notifier) {
|
|
532
538
|
return `The workflow runs asynchronously. You will be NOTIFIED when it completes (the notification carries the result). End your turn and wait — do not poll unless the user asks for progress.${carries}`;
|
|
533
539
|
}
|
package/dist/tools/fs/index.js
CHANGED
|
@@ -1028,7 +1028,7 @@ export function makeGrepTool(env, rootCanonical, additionalRoots) {
|
|
|
1028
1028
|
'- Filter with `glob` (e.g. "**/*.tsx") or `type` (e.g. "js", "py", "rust").\n' +
|
|
1029
1029
|
'- `output_mode`: "content" (matching lines), "files_with_matches" (paths only, default), or "count".\n' +
|
|
1030
1030
|
"- `multiline: true` for patterns that span lines.\n" +
|
|
1031
|
-
"- Uses ripgrep when available (respects .gitignore, skips binary
|
|
1031
|
+
"- Uses ripgrep when available (respects .gitignore, skips binary files and VCS directories), otherwise a JS fallback that skips node_modules/build/… and parses .gitignore. Hidden files/directories ARE searched.\n" +
|
|
1032
1032
|
"- Use Agent tool for open-ended searches requiring multiple rounds",
|
|
1033
1033
|
parameters: Type.Object({
|
|
1034
1034
|
pattern: Type.String({ description: "The regular expression pattern to search for in file contents" }),
|
package/dist/tools/fs/search.js
CHANGED
|
@@ -5,10 +5,11 @@ const WALK_MAX_DEPTH = 32;
|
|
|
5
5
|
const GREP_DEFAULT_CAP = 250;
|
|
6
6
|
const FILE_MAX_BYTES = 5 * 1024 * 1024;
|
|
7
7
|
export const DEFAULT_IGNORE_DIRS = new Set([
|
|
8
|
-
"node_modules", ".git", ".hg", ".svn", "
|
|
9
|
-
".next", ".nuxt", ".gradle", ".idea", ".vscode", "Pods", ".venv", "venv",
|
|
10
|
-
".pytest_cache", "coverage", ".turbo", ".cache", "vendor",
|
|
8
|
+
"node_modules", ".git", ".hg", ".svn", ".bzr", ".jj", ".sl", "build", "dist", "out", "target",
|
|
9
|
+
".dart_tool", ".pub-cache", ".next", ".nuxt", ".gradle", ".idea", ".vscode", "Pods", ".venv", "venv",
|
|
10
|
+
"__pycache__", ".mypy_cache", ".pytest_cache", "coverage", ".turbo", ".cache", "vendor",
|
|
11
11
|
]);
|
|
12
|
+
const VCS_DIRS = [".git", ".svn", ".hg", ".bzr", ".jj", ".sl"];
|
|
12
13
|
const TYPE_GLOBS = {
|
|
13
14
|
js: "*.{js,jsx,mjs,cjs}",
|
|
14
15
|
ts: "*.{ts,tsx,mts,cts}",
|
|
@@ -152,8 +153,6 @@ export async function buildIgnore(env, root, signal) {
|
|
|
152
153
|
const base = basename(rel);
|
|
153
154
|
if (isDir && DEFAULT_IGNORE_DIRS.has(base))
|
|
154
155
|
return true;
|
|
155
|
-
if (base.startsWith(".") && base !== ".")
|
|
156
|
-
return true;
|
|
157
156
|
if (gi && gi(rel, isDir))
|
|
158
157
|
return true;
|
|
159
158
|
return false;
|
|
@@ -945,7 +944,9 @@ async function jsGrepFallback(env, root, p, signal, reason) {
|
|
|
945
944
|
}
|
|
946
945
|
export async function rgGrepDetailed(env, root, p, signal) {
|
|
947
946
|
const mode = p.output_mode ?? "files_with_matches";
|
|
948
|
-
const flags = ["--no-messages", "--no-require-git"];
|
|
947
|
+
const flags = ["--no-messages", "--no-require-git", "--hidden"];
|
|
948
|
+
for (const d of VCS_DIRS)
|
|
949
|
+
flags.push("--glob", `!${d}`);
|
|
949
950
|
flags.push("--max-columns", "500", "--max-columns-preview");
|
|
950
951
|
if (p.ignore_case)
|
|
951
952
|
flags.push("-i");
|