{"repo": "chen-zhuofu/langbridge-code", "files": {"src/config.json": {"6cc160d57b2e5eef49093380d51a08924187c19e": {"t": 1785746268.901527, "n": 2604, "h": "be46c535c72be39d", "c": "{\n \"model\": null,\n \"api\": {\n \"provider\": \"deepseek\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"]\n },\n \"openai\": {\n \"base_url\": \"https://api.openai.com/v1\",\n \"model\": \"gpt-5.6\",\n \"models\": [\n \"gpt-5.6-sol\",\n \"gpt-5.6-terra\",\n \"gpt-5.6-luna\",\n \"gpt-5.5\",\n \"gpt-5.5-pro\",\n \"gpt-5.4\",\n \"gpt-5.3-codex\"\n ]\n },\n \"anthropic\": {\n \"base_url\": \"https://api.anthropic.com/v1/\",\n \"model\": \"claude-fable-5\"\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-flash\",\n \"agent_models\": {\n \"explorer\": \"deepseek-v4-flash\"\n }\n }\n },\n \"timeout_seconds\": 120,\n \"max_retries\": 2,\n \"streaming_enabled\": true,\n \"max_output_tokens\": 8000,\n \"escalated_max_output_tokens\": 64000\n },\n \"api_keys\": {\n \"moonshot\": null,\n \"openai\": null,\n \"anthropic\": null,\n \"deepseek\": null\n },\n \"agent\": {\n \"max_agent_steps\": 1000000,\n \"max_agent_seconds\": 1000000,\n \"max_explorer_steps\": null,\n \"max_explorer_seconds\": null,\n \"max_worker_steps\": 1000000,\n \"max_worker_seconds\": 1000000,\n \"max_reviewer_steps\": 1000000,\n \"max_reviewer_seconds\": 1000000,\n \"max_planner_steps\": 1000000,\n \"max_planner_seconds\": 1000000,\n \"max_worker_reviewer_steps\": 1000000,\n \"max_worker_reviewer_seconds\": 1000000,\n \"max_parallel_tool_calls\": 1000,\n \"parallel_agents_enabled\": true\n },\n \"goal\": {\n \"default_max_turns\": 1000000,\n \"eval_input_chars\": 12000,\n \"evaluator_max_steps\": 1000000\n },\n \"context\": {\n \"context_window_max_fraction\": 0.4,\n \"default_context_window_tokens\": 128000,\n \"model_context_windows\": {},\n \"max_session_choices\": 10,\n \"compact_raw_keep\": 11,\n \"compact_threshold_tokens\": 100000,\n \"traces_resume_max_fraction\": 0.3,\n \"progress_note_reminder_rounds\": 10\n },\n \"tools\": {\n \"filesystem\": {\n \"max_file_bytes\": 262144\n },\n \"execution\": {\n \"max_output_chars\": 30000,\n \"default_timeout_seconds\": 60,\n \"max_timeout_seconds\": 300\n },\n \"web\": {\n \"default_timeout_seconds\": 30,\n \"max_timeout_seconds\": 120,\n \"max_webpage_chars\": 20000\n },\n \"debug\": {\n \"default_max_chars\": 200\n }\n },\n \"eval\": {\n \"eval_layer_timeout_seconds\": 2400,\n \"grade_timeout_seconds\": 600\n },\n \"paths\": {\n \"agent_state_dir\": null,\n \"artifacts_dir\": null\n }\n}\n"}, "3efe32586974c1d67ca058af9bed594bb403b33b": {"t": 1785761304.9682014, "n": 2604, "h": "be46c535c72be39d", "c": "{\n \"model\": null,\n \"api\": {\n \"provider\": \"deepseek\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"]\n },\n \"openai\": {\n \"base_url\": \"https://api.openai.com/v1\",\n \"model\": \"gpt-5.6\",\n \"models\": [\n \"gpt-5.6-sol\",\n \"gpt-5.6-terra\",\n \"gpt-5.6-luna\",\n \"gpt-5.5\",\n \"gpt-5.5-pro\",\n \"gpt-5.4\",\n \"gpt-5.3-codex\"\n ]\n },\n \"anthropic\": {\n \"base_url\": \"https://api.anthropic.com/v1/\",\n \"model\": \"claude-fable-5\"\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-flash\",\n \"agent_models\": {\n \"explorer\": \"deepseek-v4-flash\"\n }\n }\n },\n \"timeout_seconds\": 120,\n \"max_retries\": 2,\n \"streaming_enabled\": true,\n \"max_output_tokens\": 8000,\n \"escalated_max_output_tokens\": 64000\n },\n \"api_keys\": {\n \"moonshot\": null,\n \"openai\": null,\n \"anthropic\": null,\n \"deepseek\": null\n },\n \"agent\": {\n \"max_agent_steps\": 1000000,\n \"max_agent_seconds\": 1000000,\n \"max_explorer_steps\": null,\n \"max_explorer_seconds\": null,\n \"max_worker_steps\": 1000000,\n \"max_worker_seconds\": 1000000,\n \"max_reviewer_steps\": 1000000,\n \"max_reviewer_seconds\": 1000000,\n \"max_planner_steps\": 1000000,\n \"max_planner_seconds\": 1000000,\n \"max_worker_reviewer_steps\": 1000000,\n \"max_worker_reviewer_seconds\": 1000000,\n \"max_parallel_tool_calls\": 1000,\n \"parallel_agents_enabled\": true\n },\n \"goal\": {\n \"default_max_turns\": 1000000,\n \"eval_input_chars\": 12000,\n \"evaluator_max_steps\": 1000000\n },\n \"context\": {\n \"context_window_max_fraction\": 0.4,\n \"default_context_window_tokens\": 128000,\n \"model_context_windows\": {},\n \"max_session_choices\": 10,\n \"compact_raw_keep\": 11,\n \"compact_threshold_tokens\": 100000,\n \"traces_resume_max_fraction\": 0.3,\n \"progress_note_reminder_rounds\": 10\n },\n \"tools\": {\n \"filesystem\": {\n \"max_file_bytes\": 262144\n },\n \"execution\": {\n \"max_output_chars\": 30000,\n \"default_timeout_seconds\": 60,\n \"max_timeout_seconds\": 300\n },\n \"web\": {\n \"default_timeout_seconds\": 30,\n \"max_timeout_seconds\": 120,\n \"max_webpage_chars\": 20000\n },\n \"debug\": {\n \"default_max_chars\": 200\n }\n },\n \"eval\": {\n \"eval_layer_timeout_seconds\": 2400,\n \"grade_timeout_seconds\": 600\n },\n \"paths\": {\n \"agent_state_dir\": null,\n \"artifacts_dir\": null\n }\n}\n"}, "f95fb230875b8617bc4535e916e1b1c9f08f44c7": {"t": 1785761306.4444404, "n": 2602, "h": "5ee864ee60f76ceb", "c": "{\n \"model\": null,\n \"api\": {\n \"provider\": \"deepseek\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"]\n },\n \"openai\": {\n \"base_url\": \"https://api.openai.com/v1\",\n \"model\": \"gpt-5.6\",\n \"models\": [\n \"gpt-5.6-sol\",\n \"gpt-5.6-terra\",\n \"gpt-5.6-luna\",\n \"gpt-5.5\",\n \"gpt-5.5-pro\",\n \"gpt-5.4\",\n \"gpt-5.3-codex\"\n ]\n },\n \"anthropic\": {\n \"base_url\": \"https://api.anthropic.com/v1/\",\n \"model\": \"claude-fable-5\"\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n \"agent_models\": {\n \"explorer\": \"deepseek-v4-flash\"\n }\n }\n },\n \"timeout_seconds\": 120,\n \"max_retries\": 2,\n \"streaming_enabled\": true,\n \"max_output_tokens\": 8000,\n \"escalated_max_output_tokens\": 64000\n },\n \"api_keys\": {\n \"moonshot\": null,\n \"openai\": null,\n \"anthropic\": null,\n \"deepseek\": null\n },\n \"agent\": {\n \"max_agent_steps\": 1000000,\n \"max_agent_seconds\": 1000000,\n \"max_explorer_steps\": null,\n \"max_explorer_seconds\": null,\n \"max_worker_steps\": 1000000,\n \"max_worker_seconds\": 1000000,\n \"max_reviewer_steps\": 1000000,\n \"max_reviewer_seconds\": 1000000,\n \"max_planner_steps\": 1000000,\n \"max_planner_seconds\": 1000000,\n \"max_worker_reviewer_steps\": 1000000,\n \"max_worker_reviewer_seconds\": 1000000,\n \"max_parallel_tool_calls\": 1000,\n \"parallel_agents_enabled\": true\n },\n \"goal\": {\n \"default_max_turns\": 1000000,\n \"eval_input_chars\": 12000,\n \"evaluator_max_steps\": 1000000\n },\n \"context\": {\n \"context_window_max_fraction\": 0.4,\n \"default_context_window_tokens\": 128000,\n \"model_context_windows\": {},\n \"max_session_choices\": 10,\n \"compact_raw_keep\": 11,\n \"compact_threshold_tokens\": 100000,\n \"traces_resume_max_fraction\": 0.3,\n \"progress_note_reminder_rounds\": 10\n },\n \"tools\": {\n \"filesystem\": {\n \"max_file_bytes\": 262144\n },\n \"execution\": {\n \"max_output_chars\": 30000,\n \"default_timeout_seconds\": 60,\n \"max_timeout_seconds\": 300\n },\n \"web\": {\n \"default_timeout_seconds\": 30,\n \"max_timeout_seconds\": 120,\n \"max_webpage_chars\": 20000\n },\n \"debug\": {\n \"default_max_chars\": 200\n }\n },\n \"eval\": {\n \"eval_layer_timeout_seconds\": 2400,\n \"grade_timeout_seconds\": 600\n },\n \"paths\": {\n \"agent_state_dir\": null,\n \"artifacts_dir\": null\n }\n}\n"}, "7286c5ebc6535a7e75b7806380e133b3a68a8375": {"t": 1785761307.705019, "n": 2241, "h": "331310463993d703", "c": "{\n \"model\": null,\n \"api\": {\n \"provider\": \"deepseek\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"]\n },\n \"openai\": {\n \"base_url\": \"\",\n \"model\": \"gpt-5.3-codex\"\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n \"agent_models\": {\n \"explorer\": \"deepseek-v4-flash\"\n }\n }\n },\n \"timeout_seconds\": 120,\n \"max_retries\": 2,\n \"streaming_enabled\": true,\n \"max_output_tokens\": 8000,\n \"escalated_max_output_tokens\": 64000\n },\n \"api_keys\": {\n \"moonshot\": null,\n \"openai\": null,\n \"deepseek\": null\n },\n \"agent\": {\n \"max_agent_steps\": 1000000,\n \"max_agent_seconds\": 1000000,\n \"max_explorer_steps\": null,\n \"max_explorer_seconds\": null,\n \"max_worker_steps\": 1000000,\n \"max_worker_seconds\": 1000000,\n \"max_reviewer_steps\": 1000000,\n \"max_reviewer_seconds\": 1000000,\n \"max_planner_steps\": 1000000,\n \"max_planner_seconds\": 1000000,\n \"max_worker_reviewer_steps\": 1000000,\n \"max_worker_reviewer_seconds\": 1000000,\n \"max_parallel_tool_calls\": 1000,\n \"parallel_agents_enabled\": true\n },\n \"goal\": {\n \"default_max_turns\": 1000000,\n \"eval_input_chars\": 12000,\n \"evaluator_max_steps\": 1000000\n },\n \"context\": {\n \"context_window_max_fraction\": 0.4,\n \"default_context_window_tokens\": 128000,\n \"model_context_windows\": {},\n \"max_session_choices\": 10,\n \"compact_raw_keep\": 11,\n \"compact_threshold_tokens\": 100000,\n \"traces_resume_max_fraction\": 0.3,\n \"progress_note_reminder_rounds\": 10\n },\n \"tools\": {\n \"filesystem\": {\n \"max_file_bytes\": 262144\n },\n \"execution\": {\n \"max_output_chars\": 30000,\n \"default_timeout_seconds\": 60,\n \"max_timeout_seconds\": 300\n },\n \"web\": {\n \"default_timeout_seconds\": 30,\n \"max_timeout_seconds\": 120,\n \"max_webpage_chars\": 20000\n },\n \"debug\": {\n \"default_max_chars\": 200\n }\n },\n \"eval\": {\n \"eval_layer_timeout_seconds\": 2400,\n \"grade_timeout_seconds\": 600\n },\n \"paths\": {\n \"agent_state_dir\": null,\n \"artifacts_dir\": null\n }\n}\n"}, "747aa3cdacace050b0ba1134e49752215754e947": {"t": 1785761308.9020634, "n": 2241, "h": "9bd80f1f7d7fc9b1", "c": "{\n \"model\": null,\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"]\n },\n \"openai\": {\n \"base_url\": \"\",\n \"model\": \"gpt-5.3-codex\"\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n \"agent_models\": {\n \"explorer\": \"deepseek-v4-flash\"\n }\n }\n },\n \"timeout_seconds\": 120,\n \"max_retries\": 2,\n \"streaming_enabled\": true,\n \"max_output_tokens\": 8000,\n \"escalated_max_output_tokens\": 64000\n },\n \"api_keys\": {\n \"moonshot\": null,\n \"openai\": null,\n \"deepseek\": null\n },\n \"agent\": {\n \"max_agent_steps\": 1000000,\n \"max_agent_seconds\": 1000000,\n \"max_explorer_steps\": null,\n \"max_explorer_seconds\": null,\n \"max_worker_steps\": 1000000,\n \"max_worker_seconds\": 1000000,\n \"max_reviewer_steps\": 1000000,\n \"max_reviewer_seconds\": 1000000,\n \"max_planner_steps\": 1000000,\n \"max_planner_seconds\": 1000000,\n \"max_worker_reviewer_steps\": 1000000,\n \"max_worker_reviewer_seconds\": 1000000,\n \"max_parallel_tool_calls\": 1000,\n \"parallel_agents_enabled\": true\n },\n \"goal\": {\n \"default_max_turns\": 1000000,\n \"eval_input_chars\": 12000,\n \"evaluator_max_steps\": 1000000\n },\n \"context\": {\n \"context_window_max_fraction\": 0.4,\n \"default_context_window_tokens\": 128000,\n \"model_context_windows\": {},\n \"max_session_choices\": 10,\n \"compact_raw_keep\": 11,\n \"compact_threshold_tokens\": 100000,\n \"traces_resume_max_fraction\": 0.3,\n \"progress_note_reminder_rounds\": 10\n },\n \"tools\": {\n \"filesystem\": {\n \"max_file_bytes\": 262144\n },\n \"execution\": {\n \"max_output_chars\": 30000,\n \"default_timeout_seconds\": 60,\n \"max_timeout_seconds\": 300\n },\n \"web\": {\n \"default_timeout_seconds\": 30,\n \"max_timeout_seconds\": 120,\n \"max_webpage_chars\": 20000\n },\n \"debug\": {\n \"default_max_chars\": 200\n }\n },\n \"eval\": {\n \"eval_layer_timeout_seconds\": 2400,\n \"grade_timeout_seconds\": 600\n },\n \"paths\": {\n \"agent_state_dir\": null,\n \"artifacts_dir\": null\n }\n}\n"}}, "interactive-bench/tests/test_bench_config.py": {"6cc160d57b2e5eef49093380d51a08924187c19e": {"t": 1785746903.061995, "n": 2982, "h": "e888f18f3ee58df2", "c": "\"\"\"interactive-bench/config.json is the source of truth for this bench's models.\"\"\"\nfrom __future__ import annotations\n\nimport sys\nfrom pathlib import Path\n\nPIPELINE = Path(__file__).resolve().parents[1] / \"data-pipeline\"\nif str(PIPELINE) not in sys.path:\n sys.path.insert(0, str(PIPELINE))\n\nfrom _lib.bench_config import ( # noqa: E402\n agent_defaults,\n eval_run_metadata,\n interactive_defaults,\n load_bench_config,\n merge_agent_user_config,\n pipeline_defaults,\n resolve_coverage_model,\n resolve_intent_model,\n resolve_sim_model,\n)\n\n\ndef test_shipped_config_defaults():\n cfg = load_bench_config()\n agent = agent_defaults(cfg)\n assert agent[\"provider\"] == \"deepseek\"\n assert agent[\"model\"] == \"deepseek-v4-pro\"\n assert agent[\"agent_models\"][\"explorer\"] == \"deepseek-v4-flash\"\n interactive = interactive_defaults(cfg)\n assert interactive[\"sim_model\"] == \"gpt-5.6\"\n assert interactive[\"coverage_model\"] == \"claude-fable-5\"\n assert pipeline_defaults(cfg)[\"intent_model\"] == \"claude-fable-5\"\n\n\ndef test_resolve_models_prefer_env(monkeypatch):\n monkeypatch.setenv(\"LB_SIM_MODEL\", \"sim-override\")\n monkeypatch.setenv(\"LB_COVERAGE_MODEL\", \"cov-override\")\n monkeypatch.setenv(\"LB_INTENT_MODEL\", \"intent-override\")\n assert resolve_sim_model() == \"sim-override\"\n assert resolve_coverage_model() == \"cov-override\"\n assert resolve_intent_model() == \"intent-override\"\n\n\ndef test_generic_interactive_env_fallback(monkeypatch):\n monkeypatch.delenv(\"LB_SIM_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_COVERAGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_INTENT_MODEL\", raising=False)\n monkeypatch.setenv(\"LB_INTERACTIVE_MODEL\", \"generic-override\")\n assert resolve_sim_model() == \"generic-override\"\n assert resolve_coverage_model() == \"generic-override\"\n assert resolve_intent_model() == \"generic-override\"\n\n\ndef test_merge_agent_user_config_pins_bench_stack():\n merged = merge_agent_user_config({\n \"model\": \"kimi-k3\",\n \"api\": {\"provider\": \"moonshot\"},\n \"api_keys\": {\"moonshot\": \"sk-moon\", \"deepseek\": \"sk-deep\"},\n })\n assert merged[\"model\"] is None\n assert merged[\"api\"][\"provider\"] == \"deepseek\"\n assert merged[\"api\"][\"providers\"][\"deepseek\"][\"model\"] == \"deepseek-v4-pro\"\n assert merged[\"api_keys\"][\"deepseek\"] == \"sk-deep\"\n\n\ndef test_eval_run_metadata_shape(monkeypatch):\n monkeypatch.delenv(\"LB_SIM_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_COVERAGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_INTERACTIVE_MODEL\", raising=False)\n meta = eval_run_metadata(agent_model=\"custom-agent\", stub=True)\n assert meta[\"agent\"][\"model\"] == \"custom-agent\"\n assert meta[\"agent\"][\"cli_model_override\"] is True\n assert meta[\"interactive\"][\"sim_model\"] == \"gpt-5.6\"\n assert meta[\"interactive\"][\"coverage_model\"] == \"claude-fable-5\"\n assert meta[\"stub\"] is True\n assert meta[\"config_path\"].endswith(\"interactive-bench/config.json\")\n"}, "f95fb230875b8617bc4535e916e1b1c9f08f44c7": {"t": 1785761304.5860994, "n": 2982, "h": "e888f18f3ee58df2", "c": "\"\"\"interactive-bench/config.json is the source of truth for this bench's models.\"\"\"\nfrom __future__ import annotations\n\nimport sys\nfrom pathlib import Path\n\nPIPELINE = Path(__file__).resolve().parents[1] / \"data-pipeline\"\nif str(PIPELINE) not in sys.path:\n sys.path.insert(0, str(PIPELINE))\n\nfrom _lib.bench_config import ( # noqa: E402\n agent_defaults,\n eval_run_metadata,\n interactive_defaults,\n load_bench_config,\n merge_agent_user_config,\n pipeline_defaults,\n resolve_coverage_model,\n resolve_intent_model,\n resolve_sim_model,\n)\n\n\ndef test_shipped_config_defaults():\n cfg = load_bench_config()\n agent = agent_defaults(cfg)\n assert agent[\"provider\"] == \"deepseek\"\n assert agent[\"model\"] == \"deepseek-v4-pro\"\n assert agent[\"agent_models\"][\"explorer\"] == \"deepseek-v4-flash\"\n interactive = interactive_defaults(cfg)\n assert interactive[\"sim_model\"] == \"gpt-5.6\"\n assert interactive[\"coverage_model\"] == \"claude-fable-5\"\n assert pipeline_defaults(cfg)[\"intent_model\"] == \"claude-fable-5\"\n\n\ndef test_resolve_models_prefer_env(monkeypatch):\n monkeypatch.setenv(\"LB_SIM_MODEL\", \"sim-override\")\n monkeypatch.setenv(\"LB_COVERAGE_MODEL\", \"cov-override\")\n monkeypatch.setenv(\"LB_INTENT_MODEL\", \"intent-override\")\n assert resolve_sim_model() == \"sim-override\"\n assert resolve_coverage_model() == \"cov-override\"\n assert resolve_intent_model() == \"intent-override\"\n\n\ndef test_generic_interactive_env_fallback(monkeypatch):\n monkeypatch.delenv(\"LB_SIM_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_COVERAGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_INTENT_MODEL\", raising=False)\n monkeypatch.setenv(\"LB_INTERACTIVE_MODEL\", \"generic-override\")\n assert resolve_sim_model() == \"generic-override\"\n assert resolve_coverage_model() == \"generic-override\"\n assert resolve_intent_model() == \"generic-override\"\n\n\ndef test_merge_agent_user_config_pins_bench_stack():\n merged = merge_agent_user_config({\n \"model\": \"kimi-k3\",\n \"api\": {\"provider\": \"moonshot\"},\n \"api_keys\": {\"moonshot\": \"sk-moon\", \"deepseek\": \"sk-deep\"},\n })\n assert merged[\"model\"] is None\n assert merged[\"api\"][\"provider\"] == \"deepseek\"\n assert merged[\"api\"][\"providers\"][\"deepseek\"][\"model\"] == \"deepseek-v4-pro\"\n assert merged[\"api_keys\"][\"deepseek\"] == \"sk-deep\"\n\n\ndef test_eval_run_metadata_shape(monkeypatch):\n monkeypatch.delenv(\"LB_SIM_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_COVERAGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_INTERACTIVE_MODEL\", raising=False)\n meta = eval_run_metadata(agent_model=\"custom-agent\", stub=True)\n assert meta[\"agent\"][\"model\"] == \"custom-agent\"\n assert meta[\"agent\"][\"cli_model_override\"] is True\n assert meta[\"interactive\"][\"sim_model\"] == \"gpt-5.6\"\n assert meta[\"interactive\"][\"coverage_model\"] == \"claude-fable-5\"\n assert meta[\"stub\"] is True\n assert meta[\"config_path\"].endswith(\"interactive-bench/config.json\")\n"}, "be3d4d77ae9f07b61242d056228f9edad6c271b2": {"t": 1786068515.5211403, "n": 2982, "h": "e888f18f3ee58df2", "c": "\"\"\"interactive-bench/config.json is the source of truth for this bench's models.\"\"\"\nfrom __future__ import annotations\n\nimport sys\nfrom pathlib import Path\n\nPIPELINE = Path(__file__).resolve().parents[1] / \"data-pipeline\"\nif str(PIPELINE) not in sys.path:\n sys.path.insert(0, str(PIPELINE))\n\nfrom _lib.bench_config import ( # noqa: E402\n agent_defaults,\n eval_run_metadata,\n interactive_defaults,\n load_bench_config,\n merge_agent_user_config,\n pipeline_defaults,\n resolve_coverage_model,\n resolve_intent_model,\n resolve_sim_model,\n)\n\n\ndef test_shipped_config_defaults():\n cfg = load_bench_config()\n agent = agent_defaults(cfg)\n assert agent[\"provider\"] == \"deepseek\"\n assert agent[\"model\"] == \"deepseek-v4-pro\"\n assert agent[\"agent_models\"][\"explorer\"] == \"deepseek-v4-flash\"\n interactive = interactive_defaults(cfg)\n assert interactive[\"sim_model\"] == \"gpt-5.6\"\n assert interactive[\"coverage_model\"] == \"claude-fable-5\"\n assert pipeline_defaults(cfg)[\"intent_model\"] == \"claude-fable-5\"\n\n\ndef test_resolve_models_prefer_env(monkeypatch):\n monkeypatch.setenv(\"LB_SIM_MODEL\", \"sim-override\")\n monkeypatch.setenv(\"LB_COVERAGE_MODEL\", \"cov-override\")\n monkeypatch.setenv(\"LB_INTENT_MODEL\", \"intent-override\")\n assert resolve_sim_model() == \"sim-override\"\n assert resolve_coverage_model() == \"cov-override\"\n assert resolve_intent_model() == \"intent-override\"\n\n\ndef test_generic_interactive_env_fallback(monkeypatch):\n monkeypatch.delenv(\"LB_SIM_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_COVERAGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_INTENT_MODEL\", raising=False)\n monkeypatch.setenv(\"LB_INTERACTIVE_MODEL\", \"generic-override\")\n assert resolve_sim_model() == \"generic-override\"\n assert resolve_coverage_model() == \"generic-override\"\n assert resolve_intent_model() == \"generic-override\"\n\n\ndef test_merge_agent_user_config_pins_bench_stack():\n merged = merge_agent_user_config({\n \"model\": \"kimi-k3\",\n \"api\": {\"provider\": \"moonshot\"},\n \"api_keys\": {\"moonshot\": \"sk-moon\", \"deepseek\": \"sk-deep\"},\n })\n assert merged[\"model\"] is None\n assert merged[\"api\"][\"provider\"] == \"deepseek\"\n assert merged[\"api\"][\"providers\"][\"deepseek\"][\"model\"] == \"deepseek-v4-pro\"\n assert merged[\"api_keys\"][\"deepseek\"] == \"sk-deep\"\n\n\ndef test_eval_run_metadata_shape(monkeypatch):\n monkeypatch.delenv(\"LB_SIM_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_COVERAGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LB_INTERACTIVE_MODEL\", raising=False)\n meta = eval_run_metadata(agent_model=\"custom-agent\", stub=True)\n assert meta[\"agent\"][\"model\"] == \"custom-agent\"\n assert meta[\"agent\"][\"cli_model_override\"] is True\n assert meta[\"interactive\"][\"sim_model\"] == \"gpt-5.6\"\n assert meta[\"interactive\"][\"coverage_model\"] == \"claude-fable-5\"\n assert meta[\"stub\"] is True\n assert meta[\"config_path\"].endswith(\"interactive-bench/config.json\")\n"}}, "tests/unit/test_settings.py": {"6cc160d57b2e5eef49093380d51a08924187c19e": {"t": 1785746919.830637, "n": 11942, "h": "e19a22bf6022817a", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-flash\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_model_catalog_uses_config_only(monkeypatch):\n \"\"\"Picker must not dump live /models — only curated config entries.\"\"\"\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"],\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"load_config\", lambda: cfg)\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.list_model_catalog(\"sk-test\")\n assert [e[\"id\"] for e in catalog] == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n assert settings.list_available_models(\"sk-test\") == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n\n\ndef test_configured_model_catalog_owns_cross_provider_agent_models(monkeypatch):\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.configured_model_catalog(cfg)\n by_id = {e[\"id\"]: e[\"provider\"] for e in catalog}\n assert by_id[\"kimi-k2.7-code\"] == \"moonshot\"\n assert by_id[\"deepseek-v4-flash\"] == \"deepseek\"\n assert by_id[\"deepseek-v4-pro\"] == \"deepseek\"\n\n\ndef test_resolve_llm_route_uses_model_provider_key_and_base_url(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"deepseek\": \"sk-deep\",\n },\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n \"LANGBRIDGE_MODEL\",\n \"LANGBRIDGE_API_BASE_URL\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n moon = settings.resolve_llm_route(\"kimi-k2.7-code\", \"sk-session\")\n assert moon[\"provider\"] == \"moonshot\"\n assert moon[\"api_key\"] == \"sk-moon\"\n assert moon[\"base_url\"] == \"https://api.moonshot.ai/v1\"\n\n deep = settings.resolve_llm_route(\"deepseek-v4-flash\", \"sk-session\")\n assert deep[\"provider\"] == \"deepseek\"\n assert deep[\"api_key\"] == \"sk-deep\"\n assert deep[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_resolve_llm_route_falls_back_to_session_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\"moonshot\": \"sk-moon\"},\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n route = settings.resolve_llm_route(\"deepseek-v4-pro\", \"sk-session-fallback\")\n assert route[\"provider\"] == \"deepseek\"\n assert route[\"api_key\"] == \"sk-session-fallback\"\n assert route[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n"}, "3efe32586974c1d67ca058af9bed594bb403b33b": {"t": 1785761304.7297003, "n": 11942, "h": "e19a22bf6022817a", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-flash\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_model_catalog_uses_config_only(monkeypatch):\n \"\"\"Picker must not dump live /models — only curated config entries.\"\"\"\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"],\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"load_config\", lambda: cfg)\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.list_model_catalog(\"sk-test\")\n assert [e[\"id\"] for e in catalog] == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n assert settings.list_available_models(\"sk-test\") == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n\n\ndef test_configured_model_catalog_owns_cross_provider_agent_models(monkeypatch):\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.configured_model_catalog(cfg)\n by_id = {e[\"id\"]: e[\"provider\"] for e in catalog}\n assert by_id[\"kimi-k2.7-code\"] == \"moonshot\"\n assert by_id[\"deepseek-v4-flash\"] == \"deepseek\"\n assert by_id[\"deepseek-v4-pro\"] == \"deepseek\"\n\n\ndef test_resolve_llm_route_uses_model_provider_key_and_base_url(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"deepseek\": \"sk-deep\",\n },\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n \"LANGBRIDGE_MODEL\",\n \"LANGBRIDGE_API_BASE_URL\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n moon = settings.resolve_llm_route(\"kimi-k2.7-code\", \"sk-session\")\n assert moon[\"provider\"] == \"moonshot\"\n assert moon[\"api_key\"] == \"sk-moon\"\n assert moon[\"base_url\"] == \"https://api.moonshot.ai/v1\"\n\n deep = settings.resolve_llm_route(\"deepseek-v4-flash\", \"sk-session\")\n assert deep[\"provider\"] == \"deepseek\"\n assert deep[\"api_key\"] == \"sk-deep\"\n assert deep[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_resolve_llm_route_falls_back_to_session_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\"moonshot\": \"sk-moon\"},\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n route = settings.resolve_llm_route(\"deepseek-v4-pro\", \"sk-session-fallback\")\n assert route[\"provider\"] == \"deepseek\"\n assert route[\"api_key\"] == \"sk-session-fallback\"\n assert route[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n"}, "7286c5ebc6535a7e75b7806380e133b3a68a8375": {"t": 1785761306.0858595, "n": 12011, "h": "aa4c3ec84243f5f2", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-pro\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n # Per-agent overrides: explorer runs on the cheaper flash model.\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-pro\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_model_catalog_uses_config_only(monkeypatch):\n \"\"\"Picker must not dump live /models — only curated config entries.\"\"\"\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"],\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"load_config\", lambda: cfg)\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.list_model_catalog(\"sk-test\")\n assert [e[\"id\"] for e in catalog] == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n assert settings.list_available_models(\"sk-test\") == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n\n\ndef test_configured_model_catalog_owns_cross_provider_agent_models(monkeypatch):\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.configured_model_catalog(cfg)\n by_id = {e[\"id\"]: e[\"provider\"] for e in catalog}\n assert by_id[\"kimi-k2.7-code\"] == \"moonshot\"\n assert by_id[\"deepseek-v4-flash\"] == \"deepseek\"\n assert by_id[\"deepseek-v4-pro\"] == \"deepseek\"\n\n\ndef test_resolve_llm_route_uses_model_provider_key_and_base_url(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"deepseek\": \"sk-deep\",\n },\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n \"LANGBRIDGE_MODEL\",\n \"LANGBRIDGE_API_BASE_URL\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n moon = settings.resolve_llm_route(\"kimi-k2.7-code\", \"sk-session\")\n assert moon[\"provider\"] == \"moonshot\"\n assert moon[\"api_key\"] == \"sk-moon\"\n assert moon[\"base_url\"] == \"https://api.moonshot.ai/v1\"\n\n deep = settings.resolve_llm_route(\"deepseek-v4-flash\", \"sk-session\")\n assert deep[\"provider\"] == \"deepseek\"\n assert deep[\"api_key\"] == \"sk-deep\"\n assert deep[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_resolve_llm_route_falls_back_to_session_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\"moonshot\": \"sk-moon\"},\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n route = settings.resolve_llm_route(\"deepseek-v4-pro\", \"sk-session-fallback\")\n assert route[\"provider\"] == \"deepseek\"\n assert route[\"api_key\"] == \"sk-session-fallback\"\n assert route[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n"}, "5930227a3508a50660e12c863268a98db8192450": {"t": 1785761307.6424408, "n": 8016, "h": "c3bc9088cec5421e", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-pro\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n # Per-agent overrides: explorer runs on the cheaper flash model.\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-pro\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_model_catalog_uses_config_only(monkeypatch):\n \"\"\"Picker must not dump live /models — only curated config entries.\"\"\"\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"],\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"load_config\", lambda: cfg)\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.list_model_catalog(\"sk-test\")\n assert [e[\"id\"] for e in catalog] == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n assert settings.list_available_models(\"sk-test\") == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n"}, "42d9d6dd42fc400484bca19522bdf12c54efacbc": {"t": 1785761308.7937374, "n": 7422, "h": "adc8cdb755ef1964", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-pro\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n # Per-agent overrides: explorer runs on the cheaper flash model.\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-pro\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_available_models_falls_back_to_config(monkeypatch):\n monkeypatch.setattr(\n settings,\n \"list_model_catalog\",\n lambda api_key=None, *, provider=None: [{\"id\": \"cfg-model\", \"provider\": \"moonshot\"}],\n )\n assert settings.list_available_models(\"sk-test\") == [\"cfg-model\"]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n"}, "7480a0948c5ee84c9bf48c4b5fe49a122f65e3d2": {"t": 1785761310.3237894, "n": 6309, "h": "77678f90d7061ba8", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-pro\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n # Per-agent overrides: explorer runs on the cheaper flash model.\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-pro\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n"}, "65668e3b3393466837d796c7c88f30019d274812": {"t": 1785761311.4700089, "n": 3529, "h": "eb5cd79934b6abc0", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-pro\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n # Per-agent overrides: explorer runs on the cheaper flash model.\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-pro\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n"}, "7b1d18742467c7a21300296e83d47c61062e9211": {"t": 1785761313.1089683, "n": 1921, "h": "8aefefe629bf8d79", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_legacy_api_key_falls_back_to_active_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api_key\": \"sk-legacy\"}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"moonshot\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-legacy\"\n\n\ndef test_artifacts_dir_defaults_under_package():\n assert settings.ARTIFACTS_DIR == settings.PACKAGE_DIR / \"artifacts\"\n assert settings.RUNS_DIR == settings.PACKAGE_DIR / \"artifacts\"\n"}, "9fa28be8a8b4f3110cca06c16290db27d191148b": {"t": 1785761314.3180928, "n": 1731, "h": "196836be906b41d7", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_legacy_api_key_falls_back_to_active_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api_key\": \"sk-legacy\"}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"moonshot\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-legacy\"\n"}, "f65813daa5645bccbc0b7366ac6914425207fe81": {"t": 1785761315.6885617, "n": 1730, "h": "c81cfe55efcdfd4c", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_cli.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_legacy_api_key_falls_back_to_active_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api_key\": \"sk-legacy\"}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"moonshot\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-legacy\"\n"}, "f95fb230875b8617bc4535e916e1b1c9f08f44c7": {"t": 1786067965.2182372, "n": 12011, "h": "aa4c3ec84243f5f2", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-pro\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n # Per-agent overrides: explorer runs on the cheaper flash model.\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-pro\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_model_catalog_uses_config_only(monkeypatch):\n \"\"\"Picker must not dump live /models — only curated config entries.\"\"\"\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"],\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"load_config\", lambda: cfg)\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.list_model_catalog(\"sk-test\")\n assert [e[\"id\"] for e in catalog] == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n assert settings.list_available_models(\"sk-test\") == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n\n\ndef test_configured_model_catalog_owns_cross_provider_agent_models(monkeypatch):\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.configured_model_catalog(cfg)\n by_id = {e[\"id\"]: e[\"provider\"] for e in catalog}\n assert by_id[\"kimi-k2.7-code\"] == \"moonshot\"\n assert by_id[\"deepseek-v4-flash\"] == \"deepseek\"\n assert by_id[\"deepseek-v4-pro\"] == \"deepseek\"\n\n\ndef test_resolve_llm_route_uses_model_provider_key_and_base_url(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"deepseek\": \"sk-deep\",\n },\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n \"LANGBRIDGE_MODEL\",\n \"LANGBRIDGE_API_BASE_URL\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n moon = settings.resolve_llm_route(\"kimi-k2.7-code\", \"sk-session\")\n assert moon[\"provider\"] == \"moonshot\"\n assert moon[\"api_key\"] == \"sk-moon\"\n assert moon[\"base_url\"] == \"https://api.moonshot.ai/v1\"\n\n deep = settings.resolve_llm_route(\"deepseek-v4-flash\", \"sk-session\")\n assert deep[\"provider\"] == \"deepseek\"\n assert deep[\"api_key\"] == \"sk-deep\"\n assert deep[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_resolve_llm_route_falls_back_to_session_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\"moonshot\": \"sk-moon\"},\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n route = settings.resolve_llm_route(\"deepseek-v4-pro\", \"sk-session-fallback\")\n assert route[\"provider\"] == \"deepseek\"\n assert route[\"api_key\"] == \"sk-session-fallback\"\n assert route[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n"}, "be3d4d77ae9f07b61242d056228f9edad6c271b2": {"t": 1786068522.5265028, "n": 11942, "h": "e19a22bf6022817a", "c": "import json\nfrom pathlib import Path\n\nimport langbridge_code.settings as settings\n\n\ndef test_load_api_key_uses_provider_specific_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"openai\": \"sk-openai\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n monkeypatch.delenv(\"OPENAI_API_KEY\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-moon\"\n assert settings.load_api_key(\"openai\") == \"sk-openai\"\n\n\ndef test_load_api_key_prefers_env_for_matching_provider(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"OPENAI_API_KEY\", \"sk-env-openai\")\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"openai\") == \"sk-env-openai\"\n\n\ndef test_load_api_key_uses_deepseek_env(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setenv(\"DEEPSEEK_API_KEY\", \"sk-env-deepseek\")\n\n assert settings.load_api_key(\"deepseek\") == \"sk-env-deepseek\"\n\n\ndef test_sanitize_api_key_strips_terminal_escape_junk():\n junk = \"\\x1b[<0;21;23M\\x1b[<0;21;23Msk-real-key\"\n assert settings.sanitize_api_key(junk) == \"sk-real-key\"\n assert settings.sanitize_api_key(\" sk-clean \") == \"sk-clean\"\n assert settings.sanitize_api_key(\"\\x1b[<0;1;2M\") is None\n assert settings.sanitize_api_key(\"\") is None\n assert settings.sanitize_api_key(None) is None\n\n\ndef test_load_api_key_strips_escape_junk_from_config(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api_keys\": {\n \"moonshot\": \"\\x1b[<0;21;23Msk-clean-moon\",\n }\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"MOONSHOT_API_KEY\", raising=False)\n monkeypatch.delenv(\"KIMI_API_KEY\", raising=False)\n\n assert settings.load_api_key(\"moonshot\") == \"sk-clean-moon\"\n\n\ndef test_save_api_key_persists_sanitized_value(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n\n settings.save_api_key(\"\\x1b[<0;21;23Msk-saved\", \"moonshot\")\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-saved\"\n\n\ndef test_prompt_and_save_api_key_retries_until_valid(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: True)\n answers = iter([\"bad-key\", \"sk-good\"])\n monkeypatch.setattr(settings.getpass, \"getpass\", lambda _prompt: next(answers))\n attempts = {\"n\": 0}\n\n def fake_validate(api_key, *, provider=None):\n attempts[\"n\"] += 1\n if api_key == \"sk-good\":\n return True, \"ok\"\n return False, \"401 unauthorized\"\n\n monkeypatch.setattr(settings, \"validate_api_key\", fake_validate)\n\n assert settings._prompt_and_save_api_key(\"moonshot\") == \"sk-good\"\n assert attempts[\"n\"] == 2\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"api_keys\"][\"moonshot\"] == \"sk-good\"\n\n\ndef test_prompt_and_save_api_key_non_interactive_errors(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n try:\n settings._prompt_and_save_api_key(\"moonshot\")\n raise AssertionError(\"expected ValueError\")\n except ValueError as error:\n assert \"No Moonshot/Kimi API key\" in str(error)\n\n\ndef test_provider_binding_resolves_deepseek_defaults(monkeypatch, tmp_path):\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", tmp_path / \"missing.json\")\n monkeypatch.setenv(\"LANGBRIDGE_API_PROVIDER\", \"deepseek\")\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n monkeypatch.delenv(\"LANGBRIDGE_API_BASE_URL\", raising=False)\n try:\n settings._bind(settings.load_config())\n assert settings.API_PROVIDER == \"deepseek\"\n assert settings.DEFAULT_MODEL == \"deepseek-v4-flash\"\n assert settings.API_BASE_URL == \"https://api.deepseek.com\"\n assert settings.model_for_agent(\"explorer\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\") == \"deepseek-v4-flash\"\n assert settings.model_for_agent(\"worker\", \"custom-model\") == \"custom-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_choose_api_provider_uses_saved_choice(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(json.dumps({\"api\": {\"provider\": \"deepseek\"}}), encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n\n assert settings.choose_api_provider() == \"deepseek\"\n\n\ndef test_choose_api_provider_non_interactive_falls_back(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"missing.json\"\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_API_PROVIDER\", raising=False)\n monkeypatch.setattr(settings.sys.stdin, \"isatty\", lambda: False)\n\n assert settings.choose_api_provider() == settings.active_api_provider()\n\n\ndef test_artifacts_dir_defaults_under_install_root_per_project():\n expected = settings.INSTALL_ROOT / \"artifacts\" / settings.WORKSPACE_ROOT.name\n assert settings.ARTIFACTS_DIR == expected\n\n\ndef test_set_default_model_persists(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\"{}\", encoding=\"utf-8\")\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n monkeypatch.delenv(\"LANGBRIDGE_MODEL\", raising=False)\n try:\n assert settings.set_default_model(\"picked-model\") == \"picked-model\"\n saved = json.loads(user_cfg.read_text(encoding=\"utf-8\"))\n assert saved[\"model\"] == \"picked-model\"\n assert settings.DEFAULT_MODEL == \"picked-model\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_list_model_catalog_uses_config_only(monkeypatch):\n \"\"\"Picker must not dump live /models — only curated config entries.\"\"\"\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"models\": [\"kimi-k3\"],\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"load_config\", lambda: cfg)\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.list_model_catalog(\"sk-test\")\n assert [e[\"id\"] for e in catalog] == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n assert settings.list_available_models(\"sk-test\") == [\n \"kimi-k2.7-code\",\n \"kimi-k3\",\n \"deepseek-v4-pro\",\n ]\n\n\ndef test_infer_provider_for_kimi_k3():\n assert settings.infer_provider_for_model(\"kimi-k3\") == \"moonshot\"\n assert settings.infer_provider_for_model(\"deepseek-v4-pro\") == \"deepseek\"\n\n\ndef test_configured_model_catalog_owns_cross_provider_agent_models(monkeypatch):\n cfg = {\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\"model\": \"deepseek-v4-pro\"},\n },\n }\n }\n monkeypatch.setattr(settings, \"active_api_provider\", lambda: \"moonshot\")\n catalog = settings.configured_model_catalog(cfg)\n by_id = {e[\"id\"]: e[\"provider\"] for e in catalog}\n assert by_id[\"kimi-k2.7-code\"] == \"moonshot\"\n assert by_id[\"deepseek-v4-flash\"] == \"deepseek\"\n assert by_id[\"deepseek-v4-pro\"] == \"deepseek\"\n\n\ndef test_resolve_llm_route_uses_model_provider_key_and_base_url(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n \"agent_models\": {\"explorer\": \"deepseek-v4-flash\"},\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\n \"moonshot\": \"sk-moon\",\n \"deepseek\": \"sk-deep\",\n },\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n \"LANGBRIDGE_MODEL\",\n \"LANGBRIDGE_API_BASE_URL\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n moon = settings.resolve_llm_route(\"kimi-k2.7-code\", \"sk-session\")\n assert moon[\"provider\"] == \"moonshot\"\n assert moon[\"api_key\"] == \"sk-moon\"\n assert moon[\"base_url\"] == \"https://api.moonshot.ai/v1\"\n\n deep = settings.resolve_llm_route(\"deepseek-v4-flash\", \"sk-session\")\n assert deep[\"provider\"] == \"deepseek\"\n assert deep[\"api_key\"] == \"sk-deep\"\n assert deep[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n\n\ndef test_resolve_llm_route_falls_back_to_session_key(monkeypatch, tmp_path):\n user_cfg = tmp_path / \"config.json\"\n user_cfg.write_text(\n json.dumps({\n \"api\": {\n \"provider\": \"moonshot\",\n \"providers\": {\n \"moonshot\": {\n \"base_url\": \"https://api.moonshot.ai/v1\",\n \"model\": \"kimi-k2.7-code\",\n },\n \"deepseek\": {\n \"base_url\": \"https://api.deepseek.com\",\n \"model\": \"deepseek-v4-pro\",\n },\n },\n },\n \"api_keys\": {\"moonshot\": \"sk-moon\"},\n }),\n encoding=\"utf-8\",\n )\n monkeypatch.setattr(settings, \"USER_CONFIG_PATH\", user_cfg)\n for key in (\n \"MOONSHOT_API_KEY\",\n \"KIMI_API_KEY\",\n \"DEEPSEEK_API_KEY\",\n \"OPENAI_API_KEY\",\n \"LANGBRIDGE_API_PROVIDER\",\n ):\n monkeypatch.delenv(key, raising=False)\n try:\n settings._bind(settings.load_config())\n route = settings.resolve_llm_route(\"deepseek-v4-pro\", \"sk-session-fallback\")\n assert route[\"provider\"] == \"deepseek\"\n assert route[\"api_key\"] == \"sk-session-fallback\"\n assert route[\"base_url\"] == \"https://api.deepseek.com\"\n finally:\n monkeypatch.undo()\n settings._bind(settings.load_config())\n"}}}}