@burtson-labs/agent-core 1.6.44 → 1.6.45

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.
@@ -4,4 +4,5 @@ export * from './loopNode';
4
4
  export * from './contracts';
5
5
  export * from './envelopes';
6
6
  export * from './planner';
7
+ export * from './routing';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,YAAY,CAAC;AAC3B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,WAAW,CAAC;AAC1B,cAAc,WAAW,CAAC"}
@@ -20,4 +20,5 @@ __exportStar(require("./loopNode"), exports);
20
20
  __exportStar(require("./contracts"), exports);
21
21
  __exportStar(require("./envelopes"), exports);
22
22
  __exportStar(require("./planner"), exports);
23
+ __exportStar(require("./routing"), exports);
23
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,8CAA4B;AAC5B,6CAA2B;AAC3B,8CAA4B;AAC5B,8CAA4B;AAC5B,4CAA0B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/graph/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,8CAA4B;AAC5B,6CAA2B;AAC3B,8CAA4B;AAC5B,8CAA4B;AAC5B,4CAA0B;AAC1B,4CAA0B"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Phase 10 — routing heuristics (the cheap pre-gate).
3
+ *
4
+ * Empirical routing (Phase 10 proper) needs the BanditBench baseline to say
5
+ * WHICH execution mode wins for WHICH task shape. But calling the planner
6
+ * model on every prompt just to hear "this is a plain loop" is wasteful — most
7
+ * prompts are obviously not graph-shaped. This module is the zero-inference
8
+ * pre-gate: a fast, explainable signal for whether a prompt is even worth
9
+ * asking the planner about.
10
+ *
11
+ * It NEVER decides execution — it only gates the (paid) planner call:
12
+ * score low → don't bother the planner; run the normal loop
13
+ * score high → the prompt smells decomposable; offer/consult the planner
14
+ *
15
+ * Deliberately conservative and transparent (returns its reasons) so a host
16
+ * can log why it routed, and so tuning it against the bench is inspectable
17
+ * rather than a black box. "graph rarely wins" is the null hypothesis the
18
+ * bench exists to test, so the bar to even SUGGEST a graph is high.
19
+ */
20
+ export interface GraphShapeSignal {
21
+ /** 0..1 — how graph-shaped the prompt looks. */
22
+ score: number;
23
+ /** Human-readable contributors, for logging + tuning. */
24
+ reasons: string[];
25
+ /** Convenience: score >= the suggest threshold. */
26
+ suggestsGraph: boolean;
27
+ }
28
+ export interface GraphShapeOptions {
29
+ /** Score at/above which we'd consult the planner. Default 0.6 (high bar). */
30
+ suggestThreshold?: number;
31
+ }
32
+ /**
33
+ * Score how graph-shaped a prompt looks. Pure, fast, no model call.
34
+ */
35
+ export declare function classifyGraphShaped(prompt: string, opts?: GraphShapeOptions): GraphShapeSignal;
36
+ //# sourceMappingURL=routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.d.ts","sourceRoot":"","sources":["../../src/graph/routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,gDAAgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,yDAAyD;IACzD,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,mDAAmD;IACnD,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,6EAA6E;IAC7E,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AA+CD;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAsB,GAAG,gBAAgB,CA0DlG"}
@@ -0,0 +1,122 @@
1
+ "use strict";
2
+ /**
3
+ * Phase 10 — routing heuristics (the cheap pre-gate).
4
+ *
5
+ * Empirical routing (Phase 10 proper) needs the BanditBench baseline to say
6
+ * WHICH execution mode wins for WHICH task shape. But calling the planner
7
+ * model on every prompt just to hear "this is a plain loop" is wasteful — most
8
+ * prompts are obviously not graph-shaped. This module is the zero-inference
9
+ * pre-gate: a fast, explainable signal for whether a prompt is even worth
10
+ * asking the planner about.
11
+ *
12
+ * It NEVER decides execution — it only gates the (paid) planner call:
13
+ * score low → don't bother the planner; run the normal loop
14
+ * score high → the prompt smells decomposable; offer/consult the planner
15
+ *
16
+ * Deliberately conservative and transparent (returns its reasons) so a host
17
+ * can log why it routed, and so tuning it against the bench is inspectable
18
+ * rather than a black box. "graph rarely wins" is the null hypothesis the
19
+ * bench exists to test, so the bar to even SUGGEST a graph is high.
20
+ */
21
+ Object.defineProperty(exports, "__esModule", { value: true });
22
+ exports.classifyGraphShaped = classifyGraphShaped;
23
+ // Phrases that signal INDEPENDENT sub-parts (the thing a graph is for).
24
+ const MULTI_PART_MARKERS = [
25
+ /\bcompare\b[\s\S]*\b(?:and|vs\.?|versus|with|to|against)\b/i, // two-sided compare
26
+ /\bcontrast\b/i,
27
+ /\beach of\b/i,
28
+ /\bboth\b[\s\S]*\band\b/i,
29
+ /\bin parallel\b/i,
30
+ /\bseparately\b/i,
31
+ /\bindependently\b/i,
32
+ /\bacross (the |these |all )?\w+/i,
33
+ /\bfor (?:each|every)\b/i,
34
+ // Sequential fan-in: "…then/finally summarize/combine/merge the results".
35
+ /\b(?:then|afterwards|finally)\b[\s\S]*\b(?:summari[sz]|synthesi[sz]|combin|merg|compil)/i,
36
+ ];
37
+ // Explicit enumeration: "A, B, and C" or "A and B" of comparable nouns.
38
+ const AND_LIST = /\b\w[\w./-]*(?:,\s*\w[\w./-]*)+\s*,?\s*and\s+\w[\w./-]*/i;
39
+ const SIMPLE_AND = /\band\b/i;
40
+ // A synthesis verb paired with multiple sources is the classic fan-in shape.
41
+ // "compar(e|ison)" counts here too — a comparison IS a synthesis over sources.
42
+ const SYNTHESIS_MARKERS = [
43
+ /\bsummari[sz]e\b/i,
44
+ /\bsynthesi[sz]e\b/i,
45
+ /\bcombine\b/i,
46
+ /\breport\b/i,
47
+ /\boverview\b/i,
48
+ /\bcompar(?:e|ison|ing)\b/i,
49
+ ];
50
+ // Strong single-step signals that argue AGAINST a graph regardless.
51
+ const SINGLE_STEP_MARKERS = [
52
+ /\bfix (the |a )?typo\b/i,
53
+ /\brename\b/i,
54
+ /\bbump (the )?version\b/i,
55
+ /^\s*(what|where|when|who|why|how)\b.*\?\s*$/i, // a single question
56
+ /\badd (a |an )?(comment|line|import|field)\b/i,
57
+ ];
58
+ /** Count distinct file-ish tokens (paths, dotted names) mentioned. */
59
+ function fileMentions(text) {
60
+ const matches = text.match(/\b[\w-]+\/[\w./-]+|\b[\w-]+\.(ts|tsx|js|jsx|py|cs|go|rs|md|json|ya?ml|sh)\b/gi) ?? [];
61
+ return new Set(matches.map((m) => m.toLowerCase())).size;
62
+ }
63
+ /**
64
+ * Score how graph-shaped a prompt looks. Pure, fast, no model call.
65
+ */
66
+ function classifyGraphShaped(prompt, opts = {}) {
67
+ const threshold = opts.suggestThreshold ?? 0.6;
68
+ const text = prompt.trim();
69
+ const reasons = [];
70
+ let score = 0;
71
+ // Very short prompts are almost never worth decomposing.
72
+ const words = text.split(/\s+/).filter(Boolean).length;
73
+ if (words < 8) {
74
+ return { score: 0, reasons: ['prompt too short to decompose'], suggestsGraph: false };
75
+ }
76
+ // Hard single-step signals cap the score low — a typo fix is a typo fix.
77
+ for (const re of SINGLE_STEP_MARKERS) {
78
+ if (re.test(text)) {
79
+ return { score: 0.1, reasons: [`single-step marker: ${re.source}`], suggestsGraph: false };
80
+ }
81
+ }
82
+ const multiPartHits = MULTI_PART_MARKERS.filter((re) => re.test(text));
83
+ if (multiPartHits.length > 0) {
84
+ score += 0.4;
85
+ reasons.push(`multi-part phrasing (${multiPartHits.length})`);
86
+ }
87
+ const files = fileMentions(text);
88
+ if (files >= 3) {
89
+ score += 0.3;
90
+ reasons.push(`${files} distinct files/paths mentioned`);
91
+ }
92
+ else if (files === 2) {
93
+ score += 0.15;
94
+ reasons.push('2 files/paths mentioned');
95
+ }
96
+ const hasSynthesis = SYNTHESIS_MARKERS.some((re) => re.test(text));
97
+ const hasList = AND_LIST.test(text);
98
+ if (hasSynthesis && (hasList || multiPartHits.length > 0 || files >= 2)) {
99
+ // Synthesis over multiple things = the fan-in a graph handles well.
100
+ score += 0.3;
101
+ reasons.push('synthesis over multiple sources');
102
+ }
103
+ else if (hasList) {
104
+ score += 0.15;
105
+ reasons.push('enumerated list of targets');
106
+ }
107
+ else if (SIMPLE_AND.test(text) && words >= 20) {
108
+ // A bare "and" in a long prompt is weak evidence at most.
109
+ score += 0.05;
110
+ reasons.push('conjunction in a long prompt');
111
+ }
112
+ // Long, dense prompts have more room for separable work.
113
+ if (words >= 40) {
114
+ score += 0.1;
115
+ reasons.push('long prompt');
116
+ }
117
+ score = Math.min(1, score);
118
+ if (reasons.length === 0)
119
+ reasons.push('no graph-shape signals');
120
+ return { score, reasons, suggestsGraph: score >= threshold };
121
+ }
122
+ //# sourceMappingURL=routing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"routing.js","sourceRoot":"","sources":["../../src/graph/routing.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burtson-labs/agent-core",
3
- "version": "1.6.44",
3
+ "version": "1.6.45",
4
4
  "author": {
5
5
  "name": "Burtson Labs",
6
6
  "email": "team@burtson.ai",