@dungle-scrubs/synapse 0.1.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/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/classifier.d.ts +34 -0
- package/dist/classifier.d.ts.map +1 -0
- package/dist/classifier.js +151 -0
- package/dist/classifier.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +15 -0
- package/dist/index.js.map +1 -0
- package/dist/matrix.d.ts +41 -0
- package/dist/matrix.d.ts.map +1 -0
- package/dist/matrix.js +97 -0
- package/dist/matrix.js.map +1 -0
- package/dist/resolver.d.ts +39 -0
- package/dist/resolver.d.ts.map +1 -0
- package/dist/resolver.js +221 -0
- package/dist/resolver.js.map +1 -0
- package/dist/selector.d.ts +27 -0
- package/dist/selector.d.ts.map +1 -0
- package/dist/selector.js +126 -0
- package/dist/selector.js.map +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +37 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.1.0](https://github.com/dungle-scrubs/synapse/releases/tag/v0.1.0) (2026-02-17)
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **matrix:** `MODEL_MATRIX` capability ratings for 30+ models across code, vision, text
|
|
13
|
+
- **matrix:** `getModelRatings` with longest-prefix matching and provider stripping
|
|
14
|
+
- **matrix:** `modelSupportsTask` for capability/complexity filtering
|
|
15
|
+
- **resolver:** `resolveModelFuzzy` with 6-tier resolution cascade (exact → case-insensitive →
|
|
16
|
+
normalized → provider/id → token overlap → substring)
|
|
17
|
+
- **resolver:** `resolveModelCandidates` for scoped routing (returns all tied matches)
|
|
18
|
+
- **resolver:** `listAvailableModels` for error messages
|
|
19
|
+
- **classifier:** `classifyTask` using in-process `completeSimple` instead of CLI subprocess
|
|
20
|
+
- **classifier:** `findCheapestModel` by effective cost
|
|
21
|
+
- **selector:** `selectModels` with eco/balanced/premium cost preference sorting
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Kevin Frilot
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# synapse
|
|
2
|
+
|
|
3
|
+
Model capability matrix, fuzzy resolver, task classifier, and selection
|
|
4
|
+
algorithm for [pi-ai](https://github.com/nicobrinkkemper/pi-ai) models.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm install @dungle-scrubs/synapse
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
Requires `@mariozechner/pi-ai` as a peer dependency.
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
import {
|
|
18
|
+
classifyTask,
|
|
19
|
+
resolveModelFuzzy,
|
|
20
|
+
selectModels,
|
|
21
|
+
MODEL_MATRIX,
|
|
22
|
+
} from "synapse";
|
|
23
|
+
|
|
24
|
+
// Fuzzy resolve a human-friendly model name
|
|
25
|
+
const model = resolveModelFuzzy("opus");
|
|
26
|
+
// → { provider: "anthropic", id: "claude-opus-4-6", displayName: "anthropic/claude-opus-4-6" }
|
|
27
|
+
|
|
28
|
+
// Classify a task's type and complexity
|
|
29
|
+
const classification = await classifyTask("Refactor the auth module", "code");
|
|
30
|
+
// → { type: "code", complexity: 3, reasoning: "..." }
|
|
31
|
+
|
|
32
|
+
// Select ranked models for the task
|
|
33
|
+
const ranked = selectModels(classification, "balanced");
|
|
34
|
+
// → [{ provider: "anthropic", id: "claude-sonnet-4-5-...", ... }, ...]
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## API
|
|
38
|
+
|
|
39
|
+
### Matrix
|
|
40
|
+
|
|
41
|
+
- `MODEL_MATRIX` — Capability ratings for known models
|
|
42
|
+
- `getModelRatings(modelId)` — Look up ratings by model ID (prefix matching)
|
|
43
|
+
- `modelSupportsTask(modelId, type, minRating)` — Check if a model supports a task type
|
|
44
|
+
|
|
45
|
+
### Resolver
|
|
46
|
+
|
|
47
|
+
- `resolveModelFuzzy(query)` — Fuzzy resolve a name to a single model
|
|
48
|
+
- `resolveModelCandidates(query)` — Resolve to all tied candidates
|
|
49
|
+
- `listAvailableModels()` — List all registered models
|
|
50
|
+
|
|
51
|
+
### Classifier
|
|
52
|
+
|
|
53
|
+
- `classifyTask(task, primaryType, agentRole?)` — Classify task type and complexity
|
|
54
|
+
- `findCheapestModel()` — Find the cheapest available model
|
|
55
|
+
|
|
56
|
+
### Selector
|
|
57
|
+
|
|
58
|
+
- `selectModels(classification, costPreference, pool?)` — Rank models for a classified task
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task classification via cheap LLM call.
|
|
3
|
+
*
|
|
4
|
+
* Determines a task's type (code/vision/text) and complexity (1-5)
|
|
5
|
+
* using the cheapest available model from the registry. Uses pi-ai's
|
|
6
|
+
* `completeSimple` for in-process inference — no CLI subprocess.
|
|
7
|
+
*/
|
|
8
|
+
import type { ClassificationResult, TaskType } from "./types.js";
|
|
9
|
+
/** Cheapest model info with the data needed to call completeSimple. */
|
|
10
|
+
interface CheapestModelInfo {
|
|
11
|
+
provider: string;
|
|
12
|
+
id: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Finds the cheapest available model by effective cost.
|
|
16
|
+
*
|
|
17
|
+
* @returns Provider and ID of the cheapest model, or undefined if no models available
|
|
18
|
+
*/
|
|
19
|
+
export declare function findCheapestModel(): CheapestModelInfo | undefined;
|
|
20
|
+
/**
|
|
21
|
+
* Classify a task's type and complexity using the cheapest available LLM.
|
|
22
|
+
*
|
|
23
|
+
* Picks the cheapest model from the registry by (input + output) / 2 cost,
|
|
24
|
+
* sends a structured classification prompt via `completeSimple`, and parses
|
|
25
|
+
* the JSON response. Falls back to primaryType + complexity 3 on any failure.
|
|
26
|
+
*
|
|
27
|
+
* @param task - The task description to classify
|
|
28
|
+
* @param primaryType - Agent's default type (used when ambiguous or on failure)
|
|
29
|
+
* @param agentRole - Optional agent role for additional context
|
|
30
|
+
* @returns Classification result with type, complexity, and reasoning
|
|
31
|
+
*/
|
|
32
|
+
export declare function classifyTask(task: string, primaryType: TaskType, agentRole?: string): Promise<ClassificationResult>;
|
|
33
|
+
export {};
|
|
34
|
+
//# sourceMappingURL=classifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifier.d.ts","sourceRoot":"","sources":["../src/classifier.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAkB,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQjF,uEAAuE;AACvE,UAAU,iBAAiB;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;CACX;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,IAAI,iBAAiB,GAAG,SAAS,CAejE;AA0ED;;;;;;;;;;;GAWG;AACH,wBAAsB,YAAY,CACjC,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,QAAQ,EACrB,SAAS,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,oBAAoB,CAAC,CAwC/B"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task classification via cheap LLM call.
|
|
3
|
+
*
|
|
4
|
+
* Determines a task's type (code/vision/text) and complexity (1-5)
|
|
5
|
+
* using the cheapest available model from the registry. Uses pi-ai's
|
|
6
|
+
* `completeSimple` for in-process inference — no CLI subprocess.
|
|
7
|
+
*/
|
|
8
|
+
import { completeSimple, getModel, getModels, getProviders } from "@mariozechner/pi-ai";
|
|
9
|
+
/** Valid task types for validation. */
|
|
10
|
+
const VALID_TYPES = new Set(["code", "vision", "text"]);
|
|
11
|
+
/** Valid complexity values for validation. */
|
|
12
|
+
const VALID_COMPLEXITIES = new Set([1, 2, 3, 4, 5]);
|
|
13
|
+
/**
|
|
14
|
+
* Finds the cheapest available model by effective cost.
|
|
15
|
+
*
|
|
16
|
+
* @returns Provider and ID of the cheapest model, or undefined if no models available
|
|
17
|
+
*/
|
|
18
|
+
export function findCheapestModel() {
|
|
19
|
+
let cheapest;
|
|
20
|
+
let cheapestCost = Number.POSITIVE_INFINITY;
|
|
21
|
+
for (const provider of getProviders()) {
|
|
22
|
+
for (const m of getModels(provider)) {
|
|
23
|
+
const effective = (m.cost.input + m.cost.output) / 2;
|
|
24
|
+
if (effective < cheapestCost) {
|
|
25
|
+
cheapestCost = effective;
|
|
26
|
+
cheapest = { provider: m.provider, id: m.id };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return cheapest;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Builds the classification prompt for the LLM.
|
|
34
|
+
*
|
|
35
|
+
* @param task - Task description
|
|
36
|
+
* @param primaryType - Agent's default type
|
|
37
|
+
* @param agentRole - Optional agent role context
|
|
38
|
+
* @returns Formatted prompt string
|
|
39
|
+
*/
|
|
40
|
+
function buildPrompt(task, primaryType, agentRole) {
|
|
41
|
+
const roleLine = agentRole ? `\nAgent role: ${agentRole}` : "";
|
|
42
|
+
return `Classify this task on two axes.
|
|
43
|
+
|
|
44
|
+
TYPE — what LLM capability is needed:
|
|
45
|
+
- code: writing, refactoring, debugging, reviewing code
|
|
46
|
+
- vision: analyzing images, screenshots, UI mockups
|
|
47
|
+
- text: writing docs, planning, general reasoning, research
|
|
48
|
+
|
|
49
|
+
COMPLEXITY (1-5):
|
|
50
|
+
1 = Trivial (rename file, simple lookup, basic edit)
|
|
51
|
+
2 = Simple (single-file change, add test, fix typo)
|
|
52
|
+
3 = Moderate (multi-file change, implement function, debug)
|
|
53
|
+
4 = Complex (design + implement feature, architecture)
|
|
54
|
+
5 = Expert (cross-system design, security audit, optimization)
|
|
55
|
+
|
|
56
|
+
Default type for this agent: ${primaryType}
|
|
57
|
+
Use the default unless the task clearly requires a different type.
|
|
58
|
+
|
|
59
|
+
Task: ${task}${roleLine}
|
|
60
|
+
|
|
61
|
+
Respond with JSON only: {"type": "<type>", "complexity": <1-5>, "reasoning": "<one line>"}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Extracts and parses JSON from LLM output that may contain markdown fences.
|
|
65
|
+
*
|
|
66
|
+
* @param raw - Raw LLM output string
|
|
67
|
+
* @returns Parsed object, or undefined on failure
|
|
68
|
+
*/
|
|
69
|
+
function extractJson(raw) {
|
|
70
|
+
// Strip markdown code fences if present
|
|
71
|
+
const fenceMatch = raw.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
|
|
72
|
+
const jsonStr = fenceMatch ? fenceMatch[1] : raw;
|
|
73
|
+
try {
|
|
74
|
+
return JSON.parse(jsonStr.trim());
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Try to find a JSON object anywhere in the string
|
|
78
|
+
const objectMatch = jsonStr.match(/\{[\s\S]*\}/);
|
|
79
|
+
if (objectMatch) {
|
|
80
|
+
try {
|
|
81
|
+
return JSON.parse(objectMatch[0]);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
return undefined;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
/**
|
|
91
|
+
* Extracts text content from an AssistantMessage's content array.
|
|
92
|
+
*
|
|
93
|
+
* @param content - Array of content blocks from pi-ai response
|
|
94
|
+
* @returns Concatenated text content
|
|
95
|
+
*/
|
|
96
|
+
function extractText(content) {
|
|
97
|
+
return content
|
|
98
|
+
.filter((c) => c.type === "text" && c.text)
|
|
99
|
+
.map((c) => c.text)
|
|
100
|
+
.join("");
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Classify a task's type and complexity using the cheapest available LLM.
|
|
104
|
+
*
|
|
105
|
+
* Picks the cheapest model from the registry by (input + output) / 2 cost,
|
|
106
|
+
* sends a structured classification prompt via `completeSimple`, and parses
|
|
107
|
+
* the JSON response. Falls back to primaryType + complexity 3 on any failure.
|
|
108
|
+
*
|
|
109
|
+
* @param task - The task description to classify
|
|
110
|
+
* @param primaryType - Agent's default type (used when ambiguous or on failure)
|
|
111
|
+
* @param agentRole - Optional agent role for additional context
|
|
112
|
+
* @returns Classification result with type, complexity, and reasoning
|
|
113
|
+
*/
|
|
114
|
+
export async function classifyTask(task, primaryType, agentRole) {
|
|
115
|
+
const fallback = {
|
|
116
|
+
type: primaryType,
|
|
117
|
+
complexity: 3,
|
|
118
|
+
reasoning: "fallback: classification unavailable",
|
|
119
|
+
};
|
|
120
|
+
const cheapest = findCheapestModel();
|
|
121
|
+
if (!cheapest)
|
|
122
|
+
return fallback;
|
|
123
|
+
const prompt = buildPrompt(task, primaryType, agentRole);
|
|
124
|
+
try {
|
|
125
|
+
const model = getModel(cheapest.provider, cheapest.id);
|
|
126
|
+
const response = await completeSimple(model, {
|
|
127
|
+
messages: [
|
|
128
|
+
{ role: "user", content: [{ type: "text", text: prompt }], timestamp: Date.now() },
|
|
129
|
+
],
|
|
130
|
+
});
|
|
131
|
+
const output = extractText(response.content);
|
|
132
|
+
const parsed = extractJson(output);
|
|
133
|
+
if (!parsed)
|
|
134
|
+
return fallback;
|
|
135
|
+
const type = String(parsed.type);
|
|
136
|
+
const complexity = Number(parsed.complexity);
|
|
137
|
+
const reasoning = String(parsed.reasoning ?? "");
|
|
138
|
+
if (!VALID_TYPES.has(type) || !VALID_COMPLEXITIES.has(complexity)) {
|
|
139
|
+
return fallback;
|
|
140
|
+
}
|
|
141
|
+
return {
|
|
142
|
+
type: type,
|
|
143
|
+
complexity: complexity,
|
|
144
|
+
reasoning,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
catch {
|
|
148
|
+
return fallback;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=classifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"classifier.js","sourceRoot":"","sources":["../src/classifier.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* synapse — Model capability matrix, fuzzy resolver, task classifier,
|
|
3
|
+
* and selection algorithm for pi-ai models.
|
|
4
|
+
*
|
|
5
|
+
* @module synapse
|
|
6
|
+
*/
|
|
7
|
+
export type { CandidateModel, ClassificationResult, CostPreference, ModelRatings, ModelSource, ResolvedModel, TaskComplexity, TaskType, } from "./types.js";
|
|
8
|
+
export { getModelRatings, MODEL_MATRIX, modelSupportsTask } from "./matrix.js";
|
|
9
|
+
export { listAvailableModels, resolveModelCandidates, resolveModelFuzzy } from "./resolver.js";
|
|
10
|
+
export { classifyTask, findCheapestModel } from "./classifier.js";
|
|
11
|
+
export { selectModels } from "./selector.js";
|
|
12
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EACX,cAAc,EACd,oBAAoB,EACpB,cAAc,EACd,YAAY,EACZ,WAAW,EACX,aAAa,EACb,cAAc,EACd,QAAQ,GACR,MAAM,YAAY,CAAC;AAGpB,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAG/E,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAG/F,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAGlE,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* synapse — Model capability matrix, fuzzy resolver, task classifier,
|
|
3
|
+
* and selection algorithm for pi-ai models.
|
|
4
|
+
*
|
|
5
|
+
* @module synapse
|
|
6
|
+
*/
|
|
7
|
+
// Matrix
|
|
8
|
+
export { getModelRatings, MODEL_MATRIX, modelSupportsTask } from "./matrix.js";
|
|
9
|
+
// Resolver
|
|
10
|
+
export { listAvailableModels, resolveModelCandidates, resolveModelFuzzy } from "./resolver.js";
|
|
11
|
+
// Classifier
|
|
12
|
+
export { classifyTask, findCheapestModel } from "./classifier.js";
|
|
13
|
+
// Selector
|
|
14
|
+
export { selectModels } from "./selector.js";
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAcH,SAAS;AACT,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/E,WAAW;AACX,OAAO,EAAE,mBAAmB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAE/F,aAAa;AACb,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAElE,WAAW;AACX,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/matrix.d.ts
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-dimensional model capability matrix.
|
|
3
|
+
*
|
|
4
|
+
* Maps model ID prefixes to per-task-type capability ratings.
|
|
5
|
+
* Source: Arena leaderboards (arena.ai/leaderboard/*).
|
|
6
|
+
*/
|
|
7
|
+
import type { ModelRatings, TaskType } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Multi-dimensional model capability matrix.
|
|
10
|
+
*
|
|
11
|
+
* Source: Arena leaderboards (arena.ai/leaderboard/*), Feb 2026.
|
|
12
|
+
*
|
|
13
|
+
* ELO → tier mapping per leaderboard (each has different ELO scale):
|
|
14
|
+
* Code: 5=≥1440 4=1370-1439 3=1280-1369 2=1180-1279 1=<1180
|
|
15
|
+
* Vision: 5=≥1250 4=1200-1249 3=1150-1199 2=1100-1149 1=<1100
|
|
16
|
+
* Text: 5=≥1460 4=1410-1459 3=1370-1409 2=1320-1369 1=<1320
|
|
17
|
+
*
|
|
18
|
+
* Ratings use base model scores — no thinking, default effort.
|
|
19
|
+
*/
|
|
20
|
+
export declare const MODEL_MATRIX: Record<string, ModelRatings>;
|
|
21
|
+
/**
|
|
22
|
+
* Get capability ratings for a model by its ID.
|
|
23
|
+
*
|
|
24
|
+
* Uses longest-prefix matching: strips provider prefix (e.g. "anthropic/"),
|
|
25
|
+
* then finds the longest key in MODEL_MATRIX that the model ID starts with.
|
|
26
|
+
* E.g., "claude-sonnet-4-5-20250929" matches "claude-sonnet-4-5".
|
|
27
|
+
*
|
|
28
|
+
* @param modelId - Full model ID (may include date suffixes)
|
|
29
|
+
* @returns Capability ratings, or undefined if model not in matrix
|
|
30
|
+
*/
|
|
31
|
+
export declare function getModelRatings(modelId: string): ModelRatings | undefined;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a model supports a given task type at the required complexity level.
|
|
34
|
+
*
|
|
35
|
+
* @param modelId - Full model ID
|
|
36
|
+
* @param type - Required task type
|
|
37
|
+
* @param minRating - Minimum required rating (1-5)
|
|
38
|
+
* @returns true if the model has a rating for the type >= minRating
|
|
39
|
+
*/
|
|
40
|
+
export declare function modelSupportsTask(modelId: string, type: TaskType, minRating: number): boolean;
|
|
41
|
+
//# sourceMappingURL=matrix.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.d.ts","sourceRoot":"","sources":["../src/matrix.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEzD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA6CrD,CAAC;AAKF;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,GAAG,SAAS,CAIzE;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAK7F"}
|
package/dist/matrix.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-dimensional model capability matrix.
|
|
3
|
+
*
|
|
4
|
+
* Maps model ID prefixes to per-task-type capability ratings.
|
|
5
|
+
* Source: Arena leaderboards (arena.ai/leaderboard/*).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Multi-dimensional model capability matrix.
|
|
9
|
+
*
|
|
10
|
+
* Source: Arena leaderboards (arena.ai/leaderboard/*), Feb 2026.
|
|
11
|
+
*
|
|
12
|
+
* ELO → tier mapping per leaderboard (each has different ELO scale):
|
|
13
|
+
* Code: 5=≥1440 4=1370-1439 3=1280-1369 2=1180-1279 1=<1180
|
|
14
|
+
* Vision: 5=≥1250 4=1200-1249 3=1150-1199 2=1100-1149 1=<1100
|
|
15
|
+
* Text: 5=≥1460 4=1410-1459 3=1370-1409 2=1320-1369 1=<1320
|
|
16
|
+
*
|
|
17
|
+
* Ratings use base model scores — no thinking, default effort.
|
|
18
|
+
*/
|
|
19
|
+
export const MODEL_MATRIX = {
|
|
20
|
+
// Anthropic
|
|
21
|
+
"claude-opus-4-6": { code: 5, vision: 3, text: 5 },
|
|
22
|
+
"claude-opus-4-5": { code: 5, vision: 3, text: 5 },
|
|
23
|
+
"claude-opus-4-1": { code: 4, vision: 3, text: 4 },
|
|
24
|
+
"claude-sonnet-4-5": { code: 4, vision: 3, text: 4 },
|
|
25
|
+
"claude-haiku-4-5": { code: 3, vision: 2, text: 3 },
|
|
26
|
+
// OpenAI
|
|
27
|
+
"gpt-5.2": { code: 4, vision: 4, text: 4 },
|
|
28
|
+
"gpt-5": { code: 4, vision: 4, text: 4 },
|
|
29
|
+
"gpt-5.1": { code: 3, vision: 4, text: 4 },
|
|
30
|
+
"gpt-5.3-codex": { code: 4, text: 4 },
|
|
31
|
+
"gpt-5.3-codex-spark": { code: 2, text: 2 },
|
|
32
|
+
"gpt-5.2-codex": { code: 3, text: 3 },
|
|
33
|
+
"gpt-5.1-codex-max": { code: 4, text: 4 },
|
|
34
|
+
"gpt-5.1-codex": { code: 3, text: 3 },
|
|
35
|
+
"gpt-5.1-codex-mini": { code: 2, text: 2 },
|
|
36
|
+
// Google
|
|
37
|
+
"gemini-3-pro": { code: 5, vision: 5, text: 5 },
|
|
38
|
+
"gemini-3-flash": { code: 5, vision: 5, text: 5 },
|
|
39
|
+
"gemini-2.5-pro": { code: 2, vision: 4, text: 4 },
|
|
40
|
+
"gemini-2.5-flash": { vision: 4, text: 4 },
|
|
41
|
+
// Z.ai (Zhipu)
|
|
42
|
+
"glm-5": { code: 5, text: 5 },
|
|
43
|
+
"glm-4.7": { code: 5, text: 4 },
|
|
44
|
+
"glm-4.6": { code: 3, vision: 3, text: 4 },
|
|
45
|
+
// DeepSeek
|
|
46
|
+
"deepseek-reasoner": { code: 4, text: 4 },
|
|
47
|
+
"deepseek-chat": { code: 3, text: 4 },
|
|
48
|
+
// MiniMax
|
|
49
|
+
"minimax-m2.1": { code: 4, text: 3 },
|
|
50
|
+
"minimax-m2": { code: 3, text: 2 },
|
|
51
|
+
// Moonshot (Kimi)
|
|
52
|
+
"kimi-k2.5": { code: 4, text: 4 },
|
|
53
|
+
"kimi-k2": { code: 3, text: 4 },
|
|
54
|
+
// Qwen (Alibaba)
|
|
55
|
+
"qwen3-coder": { code: 3, text: 3 },
|
|
56
|
+
"qwen3-max": { text: 4 },
|
|
57
|
+
// xAI
|
|
58
|
+
"grok-4.1": { code: 2, text: 5 },
|
|
59
|
+
"grok-4": { code: 1, text: 4 },
|
|
60
|
+
// Mistral
|
|
61
|
+
"mistral-large-3": { code: 2, text: 4 },
|
|
62
|
+
"devstral-2": { code: 2 },
|
|
63
|
+
"devstral-medium": { code: 1 },
|
|
64
|
+
};
|
|
65
|
+
/** Sorted keys longest-first for prefix matching. */
|
|
66
|
+
const SORTED_KEYS = Object.keys(MODEL_MATRIX).sort((a, b) => b.length - a.length);
|
|
67
|
+
/**
|
|
68
|
+
* Get capability ratings for a model by its ID.
|
|
69
|
+
*
|
|
70
|
+
* Uses longest-prefix matching: strips provider prefix (e.g. "anthropic/"),
|
|
71
|
+
* then finds the longest key in MODEL_MATRIX that the model ID starts with.
|
|
72
|
+
* E.g., "claude-sonnet-4-5-20250929" matches "claude-sonnet-4-5".
|
|
73
|
+
*
|
|
74
|
+
* @param modelId - Full model ID (may include date suffixes)
|
|
75
|
+
* @returns Capability ratings, or undefined if model not in matrix
|
|
76
|
+
*/
|
|
77
|
+
export function getModelRatings(modelId) {
|
|
78
|
+
const bare = modelId.includes("/") ? modelId.slice(modelId.indexOf("/") + 1) : modelId;
|
|
79
|
+
const key = SORTED_KEYS.find((k) => bare.startsWith(k));
|
|
80
|
+
return key ? MODEL_MATRIX[key] : undefined;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Check if a model supports a given task type at the required complexity level.
|
|
84
|
+
*
|
|
85
|
+
* @param modelId - Full model ID
|
|
86
|
+
* @param type - Required task type
|
|
87
|
+
* @param minRating - Minimum required rating (1-5)
|
|
88
|
+
* @returns true if the model has a rating for the type >= minRating
|
|
89
|
+
*/
|
|
90
|
+
export function modelSupportsTask(modelId, type, minRating) {
|
|
91
|
+
const ratings = getModelRatings(modelId);
|
|
92
|
+
if (!ratings)
|
|
93
|
+
return false;
|
|
94
|
+
const rating = ratings[type];
|
|
95
|
+
return rating !== undefined && rating >= minRating;
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=matrix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"matrix.js","sourceRoot":"","sources":["../src/matrix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy model name resolution against the pi-ai model registry.
|
|
3
|
+
*
|
|
4
|
+
* Resolves human-friendly names like "opus", "sonnet 4.5" to exact
|
|
5
|
+
* provider/model-id pairs using a 6-tier resolution cascade.
|
|
6
|
+
*/
|
|
7
|
+
import type { ModelSource, ResolvedModel } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolves a human-friendly model name to a single exact provider/model-id.
|
|
10
|
+
*
|
|
11
|
+
* Finds all tied candidates via the resolution cascade, then picks the
|
|
12
|
+
* best one using capability score → shortest ID → lexicographic ordering.
|
|
13
|
+
*
|
|
14
|
+
* @param query - Human-friendly model name (e.g. "opus", "sonnet 4.5", "claude-opus-4-5")
|
|
15
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
16
|
+
* @returns Resolved model, or undefined if no match found
|
|
17
|
+
*/
|
|
18
|
+
export declare function resolveModelFuzzy(query: string, modelSource?: ModelSource): ResolvedModel | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves a human-friendly model name to ALL tied candidates.
|
|
21
|
+
*
|
|
22
|
+
* Same resolution cascade as `resolveModelFuzzy`, but returns every model
|
|
23
|
+
* that ties at the best score instead of picking one. Used by the model
|
|
24
|
+
* router for scoped auto-routing: "codex" → all codex models → classify
|
|
25
|
+
* task → pick the right one for the job.
|
|
26
|
+
*
|
|
27
|
+
* @param query - Human-friendly model name (e.g. "codex", "opus", "gemini flash")
|
|
28
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
29
|
+
* @returns Array of resolved models (may be empty if no match)
|
|
30
|
+
*/
|
|
31
|
+
export declare function resolveModelCandidates(query: string, modelSource?: ModelSource): ResolvedModel[];
|
|
32
|
+
/**
|
|
33
|
+
* Lists all available models from the registry for error messages.
|
|
34
|
+
*
|
|
35
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
36
|
+
* @returns Array of model display strings ("provider/id")
|
|
37
|
+
*/
|
|
38
|
+
export declare function listAvailableModels(modelSource?: ModelSource): string[];
|
|
39
|
+
//# sourceMappingURL=resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAkB,WAAW,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAsL7E;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,EACb,WAAW,CAAC,EAAE,WAAW,GACvB,aAAa,GAAG,SAAS,CAI3B;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,aAAa,EAAE,CAEhG;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,CAGvE"}
|
package/dist/resolver.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fuzzy model name resolution against the pi-ai model registry.
|
|
3
|
+
*
|
|
4
|
+
* Resolves human-friendly names like "opus", "sonnet 4.5" to exact
|
|
5
|
+
* provider/model-id pairs using a 6-tier resolution cascade.
|
|
6
|
+
*/
|
|
7
|
+
import { getModels, getProviders } from "@mariozechner/pi-ai";
|
|
8
|
+
import { getModelRatings } from "./matrix.js";
|
|
9
|
+
/**
|
|
10
|
+
* Collects all models from every registered provider.
|
|
11
|
+
*
|
|
12
|
+
* @returns Flat array of candidate models with provider, id, and name
|
|
13
|
+
*/
|
|
14
|
+
function getAllModels() {
|
|
15
|
+
const result = [];
|
|
16
|
+
for (const provider of getProviders()) {
|
|
17
|
+
for (const m of getModels(provider)) {
|
|
18
|
+
result.push({ provider: m.provider, id: m.id, name: m.name });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Builds a ResolvedModel from a candidate.
|
|
25
|
+
*
|
|
26
|
+
* @param m - Candidate model
|
|
27
|
+
* @returns ResolvedModel with display name
|
|
28
|
+
*/
|
|
29
|
+
function toResolved(m) {
|
|
30
|
+
return { provider: m.provider, id: m.id, displayName: `${m.provider}/${m.id}` };
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Sum of all capability ratings for a model from the matrix.
|
|
34
|
+
* Higher = more capable. Returns 0 if not in matrix.
|
|
35
|
+
*
|
|
36
|
+
* @param id - Model ID
|
|
37
|
+
* @returns Total capability score
|
|
38
|
+
*/
|
|
39
|
+
function capabilityScore(id) {
|
|
40
|
+
const ratings = getModelRatings(id);
|
|
41
|
+
if (!ratings)
|
|
42
|
+
return 0;
|
|
43
|
+
return Object.values(ratings).reduce((sum, v) => sum + (v ?? 0), 0);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Picks the best candidate from a list of fuzzy-match ties.
|
|
47
|
+
*
|
|
48
|
+
* Tiebreak order:
|
|
49
|
+
* 1. Highest capability score (from model matrix) — picks the most capable model
|
|
50
|
+
* 2. Shortest model ID — prefers concise canonical names over variants
|
|
51
|
+
* 3. Lexicographically last — higher version numbers win ("5.3" > "5.2")
|
|
52
|
+
*
|
|
53
|
+
* @param models - Array of candidates to pick from
|
|
54
|
+
* @returns The best candidate by capability-then-shortest-then-latest
|
|
55
|
+
*/
|
|
56
|
+
function pickBest(models) {
|
|
57
|
+
return models.reduce((a, b) => {
|
|
58
|
+
const aCap = capabilityScore(a.id);
|
|
59
|
+
const bCap = capabilityScore(b.id);
|
|
60
|
+
if (aCap !== bCap)
|
|
61
|
+
return aCap > bCap ? a : b;
|
|
62
|
+
if (a.id.length !== b.id.length)
|
|
63
|
+
return a.id.length < b.id.length ? a : b;
|
|
64
|
+
return a.id >= b.id ? a : b;
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Splits a string into lowercase tokens on spaces, hyphens, underscores, dots,
|
|
69
|
+
* and word↔digit boundaries (e.g. "codex5" → ["codex", "5"]).
|
|
70
|
+
*
|
|
71
|
+
* @param s - Input string
|
|
72
|
+
* @returns Array of non-empty lowercase tokens
|
|
73
|
+
*/
|
|
74
|
+
function tokenize(s) {
|
|
75
|
+
return s
|
|
76
|
+
.toLowerCase()
|
|
77
|
+
.replace(/([a-z])(\d)/g, "$1 $2")
|
|
78
|
+
.replace(/(\d)([a-z])/g, "$1 $2")
|
|
79
|
+
.split(/[\s\-_.]+/)
|
|
80
|
+
.filter((t) => t.length > 0);
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Strips all common separators and lowercases for normalized comparison.
|
|
84
|
+
* "glm-5" → "glm5", "claude-sonnet-4-5" → "claudesonnet45"
|
|
85
|
+
*
|
|
86
|
+
* @param s - Input string
|
|
87
|
+
* @returns Normalized string with separators removed
|
|
88
|
+
*/
|
|
89
|
+
function normalize(s) {
|
|
90
|
+
return s.toLowerCase().replace(/[\s\-_.]+/g, "");
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Finds all fuzzy-matched candidates for a query (before tiebreaking).
|
|
94
|
+
*
|
|
95
|
+
* Returns all models that tie at the best score for whichever resolution
|
|
96
|
+
* tier first produces a match. Used by `resolveModelFuzzy` (picks one)
|
|
97
|
+
* and `resolveModelCandidates` (returns all for scoped routing).
|
|
98
|
+
*
|
|
99
|
+
* Resolution cascade:
|
|
100
|
+
* 1. Exact ID match across all providers
|
|
101
|
+
* 2. Case-insensitive ID match
|
|
102
|
+
* 2.5. Normalized match — strips separators ("glm5" → "glm-5")
|
|
103
|
+
* 3. Provider/ID format (e.g. "anthropic/claude-sonnet-4-5")
|
|
104
|
+
* 4. Token overlap — split query into tokens, score models by weighted
|
|
105
|
+
* token matches. ID/name matches score 2, provider-only matches score 1.
|
|
106
|
+
* Best score wins.
|
|
107
|
+
* 5. Substring match — query appears as substring in model ID or name
|
|
108
|
+
* 6. Normalized substring — strips separators before substring comparison
|
|
109
|
+
*
|
|
110
|
+
* @param query - Human-friendly model name (e.g. "opus", "sonnet 4.5", "codex")
|
|
111
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
112
|
+
* @returns Array of tied candidates from the first matching tier, or empty
|
|
113
|
+
*/
|
|
114
|
+
function findCandidates(query, modelSource) {
|
|
115
|
+
const models = modelSource ? modelSource() : getAllModels();
|
|
116
|
+
if (models.length === 0)
|
|
117
|
+
return [];
|
|
118
|
+
const q = query.trim();
|
|
119
|
+
if (q.length === 0)
|
|
120
|
+
return [];
|
|
121
|
+
const qLower = q.toLowerCase();
|
|
122
|
+
// 1. Exact ID match
|
|
123
|
+
const exact = models.filter((m) => m.id === q);
|
|
124
|
+
if (exact.length > 0)
|
|
125
|
+
return exact;
|
|
126
|
+
// 2. Case-insensitive ID match
|
|
127
|
+
const ciMatch = models.filter((m) => m.id.toLowerCase() === qLower);
|
|
128
|
+
if (ciMatch.length > 0)
|
|
129
|
+
return ciMatch;
|
|
130
|
+
// 2.5. Normalized match — strips separators ("glm5" matches "glm-5")
|
|
131
|
+
const qNorm = normalize(q);
|
|
132
|
+
const normMatch = models.filter((m) => normalize(m.id) === qNorm);
|
|
133
|
+
if (normMatch.length > 0)
|
|
134
|
+
return normMatch;
|
|
135
|
+
// 3. Provider/ID format
|
|
136
|
+
if (q.includes("/")) {
|
|
137
|
+
const slashIdx = q.indexOf("/");
|
|
138
|
+
const provider = q.slice(0, slashIdx).toLowerCase();
|
|
139
|
+
const id = q.slice(slashIdx + 1).toLowerCase();
|
|
140
|
+
const providerMatch = models.filter((m) => m.provider.toLowerCase() === provider && m.id.toLowerCase() === id);
|
|
141
|
+
if (providerMatch.length > 0)
|
|
142
|
+
return providerMatch;
|
|
143
|
+
}
|
|
144
|
+
// 4. Token overlap scoring (ID/name matches weighted 2×, provider-only 1×)
|
|
145
|
+
const queryTokens = tokenize(q);
|
|
146
|
+
if (queryTokens.length > 0) {
|
|
147
|
+
let bestScore = 0;
|
|
148
|
+
let bestMatches = [];
|
|
149
|
+
for (const m of models) {
|
|
150
|
+
const idName = `${m.id} ${m.name}`.toLowerCase();
|
|
151
|
+
const providerStr = m.provider.toLowerCase();
|
|
152
|
+
let score = 0;
|
|
153
|
+
for (const t of queryTokens) {
|
|
154
|
+
if (idName.includes(t))
|
|
155
|
+
score += 2;
|
|
156
|
+
else if (providerStr.includes(t))
|
|
157
|
+
score += 1;
|
|
158
|
+
}
|
|
159
|
+
if (score > bestScore) {
|
|
160
|
+
bestScore = score;
|
|
161
|
+
bestMatches = [m];
|
|
162
|
+
}
|
|
163
|
+
else if (score === bestScore && score > 0) {
|
|
164
|
+
bestMatches.push(m);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (bestScore > 0 && bestMatches.length > 0)
|
|
168
|
+
return bestMatches;
|
|
169
|
+
}
|
|
170
|
+
// 5. Substring match (raw)
|
|
171
|
+
const subMatches = models.filter((m) => m.id.toLowerCase().includes(qLower) || m.name.toLowerCase().includes(qLower));
|
|
172
|
+
if (subMatches.length > 0)
|
|
173
|
+
return subMatches;
|
|
174
|
+
// 6. Substring match (normalized — strips separators before comparing)
|
|
175
|
+
const normSubMatches = models.filter((m) => normalize(m.id).includes(qNorm) || normalize(m.name).includes(qNorm));
|
|
176
|
+
if (normSubMatches.length > 0)
|
|
177
|
+
return normSubMatches;
|
|
178
|
+
return [];
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Resolves a human-friendly model name to a single exact provider/model-id.
|
|
182
|
+
*
|
|
183
|
+
* Finds all tied candidates via the resolution cascade, then picks the
|
|
184
|
+
* best one using capability score → shortest ID → lexicographic ordering.
|
|
185
|
+
*
|
|
186
|
+
* @param query - Human-friendly model name (e.g. "opus", "sonnet 4.5", "claude-opus-4-5")
|
|
187
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
188
|
+
* @returns Resolved model, or undefined if no match found
|
|
189
|
+
*/
|
|
190
|
+
export function resolveModelFuzzy(query, modelSource) {
|
|
191
|
+
const candidates = findCandidates(query, modelSource);
|
|
192
|
+
if (candidates.length === 0)
|
|
193
|
+
return undefined;
|
|
194
|
+
return toResolved(pickBest(candidates));
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Resolves a human-friendly model name to ALL tied candidates.
|
|
198
|
+
*
|
|
199
|
+
* Same resolution cascade as `resolveModelFuzzy`, but returns every model
|
|
200
|
+
* that ties at the best score instead of picking one. Used by the model
|
|
201
|
+
* router for scoped auto-routing: "codex" → all codex models → classify
|
|
202
|
+
* task → pick the right one for the job.
|
|
203
|
+
*
|
|
204
|
+
* @param query - Human-friendly model name (e.g. "codex", "opus", "gemini flash")
|
|
205
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
206
|
+
* @returns Array of resolved models (may be empty if no match)
|
|
207
|
+
*/
|
|
208
|
+
export function resolveModelCandidates(query, modelSource) {
|
|
209
|
+
return findCandidates(query, modelSource).map(toResolved);
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Lists all available models from the registry for error messages.
|
|
213
|
+
*
|
|
214
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
215
|
+
* @returns Array of model display strings ("provider/id")
|
|
216
|
+
*/
|
|
217
|
+
export function listAvailableModels(modelSource) {
|
|
218
|
+
const models = modelSource ? modelSource() : getAllModels();
|
|
219
|
+
return models.map((m) => `${m.provider}/${m.id}`);
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolver.js","sourceRoot":"","sources":["../src/resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model selection algorithm.
|
|
3
|
+
*
|
|
4
|
+
* Given a classified task and cost preference, ranks available models
|
|
5
|
+
* by suitability. Consumers use the first result and fall back to the rest.
|
|
6
|
+
*/
|
|
7
|
+
import type { ClassificationResult, CostPreference, ResolvedModel } from "./types.js";
|
|
8
|
+
/**
|
|
9
|
+
* Selects models for a classified task, ranked by preference.
|
|
10
|
+
*
|
|
11
|
+
* Algorithm:
|
|
12
|
+
* 1. Enumerate all models from registry that have matrix ratings
|
|
13
|
+
* 2. Filter: model has rating for classification.type
|
|
14
|
+
* 3. Filter: rating[type] >= classification.complexity
|
|
15
|
+
* 4. Sort by cost preference:
|
|
16
|
+
* - "eco": ascending by effective cost
|
|
17
|
+
* - "premium": descending by effective cost
|
|
18
|
+
* - "balanced": exact rating match first, then ascending cost
|
|
19
|
+
* 5. Return ranked list (caller uses first, falls back to rest)
|
|
20
|
+
*
|
|
21
|
+
* @param classification - Task classification result
|
|
22
|
+
* @param costPreference - Cost preference for sorting
|
|
23
|
+
* @param pool - Optional pre-resolved model pool (for scoped routing)
|
|
24
|
+
* @returns Ranked list of suitable models (may be empty)
|
|
25
|
+
*/
|
|
26
|
+
export declare function selectModels(classification: ClassificationResult, costPreference: CostPreference, pool?: ResolvedModel[]): ResolvedModel[];
|
|
27
|
+
//# sourceMappingURL=selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../src/selector.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAEX,oBAAoB,EACpB,cAAc,EAGd,aAAa,EACb,MAAM,YAAY,CAAC;AAuFpB;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,YAAY,CAC3B,cAAc,EAAE,oBAAoB,EACpC,cAAc,EAAE,cAAc,EAC9B,IAAI,CAAC,EAAE,aAAa,EAAE,GACpB,aAAa,EAAE,CAyBjB"}
|
package/dist/selector.js
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model selection algorithm.
|
|
3
|
+
*
|
|
4
|
+
* Given a classified task and cost preference, ranks available models
|
|
5
|
+
* by suitability. Consumers use the first result and fall back to the rest.
|
|
6
|
+
*/
|
|
7
|
+
import { getModels, getProviders } from "@mariozechner/pi-ai";
|
|
8
|
+
import { getModelRatings } from "./matrix.js";
|
|
9
|
+
/**
|
|
10
|
+
* Collects all models from every registered provider.
|
|
11
|
+
*
|
|
12
|
+
* @returns Flat array of candidate models
|
|
13
|
+
*/
|
|
14
|
+
function getAllModels() {
|
|
15
|
+
const result = [];
|
|
16
|
+
for (const provider of getProviders()) {
|
|
17
|
+
for (const m of getModels(provider)) {
|
|
18
|
+
result.push({ provider: m.provider, id: m.id, name: m.name });
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Enumerates all models from the registry with their ratings and costs.
|
|
25
|
+
*
|
|
26
|
+
* @param modelSource - Optional model-fetching function (defaults to pi-ai registry)
|
|
27
|
+
* @returns Array of candidates that exist in the capability matrix
|
|
28
|
+
*/
|
|
29
|
+
function enumerateCandidates(modelSource) {
|
|
30
|
+
const candidates = [];
|
|
31
|
+
const models = modelSource ? modelSource() : getAllModels();
|
|
32
|
+
for (const provider of getProviders()) {
|
|
33
|
+
for (const regModel of getModels(provider)) {
|
|
34
|
+
// Only include models that are in our source list (or all if no source)
|
|
35
|
+
if (modelSource &&
|
|
36
|
+
!models.some((m) => m.id === regModel.id && m.provider === regModel.provider)) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const ratings = getModelRatings(regModel.id);
|
|
40
|
+
if (!ratings)
|
|
41
|
+
continue;
|
|
42
|
+
candidates.push({
|
|
43
|
+
resolved: {
|
|
44
|
+
provider: regModel.provider,
|
|
45
|
+
id: regModel.id,
|
|
46
|
+
displayName: `${regModel.provider}/${regModel.id}`,
|
|
47
|
+
},
|
|
48
|
+
ratings,
|
|
49
|
+
effectiveCost: (regModel.cost.input + regModel.cost.output) / 2,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return candidates;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Converts a set of pre-resolved models into scored candidates.
|
|
57
|
+
*
|
|
58
|
+
* Used for scoped routing: takes fuzzy-matched models and enriches them
|
|
59
|
+
* with ratings and cost data so they can be filtered/sorted by selectModels.
|
|
60
|
+
*
|
|
61
|
+
* @param pool - Pre-resolved models to convert
|
|
62
|
+
* @returns Scored candidates (only those with matrix ratings)
|
|
63
|
+
*/
|
|
64
|
+
function candidatesFromPool(pool) {
|
|
65
|
+
const candidates = [];
|
|
66
|
+
for (const resolved of pool) {
|
|
67
|
+
const ratings = getModelRatings(resolved.id);
|
|
68
|
+
if (!ratings)
|
|
69
|
+
continue;
|
|
70
|
+
// Look up cost from registry
|
|
71
|
+
let effectiveCost = 0;
|
|
72
|
+
for (const provider of getProviders()) {
|
|
73
|
+
for (const model of getModels(provider)) {
|
|
74
|
+
if (model.id === resolved.id && model.provider === resolved.provider) {
|
|
75
|
+
effectiveCost = (model.cost.input + model.cost.output) / 2;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
candidates.push({ resolved, ratings, effectiveCost });
|
|
80
|
+
}
|
|
81
|
+
return candidates;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Selects models for a classified task, ranked by preference.
|
|
85
|
+
*
|
|
86
|
+
* Algorithm:
|
|
87
|
+
* 1. Enumerate all models from registry that have matrix ratings
|
|
88
|
+
* 2. Filter: model has rating for classification.type
|
|
89
|
+
* 3. Filter: rating[type] >= classification.complexity
|
|
90
|
+
* 4. Sort by cost preference:
|
|
91
|
+
* - "eco": ascending by effective cost
|
|
92
|
+
* - "premium": descending by effective cost
|
|
93
|
+
* - "balanced": exact rating match first, then ascending cost
|
|
94
|
+
* 5. Return ranked list (caller uses first, falls back to rest)
|
|
95
|
+
*
|
|
96
|
+
* @param classification - Task classification result
|
|
97
|
+
* @param costPreference - Cost preference for sorting
|
|
98
|
+
* @param pool - Optional pre-resolved model pool (for scoped routing)
|
|
99
|
+
* @returns Ranked list of suitable models (may be empty)
|
|
100
|
+
*/
|
|
101
|
+
export function selectModels(classification, costPreference, pool) {
|
|
102
|
+
const { type, complexity } = classification;
|
|
103
|
+
const allCandidates = pool ? candidatesFromPool(pool) : enumerateCandidates();
|
|
104
|
+
const candidates = allCandidates.filter((c) => {
|
|
105
|
+
const rating = c.ratings[type];
|
|
106
|
+
return rating !== undefined && rating >= complexity;
|
|
107
|
+
});
|
|
108
|
+
if (candidates.length === 0)
|
|
109
|
+
return [];
|
|
110
|
+
candidates.sort((a, b) => {
|
|
111
|
+
if (costPreference === "eco") {
|
|
112
|
+
return a.effectiveCost - b.effectiveCost;
|
|
113
|
+
}
|
|
114
|
+
if (costPreference === "premium") {
|
|
115
|
+
return b.effectiveCost - a.effectiveCost;
|
|
116
|
+
}
|
|
117
|
+
// "balanced": exact-match rating sorts first, then ascending cost
|
|
118
|
+
const aExact = a.ratings[type] === complexity ? 0 : 1;
|
|
119
|
+
const bExact = b.ratings[type] === complexity ? 0 : 1;
|
|
120
|
+
if (aExact !== bExact)
|
|
121
|
+
return aExact - bExact;
|
|
122
|
+
return a.effectiveCost - b.effectiveCost;
|
|
123
|
+
});
|
|
124
|
+
return candidates.map((c) => c.resolved);
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.js","sourceRoot":"","sources":["../src/selector.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** LLM task types for routing. */
|
|
2
|
+
export type TaskType = "code" | "vision" | "text";
|
|
3
|
+
/**
|
|
4
|
+
* Per-type capability ratings. Scale: 1 (basic) to 5 (frontier).
|
|
5
|
+
* Missing key = model doesn't support that type.
|
|
6
|
+
*/
|
|
7
|
+
export type ModelRatings = Partial<Record<TaskType, number>>;
|
|
8
|
+
/** User's cost preference for model routing. */
|
|
9
|
+
export type CostPreference = "eco" | "balanced" | "premium";
|
|
10
|
+
/** Task complexity level (1-5). */
|
|
11
|
+
export type TaskComplexity = 1 | 2 | 3 | 4 | 5;
|
|
12
|
+
/** Result of task classification. */
|
|
13
|
+
export interface ClassificationResult {
|
|
14
|
+
type: TaskType;
|
|
15
|
+
complexity: TaskComplexity;
|
|
16
|
+
reasoning: string;
|
|
17
|
+
}
|
|
18
|
+
/** A resolved model with provider and display name. */
|
|
19
|
+
export interface ResolvedModel {
|
|
20
|
+
provider: string;
|
|
21
|
+
id: string;
|
|
22
|
+
displayName: string;
|
|
23
|
+
}
|
|
24
|
+
/** Model-fetching function signature for dependency injection. */
|
|
25
|
+
export interface CandidateModel {
|
|
26
|
+
provider: string;
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
}
|
|
30
|
+
/** Model source function for dependency injection in resolver/selector. */
|
|
31
|
+
export type ModelSource = () => CandidateModel[];
|
|
32
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAC;AAElD;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAE7D,gDAAgD;AAChD,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,CAAC;AAE5D,mCAAmC;AACnC,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE/C,qCAAqC;AACrC,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,cAAc,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;CAClB;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;CACpB;AAED,kEAAkE;AAClE,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACb;AAED,2EAA2E;AAC3E,MAAM,MAAM,WAAW,GAAG,MAAM,cAAc,EAAE,CAAC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/package.json
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dungle-scrubs/synapse",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Model capability matrix, fuzzy resolver, task classifier, and selection algorithm for pi-ai models",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": ["dist", "README.md", "CHANGELOG.md"],
|
|
15
|
+
"peerDependencies": {
|
|
16
|
+
"@mariozechner/pi-ai": ">=0.50.0"
|
|
17
|
+
},
|
|
18
|
+
"devDependencies": {
|
|
19
|
+
"@biomejs/biome": "^1.9.4",
|
|
20
|
+
"@mariozechner/pi-ai": "0.52.12",
|
|
21
|
+
"@types/bun": "^1.2.5",
|
|
22
|
+
"typescript": "^5.7.3"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"typecheck": "tsc --noEmit",
|
|
27
|
+
"test": "bun test",
|
|
28
|
+
"lint": "biome check src/ __tests__/",
|
|
29
|
+
"lint:fix": "biome check --write src/ __tests__/"
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://github.com/dungle-scrubs/synapse.git"
|
|
34
|
+
},
|
|
35
|
+
"author": "Kevin Frilot",
|
|
36
|
+
"license": "MIT"
|
|
37
|
+
}
|