Files
云服务部-叶林立andDevin <158243242+devin-ai-integration[bot]@users.noreply.github.com> dae1a01f23 feat(prompt): 搜索引导改为意图→工具的正向指引,multi_grep 按上游保持关闭
真实会话中模型仍用 bash grep -o | sort -u 做抽取,被拒后直接放弃核对;
原提示词只说"不要",没告诉它抽取/计数、给程序传文件清单、过滤命令输出时该用什么。

- routing:按已知信息选 grep/find(多变体用 grep 正则 alternation),
  codemode + tools.grep 做聚合,bash 文件清单用 git ls-files,
  overflow_query 过滤输出,被拒后改用替代方案继续
- 权限策略:rg/grep/git grep/find/fd 的 deny 附带指向替代工具的 reason
- tools.jsonc:grep/find 新 snippet,补上 codegraph_explore snippet
- FFF 上游标注 multi_grep 有害:wrapper 删除 PI_FFF_MULTIGREP,清理全部引用
- JSONC 测试改用字符串感知的注释剥离(reason 中含 'src/**/*.ts')

Generated with [Devin](https://devin.ai)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
2026-10-22 00:14:49 -07:00

108 lines
3.6 KiB
TypeScript

import { readFileSync } from "node:fs";
import { fileURLToPath } from "node:url";
import { describe, expect, it } from "vitest";
import {
autoReviewConfigFileSchema,
normalizeAutoReviewConfig,
} from "#src/auto-review/config";
import { stripJsonComments } from "#src/config-loader";
import { unifiedConfigSchema } from "#src/config-schema";
/** The bundle's authoritative policy seed, as shipped. */
const SEED_PATH = fileURLToPath(
new URL("../../config/pi-permission-policy.jsonc", import.meta.url),
);
function readSeed(): Record<string, unknown> {
const raw = readFileSync(SEED_PATH, "utf8");
// Parse with the same string-aware stripper the loader uses: a naive regex
// strips `/*`-looking runs inside string values (e.g. a `'src/**/*.ts'`
// glob in a deny reason) and corrupts the JSON.
return JSON.parse(stripJsonComments(raw)) as Record<string, unknown>;
}
describe("bundled policy seed", () => {
it("follows the session model: enabled, with no provider/model pair", () => {
const seed = readSeed();
const parsed = autoReviewConfigFileSchema.safeParse(seed.autoReview);
expect(parsed.success).toBe(true);
if (!parsed.success) throw new Error("seed autoReview block is invalid");
expect(parsed.data).toEqual({ enabled: true });
});
it("ships no overrides, so the bundle runs the code-default review knobs", () => {
const seed = readSeed();
const parsed = autoReviewConfigFileSchema.parse(seed.autoReview);
// The seed writes `enabled` only; every effective value below lives in
// normalizeAutoReviewConfig's defaults. If either the seed or the
// defaults drift, this fails.
const effective = normalizeAutoReviewConfig(parsed);
expect(effective.enabled).toBe(true);
expect(effective.provider).toBeUndefined();
expect(effective.model).toBeUndefined();
expect(effective.reasoning).toBe("low");
expect(effective.timeoutMs).toBe(30_000);
expect(effective.maxAttempts).toBe(2);
expect(effective.maxOutputTokens).toBe(4_000);
expect(effective.transcript).toEqual({
messageTokens: 10_000,
toolTokens: 10_000,
maxUntrustedEntries: 40,
});
});
it("keeps auto-review in the authorizer chain", () => {
const seed = readSeed();
expect(seed.authorizerChain).toEqual(["auto-review"]);
});
it("passes the unified schema", () => {
const seed = readSeed();
expect(unifiedConfigSchema.safeParse(seed).success).toBe(true);
});
});
describe("backward compatibility with a deployed config", () => {
it("still accepts the retired annotators key and ignores it", () => {
// A config file saved by an older bundle revision may still carry the
// retired `annotators` key. Rejecting it would fail that file closed
// instead of ignoring the key.
const result = unifiedConfigSchema.safeParse({
annotators: ["model-explanation"],
});
expect(result.success).toBe(true);
});
it("still accepts a configured provider/model pair", () => {
const parsed = autoReviewConfigFileSchema.safeParse({
enabled: true,
provider: "openai",
model: "gpt-5-mini",
reasoning: "off",
});
expect(parsed.success).toBe(true);
const effective = normalizeAutoReviewConfig(
parsed.success ? parsed.data : undefined,
);
expect(effective.provider).toBe("openai");
expect(effective.model).toBe("gpt-5-mini");
expect(effective.reasoning).toBe("off");
});
it("applies defaults when the block is absent", () => {
const effective = normalizeAutoReviewConfig(undefined);
expect(effective.enabled).toBe(true);
expect(effective.reasoning).toBe("low");
expect(effective.maxAttempts).toBe(2);
});
});