agent-nuvira 1.14.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 +891 -0
- package/dist/agent-sdk/src/agent.d.ts +118 -0
- package/dist/agent-sdk/src/agent.d.ts.map +1 -0
- package/dist/agent-sdk/src/agent.js +88 -0
- package/dist/agent-sdk/src/agent.js.map +1 -0
- package/dist/agent-sdk/src/index.d.ts +33 -0
- package/dist/agent-sdk/src/index.d.ts.map +1 -0
- package/dist/agent-sdk/src/index.js +32 -0
- package/dist/agent-sdk/src/index.js.map +1 -0
- package/dist/agent-sdk/src/register.d.ts +70 -0
- package/dist/agent-sdk/src/register.d.ts.map +1 -0
- package/dist/agent-sdk/src/register.js +181 -0
- package/dist/agent-sdk/src/register.js.map +1 -0
- package/dist/agent-sdk/src/scaffold.d.ts +50 -0
- package/dist/agent-sdk/src/scaffold.d.ts.map +1 -0
- package/dist/agent-sdk/src/scaffold.js +291 -0
- package/dist/agent-sdk/src/scaffold.js.map +1 -0
- package/dist/agent-sdk/src/testing.d.ts +187 -0
- package/dist/agent-sdk/src/testing.d.ts.map +1 -0
- package/dist/agent-sdk/src/testing.js +243 -0
- package/dist/agent-sdk/src/testing.js.map +1 -0
- package/dist/agent-sdk/src/types.d.ts +202 -0
- package/dist/agent-sdk/src/types.d.ts.map +1 -0
- package/dist/agent-sdk/src/types.js +11 -0
- package/dist/agent-sdk/src/types.js.map +1 -0
- package/dist/agents/agent.d.ts +132 -0
- package/dist/agents/agent.d.ts.map +1 -0
- package/dist/agents/agent.js +19 -0
- package/dist/agents/agent.js.map +1 -0
- package/dist/agents/agents/context-gatherer.d.ts +42 -0
- package/dist/agents/agents/context-gatherer.d.ts.map +1 -0
- package/dist/agents/agents/context-gatherer.js +366 -0
- package/dist/agents/agents/context-gatherer.js.map +1 -0
- package/dist/agents/agents/debugger.d.ts +58 -0
- package/dist/agents/agents/debugger.d.ts.map +1 -0
- package/dist/agents/agents/debugger.js +257 -0
- package/dist/agents/agents/debugger.js.map +1 -0
- package/dist/agents/agents/git-agent.d.ts +34 -0
- package/dist/agents/agents/git-agent.d.ts.map +1 -0
- package/dist/agents/agents/git-agent.js +200 -0
- package/dist/agents/agents/git-agent.js.map +1 -0
- package/dist/agents/agents/github-release-agent.d.ts +65 -0
- package/dist/agents/agents/github-release-agent.d.ts.map +1 -0
- package/dist/agents/agents/github-release-agent.js +439 -0
- package/dist/agents/agents/github-release-agent.js.map +1 -0
- package/dist/agents/agents/package-agent.d.ts +33 -0
- package/dist/agents/agents/package-agent.d.ts.map +1 -0
- package/dist/agents/agents/package-agent.js +233 -0
- package/dist/agents/agents/package-agent.js.map +1 -0
- package/dist/agents/agents/planner.d.ts +26 -0
- package/dist/agents/agents/planner.d.ts.map +1 -0
- package/dist/agents/agents/planner.js +222 -0
- package/dist/agents/agents/planner.js.map +1 -0
- package/dist/agents/agents/reviewer.d.ts +34 -0
- package/dist/agents/agents/reviewer.d.ts.map +1 -0
- package/dist/agents/agents/reviewer.js +159 -0
- package/dist/agents/agents/reviewer.js.map +1 -0
- package/dist/agents/agents/runner.d.ts +73 -0
- package/dist/agents/agents/runner.d.ts.map +1 -0
- package/dist/agents/agents/runner.js +299 -0
- package/dist/agents/agents/runner.js.map +1 -0
- package/dist/agents/agents/security-agent.d.ts +33 -0
- package/dist/agents/agents/security-agent.d.ts.map +1 -0
- package/dist/agents/agents/security-agent.js +184 -0
- package/dist/agents/agents/security-agent.js.map +1 -0
- package/dist/agents/agents/tester.d.ts +96 -0
- package/dist/agents/agents/tester.d.ts.map +1 -0
- package/dist/agents/agents/tester.js +410 -0
- package/dist/agents/agents/tester.js.map +1 -0
- package/dist/agents/agents/writer.d.ts +51 -0
- package/dist/agents/agents/writer.d.ts.map +1 -0
- package/dist/agents/agents/writer.js +384 -0
- package/dist/agents/agents/writer.js.map +1 -0
- package/dist/agents/context-vault.d.ts +49 -0
- package/dist/agents/context-vault.d.ts.map +1 -0
- package/dist/agents/context-vault.js +134 -0
- package/dist/agents/context-vault.js.map +1 -0
- package/dist/agents/orchestrator.d.ts +97 -0
- package/dist/agents/orchestrator.d.ts.map +1 -0
- package/dist/agents/orchestrator.js +696 -0
- package/dist/agents/orchestrator.js.map +1 -0
- package/dist/agents/utils/file-tree.d.ts +28 -0
- package/dist/agents/utils/file-tree.d.ts.map +1 -0
- package/dist/agents/utils/file-tree.js +93 -0
- package/dist/agents/utils/file-tree.js.map +1 -0
- package/dist/cli/agent.d.ts +25 -0
- package/dist/cli/agent.d.ts.map +1 -0
- package/dist/cli/agent.js +374 -0
- package/dist/cli/agent.js.map +1 -0
- package/dist/cli/benchmark.d.ts +24 -0
- package/dist/cli/benchmark.d.ts.map +1 -0
- package/dist/cli/benchmark.js +235 -0
- package/dist/cli/benchmark.js.map +1 -0
- package/dist/cli/cache.d.ts +12 -0
- package/dist/cli/cache.d.ts.map +1 -0
- package/dist/cli/cache.js +58 -0
- package/dist/cli/cache.js.map +1 -0
- package/dist/cli/chat.d.ts +37 -0
- package/dist/cli/chat.d.ts.map +1 -0
- package/dist/cli/chat.js +393 -0
- package/dist/cli/chat.js.map +1 -0
- package/dist/cli/commands.d.ts +24 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +18 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +19 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +162 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/dashboard.d.ts +34 -0
- package/dist/cli/dashboard.d.ts.map +1 -0
- package/dist/cli/dashboard.js +126 -0
- package/dist/cli/dashboard.js.map +1 -0
- package/dist/cli/doctor.d.ts +68 -0
- package/dist/cli/doctor.d.ts.map +1 -0
- package/dist/cli/doctor.js +585 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/edit.d.ts +11 -0
- package/dist/cli/edit.d.ts.map +1 -0
- package/dist/cli/edit.js +86 -0
- package/dist/cli/edit.js.map +1 -0
- package/dist/cli/execute.d.ts +25 -0
- package/dist/cli/execute.d.ts.map +1 -0
- package/dist/cli/execute.js +186 -0
- package/dist/cli/execute.js.map +1 -0
- package/dist/cli/federation.d.ts +31 -0
- package/dist/cli/federation.d.ts.map +1 -0
- package/dist/cli/federation.js +387 -0
- package/dist/cli/federation.js.map +1 -0
- package/dist/cli/history.d.ts +22 -0
- package/dist/cli/history.d.ts.map +1 -0
- package/dist/cli/history.js +140 -0
- package/dist/cli/history.js.map +1 -0
- package/dist/cli/init.d.ts +49 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +423 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/learn.d.ts +31 -0
- package/dist/cli/learn.d.ts.map +1 -0
- package/dist/cli/learn.js +320 -0
- package/dist/cli/learn.js.map +1 -0
- package/dist/cli/memory.d.ts +38 -0
- package/dist/cli/memory.d.ts.map +1 -0
- package/dist/cli/memory.js +295 -0
- package/dist/cli/memory.js.map +1 -0
- package/dist/cli/model-picker.d.ts +18 -0
- package/dist/cli/model-picker.d.ts.map +1 -0
- package/dist/cli/model-picker.js +225 -0
- package/dist/cli/model-picker.js.map +1 -0
- package/dist/cli/models.d.ts +11 -0
- package/dist/cli/models.d.ts.map +1 -0
- package/dist/cli/models.js +132 -0
- package/dist/cli/models.js.map +1 -0
- package/dist/cli/plan.d.ts +11 -0
- package/dist/cli/plan.d.ts.map +1 -0
- package/dist/cli/plan.js +94 -0
- package/dist/cli/plan.js.map +1 -0
- package/dist/cli/plugins.d.ts +15 -0
- package/dist/cli/plugins.d.ts.map +1 -0
- package/dist/cli/plugins.js +123 -0
- package/dist/cli/plugins.js.map +1 -0
- package/dist/cli/router.d.ts +20 -0
- package/dist/cli/router.d.ts.map +1 -0
- package/dist/cli/router.js +142 -0
- package/dist/cli/router.js.map +1 -0
- package/dist/cli/run.d.ts +22 -0
- package/dist/cli/run.d.ts.map +1 -0
- package/dist/cli/run.js +110 -0
- package/dist/cli/run.js.map +1 -0
- package/dist/cli/sandbox.d.ts +27 -0
- package/dist/cli/sandbox.d.ts.map +1 -0
- package/dist/cli/sandbox.js +264 -0
- package/dist/cli/sandbox.js.map +1 -0
- package/dist/cli/sdk.d.ts +27 -0
- package/dist/cli/sdk.d.ts.map +1 -0
- package/dist/cli/sdk.js +204 -0
- package/dist/cli/sdk.js.map +1 -0
- package/dist/cli/stats.d.ts +18 -0
- package/dist/cli/stats.d.ts.map +1 -0
- package/dist/cli/stats.js +78 -0
- package/dist/cli/stats.js.map +1 -0
- package/dist/cli/team.d.ts +42 -0
- package/dist/cli/team.d.ts.map +1 -0
- package/dist/cli/team.js +473 -0
- package/dist/cli/team.js.map +1 -0
- package/dist/cli/workflow.d.ts +27 -0
- package/dist/cli/workflow.d.ts.map +1 -0
- package/dist/cli/workflow.js +347 -0
- package/dist/cli/workflow.js.map +1 -0
- package/dist/config/manager.d.ts +37 -0
- package/dist/config/manager.d.ts.map +1 -0
- package/dist/config/manager.js +147 -0
- package/dist/config/manager.js.map +1 -0
- package/dist/config/types.d.ts +53 -0
- package/dist/config/types.d.ts.map +1 -0
- package/dist/config/types.js +2 -0
- package/dist/config/types.js.map +1 -0
- package/dist/context/cache.d.ts +27 -0
- package/dist/context/cache.d.ts.map +1 -0
- package/dist/context/cache.js +116 -0
- package/dist/context/cache.js.map +1 -0
- package/dist/context/history.d.ts +87 -0
- package/dist/context/history.d.ts.map +1 -0
- package/dist/context/history.js +249 -0
- package/dist/context/history.js.map +1 -0
- package/dist/context/parser.d.ts +61 -0
- package/dist/context/parser.d.ts.map +1 -0
- package/dist/context/parser.js +194 -0
- package/dist/context/parser.js.map +1 -0
- package/dist/federation/client.d.ts +49 -0
- package/dist/federation/client.d.ts.map +1 -0
- package/dist/federation/client.js +239 -0
- package/dist/federation/client.js.map +1 -0
- package/dist/federation/protocol.d.ts +155 -0
- package/dist/federation/protocol.d.ts.map +1 -0
- package/dist/federation/protocol.js +57 -0
- package/dist/federation/protocol.js.map +1 -0
- package/dist/federation/server.d.ts +25 -0
- package/dist/federation/server.d.ts.map +1 -0
- package/dist/federation/server.js +401 -0
- package/dist/federation/server.js.map +1 -0
- package/dist/index.d.ts +67 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/inference/factory.d.ts +20 -0
- package/dist/inference/factory.d.ts.map +1 -0
- package/dist/inference/factory.js +46 -0
- package/dist/inference/factory.js.map +1 -0
- package/dist/inference/gemini-adapter.d.ts +17 -0
- package/dist/inference/gemini-adapter.d.ts.map +1 -0
- package/dist/inference/gemini-adapter.js +176 -0
- package/dist/inference/gemini-adapter.js.map +1 -0
- package/dist/inference/groq-adapter.d.ts +17 -0
- package/dist/inference/groq-adapter.d.ts.map +1 -0
- package/dist/inference/groq-adapter.js +103 -0
- package/dist/inference/groq-adapter.js.map +1 -0
- package/dist/inference/interface.d.ts +49 -0
- package/dist/inference/interface.d.ts.map +1 -0
- package/dist/inference/interface.js +2 -0
- package/dist/inference/interface.js.map +1 -0
- package/dist/inference/local-adapter.d.ts +35 -0
- package/dist/inference/local-adapter.d.ts.map +1 -0
- package/dist/inference/local-adapter.js +311 -0
- package/dist/inference/local-adapter.js.map +1 -0
- package/dist/inference/model-catalog.d.ts +53 -0
- package/dist/inference/model-catalog.d.ts.map +1 -0
- package/dist/inference/model-catalog.js +306 -0
- package/dist/inference/model-catalog.js.map +1 -0
- package/dist/inference/nim-adapter.d.ts +17 -0
- package/dist/inference/nim-adapter.d.ts.map +1 -0
- package/dist/inference/nim-adapter.js +103 -0
- package/dist/inference/nim-adapter.js.map +1 -0
- package/dist/inference/openrouter-adapter.d.ts +17 -0
- package/dist/inference/openrouter-adapter.d.ts.map +1 -0
- package/dist/inference/openrouter-adapter.js +105 -0
- package/dist/inference/openrouter-adapter.js.map +1 -0
- package/dist/inference/sse.d.ts +20 -0
- package/dist/inference/sse.d.ts.map +1 -0
- package/dist/inference/sse.js +91 -0
- package/dist/inference/sse.js.map +1 -0
- package/dist/learning/agent-stats.d.ts +109 -0
- package/dist/learning/agent-stats.d.ts.map +1 -0
- package/dist/learning/agent-stats.js +240 -0
- package/dist/learning/agent-stats.js.map +1 -0
- package/dist/learning/benchmark.d.ts +161 -0
- package/dist/learning/benchmark.d.ts.map +1 -0
- package/dist/learning/benchmark.js +589 -0
- package/dist/learning/benchmark.js.map +1 -0
- package/dist/learning/cost-tracker.d.ts +101 -0
- package/dist/learning/cost-tracker.d.ts.map +1 -0
- package/dist/learning/cost-tracker.js +224 -0
- package/dist/learning/cost-tracker.js.map +1 -0
- package/dist/learning/feedback.d.ts +88 -0
- package/dist/learning/feedback.d.ts.map +1 -0
- package/dist/learning/feedback.js +169 -0
- package/dist/learning/feedback.js.map +1 -0
- package/dist/learning/hybrid-router.d.ts +201 -0
- package/dist/learning/hybrid-router.d.ts.map +1 -0
- package/dist/learning/hybrid-router.js +450 -0
- package/dist/learning/hybrid-router.js.map +1 -0
- package/dist/learning/model-compare.d.ts +76 -0
- package/dist/learning/model-compare.d.ts.map +1 -0
- package/dist/learning/model-compare.js +252 -0
- package/dist/learning/model-compare.js.map +1 -0
- package/dist/learning/model-router.d.ts +68 -0
- package/dist/learning/model-router.d.ts.map +1 -0
- package/dist/learning/model-router.js +140 -0
- package/dist/learning/model-router.js.map +1 -0
- package/dist/learning/pattern-extractor.d.ts +99 -0
- package/dist/learning/pattern-extractor.d.ts.map +1 -0
- package/dist/learning/pattern-extractor.js +310 -0
- package/dist/learning/pattern-extractor.js.map +1 -0
- package/dist/learning/scorer.d.ts +51 -0
- package/dist/learning/scorer.d.ts.map +1 -0
- package/dist/learning/scorer.js +64 -0
- package/dist/learning/scorer.js.map +1 -0
- package/dist/learning/self-improver.d.ts +48 -0
- package/dist/learning/self-improver.d.ts.map +1 -0
- package/dist/learning/self-improver.js +161 -0
- package/dist/learning/self-improver.js.map +1 -0
- package/dist/memory/embedder.d.ts +65 -0
- package/dist/memory/embedder.d.ts.map +1 -0
- package/dist/memory/embedder.js +424 -0
- package/dist/memory/embedder.js.map +1 -0
- package/dist/memory/memory-integration.d.ts +56 -0
- package/dist/memory/memory-integration.d.ts.map +1 -0
- package/dist/memory/memory-integration.js +95 -0
- package/dist/memory/memory-integration.js.map +1 -0
- package/dist/memory/trajectory-store.d.ts +149 -0
- package/dist/memory/trajectory-store.d.ts.map +1 -0
- package/dist/memory/trajectory-store.js +476 -0
- package/dist/memory/trajectory-store.js.map +1 -0
- package/dist/memory/vector-store.d.ts +78 -0
- package/dist/memory/vector-store.d.ts.map +1 -0
- package/dist/memory/vector-store.js +186 -0
- package/dist/memory/vector-store.js.map +1 -0
- package/dist/plugins/agent-plugin.d.ts +73 -0
- package/dist/plugins/agent-plugin.d.ts.map +1 -0
- package/dist/plugins/agent-plugin.js +199 -0
- package/dist/plugins/agent-plugin.js.map +1 -0
- package/dist/plugins/registry.d.ts +61 -0
- package/dist/plugins/registry.d.ts.map +1 -0
- package/dist/plugins/registry.js +67 -0
- package/dist/plugins/registry.js.map +1 -0
- package/dist/sandbox/images.d.ts +31 -0
- package/dist/sandbox/images.d.ts.map +1 -0
- package/dist/sandbox/images.js +129 -0
- package/dist/sandbox/images.js.map +1 -0
- package/dist/sandbox/manager.d.ts +134 -0
- package/dist/sandbox/manager.d.ts.map +1 -0
- package/dist/sandbox/manager.js +470 -0
- package/dist/sandbox/manager.js.map +1 -0
- package/dist/sandbox/types.d.ts +113 -0
- package/dist/sandbox/types.d.ts.map +1 -0
- package/dist/sandbox/types.js +107 -0
- package/dist/sandbox/types.js.map +1 -0
- package/dist/security/scanner.d.ts +53 -0
- package/dist/security/scanner.d.ts.map +1 -0
- package/dist/security/scanner.js +271 -0
- package/dist/security/scanner.js.map +1 -0
- package/dist/team/config.d.ts +50 -0
- package/dist/team/config.d.ts.map +1 -0
- package/dist/team/config.js +108 -0
- package/dist/team/config.js.map +1 -0
- package/dist/team/memory.d.ts +63 -0
- package/dist/team/memory.d.ts.map +1 -0
- package/dist/team/memory.js +282 -0
- package/dist/team/memory.js.map +1 -0
- package/dist/team/review.d.ts +123 -0
- package/dist/team/review.d.ts.map +1 -0
- package/dist/team/review.js +293 -0
- package/dist/team/review.js.map +1 -0
- package/dist/utils/env.d.ts +19 -0
- package/dist/utils/env.d.ts.map +1 -0
- package/dist/utils/env.js +250 -0
- package/dist/utils/env.js.map +1 -0
- package/dist/utils/logger.d.ts +11 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +45 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/web-dashboard/server.d.ts +59 -0
- package/dist/web-dashboard/server.d.ts.map +1 -0
- package/dist/web-dashboard/server.js +418 -0
- package/dist/web-dashboard/server.js.map +1 -0
- package/dist/workflow/registry.d.ts +127 -0
- package/dist/workflow/registry.d.ts.map +1 -0
- package/dist/workflow/registry.js +482 -0
- package/dist/workflow/registry.js.map +1 -0
- package/dist/workflow/templates.d.ts +93 -0
- package/dist/workflow/templates.d.ts.map +1 -0
- package/dist/workflow/templates.js +481 -0
- package/dist/workflow/templates.js.map +1 -0
- package/package.json +78 -0
- package/src/web-dashboard/public/assets/index-B08nDkSB.css +1 -0
- package/src/web-dashboard/public/assets/index-BKL8YOFD.js +135 -0
- package/src/web-dashboard/public/assets/index-BKL8YOFD.js.map +1 -0
- package/src/web-dashboard/public/index.html +13 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker — Tracks API usage costs per provider per session.
|
|
3
|
+
*
|
|
4
|
+
* Stores cost data as JSON at ~/.buff/memory/cost-tracker.json
|
|
5
|
+
* and provides CLI commands to view costs.
|
|
6
|
+
*
|
|
7
|
+
* Cost per 1K tokens (approximate, in USD):
|
|
8
|
+
* - Groq: llama-3.3-70b = $0.59/$0.79, llama-3.1-8b = $0.05/$0.08
|
|
9
|
+
* - NVIDIA NIM: varies by model, typically $0.10-$0.50/$1K
|
|
10
|
+
* - Google Gemini: free tier (limited), paid tier ~$0.10/$1K
|
|
11
|
+
* - OpenRouter: varies by model (pass-through pricing)
|
|
12
|
+
* - Local: free
|
|
13
|
+
*
|
|
14
|
+
* Costs are configurable via config file for accuracy.
|
|
15
|
+
*/
|
|
16
|
+
export interface CostEntry {
|
|
17
|
+
/** Provider name (e.g., 'groq', 'gemini', 'openrouter', 'nim', 'local') */
|
|
18
|
+
provider: string;
|
|
19
|
+
/** Model name used */
|
|
20
|
+
model: string;
|
|
21
|
+
/** Timestamp of the request */
|
|
22
|
+
timestamp: number;
|
|
23
|
+
/** Input tokens used */
|
|
24
|
+
inputTokens: number;
|
|
25
|
+
/** Output tokens generated */
|
|
26
|
+
outputTokens: number;
|
|
27
|
+
/** Total tokens */
|
|
28
|
+
totalTokens: number;
|
|
29
|
+
/** Estimated cost in USD (micro-cents precision) */
|
|
30
|
+
costUsd: number;
|
|
31
|
+
/** The task/goal that triggered this request */
|
|
32
|
+
task?: string;
|
|
33
|
+
}
|
|
34
|
+
export interface CostSummary {
|
|
35
|
+
/** Total cost in USD across all time */
|
|
36
|
+
totalCost: number;
|
|
37
|
+
/** Total cost by provider */
|
|
38
|
+
byProvider: Record<string, number>;
|
|
39
|
+
/** Total cost by model */
|
|
40
|
+
byModel: Record<string, number>;
|
|
41
|
+
/** Total tokens consumed */
|
|
42
|
+
totalTokens: number;
|
|
43
|
+
/** Total requests made */
|
|
44
|
+
totalRequests: number;
|
|
45
|
+
/** Number of entries in the current session */
|
|
46
|
+
sessionRequests: number;
|
|
47
|
+
/** Session cost in USD */
|
|
48
|
+
sessionCost: number;
|
|
49
|
+
/** Session start timestamp */
|
|
50
|
+
sessionStart: number;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Estimate the number of tokens from text length.
|
|
54
|
+
* Rough heuristic: ~4 characters per token for code, ~5 for prose.
|
|
55
|
+
*/
|
|
56
|
+
export declare function estimateTokens(text: string): number;
|
|
57
|
+
/**
|
|
58
|
+
* Calculate the cost for a given provider, model, and token counts.
|
|
59
|
+
*/
|
|
60
|
+
export declare function calculateCost(provider: string, model: string, inputTokens: number, outputTokens: number): number;
|
|
61
|
+
/**
|
|
62
|
+
* Tracks API usage costs per provider.
|
|
63
|
+
*/
|
|
64
|
+
export declare class CostTracker {
|
|
65
|
+
private sessionStart;
|
|
66
|
+
private sessionEntries;
|
|
67
|
+
constructor();
|
|
68
|
+
/**
|
|
69
|
+
* Record a single API call's cost.
|
|
70
|
+
*
|
|
71
|
+
* @param provider Provider name
|
|
72
|
+
* @param model Model name
|
|
73
|
+
* @param inputTokens Input tokens used (or estimated)
|
|
74
|
+
* @param outputTokens Output tokens generated (or estimated)
|
|
75
|
+
* @param task Optional task description
|
|
76
|
+
*/
|
|
77
|
+
recordCall(provider: string, model: string, inputTokens: number, outputTokens: number, task?: string): CostEntry;
|
|
78
|
+
/**
|
|
79
|
+
* Record a call with estimated tokens from prompt/response lengths.
|
|
80
|
+
* Useful when the API doesn't return exact token counts.
|
|
81
|
+
*/
|
|
82
|
+
recordCallEstimated(provider: string, model: string, promptText: string, responseText: string, task?: string): CostEntry;
|
|
83
|
+
/**
|
|
84
|
+
* Get cost summary across all time and current session.
|
|
85
|
+
*/
|
|
86
|
+
getSummary(): CostSummary;
|
|
87
|
+
/**
|
|
88
|
+
* Format cost summary as a human-readable string.
|
|
89
|
+
*/
|
|
90
|
+
formatSummary(): string;
|
|
91
|
+
/**
|
|
92
|
+
* Clear all cost tracking data.
|
|
93
|
+
*/
|
|
94
|
+
clear(): void;
|
|
95
|
+
/**
|
|
96
|
+
* Get all cost entries (for export).
|
|
97
|
+
*/
|
|
98
|
+
getAllEntries(): CostEntry[];
|
|
99
|
+
}
|
|
100
|
+
export declare function getCostTracker(): CostTracker;
|
|
101
|
+
//# sourceMappingURL=cost-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.d.ts","sourceRoot":"","sources":["../../src/learning/cost-tracker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAQH,MAAM,WAAW,SAAS;IACxB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,+BAA+B;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC;IAChB,gDAAgD;IAChD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,WAAW;IAC1B,wCAAwC;IACxC,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,0BAA0B;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,4BAA4B;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,0BAA0B;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,+CAA+C;IAC/C,eAAe,EAAE,MAAM,CAAC;IACxB,0BAA0B;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,8BAA8B;IAC9B,YAAY,EAAE,MAAM,CAAC;CACtB;AAuDD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,MAAM,CAiBR;AAID;;GAEG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,cAAc,CAAmB;;IAMzC;;;;;;;;OAQG;IACH,UAAU,CACR,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS;IA+BZ;;;OAGG;IACH,mBAAmB,CACjB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,MAAM,EACpB,IAAI,CAAC,EAAE,MAAM,GACZ,SAAS;IAMZ;;OAEG;IACH,UAAU,IAAI,WAAW;IA8BzB;;OAEG;IACH,aAAa,IAAI,MAAM;IAsCvB;;OAEG;IACH,KAAK,IAAI,IAAI;IAMb;;OAEG;IACH,aAAa,IAAI,SAAS,EAAE;CAI7B;AAKD,wBAAgB,cAAc,IAAI,WAAW,CAK5C"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CostTracker — Tracks API usage costs per provider per session.
|
|
3
|
+
*
|
|
4
|
+
* Stores cost data as JSON at ~/.buff/memory/cost-tracker.json
|
|
5
|
+
* and provides CLI commands to view costs.
|
|
6
|
+
*
|
|
7
|
+
* Cost per 1K tokens (approximate, in USD):
|
|
8
|
+
* - Groq: llama-3.3-70b = $0.59/$0.79, llama-3.1-8b = $0.05/$0.08
|
|
9
|
+
* - NVIDIA NIM: varies by model, typically $0.10-$0.50/$1K
|
|
10
|
+
* - Google Gemini: free tier (limited), paid tier ~$0.10/$1K
|
|
11
|
+
* - OpenRouter: varies by model (pass-through pricing)
|
|
12
|
+
* - Local: free
|
|
13
|
+
*
|
|
14
|
+
* Costs are configurable via config file for accuracy.
|
|
15
|
+
*/
|
|
16
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
20
|
+
const MEMORY_DIR = join(homedir(), '.buff', 'memory');
|
|
21
|
+
const COST_PATH = join(MEMORY_DIR, 'cost-tracker.json');
|
|
22
|
+
const CURRENT_VERSION = 1;
|
|
23
|
+
/**
|
|
24
|
+
* Default pricing per 1K tokens (input/output) in USD.
|
|
25
|
+
* Users can override these via config file.
|
|
26
|
+
* Source: provider pricing pages (approximate, may change).
|
|
27
|
+
*/
|
|
28
|
+
const DEFAULT_PRICING = {
|
|
29
|
+
groq: { inputPer1K: 0.00059, outputPer1K: 0.00079 }, // Average across models
|
|
30
|
+
nim: { inputPer1K: 0.00010, outputPer1K: 0.00050 }, // Varies by model
|
|
31
|
+
gemini: { inputPer1K: 0, outputPer1K: 0 }, // Free tier by default
|
|
32
|
+
openrouter: { inputPer1K: 0.00010, outputPer1K: 0.00010 }, // Minimum; most models cost more
|
|
33
|
+
local: { inputPer1K: 0, outputPer1K: 0 }, // Free (local compute)
|
|
34
|
+
};
|
|
35
|
+
/** Maximum number of cost entries to keep */
|
|
36
|
+
const MAX_ENTRIES = 10000;
|
|
37
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
38
|
+
function ensureDir() {
|
|
39
|
+
if (!existsSync(MEMORY_DIR)) {
|
|
40
|
+
mkdirSync(MEMORY_DIR, { recursive: true });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function readCosts() {
|
|
44
|
+
try {
|
|
45
|
+
ensureDir();
|
|
46
|
+
if (!existsSync(COST_PATH)) {
|
|
47
|
+
return { entries: [], version: CURRENT_VERSION };
|
|
48
|
+
}
|
|
49
|
+
const raw = readFileSync(COST_PATH, 'utf-8');
|
|
50
|
+
return JSON.parse(raw);
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return { entries: [], version: CURRENT_VERSION };
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function writeCosts(data) {
|
|
57
|
+
ensureDir();
|
|
58
|
+
writeFileSync(COST_PATH, JSON.stringify(data, null, 2), 'utf-8');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Estimate the number of tokens from text length.
|
|
62
|
+
* Rough heuristic: ~4 characters per token for code, ~5 for prose.
|
|
63
|
+
*/
|
|
64
|
+
export function estimateTokens(text) {
|
|
65
|
+
return Math.ceil(text.length / 4.5);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Calculate the cost for a given provider, model, and token counts.
|
|
69
|
+
*/
|
|
70
|
+
export function calculateCost(provider, model, inputTokens, outputTokens) {
|
|
71
|
+
const pricing = DEFAULT_PRICING[provider] || { inputPer1K: 0.00010, outputPer1K: 0.00010 };
|
|
72
|
+
// Model-specific pricing overrides for known expensive models
|
|
73
|
+
const expensiveModels = {
|
|
74
|
+
'llama-3.3-70b-versatile': { inputPer1K: 0.00059, outputPer1K: 0.00079 },
|
|
75
|
+
'llama-3.1-405b-reasoning': { inputPer1K: 0.00279, outputPer1K: 0.00279 },
|
|
76
|
+
'mixtral-8x7b-32768': { inputPer1K: 0.00024, outputPer1K: 0.00024 },
|
|
77
|
+
};
|
|
78
|
+
const modelPricing = expensiveModels[model];
|
|
79
|
+
const p = modelPricing || pricing;
|
|
80
|
+
const inputCost = (inputTokens / 1000) * p.inputPer1K;
|
|
81
|
+
const outputCost = (outputTokens / 1000) * p.outputPer1K;
|
|
82
|
+
return Math.round((inputCost + outputCost) * 100000) / 100000; // Micro-cent precision
|
|
83
|
+
}
|
|
84
|
+
// ─── CostTracker ────────────────────────────────────────────────────────────
|
|
85
|
+
/**
|
|
86
|
+
* Tracks API usage costs per provider.
|
|
87
|
+
*/
|
|
88
|
+
export class CostTracker {
|
|
89
|
+
sessionStart;
|
|
90
|
+
sessionEntries = [];
|
|
91
|
+
constructor() {
|
|
92
|
+
this.sessionStart = Date.now();
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Record a single API call's cost.
|
|
96
|
+
*
|
|
97
|
+
* @param provider Provider name
|
|
98
|
+
* @param model Model name
|
|
99
|
+
* @param inputTokens Input tokens used (or estimated)
|
|
100
|
+
* @param outputTokens Output tokens generated (or estimated)
|
|
101
|
+
* @param task Optional task description
|
|
102
|
+
*/
|
|
103
|
+
recordCall(provider, model, inputTokens, outputTokens, task) {
|
|
104
|
+
const costUsd = calculateCost(provider, model, inputTokens, outputTokens);
|
|
105
|
+
const entry = {
|
|
106
|
+
provider,
|
|
107
|
+
model,
|
|
108
|
+
timestamp: Date.now(),
|
|
109
|
+
inputTokens,
|
|
110
|
+
outputTokens,
|
|
111
|
+
totalTokens: inputTokens + outputTokens,
|
|
112
|
+
costUsd,
|
|
113
|
+
task,
|
|
114
|
+
};
|
|
115
|
+
// Store in session
|
|
116
|
+
this.sessionEntries.push(entry);
|
|
117
|
+
// Persist to disk
|
|
118
|
+
const data = readCosts();
|
|
119
|
+
data.entries.push(entry);
|
|
120
|
+
// Prune old entries if over limit
|
|
121
|
+
if (data.entries.length > MAX_ENTRIES) {
|
|
122
|
+
data.entries = data.entries.slice(-MAX_ENTRIES);
|
|
123
|
+
}
|
|
124
|
+
writeCosts(data);
|
|
125
|
+
return entry;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Record a call with estimated tokens from prompt/response lengths.
|
|
129
|
+
* Useful when the API doesn't return exact token counts.
|
|
130
|
+
*/
|
|
131
|
+
recordCallEstimated(provider, model, promptText, responseText, task) {
|
|
132
|
+
const inputTokens = estimateTokens(promptText);
|
|
133
|
+
const outputTokens = estimateTokens(responseText);
|
|
134
|
+
return this.recordCall(provider, model, inputTokens, outputTokens, task);
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Get cost summary across all time and current session.
|
|
138
|
+
*/
|
|
139
|
+
getSummary() {
|
|
140
|
+
const data = readCosts();
|
|
141
|
+
const allEntries = data.entries;
|
|
142
|
+
const byProvider = {};
|
|
143
|
+
const byModel = {};
|
|
144
|
+
let totalCost = 0;
|
|
145
|
+
let totalTokens = 0;
|
|
146
|
+
for (const entry of allEntries) {
|
|
147
|
+
totalCost += entry.costUsd;
|
|
148
|
+
totalTokens += entry.totalTokens;
|
|
149
|
+
byProvider[entry.provider] = (byProvider[entry.provider] || 0) + entry.costUsd;
|
|
150
|
+
byModel[entry.model] = (byModel[entry.model] || 0) + entry.costUsd;
|
|
151
|
+
}
|
|
152
|
+
const sessionCost = this.sessionEntries.reduce((sum, e) => sum + e.costUsd, 0);
|
|
153
|
+
return {
|
|
154
|
+
totalCost: Math.round(totalCost * 100000) / 100000,
|
|
155
|
+
byProvider,
|
|
156
|
+
byModel,
|
|
157
|
+
totalTokens,
|
|
158
|
+
totalRequests: allEntries.length,
|
|
159
|
+
sessionRequests: this.sessionEntries.length,
|
|
160
|
+
sessionCost: Math.round(sessionCost * 100000) / 100000,
|
|
161
|
+
sessionStart: this.sessionStart,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Format cost summary as a human-readable string.
|
|
166
|
+
*/
|
|
167
|
+
formatSummary() {
|
|
168
|
+
const summary = this.getSummary();
|
|
169
|
+
const lines = [
|
|
170
|
+
'💰 Cost Tracker',
|
|
171
|
+
'',
|
|
172
|
+
'── Session ──',
|
|
173
|
+
` Started: ${new Date(summary.sessionStart).toLocaleString()}`,
|
|
174
|
+
` Requests: ${summary.sessionRequests}`,
|
|
175
|
+
` Session cost: $${summary.sessionCost.toFixed(6)}`,
|
|
176
|
+
'',
|
|
177
|
+
'── All Time ──',
|
|
178
|
+
` Total requests: ${summary.totalRequests}`,
|
|
179
|
+
` Total tokens: ${summary.totalTokens.toLocaleString()}`,
|
|
180
|
+
` Total cost: $${summary.totalCost.toFixed(6)}`,
|
|
181
|
+
'',
|
|
182
|
+
];
|
|
183
|
+
if (Object.keys(summary.byProvider).length > 0) {
|
|
184
|
+
lines.push('── By Provider ──');
|
|
185
|
+
for (const [provider, cost] of Object.entries(summary.byProvider).sort(([, a], [, b]) => b - a)) {
|
|
186
|
+
const pct = summary.totalCost > 0 ? (cost / summary.totalCost * 100).toFixed(1) : '0.0';
|
|
187
|
+
lines.push(` ${provider.padEnd(15)} $${cost.toFixed(6)} (${pct}%)`);
|
|
188
|
+
}
|
|
189
|
+
lines.push('');
|
|
190
|
+
}
|
|
191
|
+
if (Object.keys(summary.byModel).length > 0) {
|
|
192
|
+
lines.push('── By Model ──');
|
|
193
|
+
for (const [model, cost] of Object.entries(summary.byModel).sort(([, a], [, b]) => b - a).slice(0, 10)) {
|
|
194
|
+
lines.push(` ${model.padEnd(40)} $${cost.toFixed(6)}`);
|
|
195
|
+
}
|
|
196
|
+
lines.push('');
|
|
197
|
+
}
|
|
198
|
+
return lines.join('\n');
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Clear all cost tracking data.
|
|
202
|
+
*/
|
|
203
|
+
clear() {
|
|
204
|
+
this.sessionEntries = [];
|
|
205
|
+
this.sessionStart = Date.now();
|
|
206
|
+
writeCosts({ entries: [], version: CURRENT_VERSION });
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get all cost entries (for export).
|
|
210
|
+
*/
|
|
211
|
+
getAllEntries() {
|
|
212
|
+
const data = readCosts();
|
|
213
|
+
return [...data.entries];
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Singleton instance
|
|
217
|
+
let trackerInstance = null;
|
|
218
|
+
export function getCostTracker() {
|
|
219
|
+
if (!trackerInstance) {
|
|
220
|
+
trackerInstance = new CostTracker();
|
|
221
|
+
}
|
|
222
|
+
return trackerInstance;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=cost-tracker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-tracker.js","sourceRoot":"","sources":["../../src/learning/cost-tracker.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback — User feedback integration for the self-improvement system.
|
|
3
|
+
*
|
|
4
|
+
* Tracks user ratings (👍/👎/skip) on individual trajectory results and
|
|
5
|
+
* injects those scores back into the scoring system. This enables the
|
|
6
|
+
* self-improver to learn which kinds of outputs users actually find useful.
|
|
7
|
+
*
|
|
8
|
+
* Data stored at: ~/.buff/memory/feedback.json
|
|
9
|
+
*
|
|
10
|
+
* The feedback system provides:
|
|
11
|
+
* - Simple rating collection (positive, negative, neutral)
|
|
12
|
+
* - Rating trails (sequences of ratings over time)
|
|
13
|
+
* - Score injection into trajectory search ranking
|
|
14
|
+
* - Feedback-driven pattern validation
|
|
15
|
+
*/
|
|
16
|
+
/** User rating for a specific execution result */
|
|
17
|
+
export type Rating = 'positive' | 'negative' | 'neutral' | 'skip';
|
|
18
|
+
/** A single feedback record */
|
|
19
|
+
export interface FeedbackEntry {
|
|
20
|
+
/** Unique feedback ID */
|
|
21
|
+
id: string;
|
|
22
|
+
/** Trajectory ID this feedback refers to */
|
|
23
|
+
trajectoryId: string;
|
|
24
|
+
/** User rating */
|
|
25
|
+
rating: Rating;
|
|
26
|
+
/** Optional user comment */
|
|
27
|
+
comment?: string;
|
|
28
|
+
/** Which goal/command was being executed */
|
|
29
|
+
goal: string;
|
|
30
|
+
/** Which provider/model was used */
|
|
31
|
+
provider: string;
|
|
32
|
+
model: string;
|
|
33
|
+
/** Timestamp */
|
|
34
|
+
createdAt: number;
|
|
35
|
+
/** Source of the feedback (cli, api, etc.) */
|
|
36
|
+
source: string;
|
|
37
|
+
}
|
|
38
|
+
/** Aggregated feedback statistics */
|
|
39
|
+
export interface FeedbackStats {
|
|
40
|
+
totalRatings: number;
|
|
41
|
+
positiveRatio: number;
|
|
42
|
+
negativeRatio: number;
|
|
43
|
+
neutralRatio: number;
|
|
44
|
+
recentTrend: 'improving' | 'declining' | 'stable';
|
|
45
|
+
}
|
|
46
|
+
export declare class FeedbackStore {
|
|
47
|
+
private entries;
|
|
48
|
+
constructor();
|
|
49
|
+
/**
|
|
50
|
+
* Record a user rating.
|
|
51
|
+
*/
|
|
52
|
+
record(trajectoryId: string, rating: Rating, context: {
|
|
53
|
+
goal: string;
|
|
54
|
+
provider: string;
|
|
55
|
+
model: string;
|
|
56
|
+
comment?: string;
|
|
57
|
+
}): FeedbackEntry;
|
|
58
|
+
/**
|
|
59
|
+
* Get all feedback entries.
|
|
60
|
+
*/
|
|
61
|
+
getAll(): FeedbackEntry[];
|
|
62
|
+
/**
|
|
63
|
+
* Get feedback for a specific trajectory.
|
|
64
|
+
*/
|
|
65
|
+
getByTrajectory(trajectoryId: string): FeedbackEntry[];
|
|
66
|
+
/**
|
|
67
|
+
* Get the most recent rating for a trajectory (if any).
|
|
68
|
+
*/
|
|
69
|
+
getLastRating(trajectoryId: string): Rating | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Convert a user rating to a score multiplier for trajectory ranking.
|
|
72
|
+
* Positive → +0.3, Negative → -0.3, Neutral → 0, Skip → 0
|
|
73
|
+
*/
|
|
74
|
+
ratingToScoreDelta(rating: Rating): number;
|
|
75
|
+
/**
|
|
76
|
+
* Get aggregated feedback statistics.
|
|
77
|
+
*/
|
|
78
|
+
getStats(): FeedbackStats;
|
|
79
|
+
/**
|
|
80
|
+
* Clear all feedback data.
|
|
81
|
+
*/
|
|
82
|
+
clear(): void;
|
|
83
|
+
private load;
|
|
84
|
+
private save;
|
|
85
|
+
}
|
|
86
|
+
export declare function getFeedbackStore(): FeedbackStore;
|
|
87
|
+
export declare function resetFeedbackStore(): void;
|
|
88
|
+
//# sourceMappingURL=feedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/learning/feedback.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAUH,kDAAkD;AAClD,MAAM,MAAM,MAAM,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,CAAC;AAElE,+BAA+B;AAC/B,MAAM,WAAW,aAAa;IAC5B,yBAAyB;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,YAAY,EAAE,MAAM,CAAC;IACrB,kBAAkB;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,gBAAgB;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,8CAA8C;IAC9C,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,qCAAqC;AACrC,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,WAAW,GAAG,WAAW,GAAG,QAAQ,CAAC;CACnD;AAkBD,qBAAa,aAAa;IACxB,OAAO,CAAC,OAAO,CAAuB;;IAQtC;;OAEG;IACH,MAAM,CACJ,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,CAAC,EAAE,MAAM,CAAC;KAClB,GACA,aAAa;IAwBhB;;OAEG;IACH,MAAM,IAAI,aAAa,EAAE;IAIzB;;OAEG;IACH,eAAe,CAAC,YAAY,EAAE,MAAM,GAAG,aAAa,EAAE;IAItD;;OAEG;IACH,aAAa,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAQvD;;;OAGG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAS1C;;OAEG;IACH,QAAQ,IAAI,aAAa;IAsCzB;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,IAAI;IAYZ,OAAO,CAAC,IAAI;CAKb;AAMD,wBAAgB,gBAAgB,IAAI,aAAa,CAKhD;AAED,wBAAgB,kBAAkB,IAAI,IAAI,CAEzC"}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Feedback — User feedback integration for the self-improvement system.
|
|
3
|
+
*
|
|
4
|
+
* Tracks user ratings (👍/👎/skip) on individual trajectory results and
|
|
5
|
+
* injects those scores back into the scoring system. This enables the
|
|
6
|
+
* self-improver to learn which kinds of outputs users actually find useful.
|
|
7
|
+
*
|
|
8
|
+
* Data stored at: ~/.buff/memory/feedback.json
|
|
9
|
+
*
|
|
10
|
+
* The feedback system provides:
|
|
11
|
+
* - Simple rating collection (positive, negative, neutral)
|
|
12
|
+
* - Rating trails (sequences of ratings over time)
|
|
13
|
+
* - Score injection into trajectory search ranking
|
|
14
|
+
* - Feedback-driven pattern validation
|
|
15
|
+
*/
|
|
16
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'node:fs';
|
|
17
|
+
import { join } from 'node:path';
|
|
18
|
+
import { homedir } from 'node:os';
|
|
19
|
+
// ─── Constants ──────────────────────────────────────────────────────────────
|
|
20
|
+
const MEMORY_DIR = join(homedir(), '.buff', 'memory');
|
|
21
|
+
const FEEDBACK_PATH = join(MEMORY_DIR, 'feedback.json');
|
|
22
|
+
const CURRENT_VERSION = 1;
|
|
23
|
+
const MAX_ENTRIES = 1000;
|
|
24
|
+
const TREND_WINDOW = 10; // Last N ratings for trend calculation
|
|
25
|
+
// ─── FeedbackStore ──────────────────────────────────────────────────────────
|
|
26
|
+
export class FeedbackStore {
|
|
27
|
+
entries = [];
|
|
28
|
+
constructor() {
|
|
29
|
+
this.entries = this.load();
|
|
30
|
+
}
|
|
31
|
+
// ── Public API ──────────────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Record a user rating.
|
|
34
|
+
*/
|
|
35
|
+
record(trajectoryId, rating, context) {
|
|
36
|
+
const entry = {
|
|
37
|
+
id: `feedback-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
38
|
+
trajectoryId,
|
|
39
|
+
rating,
|
|
40
|
+
goal: context.goal,
|
|
41
|
+
provider: context.provider,
|
|
42
|
+
model: context.model,
|
|
43
|
+
createdAt: Date.now(),
|
|
44
|
+
source: 'cli',
|
|
45
|
+
comment: context.comment,
|
|
46
|
+
};
|
|
47
|
+
this.entries.push(entry);
|
|
48
|
+
// Prune old entries
|
|
49
|
+
if (this.entries.length > MAX_ENTRIES) {
|
|
50
|
+
this.entries = this.entries.slice(-MAX_ENTRIES);
|
|
51
|
+
}
|
|
52
|
+
this.save();
|
|
53
|
+
return entry;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Get all feedback entries.
|
|
57
|
+
*/
|
|
58
|
+
getAll() {
|
|
59
|
+
return [...this.entries];
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Get feedback for a specific trajectory.
|
|
63
|
+
*/
|
|
64
|
+
getByTrajectory(trajectoryId) {
|
|
65
|
+
return this.entries.filter((e) => e.trajectoryId === trajectoryId);
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Get the most recent rating for a trajectory (if any).
|
|
69
|
+
*/
|
|
70
|
+
getLastRating(trajectoryId) {
|
|
71
|
+
const trajectoryFeedback = this.entries
|
|
72
|
+
.filter((e) => e.trajectoryId === trajectoryId)
|
|
73
|
+
.sort((a, b) => b.createdAt - a.createdAt);
|
|
74
|
+
return trajectoryFeedback[0]?.rating;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Convert a user rating to a score multiplier for trajectory ranking.
|
|
78
|
+
* Positive → +0.3, Negative → -0.3, Neutral → 0, Skip → 0
|
|
79
|
+
*/
|
|
80
|
+
ratingToScoreDelta(rating) {
|
|
81
|
+
switch (rating) {
|
|
82
|
+
case 'positive': return 0.3;
|
|
83
|
+
case 'negative': return -0.3;
|
|
84
|
+
case 'neutral': return 0;
|
|
85
|
+
case 'skip': return 0;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Get aggregated feedback statistics.
|
|
90
|
+
*/
|
|
91
|
+
getStats() {
|
|
92
|
+
const total = this.entries.length;
|
|
93
|
+
if (total === 0) {
|
|
94
|
+
return { totalRatings: 0, positiveRatio: 0, negativeRatio: 0, neutralRatio: 0, recentTrend: 'stable' };
|
|
95
|
+
}
|
|
96
|
+
const positives = this.entries.filter((e) => e.rating === 'positive').length;
|
|
97
|
+
const negatives = this.entries.filter((e) => e.rating === 'negative').length;
|
|
98
|
+
const neutrals = this.entries.filter((e) => e.rating === 'neutral').length;
|
|
99
|
+
// Calculate trend from recent window
|
|
100
|
+
const recent = this.entries.slice(-TREND_WINDOW);
|
|
101
|
+
const recentPositives = recent.filter((e) => e.rating === 'positive').length;
|
|
102
|
+
const recentNegatives = recent.filter((e) => e.rating === 'negative').length;
|
|
103
|
+
const recentRatio = recentNegatives > 0 ? recentPositives / recentNegatives : recentPositives;
|
|
104
|
+
const overallPositives = this.entries.slice(0, -TREND_WINDOW).filter((e) => e.rating === 'positive').length;
|
|
105
|
+
const overallNegatives = this.entries.slice(0, -TREND_WINDOW).filter((e) => e.rating === 'negative').length;
|
|
106
|
+
const overallRatio = overallNegatives > 0 ? overallPositives / overallNegatives : overallPositives;
|
|
107
|
+
let recentTrend;
|
|
108
|
+
if (recentRatio > overallRatio * 1.1) {
|
|
109
|
+
recentTrend = 'improving';
|
|
110
|
+
}
|
|
111
|
+
else if (recentRatio < overallRatio * 0.9) {
|
|
112
|
+
recentTrend = 'declining';
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
recentTrend = 'stable';
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
totalRatings: total,
|
|
119
|
+
positiveRatio: total > 0 ? positives / total : 0,
|
|
120
|
+
negativeRatio: total > 0 ? negatives / total : 0,
|
|
121
|
+
neutralRatio: total > 0 ? neutrals / total : 0,
|
|
122
|
+
recentTrend,
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Clear all feedback data.
|
|
127
|
+
*/
|
|
128
|
+
clear() {
|
|
129
|
+
this.entries = [];
|
|
130
|
+
this.save();
|
|
131
|
+
}
|
|
132
|
+
// ── Private ────────────────────────────────────────────────────────────
|
|
133
|
+
load() {
|
|
134
|
+
try {
|
|
135
|
+
ensureDir();
|
|
136
|
+
if (!existsSync(FEEDBACK_PATH))
|
|
137
|
+
return [];
|
|
138
|
+
const raw = readFileSync(FEEDBACK_PATH, 'utf-8');
|
|
139
|
+
const data = JSON.parse(raw);
|
|
140
|
+
return data.entries || [];
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
save() {
|
|
147
|
+
ensureDir();
|
|
148
|
+
const data = { entries: this.entries, version: CURRENT_VERSION };
|
|
149
|
+
writeFileSync(FEEDBACK_PATH, JSON.stringify(data, null, 2), 'utf-8');
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
// ─── Singleton ──────────────────────────────────────────────────────────────
|
|
153
|
+
let storeInstance = null;
|
|
154
|
+
export function getFeedbackStore() {
|
|
155
|
+
if (!storeInstance) {
|
|
156
|
+
storeInstance = new FeedbackStore();
|
|
157
|
+
}
|
|
158
|
+
return storeInstance;
|
|
159
|
+
}
|
|
160
|
+
export function resetFeedbackStore() {
|
|
161
|
+
storeInstance = null;
|
|
162
|
+
}
|
|
163
|
+
// ─── Helpers ────────────────────────────────────────────────────────────────
|
|
164
|
+
function ensureDir() {
|
|
165
|
+
if (!existsSync(MEMORY_DIR)) {
|
|
166
|
+
mkdirSync(MEMORY_DIR, { recursive: true });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../../src/learning/feedback.ts"],"names":[],"mappings":"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"}
|