@hypercli/gen 0.1.1
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 +24 -0
- package/dist/actions/communication.d.ts +201 -0
- package/dist/actions/communication.d.ts.map +1 -0
- package/dist/actions/communication.js +515 -0
- package/dist/actions/communication.js.map +1 -0
- package/dist/actions/decorator.d.ts +22 -0
- package/dist/actions/decorator.d.ts.map +1 -0
- package/dist/actions/decorator.js +110 -0
- package/dist/actions/decorator.js.map +1 -0
- package/dist/actions/executor.d.ts +85 -0
- package/dist/actions/executor.d.ts.map +1 -0
- package/dist/actions/executor.js +289 -0
- package/dist/actions/executor.js.map +1 -0
- package/dist/actions/index.d.ts +14 -0
- package/dist/actions/index.d.ts.map +1 -0
- package/dist/actions/index.js +15 -0
- package/dist/actions/index.js.map +1 -0
- package/dist/actions/parameter-resolver.d.ts +54 -0
- package/dist/actions/parameter-resolver.d.ts.map +1 -0
- package/dist/actions/parameter-resolver.js +300 -0
- package/dist/actions/parameter-resolver.js.map +1 -0
- package/dist/actions/registry.d.ts +78 -0
- package/dist/actions/registry.d.ts.map +1 -0
- package/dist/actions/registry.js +221 -0
- package/dist/actions/registry.js.map +1 -0
- package/dist/actions/types.d.ts +109 -0
- package/dist/actions/types.d.ts.map +1 -0
- package/dist/actions/types.js +31 -0
- package/dist/actions/types.js.map +1 -0
- package/dist/actions/utils.d.ts +42 -0
- package/dist/actions/utils.d.ts.map +1 -0
- package/dist/actions/utils.js +144 -0
- package/dist/actions/utils.js.map +1 -0
- package/dist/ai/ai-collector.d.ts +52 -0
- package/dist/ai/ai-collector.d.ts.map +1 -0
- package/dist/ai/ai-collector.js +64 -0
- package/dist/ai/ai-collector.js.map +1 -0
- package/dist/ai/ai-config.d.ts +230 -0
- package/dist/ai/ai-config.d.ts.map +1 -0
- package/dist/ai/ai-config.js +8 -0
- package/dist/ai/ai-config.js.map +1 -0
- package/dist/ai/ai-service.d.ts +66 -0
- package/dist/ai/ai-service.d.ts.map +1 -0
- package/dist/ai/ai-service.js +198 -0
- package/dist/ai/ai-service.js.map +1 -0
- package/dist/ai/ai-variable-resolver.d.ts +59 -0
- package/dist/ai/ai-variable-resolver.d.ts.map +1 -0
- package/dist/ai/ai-variable-resolver.js +219 -0
- package/dist/ai/ai-variable-resolver.js.map +1 -0
- package/dist/ai/context-collector.d.ts +30 -0
- package/dist/ai/context-collector.d.ts.map +1 -0
- package/dist/ai/context-collector.js +158 -0
- package/dist/ai/context-collector.js.map +1 -0
- package/dist/ai/cost-tracker.d.ts +41 -0
- package/dist/ai/cost-tracker.d.ts.map +1 -0
- package/dist/ai/cost-tracker.js +131 -0
- package/dist/ai/cost-tracker.js.map +1 -0
- package/dist/ai/env.d.ts +36 -0
- package/dist/ai/env.d.ts.map +1 -0
- package/dist/ai/env.js +100 -0
- package/dist/ai/env.js.map +1 -0
- package/dist/ai/index.d.ts +17 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +25 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/model-router.d.ts +32 -0
- package/dist/ai/model-router.d.ts.map +1 -0
- package/dist/ai/model-router.js +113 -0
- package/dist/ai/model-router.js.map +1 -0
- package/dist/ai/output-validator.d.ts +24 -0
- package/dist/ai/output-validator.d.ts.map +1 -0
- package/dist/ai/output-validator.js +279 -0
- package/dist/ai/output-validator.js.map +1 -0
- package/dist/ai/prompt-assembler.d.ts +30 -0
- package/dist/ai/prompt-assembler.d.ts.map +1 -0
- package/dist/ai/prompt-assembler.js +93 -0
- package/dist/ai/prompt-assembler.js.map +1 -0
- package/dist/ai/prompt-pipeline.d.ts +63 -0
- package/dist/ai/prompt-pipeline.d.ts.map +1 -0
- package/dist/ai/prompt-pipeline.js +119 -0
- package/dist/ai/prompt-pipeline.js.map +1 -0
- package/dist/ai/prompt-template.jig +88 -0
- package/dist/ai/transports/api-transport.d.ts +12 -0
- package/dist/ai/transports/api-transport.d.ts.map +1 -0
- package/dist/ai/transports/api-transport.js +86 -0
- package/dist/ai/transports/api-transport.js.map +1 -0
- package/dist/ai/transports/command-transport.d.ts +20 -0
- package/dist/ai/transports/command-transport.d.ts.map +1 -0
- package/dist/ai/transports/command-transport.js +203 -0
- package/dist/ai/transports/command-transport.js.map +1 -0
- package/dist/ai/transports/index.d.ts +11 -0
- package/dist/ai/transports/index.d.ts.map +1 -0
- package/dist/ai/transports/index.js +10 -0
- package/dist/ai/transports/index.js.map +1 -0
- package/dist/ai/transports/resolve-transport.d.ts +15 -0
- package/dist/ai/transports/resolve-transport.d.ts.map +1 -0
- package/dist/ai/transports/resolve-transport.js +96 -0
- package/dist/ai/transports/resolve-transport.js.map +1 -0
- package/dist/ai/transports/stdout-transport.d.ts +14 -0
- package/dist/ai/transports/stdout-transport.d.ts.map +1 -0
- package/dist/ai/transports/stdout-transport.js +27 -0
- package/dist/ai/transports/stdout-transport.js.map +1 -0
- package/dist/ai/transports/types.d.ts +77 -0
- package/dist/ai/transports/types.d.ts.map +1 -0
- package/dist/ai/transports/types.js +8 -0
- package/dist/ai/transports/types.js.map +1 -0
- package/dist/commands/cookbook/info.d.ts +22 -0
- package/dist/commands/cookbook/info.d.ts.map +1 -0
- package/dist/commands/cookbook/info.js +217 -0
- package/dist/commands/cookbook/info.js.map +1 -0
- package/dist/commands/cookbook/list.d.ts +20 -0
- package/dist/commands/cookbook/list.d.ts.map +1 -0
- package/dist/commands/cookbook/list.js +133 -0
- package/dist/commands/cookbook/list.js.map +1 -0
- package/dist/commands/gen.d.ts +65 -0
- package/dist/commands/gen.d.ts.map +1 -0
- package/dist/commands/gen.js +478 -0
- package/dist/commands/gen.js.map +1 -0
- package/dist/commands/recipe/info.d.ts +18 -0
- package/dist/commands/recipe/info.d.ts.map +1 -0
- package/dist/commands/recipe/info.js +89 -0
- package/dist/commands/recipe/info.js.map +1 -0
- package/dist/commands/recipe/list.d.ts +29 -0
- package/dist/commands/recipe/list.d.ts.map +1 -0
- package/dist/commands/recipe/list.js +215 -0
- package/dist/commands/recipe/list.js.map +1 -0
- package/dist/commands/recipe/run.d.ts +44 -0
- package/dist/commands/recipe/run.d.ts.map +1 -0
- package/dist/commands/recipe/run.js +239 -0
- package/dist/commands/recipe/run.js.map +1 -0
- package/dist/commands/recipe/validate.d.ts +19 -0
- package/dist/commands/recipe/validate.d.ts.map +1 -0
- package/dist/commands/recipe/validate.js +66 -0
- package/dist/commands/recipe/validate.js.map +1 -0
- package/dist/discovery/generator-discovery.d.ts +130 -0
- package/dist/discovery/generator-discovery.d.ts.map +1 -0
- package/dist/discovery/generator-discovery.js +674 -0
- package/dist/discovery/generator-discovery.js.map +1 -0
- package/dist/discovery/index.d.ts +8 -0
- package/dist/discovery/index.d.ts.map +1 -0
- package/dist/discovery/index.js +7 -0
- package/dist/discovery/index.js.map +1 -0
- package/dist/hooks/command-not-found.d.ts +18 -0
- package/dist/hooks/command-not-found.d.ts.map +1 -0
- package/dist/hooks/command-not-found.js +182 -0
- package/dist/hooks/command-not-found.js.map +1 -0
- package/dist/hooks/suggest.d.ts +13 -0
- package/dist/hooks/suggest.d.ts.map +1 -0
- package/dist/hooks/suggest.js +28 -0
- package/dist/hooks/suggest.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/base-command.d.ts +26 -0
- package/dist/lib/base-command.d.ts.map +1 -0
- package/dist/lib/base-command.js +24 -0
- package/dist/lib/base-command.js.map +1 -0
- package/dist/lib/flags.d.ts +33 -0
- package/dist/lib/flags.d.ts.map +1 -0
- package/dist/lib/flags.js +64 -0
- package/dist/lib/flags.js.map +1 -0
- package/dist/ops/add.d.ts +4 -0
- package/dist/ops/add.d.ts.map +1 -0
- package/dist/ops/add.js +85 -0
- package/dist/ops/add.js.map +1 -0
- package/dist/ops/inject.d.ts +4 -0
- package/dist/ops/inject.d.ts.map +1 -0
- package/dist/ops/inject.js +28 -0
- package/dist/ops/inject.js.map +1 -0
- package/dist/ops/injector.d.ts +4 -0
- package/dist/ops/injector.d.ts.map +1 -0
- package/dist/ops/injector.js +68 -0
- package/dist/ops/injector.js.map +1 -0
- package/dist/ops/result.d.ts +3 -0
- package/dist/ops/result.d.ts.map +1 -0
- package/dist/ops/result.js +8 -0
- package/dist/ops/result.js.map +1 -0
- package/dist/prompts/interactive-prompts.d.ts +152 -0
- package/dist/prompts/interactive-prompts.d.ts.map +1 -0
- package/dist/prompts/interactive-prompts.js +574 -0
- package/dist/prompts/interactive-prompts.js.map +1 -0
- package/dist/recipe-engine/group-executor.d.ts +97 -0
- package/dist/recipe-engine/group-executor.d.ts.map +1 -0
- package/dist/recipe-engine/group-executor.js +293 -0
- package/dist/recipe-engine/group-executor.js.map +1 -0
- package/dist/recipe-engine/index.d.ts +112 -0
- package/dist/recipe-engine/index.d.ts.map +1 -0
- package/dist/recipe-engine/index.js +223 -0
- package/dist/recipe-engine/index.js.map +1 -0
- package/dist/recipe-engine/output-evaluator.d.ts +28 -0
- package/dist/recipe-engine/output-evaluator.d.ts.map +1 -0
- package/dist/recipe-engine/output-evaluator.js +78 -0
- package/dist/recipe-engine/output-evaluator.js.map +1 -0
- package/dist/recipe-engine/recipe-engine.d.ts +227 -0
- package/dist/recipe-engine/recipe-engine.d.ts.map +1 -0
- package/dist/recipe-engine/recipe-engine.js +1036 -0
- package/dist/recipe-engine/recipe-engine.js.map +1 -0
- package/dist/recipe-engine/step-executor.d.ts +172 -0
- package/dist/recipe-engine/step-executor.d.ts.map +1 -0
- package/dist/recipe-engine/step-executor.js +802 -0
- package/dist/recipe-engine/step-executor.js.map +1 -0
- package/dist/recipe-engine/tools/action-tool.d.ts +103 -0
- package/dist/recipe-engine/tools/action-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/action-tool.js +473 -0
- package/dist/recipe-engine/tools/action-tool.js.map +1 -0
- package/dist/recipe-engine/tools/ai-tool.d.ts +26 -0
- package/dist/recipe-engine/tools/ai-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/ai-tool.js +233 -0
- package/dist/recipe-engine/tools/ai-tool.js.map +1 -0
- package/dist/recipe-engine/tools/base.d.ts +214 -0
- package/dist/recipe-engine/tools/base.d.ts.map +1 -0
- package/dist/recipe-engine/tools/base.js +397 -0
- package/dist/recipe-engine/tools/base.js.map +1 -0
- package/dist/recipe-engine/tools/codemod-tool.d.ts +130 -0
- package/dist/recipe-engine/tools/codemod-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/codemod-tool.js +786 -0
- package/dist/recipe-engine/tools/codemod-tool.js.map +1 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.js +130 -0
- package/dist/recipe-engine/tools/ensure-dirs-tool.js.map +1 -0
- package/dist/recipe-engine/tools/index.d.ts +126 -0
- package/dist/recipe-engine/tools/index.d.ts.map +1 -0
- package/dist/recipe-engine/tools/index.js +290 -0
- package/dist/recipe-engine/tools/index.js.map +1 -0
- package/dist/recipe-engine/tools/install-tool.d.ts +20 -0
- package/dist/recipe-engine/tools/install-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/install-tool.js +194 -0
- package/dist/recipe-engine/tools/install-tool.js.map +1 -0
- package/dist/recipe-engine/tools/parallel-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/parallel-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/parallel-tool.js +134 -0
- package/dist/recipe-engine/tools/parallel-tool.js.map +1 -0
- package/dist/recipe-engine/tools/patch-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/patch-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/patch-tool.js +248 -0
- package/dist/recipe-engine/tools/patch-tool.js.map +1 -0
- package/dist/recipe-engine/tools/prompt-tool.d.ts +25 -0
- package/dist/recipe-engine/tools/prompt-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/prompt-tool.js +162 -0
- package/dist/recipe-engine/tools/prompt-tool.js.map +1 -0
- package/dist/recipe-engine/tools/query-tool.d.ts +21 -0
- package/dist/recipe-engine/tools/query-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/query-tool.js +249 -0
- package/dist/recipe-engine/tools/query-tool.js.map +1 -0
- package/dist/recipe-engine/tools/recipe-tool.d.ts +103 -0
- package/dist/recipe-engine/tools/recipe-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/recipe-tool.js +617 -0
- package/dist/recipe-engine/tools/recipe-tool.js.map +1 -0
- package/dist/recipe-engine/tools/registry.d.ts +151 -0
- package/dist/recipe-engine/tools/registry.d.ts.map +1 -0
- package/dist/recipe-engine/tools/registry.js +244 -0
- package/dist/recipe-engine/tools/registry.js.map +1 -0
- package/dist/recipe-engine/tools/sequence-tool.d.ts +22 -0
- package/dist/recipe-engine/tools/sequence-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/sequence-tool.js +122 -0
- package/dist/recipe-engine/tools/sequence-tool.js.map +1 -0
- package/dist/recipe-engine/tools/shell-tool.d.ts +25 -0
- package/dist/recipe-engine/tools/shell-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/shell-tool.js +149 -0
- package/dist/recipe-engine/tools/shell-tool.js.map +1 -0
- package/dist/recipe-engine/tools/template-tool.d.ts +88 -0
- package/dist/recipe-engine/tools/template-tool.d.ts.map +1 -0
- package/dist/recipe-engine/tools/template-tool.js +613 -0
- package/dist/recipe-engine/tools/template-tool.js.map +1 -0
- package/dist/recipe-engine/types.d.ts +963 -0
- package/dist/recipe-engine/types.d.ts.map +1 -0
- package/dist/recipe-engine/types.js +94 -0
- package/dist/recipe-engine/types.js.map +1 -0
- package/dist/template-engines/ai-tags.d.ts +26 -0
- package/dist/template-engines/ai-tags.d.ts.map +1 -0
- package/dist/template-engines/ai-tags.js +233 -0
- package/dist/template-engines/ai-tags.js.map +1 -0
- package/dist/template-engines/index.d.ts +8 -0
- package/dist/template-engines/index.d.ts.map +1 -0
- package/dist/template-engines/index.js +8 -0
- package/dist/template-engines/index.js.map +1 -0
- package/dist/template-engines/jig-engine.d.ts +47 -0
- package/dist/template-engines/jig-engine.d.ts.map +1 -0
- package/dist/template-engines/jig-engine.js +173 -0
- package/dist/template-engines/jig-engine.js.map +1 -0
- package/dist/utils/coerce-value.d.ts +7 -0
- package/dist/utils/coerce-value.d.ts.map +1 -0
- package/dist/utils/coerce-value.js +18 -0
- package/dist/utils/coerce-value.js.map +1 -0
- package/dist/utils/diff.d.ts +8 -0
- package/dist/utils/diff.d.ts.map +1 -0
- package/dist/utils/diff.js +10 -0
- package/dist/utils/diff.js.map +1 -0
- package/dist/utils/global-packages.d.ts +11 -0
- package/dist/utils/global-packages.d.ts.map +1 -0
- package/dist/utils/global-packages.js +88 -0
- package/dist/utils/global-packages.js.map +1 -0
- package/dist/utils/pager.d.ts +6 -0
- package/dist/utils/pager.d.ts.map +1 -0
- package/dist/utils/pager.js +41 -0
- package/dist/utils/pager.js.map +1 -0
- package/help/cookbook/info.md +35 -0
- package/help/cookbook/list.md +37 -0
- package/help/gen.md +26 -0
- package/help/recipe/run.md +52 -0
- package/help/recipe/validate.md +51 -0
- package/oclif.manifest.json +580 -0
- package/package.json +120 -0
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Service Configuration Types
|
|
3
|
+
*
|
|
4
|
+
* Types for configuring the AI integration in Hypergen.
|
|
5
|
+
* Used in hypergen.config.js under the `ai` key.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Top-level AI configuration for hypergen.config.js
|
|
9
|
+
*/
|
|
10
|
+
export interface AiServiceConfig {
|
|
11
|
+
/**
|
|
12
|
+
* Path to a custom Jig template for the prompt document generated during
|
|
13
|
+
* Pass 1 of 2-pass AI generation. When omitted the built-in template
|
|
14
|
+
* shipped with Hypergen is used. Relative paths are resolved from the
|
|
15
|
+
* project root.
|
|
16
|
+
*/
|
|
17
|
+
promptTemplate?: string;
|
|
18
|
+
/** Default AI provider (e.g., 'anthropic', 'openai', 'ollama') */
|
|
19
|
+
provider?: string;
|
|
20
|
+
/** Default model (e.g., 'claude-sonnet-4-5', 'gpt-4o') */
|
|
21
|
+
model?: string;
|
|
22
|
+
/**
|
|
23
|
+
* Name of the environment variable that holds the API key.
|
|
24
|
+
* Example: 'ANTHROPIC_API_KEY'
|
|
25
|
+
*
|
|
26
|
+
* When omitted, a well-known default is inferred from the provider
|
|
27
|
+
* (e.g., provider 'anthropic' → ANTHROPIC_API_KEY).
|
|
28
|
+
*
|
|
29
|
+
* The env var is loaded automatically from .env files via dotenvx.
|
|
30
|
+
* NEVER put actual API keys in config — config files are committed.
|
|
31
|
+
*/
|
|
32
|
+
apiKeyEnvVar?: string;
|
|
33
|
+
/** Default system prompt prepended to all AI calls */
|
|
34
|
+
systemPrompt?: string;
|
|
35
|
+
/** Default temperature (0-2) */
|
|
36
|
+
temperature?: number;
|
|
37
|
+
/** Default max output tokens */
|
|
38
|
+
maxTokens?: number;
|
|
39
|
+
/**
|
|
40
|
+
* AI resolution mode for 2-pass @ai blocks.
|
|
41
|
+
* - 'auto': detect from config (default) — API key → api, command set → command, else stdout
|
|
42
|
+
* - 'api': call LLM via Vercel AI SDK (requires provider + API key env var)
|
|
43
|
+
* - 'command': pipe prompt to a CLI command (requires ai.command)
|
|
44
|
+
* - 'stdout': print prompt to stdout, exit code 2 (for AI agents)
|
|
45
|
+
* - 'off': no AI automation (same as stdout now; future: interactive prompts)
|
|
46
|
+
*/
|
|
47
|
+
mode?: "auto" | "api" | "command" | "stdout" | "off";
|
|
48
|
+
/**
|
|
49
|
+
* CLI command template for 'command' mode.
|
|
50
|
+
* Include {prompt} for argument substitution, or omit to pipe via stdin.
|
|
51
|
+
* Examples: 'claude -p {prompt}', 'llm', 'aichat -r coder'
|
|
52
|
+
*/
|
|
53
|
+
command?: string;
|
|
54
|
+
/**
|
|
55
|
+
* How command mode handles multiple @ai blocks.
|
|
56
|
+
* - 'batched': one invocation, expects JSON response (default)
|
|
57
|
+
* - 'per-block': one invocation per @ai block, raw text response
|
|
58
|
+
*/
|
|
59
|
+
commandMode?: "batched" | "per-block";
|
|
60
|
+
/** Cost budget configuration */
|
|
61
|
+
budget?: AIBudgetConfig;
|
|
62
|
+
/** Default guardrails applied to all AI steps */
|
|
63
|
+
defaultGuardrails?: AIGuardrailConfig;
|
|
64
|
+
/** Fallback models tried when primary fails */
|
|
65
|
+
fallbackModels?: AIModelRef[];
|
|
66
|
+
/** Cost table for token pricing (model name → pricing) */
|
|
67
|
+
costTable?: Record<string, AIModelPricing>;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Reference to a specific model on a specific provider
|
|
71
|
+
*/
|
|
72
|
+
export interface AIModelRef {
|
|
73
|
+
provider: string;
|
|
74
|
+
model: string;
|
|
75
|
+
/** Name of the environment variable holding the API key for this fallback */
|
|
76
|
+
apiKeyEnvVar?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Token pricing for a model
|
|
80
|
+
*/
|
|
81
|
+
export interface AIModelPricing {
|
|
82
|
+
/** Cost per 1M input tokens in USD */
|
|
83
|
+
inputPer1M: number;
|
|
84
|
+
/** Cost per 1M output tokens in USD */
|
|
85
|
+
outputPer1M: number;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Budget configuration for AI cost control
|
|
89
|
+
*/
|
|
90
|
+
export interface AIBudgetConfig {
|
|
91
|
+
/** Hard limit: abort if total cost exceeds this (USD) */
|
|
92
|
+
maxTotalCostUsd?: number;
|
|
93
|
+
/** Warning threshold (USD) */
|
|
94
|
+
warnAtCostUsd?: number;
|
|
95
|
+
/** Hard limit on total tokens across all AI steps */
|
|
96
|
+
maxTotalTokens?: number;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* How AI output is used
|
|
100
|
+
*/
|
|
101
|
+
export interface AIOutputConfig {
|
|
102
|
+
/** Output destination type */
|
|
103
|
+
type: "variable" | "file" | "inject" | "stdout";
|
|
104
|
+
/** Variable name to store result (for type='variable') */
|
|
105
|
+
variable?: string;
|
|
106
|
+
/** File path to write (supports Liquid interpolation, for type='file') */
|
|
107
|
+
to?: string;
|
|
108
|
+
/** File path to inject into (for type='inject') */
|
|
109
|
+
injectInto?: string;
|
|
110
|
+
/** Inject after this pattern */
|
|
111
|
+
after?: string;
|
|
112
|
+
/** Inject before this pattern */
|
|
113
|
+
before?: string;
|
|
114
|
+
/** Inject at start or end of file */
|
|
115
|
+
at?: "start" | "end";
|
|
116
|
+
/** Zod-compatible JSON schema for structured output */
|
|
117
|
+
schema?: Record<string, any>;
|
|
118
|
+
/** Load schema from file */
|
|
119
|
+
schemaFile?: string;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Context files and data to include in the prompt
|
|
123
|
+
*/
|
|
124
|
+
export interface AIContextConfig {
|
|
125
|
+
/** Glob patterns for context files */
|
|
126
|
+
files?: string[];
|
|
127
|
+
/** Explicit file paths to include */
|
|
128
|
+
include?: string[];
|
|
129
|
+
/** Include project config files */
|
|
130
|
+
projectConfig?: boolean | ("tsconfig" | "package.json" | "eslint" | ".editorconfig")[];
|
|
131
|
+
/** Include output from previous recipe steps */
|
|
132
|
+
fromSteps?: string[];
|
|
133
|
+
/** Token budget for context (prevents blowup) */
|
|
134
|
+
maxContextTokens?: number;
|
|
135
|
+
/** What to do when context exceeds budget */
|
|
136
|
+
overflow?: "truncate" | "summarize" | "error";
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Few-shot example for improving generation quality
|
|
140
|
+
*/
|
|
141
|
+
export interface AIExample {
|
|
142
|
+
/** Human-readable label */
|
|
143
|
+
label?: string;
|
|
144
|
+
/** Example input/prompt */
|
|
145
|
+
input: string;
|
|
146
|
+
/** Expected output */
|
|
147
|
+
output: string;
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Guardrails for validating AI output
|
|
151
|
+
*/
|
|
152
|
+
export interface AIGuardrailConfig {
|
|
153
|
+
/** Syntax validation (language-specific) */
|
|
154
|
+
validateSyntax?: boolean | ("typescript" | "javascript" | "json" | "yaml" | "css" | "html");
|
|
155
|
+
/** Only allow imports from these packages */
|
|
156
|
+
allowedImports?: string[];
|
|
157
|
+
/** Block specific imports */
|
|
158
|
+
blockedImports?: string[];
|
|
159
|
+
/** All imports must exist in package.json */
|
|
160
|
+
requireKnownImports?: boolean;
|
|
161
|
+
/** Max output length in characters */
|
|
162
|
+
maxOutputLength?: number;
|
|
163
|
+
/** Custom validator module path */
|
|
164
|
+
customValidator?: string;
|
|
165
|
+
/** Retry attempts on validation failure */
|
|
166
|
+
retryOnFailure?: number;
|
|
167
|
+
/** What to do on failure */
|
|
168
|
+
onFailure?: "error" | "retry" | "retry-with-feedback" | "fallback";
|
|
169
|
+
/** Static fallback if all retries fail */
|
|
170
|
+
fallback?: string;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* AI execution result returned by AiService
|
|
174
|
+
*/
|
|
175
|
+
export interface AIExecutionResult {
|
|
176
|
+
/** Generated text output */
|
|
177
|
+
output: string;
|
|
178
|
+
/** Structured output (if schema was provided) */
|
|
179
|
+
structured?: Record<string, any>;
|
|
180
|
+
/** Token usage */
|
|
181
|
+
usage: {
|
|
182
|
+
inputTokens: number;
|
|
183
|
+
outputTokens: number;
|
|
184
|
+
totalTokens: number;
|
|
185
|
+
};
|
|
186
|
+
/** Estimated cost in USD */
|
|
187
|
+
costUsd: number;
|
|
188
|
+
/** Model used */
|
|
189
|
+
model: string;
|
|
190
|
+
/** Provider used */
|
|
191
|
+
provider: string;
|
|
192
|
+
/** Number of retry attempts made */
|
|
193
|
+
retryAttempts: number;
|
|
194
|
+
/** Validation results */
|
|
195
|
+
validation?: {
|
|
196
|
+
passed: boolean;
|
|
197
|
+
errors: string[];
|
|
198
|
+
};
|
|
199
|
+
/** Duration in milliseconds */
|
|
200
|
+
durationMs: number;
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Cost summary for an entire recipe execution
|
|
204
|
+
*/
|
|
205
|
+
export interface AICostSummary {
|
|
206
|
+
/** Total input tokens across all AI steps */
|
|
207
|
+
totalInputTokens: number;
|
|
208
|
+
/** Total output tokens across all AI steps */
|
|
209
|
+
totalOutputTokens: number;
|
|
210
|
+
/** Total tokens */
|
|
211
|
+
totalTokens: number;
|
|
212
|
+
/** Total estimated cost in USD */
|
|
213
|
+
totalCostUsd: number;
|
|
214
|
+
/** Number of AI steps executed */
|
|
215
|
+
stepCount: number;
|
|
216
|
+
/** Per-step breakdown */
|
|
217
|
+
steps: Array<{
|
|
218
|
+
stepName: string;
|
|
219
|
+
model: string;
|
|
220
|
+
inputTokens: number;
|
|
221
|
+
outputTokens: number;
|
|
222
|
+
costUsd: number;
|
|
223
|
+
retryAttempts: number;
|
|
224
|
+
}>;
|
|
225
|
+
/** Whether budget warning was triggered */
|
|
226
|
+
budgetWarningTriggered: boolean;
|
|
227
|
+
/** Whether budget limit was hit */
|
|
228
|
+
budgetLimitHit: boolean;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=ai-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-config.d.ts","sourceRoot":"","sources":["../../src/ai/ai-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-config.js","sourceRoot":"","sources":["../../src/ai/ai-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Service
|
|
3
|
+
*
|
|
4
|
+
* Central gateway for all AI operations in Hypergen.
|
|
5
|
+
* Used by both AiTool (recipe steps) and {% ai %} (template tag).
|
|
6
|
+
* Orchestrates prompt pipeline, model routing, output validation,
|
|
7
|
+
* retry-with-feedback, and cost tracking.
|
|
8
|
+
*/
|
|
9
|
+
import type { StepResult } from "#recipe-engine/types";
|
|
10
|
+
import type { AICostSummary, AIExecutionResult, AIGuardrailConfig, AiServiceConfig } from "./ai-config.js";
|
|
11
|
+
import { type PromptPipelineOptions } from "./prompt-pipeline.js";
|
|
12
|
+
/**
|
|
13
|
+
* Options for a single AI generation call
|
|
14
|
+
*/
|
|
15
|
+
export interface GenerateOptions {
|
|
16
|
+
/** The prompt text (already Liquid-rendered) */
|
|
17
|
+
prompt: string;
|
|
18
|
+
/** System prompt override */
|
|
19
|
+
system?: string;
|
|
20
|
+
/** Model override */
|
|
21
|
+
model?: string;
|
|
22
|
+
/** Provider override */
|
|
23
|
+
provider?: string;
|
|
24
|
+
/** Temperature (0-2) */
|
|
25
|
+
temperature?: number;
|
|
26
|
+
/** Max output tokens */
|
|
27
|
+
maxTokens?: number;
|
|
28
|
+
/** Stream to terminal */
|
|
29
|
+
stream?: boolean;
|
|
30
|
+
/** Context configuration */
|
|
31
|
+
context?: PromptPipelineOptions["context"];
|
|
32
|
+
/** Few-shot examples */
|
|
33
|
+
examples?: PromptPipelineOptions["examples"];
|
|
34
|
+
/** Guardrails */
|
|
35
|
+
guardrails?: AIGuardrailConfig;
|
|
36
|
+
/** Project root */
|
|
37
|
+
projectRoot: string;
|
|
38
|
+
/** Previous step results */
|
|
39
|
+
stepResults?: Map<string, StepResult>;
|
|
40
|
+
/** Step name for cost tracking */
|
|
41
|
+
stepName?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare class AiService {
|
|
44
|
+
private readonly config;
|
|
45
|
+
private static instance;
|
|
46
|
+
private readonly modelRouter;
|
|
47
|
+
private readonly costTracker;
|
|
48
|
+
private readonly promptPipeline;
|
|
49
|
+
private constructor();
|
|
50
|
+
static getInstance(config?: AiServiceConfig): AiService;
|
|
51
|
+
static reset(): void;
|
|
52
|
+
/**
|
|
53
|
+
* Generate text using AI with full pipeline: prompt assembly, model routing,
|
|
54
|
+
* validation, retry-with-feedback, and cost tracking.
|
|
55
|
+
*/
|
|
56
|
+
generate(options: GenerateOptions): Promise<AIExecutionResult>;
|
|
57
|
+
/**
|
|
58
|
+
* Get cost summary for the current execution
|
|
59
|
+
*/
|
|
60
|
+
getCostSummary(): AICostSummary;
|
|
61
|
+
/**
|
|
62
|
+
* Get formatted cost report
|
|
63
|
+
*/
|
|
64
|
+
getCostReport(): string;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=ai-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-service.d.ts","sourceRoot":"","sources":["../../src/ai/ai-service.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EACX,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EAAkB,KAAK,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAIlF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC/B,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wBAAwB;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,yBAAyB;IACzB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,qBAAqB,CAAC,SAAS,CAAC,CAAC;IAC3C,wBAAwB;IACxB,QAAQ,CAAC,EAAE,qBAAqB,CAAC,UAAU,CAAC,CAAC;IAC7C,iBAAiB;IACjB,UAAU,CAAC,EAAE,iBAAiB,CAAC;IAC/B,mBAAmB;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACtC,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,SAAS;IAOD,OAAO,CAAC,QAAQ,CAAC,MAAM;IAN3C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA0B;IAEjD,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAc;IAC1C,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAEhD,OAAO;IAOP,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,eAAe,GAAG,SAAS;IAcvD,MAAM,CAAC,KAAK,IAAI,IAAI;IAIpB;;;OAGG;IACG,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkNpE;;OAEG;IACH,cAAc,IAAI,aAAa;IAI/B;;OAEG;IACH,aAAa,IAAI,MAAM;CAGvB"}
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Service
|
|
3
|
+
*
|
|
4
|
+
* Central gateway for all AI operations in Hypergen.
|
|
5
|
+
* Used by both AiTool (recipe steps) and {% ai %} (template tag).
|
|
6
|
+
* Orchestrates prompt pipeline, model routing, output validation,
|
|
7
|
+
* retry-with-feedback, and cost tracking.
|
|
8
|
+
*/
|
|
9
|
+
import { ErrorCode, ErrorHandler } from "@hypercli/core";
|
|
10
|
+
import createDebug from "debug";
|
|
11
|
+
import { CostTracker } from "./cost-tracker.js";
|
|
12
|
+
import { ModelRouter } from "./model-router.js";
|
|
13
|
+
import { buildValidationFeedback, validateOutput } from "./output-validator.js";
|
|
14
|
+
import { PromptPipeline } from "./prompt-pipeline.js";
|
|
15
|
+
const debug = createDebug("hypergen:ai:service");
|
|
16
|
+
export class AiService {
|
|
17
|
+
config;
|
|
18
|
+
static instance = null;
|
|
19
|
+
modelRouter;
|
|
20
|
+
costTracker;
|
|
21
|
+
promptPipeline;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.config = config;
|
|
24
|
+
this.modelRouter = new ModelRouter(config);
|
|
25
|
+
this.costTracker = new CostTracker(config.budget, config.costTable);
|
|
26
|
+
this.promptPipeline = new PromptPipeline();
|
|
27
|
+
debug("AiService initialized");
|
|
28
|
+
}
|
|
29
|
+
static getInstance(config) {
|
|
30
|
+
if (!AiService.instance) {
|
|
31
|
+
if (!config) {
|
|
32
|
+
throw ErrorHandler.createError(ErrorCode.AI_PROVIDER_UNAVAILABLE, "AiService not initialized. Provide AiServiceConfig on first call.", {});
|
|
33
|
+
}
|
|
34
|
+
AiService.instance = new AiService(config);
|
|
35
|
+
}
|
|
36
|
+
return AiService.instance;
|
|
37
|
+
}
|
|
38
|
+
static reset() {
|
|
39
|
+
AiService.instance = null;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generate text using AI with full pipeline: prompt assembly, model routing,
|
|
43
|
+
* validation, retry-with-feedback, and cost tracking.
|
|
44
|
+
*/
|
|
45
|
+
async generate(options) {
|
|
46
|
+
const startTime = Date.now();
|
|
47
|
+
const stepName = options.stepName || "unnamed";
|
|
48
|
+
// Check budget before starting
|
|
49
|
+
this.costTracker.checkBudget();
|
|
50
|
+
// Resolve model
|
|
51
|
+
const resolved = await this.modelRouter.resolve(options.provider, options.model);
|
|
52
|
+
// Merge guardrails: config defaults + step overrides
|
|
53
|
+
const guardrails = {
|
|
54
|
+
...this.config.defaultGuardrails,
|
|
55
|
+
...options.guardrails,
|
|
56
|
+
};
|
|
57
|
+
// Assemble prompt
|
|
58
|
+
const assembled = await this.promptPipeline.assemble({
|
|
59
|
+
globalSystemPrompt: this.config.systemPrompt,
|
|
60
|
+
stepSystemPrompt: options.system,
|
|
61
|
+
guardrails,
|
|
62
|
+
prompt: options.prompt,
|
|
63
|
+
context: options.context,
|
|
64
|
+
examples: options.examples,
|
|
65
|
+
projectRoot: options.projectRoot,
|
|
66
|
+
stepResults: options.stepResults || new Map(),
|
|
67
|
+
maxOutputTokens: options.maxTokens,
|
|
68
|
+
});
|
|
69
|
+
// Retry loop
|
|
70
|
+
const maxRetries = guardrails.retryOnFailure ?? 0;
|
|
71
|
+
let lastOutput = "";
|
|
72
|
+
let lastValidation = { passed: true, errors: [] };
|
|
73
|
+
let retryAttempts = 0;
|
|
74
|
+
let totalInputTokens = 0;
|
|
75
|
+
let totalOutputTokens = 0;
|
|
76
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
77
|
+
let userPrompt = assembled.user;
|
|
78
|
+
// On retry, append feedback
|
|
79
|
+
if (attempt > 0 && !lastValidation.passed) {
|
|
80
|
+
const feedback = buildValidationFeedback(lastValidation);
|
|
81
|
+
if (guardrails.onFailure === "retry-with-feedback") {
|
|
82
|
+
userPrompt = `${assembled.user}\n\n## Correction Required\n\n${feedback}\n\n## Previous (Incorrect) Output\n\n\`\`\`\n${lastOutput}\n\`\`\``;
|
|
83
|
+
}
|
|
84
|
+
debug("Retry attempt %d with%s feedback", attempt, guardrails.onFailure === "retry-with-feedback" ? "" : "out");
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
// Call Vercel AI SDK
|
|
88
|
+
const { generateText } = await import("ai");
|
|
89
|
+
const result = await generateText({
|
|
90
|
+
model: resolved.model,
|
|
91
|
+
system: assembled.system || undefined,
|
|
92
|
+
prompt: userPrompt,
|
|
93
|
+
temperature: options.temperature ?? this.config.temperature ?? 0.2,
|
|
94
|
+
maxTokens: options.maxTokens ?? this.config.maxTokens,
|
|
95
|
+
});
|
|
96
|
+
lastOutput = result.text;
|
|
97
|
+
const inputTokens = result.usage?.promptTokens ?? 0;
|
|
98
|
+
const outputTokens = result.usage?.completionTokens ?? 0;
|
|
99
|
+
totalInputTokens += inputTokens;
|
|
100
|
+
totalOutputTokens += outputTokens;
|
|
101
|
+
debug("AI response: %d input tokens, %d output tokens", inputTokens, outputTokens);
|
|
102
|
+
// Validate output
|
|
103
|
+
const validation = await validateOutput(lastOutput, guardrails, options.projectRoot);
|
|
104
|
+
lastValidation = validation;
|
|
105
|
+
if (validation.passed) {
|
|
106
|
+
// Record cost
|
|
107
|
+
this.costTracker.record(stepName, resolved.modelName, totalInputTokens, totalOutputTokens, retryAttempts);
|
|
108
|
+
const costUsd = this.costTracker.calculateCost(resolved.modelName, totalInputTokens, totalOutputTokens);
|
|
109
|
+
return {
|
|
110
|
+
output: lastOutput,
|
|
111
|
+
usage: {
|
|
112
|
+
inputTokens: totalInputTokens,
|
|
113
|
+
outputTokens: totalOutputTokens,
|
|
114
|
+
totalTokens: totalInputTokens + totalOutputTokens,
|
|
115
|
+
},
|
|
116
|
+
costUsd,
|
|
117
|
+
model: resolved.modelName,
|
|
118
|
+
provider: resolved.provider,
|
|
119
|
+
retryAttempts,
|
|
120
|
+
validation: { passed: true, errors: [] },
|
|
121
|
+
durationMs: Date.now() - startTime,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
retryAttempts++;
|
|
125
|
+
debug("Validation failed (attempt %d/%d): %s", attempt + 1, maxRetries + 1, validation.errors.join("; "));
|
|
126
|
+
// If we've exhausted retries, handle failure
|
|
127
|
+
if (attempt === maxRetries) {
|
|
128
|
+
// Check if fallback is configured
|
|
129
|
+
if (guardrails.onFailure === "fallback" && guardrails.fallback) {
|
|
130
|
+
debug("Using fallback output");
|
|
131
|
+
this.costTracker.record(stepName, resolved.modelName, totalInputTokens, totalOutputTokens, retryAttempts);
|
|
132
|
+
return {
|
|
133
|
+
output: guardrails.fallback,
|
|
134
|
+
usage: {
|
|
135
|
+
inputTokens: totalInputTokens,
|
|
136
|
+
outputTokens: totalOutputTokens,
|
|
137
|
+
totalTokens: totalInputTokens + totalOutputTokens,
|
|
138
|
+
},
|
|
139
|
+
costUsd: this.costTracker.calculateCost(resolved.modelName, totalInputTokens, totalOutputTokens),
|
|
140
|
+
model: resolved.modelName,
|
|
141
|
+
provider: resolved.provider,
|
|
142
|
+
retryAttempts,
|
|
143
|
+
validation: { passed: false, errors: validation.errors },
|
|
144
|
+
durationMs: Date.now() - startTime,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
// Record cost even on failure
|
|
148
|
+
this.costTracker.record(stepName, resolved.modelName, totalInputTokens, totalOutputTokens, retryAttempts);
|
|
149
|
+
throw ErrorHandler.createError(ErrorCode.AI_GENERATION_FAILED, `AI output failed validation after ${maxRetries + 1} attempts: ${validation.errors.join("; ")}`, {});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
// Handle API-level errors
|
|
154
|
+
if (error.code === ErrorCode.AI_GENERATION_FAILED ||
|
|
155
|
+
(error instanceof Error && error.name === "HypergenError")) {
|
|
156
|
+
throw error;
|
|
157
|
+
}
|
|
158
|
+
// Rate limiting
|
|
159
|
+
if (error.status === 429 || error.statusCode === 429) {
|
|
160
|
+
const retryAfter = error.headers?.["retry-after"]
|
|
161
|
+
? Number.parseInt(error.headers["retry-after"]) * 1000
|
|
162
|
+
: 5000;
|
|
163
|
+
debug("Rate limited, waiting %dms", retryAfter);
|
|
164
|
+
await sleep(retryAfter);
|
|
165
|
+
retryAttempts++;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
// Network/API errors on last attempt
|
|
169
|
+
if (attempt === maxRetries) {
|
|
170
|
+
throw ErrorHandler.createError(ErrorCode.AI_GENERATION_FAILED, `AI generation failed: ${error.message}`, {});
|
|
171
|
+
}
|
|
172
|
+
// Retry with backoff
|
|
173
|
+
const backoff = Math.min(1000 * 2 ** attempt, 30000);
|
|
174
|
+
debug("API error, retrying in %dms: %s", backoff, error.message);
|
|
175
|
+
await sleep(backoff);
|
|
176
|
+
retryAttempts++;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// Should not reach here, but safety net
|
|
180
|
+
throw ErrorHandler.createError(ErrorCode.AI_GENERATION_FAILED, "AI generation failed unexpectedly", {});
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Get cost summary for the current execution
|
|
184
|
+
*/
|
|
185
|
+
getCostSummary() {
|
|
186
|
+
return this.costTracker.getSummary();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Get formatted cost report
|
|
190
|
+
*/
|
|
191
|
+
getCostReport() {
|
|
192
|
+
return this.costTracker.formatReport();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function sleep(ms) {
|
|
196
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=ai-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-service.js","sourceRoot":"","sources":["../../src/ai/ai-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI Variable Resolver
|
|
3
|
+
*
|
|
4
|
+
* Resolves unresolved recipe variables by batching them into a single AI prompt.
|
|
5
|
+
* Uses the existing AiService/transport infrastructure for the actual LLM call.
|
|
6
|
+
*/
|
|
7
|
+
import type { TemplateVariable } from "@hypercli/core";
|
|
8
|
+
import type { AiServiceConfig } from "./ai-config.js";
|
|
9
|
+
/**
|
|
10
|
+
* Describes a single unresolved variable to be sent to the AI.
|
|
11
|
+
*/
|
|
12
|
+
export interface UnresolvedVariable {
|
|
13
|
+
name: string;
|
|
14
|
+
config: TemplateVariable;
|
|
15
|
+
/** The default value, passed as a suggestion when --no-defaults is active */
|
|
16
|
+
defaultValue?: any;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Metadata about the recipe being executed (gives the AI more context).
|
|
20
|
+
*/
|
|
21
|
+
export interface RecipeMetadata {
|
|
22
|
+
name: string;
|
|
23
|
+
description?: string;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Batched AI variable resolution.
|
|
27
|
+
*
|
|
28
|
+
* Collects all unresolved variables, builds one prompt, calls the LLM,
|
|
29
|
+
* parses the JSON response, and validates each value.
|
|
30
|
+
*/
|
|
31
|
+
export declare class AiVariableResolver {
|
|
32
|
+
private readonly aiConfig;
|
|
33
|
+
constructor(aiConfig: AiServiceConfig);
|
|
34
|
+
/**
|
|
35
|
+
* Resolve a batch of variables via a single AI call.
|
|
36
|
+
*
|
|
37
|
+
* @returns Record mapping variable names to AI-resolved values.
|
|
38
|
+
* Variables the AI could not resolve are omitted.
|
|
39
|
+
*/
|
|
40
|
+
resolveBatch(unresolvedVars: UnresolvedVariable[], resolvedVars: Record<string, any>, recipeMeta: RecipeMetadata, projectContext?: string): Promise<Record<string, any>>;
|
|
41
|
+
/**
|
|
42
|
+
* Build the user prompt that describes what variables need values.
|
|
43
|
+
*/
|
|
44
|
+
buildPrompt(unresolvedVars: UnresolvedVariable[], resolvedVars: Record<string, any>, recipeMeta: RecipeMetadata, projectContext?: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Build the system prompt instructing the AI to return JSON.
|
|
47
|
+
*/
|
|
48
|
+
buildSystemPrompt(unresolvedVars: UnresolvedVariable[]): string;
|
|
49
|
+
/**
|
|
50
|
+
* Parse the AI's JSON response and coerce values to expected types.
|
|
51
|
+
*/
|
|
52
|
+
parseResponse(raw: string, unresolvedVars: UnresolvedVariable[]): Record<string, any>;
|
|
53
|
+
/**
|
|
54
|
+
* Coerce a raw AI value to the expected variable type.
|
|
55
|
+
* Returns undefined if coercion fails.
|
|
56
|
+
*/
|
|
57
|
+
private coerceValue;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=ai-variable-resolver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-variable-resolver.d.ts","sourceRoot":"","sources":["../../src/ai/ai-variable-resolver.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAKtD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,gBAAgB,CAAC;IACzB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,GAAG,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB;IAClB,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,EAAE,eAAe;IAEtD;;;;;OAKG;IACG,YAAY,CACjB,cAAc,EAAE,kBAAkB,EAAE,EACpC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,UAAU,EAAE,cAAc,EAC1B,cAAc,CAAC,EAAE,MAAM,GACrB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IA+B/B;;OAEG;IACH,WAAW,CACV,cAAc,EAAE,kBAAkB,EAAE,EACpC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EACjC,UAAU,EAAE,cAAc,EAC1B,cAAc,CAAC,EAAE,MAAM,GACrB,MAAM;IA0DT;;OAEG;IACH,iBAAiB,CAAC,cAAc,EAAE,kBAAkB,EAAE,GAAG,MAAM;IAc/D;;OAEG;IACH,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,cAAc,EAAE,kBAAkB,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAqDrF;;;OAGG;IACH,OAAO,CAAC,WAAW;CAiDnB"}
|