arkaos 2.76.0 → 2.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.76.0
1
+ 2.77.0
@@ -76,10 +76,16 @@ class CodexCliAdapter(RuntimeAdapter):
76
76
  raise NotImplementedError("Use Codex CLI's native content search")
77
77
 
78
78
  def headless_supported(self) -> bool:
79
- # Codex CLI headless invocation syntax is not stable as of
80
- # 2026-04-20. Until verified, we surface unsupported and let
81
- # SubagentProvider fall back to AnthropicDirect or stub.
82
- return False
79
+ # Auto-detect: headless is supported iff the `codex` binary is
80
+ # on PATH. When the operator installs Codex CLI later, this
81
+ # lights up without any code change (the headless_complete()
82
+ # method below already gates on shutil.which() too, so a missing
83
+ # binary will raise cleanly).
84
+ #
85
+ # Note: even when the binary is present, headless_complete()
86
+ # still raises until the invocation syntax is verified locally.
87
+ # See TODO(llm-agnostic) below for the verification checklist.
88
+ return shutil.which("codex") is not None
83
89
 
84
90
  def headless_complete(
85
91
  self,
@@ -96,14 +102,15 @@ class CodexCliAdapter(RuntimeAdapter):
96
102
  )
97
103
  # TODO(llm-agnostic): Implement real headless completion.
98
104
  #
99
- # Status as of 2026-04-20: Codex CLI is NOT installed on the
100
- # development machine, so actual invocation syntax could not
101
- # be verified. Until a local install is available, refuse
102
- # rather than ship guessed arguments.
105
+ # Status as of 2026-05-25 (PR60): Codex CLI still not verified
106
+ # in any ArkaOS dev environment. headless_supported() now
107
+ # auto-detects the binary on PATH so this lights up the moment
108
+ # someone installs it but the actual subprocess call below
109
+ # still needs syntax verification before we can stop refusing.
103
110
  #
104
111
  # Verification checklist for whoever picks this up:
105
112
  # 1. Install: npm install -g @openai/codex-cli
106
- # 2. Discover: codex --help (confirm non-interactive flag)
113
+ # 2. Discover: codex --help (confirm non-interactive flag)
107
114
  # 3. Pattern: likely `codex exec "<prompt>"` or
108
115
  # `codex --prompt "<prompt>" --format json`
109
116
  # 4. Wire the subprocess call (mirror the Gemini adapter —
@@ -113,9 +120,11 @@ class CodexCliAdapter(RuntimeAdapter):
113
120
  # SubagentProvider cleanly falls back to anthropic-direct or
114
121
  # stub when this raises, so the chain keeps working.
115
122
  raise NotImplementedError(
116
- "Codex CLI headless mode requires local `codex` CLI. "
117
- "Install: `npm install -g @openai/codex-cli` (verified 2026-04-20). "
118
- "Verify syntax: `codex --help`. "
119
- "See TODO(llm-agnostic) in this file. "
123
+ "Codex CLI headless mode requires verified invocation syntax. "
124
+ "The `codex` binary is on PATH but ArkaOS has not validated "
125
+ "the non-interactive call shape locally. "
126
+ "Verification steps: `codex --help`, then update "
127
+ "core/runtime/codex_cli.py::headless_complete to call the "
128
+ "discovered subprocess shape. "
120
129
  "SubagentProvider will cleanly fall back to anthropic-direct or stub."
121
130
  )
@@ -362,6 +362,19 @@ def get_llm_provider(config_path: Path | None = None) -> LLMProvider:
362
362
  return last if last is not None else StubProvider()
363
363
 
364
364
 
365
+ def _current_category() -> str:
366
+ """Resolve the per-call category from the environment.
367
+
368
+ PR60 v2.77.0 — orchestration layers can set
369
+ ``ARKA_CALL_CATEGORY=skill:<slug>`` /
370
+ ``subagent:<dept>`` / ``plugin:<id>`` / ``mcp:<server>`` before
371
+ invoking the provider so `/arka costs --by-category` (PR47) can
372
+ attribute spend. Returns "" when unset, which lands in the base
373
+ bucket (backward-compatible).
374
+ """
375
+ return os.environ.get("ARKA_CALL_CATEGORY", "").strip()
376
+
377
+
365
378
  def _log_fallback(preferred: str, selected: str, reason: str = "") -> None:
366
379
  # Piggy-back on the cost telemetry file: zero-token, provider-only row.
367
380
  # Downstream can group by provider to spot degraded chains.
@@ -373,6 +386,7 @@ def _log_fallback(preferred: str, selected: str, reason: str = "") -> None:
373
386
  tokens_out=0,
374
387
  cached_tokens=0,
375
388
  estimated_cost_usd=None,
389
+ category=_current_category(),
376
390
  )
377
391
 
378
392
 
@@ -391,4 +405,5 @@ def _record(session_id: str, provider: str, response: LLMResponse) -> None:
391
405
  tokens_out=response.tokens_out,
392
406
  cached_tokens=response.cached_tokens,
393
407
  estimated_cost_usd=cost,
408
+ category=_current_category(),
394
409
  )
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "2.76.0",
3
+ "version": "2.77.0",
4
4
  "description": "The Operating System for AI Agent Teams",
5
5
  "type": "module",
6
6
  "bin": {
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "arkaos-core"
3
- version = "2.76.0"
3
+ version = "2.77.0"
4
4
  description = "Core engine for ArkaOS — The Operating System for AI Agent Teams"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}