ollama-intern-mcp 1.0.1 → 1.0.2

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.
Files changed (48) hide show
  1. package/dist/errors.d.ts +1 -1
  2. package/dist/errors.d.ts.map +1 -1
  3. package/dist/errors.js.map +1 -1
  4. package/dist/guardrails/bannedPhrases.d.ts +38 -0
  5. package/dist/guardrails/bannedPhrases.d.ts.map +1 -0
  6. package/dist/guardrails/bannedPhrases.js +83 -0
  7. package/dist/guardrails/bannedPhrases.js.map +1 -0
  8. package/dist/guardrails/stringifiedArrayGuard.d.ts +45 -0
  9. package/dist/guardrails/stringifiedArrayGuard.d.ts.map +1 -0
  10. package/dist/guardrails/stringifiedArrayGuard.js +88 -0
  11. package/dist/guardrails/stringifiedArrayGuard.js.map +1 -0
  12. package/dist/tools/changeBrief.d.ts +2 -2
  13. package/dist/tools/classify.d.ts +14 -9
  14. package/dist/tools/classify.d.ts.map +1 -1
  15. package/dist/tools/classify.js +26 -13
  16. package/dist/tools/classify.js.map +1 -1
  17. package/dist/tools/draft.d.ts +4 -0
  18. package/dist/tools/draft.d.ts.map +1 -1
  19. package/dist/tools/draft.js +54 -1
  20. package/dist/tools/draft.js.map +1 -1
  21. package/dist/tools/extract.d.ts +13 -5
  22. package/dist/tools/extract.d.ts.map +1 -1
  23. package/dist/tools/extract.js +24 -9
  24. package/dist/tools/extract.js.map +1 -1
  25. package/dist/tools/incidentBrief.d.ts +2 -2
  26. package/dist/tools/packs/changePack.d.ts +3 -3
  27. package/dist/tools/packs/changePack.d.ts.map +1 -1
  28. package/dist/tools/packs/changePack.js +2 -1
  29. package/dist/tools/packs/changePack.js.map +1 -1
  30. package/dist/tools/packs/incidentPack.d.ts +3 -3
  31. package/dist/tools/packs/incidentPack.d.ts.map +1 -1
  32. package/dist/tools/packs/incidentPack.js +2 -1
  33. package/dist/tools/packs/incidentPack.js.map +1 -1
  34. package/dist/tools/research.d.ts +3 -3
  35. package/dist/tools/research.d.ts.map +1 -1
  36. package/dist/tools/research.js +2 -1
  37. package/dist/tools/research.js.map +1 -1
  38. package/dist/tools/summarizeDeep.d.ts +3 -3
  39. package/dist/tools/summarizeDeep.d.ts.map +1 -1
  40. package/dist/tools/summarizeDeep.js +2 -3
  41. package/dist/tools/summarizeDeep.js.map +1 -1
  42. package/dist/tools/triageLogs.d.ts +1 -1
  43. package/dist/tools/triageLogs.d.ts.map +1 -1
  44. package/dist/tools/triageLogs.js +2 -1
  45. package/dist/tools/triageLogs.js.map +1 -1
  46. package/dist/version.d.ts +1 -1
  47. package/dist/version.js +1 -1
  48. package/package.json +1 -1
package/dist/errors.d.ts CHANGED
@@ -2,7 +2,7 @@
2
2
  * Structured error shape — code / message / hint / retryable.
3
3
  * Matches shipcheck hard gate B: no raw stacks, always a hint, always a retry signal.
4
4
  */
5
- export type ErrorCode = "OLLAMA_UNREACHABLE" | "OLLAMA_MODEL_MISSING" | "OLLAMA_TIMEOUT" | "TIER_TIMEOUT" | "PROTECTED_PATH_WRITE" | "CITATION_INVALID" | "COMPILE_FAILED" | "EXTRACT_UNPARSEABLE" | "SOURCE_PATH_NOT_FOUND" | "SCHEMA_INVALID" | "INTERNAL";
5
+ export type ErrorCode = "OLLAMA_UNREACHABLE" | "OLLAMA_MODEL_MISSING" | "OLLAMA_TIMEOUT" | "TIER_TIMEOUT" | "PROTECTED_PATH_WRITE" | "CITATION_INVALID" | "COMPILE_FAILED" | "EXTRACT_UNPARSEABLE" | "SOURCE_PATH_NOT_FOUND" | "SCHEMA_INVALID" | "DRAFT_BANNED_PHRASE" | "INTERNAL";
6
6
  export declare class InternError extends Error {
7
7
  readonly code: ErrorCode;
8
8
  readonly hint: string;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GACjB,oBAAoB,GACpB,sBAAsB,GACtB,gBAAgB,GAChB,cAAc,GACd,sBAAsB,GACtB,kBAAkB,GAClB,gBAAgB,GAChB,qBAAqB,GACrB,uBAAuB,GACvB,gBAAgB,GAChB,UAAU,CAAC;AAEf,qBAAa,WAAY,SAAQ,KAAK;aAElB,IAAI,EAAE,SAAS;aAEf,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,OAAO;gBAHlB,IAAI,EAAE,SAAS,EAC/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAe;CAK7C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAYrD"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,MAAM,SAAS,GACjB,oBAAoB,GACpB,sBAAsB,GACtB,gBAAgB,GAChB,cAAc,GACd,sBAAsB,GACtB,kBAAkB,GAClB,gBAAgB,GAChB,qBAAqB,GACrB,uBAAuB,GACvB,gBAAgB,GAChB,qBAAqB,GACrB,UAAU,CAAC;AAEf,qBAAa,WAAY,SAAQ,KAAK;aAElB,IAAI,EAAE,SAAS;aAEf,IAAI,EAAE,MAAM;aACZ,SAAS,EAAE,OAAO;gBAHlB,IAAI,EAAE,SAAS,EAC/B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM,EACZ,SAAS,GAAE,OAAe;CAK7C;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,IAAI,CAAC;IACZ,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAYrD"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAeH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAElB;IAEA;IACA;IAJlB,YACkB,IAAe,EAC/B,OAAe,EACC,IAAY,EACZ,YAAqB,KAAK;QAE1C,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,SAAI,GAAJ,IAAI,CAAW;QAEf,SAAI,GAAJ,IAAI,CAAQ;QACZ,cAAS,GAAT,SAAS,CAAiB;QAG1C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAUD,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;IACzG,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,UAAU;QAChB,OAAO;QACP,IAAI,EAAE,kEAAkE;QACxE,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAgBH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAElB;IAEA;IACA;IAJlB,YACkB,IAAe,EAC/B,OAAe,EACC,IAAY,EACZ,YAAqB,KAAK;QAE1C,KAAK,CAAC,OAAO,CAAC,CAAC;QALC,SAAI,GAAJ,IAAI,CAAW;QAEf,SAAI,GAAJ,IAAI,CAAQ;QACZ,cAAS,GAAT,SAAS,CAAiB;QAG1C,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;IAC5B,CAAC;CACF;AAUD,MAAM,UAAU,YAAY,CAAC,GAAY;IACvC,IAAI,GAAG,YAAY,WAAW,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC;IACzG,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACjE,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,UAAU;QAChB,OAAO;QACP,IAAI,EAAE,kEAAkE;QACxE,SAAS,EAAE,KAAK;KACjB,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * bannedPhrases — marketing-sludge rejection list for `draft(style="doc")`.
3
+ *
4
+ * The draft-for-prose problem: even strong models generate hype words when
5
+ * asked for "doc" output. A post-generation regex pass catches the obvious
6
+ * sludge and triggers regeneration. Won't catch subtle bad prose, but
7
+ * cheapens the floor by rejecting the signal words that flag it.
8
+ *
9
+ * List is curated from the 2026-04-17 adoption pass and the repo-dataset
10
+ * marketing swarm — phrases that came back in brochure-voice drafts.
11
+ *
12
+ * Kept minimal on purpose. A bloated list starts rejecting legitimate
13
+ * technical prose ("robust error handling", "leverage caching"). Each entry
14
+ * here is one we'd reject 95%+ of the time as sludge.
15
+ *
16
+ * Match is case-insensitive, whole-word. Multi-word phrases match across
17
+ * whitespace; embedded punctuation is not normalized away (matches on
18
+ * natural prose boundaries only).
19
+ */
20
+ export declare const BANNED_PHRASES: readonly string[];
21
+ export interface BannedPhraseMatch {
22
+ phrase: string;
23
+ index: number;
24
+ }
25
+ /**
26
+ * Scan `text` for any entry in `list`. Returns every match (case-insensitive,
27
+ * whole-word). Empty array means the text is clean.
28
+ *
29
+ * Whole-word match prevents false positives like "ecutting-edge" or
30
+ * "unlocksmith". Uses \b from the regex engine — which treats hyphen as a
31
+ * word boundary, so "cutting-edge" matches both "cutting-edge" (as a single
32
+ * token by its natural boundaries) and by falling back through the split
33
+ * "cutting" and "edge" variants already in the list.
34
+ */
35
+ export declare function findBannedPhrases(text: string, list?: readonly string[]): BannedPhraseMatch[];
36
+ /** True iff any banned phrase is present. Cheap wrapper for handler use. */
37
+ export declare function containsBannedPhrase(text: string, list?: readonly string[]): boolean;
38
+ //# sourceMappingURL=bannedPhrases.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bannedPhrases.d.ts","sourceRoot":"","sources":["../../src/guardrails/bannedPhrases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EA+B1C,CAAC;AAEH,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,SAAS,MAAM,EAAmB,GACvC,iBAAiB,EAAE,CAgBrB;AAED,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,GAAE,SAAS,MAAM,EAAmB,GACvC,OAAO,CAET"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * bannedPhrases — marketing-sludge rejection list for `draft(style="doc")`.
3
+ *
4
+ * The draft-for-prose problem: even strong models generate hype words when
5
+ * asked for "doc" output. A post-generation regex pass catches the obvious
6
+ * sludge and triggers regeneration. Won't catch subtle bad prose, but
7
+ * cheapens the floor by rejecting the signal words that flag it.
8
+ *
9
+ * List is curated from the 2026-04-17 adoption pass and the repo-dataset
10
+ * marketing swarm — phrases that came back in brochure-voice drafts.
11
+ *
12
+ * Kept minimal on purpose. A bloated list starts rejecting legitimate
13
+ * technical prose ("robust error handling", "leverage caching"). Each entry
14
+ * here is one we'd reject 95%+ of the time as sludge.
15
+ *
16
+ * Match is case-insensitive, whole-word. Multi-word phrases match across
17
+ * whitespace; embedded punctuation is not normalized away (matches on
18
+ * natural prose boundaries only).
19
+ */
20
+ export const BANNED_PHRASES = Object.freeze([
21
+ "blazing fast",
22
+ "industry-leading",
23
+ "industry leading",
24
+ "the only",
25
+ "effortless",
26
+ "effortlessly",
27
+ "seamless",
28
+ "seamlessly",
29
+ "enhance",
30
+ "enhances",
31
+ "enhanced",
32
+ "streamline",
33
+ "streamlines",
34
+ "streamlined",
35
+ "leverage",
36
+ "leverages",
37
+ "leveraging",
38
+ "unlock",
39
+ "unlocks",
40
+ "unlocking",
41
+ "empower",
42
+ "empowers",
43
+ "empowering",
44
+ "robust",
45
+ "cutting-edge",
46
+ "cutting edge",
47
+ "next-generation",
48
+ "next generation",
49
+ "best-in-class",
50
+ "best in class",
51
+ ]);
52
+ /**
53
+ * Scan `text` for any entry in `list`. Returns every match (case-insensitive,
54
+ * whole-word). Empty array means the text is clean.
55
+ *
56
+ * Whole-word match prevents false positives like "ecutting-edge" or
57
+ * "unlocksmith". Uses \b from the regex engine — which treats hyphen as a
58
+ * word boundary, so "cutting-edge" matches both "cutting-edge" (as a single
59
+ * token by its natural boundaries) and by falling back through the split
60
+ * "cutting" and "edge" variants already in the list.
61
+ */
62
+ export function findBannedPhrases(text, list = BANNED_PHRASES) {
63
+ const matches = [];
64
+ const lower = text.toLowerCase();
65
+ for (const phrase of list) {
66
+ const lowerPhrase = phrase.toLowerCase();
67
+ // Escape regex metachars in the phrase, then bound on word chars.
68
+ const escaped = lowerPhrase.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
69
+ // Allow flexible whitespace inside multi-word phrases.
70
+ const pattern = escaped.replace(/\s+/g, "\\s+");
71
+ const re = new RegExp(`\\b${pattern}\\b`, "g");
72
+ let m;
73
+ while ((m = re.exec(lower)) !== null) {
74
+ matches.push({ phrase, index: m.index });
75
+ }
76
+ }
77
+ return matches;
78
+ }
79
+ /** True iff any banned phrase is present. Cheap wrapper for handler use. */
80
+ export function containsBannedPhrase(text, list = BANNED_PHRASES) {
81
+ return findBannedPhrases(text, list).length > 0;
82
+ }
83
+ //# sourceMappingURL=bannedPhrases.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bannedPhrases.js","sourceRoot":"","sources":["../../src/guardrails/bannedPhrases.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,CAAC,MAAM,cAAc,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC7D,cAAc;IACd,kBAAkB;IAClB,kBAAkB;IAClB,UAAU;IACV,YAAY;IACZ,cAAc;IACd,UAAU;IACV,YAAY;IACZ,SAAS;IACT,UAAU;IACV,UAAU;IACV,YAAY;IACZ,aAAa;IACb,aAAa;IACb,UAAU;IACV,WAAW;IACX,YAAY;IACZ,QAAQ;IACR,SAAS;IACT,WAAW;IACX,SAAS;IACT,UAAU;IACV,YAAY;IACZ,QAAQ;IACR,cAAc;IACd,cAAc;IACd,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,eAAe;CAChB,CAAC,CAAC;AAOH;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,IAAY,EACZ,OAA0B,cAAc;IAExC,MAAM,OAAO,GAAwB,EAAE,CAAC;IACxC,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,KAAK,MAAM,MAAM,IAAI,IAAI,EAAE,CAAC;QAC1B,MAAM,WAAW,GAAG,MAAM,CAAC,WAAW,EAAE,CAAC;QACzC,kEAAkE;QAClE,MAAM,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;QACnE,uDAAuD;QACvD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChD,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,MAAM,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC;QAC/C,IAAI,CAAyB,CAAC;QAC9B,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC3C,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,oBAAoB,CAClC,IAAY,EACZ,OAA0B,cAAc;IAExC,OAAO,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;AAClD,CAAC"}
@@ -0,0 +1,45 @@
1
+ /**
2
+ * stringifiedArrayGuard — diagnostic schema helper.
3
+ *
4
+ * Problem:
5
+ * Some callers (observed in the repo-dataset marketing swarm, 2026-04-17)
6
+ * serialize nested array params as JSON strings before the MCP transport
7
+ * sees them. `source_paths: ["file.md"]` arrives at the server as
8
+ * `"[\"file.md\"]"` — a string. Strict `z.array(z.string())` then fails
9
+ * with a generic "expected array, received string", which hides the real
10
+ * cause (upstream stringification) behind a schema error the caller can't
11
+ * act on.
12
+ *
13
+ * Decision (user-directed, 2026-04-17):
14
+ * Keep the public contract strict — do NOT silently coerce. Instead, when
15
+ * a string arrives where an array is required, emit a diagnostic error
16
+ * that explicitly names the upstream-stringification case and tells the
17
+ * caller to fix their tool-call path. This keeps the product honest while
18
+ * giving the offending caller a fast signal. If later evidence shows
19
+ * multiple uncontrolled callers, a compatibility-coercion path can be
20
+ * added behind an explicit, warning-counted flag — but not yet.
21
+ *
22
+ * Parent doc: memory/ollama-intern-output-quality-report-2026-04-17.md
23
+ * Runbook: memory/ollama-intern-phase-a-runbook-2026-04-17.md
24
+ */
25
+ import { z } from "zod";
26
+ export interface StrictStringArrayOpts {
27
+ min?: number;
28
+ max?: number;
29
+ minItemLen?: number;
30
+ fieldName?: string;
31
+ }
32
+ /**
33
+ * Strict array<string> schema with diagnostic for upstream-stringified input.
34
+ *
35
+ * Behavior:
36
+ * - array<string> matching min/max/minItemLen: pass
37
+ * - string (any shape): fail with specific diagnostic naming the
38
+ * stringification case when the string looks like a JSON array,
39
+ * or with a "wrap in array" hint otherwise
40
+ * - anything else: fail with zod's normal messages
41
+ *
42
+ * Output type is `string[]`. Chain `.optional()` for optional fields.
43
+ */
44
+ export declare function strictStringArray(opts?: StrictStringArrayOpts): z.ZodType<string[]>;
45
+ //# sourceMappingURL=stringifiedArrayGuard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringifiedArrayGuard.d.ts","sourceRoot":"","sources":["../../src/guardrails/stringifiedArrayGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA6BD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,GAAE,qBAA0B,GAC/B,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAuCrB"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * stringifiedArrayGuard — diagnostic schema helper.
3
+ *
4
+ * Problem:
5
+ * Some callers (observed in the repo-dataset marketing swarm, 2026-04-17)
6
+ * serialize nested array params as JSON strings before the MCP transport
7
+ * sees them. `source_paths: ["file.md"]` arrives at the server as
8
+ * `"[\"file.md\"]"` — a string. Strict `z.array(z.string())` then fails
9
+ * with a generic "expected array, received string", which hides the real
10
+ * cause (upstream stringification) behind a schema error the caller can't
11
+ * act on.
12
+ *
13
+ * Decision (user-directed, 2026-04-17):
14
+ * Keep the public contract strict — do NOT silently coerce. Instead, when
15
+ * a string arrives where an array is required, emit a diagnostic error
16
+ * that explicitly names the upstream-stringification case and tells the
17
+ * caller to fix their tool-call path. This keeps the product honest while
18
+ * giving the offending caller a fast signal. If later evidence shows
19
+ * multiple uncontrolled callers, a compatibility-coercion path can be
20
+ * added behind an explicit, warning-counted flag — but not yet.
21
+ *
22
+ * Parent doc: memory/ollama-intern-output-quality-report-2026-04-17.md
23
+ * Runbook: memory/ollama-intern-phase-a-runbook-2026-04-17.md
24
+ */
25
+ import { z } from "zod";
26
+ function buildStringDiagnostic(value, fieldName) {
27
+ const field = fieldName ?? "field";
28
+ const trimmed = value.trim();
29
+ const looksLikeJsonArray = trimmed.startsWith("[") && trimmed.endsWith("]");
30
+ const preview = trimmed.length > 80 ? `${trimmed.slice(0, 80)}...` : trimmed;
31
+ if (looksLikeJsonArray) {
32
+ return (`Stringified array detected on \`${field}\`. ` +
33
+ `Expected array<string>, received a string containing JSON: "${preview}". ` +
34
+ `The caller serialized the array before the MCP transport saw it — ` +
35
+ `fix the caller, not the server. ` +
36
+ `If you are a subagent, swarm, or custom tool-call path, ` +
37
+ `your serializer is JSON-encoding nested params; pass the array as a native array.`);
38
+ }
39
+ return (`Expected array<string> on \`${field}\`, got string "${preview}". ` +
40
+ `Wrap single values as an array: ["value"], not "value".`);
41
+ }
42
+ /**
43
+ * Strict array<string> schema with diagnostic for upstream-stringified input.
44
+ *
45
+ * Behavior:
46
+ * - array<string> matching min/max/minItemLen: pass
47
+ * - string (any shape): fail with specific diagnostic naming the
48
+ * stringification case when the string looks like a JSON array,
49
+ * or with a "wrap in array" hint otherwise
50
+ * - anything else: fail with zod's normal messages
51
+ *
52
+ * Output type is `string[]`. Chain `.optional()` for optional fields.
53
+ */
54
+ export function strictStringArray(opts = {}) {
55
+ const min = opts.min ?? 1;
56
+ const max = opts.max;
57
+ const minItemLen = opts.minItemLen ?? 1;
58
+ const fieldName = opts.fieldName;
59
+ const real = (() => {
60
+ let s = z.array(z.string().min(minItemLen)).min(min);
61
+ if (max !== undefined)
62
+ s = s.max(max);
63
+ return s;
64
+ })();
65
+ return z
66
+ .any()
67
+ .transform((v, ctx) => {
68
+ if (typeof v === "string") {
69
+ // Log to stderr so MCP host captures the diagnostic event even
70
+ // though the handler never runs. Tagged for grep.
71
+ // eslint-disable-next-line no-console
72
+ console.error(`[ollama-intern:stringified-array-guard] field=${fieldName ?? "?"} received=string looks_like_json_array=${v.trim().startsWith("[") && v.trim().endsWith("]")}`);
73
+ ctx.addIssue({
74
+ code: z.ZodIssueCode.custom,
75
+ message: buildStringDiagnostic(v, fieldName),
76
+ });
77
+ return z.NEVER;
78
+ }
79
+ const res = real.safeParse(v);
80
+ if (!res.success) {
81
+ for (const issue of res.error.issues)
82
+ ctx.addIssue(issue);
83
+ return z.NEVER;
84
+ }
85
+ return res.data;
86
+ });
87
+ }
88
+ //# sourceMappingURL=stringifiedArrayGuard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stringifiedArrayGuard.js","sourceRoot":"","sources":["../../src/guardrails/stringifiedArrayGuard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AASxB,SAAS,qBAAqB,CAC5B,KAAa,EACb,SAA6B;IAE7B,MAAM,KAAK,GAAG,SAAS,IAAI,OAAO,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;IAC7B,MAAM,kBAAkB,GACtB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACnD,MAAM,OAAO,GACX,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC;IAE/D,IAAI,kBAAkB,EAAE,CAAC;QACvB,OAAO,CACL,mCAAmC,KAAK,MAAM;YAC9C,+DAA+D,OAAO,KAAK;YAC3E,oEAAoE;YACpE,kCAAkC;YAClC,0DAA0D;YAC1D,mFAAmF,CACpF,CAAC;IACJ,CAAC;IACD,OAAO,CACL,+BAA+B,KAAK,mBAAmB,OAAO,KAAK;QACnE,yDAAyD,CAC1D,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,iBAAiB,CAC/B,OAA8B,EAAE;IAEhC,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;IACrB,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;IACxC,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;IAEjC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE;QACjB,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrD,IAAI,GAAG,KAAK,SAAS;YAAE,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO,CAAC;SACL,GAAG,EAAE;SACL,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAY,EAAE;QAC9B,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;YAC1B,+DAA+D;YAC/D,kDAAkD;YAClD,sCAAsC;YACtC,OAAO,CAAC,KAAK,CACX,iDACE,SAAS,IAAI,GACf,0CACE,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CACnD,EAAE,CACH,CAAC;YACF,GAAG,CAAC,QAAQ,CAAC;gBACX,IAAI,EAAE,CAAC,CAAC,YAAY,CAAC,MAAM;gBAC3B,OAAO,EAAE,qBAAqB,CAAC,CAAC,EAAE,SAAS,CAAC;aAC7C,CAAC,CAAC;YACH,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAC9B,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,MAAM,KAAK,IAAI,GAAG,CAAC,KAAK,CAAC,MAAM;gBAAE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC1D,OAAO,CAAC,CAAC,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC,CAAmC,CAAC;AACzC,CAAC"}
@@ -30,16 +30,16 @@ export declare const changeBriefSchema: z.ZodObject<{
30
30
  max_breakpoints: z.ZodOptional<z.ZodNumber>;
31
31
  max_validation_checks: z.ZodOptional<z.ZodNumber>;
32
32
  }, "strip", z.ZodTypeAny, {
33
- source_paths?: string[] | undefined;
34
33
  per_file_max_chars?: number | undefined;
34
+ source_paths?: string[] | undefined;
35
35
  corpus?: string | undefined;
36
36
  corpus_query?: string | undefined;
37
37
  diff_text?: string | undefined;
38
38
  max_breakpoints?: number | undefined;
39
39
  max_validation_checks?: number | undefined;
40
40
  }, {
41
- source_paths?: string[] | undefined;
42
41
  per_file_max_chars?: number | undefined;
42
+ source_paths?: string[] | undefined;
43
43
  corpus?: string | undefined;
44
44
  corpus_query?: string | undefined;
45
45
  diff_text?: string | undefined;
@@ -2,15 +2,14 @@
2
2
  * ollama_classify — single-label classification with confidence.
3
3
  * Tier: Instant.
4
4
  *
5
- * Two input modes:
6
- * - `text` (single string) : returns {label, confidence}
7
- * - `items` (array with ids) : returns one coherent batch envelope with
8
- * result.items[] of {id, ok, result|error}.
9
- * Token accounting / residency / elapsed are at the envelope level.
10
- * A single malformed item never explodes the batch — the batch
11
- * completes and ok_count/error_count surface the split.
5
+ * Three input modes (exactly one):
6
+ * - `text` : single text, classified directly
7
+ * - `source_path` : single file, read + classified server-side caller
8
+ * never pre-reads the file (context preservation)
9
+ * - `items` : batch of {id, text} returns one batch envelope with
10
+ * per-item {id, ok, result|error}
12
11
  *
13
- * Exactly one of {text, items} must be provided.
12
+ * Exactly one of {text, source_path, items} must be provided.
14
13
  */
15
14
  import { z } from "zod";
16
15
  import type { Envelope } from "../envelope.js";
@@ -19,6 +18,7 @@ import { type ClassifyGuarded } from "../guardrails/confidence.js";
19
18
  import type { RunContext } from "../runContext.js";
20
19
  export declare const classifySchema: z.ZodObject<{
21
20
  text: z.ZodOptional<z.ZodString>;
21
+ source_path: z.ZodOptional<z.ZodString>;
22
22
  items: z.ZodOptional<z.ZodArray<z.ZodObject<{
23
23
  id: z.ZodString;
24
24
  text: z.ZodString;
@@ -29,9 +29,10 @@ export declare const classifySchema: z.ZodObject<{
29
29
  text: string;
30
30
  id: string;
31
31
  }>, "many">>;
32
- labels: z.ZodArray<z.ZodString, "many">;
32
+ labels: z.ZodType<string[], z.ZodTypeDef, string[]>;
33
33
  allow_none: z.ZodOptional<z.ZodBoolean>;
34
34
  threshold: z.ZodOptional<z.ZodNumber>;
35
+ per_file_max_chars: z.ZodOptional<z.ZodNumber>;
35
36
  }, "strip", z.ZodTypeAny, {
36
37
  labels: string[];
37
38
  items?: {
@@ -39,8 +40,10 @@ export declare const classifySchema: z.ZodObject<{
39
40
  id: string;
40
41
  }[] | undefined;
41
42
  text?: string | undefined;
43
+ source_path?: string | undefined;
42
44
  allow_none?: boolean | undefined;
43
45
  threshold?: number | undefined;
46
+ per_file_max_chars?: number | undefined;
44
47
  }, {
45
48
  labels: string[];
46
49
  items?: {
@@ -48,8 +51,10 @@ export declare const classifySchema: z.ZodObject<{
48
51
  id: string;
49
52
  }[] | undefined;
50
53
  text?: string | undefined;
54
+ source_path?: string | undefined;
51
55
  allow_none?: boolean | undefined;
52
56
  threshold?: number | undefined;
57
+ per_file_max_chars?: number | undefined;
53
58
  }>;
54
59
  export type ClassifyInput = z.infer<typeof classifySchema>;
55
60
  export declare function handleClassify(input: ClassifyInput, ctx: RunContext): Promise<Envelope<ClassifyGuarded> | Envelope<BatchResult<ClassifyGuarded>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/tools/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAE7F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAezB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAwC3D,wBAAsB,cAAc,CAClC,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CAwC7E"}
1
+ {"version":3,"file":"classify.d.ts","sourceRoot":"","sources":["../../src/tools/classify.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAY,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAA4B,KAAK,eAAe,EAAE,MAAM,6BAA6B,CAAC;AAI7F,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBzB,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AA2C3D,wBAAsB,cAAc,CAClC,KAAK,EAAE,aAAa,EACpB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,CAAC,CA+C7E"}
@@ -2,24 +2,26 @@
2
2
  * ollama_classify — single-label classification with confidence.
3
3
  * Tier: Instant.
4
4
  *
5
- * Two input modes:
6
- * - `text` (single string) : returns {label, confidence}
7
- * - `items` (array with ids) : returns one coherent batch envelope with
8
- * result.items[] of {id, ok, result|error}.
9
- * Token accounting / residency / elapsed are at the envelope level.
10
- * A single malformed item never explodes the batch — the batch
11
- * completes and ok_count/error_count surface the split.
5
+ * Three input modes (exactly one):
6
+ * - `text` : single text, classified directly
7
+ * - `source_path` : single file, read + classified server-side caller
8
+ * never pre-reads the file (context preservation)
9
+ * - `items` : batch of {id, text} returns one batch envelope with
10
+ * per-item {id, ok, result|error}
12
11
  *
13
- * Exactly one of {text, items} must be provided.
12
+ * Exactly one of {text, source_path, items} must be provided.
14
13
  */
15
14
  import { z } from "zod";
16
15
  import { TEMPERATURE_BY_SHAPE } from "../tiers.js";
17
16
  import { runTool } from "./runner.js";
18
17
  import { runBatch } from "./batch.js";
19
18
  import { applyConfidenceThreshold } from "../guardrails/confidence.js";
19
+ import { strictStringArray } from "../guardrails/stringifiedArrayGuard.js";
20
+ import { loadSources } from "../sources.js";
20
21
  import { InternError } from "../errors.js";
21
22
  export const classifySchema = z.object({
22
- text: z.string().min(1).optional().describe("The single text to classify. Use this OR items, not both."),
23
+ text: z.string().min(1).optional().describe("The single text to classify. Use this OR source_path OR items exactly one."),
24
+ source_path: z.string().min(1).optional().describe("A single file path to read + classify server-side. Use this instead of `text` to save Claude context — the server reads the file, Claude never sees its contents."),
23
25
  items: z
24
26
  .array(z.object({
25
27
  id: z.string().min(1).describe("Caller-provided, unique within the batch."),
@@ -28,9 +30,10 @@ export const classifySchema = z.object({
28
30
  .min(1)
29
31
  .optional()
30
32
  .describe("Batch of texts to classify. Each needs a stable caller-provided id so results join back to source inputs cleanly. Returns one batch envelope with per-item {id, ok, result|error} entries."),
31
- labels: z.array(z.string().min(1)).min(2).describe("Candidate labels — the model picks exactly one, or null if allow_none."),
33
+ labels: strictStringArray({ min: 2, fieldName: "labels" }).describe("Candidate labels — the model picks exactly one, or null if allow_none."),
32
34
  allow_none: z.boolean().optional().describe("If true and confidence < threshold, return label=null instead of a weak guess."),
33
35
  threshold: z.number().min(0).max(1).optional().describe("Confidence floor (default 0.7)."),
36
+ per_file_max_chars: z.number().int().min(1000).max(200_000).optional().describe("Chars to read when source_path is used (default 40k)."),
34
37
  });
35
38
  function buildPromptFor(text, input) {
36
39
  const labels = input.labels.map((l) => `"${l}"`).join(", ");
@@ -58,9 +61,11 @@ function parseClassify(raw) {
58
61
  }
59
62
  }
60
63
  function assertExactlyOneInput(input) {
61
- const given = (input.text !== undefined ? 1 : 0) + (input.items !== undefined ? 1 : 0);
64
+ const given = (input.text !== undefined ? 1 : 0) +
65
+ (input.source_path !== undefined ? 1 : 0) +
66
+ (input.items !== undefined ? 1 : 0);
62
67
  if (given !== 1) {
63
- throw new InternError("SCHEMA_INVALID", `ollama_classify: provide exactly one of "text" or "items" (given ${given}).`, "Pass text for a single call, or items:[{id,text}] for a batch. Not both, not neither.", false);
68
+ throw new InternError("SCHEMA_INVALID", `ollama_classify: provide exactly one of "text", "source_path", or "items" (given ${given}).`, "Pass text for a single call, source_path to read a file server-side, or items:[{id,text}] for a batch.", false);
64
69
  }
65
70
  }
66
71
  export async function handleClassify(input, ctx) {
@@ -83,7 +88,15 @@ export async function handleClassify(input, ctx) {
83
88
  }),
84
89
  });
85
90
  }
86
- const text = input.text;
91
+ let text;
92
+ if (input.source_path !== undefined) {
93
+ const perFileMax = input.per_file_max_chars ?? 40_000;
94
+ const [loaded] = await loadSources([input.source_path], perFileMax);
95
+ text = loaded.body;
96
+ }
97
+ else {
98
+ text = input.text;
99
+ }
87
100
  return runTool({
88
101
  tool: "ollama_classify",
89
102
  tier: "instant",
@@ -1 +1 @@
1
- {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/tools/classify.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../src/tools/classify.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,10 @@ export interface DraftResult {
33
33
  draft: string;
34
34
  is_draft: true;
35
35
  compile_check?: CompileCheckResult;
36
+ /** Number of regeneration rounds triggered by the banned-phrase guard (style="doc" only). 0 means the first attempt passed. */
37
+ regenerations_triggered?: number;
38
+ /** Phrases detected in rejected attempts, deduped in order of first appearance. */
39
+ detected_phrases?: string[];
36
40
  }
37
41
  export declare function handleDraft(input: DraftInput, ctx: RunContext): Promise<Envelope<DraftResult>>;
38
42
  //# sourceMappingURL=draft.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI/C,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEtF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;EAStB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,IAAI,CAAC;IACf,aAAa,CAAC,EAAE,kBAAkB,CAAC;CACpC;AAeD,wBAAsB,WAAW,CAC/B,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAgChC"}
1
+ {"version":3,"file":"draft.d.ts","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAI/C,OAAO,EAAgB,KAAK,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAItF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;EAStB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,IAAI,CAAC;IACf,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,+HAA+H;IAC/H,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAeD,wBAAsB,WAAW,CAC/B,KAAK,EAAE,UAAU,EACjB,GAAG,EAAE,UAAU,GACd,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAuFhC"}
@@ -10,7 +10,10 @@ import { TEMPERATURE_BY_SHAPE } from "../tiers.js";
10
10
  import { runTool } from "./runner.js";
11
11
  import { assertWriteAllowed } from "../guardrails/writeConfirm.js";
12
12
  import { compileCheck } from "../guardrails/compileCheck.js";
13
+ import { findBannedPhrases } from "../guardrails/bannedPhrases.js";
14
+ import { InternError } from "../errors.js";
13
15
  import { timestamp } from "../observability.js";
16
+ const DOC_MAX_ATTEMPTS = 3;
14
17
  export const draftSchema = z.object({
15
18
  prompt: z.string().min(1).describe("What to draft. Be concrete."),
16
19
  language: z
@@ -48,7 +51,7 @@ export async function handleDraft(input, ctx) {
48
51
  });
49
52
  throw err;
50
53
  }
51
- const envelope = await runTool({
54
+ const runOnce = async () => runTool({
52
55
  tool: "ollama_draft",
53
56
  tier: "workhorse",
54
57
  ctx,
@@ -59,6 +62,56 @@ export async function handleDraft(input, ctx) {
59
62
  }),
60
63
  parse: (raw) => ({ draft: stripCodeFence(raw), is_draft: true }),
61
64
  });
65
+ let envelope;
66
+ const detectedPhraseLog = [];
67
+ let regenerations = 0;
68
+ if (input.style === "doc") {
69
+ let attempt = 0;
70
+ let lastMatches = [];
71
+ envelope = await runOnce();
72
+ attempt = 1;
73
+ lastMatches = findBannedPhrases(envelope.result.draft);
74
+ while (lastMatches.length > 0 && attempt < DOC_MAX_ATTEMPTS) {
75
+ for (const m of lastMatches) {
76
+ if (!detectedPhraseLog.includes(m.phrase))
77
+ detectedPhraseLog.push(m.phrase);
78
+ }
79
+ await ctx.logger.log({
80
+ kind: "guardrail",
81
+ ts: timestamp(),
82
+ tool: "ollama_draft",
83
+ rule: "bannedPhrases",
84
+ action: "regenerated",
85
+ detail: { attempt, detected: lastMatches.map((m) => m.phrase) },
86
+ });
87
+ regenerations += 1;
88
+ envelope = await runOnce();
89
+ attempt += 1;
90
+ lastMatches = findBannedPhrases(envelope.result.draft);
91
+ }
92
+ if (lastMatches.length > 0) {
93
+ for (const m of lastMatches) {
94
+ if (!detectedPhraseLog.includes(m.phrase))
95
+ detectedPhraseLog.push(m.phrase);
96
+ }
97
+ await ctx.logger.log({
98
+ kind: "guardrail",
99
+ ts: timestamp(),
100
+ tool: "ollama_draft",
101
+ rule: "bannedPhrases",
102
+ action: "blocked",
103
+ detail: { attempts: attempt, detected: detectedPhraseLog },
104
+ });
105
+ throw new InternError("DRAFT_BANNED_PHRASE", `draft(style="doc") produced banned marketing phrases after ${attempt} attempts: ${detectedPhraseLog.join(", ")}`, `Rewrite the prompt to demand concrete, falsifiable claims — e.g. "name a specific capability and a measurable outcome; avoid words like 'seamless', 'effortless', 'leverage'". Consider style="concise" if brevity matters more than tone.`, true);
106
+ }
107
+ if (regenerations > 0)
108
+ envelope.result.regenerations_triggered = regenerations;
109
+ if (detectedPhraseLog.length > 0)
110
+ envelope.result.detected_phrases = detectedPhraseLog;
111
+ }
112
+ else {
113
+ envelope = await runOnce();
114
+ }
62
115
  if (input.language) {
63
116
  envelope.result.compile_check = await compileCheck(envelope.result.draft, input.language);
64
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"draft.js","sourceRoot":"","sources":["../../src/tools/draft.ts"],"names":[],"mappings":"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"}