agent-bober 0.6.2 → 0.8.0
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.
- package/README.md +220 -30
- package/dist/cli/commands/eval.d.ts +2 -0
- package/dist/cli/commands/eval.d.ts.map +1 -1
- package/dist/cli/commands/eval.js +10 -0
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +357 -62
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/plan.d.ts +2 -0
- package/dist/cli/commands/plan.d.ts.map +1 -1
- package/dist/cli/commands/plan.js +10 -0
- package/dist/cli/commands/plan.js.map +1 -1
- package/dist/cli/commands/run.d.ts +2 -0
- package/dist/cli/commands/run.d.ts.map +1 -1
- package/dist/cli/commands/run.js +10 -0
- package/dist/cli/commands/run.js.map +1 -1
- package/dist/cli/commands/sprint.d.ts +2 -0
- package/dist/cli/commands/sprint.d.ts.map +1 -1
- package/dist/cli/commands/sprint.js +10 -0
- package/dist/cli/commands/sprint.js.map +1 -1
- package/dist/cli/index.js +22 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/config/schema.d.ts +160 -43
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +11 -7
- package/dist/config/schema.js.map +1 -1
- package/dist/contracts/sprint-contract.d.ts +8 -8
- package/dist/discovery/config-generator.d.ts +28 -0
- package/dist/discovery/config-generator.d.ts.map +1 -0
- package/dist/discovery/config-generator.js +225 -0
- package/dist/discovery/config-generator.js.map +1 -0
- package/dist/discovery/index.d.ts +20 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +19 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/discovery/scanner.d.ts +17 -0
- package/dist/discovery/scanner.d.ts.map +1 -0
- package/dist/discovery/scanner.js +120 -0
- package/dist/discovery/scanner.js.map +1 -0
- package/dist/discovery/scanners/ci-checks.d.ts +10 -0
- package/dist/discovery/scanners/ci-checks.d.ts.map +1 -0
- package/dist/discovery/scanners/ci-checks.js +169 -0
- package/dist/discovery/scanners/ci-checks.js.map +1 -0
- package/dist/discovery/scanners/code-conventions.d.ts +12 -0
- package/dist/discovery/scanners/code-conventions.d.ts.map +1 -0
- package/dist/discovery/scanners/code-conventions.js +216 -0
- package/dist/discovery/scanners/code-conventions.js.map +1 -0
- package/dist/discovery/scanners/documentation.d.ts +17 -0
- package/dist/discovery/scanners/documentation.d.ts.map +1 -0
- package/dist/discovery/scanners/documentation.js +92 -0
- package/dist/discovery/scanners/documentation.js.map +1 -0
- package/dist/discovery/scanners/git-conventions.d.ts +11 -0
- package/dist/discovery/scanners/git-conventions.d.ts.map +1 -0
- package/dist/discovery/scanners/git-conventions.js +128 -0
- package/dist/discovery/scanners/git-conventions.js.map +1 -0
- package/dist/discovery/scanners/package-scripts.d.ts +9 -0
- package/dist/discovery/scanners/package-scripts.d.ts.map +1 -0
- package/dist/discovery/scanners/package-scripts.js +112 -0
- package/dist/discovery/scanners/package-scripts.js.map +1 -0
- package/dist/discovery/scanners/test-conventions.d.ts +9 -0
- package/dist/discovery/scanners/test-conventions.d.ts.map +1 -0
- package/dist/discovery/scanners/test-conventions.js +231 -0
- package/dist/discovery/scanners/test-conventions.js.map +1 -0
- package/dist/discovery/synthesizer.d.ts +30 -0
- package/dist/discovery/synthesizer.d.ts.map +1 -0
- package/dist/discovery/synthesizer.js +348 -0
- package/dist/discovery/synthesizer.js.map +1 -0
- package/dist/discovery/types.d.ts +160 -0
- package/dist/discovery/types.d.ts.map +1 -0
- package/dist/discovery/types.js +9 -0
- package/dist/discovery/types.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +4 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/run-manager.d.ts +47 -0
- package/dist/mcp/run-manager.d.ts.map +1 -0
- package/dist/mcp/run-manager.js +79 -0
- package/dist/mcp/run-manager.js.map +1 -0
- package/dist/mcp/server.d.ts +15 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +107 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools/config.d.ts +2 -0
- package/dist/mcp/tools/config.d.ts.map +1 -0
- package/dist/mcp/tools/config.js +153 -0
- package/dist/mcp/tools/config.js.map +1 -0
- package/dist/mcp/tools/contracts.d.ts +2 -0
- package/dist/mcp/tools/contracts.d.ts.map +1 -0
- package/dist/mcp/tools/contracts.js +61 -0
- package/dist/mcp/tools/contracts.js.map +1 -0
- package/dist/mcp/tools/eval.d.ts +2 -0
- package/dist/mcp/tools/eval.d.ts.map +1 -0
- package/dist/mcp/tools/eval.js +157 -0
- package/dist/mcp/tools/eval.js.map +1 -0
- package/dist/mcp/tools/index.d.ts +20 -0
- package/dist/mcp/tools/index.d.ts.map +1 -0
- package/dist/mcp/tools/index.js +47 -0
- package/dist/mcp/tools/index.js.map +1 -0
- package/dist/mcp/tools/init.d.ts +2 -0
- package/dist/mcp/tools/init.d.ts.map +1 -0
- package/dist/mcp/tools/init.js +222 -0
- package/dist/mcp/tools/init.js.map +1 -0
- package/dist/mcp/tools/plan.d.ts +2 -0
- package/dist/mcp/tools/plan.d.ts.map +1 -0
- package/dist/mcp/tools/plan.js +97 -0
- package/dist/mcp/tools/plan.js.map +1 -0
- package/dist/mcp/tools/principles.d.ts +2 -0
- package/dist/mcp/tools/principles.d.ts.map +1 -0
- package/dist/mcp/tools/principles.js +66 -0
- package/dist/mcp/tools/principles.js.map +1 -0
- package/dist/mcp/tools/registry.d.ts +45 -0
- package/dist/mcp/tools/registry.d.ts.map +1 -0
- package/dist/mcp/tools/registry.js +23 -0
- package/dist/mcp/tools/registry.js.map +1 -0
- package/dist/mcp/tools/run.d.ts +2 -0
- package/dist/mcp/tools/run.d.ts.map +1 -0
- package/dist/mcp/tools/run.js +66 -0
- package/dist/mcp/tools/run.js.map +1 -0
- package/dist/mcp/tools/spec.d.ts +2 -0
- package/dist/mcp/tools/spec.d.ts.map +1 -0
- package/dist/mcp/tools/spec.js +32 -0
- package/dist/mcp/tools/spec.js.map +1 -0
- package/dist/mcp/tools/sprint.d.ts +2 -0
- package/dist/mcp/tools/sprint.d.ts.map +1 -0
- package/dist/mcp/tools/sprint.js +243 -0
- package/dist/mcp/tools/sprint.js.map +1 -0
- package/dist/mcp/tools/status.d.ts +2 -0
- package/dist/mcp/tools/status.d.ts.map +1 -0
- package/dist/mcp/tools/status.js +76 -0
- package/dist/mcp/tools/status.js.map +1 -0
- package/dist/orchestrator/agentic-loop.d.ts +7 -6
- package/dist/orchestrator/agentic-loop.d.ts.map +1 -1
- package/dist/orchestrator/agentic-loop.js +33 -40
- package/dist/orchestrator/agentic-loop.js.map +1 -1
- package/dist/orchestrator/context-handoff.d.ts +20 -20
- package/dist/orchestrator/evaluator-agent.d.ts.map +1 -1
- package/dist/orchestrator/evaluator-agent.js +2 -2
- package/dist/orchestrator/evaluator-agent.js.map +1 -1
- package/dist/orchestrator/generator-agent.d.ts.map +1 -1
- package/dist/orchestrator/generator-agent.js +2 -2
- package/dist/orchestrator/generator-agent.js.map +1 -1
- package/dist/orchestrator/model-resolver.d.ts +35 -4
- package/dist/orchestrator/model-resolver.d.ts.map +1 -1
- package/dist/orchestrator/model-resolver.js +68 -15
- package/dist/orchestrator/model-resolver.js.map +1 -1
- package/dist/orchestrator/planner-agent.d.ts.map +1 -1
- package/dist/orchestrator/planner-agent.js +2 -2
- package/dist/orchestrator/planner-agent.js.map +1 -1
- package/dist/orchestrator/tools/index.d.ts +3 -4
- package/dist/orchestrator/tools/index.d.ts.map +1 -1
- package/dist/orchestrator/tools/index.js.map +1 -1
- package/dist/orchestrator/tools/schemas.d.ts +11 -12
- package/dist/orchestrator/tools/schemas.d.ts.map +1 -1
- package/dist/orchestrator/tools/schemas.js +3 -2
- package/dist/orchestrator/tools/schemas.js.map +1 -1
- package/dist/providers/anthropic.d.ts +15 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +133 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/factory.d.ts +37 -0
- package/dist/providers/factory.d.ts.map +1 -0
- package/dist/providers/factory.js +119 -0
- package/dist/providers/factory.js.map +1 -0
- package/dist/providers/google.d.ts +39 -0
- package/dist/providers/google.d.ts.map +1 -0
- package/dist/providers/google.js +195 -0
- package/dist/providers/google.js.map +1 -0
- package/dist/providers/index.d.ts +7 -0
- package/dist/providers/index.d.ts.map +1 -0
- package/dist/providers/index.js +6 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-compat.d.ts +39 -0
- package/dist/providers/openai-compat.d.ts.map +1 -0
- package/dist/providers/openai-compat.js +42 -0
- package/dist/providers/openai-compat.js.map +1 -0
- package/dist/providers/openai.d.ts +41 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +205 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/providers/types.d.ts +144 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +8 -0
- package/dist/providers/types.js.map +1 -0
- package/package.json +22 -4
- package/skills/bober.principles/SKILL.md +36 -3
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible provider adapter.
|
|
3
|
+
*
|
|
4
|
+
* Creates an OpenAI client pointed at a custom base URL, enabling use with
|
|
5
|
+
* any OpenAI-compatible API server (e.g. Ollama, LM Studio, vLLM, Together AI).
|
|
6
|
+
*
|
|
7
|
+
* Reuses all tool conversion, message conversion, and response normalisation
|
|
8
|
+
* logic from OpenAIAdapter by extending it with a custom base URL and a
|
|
9
|
+
* default API key of "not-needed" (required by the openai SDK but ignored
|
|
10
|
+
* by servers like Ollama that don't require authentication).
|
|
11
|
+
*/
|
|
12
|
+
import { OpenAIAdapter } from "./openai.js";
|
|
13
|
+
/**
|
|
14
|
+
* LLMClient implementation for OpenAI-compatible endpoints.
|
|
15
|
+
*
|
|
16
|
+
* Extends OpenAIAdapter with a required `endpoint` (baseURL) parameter.
|
|
17
|
+
* All tool conversion and response normalisation is inherited from
|
|
18
|
+
* OpenAIAdapter — only the client configuration differs.
|
|
19
|
+
*
|
|
20
|
+
* Usage example (Ollama):
|
|
21
|
+
* ```ts
|
|
22
|
+
* const client = new OpenAICompatAdapter(
|
|
23
|
+
* "http://localhost:11434/v1",
|
|
24
|
+
* "llama3",
|
|
25
|
+
* );
|
|
26
|
+
* ```
|
|
27
|
+
*/
|
|
28
|
+
export class OpenAICompatAdapter extends OpenAIAdapter {
|
|
29
|
+
/**
|
|
30
|
+
* @param endpoint - Required base URL of the OpenAI-compatible server
|
|
31
|
+
* (e.g. "http://localhost:11434/v1" for Ollama).
|
|
32
|
+
* @param model - Model identifier to use with this server.
|
|
33
|
+
* @param apiKey - Optional API key. Defaults to "not-needed" for servers
|
|
34
|
+
* that do not require authentication (e.g. Ollama).
|
|
35
|
+
*/
|
|
36
|
+
constructor(endpoint, model, apiKey) {
|
|
37
|
+
// Pass "not-needed" as apiKey default — the openai SDK requires a non-empty
|
|
38
|
+
// value but OpenAI-compat servers (like Ollama) typically ignore it.
|
|
39
|
+
super(model, apiKey ?? "not-needed", endpoint);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=openai-compat.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compat.js","sourceRoot":"","sources":["../../src/providers/openai-compat.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAG5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,mBAAoB,SAAQ,aAAa;IACpD;;;;;;OAMG;IACH,YAAY,QAAgB,EAAE,KAAa,EAAE,MAAe;QAC1D,4EAA4E;QAC5E,qEAAqE;QACrE,KAAK,CAAC,KAAK,EAAE,MAAM,IAAI,YAAY,EAAE,QAAQ,CAAC,CAAC;IACjD,CAAC;CACF"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI provider adapter.
|
|
3
|
+
*
|
|
4
|
+
* Uses a dynamic import so the `openai` package is an optional peer dependency.
|
|
5
|
+
* If the package is not installed, a clear installation error is thrown at
|
|
6
|
+
* call-time rather than at module load time.
|
|
7
|
+
*
|
|
8
|
+
* All OpenAI SDK types are inlined below so this file compiles without the
|
|
9
|
+
* `openai` package present in node_modules.
|
|
10
|
+
*/
|
|
11
|
+
import type { LLMClient, ChatParams, ChatResponse } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* LLMClient implementation that wraps the OpenAI chat completions API.
|
|
14
|
+
*
|
|
15
|
+
* The `openai` npm package is dynamically imported so it remains an optional
|
|
16
|
+
* peer dependency. If the package is absent a descriptive install error is
|
|
17
|
+
* thrown on the first call.
|
|
18
|
+
*
|
|
19
|
+
* Supports:
|
|
20
|
+
* - Function/tool calling via the tools array format
|
|
21
|
+
* - Parallel tool calls
|
|
22
|
+
* - Custom base URL for OpenAI-compatible endpoints
|
|
23
|
+
* - Optional provider-level configuration
|
|
24
|
+
*/
|
|
25
|
+
export declare class OpenAIAdapter implements LLMClient {
|
|
26
|
+
private readonly model;
|
|
27
|
+
private readonly apiKey;
|
|
28
|
+
private readonly baseURL;
|
|
29
|
+
private readonly providerConfig;
|
|
30
|
+
/** Lazily initialised after the dynamic import succeeds. */
|
|
31
|
+
private client;
|
|
32
|
+
constructor(model: string, apiKey?: string, endpoint?: string, providerConfig?: Record<string, unknown>);
|
|
33
|
+
/**
|
|
34
|
+
* Lazily import the `openai` package and return the initialised client.
|
|
35
|
+
*
|
|
36
|
+
* @throws If the `openai` package is not installed.
|
|
37
|
+
*/
|
|
38
|
+
private getClient;
|
|
39
|
+
chat(params: ChatParams): Promise<ChatResponse>;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,SAAS,EACT,UAAU,EACV,YAAY,EAKb,MAAM,YAAY,CAAC;AA0MpB;;;;;;;;;;;;GAYG;AACH,qBAAa,aAAc,YAAW,SAAS;IAC7C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAsC;IAErE,4DAA4D;IAC5D,OAAO,CAAC,MAAM,CAA8B;gBAG1C,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,EACjB,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAQ1C;;;;OAIG;YACW,SAAS;IAqCjB,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC;CA8CtD"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI provider adapter.
|
|
3
|
+
*
|
|
4
|
+
* Uses a dynamic import so the `openai` package is an optional peer dependency.
|
|
5
|
+
* If the package is not installed, a clear installation error is thrown at
|
|
6
|
+
* call-time rather than at module load time.
|
|
7
|
+
*
|
|
8
|
+
* All OpenAI SDK types are inlined below so this file compiles without the
|
|
9
|
+
* `openai` package present in node_modules.
|
|
10
|
+
*/
|
|
11
|
+
// ── Conversion helpers ──────────────────────────────────────────────
|
|
12
|
+
/**
|
|
13
|
+
* Convert a provider-agnostic ToolDef to OpenAI function calling format.
|
|
14
|
+
*/
|
|
15
|
+
function toOpenAITool(tool) {
|
|
16
|
+
return {
|
|
17
|
+
type: "function",
|
|
18
|
+
function: {
|
|
19
|
+
name: tool.name,
|
|
20
|
+
description: tool.description,
|
|
21
|
+
// input_schema is already a JSON Schema object; OpenAI uses `parameters`
|
|
22
|
+
parameters: tool.input_schema,
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Normalize the OpenAI finish_reason to our StopReason type.
|
|
28
|
+
*/
|
|
29
|
+
function normalizeStopReason(finishReason) {
|
|
30
|
+
switch (finishReason) {
|
|
31
|
+
case "stop":
|
|
32
|
+
return "end";
|
|
33
|
+
case "tool_calls":
|
|
34
|
+
return "tool_use";
|
|
35
|
+
case "length":
|
|
36
|
+
return "max_tokens";
|
|
37
|
+
default:
|
|
38
|
+
return finishReason ?? "end";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Convert a provider-agnostic Message to one or more OpenAI request messages.
|
|
43
|
+
*
|
|
44
|
+
* Returns an array because ToolResultMessage expands into one OAI tool
|
|
45
|
+
* message per tool result (OpenAI requires separate messages per tool call).
|
|
46
|
+
*/
|
|
47
|
+
function toOpenAIMessages(message) {
|
|
48
|
+
// ToolResultMessage → one role:"tool" message per result
|
|
49
|
+
if ("toolResults" in message) {
|
|
50
|
+
return message.toolResults.map((tr) => ({
|
|
51
|
+
role: "tool",
|
|
52
|
+
tool_call_id: tr.toolUseId,
|
|
53
|
+
content: tr.content,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
// AssistantMessage → role:"assistant" with optional tool_calls
|
|
57
|
+
if ("toolCalls" in message && message.toolCalls.length > 0) {
|
|
58
|
+
const oaiMsg = {
|
|
59
|
+
role: "assistant",
|
|
60
|
+
content: message.content || null,
|
|
61
|
+
tool_calls: message.toolCalls.map((tc) => ({
|
|
62
|
+
id: tc.id,
|
|
63
|
+
type: "function",
|
|
64
|
+
function: {
|
|
65
|
+
name: tc.name,
|
|
66
|
+
arguments: JSON.stringify(tc.input),
|
|
67
|
+
},
|
|
68
|
+
})),
|
|
69
|
+
};
|
|
70
|
+
return [oaiMsg];
|
|
71
|
+
}
|
|
72
|
+
// TextMessage (user or assistant without tool calls)
|
|
73
|
+
const textMsg = message;
|
|
74
|
+
if (textMsg.role === "user") {
|
|
75
|
+
return [{ role: "user", content: textMsg.content }];
|
|
76
|
+
}
|
|
77
|
+
// Plain assistant text message (no tool calls)
|
|
78
|
+
return [{ role: "assistant", content: textMsg.content }];
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Parse tool_calls from an OAI response message into ToolCall[].
|
|
82
|
+
*
|
|
83
|
+
* Guards against an empty array (treated as no tool calls) and handles
|
|
84
|
+
* JSON parse errors in arguments gracefully.
|
|
85
|
+
*/
|
|
86
|
+
function normalizeToolCalls(toolCalls) {
|
|
87
|
+
if (!toolCalls || toolCalls.length === 0) {
|
|
88
|
+
return [];
|
|
89
|
+
}
|
|
90
|
+
return toolCalls.map((tc) => {
|
|
91
|
+
let input = {};
|
|
92
|
+
try {
|
|
93
|
+
const parsed = JSON.parse(tc.function.arguments);
|
|
94
|
+
if (parsed !== null && typeof parsed === "object" && !Array.isArray(parsed)) {
|
|
95
|
+
input = parsed;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
catch {
|
|
99
|
+
// Malformed JSON from the model — fall back to empty input
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
id: tc.id,
|
|
103
|
+
name: tc.function.name,
|
|
104
|
+
input,
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
// ── OpenAIAdapter ────────────────────────────────────────────────────
|
|
109
|
+
/**
|
|
110
|
+
* LLMClient implementation that wraps the OpenAI chat completions API.
|
|
111
|
+
*
|
|
112
|
+
* The `openai` npm package is dynamically imported so it remains an optional
|
|
113
|
+
* peer dependency. If the package is absent a descriptive install error is
|
|
114
|
+
* thrown on the first call.
|
|
115
|
+
*
|
|
116
|
+
* Supports:
|
|
117
|
+
* - Function/tool calling via the tools array format
|
|
118
|
+
* - Parallel tool calls
|
|
119
|
+
* - Custom base URL for OpenAI-compatible endpoints
|
|
120
|
+
* - Optional provider-level configuration
|
|
121
|
+
*/
|
|
122
|
+
export class OpenAIAdapter {
|
|
123
|
+
model;
|
|
124
|
+
apiKey;
|
|
125
|
+
baseURL;
|
|
126
|
+
providerConfig;
|
|
127
|
+
/** Lazily initialised after the dynamic import succeeds. */
|
|
128
|
+
client = null;
|
|
129
|
+
constructor(model, apiKey, endpoint, providerConfig) {
|
|
130
|
+
this.model = model;
|
|
131
|
+
this.apiKey = apiKey;
|
|
132
|
+
this.baseURL = endpoint;
|
|
133
|
+
this.providerConfig = providerConfig;
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Lazily import the `openai` package and return the initialised client.
|
|
137
|
+
*
|
|
138
|
+
* @throws If the `openai` package is not installed.
|
|
139
|
+
*/
|
|
140
|
+
async getClient() {
|
|
141
|
+
if (this.client) {
|
|
142
|
+
return this.client;
|
|
143
|
+
}
|
|
144
|
+
let OpenAI;
|
|
145
|
+
try {
|
|
146
|
+
// Construct the specifier at runtime so TypeScript does not attempt
|
|
147
|
+
// to statically resolve the optional peer dependency at compile time.
|
|
148
|
+
const specifier = "openai";
|
|
149
|
+
const mod = (await import(/* @vite-ignore */ specifier));
|
|
150
|
+
// Handle both ESM default export and CommonJS-style .default wrapping
|
|
151
|
+
OpenAI = (mod["default"] ?? mod);
|
|
152
|
+
}
|
|
153
|
+
catch {
|
|
154
|
+
throw new Error('OpenAI provider requires the "openai" package. Run: npm install openai');
|
|
155
|
+
}
|
|
156
|
+
const apiKey = this.apiKey ??
|
|
157
|
+
(typeof this.providerConfig?.["apiKey"] === "string"
|
|
158
|
+
? this.providerConfig["apiKey"]
|
|
159
|
+
: process.env["OPENAI_API_KEY"]);
|
|
160
|
+
this.client = new OpenAI({
|
|
161
|
+
apiKey,
|
|
162
|
+
...(this.baseURL ? { baseURL: this.baseURL } : {}),
|
|
163
|
+
});
|
|
164
|
+
return this.client;
|
|
165
|
+
}
|
|
166
|
+
async chat(params) {
|
|
167
|
+
const { model, system, messages, tools, maxTokens = 16384 } = params;
|
|
168
|
+
const client = await this.getClient();
|
|
169
|
+
// Build the messages array: system message first, then conversation
|
|
170
|
+
const oaiMessages = [
|
|
171
|
+
{ role: "system", content: system },
|
|
172
|
+
...messages.flatMap(toOpenAIMessages),
|
|
173
|
+
];
|
|
174
|
+
// Convert ToolDef[] to OpenAI tools format
|
|
175
|
+
const oaiTools = tools && tools.length > 0 ? tools.map(toOpenAITool) : undefined;
|
|
176
|
+
const response = await client.chat.completions.create({
|
|
177
|
+
model: model || this.model,
|
|
178
|
+
messages: oaiMessages,
|
|
179
|
+
...(oaiTools ? { tools: oaiTools } : {}),
|
|
180
|
+
max_tokens: maxTokens,
|
|
181
|
+
});
|
|
182
|
+
const choice = response.choices[0];
|
|
183
|
+
if (!choice) {
|
|
184
|
+
return {
|
|
185
|
+
text: "",
|
|
186
|
+
toolCalls: [],
|
|
187
|
+
stopReason: "error",
|
|
188
|
+
usage: { inputTokens: 0, outputTokens: 0 },
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
const text = choice.message.content ?? "";
|
|
192
|
+
const toolCalls = normalizeToolCalls(choice.message.tool_calls);
|
|
193
|
+
const stopReason = normalizeStopReason(choice.finish_reason);
|
|
194
|
+
return {
|
|
195
|
+
text,
|
|
196
|
+
toolCalls,
|
|
197
|
+
stopReason,
|
|
198
|
+
usage: {
|
|
199
|
+
inputTokens: response.usage?.prompt_tokens ?? 0,
|
|
200
|
+
outputTokens: response.usage?.completion_tokens ?? 0,
|
|
201
|
+
},
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider-agnostic LLM interface types.
|
|
3
|
+
*
|
|
4
|
+
* These types decouple agent-bober from any specific LLM SDK. All provider
|
|
5
|
+
* adapters (Anthropic, OpenAI, etc.) convert to/from these types.
|
|
6
|
+
*/
|
|
7
|
+
export interface JsonSchemaProperty {
|
|
8
|
+
type: string;
|
|
9
|
+
description?: string;
|
|
10
|
+
enum?: string[];
|
|
11
|
+
items?: JsonSchemaProperty;
|
|
12
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
13
|
+
required?: string[];
|
|
14
|
+
}
|
|
15
|
+
export interface JsonSchemaObject {
|
|
16
|
+
type: "object";
|
|
17
|
+
properties?: Record<string, JsonSchemaProperty>;
|
|
18
|
+
required?: string[];
|
|
19
|
+
additionalProperties?: boolean;
|
|
20
|
+
/** Allow extra keys so this type is assignable to Anthropic's InputSchema (which has [k: string]: unknown). */
|
|
21
|
+
[key: string]: unknown;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Provider-agnostic tool definition.
|
|
25
|
+
*
|
|
26
|
+
* Uses plain JSON Schema for parameters (no SDK-specific types).
|
|
27
|
+
* Maps directly to the Anthropic Tool shape (input_schema → parameters)
|
|
28
|
+
* and to OpenAI function calling format.
|
|
29
|
+
*/
|
|
30
|
+
export interface ToolDef {
|
|
31
|
+
/** Unique tool name (snake_case). */
|
|
32
|
+
name: string;
|
|
33
|
+
/** Human-readable description of what the tool does. */
|
|
34
|
+
description: string;
|
|
35
|
+
/** JSON Schema object describing the tool's input parameters. */
|
|
36
|
+
input_schema: JsonSchemaObject;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* A single tool invocation requested by the model.
|
|
40
|
+
*/
|
|
41
|
+
export interface ToolCall {
|
|
42
|
+
/** Unique ID for this tool call (used to correlate results). */
|
|
43
|
+
id: string;
|
|
44
|
+
/** Tool name. */
|
|
45
|
+
name: string;
|
|
46
|
+
/** Parsed input arguments. */
|
|
47
|
+
input: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* A tool result item, returned by the agent after executing a tool.
|
|
51
|
+
* Used within ToolResultMessage to correlate results with tool call IDs.
|
|
52
|
+
*/
|
|
53
|
+
export interface ToolResult {
|
|
54
|
+
/** The ID of the tool call this result corresponds to. */
|
|
55
|
+
toolUseId: string;
|
|
56
|
+
/** The output text from the tool execution. */
|
|
57
|
+
content: string;
|
|
58
|
+
/** Whether this result represents a tool execution error. */
|
|
59
|
+
isError?: boolean;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* An assistant message that contains both optional text and tool call requests.
|
|
63
|
+
*/
|
|
64
|
+
export interface AssistantMessage {
|
|
65
|
+
role: "assistant";
|
|
66
|
+
/** Text portion of the response (may be empty when only tool calls are present). */
|
|
67
|
+
content: string;
|
|
68
|
+
/** Tool calls the assistant wants to execute. */
|
|
69
|
+
toolCalls: ToolCall[];
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* A user message that carries tool execution results back to the model.
|
|
73
|
+
*/
|
|
74
|
+
export interface ToolResultMessage {
|
|
75
|
+
role: "user";
|
|
76
|
+
/** Tool results keyed by tool call ID. */
|
|
77
|
+
toolResults: ToolResult[];
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* A plain text message from user or assistant.
|
|
81
|
+
*/
|
|
82
|
+
export interface TextMessage {
|
|
83
|
+
role: "user" | "assistant";
|
|
84
|
+
/** Text content. */
|
|
85
|
+
content: string;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* A message in the conversation history.
|
|
89
|
+
*
|
|
90
|
+
* Three variants:
|
|
91
|
+
* - TextMessage: plain user or assistant text
|
|
92
|
+
* - AssistantMessage: assistant response that includes tool call requests
|
|
93
|
+
* - ToolResultMessage: user message carrying tool execution results
|
|
94
|
+
*/
|
|
95
|
+
export type Message = TextMessage | AssistantMessage | ToolResultMessage;
|
|
96
|
+
/**
|
|
97
|
+
* Parameters for a single LLM chat request.
|
|
98
|
+
*/
|
|
99
|
+
export interface ChatParams {
|
|
100
|
+
/** Model identifier (resolved by the factory / model-resolver). */
|
|
101
|
+
model: string;
|
|
102
|
+
/** System prompt. */
|
|
103
|
+
system: string;
|
|
104
|
+
/** Conversation history. */
|
|
105
|
+
messages: Message[];
|
|
106
|
+
/** Tools available to the model for this request. */
|
|
107
|
+
tools?: ToolDef[];
|
|
108
|
+
/** Maximum tokens to generate. Defaults to 16384. */
|
|
109
|
+
maxTokens?: number;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Stop reason indicating why the model stopped generating.
|
|
113
|
+
*/
|
|
114
|
+
export type StopReason = "end" | "tool_use" | "max_tokens" | "error" | string;
|
|
115
|
+
/**
|
|
116
|
+
* Normalized response from a single LLM chat request.
|
|
117
|
+
*/
|
|
118
|
+
export interface ChatResponse {
|
|
119
|
+
/** The assistant's text response (may be empty if only tool calls). */
|
|
120
|
+
text: string;
|
|
121
|
+
/** Tool calls requested by the model (may be empty). */
|
|
122
|
+
toolCalls: ToolCall[];
|
|
123
|
+
/** Why the model stopped generating. */
|
|
124
|
+
stopReason: StopReason;
|
|
125
|
+
/** Token usage for this request. */
|
|
126
|
+
usage: {
|
|
127
|
+
inputTokens: number;
|
|
128
|
+
outputTokens: number;
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Unified interface for all LLM provider adapters.
|
|
133
|
+
*
|
|
134
|
+
* Implementations must handle tool conversion to/from their native
|
|
135
|
+
* format and normalize responses to ChatResponse.
|
|
136
|
+
*/
|
|
137
|
+
export interface LLMClient {
|
|
138
|
+
/**
|
|
139
|
+
* Send a chat request to the underlying provider and return a
|
|
140
|
+
* normalized ChatResponse.
|
|
141
|
+
*/
|
|
142
|
+
chat(params: ChatParams): Promise<ChatResponse>;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/providers/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agent-bober",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Generator-Evaluator multi-agent harness for building applications autonomously with
|
|
3
|
+
"version": "0.8.0",
|
|
4
|
+
"description": "Generator-Evaluator multi-agent harness for building applications autonomously with any LLM. Supports Claude, GPT, Gemini, Ollama. Includes MCP server for Cursor/Windsurf.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -17,18 +17,23 @@
|
|
|
17
17
|
"prepublishOnly": "npm run build"
|
|
18
18
|
},
|
|
19
19
|
"keywords": [
|
|
20
|
-
"claude",
|
|
21
20
|
"agent",
|
|
22
21
|
"harness",
|
|
23
22
|
"multi-agent",
|
|
24
23
|
"autonomous",
|
|
25
24
|
"generator-evaluator",
|
|
26
25
|
"claude-code",
|
|
26
|
+
"cursor",
|
|
27
|
+
"mcp",
|
|
28
|
+
"claude",
|
|
29
|
+
"openai",
|
|
30
|
+
"gemini",
|
|
31
|
+
"ollama",
|
|
27
32
|
"plugin"
|
|
28
33
|
],
|
|
29
34
|
"author": "BOBER3r",
|
|
30
35
|
"license": "MIT",
|
|
31
|
-
"homepage": "https://
|
|
36
|
+
"homepage": "https://agentbober.com",
|
|
32
37
|
"repository": {
|
|
33
38
|
"type": "git",
|
|
34
39
|
"url": "git+https://github.com/BOBER3r/agent-bober.git"
|
|
@@ -50,6 +55,7 @@
|
|
|
50
55
|
],
|
|
51
56
|
"dependencies": {
|
|
52
57
|
"@anthropic-ai/sdk": "^0.39.0",
|
|
58
|
+
"@modelcontextprotocol/sdk": "^1.28.0",
|
|
53
59
|
"chalk": "^5.4.1",
|
|
54
60
|
"commander": "^13.1.0",
|
|
55
61
|
"execa": "^9.5.2",
|
|
@@ -58,6 +64,18 @@
|
|
|
58
64
|
"prompts": "^2.4.2",
|
|
59
65
|
"zod": "^3.24.2"
|
|
60
66
|
},
|
|
67
|
+
"peerDependencies": {
|
|
68
|
+
"@google/generative-ai": ">=0.21.0",
|
|
69
|
+
"openai": ">=4.0.0"
|
|
70
|
+
},
|
|
71
|
+
"peerDependenciesMeta": {
|
|
72
|
+
"openai": {
|
|
73
|
+
"optional": true
|
|
74
|
+
},
|
|
75
|
+
"@google/generative-ai": {
|
|
76
|
+
"optional": true
|
|
77
|
+
}
|
|
78
|
+
},
|
|
61
79
|
"devDependencies": {
|
|
62
80
|
"@eslint/js": "^10.0.1",
|
|
63
81
|
"@types/node": "^22.13.0",
|
|
@@ -37,7 +37,40 @@ If the user wants to update, proceed to Step 3 with the existing content as a st
|
|
|
37
37
|
|
|
38
38
|
Proceed to Step 2.
|
|
39
39
|
|
|
40
|
-
## Step 2:
|
|
40
|
+
## Step 2: Auto-Discovery (Brownfield mode)
|
|
41
|
+
|
|
42
|
+
**Check this FIRST before interviewing the user.**
|
|
43
|
+
|
|
44
|
+
If `bober.config.json` exists with `"mode": "brownfield"` AND no arguments were provided to this command:
|
|
45
|
+
|
|
46
|
+
1. **Run the auto-discovery pipeline** — analyze the codebase to discover conventions:
|
|
47
|
+
- Read and parse `package.json` to detect scripts, dependencies, and package manager
|
|
48
|
+
- Scan `.github/workflows/` or `.gitlab-ci.yml` to identify CI checks
|
|
49
|
+
- Read recent git log to detect commit style (conventional commits, prefix patterns)
|
|
50
|
+
- Sample source files to detect naming conventions, import style, export style, TypeScript patterns
|
|
51
|
+
- Find test files to identify the testing framework and file patterns
|
|
52
|
+
|
|
53
|
+
2. **Generate principles from discovered patterns** — synthesize the discovered conventions into a structured `principles.md` document using the same format as Step 3. Ground every rule in actual evidence from the codebase scan.
|
|
54
|
+
|
|
55
|
+
3. **Show the generated principles** to the user:
|
|
56
|
+
```
|
|
57
|
+
I analyzed your codebase and discovered these conventions:
|
|
58
|
+
|
|
59
|
+
<generated principles content>
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
4. **Ask for additions or confirmation:**
|
|
63
|
+
```
|
|
64
|
+
Want to add or modify anything? You can provide additional notes or say "looks good".
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
5. **If the user provides additions**, merge them into the generated principles document. Expand any short notes into full principle statements following the quality rules in Step 3.
|
|
68
|
+
|
|
69
|
+
6. **Save to `.bober/principles.md`** and proceed to Step 4 (Confirm and Report).
|
|
70
|
+
|
|
71
|
+
The existing interview flow (below) applies only to greenfield projects or when arguments are provided.
|
|
72
|
+
|
|
73
|
+
## Step 2a: Interview the User (Greenfield or with args)
|
|
41
74
|
|
|
42
75
|
Ask the user 3-5 targeted questions to understand their project principles. Adapt the questions based on whether `bober.config.json` exists and what it reveals about the project type.
|
|
43
76
|
|
|
@@ -80,7 +113,7 @@ E) Not applicable (no UI in this project)
|
|
|
80
113
|
F) Other (please describe)
|
|
81
114
|
```
|
|
82
115
|
|
|
83
|
-
## Step
|
|
116
|
+
## Step 2b: Expand Raw Input (if user provides a prompt/argument)
|
|
84
117
|
|
|
85
118
|
If the user provides text with this command — whether a short note like `"performance-first, minimal dependencies"` or a long paste of requirements, a PRD, or rough notes — your job is to **intelligently expand and elevate** that input into a polished principles document:
|
|
86
119
|
|
|
@@ -92,7 +125,7 @@ If the user provides text with this command — whether a short note like `"perf
|
|
|
92
125
|
|
|
93
126
|
The goal: the user pastes rough notes, you produce a comprehensive, opinionated principles document that makes them say "yes, exactly — and I didn't even think of those."
|
|
94
127
|
|
|
95
|
-
Skip the interview (Step
|
|
128
|
+
Skip the interview (Step 2a) entirely when the user provides substantive input. Go straight to generating the document.
|
|
96
129
|
|
|
97
130
|
## Step 3: Generate Principles Document
|
|
98
131
|
|