@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 CHANGED
@@ -3,5 +3,8 @@
3
3
  ## Unreleased
4
4
  - Initial public packaging for @mcoda/agents.
5
5
 
6
- ## 0.1.7
6
+ ## 0.1.9
7
+ - Release v0.1.9.
8
+
9
+ ## 0.1.8
7
10
  - Initial release.
package/README.md CHANGED
@@ -1,9 +1,36 @@
1
1
  # @mcoda/agents
2
2
 
3
- Agent registry and capability definitions for mcoda.
3
+ Agent registry, adapter wiring, and invocation helpers for mcoda.
4
4
 
5
- ## Usage
6
- This package is primarily an internal dependency of `mcoda`.
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":"AACA,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;AAoFhG,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;IAmB9E,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;YA0B5F,mBAAmB;CASlC"}
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 enriched = await this.applyGatewayHandoff(request);
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 enriched = await this.applyGatewayHandoff(request);
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":"AAIA,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;CAyC1F,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,CA0EhE"}
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 args = ["exec", "--model", model ?? "gpt-5.1-codex-max", "--full-auto", "--json"];
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 args = ["exec", "--model", model ?? "gpt-5.1-codex-max", "--full-auto", "--json"];
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.7",
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.7",
34
- "@mcoda/db": "0.1.7"
33
+ "@mcoda/shared": "0.1.9",
34
+ "@mcoda/db": "0.1.9"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsc -p tsconfig.json",