homegraph 1.1.2 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -21
- package/README.md +268 -243
- package/dist/arkts/ohos-api-index.d.ts +15 -0
- package/dist/arkts/ohos-api-index.d.ts.map +1 -0
- package/dist/arkts/ohos-api-index.js +190 -0
- package/dist/arkts/ohos-api-index.js.map +1 -0
- package/dist/arkts/ohos-sdk-input.d.ts +36 -0
- package/dist/arkts/ohos-sdk-input.d.ts.map +1 -0
- package/dist/arkts/ohos-sdk-input.js +214 -0
- package/dist/arkts/ohos-sdk-input.js.map +1 -0
- package/dist/bin/command-supervision.d.ts +12 -0
- package/dist/bin/command-supervision.d.ts.map +1 -0
- package/dist/bin/command-supervision.js +86 -0
- package/dist/bin/command-supervision.js.map +1 -0
- package/dist/bin/homegraph.d.ts +1 -1
- package/dist/bin/homegraph.js +971 -71
- package/dist/bin/homegraph.js.map +1 -1
- package/dist/db/index.d.ts +20 -0
- package/dist/db/index.d.ts.map +1 -1
- package/dist/db/index.js +39 -0
- 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 +58 -19
- package/dist/db/migrations.js.map +1 -1
- package/dist/db/queries.d.ts +14 -0
- package/dist/db/queries.d.ts.map +1 -1
- package/dist/db/queries.js +314 -143
- package/dist/db/queries.js.map +1 -1
- package/dist/db/schema.sql +172 -152
- package/dist/directory.d.ts +32 -0
- package/dist/directory.d.ts.map +1 -1
- package/dist/directory.js +88 -5
- package/dist/directory.js.map +1 -1
- package/dist/extraction/arkts-batch-worker.d.ts +2 -0
- package/dist/extraction/arkts-batch-worker.d.ts.map +1 -0
- package/dist/extraction/arkts-batch-worker.js +28 -0
- package/dist/extraction/arkts-batch-worker.js.map +1 -0
- package/dist/extraction/context.d.ts +11 -0
- package/dist/extraction/context.d.ts.map +1 -1
- package/dist/extraction/context.js +20 -0
- package/dist/extraction/context.js.map +1 -1
- package/dist/extraction/index.d.ts +16 -2
- package/dist/extraction/index.d.ts.map +1 -1
- package/dist/extraction/index.js +619 -380
- package/dist/extraction/index.js.map +1 -1
- package/dist/extraction/languages/arkts-state-decorators.d.ts +13 -0
- package/dist/extraction/languages/arkts-state-decorators.d.ts.map +1 -0
- package/dist/extraction/languages/arkts-state-decorators.js +26 -0
- package/dist/extraction/languages/arkts-state-decorators.js.map +1 -0
- package/dist/extraction/languages/arkts-viewtree.d.ts +4 -2
- package/dist/extraction/languages/arkts-viewtree.d.ts.map +1 -1
- package/dist/extraction/languages/arkts-viewtree.js +21 -6
- package/dist/extraction/languages/arkts-viewtree.js.map +1 -1
- package/dist/extraction/languages/arkts.d.ts +98 -2
- package/dist/extraction/languages/arkts.d.ts.map +1 -1
- package/dist/extraction/languages/arkts.js +1290 -61
- package/dist/extraction/languages/arkts.js.map +1 -1
- package/dist/extraction/languages/c-cpp.d.ts +56 -0
- package/dist/extraction/languages/c-cpp.d.ts.map +1 -1
- package/dist/extraction/languages/c-cpp.js +198 -1
- package/dist/extraction/languages/c-cpp.js.map +1 -1
- package/dist/extraction/languages/ohos-api-consumer.d.ts +34 -0
- package/dist/extraction/languages/ohos-api-consumer.d.ts.map +1 -0
- package/dist/extraction/languages/ohos-api-consumer.js +283 -0
- package/dist/extraction/languages/ohos-api-consumer.js.map +1 -0
- package/dist/extraction/parse-pool.d.ts +126 -0
- package/dist/extraction/parse-pool.d.ts.map +1 -0
- package/dist/extraction/parse-pool.js +319 -0
- package/dist/extraction/parse-pool.js.map +1 -0
- package/dist/extraction/tree-sitter-types.d.ts +17 -0
- package/dist/extraction/tree-sitter-types.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.d.ts +21 -0
- package/dist/extraction/tree-sitter.d.ts.map +1 -1
- package/dist/extraction/tree-sitter.js +198 -27
- package/dist/extraction/tree-sitter.js.map +1 -1
- package/dist/extraction/wasm/tree-sitter-c_sharp.wasm +0 -0
- package/dist/extraction/wasm/tree-sitter-pascal.wasm +0 -0
- package/dist/graph/traversal.d.ts.map +1 -1
- package/dist/graph/traversal.js +76 -17
- package/dist/graph/traversal.js.map +1 -1
- package/dist/index.d.ts +25 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +78 -4
- package/dist/index.js.map +1 -1
- package/dist/installer/instructions-template.js +9 -9
- package/dist/installer/targets/shared.d.ts +5 -6
- package/dist/installer/targets/shared.d.ts.map +1 -1
- package/dist/installer/targets/shared.js +5 -6
- package/dist/installer/targets/shared.js.map +1 -1
- package/dist/mcp/daemon-paths.d.ts +30 -3
- package/dist/mcp/daemon-paths.d.ts.map +1 -1
- package/dist/mcp/daemon-paths.js +50 -10
- package/dist/mcp/daemon-paths.js.map +1 -1
- package/dist/mcp/daemon-registry.d.ts.map +1 -1
- package/dist/mcp/daemon-registry.js +7 -3
- package/dist/mcp/daemon-registry.js.map +1 -1
- package/dist/mcp/daemon.d.ts +48 -0
- package/dist/mcp/daemon.d.ts.map +1 -1
- package/dist/mcp/daemon.js +196 -32
- package/dist/mcp/daemon.js.map +1 -1
- package/dist/mcp/engine.d.ts +17 -0
- package/dist/mcp/engine.d.ts.map +1 -1
- package/dist/mcp/engine.js +73 -1
- package/dist/mcp/engine.js.map +1 -1
- package/dist/mcp/index.d.ts.map +1 -1
- package/dist/mcp/index.js +25 -43
- package/dist/mcp/index.js.map +1 -1
- package/dist/mcp/liveness-watchdog.js +16 -16
- package/dist/mcp/ppid-watchdog.d.ts +18 -0
- package/dist/mcp/ppid-watchdog.d.ts.map +1 -1
- package/dist/mcp/ppid-watchdog.js +37 -0
- package/dist/mcp/ppid-watchdog.js.map +1 -1
- package/dist/mcp/query-cache.d.ts +25 -0
- package/dist/mcp/query-cache.d.ts.map +1 -0
- package/dist/mcp/query-cache.js +191 -0
- package/dist/mcp/query-cache.js.map +1 -0
- package/dist/mcp/query-pool.d.ts +94 -0
- package/dist/mcp/query-pool.d.ts.map +1 -0
- package/dist/mcp/query-pool.js +297 -0
- package/dist/mcp/query-pool.js.map +1 -0
- package/dist/mcp/query-worker.d.ts +24 -0
- package/dist/mcp/query-worker.d.ts.map +1 -0
- package/dist/mcp/query-worker.js +87 -0
- package/dist/mcp/query-worker.js.map +1 -0
- package/dist/mcp/server-instructions.d.ts +5 -7
- package/dist/mcp/server-instructions.d.ts.map +1 -1
- package/dist/mcp/server-instructions.js +72 -74
- package/dist/mcp/server-instructions.js.map +1 -1
- package/dist/mcp/tools.d.ts +94 -4
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +877 -71
- package/dist/mcp/tools.js.map +1 -1
- package/dist/project-config.d.ts +20 -0
- package/dist/project-config.d.ts.map +1 -1
- package/dist/project-config.js +42 -2
- package/dist/project-config.js.map +1 -1
- package/dist/reasoning/login.js +1 -1
- package/dist/reasoning/login.js.map +1 -1
- package/dist/reasoning/reasoner.js +32 -32
- package/dist/resolution/c-fnptr-synthesizer.d.ts +0 -28
- package/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
- package/dist/resolution/c-fnptr-synthesizer.js +765 -79
- package/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
- package/dist/resolution/callback-synthesizer.d.ts +1 -1
- package/dist/resolution/callback-synthesizer.d.ts.map +1 -1
- package/dist/resolution/callback-synthesizer.js +72 -11
- package/dist/resolution/callback-synthesizer.js.map +1 -1
- package/dist/resolution/cooperative-yield.d.ts +32 -0
- package/dist/resolution/cooperative-yield.d.ts.map +1 -0
- package/dist/resolution/cooperative-yield.js +42 -0
- package/dist/resolution/cooperative-yield.js.map +1 -0
- package/dist/resolution/index.d.ts +11 -2
- package/dist/resolution/index.d.ts.map +1 -1
- package/dist/resolution/index.js +72 -4
- package/dist/resolution/index.js.map +1 -1
- package/dist/resolution/name-matcher.d.ts +22 -0
- package/dist/resolution/name-matcher.d.ts.map +1 -1
- package/dist/resolution/name-matcher.js +317 -20
- package/dist/resolution/name-matcher.js.map +1 -1
- package/dist/spec/config.d.ts +39 -0
- package/dist/spec/config.d.ts.map +1 -0
- package/dist/spec/config.js +304 -0
- package/dist/spec/config.js.map +1 -0
- package/dist/spec/db/commit-node.d.ts +23 -0
- package/dist/spec/db/commit-node.d.ts.map +1 -0
- package/dist/spec/db/commit-node.js +62 -0
- package/dist/spec/db/commit-node.js.map +1 -0
- package/dist/spec/db/fragment-node.d.ts +24 -0
- package/dist/spec/db/fragment-node.d.ts.map +1 -0
- package/dist/spec/db/fragment-node.js +128 -0
- package/dist/spec/db/fragment-node.js.map +1 -0
- package/dist/spec/db/fts.d.ts +74 -0
- package/dist/spec/db/fts.d.ts.map +1 -0
- package/dist/spec/db/fts.js +324 -0
- package/dist/spec/db/fts.js.map +1 -0
- package/dist/spec/db/index.d.ts +13 -0
- package/dist/spec/db/index.d.ts.map +1 -0
- package/dist/spec/db/index.js +50 -0
- package/dist/spec/db/index.js.map +1 -0
- package/dist/spec/db/relations.d.ts +55 -0
- package/dist/spec/db/relations.d.ts.map +1 -0
- package/dist/spec/db/relations.js +158 -0
- package/dist/spec/db/relations.js.map +1 -0
- package/dist/spec/db/schema.d.ts +33 -0
- package/dist/spec/db/schema.d.ts.map +1 -0
- package/dist/spec/db/schema.js +119 -0
- package/dist/spec/db/schema.js.map +1 -0
- package/dist/spec/db/schema.sql +117 -0
- package/dist/spec/db/spec-node.d.ts +41 -0
- package/dist/spec/db/spec-node.d.ts.map +1 -0
- package/dist/spec/db/spec-node.js +114 -0
- package/dist/spec/db/spec-node.js.map +1 -0
- package/dist/spec/evolve/impact-locator.d.ts +13 -0
- package/dist/spec/evolve/impact-locator.d.ts.map +1 -0
- package/dist/spec/evolve/impact-locator.js +25 -0
- package/dist/spec/evolve/impact-locator.js.map +1 -0
- package/dist/spec/evolve/llm-client.d.ts +50 -0
- package/dist/spec/evolve/llm-client.d.ts.map +1 -0
- package/dist/spec/evolve/llm-client.js +176 -0
- package/dist/spec/evolve/llm-client.js.map +1 -0
- package/dist/spec/evolve/logic-checker.d.ts +12 -0
- package/dist/spec/evolve/logic-checker.d.ts.map +1 -0
- package/dist/spec/evolve/logic-checker.js +24 -0
- package/dist/spec/evolve/logic-checker.js.map +1 -0
- package/dist/spec/evolve/pipeline.d.ts +42 -0
- package/dist/spec/evolve/pipeline.d.ts.map +1 -0
- package/dist/spec/evolve/pipeline.js +567 -0
- package/dist/spec/evolve/pipeline.js.map +1 -0
- package/dist/spec/evolve/spec-rewriter.d.ts +42 -0
- package/dist/spec/evolve/spec-rewriter.d.ts.map +1 -0
- package/dist/spec/evolve/spec-rewriter.js +230 -0
- package/dist/spec/evolve/spec-rewriter.js.map +1 -0
- package/dist/spec/graph/queries.d.ts +155 -0
- package/dist/spec/graph/queries.d.ts.map +1 -0
- package/dist/spec/graph/queries.js +440 -0
- package/dist/spec/graph/queries.js.map +1 -0
- package/dist/spec/llm/client.d.ts +29 -0
- package/dist/spec/llm/client.d.ts.map +1 -0
- package/dist/spec/llm/client.js +123 -0
- package/dist/spec/llm/client.js.map +1 -0
- package/dist/spec/llm/index.d.ts +3 -0
- package/dist/spec/llm/index.d.ts.map +1 -0
- package/dist/spec/llm/index.js +11 -0
- package/dist/spec/llm/index.js.map +1 -0
- package/dist/spec/llm/prompts.d.ts +13 -0
- package/dist/spec/llm/prompts.d.ts.map +1 -0
- package/dist/spec/llm/prompts.js +75 -0
- package/dist/spec/llm/prompts.js.map +1 -0
- package/dist/spec/mining/diff-parser.d.ts +33 -0
- package/dist/spec/mining/diff-parser.d.ts.map +1 -0
- package/dist/spec/mining/diff-parser.js +166 -0
- package/dist/spec/mining/diff-parser.js.map +1 -0
- package/dist/spec/mining/git-scanner.d.ts +103 -0
- package/dist/spec/mining/git-scanner.d.ts.map +1 -0
- package/dist/spec/mining/git-scanner.js +307 -0
- package/dist/spec/mining/git-scanner.js.map +1 -0
- package/dist/spec/mining/pipeline.d.ts +53 -0
- package/dist/spec/mining/pipeline.d.ts.map +1 -0
- package/dist/spec/mining/pipeline.js +178 -0
- package/dist/spec/mining/pipeline.js.map +1 -0
- package/dist/spec/mining/scope-resolver.d.ts +45 -0
- package/dist/spec/mining/scope-resolver.d.ts.map +1 -0
- package/dist/spec/mining/scope-resolver.js +103 -0
- package/dist/spec/mining/scope-resolver.js.map +1 -0
- package/dist/spec/mining/spec-extractor.d.ts +69 -0
- package/dist/spec/mining/spec-extractor.d.ts.map +1 -0
- package/dist/spec/mining/spec-extractor.js +369 -0
- package/dist/spec/mining/spec-extractor.js.map +1 -0
- package/dist/spec/types.d.ts +149 -0
- package/dist/spec/types.d.ts.map +1 -0
- package/dist/spec/types.js +15 -0
- package/dist/spec/types.js.map +1 -0
- package/dist/spec/utils.d.ts +167 -0
- package/dist/spec/utils.d.ts.map +1 -0
- package/dist/spec/utils.js +463 -0
- package/dist/spec/utils.js.map +1 -0
- package/dist/sync/worktree.d.ts +9 -0
- package/dist/sync/worktree.d.ts.map +1 -1
- package/dist/sync/worktree.js +40 -0
- package/dist/sync/worktree.js.map +1 -1
- package/dist/types.d.ts +6 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.d.ts +2 -0
- package/dist/ui/shimmer-progress.d.ts.map +1 -1
- package/dist/ui/shimmer-progress.js +19 -2
- package/dist/ui/shimmer-progress.js.map +1 -1
- package/dist/upgrade/index.js +1 -1
- package/dist/upgrade/index.js.map +1 -1
- package/package.json +58 -57
- package/scripts/add-lang/bench.sh +60 -60
- package/scripts/add-lang/check-grammar.mjs +75 -75
- package/scripts/add-lang/dump-ast.mjs +103 -103
- package/scripts/add-lang/verify-extraction.mjs +70 -70
- package/scripts/agent-eval/ab-adoption.sh +91 -91
- package/scripts/agent-eval/ab-hook.sh +86 -86
- package/scripts/agent-eval/ab-impl.sh +78 -78
- package/scripts/agent-eval/ab-new-vs-baseline.sh +102 -102
- package/scripts/agent-eval/ab-sufficiency.sh +78 -78
- package/scripts/agent-eval/arms-F.sh +21 -21
- package/scripts/agent-eval/arms-matrix.sh +37 -37
- package/scripts/agent-eval/audit.sh +68 -68
- package/scripts/agent-eval/bench-readme.sh +28 -28
- package/scripts/agent-eval/bench-why-repo.sh +22 -22
- package/scripts/agent-eval/block-read-hook.sh +19 -19
- package/scripts/agent-eval/hook-settings.json +15 -15
- package/scripts/agent-eval/itrun.sh +120 -120
- package/scripts/agent-eval/offload-eval-3arm.sh +72 -72
- package/scripts/agent-eval/offload-eval-cost.mjs +133 -133
- package/scripts/agent-eval/offload-eval-effort.mjs +108 -108
- package/scripts/agent-eval/offload-eval-frontload-matrix.sh +25 -25
- package/scripts/agent-eval/offload-eval-frontload.sh +47 -47
- package/scripts/agent-eval/offload-eval-ground-truth.json +18 -18
- package/scripts/agent-eval/offload-eval-hook.mjs +84 -84
- package/scripts/agent-eval/offload-eval-judge.mjs +103 -103
- package/scripts/agent-eval/offload-eval-matrix.sh +20 -20
- package/scripts/agent-eval/offload-eval-metrics.mjs +94 -94
- package/scripts/agent-eval/offload-eval-refs1.sh +50 -50
- package/scripts/agent-eval/offload-eval-setup.sh +24 -24
- package/scripts/agent-eval/offload-eval-styles.sh +71 -71
- package/scripts/agent-eval/offload-eval-summarize.mjs +68 -68
- package/scripts/agent-eval/offload-eval.md +76 -76
- package/scripts/agent-eval/parse-arms.mjs +116 -116
- package/scripts/agent-eval/parse-bench-readme.mjs +84 -84
- package/scripts/agent-eval/parse-run.mjs +45 -45
- package/scripts/agent-eval/parse-session.mjs +93 -93
- package/scripts/agent-eval/probe-context.mjs +21 -21
- package/scripts/agent-eval/probe-explore.mjs +40 -40
- package/scripts/agent-eval/probe-node.mjs +20 -20
- package/scripts/agent-eval/probe-sweep.mjs +119 -119
- package/scripts/agent-eval/probe-trace.mjs +20 -20
- package/scripts/agent-eval/redirect-read-hook.sh +38 -38
- package/scripts/agent-eval/repro-concurrent-explore.mjs +119 -0
- package/scripts/agent-eval/repro-daemon-clients.mjs +125 -0
- package/scripts/agent-eval/run-agent.sh +34 -34
- package/scripts/agent-eval/run-all.sh +69 -69
- package/scripts/agent-eval/run-arms.sh +56 -56
- package/scripts/agent-eval/seq-matrix.mjs +137 -137
- package/scripts/build-bundle.sh +118 -118
- package/scripts/exp_boundary_eval/README.md +247 -0
- 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/_test_mcp_chain.py +78 -0
- package/scripts/exp_boundary_eval/_test_stdin.py +8 -0
- package/scripts/exp_boundary_eval/_utils.py +1116 -0
- package/scripts/exp_boundary_eval/analyze.py +1313 -0
- package/scripts/exp_boundary_eval/data/agents.json +109 -0
- package/scripts/exp_boundary_eval/data/experiments.json +140 -0
- package/scripts/exp_boundary_eval/deveco_arm.py +519 -0
- package/scripts/exp_boundary_eval/run_all.py +378 -0
- package/scripts/exp_boundary_eval/run_one.py +165 -0
- package/scripts/exp_boundary_eval/run_session.py +158 -0
- package/scripts/exp_boundary_eval/setup.py +120 -0
- package/scripts/exp_boundary_eval/win_mcp_launcher.py +73 -0
- package/scripts/exp_boundary_eval/win_mcp_stdio_wrap.js +36 -0
- package/scripts/exp_boundary_eval/win_node_launcher.py +24 -0
- package/scripts/extract-release-notes.mjs +130 -130
- package/scripts/local-install.sh +41 -41
- package/scripts/npm-sdk.js +75 -75
- package/scripts/npm-shim.js +268 -246
- package/scripts/ohos-sdk-publish.mjs +133 -0
- package/scripts/pack-npm.sh +119 -119
- package/scripts/prepare-release.mjs +270 -270
- package/scripts/qa_eval/README.md +407 -404
- package/scripts/qa_eval/_test_deveco_probe.py +41 -41
- package/scripts/qa_eval/agent_runner.py +526 -526
- package/scripts/qa_eval/data/.gitignore +4 -4
- package/scripts/qa_eval/data/test-set.jsonl +2 -22
- package/scripts/qa_eval/eval_metrics.py +274 -233
- package/scripts/qa_eval/external_agent.py +976 -671
- package/scripts/qa_eval/llm_config.py +92 -92
- package/scripts/qa_eval/memory_monitor.py +132 -132
- package/scripts/qa_eval/my_answer_accuracy.py +187 -187
- package/scripts/qa_eval/requirements.txt +2 -2
- package/scripts/qa_eval/run_pipeline.py +804 -711
- package/scripts/qa_eval/stats_efficiency.py +279 -279
- package/scripts/qa_eval/stats_scores.py +207 -207
|
@@ -1,92 +1,92 @@
|
|
|
1
|
-
"""LLM provider presets for qa_eval (DashScope Qwen / 智谱 Zhipu)."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
from dataclasses import dataclass
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
@dataclass(frozen=True)
|
|
10
|
-
class LlmConfig:
|
|
11
|
-
provider: str
|
|
12
|
-
api_key: str
|
|
13
|
-
base_url: str
|
|
14
|
-
model: str
|
|
15
|
-
extra_body: dict | None
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
PROVIDER_DASHSCOPE = "dashscope"
|
|
19
|
-
PROVIDER_ZHIPU = "zhipu"
|
|
20
|
-
|
|
21
|
-
_PRESETS: dict[str, dict] = {
|
|
22
|
-
PROVIDER_DASHSCOPE: {
|
|
23
|
-
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
24
|
-
"model": "qwen3-235b-a22b-instruct-2507",
|
|
25
|
-
"api_key_envs": ("DASHSCOPE_API_KEY", "OPENAI_API_KEY"),
|
|
26
|
-
"extra_body": {"enable_thinking": False},
|
|
27
|
-
},
|
|
28
|
-
PROVIDER_ZHIPU: {
|
|
29
|
-
"base_url": "https://open.bigmodel.cn/api/paas/v4/",
|
|
30
|
-
"model": "glm-4-flash",
|
|
31
|
-
"api_key_envs": ("ZHIPU_API_KEY", "ZAI_API_KEY", "OPENAI_API_KEY"),
|
|
32
|
-
"extra_body": None,
|
|
33
|
-
},
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
def _read_key(env_names: tuple[str, ...]) -> str | None:
|
|
38
|
-
for name in env_names:
|
|
39
|
-
val = os.environ.get(name, "").strip()
|
|
40
|
-
if val:
|
|
41
|
-
return val
|
|
42
|
-
return None
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def detect_provider() -> str:
|
|
46
|
-
"""Prefer explicit ZHIPU key over DashScope when both are set."""
|
|
47
|
-
if _read_key(_PRESETS[PROVIDER_ZHIPU]["api_key_envs"]):
|
|
48
|
-
return PROVIDER_ZHIPU
|
|
49
|
-
if _read_key(_PRESETS[PROVIDER_DASHSCOPE]["api_key_envs"]):
|
|
50
|
-
return PROVIDER_DASHSCOPE
|
|
51
|
-
return PROVIDER_DASHSCOPE
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
def resolve_llm_config(
|
|
55
|
-
*,
|
|
56
|
-
provider: str | None = None,
|
|
57
|
-
model: str | None = None,
|
|
58
|
-
base_url: str | None = None,
|
|
59
|
-
) -> LlmConfig:
|
|
60
|
-
name = (provider or detect_provider()).strip().lower()
|
|
61
|
-
if name not in _PRESETS:
|
|
62
|
-
known = ", ".join(_PRESETS)
|
|
63
|
-
raise ValueError(f"未知 LLM provider: {provider!r},可选: {known}")
|
|
64
|
-
|
|
65
|
-
preset = _PRESETS[name]
|
|
66
|
-
api_key = _read_key(preset["api_key_envs"])
|
|
67
|
-
if not api_key:
|
|
68
|
-
env_hint = " / ".join(preset["api_key_envs"])
|
|
69
|
-
raise RuntimeError(
|
|
70
|
-
f"未找到 {name} 的 API Key。请设置环境变量: {env_hint}\n"
|
|
71
|
-
f" 智谱: export ZHIPU_API_KEY='your-id.your-secret'\n"
|
|
72
|
-
f" DashScope: export DASHSCOPE_API_KEY='sk-...'"
|
|
73
|
-
)
|
|
74
|
-
|
|
75
|
-
# Strip mistaken sk- prefix on Zhipu keys (id.secret format).
|
|
76
|
-
if name == PROVIDER_ZHIPU and api_key.startswith("sk-") and "." in api_key[3:]:
|
|
77
|
-
api_key = api_key[3:]
|
|
78
|
-
|
|
79
|
-
return LlmConfig(
|
|
80
|
-
provider=name,
|
|
81
|
-
api_key=api_key,
|
|
82
|
-
base_url=(base_url or preset["base_url"]).rstrip("/") + "/",
|
|
83
|
-
model=model or preset["model"],
|
|
84
|
-
extra_body=preset["extra_body"],
|
|
85
|
-
)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def provider_help() -> str:
|
|
89
|
-
return (
|
|
90
|
-
f"dashscope (默认 Qwen, { _PRESETS[PROVIDER_DASHSCOPE]['model']}) | "
|
|
91
|
-
f"zhipu (智谱, 默认 { _PRESETS[PROVIDER_ZHIPU]['model']})"
|
|
92
|
-
)
|
|
1
|
+
"""LLM provider presets for qa_eval (DashScope Qwen / 智谱 Zhipu)."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
from dataclasses import dataclass
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@dataclass(frozen=True)
|
|
10
|
+
class LlmConfig:
|
|
11
|
+
provider: str
|
|
12
|
+
api_key: str
|
|
13
|
+
base_url: str
|
|
14
|
+
model: str
|
|
15
|
+
extra_body: dict | None
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
PROVIDER_DASHSCOPE = "dashscope"
|
|
19
|
+
PROVIDER_ZHIPU = "zhipu"
|
|
20
|
+
|
|
21
|
+
_PRESETS: dict[str, dict] = {
|
|
22
|
+
PROVIDER_DASHSCOPE: {
|
|
23
|
+
"base_url": "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
|
24
|
+
"model": "qwen3-235b-a22b-instruct-2507",
|
|
25
|
+
"api_key_envs": ("DASHSCOPE_API_KEY", "OPENAI_API_KEY"),
|
|
26
|
+
"extra_body": {"enable_thinking": False},
|
|
27
|
+
},
|
|
28
|
+
PROVIDER_ZHIPU: {
|
|
29
|
+
"base_url": "https://open.bigmodel.cn/api/paas/v4/",
|
|
30
|
+
"model": "glm-4-flash",
|
|
31
|
+
"api_key_envs": ("ZHIPU_API_KEY", "ZAI_API_KEY", "OPENAI_API_KEY"),
|
|
32
|
+
"extra_body": None,
|
|
33
|
+
},
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _read_key(env_names: tuple[str, ...]) -> str | None:
|
|
38
|
+
for name in env_names:
|
|
39
|
+
val = os.environ.get(name, "").strip()
|
|
40
|
+
if val:
|
|
41
|
+
return val
|
|
42
|
+
return None
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def detect_provider() -> str:
|
|
46
|
+
"""Prefer explicit ZHIPU key over DashScope when both are set."""
|
|
47
|
+
if _read_key(_PRESETS[PROVIDER_ZHIPU]["api_key_envs"]):
|
|
48
|
+
return PROVIDER_ZHIPU
|
|
49
|
+
if _read_key(_PRESETS[PROVIDER_DASHSCOPE]["api_key_envs"]):
|
|
50
|
+
return PROVIDER_DASHSCOPE
|
|
51
|
+
return PROVIDER_DASHSCOPE
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
def resolve_llm_config(
|
|
55
|
+
*,
|
|
56
|
+
provider: str | None = None,
|
|
57
|
+
model: str | None = None,
|
|
58
|
+
base_url: str | None = None,
|
|
59
|
+
) -> LlmConfig:
|
|
60
|
+
name = (provider or detect_provider()).strip().lower()
|
|
61
|
+
if name not in _PRESETS:
|
|
62
|
+
known = ", ".join(_PRESETS)
|
|
63
|
+
raise ValueError(f"未知 LLM provider: {provider!r},可选: {known}")
|
|
64
|
+
|
|
65
|
+
preset = _PRESETS[name]
|
|
66
|
+
api_key = _read_key(preset["api_key_envs"])
|
|
67
|
+
if not api_key:
|
|
68
|
+
env_hint = " / ".join(preset["api_key_envs"])
|
|
69
|
+
raise RuntimeError(
|
|
70
|
+
f"未找到 {name} 的 API Key。请设置环境变量: {env_hint}\n"
|
|
71
|
+
f" 智谱: export ZHIPU_API_KEY='your-id.your-secret'\n"
|
|
72
|
+
f" DashScope: export DASHSCOPE_API_KEY='sk-...'"
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
# Strip mistaken sk- prefix on Zhipu keys (id.secret format).
|
|
76
|
+
if name == PROVIDER_ZHIPU and api_key.startswith("sk-") and "." in api_key[3:]:
|
|
77
|
+
api_key = api_key[3:]
|
|
78
|
+
|
|
79
|
+
return LlmConfig(
|
|
80
|
+
provider=name,
|
|
81
|
+
api_key=api_key,
|
|
82
|
+
base_url=(base_url or preset["base_url"]).rstrip("/") + "/",
|
|
83
|
+
model=model or preset["model"],
|
|
84
|
+
extra_body=preset["extra_body"],
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def provider_help() -> str:
|
|
89
|
+
return (
|
|
90
|
+
f"dashscope (默认 Qwen, { _PRESETS[PROVIDER_DASHSCOPE]['model']}) | "
|
|
91
|
+
f"zhipu (智谱, 默认 { _PRESETS[PROVIDER_ZHIPU]['model']})"
|
|
92
|
+
)
|
|
@@ -1,132 +1,132 @@
|
|
|
1
|
-
"""Sample RSS for a process tree (Linux /proc). Used by qa_eval Agent runs."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
import sys
|
|
7
|
-
import threading
|
|
8
|
-
import time
|
|
9
|
-
from contextlib import contextmanager
|
|
10
|
-
from statistics import mean
|
|
11
|
-
|
|
12
|
-
_PROC_AVAILABLE = sys.platform == "linux" and os.path.isdir("/proc")
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
def memory_sampling_supported() -> bool:
|
|
16
|
-
"""True when process-tree RSS sampling is available (Linux /proc)."""
|
|
17
|
-
return _PROC_AVAILABLE
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def _read_rss_kb(pid: int) -> int:
|
|
21
|
-
if not _PROC_AVAILABLE:
|
|
22
|
-
return 0
|
|
23
|
-
try:
|
|
24
|
-
with open(f"/proc/{pid}/status", encoding="utf-8") as f:
|
|
25
|
-
for line in f:
|
|
26
|
-
if line.startswith("VmRSS:"):
|
|
27
|
-
return int(line.split()[1])
|
|
28
|
-
except OSError:
|
|
29
|
-
return 0
|
|
30
|
-
return 0
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
def _build_ppid_map() -> dict[int, list[int]]:
|
|
34
|
-
children: dict[int, list[int]] = {}
|
|
35
|
-
if not _PROC_AVAILABLE:
|
|
36
|
-
return children
|
|
37
|
-
try:
|
|
38
|
-
proc_entries = os.listdir("/proc")
|
|
39
|
-
except OSError:
|
|
40
|
-
return children
|
|
41
|
-
for name in proc_entries:
|
|
42
|
-
if not name.isdigit():
|
|
43
|
-
continue
|
|
44
|
-
pid = int(name)
|
|
45
|
-
try:
|
|
46
|
-
with open(f"/proc/{pid}/stat", encoding="utf-8") as f:
|
|
47
|
-
stat = f.read()
|
|
48
|
-
# comm may contain ')'; ppid follows closing paren + space
|
|
49
|
-
after = stat.rsplit(")", 1)[1].split()
|
|
50
|
-
ppid = int(after[1])
|
|
51
|
-
except (OSError, IndexError, ValueError):
|
|
52
|
-
continue
|
|
53
|
-
children.setdefault(ppid, []).append(pid)
|
|
54
|
-
return children
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
def process_tree_pids(root_pid: int) -> set[int]:
|
|
58
|
-
if root_pid <= 0:
|
|
59
|
-
return set()
|
|
60
|
-
children = _build_ppid_map()
|
|
61
|
-
seen: set[int] = set()
|
|
62
|
-
stack = [root_pid]
|
|
63
|
-
while stack:
|
|
64
|
-
pid = stack.pop()
|
|
65
|
-
if pid in seen:
|
|
66
|
-
continue
|
|
67
|
-
seen.add(pid)
|
|
68
|
-
stack.extend(children.get(pid, []))
|
|
69
|
-
return seen
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
def tree_rss_kb(root_pid: int) -> int:
|
|
73
|
-
return sum(_read_rss_kb(pid) for pid in process_tree_pids(root_pid))
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
class MemorySampler:
|
|
77
|
-
"""Background RSS sampler for root_pid and its descendants."""
|
|
78
|
-
|
|
79
|
-
def __init__(self, interval_sec: float = 0.25) -> None:
|
|
80
|
-
self.interval_sec = interval_sec
|
|
81
|
-
self._root_pid = os.getpid()
|
|
82
|
-
self._samples_kb: list[int] = []
|
|
83
|
-
self._stop = threading.Event()
|
|
84
|
-
self._thread: threading.Thread | None = None
|
|
85
|
-
|
|
86
|
-
def start(self, root_pid: int | None = None) -> None:
|
|
87
|
-
self._root_pid = root_pid if root_pid is not None else os.getpid()
|
|
88
|
-
self._samples_kb = []
|
|
89
|
-
self._stop.clear()
|
|
90
|
-
if not _PROC_AVAILABLE:
|
|
91
|
-
self._thread = None
|
|
92
|
-
return
|
|
93
|
-
self._thread = threading.Thread(target=self._loop, daemon=True)
|
|
94
|
-
self._thread.start()
|
|
95
|
-
|
|
96
|
-
def _loop(self) -> None:
|
|
97
|
-
while not self._stop.is_set():
|
|
98
|
-
try:
|
|
99
|
-
self._samples_kb.append(tree_rss_kb(self._root_pid))
|
|
100
|
-
except OSError:
|
|
101
|
-
break
|
|
102
|
-
self._stop.wait(self.interval_sec)
|
|
103
|
-
|
|
104
|
-
@property
|
|
105
|
-
def last_stats(self) -> dict[str, float | None]:
|
|
106
|
-
"""Peak/avg RSS so far (safe to read while sampling is active)."""
|
|
107
|
-
if not self._samples_kb:
|
|
108
|
-
return {"peak_rss_mb": None, "avg_rss_mb": None}
|
|
109
|
-
peak_kb = max(self._samples_kb)
|
|
110
|
-
avg_kb = mean(self._samples_kb)
|
|
111
|
-
return {
|
|
112
|
-
"peak_rss_mb": round(peak_kb / 1024, 2),
|
|
113
|
-
"avg_rss_mb": round(avg_kb / 1024, 2),
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
def stop(self) -> dict[str, float | None]:
|
|
117
|
-
self._stop.set()
|
|
118
|
-
if self._thread:
|
|
119
|
-
self._thread.join(timeout=2.0)
|
|
120
|
-
return self.last_stats
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
@contextmanager
|
|
124
|
-
def sample_memory(root_pid: int | None = None):
|
|
125
|
-
"""Sample process-tree RSS while the wrapped block runs."""
|
|
126
|
-
sampler = MemorySampler()
|
|
127
|
-
pid = root_pid if root_pid is not None else os.getpid()
|
|
128
|
-
sampler.start(pid)
|
|
129
|
-
try:
|
|
130
|
-
yield sampler
|
|
131
|
-
finally:
|
|
132
|
-
sampler.stop()
|
|
1
|
+
"""Sample RSS for a process tree (Linux /proc). Used by qa_eval Agent runs."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import os
|
|
6
|
+
import sys
|
|
7
|
+
import threading
|
|
8
|
+
import time
|
|
9
|
+
from contextlib import contextmanager
|
|
10
|
+
from statistics import mean
|
|
11
|
+
|
|
12
|
+
_PROC_AVAILABLE = sys.platform == "linux" and os.path.isdir("/proc")
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def memory_sampling_supported() -> bool:
|
|
16
|
+
"""True when process-tree RSS sampling is available (Linux /proc)."""
|
|
17
|
+
return _PROC_AVAILABLE
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _read_rss_kb(pid: int) -> int:
|
|
21
|
+
if not _PROC_AVAILABLE:
|
|
22
|
+
return 0
|
|
23
|
+
try:
|
|
24
|
+
with open(f"/proc/{pid}/status", encoding="utf-8") as f:
|
|
25
|
+
for line in f:
|
|
26
|
+
if line.startswith("VmRSS:"):
|
|
27
|
+
return int(line.split()[1])
|
|
28
|
+
except OSError:
|
|
29
|
+
return 0
|
|
30
|
+
return 0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _build_ppid_map() -> dict[int, list[int]]:
|
|
34
|
+
children: dict[int, list[int]] = {}
|
|
35
|
+
if not _PROC_AVAILABLE:
|
|
36
|
+
return children
|
|
37
|
+
try:
|
|
38
|
+
proc_entries = os.listdir("/proc")
|
|
39
|
+
except OSError:
|
|
40
|
+
return children
|
|
41
|
+
for name in proc_entries:
|
|
42
|
+
if not name.isdigit():
|
|
43
|
+
continue
|
|
44
|
+
pid = int(name)
|
|
45
|
+
try:
|
|
46
|
+
with open(f"/proc/{pid}/stat", encoding="utf-8") as f:
|
|
47
|
+
stat = f.read()
|
|
48
|
+
# comm may contain ')'; ppid follows closing paren + space
|
|
49
|
+
after = stat.rsplit(")", 1)[1].split()
|
|
50
|
+
ppid = int(after[1])
|
|
51
|
+
except (OSError, IndexError, ValueError):
|
|
52
|
+
continue
|
|
53
|
+
children.setdefault(ppid, []).append(pid)
|
|
54
|
+
return children
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
def process_tree_pids(root_pid: int) -> set[int]:
|
|
58
|
+
if root_pid <= 0:
|
|
59
|
+
return set()
|
|
60
|
+
children = _build_ppid_map()
|
|
61
|
+
seen: set[int] = set()
|
|
62
|
+
stack = [root_pid]
|
|
63
|
+
while stack:
|
|
64
|
+
pid = stack.pop()
|
|
65
|
+
if pid in seen:
|
|
66
|
+
continue
|
|
67
|
+
seen.add(pid)
|
|
68
|
+
stack.extend(children.get(pid, []))
|
|
69
|
+
return seen
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def tree_rss_kb(root_pid: int) -> int:
|
|
73
|
+
return sum(_read_rss_kb(pid) for pid in process_tree_pids(root_pid))
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class MemorySampler:
|
|
77
|
+
"""Background RSS sampler for root_pid and its descendants."""
|
|
78
|
+
|
|
79
|
+
def __init__(self, interval_sec: float = 0.25) -> None:
|
|
80
|
+
self.interval_sec = interval_sec
|
|
81
|
+
self._root_pid = os.getpid()
|
|
82
|
+
self._samples_kb: list[int] = []
|
|
83
|
+
self._stop = threading.Event()
|
|
84
|
+
self._thread: threading.Thread | None = None
|
|
85
|
+
|
|
86
|
+
def start(self, root_pid: int | None = None) -> None:
|
|
87
|
+
self._root_pid = root_pid if root_pid is not None else os.getpid()
|
|
88
|
+
self._samples_kb = []
|
|
89
|
+
self._stop.clear()
|
|
90
|
+
if not _PROC_AVAILABLE:
|
|
91
|
+
self._thread = None
|
|
92
|
+
return
|
|
93
|
+
self._thread = threading.Thread(target=self._loop, daemon=True)
|
|
94
|
+
self._thread.start()
|
|
95
|
+
|
|
96
|
+
def _loop(self) -> None:
|
|
97
|
+
while not self._stop.is_set():
|
|
98
|
+
try:
|
|
99
|
+
self._samples_kb.append(tree_rss_kb(self._root_pid))
|
|
100
|
+
except OSError:
|
|
101
|
+
break
|
|
102
|
+
self._stop.wait(self.interval_sec)
|
|
103
|
+
|
|
104
|
+
@property
|
|
105
|
+
def last_stats(self) -> dict[str, float | None]:
|
|
106
|
+
"""Peak/avg RSS so far (safe to read while sampling is active)."""
|
|
107
|
+
if not self._samples_kb:
|
|
108
|
+
return {"peak_rss_mb": None, "avg_rss_mb": None}
|
|
109
|
+
peak_kb = max(self._samples_kb)
|
|
110
|
+
avg_kb = mean(self._samples_kb)
|
|
111
|
+
return {
|
|
112
|
+
"peak_rss_mb": round(peak_kb / 1024, 2),
|
|
113
|
+
"avg_rss_mb": round(avg_kb / 1024, 2),
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
def stop(self) -> dict[str, float | None]:
|
|
117
|
+
self._stop.set()
|
|
118
|
+
if self._thread:
|
|
119
|
+
self._thread.join(timeout=2.0)
|
|
120
|
+
return self.last_stats
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@contextmanager
|
|
124
|
+
def sample_memory(root_pid: int | None = None):
|
|
125
|
+
"""Sample process-tree RSS while the wrapped block runs."""
|
|
126
|
+
sampler = MemorySampler()
|
|
127
|
+
pid = root_pid if root_pid is not None else os.getpid()
|
|
128
|
+
sampler.start(pid)
|
|
129
|
+
try:
|
|
130
|
+
yield sampler
|
|
131
|
+
finally:
|
|
132
|
+
sampler.stop()
|