agentv 0.5.0 → 0.5.1
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.
- package/dist/{chunk-THVRLL37.js → chunk-HPH4YWGU.js} +1235 -1173
- package/dist/chunk-HPH4YWGU.js.map +1 -0
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/dist/templates/.env.template +35 -0
- package/dist/templates/agentv/.env.template +23 -0
- package/dist/templates/agentv/config.yaml +16 -0
- package/dist/templates/agentv/targets.yaml +74 -0
- package/dist/templates/{eval-build.prompt.md → github/prompts/eval-build.prompt.md} +1 -0
- package/package.json +2 -2
- package/dist/chunk-THVRLL37.js.map +0 -1
- /package/dist/templates/{config-schema.json → github/contexts/config-schema.json} +0 -0
- /package/dist/templates/{eval-schema.json → github/contexts/eval-schema.json} +0 -0
|
@@ -5039,6 +5039,13 @@ var ba = new Error("Agent definition is the prompt you give to the LLM for the a
|
|
|
5039
5039
|
import { exec as execWithCallback } from "node:child_process";
|
|
5040
5040
|
import path22 from "node:path";
|
|
5041
5041
|
import { promisify as promisify2 } from "node:util";
|
|
5042
|
+
import { exec as execCallback, spawn as spawn2 } from "node:child_process";
|
|
5043
|
+
import { constants as constants22 } from "node:fs";
|
|
5044
|
+
import { access as access22, copyFile as copyFile2, mkdtemp, mkdir as mkdir3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
5045
|
+
import { tmpdir } from "node:os";
|
|
5046
|
+
import path42 from "node:path";
|
|
5047
|
+
import { promisify as promisify22 } from "node:util";
|
|
5048
|
+
import path32 from "node:path";
|
|
5042
5049
|
|
|
5043
5050
|
// ../../node_modules/.pnpm/zod@3.25.76/node_modules/zod/v3/external.js
|
|
5044
5051
|
var external_exports = {};
|
|
@@ -9083,7 +9090,7 @@ var NEVER = INVALID;
|
|
|
9083
9090
|
|
|
9084
9091
|
// ../../packages/core/dist/index.js
|
|
9085
9092
|
import { readFile as readFile22 } from "node:fs/promises";
|
|
9086
|
-
import
|
|
9093
|
+
import path52 from "node:path";
|
|
9087
9094
|
|
|
9088
9095
|
// ../../node_modules/.pnpm/subagent@0.4.6/node_modules/subagent/dist/vscode/agentDispatch.js
|
|
9089
9096
|
import { exec, spawn } from "child_process";
|
|
@@ -11021,13 +11028,6 @@ async function provisionSubagents(options) {
|
|
|
11021
11028
|
}
|
|
11022
11029
|
|
|
11023
11030
|
// ../../packages/core/dist/index.js
|
|
11024
|
-
import { exec as execCallback, spawn as spawn2 } from "node:child_process";
|
|
11025
|
-
import { constants as constants22 } from "node:fs";
|
|
11026
|
-
import { access as access22, copyFile as copyFile2, mkdtemp, mkdir as mkdir3, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
11027
|
-
import { tmpdir } from "node:os";
|
|
11028
|
-
import path52 from "node:path";
|
|
11029
|
-
import { promisify as promisify22 } from "node:util";
|
|
11030
|
-
import path42 from "node:path";
|
|
11031
11031
|
import { constants as constants32 } from "node:fs";
|
|
11032
11032
|
import { access as access32, readFile as readFile3 } from "node:fs/promises";
|
|
11033
11033
|
import path62 from "node:path";
|
|
@@ -11960,1301 +11960,1301 @@ function formatTimeoutSuffix(timeoutMs) {
|
|
|
11960
11960
|
const seconds = Math.ceil(timeoutMs / 1e3);
|
|
11961
11961
|
return ` after ${seconds}s`;
|
|
11962
11962
|
}
|
|
11963
|
-
|
|
11964
|
-
|
|
11963
|
+
function buildPromptDocument(request, inputFiles, options) {
|
|
11964
|
+
const parts = [];
|
|
11965
|
+
const guidelineFiles = collectGuidelineFiles(
|
|
11966
|
+
inputFiles,
|
|
11967
|
+
options?.guidelinePatterns ?? request.guideline_patterns,
|
|
11968
|
+
options?.guidelineOverrides
|
|
11969
|
+
);
|
|
11970
|
+
const inputFilesList = collectInputFiles(inputFiles);
|
|
11971
|
+
const nonGuidelineInputFiles = inputFilesList.filter(
|
|
11972
|
+
(file) => !guidelineFiles.includes(file)
|
|
11973
|
+
);
|
|
11974
|
+
const prereadBlock = buildMandatoryPrereadBlock(guidelineFiles, nonGuidelineInputFiles);
|
|
11975
|
+
if (prereadBlock.length > 0) {
|
|
11976
|
+
parts.push("\n", prereadBlock);
|
|
11977
|
+
}
|
|
11978
|
+
parts.push("\n[[ ## user_query ## ]]\n", request.prompt.trim());
|
|
11979
|
+
return parts.join("\n").trim();
|
|
11980
|
+
}
|
|
11981
|
+
function normalizeInputFiles2(inputFiles) {
|
|
11982
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
11983
|
+
return void 0;
|
|
11984
|
+
}
|
|
11985
|
+
const deduped = /* @__PURE__ */ new Map();
|
|
11986
|
+
for (const inputFile of inputFiles) {
|
|
11987
|
+
const absolutePath = path32.resolve(inputFile);
|
|
11988
|
+
if (!deduped.has(absolutePath)) {
|
|
11989
|
+
deduped.set(absolutePath, absolutePath);
|
|
11990
|
+
}
|
|
11991
|
+
}
|
|
11992
|
+
return Array.from(deduped.values());
|
|
11993
|
+
}
|
|
11994
|
+
function collectGuidelineFiles(inputFiles, guidelinePatterns, overrides) {
|
|
11995
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
11996
|
+
return [];
|
|
11997
|
+
}
|
|
11998
|
+
const unique = /* @__PURE__ */ new Map();
|
|
11999
|
+
for (const inputFile of inputFiles) {
|
|
12000
|
+
const absolutePath = path32.resolve(inputFile);
|
|
12001
|
+
if (overrides?.has(absolutePath)) {
|
|
12002
|
+
if (!unique.has(absolutePath)) {
|
|
12003
|
+
unique.set(absolutePath, absolutePath);
|
|
12004
|
+
}
|
|
12005
|
+
continue;
|
|
12006
|
+
}
|
|
12007
|
+
const normalized = absolutePath.split(path32.sep).join("/");
|
|
12008
|
+
if (isGuidelineFile(normalized, guidelinePatterns)) {
|
|
12009
|
+
if (!unique.has(absolutePath)) {
|
|
12010
|
+
unique.set(absolutePath, absolutePath);
|
|
12011
|
+
}
|
|
12012
|
+
}
|
|
12013
|
+
}
|
|
12014
|
+
return Array.from(unique.values());
|
|
12015
|
+
}
|
|
12016
|
+
function collectInputFiles(inputFiles) {
|
|
12017
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
12018
|
+
return [];
|
|
12019
|
+
}
|
|
12020
|
+
const unique = /* @__PURE__ */ new Map();
|
|
12021
|
+
for (const inputFile of inputFiles) {
|
|
12022
|
+
const absolutePath = path32.resolve(inputFile);
|
|
12023
|
+
if (!unique.has(absolutePath)) {
|
|
12024
|
+
unique.set(absolutePath, absolutePath);
|
|
12025
|
+
}
|
|
12026
|
+
}
|
|
12027
|
+
return Array.from(unique.values());
|
|
12028
|
+
}
|
|
12029
|
+
function buildMandatoryPrereadBlock(guidelineFiles, inputFiles) {
|
|
12030
|
+
if (guidelineFiles.length === 0 && inputFiles.length === 0) {
|
|
12031
|
+
return "";
|
|
12032
|
+
}
|
|
12033
|
+
const buildList = (files) => files.map((absolutePath) => {
|
|
12034
|
+
const fileName = path32.basename(absolutePath);
|
|
12035
|
+
const fileUri = pathToFileUri2(absolutePath);
|
|
12036
|
+
return `* [${fileName}](${fileUri})`;
|
|
12037
|
+
});
|
|
12038
|
+
const sections = [];
|
|
12039
|
+
if (guidelineFiles.length > 0) {
|
|
12040
|
+
sections.push(`Read all guideline files:
|
|
12041
|
+
${buildList(guidelineFiles).join("\n")}.`);
|
|
12042
|
+
}
|
|
12043
|
+
if (inputFiles.length > 0) {
|
|
12044
|
+
sections.push(`Read all input files:
|
|
12045
|
+
${buildList(inputFiles).join("\n")}.`);
|
|
12046
|
+
}
|
|
12047
|
+
sections.push(
|
|
12048
|
+
"If any file is missing, fail with ERROR: missing-file <filename> and stop.",
|
|
12049
|
+
"Then apply system_instructions on the user query below."
|
|
12050
|
+
);
|
|
12051
|
+
return sections.join("\n");
|
|
12052
|
+
}
|
|
12053
|
+
function pathToFileUri2(filePath) {
|
|
12054
|
+
const absolutePath = path32.isAbsolute(filePath) ? filePath : path32.resolve(filePath);
|
|
12055
|
+
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
12056
|
+
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
12057
|
+
return `file:///${normalizedPath}`;
|
|
12058
|
+
}
|
|
12059
|
+
return `file://${normalizedPath}`;
|
|
12060
|
+
}
|
|
12061
|
+
var execAsync22 = promisify22(execCallback);
|
|
12062
|
+
var WORKSPACE_PREFIX = "agentv-codex-";
|
|
12063
|
+
var PROMPT_FILENAME = "prompt.md";
|
|
12064
|
+
var FILES_DIR = "files";
|
|
12065
|
+
var JSONL_TYPE_ITEM_COMPLETED = "item.completed";
|
|
12066
|
+
var CodexProvider = class {
|
|
11965
12067
|
id;
|
|
11966
|
-
kind = "
|
|
12068
|
+
kind = "codex";
|
|
11967
12069
|
targetName;
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
11971
|
-
|
|
11972
|
-
|
|
11973
|
-
|
|
12070
|
+
supportsBatch = false;
|
|
12071
|
+
config;
|
|
12072
|
+
runCodex;
|
|
12073
|
+
environmentCheck;
|
|
12074
|
+
resolvedExecutable;
|
|
12075
|
+
constructor(targetName, config, runner = defaultCodexRunner) {
|
|
12076
|
+
this.id = `codex:${targetName}`;
|
|
11974
12077
|
this.targetName = targetName;
|
|
11975
|
-
this.
|
|
11976
|
-
this.
|
|
11977
|
-
this.delayMinMs = config.delayMinMs ?? 0;
|
|
11978
|
-
this.delayMaxMs = config.delayMaxMs ?? 0;
|
|
12078
|
+
this.config = config;
|
|
12079
|
+
this.runCodex = runner;
|
|
11979
12080
|
}
|
|
11980
12081
|
async invoke(request) {
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
12082
|
+
if (request.signal?.aborted) {
|
|
12083
|
+
throw new Error("Codex provider request was aborted before execution");
|
|
11984
12084
|
}
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
11988
|
-
|
|
11989
|
-
|
|
12085
|
+
await this.ensureEnvironmentReady();
|
|
12086
|
+
const inputFiles = normalizeInputFiles2(request.inputFiles);
|
|
12087
|
+
const originalGuidelines = new Set(
|
|
12088
|
+
collectGuidelineFiles(inputFiles, request.guideline_patterns).map((file) => path42.resolve(file))
|
|
12089
|
+
);
|
|
12090
|
+
const workspaceRoot = await this.createWorkspace();
|
|
12091
|
+
try {
|
|
12092
|
+
const { mirroredInputFiles, guidelineMirrors } = await this.mirrorInputFiles(
|
|
12093
|
+
inputFiles,
|
|
12094
|
+
workspaceRoot,
|
|
12095
|
+
originalGuidelines
|
|
12096
|
+
);
|
|
12097
|
+
const promptContent = buildPromptDocument(request, mirroredInputFiles, {
|
|
12098
|
+
guidelinePatterns: request.guideline_patterns,
|
|
12099
|
+
guidelineOverrides: guidelineMirrors
|
|
12100
|
+
});
|
|
12101
|
+
const promptFile = path42.join(workspaceRoot, PROMPT_FILENAME);
|
|
12102
|
+
await writeFile3(promptFile, promptContent, "utf8");
|
|
12103
|
+
const args = this.buildCodexArgs();
|
|
12104
|
+
const cwd = this.resolveCwd(workspaceRoot);
|
|
12105
|
+
const result = await this.executeCodex(args, cwd, promptContent, request.signal);
|
|
12106
|
+
if (result.timedOut) {
|
|
12107
|
+
throw new Error(
|
|
12108
|
+
`Codex CLI timed out${formatTimeoutSuffix2(this.config.timeoutMs ?? void 0)}`
|
|
12109
|
+
);
|
|
11990
12110
|
}
|
|
11991
|
-
|
|
12111
|
+
if (result.exitCode !== 0) {
|
|
12112
|
+
const detail = pickDetail(result.stderr, result.stdout);
|
|
12113
|
+
const prefix = `Codex CLI exited with code ${result.exitCode}`;
|
|
12114
|
+
throw new Error(detail ? `${prefix}: ${detail}` : prefix);
|
|
12115
|
+
}
|
|
12116
|
+
const parsed = parseCodexJson(result.stdout);
|
|
12117
|
+
const assistantText = extractAssistantText(parsed);
|
|
12118
|
+
return {
|
|
12119
|
+
text: assistantText,
|
|
12120
|
+
raw: {
|
|
12121
|
+
response: parsed,
|
|
12122
|
+
stdout: result.stdout,
|
|
12123
|
+
stderr: result.stderr,
|
|
12124
|
+
exitCode: result.exitCode,
|
|
12125
|
+
args,
|
|
12126
|
+
executable: this.resolvedExecutable ?? this.config.executable,
|
|
12127
|
+
promptFile,
|
|
12128
|
+
workspace: workspaceRoot,
|
|
12129
|
+
inputFiles: mirroredInputFiles
|
|
12130
|
+
}
|
|
12131
|
+
};
|
|
12132
|
+
} finally {
|
|
12133
|
+
await this.cleanupWorkspace(workspaceRoot);
|
|
12134
|
+
}
|
|
11992
12135
|
}
|
|
11993
|
-
|
|
11994
|
-
if (this.
|
|
11995
|
-
|
|
11996
|
-
const max = Math.max(min, this.delayMaxMs);
|
|
11997
|
-
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
12136
|
+
async ensureEnvironmentReady() {
|
|
12137
|
+
if (!this.environmentCheck) {
|
|
12138
|
+
this.environmentCheck = this.validateEnvironment();
|
|
11998
12139
|
}
|
|
11999
|
-
|
|
12140
|
+
await this.environmentCheck;
|
|
12000
12141
|
}
|
|
12001
|
-
|
|
12002
|
-
|
|
12003
|
-
var BASE_TARGET_SCHEMA = external_exports.object({
|
|
12004
|
-
name: external_exports.string().min(1, "target name is required"),
|
|
12005
|
-
provider: external_exports.string().min(1, "provider is required"),
|
|
12006
|
-
settings: external_exports.record(external_exports.unknown()).optional(),
|
|
12007
|
-
judge_target: external_exports.string().optional(),
|
|
12008
|
-
workers: external_exports.number().int().min(1).optional()
|
|
12009
|
-
});
|
|
12010
|
-
var DEFAULT_AZURE_API_VERSION = "2024-10-01-preview";
|
|
12011
|
-
function normalizeAzureApiVersion(value) {
|
|
12012
|
-
if (!value) {
|
|
12013
|
-
return DEFAULT_AZURE_API_VERSION;
|
|
12142
|
+
async validateEnvironment() {
|
|
12143
|
+
this.resolvedExecutable = await locateExecutable(this.config.executable);
|
|
12014
12144
|
}
|
|
12015
|
-
|
|
12016
|
-
|
|
12017
|
-
|
|
12145
|
+
resolveCwd(workspaceRoot) {
|
|
12146
|
+
if (!this.config.cwd) {
|
|
12147
|
+
return workspaceRoot;
|
|
12148
|
+
}
|
|
12149
|
+
return path42.resolve(this.config.cwd);
|
|
12018
12150
|
}
|
|
12019
|
-
|
|
12020
|
-
|
|
12021
|
-
|
|
12022
|
-
|
|
12023
|
-
|
|
12024
|
-
|
|
12025
|
-
|
|
12026
|
-
|
|
12027
|
-
)
|
|
12028
|
-
|
|
12029
|
-
|
|
12030
|
-
|
|
12031
|
-
|
|
12032
|
-
|
|
12033
|
-
|
|
12034
|
-
|
|
12035
|
-
|
|
12036
|
-
|
|
12037
|
-
|
|
12038
|
-
|
|
12039
|
-
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
|
|
12043
|
-
|
|
12044
|
-
|
|
12045
|
-
|
|
12046
|
-
|
|
12047
|
-
|
|
12048
|
-
|
|
12049
|
-
|
|
12050
|
-
case "google-gemini":
|
|
12051
|
-
return {
|
|
12052
|
-
kind: "gemini",
|
|
12053
|
-
name: parsed.name,
|
|
12054
|
-
judgeTarget: parsed.judge_target,
|
|
12055
|
-
workers: parsed.workers,
|
|
12056
|
-
providerBatching,
|
|
12057
|
-
config: resolveGeminiConfig(parsed, env)
|
|
12058
|
-
};
|
|
12059
|
-
case "codex":
|
|
12060
|
-
case "codex-cli":
|
|
12061
|
-
return {
|
|
12062
|
-
kind: "codex",
|
|
12063
|
-
name: parsed.name,
|
|
12064
|
-
judgeTarget: parsed.judge_target,
|
|
12065
|
-
workers: parsed.workers,
|
|
12066
|
-
providerBatching,
|
|
12067
|
-
config: resolveCodexConfig(parsed, env)
|
|
12068
|
-
};
|
|
12069
|
-
case "mock":
|
|
12070
|
-
return {
|
|
12071
|
-
kind: "mock",
|
|
12072
|
-
name: parsed.name,
|
|
12073
|
-
judgeTarget: parsed.judge_target,
|
|
12074
|
-
workers: parsed.workers,
|
|
12075
|
-
providerBatching,
|
|
12076
|
-
config: resolveMockConfig(parsed)
|
|
12077
|
-
};
|
|
12078
|
-
case "vscode":
|
|
12079
|
-
case "vscode-insiders":
|
|
12080
|
-
return {
|
|
12081
|
-
kind: provider,
|
|
12082
|
-
name: parsed.name,
|
|
12083
|
-
judgeTarget: parsed.judge_target,
|
|
12084
|
-
workers: parsed.workers,
|
|
12085
|
-
providerBatching,
|
|
12086
|
-
config: resolveVSCodeConfig(parsed, env, provider === "vscode-insiders")
|
|
12087
|
-
};
|
|
12088
|
-
case "cli":
|
|
12151
|
+
buildCodexArgs() {
|
|
12152
|
+
const args = ["--ask-for-approval", "never", "exec", "--json", "--color", "never", "--skip-git-repo-check"];
|
|
12153
|
+
if (this.config.args && this.config.args.length > 0) {
|
|
12154
|
+
args.push(...this.config.args);
|
|
12155
|
+
}
|
|
12156
|
+
args.push("-");
|
|
12157
|
+
return args;
|
|
12158
|
+
}
|
|
12159
|
+
async executeCodex(args, cwd, promptContent, signal) {
|
|
12160
|
+
try {
|
|
12161
|
+
return await this.runCodex({
|
|
12162
|
+
executable: this.resolvedExecutable ?? this.config.executable,
|
|
12163
|
+
args,
|
|
12164
|
+
cwd,
|
|
12165
|
+
prompt: promptContent,
|
|
12166
|
+
timeoutMs: this.config.timeoutMs,
|
|
12167
|
+
env: process.env,
|
|
12168
|
+
signal
|
|
12169
|
+
});
|
|
12170
|
+
} catch (error) {
|
|
12171
|
+
const err = error;
|
|
12172
|
+
if (err.code === "ENOENT") {
|
|
12173
|
+
throw new Error(
|
|
12174
|
+
`Codex executable '${this.config.executable}' was not found. Update the target settings.executable or add it to PATH.`
|
|
12175
|
+
);
|
|
12176
|
+
}
|
|
12177
|
+
throw error;
|
|
12178
|
+
}
|
|
12179
|
+
}
|
|
12180
|
+
async mirrorInputFiles(inputFiles, workspaceRoot, guidelineOriginals) {
|
|
12181
|
+
if (!inputFiles || inputFiles.length === 0) {
|
|
12089
12182
|
return {
|
|
12090
|
-
|
|
12091
|
-
|
|
12092
|
-
judgeTarget: parsed.judge_target,
|
|
12093
|
-
workers: parsed.workers,
|
|
12094
|
-
providerBatching,
|
|
12095
|
-
config: resolveCliConfig(parsed, env)
|
|
12183
|
+
mirroredInputFiles: void 0,
|
|
12184
|
+
guidelineMirrors: /* @__PURE__ */ new Set()
|
|
12096
12185
|
};
|
|
12097
|
-
|
|
12098
|
-
|
|
12186
|
+
}
|
|
12187
|
+
const filesRoot = path42.join(workspaceRoot, FILES_DIR);
|
|
12188
|
+
await mkdir3(filesRoot, { recursive: true });
|
|
12189
|
+
const mirrored = [];
|
|
12190
|
+
const guidelineMirrors = /* @__PURE__ */ new Set();
|
|
12191
|
+
const nameCounts = /* @__PURE__ */ new Map();
|
|
12192
|
+
for (const inputFile of inputFiles) {
|
|
12193
|
+
const absoluteSource = path42.resolve(inputFile);
|
|
12194
|
+
const baseName = path42.basename(absoluteSource);
|
|
12195
|
+
const count = nameCounts.get(baseName) ?? 0;
|
|
12196
|
+
nameCounts.set(baseName, count + 1);
|
|
12197
|
+
const finalName = count === 0 ? baseName : `${baseName}.${count}`;
|
|
12198
|
+
const destination = path42.join(filesRoot, finalName);
|
|
12199
|
+
await copyFile2(absoluteSource, destination);
|
|
12200
|
+
const resolvedDestination = path42.resolve(destination);
|
|
12201
|
+
mirrored.push(resolvedDestination);
|
|
12202
|
+
if (guidelineOriginals.has(absoluteSource)) {
|
|
12203
|
+
guidelineMirrors.add(resolvedDestination);
|
|
12204
|
+
}
|
|
12205
|
+
}
|
|
12206
|
+
return {
|
|
12207
|
+
mirroredInputFiles: mirrored,
|
|
12208
|
+
guidelineMirrors
|
|
12209
|
+
};
|
|
12099
12210
|
}
|
|
12100
|
-
|
|
12101
|
-
|
|
12102
|
-
const settings = target.settings ?? {};
|
|
12103
|
-
const endpointSource = settings.endpoint ?? settings.resource ?? settings.resourceName;
|
|
12104
|
-
const apiKeySource = settings.api_key ?? settings.apiKey;
|
|
12105
|
-
const deploymentSource = settings.deployment ?? settings.deploymentName ?? settings.model;
|
|
12106
|
-
const versionSource = settings.version ?? settings.api_version;
|
|
12107
|
-
const temperatureSource = settings.temperature;
|
|
12108
|
-
const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
|
|
12109
|
-
const resourceName = resolveString(endpointSource, env, `${target.name} endpoint`);
|
|
12110
|
-
const apiKey = resolveString(apiKeySource, env, `${target.name} api key`);
|
|
12111
|
-
const deploymentName = resolveString(deploymentSource, env, `${target.name} deployment`);
|
|
12112
|
-
const version = normalizeAzureApiVersion(
|
|
12113
|
-
resolveOptionalString(versionSource, env, `${target.name} api version`)
|
|
12114
|
-
);
|
|
12115
|
-
const temperature = resolveOptionalNumber(temperatureSource, `${target.name} temperature`);
|
|
12116
|
-
const maxOutputTokens = resolveOptionalNumber(
|
|
12117
|
-
maxTokensSource,
|
|
12118
|
-
`${target.name} max output tokens`
|
|
12119
|
-
);
|
|
12120
|
-
return {
|
|
12121
|
-
resourceName,
|
|
12122
|
-
deploymentName,
|
|
12123
|
-
apiKey,
|
|
12124
|
-
version,
|
|
12125
|
-
temperature,
|
|
12126
|
-
maxOutputTokens
|
|
12127
|
-
};
|
|
12128
|
-
}
|
|
12129
|
-
function resolveAnthropicConfig(target, env) {
|
|
12130
|
-
const settings = target.settings ?? {};
|
|
12131
|
-
const apiKeySource = settings.api_key ?? settings.apiKey;
|
|
12132
|
-
const modelSource = settings.model ?? settings.deployment ?? settings.variant;
|
|
12133
|
-
const temperatureSource = settings.temperature;
|
|
12134
|
-
const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
|
|
12135
|
-
const thinkingBudgetSource = settings.thinking_budget ?? settings.thinkingBudget;
|
|
12136
|
-
const apiKey = resolveString(apiKeySource, env, `${target.name} Anthropic api key`);
|
|
12137
|
-
const model = resolveString(modelSource, env, `${target.name} Anthropic model`);
|
|
12138
|
-
return {
|
|
12139
|
-
apiKey,
|
|
12140
|
-
model,
|
|
12141
|
-
temperature: resolveOptionalNumber(temperatureSource, `${target.name} temperature`),
|
|
12142
|
-
maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`),
|
|
12143
|
-
thinkingBudget: resolveOptionalNumber(thinkingBudgetSource, `${target.name} thinking budget`)
|
|
12144
|
-
};
|
|
12145
|
-
}
|
|
12146
|
-
function resolveGeminiConfig(target, env) {
|
|
12147
|
-
const settings = target.settings ?? {};
|
|
12148
|
-
const apiKeySource = settings.api_key ?? settings.apiKey;
|
|
12149
|
-
const modelSource = settings.model ?? settings.deployment ?? settings.variant;
|
|
12150
|
-
const temperatureSource = settings.temperature;
|
|
12151
|
-
const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
|
|
12152
|
-
const apiKey = resolveString(apiKeySource, env, `${target.name} Google API key`);
|
|
12153
|
-
const model = resolveOptionalString(modelSource, env, `${target.name} Gemini model`, {
|
|
12154
|
-
allowLiteral: true,
|
|
12155
|
-
optionalEnv: true
|
|
12156
|
-
}) ?? "gemini-2.5-flash";
|
|
12157
|
-
return {
|
|
12158
|
-
apiKey,
|
|
12159
|
-
model,
|
|
12160
|
-
temperature: resolveOptionalNumber(temperatureSource, `${target.name} temperature`),
|
|
12161
|
-
maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`)
|
|
12162
|
-
};
|
|
12163
|
-
}
|
|
12164
|
-
function resolveCodexConfig(target, env) {
|
|
12165
|
-
const settings = target.settings ?? {};
|
|
12166
|
-
const executableSource = settings.executable ?? settings.command ?? settings.binary;
|
|
12167
|
-
const argsSource = settings.args ?? settings.arguments;
|
|
12168
|
-
const cwdSource = settings.cwd;
|
|
12169
|
-
const timeoutSource = settings.timeout_seconds ?? settings.timeoutSeconds;
|
|
12170
|
-
const executable = resolveOptionalString(executableSource, env, `${target.name} codex executable`, {
|
|
12171
|
-
allowLiteral: true,
|
|
12172
|
-
optionalEnv: true
|
|
12173
|
-
}) ?? "codex";
|
|
12174
|
-
const args = resolveOptionalStringArray(argsSource, env, `${target.name} codex args`);
|
|
12175
|
-
const cwd = resolveOptionalString(cwdSource, env, `${target.name} codex cwd`, {
|
|
12176
|
-
allowLiteral: true,
|
|
12177
|
-
optionalEnv: true
|
|
12178
|
-
});
|
|
12179
|
-
const timeoutMs = resolveTimeoutMs(timeoutSource, `${target.name} codex timeout`);
|
|
12180
|
-
return {
|
|
12181
|
-
executable,
|
|
12182
|
-
args,
|
|
12183
|
-
cwd,
|
|
12184
|
-
timeoutMs
|
|
12185
|
-
};
|
|
12186
|
-
}
|
|
12187
|
-
function resolveMockConfig(target) {
|
|
12188
|
-
const settings = target.settings ?? {};
|
|
12189
|
-
const response = typeof settings.response === "string" ? settings.response : void 0;
|
|
12190
|
-
return { response };
|
|
12191
|
-
}
|
|
12192
|
-
function resolveVSCodeConfig(target, env, insiders) {
|
|
12193
|
-
const settings = target.settings ?? {};
|
|
12194
|
-
const workspaceTemplateEnvVar = resolveOptionalLiteralString(settings.workspace_template ?? settings.workspaceTemplate);
|
|
12195
|
-
const workspaceTemplate = workspaceTemplateEnvVar ? resolveOptionalString(workspaceTemplateEnvVar, env, `${target.name} workspace template path`, {
|
|
12196
|
-
allowLiteral: false,
|
|
12197
|
-
optionalEnv: true
|
|
12198
|
-
}) : void 0;
|
|
12199
|
-
const commandSource = settings.vscode_cmd ?? settings.command;
|
|
12200
|
-
const waitSource = settings.wait;
|
|
12201
|
-
const dryRunSource = settings.dry_run ?? settings.dryRun;
|
|
12202
|
-
const subagentRootSource = settings.subagent_root ?? settings.subagentRoot;
|
|
12203
|
-
const defaultCommand = insiders ? "code-insiders" : "code";
|
|
12204
|
-
const command = resolveOptionalLiteralString(commandSource) ?? defaultCommand;
|
|
12205
|
-
return {
|
|
12206
|
-
command,
|
|
12207
|
-
waitForResponse: resolveOptionalBoolean(waitSource) ?? true,
|
|
12208
|
-
dryRun: resolveOptionalBoolean(dryRunSource) ?? false,
|
|
12209
|
-
subagentRoot: resolveOptionalString(subagentRootSource, env, `${target.name} subagent root`, {
|
|
12210
|
-
allowLiteral: true,
|
|
12211
|
-
optionalEnv: true
|
|
12212
|
-
}),
|
|
12213
|
-
workspaceTemplate
|
|
12214
|
-
};
|
|
12215
|
-
}
|
|
12216
|
-
function resolveCliConfig(target, env) {
|
|
12217
|
-
const settings = target.settings ?? {};
|
|
12218
|
-
const commandTemplateSource = settings.command_template ?? settings.commandTemplate;
|
|
12219
|
-
const filesFormat = resolveOptionalLiteralString(
|
|
12220
|
-
settings.files_format ?? settings.filesFormat ?? settings.attachments_format ?? settings.attachmentsFormat
|
|
12221
|
-
);
|
|
12222
|
-
const cwd = resolveOptionalString(settings.cwd, env, `${target.name} working directory`, {
|
|
12223
|
-
allowLiteral: true,
|
|
12224
|
-
optionalEnv: true
|
|
12225
|
-
});
|
|
12226
|
-
const envOverrides = resolveEnvOverrides(settings.env, env, target.name);
|
|
12227
|
-
const timeoutMs = resolveTimeoutMs(settings.timeout_seconds ?? settings.timeoutSeconds, `${target.name} timeout`);
|
|
12228
|
-
const healthcheck = resolveCliHealthcheck(settings.healthcheck, env, target.name);
|
|
12229
|
-
const commandTemplate = resolveString(
|
|
12230
|
-
commandTemplateSource,
|
|
12231
|
-
env,
|
|
12232
|
-
`${target.name} CLI command template`,
|
|
12233
|
-
true
|
|
12234
|
-
);
|
|
12235
|
-
assertSupportedCliPlaceholders(commandTemplate, `${target.name} CLI command template`);
|
|
12236
|
-
return {
|
|
12237
|
-
commandTemplate,
|
|
12238
|
-
filesFormat,
|
|
12239
|
-
cwd,
|
|
12240
|
-
env: envOverrides,
|
|
12241
|
-
timeoutMs,
|
|
12242
|
-
healthcheck
|
|
12243
|
-
};
|
|
12244
|
-
}
|
|
12245
|
-
function resolveEnvOverrides(source2, env, targetName) {
|
|
12246
|
-
if (source2 === void 0 || source2 === null) {
|
|
12247
|
-
return void 0;
|
|
12211
|
+
async createWorkspace() {
|
|
12212
|
+
return await mkdtemp(path42.join(tmpdir(), WORKSPACE_PREFIX));
|
|
12248
12213
|
}
|
|
12249
|
-
|
|
12250
|
-
|
|
12214
|
+
async cleanupWorkspace(workspaceRoot) {
|
|
12215
|
+
try {
|
|
12216
|
+
await rm2(workspaceRoot, { recursive: true, force: true });
|
|
12217
|
+
} catch {
|
|
12218
|
+
}
|
|
12251
12219
|
}
|
|
12252
|
-
|
|
12253
|
-
|
|
12254
|
-
|
|
12255
|
-
|
|
12256
|
-
|
|
12220
|
+
};
|
|
12221
|
+
async function locateExecutable(candidate) {
|
|
12222
|
+
const includesPathSeparator = candidate.includes("/") || candidate.includes("\\");
|
|
12223
|
+
if (includesPathSeparator) {
|
|
12224
|
+
const resolved = path42.isAbsolute(candidate) ? candidate : path42.resolve(candidate);
|
|
12225
|
+
const executablePath = await ensureWindowsExecutableVariant(resolved);
|
|
12226
|
+
await access22(executablePath, constants22.F_OK);
|
|
12227
|
+
return executablePath;
|
|
12228
|
+
}
|
|
12229
|
+
const locator = process.platform === "win32" ? "where" : "which";
|
|
12230
|
+
try {
|
|
12231
|
+
const { stdout } = await execAsync22(`${locator} ${candidate}`);
|
|
12232
|
+
const lines = stdout.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2.length > 0);
|
|
12233
|
+
const preferred = selectExecutableCandidate(lines);
|
|
12234
|
+
if (preferred) {
|
|
12235
|
+
const executablePath = await ensureWindowsExecutableVariant(preferred);
|
|
12236
|
+
await access22(executablePath, constants22.F_OK);
|
|
12237
|
+
return executablePath;
|
|
12257
12238
|
}
|
|
12258
|
-
|
|
12259
|
-
resolved[key2] = resolvedValue;
|
|
12239
|
+
} catch {
|
|
12260
12240
|
}
|
|
12261
|
-
|
|
12241
|
+
throw new Error(`Codex executable '${candidate}' was not found on PATH`);
|
|
12262
12242
|
}
|
|
12263
|
-
function
|
|
12264
|
-
|
|
12265
|
-
if (seconds === void 0) {
|
|
12243
|
+
function selectExecutableCandidate(candidates) {
|
|
12244
|
+
if (candidates.length === 0) {
|
|
12266
12245
|
return void 0;
|
|
12267
12246
|
}
|
|
12268
|
-
if (
|
|
12269
|
-
|
|
12247
|
+
if (process.platform !== "win32") {
|
|
12248
|
+
return candidates[0];
|
|
12270
12249
|
}
|
|
12271
|
-
|
|
12250
|
+
const extensions = getWindowsExecutableExtensions();
|
|
12251
|
+
for (const ext of extensions) {
|
|
12252
|
+
const match = candidates.find((candidate) => candidate.toLowerCase().endsWith(ext));
|
|
12253
|
+
if (match) {
|
|
12254
|
+
return match;
|
|
12255
|
+
}
|
|
12256
|
+
}
|
|
12257
|
+
return candidates[0];
|
|
12272
12258
|
}
|
|
12273
|
-
function
|
|
12274
|
-
if (
|
|
12275
|
-
return
|
|
12259
|
+
async function ensureWindowsExecutableVariant(candidate) {
|
|
12260
|
+
if (process.platform !== "win32") {
|
|
12261
|
+
return candidate;
|
|
12276
12262
|
}
|
|
12277
|
-
if (
|
|
12278
|
-
|
|
12263
|
+
if (hasExecutableExtension(candidate)) {
|
|
12264
|
+
return candidate;
|
|
12279
12265
|
}
|
|
12280
|
-
const
|
|
12281
|
-
const
|
|
12282
|
-
|
|
12283
|
-
|
|
12284
|
-
|
|
12285
|
-
|
|
12286
|
-
|
|
12287
|
-
|
|
12288
|
-
return {
|
|
12289
|
-
type: "http",
|
|
12290
|
-
url,
|
|
12291
|
-
timeoutMs
|
|
12292
|
-
};
|
|
12266
|
+
const extensions = getWindowsExecutableExtensions();
|
|
12267
|
+
for (const ext of extensions) {
|
|
12268
|
+
const withExtension = `${candidate}${ext}`;
|
|
12269
|
+
try {
|
|
12270
|
+
await access22(withExtension, constants22.F_OK);
|
|
12271
|
+
return withExtension;
|
|
12272
|
+
} catch {
|
|
12273
|
+
}
|
|
12293
12274
|
}
|
|
12294
|
-
|
|
12295
|
-
|
|
12296
|
-
|
|
12297
|
-
|
|
12298
|
-
|
|
12299
|
-
|
|
12300
|
-
|
|
12301
|
-
|
|
12302
|
-
|
|
12303
|
-
|
|
12304
|
-
optionalEnv: true
|
|
12305
|
-
});
|
|
12306
|
-
return {
|
|
12307
|
-
type: "command",
|
|
12308
|
-
commandTemplate,
|
|
12309
|
-
timeoutMs,
|
|
12310
|
-
cwd
|
|
12311
|
-
};
|
|
12275
|
+
return candidate;
|
|
12276
|
+
}
|
|
12277
|
+
function hasExecutableExtension(candidate) {
|
|
12278
|
+
const lower = candidate.toLowerCase();
|
|
12279
|
+
return getWindowsExecutableExtensions().some((ext) => lower.endsWith(ext));
|
|
12280
|
+
}
|
|
12281
|
+
var DEFAULT_WINDOWS_EXTENSIONS = [".com", ".exe", ".bat", ".cmd", ".ps1"];
|
|
12282
|
+
function getWindowsExecutableExtensions() {
|
|
12283
|
+
if (process.platform !== "win32") {
|
|
12284
|
+
return [];
|
|
12312
12285
|
}
|
|
12313
|
-
|
|
12286
|
+
const fromEnv = process.env.PATHEXT?.split(";").map((ext) => ext.trim().toLowerCase()).filter((ext) => ext.length > 0);
|
|
12287
|
+
return fromEnv && fromEnv.length > 0 ? fromEnv : DEFAULT_WINDOWS_EXTENSIONS;
|
|
12314
12288
|
}
|
|
12315
|
-
function
|
|
12316
|
-
const
|
|
12317
|
-
|
|
12318
|
-
|
|
12319
|
-
|
|
12320
|
-
|
|
12321
|
-
|
|
12289
|
+
function parseCodexJson(output) {
|
|
12290
|
+
const trimmed = output.trim();
|
|
12291
|
+
if (trimmed.length === 0) {
|
|
12292
|
+
throw new Error("Codex CLI produced no output in --json mode");
|
|
12293
|
+
}
|
|
12294
|
+
try {
|
|
12295
|
+
return JSON.parse(trimmed);
|
|
12296
|
+
} catch {
|
|
12297
|
+
const lineObjects = parseJsonLines(trimmed);
|
|
12298
|
+
if (lineObjects) {
|
|
12299
|
+
return lineObjects;
|
|
12300
|
+
}
|
|
12301
|
+
const lastBrace = trimmed.lastIndexOf("{");
|
|
12302
|
+
if (lastBrace >= 0) {
|
|
12303
|
+
const candidate = trimmed.slice(lastBrace);
|
|
12304
|
+
try {
|
|
12305
|
+
return JSON.parse(candidate);
|
|
12306
|
+
} catch {
|
|
12307
|
+
}
|
|
12322
12308
|
}
|
|
12309
|
+
const preview = trimmed.slice(0, 200);
|
|
12310
|
+
throw new Error(`Codex CLI emitted invalid JSON: ${preview}${trimmed.length > 200 ? "\u2026" : ""}`);
|
|
12323
12311
|
}
|
|
12324
12312
|
}
|
|
12325
|
-
function
|
|
12326
|
-
|
|
12327
|
-
|
|
12328
|
-
|
|
12329
|
-
|
|
12330
|
-
results.push(match[1]);
|
|
12313
|
+
function extractAssistantText(parsed) {
|
|
12314
|
+
if (Array.isArray(parsed)) {
|
|
12315
|
+
const text = extractFromEventStream(parsed);
|
|
12316
|
+
if (text) {
|
|
12317
|
+
return text;
|
|
12331
12318
|
}
|
|
12332
12319
|
}
|
|
12333
|
-
|
|
12334
|
-
|
|
12335
|
-
function resolveString(source2, env, description, allowLiteral = false) {
|
|
12336
|
-
const value = resolveOptionalString(source2, env, description, {
|
|
12337
|
-
allowLiteral,
|
|
12338
|
-
optionalEnv: false
|
|
12339
|
-
});
|
|
12340
|
-
if (value === void 0) {
|
|
12341
|
-
throw new Error(`${description} is required`);
|
|
12320
|
+
if (!parsed || typeof parsed !== "object") {
|
|
12321
|
+
throw new Error("Codex CLI JSON response did not include an assistant message");
|
|
12342
12322
|
}
|
|
12343
|
-
|
|
12344
|
-
|
|
12345
|
-
|
|
12346
|
-
|
|
12347
|
-
return void 0;
|
|
12323
|
+
const record = parsed;
|
|
12324
|
+
const eventText = extractFromEvent(record);
|
|
12325
|
+
if (eventText) {
|
|
12326
|
+
return eventText;
|
|
12348
12327
|
}
|
|
12349
|
-
|
|
12350
|
-
|
|
12328
|
+
const messages = Array.isArray(record.messages) ? record.messages : void 0;
|
|
12329
|
+
if (messages) {
|
|
12330
|
+
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
12331
|
+
const entry = messages[index];
|
|
12332
|
+
if (!entry || typeof entry !== "object") {
|
|
12333
|
+
continue;
|
|
12334
|
+
}
|
|
12335
|
+
const role = entry.role;
|
|
12336
|
+
if (role !== "assistant") {
|
|
12337
|
+
continue;
|
|
12338
|
+
}
|
|
12339
|
+
const content = entry.content;
|
|
12340
|
+
const flattened = flattenContent(content);
|
|
12341
|
+
if (flattened) {
|
|
12342
|
+
return flattened;
|
|
12343
|
+
}
|
|
12344
|
+
}
|
|
12345
|
+
}
|
|
12346
|
+
const response = record.response;
|
|
12347
|
+
if (response && typeof response === "object") {
|
|
12348
|
+
const content = response.content;
|
|
12349
|
+
const flattened = flattenContent(content);
|
|
12350
|
+
if (flattened) {
|
|
12351
|
+
return flattened;
|
|
12352
|
+
}
|
|
12353
|
+
}
|
|
12354
|
+
const output = record.output;
|
|
12355
|
+
const flattenedOutput = flattenContent(output);
|
|
12356
|
+
if (flattenedOutput) {
|
|
12357
|
+
return flattenedOutput;
|
|
12358
|
+
}
|
|
12359
|
+
throw new Error("Codex CLI JSON response did not include an assistant message");
|
|
12360
|
+
}
|
|
12361
|
+
function extractFromEventStream(events) {
|
|
12362
|
+
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
12363
|
+
const candidate = events[index];
|
|
12364
|
+
const text = extractFromEvent(candidate);
|
|
12365
|
+
if (text) {
|
|
12366
|
+
return text;
|
|
12367
|
+
}
|
|
12351
12368
|
}
|
|
12352
|
-
|
|
12353
|
-
|
|
12369
|
+
return void 0;
|
|
12370
|
+
}
|
|
12371
|
+
function extractFromEvent(event) {
|
|
12372
|
+
if (!event || typeof event !== "object") {
|
|
12354
12373
|
return void 0;
|
|
12355
12374
|
}
|
|
12356
|
-
const
|
|
12357
|
-
|
|
12358
|
-
|
|
12359
|
-
|
|
12375
|
+
const record = event;
|
|
12376
|
+
const type = typeof record.type === "string" ? record.type : void 0;
|
|
12377
|
+
if (type === JSONL_TYPE_ITEM_COMPLETED) {
|
|
12378
|
+
const item = record.item;
|
|
12379
|
+
const text = extractFromItem(item);
|
|
12380
|
+
if (text) {
|
|
12381
|
+
return text;
|
|
12360
12382
|
}
|
|
12361
|
-
return envValue;
|
|
12362
12383
|
}
|
|
12363
|
-
const
|
|
12364
|
-
const
|
|
12365
|
-
|
|
12366
|
-
|
|
12367
|
-
if (optionalEnv) {
|
|
12368
|
-
return void 0;
|
|
12369
|
-
}
|
|
12370
|
-
if (!allowLiteral) {
|
|
12371
|
-
throw new Error(`Environment variable '${trimmed}' required for ${description} is not set`);
|
|
12372
|
-
}
|
|
12384
|
+
const output = record.output ?? record.content;
|
|
12385
|
+
const flattened = flattenContent(output);
|
|
12386
|
+
if (flattened) {
|
|
12387
|
+
return flattened;
|
|
12373
12388
|
}
|
|
12374
|
-
return
|
|
12389
|
+
return void 0;
|
|
12375
12390
|
}
|
|
12376
|
-
function
|
|
12377
|
-
if (
|
|
12391
|
+
function extractFromItem(item) {
|
|
12392
|
+
if (!item || typeof item !== "object") {
|
|
12378
12393
|
return void 0;
|
|
12379
12394
|
}
|
|
12380
|
-
|
|
12381
|
-
|
|
12395
|
+
const record = item;
|
|
12396
|
+
const itemType = typeof record.type === "string" ? record.type : void 0;
|
|
12397
|
+
if (itemType === "agent_message" || itemType === "response" || itemType === "output") {
|
|
12398
|
+
const text = flattenContent(record.text ?? record.content ?? record.output);
|
|
12399
|
+
if (text) {
|
|
12400
|
+
return text;
|
|
12401
|
+
}
|
|
12382
12402
|
}
|
|
12383
|
-
|
|
12384
|
-
return trimmed.length > 0 ? trimmed : void 0;
|
|
12403
|
+
return void 0;
|
|
12385
12404
|
}
|
|
12386
|
-
function
|
|
12387
|
-
if (
|
|
12388
|
-
return
|
|
12405
|
+
function flattenContent(value) {
|
|
12406
|
+
if (typeof value === "string") {
|
|
12407
|
+
return value;
|
|
12389
12408
|
}
|
|
12390
|
-
if (
|
|
12391
|
-
|
|
12409
|
+
if (Array.isArray(value)) {
|
|
12410
|
+
const parts = value.map((segment) => {
|
|
12411
|
+
if (typeof segment === "string") {
|
|
12412
|
+
return segment;
|
|
12413
|
+
}
|
|
12414
|
+
if (segment && typeof segment === "object" && "text" in segment) {
|
|
12415
|
+
const text = segment.text;
|
|
12416
|
+
return typeof text === "string" ? text : void 0;
|
|
12417
|
+
}
|
|
12418
|
+
return void 0;
|
|
12419
|
+
}).filter((part) => typeof part === "string" && part.length > 0);
|
|
12420
|
+
return parts.length > 0 ? parts.join(" \n") : void 0;
|
|
12392
12421
|
}
|
|
12393
|
-
if (typeof
|
|
12394
|
-
const
|
|
12395
|
-
|
|
12396
|
-
return numeric;
|
|
12397
|
-
}
|
|
12422
|
+
if (value && typeof value === "object" && "text" in value) {
|
|
12423
|
+
const text = value.text;
|
|
12424
|
+
return typeof text === "string" ? text : void 0;
|
|
12398
12425
|
}
|
|
12399
|
-
|
|
12426
|
+
return void 0;
|
|
12400
12427
|
}
|
|
12401
|
-
function
|
|
12402
|
-
|
|
12428
|
+
function parseJsonLines(output) {
|
|
12429
|
+
const lines = output.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2.length > 0);
|
|
12430
|
+
if (lines.length <= 1) {
|
|
12403
12431
|
return void 0;
|
|
12404
12432
|
}
|
|
12405
|
-
|
|
12406
|
-
|
|
12407
|
-
|
|
12408
|
-
|
|
12409
|
-
|
|
12410
|
-
|
|
12411
|
-
return true;
|
|
12412
|
-
}
|
|
12413
|
-
if (lowered === "false" || lowered === "0") {
|
|
12414
|
-
return false;
|
|
12433
|
+
const parsed = [];
|
|
12434
|
+
for (const line2 of lines) {
|
|
12435
|
+
try {
|
|
12436
|
+
parsed.push(JSON.parse(line2));
|
|
12437
|
+
} catch {
|
|
12438
|
+
return void 0;
|
|
12415
12439
|
}
|
|
12416
12440
|
}
|
|
12417
|
-
|
|
12418
|
-
}
|
|
12419
|
-
function isLikelyEnvReference(value) {
|
|
12420
|
-
return /^[A-Z0-9_]+$/.test(value);
|
|
12441
|
+
return parsed;
|
|
12421
12442
|
}
|
|
12422
|
-
function
|
|
12423
|
-
|
|
12424
|
-
|
|
12425
|
-
|
|
12426
|
-
if (!Array.isArray(source2)) {
|
|
12427
|
-
throw new Error(`${description} must be an array of strings`);
|
|
12443
|
+
function pickDetail(stderr, stdout) {
|
|
12444
|
+
const errorText = stderr.trim();
|
|
12445
|
+
if (errorText.length > 0) {
|
|
12446
|
+
return errorText;
|
|
12428
12447
|
}
|
|
12429
|
-
|
|
12430
|
-
|
|
12448
|
+
const stdoutText = stdout.trim();
|
|
12449
|
+
return stdoutText.length > 0 ? stdoutText : void 0;
|
|
12450
|
+
}
|
|
12451
|
+
function formatTimeoutSuffix2(timeoutMs) {
|
|
12452
|
+
if (!timeoutMs || timeoutMs <= 0) {
|
|
12453
|
+
return "";
|
|
12431
12454
|
}
|
|
12432
|
-
const
|
|
12433
|
-
|
|
12434
|
-
|
|
12435
|
-
|
|
12436
|
-
|
|
12455
|
+
const seconds = Math.ceil(timeoutMs / 1e3);
|
|
12456
|
+
return ` after ${seconds}s`;
|
|
12457
|
+
}
|
|
12458
|
+
async function defaultCodexRunner(options) {
|
|
12459
|
+
return await new Promise((resolve, reject) => {
|
|
12460
|
+
const child = spawn2(options.executable, options.args, {
|
|
12461
|
+
cwd: options.cwd,
|
|
12462
|
+
env: options.env,
|
|
12463
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
12464
|
+
shell: shouldShellExecute(options.executable)
|
|
12465
|
+
});
|
|
12466
|
+
let stdout = "";
|
|
12467
|
+
let stderr = "";
|
|
12468
|
+
let timedOut = false;
|
|
12469
|
+
const onAbort = () => {
|
|
12470
|
+
child.kill("SIGTERM");
|
|
12471
|
+
};
|
|
12472
|
+
if (options.signal) {
|
|
12473
|
+
if (options.signal.aborted) {
|
|
12474
|
+
onAbort();
|
|
12475
|
+
} else {
|
|
12476
|
+
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
12477
|
+
}
|
|
12437
12478
|
}
|
|
12438
|
-
|
|
12439
|
-
if (
|
|
12440
|
-
|
|
12479
|
+
let timeoutHandle;
|
|
12480
|
+
if (options.timeoutMs && options.timeoutMs > 0) {
|
|
12481
|
+
timeoutHandle = setTimeout(() => {
|
|
12482
|
+
timedOut = true;
|
|
12483
|
+
child.kill("SIGTERM");
|
|
12484
|
+
}, options.timeoutMs);
|
|
12485
|
+
timeoutHandle.unref?.();
|
|
12441
12486
|
}
|
|
12442
|
-
|
|
12443
|
-
|
|
12444
|
-
|
|
12445
|
-
|
|
12487
|
+
child.stdout.setEncoding("utf8");
|
|
12488
|
+
child.stdout.on("data", (chunk) => {
|
|
12489
|
+
stdout += chunk;
|
|
12490
|
+
});
|
|
12491
|
+
child.stderr.setEncoding("utf8");
|
|
12492
|
+
child.stderr.on("data", (chunk) => {
|
|
12493
|
+
stderr += chunk;
|
|
12494
|
+
});
|
|
12495
|
+
child.stdin.end(options.prompt);
|
|
12496
|
+
const cleanup = () => {
|
|
12497
|
+
if (timeoutHandle) {
|
|
12498
|
+
clearTimeout(timeoutHandle);
|
|
12446
12499
|
}
|
|
12447
|
-
|
|
12448
|
-
|
|
12449
|
-
|
|
12450
|
-
}
|
|
12500
|
+
if (options.signal) {
|
|
12501
|
+
options.signal.removeEventListener("abort", onAbort);
|
|
12502
|
+
}
|
|
12503
|
+
};
|
|
12504
|
+
child.on("error", (error) => {
|
|
12505
|
+
cleanup();
|
|
12506
|
+
reject(error);
|
|
12507
|
+
});
|
|
12508
|
+
child.on("close", (code) => {
|
|
12509
|
+
cleanup();
|
|
12510
|
+
resolve({
|
|
12511
|
+
stdout,
|
|
12512
|
+
stderr,
|
|
12513
|
+
exitCode: typeof code === "number" ? code : -1,
|
|
12514
|
+
timedOut
|
|
12515
|
+
});
|
|
12516
|
+
});
|
|
12517
|
+
});
|
|
12518
|
+
}
|
|
12519
|
+
function shouldShellExecute(executable) {
|
|
12520
|
+
if (process.platform !== "win32") {
|
|
12521
|
+
return false;
|
|
12451
12522
|
}
|
|
12452
|
-
|
|
12523
|
+
const lower = executable.toLowerCase();
|
|
12524
|
+
return lower.endsWith(".cmd") || lower.endsWith(".bat") || lower.endsWith(".ps1");
|
|
12453
12525
|
}
|
|
12454
|
-
var
|
|
12526
|
+
var DEFAULT_MOCK_RESPONSE = '{"answer":"Mock provider response. Configure targets.yaml to supply a custom value."}';
|
|
12527
|
+
var MockProvider = class {
|
|
12455
12528
|
id;
|
|
12456
|
-
kind;
|
|
12529
|
+
kind = "mock";
|
|
12457
12530
|
targetName;
|
|
12458
|
-
|
|
12459
|
-
|
|
12460
|
-
|
|
12461
|
-
|
|
12462
|
-
|
|
12463
|
-
this.
|
|
12464
|
-
this.
|
|
12465
|
-
|
|
12466
|
-
|
|
12467
|
-
|
|
12468
|
-
|
|
12469
|
-
|
|
12470
|
-
|
|
12471
|
-
const
|
|
12472
|
-
|
|
12473
|
-
|
|
12474
|
-
extraAttachments: inputFiles,
|
|
12475
|
-
wait: this.config.waitForResponse,
|
|
12476
|
-
dryRun: this.config.dryRun,
|
|
12477
|
-
vscodeCmd: this.config.command,
|
|
12478
|
-
subagentRoot: this.config.subagentRoot,
|
|
12479
|
-
workspaceTemplate: this.config.workspaceTemplate,
|
|
12480
|
-
silent: true
|
|
12481
|
-
});
|
|
12482
|
-
if (session.exitCode !== 0 || !session.responseFile) {
|
|
12483
|
-
const failure = session.error ?? "VS Code subagent did not produce a response";
|
|
12484
|
-
throw new Error(failure);
|
|
12485
|
-
}
|
|
12486
|
-
if (this.config.dryRun) {
|
|
12487
|
-
return {
|
|
12488
|
-
text: "",
|
|
12489
|
-
raw: {
|
|
12490
|
-
session,
|
|
12491
|
-
inputFiles
|
|
12492
|
-
}
|
|
12493
|
-
};
|
|
12531
|
+
cannedResponse;
|
|
12532
|
+
delayMs;
|
|
12533
|
+
delayMinMs;
|
|
12534
|
+
delayMaxMs;
|
|
12535
|
+
constructor(targetName, config) {
|
|
12536
|
+
this.id = `mock:${targetName}`;
|
|
12537
|
+
this.targetName = targetName;
|
|
12538
|
+
this.cannedResponse = config.response ?? DEFAULT_MOCK_RESPONSE;
|
|
12539
|
+
this.delayMs = config.delayMs ?? 0;
|
|
12540
|
+
this.delayMinMs = config.delayMinMs ?? 0;
|
|
12541
|
+
this.delayMaxMs = config.delayMaxMs ?? 0;
|
|
12542
|
+
}
|
|
12543
|
+
async invoke(request) {
|
|
12544
|
+
const delay = this.calculateDelay();
|
|
12545
|
+
if (delay > 0) {
|
|
12546
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
12494
12547
|
}
|
|
12495
|
-
const responseText = await readFile22(session.responseFile, "utf8");
|
|
12496
12548
|
return {
|
|
12497
|
-
text:
|
|
12549
|
+
text: this.cannedResponse,
|
|
12498
12550
|
raw: {
|
|
12499
|
-
|
|
12500
|
-
|
|
12551
|
+
prompt: request.prompt,
|
|
12552
|
+
guidelines: request.guidelines
|
|
12501
12553
|
}
|
|
12502
12554
|
};
|
|
12503
12555
|
}
|
|
12504
|
-
|
|
12505
|
-
if (
|
|
12506
|
-
|
|
12507
|
-
|
|
12508
|
-
|
|
12509
|
-
request: req,
|
|
12510
|
-
inputFiles: normalizeAttachments(req.inputFiles)
|
|
12511
|
-
}));
|
|
12512
|
-
const combinedInputFiles = mergeAttachments(
|
|
12513
|
-
normalizedRequests.map(({ inputFiles }) => inputFiles)
|
|
12514
|
-
);
|
|
12515
|
-
const userQueries = normalizedRequests.map(
|
|
12516
|
-
({ request, inputFiles }) => buildPromptDocument(request, inputFiles, request.guideline_patterns)
|
|
12517
|
-
);
|
|
12518
|
-
const session = await dispatchBatchAgent({
|
|
12519
|
-
userQueries,
|
|
12520
|
-
extraAttachments: combinedInputFiles,
|
|
12521
|
-
wait: this.config.waitForResponse,
|
|
12522
|
-
dryRun: this.config.dryRun,
|
|
12523
|
-
vscodeCmd: this.config.command,
|
|
12524
|
-
subagentRoot: this.config.subagentRoot,
|
|
12525
|
-
workspaceTemplate: this.config.workspaceTemplate,
|
|
12526
|
-
silent: true
|
|
12527
|
-
});
|
|
12528
|
-
if (session.exitCode !== 0 || !session.responseFiles) {
|
|
12529
|
-
const failure = session.error ?? "VS Code subagent did not produce batch responses";
|
|
12530
|
-
throw new Error(failure);
|
|
12531
|
-
}
|
|
12532
|
-
if (this.config.dryRun) {
|
|
12533
|
-
return normalizedRequests.map(({ inputFiles }) => ({
|
|
12534
|
-
text: "",
|
|
12535
|
-
raw: {
|
|
12536
|
-
session,
|
|
12537
|
-
inputFiles,
|
|
12538
|
-
allInputFiles: combinedInputFiles
|
|
12539
|
-
}
|
|
12540
|
-
}));
|
|
12541
|
-
}
|
|
12542
|
-
if (session.responseFiles.length !== requests.length) {
|
|
12543
|
-
throw new Error(
|
|
12544
|
-
`VS Code batch returned ${session.responseFiles.length} responses for ${requests.length} requests`
|
|
12545
|
-
);
|
|
12546
|
-
}
|
|
12547
|
-
const responses = [];
|
|
12548
|
-
for (const [index, responseFile] of session.responseFiles.entries()) {
|
|
12549
|
-
const responseText = await readFile22(responseFile, "utf8");
|
|
12550
|
-
responses.push({
|
|
12551
|
-
text: responseText,
|
|
12552
|
-
raw: {
|
|
12553
|
-
session,
|
|
12554
|
-
inputFiles: normalizedRequests[index]?.inputFiles,
|
|
12555
|
-
allInputFiles: combinedInputFiles,
|
|
12556
|
-
responseFile
|
|
12557
|
-
}
|
|
12558
|
-
});
|
|
12556
|
+
calculateDelay() {
|
|
12557
|
+
if (this.delayMinMs > 0 || this.delayMaxMs > 0) {
|
|
12558
|
+
const min = Math.max(0, this.delayMinMs);
|
|
12559
|
+
const max = Math.max(min, this.delayMaxMs);
|
|
12560
|
+
return Math.floor(Math.random() * (max - min + 1)) + min;
|
|
12559
12561
|
}
|
|
12560
|
-
return
|
|
12562
|
+
return this.delayMs;
|
|
12561
12563
|
}
|
|
12562
12564
|
};
|
|
12563
|
-
|
|
12564
|
-
|
|
12565
|
-
|
|
12566
|
-
|
|
12567
|
-
|
|
12568
|
-
|
|
12569
|
-
)
|
|
12570
|
-
|
|
12571
|
-
|
|
12572
|
-
|
|
12573
|
-
|
|
12574
|
-
|
|
12575
|
-
return parts.join("\n").trim();
|
|
12576
|
-
}
|
|
12577
|
-
function buildMandatoryPrereadBlock(guidelineFiles, attachmentFiles) {
|
|
12578
|
-
if (guidelineFiles.length === 0 && attachmentFiles.length === 0) {
|
|
12579
|
-
return "";
|
|
12580
|
-
}
|
|
12581
|
-
const buildList = (files) => files.map((absolutePath) => {
|
|
12582
|
-
const fileName = path32.basename(absolutePath);
|
|
12583
|
-
const fileUri = pathToFileUri2(absolutePath);
|
|
12584
|
-
return `* [${fileName}](${fileUri})`;
|
|
12585
|
-
});
|
|
12586
|
-
const sections = [];
|
|
12587
|
-
if (guidelineFiles.length > 0) {
|
|
12588
|
-
sections.push(`Read all guideline files:
|
|
12589
|
-
${buildList(guidelineFiles).join("\n")}.`);
|
|
12565
|
+
var CLI_PLACEHOLDERS = /* @__PURE__ */ new Set(["PROMPT", "GUIDELINES", "EVAL_ID", "ATTEMPT", "FILES"]);
|
|
12566
|
+
var BASE_TARGET_SCHEMA = external_exports.object({
|
|
12567
|
+
name: external_exports.string().min(1, "target name is required"),
|
|
12568
|
+
provider: external_exports.string().min(1, "provider is required"),
|
|
12569
|
+
settings: external_exports.record(external_exports.unknown()).optional(),
|
|
12570
|
+
judge_target: external_exports.string().optional(),
|
|
12571
|
+
workers: external_exports.number().int().min(1).optional()
|
|
12572
|
+
});
|
|
12573
|
+
var DEFAULT_AZURE_API_VERSION = "2024-10-01-preview";
|
|
12574
|
+
function normalizeAzureApiVersion(value) {
|
|
12575
|
+
if (!value) {
|
|
12576
|
+
return DEFAULT_AZURE_API_VERSION;
|
|
12590
12577
|
}
|
|
12591
|
-
|
|
12592
|
-
|
|
12593
|
-
|
|
12578
|
+
const trimmed = value.trim();
|
|
12579
|
+
if (trimmed.length === 0) {
|
|
12580
|
+
return DEFAULT_AZURE_API_VERSION;
|
|
12594
12581
|
}
|
|
12595
|
-
|
|
12596
|
-
|
|
12597
|
-
"Then apply system_instructions on the user query below."
|
|
12598
|
-
);
|
|
12599
|
-
return sections.join("\n");
|
|
12582
|
+
const withoutPrefix = trimmed.replace(/^api[-_]?version\s*=\s*/i, "").trim();
|
|
12583
|
+
return withoutPrefix.length > 0 ? withoutPrefix : DEFAULT_AZURE_API_VERSION;
|
|
12600
12584
|
}
|
|
12601
|
-
function
|
|
12602
|
-
|
|
12603
|
-
|
|
12604
|
-
|
|
12605
|
-
|
|
12606
|
-
|
|
12607
|
-
|
|
12608
|
-
|
|
12609
|
-
|
|
12610
|
-
|
|
12611
|
-
|
|
12612
|
-
|
|
12613
|
-
|
|
12585
|
+
function resolveTargetDefinition(definition, env = process.env) {
|
|
12586
|
+
const parsed = BASE_TARGET_SCHEMA.parse(definition);
|
|
12587
|
+
const provider = parsed.provider.toLowerCase();
|
|
12588
|
+
const providerBatching = resolveOptionalBoolean(
|
|
12589
|
+
parsed.settings?.provider_batching ?? parsed.settings?.providerBatching
|
|
12590
|
+
);
|
|
12591
|
+
switch (provider) {
|
|
12592
|
+
case "azure":
|
|
12593
|
+
case "azure-openai":
|
|
12594
|
+
return {
|
|
12595
|
+
kind: "azure",
|
|
12596
|
+
name: parsed.name,
|
|
12597
|
+
judgeTarget: parsed.judge_target,
|
|
12598
|
+
workers: parsed.workers,
|
|
12599
|
+
providerBatching,
|
|
12600
|
+
config: resolveAzureConfig(parsed, env)
|
|
12601
|
+
};
|
|
12602
|
+
case "anthropic":
|
|
12603
|
+
return {
|
|
12604
|
+
kind: "anthropic",
|
|
12605
|
+
name: parsed.name,
|
|
12606
|
+
judgeTarget: parsed.judge_target,
|
|
12607
|
+
workers: parsed.workers,
|
|
12608
|
+
providerBatching,
|
|
12609
|
+
config: resolveAnthropicConfig(parsed, env)
|
|
12610
|
+
};
|
|
12611
|
+
case "gemini":
|
|
12612
|
+
case "google":
|
|
12613
|
+
case "google-gemini":
|
|
12614
|
+
return {
|
|
12615
|
+
kind: "gemini",
|
|
12616
|
+
name: parsed.name,
|
|
12617
|
+
judgeTarget: parsed.judge_target,
|
|
12618
|
+
workers: parsed.workers,
|
|
12619
|
+
providerBatching,
|
|
12620
|
+
config: resolveGeminiConfig(parsed, env)
|
|
12621
|
+
};
|
|
12622
|
+
case "codex":
|
|
12623
|
+
case "codex-cli":
|
|
12624
|
+
return {
|
|
12625
|
+
kind: "codex",
|
|
12626
|
+
name: parsed.name,
|
|
12627
|
+
judgeTarget: parsed.judge_target,
|
|
12628
|
+
workers: parsed.workers,
|
|
12629
|
+
providerBatching,
|
|
12630
|
+
config: resolveCodexConfig(parsed, env)
|
|
12631
|
+
};
|
|
12632
|
+
case "mock":
|
|
12633
|
+
return {
|
|
12634
|
+
kind: "mock",
|
|
12635
|
+
name: parsed.name,
|
|
12636
|
+
judgeTarget: parsed.judge_target,
|
|
12637
|
+
workers: parsed.workers,
|
|
12638
|
+
providerBatching,
|
|
12639
|
+
config: resolveMockConfig(parsed)
|
|
12640
|
+
};
|
|
12641
|
+
case "vscode":
|
|
12642
|
+
case "vscode-insiders":
|
|
12643
|
+
return {
|
|
12644
|
+
kind: provider,
|
|
12645
|
+
name: parsed.name,
|
|
12646
|
+
judgeTarget: parsed.judge_target,
|
|
12647
|
+
workers: parsed.workers,
|
|
12648
|
+
providerBatching,
|
|
12649
|
+
config: resolveVSCodeConfig(parsed, env, provider === "vscode-insiders")
|
|
12650
|
+
};
|
|
12651
|
+
case "cli":
|
|
12652
|
+
return {
|
|
12653
|
+
kind: "cli",
|
|
12654
|
+
name: parsed.name,
|
|
12655
|
+
judgeTarget: parsed.judge_target,
|
|
12656
|
+
workers: parsed.workers,
|
|
12657
|
+
providerBatching,
|
|
12658
|
+
config: resolveCliConfig(parsed, env)
|
|
12659
|
+
};
|
|
12660
|
+
default:
|
|
12661
|
+
throw new Error(`Unsupported provider '${parsed.provider}' in target '${parsed.name}'`);
|
|
12614
12662
|
}
|
|
12615
|
-
return Array.from(unique.values());
|
|
12616
12663
|
}
|
|
12617
|
-
function
|
|
12618
|
-
|
|
12619
|
-
|
|
12620
|
-
|
|
12621
|
-
const
|
|
12622
|
-
|
|
12623
|
-
|
|
12624
|
-
|
|
12625
|
-
|
|
12626
|
-
|
|
12627
|
-
}
|
|
12628
|
-
|
|
12664
|
+
function resolveAzureConfig(target, env) {
|
|
12665
|
+
const settings = target.settings ?? {};
|
|
12666
|
+
const endpointSource = settings.endpoint ?? settings.resource ?? settings.resourceName;
|
|
12667
|
+
const apiKeySource = settings.api_key ?? settings.apiKey;
|
|
12668
|
+
const deploymentSource = settings.deployment ?? settings.deploymentName ?? settings.model;
|
|
12669
|
+
const versionSource = settings.version ?? settings.api_version;
|
|
12670
|
+
const temperatureSource = settings.temperature;
|
|
12671
|
+
const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
|
|
12672
|
+
const resourceName = resolveString(endpointSource, env, `${target.name} endpoint`);
|
|
12673
|
+
const apiKey = resolveString(apiKeySource, env, `${target.name} api key`);
|
|
12674
|
+
const deploymentName = resolveString(deploymentSource, env, `${target.name} deployment`);
|
|
12675
|
+
const version = normalizeAzureApiVersion(
|
|
12676
|
+
resolveOptionalString(versionSource, env, `${target.name} api version`)
|
|
12677
|
+
);
|
|
12678
|
+
const temperature = resolveOptionalNumber(temperatureSource, `${target.name} temperature`);
|
|
12679
|
+
const maxOutputTokens = resolveOptionalNumber(
|
|
12680
|
+
maxTokensSource,
|
|
12681
|
+
`${target.name} max output tokens`
|
|
12682
|
+
);
|
|
12683
|
+
return {
|
|
12684
|
+
resourceName,
|
|
12685
|
+
deploymentName,
|
|
12686
|
+
apiKey,
|
|
12687
|
+
version,
|
|
12688
|
+
temperature,
|
|
12689
|
+
maxOutputTokens
|
|
12690
|
+
};
|
|
12691
|
+
}
|
|
12692
|
+
function resolveAnthropicConfig(target, env) {
|
|
12693
|
+
const settings = target.settings ?? {};
|
|
12694
|
+
const apiKeySource = settings.api_key ?? settings.apiKey;
|
|
12695
|
+
const modelSource = settings.model ?? settings.deployment ?? settings.variant;
|
|
12696
|
+
const temperatureSource = settings.temperature;
|
|
12697
|
+
const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
|
|
12698
|
+
const thinkingBudgetSource = settings.thinking_budget ?? settings.thinkingBudget;
|
|
12699
|
+
const apiKey = resolveString(apiKeySource, env, `${target.name} Anthropic api key`);
|
|
12700
|
+
const model = resolveString(modelSource, env, `${target.name} Anthropic model`);
|
|
12701
|
+
return {
|
|
12702
|
+
apiKey,
|
|
12703
|
+
model,
|
|
12704
|
+
temperature: resolveOptionalNumber(temperatureSource, `${target.name} temperature`),
|
|
12705
|
+
maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`),
|
|
12706
|
+
thinkingBudget: resolveOptionalNumber(thinkingBudgetSource, `${target.name} thinking budget`)
|
|
12707
|
+
};
|
|
12629
12708
|
}
|
|
12630
|
-
function
|
|
12631
|
-
const
|
|
12632
|
-
const
|
|
12633
|
-
|
|
12634
|
-
|
|
12635
|
-
|
|
12636
|
-
|
|
12709
|
+
function resolveGeminiConfig(target, env) {
|
|
12710
|
+
const settings = target.settings ?? {};
|
|
12711
|
+
const apiKeySource = settings.api_key ?? settings.apiKey;
|
|
12712
|
+
const modelSource = settings.model ?? settings.deployment ?? settings.variant;
|
|
12713
|
+
const temperatureSource = settings.temperature;
|
|
12714
|
+
const maxTokensSource = settings.max_output_tokens ?? settings.maxTokens;
|
|
12715
|
+
const apiKey = resolveString(apiKeySource, env, `${target.name} Google API key`);
|
|
12716
|
+
const model = resolveOptionalString(modelSource, env, `${target.name} Gemini model`, {
|
|
12717
|
+
allowLiteral: true,
|
|
12718
|
+
optionalEnv: true
|
|
12719
|
+
}) ?? "gemini-2.5-flash";
|
|
12720
|
+
return {
|
|
12721
|
+
apiKey,
|
|
12722
|
+
model,
|
|
12723
|
+
temperature: resolveOptionalNumber(temperatureSource, `${target.name} temperature`),
|
|
12724
|
+
maxOutputTokens: resolveOptionalNumber(maxTokensSource, `${target.name} max output tokens`)
|
|
12725
|
+
};
|
|
12637
12726
|
}
|
|
12638
|
-
function
|
|
12639
|
-
|
|
12640
|
-
|
|
12641
|
-
|
|
12642
|
-
const
|
|
12643
|
-
|
|
12644
|
-
|
|
12645
|
-
|
|
12646
|
-
|
|
12727
|
+
function resolveCodexConfig(target, env) {
|
|
12728
|
+
const settings = target.settings ?? {};
|
|
12729
|
+
const executableSource = settings.executable ?? settings.command ?? settings.binary;
|
|
12730
|
+
const argsSource = settings.args ?? settings.arguments;
|
|
12731
|
+
const cwdSource = settings.cwd;
|
|
12732
|
+
const timeoutSource = settings.timeout_seconds ?? settings.timeoutSeconds;
|
|
12733
|
+
const executable = resolveOptionalString(executableSource, env, `${target.name} codex executable`, {
|
|
12734
|
+
allowLiteral: true,
|
|
12735
|
+
optionalEnv: true
|
|
12736
|
+
}) ?? "codex";
|
|
12737
|
+
const args = resolveOptionalStringArray(argsSource, env, `${target.name} codex args`);
|
|
12738
|
+
const cwd = resolveOptionalString(cwdSource, env, `${target.name} codex cwd`, {
|
|
12739
|
+
allowLiteral: true,
|
|
12740
|
+
optionalEnv: true
|
|
12741
|
+
});
|
|
12742
|
+
const timeoutMs = resolveTimeoutMs(timeoutSource, `${target.name} codex timeout`);
|
|
12743
|
+
return {
|
|
12744
|
+
executable,
|
|
12745
|
+
args,
|
|
12746
|
+
cwd,
|
|
12747
|
+
timeoutMs
|
|
12748
|
+
};
|
|
12647
12749
|
}
|
|
12648
|
-
function
|
|
12649
|
-
const
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
for (const inputFile of list) {
|
|
12653
|
-
deduped.add(path32.resolve(inputFile));
|
|
12654
|
-
}
|
|
12655
|
-
}
|
|
12656
|
-
return deduped.size > 0 ? Array.from(deduped) : void 0;
|
|
12750
|
+
function resolveMockConfig(target) {
|
|
12751
|
+
const settings = target.settings ?? {};
|
|
12752
|
+
const response = typeof settings.response === "string" ? settings.response : void 0;
|
|
12753
|
+
return { response };
|
|
12657
12754
|
}
|
|
12658
|
-
|
|
12659
|
-
const
|
|
12660
|
-
const
|
|
12661
|
-
const
|
|
12662
|
-
|
|
12663
|
-
|
|
12664
|
-
|
|
12665
|
-
|
|
12666
|
-
|
|
12667
|
-
|
|
12668
|
-
|
|
12669
|
-
|
|
12670
|
-
|
|
12671
|
-
|
|
12672
|
-
|
|
12673
|
-
|
|
12674
|
-
|
|
12675
|
-
|
|
12676
|
-
|
|
12677
|
-
|
|
12678
|
-
|
|
12679
|
-
|
|
12680
|
-
|
|
12681
|
-
return {
|
|
12682
|
-
provisioned: true,
|
|
12683
|
-
message: `Provisioned ${count} subagent(s): ${result.created.length} created, ${result.skippedExisting.length} reused`
|
|
12684
|
-
};
|
|
12685
|
-
} catch (error) {
|
|
12686
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
12687
|
-
if (verbose) {
|
|
12688
|
-
console.warn(`Provisioning failed (continuing anyway): ${errorMessage}`);
|
|
12689
|
-
}
|
|
12690
|
-
return {
|
|
12691
|
-
provisioned: false,
|
|
12692
|
-
message: `Provisioning failed: ${errorMessage}`
|
|
12693
|
-
};
|
|
12694
|
-
}
|
|
12755
|
+
function resolveVSCodeConfig(target, env, insiders) {
|
|
12756
|
+
const settings = target.settings ?? {};
|
|
12757
|
+
const workspaceTemplateEnvVar = resolveOptionalLiteralString(settings.workspace_template ?? settings.workspaceTemplate);
|
|
12758
|
+
const workspaceTemplate = workspaceTemplateEnvVar ? resolveOptionalString(workspaceTemplateEnvVar, env, `${target.name} workspace template path`, {
|
|
12759
|
+
allowLiteral: false,
|
|
12760
|
+
optionalEnv: true
|
|
12761
|
+
}) : void 0;
|
|
12762
|
+
const commandSource = settings.vscode_cmd ?? settings.command;
|
|
12763
|
+
const waitSource = settings.wait;
|
|
12764
|
+
const dryRunSource = settings.dry_run ?? settings.dryRun;
|
|
12765
|
+
const subagentRootSource = settings.subagent_root ?? settings.subagentRoot;
|
|
12766
|
+
const defaultCommand = insiders ? "code-insiders" : "code";
|
|
12767
|
+
const command = resolveOptionalLiteralString(commandSource) ?? defaultCommand;
|
|
12768
|
+
return {
|
|
12769
|
+
command,
|
|
12770
|
+
waitForResponse: resolveOptionalBoolean(waitSource) ?? true,
|
|
12771
|
+
dryRun: resolveOptionalBoolean(dryRunSource) ?? false,
|
|
12772
|
+
subagentRoot: resolveOptionalString(subagentRootSource, env, `${target.name} subagent root`, {
|
|
12773
|
+
allowLiteral: true,
|
|
12774
|
+
optionalEnv: true
|
|
12775
|
+
}),
|
|
12776
|
+
workspaceTemplate
|
|
12777
|
+
};
|
|
12695
12778
|
}
|
|
12696
|
-
function
|
|
12697
|
-
const
|
|
12698
|
-
const
|
|
12699
|
-
|
|
12700
|
-
|
|
12701
|
-
options?.guidelineOverrides
|
|
12779
|
+
function resolveCliConfig(target, env) {
|
|
12780
|
+
const settings = target.settings ?? {};
|
|
12781
|
+
const commandTemplateSource = settings.command_template ?? settings.commandTemplate;
|
|
12782
|
+
const filesFormat = resolveOptionalLiteralString(
|
|
12783
|
+
settings.files_format ?? settings.filesFormat ?? settings.attachments_format ?? settings.attachmentsFormat
|
|
12702
12784
|
);
|
|
12703
|
-
const
|
|
12704
|
-
|
|
12705
|
-
|
|
12785
|
+
const cwd = resolveOptionalString(settings.cwd, env, `${target.name} working directory`, {
|
|
12786
|
+
allowLiteral: true,
|
|
12787
|
+
optionalEnv: true
|
|
12788
|
+
});
|
|
12789
|
+
const envOverrides = resolveEnvOverrides(settings.env, env, target.name);
|
|
12790
|
+
const timeoutMs = resolveTimeoutMs(settings.timeout_seconds ?? settings.timeoutSeconds, `${target.name} timeout`);
|
|
12791
|
+
const healthcheck = resolveCliHealthcheck(settings.healthcheck, env, target.name);
|
|
12792
|
+
const commandTemplate = resolveString(
|
|
12793
|
+
commandTemplateSource,
|
|
12794
|
+
env,
|
|
12795
|
+
`${target.name} CLI command template`,
|
|
12796
|
+
true
|
|
12706
12797
|
);
|
|
12707
|
-
|
|
12708
|
-
|
|
12709
|
-
|
|
12710
|
-
|
|
12711
|
-
|
|
12712
|
-
|
|
12798
|
+
assertSupportedCliPlaceholders(commandTemplate, `${target.name} CLI command template`);
|
|
12799
|
+
return {
|
|
12800
|
+
commandTemplate,
|
|
12801
|
+
filesFormat,
|
|
12802
|
+
cwd,
|
|
12803
|
+
env: envOverrides,
|
|
12804
|
+
timeoutMs,
|
|
12805
|
+
healthcheck
|
|
12806
|
+
};
|
|
12713
12807
|
}
|
|
12714
|
-
function
|
|
12715
|
-
if (
|
|
12808
|
+
function resolveEnvOverrides(source2, env, targetName) {
|
|
12809
|
+
if (source2 === void 0 || source2 === null) {
|
|
12716
12810
|
return void 0;
|
|
12717
12811
|
}
|
|
12718
|
-
|
|
12719
|
-
|
|
12720
|
-
const absolutePath = path42.resolve(inputFile);
|
|
12721
|
-
if (!deduped.has(absolutePath)) {
|
|
12722
|
-
deduped.set(absolutePath, absolutePath);
|
|
12723
|
-
}
|
|
12724
|
-
}
|
|
12725
|
-
return Array.from(deduped.values());
|
|
12726
|
-
}
|
|
12727
|
-
function collectGuidelineFiles2(inputFiles, guidelinePatterns, overrides) {
|
|
12728
|
-
if (!inputFiles || inputFiles.length === 0) {
|
|
12729
|
-
return [];
|
|
12730
|
-
}
|
|
12731
|
-
const unique = /* @__PURE__ */ new Map();
|
|
12732
|
-
for (const inputFile of inputFiles) {
|
|
12733
|
-
const absolutePath = path42.resolve(inputFile);
|
|
12734
|
-
if (overrides?.has(absolutePath)) {
|
|
12735
|
-
if (!unique.has(absolutePath)) {
|
|
12736
|
-
unique.set(absolutePath, absolutePath);
|
|
12737
|
-
}
|
|
12738
|
-
continue;
|
|
12739
|
-
}
|
|
12740
|
-
const normalized = absolutePath.split(path42.sep).join("/");
|
|
12741
|
-
if (isGuidelineFile(normalized, guidelinePatterns)) {
|
|
12742
|
-
if (!unique.has(absolutePath)) {
|
|
12743
|
-
unique.set(absolutePath, absolutePath);
|
|
12744
|
-
}
|
|
12745
|
-
}
|
|
12746
|
-
}
|
|
12747
|
-
return Array.from(unique.values());
|
|
12748
|
-
}
|
|
12749
|
-
function collectInputFiles(inputFiles) {
|
|
12750
|
-
if (!inputFiles || inputFiles.length === 0) {
|
|
12751
|
-
return [];
|
|
12812
|
+
if (typeof source2 !== "object" || Array.isArray(source2)) {
|
|
12813
|
+
throw new Error(`${targetName} env overrides must be an object map of strings`);
|
|
12752
12814
|
}
|
|
12753
|
-
const
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
if (
|
|
12757
|
-
|
|
12815
|
+
const entries = Object.entries(source2);
|
|
12816
|
+
const resolved = {};
|
|
12817
|
+
for (const [key2, value] of entries) {
|
|
12818
|
+
if (typeof value !== "string") {
|
|
12819
|
+
throw new Error(`${targetName} env override '${key2}' must be a string`);
|
|
12758
12820
|
}
|
|
12821
|
+
const resolvedValue = resolveString(value, env, `${targetName} env override '${key2}'`);
|
|
12822
|
+
resolved[key2] = resolvedValue;
|
|
12759
12823
|
}
|
|
12760
|
-
return
|
|
12824
|
+
return Object.keys(resolved).length > 0 ? resolved : void 0;
|
|
12761
12825
|
}
|
|
12762
|
-
function
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
const buildList = (files) => files.map((absolutePath) => {
|
|
12767
|
-
const fileName = path42.basename(absolutePath);
|
|
12768
|
-
const fileUri = pathToFileUri22(absolutePath);
|
|
12769
|
-
return `* [${fileName}](${fileUri})`;
|
|
12770
|
-
});
|
|
12771
|
-
const sections = [];
|
|
12772
|
-
if (guidelineFiles.length > 0) {
|
|
12773
|
-
sections.push(`Read all guideline files:
|
|
12774
|
-
${buildList(guidelineFiles).join("\n")}.`);
|
|
12775
|
-
}
|
|
12776
|
-
if (inputFiles.length > 0) {
|
|
12777
|
-
sections.push(`Read all input files:
|
|
12778
|
-
${buildList(inputFiles).join("\n")}.`);
|
|
12826
|
+
function resolveTimeoutMs(source2, description) {
|
|
12827
|
+
const seconds = resolveOptionalNumber(source2, `${description} (seconds)`);
|
|
12828
|
+
if (seconds === void 0) {
|
|
12829
|
+
return void 0;
|
|
12779
12830
|
}
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
"Then apply system_instructions on the user query below."
|
|
12783
|
-
);
|
|
12784
|
-
return sections.join("\n");
|
|
12785
|
-
}
|
|
12786
|
-
function pathToFileUri22(filePath) {
|
|
12787
|
-
const absolutePath = path42.isAbsolute(filePath) ? filePath : path42.resolve(filePath);
|
|
12788
|
-
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
12789
|
-
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
12790
|
-
return `file:///${normalizedPath}`;
|
|
12831
|
+
if (seconds <= 0) {
|
|
12832
|
+
throw new Error(`${description} must be greater than zero seconds`);
|
|
12791
12833
|
}
|
|
12792
|
-
return
|
|
12834
|
+
return Math.floor(seconds * 1e3);
|
|
12793
12835
|
}
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
var FILES_DIR = "files";
|
|
12798
|
-
var JSONL_TYPE_ITEM_COMPLETED = "item.completed";
|
|
12799
|
-
var CodexProvider = class {
|
|
12800
|
-
id;
|
|
12801
|
-
kind = "codex";
|
|
12802
|
-
targetName;
|
|
12803
|
-
supportsBatch = false;
|
|
12804
|
-
config;
|
|
12805
|
-
runCodex;
|
|
12806
|
-
environmentCheck;
|
|
12807
|
-
resolvedExecutable;
|
|
12808
|
-
constructor(targetName, config, runner = defaultCodexRunner) {
|
|
12809
|
-
this.id = `codex:${targetName}`;
|
|
12810
|
-
this.targetName = targetName;
|
|
12811
|
-
this.config = config;
|
|
12812
|
-
this.runCodex = runner;
|
|
12836
|
+
function resolveCliHealthcheck(source2, env, targetName) {
|
|
12837
|
+
if (source2 === void 0 || source2 === null) {
|
|
12838
|
+
return void 0;
|
|
12813
12839
|
}
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
12840
|
+
if (typeof source2 !== "object" || Array.isArray(source2)) {
|
|
12841
|
+
throw new Error(`${targetName} healthcheck must be an object`);
|
|
12842
|
+
}
|
|
12843
|
+
const candidate = source2;
|
|
12844
|
+
const type = candidate.type;
|
|
12845
|
+
const timeoutMs = resolveTimeoutMs(
|
|
12846
|
+
candidate.timeout_seconds ?? candidate.timeoutSeconds,
|
|
12847
|
+
`${targetName} healthcheck timeout`
|
|
12848
|
+
);
|
|
12849
|
+
if (type === "http") {
|
|
12850
|
+
const url = resolveString(candidate.url, env, `${targetName} healthcheck URL`);
|
|
12851
|
+
return {
|
|
12852
|
+
type: "http",
|
|
12853
|
+
url,
|
|
12854
|
+
timeoutMs
|
|
12855
|
+
};
|
|
12856
|
+
}
|
|
12857
|
+
if (type === "command") {
|
|
12858
|
+
const commandTemplate = resolveString(
|
|
12859
|
+
candidate.command_template ?? candidate.commandTemplate,
|
|
12860
|
+
env,
|
|
12861
|
+
`${targetName} healthcheck command template`,
|
|
12862
|
+
true
|
|
12822
12863
|
);
|
|
12823
|
-
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12864
|
+
assertSupportedCliPlaceholders(commandTemplate, `${targetName} healthcheck command template`);
|
|
12865
|
+
const cwd = resolveOptionalString(candidate.cwd, env, `${targetName} healthcheck cwd`, {
|
|
12866
|
+
allowLiteral: true,
|
|
12867
|
+
optionalEnv: true
|
|
12868
|
+
});
|
|
12869
|
+
return {
|
|
12870
|
+
type: "command",
|
|
12871
|
+
commandTemplate,
|
|
12872
|
+
timeoutMs,
|
|
12873
|
+
cwd
|
|
12874
|
+
};
|
|
12875
|
+
}
|
|
12876
|
+
throw new Error(`${targetName} healthcheck type must be 'http' or 'command'`);
|
|
12877
|
+
}
|
|
12878
|
+
function assertSupportedCliPlaceholders(template, description) {
|
|
12879
|
+
const placeholders = extractCliPlaceholders(template);
|
|
12880
|
+
for (const placeholder of placeholders) {
|
|
12881
|
+
if (!CLI_PLACEHOLDERS.has(placeholder)) {
|
|
12882
|
+
throw new Error(
|
|
12883
|
+
`${description} includes unsupported placeholder '{${placeholder}}'. Supported placeholders: ${Array.from(CLI_PLACEHOLDERS).join(", ")}`
|
|
12829
12884
|
);
|
|
12830
|
-
const promptContent = buildPromptDocument2(request, mirroredInputFiles, {
|
|
12831
|
-
guidelinePatterns: request.guideline_patterns,
|
|
12832
|
-
guidelineOverrides: guidelineMirrors
|
|
12833
|
-
});
|
|
12834
|
-
const promptFile = path52.join(workspaceRoot, PROMPT_FILENAME);
|
|
12835
|
-
await writeFile3(promptFile, promptContent, "utf8");
|
|
12836
|
-
const args = this.buildCodexArgs();
|
|
12837
|
-
const cwd = this.resolveCwd(workspaceRoot);
|
|
12838
|
-
const result = await this.executeCodex(args, cwd, promptContent, request.signal);
|
|
12839
|
-
if (result.timedOut) {
|
|
12840
|
-
throw new Error(
|
|
12841
|
-
`Codex CLI timed out${formatTimeoutSuffix2(this.config.timeoutMs ?? void 0)}`
|
|
12842
|
-
);
|
|
12843
|
-
}
|
|
12844
|
-
if (result.exitCode !== 0) {
|
|
12845
|
-
const detail = pickDetail(result.stderr, result.stdout);
|
|
12846
|
-
const prefix = `Codex CLI exited with code ${result.exitCode}`;
|
|
12847
|
-
throw new Error(detail ? `${prefix}: ${detail}` : prefix);
|
|
12848
|
-
}
|
|
12849
|
-
const parsed = parseCodexJson(result.stdout);
|
|
12850
|
-
const assistantText = extractAssistantText(parsed);
|
|
12851
|
-
return {
|
|
12852
|
-
text: assistantText,
|
|
12853
|
-
raw: {
|
|
12854
|
-
response: parsed,
|
|
12855
|
-
stdout: result.stdout,
|
|
12856
|
-
stderr: result.stderr,
|
|
12857
|
-
exitCode: result.exitCode,
|
|
12858
|
-
args,
|
|
12859
|
-
executable: this.resolvedExecutable ?? this.config.executable,
|
|
12860
|
-
promptFile,
|
|
12861
|
-
workspace: workspaceRoot,
|
|
12862
|
-
inputFiles: mirroredInputFiles
|
|
12863
|
-
}
|
|
12864
|
-
};
|
|
12865
|
-
} finally {
|
|
12866
|
-
await this.cleanupWorkspace(workspaceRoot);
|
|
12867
12885
|
}
|
|
12868
12886
|
}
|
|
12869
|
-
|
|
12870
|
-
|
|
12871
|
-
|
|
12887
|
+
}
|
|
12888
|
+
function extractCliPlaceholders(template) {
|
|
12889
|
+
const matches = template.matchAll(/\{([A-Z_]+)\}/g);
|
|
12890
|
+
const results = [];
|
|
12891
|
+
for (const match of matches) {
|
|
12892
|
+
if (match[1]) {
|
|
12893
|
+
results.push(match[1]);
|
|
12872
12894
|
}
|
|
12873
|
-
await this.environmentCheck;
|
|
12874
12895
|
}
|
|
12875
|
-
|
|
12876
|
-
|
|
12896
|
+
return results;
|
|
12897
|
+
}
|
|
12898
|
+
function resolveString(source2, env, description, allowLiteral = false) {
|
|
12899
|
+
const value = resolveOptionalString(source2, env, description, {
|
|
12900
|
+
allowLiteral,
|
|
12901
|
+
optionalEnv: false
|
|
12902
|
+
});
|
|
12903
|
+
if (value === void 0) {
|
|
12904
|
+
throw new Error(`${description} is required`);
|
|
12877
12905
|
}
|
|
12878
|
-
|
|
12879
|
-
|
|
12880
|
-
|
|
12881
|
-
|
|
12882
|
-
return
|
|
12906
|
+
return value;
|
|
12907
|
+
}
|
|
12908
|
+
function resolveOptionalString(source2, env, description, options) {
|
|
12909
|
+
if (source2 === void 0 || source2 === null) {
|
|
12910
|
+
return void 0;
|
|
12883
12911
|
}
|
|
12884
|
-
|
|
12885
|
-
|
|
12886
|
-
if (this.config.args && this.config.args.length > 0) {
|
|
12887
|
-
args.push(...this.config.args);
|
|
12888
|
-
}
|
|
12889
|
-
args.push("-");
|
|
12890
|
-
return args;
|
|
12912
|
+
if (typeof source2 !== "string") {
|
|
12913
|
+
throw new Error(`${description} must be a string`);
|
|
12891
12914
|
}
|
|
12892
|
-
|
|
12893
|
-
|
|
12894
|
-
|
|
12895
|
-
executable: this.resolvedExecutable ?? this.config.executable,
|
|
12896
|
-
args,
|
|
12897
|
-
cwd,
|
|
12898
|
-
prompt: promptContent,
|
|
12899
|
-
timeoutMs: this.config.timeoutMs,
|
|
12900
|
-
env: process.env,
|
|
12901
|
-
signal
|
|
12902
|
-
});
|
|
12903
|
-
} catch (error) {
|
|
12904
|
-
const err = error;
|
|
12905
|
-
if (err.code === "ENOENT") {
|
|
12906
|
-
throw new Error(
|
|
12907
|
-
`Codex executable '${this.config.executable}' was not found. Update the target settings.executable or add it to PATH.`
|
|
12908
|
-
);
|
|
12909
|
-
}
|
|
12910
|
-
throw error;
|
|
12911
|
-
}
|
|
12915
|
+
const trimmed = source2.trim();
|
|
12916
|
+
if (trimmed.length === 0) {
|
|
12917
|
+
return void 0;
|
|
12912
12918
|
}
|
|
12913
|
-
|
|
12914
|
-
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
guidelineMirrors: /* @__PURE__ */ new Set()
|
|
12918
|
-
};
|
|
12919
|
-
}
|
|
12920
|
-
const filesRoot = path52.join(workspaceRoot, FILES_DIR);
|
|
12921
|
-
await mkdir3(filesRoot, { recursive: true });
|
|
12922
|
-
const mirrored = [];
|
|
12923
|
-
const guidelineMirrors = /* @__PURE__ */ new Set();
|
|
12924
|
-
const nameCounts = /* @__PURE__ */ new Map();
|
|
12925
|
-
for (const inputFile of inputFiles) {
|
|
12926
|
-
const absoluteSource = path52.resolve(inputFile);
|
|
12927
|
-
const baseName = path52.basename(absoluteSource);
|
|
12928
|
-
const count = nameCounts.get(baseName) ?? 0;
|
|
12929
|
-
nameCounts.set(baseName, count + 1);
|
|
12930
|
-
const finalName = count === 0 ? baseName : `${baseName}.${count}`;
|
|
12931
|
-
const destination = path52.join(filesRoot, finalName);
|
|
12932
|
-
await copyFile2(absoluteSource, destination);
|
|
12933
|
-
const resolvedDestination = path52.resolve(destination);
|
|
12934
|
-
mirrored.push(resolvedDestination);
|
|
12935
|
-
if (guidelineOriginals.has(absoluteSource)) {
|
|
12936
|
-
guidelineMirrors.add(resolvedDestination);
|
|
12937
|
-
}
|
|
12919
|
+
const envValue = env[trimmed];
|
|
12920
|
+
if (envValue !== void 0) {
|
|
12921
|
+
if (envValue.trim().length === 0) {
|
|
12922
|
+
throw new Error(`Environment variable '${trimmed}' for ${description} is empty`);
|
|
12938
12923
|
}
|
|
12939
|
-
return
|
|
12940
|
-
mirroredInputFiles: mirrored,
|
|
12941
|
-
guidelineMirrors
|
|
12942
|
-
};
|
|
12943
|
-
}
|
|
12944
|
-
async createWorkspace() {
|
|
12945
|
-
return await mkdtemp(path52.join(tmpdir(), WORKSPACE_PREFIX));
|
|
12924
|
+
return envValue;
|
|
12946
12925
|
}
|
|
12947
|
-
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12926
|
+
const allowLiteral = options?.allowLiteral ?? false;
|
|
12927
|
+
const optionalEnv = options?.optionalEnv ?? false;
|
|
12928
|
+
const looksLikeEnv = isLikelyEnvReference(trimmed);
|
|
12929
|
+
if (looksLikeEnv) {
|
|
12930
|
+
if (optionalEnv) {
|
|
12931
|
+
return void 0;
|
|
12932
|
+
}
|
|
12933
|
+
if (!allowLiteral) {
|
|
12934
|
+
throw new Error(`Environment variable '${trimmed}' required for ${description} is not set`);
|
|
12951
12935
|
}
|
|
12952
12936
|
}
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
if (
|
|
12957
|
-
|
|
12958
|
-
const executablePath = await ensureWindowsExecutableVariant(resolved);
|
|
12959
|
-
await access22(executablePath, constants22.F_OK);
|
|
12960
|
-
return executablePath;
|
|
12937
|
+
return trimmed;
|
|
12938
|
+
}
|
|
12939
|
+
function resolveOptionalLiteralString(source2) {
|
|
12940
|
+
if (source2 === void 0 || source2 === null) {
|
|
12941
|
+
return void 0;
|
|
12961
12942
|
}
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
const { stdout } = await execAsync22(`${locator} ${candidate}`);
|
|
12965
|
-
const lines = stdout.split(/\r?\n/).map((line2) => line2.trim()).filter((line2) => line2.length > 0);
|
|
12966
|
-
const preferred = selectExecutableCandidate(lines);
|
|
12967
|
-
if (preferred) {
|
|
12968
|
-
const executablePath = await ensureWindowsExecutableVariant(preferred);
|
|
12969
|
-
await access22(executablePath, constants22.F_OK);
|
|
12970
|
-
return executablePath;
|
|
12971
|
-
}
|
|
12972
|
-
} catch {
|
|
12943
|
+
if (typeof source2 !== "string") {
|
|
12944
|
+
throw new Error("expected string value");
|
|
12973
12945
|
}
|
|
12974
|
-
|
|
12946
|
+
const trimmed = source2.trim();
|
|
12947
|
+
return trimmed.length > 0 ? trimmed : void 0;
|
|
12975
12948
|
}
|
|
12976
|
-
function
|
|
12977
|
-
if (
|
|
12949
|
+
function resolveOptionalNumber(source2, description) {
|
|
12950
|
+
if (source2 === void 0 || source2 === null || source2 === "") {
|
|
12978
12951
|
return void 0;
|
|
12979
12952
|
}
|
|
12980
|
-
if (
|
|
12981
|
-
return
|
|
12953
|
+
if (typeof source2 === "number") {
|
|
12954
|
+
return Number.isFinite(source2) ? source2 : void 0;
|
|
12982
12955
|
}
|
|
12983
|
-
|
|
12984
|
-
|
|
12985
|
-
|
|
12986
|
-
|
|
12987
|
-
return match;
|
|
12956
|
+
if (typeof source2 === "string") {
|
|
12957
|
+
const numeric = Number(source2);
|
|
12958
|
+
if (Number.isFinite(numeric)) {
|
|
12959
|
+
return numeric;
|
|
12988
12960
|
}
|
|
12989
12961
|
}
|
|
12990
|
-
|
|
12962
|
+
throw new Error(`${description} must be a number`);
|
|
12991
12963
|
}
|
|
12992
|
-
|
|
12993
|
-
if (
|
|
12994
|
-
return
|
|
12964
|
+
function resolveOptionalBoolean(source2) {
|
|
12965
|
+
if (source2 === void 0 || source2 === null || source2 === "") {
|
|
12966
|
+
return void 0;
|
|
12995
12967
|
}
|
|
12996
|
-
if (
|
|
12997
|
-
return
|
|
12968
|
+
if (typeof source2 === "boolean") {
|
|
12969
|
+
return source2;
|
|
12998
12970
|
}
|
|
12999
|
-
|
|
13000
|
-
|
|
13001
|
-
|
|
13002
|
-
|
|
13003
|
-
|
|
13004
|
-
|
|
13005
|
-
|
|
12971
|
+
if (typeof source2 === "string") {
|
|
12972
|
+
const lowered = source2.trim().toLowerCase();
|
|
12973
|
+
if (lowered === "true" || lowered === "1") {
|
|
12974
|
+
return true;
|
|
12975
|
+
}
|
|
12976
|
+
if (lowered === "false" || lowered === "0") {
|
|
12977
|
+
return false;
|
|
13006
12978
|
}
|
|
13007
12979
|
}
|
|
13008
|
-
|
|
12980
|
+
throw new Error("expected boolean value");
|
|
13009
12981
|
}
|
|
13010
|
-
function
|
|
13011
|
-
|
|
13012
|
-
return getWindowsExecutableExtensions().some((ext) => lower.endsWith(ext));
|
|
12982
|
+
function isLikelyEnvReference(value) {
|
|
12983
|
+
return /^[A-Z0-9_]+$/.test(value);
|
|
13013
12984
|
}
|
|
13014
|
-
|
|
13015
|
-
|
|
13016
|
-
|
|
13017
|
-
return [];
|
|
12985
|
+
function resolveOptionalStringArray(source2, env, description) {
|
|
12986
|
+
if (source2 === void 0 || source2 === null) {
|
|
12987
|
+
return void 0;
|
|
13018
12988
|
}
|
|
13019
|
-
|
|
13020
|
-
|
|
13021
|
-
}
|
|
13022
|
-
function parseCodexJson(output) {
|
|
13023
|
-
const trimmed = output.trim();
|
|
13024
|
-
if (trimmed.length === 0) {
|
|
13025
|
-
throw new Error("Codex CLI produced no output in --json mode");
|
|
12989
|
+
if (!Array.isArray(source2)) {
|
|
12990
|
+
throw new Error(`${description} must be an array of strings`);
|
|
13026
12991
|
}
|
|
13027
|
-
|
|
13028
|
-
return
|
|
13029
|
-
}
|
|
13030
|
-
|
|
13031
|
-
|
|
13032
|
-
|
|
12992
|
+
if (source2.length === 0) {
|
|
12993
|
+
return void 0;
|
|
12994
|
+
}
|
|
12995
|
+
const resolved = [];
|
|
12996
|
+
for (let i6 = 0; i6 < source2.length; i6++) {
|
|
12997
|
+
const item = source2[i6];
|
|
12998
|
+
if (typeof item !== "string") {
|
|
12999
|
+
throw new Error(`${description}[${i6}] must be a string`);
|
|
13033
13000
|
}
|
|
13034
|
-
const
|
|
13035
|
-
if (
|
|
13036
|
-
|
|
13037
|
-
|
|
13038
|
-
|
|
13039
|
-
|
|
13001
|
+
const trimmed = item.trim();
|
|
13002
|
+
if (trimmed.length === 0) {
|
|
13003
|
+
throw new Error(`${description}[${i6}] cannot be empty`);
|
|
13004
|
+
}
|
|
13005
|
+
const envValue = env[trimmed];
|
|
13006
|
+
if (envValue !== void 0) {
|
|
13007
|
+
if (envValue.trim().length === 0) {
|
|
13008
|
+
throw new Error(`Environment variable '${trimmed}' for ${description}[${i6}] is empty`);
|
|
13040
13009
|
}
|
|
13010
|
+
resolved.push(envValue);
|
|
13011
|
+
} else {
|
|
13012
|
+
resolved.push(trimmed);
|
|
13041
13013
|
}
|
|
13042
|
-
const preview = trimmed.slice(0, 200);
|
|
13043
|
-
throw new Error(`Codex CLI emitted invalid JSON: ${preview}${trimmed.length > 200 ? "\u2026" : ""}`);
|
|
13044
13014
|
}
|
|
13015
|
+
return resolved.length > 0 ? resolved : void 0;
|
|
13045
13016
|
}
|
|
13046
|
-
|
|
13047
|
-
|
|
13048
|
-
|
|
13049
|
-
|
|
13050
|
-
|
|
13051
|
-
|
|
13052
|
-
|
|
13053
|
-
|
|
13054
|
-
|
|
13055
|
-
|
|
13056
|
-
|
|
13057
|
-
const eventText = extractFromEvent(record);
|
|
13058
|
-
if (eventText) {
|
|
13059
|
-
return eventText;
|
|
13017
|
+
var VSCodeProvider = class {
|
|
13018
|
+
id;
|
|
13019
|
+
kind;
|
|
13020
|
+
targetName;
|
|
13021
|
+
supportsBatch = true;
|
|
13022
|
+
config;
|
|
13023
|
+
constructor(targetName, config, kind) {
|
|
13024
|
+
this.id = `${kind}:${targetName}`;
|
|
13025
|
+
this.kind = kind;
|
|
13026
|
+
this.targetName = targetName;
|
|
13027
|
+
this.config = config;
|
|
13060
13028
|
}
|
|
13061
|
-
|
|
13062
|
-
|
|
13063
|
-
|
|
13064
|
-
const entry = messages[index];
|
|
13065
|
-
if (!entry || typeof entry !== "object") {
|
|
13066
|
-
continue;
|
|
13067
|
-
}
|
|
13068
|
-
const role = entry.role;
|
|
13069
|
-
if (role !== "assistant") {
|
|
13070
|
-
continue;
|
|
13071
|
-
}
|
|
13072
|
-
const content = entry.content;
|
|
13073
|
-
const flattened = flattenContent(content);
|
|
13074
|
-
if (flattened) {
|
|
13075
|
-
return flattened;
|
|
13076
|
-
}
|
|
13029
|
+
async invoke(request) {
|
|
13030
|
+
if (request.signal?.aborted) {
|
|
13031
|
+
throw new Error("VS Code provider request was aborted before dispatch");
|
|
13077
13032
|
}
|
|
13078
|
-
|
|
13079
|
-
|
|
13080
|
-
|
|
13081
|
-
|
|
13082
|
-
|
|
13083
|
-
|
|
13084
|
-
|
|
13033
|
+
const inputFiles = normalizeAttachments(request.inputFiles);
|
|
13034
|
+
const promptContent = buildPromptDocument2(request, inputFiles, request.guideline_patterns);
|
|
13035
|
+
const session = await dispatchAgentSession({
|
|
13036
|
+
userQuery: promptContent,
|
|
13037
|
+
extraAttachments: inputFiles,
|
|
13038
|
+
wait: this.config.waitForResponse,
|
|
13039
|
+
dryRun: this.config.dryRun,
|
|
13040
|
+
vscodeCmd: this.config.command,
|
|
13041
|
+
subagentRoot: this.config.subagentRoot,
|
|
13042
|
+
workspaceTemplate: this.config.workspaceTemplate,
|
|
13043
|
+
silent: true
|
|
13044
|
+
});
|
|
13045
|
+
if (session.exitCode !== 0 || !session.responseFile) {
|
|
13046
|
+
const failure = session.error ?? "VS Code subagent did not produce a response";
|
|
13047
|
+
throw new Error(failure);
|
|
13085
13048
|
}
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
}
|
|
13094
|
-
function extractFromEventStream(events) {
|
|
13095
|
-
for (let index = events.length - 1; index >= 0; index -= 1) {
|
|
13096
|
-
const candidate = events[index];
|
|
13097
|
-
const text = extractFromEvent(candidate);
|
|
13098
|
-
if (text) {
|
|
13099
|
-
return text;
|
|
13049
|
+
if (this.config.dryRun) {
|
|
13050
|
+
return {
|
|
13051
|
+
text: "",
|
|
13052
|
+
raw: {
|
|
13053
|
+
session,
|
|
13054
|
+
inputFiles
|
|
13055
|
+
}
|
|
13056
|
+
};
|
|
13100
13057
|
}
|
|
13058
|
+
const responseText = await readFile22(session.responseFile, "utf8");
|
|
13059
|
+
return {
|
|
13060
|
+
text: responseText,
|
|
13061
|
+
raw: {
|
|
13062
|
+
session,
|
|
13063
|
+
inputFiles
|
|
13064
|
+
}
|
|
13065
|
+
};
|
|
13101
13066
|
}
|
|
13102
|
-
|
|
13103
|
-
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13114
|
-
|
|
13067
|
+
async invokeBatch(requests) {
|
|
13068
|
+
if (requests.length === 0) {
|
|
13069
|
+
return [];
|
|
13070
|
+
}
|
|
13071
|
+
const normalizedRequests = requests.map((req) => ({
|
|
13072
|
+
request: req,
|
|
13073
|
+
inputFiles: normalizeAttachments(req.inputFiles)
|
|
13074
|
+
}));
|
|
13075
|
+
const combinedInputFiles = mergeAttachments(
|
|
13076
|
+
normalizedRequests.map(({ inputFiles }) => inputFiles)
|
|
13077
|
+
);
|
|
13078
|
+
const userQueries = normalizedRequests.map(
|
|
13079
|
+
({ request, inputFiles }) => buildPromptDocument2(request, inputFiles, request.guideline_patterns)
|
|
13080
|
+
);
|
|
13081
|
+
const session = await dispatchBatchAgent({
|
|
13082
|
+
userQueries,
|
|
13083
|
+
extraAttachments: combinedInputFiles,
|
|
13084
|
+
wait: this.config.waitForResponse,
|
|
13085
|
+
dryRun: this.config.dryRun,
|
|
13086
|
+
vscodeCmd: this.config.command,
|
|
13087
|
+
subagentRoot: this.config.subagentRoot,
|
|
13088
|
+
workspaceTemplate: this.config.workspaceTemplate,
|
|
13089
|
+
silent: true
|
|
13090
|
+
});
|
|
13091
|
+
if (session.exitCode !== 0 || !session.responseFiles) {
|
|
13092
|
+
const failure = session.error ?? "VS Code subagent did not produce batch responses";
|
|
13093
|
+
throw new Error(failure);
|
|
13094
|
+
}
|
|
13095
|
+
if (this.config.dryRun) {
|
|
13096
|
+
return normalizedRequests.map(({ inputFiles }) => ({
|
|
13097
|
+
text: "",
|
|
13098
|
+
raw: {
|
|
13099
|
+
session,
|
|
13100
|
+
inputFiles,
|
|
13101
|
+
allInputFiles: combinedInputFiles
|
|
13102
|
+
}
|
|
13103
|
+
}));
|
|
13104
|
+
}
|
|
13105
|
+
if (session.responseFiles.length !== requests.length) {
|
|
13106
|
+
throw new Error(
|
|
13107
|
+
`VS Code batch returned ${session.responseFiles.length} responses for ${requests.length} requests`
|
|
13108
|
+
);
|
|
13109
|
+
}
|
|
13110
|
+
const responses = [];
|
|
13111
|
+
for (const [index, responseFile] of session.responseFiles.entries()) {
|
|
13112
|
+
const responseText = await readFile22(responseFile, "utf8");
|
|
13113
|
+
responses.push({
|
|
13114
|
+
text: responseText,
|
|
13115
|
+
raw: {
|
|
13116
|
+
session,
|
|
13117
|
+
inputFiles: normalizedRequests[index]?.inputFiles,
|
|
13118
|
+
allInputFiles: combinedInputFiles,
|
|
13119
|
+
responseFile
|
|
13120
|
+
}
|
|
13121
|
+
});
|
|
13115
13122
|
}
|
|
13123
|
+
return responses;
|
|
13116
13124
|
}
|
|
13117
|
-
|
|
13118
|
-
|
|
13119
|
-
|
|
13120
|
-
|
|
13125
|
+
};
|
|
13126
|
+
function buildPromptDocument2(request, attachments, guidelinePatterns) {
|
|
13127
|
+
const parts = [];
|
|
13128
|
+
const guidelineFiles = collectGuidelineFiles2(attachments, guidelinePatterns);
|
|
13129
|
+
const attachmentFiles = collectAttachmentFiles(attachments);
|
|
13130
|
+
const nonGuidelineAttachments = attachmentFiles.filter(
|
|
13131
|
+
(file) => !guidelineFiles.includes(file)
|
|
13132
|
+
);
|
|
13133
|
+
const prereadBlock = buildMandatoryPrereadBlock2(guidelineFiles, nonGuidelineAttachments);
|
|
13134
|
+
if (prereadBlock.length > 0) {
|
|
13135
|
+
parts.push("\n", prereadBlock);
|
|
13121
13136
|
}
|
|
13122
|
-
|
|
13137
|
+
parts.push("\n[[ ## user_query ## ]]\n", request.prompt.trim());
|
|
13138
|
+
return parts.join("\n").trim();
|
|
13123
13139
|
}
|
|
13124
|
-
function
|
|
13125
|
-
if (
|
|
13126
|
-
return
|
|
13140
|
+
function buildMandatoryPrereadBlock2(guidelineFiles, attachmentFiles) {
|
|
13141
|
+
if (guidelineFiles.length === 0 && attachmentFiles.length === 0) {
|
|
13142
|
+
return "";
|
|
13127
13143
|
}
|
|
13128
|
-
const
|
|
13129
|
-
|
|
13130
|
-
|
|
13131
|
-
|
|
13132
|
-
|
|
13133
|
-
|
|
13134
|
-
|
|
13144
|
+
const buildList = (files) => files.map((absolutePath) => {
|
|
13145
|
+
const fileName = path52.basename(absolutePath);
|
|
13146
|
+
const fileUri = pathToFileUri22(absolutePath);
|
|
13147
|
+
return `* [${fileName}](${fileUri})`;
|
|
13148
|
+
});
|
|
13149
|
+
const sections = [];
|
|
13150
|
+
if (guidelineFiles.length > 0) {
|
|
13151
|
+
sections.push(`Read all guideline files:
|
|
13152
|
+
${buildList(guidelineFiles).join("\n")}.`);
|
|
13135
13153
|
}
|
|
13136
|
-
|
|
13154
|
+
if (attachmentFiles.length > 0) {
|
|
13155
|
+
sections.push(`Read all attachment files:
|
|
13156
|
+
${buildList(attachmentFiles).join("\n")}.`);
|
|
13157
|
+
}
|
|
13158
|
+
sections.push(
|
|
13159
|
+
"If any file is missing, fail with ERROR: missing-file <filename> and stop.",
|
|
13160
|
+
"Then apply system_instructions on the user query below."
|
|
13161
|
+
);
|
|
13162
|
+
return sections.join("\n");
|
|
13137
13163
|
}
|
|
13138
|
-
function
|
|
13139
|
-
if (
|
|
13140
|
-
return
|
|
13164
|
+
function collectGuidelineFiles2(attachments, guidelinePatterns) {
|
|
13165
|
+
if (!attachments || attachments.length === 0) {
|
|
13166
|
+
return [];
|
|
13141
13167
|
}
|
|
13142
|
-
|
|
13143
|
-
|
|
13144
|
-
|
|
13145
|
-
|
|
13146
|
-
|
|
13147
|
-
if (
|
|
13148
|
-
|
|
13149
|
-
return typeof text === "string" ? text : void 0;
|
|
13168
|
+
const unique = /* @__PURE__ */ new Map();
|
|
13169
|
+
for (const attachment of attachments) {
|
|
13170
|
+
const absolutePath = path52.resolve(attachment);
|
|
13171
|
+
const normalized = absolutePath.split(path52.sep).join("/");
|
|
13172
|
+
if (isGuidelineFile(normalized, guidelinePatterns)) {
|
|
13173
|
+
if (!unique.has(absolutePath)) {
|
|
13174
|
+
unique.set(absolutePath, absolutePath);
|
|
13150
13175
|
}
|
|
13151
|
-
|
|
13152
|
-
}).filter((part) => typeof part === "string" && part.length > 0);
|
|
13153
|
-
return parts.length > 0 ? parts.join(" \n") : void 0;
|
|
13154
|
-
}
|
|
13155
|
-
if (value && typeof value === "object" && "text" in value) {
|
|
13156
|
-
const text = value.text;
|
|
13157
|
-
return typeof text === "string" ? text : void 0;
|
|
13176
|
+
}
|
|
13158
13177
|
}
|
|
13159
|
-
return
|
|
13178
|
+
return Array.from(unique.values());
|
|
13160
13179
|
}
|
|
13161
|
-
function
|
|
13162
|
-
|
|
13163
|
-
|
|
13164
|
-
return void 0;
|
|
13180
|
+
function collectAttachmentFiles(attachments) {
|
|
13181
|
+
if (!attachments || attachments.length === 0) {
|
|
13182
|
+
return [];
|
|
13165
13183
|
}
|
|
13166
|
-
const
|
|
13167
|
-
for (const
|
|
13168
|
-
|
|
13169
|
-
|
|
13170
|
-
|
|
13171
|
-
return void 0;
|
|
13184
|
+
const unique = /* @__PURE__ */ new Map();
|
|
13185
|
+
for (const attachment of attachments) {
|
|
13186
|
+
const absolutePath = path52.resolve(attachment);
|
|
13187
|
+
if (!unique.has(absolutePath)) {
|
|
13188
|
+
unique.set(absolutePath, absolutePath);
|
|
13172
13189
|
}
|
|
13173
13190
|
}
|
|
13174
|
-
return
|
|
13191
|
+
return Array.from(unique.values());
|
|
13175
13192
|
}
|
|
13176
|
-
function
|
|
13177
|
-
const
|
|
13178
|
-
|
|
13179
|
-
|
|
13193
|
+
function pathToFileUri22(filePath) {
|
|
13194
|
+
const absolutePath = path52.isAbsolute(filePath) ? filePath : path52.resolve(filePath);
|
|
13195
|
+
const normalizedPath = absolutePath.replace(/\\/g, "/");
|
|
13196
|
+
if (/^[a-zA-Z]:\//.test(normalizedPath)) {
|
|
13197
|
+
return `file:///${normalizedPath}`;
|
|
13180
13198
|
}
|
|
13181
|
-
|
|
13182
|
-
return stdoutText.length > 0 ? stdoutText : void 0;
|
|
13199
|
+
return `file://${normalizedPath}`;
|
|
13183
13200
|
}
|
|
13184
|
-
function
|
|
13185
|
-
if (!
|
|
13186
|
-
return
|
|
13201
|
+
function normalizeAttachments(attachments) {
|
|
13202
|
+
if (!attachments || attachments.length === 0) {
|
|
13203
|
+
return void 0;
|
|
13187
13204
|
}
|
|
13188
|
-
const
|
|
13189
|
-
|
|
13205
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
13206
|
+
for (const attachment of attachments) {
|
|
13207
|
+
deduped.add(path52.resolve(attachment));
|
|
13208
|
+
}
|
|
13209
|
+
return Array.from(deduped);
|
|
13190
13210
|
}
|
|
13191
|
-
|
|
13192
|
-
|
|
13193
|
-
|
|
13194
|
-
|
|
13195
|
-
|
|
13196
|
-
|
|
13197
|
-
shell: shouldShellExecute(options.executable)
|
|
13198
|
-
});
|
|
13199
|
-
let stdout = "";
|
|
13200
|
-
let stderr = "";
|
|
13201
|
-
let timedOut = false;
|
|
13202
|
-
const onAbort = () => {
|
|
13203
|
-
child.kill("SIGTERM");
|
|
13204
|
-
};
|
|
13205
|
-
if (options.signal) {
|
|
13206
|
-
if (options.signal.aborted) {
|
|
13207
|
-
onAbort();
|
|
13208
|
-
} else {
|
|
13209
|
-
options.signal.addEventListener("abort", onAbort, { once: true });
|
|
13210
|
-
}
|
|
13211
|
+
function mergeAttachments(all) {
|
|
13212
|
+
const deduped = /* @__PURE__ */ new Set();
|
|
13213
|
+
for (const list of all) {
|
|
13214
|
+
if (!list) continue;
|
|
13215
|
+
for (const inputFile of list) {
|
|
13216
|
+
deduped.add(path52.resolve(inputFile));
|
|
13211
13217
|
}
|
|
13212
|
-
|
|
13213
|
-
|
|
13214
|
-
|
|
13215
|
-
|
|
13216
|
-
|
|
13217
|
-
|
|
13218
|
-
|
|
13218
|
+
}
|
|
13219
|
+
return deduped.size > 0 ? Array.from(deduped) : void 0;
|
|
13220
|
+
}
|
|
13221
|
+
async function ensureVSCodeSubagents(options) {
|
|
13222
|
+
const { kind, count, verbose = false } = options;
|
|
13223
|
+
const vscodeCmd = kind === "vscode-insiders" ? "code-insiders" : "code";
|
|
13224
|
+
const subagentRoot = getSubagentRoot(vscodeCmd);
|
|
13225
|
+
try {
|
|
13226
|
+
if (verbose) {
|
|
13227
|
+
console.log(`Provisioning ${count} subagent(s) via: subagent ${vscodeCmd} provision`);
|
|
13219
13228
|
}
|
|
13220
|
-
|
|
13221
|
-
|
|
13222
|
-
|
|
13223
|
-
|
|
13224
|
-
child.stderr.setEncoding("utf8");
|
|
13225
|
-
child.stderr.on("data", (chunk) => {
|
|
13226
|
-
stderr += chunk;
|
|
13229
|
+
const result = await provisionSubagents({
|
|
13230
|
+
targetRoot: subagentRoot,
|
|
13231
|
+
subagents: count,
|
|
13232
|
+
dryRun: false
|
|
13227
13233
|
});
|
|
13228
|
-
|
|
13229
|
-
|
|
13230
|
-
|
|
13231
|
-
clearTimeout(timeoutHandle);
|
|
13234
|
+
if (verbose) {
|
|
13235
|
+
if (result.created.length > 0) {
|
|
13236
|
+
console.log(`Created ${result.created.length} new subagent(s)`);
|
|
13232
13237
|
}
|
|
13233
|
-
if (
|
|
13234
|
-
|
|
13238
|
+
if (result.skippedExisting.length > 0) {
|
|
13239
|
+
console.log(`Reusing ${result.skippedExisting.length} existing unlocked subagent(s)`);
|
|
13235
13240
|
}
|
|
13241
|
+
console.log(`
|
|
13242
|
+
total unlocked subagents available: ${result.created.length + result.skippedExisting.length}`);
|
|
13243
|
+
}
|
|
13244
|
+
return {
|
|
13245
|
+
provisioned: true,
|
|
13246
|
+
message: `Provisioned ${count} subagent(s): ${result.created.length} created, ${result.skippedExisting.length} reused`
|
|
13247
|
+
};
|
|
13248
|
+
} catch (error) {
|
|
13249
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
13250
|
+
if (verbose) {
|
|
13251
|
+
console.warn(`Provisioning failed (continuing anyway): ${errorMessage}`);
|
|
13252
|
+
}
|
|
13253
|
+
return {
|
|
13254
|
+
provisioned: false,
|
|
13255
|
+
message: `Provisioning failed: ${errorMessage}`
|
|
13236
13256
|
};
|
|
13237
|
-
child.on("error", (error) => {
|
|
13238
|
-
cleanup();
|
|
13239
|
-
reject(error);
|
|
13240
|
-
});
|
|
13241
|
-
child.on("close", (code) => {
|
|
13242
|
-
cleanup();
|
|
13243
|
-
resolve({
|
|
13244
|
-
stdout,
|
|
13245
|
-
stderr,
|
|
13246
|
-
exitCode: typeof code === "number" ? code : -1,
|
|
13247
|
-
timedOut
|
|
13248
|
-
});
|
|
13249
|
-
});
|
|
13250
|
-
});
|
|
13251
|
-
}
|
|
13252
|
-
function shouldShellExecute(executable) {
|
|
13253
|
-
if (process.platform !== "win32") {
|
|
13254
|
-
return false;
|
|
13255
13257
|
}
|
|
13256
|
-
const lower = executable.toLowerCase();
|
|
13257
|
-
return lower.endsWith(".cmd") || lower.endsWith(".bat") || lower.endsWith(".ps1");
|
|
13258
13258
|
}
|
|
13259
13259
|
function isRecord(value) {
|
|
13260
13260
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -15526,58 +15526,105 @@ function registerEvalCommand(program) {
|
|
|
15526
15526
|
// src/commands/init/index.ts
|
|
15527
15527
|
import { existsSync, mkdirSync, writeFileSync } from "node:fs";
|
|
15528
15528
|
import path15 from "node:path";
|
|
15529
|
+
import * as readline from "node:readline/promises";
|
|
15529
15530
|
|
|
15530
15531
|
// src/templates/index.ts
|
|
15531
|
-
import { readFileSync } from "node:fs";
|
|
15532
|
+
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
15532
15533
|
import path14 from "node:path";
|
|
15533
15534
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
15534
15535
|
var TemplateManager = class {
|
|
15535
|
-
static
|
|
15536
|
+
static getGithubTemplates() {
|
|
15537
|
+
return this.getTemplatesFromDir("github");
|
|
15538
|
+
}
|
|
15539
|
+
static getAgentvTemplates() {
|
|
15540
|
+
return this.getTemplatesFromDir("agentv");
|
|
15541
|
+
}
|
|
15542
|
+
static getTemplatesFromDir(subdir) {
|
|
15536
15543
|
const currentDir = path14.dirname(fileURLToPath2(import.meta.url));
|
|
15537
15544
|
let templatesDir;
|
|
15538
15545
|
if (currentDir.includes(path14.sep + "dist")) {
|
|
15539
|
-
templatesDir = path14.join(currentDir, "templates");
|
|
15546
|
+
templatesDir = path14.join(currentDir, "templates", subdir);
|
|
15540
15547
|
} else {
|
|
15541
|
-
templatesDir = currentDir;
|
|
15548
|
+
templatesDir = path14.join(currentDir, subdir);
|
|
15542
15549
|
}
|
|
15543
|
-
|
|
15544
|
-
|
|
15545
|
-
|
|
15546
|
-
|
|
15547
|
-
const
|
|
15548
|
-
|
|
15549
|
-
|
|
15550
|
-
|
|
15551
|
-
|
|
15552
|
-
|
|
15553
|
-
|
|
15554
|
-
|
|
15555
|
-
|
|
15556
|
-
|
|
15557
|
-
|
|
15558
|
-
|
|
15559
|
-
|
|
15560
|
-
|
|
15561
|
-
path: "contexts/eval-schema.json",
|
|
15562
|
-
content: evalSchema
|
|
15563
|
-
},
|
|
15564
|
-
{
|
|
15565
|
-
path: "contexts/config-schema.json",
|
|
15566
|
-
content: configSchema
|
|
15550
|
+
return this.readTemplatesRecursively(templatesDir, "");
|
|
15551
|
+
}
|
|
15552
|
+
static readTemplatesRecursively(dir, relativePath) {
|
|
15553
|
+
const templates = [];
|
|
15554
|
+
const entries = readdirSync(dir);
|
|
15555
|
+
for (const entry of entries) {
|
|
15556
|
+
const fullPath = path14.join(dir, entry);
|
|
15557
|
+
const stat4 = statSync(fullPath);
|
|
15558
|
+
const entryRelativePath = relativePath ? path14.join(relativePath, entry) : entry;
|
|
15559
|
+
if (stat4.isDirectory()) {
|
|
15560
|
+
templates.push(...this.readTemplatesRecursively(fullPath, entryRelativePath));
|
|
15561
|
+
} else {
|
|
15562
|
+
const content = readFileSync(fullPath, "utf-8");
|
|
15563
|
+
templates.push({
|
|
15564
|
+
path: entryRelativePath.split(path14.sep).join("/"),
|
|
15565
|
+
// Normalize to forward slashes
|
|
15566
|
+
content
|
|
15567
|
+
});
|
|
15567
15568
|
}
|
|
15568
|
-
|
|
15569
|
+
}
|
|
15570
|
+
return templates;
|
|
15569
15571
|
}
|
|
15570
15572
|
};
|
|
15571
15573
|
|
|
15572
15574
|
// src/commands/init/index.ts
|
|
15575
|
+
async function promptYesNo(message) {
|
|
15576
|
+
const rl = readline.createInterface({
|
|
15577
|
+
input: process.stdin,
|
|
15578
|
+
output: process.stdout
|
|
15579
|
+
});
|
|
15580
|
+
try {
|
|
15581
|
+
const answer = await rl.question(`${message} (y/N): `);
|
|
15582
|
+
return answer.toLowerCase() === "y" || answer.toLowerCase() === "yes";
|
|
15583
|
+
} finally {
|
|
15584
|
+
rl.close();
|
|
15585
|
+
}
|
|
15586
|
+
}
|
|
15573
15587
|
async function initCommand(options = {}) {
|
|
15574
15588
|
const targetPath = path15.resolve(options.targetPath ?? ".");
|
|
15575
15589
|
const githubDir = path15.join(targetPath, ".github");
|
|
15590
|
+
const agentvDir = path15.join(targetPath, ".agentv");
|
|
15591
|
+
const githubTemplates = TemplateManager.getGithubTemplates();
|
|
15592
|
+
const agentvTemplates = TemplateManager.getAgentvTemplates();
|
|
15593
|
+
const existingFiles = [];
|
|
15594
|
+
if (existsSync(githubDir)) {
|
|
15595
|
+
for (const template of githubTemplates) {
|
|
15596
|
+
const targetFilePath = path15.join(githubDir, template.path);
|
|
15597
|
+
if (existsSync(targetFilePath)) {
|
|
15598
|
+
existingFiles.push(path15.relative(targetPath, targetFilePath));
|
|
15599
|
+
}
|
|
15600
|
+
}
|
|
15601
|
+
}
|
|
15602
|
+
if (existsSync(agentvDir)) {
|
|
15603
|
+
for (const template of agentvTemplates) {
|
|
15604
|
+
const targetFilePath = path15.join(agentvDir, template.path);
|
|
15605
|
+
if (existsSync(targetFilePath)) {
|
|
15606
|
+
existingFiles.push(path15.relative(targetPath, targetFilePath));
|
|
15607
|
+
}
|
|
15608
|
+
}
|
|
15609
|
+
}
|
|
15610
|
+
if (existingFiles.length > 0) {
|
|
15611
|
+
console.log("We detected an existing setup:");
|
|
15612
|
+
existingFiles.forEach((file) => console.log(` - ${file}`));
|
|
15613
|
+
console.log();
|
|
15614
|
+
const shouldReplace = await promptYesNo("Do you want to replace these files?");
|
|
15615
|
+
if (!shouldReplace) {
|
|
15616
|
+
console.log("\nInit cancelled. No files were changed.");
|
|
15617
|
+
return;
|
|
15618
|
+
}
|
|
15619
|
+
console.log();
|
|
15620
|
+
}
|
|
15576
15621
|
if (!existsSync(githubDir)) {
|
|
15577
15622
|
mkdirSync(githubDir, { recursive: true });
|
|
15578
15623
|
}
|
|
15579
|
-
|
|
15580
|
-
|
|
15624
|
+
if (!existsSync(agentvDir)) {
|
|
15625
|
+
mkdirSync(agentvDir, { recursive: true });
|
|
15626
|
+
}
|
|
15627
|
+
for (const template of githubTemplates) {
|
|
15581
15628
|
const targetFilePath = path15.join(githubDir, template.path);
|
|
15582
15629
|
const targetDirPath = path15.dirname(targetFilePath);
|
|
15583
15630
|
if (!existsSync(targetDirPath)) {
|
|
@@ -15586,11 +15633,26 @@ async function initCommand(options = {}) {
|
|
|
15586
15633
|
writeFileSync(targetFilePath, template.content, "utf-8");
|
|
15587
15634
|
console.log(`Created ${path15.relative(targetPath, targetFilePath)}`);
|
|
15588
15635
|
}
|
|
15636
|
+
for (const template of agentvTemplates) {
|
|
15637
|
+
const targetFilePath = path15.join(agentvDir, template.path);
|
|
15638
|
+
const targetDirPath = path15.dirname(targetFilePath);
|
|
15639
|
+
if (!existsSync(targetDirPath)) {
|
|
15640
|
+
mkdirSync(targetDirPath, { recursive: true });
|
|
15641
|
+
}
|
|
15642
|
+
writeFileSync(targetFilePath, template.content, "utf-8");
|
|
15643
|
+
console.log(`Created ${path15.relative(targetPath, targetFilePath)}`);
|
|
15644
|
+
}
|
|
15589
15645
|
console.log("\nAgentV initialized successfully!");
|
|
15590
15646
|
console.log(`
|
|
15591
15647
|
Files installed to ${path15.relative(targetPath, githubDir)}:`);
|
|
15592
|
-
|
|
15593
|
-
console.log(
|
|
15648
|
+
githubTemplates.forEach((t) => console.log(` - ${t.path}`));
|
|
15649
|
+
console.log(`
|
|
15650
|
+
Files installed to ${path15.relative(targetPath, agentvDir)}:`);
|
|
15651
|
+
agentvTemplates.forEach((t) => console.log(` - ${t.path}`));
|
|
15652
|
+
console.log("\nYou can now:");
|
|
15653
|
+
console.log(" 1. Edit .agentv/.env with your API credentials");
|
|
15654
|
+
console.log(" 2. Configure targets in .agentv/targets.yaml");
|
|
15655
|
+
console.log(" 3. Create eval files using the schema and prompt templates");
|
|
15594
15656
|
}
|
|
15595
15657
|
|
|
15596
15658
|
// src/commands/status.ts
|
|
@@ -16556,4 +16618,4 @@ export {
|
|
|
16556
16618
|
createProgram,
|
|
16557
16619
|
runCli
|
|
16558
16620
|
};
|
|
16559
|
-
//# sourceMappingURL=chunk-
|
|
16621
|
+
//# sourceMappingURL=chunk-HPH4YWGU.js.map
|