Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion .github/workflows/daytona-e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ on:
model:
description: "Model to use"
required: false
default: "zai-coding-plan/glm-4.7-flash"
default: "openai/gpt-5.3-codex"
variant:
description: "Model variant"
required: false
default: "high"
analyze_timeout_sec:
description: "Analyze timeout seconds"
required: false
Expand All @@ -26,6 +30,7 @@ permissions:
env:
DAYTONA_API_KEY: ${{ secrets.DAYTONA_API_KEY }}
DAYTONA_API_URL: ${{ vars.DAYTONA_API_URL }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
ZHIPU_API_KEY: ${{ secrets.ZHIPU_API_KEY }}

jobs:
Expand Down Expand Up @@ -58,6 +63,7 @@ jobs:
bun run analyze -- \
--out-dir .memory/daytona-e2e/findings \
--model "${{ inputs.model }}" \
--variant "${{ inputs.variant }}" \
--install-timeout-sec "${{ inputs.install_timeout_sec }}" \
--analyze-timeout-sec "${{ inputs.analyze_timeout_sec }}" \
"${{ inputs.repo_url }}"
Expand Down
18 changes: 10 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,11 @@ bun run start -- --no-open
### Defaults and behavior

- Default model selection:
- Standard: `zai-coding-plan/glm-4.7-flash`
- Standard: `openai/gpt-5.3-codex`
- Standard variant: `high`
- Vision mode (`--vision`): `zai-coding-plan/glm-4.6v`
- Override with `--model`, `--variant`, `OPENCODE_ANALYZE_MODEL`, or `OPENCODE_ANALYZE_VARIANT`
- If you override the model, variant is opt-in (no forced default variant for custom/env model overrides)
- Auto-installs missing `git` and `node/npm` inside sandbox
- Forwards provider env vars (`OPENAI_*`, `ANTHROPIC_*`, `XAI_*`, `OPENROUTER_*`, `ZHIPU_*`, `MINIMAX_*`, etc.)
- Syncs local OpenCode config files from `~/.config/opencode` when present
Expand All @@ -196,7 +198,7 @@ bun run start -- --no-open
```bash
bun run analyze -- --input example.md
bun run analyze -- https://github.com/owner/repo-one https://github.com/owner/repo-two
bun run analyze -- --out-dir findings --model zai-coding-plan/glm-4.7-flash --target us
bun run analyze -- --out-dir findings --model openai/gpt-5.3-codex --variant high --target us
bun run analyze -- --vision
bun run analyze -- --analyze-timeout-sec 3600 --keep-sandbox
```
Expand All @@ -208,15 +210,15 @@ If no URLs and no `--input` are provided, the script uses `example.md` when it e
## Output Layout

- `<out-dir>/index.md` - summary across all URLs
- `<out-dir>/<NN-slug>/findings.md` - final report for each repository
- `<out-dir>/<NN-slug>/README.*` - copied repository README (if found)
- `<out-dir>/<NN-slug>/opencode-run.log` - raw OpenCode run output
- `<out-dir>/<NN-slug>/opencode-models-anthropic.log` - Anthropic model-list preflight output (only when `anthropic/*` model is requested)
- `<out-dir>/<YYYY-MM-DD-NN-slug>/findings.md` - final report for each repository
- `<out-dir>/<YYYY-MM-DD-NN-slug>/README.*` - copied repository README (if found)
- `<out-dir>/<YYYY-MM-DD-NN-slug>/opencode-run.log` - raw OpenCode run output
- `<out-dir>/<YYYY-MM-DD-NN-slug>/opencode-models-anthropic.log` - Anthropic model-list preflight output (only when `anthropic/*` model is requested)

Example retained in this repo:
Recommended naming convention for manual runs:

```bash
bun run analyze -- --input example.md --out-dir findings-confidence-3 --analyze-timeout-sec 3600 --keep-sandbox
bun run analyze -- --input example.md --out-dir findings-2026-03-03 --analyze-timeout-sec 3600 --keep-sandbox
```

---
Expand Down
19 changes: 14 additions & 5 deletions src/analyze-model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ describe("resolveAnalyzeModel", () => {
delete process.env.OPENCODE_ANALYZE_VISION_MODEL;

const resolved = resolveAnalyzeModel({});
expect(resolved.model).toBe("zai-coding-plan/glm-4.7-flash");
expect(resolved.variant).toBeUndefined();
expect(resolved.model).toBe("openai/gpt-5.3-codex");
expect(resolved.variant).toBe("high");
});

test("uses vision default when requested", () => {
Expand All @@ -34,6 +34,15 @@ describe("resolveAnalyzeModel", () => {
expect(resolved.variant).toBeUndefined();
});

test("does not force default variant when model is overridden by env", () => {
process.env.OPENCODE_ANALYZE_MODEL = "openai/gpt-5.3-codex";
delete process.env.OPENCODE_ANALYZE_VARIANT;

const resolved = resolveAnalyzeModel({});
expect(resolved.model).toBe("openai/gpt-5.3-codex");
expect(resolved.variant).toBeUndefined();
});

test("respects env overrides", () => {
process.env.OPENCODE_ANALYZE_MODEL = "zai-coding-plan/glm-5";
process.env.OPENCODE_ANALYZE_VARIANT = "high";
Expand All @@ -44,15 +53,15 @@ describe("resolveAnalyzeModel", () => {
});

test("cli args override env", () => {
process.env.OPENCODE_ANALYZE_MODEL = "zai-coding-plan/glm-4.7-flash";
process.env.OPENCODE_ANALYZE_MODEL = "openai/gpt-5.3-codex";
process.env.OPENCODE_ANALYZE_VARIANT = "low";

const resolved = resolveAnalyzeModel({
model: "zai-coding-plan/glm-4.6v",
model: "anthropic/claude-sonnet-4-6",
variant: "high",
});

expect(resolved.model).toBe("zai-coding-plan/glm-4.6v");
expect(resolved.model).toBe("anthropic/claude-sonnet-4-6");
expect(resolved.variant).toBe("high");
});

Expand Down
8 changes: 5 additions & 3 deletions src/analyze-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@ export type ResolvedAnalyzeModel = {
};

export function resolveAnalyzeModel(input: AnalyzeModelInput): ResolvedAnalyzeModel {
const modelOverride = input.model ?? process.env.OPENCODE_ANALYZE_MODEL;
const defaultModel = input.vision
? (process.env.OPENCODE_ANALYZE_VISION_MODEL ?? "zai-coding-plan/glm-4.6v")
: "zai-coding-plan/glm-4.7-flash";
const model = input.model ?? process.env.OPENCODE_ANALYZE_MODEL ?? defaultModel;
const variant = input.variant ?? process.env.OPENCODE_ANALYZE_VARIANT;
: "openai/gpt-5.3-codex";
const model = modelOverride ?? defaultModel;
const defaultVariant = !input.vision && !modelOverride ? "high" : undefined;
const variant = input.variant ?? process.env.OPENCODE_ANALYZE_VARIANT ?? defaultVariant;

return {
model,
Expand Down
16 changes: 12 additions & 4 deletions src/analyze-repos.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,13 @@ function slugFromRepoUrl(url: string): string {
return sanitizeSlug(`${owner}-${repo}`);
}

function formatDatePrefix(date: Date): string {
const year = String(date.getFullYear());
const month = String(date.getMonth() + 1).padStart(2, "0");
const day = String(date.getDate()).padStart(2, "0");
return `${year}-${month}-${day}`;
}

function normalizeUrlCandidate(raw: string): string | undefined {
const cleaned = raw.trim().replace(/[),.;]+$/g, "");
if (!cleaned.startsWith("http://") && !cleaned.startsWith("https://")) {
Expand Down Expand Up @@ -250,7 +257,7 @@ function parseCliOptions(): CliOptions {
Examples:
bun run analyze -- --input example.md
bun run analyze -- https://github.com/agenticnotetaking/arscontexta
bun run analyze -- --input links.md --out-dir findings --model zai-coding-plan/glm-4.7-flash
bun run analyze -- --input links.md --out-dir findings --model openai/gpt-5.3-codex --variant high
bun run analyze -- --vision

Options:
Expand All @@ -260,8 +267,8 @@ Options:
--install-timeout-sec <n> OpenCode install timeout (default: 900)
--analyze-timeout-sec <n> Per-repo analysis timeout (default: 2400)
--target <name> Daytona target override
--model <provider/model> OpenCode model (default: zai-coding-plan/glm-4.7-flash)
--variant <name> Model variant (example: xhigh)
--model <provider/model> OpenCode model (default: openai/gpt-5.3-codex)
--variant <name> Model variant (default: high, when using built-in default model)
--vision Prefer vision-capable default model (zai-coding-plan/glm-4.6v)
--keep-sandbox Keep each sandbox instead of deleting it
-h, --help Show this help
Expand Down Expand Up @@ -676,7 +683,8 @@ async function analyzeOneRepo(params: {
const { daytona, options, config, url, index, total } = params;
const slug = slugFromRepoUrl(url);
const runPrefix = `${String(index + 1).padStart(2, "0")}-${slug}`;
const localDir = path.join(options.outDir, runPrefix);
const datedRunPrefix = `${formatDatePrefix(new Date())}-${runPrefix}`;
const localDir = path.join(options.outDir, datedRunPrefix);
const findingsPath = path.join(localDir, "findings.md");
let readmePath: string | undefined;

Expand Down