algo-cli-runtime 0.14.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (237) hide show
  1. algo_cli/__init__.py +3 -0
  2. algo_cli/__main__.py +7 -0
  3. algo_cli/_internal/__init__.py +12 -0
  4. algo_cli/_internal/policy_chain.py +259 -0
  5. algo_cli/action_registry.py +1047 -0
  6. algo_cli/agent_blocks.py +550 -0
  7. algo_cli/agent_pipeline.py +1457 -0
  8. algo_cli/agent_threads.py +308 -0
  9. algo_cli/animations.py +316 -0
  10. algo_cli/cache_admission.py +209 -0
  11. algo_cli/capability_mask.py +66 -0
  12. algo_cli/chat_protocol.py +116 -0
  13. algo_cli/chatgpt_auth.py +510 -0
  14. algo_cli/chatgpt_client.py +657 -0
  15. algo_cli/code_rag.py +479 -0
  16. algo_cli/config.py +651 -0
  17. algo_cli/context_budget.py +679 -0
  18. algo_cli/credential_helpers.py +315 -0
  19. algo_cli/deliberation.py +29 -0
  20. algo_cli/display.py +1470 -0
  21. algo_cli/evals/__init__.py +21 -0
  22. algo_cli/evals/algorithm_effectiveness.py +560 -0
  23. algo_cli/evals/competitive_harness_rating.py +702 -0
  24. algo_cli/evals/cot_quality.py +220 -0
  25. algo_cli/evals/harness_retrieval_benchmark.py +401 -0
  26. algo_cli/evals/performance_regression.py +136 -0
  27. algo_cli/evals/scorecard_grading.py +308 -0
  28. algo_cli/evals/session_distribution.py +84 -0
  29. algo_cli/execution_guardrails.py +806 -0
  30. algo_cli/extensions_manifest.py +84 -0
  31. algo_cli/git_evidence.py +227 -0
  32. algo_cli/google_workspace.py +407 -0
  33. algo_cli/google_workspace_auth.py +523 -0
  34. algo_cli/harness.py +2587 -0
  35. algo_cli/identity.py +557 -0
  36. algo_cli/index_compute_lab.py +228 -0
  37. algo_cli/inference_harness.py +70 -0
  38. algo_cli/intelligence/__init__.py +1103 -0
  39. algo_cli/intelligence/acrobat_config.py +307 -0
  40. algo_cli/intelligence/acrobat_manifests.py +338 -0
  41. algo_cli/intelligence/acrobat_models.py +195 -0
  42. algo_cli/intelligence/acrobat_pipeline.py +295 -0
  43. algo_cli/intelligence/acrobat_runtime.py +302 -0
  44. algo_cli/intelligence/acrobat_security.py +261 -0
  45. algo_cli/intelligence/acrobat_workflows.py +226 -0
  46. algo_cli/intelligence/actionability.py +165 -0
  47. algo_cli/intelligence/adversarial_audit.py +136 -0
  48. algo_cli/intelligence/agent_arena.py +92 -0
  49. algo_cli/intelligence/agent_benchmark.py +236 -0
  50. algo_cli/intelligence/agent_runtime.py +171 -0
  51. algo_cli/intelligence/agents_as_tools.py +70 -0
  52. algo_cli/intelligence/artifact_binding.py +80 -0
  53. algo_cli/intelligence/autonomous_engineer.py +1976 -0
  54. algo_cli/intelligence/backpressure.py +99 -0
  55. algo_cli/intelligence/bloom_filter.py +186 -0
  56. algo_cli/intelligence/bonferroni.py +66 -0
  57. algo_cli/intelligence/boundary_compaction.py +98 -0
  58. algo_cli/intelligence/catalog_verifier.py +172 -0
  59. algo_cli/intelligence/cavecrew.py +118 -0
  60. algo_cli/intelligence/changelog.py +176 -0
  61. algo_cli/intelligence/checkpoint_resume.py +92 -0
  62. algo_cli/intelligence/circuit_breaker.py +88 -0
  63. algo_cli/intelligence/clarification_gate.py +101 -0
  64. algo_cli/intelligence/code_graph.py +180 -0
  65. algo_cli/intelligence/coderank.py +97 -0
  66. algo_cli/intelligence/consistent_hash.py +150 -0
  67. algo_cli/intelligence/consortium_synthesis.py +139 -0
  68. algo_cli/intelligence/construction/__init__.py +241 -0
  69. algo_cli/intelligence/construction/common.py +273 -0
  70. algo_cli/intelligence/construction/documents.py +496 -0
  71. algo_cli/intelligence/construction/labor_units.py +1395 -0
  72. algo_cli/intelligence/construction/payments.py +470 -0
  73. algo_cli/intelligence/construction/risk.py +784 -0
  74. algo_cli/intelligence/content_extractor.py +132 -0
  75. algo_cli/intelligence/context_adaptive.py +102 -0
  76. algo_cli/intelligence/context_ops.py +95 -0
  77. algo_cli/intelligence/count_min.py +145 -0
  78. algo_cli/intelligence/cow_state.py +103 -0
  79. algo_cli/intelligence/critic_loop.py +119 -0
  80. algo_cli/intelligence/cross_source.py +113 -0
  81. algo_cli/intelligence/daemon_mode.py +99 -0
  82. algo_cli/intelligence/dag_orchestration.py +151 -0
  83. algo_cli/intelligence/deep_research.py +155 -0
  84. algo_cli/intelligence/degenerate_detector.py +78 -0
  85. algo_cli/intelligence/delta_report.py +92 -0
  86. algo_cli/intelligence/discovery_event_log.py +92 -0
  87. algo_cli/intelligence/document_ingest.py +298 -0
  88. algo_cli/intelligence/dual_layer_validate.py +151 -0
  89. algo_cli/intelligence/echo_fidelity.py +73 -0
  90. algo_cli/intelligence/ema_tuning.py +104 -0
  91. algo_cli/intelligence/event_log.py +92 -0
  92. algo_cli/intelligence/evidence_graph.py +114 -0
  93. algo_cli/intelligence/extension_host.py +162 -0
  94. algo_cli/intelligence/extension_manifest.py +115 -0
  95. algo_cli/intelligence/falsification_suite.py +178 -0
  96. algo_cli/intelligence/finance/__init__.py +169 -0
  97. algo_cli/intelligence/finance/anomalies.py +135 -0
  98. algo_cli/intelligence/finance/ap_ar.py +351 -0
  99. algo_cli/intelligence/finance/cash.py +162 -0
  100. algo_cli/intelligence/finance/close.py +332 -0
  101. algo_cli/intelligence/finance/common.py +244 -0
  102. algo_cli/intelligence/finance/construction.py +135 -0
  103. algo_cli/intelligence/finance/controls.py +172 -0
  104. algo_cli/intelligence/finance/evidence.py +119 -0
  105. algo_cli/intelligence/finance/exceptions.py +157 -0
  106. algo_cli/intelligence/finance/reconciliations.py +254 -0
  107. algo_cli/intelligence/finance/revenue.py +109 -0
  108. algo_cli/intelligence/finance/tax.py +74 -0
  109. algo_cli/intelligence/finance/workpapers.py +111 -0
  110. algo_cli/intelligence/finding_record.py +120 -0
  111. algo_cli/intelligence/flow_dag.py +267 -0
  112. algo_cli/intelligence/gatherer.py +223 -0
  113. algo_cli/intelligence/golden_master.py +98 -0
  114. algo_cli/intelligence/graph_rag.py +195 -0
  115. algo_cli/intelligence/group_chat.py +143 -0
  116. algo_cli/intelligence/hash_dedup.py +145 -0
  117. algo_cli/intelligence/hyperloglog.py +128 -0
  118. algo_cli/intelligence/incremental_index.py +316 -0
  119. algo_cli/intelligence/index_store.py +16 -0
  120. algo_cli/intelligence/iteration_plan.py +133 -0
  121. algo_cli/intelligence/kernel_plugins.py +167 -0
  122. algo_cli/intelligence/lesson_catalog.py +135 -0
  123. algo_cli/intelligence/llm_fallback.py +169 -0
  124. algo_cli/intelligence/log2_histogram.py +267 -0
  125. algo_cli/intelligence/lsp_integration.py +147 -0
  126. algo_cli/intelligence/memory_evolution.py +117 -0
  127. algo_cli/intelligence/minhash_lsh.py +182 -0
  128. algo_cli/intelligence/multi_model_score.py +174 -0
  129. algo_cli/intelligence/multi_tier_grade.py +211 -0
  130. algo_cli/intelligence/negative_controls.py +113 -0
  131. algo_cli/intelligence/numeric_clamp.py +63 -0
  132. algo_cli/intelligence/occ_editor.py +66 -0
  133. algo_cli/intelligence/output_normalize.py +112 -0
  134. algo_cli/intelligence/parallel_delegation.py +98 -0
  135. algo_cli/intelligence/parallel_fanout.py +104 -0
  136. algo_cli/intelligence/permission_modes.py +105 -0
  137. algo_cli/intelligence/pre_push_gate.py +68 -0
  138. algo_cli/intelligence/prefetch.py +171 -0
  139. algo_cli/intelligence/process_framework.py +217 -0
  140. algo_cli/intelligence/project_graph.py +387 -0
  141. algo_cli/intelligence/query_expansion.py +146 -0
  142. algo_cli/intelligence/ralph_loop.py +117 -0
  143. algo_cli/intelligence/rate_limiter.py +153 -0
  144. algo_cli/intelligence/refactor_transaction.py +94 -0
  145. algo_cli/intelligence/research_workspace.py +108 -0
  146. algo_cli/intelligence/retraction_ledger.py +72 -0
  147. algo_cli/intelligence/saga_pattern.py +88 -0
  148. algo_cli/intelligence/session_fork.py +100 -0
  149. algo_cli/intelligence/shadow_editor.py +67 -0
  150. algo_cli/intelligence/shell_session.py +213 -0
  151. algo_cli/intelligence/source_registry.py +143 -0
  152. algo_cli/intelligence/spawn_scales.py +99 -0
  153. algo_cli/intelligence/stat_stability.py +104 -0
  154. algo_cli/intelligence/structural_validator.py +148 -0
  155. algo_cli/intelligence/subagent_spawner.py +111 -0
  156. algo_cli/intelligence/symmetric_verify.py +70 -0
  157. algo_cli/intelligence/task_classifier.py +129 -0
  158. algo_cli/intelligence/team_execution.py +122 -0
  159. algo_cli/intelligence/tiered_access.py +121 -0
  160. algo_cli/intelligence/utility_registry.py +159 -0
  161. algo_cli/intuition_engine.py +560 -0
  162. algo_cli/intuition_injector.py +82 -0
  163. algo_cli/kernels/__init__.py +5 -0
  164. algo_cli/kernels/manifest.py +763 -0
  165. algo_cli/main.py +3903 -0
  166. algo_cli/memory_candidates.py +541 -0
  167. algo_cli/memory_echo_veil.py +394 -0
  168. algo_cli/memory_runtime.py +112 -0
  169. algo_cli/model_info.py +548 -0
  170. algo_cli/model_profile.py +160 -0
  171. algo_cli/model_routing.py +74 -0
  172. algo_cli/oneshot.py +331 -0
  173. algo_cli/perf_telemetry.py +389 -0
  174. algo_cli/plugins.py +245 -0
  175. algo_cli/private_event_store.py +654 -0
  176. algo_cli/quantization/__init__.py +24 -0
  177. algo_cli/quantization/lloyd_max.py +98 -0
  178. algo_cli/quantization/turbo_quant.py +308 -0
  179. algo_cli/reasoning/__init__.py +46 -0
  180. algo_cli/reasoning/combinatorial.py +356 -0
  181. algo_cli/reasoning/graph_of_thought.py +297 -0
  182. algo_cli/reasoning/mcts.py +220 -0
  183. algo_cli/reasoning/neuro_symbolic.py +250 -0
  184. algo_cli/reasoning/react.py +246 -0
  185. algo_cli/reasoning/reflexion.py +225 -0
  186. algo_cli/reasoning/tree_of_thought.py +241 -0
  187. algo_cli/reasoning_bridge.py +150 -0
  188. algo_cli/reconciliation.py +284 -0
  189. algo_cli/reflex.py +385 -0
  190. algo_cli/resources/docs/ALGO.md +13958 -0
  191. algo_cli/resources/docs/algo-cli-algorithm-evidence-contract.md +60 -0
  192. algo_cli/resources/docs/algo-cli-execution-verification-contract.md +59 -0
  193. algo_cli/resources/docs/algo-cli-memory-lifecycle-contract.md +72 -0
  194. algo_cli/resources/docs/harness-extension-cleanup-recommendation.md +41 -0
  195. algo_cli/resources/docs/index-compute-lab-integration.md +32 -0
  196. algo_cli/resources/docs/inference-harness-loop-blueprint-2026-06.md +55 -0
  197. algo_cli/resources/docs/main-split-map.md +35 -0
  198. algo_cli/resources/docs/privacy-and-context.md +48 -0
  199. algo_cli/resources/docs/reflex-loop-v0.2.md +354 -0
  200. algo_cli/resources/skills/README.md +26 -0
  201. algo_cli/resources/skills/algo-cli.md +59 -0
  202. algo_cli/resources/skills/edit-file-precision.md +49 -0
  203. algo_cli/resources/skills/harness-search-first.md +47 -0
  204. algo_cli/resources/skills/memory-recall-ritual.md +51 -0
  205. algo_cli/resources/skills/qol-algorithms.md +224 -0
  206. algo_cli/resources/skills/smart-error-recovery.md +56 -0
  207. algo_cli/resources/skills/tool-selection-cheatsheet.md +65 -0
  208. algo_cli/retrieval_algorithms.py +127 -0
  209. algo_cli/runtime_qos.py +236 -0
  210. algo_cli/runtime_services.py +320 -0
  211. algo_cli/session_commands.py +95 -0
  212. algo_cli/session_mode.py +113 -0
  213. algo_cli/skills.py +430 -0
  214. algo_cli/slash_dispatch.py +1265 -0
  215. algo_cli/small_context.py +206 -0
  216. algo_cli/spawn_budget.py +89 -0
  217. algo_cli/task_ledger.py +84 -0
  218. algo_cli/task_router.py +197 -0
  219. algo_cli/tool_context.py +94 -0
  220. algo_cli/tool_contract.py +99 -0
  221. algo_cli/tool_policy.py +357 -0
  222. algo_cli/tool_runtime.py +647 -0
  223. algo_cli/tools.py +3056 -0
  224. algo_cli/url_scheme.py +174 -0
  225. algo_cli/verify.py +154 -0
  226. algo_cli/version_manifest.py +178 -0
  227. algo_cli/vision_screenshot_verify.py +76 -0
  228. algo_cli/workspace_resolver.py +68 -0
  229. algo_cli/x_account.py +209 -0
  230. algo_cli/xai_auth.py +374 -0
  231. algo_cli/xai_client.py +600 -0
  232. algo_cli_runtime-0.14.0.dist-info/METADATA +369 -0
  233. algo_cli_runtime-0.14.0.dist-info/RECORD +237 -0
  234. algo_cli_runtime-0.14.0.dist-info/WHEEL +4 -0
  235. algo_cli_runtime-0.14.0.dist-info/entry_points.txt +3 -0
  236. algo_cli_runtime-0.14.0.dist-info/licenses/LICENSE +21 -0
  237. ollama_cli/__init__.py +67 -0
@@ -0,0 +1,315 @@
1
+ """Credential helper interface for Algo CLI.
2
+
3
+ Provides a standard get/store/erase interface for credential backends,
4
+ inspired by Docker's docker-credential-<name> pattern.
5
+
6
+ Each credential helper is a Python class that implements:
7
+ - get(key: str) -> str | None
8
+ - store(key: str, value: str) -> None
9
+ - erase(key: str) -> None
10
+ - list_keys() -> list[str]
11
+
12
+ Built-in helpers:
13
+ - ollama-cloud (OLLAMA_API_KEY)
14
+ - xai-oauth (xAI OAuth tokens)
15
+ - google-workspace (Google Workspace OAuth tokens)
16
+ - github-token (GitHub API token)
17
+ - env (fallback: read from environment variables)
18
+
19
+ Custom helpers can be registered at runtime or discovered from
20
+ ~/.algo_cli/credentials/ as Python modules with a create_helper() function.
21
+ """
22
+ from __future__ import annotations
23
+
24
+ import abc
25
+ import json
26
+ import logging
27
+ import os
28
+ from pathlib import Path
29
+ from typing import Any
30
+
31
+ from .config import CONFIG_DIR, _atomic_write_text
32
+
33
+ logger = logging.getLogger(__name__)
34
+
35
+ CREDENTIALS_DIR = CONFIG_DIR / "credentials"
36
+
37
+
38
+ class CredentialHelper(abc.ABC):
39
+ """Abstract base class for credential helpers."""
40
+
41
+ @property
42
+ @abc.abstractmethod
43
+ def name(self) -> str:
44
+ """Helper identifier (e.g. 'ollama-cloud')."""
45
+ ...
46
+
47
+ @property
48
+ def description(self) -> str:
49
+ """Short safe description for list/status UIs."""
50
+ doc = type(self).__doc__ or "Credential helper"
51
+ return " ".join(doc.strip().splitlines()[:1])
52
+
53
+ @abc.abstractmethod
54
+ def get(self, key: str) -> str | None:
55
+ """Retrieve a credential value by key. Returns None if not found."""
56
+ ...
57
+
58
+ @abc.abstractmethod
59
+ def store(self, key: str, value: str) -> None:
60
+ """Store a credential value."""
61
+ ...
62
+
63
+ @abc.abstractmethod
64
+ def erase(self, key: str) -> None:
65
+ """Delete a credential by key."""
66
+ ...
67
+
68
+ @abc.abstractmethod
69
+ def list_keys(self) -> list[str]:
70
+ """List all stored credential keys."""
71
+ ...
72
+
73
+
74
+ class EnvCredentialHelper(CredentialHelper):
75
+ """Fallback helper that reads from environment variables."""
76
+
77
+ @property
78
+ def name(self) -> str:
79
+ return "env"
80
+
81
+ def get(self, key: str) -> str | None:
82
+ return os.environ.get(key)
83
+
84
+ def store(self, key: str, value: str) -> None:
85
+ os.environ[key] = value
86
+
87
+ def erase(self, key: str) -> None:
88
+ os.environ.pop(key, None)
89
+
90
+ def list_keys(self) -> list[str]:
91
+ # Can't meaningfully list env vars as credential keys
92
+ return []
93
+
94
+
95
+ class FileCredentialHelper(CredentialHelper):
96
+ """File-based credential helper storing JSON in ~/.algo_cli/credentials/.
97
+
98
+ Each helper gets its own JSON file: <name>.json
99
+ Credentials are stored as {key: value} pairs.
100
+ """
101
+
102
+ def __init__(self, helper_name: str, base_dir: Path | None = None):
103
+ self._name = helper_name
104
+ self._base_dir = base_dir or CREDENTIALS_DIR
105
+ self._file = self._base_dir / f"{helper_name}.json"
106
+
107
+ @property
108
+ def name(self) -> str:
109
+ return self._name
110
+
111
+ def _load(self) -> dict[str, str]:
112
+ try:
113
+ return json.loads(self._file.read_text(encoding="utf-8"))
114
+ except (FileNotFoundError, json.JSONDecodeError):
115
+ return {}
116
+
117
+ def _save(self, data: dict[str, str]) -> None:
118
+ self._base_dir.mkdir(parents=True, exist_ok=True)
119
+ _atomic_write_text(self._file, json.dumps(data, indent=2))
120
+
121
+ def get(self, key: str) -> str | None:
122
+ return self._load().get(key)
123
+
124
+ def store(self, key: str, value: str) -> None:
125
+ data = self._load()
126
+ data[key] = value
127
+ self._save(data)
128
+
129
+ def erase(self, key: str) -> None:
130
+ data = self._load()
131
+ data.pop(key, None)
132
+ self._save(data)
133
+
134
+ def list_keys(self) -> list[str]:
135
+ return list(self._load().keys())
136
+
137
+
138
+ class OllamaCloudCredentialHelper(CredentialHelper):
139
+ """Credential helper for OLLAMA_API_KEY.
140
+
141
+ Reads from environment first, falls back to the runtime env file,
142
+ then to the file-based credential store.
143
+ """
144
+
145
+ def __init__(self, file_helper: FileCredentialHelper | None = None):
146
+ self._file_helper = file_helper or FileCredentialHelper("ollama-cloud")
147
+
148
+ @property
149
+ def name(self) -> str:
150
+ return "ollama-cloud"
151
+
152
+ def get(self, key: str) -> str | None:
153
+ if key == "OLLAMA_API_KEY":
154
+ # Check env first
155
+ val = os.environ.get("OLLAMA_API_KEY", "").strip()
156
+ if val:
157
+ return val
158
+ # Check runtime env file
159
+ try:
160
+ from .config import load_runtime_env
161
+ load_runtime_env(override=True)
162
+ val = os.environ.get("OLLAMA_API_KEY", "").strip()
163
+ if val:
164
+ return val
165
+ except Exception:
166
+ pass
167
+ # Fall back to file store
168
+ return self._file_helper.get(key)
169
+ return self._file_helper.get(key)
170
+
171
+ def store(self, key: str, value: str) -> None:
172
+ self._file_helper.store(key, value)
173
+
174
+ def erase(self, key: str) -> None:
175
+ self._file_helper.erase(key)
176
+
177
+ def list_keys(self) -> list[str]:
178
+ return self._file_helper.list_keys()
179
+
180
+
181
+ class XAIOAuthCredentialHelper(CredentialHelper):
182
+ """Credential helper for xAI OAuth tokens.
183
+
184
+ Delegates to the existing xai_auth.json file, providing a standard
185
+ interface while keeping backward compatibility.
186
+ """
187
+
188
+ def __init__(self):
189
+ self._auth_file = CONFIG_DIR / "xai_auth.json"
190
+
191
+ @property
192
+ def name(self) -> str:
193
+ return "xai-oauth"
194
+
195
+ def _load(self) -> dict[str, Any]:
196
+ try:
197
+ return json.loads(self._auth_file.read_text(encoding="utf-8"))
198
+ except (FileNotFoundError, json.JSONDecodeError):
199
+ return {}
200
+
201
+ def get(self, key: str) -> str | None:
202
+ data = self._load()
203
+ return data.get(key)
204
+
205
+ def store(self, key: str, value: str) -> None:
206
+ data = self._load()
207
+ data[key] = value
208
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
209
+ _atomic_write_text(self._auth_file, json.dumps(data, indent=2))
210
+
211
+ def erase(self, key: str) -> None:
212
+ data = self._load()
213
+ data.pop(key, None)
214
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
215
+ _atomic_write_text(self._auth_file, json.dumps(data, indent=2))
216
+
217
+ def list_keys(self) -> list[str]:
218
+ return list(self._load().keys())
219
+
220
+
221
+ class GoogleWorkspaceCredentialHelper(CredentialHelper):
222
+ """Credential helper for Google Workspace OAuth tokens.
223
+
224
+ Delegates to the existing google_workspace token file.
225
+ """
226
+
227
+ def __init__(self):
228
+ self._auth_file = CONFIG_DIR / "google_workspace_tokens.json"
229
+
230
+ @property
231
+ def name(self) -> str:
232
+ return "google-workspace"
233
+
234
+ def _load(self) -> dict[str, Any]:
235
+ try:
236
+ return json.loads(self._auth_file.read_text(encoding="utf-8"))
237
+ except (FileNotFoundError, json.JSONDecodeError):
238
+ return {}
239
+
240
+ def get(self, key: str) -> str | None:
241
+ return self._load().get(key)
242
+
243
+ def store(self, key: str, value: str) -> None:
244
+ data = self._load()
245
+ data[key] = value
246
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
247
+ _atomic_write_text(self._auth_file, json.dumps(data, indent=2))
248
+
249
+ def erase(self, key: str) -> None:
250
+ data = self._load()
251
+ data.pop(key, None)
252
+ CONFIG_DIR.mkdir(parents=True, exist_ok=True)
253
+ _atomic_write_text(self._auth_file, json.dumps(data, indent=2))
254
+
255
+ def list_keys(self) -> list[str]:
256
+ return list(self._load().keys())
257
+
258
+
259
+ # --- Registry ---
260
+
261
+ _REGISTRY: dict[str, CredentialHelper] = {}
262
+
263
+
264
+ def register_helper(helper: CredentialHelper) -> None:
265
+ """Register a credential helper."""
266
+ _REGISTRY[helper.name] = helper
267
+
268
+
269
+ def get_helper(name: str) -> CredentialHelper | None:
270
+ """Get a registered credential helper by name."""
271
+ return _REGISTRY.get(name)
272
+
273
+
274
+ def list_helpers() -> list[str]:
275
+ """List all registered credential helper names."""
276
+ return sorted(_REGISTRY.keys())
277
+
278
+
279
+ def get_credential(helper_name: str, key: str) -> str | None:
280
+ """Convenience: get a credential via a named helper."""
281
+ helper = get_helper(helper_name)
282
+ if helper is None:
283
+ return None
284
+ return helper.get(key)
285
+
286
+
287
+ def store_credential(helper_name: str, key: str, value: str) -> bool:
288
+ """Convenience: store a credential via a named helper. Returns False if helper not found."""
289
+ helper = get_helper(helper_name)
290
+ if helper is None:
291
+ return False
292
+ helper.store(key, value)
293
+ return True
294
+
295
+
296
+ def erase_credential(helper_name: str, key: str) -> bool:
297
+ """Convenience: erase a credential via a named helper. Returns False if helper not found."""
298
+ helper = get_helper(helper_name)
299
+ if helper is None:
300
+ return False
301
+ helper.erase(key)
302
+ return True
303
+
304
+
305
+ def _init_default_helpers() -> None:
306
+ """Register built-in credential helpers."""
307
+ register_helper(EnvCredentialHelper())
308
+ register_helper(FileCredentialHelper("github-token"))
309
+ register_helper(OllamaCloudCredentialHelper())
310
+ register_helper(XAIOAuthCredentialHelper())
311
+ register_helper(GoogleWorkspaceCredentialHelper())
312
+
313
+
314
+ # Initialize on import
315
+ _init_default_helpers()
@@ -0,0 +1,29 @@
1
+ """Adaptive deliberation policy for non-interactive runs."""
2
+
3
+ from __future__ import annotations
4
+
5
+
6
+ _DEEP_CUES = (
7
+ "deep analysis",
8
+ "architecture decision",
9
+ "architectural tradeoff",
10
+ "security audit",
11
+ "threat model",
12
+ "formal proof",
13
+ "prove that",
14
+ "root cause analysis",
15
+ "compare strategies",
16
+ "evaluate alternatives",
17
+ "multi-system",
18
+ "ambiguous requirements",
19
+ )
20
+
21
+
22
+ def needs_deliberation(prompt: str) -> bool:
23
+ """Enable model reasoning only when a one-shot task signals depth."""
24
+
25
+ lowered = (prompt or "").casefold()
26
+ return any(cue in lowered for cue in _DEEP_CUES)
27
+
28
+
29
+ __all__ = ["needs_deliberation"]