Fix remaining OpenCode review comments
This commit is contained in:
@@ -141,38 +141,41 @@ export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExec
|
|||||||
}
|
}
|
||||||
|
|
||||||
const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
|
const instructionsFilePath = asString(config.instructionsFilePath, "").trim();
|
||||||
const instructionsDir = instructionsFilePath ? `${path.dirname(instructionsFilePath)}/` : "";
|
const resolvedInstructionsFilePath = instructionsFilePath
|
||||||
|
? path.resolve(cwd, instructionsFilePath)
|
||||||
|
: "";
|
||||||
|
const instructionsDir = resolvedInstructionsFilePath ? `${path.dirname(resolvedInstructionsFilePath)}/` : "";
|
||||||
let instructionsPrefix = "";
|
let instructionsPrefix = "";
|
||||||
if (instructionsFilePath) {
|
if (resolvedInstructionsFilePath) {
|
||||||
try {
|
try {
|
||||||
const instructionsContents = await fs.readFile(instructionsFilePath, "utf8");
|
const instructionsContents = await fs.readFile(resolvedInstructionsFilePath, "utf8");
|
||||||
instructionsPrefix =
|
instructionsPrefix =
|
||||||
`${instructionsContents}\n\n` +
|
`${instructionsContents}\n\n` +
|
||||||
`The above agent instructions were loaded from ${instructionsFilePath}. ` +
|
`The above agent instructions were loaded from ${resolvedInstructionsFilePath}. ` +
|
||||||
`Resolve any relative file references from ${instructionsDir}.\n\n`;
|
`Resolve any relative file references from ${instructionsDir}.\n\n`;
|
||||||
await onLog(
|
await onLog(
|
||||||
"stderr",
|
"stderr",
|
||||||
`[paperclip] Loaded agent instructions file: ${instructionsFilePath}\n`,
|
`[paperclip] Loaded agent instructions file: ${resolvedInstructionsFilePath}\n`,
|
||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
const reason = err instanceof Error ? err.message : String(err);
|
const reason = err instanceof Error ? err.message : String(err);
|
||||||
await onLog(
|
await onLog(
|
||||||
"stderr",
|
"stderr",
|
||||||
`[paperclip] Warning: could not read agent instructions file "${instructionsFilePath}": ${reason}\n`,
|
`[paperclip] Warning: could not read agent instructions file "${resolvedInstructionsFilePath}": ${reason}\n`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const commandNotes = (() => {
|
const commandNotes = (() => {
|
||||||
if (!instructionsFilePath) return [] as string[];
|
if (!resolvedInstructionsFilePath) return [] as string[];
|
||||||
if (instructionsPrefix.length > 0) {
|
if (instructionsPrefix.length > 0) {
|
||||||
return [
|
return [
|
||||||
`Loaded agent instructions from ${instructionsFilePath}`,
|
`Loaded agent instructions from ${resolvedInstructionsFilePath}`,
|
||||||
`Prepended instructions + path directive to stdin prompt (relative references from ${instructionsDir}).`,
|
`Prepended instructions + path directive to stdin prompt (relative references from ${instructionsDir}).`,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
return [
|
return [
|
||||||
`Configured instructionsFilePath ${instructionsFilePath}, but file could not be read; continuing without injected instructions.`,
|
`Configured instructionsFilePath ${resolvedInstructionsFilePath}, but file could not be read; continuing without injected instructions.`,
|
||||||
];
|
];
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
|||||||
@@ -81,20 +81,30 @@ export async function testEnvironment(
|
|||||||
}
|
}
|
||||||
const runtimeEnv = normalizeEnv(ensurePathInEnv({ ...process.env, ...env }));
|
const runtimeEnv = normalizeEnv(ensurePathInEnv({ ...process.env, ...env }));
|
||||||
|
|
||||||
try {
|
const cwdInvalid = checks.some((check) => check.code === "opencode_cwd_invalid");
|
||||||
await ensureCommandResolvable(command, cwd, runtimeEnv);
|
if (cwdInvalid) {
|
||||||
checks.push({
|
checks.push({
|
||||||
code: "opencode_command_resolvable",
|
code: "opencode_command_skipped",
|
||||||
level: "info",
|
level: "warn",
|
||||||
message: `Command is executable: ${command}`,
|
message: "Skipped command check because working directory validation failed.",
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
checks.push({
|
|
||||||
code: "opencode_command_unresolvable",
|
|
||||||
level: "error",
|
|
||||||
message: err instanceof Error ? err.message : "Command is not executable",
|
|
||||||
detail: command,
|
detail: command,
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
try {
|
||||||
|
await ensureCommandResolvable(command, cwd, runtimeEnv);
|
||||||
|
checks.push({
|
||||||
|
code: "opencode_command_resolvable",
|
||||||
|
level: "info",
|
||||||
|
message: `Command is executable: ${command}`,
|
||||||
|
});
|
||||||
|
} catch (err) {
|
||||||
|
checks.push({
|
||||||
|
code: "opencode_command_unresolvable",
|
||||||
|
level: "error",
|
||||||
|
message: err instanceof Error ? err.message : "Command is not executable",
|
||||||
|
detail: command,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const canRunProbe =
|
const canRunProbe =
|
||||||
@@ -174,61 +184,71 @@ export async function testEnvironment(
|
|||||||
if (variant) args.push("--variant", variant);
|
if (variant) args.push("--variant", variant);
|
||||||
if (extraArgs.length > 0) args.push(...extraArgs);
|
if (extraArgs.length > 0) args.push(...extraArgs);
|
||||||
|
|
||||||
const probe = await runChildProcess(
|
try {
|
||||||
`opencode-envtest-${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
const probe = await runChildProcess(
|
||||||
command,
|
`opencode-envtest-${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
||||||
args,
|
command,
|
||||||
{
|
args,
|
||||||
cwd,
|
{
|
||||||
env: runtimeEnv,
|
cwd,
|
||||||
timeoutSec: 60,
|
env: runtimeEnv,
|
||||||
graceSec: 5,
|
timeoutSec: 60,
|
||||||
stdin: "Respond with hello.",
|
graceSec: 5,
|
||||||
onLog: async () => {},
|
stdin: "Respond with hello.",
|
||||||
},
|
onLog: async () => {},
|
||||||
);
|
},
|
||||||
|
);
|
||||||
|
|
||||||
const parsed = parseOpenCodeJsonl(probe.stdout);
|
const parsed = parseOpenCodeJsonl(probe.stdout);
|
||||||
const detail = summarizeProbeDetail(probe.stdout, probe.stderr, parsed.errorMessage);
|
const detail = summarizeProbeDetail(probe.stdout, probe.stderr, parsed.errorMessage);
|
||||||
const authEvidence = `${parsed.errorMessage ?? ""}\n${probe.stdout}\n${probe.stderr}`.trim();
|
const authEvidence = `${parsed.errorMessage ?? ""}\n${probe.stdout}\n${probe.stderr}`.trim();
|
||||||
|
|
||||||
if (probe.timedOut) {
|
if (probe.timedOut) {
|
||||||
checks.push({
|
checks.push({
|
||||||
code: "opencode_hello_probe_timed_out",
|
code: "opencode_hello_probe_timed_out",
|
||||||
level: "warn",
|
level: "warn",
|
||||||
message: "OpenCode hello probe timed out.",
|
message: "OpenCode hello probe timed out.",
|
||||||
hint: "Retry the probe. If this persists, run OpenCode manually in this working directory.",
|
hint: "Retry the probe. If this persists, run OpenCode manually in this working directory.",
|
||||||
});
|
});
|
||||||
} else if ((probe.exitCode ?? 1) === 0 && !parsed.errorMessage) {
|
} else if ((probe.exitCode ?? 1) === 0 && !parsed.errorMessage) {
|
||||||
const summary = parsed.summary.trim();
|
const summary = parsed.summary.trim();
|
||||||
const hasHello = /\bhello\b/i.test(summary);
|
const hasHello = /\bhello\b/i.test(summary);
|
||||||
checks.push({
|
checks.push({
|
||||||
code: hasHello ? "opencode_hello_probe_passed" : "opencode_hello_probe_unexpected_output",
|
code: hasHello ? "opencode_hello_probe_passed" : "opencode_hello_probe_unexpected_output",
|
||||||
level: hasHello ? "info" : "warn",
|
level: hasHello ? "info" : "warn",
|
||||||
message: hasHello
|
message: hasHello
|
||||||
? "OpenCode hello probe succeeded."
|
? "OpenCode hello probe succeeded."
|
||||||
: "OpenCode probe ran but did not return `hello` as expected.",
|
: "OpenCode probe ran but did not return `hello` as expected.",
|
||||||
...(summary ? { detail: summary.replace(/\s+/g, " ").trim().slice(0, 240) } : {}),
|
...(summary ? { detail: summary.replace(/\s+/g, " ").trim().slice(0, 240) } : {}),
|
||||||
...(hasHello
|
...(hasHello
|
||||||
? {}
|
? {}
|
||||||
: {
|
: {
|
||||||
hint: "Run `opencode run --format json` manually and prompt `Respond with hello` to inspect output.",
|
hint: "Run `opencode run --format json` manually and prompt `Respond with hello` to inspect output.",
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
} else if (OPENCODE_AUTH_REQUIRED_RE.test(authEvidence)) {
|
} else if (OPENCODE_AUTH_REQUIRED_RE.test(authEvidence)) {
|
||||||
checks.push({
|
checks.push({
|
||||||
code: "opencode_hello_probe_auth_required",
|
code: "opencode_hello_probe_auth_required",
|
||||||
level: "warn",
|
level: "warn",
|
||||||
message: "OpenCode is installed, but provider authentication is not ready.",
|
message: "OpenCode is installed, but provider authentication is not ready.",
|
||||||
...(detail ? { detail } : {}),
|
...(detail ? { detail } : {}),
|
||||||
hint: "Run `opencode auth login` or set provider credentials, then retry the probe.",
|
hint: "Run `opencode auth login` or set provider credentials, then retry the probe.",
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
|
checks.push({
|
||||||
|
code: "opencode_hello_probe_failed",
|
||||||
|
level: "error",
|
||||||
|
message: "OpenCode hello probe failed.",
|
||||||
|
...(detail ? { detail } : {}),
|
||||||
|
hint: "Run `opencode run --format json` manually in this working directory to debug.",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
checks.push({
|
checks.push({
|
||||||
code: "opencode_hello_probe_failed",
|
code: "opencode_hello_probe_failed",
|
||||||
level: "error",
|
level: "error",
|
||||||
message: "OpenCode hello probe failed.",
|
message: "OpenCode hello probe failed.",
|
||||||
...(detail ? { detail } : {}),
|
detail: err instanceof Error ? err.message : String(err),
|
||||||
hint: "Run `opencode run --format json` manually in this working directory to debug.",
|
hint: "Run `opencode run --format json` manually in this working directory to debug.",
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -149,6 +149,8 @@ export function OnboardingWizard() {
|
|||||||
const {
|
const {
|
||||||
data: adapterModels,
|
data: adapterModels,
|
||||||
error: adapterModelsError,
|
error: adapterModelsError,
|
||||||
|
isLoading: adapterModelsLoading,
|
||||||
|
isFetching: adapterModelsFetching,
|
||||||
} = useQuery({
|
} = useQuery({
|
||||||
queryKey:
|
queryKey:
|
||||||
createdCompanyId
|
createdCompanyId
|
||||||
@@ -332,6 +334,10 @@ export function OnboardingWizard() {
|
|||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (adapterModelsLoading || adapterModelsFetching) {
|
||||||
|
setError("OpenCode models are still loading. Please wait and try again.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
const discoveredModels = adapterModels ?? [];
|
const discoveredModels = adapterModels ?? [];
|
||||||
if (!discoveredModels.some((entry) => entry.id === selectedModelId)) {
|
if (!discoveredModels.some((entry) => entry.id === selectedModelId)) {
|
||||||
setError(
|
setError(
|
||||||
|
|||||||
@@ -12,5 +12,5 @@ export function extractProviderIdWithFallback(modelId: string, fallback = "other
|
|||||||
export function extractModelName(modelId: string): string {
|
export function extractModelName(modelId: string): string {
|
||||||
const trimmed = modelId.trim();
|
const trimmed = modelId.trim();
|
||||||
if (!trimmed.includes("/")) return trimmed;
|
if (!trimmed.includes("/")) return trimmed;
|
||||||
return trimmed.slice(trimmed.indexOf("/") + 1);
|
return trimmed.slice(trimmed.indexOf("/") + 1).trim();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user