agentic-flow 3.0.0 → 3.2.0

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 (115) hide show
  1. package/.agents/skills/agentic-flow-ecosystem/SKILL.md +50 -0
  2. package/.claude/skills/agentic-flow-ecosystem/skill.md +58 -0
  3. package/.claude/skills/agentic-flow-quickstart/skill.md +6 -6
  4. package/.claude/skills/hooks-automation/skill.md +11 -11
  5. package/.claude/skills/memory-patterns/skill.md +7 -7
  6. package/.claude/skills/sparc-methodology/skill.md +13 -13
  7. package/.claude/skills/swarm-coordination/skill.md +5 -5
  8. package/.claude/skills/worker-benchmarks/skill.md +5 -5
  9. package/.claude/skills/worker-integration/skill.md +5 -5
  10. package/.claude/statusline.mjs +22 -5
  11. package/CHANGELOG.md +48 -0
  12. package/README.md +83 -71
  13. package/dist/.tsbuildinfo +1 -1
  14. package/dist/cli/commands/hooks.d.ts.map +1 -1
  15. package/dist/cli/commands/hooks.js +17 -17
  16. package/dist/cli/commands/hooks.js.map +1 -1
  17. package/dist/cli/commands/init.d.ts +2 -5
  18. package/dist/cli/commands/init.d.ts.map +1 -1
  19. package/dist/cli/commands/init.js +11 -15
  20. package/dist/cli/commands/init.js.map +1 -1
  21. package/dist/cli/commands/swarm.d.ts.map +1 -1
  22. package/dist/cli/commands/swarm.js +3 -2
  23. package/dist/cli/commands/swarm.js.map +1 -1
  24. package/dist/core/agentdb-fast.d.ts +21 -11
  25. package/dist/core/agentdb-fast.d.ts.map +1 -1
  26. package/dist/core/agentdb-fast.js +39 -14
  27. package/dist/core/agentdb-fast.js.map +1 -1
  28. package/dist/integrations/agent-booster.d.ts +35 -0
  29. package/dist/integrations/agent-booster.d.ts.map +1 -0
  30. package/dist/integrations/agent-booster.js +45 -0
  31. package/dist/integrations/agent-booster.js.map +1 -0
  32. package/dist/integrations/index.d.ts +15 -0
  33. package/dist/integrations/index.d.ts.map +1 -0
  34. package/dist/integrations/index.js +11 -0
  35. package/dist/integrations/index.js.map +1 -0
  36. package/dist/integrations/onnx-wasm-embedder.d.ts +59 -0
  37. package/dist/integrations/onnx-wasm-embedder.d.ts.map +1 -0
  38. package/dist/integrations/onnx-wasm-embedder.js +145 -0
  39. package/dist/integrations/onnx-wasm-embedder.js.map +1 -0
  40. package/dist/integrations/optional.d.ts +44 -0
  41. package/dist/integrations/optional.d.ts.map +1 -0
  42. package/dist/integrations/optional.js +107 -0
  43. package/dist/integrations/optional.js.map +1 -0
  44. package/dist/integrations/prompt-injection.d.ts +52 -0
  45. package/dist/integrations/prompt-injection.d.ts.map +1 -0
  46. package/dist/integrations/prompt-injection.js +126 -0
  47. package/dist/integrations/prompt-injection.js.map +1 -0
  48. package/dist/integrations/sublinear.d.ts +71 -0
  49. package/dist/integrations/sublinear.d.ts.map +1 -0
  50. package/dist/integrations/sublinear.js +227 -0
  51. package/dist/integrations/sublinear.js.map +1 -0
  52. package/dist/integrations/task-partition.d.ts +40 -0
  53. package/dist/integrations/task-partition.d.ts.map +1 -0
  54. package/dist/integrations/task-partition.js +173 -0
  55. package/dist/integrations/task-partition.js.map +1 -0
  56. package/dist/mcp/mcp-policy.d.ts.map +1 -1
  57. package/dist/mcp/mcp-policy.js +2 -0
  58. package/dist/mcp/mcp-policy.js.map +1 -1
  59. package/dist/mcp/standalone-stdio.js +12 -26
  60. package/dist/mcp/standalone-stdio.js.map +1 -1
  61. package/dist/mcp/tools/ecosystem-tools.d.ts +49 -0
  62. package/dist/mcp/tools/ecosystem-tools.d.ts.map +1 -0
  63. package/dist/mcp/tools/ecosystem-tools.js +126 -0
  64. package/dist/mcp/tools/ecosystem-tools.js.map +1 -0
  65. package/dist/proxy/anthropic-to-gemini.d.ts.map +1 -1
  66. package/dist/proxy/anthropic-to-gemini.js +10 -14
  67. package/dist/proxy/anthropic-to-gemini.js.map +1 -1
  68. package/dist/proxy/anthropic-to-openrouter.d.ts.map +1 -1
  69. package/dist/proxy/anthropic-to-openrouter.js +6 -25
  70. package/dist/proxy/anthropic-to-openrouter.js.map +1 -1
  71. package/dist/proxy/anthropic-to-requesty.d.ts.map +1 -1
  72. package/dist/proxy/anthropic-to-requesty.js +8 -10
  73. package/dist/proxy/anthropic-to-requesty.js.map +1 -1
  74. package/dist/proxy/sse-lines.d.ts +9 -0
  75. package/dist/proxy/sse-lines.d.ts.map +1 -0
  76. package/dist/proxy/sse-lines.js +37 -0
  77. package/dist/proxy/sse-lines.js.map +1 -0
  78. package/dist/reasoningbank/index.d.ts +2 -1
  79. package/dist/reasoningbank/index.d.ts.map +1 -1
  80. package/dist/reasoningbank/index.js +1 -1
  81. package/dist/reasoningbank/index.js.map +1 -1
  82. package/dist/reasoningbank/utils/embeddings.d.ts +17 -0
  83. package/dist/reasoningbank/utils/embeddings.d.ts.map +1 -1
  84. package/dist/reasoningbank/utils/embeddings.js +48 -17
  85. package/dist/reasoningbank/utils/embeddings.js.map +1 -1
  86. package/dist/routing/SemanticRouter.d.ts +25 -9
  87. package/dist/routing/SemanticRouter.d.ts.map +1 -1
  88. package/dist/routing/SemanticRouter.js +63 -12
  89. package/dist/routing/SemanticRouter.js.map +1 -1
  90. package/dist/utils/input-validator.d.ts +10 -2
  91. package/dist/utils/input-validator.d.ts.map +1 -1
  92. package/dist/utils/input-validator.js +30 -2
  93. package/dist/utils/input-validator.js.map +1 -1
  94. package/dist/utils/model-cache.d.ts.map +1 -1
  95. package/dist/utils/model-cache.js +6 -25
  96. package/dist/utils/model-cache.js.map +1 -1
  97. package/dist/utils/package-version.d.ts +9 -0
  98. package/dist/utils/package-version.d.ts.map +1 -0
  99. package/dist/utils/package-version.js +39 -0
  100. package/dist/utils/package-version.js.map +1 -0
  101. package/dist/wasm/onnx-embeddings-wasm.d.ts.map +1 -1
  102. package/dist/wasm/onnx-embeddings-wasm.js +21 -10
  103. package/dist/wasm/onnx-embeddings-wasm.js.map +1 -1
  104. package/docs/docker-tests/TEST-V1.7.8.Dockerfile +2 -2
  105. package/docs/docker-tests/TEST-V1.7.9-NODE20.Dockerfile +2 -2
  106. package/docs/docker-tests/TEST-V1.7.9.Dockerfile +2 -2
  107. package/docs/guides/CLAUDE-CODE-INTEGRATION.md +25 -8
  108. package/docs/guides/PROXY-ARCHITECTURE-AND-EXTENSION.md +22 -9
  109. package/docs/guides/STANDALONE_PROXY_GUIDE.md +16 -6
  110. package/docs/integrations/FASTMCP_CLI_INTEGRATION.md +1 -1
  111. package/docs/plans/requesty/02-architecture.md +5 -6
  112. package/docs/plans/requesty/03-implementation-phases.md +3 -4
  113. package/docs/plans/requesty/05-migration-guide.md +2 -2
  114. package/package.json +12 -7
  115. package/scripts/validate-providers.sh +7 -4
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Prompt-injection screening for task text.
3
+ *
4
+ * Uses the optional `aidefence` package (53 curated patterns across encodings
5
+ * and obfuscation variants) when installed, and a small built-in pattern set
6
+ * otherwise. Only the `aidefence/dist/detection` subpath is loaded: the package
7
+ * root starts an Express server stack, the detection engine has no deps.
8
+ *
9
+ * Policy (env `AGENTIC_FLOW_PROMPT_INJECTION`):
10
+ * - `block` (default): reject `critical` findings, warn on the rest
11
+ * - `strict`: reject `critical` and `high`, warn on the rest
12
+ * - `warn`: never reject, warn on every finding
13
+ * - `off`: do not scan
14
+ *
15
+ * `high` is not rejected by default because legitimate agent prompts often
16
+ * trip it — "You are now a code reviewer…" matches aidefence's role-switch rule.
17
+ */
18
+ import { requireOptional } from './optional.js';
19
+ const SEVERITY_RANK = { low: 1, medium: 2, high: 3, critical: 4 };
20
+ /** Built-in fallback: the highest-signal override/exfiltration/jailbreak shapes. */
21
+ const BUILTIN_RULES = [
22
+ {
23
+ id: 'AF-001', type: 'instruction_override', severity: 'critical', confidence: 0.95,
24
+ description: 'Attempt to override prior instructions',
25
+ pattern: /\b(ignore|disregard|forget|override)\s+(all\s+|any\s+|the\s+|your\s+)*(previous|prior|above|earlier|preceding|system)\s+(instructions?|rules?|prompts?|directions?|guidelines?)/i,
26
+ },
27
+ {
28
+ id: 'AF-002', type: 'prompt_exfiltration', severity: 'high', confidence: 0.9,
29
+ description: 'Attempt to reveal the system prompt or hidden instructions',
30
+ pattern: /\b(reveal|print|show|output|repeat|leak)\s+(me\s+)?(your|the)\s+(system\s+prompt|hidden\s+instructions?|initial\s+instructions?)/i,
31
+ },
32
+ {
33
+ id: 'AF-003', type: 'jailbreak', severity: 'high', confidence: 0.9,
34
+ description: 'Known jailbreak persona or mode switch',
35
+ pattern: /\b(do\s+anything\s+now|DAN\s+mode|developer\s+mode\s+(enabled|on)|jailbreak(ed)?\s+mode)\b/i,
36
+ },
37
+ {
38
+ id: 'AF-004', type: 'role_token_injection', severity: 'high', confidence: 0.9,
39
+ description: 'Chat-template role markers embedded in user text',
40
+ pattern: /<\|?(im_start|im_end|system|endoftext)\|?>|\[\/?INST\]/i,
41
+ },
42
+ ];
43
+ let detector;
44
+ let detectorOverride;
45
+ function getDetector() {
46
+ if (detectorOverride !== undefined)
47
+ return detectorOverride;
48
+ if (detector !== undefined)
49
+ return detector;
50
+ const mod = requireOptional('aidefence/dist/detection');
51
+ try {
52
+ detector = mod?.createInjectionDetector ? mod.createInjectionDetector() : null;
53
+ }
54
+ catch {
55
+ detector = null;
56
+ }
57
+ return detector;
58
+ }
59
+ export function getInjectionPolicy() {
60
+ const raw = (process.env.AGENTIC_FLOW_PROMPT_INJECTION ?? 'block').toLowerCase();
61
+ return ['block', 'strict', 'warn', 'off'].includes(raw)
62
+ ? raw
63
+ : 'block';
64
+ }
65
+ function builtinDetect(text) {
66
+ const threats = [];
67
+ for (const { pattern, ...rule } of BUILTIN_RULES) {
68
+ const m = pattern.exec(text);
69
+ if (m)
70
+ threats.push({ ...rule, match: m[0] });
71
+ }
72
+ return { threats, maxSeverity: highest(threats) };
73
+ }
74
+ function highest(threats) {
75
+ let best = null;
76
+ for (const t of threats) {
77
+ if (!best || SEVERITY_RANK[t.severity] > SEVERITY_RANK[best])
78
+ best = t.severity;
79
+ }
80
+ return best;
81
+ }
82
+ function decide(maxSeverity, policy) {
83
+ if (!maxSeverity || policy === 'off')
84
+ return 'allow';
85
+ if (policy === 'warn')
86
+ return 'warn';
87
+ const threshold = policy === 'strict' ? SEVERITY_RANK.high : SEVERITY_RANK.critical;
88
+ return SEVERITY_RANK[maxSeverity] >= threshold ? 'block' : 'warn';
89
+ }
90
+ /** Scan `text` for prompt-injection attempts under the active policy. */
91
+ export function scanPromptInjection(text, policy = getInjectionPolicy()) {
92
+ if (policy === 'off') {
93
+ return { safe: true, maxSeverity: null, threats: [], engine: 'disabled', decision: 'allow' };
94
+ }
95
+ const engine = getDetector();
96
+ let threats;
97
+ let maxSeverity;
98
+ let engineName = 'builtin';
99
+ if (engine) {
100
+ try {
101
+ const r = engine.detect(text);
102
+ threats = r.threats.map((t) => ({
103
+ id: t.id, type: t.type, severity: t.severity, confidence: t.confidence,
104
+ description: t.description, match: t.match,
105
+ }));
106
+ maxSeverity = r.maxSeverity ?? highest(threats);
107
+ engineName = 'aidefence';
108
+ }
109
+ catch {
110
+ ({ threats, maxSeverity } = builtinDetect(text));
111
+ }
112
+ }
113
+ else {
114
+ ({ threats, maxSeverity } = builtinDetect(text));
115
+ }
116
+ return { safe: threats.length === 0, maxSeverity, threats, engine: engineName, decision: decide(maxSeverity, policy) };
117
+ }
118
+ /** Which engine `scanPromptInjection` will use. */
119
+ export function promptInjectionEngine() {
120
+ return getDetector() ? 'aidefence' : 'builtin';
121
+ }
122
+ /** Test hook: `null` forces the built-in engine, `undefined` restores auto-detection. */
123
+ export function _setInjectionDetectorForTests(d) {
124
+ detectorOverride = d;
125
+ }
126
+ //# sourceMappingURL=prompt-injection.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-injection.js","sourceRoot":"","sources":["../../src/integrations/prompt-injection.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Prompt-injection screening for task text.\n *\n * Uses the optional `aidefence` package (53 curated patterns across encodings\n * and obfuscation variants) when installed, and a small built-in pattern set\n * otherwise. Only the `aidefence/dist/detection` subpath is loaded: the package\n * root starts an Express server stack, the detection engine has no deps.\n *\n * Policy (env `AGENTIC_FLOW_PROMPT_INJECTION`):\n * - `block` (default): reject `critical` findings, warn on the rest\n * - `strict`: reject `critical` and `high`, warn on the rest\n * - `warn`: never reject, warn on every finding\n * - `off`: do not scan\n *\n * `high` is not rejected by default because legitimate agent prompts often\n * trip it — \"You are now a code reviewer…\" matches aidefence's role-switch rule.\n */\n\nimport { requireOptional } from './optional.js';\n\nexport type InjectionSeverity = 'low' | 'medium' | 'high' | 'critical';\nexport type InjectionPolicy = 'block' | 'strict' | 'warn' | 'off';\n\nexport interface InjectionThreat {\n id: string;\n type: string;\n severity: InjectionSeverity;\n confidence: number;\n description: string;\n match?: string;\n}\n\nexport interface InjectionScan {\n safe: boolean;\n maxSeverity: InjectionSeverity | null;\n threats: InjectionThreat[];\n /** Which engine produced the result. */\n engine: 'aidefence' | 'builtin' | 'disabled';\n /** What the active policy decided. */\n decision: 'allow' | 'warn' | 'block';\n}\n\ninterface AidefenceDetector {\n detect(text: string): {\n safe: boolean;\n maxSeverity: InjectionSeverity | null;\n threats: Array<InjectionThreat & Record<string, unknown>>;\n };\n}\n\nconst SEVERITY_RANK: Record<InjectionSeverity, number> = { low: 1, medium: 2, high: 3, critical: 4 };\n\n/** Built-in fallback: the highest-signal override/exfiltration/jailbreak shapes. */\nconst BUILTIN_RULES: Array<Omit<InjectionThreat, 'match'> & { pattern: RegExp }> = [\n {\n id: 'AF-001', type: 'instruction_override', severity: 'critical', confidence: 0.95,\n description: 'Attempt to override prior instructions',\n pattern: /\\b(ignore|disregard|forget|override)\\s+(all\\s+|any\\s+|the\\s+|your\\s+)*(previous|prior|above|earlier|preceding|system)\\s+(instructions?|rules?|prompts?|directions?|guidelines?)/i,\n },\n {\n id: 'AF-002', type: 'prompt_exfiltration', severity: 'high', confidence: 0.9,\n description: 'Attempt to reveal the system prompt or hidden instructions',\n pattern: /\\b(reveal|print|show|output|repeat|leak)\\s+(me\\s+)?(your|the)\\s+(system\\s+prompt|hidden\\s+instructions?|initial\\s+instructions?)/i,\n },\n {\n id: 'AF-003', type: 'jailbreak', severity: 'high', confidence: 0.9,\n description: 'Known jailbreak persona or mode switch',\n pattern: /\\b(do\\s+anything\\s+now|DAN\\s+mode|developer\\s+mode\\s+(enabled|on)|jailbreak(ed)?\\s+mode)\\b/i,\n },\n {\n id: 'AF-004', type: 'role_token_injection', severity: 'high', confidence: 0.9,\n description: 'Chat-template role markers embedded in user text',\n pattern: /<\\|?(im_start|im_end|system|endoftext)\\|?>|\\[\\/?INST\\]/i,\n },\n];\n\nlet detector: AidefenceDetector | null | undefined;\nlet detectorOverride: AidefenceDetector | null | undefined;\n\nfunction getDetector(): AidefenceDetector | null {\n if (detectorOverride !== undefined) return detectorOverride;\n if (detector !== undefined) return detector;\n const mod = requireOptional<{ createInjectionDetector?: () => AidefenceDetector }>('aidefence/dist/detection');\n try {\n detector = mod?.createInjectionDetector ? mod.createInjectionDetector() : null;\n } catch {\n detector = null;\n }\n return detector;\n}\n\nexport function getInjectionPolicy(): InjectionPolicy {\n const raw = (process.env.AGENTIC_FLOW_PROMPT_INJECTION ?? 'block').toLowerCase();\n return (['block', 'strict', 'warn', 'off'] as const).includes(raw as InjectionPolicy)\n ? (raw as InjectionPolicy)\n : 'block';\n}\n\nfunction builtinDetect(text: string): Pick<InjectionScan, 'threats' | 'maxSeverity'> {\n const threats: InjectionThreat[] = [];\n for (const { pattern, ...rule } of BUILTIN_RULES) {\n const m = pattern.exec(text);\n if (m) threats.push({ ...rule, match: m[0] });\n }\n return { threats, maxSeverity: highest(threats) };\n}\n\nfunction highest(threats: InjectionThreat[]): InjectionSeverity | null {\n let best: InjectionSeverity | null = null;\n for (const t of threats) {\n if (!best || SEVERITY_RANK[t.severity] > SEVERITY_RANK[best]) best = t.severity;\n }\n return best;\n}\n\nfunction decide(maxSeverity: InjectionSeverity | null, policy: InjectionPolicy): InjectionScan['decision'] {\n if (!maxSeverity || policy === 'off') return 'allow';\n if (policy === 'warn') return 'warn';\n const threshold = policy === 'strict' ? SEVERITY_RANK.high : SEVERITY_RANK.critical;\n return SEVERITY_RANK[maxSeverity] >= threshold ? 'block' : 'warn';\n}\n\n/** Scan `text` for prompt-injection attempts under the active policy. */\nexport function scanPromptInjection(text: string, policy: InjectionPolicy = getInjectionPolicy()): InjectionScan {\n if (policy === 'off') {\n return { safe: true, maxSeverity: null, threats: [], engine: 'disabled', decision: 'allow' };\n }\n const engine = getDetector();\n let threats: InjectionThreat[];\n let maxSeverity: InjectionSeverity | null;\n let engineName: InjectionScan['engine'] = 'builtin';\n if (engine) {\n try {\n const r = engine.detect(text);\n threats = r.threats.map((t) => ({\n id: t.id, type: t.type, severity: t.severity, confidence: t.confidence,\n description: t.description, match: t.match,\n }));\n maxSeverity = r.maxSeverity ?? highest(threats);\n engineName = 'aidefence';\n } catch {\n ({ threats, maxSeverity } = builtinDetect(text));\n }\n } else {\n ({ threats, maxSeverity } = builtinDetect(text));\n }\n return { safe: threats.length === 0, maxSeverity, threats, engine: engineName, decision: decide(maxSeverity, policy) };\n}\n\n/** Which engine `scanPromptInjection` will use. */\nexport function promptInjectionEngine(): 'aidefence' | 'builtin' {\n return getDetector() ? 'aidefence' : 'builtin';\n}\n\n/** Test hook: `null` forces the built-in engine, `undefined` restores auto-detection. */\nexport function _setInjectionDetectorForTests(d: AidefenceDetector | null | undefined): void {\n detectorOverride = d;\n}\n"]}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * Linear solves and PageRank through `sublinear-time-solver`, verified.
3
+ *
4
+ * sublinear-time-solver (optionalDependency, ~120 MB installed with its own
5
+ * deps) solves diagonally dominant systems with push / random-walk methods.
6
+ * Measured against 1.7.2: `forward-push` is accurate, but the default
7
+ * `neumann` method returned a wrong answer with `converged: false` and
8
+ * `random-walk` threw, and the package logs banners with `console.log`. So:
9
+ * - only `forward-push` is used;
10
+ * - every answer is checked against the residual ||Mx - b||_inf here, and a
11
+ * built-in Gauss-Seidel solve replaces it when the check fails;
12
+ * - the import, construction and solve run with console output sent to stderr
13
+ * (the MCP stdio server owns stdout).
14
+ *
15
+ * The 5 bundled `sublinear/*` agents name sublinear-time-solver tools; the
16
+ * `sublinear_solve` / `sublinear_pagerank` MCP tools in this package give them
17
+ * a working in-process path without a separate MCP server.
18
+ */
19
+ export interface SparseEntry {
20
+ row: number;
21
+ col: number;
22
+ value: number;
23
+ }
24
+ export type MatrixInput = number[][] | {
25
+ size: number;
26
+ entries: SparseEntry[];
27
+ };
28
+ export interface LinearSolveResult {
29
+ solution: number[];
30
+ /** max_i |(Mx - b)_i| */
31
+ residual: number;
32
+ converged: boolean;
33
+ iterations: number;
34
+ diagonallyDominant: boolean;
35
+ engine: 'sublinear-time-solver' | 'builtin';
36
+ /** Set when the library answered but failed verification. */
37
+ libraryRejected?: string;
38
+ }
39
+ /**
40
+ * Solve Mx = b. Intended for (row) diagonally dominant M; other matrices are
41
+ * attempted with Gauss-Seidel and reported with `converged: false` if it fails.
42
+ */
43
+ export declare function solveLinearSystem(matrix: MatrixInput, b: number[], options?: {
44
+ tolerance?: number;
45
+ maxIterations?: number;
46
+ engine?: 'auto' | 'builtin';
47
+ }): Promise<LinearSolveResult>;
48
+ export interface PageRankResult {
49
+ scores: Record<string, number>;
50
+ ranking: Array<{
51
+ node: string;
52
+ score: number;
53
+ }>;
54
+ engine: LinearSolveResult['engine'];
55
+ residual: number;
56
+ }
57
+ /**
58
+ * PageRank over a directed graph as a linear system:
59
+ * (I - d·Pᵀ) y = 1, then scores = y / Σy. With dangling rows left at zero this
60
+ * equals PageRank with uniform teleport from dangling nodes.
61
+ */
62
+ export declare function pageRank(edges: Array<{
63
+ from: string;
64
+ to: string;
65
+ weight?: number;
66
+ }>, options?: {
67
+ damping?: number;
68
+ nodes?: string[];
69
+ engine?: 'auto' | 'builtin';
70
+ }): Promise<PageRankResult>;
71
+ //# sourceMappingURL=sublinear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sublinear.d.ts","sourceRoot":"","sources":["../../src/integrations/sublinear.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAIH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,MAAM,EAAE,EAAE,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAEhF,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,OAAO,CAAC;IAC5B,MAAM,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC5C,6DAA6D;IAC7D,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAsGD;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,WAAW,EACnB,CAAC,EAAE,MAAM,EAAE,EACX,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GACxF,OAAO,CAAC,iBAAiB,CAAC,CAsC5B;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,MAAM,EAAE,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;GAIG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,EAC3D,OAAO,GAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAChF,OAAO,CAAC,cAAc,CAAC,CA8CzB"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Linear solves and PageRank through `sublinear-time-solver`, verified.
3
+ *
4
+ * sublinear-time-solver (optionalDependency, ~120 MB installed with its own
5
+ * deps) solves diagonally dominant systems with push / random-walk methods.
6
+ * Measured against 1.7.2: `forward-push` is accurate, but the default
7
+ * `neumann` method returned a wrong answer with `converged: false` and
8
+ * `random-walk` threw, and the package logs banners with `console.log`. So:
9
+ * - only `forward-push` is used;
10
+ * - every answer is checked against the residual ||Mx - b||_inf here, and a
11
+ * built-in Gauss-Seidel solve replaces it when the check fails;
12
+ * - the import, construction and solve run with console output sent to stderr
13
+ * (the MCP stdio server owns stdout).
14
+ *
15
+ * The 5 bundled `sublinear/*` agents name sublinear-time-solver tools; the
16
+ * `sublinear_solve` / `sublinear_pagerank` MCP tools in this package give them
17
+ * a working in-process path without a separate MCP server.
18
+ */
19
+ import { importOptional, withStdoutToStderr } from './optional.js';
20
+ function toCsr(m) {
21
+ if (Array.isArray(m)) {
22
+ const n = m.length;
23
+ const rows = m.map((row, i) => {
24
+ if (!Array.isArray(row) || row.length !== n)
25
+ throw new Error(`matrix must be square; row ${i} has ${row?.length}`);
26
+ const out = [];
27
+ row.forEach((v, j) => {
28
+ if (!Number.isFinite(v))
29
+ throw new Error(`matrix[${i}][${j}] is not finite`);
30
+ if (v !== 0)
31
+ out.push([j, v]);
32
+ });
33
+ return out;
34
+ });
35
+ return { n, rows, diag: m.map((row, i) => row[i]) };
36
+ }
37
+ const n = m.size;
38
+ if (!Number.isInteger(n) || n < 1)
39
+ throw new Error('size must be a positive integer');
40
+ const acc = Array.from({ length: n }, () => new Map());
41
+ for (const { row, col, value } of m.entries) {
42
+ if (!Number.isInteger(row) || !Number.isInteger(col) || row < 0 || col < 0 || row >= n || col >= n) {
43
+ throw new Error(`entry (${row}, ${col}) is outside a ${n}x${n} matrix`);
44
+ }
45
+ if (!Number.isFinite(value))
46
+ throw new Error(`entry (${row}, ${col}) is not finite`);
47
+ acc[row].set(col, (acc[row].get(col) ?? 0) + value);
48
+ }
49
+ const rows = acc.map((r) => [...r.entries()].filter(([, v]) => v !== 0));
50
+ return { n, rows, diag: acc.map((r, i) => r.get(i) ?? 0) };
51
+ }
52
+ function residualInf(a, x, b) {
53
+ let worst = 0;
54
+ for (let i = 0; i < a.n; i++) {
55
+ let s = 0;
56
+ for (const [j, v] of a.rows[i])
57
+ s += v * x[j];
58
+ worst = Math.max(worst, Math.abs(s - b[i]));
59
+ }
60
+ return worst;
61
+ }
62
+ function isDiagonallyDominant(a) {
63
+ return a.rows.every((row, i) => {
64
+ let off = 0;
65
+ for (const [j, v] of row)
66
+ if (j !== i)
67
+ off += Math.abs(v);
68
+ return Math.abs(a.diag[i]) >= off && a.diag[i] !== 0;
69
+ });
70
+ }
71
+ function gaussSeidel(a, b, tol, maxIterations) {
72
+ const x = new Array(a.n).fill(0);
73
+ let it = 0;
74
+ for (; it < maxIterations; it++) {
75
+ for (let i = 0; i < a.n; i++) {
76
+ if (a.diag[i] === 0)
77
+ throw new Error(`zero diagonal at row ${i}: Gauss-Seidel needs a nonzero diagonal`);
78
+ let s = b[i];
79
+ for (const [j, v] of a.rows[i])
80
+ if (j !== i)
81
+ s -= v * x[j];
82
+ x[i] = s / a.diag[i];
83
+ }
84
+ if (residualInf(a, x, b) <= tol)
85
+ return { x, iterations: it + 1 };
86
+ }
87
+ return { x, iterations: it };
88
+ }
89
+ const solverCache = new Map();
90
+ async function librarySolve(a, b, tol, maxIterations) {
91
+ return withStdoutToStderr(async () => {
92
+ const mod = await importOptional('sublinear-time-solver/core', { quietStdout: true });
93
+ const Solver = mod?.SublinearSolver;
94
+ if (typeof Solver !== 'function')
95
+ return null;
96
+ const key = `${tol}|${maxIterations}`;
97
+ let solver = solverCache.get(key);
98
+ if (!solver) {
99
+ solver = new Solver({ method: 'forward-push', epsilon: tol, maxIterations });
100
+ // The constructor starts WASM probing asynchronously and logs when it
101
+ // finishes; let that settle while console output is still redirected.
102
+ await solver.initializeWasm?.().catch(() => undefined);
103
+ await new Promise((r) => setTimeout(r, 0));
104
+ if (solverCache.size > 8)
105
+ solverCache.clear();
106
+ solverCache.set(key, solver);
107
+ }
108
+ const values = [];
109
+ const rowIndices = [];
110
+ const colIndices = [];
111
+ a.rows.forEach((row, i) => {
112
+ for (const [j, v] of row) {
113
+ values.push(v);
114
+ rowIndices.push(i);
115
+ colIndices.push(j);
116
+ }
117
+ });
118
+ const res = await solver.solve({ rows: a.n, cols: a.n, values, rowIndices, colIndices, format: 'coo' }, b);
119
+ return Array.isArray(res?.solution) ? res.solution.map(Number) : null;
120
+ });
121
+ }
122
+ /**
123
+ * Solve Mx = b. Intended for (row) diagonally dominant M; other matrices are
124
+ * attempted with Gauss-Seidel and reported with `converged: false` if it fails.
125
+ */
126
+ export async function solveLinearSystem(matrix, b, options = {}) {
127
+ const a = toCsr(matrix);
128
+ if (!Array.isArray(b) || b.length !== a.n)
129
+ throw new Error(`vector length ${b?.length} != matrix size ${a.n}`);
130
+ if (!b.every(Number.isFinite))
131
+ throw new Error('vector entries must be finite');
132
+ const tol = options.tolerance ?? 1e-8;
133
+ const maxIterations = Math.min(options.maxIterations ?? 10000, 1_000_000);
134
+ // Residual tolerance scaled to the problem: absolute tol on ||b||_inf ~ 1.
135
+ const scale = Math.max(1, ...b.map(Math.abs));
136
+ const accept = tol * scale * 10;
137
+ const diagonallyDominant = isDiagonallyDominant(a);
138
+ let libraryRejected;
139
+ if (options.engine !== 'builtin') {
140
+ try {
141
+ const x = await librarySolve(a, b, tol, maxIterations);
142
+ if (x && x.length === a.n && x.every(Number.isFinite)) {
143
+ const r = residualInf(a, x, b);
144
+ if (r <= accept) {
145
+ return { solution: x, residual: r, converged: true, iterations: 0, diagonallyDominant, engine: 'sublinear-time-solver' };
146
+ }
147
+ libraryRejected = `residual ${r.toExponential(2)} above ${accept.toExponential(2)}`;
148
+ }
149
+ }
150
+ catch (err) {
151
+ libraryRejected = err?.message ?? String(err);
152
+ }
153
+ }
154
+ const { x, iterations } = gaussSeidel(a, b, accept, maxIterations);
155
+ const residual = residualInf(a, x, b);
156
+ return {
157
+ solution: x,
158
+ residual,
159
+ converged: residual <= accept,
160
+ iterations,
161
+ diagonallyDominant,
162
+ engine: 'builtin',
163
+ ...(libraryRejected ? { libraryRejected } : {}),
164
+ };
165
+ }
166
+ /**
167
+ * PageRank over a directed graph as a linear system:
168
+ * (I - d·Pᵀ) y = 1, then scores = y / Σy. With dangling rows left at zero this
169
+ * equals PageRank with uniform teleport from dangling nodes.
170
+ */
171
+ export async function pageRank(edges, options = {}) {
172
+ const d = options.damping ?? 0.85;
173
+ if (!(d > 0 && d < 1))
174
+ throw new Error('damping must be in (0, 1)');
175
+ const ids = new Map();
176
+ const names = [];
177
+ const add = (s) => {
178
+ if (!ids.has(s)) {
179
+ ids.set(s, names.length);
180
+ names.push(s);
181
+ }
182
+ return ids.get(s);
183
+ };
184
+ for (const n of options.nodes ?? [])
185
+ add(String(n));
186
+ const out = [];
187
+ for (const e of edges) {
188
+ const w = e.weight ?? 1;
189
+ if (!Number.isFinite(w) || w < 0)
190
+ throw new Error(`invalid edge weight ${w}`);
191
+ const a = add(String(e.from));
192
+ const b = add(String(e.to));
193
+ while (out.length < names.length)
194
+ out.push(new Map());
195
+ out[a].set(b, (out[a].get(b) ?? 0) + w);
196
+ }
197
+ while (out.length < names.length)
198
+ out.push(new Map());
199
+ const n = names.length;
200
+ if (n === 0)
201
+ return { scores: {}, ranking: [], engine: 'builtin', residual: 0 };
202
+ // M = I - d * P^T, P row-normalised out-links.
203
+ const entries = [];
204
+ for (let i = 0; i < n; i++)
205
+ entries.push({ row: i, col: i, value: 1 });
206
+ out.forEach((links, src) => {
207
+ let total = 0;
208
+ for (const w of links.values())
209
+ total += w;
210
+ if (total === 0)
211
+ return;
212
+ for (const [dst, w] of links)
213
+ entries.push({ row: dst, col: src, value: -d * (w / total) });
214
+ });
215
+ const res = await solveLinearSystem({ size: n, entries }, new Array(n).fill(1), {
216
+ tolerance: 1e-10,
217
+ engine: options.engine,
218
+ });
219
+ const sum = res.solution.reduce((s, v) => s + v, 0) || 1;
220
+ const scores = {};
221
+ names.forEach((name, i) => (scores[name] = res.solution[i] / sum));
222
+ const ranking = names
223
+ .map((node) => ({ node, score: scores[node] }))
224
+ .sort((x, y) => y.score - x.score);
225
+ return { scores, ranking, engine: res.engine, residual: res.residual };
226
+ }
227
+ //# sourceMappingURL=sublinear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sublinear.js","sourceRoot":"","sources":["../../src/integrations/sublinear.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Linear solves and PageRank through `sublinear-time-solver`, verified.\n *\n * sublinear-time-solver (optionalDependency, ~120 MB installed with its own\n * deps) solves diagonally dominant systems with push / random-walk methods.\n * Measured against 1.7.2: `forward-push` is accurate, but the default\n * `neumann` method returned a wrong answer with `converged: false` and\n * `random-walk` threw, and the package logs banners with `console.log`. So:\n * - only `forward-push` is used;\n * - every answer is checked against the residual ||Mx - b||_inf here, and a\n * built-in Gauss-Seidel solve replaces it when the check fails;\n * - the import, construction and solve run with console output sent to stderr\n * (the MCP stdio server owns stdout).\n *\n * The 5 bundled `sublinear/*` agents name sublinear-time-solver tools; the\n * `sublinear_solve` / `sublinear_pagerank` MCP tools in this package give them\n * a working in-process path without a separate MCP server.\n */\n\nimport { importOptional, withStdoutToStderr } from './optional.js';\n\nexport interface SparseEntry {\n row: number;\n col: number;\n value: number;\n}\n\nexport type MatrixInput = number[][] | { size: number; entries: SparseEntry[] };\n\nexport interface LinearSolveResult {\n solution: number[];\n /** max_i |(Mx - b)_i| */\n residual: number;\n converged: boolean;\n iterations: number;\n diagonallyDominant: boolean;\n engine: 'sublinear-time-solver' | 'builtin';\n /** Set when the library answered but failed verification. */\n libraryRejected?: string;\n}\n\ninterface Csr {\n n: number;\n rows: Array<Array<[number, number]>>; // per row: [col, value]\n diag: number[];\n}\n\nfunction toCsr(m: MatrixInput): Csr {\n if (Array.isArray(m)) {\n const n = m.length;\n const rows = m.map((row, i) => {\n if (!Array.isArray(row) || row.length !== n) throw new Error(`matrix must be square; row ${i} has ${row?.length}`);\n const out: Array<[number, number]> = [];\n row.forEach((v, j) => {\n if (!Number.isFinite(v)) throw new Error(`matrix[${i}][${j}] is not finite`);\n if (v !== 0) out.push([j, v]);\n });\n return out;\n });\n return { n, rows, diag: m.map((row, i) => row[i]) };\n }\n const n = m.size;\n if (!Number.isInteger(n) || n < 1) throw new Error('size must be a positive integer');\n const acc: Array<Map<number, number>> = Array.from({ length: n }, () => new Map());\n for (const { row, col, value } of m.entries) {\n if (!Number.isInteger(row) || !Number.isInteger(col) || row < 0 || col < 0 || row >= n || col >= n) {\n throw new Error(`entry (${row}, ${col}) is outside a ${n}x${n} matrix`);\n }\n if (!Number.isFinite(value)) throw new Error(`entry (${row}, ${col}) is not finite`);\n acc[row].set(col, (acc[row].get(col) ?? 0) + value);\n }\n const rows = acc.map((r) => [...r.entries()].filter(([, v]) => v !== 0));\n return { n, rows, diag: acc.map((r, i) => r.get(i) ?? 0) };\n}\n\nfunction residualInf(a: Csr, x: number[], b: number[]): number {\n let worst = 0;\n for (let i = 0; i < a.n; i++) {\n let s = 0;\n for (const [j, v] of a.rows[i]) s += v * x[j];\n worst = Math.max(worst, Math.abs(s - b[i]));\n }\n return worst;\n}\n\nfunction isDiagonallyDominant(a: Csr): boolean {\n return a.rows.every((row, i) => {\n let off = 0;\n for (const [j, v] of row) if (j !== i) off += Math.abs(v);\n return Math.abs(a.diag[i]) >= off && a.diag[i] !== 0;\n });\n}\n\nfunction gaussSeidel(a: Csr, b: number[], tol: number, maxIterations: number) {\n const x = new Array(a.n).fill(0);\n let it = 0;\n for (; it < maxIterations; it++) {\n for (let i = 0; i < a.n; i++) {\n if (a.diag[i] === 0) throw new Error(`zero diagonal at row ${i}: Gauss-Seidel needs a nonzero diagonal`);\n let s = b[i];\n for (const [j, v] of a.rows[i]) if (j !== i) s -= v * x[j];\n x[i] = s / a.diag[i];\n }\n if (residualInf(a, x, b) <= tol) return { x, iterations: it + 1 };\n }\n return { x, iterations: it };\n}\n\nconst solverCache = new Map<string, any>();\n\nasync function librarySolve(a: Csr, b: number[], tol: number, maxIterations: number): Promise<number[] | null> {\n return withStdoutToStderr(async () => {\n const mod = await importOptional<any>('sublinear-time-solver/core', { quietStdout: true });\n const Solver = mod?.SublinearSolver;\n if (typeof Solver !== 'function') return null;\n const key = `${tol}|${maxIterations}`;\n let solver = solverCache.get(key);\n if (!solver) {\n solver = new Solver({ method: 'forward-push', epsilon: tol, maxIterations });\n // The constructor starts WASM probing asynchronously and logs when it\n // finishes; let that settle while console output is still redirected.\n await solver.initializeWasm?.().catch(() => undefined);\n await new Promise((r) => setTimeout(r, 0));\n if (solverCache.size > 8) solverCache.clear();\n solverCache.set(key, solver);\n }\n const values: number[] = [];\n const rowIndices: number[] = [];\n const colIndices: number[] = [];\n a.rows.forEach((row, i) => {\n for (const [j, v] of row) {\n values.push(v);\n rowIndices.push(i);\n colIndices.push(j);\n }\n });\n const res = await solver.solve({ rows: a.n, cols: a.n, values, rowIndices, colIndices, format: 'coo' }, b);\n return Array.isArray(res?.solution) ? res.solution.map(Number) : null;\n });\n}\n\n/**\n * Solve Mx = b. Intended for (row) diagonally dominant M; other matrices are\n * attempted with Gauss-Seidel and reported with `converged: false` if it fails.\n */\nexport async function solveLinearSystem(\n matrix: MatrixInput,\n b: number[],\n options: { tolerance?: number; maxIterations?: number; engine?: 'auto' | 'builtin' } = {},\n): Promise<LinearSolveResult> {\n const a = toCsr(matrix);\n if (!Array.isArray(b) || b.length !== a.n) throw new Error(`vector length ${b?.length} != matrix size ${a.n}`);\n if (!b.every(Number.isFinite)) throw new Error('vector entries must be finite');\n const tol = options.tolerance ?? 1e-8;\n const maxIterations = Math.min(options.maxIterations ?? 10000, 1_000_000);\n // Residual tolerance scaled to the problem: absolute tol on ||b||_inf ~ 1.\n const scale = Math.max(1, ...b.map(Math.abs));\n const accept = tol * scale * 10;\n const diagonallyDominant = isDiagonallyDominant(a);\n\n let libraryRejected: string | undefined;\n if (options.engine !== 'builtin') {\n try {\n const x = await librarySolve(a, b, tol, maxIterations);\n if (x && x.length === a.n && x.every(Number.isFinite)) {\n const r = residualInf(a, x, b);\n if (r <= accept) {\n return { solution: x, residual: r, converged: true, iterations: 0, diagonallyDominant, engine: 'sublinear-time-solver' };\n }\n libraryRejected = `residual ${r.toExponential(2)} above ${accept.toExponential(2)}`;\n }\n } catch (err: any) {\n libraryRejected = err?.message ?? String(err);\n }\n }\n\n const { x, iterations } = gaussSeidel(a, b, accept, maxIterations);\n const residual = residualInf(a, x, b);\n return {\n solution: x,\n residual,\n converged: residual <= accept,\n iterations,\n diagonallyDominant,\n engine: 'builtin',\n ...(libraryRejected ? { libraryRejected } : {}),\n };\n}\n\nexport interface PageRankResult {\n scores: Record<string, number>;\n ranking: Array<{ node: string; score: number }>;\n engine: LinearSolveResult['engine'];\n residual: number;\n}\n\n/**\n * PageRank over a directed graph as a linear system:\n * (I - d·Pᵀ) y = 1, then scores = y / Σy. With dangling rows left at zero this\n * equals PageRank with uniform teleport from dangling nodes.\n */\nexport async function pageRank(\n edges: Array<{ from: string; to: string; weight?: number }>,\n options: { damping?: number; nodes?: string[]; engine?: 'auto' | 'builtin' } = {},\n): Promise<PageRankResult> {\n const d = options.damping ?? 0.85;\n if (!(d > 0 && d < 1)) throw new Error('damping must be in (0, 1)');\n const ids = new Map<string, number>();\n const names: string[] = [];\n const add = (s: string) => {\n if (!ids.has(s)) {\n ids.set(s, names.length);\n names.push(s);\n }\n return ids.get(s)!;\n };\n for (const n of options.nodes ?? []) add(String(n));\n const out: Array<Map<number, number>> = [];\n for (const e of edges) {\n const w = e.weight ?? 1;\n if (!Number.isFinite(w) || w < 0) throw new Error(`invalid edge weight ${w}`);\n const a = add(String(e.from));\n const b = add(String(e.to));\n while (out.length < names.length) out.push(new Map());\n out[a].set(b, (out[a].get(b) ?? 0) + w);\n }\n while (out.length < names.length) out.push(new Map());\n const n = names.length;\n if (n === 0) return { scores: {}, ranking: [], engine: 'builtin', residual: 0 };\n\n // M = I - d * P^T, P row-normalised out-links.\n const entries: SparseEntry[] = [];\n for (let i = 0; i < n; i++) entries.push({ row: i, col: i, value: 1 });\n out.forEach((links, src) => {\n let total = 0;\n for (const w of links.values()) total += w;\n if (total === 0) return;\n for (const [dst, w] of links) entries.push({ row: dst, col: src, value: -d * (w / total) });\n });\n const res = await solveLinearSystem({ size: n, entries }, new Array(n).fill(1), {\n tolerance: 1e-10,\n engine: options.engine,\n });\n const sum = res.solution.reduce((s, v) => s + v, 0) || 1;\n const scores: Record<string, number> = {};\n names.forEach((name, i) => (scores[name] = res.solution[i] / sum));\n const ranking = names\n .map((node) => ({ node, score: scores[node] }))\n .sort((x, y) => y.score - x.score);\n return { scores, ranking, engine: res.engine, residual: res.residual };\n}\n"]}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Split a task-dependency graph into two groups with the least coupling.
3
+ *
4
+ * A global minimum cut over the (undirected, weighted) dependency graph finds
5
+ * the split that severs the fewest/lightest dependencies — the natural seam for
6
+ * handing work to two agent teams so they block on each other least.
7
+ *
8
+ * Engine: `@ruvector/mincut-wasm` (optionalDependency) when installed; a
9
+ * built-in Stoer-Wagner implementation otherwise (O(n^3), capped at
10
+ * BUILTIN_MAX_TASKS). Both are exact, so they agree on the cut weight.
11
+ *
12
+ * A global min cut can be lopsided (one loosely-attached task vs the rest):
13
+ * that is the correct answer to "where is the weakest seam", not a balance
14
+ * guarantee. Tasks with no dependencies have nothing to cut and are reported
15
+ * in `isolated` rather than forced into a side.
16
+ */
17
+ export interface TaskDependency {
18
+ from: string;
19
+ to: string;
20
+ /** Coupling strength, default 1. Must be finite and >= 0. */
21
+ weight?: number;
22
+ }
23
+ export interface TaskPartition {
24
+ groups: [string[], string[]];
25
+ /** Tasks that have no dependencies at all. */
26
+ isolated: string[];
27
+ /** Sum of weights of the dependencies crossing between the groups. */
28
+ cutWeight: number;
29
+ cutEdges: Array<{
30
+ from: string;
31
+ to: string;
32
+ weight: number;
33
+ }>;
34
+ engine: 'mincut-wasm' | 'builtin';
35
+ }
36
+ export declare const BUILTIN_MAX_TASKS = 400;
37
+ export declare function partitionTaskGraph(tasks: string[], dependencies: TaskDependency[], options?: {
38
+ engine?: 'auto' | 'builtin';
39
+ }): Promise<TaskPartition>;
40
+ //# sourceMappingURL=task-partition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"task-partition.d.ts","sourceRoot":"","sources":["../../src/integrations/task-partition.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAC7B,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,sEAAsE;IACtE,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC9D,MAAM,EAAE,aAAa,GAAG,SAAS,CAAC;CACnC;AAED,eAAO,MAAM,iBAAiB,MAAM,CAAC;AAmGrC,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EAAE,EACf,YAAY,EAAE,cAAc,EAAE,EAC9B,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAO,GAC5C,OAAO,CAAC,aAAa,CAAC,CAkExB"}