@mcoda/agents 0.1.72 → 0.1.74

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.
@@ -1 +1 @@
1
- {"version":3,"file":"AgentService.d.ts","sourceRoot":"","sources":["../../src/AgentService/AgentService.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EAKpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAa7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAgOhG,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,qBAAa,YAAY;IAErB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;gBADP,IAAI,EAAE,gBAAgB,EACtB,OAAO,GAAE,mBAAwB;WAG9B,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+CpB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA+C/E,OAAO,CAAC,KAAK;YAIC,OAAO;YASP,UAAU;IAQxB,OAAO,CAAC,6BAA6B;YAOvB,mBAAmB;YAgCnB,uBAAuB;YAiBvB,gBAAgB;IAM9B,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,8BAA8B;IAStC,OAAO,CAAC,iBAAiB;YAOX,oBAAoB;YA6BpB,oBAAoB;YA6CpB,sBAAsB;YAkBtB,mBAAmB;YAUnB,4BAA4B;IAkCpC,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;IA6H9E,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;YAwP5F,mBAAmB;YAkBnB,uBAAuB;YAwBvB,mBAAmB;CAYlC"}
1
+ {"version":3,"file":"AgentService.d.ts","sourceRoot":"","sources":["../../src/AgentService/AgentService.ts"],"names":[],"mappings":"AAGA,OAAO,EACL,KAAK,EACL,iBAAiB,EACjB,WAAW,EACX,mBAAmB,EAOpB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAa7C,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,6BAA6B,CAAC;AAuOhG,UAAU,mBAAmB;IAC3B,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,sBAAsB,CAAC,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;IAChD,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAED,qBAAa,YAAY;IAErB,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;gBADP,IAAI,EAAE,gBAAgB,EACtB,OAAO,GAAE,mBAAwB;WAG9B,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+CpB,UAAU,CAAC,KAAK,EAAE,KAAK,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IA+C/E,OAAO,CAAC,KAAK;YAIC,OAAO;YASP,UAAU;IAQxB,OAAO,CAAC,6BAA6B;YAOvB,mBAAmB;YAgCnB,uBAAuB;YAiBvB,gBAAgB;IAM9B,OAAO,CAAC,MAAM;IAId,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,8BAA8B;IAStC,OAAO,CAAC,iBAAiB;YAOX,oBAAoB;YA6BpB,oBAAoB;YA6CpB,sBAAsB;YAkBtB,mBAAmB;YAUnB,4BAA4B;IAkCpC,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;IA6H9E,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,cAAc,CAAC,gBAAgB,CAAC,CAAC;YAwP5F,mBAAmB;YAkBnB,uBAAuB;YAwBvB,mBAAmB;CAYlC"}
@@ -1,7 +1,7 @@
1
1
  import { promises as fs } from "node:fs";
2
2
  import os from "node:os";
3
3
  import path from "node:path";
4
- import { CryptoHelper, } from "@mcoda/shared";
4
+ import { CryptoHelper, LOCAL_OPENAI_COMPATIBLE_ADAPTER_ALIASES, isLocalOpenAiCompatibleAdapter, } from "@mcoda/shared";
5
5
  import { GlobalRepository } from "@mcoda/db";
6
6
  import { CodexAdapter } from "../adapters/codex/CodexAdapter.js";
7
7
  import { GeminiAdapter } from "../adapters/gemini/GeminiAdapter.js";
@@ -18,7 +18,13 @@ import { ClaudeAdapter } from "../adapters/claude/ClaudeAdapter.js";
18
18
  import { parseInvocationFailure } from "./InvocationFailureParser.js";
19
19
  const CLI_BASED_ADAPTERS = new Set(["codex-cli", "gemini-cli", "openai-cli", "ollama-cli", "codali-cli", "claude-cli"]);
20
20
  const LOCAL_ADAPTERS = new Set(["local-model"]);
21
- const OFFLINE_CAPABLE_ADAPTERS = new Set(["local-model", "ollama-cli", "qa-cli"]);
21
+ const LOCAL_OPENAI_COMPATIBLE_ADAPTERS = new Set(LOCAL_OPENAI_COMPATIBLE_ADAPTER_ALIASES);
22
+ const OFFLINE_CAPABLE_ADAPTERS = new Set([
23
+ "local-model",
24
+ "ollama-cli",
25
+ "qa-cli",
26
+ ...LOCAL_OPENAI_COMPATIBLE_ADAPTERS,
27
+ ]);
22
28
  const SUPPORTED_ADAPTERS = new Set([
23
29
  "openai-api",
24
30
  "codex-cli",
@@ -32,6 +38,7 @@ const SUPPORTED_ADAPTERS = new Set([
32
38
  "ollama-cli",
33
39
  "codali-cli",
34
40
  "mswarm-worker",
41
+ ...LOCAL_OPENAI_COMPATIBLE_ADAPTERS,
35
42
  ]);
36
43
  const DEFAULT_JOB_PROMPT = "You are an mcoda agent that follows workspace runbooks and responds with actionable, concise output.";
37
44
  const DEFAULT_CHARACTER_PROMPT = "Write clearly, avoid hallucinations, cite assumptions, and prioritize risk mitigation for the user.";
@@ -332,7 +339,7 @@ export class AgentService {
332
339
  const config = await this.buildAdapterConfig(agent);
333
340
  const adapterType = this.resolveAdapterType(agent, config.apiKey, adapterOverride);
334
341
  const configWithAdapter = { ...config, adapter: adapterType };
335
- if (adapterType === "openai-api") {
342
+ if (adapterType === "openai-api" || isLocalOpenAiCompatibleAdapter(adapterType)) {
336
343
  return new OpenAiAdapter(configWithAdapter);
337
344
  }
338
345
  if (adapterType === "mswarm-worker") {
@@ -1,4 +1,4 @@
1
- import { Agent, AgentAuthMetadata, AgentHealth, AgentPromptManifest } from "@mcoda/shared";
1
+ import type { Agent, AgentAuthMetadata, AgentHealth, AgentPromptManifest, LocalOpenAiCompatibleRunnerConfig, LocalRunnerAuthMode, LocalRunnerKind, LocalRunnerResponseFormatStrategy } from "@mcoda/shared";
2
2
  export interface AdapterConfig {
3
3
  agent: Agent;
4
4
  capabilities: string[];
@@ -13,6 +13,20 @@ export interface AdapterConfig {
13
13
  prompts?: AgentPromptManifest;
14
14
  authMetadata?: AgentAuthMetadata;
15
15
  adapter?: string;
16
+ localRunner?: LocalOpenAiCompatibleRunnerConfig;
17
+ runnerKind?: LocalRunnerKind;
18
+ authMode?: LocalRunnerAuthMode;
19
+ dummyBearerToken?: string;
20
+ headers?: Record<string, string>;
21
+ extraBody?: Record<string, unknown>;
22
+ responseFormatStrategy?: LocalRunnerResponseFormatStrategy;
23
+ healthPath?: string;
24
+ modelsPath?: string;
25
+ requireModelInRequest?: boolean;
26
+ supportsStreaming?: boolean;
27
+ supportsTools?: boolean;
28
+ supportsJsonSchema?: boolean;
29
+ supportsGbnf?: boolean;
16
30
  }
17
31
  export interface DocdexRuntimeContext {
18
32
  enabled?: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"AdapterTypes.d.ts","sourceRoot":"","sources":["../../src/adapters/AdapterTypes.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE3F,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IACb,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,OAAO,CAAC,EAAE,mBAAmB,CAAC;IAC9B,YAAY,CAAC,EAAE,iBAAiB,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,gBAAgB,CAAC,EAAE,yBAAyB,GAAG,MAAM,CAAC;IACtD,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC,CAAC;IACnD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACrC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC,CAAC;IACpC,MAAM,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAC/D,YAAY,CAAC,CAAC,MAAM,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;CAC3F;AAED,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAC;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC"}
1
+ {"version":3,"file":"AdapterTypes.d.ts","sourceRoot":"","sources":["../../src/adapters/AdapterTypes.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,15 @@
1
1
  import { AgentHealth } from "@mcoda/shared";
2
2
  import { AdapterConfig, AgentAdapter, InvocationRequest, InvocationResult } from "../AdapterTypes.js";
3
- export declare const resolveCodaliProviderFromAdapter: (params: {
4
- sourceAdapter?: string;
5
- explicitProvider?: string;
6
- }) => {
3
+ type CodaliProviderResolution = {
7
4
  provider: string;
8
5
  sourceAdapter?: string;
9
6
  requiresApiKey: boolean;
7
+ localOpenAiCompatible: boolean;
10
8
  };
9
+ export declare const resolveCodaliProviderFromAdapter: (params: {
10
+ sourceAdapter?: string;
11
+ explicitProvider?: string;
12
+ }) => CodaliProviderResolution;
11
13
  export declare class CodaliAdapter implements AgentAdapter {
12
14
  private config;
13
15
  constructor(config: AdapterConfig);
@@ -16,4 +18,5 @@ export declare class CodaliAdapter implements AgentAdapter {
16
18
  invoke(request: InvocationRequest): Promise<InvocationResult>;
17
19
  invokeStream(request: InvocationRequest): AsyncGenerator<InvocationResult, void, unknown>;
18
20
  }
21
+ export {};
19
22
  //# sourceMappingURL=CodaliAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CodaliAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/codali/CodaliAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAyEtG,eAAO,MAAM,gCAAgC,GAAI,QAAQ;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,KAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAiCtE,CAAC;AAmEF,qBAAa,aAAc,YAAW,YAAY;IACpC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEnC,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIpC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAanC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAwE5D,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC;CAyEjG"}
1
+ {"version":3,"file":"CodaliAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/codali/CodaliAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAIZ,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AA4CtG,KAAK,wBAAwB,GAAG;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,OAAO,CAAC;IACxB,qBAAqB,EAAE,OAAO,CAAC;CAChC,CAAC;AA+BF,eAAO,MAAM,gCAAgC,GAAI,QAAQ;IACvD,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B,KAAG,wBAuCH,CAAC;AAiIF,qBAAa,aAAc,YAAW,YAAY;IACpC,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,aAAa;IAEnC,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIpC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAanC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA2E5D,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC;CA4EjG"}
@@ -1,3 +1,4 @@
1
+ import { isLocalOpenAiCompatibleAdapter, normalizeLocalOpenAiCompatibleRunnerConfig, } from "@mcoda/shared";
1
2
  import { cliHealthy, runCodaliExec, runCodaliStream } from "./CodaliCliRunner.js";
2
3
  const resolveString = (value) => (typeof value === "string" && value.trim() ? value : undefined);
3
4
  const resolveMetadataValue = (metadata, keys) => {
@@ -60,13 +61,16 @@ const resolveAgentSlug = (request, config) => {
60
61
  export const resolveCodaliProviderFromAdapter = (params) => {
61
62
  const sourceAdapter = params.sourceAdapter;
62
63
  const explicitProvider = params.explicitProvider;
64
+ const localOpenAiCompatible = isLocalOpenAiCompatibleAdapter(sourceAdapter);
63
65
  if (explicitProvider) {
64
66
  const providerRequires = PROVIDERS_REQUIRING_API_KEY.has(explicitProvider);
65
- const requiresApiKey = providerRequires && !SESSION_AUTH_ADAPTERS.has(sourceAdapter ?? "");
67
+ const sourceUsesSessionAuth = SESSION_AUTH_ADAPTERS.has(sourceAdapter ?? "") || localOpenAiCompatible;
68
+ const requiresApiKey = providerRequires && !sourceUsesSessionAuth;
66
69
  return {
67
70
  provider: explicitProvider,
68
71
  sourceAdapter,
69
72
  requiresApiKey,
73
+ localOpenAiCompatible,
70
74
  };
71
75
  }
72
76
  if (sourceAdapter) {
@@ -74,17 +78,20 @@ export const resolveCodaliProviderFromAdapter = (params) => {
74
78
  throw new Error(`CODALI_UNSUPPORTED_ADAPTER: ${sourceAdapter} is not supported; configure a codali provider explicitly or use an openai/ollama adapter.`);
75
79
  }
76
80
  if (sourceAdapter === "openai-api") {
77
- return { provider: "openai-compatible", sourceAdapter, requiresApiKey: true };
81
+ return { provider: "openai-compatible", sourceAdapter, requiresApiKey: true, localOpenAiCompatible };
82
+ }
83
+ if (localOpenAiCompatible) {
84
+ return { provider: "openai-compatible", sourceAdapter, requiresApiKey: false, localOpenAiCompatible };
78
85
  }
79
86
  if (["openai-cli", "codex-cli"].includes(sourceAdapter)) {
80
- return { provider: "codex-cli", sourceAdapter, requiresApiKey: false };
87
+ return { provider: "codex-cli", sourceAdapter, requiresApiKey: false, localOpenAiCompatible };
81
88
  }
82
89
  if (["ollama-remote", "ollama-cli", "local-model"].includes(sourceAdapter)) {
83
- return { provider: "ollama-remote", sourceAdapter, requiresApiKey: false };
90
+ return { provider: "ollama-remote", sourceAdapter, requiresApiKey: false, localOpenAiCompatible };
84
91
  }
85
92
  }
86
93
  const requiresApiKey = PROVIDERS_REQUIRING_API_KEY.has("openai-compatible") && !SESSION_AUTH_ADAPTERS.has(sourceAdapter ?? "");
87
- return { provider: "openai-compatible", sourceAdapter, requiresApiKey };
94
+ return { provider: "openai-compatible", sourceAdapter, requiresApiKey, localOpenAiCompatible };
88
95
  };
89
96
  const resolveProviderInfo = (request, config) => {
90
97
  const anyConfig = config;
@@ -101,6 +108,12 @@ const ensureApiKey = (provider, sourceAdapter, requiresApiKey, config) => {
101
108
  const sourceLabel = sourceAdapter ? ` (source adapter: ${sourceAdapter})` : "";
102
109
  throw new Error(`AUTH_REQUIRED: API key missing for codali provider ${provider}${sourceLabel}; set CODALI_API_KEY or run \\\"mcoda agent auth set ${agentLabel}\\\".`);
103
110
  };
111
+ const ensureLocalOpenAiCompatibleBaseUrl = (providerInfo, baseUrl) => {
112
+ if (providerInfo.provider !== "openai-compatible" || !providerInfo.localOpenAiCompatible || baseUrl)
113
+ return;
114
+ const sourceLabel = providerInfo.sourceAdapter ? ` (source adapter: ${providerInfo.sourceAdapter})` : "";
115
+ throw new Error(`CONFIG_REQUIRED: baseUrl missing for local OpenAI-compatible codali provider${sourceLabel}; set config.baseUrl or agent.config.baseUrl.`);
116
+ };
104
117
  const resolveBaseUrl = (config) => {
105
118
  const anyConfig = config;
106
119
  const agentConfig = config.agent?.config;
@@ -111,6 +124,36 @@ const resolveBaseUrl = (config) => {
111
124
  resolveString(agentConfig?.endpoint) ??
112
125
  resolveString(agentConfig?.apiBaseUrl));
113
126
  };
127
+ const compactLocalRunnerConfig = (config) => {
128
+ const normalized = normalizeLocalOpenAiCompatibleRunnerConfig({
129
+ adapter: config.adapter ?? config.agent.adapter,
130
+ config,
131
+ agentConfig: config.agent.config,
132
+ });
133
+ const entries = Object.entries(normalized.config).filter(([, value]) => value !== undefined);
134
+ if (!normalized.isLocalOpenAiCompatible && entries.length === 0)
135
+ return undefined;
136
+ return Object.fromEntries(entries);
137
+ };
138
+ const resolveLocalRunnerCliOptions = (config) => {
139
+ const localRunner = compactLocalRunnerConfig(config);
140
+ return {
141
+ localRunner,
142
+ runnerKind: localRunner?.runnerKind,
143
+ authMode: localRunner?.authMode,
144
+ dummyBearerToken: localRunner?.dummyBearerToken,
145
+ headers: localRunner?.headers,
146
+ extraBody: localRunner?.extraBody,
147
+ responseFormatStrategy: localRunner?.responseFormatStrategy,
148
+ healthPath: localRunner?.healthPath,
149
+ modelsPath: localRunner?.modelsPath,
150
+ requireModelInRequest: localRunner?.requireModelInRequest,
151
+ supportsStreaming: localRunner?.supportsStreaming,
152
+ supportsTools: localRunner?.supportsTools,
153
+ supportsJsonSchema: localRunner?.supportsJsonSchema,
154
+ supportsGbnf: localRunner?.supportsGbnf,
155
+ };
156
+ };
114
157
  const resolveDocdexBaseUrl = (config) => {
115
158
  const anyConfig = config;
116
159
  return resolveString(anyConfig.docdexBaseUrl) ?? resolveString(anyConfig.docdex?.baseUrl);
@@ -162,6 +205,8 @@ export class CodaliAdapter {
162
205
  const agentId = resolveAgentId(request, this.config);
163
206
  const agentSlug = resolveAgentSlug(request, this.config);
164
207
  const baseUrl = resolveBaseUrl(this.config);
208
+ ensureLocalOpenAiCompatibleBaseUrl(providerInfo, baseUrl);
209
+ const localRunnerOptions = resolveLocalRunnerCliOptions(this.config);
165
210
  const docdexBaseUrl = resolveMetadataValue(metadata, ["docdexBaseUrl", "docdex_base_url"]) ?? resolveDocdexBaseUrl(this.config);
166
211
  const docdexRepoId = resolveMetadataValue(metadata, ["docdexRepoId", "docdex_repo_id"]) ?? resolveDocdexRepoId(this.config);
167
212
  const docdexRepoRoot = resolveMetadataValue(metadata, ["docdexRepoRoot", "docdex_repo_root"]) ?? resolveDocdexRepoRoot(this.config);
@@ -188,6 +233,7 @@ export class CodaliAdapter {
188
233
  model: this.config.model ?? "default",
189
234
  apiKey: this.config.apiKey,
190
235
  baseUrl,
236
+ ...localRunnerOptions,
191
237
  docdexBaseUrl,
192
238
  docdexRepoId,
193
239
  docdexRepoRoot,
@@ -229,6 +275,8 @@ export class CodaliAdapter {
229
275
  const agentId = resolveAgentId(request, this.config);
230
276
  const agentSlug = resolveAgentSlug(request, this.config);
231
277
  const baseUrl = resolveBaseUrl(this.config);
278
+ ensureLocalOpenAiCompatibleBaseUrl(providerInfo, baseUrl);
279
+ const localRunnerOptions = resolveLocalRunnerCliOptions(this.config);
232
280
  const docdexBaseUrl = resolveMetadataValue(metadata, ["docdexBaseUrl", "docdex_base_url"]) ?? resolveDocdexBaseUrl(this.config);
233
281
  const docdexRepoId = resolveMetadataValue(metadata, ["docdexRepoId", "docdex_repo_id"]) ?? resolveDocdexRepoId(this.config);
234
282
  const docdexRepoRoot = resolveMetadataValue(metadata, ["docdexRepoRoot", "docdex_repo_root"]) ?? resolveDocdexRepoRoot(this.config);
@@ -272,6 +320,7 @@ export class CodaliAdapter {
272
320
  model: this.config.model ?? "default",
273
321
  apiKey: this.config.apiKey,
274
322
  baseUrl,
323
+ ...localRunnerOptions,
275
324
  docdexBaseUrl,
276
325
  docdexRepoId,
277
326
  docdexRepoRoot,
@@ -1,3 +1,4 @@
1
+ import type { LocalOpenAiCompatibleRunnerConfig, LocalRunnerAuthMode, LocalRunnerKind, LocalRunnerResponseFormatStrategy } from "@mcoda/shared";
1
2
  export interface CodaliCliOptions {
2
3
  workspaceRoot: string;
3
4
  project?: string;
@@ -13,6 +14,20 @@ export interface CodaliCliOptions {
13
14
  model: string;
14
15
  apiKey?: string;
15
16
  baseUrl?: string;
17
+ localRunner?: LocalOpenAiCompatibleRunnerConfig;
18
+ runnerKind?: LocalRunnerKind;
19
+ authMode?: LocalRunnerAuthMode;
20
+ dummyBearerToken?: string;
21
+ headers?: Record<string, string>;
22
+ extraBody?: Record<string, unknown>;
23
+ responseFormatStrategy?: LocalRunnerResponseFormatStrategy;
24
+ healthPath?: string;
25
+ modelsPath?: string;
26
+ requireModelInRequest?: boolean;
27
+ supportsStreaming?: boolean;
28
+ supportsTools?: boolean;
29
+ supportsJsonSchema?: boolean;
30
+ supportsGbnf?: boolean;
16
31
  docdexBaseUrl?: string;
17
32
  docdexRepoId?: string;
18
33
  docdexRepoRoot?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"CodaliCliRunner.d.ts","sourceRoot":"","sources":["../../../src/adapters/codali/CodaliCliRunner.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,UAAU,GAAI,sBAAoB,KAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAiBjG,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,gBAAgB,KAAG,MAAM,EA0C3D,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,SAAS,gBAAgB,KAAG,MAAM,CAAC,UAe3D,CAAC;AAwBF,wBAAuB,eAAe,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,GACxB,cAAc,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAuGpE;AAED,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,SAAS,gBAAgB,KACxB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAgC/D,CAAC"}
1
+ {"version":3,"file":"CodaliCliRunner.d.ts","sourceRoot":"","sources":["../../../src/adapters/codali/CodaliCliRunner.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iCAAiC,EACjC,mBAAmB,EACnB,eAAe,EACf,iCAAiC,EAClC,MAAM,eAAe,CAAC;AAMvB,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,iCAAiC,CAAC;IAChD,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,sBAAsB,CAAC,EAAE,iCAAiC,CAAC;IAC3D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC9B;AAED,eAAO,MAAM,UAAU,GAAI,sBAAoB,KAAG;IAAE,EAAE,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAiBjG,CAAC;AAEF,eAAO,MAAM,SAAS,GAAI,SAAS,gBAAgB,KAAG,MAAM,EAoF3D,CAAC;AAEF,eAAO,MAAM,QAAQ,GAAI,SAAS,gBAAgB,KAAG,MAAM,CAAC,UAkB3D,CAAC;AAwBF,wBAAuB,eAAe,CACpC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,gBAAgB,GACxB,cAAc,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAAC,CAuGpE;AAED,eAAO,MAAM,aAAa,GACxB,OAAO,MAAM,EACb,SAAS,gBAAgB,KACxB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAgC/D,CAAC"}
@@ -53,6 +53,48 @@ export const buildArgs = (options) => {
53
53
  if (options.baseUrl) {
54
54
  args.push("--base-url", options.baseUrl);
55
55
  }
56
+ if (options.localRunner) {
57
+ args.push("--local-runner-json", JSON.stringify(options.localRunner));
58
+ }
59
+ if (options.runnerKind) {
60
+ args.push("--runner-kind", options.runnerKind);
61
+ }
62
+ if (options.authMode) {
63
+ args.push("--auth-mode", options.authMode);
64
+ }
65
+ if (options.dummyBearerToken) {
66
+ args.push("--dummy-bearer-token", options.dummyBearerToken);
67
+ }
68
+ if (options.headers) {
69
+ args.push("--headers-json", JSON.stringify(options.headers));
70
+ }
71
+ if (options.extraBody) {
72
+ args.push("--extra-body-json", JSON.stringify(options.extraBody));
73
+ }
74
+ if (options.responseFormatStrategy) {
75
+ args.push("--response-format-strategy", options.responseFormatStrategy);
76
+ }
77
+ if (options.healthPath) {
78
+ args.push("--health-path", options.healthPath);
79
+ }
80
+ if (options.modelsPath) {
81
+ args.push("--models-path", options.modelsPath);
82
+ }
83
+ if (options.requireModelInRequest !== undefined) {
84
+ args.push("--require-model-in-request", String(options.requireModelInRequest));
85
+ }
86
+ if (options.supportsStreaming !== undefined) {
87
+ args.push("--supports-streaming", String(options.supportsStreaming));
88
+ }
89
+ if (options.supportsTools !== undefined) {
90
+ args.push("--supports-tools", String(options.supportsTools));
91
+ }
92
+ if (options.supportsJsonSchema !== undefined) {
93
+ args.push("--supports-json-schema", String(options.supportsJsonSchema));
94
+ }
95
+ if (options.supportsGbnf !== undefined) {
96
+ args.push("--supports-gbnf", String(options.supportsGbnf));
97
+ }
56
98
  if (options.docdexBaseUrl) {
57
99
  args.push("--docdex-base-url", options.docdexBaseUrl);
58
100
  }
@@ -78,6 +120,9 @@ export const buildEnv = (options) => {
78
120
  if (options.baseUrl && !env.CODALI_BASE_URL) {
79
121
  env.CODALI_BASE_URL = options.baseUrl;
80
122
  }
123
+ if (options.localRunner && !env.CODALI_LOCAL_RUNNER_JSON) {
124
+ env.CODALI_LOCAL_RUNNER_JSON = JSON.stringify(options.localRunner);
125
+ }
81
126
  return env;
82
127
  };
83
128
  const parseRunMetaLine = (line) => {
@@ -1,4 +1,4 @@
1
- import { AgentHealth } from "@mcoda/shared";
1
+ import { AgentHealth, type LocalOpenAiCompatibleRunnerConfig, type LocalRunnerAuthMode, type LocalRunnerKind } from "@mcoda/shared";
2
2
  import { AdapterConfig, AgentAdapter, InvocationRequest, InvocationResult } from "../AdapterTypes.js";
3
3
  type OpenAiConfig = AdapterConfig & {
4
4
  baseUrl?: string;
@@ -7,6 +7,18 @@ type OpenAiConfig = AdapterConfig & {
7
7
  headers?: Record<string, string>;
8
8
  temperature?: number;
9
9
  extraBody?: Record<string, unknown>;
10
+ localRunner?: LocalOpenAiCompatibleRunnerConfig;
11
+ runnerKind?: LocalRunnerKind;
12
+ authMode?: LocalRunnerAuthMode;
13
+ dummyBearerToken?: string;
14
+ responseFormatStrategy?: string;
15
+ healthPath?: string;
16
+ modelsPath?: string;
17
+ requireModelInRequest?: boolean;
18
+ supportsStreaming?: boolean;
19
+ supportsTools?: boolean;
20
+ supportsJsonSchema?: boolean;
21
+ supportsGbnf?: boolean;
10
22
  };
11
23
  export declare class OpenAiAdapter implements AgentAdapter {
12
24
  private config;
@@ -14,6 +26,13 @@ export declare class OpenAiAdapter implements AgentAdapter {
14
26
  private headers;
15
27
  private temperature;
16
28
  private extraBody;
29
+ private runnerKind;
30
+ private authMode;
31
+ private dummyBearerToken;
32
+ private healthPath;
33
+ private modelsPath;
34
+ private localConfigIssues;
35
+ private isLocalOpenAiCompatible;
17
36
  constructor(config: OpenAiConfig);
18
37
  getCapabilities(): Promise<string[]>;
19
38
  healthCheck(): Promise<AgentHealth>;
@@ -22,10 +41,21 @@ export declare class OpenAiAdapter implements AgentAdapter {
22
41
  private assertConfig;
23
42
  private ensureBaseUrl;
24
43
  private ensureModel;
25
- private ensureApiKey;
44
+ private resolveAuth;
26
45
  private buildHeaders;
27
46
  private buildBody;
28
47
  private buildHealthCheckBody;
48
+ private healthCheckLocal;
49
+ private buildHealthResult;
50
+ private fetchHealthPath;
51
+ private fetchModels;
52
+ private fetchChatProbe;
53
+ private fetchJsonProbe;
54
+ private resolveRunnerUrl;
55
+ private resolveModelListUrls;
56
+ private extractModelIds;
57
+ private summarizeProbe;
58
+ private summarizeModelListing;
29
59
  }
30
60
  export {};
31
61
  //# sourceMappingURL=OpenAiAdapter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAiAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/OpenAiAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,oBAAoB,CAAC;AAuW5B,KAAK,YAAY,GAAG,aAAa,GAAG;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACrC,CAAC;AAEF,qBAAa,aAAc,YAAW,YAAY;IAMpC,OAAO,CAAC,MAAM;IAL1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,SAAS,CAAsC;gBAEnC,MAAM,EAAE,YAAY;IAUlC,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIpC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IA6GnC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyC5D,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC;IAyFhG,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,SAAS;IA4BjB,OAAO,CAAC,oBAAoB;CAU7B"}
1
+ {"version":3,"file":"OpenAiAdapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/openai/OpenAiAdapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAEX,KAAK,iCAAiC,EACtC,KAAK,mBAAmB,EAExB,KAAK,eAAe,EACrB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,gBAAgB,EAEjB,MAAM,oBAAoB,CAAC;AAwW5B,KAAK,YAAY,GAAG,aAAa,GAAG;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,WAAW,CAAC,EAAE,iCAAiC,CAAC;IAChD,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB,CAAC;AAsBF,qBAAa,aAAc,YAAW,YAAY;IAapC,OAAO,CAAC,MAAM;IAZ1B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAqC;IACpD,OAAO,CAAC,WAAW,CAAqB;IACxC,OAAO,CAAC,SAAS,CAAsC;IACvD,OAAO,CAAC,UAAU,CAA8B;IAChD,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,gBAAgB,CAAqB;IAC7C,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,UAAU,CAAqB;IACvC,OAAO,CAAC,iBAAiB,CAA2B;IACpD,OAAO,CAAC,uBAAuB,CAAU;gBAErB,MAAM,EAAE,YAAY;IAoBlC,eAAe,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAIpC,WAAW,IAAI,OAAO,CAAC,WAAW,CAAC;IAkGnC,MAAM,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyC5D,YAAY,CAAC,OAAO,EAAE,iBAAiB,GAAG,cAAc,CAAC,gBAAgB,EAAE,IAAI,EAAE,OAAO,CAAC;IAyFhG,OAAO,CAAC,YAAY;IAMpB,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,WAAW;IAOnB,OAAO,CAAC,WAAW;IAuBnB,OAAO,CAAC,YAAY;IAYpB,OAAO,CAAC,SAAS;IA4BjB,OAAO,CAAC,oBAAoB;YAWd,gBAAgB;IAwE9B,OAAO,CAAC,iBAAiB;YAqBX,eAAe;YAKf,WAAW;YAyBX,cAAc;YAQd,cAAc;IAyC5B,OAAO,CAAC,gBAAgB;IAaxB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,eAAe;IAavB,OAAO,CAAC,cAAc;IAUtB,OAAO,CAAC,qBAAqB;CAQ9B"}
@@ -1,6 +1,8 @@
1
+ import { normalizeLocalOpenAiCompatibleRunnerConfig, } from "@mcoda/shared";
1
2
  import { parseUsageLimitError } from "../../AgentService/UsageLimitParser.js";
2
3
  const DEFAULT_BASE_URL = "https://api.openai.com/v1";
3
4
  const MAX_RESPONSE_DETAIL_CHARS = 500;
5
+ const LOCAL_HEALTH_TIMEOUT_MS = 10000;
4
6
  const RATE_LIMIT_HEADER_NAMES = [
5
7
  "retry-after",
6
8
  "x-ratelimit-reset-after",
@@ -269,40 +271,39 @@ const extractResponseText = (data) => {
269
271
  export class OpenAiAdapter {
270
272
  constructor(config) {
271
273
  this.config = config;
272
- this.baseUrl = resolveBaseUrl(config);
273
- this.headers = isRecord(config.headers) ? config.headers : undefined;
274
+ const normalizedLocal = normalizeLocalOpenAiCompatibleRunnerConfig({
275
+ adapter: config.adapter ?? config.agent.adapter,
276
+ config,
277
+ agentConfig: config.agent.config,
278
+ });
279
+ this.baseUrl = normalizeBaseUrl(normalizedLocal.config.baseUrl) ?? resolveBaseUrl(config);
280
+ this.headers = normalizedLocal.config.headers;
274
281
  this.temperature = typeof config.temperature === "number" ? config.temperature : undefined;
275
- this.extraBody = isRecord(config.extraBody)
276
- ? config.extraBody
277
- : undefined;
282
+ this.extraBody = normalizedLocal.config.extraBody;
283
+ this.runnerKind = normalizedLocal.config.runnerKind;
284
+ this.authMode = normalizedLocal.config.authMode ?? "bearer";
285
+ this.dummyBearerToken = normalizedLocal.config.dummyBearerToken;
286
+ this.healthPath = normalizedLocal.config.healthPath;
287
+ this.modelsPath = normalizedLocal.config.modelsPath;
288
+ this.localConfigIssues = normalizedLocal.issues;
289
+ this.isLocalOpenAiCompatible = normalizedLocal.isLocalOpenAiCompatible || this.authMode !== "bearer";
278
290
  this.assertConfig();
279
291
  }
280
292
  async getCapabilities() {
281
293
  return this.config.capabilities;
282
294
  }
283
295
  async healthCheck() {
284
- if (!this.config.apiKey) {
285
- return {
286
- agentId: this.config.agent.id,
287
- status: "unreachable",
288
- lastCheckedAt: new Date().toISOString(),
289
- details: {
290
- adapter: "openai-api",
291
- source: "openai_probe",
292
- model: this.config.model,
293
- baseUrl: this.baseUrl,
294
- reason: "missing_api_key",
295
- },
296
- };
297
- }
298
296
  const startedAt = Date.now();
299
297
  try {
300
298
  const model = this.ensureModel();
301
- const apiKey = this.ensureApiKey();
299
+ const auth = this.resolveAuth();
302
300
  const url = this.ensureBaseUrl();
301
+ if (this.isLocalOpenAiCompatible) {
302
+ return await this.healthCheckLocal({ model, auth, url, startedAt });
303
+ }
303
304
  const response = await fetch(`${url}/chat/completions`, {
304
305
  method: "POST",
305
- headers: this.buildHeaders(apiKey, false),
306
+ headers: this.buildHeaders(auth, false),
306
307
  body: JSON.stringify(this.buildHealthCheckBody(model)),
307
308
  });
308
309
  const responseText = await response.text().catch(() => "");
@@ -367,7 +368,7 @@ export class OpenAiAdapter {
367
368
  const message = error instanceof Error ? error.message : String(error);
368
369
  const reason = /model is not configured/i.test(message)
369
370
  ? "missing_model"
370
- : /missing api key/i.test(message)
371
+ : /missing api key|api key missing/i.test(message)
371
372
  ? "missing_api_key"
372
373
  : "probe_failed";
373
374
  return {
@@ -389,11 +390,11 @@ export class OpenAiAdapter {
389
390
  async invoke(request) {
390
391
  const url = this.ensureBaseUrl();
391
392
  const model = this.ensureModel();
392
- const apiKey = this.ensureApiKey();
393
+ const auth = this.resolveAuth();
393
394
  const docdex = resolveDocdexContext(this.config, request.metadata);
394
395
  const resp = await fetch(`${url}/chat/completions`, {
395
396
  method: "POST",
396
- headers: this.buildHeaders(apiKey, false, docdex),
397
+ headers: this.buildHeaders(auth, false, docdex),
397
398
  body: JSON.stringify(this.buildBody(request.input, model, false, docdex)),
398
399
  });
399
400
  if (!resp.ok) {
@@ -411,7 +412,7 @@ export class OpenAiAdapter {
411
412
  mode: "api",
412
413
  capabilities: this.config.capabilities,
413
414
  prompts: this.config.prompts,
414
- authMode: "api",
415
+ authMode: auth.metadataAuthMode,
415
416
  adapterType: this.config.adapter ?? "openai-api",
416
417
  baseUrl: url,
417
418
  usage: isRecord(data) ? data.usage : undefined,
@@ -428,11 +429,11 @@ export class OpenAiAdapter {
428
429
  async *invokeStream(request) {
429
430
  const url = this.ensureBaseUrl();
430
431
  const model = this.ensureModel();
431
- const apiKey = this.ensureApiKey();
432
+ const auth = this.resolveAuth();
432
433
  const docdex = resolveDocdexContext(this.config, request.metadata);
433
434
  const resp = await fetch(`${url}/chat/completions`, {
434
435
  method: "POST",
435
- headers: this.buildHeaders(apiKey, true, docdex),
436
+ headers: this.buildHeaders(auth, true, docdex),
436
437
  body: JSON.stringify(this.buildBody(request.input, model, true, docdex)),
437
438
  });
438
439
  if (!resp.ok || !resp.body) {
@@ -457,7 +458,7 @@ export class OpenAiAdapter {
457
458
  model,
458
459
  metadata: {
459
460
  mode: "api",
460
- authMode: "api",
461
+ authMode: auth.metadataAuthMode,
461
462
  adapterType: this.config.adapter ?? "openai-api",
462
463
  baseUrl: url,
463
464
  capabilities: this.config.capabilities,
@@ -536,15 +537,29 @@ export class OpenAiAdapter {
536
537
  }
537
538
  return this.config.model;
538
539
  }
539
- ensureApiKey() {
540
+ resolveAuth() {
541
+ if (this.authMode === "none") {
542
+ return { mode: "none", metadataAuthMode: "none" };
543
+ }
544
+ if (this.authMode === "dummy-bearer") {
545
+ return {
546
+ mode: "dummy-bearer",
547
+ authorization: `Bearer ${this.dummyBearerToken ?? "local"}`,
548
+ metadataAuthMode: "dummy-bearer",
549
+ };
550
+ }
540
551
  if (!this.config.apiKey) {
541
552
  throw new Error(`AUTH_REQUIRED: OpenAI API key missing; run \`mcoda agent auth set ${this.config.agent.slug ?? this.config.agent.id}\``);
542
553
  }
543
- return this.config.apiKey;
554
+ return {
555
+ mode: "bearer",
556
+ authorization: `Bearer ${this.config.apiKey}`,
557
+ metadataAuthMode: "api",
558
+ };
544
559
  }
545
- buildHeaders(apiKey, streaming, docdex) {
560
+ buildHeaders(auth, streaming, docdex) {
546
561
  return {
547
- Authorization: `Bearer ${apiKey}`,
562
+ ...(auth.authorization ? { Authorization: auth.authorization } : {}),
548
563
  "Content-Type": "application/json",
549
564
  Accept: streaming ? "text/event-stream" : "application/json",
550
565
  ...(docdex?.repoId ? { "x-docdex-repo-id": docdex.repoId } : {}),
@@ -586,4 +601,213 @@ export class OpenAiAdapter {
586
601
  }
587
602
  return body;
588
603
  }
604
+ async healthCheckLocal(params) {
605
+ const { model, auth, url, startedAt } = params;
606
+ if (this.healthPath) {
607
+ const result = await this.fetchHealthPath(url, auth, this.healthPath);
608
+ const checkedAtMs = Date.now();
609
+ if (result.ok) {
610
+ return this.buildHealthResult("healthy", checkedAtMs, startedAt, {
611
+ source: "local_health_path",
612
+ model,
613
+ baseUrl: url,
614
+ healthPath: this.healthPath,
615
+ health: this.summarizeProbe(result),
616
+ });
617
+ }
618
+ return this.buildHealthResult("unreachable", checkedAtMs, startedAt, {
619
+ source: "local_health_path",
620
+ model,
621
+ baseUrl: url,
622
+ reason: result.error ? "health_path_failed" : "health_path_http_error",
623
+ healthPath: this.healthPath,
624
+ health: this.summarizeProbe(result),
625
+ });
626
+ }
627
+ const modelListing = await this.fetchModels(url, auth, model);
628
+ const checkedAtMs = Date.now();
629
+ if (modelListing.ok) {
630
+ if (modelListing.modelFound === false) {
631
+ return this.buildHealthResult("degraded", checkedAtMs, startedAt, {
632
+ source: "local_models",
633
+ model,
634
+ baseUrl: url,
635
+ reason: "model_not_listed",
636
+ modelListing: this.summarizeModelListing(modelListing),
637
+ });
638
+ }
639
+ return this.buildHealthResult("healthy", checkedAtMs, startedAt, {
640
+ source: "local_models",
641
+ model,
642
+ baseUrl: url,
643
+ modelListing: this.summarizeModelListing(modelListing),
644
+ });
645
+ }
646
+ const chatProbe = await this.fetchChatProbe(url, auth, model);
647
+ const afterChatMs = Date.now();
648
+ if (chatProbe.ok) {
649
+ return this.buildHealthResult("degraded", afterChatMs, startedAt, {
650
+ source: "local_chat_probe",
651
+ model,
652
+ baseUrl: url,
653
+ reason: "model_listing_failed",
654
+ modelListing: this.summarizeModelListing(modelListing),
655
+ chatProbe: this.summarizeProbe(chatProbe),
656
+ });
657
+ }
658
+ return this.buildHealthResult("unreachable", afterChatMs, startedAt, {
659
+ source: "local_models",
660
+ model,
661
+ baseUrl: url,
662
+ reason: modelListing.error ? "model_listing_failed" : "model_listing_http_error",
663
+ modelListing: this.summarizeModelListing(modelListing),
664
+ chatProbe: this.summarizeProbe(chatProbe),
665
+ });
666
+ }
667
+ buildHealthResult(status, checkedAtMs, startedAt, details) {
668
+ return {
669
+ agentId: this.config.agent.id,
670
+ status,
671
+ lastCheckedAt: new Date(checkedAtMs).toISOString(),
672
+ latencyMs: checkedAtMs - startedAt,
673
+ details: {
674
+ adapter: this.config.adapter ?? "openai-api",
675
+ runnerKind: this.runnerKind,
676
+ authMode: this.authMode,
677
+ configIssues: this.localConfigIssues.length ? this.localConfigIssues : undefined,
678
+ ...details,
679
+ },
680
+ };
681
+ }
682
+ async fetchHealthPath(baseUrl, auth, healthPath) {
683
+ const url = this.resolveRunnerUrl(baseUrl, healthPath);
684
+ return this.fetchJsonProbe(url, auth);
685
+ }
686
+ async fetchModels(baseUrl, auth, model) {
687
+ const candidates = this.resolveModelListUrls(baseUrl);
688
+ let last;
689
+ for (const url of candidates) {
690
+ const result = await this.fetchJsonProbe(url, auth);
691
+ if (!result.ok) {
692
+ last = { ...result, models: [], modelFound: false };
693
+ continue;
694
+ }
695
+ const models = this.extractModelIds(result.data);
696
+ return {
697
+ ...result,
698
+ models,
699
+ modelFound: models.length === 0 ? undefined : models.includes(model),
700
+ };
701
+ }
702
+ return last ?? {
703
+ ok: false,
704
+ url: candidates[0] ?? baseUrl,
705
+ error: "No model listing URL candidates were available.",
706
+ models: [],
707
+ modelFound: false,
708
+ };
709
+ }
710
+ async fetchChatProbe(baseUrl, auth, model) {
711
+ const url = `${baseUrl}/chat/completions`;
712
+ return this.fetchJsonProbe(url, auth, {
713
+ method: "POST",
714
+ body: JSON.stringify(this.buildHealthCheckBody(model)),
715
+ });
716
+ }
717
+ async fetchJsonProbe(url, auth, init = {}) {
718
+ const controller = new AbortController();
719
+ const timeout = setTimeout(() => controller.abort(), LOCAL_HEALTH_TIMEOUT_MS);
720
+ try {
721
+ const response = await fetch(url, {
722
+ method: init.method ?? "GET",
723
+ headers: this.buildHeaders(auth, false),
724
+ body: init.body,
725
+ signal: controller.signal,
726
+ });
727
+ const responseText = await response.text().catch(() => "");
728
+ let data;
729
+ if (responseText.trim()) {
730
+ try {
731
+ data = JSON.parse(responseText);
732
+ }
733
+ catch {
734
+ data = undefined;
735
+ }
736
+ }
737
+ return {
738
+ ok: response.ok,
739
+ status: response.status,
740
+ url,
741
+ response: responseText.slice(0, MAX_RESPONSE_DETAIL_CHARS),
742
+ data,
743
+ };
744
+ }
745
+ catch (error) {
746
+ return {
747
+ ok: false,
748
+ url,
749
+ error: error instanceof Error ? error.message : String(error),
750
+ };
751
+ }
752
+ finally {
753
+ clearTimeout(timeout);
754
+ }
755
+ }
756
+ resolveRunnerUrl(baseUrl, rawPath) {
757
+ try {
758
+ return new URL(rawPath).toString();
759
+ }
760
+ catch {
761
+ // Continue with relative runner paths below.
762
+ }
763
+ if (rawPath.startsWith("/")) {
764
+ const root = new URL(baseUrl);
765
+ return new URL(rawPath, root.origin).toString();
766
+ }
767
+ return new URL(rawPath, `${baseUrl}/`).toString();
768
+ }
769
+ resolveModelListUrls(baseUrl) {
770
+ if (this.modelsPath)
771
+ return [this.resolveRunnerUrl(baseUrl, this.modelsPath)];
772
+ const root = new URL(baseUrl);
773
+ const urls = new Set();
774
+ if (!root.pathname.replace(/\/+$/, "").endsWith("/v1")) {
775
+ urls.add(new URL("/v1/models", root.origin).toString());
776
+ }
777
+ urls.add(new URL("models", `${baseUrl}/`).toString());
778
+ urls.add(new URL("/models", root.origin).toString());
779
+ return Array.from(urls);
780
+ }
781
+ extractModelIds(data) {
782
+ if (!isRecord(data))
783
+ return [];
784
+ const entries = Array.isArray(data.data) ? data.data : Array.isArray(data.models) ? data.models : [];
785
+ const ids = entries
786
+ .map((entry) => {
787
+ if (typeof entry === "string")
788
+ return entry.trim();
789
+ if (isRecord(entry))
790
+ return resolveString(entry.id) ?? resolveString(entry.name);
791
+ return undefined;
792
+ })
793
+ .filter((entry) => Boolean(entry));
794
+ return Array.from(new Set(ids));
795
+ }
796
+ summarizeProbe(result) {
797
+ return {
798
+ ok: result.ok,
799
+ url: result.url,
800
+ httpStatus: result.status,
801
+ response: result.response,
802
+ error: result.error,
803
+ };
804
+ }
805
+ summarizeModelListing(result) {
806
+ return {
807
+ ...this.summarizeProbe(result),
808
+ models: result.models?.slice(0, 25),
809
+ modelCount: result.models?.length,
810
+ modelFound: result.modelFound,
811
+ };
812
+ }
589
813
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcoda/agents",
3
- "version": "0.1.72",
3
+ "version": "0.1.74",
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.72",
34
- "@mcoda/db": "0.1.72"
33
+ "@mcoda/db": "0.1.74",
34
+ "@mcoda/shared": "0.1.74"
35
35
  },
36
36
  "scripts": {
37
37
  "build": "tsc -p tsconfig.json",