@planu/cli 0.24.0 → 0.26.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/dist/config/ai-model-pricing.json +81 -0
- package/dist/config/framework-registry/csharp-aspnet.json +67 -0
- package/dist/config/framework-registry/dart-flutter.json +61 -0
- package/dist/config/framework-registry/go-gin.json +62 -0
- package/dist/config/framework-registry/index.json +164 -0
- package/dist/config/framework-registry/java-springboot.json +67 -0
- package/dist/config/framework-registry/php-laravel.json +67 -0
- package/dist/config/framework-registry/python-django.json +72 -0
- package/dist/config/framework-registry/python-fastapi.json +72 -0
- package/dist/config/framework-registry/ruby-rails.json +67 -0
- package/dist/config/framework-registry/rust-actix.json +61 -0
- package/dist/config/framework-registry/swift-swiftui.json +67 -0
- package/dist/config/framework-registry/typescript-angular.json +67 -0
- package/dist/config/framework-registry/typescript-astro.json +61 -0
- package/dist/config/framework-registry/typescript-express.json +67 -0
- package/dist/config/framework-registry/typescript-nestjs.json +62 -0
- package/dist/config/framework-registry/typescript-nextjs.json +82 -0
- package/dist/config/framework-registry/typescript-nuxt.json +67 -0
- package/dist/config/framework-registry/typescript-react.json +77 -0
- package/dist/config/framework-registry/typescript-remix.json +61 -0
- package/dist/config/framework-registry/typescript-sveltekit.json +67 -0
- package/dist/config/framework-registry/typescript-vue.json +72 -0
- package/dist/config/license-plans.json +23 -3
- package/dist/engine/agile-config-builder.d.ts.map +1 -1
- package/dist/engine/agile-config-builder.js +3 -0
- package/dist/engine/agile-config-builder.js.map +1 -1
- package/dist/engine/ai-cost-estimator/core.d.ts +8 -0
- package/dist/engine/ai-cost-estimator/core.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/core.js +257 -0
- package/dist/engine/ai-cost-estimator/core.js.map +1 -0
- package/dist/engine/ai-cost-estimator/index.d.ts +4 -0
- package/dist/engine/ai-cost-estimator/index.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/index.js +5 -0
- package/dist/engine/ai-cost-estimator/index.js.map +1 -0
- package/dist/engine/ai-cost-estimator/model-pricing.d.ts +31 -0
- package/dist/engine/ai-cost-estimator/model-pricing.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/model-pricing.js +96 -0
- package/dist/engine/ai-cost-estimator/model-pricing.js.map +1 -0
- package/dist/engine/ai-cost-estimator/token-estimator.d.ts +37 -0
- package/dist/engine/ai-cost-estimator/token-estimator.d.ts.map +1 -0
- package/dist/engine/ai-cost-estimator/token-estimator.js +194 -0
- package/dist/engine/ai-cost-estimator/token-estimator.js.map +1 -0
- package/dist/engine/ci-generator/context-builders.d.ts +4 -0
- package/dist/engine/ci-generator/context-builders.d.ts.map +1 -0
- package/dist/engine/ci-generator/context-builders.js +129 -0
- package/dist/engine/ci-generator/context-builders.js.map +1 -0
- package/dist/engine/ci-generator/index.d.ts +7 -0
- package/dist/engine/ci-generator/index.d.ts.map +1 -0
- package/dist/engine/ci-generator/index.js +44 -0
- package/dist/engine/ci-generator/index.js.map +1 -0
- package/dist/engine/ci-generator/stack-detector.d.ts +21 -0
- package/dist/engine/ci-generator/stack-detector.d.ts.map +1 -0
- package/dist/engine/ci-generator/stack-detector.js +203 -0
- package/dist/engine/ci-generator/stack-detector.js.map +1 -0
- package/dist/engine/ci-generator/yaml-builder.d.ts +8 -0
- package/dist/engine/ci-generator/yaml-builder.d.ts.map +1 -0
- package/dist/engine/ci-generator/yaml-builder.js +285 -0
- package/dist/engine/ci-generator/yaml-builder.js.map +1 -0
- package/dist/engine/dashboard/data-loader.d.ts +21 -0
- package/dist/engine/dashboard/data-loader.d.ts.map +1 -0
- package/dist/engine/dashboard/data-loader.js +196 -0
- package/dist/engine/dashboard/data-loader.js.map +1 -0
- package/dist/engine/dashboard/index.d.ts +5 -0
- package/dist/engine/dashboard/index.d.ts.map +1 -0
- package/dist/engine/dashboard/index.js +6 -0
- package/dist/engine/dashboard/index.js.map +1 -0
- package/dist/engine/dashboard/routes.d.ts +4 -0
- package/dist/engine/dashboard/routes.d.ts.map +1 -0
- package/dist/engine/dashboard/routes.js +120 -0
- package/dist/engine/dashboard/routes.js.map +1 -0
- package/dist/engine/dashboard/server.d.ts +14 -0
- package/dist/engine/dashboard/server.d.ts.map +1 -0
- package/dist/engine/dashboard/server.js +88 -0
- package/dist/engine/dashboard/server.js.map +1 -0
- package/dist/engine/dashboard/templates-layout.d.ts +11 -0
- package/dist/engine/dashboard/templates-layout.d.ts.map +1 -0
- package/dist/engine/dashboard/templates-layout.js +305 -0
- package/dist/engine/dashboard/templates-layout.js.map +1 -0
- package/dist/engine/dashboard/templates-project.d.ts +10 -0
- package/dist/engine/dashboard/templates-project.d.ts.map +1 -0
- package/dist/engine/dashboard/templates-project.js +163 -0
- package/dist/engine/dashboard/templates-project.js.map +1 -0
- package/dist/engine/dashboard/templates.d.ts +3 -0
- package/dist/engine/dashboard/templates.d.ts.map +1 -0
- package/dist/engine/dashboard/templates.js +4 -0
- package/dist/engine/dashboard/templates.js.map +1 -0
- package/dist/engine/focus-tracker.d.ts.map +1 -1
- package/dist/engine/focus-tracker.js +1 -0
- package/dist/engine/focus-tracker.js.map +1 -1
- package/dist/engine/hooks/core.d.ts +26 -0
- package/dist/engine/hooks/core.d.ts.map +1 -0
- package/dist/engine/hooks/core.js +164 -0
- package/dist/engine/hooks/core.js.map +1 -0
- package/dist/engine/hooks/git-hook-generator.d.ts +14 -0
- package/dist/engine/hooks/git-hook-generator.d.ts.map +1 -0
- package/dist/engine/hooks/git-hook-generator.js +119 -0
- package/dist/engine/hooks/git-hook-generator.js.map +1 -0
- package/dist/engine/hooks/index.d.ts +5 -0
- package/dist/engine/hooks/index.d.ts.map +1 -0
- package/dist/engine/hooks/index.js +6 -0
- package/dist/engine/hooks/index.js.map +1 -0
- package/dist/engine/hooks/templates.d.ts +14 -0
- package/dist/engine/hooks/templates.d.ts.map +1 -0
- package/dist/engine/hooks/templates.js +138 -0
- package/dist/engine/hooks/templates.js.map +1 -0
- package/dist/engine/hooks/triggers.d.ts +27 -0
- package/dist/engine/hooks/triggers.d.ts.map +1 -0
- package/dist/engine/hooks/triggers.js +104 -0
- package/dist/engine/hooks/triggers.js.map +1 -0
- package/dist/engine/registry/core.d.ts +32 -0
- package/dist/engine/registry/core.d.ts.map +1 -0
- package/dist/engine/registry/core.js +85 -0
- package/dist/engine/registry/core.js.map +1 -0
- package/dist/engine/registry/index.d.ts +6 -0
- package/dist/engine/registry/index.d.ts.map +1 -0
- package/dist/engine/registry/index.js +8 -0
- package/dist/engine/registry/index.js.map +1 -0
- package/dist/engine/registry/loader.d.ts +18 -0
- package/dist/engine/registry/loader.d.ts.map +1 -0
- package/dist/engine/registry/loader.js +81 -0
- package/dist/engine/registry/loader.js.map +1 -0
- package/dist/engine/registry/matcher.d.ts +19 -0
- package/dist/engine/registry/matcher.d.ts.map +1 -0
- package/dist/engine/registry/matcher.js +150 -0
- package/dist/engine/registry/matcher.js.map +1 -0
- package/dist/engine/registry/reporter.d.ts +10 -0
- package/dist/engine/registry/reporter.d.ts.map +1 -0
- package/dist/engine/registry/reporter.js +132 -0
- package/dist/engine/registry/reporter.js.map +1 -0
- package/dist/engine/registry/validator.d.ts +17 -0
- package/dist/engine/registry/validator.d.ts.map +1 -0
- package/dist/engine/registry/validator.js +103 -0
- package/dist/engine/registry/validator.js.map +1 -0
- package/dist/engine/spec-changelog/core.d.ts +16 -0
- package/dist/engine/spec-changelog/core.d.ts.map +1 -0
- package/dist/engine/spec-changelog/core.js +175 -0
- package/dist/engine/spec-changelog/core.js.map +1 -0
- package/dist/engine/spec-changelog/diff.d.ts +18 -0
- package/dist/engine/spec-changelog/diff.d.ts.map +1 -0
- package/dist/engine/spec-changelog/diff.js +116 -0
- package/dist/engine/spec-changelog/diff.js.map +1 -0
- package/dist/engine/spec-changelog/index.d.ts +3 -0
- package/dist/engine/spec-changelog/index.d.ts.map +1 -0
- package/dist/engine/spec-changelog/index.js +4 -0
- package/dist/engine/spec-changelog/index.js.map +1 -0
- package/dist/engine/spec-coverage/core.d.ts +14 -0
- package/dist/engine/spec-coverage/core.d.ts.map +1 -0
- package/dist/engine/spec-coverage/core.js +132 -0
- package/dist/engine/spec-coverage/core.js.map +1 -0
- package/dist/engine/spec-coverage/criteria-mapper.d.ts +18 -0
- package/dist/engine/spec-coverage/criteria-mapper.d.ts.map +1 -0
- package/dist/engine/spec-coverage/criteria-mapper.js +306 -0
- package/dist/engine/spec-coverage/criteria-mapper.js.map +1 -0
- package/dist/engine/spec-coverage/index.d.ts +4 -0
- package/dist/engine/spec-coverage/index.d.ts.map +1 -0
- package/dist/engine/spec-coverage/index.js +5 -0
- package/dist/engine/spec-coverage/index.js.map +1 -0
- package/dist/engine/spec-coverage/test-finder.d.ts +17 -0
- package/dist/engine/spec-coverage/test-finder.d.ts.map +1 -0
- package/dist/engine/spec-coverage/test-finder.js +250 -0
- package/dist/engine/spec-coverage/test-finder.js.map +1 -0
- package/dist/engine/spec-templates/catalog-extra.d.ts +4 -0
- package/dist/engine/spec-templates/catalog-extra.d.ts.map +1 -0
- package/dist/engine/spec-templates/catalog-extra.js +367 -0
- package/dist/engine/spec-templates/catalog-extra.js.map +1 -0
- package/dist/engine/spec-templates/catalog.d.ts +4 -0
- package/dist/engine/spec-templates/catalog.d.ts.map +1 -0
- package/dist/engine/spec-templates/catalog.js +386 -0
- package/dist/engine/spec-templates/catalog.js.map +1 -0
- package/dist/engine/spec-templates/index.d.ts +4 -0
- package/dist/engine/spec-templates/index.d.ts.map +1 -0
- package/dist/engine/spec-templates/index.js +5 -0
- package/dist/engine/spec-templates/index.js.map +1 -0
- package/dist/engine/spec-templates/query.d.ts +14 -0
- package/dist/engine/spec-templates/query.d.ts.map +1 -0
- package/dist/engine/spec-templates/query.js +56 -0
- package/dist/engine/spec-templates/query.js.map +1 -0
- package/dist/engine/spec-templates/renderer.d.ts +19 -0
- package/dist/engine/spec-templates/renderer.d.ts.map +1 -0
- package/dist/engine/spec-templates/renderer.js +45 -0
- package/dist/engine/spec-templates/renderer.js.map +1 -0
- package/dist/engine/usage-tracker/trial.d.ts +4 -4
- package/dist/engine/usage-tracker/trial.d.ts.map +1 -1
- package/dist/engine/usage-tracker/trial.js +4 -4
- package/dist/engine/usage-tracker/trial.js.map +1 -1
- package/dist/engine/webhook/event-handlers.d.ts +25 -0
- package/dist/engine/webhook/event-handlers.d.ts.map +1 -0
- package/dist/engine/webhook/event-handlers.js +89 -0
- package/dist/engine/webhook/event-handlers.js.map +1 -0
- package/dist/engine/webhook/index.d.ts +4 -0
- package/dist/engine/webhook/index.d.ts.map +1 -0
- package/dist/engine/webhook/index.js +5 -0
- package/dist/engine/webhook/index.js.map +1 -0
- package/dist/engine/webhook/server.d.ts +18 -0
- package/dist/engine/webhook/server.d.ts.map +1 -0
- package/dist/engine/webhook/server.js +187 -0
- package/dist/engine/webhook/server.js.map +1 -0
- package/dist/engine/webhook/signature.d.ts +16 -0
- package/dist/engine/webhook/signature.d.ts.map +1 -0
- package/dist/engine/webhook/signature.js +49 -0
- package/dist/engine/webhook/signature.js.map +1 -0
- package/dist/index.js +18 -0
- package/dist/index.js.map +1 -1
- package/dist/storage/hooks-store.d.ts +34 -0
- package/dist/storage/hooks-store.d.ts.map +1 -0
- package/dist/storage/hooks-store.js +128 -0
- package/dist/storage/hooks-store.js.map +1 -0
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +1 -0
- package/dist/storage/index.js.map +1 -1
- package/dist/tools/check-spec-accuracy.d.ts +7 -0
- package/dist/tools/check-spec-accuracy.d.ts.map +1 -0
- package/dist/tools/check-spec-accuracy.js +28 -0
- package/dist/tools/check-spec-accuracy.js.map +1 -0
- package/dist/tools/ci-generator.d.ts +7 -0
- package/dist/tools/ci-generator.d.ts.map +1 -0
- package/dist/tools/ci-generator.js +49 -0
- package/dist/tools/ci-generator.js.map +1 -0
- package/dist/tools/create-spec.d.ts.map +1 -1
- package/dist/tools/create-spec.js +4 -0
- package/dist/tools/create-spec.js.map +1 -1
- package/dist/tools/dashboard.d.ts +6 -0
- package/dist/tools/dashboard.d.ts.map +1 -0
- package/dist/tools/dashboard.js +48 -0
- package/dist/tools/dashboard.js.map +1 -0
- package/dist/tools/detect-drift.d.ts.map +1 -1
- package/dist/tools/detect-drift.js +6 -0
- package/dist/tools/detect-drift.js.map +1 -1
- package/dist/tools/estimate-ai-cost.d.ts +8 -0
- package/dist/tools/estimate-ai-cost.d.ts.map +1 -0
- package/dist/tools/estimate-ai-cost.js +29 -0
- package/dist/tools/estimate-ai-cost.js.map +1 -0
- package/dist/tools/list-specs.d.ts.map +1 -1
- package/dist/tools/list-specs.js +15 -0
- package/dist/tools/list-specs.js.map +1 -1
- package/dist/tools/manage-hooks.d.ts +5 -0
- package/dist/tools/manage-hooks.d.ts.map +1 -0
- package/dist/tools/manage-hooks.js +247 -0
- package/dist/tools/manage-hooks.js.map +1 -0
- package/dist/tools/reconcile-spec.d.ts.map +1 -1
- package/dist/tools/reconcile-spec.js +24 -0
- package/dist/tools/reconcile-spec.js.map +1 -1
- package/dist/tools/register-ai-cost-tools.d.ts +3 -0
- package/dist/tools/register-ai-cost-tools.d.ts.map +1 -0
- package/dist/tools/register-ai-cost-tools.js +25 -0
- package/dist/tools/register-ai-cost-tools.js.map +1 -0
- package/dist/tools/register-changelog-tools.d.ts +3 -0
- package/dist/tools/register-changelog-tools.d.ts.map +1 -0
- package/dist/tools/register-changelog-tools.js +23 -0
- package/dist/tools/register-changelog-tools.js.map +1 -0
- package/dist/tools/register-ci-tools.d.ts +3 -0
- package/dist/tools/register-ci-tools.d.ts.map +1 -0
- package/dist/tools/register-ci-tools.js +50 -0
- package/dist/tools/register-ci-tools.js.map +1 -0
- package/dist/tools/register-coverage-tools.d.ts +7 -0
- package/dist/tools/register-coverage-tools.d.ts.map +1 -0
- package/dist/tools/register-coverage-tools.js +27 -0
- package/dist/tools/register-coverage-tools.js.map +1 -0
- package/dist/tools/register-dashboard-tools.d.ts +3 -0
- package/dist/tools/register-dashboard-tools.d.ts.map +1 -0
- package/dist/tools/register-dashboard-tools.js +29 -0
- package/dist/tools/register-dashboard-tools.js.map +1 -0
- package/dist/tools/register-hooks-tools.d.ts +3 -0
- package/dist/tools/register-hooks-tools.d.ts.map +1 -0
- package/dist/tools/register-hooks-tools.js +107 -0
- package/dist/tools/register-hooks-tools.js.map +1 -0
- package/dist/tools/register-registry-tools.d.ts +3 -0
- package/dist/tools/register-registry-tools.d.ts.map +1 -0
- package/dist/tools/register-registry-tools.js +43 -0
- package/dist/tools/register-registry-tools.js.map +1 -0
- package/dist/tools/register-template-tools.d.ts +8 -0
- package/dist/tools/register-template-tools.d.ts.map +1 -0
- package/dist/tools/register-template-tools.js +71 -0
- package/dist/tools/register-template-tools.js.map +1 -0
- package/dist/tools/register-webhook-tools.d.ts +3 -0
- package/dist/tools/register-webhook-tools.d.ts.map +1 -0
- package/dist/tools/register-webhook-tools.js +49 -0
- package/dist/tools/register-webhook-tools.js.map +1 -0
- package/dist/tools/schemas/index.d.ts +1 -0
- package/dist/tools/schemas/index.d.ts.map +1 -1
- package/dist/tools/schemas/index.js +1 -0
- package/dist/tools/schemas/index.js.map +1 -1
- package/dist/tools/schemas/registry.d.ts +41 -0
- package/dist/tools/schemas/registry.d.ts.map +1 -0
- package/dist/tools/schemas/registry.js +62 -0
- package/dist/tools/schemas/registry.js.map +1 -0
- package/dist/tools/spec-coverage.d.ts +3 -0
- package/dist/tools/spec-coverage.d.ts.map +1 -0
- package/dist/tools/spec-coverage.js +176 -0
- package/dist/tools/spec-coverage.js.map +1 -0
- package/dist/tools/spec-history.d.ts +3 -0
- package/dist/tools/spec-history.d.ts.map +1 -0
- package/dist/tools/spec-history.js +67 -0
- package/dist/tools/spec-history.js.map +1 -0
- package/dist/tools/spec-templates.d.ts +10 -0
- package/dist/tools/spec-templates.d.ts.map +1 -0
- package/dist/tools/spec-templates.js +155 -0
- package/dist/tools/spec-templates.js.map +1 -0
- package/dist/tools/update-registry.d.ts +8 -0
- package/dist/tools/update-registry.d.ts.map +1 -0
- package/dist/tools/update-registry.js +53 -0
- package/dist/tools/update-registry.js.map +1 -0
- package/dist/tools/update-status.d.ts.map +1 -1
- package/dist/tools/update-status.js +24 -0
- package/dist/tools/update-status.js.map +1 -1
- package/dist/tools/webhook.d.ts +6 -0
- package/dist/tools/webhook.d.ts.map +1 -0
- package/dist/tools/webhook.js +150 -0
- package/dist/tools/webhook.js.map +1 -0
- package/dist/types/ai-cost.d.ts +98 -0
- package/dist/types/ai-cost.d.ts.map +1 -0
- package/dist/types/ai-cost.js +4 -0
- package/dist/types/ai-cost.js.map +1 -0
- package/dist/types/analysis.d.ts +64 -0
- package/dist/types/analysis.d.ts.map +1 -1
- package/dist/types/changelog.d.ts +49 -0
- package/dist/types/changelog.d.ts.map +1 -0
- package/dist/types/changelog.js +3 -0
- package/dist/types/changelog.js.map +1 -0
- package/dist/types/ci.d.ts +105 -0
- package/dist/types/ci.d.ts.map +1 -0
- package/dist/types/ci.js +3 -0
- package/dist/types/ci.js.map +1 -0
- package/dist/types/coverage.d.ts +95 -0
- package/dist/types/coverage.d.ts.map +1 -0
- package/dist/types/coverage.js +4 -0
- package/dist/types/coverage.js.map +1 -0
- package/dist/types/hooks.d.ts +139 -0
- package/dist/types/hooks.d.ts.map +1 -0
- package/dist/types/hooks.js +3 -0
- package/dist/types/hooks.js.map +1 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +8 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/registry.d.ts +90 -0
- package/dist/types/registry.d.ts.map +1 -0
- package/dist/types/registry.js +5 -0
- package/dist/types/registry.js.map +1 -0
- package/dist/types/spec-templates.d.ts +87 -0
- package/dist/types/spec-templates.d.ts.map +1 -0
- package/dist/types/spec-templates.js +3 -0
- package/dist/types/spec-templates.js.map +1 -0
- package/dist/types/ui.d.ts +76 -0
- package/dist/types/ui.d.ts.map +1 -1
- package/dist/types/webhook.d.ts +62 -0
- package/dist/types/webhook.d.ts.map +1 -0
- package/dist/types/webhook.js +4 -0
- package/dist/types/webhook.js.map +1 -0
- package/package.json +1 -1
- package/src/config/ai-model-pricing.json +81 -0
- package/src/config/framework-registry/csharp-aspnet.json +67 -0
- package/src/config/framework-registry/dart-flutter.json +61 -0
- package/src/config/framework-registry/go-gin.json +62 -0
- package/src/config/framework-registry/index.json +164 -0
- package/src/config/framework-registry/java-springboot.json +67 -0
- package/src/config/framework-registry/php-laravel.json +67 -0
- package/src/config/framework-registry/python-django.json +72 -0
- package/src/config/framework-registry/python-fastapi.json +72 -0
- package/src/config/framework-registry/ruby-rails.json +67 -0
- package/src/config/framework-registry/rust-actix.json +61 -0
- package/src/config/framework-registry/swift-swiftui.json +67 -0
- package/src/config/framework-registry/typescript-angular.json +67 -0
- package/src/config/framework-registry/typescript-astro.json +61 -0
- package/src/config/framework-registry/typescript-express.json +67 -0
- package/src/config/framework-registry/typescript-nestjs.json +62 -0
- package/src/config/framework-registry/typescript-nextjs.json +82 -0
- package/src/config/framework-registry/typescript-nuxt.json +67 -0
- package/src/config/framework-registry/typescript-react.json +77 -0
- package/src/config/framework-registry/typescript-remix.json +61 -0
- package/src/config/framework-registry/typescript-sveltekit.json +67 -0
- package/src/config/framework-registry/typescript-vue.json +72 -0
- package/src/config/license-plans.json +23 -3
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
// engine/ai-cost-estimator/core.ts — Orchestrates AI cost estimation for specs.
|
|
2
|
+
// Coordinates token-estimator + model-pricing to produce AiCostEstimateResult.
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { loadPricingConfig, getAllModels, calculateCost, calculateAgentTurns, isPricingStale, } from './model-pricing.js';
|
|
6
|
+
import { buildTokenEstimate } from './token-estimator.js';
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Complexity thresholds
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
const LOW_COMPLEXITY_MAX_AC = 5;
|
|
11
|
+
const MEDIUM_COMPLEXITY_MAX_AC = 12;
|
|
12
|
+
/** Returns the confidence range percentage based on number of acceptance criteria. */
|
|
13
|
+
function getConfidenceRangePct(acCount) {
|
|
14
|
+
if (acCount <= LOW_COMPLEXITY_MAX_AC) {
|
|
15
|
+
return 20;
|
|
16
|
+
}
|
|
17
|
+
if (acCount <= MEDIUM_COMPLEXITY_MAX_AC) {
|
|
18
|
+
return 30;
|
|
19
|
+
}
|
|
20
|
+
return 40;
|
|
21
|
+
}
|
|
22
|
+
/** Returns the complexity level label for a given AC count. */
|
|
23
|
+
function getComplexityLevel(acCount) {
|
|
24
|
+
if (acCount <= LOW_COMPLEXITY_MAX_AC) {
|
|
25
|
+
return 'low';
|
|
26
|
+
}
|
|
27
|
+
if (acCount <= MEDIUM_COMPLEXITY_MAX_AC) {
|
|
28
|
+
return 'medium';
|
|
29
|
+
}
|
|
30
|
+
return 'high';
|
|
31
|
+
}
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// Spec content loading
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Reads spec content from a sdd/specs directory.
|
|
37
|
+
* Tries to find the spec directory by matching specId prefix.
|
|
38
|
+
*/
|
|
39
|
+
async function loadSpecContent(specId) {
|
|
40
|
+
const specsRoot = 'docs/sdd/specs';
|
|
41
|
+
let entries;
|
|
42
|
+
try {
|
|
43
|
+
const { readdir } = await import('node:fs/promises');
|
|
44
|
+
entries = await readdir(specsRoot);
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
throw new Error(`Spec directory not found at "${specsRoot}". ` +
|
|
48
|
+
'Make sure you are running from the project root.');
|
|
49
|
+
}
|
|
50
|
+
// Find a directory matching the specId (e.g., "SPEC-069" matches "SPEC-069-ai-cost-estimator")
|
|
51
|
+
const specDirName = entries.find((e) => e.startsWith(specId));
|
|
52
|
+
if (!specDirName) {
|
|
53
|
+
throw new Error(`Spec "${specId}" not found in "${specsRoot}". ` +
|
|
54
|
+
`Available specs: ${entries.slice(0, 5).join(', ')}...`);
|
|
55
|
+
}
|
|
56
|
+
const specDir = join(specsRoot, specDirName);
|
|
57
|
+
const parts = [];
|
|
58
|
+
for (const filename of ['HU.md', 'FICHA-TECNICA.md']) {
|
|
59
|
+
try {
|
|
60
|
+
const content = await readFile(join(specDir, filename), 'utf-8');
|
|
61
|
+
parts.push(content);
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
// File not present — skip (not fatal)
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
if (parts.length === 0) {
|
|
68
|
+
throw new Error(`Spec "${specId}" has no HU.md or FICHA-TECNICA.md in "${specDir}". ` +
|
|
69
|
+
'Cannot estimate without spec content.');
|
|
70
|
+
}
|
|
71
|
+
return { content: parts.join('\n\n'), specDir };
|
|
72
|
+
}
|
|
73
|
+
/** Counts acceptance criteria (lines starting with "- [ ]" or "- [x]") in spec content. */
|
|
74
|
+
function countAcceptanceCriteria(specContent) {
|
|
75
|
+
const matches = specContent.match(/^- \[[ xX]\]/gm);
|
|
76
|
+
return matches?.length ?? 0;
|
|
77
|
+
}
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
// Usage calibration
|
|
80
|
+
// ---------------------------------------------------------------------------
|
|
81
|
+
/** Reads average tokens per call from usage.json if available. */
|
|
82
|
+
async function readUsageAvgTokensPerCall() {
|
|
83
|
+
try {
|
|
84
|
+
const { readFile: rf } = await import('node:fs/promises');
|
|
85
|
+
const raw = await rf('data/global/usage.json', 'utf-8');
|
|
86
|
+
/* v8 ignore start */
|
|
87
|
+
const log = JSON.parse(raw);
|
|
88
|
+
if (log.events.length === 0) {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
// Usage events don't track token counts — return undefined to use defaults
|
|
92
|
+
return undefined;
|
|
93
|
+
/* v8 ignore stop */
|
|
94
|
+
}
|
|
95
|
+
catch {
|
|
96
|
+
return undefined;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
// Recommendation logic
|
|
101
|
+
// ---------------------------------------------------------------------------
|
|
102
|
+
/** Selects the recommended model based on spec complexity. */
|
|
103
|
+
function selectRecommendedModel(models, complexity) {
|
|
104
|
+
const preferencesByComplexity = {
|
|
105
|
+
low: [
|
|
106
|
+
'claude-haiku-3-5',
|
|
107
|
+
'gemini-2-5-pro',
|
|
108
|
+
'gpt-4-1',
|
|
109
|
+
'gpt-4o',
|
|
110
|
+
'claude-sonnet-4',
|
|
111
|
+
'claude-opus-4',
|
|
112
|
+
],
|
|
113
|
+
medium: [
|
|
114
|
+
'claude-sonnet-4',
|
|
115
|
+
'gpt-4o',
|
|
116
|
+
'gpt-4-1',
|
|
117
|
+
'gemini-2-5-pro',
|
|
118
|
+
'claude-haiku-3-5',
|
|
119
|
+
'claude-opus-4',
|
|
120
|
+
],
|
|
121
|
+
high: [
|
|
122
|
+
'claude-opus-4',
|
|
123
|
+
'claude-sonnet-4',
|
|
124
|
+
'gpt-4o',
|
|
125
|
+
'gpt-4-1',
|
|
126
|
+
'gemini-2-5-pro',
|
|
127
|
+
'claude-haiku-3-5',
|
|
128
|
+
],
|
|
129
|
+
};
|
|
130
|
+
const preferences = preferencesByComplexity[complexity] ?? preferencesByComplexity.medium ?? [];
|
|
131
|
+
for (const modelId of preferences) {
|
|
132
|
+
const model = models.find((m) => m.id === modelId);
|
|
133
|
+
if (model) {
|
|
134
|
+
return model;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// Fallback: cheapest model
|
|
138
|
+
/* v8 ignore start */
|
|
139
|
+
const sorted = [...models].sort((a, b) => a.inputPricePerMillion - b.inputPricePerMillion);
|
|
140
|
+
const first = sorted[0];
|
|
141
|
+
if (!first) {
|
|
142
|
+
throw new Error('No models available in pricing config');
|
|
143
|
+
}
|
|
144
|
+
return first;
|
|
145
|
+
/* v8 ignore stop */
|
|
146
|
+
}
|
|
147
|
+
/** Builds a human-readable recommendation reason. */
|
|
148
|
+
function buildRecommendationReason(model, complexity, savingsVsMostExpensive) {
|
|
149
|
+
const complexityLabel = { low: 'baja', medium: 'media', high: 'alta' }[complexity];
|
|
150
|
+
const baseReason = `Para complejidad ${complexityLabel}, **${model.displayName}** ofrece `;
|
|
151
|
+
if (complexity === 'low') {
|
|
152
|
+
return (baseReason +
|
|
153
|
+
`el mejor precio sin sacrificar calidad. ` +
|
|
154
|
+
`Ahorro estimado vs modelo más caro: $${savingsVsMostExpensive.toFixed(4)} USD.`);
|
|
155
|
+
}
|
|
156
|
+
if (complexity === 'medium') {
|
|
157
|
+
return (baseReason +
|
|
158
|
+
`el mejor balance calidad/precio. ` +
|
|
159
|
+
`Ahorro estimado vs modelo más caro: $${savingsVsMostExpensive.toFixed(4)} USD.`);
|
|
160
|
+
}
|
|
161
|
+
return (baseReason +
|
|
162
|
+
`máxima calidad para specs complejas. ` +
|
|
163
|
+
`El costo adicional se justifica por la reducción de iteraciones.`);
|
|
164
|
+
}
|
|
165
|
+
// ---------------------------------------------------------------------------
|
|
166
|
+
// Markdown formatting
|
|
167
|
+
// ---------------------------------------------------------------------------
|
|
168
|
+
/** Formats the cost estimates as a markdown table. */
|
|
169
|
+
function formatMarkdownTable(estimates, recommendedModelId, recommendationReason, staleWarning) {
|
|
170
|
+
const header = '| Modelo | Tokens Input | Tokens Output | Costo Estimado | Rango (±) | Agent Turns |\n' +
|
|
171
|
+
'|--------|-------------|---------------|----------------|-----------|-------------|';
|
|
172
|
+
const rows = estimates.map((est) => {
|
|
173
|
+
const marker = est.modelId === recommendedModelId ? ' ⭐' : '';
|
|
174
|
+
const cost = `$${est.estimatedCostUsd.toFixed(4)}`;
|
|
175
|
+
const range = `±${est.confidenceRangePct}%`;
|
|
176
|
+
return (`| ${est.displayName}${marker} | ${est.inputTokens.toLocaleString()} | ` +
|
|
177
|
+
`${est.outputTokens.toLocaleString()} | ${cost} | ${range} | ${est.agentTurns} |`);
|
|
178
|
+
});
|
|
179
|
+
const recommended = estimates.find((e) => e.modelId === recommendedModelId);
|
|
180
|
+
const recommendedName = recommended?.displayName ?? recommendedModelId;
|
|
181
|
+
const lines = [
|
|
182
|
+
'## Estimación de Costo por Modelo IA',
|
|
183
|
+
'',
|
|
184
|
+
header,
|
|
185
|
+
...rows,
|
|
186
|
+
'',
|
|
187
|
+
`## Recomendación: ${recommendedName}`,
|
|
188
|
+
'',
|
|
189
|
+
recommendationReason,
|
|
190
|
+
];
|
|
191
|
+
if (staleWarning) {
|
|
192
|
+
lines.push('', `> **Aviso**: ${staleWarning}`);
|
|
193
|
+
}
|
|
194
|
+
return lines.join('\n');
|
|
195
|
+
}
|
|
196
|
+
// ---------------------------------------------------------------------------
|
|
197
|
+
// Main orchestrator
|
|
198
|
+
// ---------------------------------------------------------------------------
|
|
199
|
+
/**
|
|
200
|
+
* Estimates the AI cost for implementing a spec.
|
|
201
|
+
* Reads the spec from docs/sdd/specs/, loads pricing from config JSON,
|
|
202
|
+
* and returns a full AiCostEstimateResult with per-model breakdown.
|
|
203
|
+
*/
|
|
204
|
+
export async function estimateAiCost(input) {
|
|
205
|
+
const { specId, projectPath } = input;
|
|
206
|
+
// 1. Load spec content
|
|
207
|
+
const { content: specContent } = await loadSpecContent(specId);
|
|
208
|
+
const acCount = countAcceptanceCriteria(specContent);
|
|
209
|
+
// 2. Load pricing config
|
|
210
|
+
const config = await loadPricingConfig();
|
|
211
|
+
const models = await getAllModels();
|
|
212
|
+
// 3. Build token estimate
|
|
213
|
+
const usageAvg = await readUsageAvgTokensPerCall();
|
|
214
|
+
const tokenEstimate = await buildTokenEstimate(specContent, 0, // No pre-existing LOC estimate — use AC-based fallback
|
|
215
|
+
acCount, projectPath, config, usageAvg);
|
|
216
|
+
// 4. Determine complexity + confidence
|
|
217
|
+
const complexity = getComplexityLevel(acCount);
|
|
218
|
+
const confidenceRangePct = getConfidenceRangePct(acCount);
|
|
219
|
+
// 5. Calculate per-model estimates
|
|
220
|
+
const estimates = models.map((model) => {
|
|
221
|
+
const estimatedCostUsd = calculateCost(model, tokenEstimate.inputTokens, tokenEstimate.outputTokens);
|
|
222
|
+
const agentTurns = calculateAgentTurns(model, tokenEstimate.locToGenerate);
|
|
223
|
+
return {
|
|
224
|
+
modelId: model.id,
|
|
225
|
+
displayName: model.displayName,
|
|
226
|
+
inputTokens: tokenEstimate.inputTokens,
|
|
227
|
+
outputTokens: tokenEstimate.outputTokens,
|
|
228
|
+
estimatedCostUsd,
|
|
229
|
+
confidenceRangePct,
|
|
230
|
+
agentTurns,
|
|
231
|
+
};
|
|
232
|
+
});
|
|
233
|
+
// 6. Determine recommendation
|
|
234
|
+
const recommendedModel = selectRecommendedModel(models, complexity);
|
|
235
|
+
// Calculate savings vs most expensive model
|
|
236
|
+
const maxCost = Math.max(...estimates.map((e) => e.estimatedCostUsd));
|
|
237
|
+
const recommendedEstimate = estimates.find((e) => e.modelId === recommendedModel.id);
|
|
238
|
+
const recommendedCost = recommendedEstimate?.estimatedCostUsd ?? 0;
|
|
239
|
+
const savingsVsExpensiveModel = Math.max(0, maxCost - recommendedCost);
|
|
240
|
+
const recommendationReason = buildRecommendationReason(recommendedModel, complexity, savingsVsExpensiveModel);
|
|
241
|
+
// 7. Check if pricing is stale
|
|
242
|
+
const staleWarning = isPricingStale(config.lastUpdated)
|
|
243
|
+
? `Los precios del modelo pueden estar desactualizados (última actualización: ${config.lastUpdated}). ` +
|
|
244
|
+
'Verifica los precios actuales en la documentación de cada proveedor.'
|
|
245
|
+
: '';
|
|
246
|
+
// 8. Format markdown table
|
|
247
|
+
const markdownTable = formatMarkdownTable(estimates, recommendedModel.id, recommendationReason, staleWarning);
|
|
248
|
+
return {
|
|
249
|
+
specId,
|
|
250
|
+
estimates,
|
|
251
|
+
recommendedModelId: recommendedModel.id,
|
|
252
|
+
recommendationReason,
|
|
253
|
+
savingsVsExpensiveModel,
|
|
254
|
+
markdownTable,
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
//# sourceMappingURL=core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"core.js","sourceRoot":"","sources":["../../../src/engine/ai-cost-estimator/core.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { estimateAiCost } from './core.js';
|
|
2
|
+
export { loadPricingConfig, clearPricingCache, getAllModels, findModel, calculateCost, calculateAgentTurns, isPricingStale, } from './model-pricing.js';
|
|
3
|
+
export { detectProjectLanguage, estimateInputTokens, estimateOutputTokens, estimateLocFromAcCount, buildTokenEstimate, } from './token-estimator.js';
|
|
4
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/engine/ai-cost-estimator/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
// engine/ai-cost-estimator/index.ts — Barrel re-export for the ai-cost-estimator module.
|
|
2
|
+
export { estimateAiCost } from './core.js';
|
|
3
|
+
export { loadPricingConfig, clearPricingCache, getAllModels, findModel, calculateCost, calculateAgentTurns, isPricingStale, } from './model-pricing.js';
|
|
4
|
+
export { detectProjectLanguage, estimateInputTokens, estimateOutputTokens, estimateLocFromAcCount, buildTokenEstimate, } from './token-estimator.js';
|
|
5
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/engine/ai-cost-estimator/index.ts"],"names":[],"mappings":"AAAA,yFAAyF;AAEzF,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,aAAa,EACb,mBAAmB,EACnB,cAAc,GACf,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,GACnB,MAAM,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { AiModelConfig, AiModelPricingConfig } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Loads the AI model pricing configuration from disk.
|
|
4
|
+
* Results are cached after the first load.
|
|
5
|
+
*/
|
|
6
|
+
export declare function loadPricingConfig(): Promise<AiModelPricingConfig>;
|
|
7
|
+
/** Clears the in-memory cache (used in tests). */
|
|
8
|
+
export declare function clearPricingCache(): void;
|
|
9
|
+
/**
|
|
10
|
+
* Returns all configured AI models.
|
|
11
|
+
*/
|
|
12
|
+
export declare function getAllModels(): Promise<readonly AiModelConfig[]>;
|
|
13
|
+
/**
|
|
14
|
+
* Finds a model by its ID. Returns null if not found.
|
|
15
|
+
*/
|
|
16
|
+
export declare function findModel(modelId: string): Promise<AiModelConfig | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Calculates the estimated cost in USD for a given model and token counts.
|
|
19
|
+
*
|
|
20
|
+
* Formula: (inputTokens / 1_000_000 × inputPrice) + (outputTokens / 1_000_000 × outputPrice)
|
|
21
|
+
*/
|
|
22
|
+
export declare function calculateCost(model: AiModelConfig, inputTokens: number, outputTokens: number): number;
|
|
23
|
+
/**
|
|
24
|
+
* Returns the number of agent turns needed to generate the given LOC count.
|
|
25
|
+
*/
|
|
26
|
+
export declare function calculateAgentTurns(model: AiModelConfig, locToGenerate: number): number;
|
|
27
|
+
/**
|
|
28
|
+
* Returns true if the pricing config is older than STALE_DAYS days.
|
|
29
|
+
*/
|
|
30
|
+
export declare function isPricingStale(lastUpdated: string): boolean;
|
|
31
|
+
//# sourceMappingURL=model-pricing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-pricing.d.ts","sourceRoot":"","sources":["../../../src/engine/ai-cost-estimator/model-pricing.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAkBhF;;;GAGG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAoBvE;AAED,kDAAkD;AAClD,wBAAgB,iBAAiB,IAAI,IAAI,CAExC;AAMD;;GAEG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,aAAa,EAAE,CAAC,CAGtE;AAED;;GAEG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAG9E;AAMD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,aAAa,EACpB,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GACnB,MAAM,CAIR;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAKvF;AAQD;;GAEG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAM3D"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
// engine/ai-cost-estimator/model-pricing.ts — Loads AI model pricing from config JSON.
|
|
2
|
+
// Provides model lookup, cost calculation, and pricing config access.
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { dirname, join } from 'node:path';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// Config loading
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
const CONFIG_FILENAME = 'ai-model-pricing.json';
|
|
10
|
+
/** Resolve the path to the config file relative to this module. */
|
|
11
|
+
function resolveConfigPath() {
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
return join(__dirname, '../../config', CONFIG_FILENAME);
|
|
15
|
+
}
|
|
16
|
+
/** Cache to avoid repeated disk reads within a process lifetime. */
|
|
17
|
+
let cachedConfig = null;
|
|
18
|
+
/**
|
|
19
|
+
* Loads the AI model pricing configuration from disk.
|
|
20
|
+
* Results are cached after the first load.
|
|
21
|
+
*/
|
|
22
|
+
export async function loadPricingConfig() {
|
|
23
|
+
if (cachedConfig !== null) {
|
|
24
|
+
return cachedConfig;
|
|
25
|
+
}
|
|
26
|
+
const configPath = resolveConfigPath();
|
|
27
|
+
try {
|
|
28
|
+
const raw = await readFile(configPath, 'utf-8');
|
|
29
|
+
cachedConfig = JSON.parse(raw);
|
|
30
|
+
return cachedConfig;
|
|
31
|
+
/* v8 ignore start */
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
35
|
+
throw new Error(`[Planu] Failed to load AI model pricing config from ${configPath}: ${reason}`, { cause: err });
|
|
36
|
+
}
|
|
37
|
+
/* v8 ignore stop */
|
|
38
|
+
}
|
|
39
|
+
/** Clears the in-memory cache (used in tests). */
|
|
40
|
+
export function clearPricingCache() {
|
|
41
|
+
cachedConfig = null;
|
|
42
|
+
}
|
|
43
|
+
// ---------------------------------------------------------------------------
|
|
44
|
+
// Model lookup
|
|
45
|
+
// ---------------------------------------------------------------------------
|
|
46
|
+
/**
|
|
47
|
+
* Returns all configured AI models.
|
|
48
|
+
*/
|
|
49
|
+
export async function getAllModels() {
|
|
50
|
+
const config = await loadPricingConfig();
|
|
51
|
+
return config.models;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Finds a model by its ID. Returns null if not found.
|
|
55
|
+
*/
|
|
56
|
+
export async function findModel(modelId) {
|
|
57
|
+
const models = await getAllModels();
|
|
58
|
+
return models.find((m) => m.id === modelId) ?? null;
|
|
59
|
+
}
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Cost calculation
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
/**
|
|
64
|
+
* Calculates the estimated cost in USD for a given model and token counts.
|
|
65
|
+
*
|
|
66
|
+
* Formula: (inputTokens / 1_000_000 × inputPrice) + (outputTokens / 1_000_000 × outputPrice)
|
|
67
|
+
*/
|
|
68
|
+
export function calculateCost(model, inputTokens, outputTokens) {
|
|
69
|
+
const inputCost = (inputTokens / 1_000_000) * model.inputPricePerMillion;
|
|
70
|
+
const outputCost = (outputTokens / 1_000_000) * model.outputPricePerMillion;
|
|
71
|
+
return inputCost + outputCost;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Returns the number of agent turns needed to generate the given LOC count.
|
|
75
|
+
*/
|
|
76
|
+
export function calculateAgentTurns(model, locToGenerate) {
|
|
77
|
+
if (model.avgThroughputLOCPerTurn <= 0) {
|
|
78
|
+
return 1;
|
|
79
|
+
}
|
|
80
|
+
return Math.ceil(locToGenerate / model.avgThroughputLOCPerTurn);
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Price staleness check
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
const STALE_DAYS = 30;
|
|
86
|
+
/**
|
|
87
|
+
* Returns true if the pricing config is older than STALE_DAYS days.
|
|
88
|
+
*/
|
|
89
|
+
export function isPricingStale(lastUpdated) {
|
|
90
|
+
const updatedDate = new Date(lastUpdated);
|
|
91
|
+
const now = new Date();
|
|
92
|
+
const diffMs = now.getTime() - updatedDate.getTime();
|
|
93
|
+
const diffDays = diffMs / (1000 * 60 * 60 * 24);
|
|
94
|
+
return diffDays > STALE_DAYS;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=model-pricing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-pricing.js","sourceRoot":"","sources":["../../../src/engine/ai-cost-estimator/model-pricing.ts"],"names":[],"mappings":"AAAA,uFAAuF;AACvF,sEAAsE;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAG1C,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,MAAM,eAAe,GAAG,uBAAuB,CAAC;AAEhD,mEAAmE;AACnE,SAAS,iBAAiB;IACxB,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtC,OAAO,IAAI,CAAC,SAAS,EAAE,cAAc,EAAE,eAAe,CAAC,CAAC;AAC1D,CAAC;AAED,oEAAoE;AACpE,IAAI,YAAY,GAAgC,IAAI,CAAC;AAErD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;QAC1B,OAAO,YAAY,CAAC;IACtB,CAAC;IAED,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IAEvC,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAChD,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAyB,CAAC;QACvD,OAAO,YAAY,CAAC;QACpB,qBAAqB;IACvB,CAAC;IAAC,OAAO,GAAY,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,uDAAuD,UAAU,KAAK,MAAM,EAAE,EAC9E,EAAE,KAAK,EAAE,GAAG,EAAE,CACf,CAAC;IACJ,CAAC;IACD,oBAAoB;AACtB,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,iBAAiB;IAC/B,YAAY,GAAG,IAAI,CAAC;AACtB,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,MAAM,MAAM,GAAG,MAAM,iBAAiB,EAAE,CAAC;IACzC,OAAO,MAAM,CAAC,MAAM,CAAC;AACvB,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAe;IAC7C,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAC;IACpC,OAAO,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,CAAC,IAAI,IAAI,CAAC;AACtD,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,KAAoB,EACpB,WAAmB,EACnB,YAAoB;IAEpB,MAAM,SAAS,GAAG,CAAC,WAAW,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,oBAAoB,CAAC;IACzE,MAAM,UAAU,GAAG,CAAC,YAAY,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,qBAAqB,CAAC;IAC5E,OAAO,SAAS,GAAG,UAAU,CAAC;AAChC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAoB,EAAE,aAAqB;IAC7E,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,EAAE,CAAC;QACvC,OAAO,CAAC,CAAC;IACX,CAAC;IACD,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC,uBAAuB,CAAC,CAAC;AAClE,CAAC;AAED,8EAA8E;AAC9E,wBAAwB;AACxB,8EAA8E;AAE9E,MAAM,UAAU,GAAG,EAAE,CAAC;AAEtB;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB;IAChD,MAAM,WAAW,GAAG,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,MAAM,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,OAAO,EAAE,CAAC;IACrD,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC;IAChD,OAAO,QAAQ,GAAG,UAAU,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { TokenEstimate, AiModelPricingConfig } from '../../types/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* Detects the primary programming language of a project by checking config files.
|
|
4
|
+
* Falls back to scanning source file extensions.
|
|
5
|
+
*/
|
|
6
|
+
export declare function detectProjectLanguage(projectPath: string): Promise<string>;
|
|
7
|
+
/**
|
|
8
|
+
* Estimates input tokens for an AI agent session based on three components:
|
|
9
|
+
* 1. Spec content (HU.md + FICHA-TECNICA.md)
|
|
10
|
+
* 2. Codebase context (if projectPath is provided)
|
|
11
|
+
* 3. MCP tool definitions overhead (fixed constant)
|
|
12
|
+
*/
|
|
13
|
+
export declare function estimateInputTokens(specContent: string, projectPath: string | undefined, config: AiModelPricingConfig): Promise<{
|
|
14
|
+
inputTokens: number;
|
|
15
|
+
specContentTokens: number;
|
|
16
|
+
codebaseContextTokens: number;
|
|
17
|
+
toolDefinitionsTokens: number;
|
|
18
|
+
}>;
|
|
19
|
+
/**
|
|
20
|
+
* Estimates output tokens (code to be generated) for a spec.
|
|
21
|
+
*
|
|
22
|
+
* Priority:
|
|
23
|
+
* 1. Use LOC from existing estimate if available
|
|
24
|
+
* 2. Fallback: number of ACs × DEFAULT_LOC_PER_AC
|
|
25
|
+
* 3. Calibrate with usage.json average if available
|
|
26
|
+
*/
|
|
27
|
+
export declare function estimateOutputTokens(locToGenerate: number, language: string, config: AiModelPricingConfig, usageAvgTokensPerCall?: number): number;
|
|
28
|
+
/**
|
|
29
|
+
* Estimates LOC to generate based on the number of acceptance criteria.
|
|
30
|
+
* Used as a fallback when no existing estimate is available.
|
|
31
|
+
*/
|
|
32
|
+
export declare function estimateLocFromAcCount(acCount: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Produces a complete TokenEstimate for a spec.
|
|
35
|
+
*/
|
|
36
|
+
export declare function buildTokenEstimate(specContent: string, locToGenerate: number, acCount: number, projectPath: string | undefined, config: AiModelPricingConfig, usageAvgTokensPerCall?: number): Promise<TokenEstimate>;
|
|
37
|
+
//# sourceMappingURL=token-estimator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-estimator.d.ts","sourceRoot":"","sources":["../../../src/engine/ai-cost-estimator/token-estimator.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AA4ChF;;;GAGG;AACH,wBAAsB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAchF;AA0DD;;;;;GAKG;AACH,wBAAsB,mBAAmB,CACvC,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC;IACT,WAAW,EAAE,MAAM,CAAC;IACpB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,qBAAqB,EAAE,MAAM,CAAC;IAC9B,qBAAqB,EAAE,MAAM,CAAC;CAC/B,CAAC,CAuBD;AAMD;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,aAAa,EAAE,MAAM,EACrB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,oBAAoB,EAC5B,qBAAqB,CAAC,EAAE,MAAM,GAC7B,MAAM,CAoBR;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE9D;AAMD;;GAEG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,aAAa,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,MAAM,EAAE,oBAAoB,EAC5B,qBAAqB,CAAC,EAAE,MAAM,GAC7B,OAAO,CAAC,aAAa,CAAC,CAwBxB"}
|