@mandible-ai/mandible 0.3.13 → 0.3.14
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 +5 -7
- package/dist/src/cli/index.js +6 -0
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/cli/init.d.ts +25 -0
- package/dist/src/cli/init.d.ts.map +1 -0
- package/dist/src/cli/init.js +348 -0
- package/dist/src/cli/init.js.map +1 -0
- package/dist/src/core/events.d.ts +1 -1
- package/dist/src/core/events.d.ts.map +1 -1
- package/dist/src/core/events.js.map +1 -1
- package/dist/src/core/runtime.d.ts.map +1 -1
- package/dist/src/core/runtime.js +25 -2
- package/dist/src/core/runtime.js.map +1 -1
- package/dist/src/core/types.d.ts +12 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/core/types.js.map +1 -1
- package/dist/src/core/validation.d.ts +7 -0
- package/dist/src/core/validation.d.ts.map +1 -1
- package/dist/src/core/validation.js +19 -0
- package/dist/src/core/validation.js.map +1 -1
- package/dist/src/dsl/builder.d.ts +2 -0
- package/dist/src/dsl/builder.d.ts.map +1 -1
- package/dist/src/dsl/builder.js +5 -0
- package/dist/src/dsl/builder.js.map +1 -1
- package/dist/src/dsl/mandible.d.ts +1 -1
- package/dist/src/dsl/mandible.js +1 -1
- package/dist/src/environments/dolt/adapter.d.ts +21 -7
- package/dist/src/environments/dolt/adapter.d.ts.map +1 -1
- package/dist/src/environments/dolt/adapter.js +319 -59
- package/dist/src/environments/dolt/adapter.js.map +1 -1
- package/dist/src/environments/dolt/client.d.ts +72 -0
- package/dist/src/environments/dolt/client.d.ts.map +1 -0
- package/dist/src/environments/dolt/client.js +209 -0
- package/dist/src/environments/dolt/client.js.map +1 -0
- package/dist/src/environments/dolt/index.d.ts +2 -0
- package/dist/src/environments/dolt/index.d.ts.map +1 -1
- package/dist/src/environments/dolt/index.js +2 -0
- package/dist/src/environments/dolt/index.js.map +1 -1
- package/dist/src/environments/dolt/sql-client.d.ts +24 -0
- package/dist/src/environments/dolt/sql-client.d.ts.map +1 -0
- package/dist/src/environments/dolt/sql-client.js +46 -0
- package/dist/src/environments/dolt/sql-client.js.map +1 -0
- package/dist/src/environments/filesystem/adapter.d.ts +4 -0
- package/dist/src/environments/filesystem/adapter.d.ts.map +1 -1
- package/dist/src/environments/filesystem/adapter.js +23 -0
- package/dist/src/environments/filesystem/adapter.js.map +1 -1
- package/dist/src/environments/github/adapter.d.ts +4 -0
- package/dist/src/environments/github/adapter.d.ts.map +1 -1
- package/dist/src/environments/github/adapter.js +18 -0
- package/dist/src/environments/github/adapter.js.map +1 -1
- package/dist/src/hosts/docker.d.ts +52 -37
- package/dist/src/hosts/docker.d.ts.map +1 -1
- package/dist/src/hosts/docker.js +207 -90
- package/dist/src/hosts/docker.js.map +1 -1
- package/dist/src/index.d.ts +9 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +5 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/patterns/barrier.d.ts +104 -0
- package/dist/src/patterns/barrier.d.ts.map +1 -0
- package/dist/src/patterns/barrier.js +196 -0
- package/dist/src/patterns/barrier.js.map +1 -0
- package/dist/src/patterns/gate.d.ts +71 -0
- package/dist/src/patterns/gate.d.ts.map +1 -0
- package/dist/src/patterns/gate.js +167 -0
- package/dist/src/patterns/gate.js.map +1 -0
- package/dist/src/patterns/index.d.ts +4 -0
- package/dist/src/patterns/index.d.ts.map +1 -1
- package/dist/src/patterns/index.js +2 -0
- package/dist/src/patterns/index.js.map +1 -1
- package/dist/src/providers/claude-code.d.ts.map +1 -1
- package/dist/src/providers/claude-code.js +5 -4
- package/dist/src/providers/claude-code.js.map +1 -1
- package/dist/src/providers/context.d.ts.map +1 -1
- package/dist/src/providers/context.js +16 -10
- package/dist/src/providers/context.js.map +1 -1
- package/dist/src/providers/index.d.ts +12 -1
- package/dist/src/providers/index.d.ts.map +1 -1
- package/dist/src/providers/index.js +11 -0
- package/dist/src/providers/index.js.map +1 -1
- package/dist/src/providers/llm.d.ts +17 -0
- package/dist/src/providers/llm.d.ts.map +1 -0
- package/dist/src/providers/llm.js +225 -0
- package/dist/src/providers/llm.js.map +1 -0
- package/dist/src/providers/opencode.d.ts +87 -0
- package/dist/src/providers/opencode.d.ts.map +1 -0
- package/dist/src/providers/opencode.js +170 -0
- package/dist/src/providers/opencode.js.map +1 -0
- package/dist/src/providers/qwen-code.d.ts +69 -0
- package/dist/src/providers/qwen-code.d.ts.map +1 -0
- package/dist/src/providers/qwen-code.js +175 -0
- package/dist/src/providers/qwen-code.js.map +1 -0
- package/dist/src/providers/skill.d.ts +120 -0
- package/dist/src/providers/skill.d.ts.map +1 -0
- package/dist/src/providers/skill.js +262 -0
- package/dist/src/providers/skill.js.map +1 -0
- package/dist/src/providers/tool-loop.d.ts +163 -0
- package/dist/src/providers/tool-loop.d.ts.map +1 -0
- package/dist/src/providers/tool-loop.js +580 -0
- package/dist/src/providers/tool-loop.js.map +1 -0
- package/dist/src/providers/types.d.ts +63 -0
- package/dist/src/providers/types.d.ts.map +1 -1
- package/dist/src/providers/vllm.d.ts +62 -0
- package/dist/src/providers/vllm.d.ts.map +1 -0
- package/dist/src/providers/vllm.js +262 -0
- package/dist/src/providers/vllm.js.map +1 -0
- package/package.json +7 -2
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
// PURPOSE: withOpenCode — Provider-agnostic agentic coding via OpenCode SDK.
|
|
2
|
+
// PURPOSE: Wraps the OpenCode Go server's TypeScript SDK for multi-provider LLM access.
|
|
3
|
+
// ----------------------------------------------------------
|
|
4
|
+
// Provider factory
|
|
5
|
+
// ----------------------------------------------------------
|
|
6
|
+
/**
|
|
7
|
+
* Creates an action handler powered by the OpenCode SDK.
|
|
8
|
+
*
|
|
9
|
+
* The SDK must be installed separately:
|
|
10
|
+
* npm install @opencode-ai/sdk
|
|
11
|
+
*
|
|
12
|
+
* The OpenCode server must be running:
|
|
13
|
+
* opencode serve
|
|
14
|
+
*
|
|
15
|
+
* The handler:
|
|
16
|
+
* 1. Connects to the OpenCode server via the SDK
|
|
17
|
+
* 2. Creates a session with the specified agent and model
|
|
18
|
+
* 3. Optionally injects a system prompt as a noReply message
|
|
19
|
+
* 4. Sends the main prompt (with optional structured output schema)
|
|
20
|
+
* 5. Extracts text and structured output from the response
|
|
21
|
+
* 6. Maps the output to signal deposits
|
|
22
|
+
* 7. Cleans up the session
|
|
23
|
+
*/
|
|
24
|
+
export function withOpenCode(config) {
|
|
25
|
+
const { serverUrl = 'http://localhost:4096', model, agent = 'build', prompt, systemPrompt, workingDirectory, timeout = 600_000, schema, onEvent, output, autoWithdraw = true, } = config;
|
|
26
|
+
return async (signal, ctx) => {
|
|
27
|
+
const startTime = Date.now();
|
|
28
|
+
// 1. Resolve prompt
|
|
29
|
+
const resolvedPrompt = typeof prompt === 'function'
|
|
30
|
+
? await prompt(signal)
|
|
31
|
+
: prompt;
|
|
32
|
+
// 2. Resolve working directory
|
|
33
|
+
const cwd = typeof workingDirectory === 'function'
|
|
34
|
+
? workingDirectory(signal)
|
|
35
|
+
: workingDirectory;
|
|
36
|
+
// 3. Dynamic import + full SDK interaction in try/catch
|
|
37
|
+
// Catches MODULE_NOT_FOUND from both the import() and the SDK usage.
|
|
38
|
+
let client;
|
|
39
|
+
let sessionId;
|
|
40
|
+
try {
|
|
41
|
+
const sdk = await import('@opencode-ai/sdk');
|
|
42
|
+
const createOpencodeClient = sdk.createOpencodeClient;
|
|
43
|
+
// 4. Create client
|
|
44
|
+
client = createOpencodeClient({ baseUrl: serverUrl });
|
|
45
|
+
// 5. Create session
|
|
46
|
+
const sessionBody = {};
|
|
47
|
+
if (model)
|
|
48
|
+
sessionBody.model = model;
|
|
49
|
+
if (agent)
|
|
50
|
+
sessionBody.agent = agent;
|
|
51
|
+
if (cwd)
|
|
52
|
+
sessionBody.path = cwd;
|
|
53
|
+
const session = await client.session.create({ body: sessionBody });
|
|
54
|
+
sessionId = session.data.id;
|
|
55
|
+
}
|
|
56
|
+
catch (err) {
|
|
57
|
+
if (err.code === 'ERR_MODULE_NOT_FOUND' || err.code === 'MODULE_NOT_FOUND') {
|
|
58
|
+
throw new Error('withOpenCode requires @opencode-ai/sdk. Install it:\n' +
|
|
59
|
+
' npm install @opencode-ai/sdk');
|
|
60
|
+
}
|
|
61
|
+
throw err;
|
|
62
|
+
}
|
|
63
|
+
ctx.log(`OpenCode session ${sessionId} created (agent=${agent}${model ? `, model=${model}` : ''})`);
|
|
64
|
+
try {
|
|
65
|
+
// 6. Subscribe to events (fire-and-forget, errors swallowed)
|
|
66
|
+
if (onEvent) {
|
|
67
|
+
consumeEvents(client, onEvent).catch(() => { });
|
|
68
|
+
}
|
|
69
|
+
// 7. Inject system prompt as noReply message
|
|
70
|
+
if (systemPrompt) {
|
|
71
|
+
await client.session.prompt({
|
|
72
|
+
path: { id: sessionId },
|
|
73
|
+
body: {
|
|
74
|
+
parts: [{ type: 'text', text: systemPrompt }],
|
|
75
|
+
noReply: true,
|
|
76
|
+
},
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
// 8. Send main prompt
|
|
80
|
+
const promptBody = {
|
|
81
|
+
parts: [{ type: 'text', text: resolvedPrompt }],
|
|
82
|
+
};
|
|
83
|
+
if (schema) {
|
|
84
|
+
promptBody.format = {
|
|
85
|
+
type: 'json_schema',
|
|
86
|
+
schema: schema.schema,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
const response = await client.session.prompt({
|
|
90
|
+
path: { id: sessionId },
|
|
91
|
+
body: promptBody,
|
|
92
|
+
signal: AbortSignal.timeout(timeout),
|
|
93
|
+
});
|
|
94
|
+
// 9. Extract result
|
|
95
|
+
const durationMs = Date.now() - startTime;
|
|
96
|
+
const parts = response.data?.parts ?? [];
|
|
97
|
+
const textParts = parts.filter((p) => p.type === 'text');
|
|
98
|
+
const text = textParts.map((p) => p.text).join('\n');
|
|
99
|
+
const structuredOutput = response.data?.info?.structured_output;
|
|
100
|
+
const result = {
|
|
101
|
+
text,
|
|
102
|
+
structuredOutput,
|
|
103
|
+
durationMs,
|
|
104
|
+
sessionId: sessionId,
|
|
105
|
+
};
|
|
106
|
+
ctx.log(`OpenCode completed in ${durationMs}ms (session=${sessionId})`);
|
|
107
|
+
// 10. Deposit output signals
|
|
108
|
+
const deposits = resolveOutput(output, result, signal);
|
|
109
|
+
for (const deposit of deposits) {
|
|
110
|
+
await ctx.deposit(deposit.type, deposit.payload ?? { ...result }, {
|
|
111
|
+
causedBy: [signal.id],
|
|
112
|
+
tags: deposit.tags,
|
|
113
|
+
ttl: deposit.ttl,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
// 11. Auto-withdraw
|
|
117
|
+
if (autoWithdraw) {
|
|
118
|
+
await ctx.withdraw(signal.id);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
finally {
|
|
122
|
+
// 12. Clean up session
|
|
123
|
+
if (sessionId) {
|
|
124
|
+
await client.session.delete({ path: { id: sessionId } }).catch(() => { });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
// ----------------------------------------------------------
|
|
130
|
+
// Default system prompt
|
|
131
|
+
// ----------------------------------------------------------
|
|
132
|
+
export function buildOpenCodeSystemPrompt(colonyName) {
|
|
133
|
+
return [
|
|
134
|
+
`You are an agent in the "${colonyName}" colony.`,
|
|
135
|
+
'Complete the task described in the prompt.',
|
|
136
|
+
'Be thorough but concise. Focus on the specific task at hand.',
|
|
137
|
+
'If you create or modify files, ensure they compile/pass tests.',
|
|
138
|
+
].join('\n');
|
|
139
|
+
}
|
|
140
|
+
// ----------------------------------------------------------
|
|
141
|
+
// Event consumer (background, non-blocking)
|
|
142
|
+
// ----------------------------------------------------------
|
|
143
|
+
async function consumeEvents(client, onEvent) {
|
|
144
|
+
const events = await client.event.subscribe();
|
|
145
|
+
for await (const event of events.stream) {
|
|
146
|
+
try {
|
|
147
|
+
onEvent(event);
|
|
148
|
+
}
|
|
149
|
+
catch { /* swallow callback errors */ }
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ----------------------------------------------------------
|
|
153
|
+
// Output mapping (same 3-pattern as withClaudeCode/withQwenCode)
|
|
154
|
+
// ----------------------------------------------------------
|
|
155
|
+
function resolveOutput(output, result, signal) {
|
|
156
|
+
if (!output) {
|
|
157
|
+
return [{ type: `${signal.type}:completed`, payload: result }];
|
|
158
|
+
}
|
|
159
|
+
if (typeof output === 'function') {
|
|
160
|
+
const mapped = output(result, signal);
|
|
161
|
+
return Array.isArray(mapped) ? mapped : [mapped];
|
|
162
|
+
}
|
|
163
|
+
return [{
|
|
164
|
+
type: output.type,
|
|
165
|
+
payload: result,
|
|
166
|
+
tags: output.tags,
|
|
167
|
+
ttl: output.ttl,
|
|
168
|
+
}];
|
|
169
|
+
}
|
|
170
|
+
//# sourceMappingURL=opencode.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode.js","sourceRoot":"","sources":["../../../src/providers/opencode.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { Signal } from '../core/types.js';
|
|
2
|
+
import type { ActionHandler, OutputMapping } from './types.js';
|
|
3
|
+
export interface QwenCodeConfig<T = Record<string, unknown>> {
|
|
4
|
+
/** vLLM endpoint — sets OPENAI_BASE_URL for qwen-code. */
|
|
5
|
+
endpoint: string;
|
|
6
|
+
/** Model name. Default: 'Qwen3-Coder-Next'. */
|
|
7
|
+
model?: string;
|
|
8
|
+
/** Optional API key — sets OPENAI_API_KEY for qwen-code. */
|
|
9
|
+
apiKey?: string;
|
|
10
|
+
/** Build the prompt from the incoming signal. */
|
|
11
|
+
prompt: string | ((signal: Signal<T>) => string | Promise<string>);
|
|
12
|
+
/**
|
|
13
|
+
* Working directory for the qwen-code session.
|
|
14
|
+
* Can be static or derived from the signal.
|
|
15
|
+
*/
|
|
16
|
+
workingDirectory?: string | ((signal: Signal<T>) => string);
|
|
17
|
+
/**
|
|
18
|
+
* Maximum conversation turns for qwen-code. Default: 20.
|
|
19
|
+
* Maps to qwen-code's --max-turns flag.
|
|
20
|
+
*/
|
|
21
|
+
maxTurns?: number;
|
|
22
|
+
/** Timeout in ms for the entire session. Default: 600_000 (10 min). */
|
|
23
|
+
timeout?: number;
|
|
24
|
+
/**
|
|
25
|
+
* Shell commands the agent is allowed to run.
|
|
26
|
+
* If not set, qwen-code uses its default allowed commands.
|
|
27
|
+
*/
|
|
28
|
+
allowedCommands?: string[];
|
|
29
|
+
/**
|
|
30
|
+
* Additional environment variables to pass to the subprocess.
|
|
31
|
+
*/
|
|
32
|
+
env?: Record<string, string>;
|
|
33
|
+
/**
|
|
34
|
+
* Path to the qwen-code binary. Default: 'qwen-code' (from PATH).
|
|
35
|
+
*/
|
|
36
|
+
binary?: string;
|
|
37
|
+
/**
|
|
38
|
+
* Map the output to signal deposits.
|
|
39
|
+
* If not provided, deposits the raw result.
|
|
40
|
+
*/
|
|
41
|
+
output?: OutputMapping<T>;
|
|
42
|
+
/** Whether to auto-withdraw the triggering signal. Default: true. */
|
|
43
|
+
autoWithdraw?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Observability hook — called with chunks of stdout as they arrive.
|
|
46
|
+
* Use for real-time logging or progress tracking.
|
|
47
|
+
*/
|
|
48
|
+
onOutput?: (chunk: string) => void;
|
|
49
|
+
}
|
|
50
|
+
export interface QwenCodeResult {
|
|
51
|
+
/** Combined stdout from the qwen-code session. */
|
|
52
|
+
text: string;
|
|
53
|
+
/** stderr output (usually progress/debug info). */
|
|
54
|
+
stderr: string;
|
|
55
|
+
/** Process exit code. 0 = success. */
|
|
56
|
+
exitCode: number;
|
|
57
|
+
/** Wall-clock duration in ms. */
|
|
58
|
+
durationMs: number;
|
|
59
|
+
/** Whether the session completed successfully (exit code 0). */
|
|
60
|
+
success: boolean;
|
|
61
|
+
/** Whether the session was killed by timeout. */
|
|
62
|
+
timedOut: boolean;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Creates an action handler that spawns a qwen-code subprocess.
|
|
66
|
+
* The subprocess runs against local vLLM and executes agentic coding tasks.
|
|
67
|
+
*/
|
|
68
|
+
export declare function withQwenCode<T = Record<string, unknown>>(config: QwenCodeConfig<T>): ActionHandler<T>;
|
|
69
|
+
//# sourceMappingURL=qwen-code.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qwen-code.d.ts","sourceRoot":"","sources":["../../../src/providers/qwen-code.ts"],"names":[],"mappings":"AAuCA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAiB,MAAM,YAAY,CAAC;AAM9E,MAAM,WAAW,cAAc,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACzD,0DAA0D;IAC1D,QAAQ,EAAE,MAAM,CAAC;IAEjB,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB,iDAAiD;IACjD,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IAE5D;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,uEAAuE;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAE3B;;OAEG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE7B;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;OAGG;IACH,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAE1B,qEAAqE;IACrE,YAAY,CAAC,EAAE,OAAO,CAAC;IAEvB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAMD,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IAEb,mDAAmD;IACnD,MAAM,EAAE,MAAM,CAAC;IAEf,sCAAsC;IACtC,QAAQ,EAAE,MAAM,CAAC;IAEjB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IAEnB,gEAAgE;IAChE,OAAO,EAAE,OAAO,CAAC;IAEjB,iDAAiD;IACjD,QAAQ,EAAE,OAAO,CAAC;CACnB;AAMD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtD,MAAM,EAAE,cAAc,CAAC,CAAC,CAAC,GACxB,aAAa,CAAC,CAAC,CAAC,CAuElB"}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// ============================================================
|
|
2
|
+
// withQwenCode — Subprocess wrapper for qwen-code CLI agent
|
|
3
|
+
// ============================================================
|
|
4
|
+
// Wraps the qwen-code open-source terminal agent (Apache 2.0)
|
|
5
|
+
// as a Mandible action provider. qwen-code is Qwen's equivalent
|
|
6
|
+
// of Claude Code — a terminal agent that can read files, write
|
|
7
|
+
// code, run tests, and fix bugs using local vLLM inference.
|
|
8
|
+
//
|
|
9
|
+
// qwen-code supports self-hosted endpoints via OPENAI_BASE_URL.
|
|
10
|
+
// This provider spawns it as a subprocess in non-interactive mode,
|
|
11
|
+
// points it at the local vLLM, and captures the output.
|
|
12
|
+
//
|
|
13
|
+
// Same pattern as withClaudeCode (wraps Claude Agent SDK) but for
|
|
14
|
+
// local DGX deployments where all inference is on-device.
|
|
15
|
+
//
|
|
16
|
+
// Prerequisites:
|
|
17
|
+
// npm install -g qwen-code (or have it in PATH)
|
|
18
|
+
//
|
|
19
|
+
// Usage:
|
|
20
|
+
// import { withQwenCode } from '@mandible-ai/mandible/providers';
|
|
21
|
+
//
|
|
22
|
+
// colony('devops')
|
|
23
|
+
// .sense('ci:failed', { unclaimed: true })
|
|
24
|
+
// .do('fix-build', withQwenCode({
|
|
25
|
+
// endpoint: 'http://localhost:8001',
|
|
26
|
+
// model: 'Qwen3-Coder-Next',
|
|
27
|
+
// prompt: (signal) => `CI failed for PR #${signal.payload.pr}. Fix the build.`,
|
|
28
|
+
// workingDirectory: '/workspace/repo',
|
|
29
|
+
// maxTurns: 20,
|
|
30
|
+
// timeout: 600_000,
|
|
31
|
+
// output: (result) => ({
|
|
32
|
+
// type: result.exitCode === 0 ? 'fix:applied' : 'fix:failed',
|
|
33
|
+
// payload: { summary: result.text, pr: signal.payload.pr },
|
|
34
|
+
// }),
|
|
35
|
+
// }))
|
|
36
|
+
// .build();
|
|
37
|
+
// ============================================================
|
|
38
|
+
import { spawn } from 'node:child_process';
|
|
39
|
+
// ----------------------------------------------------------
|
|
40
|
+
// Provider factory
|
|
41
|
+
// ----------------------------------------------------------
|
|
42
|
+
/**
|
|
43
|
+
* Creates an action handler that spawns a qwen-code subprocess.
|
|
44
|
+
* The subprocess runs against local vLLM and executes agentic coding tasks.
|
|
45
|
+
*/
|
|
46
|
+
export function withQwenCode(config) {
|
|
47
|
+
const { endpoint, model = 'Qwen3-Coder-Next', apiKey, prompt, workingDirectory, maxTurns = 20, timeout = 600_000, allowedCommands, env: extraEnv = {}, binary = 'qwen-code', output, autoWithdraw = true, onOutput, } = config;
|
|
48
|
+
return async (signal, ctx) => {
|
|
49
|
+
const startTime = Date.now();
|
|
50
|
+
// Resolve prompt and working directory
|
|
51
|
+
const resolvedPrompt = typeof prompt === 'function'
|
|
52
|
+
? await prompt(signal)
|
|
53
|
+
: prompt;
|
|
54
|
+
const cwd = typeof workingDirectory === 'function'
|
|
55
|
+
? workingDirectory(signal)
|
|
56
|
+
: workingDirectory ?? process.cwd();
|
|
57
|
+
ctx.log(`Starting qwen-code session in ${cwd}`);
|
|
58
|
+
// Build environment
|
|
59
|
+
const processEnv = {
|
|
60
|
+
...process.env,
|
|
61
|
+
OPENAI_BASE_URL: endpoint.replace(/\/+$/, '') + '/v1',
|
|
62
|
+
OPENAI_API_KEY: apiKey ?? 'not-needed', // vLLM doesn't require a key by default
|
|
63
|
+
...extraEnv,
|
|
64
|
+
};
|
|
65
|
+
// Build args
|
|
66
|
+
const args = buildQwenCodeArgs(resolvedPrompt, model, maxTurns, allowedCommands);
|
|
67
|
+
// Spawn subprocess
|
|
68
|
+
const result = await runQwenCode(binary, args, cwd, processEnv, timeout, onOutput);
|
|
69
|
+
ctx.log(result.success
|
|
70
|
+
? `qwen-code completed in ${result.durationMs}ms`
|
|
71
|
+
: `qwen-code ${result.timedOut ? 'timed out' : 'failed'} (exit ${result.exitCode}, ${result.durationMs}ms)`);
|
|
72
|
+
// Deposit results
|
|
73
|
+
if (output) {
|
|
74
|
+
const deposits = resolveOutput(output, result, signal);
|
|
75
|
+
for (const deposit of deposits) {
|
|
76
|
+
await ctx.deposit(deposit.type, deposit.payload ?? result, {
|
|
77
|
+
causedBy: [signal.id],
|
|
78
|
+
tags: deposit.tags,
|
|
79
|
+
ttl: deposit.ttl,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
await ctx.deposit('qwen-code:completed', result, {
|
|
85
|
+
causedBy: [signal.id],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
if (autoWithdraw) {
|
|
89
|
+
await ctx.withdraw(signal.id);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
// ----------------------------------------------------------
|
|
94
|
+
// Subprocess management
|
|
95
|
+
// ----------------------------------------------------------
|
|
96
|
+
function buildQwenCodeArgs(prompt, model, maxTurns, allowedCommands) {
|
|
97
|
+
const args = [
|
|
98
|
+
'-p', prompt, // Non-interactive mode with prompt
|
|
99
|
+
'--model', model,
|
|
100
|
+
'--max-turns', String(maxTurns),
|
|
101
|
+
];
|
|
102
|
+
if (allowedCommands && allowedCommands.length > 0) {
|
|
103
|
+
args.push('--allowed-commands', allowedCommands.join(','));
|
|
104
|
+
}
|
|
105
|
+
return args;
|
|
106
|
+
}
|
|
107
|
+
function runQwenCode(binary, args, cwd, env, timeout, onOutput) {
|
|
108
|
+
return new Promise((resolve) => {
|
|
109
|
+
const startTime = Date.now();
|
|
110
|
+
let stdout = '';
|
|
111
|
+
let stderr = '';
|
|
112
|
+
let timedOut = false;
|
|
113
|
+
const child = spawn(binary, args, {
|
|
114
|
+
cwd,
|
|
115
|
+
env,
|
|
116
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
117
|
+
});
|
|
118
|
+
// Set up timeout
|
|
119
|
+
const timer = setTimeout(() => {
|
|
120
|
+
timedOut = true;
|
|
121
|
+
child.kill('SIGTERM');
|
|
122
|
+
// Force kill after 5s if SIGTERM doesn't work
|
|
123
|
+
setTimeout(() => {
|
|
124
|
+
if (!child.killed)
|
|
125
|
+
child.kill('SIGKILL');
|
|
126
|
+
}, 5000);
|
|
127
|
+
}, timeout);
|
|
128
|
+
child.stdout?.on('data', (data) => {
|
|
129
|
+
const chunk = data.toString();
|
|
130
|
+
stdout += chunk;
|
|
131
|
+
onOutput?.(chunk);
|
|
132
|
+
});
|
|
133
|
+
child.stderr?.on('data', (data) => {
|
|
134
|
+
stderr += data.toString();
|
|
135
|
+
});
|
|
136
|
+
child.on('close', (code) => {
|
|
137
|
+
clearTimeout(timer);
|
|
138
|
+
resolve({
|
|
139
|
+
text: stdout.trim(),
|
|
140
|
+
stderr: stderr.trim(),
|
|
141
|
+
exitCode: code ?? (timedOut ? 124 : 1),
|
|
142
|
+
durationMs: Date.now() - startTime,
|
|
143
|
+
success: code === 0,
|
|
144
|
+
timedOut,
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
child.on('error', (err) => {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
resolve({
|
|
150
|
+
text: '',
|
|
151
|
+
stderr: `Failed to spawn ${binary}: ${err.message}.\n\nEnsure qwen-code is installed:\n npm install -g qwen-code\n\nOr specify the path:\n withQwenCode({ binary: '/path/to/qwen-code', ... })`,
|
|
152
|
+
exitCode: 127,
|
|
153
|
+
durationMs: Date.now() - startTime,
|
|
154
|
+
success: false,
|
|
155
|
+
timedOut: false,
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
// ----------------------------------------------------------
|
|
161
|
+
// Output mapping
|
|
162
|
+
// ----------------------------------------------------------
|
|
163
|
+
function resolveOutput(output, result, signal) {
|
|
164
|
+
if (typeof output === 'function') {
|
|
165
|
+
const mapped = output(result, signal);
|
|
166
|
+
return Array.isArray(mapped) ? mapped : [mapped];
|
|
167
|
+
}
|
|
168
|
+
return [{
|
|
169
|
+
type: output.type,
|
|
170
|
+
payload: result,
|
|
171
|
+
tags: output.tags,
|
|
172
|
+
ttl: output.ttl,
|
|
173
|
+
}];
|
|
174
|
+
}
|
|
175
|
+
//# sourceMappingURL=qwen-code.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"qwen-code.js","sourceRoot":"","sources":["../../../src/providers/qwen-code.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import type { Signal } from '../core/types.js';
|
|
2
|
+
import type { ActionHandler, OutputMapping, ContextAssemblyConfig } from './types.js';
|
|
3
|
+
import type { ToolDefinition, ToolLoopConfig } from './tool-loop.js';
|
|
4
|
+
/**
|
|
5
|
+
* A loaded skill — resolved from disk at init time.
|
|
6
|
+
*/
|
|
7
|
+
export interface Skill {
|
|
8
|
+
/** Skill name (directory name). */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Raw markdown content from SKILL.md. */
|
|
11
|
+
content: string;
|
|
12
|
+
/** Path the skill was loaded from. */
|
|
13
|
+
path: string;
|
|
14
|
+
/**
|
|
15
|
+
* Optional metadata parsed from YAML frontmatter.
|
|
16
|
+
* Supports: model, tools, maxTurns, tags.
|
|
17
|
+
*/
|
|
18
|
+
meta?: SkillMeta;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Optional YAML frontmatter in SKILL.md.
|
|
22
|
+
*
|
|
23
|
+
* ---
|
|
24
|
+
* model: Qwen3-Coder-Next
|
|
25
|
+
* tools: [file_read, grep, bash]
|
|
26
|
+
* maxTurns: 25
|
|
27
|
+
* tags: [review, security]
|
|
28
|
+
* ---
|
|
29
|
+
*/
|
|
30
|
+
export interface SkillMeta {
|
|
31
|
+
/** Recommended model for this skill. */
|
|
32
|
+
model?: string;
|
|
33
|
+
/** Tool names this skill expects to be available. */
|
|
34
|
+
tools?: string[];
|
|
35
|
+
/** Recommended max turns when using this skill. */
|
|
36
|
+
maxTurns?: number;
|
|
37
|
+
/** Skill tags for filtering/discovery. */
|
|
38
|
+
tags?: string[];
|
|
39
|
+
/** Any additional frontmatter fields. */
|
|
40
|
+
[key: string]: unknown;
|
|
41
|
+
}
|
|
42
|
+
export interface SkillConfig<T = Record<string, unknown>> {
|
|
43
|
+
/** vLLM endpoint. */
|
|
44
|
+
endpoint: string;
|
|
45
|
+
/** Model name. Skills can recommend a model via frontmatter. */
|
|
46
|
+
model?: string;
|
|
47
|
+
/** Optional API key for vLLM. */
|
|
48
|
+
apiKey?: string;
|
|
49
|
+
/**
|
|
50
|
+
* Skills to load. Each entry can be:
|
|
51
|
+
* - A skill name (resolved from skillsDir)
|
|
52
|
+
* - An absolute path to a SKILL.md
|
|
53
|
+
* - A pre-loaded Skill object
|
|
54
|
+
*/
|
|
55
|
+
skills: Array<string | Skill>;
|
|
56
|
+
/**
|
|
57
|
+
* Directory containing skill folders. Default: './skills'.
|
|
58
|
+
* Each skill is a directory with a SKILL.md file inside.
|
|
59
|
+
*/
|
|
60
|
+
skillsDir?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Tools available to the agent. Skills may recommend tools via
|
|
63
|
+
* frontmatter, but this list takes precedence.
|
|
64
|
+
* If not provided, defaults to all built-in tools.
|
|
65
|
+
*/
|
|
66
|
+
tools?: ToolDefinition[];
|
|
67
|
+
/** Build the prompt from the signal. */
|
|
68
|
+
prompt: string | ((signal: Signal<T>) => string | Promise<string>);
|
|
69
|
+
/**
|
|
70
|
+
* Additional system prompt to prepend before skills.
|
|
71
|
+
* Use for colony-specific instructions that aren't part of any skill.
|
|
72
|
+
*/
|
|
73
|
+
systemPrompt?: string;
|
|
74
|
+
/** Maximum conversation turns. Skills can recommend via frontmatter. */
|
|
75
|
+
maxTurns?: number;
|
|
76
|
+
/** Token budget. */
|
|
77
|
+
maxBudget?: {
|
|
78
|
+
tokens: number;
|
|
79
|
+
};
|
|
80
|
+
/** Request timeout per LLM call in ms. */
|
|
81
|
+
timeoutMs?: number;
|
|
82
|
+
/** Working directory for tools. */
|
|
83
|
+
workingDirectory?: string | ((signal: Signal<T>) => string);
|
|
84
|
+
/** Context assembly config — enrich prompts from signal lineage. */
|
|
85
|
+
context?: ContextAssemblyConfig;
|
|
86
|
+
/** Observability hooks. */
|
|
87
|
+
onToolCall?: ToolLoopConfig<T>['onToolCall'];
|
|
88
|
+
onTurn?: ToolLoopConfig<T>['onTurn'];
|
|
89
|
+
/** Map output to signal deposits. */
|
|
90
|
+
output?: OutputMapping<T>;
|
|
91
|
+
/** Auto-withdraw triggering signal. Default: true. */
|
|
92
|
+
autoWithdraw?: boolean;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Creates an action handler powered by loaded skills.
|
|
96
|
+
*
|
|
97
|
+
* Skills are loaded once at creation time (not per-signal).
|
|
98
|
+
* The loaded skill content is composed into a system prompt
|
|
99
|
+
* and passed to withToolLoop for execution.
|
|
100
|
+
*/
|
|
101
|
+
export declare function withSkill<T = Record<string, unknown>>(config: SkillConfig<T>): ActionHandler<T>;
|
|
102
|
+
/**
|
|
103
|
+
* Load skill references into Skill objects.
|
|
104
|
+
* Handles: pre-loaded Skill objects, absolute paths, and name-based resolution.
|
|
105
|
+
*/
|
|
106
|
+
export declare function loadSkills(refs: Array<string | Skill>, skillsDir: string): Promise<Skill[]>;
|
|
107
|
+
/**
|
|
108
|
+
* Load a single skill from a directory path.
|
|
109
|
+
*/
|
|
110
|
+
export declare function loadSkill(skillDir: string): Promise<Skill>;
|
|
111
|
+
/**
|
|
112
|
+
* Parse YAML frontmatter from a SKILL.md file.
|
|
113
|
+
* Simple parser — handles key: value and key: [array] syntax.
|
|
114
|
+
* No external YAML dependency needed.
|
|
115
|
+
*/
|
|
116
|
+
export declare function parseFrontmatter(content: string): {
|
|
117
|
+
meta?: SkillMeta;
|
|
118
|
+
body: string;
|
|
119
|
+
};
|
|
120
|
+
//# sourceMappingURL=skill.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill.d.ts","sourceRoot":"","sources":["../../../src/providers/skill.ts"],"names":[],"mappings":"AA6CA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACtF,OAAO,KAAK,EAAE,cAAc,EAAE,cAAc,EAAkB,MAAM,gBAAgB,CAAC;AAMrF;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IAEb,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAC;IAEhB,sCAAsC;IACtC,IAAI,EAAE,MAAM,CAAC;IAEb;;;OAGG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAEjB,mDAAmD;IACnD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAEhB,yCAAyC;IACzC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD,MAAM,WAAW,WAAW,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACtD,qBAAqB;IACrB,QAAQ,EAAE,MAAM,CAAC;IAEjB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;OAKG;IACH,MAAM,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,CAAC;IAE9B;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;;;OAIG;IACH,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IAEzB,wCAAwC;IACxC,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC;IAEnE;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,wEAAwE;IACxE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,oBAAoB;IACpB,SAAS,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAE/B,0CAA0C;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,mCAAmC;IACnC,gBAAgB,CAAC,EAAE,MAAM,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;IAE5D,oEAAoE;IACpE,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAEhC,2BAA2B;IAC3B,UAAU,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;IAC7C,MAAM,CAAC,EAAE,cAAc,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAErC,qCAAqC;IACrC,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC;IAE1B,sDAAsD;IACtD,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAMD;;;;;;GAMG;AACH,wBAAgB,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACnD,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,GACrB,aAAa,CAAC,CAAC,CAAC,CA4ElB;AAMD;;;GAGG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,KAAK,CAAC,MAAM,GAAG,KAAK,CAAC,EAC3B,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,KAAK,EAAE,CAAC,CAiDlB;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAMhE;AAgDD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,IAAI,CAAC,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAuCpF"}
|