Fix Gemini local execution and diagnostics
This commit is contained in:
@@ -27,6 +27,20 @@ console.log(JSON.stringify({
|
||||
return commandPath;
|
||||
}
|
||||
|
||||
async function writeQuotaGeminiCommand(binDir: string): Promise<string> {
|
||||
const commandPath = path.join(binDir, "gemini");
|
||||
const script = `#!/usr/bin/env node
|
||||
if (process.argv.includes("--help")) {
|
||||
process.exit(0);
|
||||
}
|
||||
console.error("429 RESOURCE_EXHAUSTED: You exceeded your current quota and billing details.");
|
||||
process.exit(1);
|
||||
`;
|
||||
await fs.writeFile(commandPath, script, "utf8");
|
||||
await fs.chmod(commandPath, 0o755);
|
||||
return commandPath;
|
||||
}
|
||||
|
||||
describe("gemini_local environment diagnostics", () => {
|
||||
it("creates a missing working directory when cwd is absolute", async () => {
|
||||
const cwd = path.join(
|
||||
@@ -86,6 +100,35 @@ describe("gemini_local environment diagnostics", () => {
|
||||
expect(args).toContain("gemini-2.5-pro");
|
||||
expect(args).toContain("--approval-mode");
|
||||
expect(args).toContain("yolo");
|
||||
expect(args).toContain("--prompt");
|
||||
await fs.rm(root, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
it("classifies quota exhaustion as a quota warning instead of a generic failure", async () => {
|
||||
const root = path.join(
|
||||
os.tmpdir(),
|
||||
`paperclip-gemini-local-quota-${Date.now()}-${Math.random().toString(16).slice(2)}`,
|
||||
);
|
||||
const binDir = path.join(root, "bin");
|
||||
const cwd = path.join(root, "workspace");
|
||||
await fs.mkdir(binDir, { recursive: true });
|
||||
await writeQuotaGeminiCommand(binDir);
|
||||
|
||||
const result = await testEnvironment({
|
||||
companyId: "company-1",
|
||||
adapterType: "gemini_local",
|
||||
config: {
|
||||
command: "gemini",
|
||||
cwd,
|
||||
env: {
|
||||
GEMINI_API_KEY: "test-key",
|
||||
PATH: `${binDir}${path.delimiter}${process.env.PATH ?? ""}`,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(result.status).toBe("warn");
|
||||
expect(result.checks.some((check) => check.code === "gemini_hello_probe_quota_exhausted")).toBe(true);
|
||||
await fs.rm(root, { recursive: true, force: true });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -45,7 +45,7 @@ type CapturePayload = {
|
||||
};
|
||||
|
||||
describe("gemini execute", () => {
|
||||
it("passes prompt as final argument and injects paperclip env vars", async () => {
|
||||
it("passes prompt via --prompt and injects paperclip env vars", async () => {
|
||||
const root = await fs.mkdtemp(path.join(os.tmpdir(), "paperclip-gemini-execute-"));
|
||||
const workspace = path.join(root, "workspace");
|
||||
const commandPath = path.join(root, "gemini");
|
||||
@@ -96,10 +96,13 @@ describe("gemini execute", () => {
|
||||
const capture = JSON.parse(await fs.readFile(capturePath, "utf8")) as CapturePayload;
|
||||
expect(capture.argv).toContain("--output-format");
|
||||
expect(capture.argv).toContain("stream-json");
|
||||
expect(capture.argv).toContain("--prompt");
|
||||
expect(capture.argv).toContain("--approval-mode");
|
||||
expect(capture.argv).toContain("yolo");
|
||||
expect(capture.argv.at(-1)).toContain("Follow the paperclip heartbeat.");
|
||||
expect(capture.argv.at(-1)).toContain("Paperclip runtime note:");
|
||||
const promptFlagIndex = capture.argv.indexOf("--prompt");
|
||||
const promptArg = promptFlagIndex >= 0 ? capture.argv[promptFlagIndex + 1] : "";
|
||||
expect(promptArg).toContain("Follow the paperclip heartbeat.");
|
||||
expect(promptArg).toContain("Paperclip runtime note:");
|
||||
expect(capture.paperclipEnvKeys).toEqual(
|
||||
expect.arrayContaining([
|
||||
"PAPERCLIP_AGENT_ID",
|
||||
|
||||
Reference in New Issue
Block a user