@mcoda/agents 0.1.7 → 0.1.9
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/CHANGELOG.md +4 -1
- package/README.md +30 -3
- package/dist/AgentService/AgentService.d.ts +1 -0
- package/dist/AgentService/AgentService.d.ts.map +1 -1
- package/dist/AgentService/AgentService.js +34 -2
- package/dist/adapters/codex/CodexCliRunner.d.ts.map +1 -1
- package/dist/adapters/codex/CodexCliRunner.js +37 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
# @mcoda/agents
|
|
2
2
|
|
|
3
|
-
Agent registry and
|
|
3
|
+
Agent registry, adapter wiring, and invocation helpers for mcoda.
|
|
4
4
|
|
|
5
|
-
##
|
|
6
|
-
|
|
5
|
+
## Install
|
|
6
|
+
- Requires Node.js >= 20.
|
|
7
|
+
- Install: `npm i @mcoda/agents`
|
|
8
|
+
|
|
9
|
+
## What it provides
|
|
10
|
+
- AgentService for resolving agents, prompts, capabilities, and secrets.
|
|
11
|
+
- Adapter interfaces (AgentAdapter, InvocationRequest/InvocationResult).
|
|
12
|
+
- Built-in adapters for OpenAI, Codex, Gemini, Ollama, Zhipu, local models, and QA.
|
|
13
|
+
|
|
14
|
+
## Example
|
|
15
|
+
```ts
|
|
16
|
+
import { AgentService } from "@mcoda/agents";
|
|
17
|
+
|
|
18
|
+
const service = await AgentService.create();
|
|
19
|
+
const agent = await service.resolveAgent("codex");
|
|
20
|
+
const adapter = await service.getAdapter(agent);
|
|
21
|
+
const result = await adapter.invoke?.({ input: "Summarize this repo." });
|
|
22
|
+
|
|
23
|
+
if (result) {
|
|
24
|
+
console.log(result.output);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
await service.close();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Notes
|
|
31
|
+
- Primarily used by the mcoda CLI; APIs may evolve.
|
|
32
|
+
- Set `MCODA_STREAM_IO=1` to emit adapter I/O lines to stderr.
|
|
33
|
+
- If `~/.docdex/agents.md` exists, AgentService prepends it to every agent invocation.
|
|
7
34
|
|
|
8
35
|
## License
|
|
9
36
|
MIT - see `LICENSE`.
|
|
@@ -18,5 +18,6 @@ export declare class AgentService {
|
|
|
18
18
|
invoke(agentId: string, request: InvocationRequest): Promise<InvocationResult>;
|
|
19
19
|
invokeStream(agentId: string, request: InvocationRequest): Promise<AsyncGenerator<InvocationResult>>;
|
|
20
20
|
private applyGatewayHandoff;
|
|
21
|
+
private applyDocdexGuidance;
|
|
21
22
|
}
|
|
22
23
|
//# sourceMappingURL=AgentService.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentService.d.ts","sourceRoot":"","sources":["../../src/AgentService/AgentService.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"AgentService.d.ts","sourceRoot":"","sources":["../../src/AgentService/AgentService.ts"],"names":[],"mappings":"AAGA,OAAO,EAAgB,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACzG,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAU7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAuGhG,qBAAa,YAAY;IACX,OAAO,CAAC,IAAI;gBAAJ,IAAI,EAAE,gBAAgB;WAE7B,MAAM,IAAI,OAAO,CAAC,YAAY,CAAC;IAKtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAItB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IAUhD,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC;IAIrE,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAInD,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;YAIpD,kBAAkB;YAMlB,kBAAkB;IA6BhC,OAAO,CAAC,kBAAkB;IA+BpB,UAAU,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC;IAsC/C,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC;IAmBlD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAoB9E,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;YA2B5F,mBAAmB;YAUnB,mBAAmB;CAMlC"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { promises as fs } from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
2
4
|
import { CryptoHelper } from "@mcoda/shared";
|
|
3
5
|
import { GlobalRepository } from "@mcoda/db";
|
|
4
6
|
import { CodexAdapter } from "../adapters/codex/CodexAdapter.js";
|
|
@@ -32,6 +34,11 @@ const MAX_HANDOFF_CHARS = 8000;
|
|
|
32
34
|
const IO_ENV = "MCODA_STREAM_IO";
|
|
33
35
|
const IO_PROMPT_ENV = "MCODA_STREAM_IO_PROMPT";
|
|
34
36
|
const IO_PREFIX = "[agent-io]";
|
|
37
|
+
const DOCDEX_GUIDANCE_HEADER = "[Docdex guidance]";
|
|
38
|
+
const DOCDEX_GUIDANCE_MAX_CHARS = 12000;
|
|
39
|
+
const DOCDEX_GUIDANCE_PATH = path.join(os.homedir(), ".docdex", "agents.md");
|
|
40
|
+
let docdexGuidanceCache;
|
|
41
|
+
let docdexGuidanceLoaded = false;
|
|
35
42
|
const isIoEnabled = () => {
|
|
36
43
|
const raw = process.env[IO_ENV];
|
|
37
44
|
if (!raw)
|
|
@@ -87,6 +94,22 @@ const readGatewayHandoff = async () => {
|
|
|
87
94
|
return undefined;
|
|
88
95
|
}
|
|
89
96
|
};
|
|
97
|
+
const readDocdexGuidance = async () => {
|
|
98
|
+
if (docdexGuidanceLoaded)
|
|
99
|
+
return docdexGuidanceCache;
|
|
100
|
+
docdexGuidanceLoaded = true;
|
|
101
|
+
try {
|
|
102
|
+
const content = await fs.readFile(DOCDEX_GUIDANCE_PATH, "utf8");
|
|
103
|
+
const trimmed = content.trim();
|
|
104
|
+
if (!trimmed)
|
|
105
|
+
return undefined;
|
|
106
|
+
docdexGuidanceCache = trimmed.slice(0, DOCDEX_GUIDANCE_MAX_CHARS);
|
|
107
|
+
return docdexGuidanceCache;
|
|
108
|
+
}
|
|
109
|
+
catch {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
};
|
|
90
113
|
export class AgentService {
|
|
91
114
|
constructor(repo) {
|
|
92
115
|
this.repo = repo;
|
|
@@ -241,7 +264,8 @@ export class AgentService {
|
|
|
241
264
|
if (!adapter.invoke) {
|
|
242
265
|
throw new Error("Adapter does not support invoke");
|
|
243
266
|
}
|
|
244
|
-
const
|
|
267
|
+
const withDocdex = await this.applyDocdexGuidance(request);
|
|
268
|
+
const enriched = await this.applyGatewayHandoff(withDocdex);
|
|
245
269
|
const ioEnabled = isIoEnabled();
|
|
246
270
|
if (ioEnabled) {
|
|
247
271
|
renderIoHeader(agent, enriched, "invoke");
|
|
@@ -259,7 +283,8 @@ export class AgentService {
|
|
|
259
283
|
if (!adapter.invokeStream) {
|
|
260
284
|
throw new Error("Adapter does not support streaming");
|
|
261
285
|
}
|
|
262
|
-
const
|
|
286
|
+
const withDocdex = await this.applyDocdexGuidance(request);
|
|
287
|
+
const enriched = await this.applyGatewayHandoff(withDocdex);
|
|
263
288
|
const ioEnabled = isIoEnabled();
|
|
264
289
|
const generator = await adapter.invokeStream(enriched);
|
|
265
290
|
async function* wrap() {
|
|
@@ -288,4 +313,11 @@ export class AgentService {
|
|
|
288
313
|
const suffix = `\n\n${HANDOFF_HEADER}\n${handoff}`;
|
|
289
314
|
return { ...request, input: `${request.input ?? ""}${suffix}` };
|
|
290
315
|
}
|
|
316
|
+
async applyDocdexGuidance(request) {
|
|
317
|
+
const guidance = await readDocdexGuidance();
|
|
318
|
+
if (!guidance)
|
|
319
|
+
return request;
|
|
320
|
+
const prefix = `${DOCDEX_GUIDANCE_HEADER}\n${guidance}\n\n`;
|
|
321
|
+
return { ...request, input: `${prefix}${request.input ?? ""}` };
|
|
322
|
+
}
|
|
291
323
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodexCliRunner.d.ts","sourceRoot":"","sources":["../../../src/adapters/codex/CodexCliRunner.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"CodexCliRunner.d.ts","sourceRoot":"","sources":["../../../src/adapters/codex/CodexCliRunner.ts"],"names":[],"mappings":"AA0BA,eAAO,MAAM,UAAU,GAAI,sBAAoB,KAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CA2BjG,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,QAAQ,MAAM,EAAE,QAAQ,MAAM,KAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CA8C1F,CAAC;AAEF,wBAAuB,kBAAkB,CACvC,MAAM,EAAE,MAAM,EACd,KAAK,CAAC,EAAE,MAAM,GACb,cAAc,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,EAAE,IAAI,EAAE,OAAO,CAAC,CA+EhE"}
|
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
import { spawn, spawnSync } from "node:child_process";
|
|
2
2
|
const CODEX_MAX_BUFFER_BYTES = 10 * 1024 * 1024;
|
|
3
|
+
const CODEX_REASONING_ENV = "MCODA_CODEX_REASONING_EFFORT";
|
|
4
|
+
const CODEX_REASONING_ENV_FALLBACK = "CODEX_REASONING_EFFORT";
|
|
5
|
+
const normalizeReasoningEffort = (raw) => {
|
|
6
|
+
if (!raw)
|
|
7
|
+
return undefined;
|
|
8
|
+
const normalized = raw.trim().toLowerCase();
|
|
9
|
+
if (!normalized)
|
|
10
|
+
return undefined;
|
|
11
|
+
if (!["low", "medium", "high", "xhigh"].includes(normalized))
|
|
12
|
+
return undefined;
|
|
13
|
+
return normalized;
|
|
14
|
+
};
|
|
15
|
+
const resolveReasoningEffort = (model) => {
|
|
16
|
+
const configured = normalizeReasoningEffort(process.env[CODEX_REASONING_ENV] ?? process.env[CODEX_REASONING_ENV_FALLBACK]);
|
|
17
|
+
const normalizedModel = (model ?? "").toLowerCase();
|
|
18
|
+
const isGpt51 = normalizedModel.includes("gpt-5.1");
|
|
19
|
+
if (configured) {
|
|
20
|
+
if (configured === "xhigh" && isGpt51)
|
|
21
|
+
return "high";
|
|
22
|
+
return configured;
|
|
23
|
+
}
|
|
24
|
+
if (isGpt51)
|
|
25
|
+
return "high";
|
|
26
|
+
return undefined;
|
|
27
|
+
};
|
|
3
28
|
export const cliHealthy = (throwOnError = false) => {
|
|
4
29
|
if (process.env.MCODA_CLI_STUB === "1") {
|
|
5
30
|
return { ok: true, details: { stub: true } };
|
|
@@ -35,7 +60,12 @@ export const runCodexExec = (prompt, model) => {
|
|
|
35
60
|
return { output, raw };
|
|
36
61
|
}
|
|
37
62
|
const health = cliHealthy(true);
|
|
38
|
-
const
|
|
63
|
+
const resolvedModel = model ?? "gpt-5.1-codex-max";
|
|
64
|
+
const args = ["exec", "--model", resolvedModel, "--full-auto", "--json"];
|
|
65
|
+
const reasoningEffort = resolveReasoningEffort(resolvedModel);
|
|
66
|
+
if (reasoningEffort) {
|
|
67
|
+
args.push("-c", `model_reasoning_effort=${reasoningEffort}`);
|
|
68
|
+
}
|
|
39
69
|
const result = spawnSync("codex", args, {
|
|
40
70
|
input: prompt,
|
|
41
71
|
encoding: "utf8",
|
|
@@ -78,7 +108,12 @@ export async function* runCodexExecStream(prompt, model) {
|
|
|
78
108
|
return;
|
|
79
109
|
}
|
|
80
110
|
cliHealthy(true);
|
|
81
|
-
const
|
|
111
|
+
const resolvedModel = model ?? "gpt-5.1-codex-max";
|
|
112
|
+
const args = ["exec", "--model", resolvedModel, "--full-auto", "--json"];
|
|
113
|
+
const reasoningEffort = resolveReasoningEffort(resolvedModel);
|
|
114
|
+
if (reasoningEffort) {
|
|
115
|
+
args.push("-c", `model_reasoning_effort=${reasoningEffort}`);
|
|
116
|
+
}
|
|
82
117
|
const child = spawn("codex", args, { stdio: ["pipe", "pipe", "pipe"] });
|
|
83
118
|
child.stdin.write(prompt);
|
|
84
119
|
child.stdin.end();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mcoda/agents",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Agent registry and capabilities for mcoda.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"access": "public"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@mcoda/shared": "0.1.
|
|
34
|
-
"@mcoda/db": "0.1.
|
|
33
|
+
"@mcoda/shared": "0.1.9",
|
|
34
|
+
"@mcoda/db": "0.1.9"
|
|
35
35
|
},
|
|
36
36
|
"scripts": {
|
|
37
37
|
"build": "tsc -p tsconfig.json",
|