@polderlabs/bizar-plugin 0.8.0 → 0.8.2

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.
@@ -162,7 +162,7 @@ describe("BackgroundState schema backfill", () => {
162
162
  agent: "mimir",
163
163
  status: "running",
164
164
  startedAt,
165
- model: "openrouter/minimax-m3",
165
+ model: "minimax/minimax-m3",
166
166
  promptPreview: "Do the thing",
167
167
  toolCallCount: 0,
168
168
  parentAgent: "odin",
@@ -189,7 +189,7 @@ describe("BackgroundState schema backfill", () => {
189
189
  agent: "mimir",
190
190
  status: "running",
191
191
  startedAt,
192
- model: "openrouter/minimax-m3",
192
+ model: "minimax/minimax-m3",
193
193
  promptPreview: "Do the thing",
194
194
  toolCallCount: 0,
195
195
  parentAgent: "odin",
@@ -216,7 +216,7 @@ describe("BackgroundState schema backfill", () => {
216
216
  agent: "mimir",
217
217
  status: "running",
218
218
  startedAt,
219
- model: "openrouter/minimax-m3",
219
+ model: "minimax/minimax-m3",
220
220
  promptPreview: "Do the thing",
221
221
  toolCallCount: 0,
222
222
  parentAgent: "odin",
@@ -437,7 +437,7 @@ function makeBgState(overrides: Partial<BackgroundState> = {}): BackgroundState
437
437
  agent: "mimir",
438
438
  status: "running",
439
439
  startedAt: now,
440
- model: "openrouter/minimax-m3",
440
+ model: "minimax/minimax-m3",
441
441
  promptPreview: "Do the thing",
442
442
  resultPreview: undefined,
443
443
  resultMessageIds: [],
@@ -700,7 +700,7 @@ describe("bg-status toView — v0.3.0 fields", () => {
700
700
  agent: "mimir",
701
701
  status: "running",
702
702
  startedAt: now - 600_000,
703
- model: "openrouter/minimax-m3",
703
+ model: "minimax/minimax-m3",
704
704
  promptPreview: "Research X",
705
705
  toolCallCount: 0,
706
706
  parentAgent: "odin",
@@ -729,7 +729,7 @@ describe("bg-status toView — v0.3.0 fields", () => {
729
729
  agent: "mimir",
730
730
  status: "running",
731
731
  startedAt: now,
732
- model: "openrouter/minimax-m3",
732
+ model: "minimax/minimax-m3",
733
733
  promptPreview: "Research Y",
734
734
  toolCallCount: 0,
735
735
  parentAgent: "odin",
@@ -27,13 +27,13 @@ function parseModel(model: string | undefined): { providerID: string; modelID: s
27
27
  const parts = model.split("/");
28
28
  if (parts.length !== 2) {
29
29
  throw new Error(
30
- `model must be in "providerID/modelID" format (e.g. "openrouter/minimax-m3"). Omit to use the agent's default.`,
30
+ `model must be in "providerID/modelID" format (e.g. "minimax/minimax-m3"). Omit to use the agent's default.`,
31
31
  );
32
32
  }
33
33
  const [providerID, modelID] = parts;
34
34
  if (!providerID || !modelID) {
35
35
  throw new Error(
36
- `model must be in "providerID/modelID" format (e.g. "openrouter/minimax-m3"). Omit to use the agent's default.`,
36
+ `model must be in "providerID/modelID" format (e.g. "minimax/minimax-m3"). Omit to use the agent's default.`,
37
37
  );
38
38
  }
39
39
  return { providerID, modelID };
@@ -132,9 +132,9 @@ describe("bizar_spawn_background — Odin-only", () => {
132
132
  // ---------------------------------------------------------------------------
133
133
 
134
134
  describe("bizar_spawn_background — model parsing (HIGH-3, LOW-34)", () => {
135
- it('"openrouter/minimax-m3" parses to { providerID: "openrouter", modelID: "minimax-m3" }', () => {
136
- const result = parseModel("openrouter/minimax-m3");
137
- expect(result).toEqual({ providerID: "openrouter", modelID: "minimax-m3" });
135
+ it('"minimax/minimax-m3" parses to { providerID: "minimax", modelID: "minimax-m3" }', () => {
136
+ const result = parseModel("minimax/minimax-m3");
137
+ expect(result).toEqual({ providerID: "minimax", modelID: "minimax-m3" });
138
138
  });
139
139
 
140
140
  it('"opencode/deepseek-v4-flash-free" parses correctly', () => {
@@ -168,7 +168,7 @@ describe("bizar_spawn_background — model parsing (HIGH-3, LOW-34)", () => {
168
168
 
169
169
  it("spawn tool includes parsed model in POST /session body", () => {
170
170
  const result = bizarre_spawn_background(
171
- { agent: "mimir", prompt: "Do X", model: "openrouter/minimax-m3" },
171
+ { agent: "mimir", prompt: "Do X", model: "minimax/minimax-m3" },
172
172
  { agent: "odin", sessionID: "sess_parent", worktree: "/tmp" },
173
173
  );
174
174
  expect(result).not.toHaveProperty("error");
@@ -0,0 +1,115 @@
1
+ /**
2
+ * plugins/bizar/tests/tools/opencode-runner.test.ts
3
+ *
4
+ * Unit tests for `buildOpencodeRunArgs` — the pure helper extracted
5
+ * from `plugins/bizar/src/opencode-runner.ts` so the argv passed to
6
+ * `Bun.spawn(["opencode", "run", ...])` can be asserted without
7
+ * spawning a real process.
8
+ *
9
+ * These tests pin the two regressions that motivated the extraction:
10
+ *
11
+ * 1. Bug 1 (HIGH): the `--agent` flag was missing from the args list,
12
+ * so `opencode run` silently fell back to the opencode default
13
+ * agent and broke session attribution.
14
+ *
15
+ * 2. Bug 2 (HIGH): the OpenRouter model IDs were renamed. Tests assert
16
+ * the new `minimax/minimax-m3` / `minimax/minimax-m2.7` format so
17
+ * a stale `openrouter/minimax-m3` reference is caught immediately.
18
+ */
19
+
20
+ import { describe, it, expect } from "bun:test";
21
+ import {
22
+ buildOpencodeRunArgs,
23
+ type SpawnAgentOptions,
24
+ } from "../../src/opencode-runner";
25
+
26
+ function baseOpts(overrides: Partial<SpawnAgentOptions> = {}): SpawnAgentOptions {
27
+ return {
28
+ agent: "thor",
29
+ prompt: "Investigate the auth module",
30
+ worktree: "/tmp/worktree",
31
+ logPath: "/tmp/worktree/.bgr/log.log",
32
+ ...overrides,
33
+ };
34
+ }
35
+
36
+ describe("buildOpencodeRunArgs — Bug 1 regression: --agent flag", () => {
37
+ it("argv contains the --agent flag followed by the agent name", () => {
38
+ const args = buildOpencodeRunArgs(baseOpts({ agent: "thor" }));
39
+ const i = args.indexOf("--agent");
40
+ expect(i).toBeGreaterThanOrEqual(0);
41
+ expect(args[i + 1]).toBe("thor");
42
+ });
43
+
44
+ it("--agent value matches opts.agent exactly (no default fallback)", () => {
45
+ for (const agent of ["mimir", "thor", "tyr", "heimdall", "hermod"]) {
46
+ const args = buildOpencodeRunArgs(baseOpts({ agent }));
47
+ expect(args[args.indexOf("--agent") + 1]).toBe(agent);
48
+ }
49
+ });
50
+
51
+ it("throws a clear error when opts.agent is empty", () => {
52
+ expect(() => buildOpencodeRunArgs(baseOpts({ agent: "" }))).toThrow(
53
+ /agent is required/,
54
+ );
55
+ });
56
+ });
57
+
58
+ describe("buildOpencodeRunArgs — Bug 2 regression: migrated model ID", () => {
59
+ it("emits --model with the migrated 'minimax/minimax-m3' ID", () => {
60
+ const args = buildOpencodeRunArgs(
61
+ baseOpts({
62
+ model: { providerID: "minimax", modelID: "minimax-m3" },
63
+ }),
64
+ );
65
+ const i = args.indexOf("--model");
66
+ expect(i).toBeGreaterThanOrEqual(0);
67
+ expect(args[i + 1]).toBe("minimax/minimax-m3");
68
+ // The full flag pair proves the migration target — the OLD ID would
69
+ // be 'openrouter/minimax-m3'; the NEW ID is 'minimax/minimax-m3'.
70
+ expect(args[i + 1]).not.toBe("openrouter/minimax-m3");
71
+ });
72
+
73
+ it("emits --model with the migrated 'minimax/minimax-m2.7' ID", () => {
74
+ const args = buildOpencodeRunArgs(
75
+ baseOpts({
76
+ model: { providerID: "minimax", modelID: "minimax-m2.7" },
77
+ }),
78
+ );
79
+ expect(args[args.indexOf("--model") + 1]).toBe("minimax/minimax-m2.7");
80
+ });
81
+
82
+ it("omits --model entirely when opts.model is not provided", () => {
83
+ const args = buildOpencodeRunArgs(baseOpts({ model: undefined }));
84
+ expect(args).not.toContain("--model");
85
+ });
86
+ });
87
+
88
+ describe("buildOpencodeRunArgs — arg layout", () => {
89
+ it("starts with 'opencode' 'run'", () => {
90
+ const args = buildOpencodeRunArgs(baseOpts());
91
+ expect(args[0]).toBe("opencode");
92
+ expect(args[1]).toBe("run");
93
+ });
94
+
95
+ it("appends prompt after the -- separator", () => {
96
+ const args = buildOpencodeRunArgs(baseOpts({ prompt: "do the thing" }));
97
+ const sep = args.indexOf("--");
98
+ expect(sep).toBeGreaterThanOrEqual(0);
99
+ expect(args[sep + 1]).toBe("do the thing");
100
+ });
101
+
102
+ it("uses opts.title when provided, else defaults to bgr:<agent>:<ts>", () => {
103
+ const a = buildOpencodeRunArgs(baseOpts({ title: "custom title" }));
104
+ expect(a[a.indexOf("--title") + 1]).toBe("custom title");
105
+
106
+ const b = buildOpencodeRunArgs(baseOpts({ agent: "mimir" }));
107
+ expect(b[b.indexOf("--title") + 1]).toMatch(/^bgr:mimir:\d+$/);
108
+ });
109
+
110
+ it("wires --dir to opts.worktree and --log-level to INFO", () => {
111
+ const args = buildOpencodeRunArgs(baseOpts({ worktree: "/srv/repo" }));
112
+ expect(args[args.indexOf("--dir") + 1]).toBe("/srv/repo");
113
+ expect(args[args.indexOf("--log-level") + 1]).toBe("INFO");
114
+ });
115
+ });
@@ -75,6 +75,7 @@ function createManager(stateDir: string): {
75
75
  maxConcurrent: 8,
76
76
  toolCallCap: 250,
77
77
  logger,
78
+ worktree: "/tmp",
78
79
  serve: { worktree: "/tmp" } as never,
79
80
  http: {} as never,
80
81
  stream: new FakeEventStream() as never,