@kernel.chat/kbot 2.11.0 → 2.12.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.
- package/README.md +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +11 -0
- package/dist/agent.js.map +1 -1
- package/dist/agents/agents.test.d.ts +2 -0
- package/dist/agents/agents.test.d.ts.map +1 -0
- package/dist/agents/agents.test.js +127 -0
- package/dist/agents/agents.test.js.map +1 -0
- package/dist/cli.js +68 -1
- package/dist/cli.js.map +1 -1
- package/dist/evolution.d.ts +112 -0
- package/dist/evolution.d.ts.map +1 -0
- package/dist/evolution.js +642 -0
- package/dist/evolution.js.map +1 -0
- package/dist/evolution.test.d.ts +2 -0
- package/dist/evolution.test.d.ts.map +1 -0
- package/dist/evolution.test.js +160 -0
- package/dist/evolution.test.js.map +1 -0
- package/dist/ide/acp-server.js +2 -2
- package/dist/quality-diversity.d.ts +106 -0
- package/dist/quality-diversity.d.ts.map +1 -0
- package/dist/quality-diversity.js +296 -0
- package/dist/quality-diversity.js.map +1 -0
- package/dist/tools/comfyui-plugin.d.ts +2 -0
- package/dist/tools/comfyui-plugin.d.ts.map +1 -0
- package/dist/tools/comfyui-plugin.js +523 -0
- package/dist/tools/comfyui-plugin.js.map +1 -0
- package/dist/tools/creative.test.d.ts +2 -0
- package/dist/tools/creative.test.d.ts.map +1 -0
- package/dist/tools/creative.test.js +281 -0
- package/dist/tools/creative.test.js.map +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +5 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/magenta-plugin.d.ts +2 -0
- package/dist/tools/magenta-plugin.d.ts.map +1 -0
- package/dist/tools/magenta-plugin.js +405 -0
- package/dist/tools/magenta-plugin.js.map +1 -0
- package/dist/ui.js +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evolution.test.d.ts","sourceRoot":"","sources":["../src/evolution.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { diagnose, scoreMetrics, computeDelta, formatDiagnosis, formatEvolutionStatus, getEvolutionLog, getEvolutionStats, } from './evolution.js';
|
|
3
|
+
describe('evolution engine', () => {
|
|
4
|
+
// ── diagnose ──
|
|
5
|
+
it('returns an array of weaknesses', () => {
|
|
6
|
+
const weaknesses = diagnose();
|
|
7
|
+
expect(Array.isArray(weaknesses)).toBe(true);
|
|
8
|
+
for (const w of weaknesses) {
|
|
9
|
+
expect(w).toHaveProperty('area');
|
|
10
|
+
expect(w).toHaveProperty('description');
|
|
11
|
+
expect(w).toHaveProperty('severity');
|
|
12
|
+
expect(w).toHaveProperty('evidence');
|
|
13
|
+
expect(['low', 'medium', 'high']).toContain(w.severity);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
it('sorts weaknesses by severity (high first)', () => {
|
|
17
|
+
const weaknesses = diagnose();
|
|
18
|
+
if (weaknesses.length >= 2) {
|
|
19
|
+
const severityOrder = { high: 0, medium: 1, low: 2 };
|
|
20
|
+
for (let i = 1; i < weaknesses.length; i++) {
|
|
21
|
+
expect(severityOrder[weaknesses[i].severity])
|
|
22
|
+
.toBeGreaterThanOrEqual(severityOrder[weaknesses[i - 1].severity]);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
// ── scoreMetrics ──
|
|
27
|
+
it('counts lines of code excluding comments', () => {
|
|
28
|
+
const source = `// comment
|
|
29
|
+
const a = 1
|
|
30
|
+
const b = 2
|
|
31
|
+
// another comment
|
|
32
|
+
|
|
33
|
+
export function foo() {}
|
|
34
|
+
`;
|
|
35
|
+
const m = scoreMetrics(source);
|
|
36
|
+
expect(m.loc).toBe(3); // 3 non-comment, non-blank lines
|
|
37
|
+
});
|
|
38
|
+
it('counts complexity (branches + loops)', () => {
|
|
39
|
+
const source = `
|
|
40
|
+
function test(x: number) {
|
|
41
|
+
if (x > 0) {
|
|
42
|
+
for (let i = 0; i < x; i++) {
|
|
43
|
+
while (true) {
|
|
44
|
+
switch (x) {
|
|
45
|
+
case 1: break
|
|
46
|
+
case 2: break
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
const y = x > 0 ? 1 : 0
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
`;
|
|
55
|
+
const m = scoreMetrics(source);
|
|
56
|
+
// if, for, while, switch, case, case, else, ternary (?:)
|
|
57
|
+
expect(m.complexity).toBeGreaterThanOrEqual(6);
|
|
58
|
+
});
|
|
59
|
+
it('counts TODO/FIXME/HACK markers', () => {
|
|
60
|
+
const source = `
|
|
61
|
+
// TODO: fix this
|
|
62
|
+
const a = 1 // FIXME later
|
|
63
|
+
// HACK: workaround for issue
|
|
64
|
+
// XXX: temporary
|
|
65
|
+
const clean = 2
|
|
66
|
+
`;
|
|
67
|
+
const m = scoreMetrics(source);
|
|
68
|
+
expect(m.todoCount).toBe(4);
|
|
69
|
+
});
|
|
70
|
+
it('counts exported symbols', () => {
|
|
71
|
+
const source = `
|
|
72
|
+
export function foo() {}
|
|
73
|
+
export const BAR = 1
|
|
74
|
+
export class Baz {}
|
|
75
|
+
export interface Qux {}
|
|
76
|
+
export type Quux = string
|
|
77
|
+
export enum Status {}
|
|
78
|
+
function internal() {}
|
|
79
|
+
const local = 1
|
|
80
|
+
`;
|
|
81
|
+
const m = scoreMetrics(source);
|
|
82
|
+
expect(m.exportCount).toBe(6);
|
|
83
|
+
});
|
|
84
|
+
it('returns zero for empty source', () => {
|
|
85
|
+
const m = scoreMetrics('');
|
|
86
|
+
expect(m.loc).toBe(0);
|
|
87
|
+
expect(m.complexity).toBe(0);
|
|
88
|
+
expect(m.todoCount).toBe(0);
|
|
89
|
+
expect(m.exportCount).toBe(0);
|
|
90
|
+
});
|
|
91
|
+
// ── computeDelta ──
|
|
92
|
+
it('positive delta when TODOs are removed', () => {
|
|
93
|
+
const before = { loc: 100, complexity: 10, todoCount: 5, exportCount: 3 };
|
|
94
|
+
const after = { loc: 100, complexity: 10, todoCount: 2, exportCount: 3 };
|
|
95
|
+
const delta = computeDelta(before, after);
|
|
96
|
+
expect(delta).toBeGreaterThan(0);
|
|
97
|
+
});
|
|
98
|
+
it('positive delta when complexity is reduced', () => {
|
|
99
|
+
const before = { loc: 100, complexity: 20, todoCount: 0, exportCount: 3 };
|
|
100
|
+
const after = { loc: 100, complexity: 10, todoCount: 0, exportCount: 3 };
|
|
101
|
+
const delta = computeDelta(before, after);
|
|
102
|
+
expect(delta).toBeGreaterThan(0);
|
|
103
|
+
});
|
|
104
|
+
it('negative delta when exports are removed', () => {
|
|
105
|
+
const before = { loc: 100, complexity: 10, todoCount: 0, exportCount: 5 };
|
|
106
|
+
const after = { loc: 100, complexity: 10, todoCount: 0, exportCount: 3 };
|
|
107
|
+
const delta = computeDelta(before, after);
|
|
108
|
+
expect(delta).toBeLessThan(0);
|
|
109
|
+
});
|
|
110
|
+
it('negative delta when too much code is removed', () => {
|
|
111
|
+
const before = { loc: 100, complexity: 10, todoCount: 0, exportCount: 3 };
|
|
112
|
+
const after = { loc: 30, complexity: 10, todoCount: 0, exportCount: 3 };
|
|
113
|
+
const delta = computeDelta(before, after);
|
|
114
|
+
expect(delta).toBeLessThan(0);
|
|
115
|
+
});
|
|
116
|
+
it('zero delta when nothing changes', () => {
|
|
117
|
+
const metrics = { loc: 100, complexity: 10, todoCount: 0, exportCount: 3 };
|
|
118
|
+
const delta = computeDelta(metrics, metrics);
|
|
119
|
+
expect(delta).toBe(0);
|
|
120
|
+
});
|
|
121
|
+
// ── formatDiagnosis ──
|
|
122
|
+
it('formats empty weaknesses', () => {
|
|
123
|
+
const result = formatDiagnosis([]);
|
|
124
|
+
expect(result).toContain('No weaknesses');
|
|
125
|
+
});
|
|
126
|
+
it('formats weaknesses with correct severity icons', () => {
|
|
127
|
+
const weaknesses = [
|
|
128
|
+
{ area: 'test', description: 'High severity', severity: 'high', evidence: 'e1' },
|
|
129
|
+
{ area: 'test2', description: 'Low severity', severity: 'low', evidence: 'e2' },
|
|
130
|
+
];
|
|
131
|
+
const result = formatDiagnosis(weaknesses);
|
|
132
|
+
expect(result).toContain('▲');
|
|
133
|
+
expect(result).toContain('○');
|
|
134
|
+
expect(result).toContain('High severity');
|
|
135
|
+
expect(result).toContain('Low severity');
|
|
136
|
+
});
|
|
137
|
+
// ── formatEvolutionStatus ──
|
|
138
|
+
it('formats status without errors', () => {
|
|
139
|
+
const result = formatEvolutionStatus();
|
|
140
|
+
expect(result).toContain('Evolution Engine');
|
|
141
|
+
expect(result).toContain('Cycles run:');
|
|
142
|
+
expect(result).toContain('Applied:');
|
|
143
|
+
});
|
|
144
|
+
// ── getEvolutionLog / getEvolutionStats ──
|
|
145
|
+
it('returns a valid log array', () => {
|
|
146
|
+
const log = getEvolutionLog();
|
|
147
|
+
expect(Array.isArray(log)).toBe(true);
|
|
148
|
+
});
|
|
149
|
+
it('returns valid stats', () => {
|
|
150
|
+
const stats = getEvolutionStats();
|
|
151
|
+
expect(stats).toHaveProperty('totalCycles');
|
|
152
|
+
expect(stats).toHaveProperty('totalApplied');
|
|
153
|
+
expect(stats).toHaveProperty('totalRolledBack');
|
|
154
|
+
expect(stats).toHaveProperty('totalSkipped');
|
|
155
|
+
expect(stats).toHaveProperty('avgDelta');
|
|
156
|
+
expect(typeof stats.totalCycles).toBe('number');
|
|
157
|
+
expect(typeof stats.avgDelta).toBe('number');
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
//# sourceMappingURL=evolution.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"evolution.test.js","sourceRoot":"","sources":["../src/evolution.test.ts"],"names":[],"mappings":"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"}
|
package/dist/ide/acp-server.js
CHANGED
|
@@ -11,8 +11,8 @@ import { initBridge, chat, executeCommand, getStatus, getAgents, getContext, get
|
|
|
11
11
|
import { formatDiagnostics } from './lsp-bridge.js';
|
|
12
12
|
const AGENT_IDENTITY = {
|
|
13
13
|
name: 'K:BOT',
|
|
14
|
-
version: '2.
|
|
15
|
-
description: 'Open-source terminal AI agent — 39 specialists,
|
|
14
|
+
version: '2.12.0',
|
|
15
|
+
description: 'Open-source terminal AI agent — 39 specialists, 167 tools, 19 providers, local-first',
|
|
16
16
|
capabilities: ['chat', 'codeAction', 'diagnostics', 'tools'],
|
|
17
17
|
};
|
|
18
18
|
/** Encode a JSON-RPC message with Content-Length header (LSP-style framing) */
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
export interface EliteSolution {
|
|
2
|
+
pattern: {
|
|
3
|
+
intent: string;
|
|
4
|
+
toolSequence: string[];
|
|
5
|
+
keywords: string[];
|
|
6
|
+
};
|
|
7
|
+
/** Composite fitness score (0-1) */
|
|
8
|
+
fitness: number;
|
|
9
|
+
/** [taskComplexity, responseStyle] grid coordinates */
|
|
10
|
+
descriptors: [number, number];
|
|
11
|
+
metadata: {
|
|
12
|
+
tokensCost: number;
|
|
13
|
+
toolCallCount: number;
|
|
14
|
+
retryCount: number;
|
|
15
|
+
created: string;
|
|
16
|
+
uses: number;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export interface ArchiveStats {
|
|
20
|
+
totalElites: number;
|
|
21
|
+
avgFitness: number;
|
|
22
|
+
/** Fraction of cells occupied (0-1) */
|
|
23
|
+
coverage: number;
|
|
24
|
+
/** Top elites sorted by fitness descending */
|
|
25
|
+
topElites: EliteSolution[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load the archive from disk. Creates an empty grid if the file is missing or corrupt.
|
|
29
|
+
* Call once at startup.
|
|
30
|
+
*/
|
|
31
|
+
export declare function initArchive(): void;
|
|
32
|
+
/**
|
|
33
|
+
* Classify a solution into grid coordinates [taskComplexity, responseStyle].
|
|
34
|
+
*
|
|
35
|
+
* taskComplexity: based on tool count
|
|
36
|
+
* 0 = no tools (trivial)
|
|
37
|
+
* 1 = 1 tool (simple)
|
|
38
|
+
* 2 = 2-3 tools (moderate)
|
|
39
|
+
* 3 = 4-6 tools (complex)
|
|
40
|
+
* 4 = 7+ tools (expert)
|
|
41
|
+
*
|
|
42
|
+
* responseStyle: based on token cost
|
|
43
|
+
* 0 = < 200 tokens (concise)
|
|
44
|
+
* 1 = < 500 tokens (standard)
|
|
45
|
+
* 2 = < 1500 tokens (detailed)
|
|
46
|
+
* 3 = 1500+ tokens (comprehensive)
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeDescriptors(_intent: string, toolSequence: string[], tokensCost: number): [number, number];
|
|
49
|
+
/**
|
|
50
|
+
* Compute composite fitness for a solution.
|
|
51
|
+
*
|
|
52
|
+
* Weighted formula:
|
|
53
|
+
* 0.4 * quality (evalResult.overall)
|
|
54
|
+
* + 0.3 * reliability (successRate)
|
|
55
|
+
* + 0.3 * efficiency (penalize expensive solutions)
|
|
56
|
+
*/
|
|
57
|
+
export declare function computeFitness(evalResult: {
|
|
58
|
+
overall: number;
|
|
59
|
+
}, successRate: number, tokensCost: number): number;
|
|
60
|
+
/**
|
|
61
|
+
* Attempt to place a solution in the archive.
|
|
62
|
+
* Only replaces an existing cell if the new solution has higher fitness.
|
|
63
|
+
* Returns true if the solution was placed (new cell or fitness improvement).
|
|
64
|
+
*/
|
|
65
|
+
export declare function addToArchive(solution: EliteSolution): boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Get the elite solution for a specific grid cell.
|
|
68
|
+
* Returns null if the cell is empty.
|
|
69
|
+
*/
|
|
70
|
+
export declare function getElite(taskComplexity: number, responseStyle: number): EliteSolution | null;
|
|
71
|
+
/**
|
|
72
|
+
* Suggest the best strategy for a new task.
|
|
73
|
+
* Computes descriptors from the task parameters and returns the elite in that cell.
|
|
74
|
+
*/
|
|
75
|
+
export declare function suggestStrategy(intent: string, toolSequence: string[]): EliteSolution | null;
|
|
76
|
+
/**
|
|
77
|
+
* Get archive statistics: how many cells are filled, average fitness, coverage, and top elites.
|
|
78
|
+
*/
|
|
79
|
+
export declare function getArchiveStats(): ArchiveStats;
|
|
80
|
+
/**
|
|
81
|
+
* ASCII visualization of the archive grid.
|
|
82
|
+
* Filled cells show a fitness indicator, empty cells show a dot.
|
|
83
|
+
*
|
|
84
|
+
* Example output:
|
|
85
|
+
* MAP-Elites Archive (5x4)
|
|
86
|
+
* concise standard detailed comprehensive
|
|
87
|
+
* trivial . ██(0.82) . .
|
|
88
|
+
* simple ██(0.71) . ██(0.90) .
|
|
89
|
+
* moderate . ██(0.65) . ██(0.78)
|
|
90
|
+
* complex . . . .
|
|
91
|
+
* expert . . . ██(0.95)
|
|
92
|
+
*/
|
|
93
|
+
export declare function getArchiveCoverage(): string;
|
|
94
|
+
/**
|
|
95
|
+
* Remove elites older than maxAge milliseconds that have 0 uses.
|
|
96
|
+
* Frees up cells for new exploration.
|
|
97
|
+
*/
|
|
98
|
+
export declare function pruneArchive(maxAge: number): number;
|
|
99
|
+
/**
|
|
100
|
+
* Called after each agent interaction to potentially update the archive.
|
|
101
|
+
* Computes descriptors and fitness, then attempts to place the solution.
|
|
102
|
+
*/
|
|
103
|
+
export declare function learnFromOutcome(intent: string, toolSequence: string[], evalResult: {
|
|
104
|
+
overall: number;
|
|
105
|
+
}, successRate: number, tokensCost: number, retryCount: number): void;
|
|
106
|
+
//# sourceMappingURL=quality-diversity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-diversity.d.ts","sourceRoot":"","sources":["../src/quality-diversity.ts"],"names":[],"mappings":"AAyBA,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAA;QACd,YAAY,EAAE,MAAM,EAAE,CAAA;QACtB,QAAQ,EAAE,MAAM,EAAE,CAAA;KACnB,CAAA;IACD,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,uDAAuD;IACvD,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC7B,QAAQ,EAAE;QACR,UAAU,EAAE,MAAM,CAAA;QAClB,aAAa,EAAE,MAAM,CAAA;QACrB,UAAU,EAAE,MAAM,CAAA;QAClB,OAAO,EAAE,MAAM,CAAA;QACf,IAAI,EAAE,MAAM,CAAA;KACb,CAAA;CACF;AAED,MAAM,WAAW,YAAY;IAC3B,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,uCAAuC;IACvC,QAAQ,EAAE,MAAM,CAAA;IAChB,8CAA8C;IAC9C,SAAS,EAAE,aAAa,EAAE,CAAA;CAC3B;AAuDD;;;GAGG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAYlC;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,EAAE,EACtB,UAAU,EAAE,MAAM,GACjB,CAAC,MAAM,EAAE,MAAM,CAAC,CAkBlB;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAC/B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,GACjB,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,aAAa,GAAG,OAAO,CAe7D;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CACtB,cAAc,EAAE,MAAM,EACtB,aAAa,EAAE,MAAM,GACpB,aAAa,GAAG,IAAI,CAQtB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EAAE,GACrB,aAAa,GAAG,IAAI,CAKtB;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,YAAY,CAqB9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CA6B3C;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAmBnD;AAID;;;GAGG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,EAAE,EACtB,UAAU,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,EAC/B,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,IAAI,CA8BN"}
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
// K:BOT MAP-Elites Quality-Diversity Engine
|
|
2
|
+
//
|
|
3
|
+
// Implements the MAP-Elites algorithm adapted for an AI agent's learning engine.
|
|
4
|
+
// Maintains an archive of high-quality solutions indexed by behavioral descriptors,
|
|
5
|
+
// enabling exploration of diverse solution strategies.
|
|
6
|
+
//
|
|
7
|
+
// Grid dimensions:
|
|
8
|
+
// X: taskComplexity (0-4: trivial / simple / moderate / complex / expert)
|
|
9
|
+
// Y: responseStyle (0-3: concise / standard / detailed / comprehensive)
|
|
10
|
+
// Total cells: 5 x 4 = 20
|
|
11
|
+
//
|
|
12
|
+
// Each cell holds the single highest-fitness solution found for that behavioral region.
|
|
13
|
+
// Solutions are placed or replaced only when a higher-fitness candidate arrives.
|
|
14
|
+
//
|
|
15
|
+
// Persists to ~/.kbot/memory/map-elites.json using debounced writes.
|
|
16
|
+
import { homedir } from 'node:os';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { existsSync, readFileSync, writeFile, mkdirSync } from 'node:fs';
|
|
19
|
+
const LEARN_DIR = join(homedir(), '.kbot', 'memory');
|
|
20
|
+
const ARCHIVE_FILE = join(LEARN_DIR, 'map-elites.json');
|
|
21
|
+
// ═══ GRID CONSTANTS ══════════════════════════════════════════════
|
|
22
|
+
const COMPLEXITY_BINS = 5; // 0..4
|
|
23
|
+
const STYLE_BINS = 4; // 0..3
|
|
24
|
+
const TOTAL_CELLS = COMPLEXITY_BINS * STYLE_BINS;
|
|
25
|
+
// ═══ PERSISTENCE ═════════════════════════════════════════════════
|
|
26
|
+
function ensureDir() {
|
|
27
|
+
if (!existsSync(LEARN_DIR))
|
|
28
|
+
mkdirSync(LEARN_DIR, { recursive: true });
|
|
29
|
+
}
|
|
30
|
+
function loadJSON(path, fallback) {
|
|
31
|
+
ensureDir();
|
|
32
|
+
if (!existsSync(path))
|
|
33
|
+
return fallback;
|
|
34
|
+
try {
|
|
35
|
+
return JSON.parse(readFileSync(path, 'utf-8'));
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
return fallback;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Debounced async file writer — batches rapid writes into one I/O */
|
|
42
|
+
let pendingTimer = null;
|
|
43
|
+
const WRITE_DEBOUNCE_MS = 500;
|
|
44
|
+
function saveArchive() {
|
|
45
|
+
ensureDir();
|
|
46
|
+
if (pendingTimer)
|
|
47
|
+
clearTimeout(pendingTimer);
|
|
48
|
+
pendingTimer = setTimeout(() => {
|
|
49
|
+
pendingTimer = null;
|
|
50
|
+
writeFile(ARCHIVE_FILE, JSON.stringify(archive, null, 2), () => {
|
|
51
|
+
// non-critical — archive data can be regenerated from future interactions
|
|
52
|
+
});
|
|
53
|
+
}, WRITE_DEBOUNCE_MS);
|
|
54
|
+
}
|
|
55
|
+
function emptyGrid() {
|
|
56
|
+
const grid = [];
|
|
57
|
+
for (let c = 0; c < COMPLEXITY_BINS; c++) {
|
|
58
|
+
grid[c] = [];
|
|
59
|
+
for (let s = 0; s < STYLE_BINS; s++) {
|
|
60
|
+
grid[c][s] = null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return grid;
|
|
64
|
+
}
|
|
65
|
+
let archive = emptyGrid();
|
|
66
|
+
// ═══ PUBLIC API ══════════════════════════════════════════════════
|
|
67
|
+
/**
|
|
68
|
+
* Load the archive from disk. Creates an empty grid if the file is missing or corrupt.
|
|
69
|
+
* Call once at startup.
|
|
70
|
+
*/
|
|
71
|
+
export function initArchive() {
|
|
72
|
+
const raw = loadJSON(ARCHIVE_FILE, null);
|
|
73
|
+
if (raw &&
|
|
74
|
+
Array.isArray(raw) &&
|
|
75
|
+
raw.length === COMPLEXITY_BINS &&
|
|
76
|
+
raw.every(row => Array.isArray(row) && row.length === STYLE_BINS)) {
|
|
77
|
+
archive = raw;
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
archive = emptyGrid();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Classify a solution into grid coordinates [taskComplexity, responseStyle].
|
|
85
|
+
*
|
|
86
|
+
* taskComplexity: based on tool count
|
|
87
|
+
* 0 = no tools (trivial)
|
|
88
|
+
* 1 = 1 tool (simple)
|
|
89
|
+
* 2 = 2-3 tools (moderate)
|
|
90
|
+
* 3 = 4-6 tools (complex)
|
|
91
|
+
* 4 = 7+ tools (expert)
|
|
92
|
+
*
|
|
93
|
+
* responseStyle: based on token cost
|
|
94
|
+
* 0 = < 200 tokens (concise)
|
|
95
|
+
* 1 = < 500 tokens (standard)
|
|
96
|
+
* 2 = < 1500 tokens (detailed)
|
|
97
|
+
* 3 = 1500+ tokens (comprehensive)
|
|
98
|
+
*/
|
|
99
|
+
export function computeDescriptors(_intent, toolSequence, tokensCost) {
|
|
100
|
+
// Task complexity from tool count
|
|
101
|
+
const toolCount = toolSequence.length;
|
|
102
|
+
let complexity;
|
|
103
|
+
if (toolCount === 0)
|
|
104
|
+
complexity = 0;
|
|
105
|
+
else if (toolCount === 1)
|
|
106
|
+
complexity = 1;
|
|
107
|
+
else if (toolCount <= 3)
|
|
108
|
+
complexity = 2;
|
|
109
|
+
else if (toolCount <= 6)
|
|
110
|
+
complexity = 3;
|
|
111
|
+
else
|
|
112
|
+
complexity = 4;
|
|
113
|
+
// Response style from token cost
|
|
114
|
+
let style;
|
|
115
|
+
if (tokensCost < 200)
|
|
116
|
+
style = 0;
|
|
117
|
+
else if (tokensCost < 500)
|
|
118
|
+
style = 1;
|
|
119
|
+
else if (tokensCost < 1500)
|
|
120
|
+
style = 2;
|
|
121
|
+
else
|
|
122
|
+
style = 3;
|
|
123
|
+
return [complexity, style];
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Compute composite fitness for a solution.
|
|
127
|
+
*
|
|
128
|
+
* Weighted formula:
|
|
129
|
+
* 0.4 * quality (evalResult.overall)
|
|
130
|
+
* + 0.3 * reliability (successRate)
|
|
131
|
+
* + 0.3 * efficiency (penalize expensive solutions)
|
|
132
|
+
*/
|
|
133
|
+
export function computeFitness(evalResult, successRate, tokensCost) {
|
|
134
|
+
const quality = Math.max(0, Math.min(1, evalResult.overall));
|
|
135
|
+
const reliability = Math.max(0, Math.min(1, successRate));
|
|
136
|
+
const efficiency = 1 - Math.min(tokensCost / 2000, 1);
|
|
137
|
+
return 0.4 * quality + 0.3 * reliability + 0.3 * efficiency;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Attempt to place a solution in the archive.
|
|
141
|
+
* Only replaces an existing cell if the new solution has higher fitness.
|
|
142
|
+
* Returns true if the solution was placed (new cell or fitness improvement).
|
|
143
|
+
*/
|
|
144
|
+
export function addToArchive(solution) {
|
|
145
|
+
const [c, s] = solution.descriptors;
|
|
146
|
+
// Bounds check
|
|
147
|
+
if (c < 0 || c >= COMPLEXITY_BINS || s < 0 || s >= STYLE_BINS)
|
|
148
|
+
return false;
|
|
149
|
+
const current = archive[c][s];
|
|
150
|
+
if (!current || solution.fitness > current.fitness) {
|
|
151
|
+
archive[c][s] = solution;
|
|
152
|
+
saveArchive();
|
|
153
|
+
return true;
|
|
154
|
+
}
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Get the elite solution for a specific grid cell.
|
|
159
|
+
* Returns null if the cell is empty.
|
|
160
|
+
*/
|
|
161
|
+
export function getElite(taskComplexity, responseStyle) {
|
|
162
|
+
if (taskComplexity < 0 || taskComplexity >= COMPLEXITY_BINS ||
|
|
163
|
+
responseStyle < 0 || responseStyle >= STYLE_BINS) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
return archive[taskComplexity][responseStyle] ?? null;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Suggest the best strategy for a new task.
|
|
170
|
+
* Computes descriptors from the task parameters and returns the elite in that cell.
|
|
171
|
+
*/
|
|
172
|
+
export function suggestStrategy(intent, toolSequence) {
|
|
173
|
+
// Estimate token cost from tool sequence length (heuristic: ~200 tokens per tool call)
|
|
174
|
+
const estimatedTokens = Math.max(100, toolSequence.length * 200);
|
|
175
|
+
const [c, s] = computeDescriptors(intent, toolSequence, estimatedTokens);
|
|
176
|
+
return getElite(c, s);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Get archive statistics: how many cells are filled, average fitness, coverage, and top elites.
|
|
180
|
+
*/
|
|
181
|
+
export function getArchiveStats() {
|
|
182
|
+
const elites = [];
|
|
183
|
+
for (let c = 0; c < COMPLEXITY_BINS; c++) {
|
|
184
|
+
for (let s = 0; s < STYLE_BINS; s++) {
|
|
185
|
+
const cell = archive[c][s];
|
|
186
|
+
if (cell)
|
|
187
|
+
elites.push(cell);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const totalElites = elites.length;
|
|
191
|
+
const avgFitness = totalElites > 0
|
|
192
|
+
? elites.reduce((sum, e) => sum + e.fitness, 0) / totalElites
|
|
193
|
+
: 0;
|
|
194
|
+
const coverage = totalElites / TOTAL_CELLS;
|
|
195
|
+
const topElites = [...elites]
|
|
196
|
+
.sort((a, b) => b.fitness - a.fitness)
|
|
197
|
+
.slice(0, 5);
|
|
198
|
+
return { totalElites, avgFitness, coverage, topElites };
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* ASCII visualization of the archive grid.
|
|
202
|
+
* Filled cells show a fitness indicator, empty cells show a dot.
|
|
203
|
+
*
|
|
204
|
+
* Example output:
|
|
205
|
+
* MAP-Elites Archive (5x4)
|
|
206
|
+
* concise standard detailed comprehensive
|
|
207
|
+
* trivial . ██(0.82) . .
|
|
208
|
+
* simple ██(0.71) . ██(0.90) .
|
|
209
|
+
* moderate . ██(0.65) . ██(0.78)
|
|
210
|
+
* complex . . . .
|
|
211
|
+
* expert . . . ██(0.95)
|
|
212
|
+
*/
|
|
213
|
+
export function getArchiveCoverage() {
|
|
214
|
+
const complexityLabels = ['trivial ', 'simple ', 'moderate ', 'complex ', 'expert '];
|
|
215
|
+
const styleLabels = ['concise', 'standard', 'detailed', 'comprehensive'];
|
|
216
|
+
const lines = [];
|
|
217
|
+
lines.push('MAP-Elites Archive (5x4)');
|
|
218
|
+
lines.push(` ${styleLabels.map(l => l.padEnd(14)).join('')}`);
|
|
219
|
+
for (let c = 0; c < COMPLEXITY_BINS; c++) {
|
|
220
|
+
const cells = [];
|
|
221
|
+
for (let s = 0; s < STYLE_BINS; s++) {
|
|
222
|
+
const cell = archive[c][s];
|
|
223
|
+
if (cell) {
|
|
224
|
+
cells.push(`██(${cell.fitness.toFixed(2)})`.padEnd(14));
|
|
225
|
+
}
|
|
226
|
+
else {
|
|
227
|
+
cells.push('.'.padEnd(14));
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
lines.push(` ${complexityLabels[c]} ${cells.join('')}`);
|
|
231
|
+
}
|
|
232
|
+
const stats = getArchiveStats();
|
|
233
|
+
lines.push('');
|
|
234
|
+
lines.push(`Coverage: ${stats.totalElites}/${TOTAL_CELLS} cells (${(stats.coverage * 100).toFixed(0)}%)`);
|
|
235
|
+
if (stats.totalElites > 0) {
|
|
236
|
+
lines.push(`Avg fitness: ${stats.avgFitness.toFixed(3)}`);
|
|
237
|
+
}
|
|
238
|
+
return lines.join('\n');
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* Remove elites older than maxAge milliseconds that have 0 uses.
|
|
242
|
+
* Frees up cells for new exploration.
|
|
243
|
+
*/
|
|
244
|
+
export function pruneArchive(maxAge) {
|
|
245
|
+
const cutoff = Date.now() - maxAge;
|
|
246
|
+
let pruned = 0;
|
|
247
|
+
for (let c = 0; c < COMPLEXITY_BINS; c++) {
|
|
248
|
+
for (let s = 0; s < STYLE_BINS; s++) {
|
|
249
|
+
const cell = archive[c][s];
|
|
250
|
+
if (cell && cell.metadata.uses === 0) {
|
|
251
|
+
const created = new Date(cell.metadata.created).getTime();
|
|
252
|
+
if (created < cutoff) {
|
|
253
|
+
archive[c][s] = null;
|
|
254
|
+
pruned++;
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
if (pruned > 0)
|
|
260
|
+
saveArchive();
|
|
261
|
+
return pruned;
|
|
262
|
+
}
|
|
263
|
+
// ═══ INTEGRATION HOOK ════════════════════════════════════════════
|
|
264
|
+
/**
|
|
265
|
+
* Called after each agent interaction to potentially update the archive.
|
|
266
|
+
* Computes descriptors and fitness, then attempts to place the solution.
|
|
267
|
+
*/
|
|
268
|
+
export function learnFromOutcome(intent, toolSequence, evalResult, successRate, tokensCost, retryCount) {
|
|
269
|
+
const descriptors = computeDescriptors(intent, toolSequence, tokensCost);
|
|
270
|
+
const fitness = computeFitness(evalResult, successRate, tokensCost);
|
|
271
|
+
// Extract keywords from intent (simple extraction — mirrors learning.ts approach)
|
|
272
|
+
const keywords = intent
|
|
273
|
+
.toLowerCase()
|
|
274
|
+
.replace(/[^a-z0-9\s]/g, ' ')
|
|
275
|
+
.split(/\s+/)
|
|
276
|
+
.filter(w => w.length > 2)
|
|
277
|
+
.slice(0, 10);
|
|
278
|
+
const solution = {
|
|
279
|
+
pattern: {
|
|
280
|
+
intent,
|
|
281
|
+
toolSequence,
|
|
282
|
+
keywords,
|
|
283
|
+
},
|
|
284
|
+
fitness,
|
|
285
|
+
descriptors,
|
|
286
|
+
metadata: {
|
|
287
|
+
tokensCost,
|
|
288
|
+
toolCallCount: toolSequence.length,
|
|
289
|
+
retryCount,
|
|
290
|
+
created: new Date().toISOString(),
|
|
291
|
+
uses: 0,
|
|
292
|
+
},
|
|
293
|
+
};
|
|
294
|
+
addToArchive(solution);
|
|
295
|
+
}
|
|
296
|
+
//# sourceMappingURL=quality-diversity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quality-diversity.js","sourceRoot":"","sources":["../src/quality-diversity.ts"],"names":[],"mappings":"AAAA,4CAA4C;AAC5C,EAAE;AACF,iFAAiF;AACjF,oFAAoF;AACpF,uDAAuD;AACvD,EAAE;AACF,mBAAmB;AACnB,6EAA6E;AAC7E,4EAA4E;AAC5E,4BAA4B;AAC5B,EAAE;AACF,wFAAwF;AACxF,iFAAiF;AACjF,EAAE;AACF,qEAAqE;AAErE,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAExE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAA;AACpD,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAA;AAgCvD,oEAAoE;AAEpE,MAAM,eAAe,GAAG,CAAC,CAAA,CAAE,OAAO;AAClC,MAAM,UAAU,GAAG,CAAC,CAAA,CAAO,OAAO;AAClC,MAAM,WAAW,GAAG,eAAe,GAAG,UAAU,CAAA;AAEhD,oEAAoE;AAEpE,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AACvE,CAAC;AAED,SAAS,QAAQ,CAAI,IAAY,EAAE,QAAW;IAC5C,SAAS,EAAE,CAAA;IACX,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,QAAQ,CAAA;IACtC,IAAI,CAAC;QAAC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAA;IAAC,CAAC;IAAC,MAAM,CAAC;QAAC,OAAO,QAAQ,CAAA;IAAC,CAAC;AAClF,CAAC;AAED,sEAAsE;AACtE,IAAI,YAAY,GAA0B,IAAI,CAAA;AAC9C,MAAM,iBAAiB,GAAG,GAAG,CAAA;AAE7B,SAAS,WAAW;IAClB,SAAS,EAAE,CAAA;IACX,IAAI,YAAY;QAAE,YAAY,CAAC,YAAY,CAAC,CAAA;IAC5C,YAAY,GAAG,UAAU,CAAC,GAAG,EAAE;QAC7B,YAAY,GAAG,IAAI,CAAA;QACnB,SAAS,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE;YAC7D,0EAA0E;QAC5E,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,iBAAiB,CAAC,CAAA;AACvB,CAAC;AAOD,SAAS,SAAS;IAChB,MAAM,IAAI,GAAgB,EAAE,CAAA;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,IAAI,CAAC,CAAC,CAAC,GAAG,EAAE,CAAA;QACZ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;QACnB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,IAAI,OAAO,GAAgB,SAAS,EAAE,CAAA;AAEtC,oEAAoE;AAEpE;;;GAGG;AACH,MAAM,UAAU,WAAW;IACzB,MAAM,GAAG,GAAG,QAAQ,CAAqB,YAAY,EAAE,IAAI,CAAC,CAAA;IAC5D,IACE,GAAG;QACH,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;QAClB,GAAG,CAAC,MAAM,KAAK,eAAe;QAC9B,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,UAAU,CAAC,EACjE,CAAC;QACD,OAAO,GAAG,GAAG,CAAA;IACf,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,SAAS,EAAE,CAAA;IACvB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAChC,OAAe,EACf,YAAsB,EACtB,UAAkB;IAElB,kCAAkC;IAClC,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAA;IACrC,IAAI,UAAkB,CAAA;IACtB,IAAI,SAAS,KAAK,CAAC;QAAE,UAAU,GAAG,CAAC,CAAA;SAC9B,IAAI,SAAS,KAAK,CAAC;QAAE,UAAU,GAAG,CAAC,CAAA;SACnC,IAAI,SAAS,IAAI,CAAC;QAAE,UAAU,GAAG,CAAC,CAAA;SAClC,IAAI,SAAS,IAAI,CAAC;QAAE,UAAU,GAAG,CAAC,CAAA;;QAClC,UAAU,GAAG,CAAC,CAAA;IAEnB,iCAAiC;IACjC,IAAI,KAAa,CAAA;IACjB,IAAI,UAAU,GAAG,GAAG;QAAE,KAAK,GAAG,CAAC,CAAA;SAC1B,IAAI,UAAU,GAAG,GAAG;QAAE,KAAK,GAAG,CAAC,CAAA;SAC/B,IAAI,UAAU,GAAG,IAAI;QAAE,KAAK,GAAG,CAAC,CAAA;;QAChC,KAAK,GAAG,CAAC,CAAA;IAEd,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC,CAAA;AAC5B,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAC5B,UAA+B,EAC/B,WAAmB,EACnB,UAAkB;IAElB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,CAAC,CAAA;IAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,WAAW,CAAC,CAAC,CAAA;IACzD,MAAM,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,GAAG,IAAI,EAAE,CAAC,CAAC,CAAA;IAErD,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,GAAG,WAAW,GAAG,GAAG,GAAG,UAAU,CAAA;AAC7D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAuB;IAClD,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAA;IAEnC,eAAe;IACf,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,eAAe,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,UAAU;QAAE,OAAO,KAAK,CAAA;IAE3E,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IAE7B,IAAI,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACnD,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAA;QACxB,WAAW,EAAE,CAAA;QACb,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CACtB,cAAsB,EACtB,aAAqB;IAErB,IACE,cAAc,GAAG,CAAC,IAAI,cAAc,IAAI,eAAe;QACvD,aAAa,GAAG,CAAC,IAAI,aAAa,IAAI,UAAU,EAChD,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,OAAO,CAAC,cAAc,CAAC,CAAC,aAAa,CAAC,IAAI,IAAI,CAAA;AACvD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAc,EACd,YAAsB;IAEtB,uFAAuF;IACvF,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,MAAM,GAAG,GAAG,CAAC,CAAA;IAChE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,eAAe,CAAC,CAAA;IACxE,OAAO,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe;IAC7B,MAAM,MAAM,GAAoB,EAAE,CAAA;IAElC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1B,IAAI,IAAI;gBAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAA;IACjC,MAAM,UAAU,GAAG,WAAW,GAAG,CAAC;QAChC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,WAAW;QAC7D,CAAC,CAAC,CAAC,CAAA;IACL,MAAM,QAAQ,GAAG,WAAW,GAAG,WAAW,CAAA;IAE1C,MAAM,SAAS,GAAG,CAAC,GAAG,MAAM,CAAC;SAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;SACrC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAEd,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAA;AACzD,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,EAAE,WAAW,CAAC,CAAA;IAC1F,MAAM,WAAW,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,CAAC,CAAA;IAExE,MAAM,KAAK,GAAa,EAAE,CAAA;IAC1B,KAAK,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAA;IACtC,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAEzE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,KAAK,GAAa,EAAE,CAAA;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1B,IAAI,IAAI,EAAE,CAAC;gBACT,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;YACzD,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;YAC5B,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAK,gBAAgB,CAAC,CAAC,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,MAAM,KAAK,GAAG,eAAe,EAAE,CAAA;IAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;IACd,KAAK,CAAC,IAAI,CAAC,aAAa,KAAK,CAAC,WAAW,IAAI,WAAW,WAAW,CAAC,KAAK,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;IACzG,IAAI,KAAK,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;QAC1B,KAAK,CAAC,IAAI,CAAC,gBAAgB,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;IAC3D,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACzB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,MAAc;IACzC,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAA;IAClC,IAAI,MAAM,GAAG,CAAC,CAAA;IAEd,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;YAC1B,IAAI,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;gBACrC,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,OAAO,EAAE,CAAA;gBACzD,IAAI,OAAO,GAAG,MAAM,EAAE,CAAC;oBACrB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;oBACpB,MAAM,EAAE,CAAA;gBACV,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,GAAG,CAAC;QAAE,WAAW,EAAE,CAAA;IAC7B,OAAO,MAAM,CAAA;AACf,CAAC;AAED,oEAAoE;AAEpE;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAAc,EACd,YAAsB,EACtB,UAA+B,EAC/B,WAAmB,EACnB,UAAkB,EAClB,UAAkB;IAElB,MAAM,WAAW,GAAG,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,UAAU,CAAC,CAAA;IACxE,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,EAAE,WAAW,EAAE,UAAU,CAAC,CAAA;IAEnE,kFAAkF;IAClF,MAAM,QAAQ,GAAG,MAAM;SACpB,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;SACzB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;IAEf,MAAM,QAAQ,GAAkB;QAC9B,OAAO,EAAE;YACP,MAAM;YACN,YAAY;YACZ,QAAQ;SACT;QACD,OAAO;QACP,WAAW;QACX,QAAQ,EAAE;YACR,UAAU;YACV,aAAa,EAAE,YAAY,CAAC,MAAM;YAClC,UAAU;YACV,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACjC,IAAI,EAAE,CAAC;SACR;KACF,CAAA;IAED,YAAY,CAAC,QAAQ,CAAC,CAAA;AACxB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comfyui-plugin.d.ts","sourceRoot":"","sources":["../../src/tools/comfyui-plugin.ts"],"names":[],"mappings":"AA+MA,wBAAgB,oBAAoB,IAAI,IAAI,CAuW3C"}
|