@mcoda/codali 0.1.125 → 0.1.127

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":"EvidenceNormalizer.d.ts","sourceRoot":"","sources":["../../src/gateway/EvidenceNormalizer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,6BAA6B;IAC5C,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,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,gCAAgC,EAAE,CAAC;IAC/C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AA6jBD,eAAO,MAAM,uBAAuB,GAClC,OAAO,6BAA6B,KACnC,8BAoJF,CAAC;AAEF,eAAO,MAAM,wBAAwB,UAvJ5B,6BAA6B,KACnC,8BAsJ4D,CAAC"}
1
+ {"version":3,"file":"EvidenceNormalizer.d.ts","sourceRoot":"","sources":["../../src/gateway/EvidenceNormalizer.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAEnB,MAAM,yBAAyB,CAAC;AAEjC,MAAM,WAAW,gCAAgC;IAC/C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAC;IACnD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,6BAA6B;IAC5C,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,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAC;IACrB,SAAS,CAAC,EAAE,gCAAgC,EAAE,CAAC;IAC/C,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,0BAA0B;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC/B,QAAQ,EAAE,0BAA0B,EAAE,CAAC;IACvC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CACxB;AA4lBD,eAAO,MAAM,uBAAuB,GAClC,OAAO,6BAA6B,KACnC,8BAwJF,CAAC;AAEF,eAAO,MAAM,wBAAwB,UA3J5B,6BAA6B,KACnC,8BA0J4D,CAAC"}
@@ -329,6 +329,24 @@ const collectCandidates = (value, context, warnings) => {
329
329
  const trimmed = value.trim();
330
330
  if (!trimmed)
331
331
  return [];
332
+ if (context.textOnly) {
333
+ // Still worth reporting that it was malformed; just never descend into it.
334
+ if (parseMaybeJson(trimmed).malformed) {
335
+ warnings.push("malformed_worker_json");
336
+ }
337
+ return [{
338
+ claim: trimmed,
339
+ rawExcerpt: truncate(trimmed),
340
+ sourceType: "model_observation",
341
+ confidence: 0.2,
342
+ relevance: 0.4,
343
+ usedTool: context.usedTool,
344
+ tenantScoped: context.tenantScoped,
345
+ metadata: context.metadata,
346
+ value,
347
+ unprovenanced: true,
348
+ }];
349
+ }
332
350
  const parsed = parseMaybeJson(trimmed);
333
351
  if (parsed.parsed !== undefined) {
334
352
  return collectCandidates(parsed.parsed, { ...context, depth: context.depth + 1 }, warnings);
@@ -483,6 +501,10 @@ export const normalizeCodaliEvidence = (input) => {
483
501
  tenantScoped: input.defaultTenantScoped,
484
502
  depth: 0,
485
503
  rootStringMode: true,
504
+ // Nothing was retrieved, so nothing the worker wrote is data. Marking the
505
+ // candidates unprovenanced afterwards was not enough — invented rows were
506
+ // still parsed out and cited individually.
507
+ textOnly: !retrievedSomething,
486
508
  }, warnings));
487
509
  }
488
510
  // Everything gathered so far came from the worker's own words. If the task
@@ -1 +1 @@
1
- {"version":3,"file":"LocalGatewayTaskRunner.d.ts","sourceRoot":"","sources":["../../src/gateway/LocalGatewayTaskRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAGT,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,KAAK,EAEV,+BAA+B,EAC/B,gCAAgC,EAChC,6BAA6B,EAE9B,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAe1C,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;CACxD;AAED,MAAM,MAAM,2BAA2B,GACnC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAClE;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAuGN,qBAAa,sBAAuB,YAAW,6BAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,6BAA6B;IAE7D,GAAG,CACP,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,gCAAgC,CAAC;CA2U7C;AAED,eAAO,MAAM,4BAA4B,GACvC,SAAS,6BAA6B,KACrC,sBAA6D,CAAC;AAEjE,eAAO,MAAM,aAAa,UA3bD,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CA2b7B,CAAC"}
1
+ {"version":3,"file":"LocalGatewayTaskRunner.d.ts","sourceRoot":"","sources":["../../src/gateway/LocalGatewayTaskRunner.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,QAAQ,EAGT,MAAM,+BAA+B,CAAC;AACvC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGzD,OAAO,KAAK,EAEV,+BAA+B,EAC/B,gCAAgC,EAChC,6BAA6B,EAE9B,MAAM,0BAA0B,CAAC;AAElC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,8EAA8E;AAC9E,eAAO,MAAM,uBAAuB,IAAI,CAAC;AAEzC,2EAA2E;AAC3E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAe1C,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,EAAE,QAAQ,CAAC;IACnB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,WAAW,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,2BAA2B,KAAK,IAAI,CAAC;CACxD;AAED,MAAM,MAAM,2BAA2B,GACnC;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,EAAE,CAAA;CAAE,GAClF;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,OAAO,CAAA;CAAE,GAClE;IACE,IAAI,EAAE,aAAa,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GACD;IACE,IAAI,EAAE,UAAU,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAiIN,qBAAa,sBAAuB,YAAW,6BAA6B;IAC9D,OAAO,CAAC,QAAQ,CAAC,OAAO;gBAAP,OAAO,EAAE,6BAA6B;IAE7D,GAAG,CACP,KAAK,EAAE,+BAA+B,GACrC,OAAO,CAAC,gCAAgC,CAAC;CA8V7C;AAED,eAAO,MAAM,4BAA4B,GACvC,SAAS,6BAA6B,KACrC,sBAA6D,CAAC;AAEjE,eAAO,MAAM,aAAa,UAxeD,OAAO,KAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAwe7B,CAAC"}
@@ -93,6 +93,29 @@ const claimsToolExecution = (output) => {
93
93
  // Two independent markers, so a passing mention of a tool name is not enough.
94
94
  return FABRICATED_TOOL_RESULT_MARKERS.filter((marker) => marker.test(output)).length >= 2;
95
95
  };
96
+ /**
97
+ * Whether to name the tool rather than leave the choice open.
98
+ *
99
+ * Emission is intermittent at the model. Measured downstream on one prompt,
100
+ * one model and one schema: a real tool call on one run, then four runs that
101
+ * narrated instead — the last of them inventing rows. The planner had already
102
+ * decided which tool this task needs, so leaving the model to decide *whether*
103
+ * to call it adds a coin flip to a question already answered.
104
+ *
105
+ * Only when exactly one tool is allocated, because naming a tool means naming
106
+ * it; with several, the choice is genuinely the model's. And only for a task
107
+ * that exists to retrieve — a worker that may legitimately answer from its own
108
+ * knowledge must stay free not to call anything.
109
+ */
110
+ const RETRIEVAL_WORKER_ROLES = new Set(["tool_worker", "rag_worker", "extractor"]);
111
+ const forcedToolChoice = (workerRole, toolDefinitions) => {
112
+ if (toolDefinitions.length !== 1)
113
+ return undefined;
114
+ if (!RETRIEVAL_WORKER_ROLES.has((workerRole ?? "").toLowerCase()))
115
+ return undefined;
116
+ const only = toolDefinitions[0];
117
+ return only ? { name: only.name } : undefined;
118
+ };
96
119
  const buildTaskMessages = (input, hasTools) => {
97
120
  const system = [
98
121
  "You are a Codali gateway worker.",
@@ -170,13 +193,33 @@ export class LocalGatewayTaskRunner {
170
193
  let selection;
171
194
  const selectionStartedMs = Date.now();
172
195
  try {
173
- selection = await this.options.provider.generate({
196
+ const forced = toolDefinitions.length > 0
197
+ ? forcedToolChoice(input.task.workerRole, toolDefinitions)
198
+ : undefined;
199
+ const request = {
174
200
  messages,
175
201
  tools: toolDefinitions.length > 0 ? toolDefinitions : undefined,
176
- toolChoice: toolDefinitions.length > 0 ? "auto" : "none",
177
202
  maxTokens: positiveInteger(this.options.maxTokens, DEFAULT_MAX_TOKENS),
178
203
  temperature: this.options.temperature ?? DEFAULT_TEMPERATURE,
179
- });
204
+ };
205
+ const openChoice = toolDefinitions.length > 0 ? "auto" : "none";
206
+ try {
207
+ selection = await this.options.provider.generate({
208
+ ...request,
209
+ toolChoice: forced ?? openChoice,
210
+ });
211
+ }
212
+ catch (error) {
213
+ // Not every endpoint accepts a named tool, and a run must not die
214
+ // because we asked for one. Falling back costs a second call on a
215
+ // narrow path and keeps the task working where forcing is unsupported.
216
+ if (!forced)
217
+ throw error;
218
+ selection = await this.options.provider.generate({
219
+ ...request,
220
+ toolChoice: openChoice,
221
+ });
222
+ }
180
223
  }
181
224
  catch (error) {
182
225
  modelCalls.push({
@@ -1 +1 @@
1
- {"version":3,"file":"OpenAiCompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenAiCompatibleProvider.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAEd,eAAe,EACf,gBAAgB,EAGjB,MAAM,oBAAoB,CAAC;AAgJ5B,eAAO,MAAM,uBAAuB,GAClC,KAAK,MAAM,EACX,MAAM,WAAW,EACjB,aAAa,eAAe,KAC3B,OAAO,CAAC,QAAQ,CAclB,CAAC;AAEF,qBAAa,wBAAyB,YAAW,QAAQ;IAS3C,OAAO,CAAC,MAAM;IAR1B,+EAA+E;IAC/E,QAAQ,CAAC,iBAAiB,QAAQ;IAElC,IAAI,SAAuB;IAC3B,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,sBAAsB,CAAoC;gBAE9C,MAAM,EAAE,cAAc;IAWpC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0MnE,OAAO,CAAC,WAAW;CA0BpB"}
1
+ {"version":3,"file":"OpenAiCompatibleProvider.d.ts","sourceRoot":"","sources":["../../src/providers/OpenAiCompatibleProvider.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EACV,QAAQ,EACR,cAAc,EAEd,eAAe,EACf,gBAAgB,EAGjB,MAAM,oBAAoB,CAAC;AAgJ5B,eAAO,MAAM,uBAAuB,GAClC,KAAK,MAAM,EACX,MAAM,WAAW,EACjB,aAAa,eAAe,KAC3B,OAAO,CAAC,QAAQ,CAclB,CAAC;AAEF,qBAAa,wBAAyB,YAAW,QAAQ;IAS3C,OAAO,CAAC,MAAM;IAR1B,+EAA+E;IAC/E,QAAQ,CAAC,iBAAiB,QAAQ;IAElC,IAAI,SAAuB;IAC3B,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,sBAAsB,CAAoC;gBAE9C,MAAM,EAAE,cAAc;IAWpC,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAiNnE,OAAO,CAAC,WAAW;CA0BpB"}
@@ -177,7 +177,13 @@ export class OpenAiCompatibleProvider {
177
177
  parameters: tool.inputSchema ?? {},
178
178
  },
179
179
  })),
180
- tool_choice: request.toolChoice,
180
+ // `{ name }` is our shape; the wire wants
181
+ // `{"type":"function","function":{"name":…}}`. Passing ours through meant
182
+ // naming a tool was silently ignored, so the option existed and did
183
+ // nothing.
184
+ tool_choice: request.toolChoice && typeof request.toolChoice === "object"
185
+ ? { type: "function", function: { name: request.toolChoice.name } }
186
+ : request.toolChoice,
181
187
  max_tokens: request.maxTokens,
182
188
  temperature: request.temperature,
183
189
  response_format: toResponseFormat(request.responseFormat, this.responseFormatStrategy),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mcoda/codali",
3
- "version": "0.1.125",
3
+ "version": "0.1.127",
4
4
  "description": "Standalone tool-runner adapter for mcoda.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -35,8 +35,8 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@modelcontextprotocol/sdk": "1.30.0",
38
- "@mcoda/db": "0.1.125",
39
- "@mcoda/shared": "0.1.125"
38
+ "@mcoda/db": "0.1.127",
39
+ "@mcoda/shared": "0.1.127"
40
40
  },
41
41
  "scripts": {
42
42
  "build": "tsc -p tsconfig.json",