@lanjak/council 0.0.0-stage → 0.5.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 +512 -2
- package/dist/artifacts.d.ts +24 -0
- package/dist/artifacts.js +227 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/blocks.d.ts +12 -0
- package/dist/blocks.js +197 -0
- package/dist/blocks.js.map +1 -0
- package/dist/chairman.d.ts +7 -0
- package/dist/chairman.js +51 -0
- package/dist/chairman.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +109 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/debate.d.ts +15 -0
- package/dist/commands/debate.js +172 -0
- package/dist/commands/debate.js.map +1 -0
- package/dist/commands/home.d.ts +1 -0
- package/dist/commands/home.js +27 -0
- package/dist/commands/home.js.map +1 -0
- package/dist/commands/hook.d.ts +3 -0
- package/dist/commands/hook.js +138 -0
- package/dist/commands/hook.js.map +1 -0
- package/dist/commands/plan.d.ts +6 -0
- package/dist/commands/plan.js +23 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/review.d.ts +18 -0
- package/dist/commands/review.js +37 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/setup.js +23 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.js +101 -0
- package/dist/config.js.map +1 -0
- package/dist/council.d.ts +3 -0
- package/dist/council.js +61 -0
- package/dist/council.js.map +1 -0
- package/dist/debate/loop.d.ts +28 -0
- package/dist/debate/loop.js +188 -0
- package/dist/debate/loop.js.map +1 -0
- package/dist/debate/prompts.d.ts +10 -0
- package/dist/debate/prompts.js +47 -0
- package/dist/debate/prompts.js.map +1 -0
- package/dist/debate/render.d.ts +22 -0
- package/dist/debate/render.js +112 -0
- package/dist/debate/render.js.map +1 -0
- package/dist/debate/session.d.ts +7 -0
- package/dist/debate/session.js +85 -0
- package/dist/debate/session.js.map +1 -0
- package/dist/errors.d.ts +5 -0
- package/dist/errors.js +18 -0
- package/dist/errors.js.map +1 -0
- package/dist/exit.d.ts +7 -0
- package/dist/exit.js +13 -0
- package/dist/exit.js.map +1 -0
- package/dist/hooks/gate.d.ts +12 -0
- package/dist/hooks/gate.js +41 -0
- package/dist/hooks/gate.js.map +1 -0
- package/dist/hooks/payload.d.ts +8 -0
- package/dist/hooks/payload.js +63 -0
- package/dist/hooks/payload.js.map +1 -0
- package/dist/hooks/state.d.ts +6 -0
- package/dist/hooks/state.js +73 -0
- package/dist/hooks/state.js.map +1 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/input.d.ts +14 -0
- package/dist/input.js +30 -0
- package/dist/input.js.map +1 -0
- package/dist/output.d.ts +3 -0
- package/dist/output.js +80 -0
- package/dist/output.js.map +1 -0
- package/dist/prompts.d.ts +3 -0
- package/dist/prompts.js +48 -0
- package/dist/prompts.js.map +1 -0
- package/dist/providers/anthropic.d.ts +12 -0
- package/dist/providers/anthropic.js +98 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/base.d.ts +35 -0
- package/dist/providers/base.js +7 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/constants.d.ts +2 -0
- package/dist/providers/constants.js +11 -0
- package/dist/providers/constants.js.map +1 -0
- package/dist/providers/index.d.ts +6 -0
- package/dist/providers/index.js +20 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/openai-compatible.d.ts +12 -0
- package/dist/providers/openai-compatible.js +68 -0
- package/dist/providers/openai-compatible.js.map +1 -0
- package/dist/runners/plan.d.ts +14 -0
- package/dist/runners/plan.js +43 -0
- package/dist/runners/plan.js.map +1 -0
- package/dist/runners/review.d.ts +14 -0
- package/dist/runners/review.js +45 -0
- package/dist/runners/review.js.map +1 -0
- package/dist/stdin.d.ts +9 -0
- package/dist/stdin.js +51 -0
- package/dist/stdin.js.map +1 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/verdict.d.ts +2 -0
- package/dist/verdict.js +12 -0
- package/dist/verdict.js.map +1 -0
- package/package.json +54 -4
- package/skills/council/SKILL.md +82 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAC;AAC1C,OAAO,EAAE,WAAW,EAA6D,MAAM,WAAW,CAAC;AAEnG,OAAO,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAC;AAE9D,MAAM,OAAO,iBAAkB,SAAQ,WAAW;IACvC,IAAI,CAAS;IACb,WAAW,CAAS;IACpB,YAAY,CAAuB;IAClC,MAAM,CAAY;IAE5B,YAAY,MAAsB;QAChC,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,SAAS,CAAC;QACrC,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,IAAI,IAAI,kBAAkB,CAAC;QAC3E,IAAI,CAAC,YAAY,GAAG,EAAE,iBAAiB,EAAE,KAAK,EAAE,gBAAgB,EAAE,KAAK,EAAE,CAAC;QAC1E,qEAAqE;QACrE,wEAAwE;QACxE,oEAAoE;QACpE,uDAAuD;QACvD,IAAI,CAAC,MAAM,GAAG,IAAI,SAAS,CAAC;YAC1B,MAAM,EAAE,MAAM,CAAC,MAAM;YACrB,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACvD,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAS;QACb,qEAAqE;QACrE,wEAAwE;QACxE,+DAA+D;QAC/D,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;YACxB,OAAO;gBACL,SAAS,EAAE,IAAI;gBACf,aAAa,EAAE,KAAK;gBACpB,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,qBAAqB;aACjD,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,iBAAiB,EAAE,CAAC;IAChG,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;QACnE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;QAEnE,sEAAsE;QACtE,uEAAuE;QACvE,sEAAsE;QACtE,mEAAmE;QACnE,qEAAqE;QACrE,kEAAkE;QAClE,8CAA8C;QAC9C,uEAAuE;QACvE,gEAAgE;QAChE,iEAAiE;QACjE,sEAAsE;QACtE,qDAAqD;QACrD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ;aACxC,MAAM,CAAC;YACN,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,SAAS;gBACtD,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE;gBACrE,CAAC,CAAC,EAAE,CAAC;YACP,UAAU,EAAE,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,IAAI,4BAA4B;YACtF,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC7B,GAAG,CAAC,WAAW,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtD,CAAC;aACD,YAAY,EAAE,CAAC;QAElB,wEAAwE;QACxE,uEAAuE;QACvE,wEAAwE;QACxE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO;aAC7B,MAAM,CAAC,CAAC,KAAK,EAAgC,EAAE,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC;aACtE,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC;aAC1B,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,wEAAwE;QACxE,wEAAwE;QACxE,wEAAwE;QACxE,+BAA+B;QAC/B,EAAE;QACF,sEAAsE;QACtE,sEAAsE;QACtE,uEAAuE;QACvE,uEAAuE;QACvE,iEAAiE;QACjE,sEAAsE;QACtE,oEAAoE;QACpE,uEAAuE;QACvE,kEAAkE;QAClE,uEAAuE;QACvE,mEAAmE;QACnE,aAAa;QACb,MAAM,KAAK,GAAG;YACZ,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC;YAC7C,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC;YAC/C,WAAW,EACT,CAAC,QAAQ,CAAC,KAAK,CAAC,YAAY,IAAI,CAAC,CAAC;gBAClC,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,CAAC;gBACnC,CAAC,QAAQ,CAAC,KAAK,CAAC,2BAA2B,IAAI,CAAC,CAAC;gBACjD,CAAC,QAAQ,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,CAAC;SAChD,CAAC;QAEF,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;CACF"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { ProviderConfig, RunControls } from '../types.js';
|
|
2
|
+
export interface ChatOptions extends RunControls {
|
|
3
|
+
prompt: string;
|
|
4
|
+
system?: string;
|
|
5
|
+
model: string;
|
|
6
|
+
temperature?: number;
|
|
7
|
+
jsonMode?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export interface ChatResult {
|
|
10
|
+
content: string;
|
|
11
|
+
reasoning?: string;
|
|
12
|
+
usage?: {
|
|
13
|
+
inputTokens: number;
|
|
14
|
+
outputTokens: number;
|
|
15
|
+
totalTokens: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export interface AuthResult {
|
|
19
|
+
available: boolean;
|
|
20
|
+
authenticated: boolean;
|
|
21
|
+
detail: string;
|
|
22
|
+
}
|
|
23
|
+
export interface ProviderCapabilities {
|
|
24
|
+
supportsReasoning: boolean;
|
|
25
|
+
supportsJsonMode: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare abstract class LLMProvider {
|
|
28
|
+
protected config: ProviderConfig;
|
|
29
|
+
abstract readonly name: string;
|
|
30
|
+
abstract readonly displayName: string;
|
|
31
|
+
abstract readonly capabilities: ProviderCapabilities;
|
|
32
|
+
constructor(config: ProviderConfig);
|
|
33
|
+
abstract checkAuth(): Promise<AuthResult>;
|
|
34
|
+
abstract chat(options: ChatOptions): Promise<ChatResult>;
|
|
35
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base.js","sourceRoot":"","sources":["../../src/providers/base.ts"],"names":[],"mappings":"AA2BA,MAAM,OAAgB,WAAW;IAKT;IAAtB,YAAsB,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;CAIjD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
// Reasoning models spend a large share of their completion budget on hidden
|
|
2
|
+
// thinking tokens, so a low cap truncates the visible answer mid-sentence.
|
|
3
|
+
// mimo-v2.5-pro and deepseek-v4-pro both support 65536; default generously and
|
|
4
|
+
// let per-call maxTokens or ${PREFIX}_MAX_TOKENS override the default.
|
|
5
|
+
export const DEFAULT_OPENAI_MAX_TOKENS = 32768;
|
|
6
|
+
// Anthropic's max output tokens is model-specific and historically lower
|
|
7
|
+
// than the OpenAI-compatible default for some models; a shared default
|
|
8
|
+
// risks every request failing until a user overrides ${PREFIX}_MAX_TOKENS.
|
|
9
|
+
// 8192 is safe across current Claude models while still generous.
|
|
10
|
+
export const DEFAULT_ANTHROPIC_MAX_TOKENS = 8192;
|
|
11
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/providers/constants.ts"],"names":[],"mappings":"AAAA,4EAA4E;AAC5E,2EAA2E;AAC3E,+EAA+E;AAC/E,uEAAuE;AACvE,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAE/C,yEAAyE;AACzE,uEAAuE;AACvE,2EAA2E;AAC3E,kEAAkE;AAClE,MAAM,CAAC,MAAM,4BAA4B,GAAG,IAAI,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { LLMProvider } from './base.js';
|
|
2
|
+
import { OpenAICompatibleProvider } from './openai-compatible.js';
|
|
3
|
+
import { AnthropicProvider } from './anthropic.js';
|
|
4
|
+
import type { ProviderConfig } from '../types.js';
|
|
5
|
+
export declare function loadProvider(name: string, config: ProviderConfig): LLMProvider;
|
|
6
|
+
export { LLMProvider, OpenAICompatibleProvider, AnthropicProvider };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { LLMProvider } from './base.js';
|
|
2
|
+
import { OpenAICompatibleProvider } from './openai-compatible.js';
|
|
3
|
+
import { AnthropicProvider } from './anthropic.js';
|
|
4
|
+
import { CouncilError } from '../errors.js';
|
|
5
|
+
export function loadProvider(name, config) {
|
|
6
|
+
// Normalize here too, not just in config.ts's env parsing: ProviderConfig
|
|
7
|
+
// can be constructed directly by library consumers who bypass loadConfig
|
|
8
|
+
// (and its literal-union type is only a compile-time guarantee, not a
|
|
9
|
+
// runtime one for callers using `any` or plain JS).
|
|
10
|
+
const kind = (config.kind ?? 'openai').toString().trim().toLowerCase();
|
|
11
|
+
if (kind === 'anthropic') {
|
|
12
|
+
return new AnthropicProvider({ ...config, name });
|
|
13
|
+
}
|
|
14
|
+
if (kind === 'openai') {
|
|
15
|
+
return new OpenAICompatibleProvider({ ...config, name });
|
|
16
|
+
}
|
|
17
|
+
throw new CouncilError(`Unrecognized provider kind "${kind}" for "${name}"`, 'BAD_KIND');
|
|
18
|
+
}
|
|
19
|
+
export { LLMProvider, OpenAICompatibleProvider, AnthropicProvider };
|
|
20
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,EAAE,wBAAwB,EAAE,MAAM,wBAAwB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAG5C,MAAM,UAAU,YAAY,CAAC,IAAY,EAAE,MAAsB;IAC/D,0EAA0E;IAC1E,yEAAyE;IACzE,sEAAsE;IACtE,oDAAoD;IACpD,MAAM,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACvE,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,OAAO,IAAI,iBAAiB,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IACD,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,IAAI,wBAAwB,CAAC,EAAE,GAAG,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,CAAC;IACD,MAAM,IAAI,YAAY,CAAC,+BAA+B,IAAI,UAAU,IAAI,GAAG,EAAE,UAAU,CAAC,CAAC;AAC3F,CAAC;AAED,OAAO,EAAE,WAAW,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { LLMProvider, ChatOptions, ChatResult, AuthResult, ProviderCapabilities } from './base.js';
|
|
3
|
+
import type { ProviderConfig } from '../types.js';
|
|
4
|
+
export declare class OpenAICompatibleProvider extends LLMProvider {
|
|
5
|
+
readonly name: string;
|
|
6
|
+
readonly displayName: string;
|
|
7
|
+
readonly capabilities: ProviderCapabilities;
|
|
8
|
+
protected client: OpenAI;
|
|
9
|
+
constructor(config: ProviderConfig);
|
|
10
|
+
checkAuth(): Promise<AuthResult>;
|
|
11
|
+
chat(options: ChatOptions): Promise<ChatResult>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import OpenAI from 'openai';
|
|
2
|
+
import { LLMProvider } from './base.js';
|
|
3
|
+
import { DEFAULT_OPENAI_MAX_TOKENS } from './constants.js';
|
|
4
|
+
export class OpenAICompatibleProvider extends LLMProvider {
|
|
5
|
+
name;
|
|
6
|
+
displayName;
|
|
7
|
+
capabilities;
|
|
8
|
+
client;
|
|
9
|
+
constructor(config) {
|
|
10
|
+
super(config);
|
|
11
|
+
this.name = config.name ?? 'unknown';
|
|
12
|
+
this.displayName = config.displayName ?? config.name ?? 'Unknown Provider';
|
|
13
|
+
this.capabilities = { supportsReasoning: false, supportsJsonMode: true };
|
|
14
|
+
this.client = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseURL });
|
|
15
|
+
}
|
|
16
|
+
async checkAuth() {
|
|
17
|
+
if (!this.config.baseURL) {
|
|
18
|
+
return {
|
|
19
|
+
available: true,
|
|
20
|
+
authenticated: false,
|
|
21
|
+
detail: `${this.displayName} base URL is not set`,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (!this.config.apiKey) {
|
|
25
|
+
return {
|
|
26
|
+
available: true,
|
|
27
|
+
authenticated: false,
|
|
28
|
+
detail: `${this.displayName} API key is not set`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return { available: true, authenticated: true, detail: `${this.displayName} API key is set` };
|
|
32
|
+
}
|
|
33
|
+
async chat(options) {
|
|
34
|
+
const messages = [];
|
|
35
|
+
if (options.system) {
|
|
36
|
+
messages.push({ role: 'system', content: options.system });
|
|
37
|
+
}
|
|
38
|
+
messages.push({ role: 'user', content: options.prompt });
|
|
39
|
+
// Temperature is opt-in (call option or <PREFIX>_TEMPERATURE env): some
|
|
40
|
+
// endpoints reject any value but their own default (kimi k3 only accepts
|
|
41
|
+
// 1), so when nothing is configured the field is omitted entirely.
|
|
42
|
+
const temperature = options.temperature ?? this.config.temperature;
|
|
43
|
+
const effort = options.effort ?? this.config.effort;
|
|
44
|
+
const completion = await this.client.chat.completions.create({
|
|
45
|
+
model: options.model,
|
|
46
|
+
// This SDK predates xhigh; compatible endpoints accept it on the wire.
|
|
47
|
+
...(effort !== undefined ? { reasoning_effort: effort } : {}),
|
|
48
|
+
messages,
|
|
49
|
+
...(temperature !== undefined ? { temperature } : {}),
|
|
50
|
+
max_tokens: options.maxTokens ?? this.config.maxTokens ?? DEFAULT_OPENAI_MAX_TOKENS,
|
|
51
|
+
response_format: options.jsonMode ? { type: 'json_object' } : undefined,
|
|
52
|
+
});
|
|
53
|
+
const choice = completion.choices[0];
|
|
54
|
+
const content = choice?.message?.content ?? '';
|
|
55
|
+
// Reasoning models (mimo-v2.5-pro, deepseek-v4-pro) return their chain of
|
|
56
|
+
// thought in a non-standard `reasoning_content` field the SDK doesn't type.
|
|
57
|
+
const reasoning = choice?.message?.reasoning_content ?? undefined;
|
|
58
|
+
const usage = completion.usage
|
|
59
|
+
? {
|
|
60
|
+
inputTokens: completion.usage.prompt_tokens,
|
|
61
|
+
outputTokens: completion.usage.completion_tokens,
|
|
62
|
+
totalTokens: completion.usage.total_tokens,
|
|
63
|
+
}
|
|
64
|
+
: undefined;
|
|
65
|
+
return { content, reasoning, usage };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=openai-compatible.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai-compatible.js","sourceRoot":"","sources":["../../src/providers/openai-compatible.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CouncilConfig } from '../config.js';
|
|
2
|
+
import type { CouncilOutput, RunControls } from '../types.js';
|
|
3
|
+
export interface PlanOptions extends RunControls {
|
|
4
|
+
prompt: string;
|
|
5
|
+
models?: string[];
|
|
6
|
+
config?: CouncilConfig;
|
|
7
|
+
files?: string[];
|
|
8
|
+
diff?: {
|
|
9
|
+
range?: string;
|
|
10
|
+
};
|
|
11
|
+
stdinContent?: string;
|
|
12
|
+
capBytes?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function runPlan(opts: PlanOptions): Promise<CouncilOutput>;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { loadConfig, resolveModels } from '../config.js';
|
|
2
|
+
import { runCouncil } from '../council.js';
|
|
3
|
+
import { synthesize } from '../chairman.js';
|
|
4
|
+
import { buildPrompt } from '../input.js';
|
|
5
|
+
import { CouncilError } from '../errors.js';
|
|
6
|
+
import { newBlockKey, aggregateBlocks, stripBlockFooter } from '../blocks.js';
|
|
7
|
+
import { planSystemPrompt } from '../prompts.js';
|
|
8
|
+
export async function runPlan(opts) {
|
|
9
|
+
const config = opts.config ?? loadConfig();
|
|
10
|
+
const models = resolveModels(opts.models, config.providers);
|
|
11
|
+
const prompt = buildPrompt(opts.prompt, opts);
|
|
12
|
+
const blockKey = newBlockKey();
|
|
13
|
+
const systemPrompt = planSystemPrompt(blockKey);
|
|
14
|
+
const judges = await runCouncil(config, {
|
|
15
|
+
prompt: prompt.text,
|
|
16
|
+
mode: 'plan',
|
|
17
|
+
models,
|
|
18
|
+
systemPrompt,
|
|
19
|
+
blockKey,
|
|
20
|
+
maxTokens: opts.maxTokens,
|
|
21
|
+
effort: opts.effort,
|
|
22
|
+
});
|
|
23
|
+
const availableCount = judges.filter((j) => j.status === 'success').length;
|
|
24
|
+
if (availableCount === 0) {
|
|
25
|
+
throw new CouncilError('All providers unavailable', 'NO_QUORUM');
|
|
26
|
+
}
|
|
27
|
+
// The judges array keeps the raw response; only the prose synthesis drops the
|
|
28
|
+
// footer, and only for judges whose footer parsed cleanly.
|
|
29
|
+
const forSynthesis = judges.map((j) => j.blockParse?.status === 'parsed' && j.response !== undefined
|
|
30
|
+
? { ...j, response: stripBlockFooter(j.response, blockKey) }
|
|
31
|
+
: j);
|
|
32
|
+
return {
|
|
33
|
+
prompt: prompt.text,
|
|
34
|
+
mode: 'plan',
|
|
35
|
+
judges,
|
|
36
|
+
synthesis: synthesize({ prompt: prompt.text, mode: 'plan', models, systemPrompt }, forSynthesis),
|
|
37
|
+
availableCount,
|
|
38
|
+
totalCount: models.length,
|
|
39
|
+
warnings: prompt.warnings,
|
|
40
|
+
...aggregateBlocks(judges),
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=plan.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/runners/plan.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAajD,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,IAAiB;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE;QACtC,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,IAAI,EAAE,MAAM;QACZ,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IAC3E,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,YAAY,CAAC,2BAA2B,EAAE,WAAW,CAAC,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,2DAA2D;IAC3D,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpC,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;QAC3D,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;QAC5D,CAAC,CAAC,CAAC,CACN,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,IAAI,EAAE,MAAM;QACZ,MAAM;QACN,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,YAAY,CAAC;QAChG,cAAc;QACd,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,eAAe,CAAC,MAAM,CAAC;KAC3B,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CouncilConfig } from '../config.js';
|
|
2
|
+
import type { CouncilOutput, RunControls } from '../types.js';
|
|
3
|
+
export interface ReviewOptions extends RunControls {
|
|
4
|
+
prompt: string;
|
|
5
|
+
models?: string[];
|
|
6
|
+
config?: CouncilConfig;
|
|
7
|
+
files?: string[];
|
|
8
|
+
diff?: {
|
|
9
|
+
range?: string;
|
|
10
|
+
};
|
|
11
|
+
stdinContent?: string;
|
|
12
|
+
capBytes?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function runReview(opts: ReviewOptions): Promise<CouncilOutput>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { loadConfig, resolveModels } from '../config.js';
|
|
2
|
+
import { runCouncil } from '../council.js';
|
|
3
|
+
import { synthesize } from '../chairman.js';
|
|
4
|
+
import { buildPrompt } from '../input.js';
|
|
5
|
+
import { CouncilError } from '../errors.js';
|
|
6
|
+
import { newBlockKey, aggregateBlocks, stripBlockFooter } from '../blocks.js';
|
|
7
|
+
import { reviewSystemPrompt } from '../prompts.js';
|
|
8
|
+
// Pure: no process.argv, no process.exit, no stdout. Warnings ride on the
|
|
9
|
+
// result rather than being printed.
|
|
10
|
+
export async function runReview(opts) {
|
|
11
|
+
const config = opts.config ?? loadConfig();
|
|
12
|
+
const models = resolveModels(opts.models, config.providers);
|
|
13
|
+
const prompt = buildPrompt(opts.prompt, opts);
|
|
14
|
+
const blockKey = newBlockKey();
|
|
15
|
+
const systemPrompt = reviewSystemPrompt(blockKey);
|
|
16
|
+
const judges = await runCouncil(config, {
|
|
17
|
+
prompt: prompt.text,
|
|
18
|
+
mode: 'review',
|
|
19
|
+
models,
|
|
20
|
+
systemPrompt,
|
|
21
|
+
blockKey,
|
|
22
|
+
maxTokens: opts.maxTokens,
|
|
23
|
+
effort: opts.effort,
|
|
24
|
+
});
|
|
25
|
+
const availableCount = judges.filter((j) => j.status === 'success').length;
|
|
26
|
+
if (availableCount === 0) {
|
|
27
|
+
throw new CouncilError('All providers unavailable', 'NO_QUORUM');
|
|
28
|
+
}
|
|
29
|
+
// The judges array keeps the raw response; only the prose synthesis drops the
|
|
30
|
+
// footer, and only for judges whose footer parsed cleanly.
|
|
31
|
+
const forSynthesis = judges.map((j) => j.blockParse?.status === 'parsed' && j.response !== undefined
|
|
32
|
+
? { ...j, response: stripBlockFooter(j.response, blockKey) }
|
|
33
|
+
: j);
|
|
34
|
+
return {
|
|
35
|
+
prompt: prompt.text,
|
|
36
|
+
mode: 'review',
|
|
37
|
+
judges,
|
|
38
|
+
synthesis: synthesize({ prompt: prompt.text, mode: 'review', models, systemPrompt }, forSynthesis),
|
|
39
|
+
availableCount,
|
|
40
|
+
totalCount: models.length,
|
|
41
|
+
warnings: prompt.warnings,
|
|
42
|
+
...aggregateBlocks(judges),
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/runners/review.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,aAAa,EAAsB,MAAM,cAAc,CAAC;AAC7E,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC5C,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,eAAe,CAAC;AAanD,0EAA0E;AAC1E,oCAAoC;AACpC,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAmB;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,EAAE,CAAC;IAC3C,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAC/B,MAAM,YAAY,GAAG,kBAAkB,CAAC,QAAQ,CAAC,CAAC;IAElD,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE;QACtC,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ;QACd,MAAM;QACN,YAAY;QACZ,QAAQ;QACR,SAAS,EAAE,IAAI,CAAC,SAAS;QACzB,MAAM,EAAE,IAAI,CAAC,MAAM;KACpB,CAAC,CAAC;IACH,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;IAC3E,IAAI,cAAc,KAAK,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,YAAY,CAAC,2BAA2B,EAAE,WAAW,CAAC,CAAC;IACnE,CAAC;IAED,8EAA8E;IAC9E,2DAA2D;IAC3D,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CACpC,CAAC,CAAC,UAAU,EAAE,MAAM,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,KAAK,SAAS;QAC3D,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,QAAQ,EAAE,gBAAgB,CAAC,CAAC,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE;QAC5D,CAAC,CAAC,CAAC,CACN,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,MAAM,CAAC,IAAI;QACnB,IAAI,EAAE,QAAQ;QACd,MAAM;QACN,SAAS,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,EAAE,YAAY,CAAC;QAClG,cAAc;QACd,UAAU,EAAE,MAAM,CAAC,MAAM;QACzB,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,GAAG,eAAe,CAAC,MAAM,CAAC;KAC3B,CAAC;AACJ,CAAC"}
|
package/dist/stdin.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Readable } from 'node:stream';
|
|
2
|
+
export interface ReadStdinOptions {
|
|
3
|
+
firstByteTimeoutMs?: number;
|
|
4
|
+
}
|
|
5
|
+
export declare const DEFAULT_STDIN_TIMEOUT_MS = 2000;
|
|
6
|
+
export declare function readStdinPayloadFrom(stream: Readable & {
|
|
7
|
+
isTTY?: boolean;
|
|
8
|
+
}, firstByteTimeoutMs?: number): Promise<string>;
|
|
9
|
+
export declare function readStdinPayload(options?: ReadStdinOptions): Promise<string>;
|
package/dist/stdin.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
export const DEFAULT_STDIN_TIMEOUT_MS = 2000;
|
|
2
|
+
// Deadline applies to the FIRST byte only. After data starts arriving we read
|
|
3
|
+
// to EOF with no cutoff, so a slow harness mid-payload is never truncated.
|
|
4
|
+
export function readStdinPayloadFrom(stream, firstByteTimeoutMs = DEFAULT_STDIN_TIMEOUT_MS) {
|
|
5
|
+
if (stream.isTTY)
|
|
6
|
+
return Promise.resolve('');
|
|
7
|
+
return new Promise((resolve) => {
|
|
8
|
+
let chunks = [];
|
|
9
|
+
let gotFirstByte = false;
|
|
10
|
+
const timer = setTimeout(() => {
|
|
11
|
+
if (!gotFirstByte) {
|
|
12
|
+
cleanup();
|
|
13
|
+
resolve('');
|
|
14
|
+
}
|
|
15
|
+
}, firstByteTimeoutMs);
|
|
16
|
+
function onData(chunk) {
|
|
17
|
+
gotFirstByte = true;
|
|
18
|
+
chunks.push(chunk);
|
|
19
|
+
}
|
|
20
|
+
function onEnd() {
|
|
21
|
+
cleanup();
|
|
22
|
+
resolve(Buffer.concat(chunks).toString('utf8'));
|
|
23
|
+
}
|
|
24
|
+
function onError() {
|
|
25
|
+
cleanup();
|
|
26
|
+
resolve(chunks.length > 0 ? Buffer.concat(chunks).toString('utf8') : '');
|
|
27
|
+
}
|
|
28
|
+
function cleanup() {
|
|
29
|
+
clearTimeout(timer);
|
|
30
|
+
stream.off('data', onData);
|
|
31
|
+
stream.off('end', onEnd);
|
|
32
|
+
stream.off('error', onError);
|
|
33
|
+
}
|
|
34
|
+
stream.on('data', onData);
|
|
35
|
+
stream.on('end', onEnd);
|
|
36
|
+
stream.on('error', onError);
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
export function readStdinPayload(options = {}) {
|
|
40
|
+
const timeout = options.firstByteTimeoutMs ??
|
|
41
|
+
parsePositiveInt(process.env.COUNCIL_HOOK_STDIN_TIMEOUT_MS) ??
|
|
42
|
+
DEFAULT_STDIN_TIMEOUT_MS;
|
|
43
|
+
return readStdinPayloadFrom(process.stdin, timeout);
|
|
44
|
+
}
|
|
45
|
+
function parsePositiveInt(value) {
|
|
46
|
+
if (!value)
|
|
47
|
+
return undefined;
|
|
48
|
+
const n = Number.parseInt(value, 10);
|
|
49
|
+
return Number.isInteger(n) && n > 0 ? n : undefined;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=stdin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdin.js","sourceRoot":"","sources":["../src/stdin.ts"],"names":[],"mappings":"AAMA,MAAM,CAAC,MAAM,wBAAwB,GAAG,IAAI,CAAC;AAE7C,8EAA8E;AAC9E,2EAA2E;AAC3E,MAAM,UAAU,oBAAoB,CAClC,MAAsC,EACtC,qBAA6B,wBAAwB;IAErD,IAAI,MAAM,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAE7C,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,MAAM,GAAa,EAAE,CAAC;QAC1B,IAAI,YAAY,GAAG,KAAK,CAAC;QAEzB,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;YAC5B,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,OAAO,EAAE,CAAC;gBACV,OAAO,CAAC,EAAE,CAAC,CAAC;YACd,CAAC;QACH,CAAC,EAAE,kBAAkB,CAAC,CAAC;QAEvB,SAAS,MAAM,CAAC,KAAa;YAC3B,YAAY,GAAG,IAAI,CAAC;YACpB,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,SAAS,KAAK;YACZ,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,SAAS,OAAO;YACd,OAAO,EAAE,CAAC;YACV,OAAO,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QACD,SAAS,OAAO;YACd,YAAY,CAAC,KAAK,CAAC,CAAC;YACpB,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;YAC3B,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YACzB,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/B,CAAC;QAED,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1B,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC9B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,UAA4B,EAAE;IAC7D,MAAM,OAAO,GACX,OAAO,CAAC,kBAAkB;QAC1B,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC;QAC3D,wBAAwB,CAAC;IAC3B,OAAO,oBAAoB,CAAC,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAyB;IACjD,IAAI,CAAC,KAAK;QAAE,OAAO,SAAS,CAAC;IAC7B,MAAM,CAAC,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACtD,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
export interface JudgeResult {
|
|
2
|
+
provider: string;
|
|
3
|
+
model: string;
|
|
4
|
+
status: 'success' | 'error' | 'skipped';
|
|
5
|
+
response?: string;
|
|
6
|
+
reasoning?: string;
|
|
7
|
+
error?: {
|
|
8
|
+
message: string;
|
|
9
|
+
code?: string;
|
|
10
|
+
};
|
|
11
|
+
usage?: {
|
|
12
|
+
inputTokens: number;
|
|
13
|
+
outputTokens: number;
|
|
14
|
+
totalTokens: number;
|
|
15
|
+
};
|
|
16
|
+
blockParse?: BlockParse;
|
|
17
|
+
}
|
|
18
|
+
export type Effort = 'low' | 'medium' | 'high' | 'xhigh';
|
|
19
|
+
export interface RunControls {
|
|
20
|
+
/** Per-judge response token cap; overrides provider config when supplied. */
|
|
21
|
+
maxTokens?: number;
|
|
22
|
+
/** Overrides provider effort; omitted from requests if neither is set. */
|
|
23
|
+
effort?: Effort;
|
|
24
|
+
}
|
|
25
|
+
export interface CouncilRequest extends RunControls {
|
|
26
|
+
prompt: string;
|
|
27
|
+
mode: 'review' | 'plan';
|
|
28
|
+
models: string[];
|
|
29
|
+
systemPrompt?: string;
|
|
30
|
+
blockKey?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface CouncilOutput {
|
|
33
|
+
prompt: string;
|
|
34
|
+
mode: 'review' | 'plan';
|
|
35
|
+
judges: JudgeResult[];
|
|
36
|
+
synthesis: string;
|
|
37
|
+
availableCount: number;
|
|
38
|
+
totalCount: number;
|
|
39
|
+
warnings?: string[];
|
|
40
|
+
blocked: boolean;
|
|
41
|
+
hardBlocks: AttributedHardBlock[];
|
|
42
|
+
diagnosticBlocks: AttributedHardBlock[];
|
|
43
|
+
unknownJudges: UnknownJudge[];
|
|
44
|
+
}
|
|
45
|
+
export interface ProviderConfig extends RunControls {
|
|
46
|
+
name: string;
|
|
47
|
+
apiKey: string;
|
|
48
|
+
baseURL: string;
|
|
49
|
+
model?: string;
|
|
50
|
+
displayName: string;
|
|
51
|
+
temperature?: number;
|
|
52
|
+
kind?: 'openai' | 'anthropic';
|
|
53
|
+
}
|
|
54
|
+
export type Verdict = 'agree' | 'disagree';
|
|
55
|
+
export interface DebateTurn extends JudgeResult {
|
|
56
|
+
round: number;
|
|
57
|
+
verdict?: Verdict;
|
|
58
|
+
}
|
|
59
|
+
export interface DebateRound {
|
|
60
|
+
round: number;
|
|
61
|
+
turns: DebateTurn[];
|
|
62
|
+
}
|
|
63
|
+
export interface DebateOutput {
|
|
64
|
+
prompt: string;
|
|
65
|
+
mode: 'debate';
|
|
66
|
+
rounds: DebateRound[];
|
|
67
|
+
consensus: boolean;
|
|
68
|
+
totalRounds: number;
|
|
69
|
+
maxRounds: number;
|
|
70
|
+
judges: DebateTurn[];
|
|
71
|
+
synthesis: string;
|
|
72
|
+
availableCount: number;
|
|
73
|
+
totalCount: number;
|
|
74
|
+
warnings?: string[];
|
|
75
|
+
}
|
|
76
|
+
export interface DebateSession extends RunControls {
|
|
77
|
+
id: string;
|
|
78
|
+
createdAt: string;
|
|
79
|
+
prompt: string;
|
|
80
|
+
models: string[];
|
|
81
|
+
maxRounds: number;
|
|
82
|
+
turns: DebateTurn[];
|
|
83
|
+
nextTurn: {
|
|
84
|
+
round: number;
|
|
85
|
+
participant: string;
|
|
86
|
+
order: string[];
|
|
87
|
+
};
|
|
88
|
+
warnings?: string[];
|
|
89
|
+
}
|
|
90
|
+
export type Severity = 'critical' | 'high';
|
|
91
|
+
export interface HardBlock {
|
|
92
|
+
severity: Severity;
|
|
93
|
+
rawSeverity?: string;
|
|
94
|
+
title: string;
|
|
95
|
+
location?: string;
|
|
96
|
+
}
|
|
97
|
+
export type UnparseableReason = 'no-key' | 'no-header' | 'bad-header' | 'count-mismatch';
|
|
98
|
+
export type BlockParse = {
|
|
99
|
+
status: 'parsed';
|
|
100
|
+
blocks: HardBlock[];
|
|
101
|
+
} | {
|
|
102
|
+
status: 'unparseable';
|
|
103
|
+
reason: UnparseableReason;
|
|
104
|
+
detail?: string;
|
|
105
|
+
diagnosticBlocks: HardBlock[];
|
|
106
|
+
};
|
|
107
|
+
export interface AttributedHardBlock extends HardBlock {
|
|
108
|
+
provider: string;
|
|
109
|
+
}
|
|
110
|
+
export interface UnknownJudge {
|
|
111
|
+
provider: string;
|
|
112
|
+
reason: UnparseableReason;
|
|
113
|
+
detail?: string;
|
|
114
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/verdict.js
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const TAG = /^VERDICT:\s*(AGREE|DISAGREE)\s*$/i;
|
|
2
|
+
// Missing or malformed tags count as disagree: fail safe toward continuing
|
|
3
|
+
// the debate, never toward false consensus.
|
|
4
|
+
export function parseVerdict(text) {
|
|
5
|
+
for (const line of text.split('\n').reverse()) {
|
|
6
|
+
const m = TAG.exec(line.trim());
|
|
7
|
+
if (m)
|
|
8
|
+
return m[1].toLowerCase();
|
|
9
|
+
}
|
|
10
|
+
return 'disagree';
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=verdict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verdict.js","sourceRoot":"","sources":["../src/verdict.ts"],"names":[],"mappings":"AAEA,MAAM,GAAG,GAAG,mCAAmC,CAAC;AAEhD,2EAA2E;AAC3E,4CAA4C;AAC5C,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;QAChC,IAAI,CAAC;YAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAa,CAAC;IAC9C,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,56 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lanjak/council",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.5.0",
|
|
4
|
+
"description": "Multi-LLM adversarial review council - an AXI",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"default": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./package.json": "./package.json"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"council": "dist/cli.js"
|
|
17
|
+
},
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=20"
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"prepack": "npm run build",
|
|
23
|
+
"build": "tsc && chmod +x dist/cli.js",
|
|
24
|
+
"dev": "tsx src/cli.ts",
|
|
25
|
+
"test": "vitest run",
|
|
26
|
+
"test:watch": "vitest",
|
|
27
|
+
"lint": "tsc --noEmit",
|
|
28
|
+
"smoke": "./scripts/smoke-package.sh"
|
|
29
|
+
},
|
|
30
|
+
"dependencies": {
|
|
31
|
+
"@anthropic-ai/sdk": "^0.115.0",
|
|
32
|
+
"commander": "^12.0.0",
|
|
33
|
+
"ignore": "^7.0.6",
|
|
34
|
+
"openai": "^4.90.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@arethetypeswrong/cli": "^0.18.5",
|
|
38
|
+
"@types/node": "^22.0.0",
|
|
39
|
+
"publint": "^0.3.22",
|
|
40
|
+
"tsx": "^4.0.0",
|
|
41
|
+
"typescript": "^5.7.0",
|
|
42
|
+
"vitest": "^3.0.0"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"skills"
|
|
47
|
+
],
|
|
48
|
+
"keywords": [
|
|
49
|
+
"axi",
|
|
50
|
+
"llm",
|
|
51
|
+
"council",
|
|
52
|
+
"adversarial-review",
|
|
53
|
+
"claude-code"
|
|
54
|
+
],
|
|
55
|
+
"license": "MIT"
|
|
56
|
+
}
|