@agentfare/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.
Files changed (102) hide show
  1. package/README.md +24 -0
  2. package/dist/analyzer/auto-model-selector.d.ts +3 -0
  3. package/dist/analyzer/auto-model-selector.d.ts.map +1 -0
  4. package/dist/analyzer/auto-model-selector.js +15 -0
  5. package/dist/analyzer/auto-model-selector.js.map +1 -0
  6. package/dist/analyzer/cache.d.ts +16 -0
  7. package/dist/analyzer/cache.d.ts.map +1 -0
  8. package/dist/analyzer/cache.js +113 -0
  9. package/dist/analyzer/cache.js.map +1 -0
  10. package/dist/analyzer/llm-analyzer.d.ts +4 -0
  11. package/dist/analyzer/llm-analyzer.d.ts.map +1 -0
  12. package/dist/analyzer/llm-analyzer.js +94 -0
  13. package/dist/analyzer/llm-analyzer.js.map +1 -0
  14. package/dist/analyzer/rules.d.ts +3 -0
  15. package/dist/analyzer/rules.d.ts.map +1 -0
  16. package/dist/analyzer/rules.js +223 -0
  17. package/dist/analyzer/rules.js.map +1 -0
  18. package/dist/analyzer/types.d.ts +52 -0
  19. package/dist/analyzer/types.d.ts.map +1 -0
  20. package/dist/analyzer/types.js +35 -0
  21. package/dist/analyzer/types.js.map +1 -0
  22. package/dist/config/defaults.d.ts +3 -0
  23. package/dist/config/defaults.d.ts.map +1 -0
  24. package/dist/config/defaults.js +41 -0
  25. package/dist/config/defaults.js.map +1 -0
  26. package/dist/config/enterprise.d.ts +7 -0
  27. package/dist/config/enterprise.d.ts.map +1 -0
  28. package/dist/config/enterprise.js +25 -0
  29. package/dist/config/enterprise.js.map +1 -0
  30. package/dist/config/loader.d.ts +10 -0
  31. package/dist/config/loader.d.ts.map +1 -0
  32. package/dist/config/loader.js +134 -0
  33. package/dist/config/loader.js.map +1 -0
  34. package/dist/config/types.d.ts +81 -0
  35. package/dist/config/types.d.ts.map +1 -0
  36. package/dist/config/types.js +3 -0
  37. package/dist/config/types.js.map +1 -0
  38. package/dist/errors.d.ts +14 -0
  39. package/dist/errors.d.ts.map +1 -0
  40. package/dist/errors.js +25 -0
  41. package/dist/errors.js.map +1 -0
  42. package/dist/index.d.ts +29 -0
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +63 -0
  45. package/dist/index.js.map +1 -0
  46. package/dist/optimizer/eval-runner.d.ts +23 -0
  47. package/dist/optimizer/eval-runner.d.ts.map +1 -0
  48. package/dist/optimizer/eval-runner.js +115 -0
  49. package/dist/optimizer/eval-runner.js.map +1 -0
  50. package/dist/optimizer/online-learning.d.ts +37 -0
  51. package/dist/optimizer/online-learning.d.ts.map +1 -0
  52. package/dist/optimizer/online-learning.js +128 -0
  53. package/dist/optimizer/online-learning.js.map +1 -0
  54. package/dist/optimizer/pipeline-parser.d.ts +4 -0
  55. package/dist/optimizer/pipeline-parser.d.ts.map +1 -0
  56. package/dist/optimizer/pipeline-parser.js +72 -0
  57. package/dist/optimizer/pipeline-parser.js.map +1 -0
  58. package/dist/optimizer/search.d.ts +7 -0
  59. package/dist/optimizer/search.d.ts.map +1 -0
  60. package/dist/optimizer/search.js +323 -0
  61. package/dist/optimizer/search.js.map +1 -0
  62. package/dist/optimizer/types.d.ts +31 -0
  63. package/dist/optimizer/types.d.ts.map +1 -0
  64. package/dist/optimizer/types.js +11 -0
  65. package/dist/optimizer/types.js.map +1 -0
  66. package/dist/routing/cross-provider.d.ts +8 -0
  67. package/dist/routing/cross-provider.d.ts.map +1 -0
  68. package/dist/routing/cross-provider.js +22 -0
  69. package/dist/routing/cross-provider.js.map +1 -0
  70. package/dist/routing/enterprise.d.ts +7 -0
  71. package/dist/routing/enterprise.d.ts.map +1 -0
  72. package/dist/routing/enterprise.js +16 -0
  73. package/dist/routing/enterprise.js.map +1 -0
  74. package/dist/routing/router.d.ts +19 -0
  75. package/dist/routing/router.d.ts.map +1 -0
  76. package/dist/routing/router.js +125 -0
  77. package/dist/routing/router.js.map +1 -0
  78. package/dist/routing/same-provider.d.ts +4 -0
  79. package/dist/routing/same-provider.d.ts.map +1 -0
  80. package/dist/routing/same-provider.js +24 -0
  81. package/dist/routing/same-provider.js.map +1 -0
  82. package/dist/tracker/cost-tracker.d.ts +13 -0
  83. package/dist/tracker/cost-tracker.d.ts.map +1 -0
  84. package/dist/tracker/cost-tracker.js +39 -0
  85. package/dist/tracker/cost-tracker.js.map +1 -0
  86. package/dist/tracker/database.d.ts +64 -0
  87. package/dist/tracker/database.d.ts.map +1 -0
  88. package/dist/tracker/database.js +194 -0
  89. package/dist/tracker/database.js.map +1 -0
  90. package/dist/tracker/quality-signal.d.ts +29 -0
  91. package/dist/tracker/quality-signal.d.ts.map +1 -0
  92. package/dist/tracker/quality-signal.js +95 -0
  93. package/dist/tracker/quality-signal.js.map +1 -0
  94. package/dist/tracker/report-exporter.d.ts +28 -0
  95. package/dist/tracker/report-exporter.d.ts.map +1 -0
  96. package/dist/tracker/report-exporter.js +39 -0
  97. package/dist/tracker/report-exporter.js.map +1 -0
  98. package/dist/utils/tokens.d.ts +10 -0
  99. package/dist/utils/tokens.d.ts.map +1 -0
  100. package/dist/utils/tokens.js +26 -0
  101. package/dist/utils/tokens.js.map +1 -0
  102. package/package.json +22 -0
package/README.md ADDED
@@ -0,0 +1,24 @@
1
+ # @agentfare/core
2
+
3
+ 核心路由引擎、成本追踪器和优化器。
4
+
5
+ ## 主要模块
6
+
7
+ - **路由引擎** (`routing/`) — 基于任务难度和置信度的模型路由
8
+ - **成本追踪** (`tracker/`) — SQLite 持久化的请求日志和费用统计
9
+ - **优化器** (`optimizer/`) — 多策略搜索和在线学习
10
+ - **分析器** (`analyzer/`) — LLM 分析流水线和缓存
11
+
12
+ ## 使用
13
+
14
+ ```typescript
15
+ import { TrackingDatabase, CostTracker, QualitySignalCollector } from "@agentfare/core";
16
+
17
+ const db = new TrackingDatabase("~/.agentfare/data.db");
18
+ const costTracker = new CostTracker(db);
19
+ const quality = new QualitySignalCollector();
20
+ ```
21
+
22
+ ## License
23
+
24
+ MIT
@@ -0,0 +1,3 @@
1
+ import type { ModelRegistry, ModelEntry } from "@agentfare/models";
2
+ export declare function selectAnalyzerModel(registry: ModelRegistry): ModelEntry | null;
3
+ //# sourceMappingURL=auto-model-selector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-model-selector.d.ts","sourceRoot":"","sources":["../../src/analyzer/auto-model-selector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGnE,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,aAAa,GAAG,UAAU,GAAG,IAAI,CAc9E"}
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.selectAnalyzerModel = selectAnalyzerModel;
4
+ const models_1 = require("@agentfare/models");
5
+ function selectAnalyzerModel(registry) {
6
+ const fastModels = registry.getByTier("fast");
7
+ const withKey = fastModels.filter((m) => {
8
+ return !!(0, models_1.getApiKeyForProvider)(m.provider);
9
+ });
10
+ if (withKey.length > 0) {
11
+ return withKey.reduce((cheapest, m) => m.pricing.outputPerMillion < cheapest.pricing.outputPerMillion ? m : cheapest);
12
+ }
13
+ return null;
14
+ }
15
+ //# sourceMappingURL=auto-model-selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auto-model-selector.js","sourceRoot":"","sources":["../../src/analyzer/auto-model-selector.ts"],"names":[],"mappings":";;AAGA,kDAcC;AAhBD,8CAAyD;AAEzD,SAAgB,mBAAmB,CAAC,QAAuB;IACzD,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAE9C,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;QACtC,OAAO,CAAC,CAAC,IAAA,6BAAoB,EAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACvB,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,EAAE,EAAE,CACpC,CAAC,CAAC,OAAO,CAAC,gBAAgB,GAAG,QAAQ,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAC9E,CAAC;IACJ,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -0,0 +1,16 @@
1
+ import type { StepAnalysis } from "./types.js";
2
+ export declare class RouteCache {
3
+ private maxSize;
4
+ private cache;
5
+ private ttlMs;
6
+ private dirty;
7
+ constructor(maxSize?: number);
8
+ static makeKey(task: string, stepType?: string): string;
9
+ get(key: string): StepAnalysis | null;
10
+ set(key: string, analysis: StepAnalysis): void;
11
+ clear(): void;
12
+ invalidateOnPricingChange(): void;
13
+ private loadFromDisk;
14
+ saveToDisk(): void;
15
+ }
16
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/analyzer/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAQ/C,qBAAa,UAAU;IAKT,OAAO,CAAC,OAAO;IAJ3B,OAAO,CAAC,KAAK,CAAyE;IACtF,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,KAAK,CAAkB;gBAEX,OAAO,GAAE,MAAa;IAM1C,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM;IAIvD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAUrC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAS9C,KAAK,IAAI,IAAI;IAMb,yBAAyB,IAAI,IAAI;IAMjC,OAAO,CAAC,YAAY;IAapB,UAAU,IAAI,IAAI;CAUnB"}
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.RouteCache = void 0;
37
+ const crypto = __importStar(require("node:crypto"));
38
+ const fs = __importStar(require("node:fs"));
39
+ const path = __importStar(require("node:path"));
40
+ const os = __importStar(require("node:os"));
41
+ const CACHE_FILE = path.join(os.homedir(), ".agentfare", "cache", "route-cache.json");
42
+ class RouteCache {
43
+ maxSize;
44
+ cache = new Map();
45
+ ttlMs = 24 * 60 * 60 * 1000;
46
+ dirty = false;
47
+ constructor(maxSize = 1000) {
48
+ this.maxSize = maxSize;
49
+ this.loadFromDisk();
50
+ // ISSUE-039: persist cache on process exit
51
+ process.on("exit", () => this.saveToDisk());
52
+ }
53
+ static makeKey(task, stepType) {
54
+ return crypto.createHash("sha256").update(`${task}::${stepType ?? ""}`).digest("hex").slice(0, 16);
55
+ }
56
+ get(key) {
57
+ const entry = this.cache.get(key);
58
+ if (!entry)
59
+ return null;
60
+ if (Date.now() - entry.timestamp > this.ttlMs) {
61
+ this.cache.delete(key);
62
+ return null;
63
+ }
64
+ return entry.analysis;
65
+ }
66
+ set(key, analysis) {
67
+ if (this.cache.size >= this.maxSize) {
68
+ const firstKey = this.cache.keys().next().value;
69
+ if (firstKey !== undefined)
70
+ this.cache.delete(firstKey);
71
+ }
72
+ this.cache.set(key, { analysis, timestamp: Date.now() });
73
+ this.dirty = true;
74
+ }
75
+ clear() {
76
+ this.cache.clear();
77
+ this.dirty = true;
78
+ this.saveToDisk();
79
+ }
80
+ invalidateOnPricingChange() {
81
+ this.cache.clear();
82
+ this.dirty = true;
83
+ this.saveToDisk();
84
+ }
85
+ loadFromDisk() {
86
+ try {
87
+ if (fs.existsSync(CACHE_FILE)) {
88
+ const data = JSON.parse(fs.readFileSync(CACHE_FILE, "utf-8"));
89
+ for (const [key, value] of data) {
90
+ if (Date.now() - value.timestamp <= this.ttlMs) {
91
+ this.cache.set(key, value);
92
+ }
93
+ }
94
+ }
95
+ }
96
+ catch { }
97
+ }
98
+ saveToDisk() {
99
+ if (!this.dirty)
100
+ return;
101
+ try {
102
+ const dir = path.dirname(CACHE_FILE);
103
+ if (!fs.existsSync(dir))
104
+ fs.mkdirSync(dir, { recursive: true });
105
+ const data = Array.from(this.cache.entries());
106
+ fs.writeFileSync(CACHE_FILE, JSON.stringify(data));
107
+ this.dirty = false;
108
+ }
109
+ catch { }
110
+ }
111
+ }
112
+ exports.RouteCache = RouteCache;
113
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/analyzer/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { StepAnalysis, LLMAnalysisInput, Message } from "./types.js";
2
+ export declare function buildAnalyzerPrompt(input: LLMAnalysisInput): string;
3
+ export declare function analyzeWithLLM(messages: Message[], fetchFn: typeof globalThis.fetch, analyzerModelUrl: string, analyzerModelId: string, apiKey: string): Promise<StepAnalysis | null>;
4
+ //# sourceMappingURL=llm-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-analyzer.d.ts","sourceRoot":"","sources":["../../src/analyzer/llm-analyzer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAI1E,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,gBAAgB,GAAG,MAAM,CAsBnE;AAED,wBAAsB,cAAc,CAClC,QAAQ,EAAE,OAAO,EAAE,EACnB,OAAO,EAAE,OAAO,UAAU,CAAC,KAAK,EAChC,gBAAgB,EAAE,MAAM,EACxB,eAAe,EAAE,MAAM,EACvB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CA2C9B"}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildAnalyzerPrompt = buildAnalyzerPrompt;
4
+ exports.analyzeWithLLM = analyzeWithLLM;
5
+ const types_js_1 = require("./types.js");
6
+ const tokens_js_1 = require("../utils/tokens.js");
7
+ function buildAnalyzerPrompt(input) {
8
+ return `你是一个 AI Agent 步骤分析器。根据以下信息判断这个步骤的难度和推荐模型等级。
9
+
10
+ 任务: ${input.task}
11
+ 对话上下文: ${input.context ?? "无"}
12
+ 可用工具: ${input.tools?.join(", ") ?? "无"}
13
+
14
+ 输出 JSON:
15
+ {
16
+ "stepType": "planning|exploration|editing|testing|reviewing|reasoning|formatting|simple_tool_use|confirmation",
17
+ "difficulty": 0.0-1.0,
18
+ "recommendedTier": "fast|standard|powerful",
19
+ "confidence": 0.0-1.0,
20
+ "reasoning": "一句话解释"
21
+ }
22
+
23
+ 判断标准:
24
+ - fast: 格式化、简单搜索、文件读取、确认操作、样板代码生成
25
+ - standard: 常规代码编写、标准重构、测试编写、中等复杂度的 bug 修复
26
+ - powerful: 架构设计、复杂多文件调试、安全审计、需要深度推理的问题
27
+
28
+ 只输出 JSON,不要其他内容。`;
29
+ }
30
+ async function analyzeWithLLM(messages, fetchFn, analyzerModelUrl, analyzerModelId, apiKey) {
31
+ const input = (0, types_js_1.extractTaskFromMessages)(messages);
32
+ const prompt = buildAnalyzerPrompt(input);
33
+ try {
34
+ const response = await fetchFn(analyzerModelUrl, {
35
+ method: "POST",
36
+ headers: {
37
+ "Content-Type": "application/json",
38
+ "Authorization": `Bearer ${apiKey}`,
39
+ "x-agentfare-internal": "true",
40
+ },
41
+ body: JSON.stringify({
42
+ model: analyzerModelId,
43
+ messages: [{ role: "user", content: prompt }],
44
+ max_tokens: 200,
45
+ temperature: 0,
46
+ }),
47
+ });
48
+ const data = await response.json();
49
+ const content = data.choices?.[0]?.message?.content ?? "";
50
+ const json = JSON.parse(extractJSON(content));
51
+ const estimatedTokens = (0, tokens_js_1.estimateTokensFromMessages)(messages);
52
+ const recommendedTier = json.recommendedTier ?? "standard";
53
+ const alternatives = buildAlternatives(recommendedTier);
54
+ return {
55
+ stepType: json.stepType ?? "unknown",
56
+ difficulty: clamp(json.difficulty, 0, 1),
57
+ confidence: clamp(json.confidence, 0, 1),
58
+ recommendedTier,
59
+ // ISSUE-029: parse recommendedModel from LLM output when present
60
+ recommendedModel: typeof json.recommendedModel === "string" && json.recommendedModel ? json.recommendedModel : "",
61
+ reasoning: json.reasoning ?? "",
62
+ needsProviderSwitch: false,
63
+ estimatedTokens,
64
+ alternatives,
65
+ };
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ function extractJSON(text) {
72
+ const match = text.match(/\{[\s\S]*\}/);
73
+ return match ? match[0] : "{}";
74
+ }
75
+ function clamp(value, min, max) {
76
+ return Math.min(max, Math.max(min, value));
77
+ }
78
+ function buildAlternatives(recommendedTier) {
79
+ const tiers = [];
80
+ if (recommendedTier === "fast") {
81
+ tiers.push({ tier: "standard", costSavingsVsRecommended: -0.5, qualityRisk: "none" });
82
+ tiers.push({ tier: "powerful", costSavingsVsRecommended: -2.0, qualityRisk: "none" });
83
+ }
84
+ else if (recommendedTier === "standard") {
85
+ tiers.push({ tier: "fast", costSavingsVsRecommended: 0.6, qualityRisk: "medium" });
86
+ tiers.push({ tier: "powerful", costSavingsVsRecommended: -1.5, qualityRisk: "none" });
87
+ }
88
+ else {
89
+ tiers.push({ tier: "standard", costSavingsVsRecommended: 1.5, qualityRisk: "low" });
90
+ tiers.push({ tier: "fast", costSavingsVsRecommended: 2.0, qualityRisk: "high" });
91
+ }
92
+ return tiers.map((t) => ({ model: "", tier: t.tier, costSavingsVsRecommended: t.costSavingsVsRecommended, qualityRisk: t.qualityRisk }));
93
+ }
94
+ //# sourceMappingURL=llm-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"llm-analyzer.js","sourceRoot":"","sources":["../../src/analyzer/llm-analyzer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { StepAnalysis, StepAnalysisRequest } from "./types.js";
2
+ export declare function analyzeStepRules(request: StepAnalysisRequest): StepAnalysis | null;
3
+ //# sourceMappingURL=rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../../src/analyzer/rules.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,mBAAmB,EAAW,MAAM,YAAY,CAAC;AA0C7E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,GAAG,IAAI,CAsMlF"}
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.analyzeStepRules = analyzeStepRules;
4
+ const tokens_js_1 = require("../utils/tokens.js");
5
+ const SIMPLE_TOOL_PATTERNS = [
6
+ /\b(list|ls|cat|head|tail|find|grep|glob|which|where|pwd)\b/i,
7
+ /\bread.file\b/i,
8
+ /\bread_dir\b/i,
9
+ /\bsearch.files\b/i,
10
+ ];
11
+ const FORMATTING_PATTERNS = [
12
+ /\bformat\b.*\bcode\b/i,
13
+ /\blint\b.*\bfix\b/i,
14
+ /\bprettier\b/i,
15
+ /\beslint\b.*--fix/i,
16
+ /\borganize\s+imports\b/i,
17
+ ];
18
+ const CONFIRMATION_PATTERNS = [
19
+ /^(yes|no|ok|okay|sure|proceed|continue|go ahead|y|n)\b/i,
20
+ /^\b(confirm|cancel|apply|reject)\b/i,
21
+ ];
22
+ const FILE_READ_TOOLS = [
23
+ "read_file",
24
+ "read_file_content",
25
+ "get_file",
26
+ "view_file",
27
+ "search_files",
28
+ ];
29
+ const EDIT_PATTERNS = [
30
+ /\b(fix|update|change|modify|rename|refactor|implement|add)\b.*\b(in|the|a|this)\b.*\b(file|function|method|class|variable|module)\b/i,
31
+ /\bwrite\s+(to|file|the)\b/i,
32
+ /\bcreate\s+(a\s+)?(new\s+)?(file|component|module|class)\b/i,
33
+ ];
34
+ const COMPLEX_KEYWORDS = [
35
+ /\b(architect|design|redesign|overhaul|security\s+audit|performance\s+tuning)\b/i,
36
+ /\b(multi[\s-]file|cross[\s-]module|system[\s-]wide|end[\s-]to[\s-]end)\b/i,
37
+ ];
38
+ function analyzeStepRules(request) {
39
+ const { messages } = request;
40
+ const lastUserMsg = messages.filter((m) => m.role === "user").at(-1)?.content ?? "";
41
+ const userText = typeof lastUserMsg === "string"
42
+ ? lastUserMsg
43
+ : lastUserMsg.map((b) => b.text ?? "").join(" ");
44
+ const toolResults = messages.filter((m) => m.role === "tool");
45
+ const hasToolCalls = messages.some((m) => m.role === "assistant" && m.tool_calls?.length);
46
+ const hasImageContent = messages.some((m) => {
47
+ if (typeof m.content !== "string" && Array.isArray(m.content)) {
48
+ return m.content.some((b) => b.type === "image" || b.type === "image_url");
49
+ }
50
+ return false;
51
+ });
52
+ // ISSUE-027: use shared estimateTokensFromMessages from utils/tokens.ts
53
+ const estimatedTokens = (0, tokens_js_1.estimateTokensFromMessages)(messages);
54
+ // Rule: confirmation
55
+ if (isMatch(userText, CONFIRMATION_PATTERNS)) {
56
+ return {
57
+ stepType: "confirmation",
58
+ difficulty: 0.1,
59
+ confidence: 0.95,
60
+ recommendedTier: "fast",
61
+ recommendedModel: "",
62
+ reasoning: "用户确认操作",
63
+ needsProviderSwitch: false,
64
+ estimatedTokens,
65
+ alternatives: [
66
+ {
67
+ model: "",
68
+ tier: "standard",
69
+ costSavingsVsRecommended: -0.5,
70
+ qualityRisk: "none",
71
+ },
72
+ ],
73
+ };
74
+ }
75
+ // Rule: formatting/lint
76
+ if (isMatch(userText, FORMATTING_PATTERNS)) {
77
+ return {
78
+ stepType: "formatting",
79
+ difficulty: 0.15,
80
+ confidence: 0.9,
81
+ recommendedTier: "fast",
82
+ recommendedModel: "",
83
+ reasoning: "格式化/lint 修复",
84
+ needsProviderSwitch: false,
85
+ estimatedTokens,
86
+ alternatives: [
87
+ {
88
+ model: "",
89
+ tier: "standard",
90
+ costSavingsVsRecommended: -0.3,
91
+ qualityRisk: "none",
92
+ },
93
+ ],
94
+ };
95
+ }
96
+ // Rule: simple tool use
97
+ if (isMatch(userText, SIMPLE_TOOL_PATTERNS)) {
98
+ return {
99
+ stepType: "simple_tool_use",
100
+ difficulty: 0.1,
101
+ confidence: 0.9,
102
+ recommendedTier: "fast",
103
+ recommendedModel: "",
104
+ reasoning: "简单工具调用",
105
+ needsProviderSwitch: false,
106
+ estimatedTokens,
107
+ alternatives: [
108
+ {
109
+ model: "",
110
+ tier: "standard",
111
+ costSavingsVsRecommended: -0.4,
112
+ qualityRisk: "none",
113
+ },
114
+ ],
115
+ };
116
+ }
117
+ // Rule: non-complex code editing -> standard tier
118
+ if (isMatch(userText, EDIT_PATTERNS) && !isMatch(userText, COMPLEX_KEYWORDS)) {
119
+ return {
120
+ stepType: "editing",
121
+ difficulty: 0.4,
122
+ confidence: 0.75,
123
+ recommendedTier: "standard",
124
+ recommendedModel: "",
125
+ reasoning: "非复杂代码编辑",
126
+ needsProviderSwitch: false,
127
+ estimatedTokens,
128
+ alternatives: [
129
+ {
130
+ model: "",
131
+ tier: "fast",
132
+ costSavingsVsRecommended: 0.6,
133
+ qualityRisk: "medium",
134
+ },
135
+ {
136
+ model: "",
137
+ tier: "powerful",
138
+ costSavingsVsRecommended: -2.0,
139
+ qualityRisk: "none",
140
+ },
141
+ ],
142
+ };
143
+ }
144
+ // Rule: file read tool calls
145
+ if (hasToolCalls) {
146
+ const lastAssistant = [...messages]
147
+ .reverse()
148
+ .find((m) => m.role === "assistant" && m.tool_calls?.length);
149
+ const toolNames = lastAssistant?.tool_calls?.map((tc) => tc.function.name) ?? [];
150
+ if (toolNames.some((name) => FILE_READ_TOOLS.includes(name))) {
151
+ return {
152
+ stepType: "exploration",
153
+ difficulty: 0.2,
154
+ confidence: 0.85,
155
+ recommendedTier: "fast",
156
+ recommendedModel: "",
157
+ reasoning: "文件读取/搜索操作",
158
+ needsProviderSwitch: false,
159
+ estimatedTokens,
160
+ alternatives: [
161
+ {
162
+ model: "",
163
+ tier: "standard",
164
+ costSavingsVsRecommended: -0.3,
165
+ qualityRisk: "none",
166
+ },
167
+ ],
168
+ };
169
+ }
170
+ }
171
+ // Rule: tool results from file reads
172
+ if (toolResults.length > 0 && !hasToolCalls) {
173
+ const resultContent = toolResults
174
+ .map((m) => (typeof m.content === "string" ? m.content : ""))
175
+ .join("");
176
+ if (resultContent.length > 0) {
177
+ return {
178
+ stepType: "exploration",
179
+ difficulty: 0.2,
180
+ confidence: 0.7,
181
+ recommendedTier: "fast",
182
+ recommendedModel: "",
183
+ reasoning: "文件读取结果",
184
+ needsProviderSwitch: false,
185
+ estimatedTokens,
186
+ alternatives: [
187
+ {
188
+ model: "",
189
+ tier: "standard",
190
+ costSavingsVsRecommended: -0.3,
191
+ qualityRisk: "none",
192
+ },
193
+ ],
194
+ };
195
+ }
196
+ }
197
+ // Multimodal: skip content analysis, use conservative strategy
198
+ if (hasImageContent) {
199
+ return {
200
+ stepType: "unknown",
201
+ difficulty: 0.5,
202
+ confidence: 0.3,
203
+ recommendedTier: "standard",
204
+ recommendedModel: "",
205
+ reasoning: "多模态内容,跳过内容分析",
206
+ needsProviderSwitch: false,
207
+ estimatedTokens,
208
+ alternatives: [
209
+ {
210
+ model: "",
211
+ tier: "powerful",
212
+ costSavingsVsRecommended: -1.5,
213
+ qualityRisk: "low",
214
+ },
215
+ ],
216
+ };
217
+ }
218
+ return null;
219
+ }
220
+ function isMatch(text, patterns) {
221
+ return patterns.some((p) => p.test(text));
222
+ }
223
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../src/analyzer/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import type { ModelTier } from "@agentfare/models";
2
+ export type StepType = "planning" | "exploration" | "editing" | "testing" | "reviewing" | "reasoning" | "formatting" | "simple_tool_use" | "confirmation" | "unknown";
3
+ export interface StepAnalysis {
4
+ stepType: StepType;
5
+ difficulty: number;
6
+ confidence: number;
7
+ recommendedTier: ModelTier;
8
+ recommendedModel: string;
9
+ reasoning: string;
10
+ needsProviderSwitch: boolean;
11
+ estimatedTokens: {
12
+ input: number;
13
+ output: number;
14
+ };
15
+ alternatives: Array<{
16
+ model: string;
17
+ tier: ModelTier;
18
+ costSavingsVsRecommended: number;
19
+ qualityRisk: "none" | "low" | "medium" | "high";
20
+ }>;
21
+ }
22
+ export interface Message {
23
+ role: "user" | "assistant" | "system" | "tool";
24
+ content: string | ContentBlock[];
25
+ tool_calls?: ToolCall[];
26
+ }
27
+ export interface ContentBlock {
28
+ type: string;
29
+ text?: string;
30
+ }
31
+ export interface ToolCall {
32
+ id: string;
33
+ type: "function";
34
+ function: {
35
+ name: string;
36
+ arguments: string;
37
+ };
38
+ }
39
+ export interface StepAnalysisRequest {
40
+ messages: Message[];
41
+ originalModel: string;
42
+ availableTools?: string[];
43
+ previousModel?: string;
44
+ }
45
+ export interface LLMAnalysisInput {
46
+ task: string;
47
+ context?: string;
48
+ tools?: string[];
49
+ previousModel?: string;
50
+ }
51
+ export declare function extractTaskFromMessages(messages: Message[]): LLMAnalysisInput;
52
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAEnD,MAAM,MAAM,QAAQ,GAChB,UAAU,GACV,aAAa,GACb,SAAS,GACT,SAAS,GACT,WAAW,GACX,WAAW,GACX,YAAY,GACZ,iBAAiB,GACjB,cAAc,GACd,SAAS,CAAC;AAEd,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,SAAS,CAAC;IAC3B,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,eAAe,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACnD,YAAY,EAAE,KAAK,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,SAAS,CAAC;QAChB,wBAAwB,EAAE,MAAM,CAAC;QACjC,WAAW,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;KACjD,CAAC,CAAC;CACJ;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,GAAG,MAAM,CAAC;IAC/C,OAAO,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;IACjC,UAAU,CAAC,EAAE,QAAQ,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAC/C;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,gBAAgB,CAkC7E"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractTaskFromMessages = extractTaskFromMessages;
4
+ function extractTaskFromMessages(messages) {
5
+ const userMessages = messages.filter((m) => m.role === "user");
6
+ const lastUserMsg = userMessages.at(-1);
7
+ const task = lastUserMsg
8
+ ? typeof lastUserMsg.content === "string"
9
+ ? lastUserMsg.content
10
+ : lastUserMsg.content
11
+ .filter((b) => b.type === "text")
12
+ .map((b) => b.text ?? "")
13
+ .join(" ")
14
+ : "";
15
+ const recentMessages = messages.slice(-6, -1);
16
+ const context = recentMessages
17
+ .map((m) => {
18
+ const text = typeof m.content === "string" ? m.content : "";
19
+ const tools = m.tool_calls
20
+ ?.map((tc) => `${tc.function.name}(${tc.function.arguments})`)
21
+ .join(", ") ?? "";
22
+ return `[${m.role}] ${text}${tools ? ` (tools: ${tools})` : ""}`;
23
+ })
24
+ .join("\n")
25
+ .slice(0, 2000);
26
+ const tools = messages
27
+ .filter((m) => m.role === "assistant" && m.tool_calls)
28
+ .flatMap((m) => m.tool_calls.map((tc) => tc.function.name));
29
+ return {
30
+ task: task.slice(0, 2000),
31
+ context: context || undefined,
32
+ tools: tools.length > 0 ? tools : undefined,
33
+ };
34
+ }
35
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analyzer/types.ts"],"names":[],"mappings":";;AA8DA,0DAkCC;AAlCD,SAAgB,uBAAuB,CAAC,QAAmB;IACzD,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;IAC/D,MAAM,WAAW,GAAG,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,WAAW;QACtB,CAAC,CAAC,OAAO,WAAW,CAAC,OAAO,KAAK,QAAQ;YACvC,CAAC,CAAC,WAAW,CAAC,OAAO;YACrB,CAAC,CAAC,WAAW,CAAC,OAAO;iBAChB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC;iBAChC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC;iBACxB,IAAI,CAAC,GAAG,CAAC;QAChB,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,cAAc,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,cAAc;SAC3B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QACT,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,MAAM,KAAK,GACT,CAAC,CAAC,UAAU;YACV,EAAE,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,CAAC,SAAS,GAAG,CAAC;aAC7D,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,YAAY,KAAK,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;IACnE,CAAC,CAAC;SACD,IAAI,CAAC,IAAI,CAAC;SACV,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IAElB,MAAM,KAAK,GAAG,QAAQ;SACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,UAAU,CAAC;SACrD,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAW,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAE/D,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC;QACzB,OAAO,EAAE,OAAO,IAAI,SAAS;QAC7B,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;KAC5C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { AgentFareConfig } from "./types.js";
2
+ export declare const DEFAULT_CONFIG: AgentFareConfig;
3
+ //# sourceMappingURL=defaults.d.ts.map