@zhixuan92/multi-model-agent-core 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/LICENSE +21 -0
- package/README.md +112 -0
- package/dist/auth/claude-oauth.d.ts +6 -0
- package/dist/auth/claude-oauth.d.ts.map +1 -0
- package/dist/auth/claude-oauth.js +8 -0
- package/dist/auth/claude-oauth.js.map +1 -0
- package/dist/auth/codex-oauth.d.ts +6 -0
- package/dist/auth/codex-oauth.d.ts.map +1 -0
- package/dist/auth/codex-oauth.js +50 -0
- package/dist/auth/codex-oauth.js.map +1 -0
- package/dist/config/load.d.ts +8 -0
- package/dist/config/load.d.ts.map +1 -0
- package/dist/config/load.js +49 -0
- package/dist/config/load.js.map +1 -0
- package/dist/config/schema.d.ts +275 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +62 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/model-profiles.json +34 -0
- package/dist/provider.d.ts +3 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +50 -0
- package/dist/provider.js.map +1 -0
- package/dist/routing/capabilities.d.ts +3 -0
- package/dist/routing/capabilities.d.ts.map +1 -0
- package/dist/routing/capabilities.js +26 -0
- package/dist/routing/capabilities.js.map +1 -0
- package/dist/routing/get-provider-eligibility.d.ts +8 -0
- package/dist/routing/get-provider-eligibility.d.ts.map +1 -0
- package/dist/routing/get-provider-eligibility.js +53 -0
- package/dist/routing/get-provider-eligibility.js.map +1 -0
- package/dist/routing/model-profiles.d.ts +24 -0
- package/dist/routing/model-profiles.d.ts.map +1 -0
- package/dist/routing/model-profiles.js +41 -0
- package/dist/routing/model-profiles.js.map +1 -0
- package/dist/routing/resolve-task-capabilities.d.ts +7 -0
- package/dist/routing/resolve-task-capabilities.d.ts.map +1 -0
- package/dist/routing/resolve-task-capabilities.js +19 -0
- package/dist/routing/resolve-task-capabilities.js.map +1 -0
- package/dist/routing/select-provider-for-task.d.ts +18 -0
- package/dist/routing/select-provider-for-task.d.ts.map +1 -0
- package/dist/routing/select-provider-for-task.js +50 -0
- package/dist/routing/select-provider-for-task.js.map +1 -0
- package/dist/run-tasks.d.ts +7 -0
- package/dist/run-tasks.d.ts.map +1 -0
- package/dist/run-tasks.js +81 -0
- package/dist/run-tasks.js.map +1 -0
- package/dist/runners/claude-runner.d.ts +7 -0
- package/dist/runners/claude-runner.d.ts.map +1 -0
- package/dist/runners/claude-runner.js +118 -0
- package/dist/runners/claude-runner.js.map +1 -0
- package/dist/runners/codex-runner.d.ts +23 -0
- package/dist/runners/codex-runner.d.ts.map +1 -0
- package/dist/runners/codex-runner.js +403 -0
- package/dist/runners/codex-runner.js.map +1 -0
- package/dist/runners/openai-runner.d.ts +22 -0
- package/dist/runners/openai-runner.d.ts.map +1 -0
- package/dist/runners/openai-runner.js +92 -0
- package/dist/runners/openai-runner.js.map +1 -0
- package/dist/tools/claude-adapter.d.ts +4 -0
- package/dist/tools/claude-adapter.d.ts.map +1 -0
- package/dist/tools/claude-adapter.js +42 -0
- package/dist/tools/claude-adapter.js.map +1 -0
- package/dist/tools/definitions.d.ts +19 -0
- package/dist/tools/definitions.d.ts.map +1 -0
- package/dist/tools/definitions.js +147 -0
- package/dist/tools/definitions.js.map +1 -0
- package/dist/tools/openai-adapter.d.ts +13 -0
- package/dist/tools/openai-adapter.d.ts.map +1 -0
- package/dist/tools/openai-adapter.js +74 -0
- package/dist/tools/openai-adapter.js.map +1 -0
- package/dist/tools/tracker.d.ts +7 -0
- package/dist/tools/tracker.d.ts.map +1 -0
- package/dist/tools/tracker.js +13 -0
- package/dist/tools/tracker.js.map +1 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +23 -0
- package/dist/types.js.map +1 -0
- package/package.json +97 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// Config
|
|
2
|
+
export { loadConfigFromFile } from './config/load.js';
|
|
3
|
+
export { parseConfig, multiModelConfigSchema } from './config/schema.js';
|
|
4
|
+
// Provider
|
|
5
|
+
export { createProvider } from './provider.js';
|
|
6
|
+
// Run tasks
|
|
7
|
+
export { runTasks } from './run-tasks.js';
|
|
8
|
+
// Routing helpers
|
|
9
|
+
export { getBaseCapabilities } from './routing/capabilities.js';
|
|
10
|
+
export { resolveTaskCapabilities } from './routing/resolve-task-capabilities.js';
|
|
11
|
+
export { findModelProfile, getEffectiveCostTier } from './routing/model-profiles.js';
|
|
12
|
+
export { selectProviderForTask } from './routing/select-provider-for-task.js';
|
|
13
|
+
export { getProviderEligibility } from './routing/get-provider-eligibility.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,SAAS;AACT,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AA0BzE,WAAW;AACX,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAE/C,YAAY;AACZ,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,kBAAkB;AAClB,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAChE,OAAO,EAAE,uBAAuB,EAAE,MAAM,wCAAwC,CAAC;AACjF,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACrF,OAAO,EAAE,qBAAqB,EAAE,MAAM,uCAAuC,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
[
|
|
2
|
+
{
|
|
3
|
+
"prefix": "claude-opus",
|
|
4
|
+
"tier": "reasoning",
|
|
5
|
+
"defaultCost": "high",
|
|
6
|
+
"bestFor": "high-ambiguity tasks where the cost of error is high",
|
|
7
|
+
"avoidFor": "routine implementation or batch transformations as the default choice",
|
|
8
|
+
"supportsEffort": true
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"prefix": "claude-sonnet",
|
|
12
|
+
"tier": "standard",
|
|
13
|
+
"defaultCost": "medium",
|
|
14
|
+
"bestFor": "most professional coding and tool-using tasks",
|
|
15
|
+
"avoidFor": "the hardest architectural decisions or highly ambiguous judgment calls",
|
|
16
|
+
"supportsEffort": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"prefix": "gpt-5",
|
|
20
|
+
"tier": "reasoning",
|
|
21
|
+
"defaultCost": "medium",
|
|
22
|
+
"bestFor": "reasoning-tier coding, agentic workflows, and tool use",
|
|
23
|
+
"avoidFor": "cases where you explicitly prefer premium escalation over cost or latency",
|
|
24
|
+
"supportsEffort": true
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"prefix": "MiniMax-M2",
|
|
28
|
+
"tier": "standard",
|
|
29
|
+
"defaultCost": "low",
|
|
30
|
+
"bestFor": "well-scoped coding and agent loops where cost matters",
|
|
31
|
+
"avoidFor": "highest-stakes ambiguous work that needs top-tier judgment",
|
|
32
|
+
"supportsEffort": true
|
|
33
|
+
}
|
|
34
|
+
]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAyB,gBAAgB,EAAkB,MAAM,YAAY,CAAC;AAGpG,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,gBAAgB,GAAG,QAAQ,CAqD/E"}
|
package/dist/provider.js
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export function createProvider(name, config) {
|
|
2
|
+
const providerConfig = config.providers[name];
|
|
3
|
+
if (!providerConfig) {
|
|
4
|
+
const available = Object.keys(config.providers).sort().join(', ');
|
|
5
|
+
throw new Error(`Provider "${name}" not found in config. Available: ${available}`);
|
|
6
|
+
}
|
|
7
|
+
const defaults = config.defaults;
|
|
8
|
+
const run = async (prompt, options = {}) => {
|
|
9
|
+
try {
|
|
10
|
+
switch (providerConfig.type) {
|
|
11
|
+
case 'codex': {
|
|
12
|
+
const { runCodex } = await import('./runners/codex-runner.js');
|
|
13
|
+
return await runCodex(prompt, options, providerConfig, defaults);
|
|
14
|
+
}
|
|
15
|
+
case 'claude': {
|
|
16
|
+
const { runClaude } = await import('./runners/claude-runner.js');
|
|
17
|
+
return await runClaude(prompt, options, providerConfig, defaults);
|
|
18
|
+
}
|
|
19
|
+
case 'openai-compatible': {
|
|
20
|
+
const { runOpenAI } = await import('./runners/openai-runner.js');
|
|
21
|
+
const { default: OpenAI } = await import('openai');
|
|
22
|
+
const apiKey = providerConfig.apiKey
|
|
23
|
+
?? (providerConfig.apiKeyEnv ? process.env[providerConfig.apiKeyEnv] : undefined);
|
|
24
|
+
const client = new OpenAI({
|
|
25
|
+
apiKey: apiKey || 'not-needed',
|
|
26
|
+
baseURL: providerConfig.baseUrl,
|
|
27
|
+
});
|
|
28
|
+
const runnerOpts = { client, providerConfig, defaults };
|
|
29
|
+
return await runOpenAI(prompt, options, runnerOpts);
|
|
30
|
+
}
|
|
31
|
+
default: {
|
|
32
|
+
// All provider types are handled above; this is a type safety net.
|
|
33
|
+
throw new Error(`Unreachable: unknown provider type`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch (err) {
|
|
38
|
+
return {
|
|
39
|
+
output: `Sub-agent error: ${err instanceof Error ? err.message : String(err)}`,
|
|
40
|
+
status: 'error',
|
|
41
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUSD: null },
|
|
42
|
+
turns: 0,
|
|
43
|
+
files: [],
|
|
44
|
+
error: err instanceof Error ? err.message : String(err),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
return { name, config: providerConfig, run };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.d.ts","sourceRoot":"","sources":["../../src/routing/capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAI9D,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,UAAU,EAAE,CAwBxE"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
const FILE_CAPABILITIES = ['file_read', 'file_write', 'grep', 'glob'];
|
|
2
|
+
export function getBaseCapabilities(config) {
|
|
3
|
+
const caps = [...FILE_CAPABILITIES];
|
|
4
|
+
if (config.sandboxPolicy === 'none') {
|
|
5
|
+
caps.push('shell');
|
|
6
|
+
}
|
|
7
|
+
switch (config.type) {
|
|
8
|
+
case 'codex': {
|
|
9
|
+
const hosted = config.hostedTools ?? ['web_search'];
|
|
10
|
+
if (hosted.includes('web_search'))
|
|
11
|
+
caps.push('web_search');
|
|
12
|
+
break;
|
|
13
|
+
}
|
|
14
|
+
case 'claude': {
|
|
15
|
+
caps.push('web_search', 'web_fetch');
|
|
16
|
+
break;
|
|
17
|
+
}
|
|
18
|
+
case 'openai-compatible': {
|
|
19
|
+
if ((config.hostedTools ?? []).includes('web_search'))
|
|
20
|
+
caps.push('web_search');
|
|
21
|
+
break;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return Array.from(new Set(caps));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"capabilities.js","sourceRoot":"","sources":["../../src/routing/capabilities.ts"],"names":[],"mappings":"AAEA,MAAM,iBAAiB,GAAiB,CAAC,WAAW,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpF,MAAM,UAAU,mBAAmB,CAAC,MAAsB;IACxD,MAAM,IAAI,GAAiB,CAAC,GAAG,iBAAiB,CAAC,CAAC;IAElD,IAAI,MAAM,CAAC,aAAa,KAAK,MAAM,EAAE,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC;IAED,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;QACpB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,MAAM,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,YAAY,CAAC,CAAC;YACpD,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC3D,MAAM;QACR,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YACrC,MAAM;QACR,CAAC;QACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,EAAE,CAAC,CAAC,QAAQ,CAAC,YAAY,CAAC;gBAAE,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC/E,MAAM;QACR,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { MultiModelConfig, ProviderEligibility, TaskSpec } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns structured eligibility report for every configured provider.
|
|
4
|
+
* Each entry states whether the provider is eligible and, if not, which
|
|
5
|
+
* specific checks failed and why.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getProviderEligibility(task: TaskSpec, config: MultiModelConfig): ProviderEligibility[];
|
|
8
|
+
//# sourceMappingURL=get-provider-eligibility.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-provider-eligibility.d.ts","sourceRoot":"","sources":["../../src/routing/get-provider-eligibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,gBAAgB,EAEhB,mBAAmB,EACnB,QAAQ,EAET,MAAM,aAAa,CAAC;AAMrB;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,gBAAgB,GACvB,mBAAmB,EAAE,CA+CvB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { resolveTaskCapabilities } from './resolve-task-capabilities.js';
|
|
2
|
+
import { findModelProfile } from './model-profiles.js';
|
|
3
|
+
const TIER_ORDER = { trivial: 0, standard: 1, reasoning: 2 };
|
|
4
|
+
/**
|
|
5
|
+
* Returns structured eligibility report for every configured provider.
|
|
6
|
+
* Each entry states whether the provider is eligible and, if not, which
|
|
7
|
+
* specific checks failed and why.
|
|
8
|
+
*/
|
|
9
|
+
export function getProviderEligibility(task, config) {
|
|
10
|
+
return Object.entries(config.providers).map(([name, providerConfig]) => {
|
|
11
|
+
const reasons = [];
|
|
12
|
+
// Capability check
|
|
13
|
+
const caps = resolveTaskCapabilities(providerConfig, {
|
|
14
|
+
tools: task.tools ?? 'full',
|
|
15
|
+
sandboxPolicy: task.sandboxPolicy ?? providerConfig.sandboxPolicy,
|
|
16
|
+
});
|
|
17
|
+
const missing = task.requiredCapabilities.filter((c) => !caps.includes(c));
|
|
18
|
+
if (missing.length > 0) {
|
|
19
|
+
reasons.push({
|
|
20
|
+
check: 'capability',
|
|
21
|
+
detail: `missing: ${missing.join(', ')}`,
|
|
22
|
+
message: `Provider "${name}" cannot satisfy requiredCapabilities: ${missing.join(', ')}.`,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
// Tier check
|
|
26
|
+
const profile = findModelProfile(providerConfig.model);
|
|
27
|
+
const requiredTierOrder = TIER_ORDER[task.tier];
|
|
28
|
+
const providerTierOrder = TIER_ORDER[profile.tier];
|
|
29
|
+
if (providerTierOrder < requiredTierOrder) {
|
|
30
|
+
reasons.push({
|
|
31
|
+
check: 'tier',
|
|
32
|
+
detail: `provider tier: ${profile.tier}, required: ${task.tier}`,
|
|
33
|
+
message: `Provider "${name}" (${profile.tier}) is below required tier ${task.tier}.`,
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
// OpenAI-compatible requires baseUrl (but this is caught by schema at parse time,
|
|
37
|
+
// so we surface it here as a sanity check)
|
|
38
|
+
if (providerConfig.type === 'openai-compatible' && !providerConfig.baseUrl) {
|
|
39
|
+
reasons.push({
|
|
40
|
+
check: 'missing_required_field',
|
|
41
|
+
detail: 'baseUrl is missing',
|
|
42
|
+
message: `Provider "${name}" (openai-compatible) is missing required field: baseUrl.`,
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
name,
|
|
47
|
+
config: providerConfig,
|
|
48
|
+
eligible: reasons.length === 0,
|
|
49
|
+
reasons,
|
|
50
|
+
};
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=get-provider-eligibility.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-provider-eligibility.js","sourceRoot":"","sources":["../../src/routing/get-provider-eligibility.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAwB,MAAM,qBAAqB,CAAC;AAE7E,MAAM,UAAU,GAAyB,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;AAEnF;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CACpC,IAAc,EACd,MAAwB;IAExB,OAAO,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,cAAc,CAAC,EAAuB,EAAE;QAC1F,MAAM,OAAO,GAAyB,EAAE,CAAC;QAEzC,mBAAmB;QACnB,MAAM,IAAI,GAAG,uBAAuB,CAAC,cAAc,EAAE;YACnD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,MAAM;YAC3B,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,cAAc,CAAC,aAAa;SAClE,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,YAAY;gBACnB,MAAM,EAAE,YAAY,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;gBACxC,OAAO,EAAE,aAAa,IAAI,0CAA0C,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;aAC1F,CAAC,CAAC;QACL,CAAC;QAED,aAAa;QACb,MAAM,OAAO,GAAG,gBAAgB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChD,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACnD,IAAI,iBAAiB,GAAG,iBAAiB,EAAE,CAAC;YAC1C,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,kBAAkB,OAAO,CAAC,IAAI,eAAe,IAAI,CAAC,IAAI,EAAE;gBAChE,OAAO,EAAE,aAAa,IAAI,MAAM,OAAO,CAAC,IAAI,4BAA4B,IAAI,CAAC,IAAI,GAAG;aACrF,CAAC,CAAC;QACL,CAAC;QAED,kFAAkF;QAClF,2CAA2C;QAC3C,IAAI,cAAc,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC;gBACX,KAAK,EAAE,wBAAwB;gBAC/B,MAAM,EAAE,oBAAoB;gBAC5B,OAAO,EAAE,aAAa,IAAI,2DAA2D;aACtF,CAAC,CAAC;QACL,CAAC;QAED,OAAO;YACL,IAAI;YACJ,MAAM,EAAE,cAAc;YACtB,QAAQ,EAAE,OAAO,CAAC,MAAM,KAAK,CAAC;YAC9B,OAAO;SACR,CAAC;IACJ,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import type { CostTier, ProviderConfig } from '../types.js';
|
|
3
|
+
export declare const modelProfileSchema: z.ZodObject<{
|
|
4
|
+
prefix: z.ZodString;
|
|
5
|
+
tier: z.ZodEnum<{
|
|
6
|
+
trivial: "trivial";
|
|
7
|
+
standard: "standard";
|
|
8
|
+
reasoning: "reasoning";
|
|
9
|
+
}>;
|
|
10
|
+
defaultCost: z.ZodEnum<{
|
|
11
|
+
low: "low";
|
|
12
|
+
medium: "medium";
|
|
13
|
+
high: "high";
|
|
14
|
+
free: "free";
|
|
15
|
+
}>;
|
|
16
|
+
bestFor: z.ZodString;
|
|
17
|
+
avoidFor: z.ZodOptional<z.ZodString>;
|
|
18
|
+
notes: z.ZodOptional<z.ZodString>;
|
|
19
|
+
supportsEffort: z.ZodBoolean;
|
|
20
|
+
}, z.core.$strip>;
|
|
21
|
+
export type ModelProfile = z.infer<typeof modelProfileSchema>;
|
|
22
|
+
export declare function findModelProfile(modelId: string): ModelProfile;
|
|
23
|
+
export declare function getEffectiveCostTier(config: ProviderConfig): CostTier;
|
|
24
|
+
//# sourceMappingURL=model-profiles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-profiles.d.ts","sourceRoot":"","sources":["../../src/routing/model-profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAMlE,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;iBAQ7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAmB9D,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAQ9D;AAED,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,cAAc,GAAG,QAAQ,CAErE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import profileData from '../model-profiles.json' with { type: 'json' };
|
|
3
|
+
const tierSchema = z.enum(['trivial', 'standard', 'reasoning']);
|
|
4
|
+
const costTierSchema = z.enum(['free', 'low', 'medium', 'high']);
|
|
5
|
+
export const modelProfileSchema = z.object({
|
|
6
|
+
prefix: z.string().min(1),
|
|
7
|
+
tier: tierSchema,
|
|
8
|
+
defaultCost: costTierSchema,
|
|
9
|
+
bestFor: z.string().min(1),
|
|
10
|
+
avoidFor: z.string().optional(),
|
|
11
|
+
notes: z.string().optional(),
|
|
12
|
+
supportsEffort: z.boolean(),
|
|
13
|
+
});
|
|
14
|
+
const DEFAULT_PROFILE = {
|
|
15
|
+
prefix: '',
|
|
16
|
+
tier: 'standard',
|
|
17
|
+
defaultCost: 'medium',
|
|
18
|
+
bestFor: 'general tasks (unprofiled model — defaults applied)',
|
|
19
|
+
supportsEffort: false,
|
|
20
|
+
};
|
|
21
|
+
// Validate and sort once at module load — longest prefix wins
|
|
22
|
+
const PROFILE_ENTRIES = (() => {
|
|
23
|
+
const parsed = z.array(modelProfileSchema).safeParse(profileData);
|
|
24
|
+
if (!parsed.success) {
|
|
25
|
+
throw new Error(`model-profiles.json is invalid: ${parsed.error.message}`);
|
|
26
|
+
}
|
|
27
|
+
return parsed.data.sort((a, b) => b.prefix.length - a.prefix.length);
|
|
28
|
+
})();
|
|
29
|
+
export function findModelProfile(modelId) {
|
|
30
|
+
const normalized = modelId.toLowerCase();
|
|
31
|
+
for (const entry of PROFILE_ENTRIES) {
|
|
32
|
+
if (normalized.startsWith(entry.prefix.toLowerCase())) {
|
|
33
|
+
return { ...entry };
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return { ...DEFAULT_PROFILE };
|
|
37
|
+
}
|
|
38
|
+
export function getEffectiveCostTier(config) {
|
|
39
|
+
return config.costTier ?? findModelProfile(config.model).defaultCost;
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=model-profiles.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-profiles.js","sourceRoot":"","sources":["../../src/routing/model-profiles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,WAAW,MAAM,wBAAwB,CAAC,OAAO,IAAI,EAAE,MAAM,EAAE,CAAC;AAEvE,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;AAChE,MAAM,cAAc,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,cAAc;IAC3B,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC1B,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC/B,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAC5B,cAAc,EAAE,CAAC,CAAC,OAAO,EAAE;CAC5B,CAAC,CAAC;AAIH,MAAM,eAAe,GAAiB;IACpC,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,UAAU;IAChB,WAAW,EAAE,QAAQ;IACrB,OAAO,EAAE,qDAAqD;IAC9D,cAAc,EAAE,KAAK;CACtB,CAAC;AAEF,8DAA8D;AAC9D,MAAM,eAAe,GAAmB,CAAC,GAAG,EAAE;IAC5C,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,SAAS,CAAC,WAAW,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,mCAAmC,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;IAC7E,CAAC;IACD,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;AACvE,CAAC,CAAC,EAAE,CAAC;AAEL,MAAM,UAAU,gBAAgB,CAAC,OAAe;IAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,eAAe,EAAE,CAAC;QACpC,IAAI,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YACtD,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,GAAG,eAAe,EAAE,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,MAAsB;IACzD,OAAO,MAAM,CAAC,QAAQ,IAAI,gBAAgB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC;AACvE,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Capability, ProviderConfig, RunOptions } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the capabilities a task will have at runtime, accounting for
|
|
4
|
+
* tools, sandboxPolicy, and hosted tools overrides.
|
|
5
|
+
*/
|
|
6
|
+
export declare function resolveTaskCapabilities(providerConfig: ProviderConfig, options: Pick<RunOptions, 'tools' | 'sandboxPolicy'>): Capability[];
|
|
7
|
+
//# sourceMappingURL=resolve-task-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-task-capabilities.d.ts","sourceRoot":"","sources":["../../src/routing/resolve-task-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAG1E;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,IAAI,CAAC,UAAU,EAAE,OAAO,GAAG,eAAe,CAAC,GACnD,UAAU,EAAE,CAad"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { getBaseCapabilities } from './capabilities.js';
|
|
2
|
+
/**
|
|
3
|
+
* Returns the capabilities a task will have at runtime, accounting for
|
|
4
|
+
* tools, sandboxPolicy, and hosted tools overrides.
|
|
5
|
+
*/
|
|
6
|
+
export function resolveTaskCapabilities(providerConfig, options) {
|
|
7
|
+
// If tools are disabled for this task, no capabilities are offered.
|
|
8
|
+
if (options.tools === 'none')
|
|
9
|
+
return [];
|
|
10
|
+
// Merge the per-task sandboxPolicy override (if any) into a config snapshot
|
|
11
|
+
// before asking getBaseCapabilities. The provider's persisted config is NOT
|
|
12
|
+
// mutated.
|
|
13
|
+
const mergedConfig = {
|
|
14
|
+
...providerConfig,
|
|
15
|
+
sandboxPolicy: options.sandboxPolicy ?? providerConfig.sandboxPolicy,
|
|
16
|
+
};
|
|
17
|
+
return getBaseCapabilities(mergedConfig);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=resolve-task-capabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-task-capabilities.js","sourceRoot":"","sources":["../../src/routing/resolve-task-capabilities.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAExD;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,cAA8B,EAC9B,OAAoD;IAEpD,oEAAoE;IACpE,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM;QAAE,OAAO,EAAE,CAAC;IAExC,4EAA4E;IAC5E,4EAA4E;IAC5E,WAAW;IACX,MAAM,YAAY,GAAmB;QACnC,GAAG,cAAc;QACjB,aAAa,EAAE,OAAO,CAAC,aAAa,IAAI,cAAc,CAAC,aAAa;KACrE,CAAC;IAEF,OAAO,mBAAmB,CAAC,YAAY,CAAC,CAAC;AAC3C,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ProviderConfig, TaskSpec, MultiModelConfig } from '../types.js';
|
|
2
|
+
export interface SelectedProvider {
|
|
3
|
+
name: string;
|
|
4
|
+
config: ProviderConfig;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Select which provider to use for a task (when provider is omitted).
|
|
8
|
+
* Algorithm:
|
|
9
|
+
* 1. Capability filter (HARD): exclude providers missing any requiredCapability.
|
|
10
|
+
* 2. Tier filter (HARD): exclude providers whose findModelProfile(model).tier < task.tier.
|
|
11
|
+
* Tier ordering: trivial < standard < reasoning.
|
|
12
|
+
* 3. Cost preference (STRONG): among remainder, select cheapest costTier.
|
|
13
|
+
* 4. Tiebreaker: ASCII/lexicographic by provider name.
|
|
14
|
+
*
|
|
15
|
+
* Returns null if no provider passes all filters.
|
|
16
|
+
*/
|
|
17
|
+
export declare function selectProviderForTask(task: TaskSpec, config: MultiModelConfig): SelectedProvider | null;
|
|
18
|
+
//# sourceMappingURL=select-provider-for-task.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-provider-for-task.d.ts","sourceRoot":"","sources":["../../src/routing/select-provider-for-task.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI9E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,cAAc,CAAA;CACvB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,gBAAgB,GACvB,gBAAgB,GAAG,IAAI,CAsCzB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { resolveTaskCapabilities } from './resolve-task-capabilities.js';
|
|
2
|
+
import { findModelProfile, getEffectiveCostTier } from './model-profiles.js';
|
|
3
|
+
/**
|
|
4
|
+
* Select which provider to use for a task (when provider is omitted).
|
|
5
|
+
* Algorithm:
|
|
6
|
+
* 1. Capability filter (HARD): exclude providers missing any requiredCapability.
|
|
7
|
+
* 2. Tier filter (HARD): exclude providers whose findModelProfile(model).tier < task.tier.
|
|
8
|
+
* Tier ordering: trivial < standard < reasoning.
|
|
9
|
+
* 3. Cost preference (STRONG): among remainder, select cheapest costTier.
|
|
10
|
+
* 4. Tiebreaker: ASCII/lexicographic by provider name.
|
|
11
|
+
*
|
|
12
|
+
* Returns null if no provider passes all filters.
|
|
13
|
+
*/
|
|
14
|
+
export function selectProviderForTask(task, config) {
|
|
15
|
+
const TIER_ORDER = { trivial: 0, standard: 1, reasoning: 2 };
|
|
16
|
+
const eligible = [];
|
|
17
|
+
for (const [name, providerConfig] of Object.entries(config.providers)) {
|
|
18
|
+
// 1. Capability check
|
|
19
|
+
const caps = resolveTaskCapabilities(providerConfig, {
|
|
20
|
+
tools: task.tools ?? 'full',
|
|
21
|
+
sandboxPolicy: task.sandboxPolicy ?? providerConfig.sandboxPolicy,
|
|
22
|
+
});
|
|
23
|
+
const missing = task.requiredCapabilities.filter((c) => !caps.includes(c));
|
|
24
|
+
if (missing.length > 0)
|
|
25
|
+
continue;
|
|
26
|
+
// 2. Tier check
|
|
27
|
+
const profile = findModelProfile(providerConfig.model);
|
|
28
|
+
const requiredTierOrder = TIER_ORDER[task.tier] ?? 0;
|
|
29
|
+
const providerTierOrder = TIER_ORDER[profile.tier] ?? 0;
|
|
30
|
+
if (providerTierOrder < requiredTierOrder)
|
|
31
|
+
continue;
|
|
32
|
+
// Passed both filters — track for cost comparison
|
|
33
|
+
const costTier = getEffectiveCostTier(providerConfig);
|
|
34
|
+
eligible.push({ name, config: providerConfig, costTier });
|
|
35
|
+
}
|
|
36
|
+
if (eligible.length === 0)
|
|
37
|
+
return null;
|
|
38
|
+
// 3. Sort by cost tier: free < low < medium < high
|
|
39
|
+
const COST_ORDER = { free: 0, low: 1, medium: 2, high: 3 };
|
|
40
|
+
eligible.sort((a, b) => {
|
|
41
|
+
const costDiff = (COST_ORDER[a.costTier] ?? 3) - (COST_ORDER[b.costTier] ?? 3);
|
|
42
|
+
if (costDiff !== 0)
|
|
43
|
+
return costDiff;
|
|
44
|
+
// 4. Tiebreaker: provider name ascending
|
|
45
|
+
return a.name.localeCompare(b.name);
|
|
46
|
+
});
|
|
47
|
+
const winner = eligible[0];
|
|
48
|
+
return { name: winner.name, config: winner.config };
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=select-provider-for-task.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"select-provider-for-task.js","sourceRoot":"","sources":["../../src/routing/select-provider-for-task.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAO7E;;;;;;;;;;GAUG;AACH,MAAM,UAAU,qBAAqB,CACnC,IAAc,EACd,MAAwB;IAExB,MAAM,UAAU,GAA2B,EAAE,OAAO,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;IAErF,MAAM,QAAQ,GAAiE,EAAE,CAAC;IAElF,KAAK,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;QACtE,sBAAsB;QACtB,MAAM,IAAI,GAAG,uBAAuB,CAAC,cAAc,EAAE;YACnD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,MAAM;YAC3B,aAAa,EAAE,IAAI,CAAC,aAAa,IAAI,cAAc,CAAC,aAAa;SAClE,CAAC,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAC3E,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,SAAS;QAEjC,gBAAgB;QAChB,MAAM,OAAO,GAAG,gBAAgB,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;QACvD,MAAM,iBAAiB,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACxD,IAAI,iBAAiB,GAAG,iBAAiB;YAAE,SAAS;QAEpD,kDAAkD;QAClD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,cAAc,CAAC,CAAC;QACtD,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,mDAAmD;IACnD,MAAM,UAAU,GAA2B,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACnF,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,MAAM,QAAQ,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/E,IAAI,QAAQ,KAAK,CAAC;YAAE,OAAO,QAAQ,CAAC;QACpC,yCAAyC;QACzC,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC;AACtD,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { RunResult, TaskSpec, MultiModelConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run tasks concurrently. Each RunResult corresponds to the matching TaskSpec
|
|
4
|
+
* at the same index. One task failing does not affect others.
|
|
5
|
+
*/
|
|
6
|
+
export declare function runTasks(tasks: TaskSpec[], config: MultiModelConfig): Promise<RunResult[]>;
|
|
7
|
+
//# sourceMappingURL=run-tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tasks.d.ts","sourceRoot":"","sources":["../src/run-tasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,SAAS,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAuClF;;;GAGG;AACH,wBAAsB,QAAQ,CAC5B,KAAK,EAAE,QAAQ,EAAE,EACjB,MAAM,EAAE,gBAAgB,GACvB,OAAO,CAAC,SAAS,EAAE,CAAC,CAmDtB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { createProvider } from './provider.js';
|
|
2
|
+
import { getProviderEligibility } from './routing/get-provider-eligibility.js';
|
|
3
|
+
import { selectProviderForTask } from './routing/select-provider-for-task.js';
|
|
4
|
+
function errorResult(error) {
|
|
5
|
+
return {
|
|
6
|
+
output: `Sub-agent error: ${error}`,
|
|
7
|
+
status: 'error',
|
|
8
|
+
usage: { inputTokens: 0, outputTokens: 0, totalTokens: 0, costUSD: null },
|
|
9
|
+
turns: 0,
|
|
10
|
+
files: [],
|
|
11
|
+
error,
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
async function executeTask(task, provider, config) {
|
|
15
|
+
try {
|
|
16
|
+
return await provider.run(task.prompt, {
|
|
17
|
+
tools: task.tools,
|
|
18
|
+
maxTurns: task.maxTurns,
|
|
19
|
+
timeoutMs: task.timeoutMs,
|
|
20
|
+
cwd: task.cwd,
|
|
21
|
+
effort: task.effort,
|
|
22
|
+
sandboxPolicy: task.sandboxPolicy,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
return errorResult(err instanceof Error ? err.message : String(err));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Run tasks concurrently. Each RunResult corresponds to the matching TaskSpec
|
|
31
|
+
* at the same index. One task failing does not affect others.
|
|
32
|
+
*/
|
|
33
|
+
export async function runTasks(tasks, config) {
|
|
34
|
+
if (tasks.length === 0)
|
|
35
|
+
return [];
|
|
36
|
+
const resolved = tasks.map((task) => {
|
|
37
|
+
// If provider specified, validate and use it
|
|
38
|
+
if (task.provider) {
|
|
39
|
+
const eligibility = getProviderEligibility(task, config);
|
|
40
|
+
const report = eligibility.find((e) => e.name === task.provider);
|
|
41
|
+
if (!report) {
|
|
42
|
+
// Provider explicitly named but not in config — fail fast with error result
|
|
43
|
+
return {
|
|
44
|
+
task,
|
|
45
|
+
error: `Provider "${task.provider}" not found in config.`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (!report.eligible) {
|
|
49
|
+
const reasons = report.reasons.map((r) => r.message).join('; ');
|
|
50
|
+
return {
|
|
51
|
+
task,
|
|
52
|
+
error: `Provider "${task.provider}" is ineligible: ${reasons}`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
return {
|
|
56
|
+
task,
|
|
57
|
+
provider: createProvider(task.provider, config),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
// Auto-routing
|
|
61
|
+
const selected = selectProviderForTask(task, config);
|
|
62
|
+
if (!selected) {
|
|
63
|
+
const available = Object.keys(config.providers);
|
|
64
|
+
return {
|
|
65
|
+
task,
|
|
66
|
+
error: `No eligible provider found for task (required tier: ${task.tier}, capabilities: ${task.requiredCapabilities.join(', ') || 'none'}). Available providers: ${available.join(', ') || 'none'}.`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
return {
|
|
70
|
+
task,
|
|
71
|
+
provider: createProvider(selected.name, config),
|
|
72
|
+
};
|
|
73
|
+
});
|
|
74
|
+
return Promise.all(resolved.map((r) => {
|
|
75
|
+
if ('error' in r) {
|
|
76
|
+
return Promise.resolve(errorResult(r.error));
|
|
77
|
+
}
|
|
78
|
+
return executeTask(r.task, r.provider, config);
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=run-tasks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-tasks.js","sourceRoot":"","sources":["../src/run-tasks.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type RunResult, type RunOptions, type ProviderConfig } from '../types.js';
|
|
2
|
+
export declare function runClaude(prompt: string, options: RunOptions, providerConfig: ProviderConfig, defaults: {
|
|
3
|
+
maxTurns: number;
|
|
4
|
+
timeoutMs: number;
|
|
5
|
+
tools: 'none' | 'full';
|
|
6
|
+
}): Promise<RunResult>;
|
|
7
|
+
//# sourceMappingURL=claude-runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-runner.d.ts","sourceRoot":"","sources":["../../src/runners/claude-runner.ts"],"names":[],"mappings":"AACA,OAAO,EAAe,KAAK,SAAS,EAAE,KAAK,UAAU,EAAE,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAKhG,wBAAsB,SAAS,CAC7B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,UAAU,EACnB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,GACxE,OAAO,CAAC,SAAS,CAAC,CAyHpB"}
|