homegraph 1.2.0 → 1.5.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/README.md +48 -11
- package/dist/bin/homegraph.js +298 -72
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +117 -11
- package/dist/context/index.js.map +1 -1
- package/dist/db/index.d.ts +207 -6
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +461 -20
- package/dist/db/index.js.map +1 -1
- package/dist/db/migrations.d.ts +1 -1
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +19 -1
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +157 -3
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +426 -9
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +32 -1
- package/dist/db/sqlite-adapter.d.ts +24 -17
- package/dist/db/sqlite-adapter.d.ts.map +1 -1
- package/dist/db/sqlite-adapter.js +292 -36
- package/dist/db/sqlite-adapter.js.map +1 -1
- package/dist/db/wal-valve.d.ts +119 -0
- package/dist/db/wal-valve.d.ts.map +1 -0
- package/dist/db/wal-valve.js +290 -0
- package/dist/db/wal-valve.js.map +1 -0
- package/dist/directory.d.ts +9 -5
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +210 -19
- package/dist/directory.js.map +1 -1
- package/dist/extraction/arkts-batch-worker.js +3 -2
- package/dist/extraction/arkts-batch-worker.js.map +1 -1
- package/dist/extraction/cfml-extractor.d.ts +107 -0
- package/dist/extraction/cfml-extractor.d.ts.map +1 -0
- package/dist/extraction/cfml-extractor.js +494 -0
- package/dist/extraction/cfml-extractor.js.map +1 -0
- package/dist/extraction/default-ignore.d.ts +39 -0
- package/dist/extraction/default-ignore.d.ts.map +1 -0
- package/dist/extraction/default-ignore.js +221 -0
- package/dist/extraction/default-ignore.js.map +1 -0
- package/dist/extraction/grammars.d.ts +25 -1
- package/dist/extraction/grammars.d.ts.map +1 -1
- package/dist/extraction/grammars.js +177 -24
- package/dist/extraction/grammars.js.map +1 -1
- package/dist/extraction/index.d.ts +52 -14
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +521 -314
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +90 -6
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1579 -128
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +42 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +369 -4
- package/dist/extraction/languages/c-cpp.js.map +1 -1
- package/dist/extraction/languages/cfquery.d.ts +12 -0
- package/dist/extraction/languages/cfquery.d.ts.map +1 -0
- package/dist/extraction/languages/cfquery.js +28 -0
- package/dist/extraction/languages/cfquery.js.map +1 -0
- package/dist/extraction/languages/cfscript.d.ts +3 -0
- package/dist/extraction/languages/cfscript.d.ts.map +1 -0
- package/dist/extraction/languages/cfscript.js +73 -0
- package/dist/extraction/languages/cfscript.js.map +1 -0
- package/dist/extraction/languages/cobol.d.ts +33 -0
- package/dist/extraction/languages/cobol.d.ts.map +1 -0
- package/dist/extraction/languages/cobol.js +499 -0
- package/dist/extraction/languages/cobol.js.map +1 -0
- package/dist/extraction/languages/erlang.d.ts +3 -0
- package/dist/extraction/languages/erlang.d.ts.map +1 -0
- package/dist/extraction/languages/erlang.js +350 -0
- package/dist/extraction/languages/erlang.js.map +1 -0
- package/dist/extraction/languages/index.d.ts.map +1 -1
- package/dist/extraction/languages/index.js +16 -0
- package/dist/extraction/languages/index.js.map +1 -1
- package/dist/extraction/languages/nix.d.ts +3 -0
- package/dist/extraction/languages/nix.d.ts.map +1 -0
- package/dist/extraction/languages/nix.js +294 -0
- package/dist/extraction/languages/nix.js.map +1 -0
- package/dist/extraction/languages/solidity.d.ts +3 -0
- package/dist/extraction/languages/solidity.d.ts.map +1 -0
- package/dist/extraction/languages/solidity.js +293 -0
- package/dist/extraction/languages/solidity.js.map +1 -0
- package/dist/extraction/languages/terraform.d.ts +3 -0
- package/dist/extraction/languages/terraform.d.ts.map +1 -0
- package/dist/extraction/languages/terraform.js +641 -0
- package/dist/extraction/languages/terraform.js.map +1 -0
- package/dist/extraction/languages/vbnet.d.ts +11 -0
- package/dist/extraction/languages/vbnet.d.ts.map +1 -0
- package/dist/extraction/languages/vbnet.js +141 -0
- package/dist/extraction/languages/vbnet.js.map +1 -0
- package/dist/extraction/mybatis-extractor.d.ts +30 -10
- package/dist/extraction/mybatis-extractor.d.ts.map +1 -1
- package/dist/extraction/mybatis-extractor.js +140 -38
- package/dist/extraction/mybatis-extractor.js.map +1 -1
- package/dist/extraction/parse-pool.d.ts +27 -1
- package/dist/extraction/parse-pool.d.ts.map +1 -1
- package/dist/extraction/parse-pool.js +75 -7
- package/dist/extraction/parse-pool.js.map +1 -1
- package/dist/extraction/parse-worker.js +9 -2
- package/dist/extraction/parse-worker.js.map +1 -1
- package/dist/extraction/store-worker.d.ts +20 -0
- package/dist/extraction/store-worker.d.ts.map +1 -0
- package/dist/extraction/store-worker.js +102 -0
- package/dist/extraction/store-worker.js.map +1 -0
- package/dist/extraction/store-writer.d.ts +48 -0
- package/dist/extraction/store-writer.d.ts.map +1 -0
- package/dist/extraction/store-writer.js +167 -0
- package/dist/extraction/store-writer.js.map +1 -0
- package/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
- package/dist/extraction/tree-sitter-helpers.js +1 -0
- package/dist/extraction/tree-sitter-helpers.js.map +1 -1
- package/dist/extraction/tree-sitter-types.d.ts +3 -1
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +38 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +801 -10
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
- package/dist/extraction/wasm-runtime-flags.d.ts +14 -4
- package/dist/extraction/wasm-runtime-flags.d.ts.map +1 -1
- package/dist/extraction/wasm-runtime-flags.js +55 -7
- package/dist/extraction/wasm-runtime-flags.js.map +1 -1
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +1 -1
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +74 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +436 -55
- package/dist/index.js.map +1 -1
- package/dist/installer/index.d.ts +42 -0
- package/dist/installer/index.d.ts.map +1 -1
- package/dist/installer/index.js +97 -2
- package/dist/installer/index.js.map +1 -1
- package/dist/mcp/daemon.d.ts +25 -3
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +62 -8
- package/dist/mcp/daemon.js.map +1 -1
- package/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
- package/dist/mcp/dynamic-boundaries.js +2 -1
- package/dist/mcp/dynamic-boundaries.js.map +1 -1
- package/dist/mcp/early-ppid.d.ts +26 -0
- package/dist/mcp/early-ppid.d.ts.map +1 -0
- package/dist/mcp/early-ppid.js +29 -0
- package/dist/mcp/early-ppid.js.map +1 -0
- package/dist/mcp/engine.d.ts +4 -5
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +27 -1
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +41 -6
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/liveness-watchdog.d.ts +18 -1
- package/dist/mcp/liveness-watchdog.d.ts.map +1 -1
- package/dist/mcp/liveness-watchdog.js +73 -13
- package/dist/mcp/liveness-watchdog.js.map +1 -1
- package/dist/mcp/memory-budget.d.ts +30 -0
- package/dist/mcp/memory-budget.d.ts.map +1 -0
- package/dist/mcp/memory-budget.js +123 -0
- package/dist/mcp/memory-budget.js.map +1 -0
- package/dist/mcp/proxy.d.ts.map +1 -1
- package/dist/mcp/proxy.js +88 -4
- package/dist/mcp/proxy.js.map +1 -1
- package/dist/mcp/query-cache.d.ts +35 -4
- package/dist/mcp/query-cache.d.ts.map +1 -1
- package/dist/mcp/query-cache.js +89 -19
- package/dist/mcp/query-cache.js.map +1 -1
- package/dist/mcp/query-pool.d.ts +46 -12
- package/dist/mcp/query-pool.d.ts.map +1 -1
- package/dist/mcp/query-pool.js +100 -23
- package/dist/mcp/query-pool.js.map +1 -1
- package/dist/mcp/query-worker.d.ts +2 -2
- package/dist/mcp/query-worker.js +2 -2
- package/dist/mcp/server-instructions.d.ts +4 -27
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +39 -84
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/session.d.ts +14 -0
- package/dist/mcp/session.d.ts.map +1 -1
- package/dist/mcp/session.js +28 -1
- package/dist/mcp/session.js.map +1 -1
- package/dist/mcp/startup-handshake.d.ts +44 -0
- package/dist/mcp/startup-handshake.d.ts.map +1 -0
- package/dist/mcp/startup-handshake.js +73 -0
- package/dist/mcp/startup-handshake.js.map +1 -0
- package/dist/mcp/tools.d.ts +104 -4
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +2432 -217
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/transport.d.ts.map +1 -1
- package/dist/mcp/transport.js +18 -0
- package/dist/mcp/transport.js.map +1 -1
- package/dist/project-config.d.ts +38 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +101 -2
- package/dist/project-config.js.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +178 -146
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +54 -10
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +1299 -257
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +10 -2
- package/dist/resolution/cooperative-yield.d.ts.map +1 -1
- package/dist/resolution/cooperative-yield.js +6 -4
- package/dist/resolution/cooperative-yield.js.map +1 -1
- package/dist/resolution/frameworks/cics.d.ts +20 -0
- package/dist/resolution/frameworks/cics.d.ts.map +1 -0
- package/dist/resolution/frameworks/cics.js +90 -0
- package/dist/resolution/frameworks/cics.js.map +1 -0
- package/dist/resolution/frameworks/go.d.ts.map +1 -1
- package/dist/resolution/frameworks/go.js +29 -6
- package/dist/resolution/frameworks/go.js.map +1 -1
- package/dist/resolution/frameworks/index.d.ts.map +1 -1
- package/dist/resolution/frameworks/index.js +3 -0
- package/dist/resolution/frameworks/index.js.map +1 -1
- package/dist/resolution/frameworks/java.d.ts.map +1 -1
- package/dist/resolution/frameworks/java.js +14 -6
- package/dist/resolution/frameworks/java.js.map +1 -1
- package/dist/resolution/frameworks/terraform.d.ts +38 -0
- package/dist/resolution/frameworks/terraform.d.ts.map +1 -0
- package/dist/resolution/frameworks/terraform.js +277 -0
- package/dist/resolution/frameworks/terraform.js.map +1 -0
- package/dist/resolution/goframe-synthesizer.d.ts +2 -1
- package/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
- package/dist/resolution/goframe-synthesizer.js +8 -3
- package/dist/resolution/goframe-synthesizer.js.map +1 -1
- package/dist/resolution/import-resolver.d.ts +9 -3
- package/dist/resolution/import-resolver.d.ts.map +1 -1
- package/dist/resolution/import-resolver.js +295 -11
- package/dist/resolution/import-resolver.js.map +1 -1
- package/dist/resolution/index.d.ts +146 -8
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +1089 -131
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/memory-budget.d.ts +48 -0
- package/dist/resolution/memory-budget.d.ts.map +1 -0
- package/dist/resolution/memory-budget.js +162 -0
- package/dist/resolution/memory-budget.js.map +1 -0
- package/dist/resolution/name-matcher.d.ts +12 -4
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +793 -130
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/resolution/resolver-pool.d.ts +106 -0
- package/dist/resolution/resolver-pool.d.ts.map +1 -0
- package/dist/resolution/resolver-pool.js +344 -0
- package/dist/resolution/resolver-pool.js.map +1 -0
- package/dist/resolution/resolver-worker.d.ts +17 -0
- package/dist/resolution/resolver-worker.d.ts.map +1 -0
- package/dist/resolution/resolver-worker.js +141 -0
- package/dist/resolution/resolver-worker.js.map +1 -0
- package/dist/resolution/strip-comments.d.ts +1 -1
- package/dist/resolution/strip-comments.d.ts.map +1 -1
- package/dist/resolution/strip-comments.js +49 -0
- package/dist/resolution/strip-comments.js.map +1 -1
- package/dist/resolution/types.d.ts +32 -0
- package/dist/resolution/types.d.ts.map +1 -1
- package/dist/resolution/workspace-packages.d.ts +10 -0
- package/dist/resolution/workspace-packages.d.ts.map +1 -1
- package/dist/resolution/workspace-packages.js +142 -4
- package/dist/resolution/workspace-packages.js.map +1 -1
- package/dist/search/identifier-segments.d.ts +60 -0
- package/dist/search/identifier-segments.d.ts.map +1 -0
- package/dist/search/identifier-segments.js +176 -0
- package/dist/search/identifier-segments.js.map +1 -0
- package/dist/search/query-utils.d.ts +201 -0
- package/dist/search/query-utils.d.ts.map +1 -1
- package/dist/search/query-utils.js +919 -2
- package/dist/search/query-utils.js.map +1 -1
- package/dist/spec/build/diff-parser.d.ts +55 -0
- package/dist/spec/build/diff-parser.d.ts.map +1 -0
- package/dist/spec/build/diff-parser.js +205 -0
- package/dist/spec/build/diff-parser.js.map +1 -0
- package/dist/spec/build/git-scanner.d.ts +93 -0
- package/dist/spec/build/git-scanner.d.ts.map +1 -0
- package/dist/spec/build/git-scanner.js +254 -0
- package/dist/spec/build/git-scanner.js.map +1 -0
- package/dist/spec/build/pipeline.d.ts +54 -0
- package/dist/spec/build/pipeline.d.ts.map +1 -0
- package/dist/spec/build/pipeline.js +170 -0
- package/dist/spec/build/pipeline.js.map +1 -0
- package/dist/spec/build/scan.d.ts +48 -0
- package/dist/spec/build/scan.d.ts.map +1 -0
- package/dist/spec/build/scan.js +89 -0
- package/dist/spec/build/scan.js.map +1 -0
- package/dist/spec/build/scope-resolver.d.ts +50 -0
- package/dist/spec/build/scope-resolver.d.ts.map +1 -0
- package/dist/spec/build/scope-resolver.js +105 -0
- package/dist/spec/build/scope-resolver.js.map +1 -0
- package/dist/spec/build/spec-extractor.d.ts +74 -0
- package/dist/spec/build/spec-extractor.d.ts.map +1 -0
- package/dist/spec/build/spec-extractor.js +344 -0
- package/dist/spec/build/spec-extractor.js.map +1 -0
- package/dist/spec/config.d.ts +35 -1
- package/dist/spec/config.d.ts.map +1 -1
- package/dist/spec/config.js +30 -5
- package/dist/spec/config.js.map +1 -1
- package/dist/spec/db/fts.d.ts.map +1 -1
- package/dist/spec/db/fts.js +19 -50
- package/dist/spec/db/fts.js.map +1 -1
- package/dist/spec/db/index.d.ts +5 -3
- package/dist/spec/db/index.d.ts.map +1 -1
- package/dist/spec/db/index.js +16 -1
- package/dist/spec/db/index.js.map +1 -1
- package/dist/spec/db/persist.d.ts +45 -0
- package/dist/spec/db/persist.d.ts.map +1 -0
- package/dist/spec/db/persist.js +66 -0
- package/dist/spec/db/persist.js.map +1 -0
- package/dist/spec/db/relations.d.ts +80 -1
- package/dist/spec/db/relations.d.ts.map +1 -1
- package/dist/spec/db/relations.js +175 -4
- package/dist/spec/db/relations.js.map +1 -1
- package/dist/spec/db/schema.d.ts +4 -0
- package/dist/spec/db/schema.d.ts.map +1 -1
- package/dist/spec/db/schema.js +4 -0
- package/dist/spec/db/schema.js.map +1 -1
- package/dist/spec/db/schema.sql +5 -1
- package/dist/spec/db/spec-node.d.ts +5 -0
- package/dist/spec/db/spec-node.d.ts.map +1 -1
- package/dist/spec/db/spec-node.js +11 -5
- package/dist/spec/db/spec-node.js.map +1 -1
- package/dist/spec/db/sql-utils.d.ts +11 -0
- package/dist/spec/db/sql-utils.d.ts.map +1 -0
- package/dist/spec/db/sql-utils.js +19 -0
- package/dist/spec/db/sql-utils.js.map +1 -0
- package/dist/spec/evolve/cluster-context.d.ts +30 -0
- package/dist/spec/evolve/cluster-context.d.ts.map +1 -0
- package/dist/spec/evolve/cluster-context.js +78 -0
- package/dist/spec/evolve/cluster-context.js.map +1 -0
- package/dist/spec/evolve/commit-spec-analyzer.d.ts +51 -0
- package/dist/spec/evolve/commit-spec-analyzer.d.ts.map +1 -0
- package/dist/spec/evolve/commit-spec-analyzer.js +88 -0
- package/dist/spec/evolve/commit-spec-analyzer.js.map +1 -0
- package/dist/spec/evolve/commit-spec-persister.d.ts +53 -0
- package/dist/spec/evolve/commit-spec-persister.d.ts.map +1 -0
- package/dist/spec/evolve/commit-spec-persister.js +93 -0
- package/dist/spec/evolve/commit-spec-persister.js.map +1 -0
- package/dist/spec/evolve/impact-locator.d.ts +23 -7
- package/dist/spec/evolve/impact-locator.d.ts.map +1 -1
- package/dist/spec/evolve/impact-locator.js +58 -14
- package/dist/spec/evolve/impact-locator.js.map +1 -1
- package/dist/spec/evolve/pipeline.d.ts +62 -25
- package/dist/spec/evolve/pipeline.d.ts.map +1 -1
- package/dist/spec/evolve/pipeline.js +436 -457
- package/dist/spec/evolve/pipeline.js.map +1 -1
- package/dist/spec/evolve/spec-rewriter.d.ts +13 -13
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -1
- package/dist/spec/evolve/spec-rewriter.js +45 -45
- package/dist/spec/evolve/spec-rewriter.js.map +1 -1
- package/dist/spec/git/commits.d.ts +85 -0
- package/dist/spec/git/commits.d.ts.map +1 -0
- package/dist/spec/git/commits.js +218 -0
- package/dist/spec/git/commits.js.map +1 -0
- package/dist/spec/git/exec.d.ts +13 -0
- package/dist/spec/git/exec.d.ts.map +1 -0
- package/dist/spec/git/exec.js +19 -0
- package/dist/spec/git/exec.js.map +1 -0
- package/dist/spec/git/index.d.ts +9 -0
- package/dist/spec/git/index.d.ts.map +1 -0
- package/dist/spec/git/index.js +22 -0
- package/dist/spec/git/index.js.map +1 -0
- package/dist/spec/git-utils.d.ts +8 -0
- package/dist/spec/git-utils.d.ts.map +1 -0
- package/dist/spec/git-utils.js +14 -0
- package/dist/spec/git-utils.js.map +1 -0
- package/dist/spec/graph/index.d.ts +8 -0
- package/dist/spec/graph/index.d.ts.map +1 -0
- package/dist/spec/graph/index.js +17 -0
- package/dist/spec/graph/index.js.map +1 -0
- package/dist/spec/graph/queries.d.ts +6 -35
- package/dist/spec/graph/queries.d.ts.map +1 -1
- package/dist/spec/graph/queries.js +71 -248
- package/dist/spec/graph/queries.js.map +1 -1
- package/dist/spec/llm/agent-client.d.ts +59 -0
- package/dist/spec/llm/agent-client.d.ts.map +1 -0
- package/dist/spec/llm/agent-client.js +213 -0
- package/dist/spec/llm/agent-client.js.map +1 -0
- package/dist/spec/llm/agents/claude-code.d.ts +32 -0
- package/dist/spec/llm/agents/claude-code.d.ts.map +1 -0
- package/dist/spec/llm/agents/claude-code.js +125 -0
- package/dist/spec/llm/agents/claude-code.js.map +1 -0
- package/dist/spec/llm/agents/codex.d.ts +32 -0
- package/dist/spec/llm/agents/codex.d.ts.map +1 -0
- package/dist/spec/llm/agents/codex.js +145 -0
- package/dist/spec/llm/agents/codex.js.map +1 -0
- package/dist/spec/llm/agents/detect-utils.d.ts +28 -0
- package/dist/spec/llm/agents/detect-utils.d.ts.map +1 -0
- package/dist/spec/llm/agents/detect-utils.js +91 -0
- package/dist/spec/llm/agents/detect-utils.js.map +1 -0
- package/dist/spec/llm/agents/deveco-code.d.ts +33 -0
- package/dist/spec/llm/agents/deveco-code.d.ts.map +1 -0
- package/dist/spec/llm/agents/deveco-code.js +165 -0
- package/dist/spec/llm/agents/deveco-code.js.map +1 -0
- package/dist/spec/llm/agents/index.d.ts +31 -0
- package/dist/spec/llm/agents/index.d.ts.map +1 -0
- package/dist/spec/llm/agents/index.js +65 -0
- package/dist/spec/llm/agents/index.js.map +1 -0
- package/dist/spec/llm/agents/types.d.ts +76 -0
- package/dist/spec/llm/agents/types.d.ts.map +1 -0
- package/dist/spec/llm/agents/types.js +15 -0
- package/dist/spec/llm/agents/types.js.map +1 -0
- package/dist/spec/llm/client.d.ts +31 -11
- package/dist/spec/llm/client.d.ts.map +1 -1
- package/dist/spec/llm/client.js +143 -81
- package/dist/spec/llm/client.js.map +1 -1
- package/dist/spec/llm/factory.d.ts +41 -0
- package/dist/spec/llm/factory.d.ts.map +1 -0
- package/dist/spec/llm/factory.js +80 -0
- package/dist/spec/llm/factory.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +24 -8
- package/dist/spec/llm/prompts.d.ts.map +1 -1
- package/dist/spec/llm/prompts.js +100 -50
- package/dist/spec/llm/prompts.js.map +1 -1
- package/dist/spec/llm/retry.d.ts +53 -0
- package/dist/spec/llm/retry.d.ts.map +1 -0
- package/dist/spec/llm/retry.js +153 -0
- package/dist/spec/llm/retry.js.map +1 -0
- package/dist/spec/mine/clusterer.d.ts +63 -0
- package/dist/spec/mine/clusterer.d.ts.map +1 -0
- package/dist/spec/mine/clusterer.js +904 -0
- package/dist/spec/mine/clusterer.js.map +1 -0
- package/dist/spec/mine/clustering/features.d.ts +38 -0
- package/dist/spec/mine/clustering/features.d.ts.map +1 -0
- package/dist/spec/mine/clustering/features.js +108 -0
- package/dist/spec/mine/clustering/features.js.map +1 -0
- package/dist/spec/mine/clustering/index.d.ts +62 -0
- package/dist/spec/mine/clustering/index.d.ts.map +1 -0
- package/dist/spec/mine/clustering/index.js +259 -0
- package/dist/spec/mine/clustering/index.js.map +1 -0
- package/dist/spec/mine/clustering/leiden.d.ts +61 -0
- package/dist/spec/mine/clustering/leiden.d.ts.map +1 -0
- package/dist/spec/mine/clustering/leiden.js +489 -0
- package/dist/spec/mine/clustering/leiden.js.map +1 -0
- package/dist/spec/mine/clustering/text-similarity.d.ts +22 -0
- package/dist/spec/mine/clustering/text-similarity.d.ts.map +1 -0
- package/dist/spec/mine/clustering/text-similarity.js +98 -0
- package/dist/spec/mine/clustering/text-similarity.js.map +1 -0
- package/dist/spec/mine/generator.d.ts +54 -0
- package/dist/spec/mine/generator.d.ts.map +1 -0
- package/dist/spec/mine/generator.js +267 -0
- package/dist/spec/mine/generator.js.map +1 -0
- package/dist/spec/mine/persist.d.ts +37 -0
- package/dist/spec/mine/persist.d.ts.map +1 -0
- package/dist/spec/mine/persist.js +170 -0
- package/dist/spec/mine/persist.js.map +1 -0
- package/dist/spec/mine/pipeline.d.ts +41 -0
- package/dist/spec/mine/pipeline.d.ts.map +1 -0
- package/dist/spec/mine/pipeline.js +236 -0
- package/dist/spec/mine/pipeline.js.map +1 -0
- package/dist/spec/mine/progress-handler.d.ts +22 -0
- package/dist/spec/mine/progress-handler.d.ts.map +1 -0
- package/dist/spec/mine/progress-handler.js +108 -0
- package/dist/spec/mine/progress-handler.js.map +1 -0
- package/dist/spec/mine/progress.d.ts +23 -0
- package/dist/spec/mine/progress.d.ts.map +1 -0
- package/dist/spec/mine/progress.js +12 -0
- package/dist/spec/mine/progress.js.map +1 -0
- package/dist/spec/mine/scanner.d.ts +59 -0
- package/dist/spec/mine/scanner.d.ts.map +1 -0
- package/dist/spec/mine/scanner.js +383 -0
- package/dist/spec/mine/scanner.js.map +1 -0
- package/dist/spec/types.d.ts +32 -0
- package/dist/spec/types.d.ts.map +1 -1
- package/dist/spec/ui/index.d.ts +9 -0
- package/dist/spec/ui/index.d.ts.map +1 -0
- package/dist/spec/ui/index.js +16 -0
- package/dist/spec/ui/index.js.map +1 -0
- package/dist/spec/ui/progress-handler.d.ts +33 -0
- package/dist/spec/ui/progress-handler.d.ts.map +1 -0
- package/dist/spec/ui/progress-handler.js +132 -0
- package/dist/spec/ui/progress-handler.js.map +1 -0
- package/dist/spec/ui/progress.d.ts +24 -0
- package/dist/spec/ui/progress.d.ts.map +1 -0
- package/dist/spec/ui/progress.js +13 -0
- package/dist/spec/ui/progress.js.map +1 -0
- package/dist/spec/utils/fs.d.ts +45 -0
- package/dist/spec/utils/fs.d.ts.map +1 -0
- package/dist/spec/utils/fs.js +163 -0
- package/dist/spec/utils/fs.js.map +1 -0
- package/dist/spec/utils/index.d.ts +12 -0
- package/dist/spec/utils/index.d.ts.map +1 -0
- package/dist/spec/utils/index.js +26 -0
- package/dist/spec/utils/index.js.map +1 -0
- package/dist/spec/utils/meta.d.ts +32 -0
- package/dist/spec/utils/meta.d.ts.map +1 -0
- package/dist/spec/utils/meta.js +122 -0
- package/dist/spec/utils/meta.js.map +1 -0
- package/dist/spec/utils/truncate.d.ts +86 -0
- package/dist/spec/utils/truncate.d.ts.map +1 -0
- package/dist/spec/utils/truncate.js +172 -0
- package/dist/spec/utils/truncate.js.map +1 -0
- package/dist/spec/utils.d.ts +4 -16
- package/dist/spec/utils.d.ts.map +1 -1
- package/dist/spec/utils.js +6 -58
- package/dist/spec/utils.js.map +1 -1
- package/dist/sync/git-hooks.d.ts.map +1 -1
- package/dist/sync/git-hooks.js +2 -0
- package/dist/sync/git-hooks.js.map +1 -1
- package/dist/sync/watcher.d.ts +35 -6
- package/dist/sync/watcher.d.ts.map +1 -1
- package/dist/sync/watcher.js +127 -17
- package/dist/sync/watcher.js.map +1 -1
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +5 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/telemetry/index.js +3 -3
- package/dist/telemetry/index.js.map +1 -1
- package/dist/types.d.ts +22 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -0
- package/dist/types.js.map +1 -1
- package/dist/upgrade/index.d.ts +32 -0
- package/dist/upgrade/index.d.ts.map +1 -1
- package/dist/upgrade/index.js +162 -14
- package/dist/upgrade/index.js.map +1 -1
- package/dist/upgrade/remove-binary.d.ts +87 -0
- package/dist/upgrade/remove-binary.d.ts.map +1 -0
- package/dist/upgrade/remove-binary.js +289 -0
- package/dist/upgrade/remove-binary.js.map +1 -0
- package/dist/upgrade/update-check.d.ts +92 -0
- package/dist/upgrade/update-check.d.ts.map +1 -0
- package/dist/upgrade/update-check.js +258 -0
- package/dist/upgrade/update-check.js.map +1 -0
- package/package.json +6 -2
- package/scripts/agent-eval/run-all.sh +6 -0
- package/scripts/build-bundle.sh +5 -0
- package/scripts/npm-shim.js +8 -1
- package/scripts/exp_boundary_eval/__pycache__/_utils.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/analyze.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/deveco_arm.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_one.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/run_session.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/__pycache__/setup.cpython-310.pyc +0 -0
- package/scripts/exp_boundary_eval/data/agents.json +0 -109
- package/scripts/exp_boundary_eval/data/experiments.json +0 -140
- package/scripts/qa_eval/README.md +0 -407
- package/scripts/qa_eval/_test_deveco_probe.py +0 -41
- package/scripts/qa_eval/agent_runner.py +0 -526
- package/scripts/qa_eval/data/.gitignore +0 -4
- package/scripts/qa_eval/data/test-set.jsonl +0 -2
- package/scripts/qa_eval/eval_metrics.py +0 -274
- package/scripts/qa_eval/external_agent.py +0 -976
- package/scripts/qa_eval/llm_config.py +0 -92
- package/scripts/qa_eval/memory_monitor.py +0 -132
- package/scripts/qa_eval/my_answer_accuracy.py +0 -187
- package/scripts/qa_eval/requirements.txt +0 -2
- package/scripts/qa_eval/run_pipeline.py +0 -804
- package/scripts/qa_eval/stats_efficiency.py +0 -279
- package/scripts/qa_eval/stats_scores.py +0 -207
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coding-agent adapter abstraction for headless LLM access.
|
|
3
|
+
*
|
|
4
|
+
* Each supported coding agent (Claude Code, Codex) implements this
|
|
5
|
+
* interface so the spec pipelines can fulfil their LLM tasks through the
|
|
6
|
+
* agent's non-interactive CLI mode — no API key required. Every adapter
|
|
7
|
+
* owns its own input construction (flags, system-prompt strategy, tool
|
|
8
|
+
* disabling) and output extraction, guaranteeing the I/O contract matches
|
|
9
|
+
* what `OpenAiLlmClient` produces.
|
|
10
|
+
*
|
|
11
|
+
* @module spec/llm/agents/types
|
|
12
|
+
*/
|
|
13
|
+
/** A prepared headless invocation: argv for execFile + stdin payload. */
|
|
14
|
+
export interface AgentInvocation {
|
|
15
|
+
/** Argument array — passed to spawn as-is (never shell-concatenated). */
|
|
16
|
+
args: string[];
|
|
17
|
+
/** Prompt payload written to the child's stdin. */
|
|
18
|
+
stdin: string;
|
|
19
|
+
}
|
|
20
|
+
/** Result of a finished headless invocation. */
|
|
21
|
+
export interface AgentRunResult {
|
|
22
|
+
stdout: string;
|
|
23
|
+
stderr: string;
|
|
24
|
+
}
|
|
25
|
+
/** Context of a failed invocation, for failure classification. */
|
|
26
|
+
export interface AgentFailure {
|
|
27
|
+
/**
|
|
28
|
+
* Process exit code; null for spawn-level failures (e.g. ENOENT).
|
|
29
|
+
* Timeouts never reach the adapters — the client owns the timer and
|
|
30
|
+
* always classifies them as retryable.
|
|
31
|
+
*/
|
|
32
|
+
exitCode: number | null;
|
|
33
|
+
stdout: string;
|
|
34
|
+
stderr: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Per-agent adapter: detection, invocation construction, output extraction,
|
|
38
|
+
* and failure classification.
|
|
39
|
+
*/
|
|
40
|
+
export interface AgentAdapter {
|
|
41
|
+
/** Stable id, also used by the HOMEGRAPH_SPEC_AGENT test override. */
|
|
42
|
+
readonly id: 'claude-code' | 'codex' | 'deveco-code';
|
|
43
|
+
/** Human-readable name for log lines. */
|
|
44
|
+
readonly displayName: string;
|
|
45
|
+
/** CLI binary name resolved against PATH. */
|
|
46
|
+
readonly binary: string;
|
|
47
|
+
/**
|
|
48
|
+
* Detect whether the agent is installed. Cheap checks only — PATH scan
|
|
49
|
+
* plus config-directory hint (mirrors the installer targets pattern).
|
|
50
|
+
* Must NOT spawn the agent itself.
|
|
51
|
+
*/
|
|
52
|
+
detect(): boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Build a non-interactive invocation for one chat call. The adapter is
|
|
55
|
+
* responsible for disabling all tool/file side effects and for its
|
|
56
|
+
* system-prompt strategy (native flag vs. prompt embedding).
|
|
57
|
+
*/
|
|
58
|
+
buildInvocation(systemPrompt: string, userPrompt: string): AgentInvocation;
|
|
59
|
+
/**
|
|
60
|
+
* Extract the model's text from raw stdout (e.g. unwrap a JSON envelope,
|
|
61
|
+
* strip log noise). The returned string must be shaped like an
|
|
62
|
+
* OpenAI chat-completion content string so downstream `chatJson`
|
|
63
|
+
* parsing behaves identically across providers.
|
|
64
|
+
*/
|
|
65
|
+
extractOutput(result: AgentRunResult): string;
|
|
66
|
+
/**
|
|
67
|
+
* Classify a failed invocation (non-zero exit or spawn-level error).
|
|
68
|
+
* 'terminal' covers auth/quota problems — retrying is pointless and the
|
|
69
|
+
* caller should fall back to the configured LLM. Anything transient
|
|
70
|
+
* (crashes, timeouts, unexpected exits) is 'retryable'. Both stdout and
|
|
71
|
+
* stderr are provided: some CLIs (e.g. Codex `--json`) report errors as
|
|
72
|
+
* structured stdout events rather than on stderr.
|
|
73
|
+
*/
|
|
74
|
+
classifyFailure(failure: AgentFailure): 'retryable' | 'terminal';
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/spec/llm/agents/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,yEAAyE;AACzE,MAAM,WAAW,eAAe;IAC9B,yEAAyE;IACzE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,mDAAmD;IACnD,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gDAAgD;AAChD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,EAAE,EAAE,aAAa,GAAG,OAAO,GAAG,aAAa,CAAC;IACrD,yCAAyC;IACzC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB;;;;OAIG;IACH,MAAM,IAAI,OAAO,CAAC;IAElB;;;;OAIG;IACH,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe,CAAC;IAE3E;;;;;OAKG;IACH,aAAa,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAAC;IAE9C;;;;;;;OAOG;IACH,eAAe,CAAC,OAAO,EAAE,YAAY,GAAG,WAAW,GAAG,UAAU,CAAC;CAClE"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Coding-agent adapter abstraction for headless LLM access.
|
|
4
|
+
*
|
|
5
|
+
* Each supported coding agent (Claude Code, Codex) implements this
|
|
6
|
+
* interface so the spec pipelines can fulfil their LLM tasks through the
|
|
7
|
+
* agent's non-interactive CLI mode — no API key required. Every adapter
|
|
8
|
+
* owns its own input construction (flags, system-prompt strategy, tool
|
|
9
|
+
* disabling) and output extraction, guaranteeing the I/O contract matches
|
|
10
|
+
* what `OpenAiLlmClient` produces.
|
|
11
|
+
*
|
|
12
|
+
* @module spec/llm/agents/types
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/spec/llm/agents/types.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG"}
|
|
@@ -3,26 +3,46 @@ export interface LlmClient {
|
|
|
3
3
|
chat(systemPrompt: string, userPrompt: string): Promise<string>;
|
|
4
4
|
chatJson(systemPrompt: string, userPrompt: string): Promise<Record<string, unknown>>;
|
|
5
5
|
}
|
|
6
|
+
/**
|
|
7
|
+
* Parse an LLM text response as a JSON object.
|
|
8
|
+
*
|
|
9
|
+
* Parsing strategy (tried in order):
|
|
10
|
+
* 1. Direct `JSON.parse(content)`.
|
|
11
|
+
* 2. Extract from `` ```json ... ``` `` fenced block.
|
|
12
|
+
* 3. Extract from `` ``` ... ``` `` fenced block.
|
|
13
|
+
* 4. Fallback: log a debug warning and return `{}`.
|
|
14
|
+
*
|
|
15
|
+
* Shared by OpenAiLlmClient and CodingAgentLlmClient so the chatJson
|
|
16
|
+
* contract is identical regardless of provider.
|
|
17
|
+
*/
|
|
18
|
+
export declare function parseJsonResponse(raw: string): Record<string, unknown>;
|
|
6
19
|
export declare class OpenAiLlmClient implements LlmClient {
|
|
7
20
|
private config;
|
|
8
21
|
constructor(config: LLMConfig);
|
|
22
|
+
/** Resolve the baseURL for the OpenAI SDK. */
|
|
23
|
+
private resolveBaseURL;
|
|
24
|
+
/**
|
|
25
|
+
* Build a fresh OpenAI client suitable for one call (no SDK-level retry —
|
|
26
|
+
* we handle retries ourselves with proper visibility).
|
|
27
|
+
*/
|
|
28
|
+
private buildClient;
|
|
9
29
|
/**
|
|
10
30
|
* Send a chat completion request and return the message content string.
|
|
11
31
|
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
32
|
+
* Automatically retries on transient errors (429, 5xx, connection failures)
|
|
33
|
+
* with exponential backoff and jitter. Retry-After headers on 429 responses
|
|
34
|
+
* are honoured as a floor for the delay.
|
|
35
|
+
*
|
|
36
|
+
* Retry configuration is in {@link LLMConfig}: `maxRetries` (default 3),
|
|
37
|
+
* `retryBaseDelayMs` (default 1000), `retryMaxDelayMs` (default 30000).
|
|
38
|
+
*
|
|
39
|
+
* Once all retries are exhausted the last error is re-thrown so callers
|
|
40
|
+
* (e.g. the spec mine generator) can count failures reliably.
|
|
14
41
|
*/
|
|
15
42
|
chat(systemPrompt: string, userPrompt: string): Promise<string>;
|
|
16
43
|
/**
|
|
17
|
-
* Same as `chat()`, but parses the response as JSON
|
|
18
|
-
*
|
|
19
|
-
* Parsing strategy (tried in order):
|
|
20
|
-
* 1. Direct `JSON.parse(content)`.
|
|
21
|
-
* 2. Extract from `` ```json ... ``` `` fenced block.
|
|
22
|
-
* 3. Extract from `` ``` ... ``` `` fenced block.
|
|
23
|
-
* 4. Fallback: log a debug warning and return `{}`.
|
|
24
|
-
*
|
|
25
|
-
* Empty or null content from `chat()` also returns `{}`.
|
|
44
|
+
* Same as `chat()`, but parses the response as JSON via
|
|
45
|
+
* {@link parseJsonResponse}. Empty content returns `{}`.
|
|
26
46
|
*/
|
|
27
47
|
chatJson(systemPrompt: string, userPrompt: string): Promise<Record<string, unknown>>;
|
|
28
48
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/spec/llm/client.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/spec/llm/client.ts"],"names":[],"mappings":"AAWA,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAQtC,MAAM,WAAW,SAAS;IACxB,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChE,QAAQ,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;CACtF;AAMD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CA4CtE;AAMD,qBAAa,eAAgB,YAAW,SAAS;IAC/C,OAAO,CAAC,MAAM,CAAY;gBAEd,MAAM,EAAE,SAAS;IAQ7B,8CAA8C;IAC9C,OAAO,CAAC,cAAc;IAMtB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAYnB;;;;;;;;;;;;OAYG;IACG,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IA6DrE;;;OAGG;IACG,QAAQ,CACZ,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAIpC"}
|
package/dist/spec/llm/client.js
CHANGED
|
@@ -4,16 +4,80 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.OpenAiLlmClient = void 0;
|
|
7
|
+
exports.parseJsonResponse = parseJsonResponse;
|
|
7
8
|
/**
|
|
8
|
-
* Provider-agnostic LLM client for spec
|
|
9
|
+
* Provider-agnostic LLM client for spec
|
|
9
10
|
*
|
|
10
|
-
* Supports OpenAI-compatible chat completions API
|
|
11
|
-
*
|
|
11
|
+
* Supports OpenAI-compatible chat completions API with automatic retry on
|
|
12
|
+
* transient errors (rate limits, server errors, network failures). No mock
|
|
13
|
+
* mode — callers that need test doubles inject their own stubs implementing
|
|
14
|
+
* the interface.
|
|
12
15
|
*
|
|
13
16
|
* @module spec/llm/client
|
|
14
17
|
*/
|
|
15
18
|
const openai_1 = __importDefault(require("openai"));
|
|
16
19
|
const errors_1 = require("../../errors");
|
|
20
|
+
const retry_1 = require("./retry");
|
|
21
|
+
// =============================================================================
|
|
22
|
+
// Shared JSON extraction
|
|
23
|
+
// =============================================================================
|
|
24
|
+
/**
|
|
25
|
+
* Parse an LLM text response as a JSON object.
|
|
26
|
+
*
|
|
27
|
+
* Parsing strategy (tried in order):
|
|
28
|
+
* 1. Direct `JSON.parse(content)`.
|
|
29
|
+
* 2. Extract from `` ```json ... ``` `` fenced block.
|
|
30
|
+
* 3. Extract from `` ``` ... ``` `` fenced block.
|
|
31
|
+
* 4. Fallback: log a debug warning and return `{}`.
|
|
32
|
+
*
|
|
33
|
+
* Shared by OpenAiLlmClient and CodingAgentLlmClient so the chatJson
|
|
34
|
+
* contract is identical regardless of provider.
|
|
35
|
+
*/
|
|
36
|
+
function parseJsonResponse(raw) {
|
|
37
|
+
if (!raw)
|
|
38
|
+
return {};
|
|
39
|
+
// 1. Direct parse
|
|
40
|
+
try {
|
|
41
|
+
const parsed = JSON.parse(raw);
|
|
42
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
43
|
+
return parsed;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch {
|
|
47
|
+
// Fall through to fence extraction
|
|
48
|
+
}
|
|
49
|
+
// 2. ```json ... ``` fence
|
|
50
|
+
const jsonFenceMatch = /```json\s*([\s\S]*?)```/.exec(raw);
|
|
51
|
+
if (jsonFenceMatch) {
|
|
52
|
+
try {
|
|
53
|
+
const parsed = JSON.parse(jsonFenceMatch[1].trim());
|
|
54
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
55
|
+
return parsed;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Fall through
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. ``` ... ``` fence
|
|
63
|
+
const fenceMatch = /```\s*([\s\S]*?)```/.exec(raw);
|
|
64
|
+
if (fenceMatch) {
|
|
65
|
+
try {
|
|
66
|
+
const parsed = JSON.parse(fenceMatch[1].trim());
|
|
67
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
68
|
+
return parsed;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Fall through
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// 4. Fallback
|
|
76
|
+
(0, errors_1.logDebug)('parseJsonResponse: could not parse response as JSON', {
|
|
77
|
+
raw: raw.length > 200 ? raw.slice(0, 200) + '…' : raw,
|
|
78
|
+
});
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
17
81
|
// =============================================================================
|
|
18
82
|
// OpenAiLlmClient
|
|
19
83
|
// =============================================================================
|
|
@@ -23,100 +87,98 @@ class OpenAiLlmClient {
|
|
|
23
87
|
this.config = config;
|
|
24
88
|
}
|
|
25
89
|
// ===========================================================================
|
|
26
|
-
//
|
|
90
|
+
// Helpers
|
|
27
91
|
// ===========================================================================
|
|
92
|
+
/** Resolve the baseURL for the OpenAI SDK. */
|
|
93
|
+
resolveBaseURL() {
|
|
94
|
+
if (this.config.baseUrl)
|
|
95
|
+
return this.config.baseUrl;
|
|
96
|
+
if (this.config.provider === 'anthropic')
|
|
97
|
+
return 'https://api.anthropic.com/v1';
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
28
100
|
/**
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
* Calls the OpenAI-compatible chat completions API and returns
|
|
32
|
-
* `choices[0].message.content`. On any error, returns an empty string.
|
|
101
|
+
* Build a fresh OpenAI client suitable for one call (no SDK-level retry —
|
|
102
|
+
* we handle retries ourselves with proper visibility).
|
|
33
103
|
*/
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
? this.config.baseUrl
|
|
37
|
-
: this.config.provider === 'anthropic'
|
|
38
|
-
? 'https://api.anthropic.com/v1'
|
|
39
|
-
: undefined;
|
|
40
|
-
const client = new openai_1.default({
|
|
104
|
+
buildClient() {
|
|
105
|
+
return new openai_1.default({
|
|
41
106
|
apiKey: this.config.apiKey,
|
|
42
|
-
baseURL,
|
|
107
|
+
baseURL: this.resolveBaseURL(),
|
|
108
|
+
maxRetries: 0, // disable SDK retry
|
|
43
109
|
});
|
|
44
|
-
try {
|
|
45
|
-
const completion = await client.chat.completions.create({
|
|
46
|
-
model: this.config.model,
|
|
47
|
-
temperature: this.config.temperature,
|
|
48
|
-
max_tokens: this.config.maxTokens,
|
|
49
|
-
messages: [
|
|
50
|
-
{ role: 'system', content: systemPrompt },
|
|
51
|
-
{ role: 'user', content: userPrompt },
|
|
52
|
-
],
|
|
53
|
-
});
|
|
54
|
-
const content = completion.choices[0]?.message?.content;
|
|
55
|
-
return content ?? '';
|
|
56
|
-
}
|
|
57
|
-
catch {
|
|
58
|
-
return '';
|
|
59
|
-
}
|
|
60
110
|
}
|
|
61
111
|
// ===========================================================================
|
|
62
|
-
//
|
|
112
|
+
// chat
|
|
63
113
|
// ===========================================================================
|
|
64
114
|
/**
|
|
65
|
-
*
|
|
115
|
+
* Send a chat completion request and return the message content string.
|
|
116
|
+
*
|
|
117
|
+
* Automatically retries on transient errors (429, 5xx, connection failures)
|
|
118
|
+
* with exponential backoff and jitter. Retry-After headers on 429 responses
|
|
119
|
+
* are honoured as a floor for the delay.
|
|
66
120
|
*
|
|
67
|
-
*
|
|
68
|
-
*
|
|
69
|
-
* 2. Extract from `` ```json ... ``` `` fenced block.
|
|
70
|
-
* 3. Extract from `` ``` ... ``` `` fenced block.
|
|
71
|
-
* 4. Fallback: log a debug warning and return `{}`.
|
|
121
|
+
* Retry configuration is in {@link LLMConfig}: `maxRetries` (default 3),
|
|
122
|
+
* `retryBaseDelayMs` (default 1000), `retryMaxDelayMs` (default 30000).
|
|
72
123
|
*
|
|
73
|
-
*
|
|
124
|
+
* Once all retries are exhausted the last error is re-thrown so callers
|
|
125
|
+
* (e.g. the spec mine generator) can count failures reliably.
|
|
74
126
|
*/
|
|
75
|
-
async
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
catch {
|
|
87
|
-
// Fall through to fence extraction
|
|
88
|
-
}
|
|
89
|
-
// 2. ```json ... ``` fence
|
|
90
|
-
const jsonFenceMatch = /```json\s*([\s\S]*?)```/.exec(raw);
|
|
91
|
-
if (jsonFenceMatch) {
|
|
92
|
-
try {
|
|
93
|
-
const parsed = JSON.parse(jsonFenceMatch[1].trim());
|
|
94
|
-
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
95
|
-
return parsed;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// Fall through
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
// 3. ``` ... ``` fence
|
|
103
|
-
const fenceMatch = /```\s*([\s\S]*?)```/.exec(raw);
|
|
104
|
-
if (fenceMatch) {
|
|
127
|
+
async chat(systemPrompt, userPrompt) {
|
|
128
|
+
// Build once per call — the OpenAI client is stateless so we can reuse it
|
|
129
|
+
// across retry attempts.
|
|
130
|
+
const client = this.buildClient();
|
|
131
|
+
const maxRetries = this.config.maxRetries;
|
|
132
|
+
const baseDelay = this.config.retryBaseDelayMs;
|
|
133
|
+
const maxDelay = this.config.retryMaxDelayMs;
|
|
134
|
+
// We track the cumulative attempt number for logging (1-based),
|
|
135
|
+
// and the zero-based index for backoff calculation.
|
|
136
|
+
for (let attemptIndex = 0; attemptIndex <= maxRetries; attemptIndex++) {
|
|
137
|
+
const callIndex = attemptIndex + 1; // 1-based for logging
|
|
105
138
|
try {
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
139
|
+
const completion = await client.chat.completions.create({
|
|
140
|
+
model: this.config.model,
|
|
141
|
+
temperature: this.config.temperature,
|
|
142
|
+
max_tokens: this.config.maxTokens,
|
|
143
|
+
messages: [
|
|
144
|
+
{ role: 'system', content: systemPrompt },
|
|
145
|
+
{ role: 'user', content: userPrompt },
|
|
146
|
+
],
|
|
147
|
+
});
|
|
148
|
+
const content = completion.choices[0]?.message?.content;
|
|
149
|
+
return content ?? '';
|
|
110
150
|
}
|
|
111
|
-
catch {
|
|
112
|
-
//
|
|
151
|
+
catch (err) {
|
|
152
|
+
// No more retries left — re-throw the raw error so callers can
|
|
153
|
+
// inspect its type (e.g. RateLimitError) if needed.
|
|
154
|
+
if (attemptIndex >= maxRetries)
|
|
155
|
+
throw err;
|
|
156
|
+
const decision = (0, retry_1.classifyError)(err);
|
|
157
|
+
if (!decision.retryable)
|
|
158
|
+
throw err;
|
|
159
|
+
const delay = (0, retry_1.computeDelay)(decision.retryAfterMs, baseDelay, maxDelay, attemptIndex);
|
|
160
|
+
(0, errors_1.logDebug)(`LLM retry ${callIndex}/${maxRetries}`, {
|
|
161
|
+
attempt: callIndex,
|
|
162
|
+
maxRetries,
|
|
163
|
+
delayMs: delay,
|
|
164
|
+
error: err instanceof Error ? err.message : String(err),
|
|
165
|
+
});
|
|
166
|
+
await (0, retry_1.sleep)(delay);
|
|
113
167
|
}
|
|
114
168
|
}
|
|
115
|
-
//
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
169
|
+
// Unreachable — the loop returns or throws in every branch.
|
|
170
|
+
throw new Error('unreachable: retry loop exited without returning');
|
|
171
|
+
}
|
|
172
|
+
// ===========================================================================
|
|
173
|
+
// chatJson
|
|
174
|
+
// ===========================================================================
|
|
175
|
+
/**
|
|
176
|
+
* Same as `chat()`, but parses the response as JSON via
|
|
177
|
+
* {@link parseJsonResponse}. Empty content returns `{}`.
|
|
178
|
+
*/
|
|
179
|
+
async chatJson(systemPrompt, userPrompt) {
|
|
180
|
+
const raw = await this.chat(systemPrompt, userPrompt);
|
|
181
|
+
return parseJsonResponse(raw);
|
|
120
182
|
}
|
|
121
183
|
}
|
|
122
184
|
exports.OpenAiLlmClient = OpenAiLlmClient;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/spec/llm/client.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/spec/llm/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LLM client factory for the spec pipelines — the single resolution point
|
|
3
|
+
* that decides WHERE LLM calls go:
|
|
4
|
+
*
|
|
5
|
+
* 1. A locally installed coding agent (Claude Code preferred, then
|
|
6
|
+
* Codex) in headless mode — no API key required;
|
|
7
|
+
* 2. The user-configured LLM (configs.json "llm" section) — used alone
|
|
8
|
+
* when no agent is installed, and as an automatic fallback when the
|
|
9
|
+
* agent's headless call fails;
|
|
10
|
+
* 3. undefined — neither available; callers keep their existing
|
|
11
|
+
* no-LLM degradation paths.
|
|
12
|
+
*
|
|
13
|
+
* Coding-agent resolution is fully automatic (spec evolve is mostly
|
|
14
|
+
* git-hook triggered, so interactive selection is impossible) and the
|
|
15
|
+
* LLMConfig surface is deliberately untouched.
|
|
16
|
+
*
|
|
17
|
+
* @module spec/llm/factory
|
|
18
|
+
*/
|
|
19
|
+
import { LLMConfig } from '../config';
|
|
20
|
+
import { LlmClient } from './client';
|
|
21
|
+
/**
|
|
22
|
+
* Composite client: try the coding agent first; on ANY failure of the
|
|
23
|
+
* primary, delegate the same call to the configured LLM. Terminal agent
|
|
24
|
+
* failures (auth/quota) therefore degrade seamlessly to the API path.
|
|
25
|
+
*/
|
|
26
|
+
export declare class FallbackLlmClient implements LlmClient {
|
|
27
|
+
private readonly primary;
|
|
28
|
+
private readonly secondary;
|
|
29
|
+
constructor(primary: LlmClient, secondary: LlmClient);
|
|
30
|
+
chat(systemPrompt: string, userPrompt: string): Promise<string>;
|
|
31
|
+
chatJson(systemPrompt: string, userPrompt: string): Promise<Record<string, unknown>>;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Resolve the LLM client for a spec pipeline run.
|
|
35
|
+
*
|
|
36
|
+
* @param llmConfig - The configs.json "llm" section (may be null).
|
|
37
|
+
* @returns A ready client, or undefined when neither a coding agent nor
|
|
38
|
+
* an LLM configuration is available.
|
|
39
|
+
*/
|
|
40
|
+
export declare function createSpecLlmClient(llmConfig: LLMConfig | null): LlmClient | undefined;
|
|
41
|
+
//# sourceMappingURL=factory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../../src/spec/llm/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,SAAS,EAAmB,MAAM,UAAU,CAAC;AAKtD;;;;GAIG;AACH,qBAAa,iBAAkB,YAAW,SAAS;IAE/C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACxB,OAAO,CAAC,QAAQ,CAAC,SAAS;gBADT,OAAO,EAAE,SAAS,EAClB,SAAS,EAAE,SAAS;IAGjC,IAAI,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAW/D,QAAQ,CACZ,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAUpC;AAED;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,SAAS,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,CAWtF"}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* LLM client factory for the spec pipelines — the single resolution point
|
|
4
|
+
* that decides WHERE LLM calls go:
|
|
5
|
+
*
|
|
6
|
+
* 1. A locally installed coding agent (Claude Code preferred, then
|
|
7
|
+
* Codex) in headless mode — no API key required;
|
|
8
|
+
* 2. The user-configured LLM (configs.json "llm" section) — used alone
|
|
9
|
+
* when no agent is installed, and as an automatic fallback when the
|
|
10
|
+
* agent's headless call fails;
|
|
11
|
+
* 3. undefined — neither available; callers keep their existing
|
|
12
|
+
* no-LLM degradation paths.
|
|
13
|
+
*
|
|
14
|
+
* Coding-agent resolution is fully automatic (spec evolve is mostly
|
|
15
|
+
* git-hook triggered, so interactive selection is impossible) and the
|
|
16
|
+
* LLMConfig surface is deliberately untouched.
|
|
17
|
+
*
|
|
18
|
+
* @module spec/llm/factory
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.FallbackLlmClient = void 0;
|
|
22
|
+
exports.createSpecLlmClient = createSpecLlmClient;
|
|
23
|
+
const client_1 = require("./client");
|
|
24
|
+
const agent_client_1 = require("./agent-client");
|
|
25
|
+
const agents_1 = require("./agents");
|
|
26
|
+
const errors_1 = require("../../errors");
|
|
27
|
+
/**
|
|
28
|
+
* Composite client: try the coding agent first; on ANY failure of the
|
|
29
|
+
* primary, delegate the same call to the configured LLM. Terminal agent
|
|
30
|
+
* failures (auth/quota) therefore degrade seamlessly to the API path.
|
|
31
|
+
*/
|
|
32
|
+
class FallbackLlmClient {
|
|
33
|
+
primary;
|
|
34
|
+
secondary;
|
|
35
|
+
constructor(primary, secondary) {
|
|
36
|
+
this.primary = primary;
|
|
37
|
+
this.secondary = secondary;
|
|
38
|
+
}
|
|
39
|
+
async chat(systemPrompt, userPrompt) {
|
|
40
|
+
try {
|
|
41
|
+
return await this.primary.chat(systemPrompt, userPrompt);
|
|
42
|
+
}
|
|
43
|
+
catch (err) {
|
|
44
|
+
(0, errors_1.logWarn)('Coding-agent LLM call failed — falling back to configured LLM', {
|
|
45
|
+
error: err instanceof Error ? err.message : String(err),
|
|
46
|
+
});
|
|
47
|
+
return this.secondary.chat(systemPrompt, userPrompt);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
async chatJson(systemPrompt, userPrompt) {
|
|
51
|
+
try {
|
|
52
|
+
return await this.primary.chatJson(systemPrompt, userPrompt);
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
(0, errors_1.logWarn)('Coding-agent LLM call failed — falling back to configured LLM', {
|
|
56
|
+
error: err instanceof Error ? err.message : String(err),
|
|
57
|
+
});
|
|
58
|
+
return this.secondary.chatJson(systemPrompt, userPrompt);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.FallbackLlmClient = FallbackLlmClient;
|
|
63
|
+
/**
|
|
64
|
+
* Resolve the LLM client for a spec pipeline run.
|
|
65
|
+
*
|
|
66
|
+
* @param llmConfig - The configs.json "llm" section (may be null).
|
|
67
|
+
* @returns A ready client, or undefined when neither a coding agent nor
|
|
68
|
+
* an LLM configuration is available.
|
|
69
|
+
*/
|
|
70
|
+
function createSpecLlmClient(llmConfig) {
|
|
71
|
+
const agent = (0, agents_1.resolveAgent)();
|
|
72
|
+
const api = llmConfig ? new client_1.OpenAiLlmClient(llmConfig) : undefined;
|
|
73
|
+
if (agent) {
|
|
74
|
+
(0, errors_1.logDebug)(`Using ${agent.displayName} (headless) for LLM tasks`, { agent: agent.id });
|
|
75
|
+
const primary = new agent_client_1.CodingAgentLlmClient(agent);
|
|
76
|
+
return api ? new FallbackLlmClient(primary, api) : primary;
|
|
77
|
+
}
|
|
78
|
+
return api;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=factory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/spec/llm/factory.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAoDH,kDAWC;AA5DD,qCAAsD;AACtD,iDAAsD;AACtD,qCAAwC;AACxC,yCAAiD;AAEjD;;;;GAIG;AACH,MAAa,iBAAiB;IAET;IACA;IAFnB,YACmB,OAAkB,EAClB,SAAoB;QADpB,YAAO,GAAP,OAAO,CAAW;QAClB,cAAS,GAAT,SAAS,CAAW;IACpC,CAAC;IAEJ,KAAK,CAAC,IAAI,CAAC,YAAoB,EAAE,UAAkB;QACjD,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,gBAAO,EAAC,+DAA+D,EAAE;gBACvE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED,KAAK,CAAC,QAAQ,CACZ,YAAoB,EACpB,UAAkB;QAElB,IAAI,CAAC;YACH,OAAO,MAAM,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,IAAA,gBAAO,EAAC,+DAA+D,EAAE;gBACvE,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;aACxD,CAAC,CAAC;YACH,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF;AA9BD,8CA8BC;AAED;;;;;;GAMG;AACH,SAAgB,mBAAmB,CAAC,SAA2B;IAC7D,MAAM,KAAK,GAAG,IAAA,qBAAY,GAAE,CAAC;IAC7B,MAAM,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,wBAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEnE,IAAI,KAAK,EAAE,CAAC;QACV,IAAA,iBAAQ,EAAC,SAAS,KAAK,CAAC,WAAW,2BAA2B,EAAE,EAAE,KAAK,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;QACrF,MAAM,OAAO,GAAG,IAAI,mCAAoB,CAAC,KAAK,CAAC,CAAC;QAChD,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,iBAAiB,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;IAC7D,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* LLM prompt templates for spec self-evolution
|
|
3
|
-
*
|
|
4
|
-
* Extracted from logic-checker.ts and spec-rewriter.ts so evolve modules
|
|
5
|
-
* don't contain prompt strings directly.
|
|
2
|
+
* LLM prompt templates for the spec pipelines — spec self-evolution
|
|
3
|
+
* (cluster evaluation) and spec mining (spec generation from clusters).
|
|
6
4
|
*
|
|
7
5
|
* @module spec/llm/prompts
|
|
8
6
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
export declare const
|
|
12
|
-
|
|
7
|
+
import { ClusterContext } from '../types';
|
|
8
|
+
/** Default markdown template for generated spec documents. */
|
|
9
|
+
export declare const DEFAULT_SPEC_TEMPLATE = "# Spec: {{title}}\n\n## Summary\n{{summary}}\n\n## Motivation\n{{motivation}}\n\n## Specification\n\n### Functional Requirements\n{{functional_requirements}}\n\n### Acceptance Criteria (EARS format)\n{{acceptance_criteria}}\n\n## Implementation Notes\n\n### Related Commits\n{{commit_list}}\n\n### Affected Files\n{{file_list}}\n\n### Key Symbols\n{{symbol_list}}\n";
|
|
10
|
+
/** System prompt for LLM spec generation from a commit cluster. */
|
|
11
|
+
export declare const SPEC_GENERATION_SYSTEM_PROMPT = "You are a technical documentation writer specializing in software design specifications. Given a cluster of related Git commits, generate a design specification in markdown format.\n\nGuidelines:\n- Focus on WHAT was built, not HOW it was implemented\n- Use EARS (Easy Approach to Requirements Syntax) for acceptance criteria\n- Be specific \u2014 reference real symbols, files, and commit messages\n- Keep the spec concise but complete\n- Output ONLY the spec document, no preamble or commentary\n\nOutput format \u2014 fill in the template exactly. Replace {{placeholders}} with real content. Do NOT include the placeholder braces in your output.";
|
|
12
|
+
export declare const SPEC_EVALUATION_CLUSTER_SYSTEM_PROMPT = "You are a technical documentation maintainer. Your task is to evaluate whether a GROUP of related git commits requires updating a software design specification.\n\nGiven the current content and a summary of multiple commits that affect this spec, determine:\n1. Whether the spec needs to be updated (UPDATE), deprecated (DEPRECATE), or left unchanged (UNCHANGED).\n2. If UPDATE: provide the new title, subtitles (as an array of heading-preview strings), and full rewritten spec_content that incorporates the changes from all commits.\n3. If DEPRECATE: provide a brief explanation in the spec_content field.\n\nKey considerations for batch evaluation:\n- Multiple commits may partially overlap in their changes \u2014 synthesize the combined impact.\n- Some commits may be bug fixes that revert earlier changes \u2014 look for the net effect.\n- If the combined changes fundamentally alter the spec's scope, prefer DEPRECATE over UPDATE.\n\nResponse format (JSON):\n{\n \"action\": \"UPDATE\" | \"DEPRECATE\" | \"UNCHANGED\",\n \"title\": \"New spec title (for UPDATE)\",\n \"subtitles\": [\"heading1 \u2192 heading2 - preview\", ...],\n \"spec_content\": \"Full rewritten markdown content (for UPDATE) or deprecation reason (for DEPRECATE)\"\n}";
|
|
13
|
+
/**
|
|
14
|
+
* Build the user prompt for cluster-based spec evaluation.
|
|
15
|
+
*
|
|
16
|
+
* Presents:
|
|
17
|
+
* 1. The current spec content.
|
|
18
|
+
* 2. A cluster overview (commit count, primary files).
|
|
19
|
+
* 3. Per-commit summaries (short hash, message, changed files, truncated diff).
|
|
20
|
+
*
|
|
21
|
+
* The prompt is designed to fit within a reasonable token budget for a
|
|
22
|
+
* single LLM call even with 5-10 commits in the cluster.
|
|
23
|
+
*
|
|
24
|
+
* @param specContent - Full current spec.md content.
|
|
25
|
+
* @param clusterContext - Pre-built cluster context from buildClusterContext.
|
|
26
|
+
* @returns Formatted user prompt string.
|
|
27
|
+
*/
|
|
28
|
+
export declare function buildClusterSpecEvaluationUserPrompt(specContent: string, clusterContext: ClusterContext): string;
|
|
13
29
|
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/spec/llm/prompts.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../../src/spec/llm/prompts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAO1C,8DAA8D;AAC9D,eAAO,MAAM,qBAAqB,kXA0BjC,CAAC;AAEF,mEAAmE;AACnE,eAAO,MAAM,6BAA6B,6oBASsG,CAAC;AAWjJ,eAAO,MAAM,qCAAqC,quCAkBhD,CAAC;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,oCAAoC,CAClD,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,cAAc,GAC7B,MAAM,CAmCR"}
|