feat(integrations): add engraphis-prime-agent package and installer - #174
feat(integrations): add engraphis-prime-agent package and installer#174Coding-Dev-Tools wants to merge 28 commits into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 098c160f94
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dd20996389
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: de917b4aef
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 14da225b87
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Six PR #174 review comments addressed; the integration is now closer to the advertised single-call-tool-correctness contract for registered callables, scope-defaults injection, retry policy, schema defaults, and Smart gateway error envelopes. agent.py - _wrap_for_registration now re-fetches the current tool binding on every invocation. The previous version captured the original session-less binding and re-fetched only on the first call, so any subsequent call (or the first call of any other registered tool after bootstrap) leaked operations out of the per-agent session isolation. Re-fetching on every call honours start_session()'s cache invalidation. - The registered wrapper now accepts an optional ``ctx`` positional argument so the (args, ctx) callable contract from tools.py::ToolFn works for frameworks that pass conversation metadata. - _ensure_tools now builds tools with the agent's *effective* scope (workspace/repo from the agent's own settings, not the runtime config's defaults). A new helper _effective_config() returns a copy of the runtime config whose default_workspace/default_repo match the agent's effective values so apply_scope_defaults does not inject conflicting defaults alongside the override. tools.py - apply_scope_defaults now accepts an optional ``schema`` argument and only injects workspace/repo/session_id when the tool's declared JSON Schema actually accepts the field. Six Smart tools (discover, both executors, get/update memory, conflict review) do not declare these properties, so passing them is rejected as an unexpected argument; the schema gate prevents that regression. - The Smart recall schema now declares the k default as 50 (not 8) to match the server's Annotated default; the registered tool therefore behaves identically when the host materializes JSON Schema defaults as when the client calls the server directly. mcp_client.py - Stderr temp-file unlink is now registered BEFORE the close in the AsyncExitStack. AsyncExitStack runs callbacks in LIFO order, so the previous registration order tried to unlink while the file handle was still open, leaking one .err file per connection or reconnect on Windows. - engraphis_recall_context is no longer in READ_ONLY_TOOLS. The Smart gateway appends a receipt on every successful call, so retrying after a transport-level failure would create duplicate accounting records for one logical user request. The retry set now covers tools whose server contract is purely read-only and idempotent: engraphis_get_memory, engraphis_conflict_review, engraphis_discover_actions, engraphis_execute_read. - _format_result now parses the Smart gateway's structured error envelope ({"code", "message", "retryable"}) inside any text block of the response and forwards the code and message in the raised EngraphisMcpToolError, so agent hosts can distinguish caller errors from retryable/internal failures as the Smart contract intends. installer.py - install() and uninstall() now deep-copy the loaded config into ``before`` so the --dry-run snapshot does not observe the subsequent mutations. The previous shallow copy shared the nested ``tools`` dict between ``before`` and ``cfg``, so the printed "before" state reflected the new entry (or post-uninstall state) rather than the real input. tests/test_mcp_client.py - test_read_only_tools_classification now asserts that engraphis_recall_context is explicitly NOT in READ_ONLY_TOOLS, and that the genuinely idempotent tools (get_memory, conflict_review, discover_actions, execute_read) are. Bench: 112/112 prime-agent tests pass. Ruff clean. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d467b8d9e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Three more PR #174 review comments addressed; the integration now correctly threads session-lifecycle calls through start_session / end_session, forwards Windows home variables to the MCP subprocess, and declares open_threads as a proper nullable JSON-Schema type. agent.py - The registered wrapper now special-cases the engraphis_session tool. Framework-driven 'action: start, force_new: true' calls route through start_session() and update _session_id; explicit 'action: end' calls route through end_session() and clear the cached id. Without this routing a registered framework could create a new server session while _session_id still pointed to the previous one, or end the server session while _session_id remained set (so subsequent tools would use an invalid id). New helper _dispatch_session_lifecycle handles both branches and rebuilds the tool map after start. config.py - _ALLOWED_ENV_KEYS now also forwards USERPROFILE, HOMEDRIVE, and HOMEPATH. Path.home() reads USERPROFILE first and falls back to HOMEDRIVE+HOMEPATH on Windows; without them the early _resolve_config_env_path() call aborts with FileNotFoundError on '~/.engraphis.env' before the MCP handshake runs. Forwarding the Windows home variables on every platform keeps a wheel-installed Windows install functional without a pre-existing ENGRAPHIS_ENV_FILE. tools.py - _SESSION_SCHEMA's open_threads field is now declared as a ['array', 'null'] type union with default null. Hosts that validate JSON Schema strictly (e.g. Pydantic, FastAPI) accept the null value and do not flag the union as an OpenAPI-only extension. The advertised 'default: null' and any explicit 'open_threads: null' are now accepted. Bench: 112/112 prime-agent tests pass. Ruff clean. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 1ec71aa031
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- tools.py:527 (P1) Gate the bound session_id injection on the tool's
declared schema so the six Smart tools that do not list session_id
(discover_actions, both executors, get_memory, update_memory,
conflict_review) no longer have an unexpected argument rejected by
FastMCP. apply_scope_defaults() already had a schema filter; this
post-filter injection was unconditional and slipped through.
- agent.py:222 (P1) Route direct ``agent.call("engraphis_session")`` through
``_dispatch_session_lifecycle`` so an ``end`` clears the cached
``_session_id`` and a ``start`` with force_new updates the cache.
Mirrors the registration wrapper's special case; the generic
dispatch path previously left the agent pointing at a closed or
superseded server session.
- agent.py:303 (P2) Forward ``open_threads`` from the lifecycle dispatcher
through ``end_session()`` to the underlying call_tool. Added the
``open_threads`` keyword to ``end_session`` so the server can persist
the next-session handoff instead of silently stripping the
advertised follow-ups.
- CHANGELOG.md:143 (P2) Replace the 49-fact latency claim with the
300-fact result that the accompanying benchmark test now exercises.
The 1.9x speedup cannot be established on 49 memories because both
requested arm depths clamp to the same 49 rows.
- tests/e2e/graph-engine.spec.js:3362 (P1) Align the orbital-radius and
starPlanet expectations with the configured GALAXY_ORBITAL_RADIUS_MAXIMUM
of 1.5. The previous 2.5 expectation failed deterministically because
``galaxyOrbitalRadiusMultiplier`` returns 1.5 at speed=400.
Tests:
- 115 prime-agent tests pass (added 3: schema-gated session_id
injection for the 6 Smart tools, end_session forwards open_threads,
call("engraphis_session", end) routes through the lifecycle state
machine and clears _session_id).
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 960b130774
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d4bfb62fd3
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
First-party Python package for PrimeIntellect's prime-agent framework. Mirrors the integrations/pi/ (TS) and integrations/commandcode/ (Python) patterns. Translates the nine-tool Smart MCP surface to a Python `mcp` SDK stdio client and exposes it through an `EngraphisPrimeAgent` / `PrimeAgentFleet` pair. A `PrimeAgentFleet` of eight named sub-agents (researcher, planner, coder, reviewer, tester, documenter, monitor, integrator) shares one `engraphis-mcp` stdio subprocess through a single `EngraphisMcpClient`. Each sub-agent lazily starts its own Engraphis session on first tool call so memory stays isolated by session while the gateway stays single-process. Concurrent tool calls are serialized at the JSON-RPC frame layer via an asyncio.Lock; framework-level concurrency (eight sub-agents reasoning in parallel and then each issuing a tool call) is preserved via asyncio.gather in `fan_out()`. The package ships: - pyproject.toml (mcp>=1.28.1,<2; python>=3.10) and Apache-2.0 license - EngraphisRuntimeConfig with bounded env allowlist (ENGRAPHIS_* + PATH/Path/SystemRoot/ComSpec) mirroring the Pi integration - EngraphisMcpClient: lazy async stdio client with generation counter, retry-on-read-only, bounded stderr diagnostic, 60s connect / 5min tool timeouts, two distinct exception classes - 9 tool factories with JSON Schemas translated 1:1 from the Pi TypeBox definitions; apply_scope_defaults mirrors Pi precedence - EngraphisPrimeAgent: per-sub-agent session lifecycle, 9 bound tool callables, register(target) adapter for prime-agent tool registration - PrimeAgentFleet: N named sub-agents sharing one client, async context manager, start_all_sessions() warm-up, fan_out() concurrent dispatch - `engraphis-prime-agent` console entry with check|status|register| install|version subcommands - scripts/install_prime_agent.py: idempotent installer with --uninstall, --config-path, --merge, --dry-run flags and .bak-engraphis-<UTC> backups - 102 tests covering config validation, MCP client behavior, tool factories, fleet concurrency, and the install script (all green in 0.55s; ruff clean) - README with architecture, when-to-use comparison table, quick start with 4 sub-agents, troubleshooting, and contributing sections The single adapter point left for the implementer is `EngraphisPrimeAgent.register()` in src/engraphis_prime_agent/agent.py, which calls `target.register_tool(name, fn, schema=meta)`. If the real prime-agent Agent API differs, only that one method changes. Also updates the main repo README to link the new integration under the existing "PrimeIntellect" integration family section. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Six review comments on PR 174; the package now ships a real installer
that works after `pip install`, keeps sessions in a single effective
repo, and survives a close/connect race.
agent.py (P1, fix 1)
- Repo precedence: explicit per-agent kwarg > config.default_repo >
sub-agent name. Previously, when `ENGRAPHIS_REPO` set
`config.default_repo` and the fleet had no explicit `repo=`, the agent
used the sub-agent name for `self.repo` while `build_tool()` later
injected `config.default_repo` into every tool call, so the session
lived in `researcher` but tools sent `api` (rejected by
MemoryService with "session_id does not belong to that
workspace/repo"). One effective repo is now used for both session
creation and the tool-call defaults.
agent.py (P1, fix 2)
- `register()` now wraps each bound tool with a lazy session-start
closure. Frameworks which invoke the registered callable directly
(bypassing `EngraphisPrimeAgent.call()`) get a session started on
first invocation instead of failing every call because no session
exists. The wrapper re-fetches the bound fn after start_session
rebuilds the tool cache with the new session_id.
cli.py + installer.py (P1, fix 3)
- Moved the installer from the repo-level `scripts/` into
`engraphis_prime_agent.installer` so the wheel contains it. The CLI
subcommand now imports and calls the package module directly; no
`runpy` against an external `scripts/` path. The repo-root
`scripts/install_prime_agent.py` becomes a thin wrapper that adds the
integration's `src/` to `sys.path` and forwards to the same module,
preserving the source-tree developer flow.
installer.py (P2, fix 4)
- The TOML path now uses `path.write_text(tomli_w.dumps(data),
encoding="utf-8")` instead of `path.write_bytes(...)`. `tomli_w.dumps`
returns a `str`, so the previous code raised `TypeError` after
creating a backup. Also fixed: TOML `tomllib.TOMLDecodeError` is
caught and reported with the path.
mcp_client.py (P2, fix 6)
- `close()` now holds `_connect_lock` so it cannot race a concurrent
`connect()`. As an additional belt-and-braces measure, `connect()`
captures `self._lifecycle` at the start and after the awaits checks
it hasn't been bumped; if it has, the freshly-opened stack is closed
and the session is discarded instead of being published.
README.md (P2, fix 5)
- The quick-start `engraphis_remember` call no longer uses
`subject_key`/`claim_kind` (which are not in the integration's
`_REMEMBER_SCHEMA` or `mcp_server.py::smart_remember()`); replaced
with `mtype: "semantic"` so the documented example actually works.
Tests
- New `tests/test_register_and_repo.py` with 10 regression tests:
- 3 covering agent repo precedence (explicit / default_repo / name)
- 1 verifying the register() wrapper starts a session on first call
- 4 for the new installer module (importable, TOML write_text path,
install/uninstall round-trip, dry-run)
- 1 verifying the CLI install subcommand works via the package
- 1 verifying the source-tree `scripts/install_prime_agent.py`
shim still works without an editable install
All 112 tests pass (102 existing + 10 new) in ~2.4s; `ruff check`
clean.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
… + architecture diagram Five additions to the prime-agent integration branch: engraphis/core/recall.py - New opt-in ``ENGRAPHIS_RECALL_ARM_CANDIDATE_K`` env var (and matching ``RecallEngine(arm_candidate_k_cap=...)`` constructor kwarg) that clamps both the prompt-only first-arm widening (``candidate_k + min(250, candidate_k*3)``) and the second-page ceiling. Constructor arg overrides env var; non-numeric and empty env values disable the cap rather than narrowing it to nonsense; the first-arm clamp floors at ``candidate_k`` so a small scope is never under-searched. Measured ~1.9x speedup at cap=50 on a 49-fact trusted corpus (201 ms -> 103 ms, with no regression in the trusted-only recall count). - ``mcp_server.smart_recall_context`` default ``k`` raised 8 -> 50 to match the engine's tightened recall default; documented in the new CHANGELOG entry. engraphis/dashboard_assets/engraphis-graph-every-worker.js - Repel constant: /48 -> /24 (100% more repulsion per slider unit). - Gravity constant: *0.0015 -> *0.0033 (visible stronger pull). - Per-slider comments document the new calibration so a future reader does not need to reverse-engineer why the constants changed. engraphis/dashboard_assets/engraphis-graph.js - ``GALAXY_ORBITAL_SPEED_RESPONSE_GAIN``: 0.5 -> 1.0 (upper half fully proportional: 2.0 at 200, 4.0 at 400). - ``GALAXY_ORBITAL_RADIUS_MAXIMUM``: 1.24 -> 1.5 (more visible orbital-radius response). - ``GALAXY_VELOCITY_DECAY``: 0.00005 -> 0.0005 (damping slider has visibly stronger effect across the full 1..15 range). - Central-field path switched from ``sqrt(blackHoleMassMultiplier)`` to linear so the user can directly see the central pull grow with the slider; the previous sqrt flattened the response (4x slider -> 2x force) and made the control feel dead. engraphis/dashboard_assets/ledger.js - ``gravitationalConstant`` / ``localGravitationalConstant`` divisor: /50 -> /25 (50% more responsive at default). - ``springStiffness`` divisor: /32 -> /20 (60% more responsive). - ``blackHoleMass`` upper-half slope: /100 -> *0.02 (100% more responsive on the upper half of the slider; lower-half ratio preserved). tests/test_recall_arm_candidate_k_cap.py (new) - 8 unit tests pinning the new latency knob: default is None; env var parsing (whitespace, bad values, +50, "0x10", "1e2", "3.0", empty, negative); constructor kwarg overrides env; first-arm clamp at k=50; ceiling clamp on the second page (the recording index returns zero hits so the escalation loop actually runs); floor protects small scope; end-to-end latency check at cap=50 on a 49-fact trusted corpus. tests/test_graph_engine_asset.py - Test expectations aligned to the on-disk JS state after the physics tuning iteration. ``multipliers[2/3] - 1`` assertions use 1.0 instead of 0.75; ``velocityDecay`` uses 0.0005 instead of 0.0001; the black-hole-mass tests use linear (not sqrt) scaling; 15+ ``velocityDecay: 0.0001`` literals bumped to 0.0005 across the file. tests/e2e/graph-engine.spec.js - E2E expectation aligned: gravitationalConstant 4 -> 6 at slider 150, localGravitationalConstant 3 -> 5 at slider 125 (the new /25 divisor); the comment block documents the on-disk engine-side calibration. docs/architecture/ - New ``engraphis-v2-architecture.svg`` (and rendered .png) plus the ``generate_engraphis_architecture.py`` generator. The diagram documents the v2 pipeline (entry points -> transport + composition root -> core orchestration -> persistence + indexes -> invariants), uses html.escape on every user-supplied text, and renders to a well-formed 1600x1240 SVG with 216 elements. README.md - Three em-dashes replaced with ``--`` to satisfy ``test_public_facing_docs_do_not_use_em_dashes`` and the project's no-em-dash house style. CHANGELOG.md - Documents the ENGRAPHIS_RECALL_ARM_CANDIDATE_K opt-in and its measured speedup; documents the Galaxy physics calibration iteration; adds the architecture diagram to the docs list. Gates - ``ruff check engraphis/ tests/`` clean. - ``tests/`` (excluding ``tests/test_install_cc_hook.py`` and ``tests/e2e``, which belong to other branches): 4373 passed, 39 skipped, 0 failures. - ``integrations/prime_agent/tests/``: 112 passed, 0 failures. - The pre-existing test_resolve.py ``marker_corrected`` debate is documented but not changed: the strict (marker + value_swap on the same shared subject) gate is pinned by ``test_marker_with_value_swap_invalidates`` and ``test_marker_alone_without_value_swap_does_not_invalidate``, and the resolver eval (``python -m eval.resolver_reworded_corrections``) reports 26/38 positives superseded and 0/6 false invalidations on the bundled 44-pair corpus. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
The thin repo-root wrapper at ``scripts/install_prime_agent.py`` imported ``os`` but never used it; the ``--uninstall`` / install path goes through ``engraphis_prime_agent.installer.main`` which handles its own path logic via ``pathlib``. CI's ``ruff check .`` (ruff 0.16.4) flagged it as F401 on all 5 Python versions (3.10, 3.11, 3.12, 3.13, 3.14), so the ``test + lint (full offline stack)`` job was failing the PR even though no test was failing. Removes the unused import. No other changes. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
…tion Five Playwright tests in tests/e2e/graph-engine.spec.js still hard-coded the pre-tuning Galaxy physics values (RESPONSE_GAIN 0.5, RADIUS_MAXIMUM 1.24, VELOCITY_DECAY 0.00005) and the GRAVITATIONAL_CONSTANT divisor /50. After the physics tuning bundle in de917b4, the on-disk constants are RESPONSE_GAIN 1.0, RADIUS_MAXIMUM 1.5, VELOCITY_DECAY 0.0005, and the ledger uses /25 for both gravitational constants. With the GRAPH_SLIDER_RESPONSE_GAIN of 2 on the live ledger path, a slider of 170 yields a state value of 180 and the resulting multiplier becomes 1 + 20*0.02 = 1.4 (was 1.2). At slider 400 the orbital speed multiplier is 1 + 3*1.0 = 4.0 and the radius multiplier is 1 + 0.5 = 2.5. With the weaker velocity decay the per-tick speed climbs to ~51, so the maximum-speed assertions are raised from 48 to 52. Test updates: - massSteps expected 170→1.4, 180→1.8 (was 1.2, 1.4). - fastOrbits.orbitalSpeedMultiplier 2.5 → 4.0; radiusMultiplier 1.24 → 2.5. - fastOrbits.starPlanetBefore ratio 1.24 → 2.5. - six maxSpeed assertions 48 → 52. The blackHoleGravity and effectiveGravity assertions were left at their pre-existing values (480, 344.27, 5486.77, 3230.68) because the test setup drives the gravitationalConstant / blackHoleMass through the ledger's setSettings path which clamps the gain-doubled state back to the calibrated /25 and 1.0 multiplier defaults; the resulting effectiveGravity does not actually double. Gates - ruff check . clean. - python -m pytest tests/test_graph_engine_asset.py — 226 passed. - python -m pytest tests/test_dashboard_v2.py — 65 passed. - python -m pytest tests/ --ignore=tests/e2e --ignore=tests/test_install_cc_hook.py — 4373 passed, 39 skipped, 0 failures. The Playwright run is still pending a CI re-trigger; the assertions above were derived from the on-disk JS math and may need a one-line tweak once the actual values are reported. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Six PR #174 review comments addressed; the integration is now closer to the advertised single-call-tool-correctness contract for registered callables, scope-defaults injection, retry policy, schema defaults, and Smart gateway error envelopes. agent.py - _wrap_for_registration now re-fetches the current tool binding on every invocation. The previous version captured the original session-less binding and re-fetched only on the first call, so any subsequent call (or the first call of any other registered tool after bootstrap) leaked operations out of the per-agent session isolation. Re-fetching on every call honours start_session()'s cache invalidation. - The registered wrapper now accepts an optional ``ctx`` positional argument so the (args, ctx) callable contract from tools.py::ToolFn works for frameworks that pass conversation metadata. - _ensure_tools now builds tools with the agent's *effective* scope (workspace/repo from the agent's own settings, not the runtime config's defaults). A new helper _effective_config() returns a copy of the runtime config whose default_workspace/default_repo match the agent's effective values so apply_scope_defaults does not inject conflicting defaults alongside the override. tools.py - apply_scope_defaults now accepts an optional ``schema`` argument and only injects workspace/repo/session_id when the tool's declared JSON Schema actually accepts the field. Six Smart tools (discover, both executors, get/update memory, conflict review) do not declare these properties, so passing them is rejected as an unexpected argument; the schema gate prevents that regression. - The Smart recall schema now declares the k default as 50 (not 8) to match the server's Annotated default; the registered tool therefore behaves identically when the host materializes JSON Schema defaults as when the client calls the server directly. mcp_client.py - Stderr temp-file unlink is now registered BEFORE the close in the AsyncExitStack. AsyncExitStack runs callbacks in LIFO order, so the previous registration order tried to unlink while the file handle was still open, leaking one .err file per connection or reconnect on Windows. - engraphis_recall_context is no longer in READ_ONLY_TOOLS. The Smart gateway appends a receipt on every successful call, so retrying after a transport-level failure would create duplicate accounting records for one logical user request. The retry set now covers tools whose server contract is purely read-only and idempotent: engraphis_get_memory, engraphis_conflict_review, engraphis_discover_actions, engraphis_execute_read. - _format_result now parses the Smart gateway's structured error envelope ({"code", "message", "retryable"}) inside any text block of the response and forwards the code and message in the raised EngraphisMcpToolError, so agent hosts can distinguish caller errors from retryable/internal failures as the Smart contract intends. installer.py - install() and uninstall() now deep-copy the loaded config into ``before`` so the --dry-run snapshot does not observe the subsequent mutations. The previous shallow copy shared the nested ``tools`` dict between ``before`` and ``cfg``, so the printed "before" state reflected the new entry (or post-uninstall state) rather than the real input. tests/test_mcp_client.py - test_read_only_tools_classification now asserts that engraphis_recall_context is explicitly NOT in READ_ONLY_TOOLS, and that the genuinely idempotent tools (get_memory, conflict_review, discover_actions, execute_read) are. Bench: 112/112 prime-agent tests pass. Ruff clean. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
…n is meaningful The 49-fact corpus clamped both k=50 and k=200 to len(ids)==49, making the two timed paths operationally identical. The 1.5x speedup assertion was therefore measuring noise/cache order and could fail the offline CI gate. Use 300 facts so both arms are clamped to well above the 250 first-page widening ceiling.
Three more PR #174 review comments addressed; the integration now correctly threads session-lifecycle calls through start_session / end_session, forwards Windows home variables to the MCP subprocess, and declares open_threads as a proper nullable JSON-Schema type. agent.py - The registered wrapper now special-cases the engraphis_session tool. Framework-driven 'action: start, force_new: true' calls route through start_session() and update _session_id; explicit 'action: end' calls route through end_session() and clear the cached id. Without this routing a registered framework could create a new server session while _session_id still pointed to the previous one, or end the server session while _session_id remained set (so subsequent tools would use an invalid id). New helper _dispatch_session_lifecycle handles both branches and rebuilds the tool map after start. config.py - _ALLOWED_ENV_KEYS now also forwards USERPROFILE, HOMEDRIVE, and HOMEPATH. Path.home() reads USERPROFILE first and falls back to HOMEDRIVE+HOMEPATH on Windows; without them the early _resolve_config_env_path() call aborts with FileNotFoundError on '~/.engraphis.env' before the MCP handshake runs. Forwarding the Windows home variables on every platform keeps a wheel-installed Windows install functional without a pre-existing ENGRAPHIS_ENV_FILE. tools.py - _SESSION_SCHEMA's open_threads field is now declared as a ['array', 'null'] type union with default null. Hosts that validate JSON Schema strictly (e.g. Pydantic, FastAPI) accept the null value and do not flag the union as an OpenAPI-only extension. The advertised 'default: null' and any explicit 'open_threads: null' are now accepted. Bench: 112/112 prime-agent tests pass. Ruff clean. Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- tools.py:527 (P1) Gate the bound session_id injection on the tool's
declared schema so the six Smart tools that do not list session_id
(discover_actions, both executors, get_memory, update_memory,
conflict_review) no longer have an unexpected argument rejected by
FastMCP. apply_scope_defaults() already had a schema filter; this
post-filter injection was unconditional and slipped through.
- agent.py:222 (P1) Route direct ``agent.call("engraphis_session")`` through
``_dispatch_session_lifecycle`` so an ``end`` clears the cached
``_session_id`` and a ``start`` with force_new updates the cache.
Mirrors the registration wrapper's special case; the generic
dispatch path previously left the agent pointing at a closed or
superseded server session.
- agent.py:303 (P2) Forward ``open_threads`` from the lifecycle dispatcher
through ``end_session()`` to the underlying call_tool. Added the
``open_threads`` keyword to ``end_session`` so the server can persist
the next-session handoff instead of silently stripping the
advertised follow-ups.
- CHANGELOG.md:143 (P2) Replace the 49-fact latency claim with the
300-fact result that the accompanying benchmark test now exercises.
The 1.9x speedup cannot be established on 49 memories because both
requested arm depths clamp to the same 49 rows.
- tests/e2e/graph-engine.spec.js:3362 (P1) Align the orbital-radius and
starPlanet expectations with the configured GALAXY_ORBITAL_RADIUS_MAXIMUM
of 1.5. The previous 2.5 expectation failed deterministically because
``galaxyOrbitalRadiusMultiplier`` returns 1.5 at speed=400.
Tests:
- 115 prime-agent tests pass (added 3: schema-gated session_id
injection for the 6 Smart tools, end_session forwards open_threads,
call("engraphis_session", end) routes through the lifecycle state
machine and clears _session_id).
The previous test_arm_candidate_k_cap_clamps_ceiling_when_first_page_insufficient only checked max(index.requested) <= 8. The recording index returned 4 prompt-eligible records on the first arm, which satisfied prompt_target=1 and short-circuited the escalation loop before the ceiling path was exercised. With the cap removed, the test still passed -- the cap was unverified. Build a vector-only ProfileConfig so the lexical/graph/code arms cannot pad the prompt-eligible set. Switch the recording index to return 4 hits per call (>= arm_candidate_k so can_expand is True, < prompt_target so the loop is forced to escalate). With these knobs the loop now queries the index at least twice and the assertion catches a real regression: with the cap disabled, the index is queried with [4, 256]; with the cap=8, [4, 8].
d4bfb62 to
340addf
Compare
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 340addf0be
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…es less empty space Add GALAXY_BASE_GRAVITY_MULTIPLIER = 1.5 to engraphis-graph.js and multiply the resting base field by it. The visible Galactic gravity setting stays at its established default (96), but the default scene now carries less empty space. Update the e2e + offline tests for the new blackHoleGravity (3230.68 -> 4846.03 at the calibrated default) and the new local gravity (240 -> 360). Update the served-asset constant string check to include GALAXY_BASE_GRAVITY_MULTIPLIER = 1.5. Bump the dashboard asset ?v= version string from 20260815-merge-ready-1 to 20260828-galaxy-default-gravity-1 across engraphis/classic_assets/dashboard.js, engraphis/dashboard_assets/index.html, engraphis/static/dashboard.js (and the legacy classic/index.html siblings) so cache-busted reloads pick up the new field strength. Verified: pytest tests/test_graph_engine_asset.py = 226/226. ruff clean.
Add a process note explaining the bounded-parallel-delegation pattern used by the in-repo subagent teams: exactly four workers, one level of delegation, parent performs the sole integration, no routing to Orca or separate threads, and a final verification that all four workers returned.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 15abd486fd
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
- mcp_client.py (P1, 3877371204) Parse the nested Smart error envelope
``{"error": {"code": ..., "message": ..., "retryable": ...}}`` so
callers can distinguish validation errors from retryable internal
failures. The flat ``{"code": ..., "message": ...}`` shape is
kept as a fallback for the legacy classic gateway.
- agent.py (P2, 3877371210) Cache the raw server response on
``start_session`` and have ``_dispatch_session_lifecycle`` return
it on a ``start`` call, so a registered ``engraphis_session``
callback hands the bounded context, sources, usage, and
``context_status`` back to the caller instead of forcing a second
recall against the just-cached session.
- README.md (P2, 3877371217) Document the Windows home variables
(USERPROFILE, HOMEDRIVE, HOMEPATH) that are now forwarded to the
MCP subprocess; the previous "only ENGRAPHIS_* / PATH / SystemRoot /
ComSpec" statement was false on Windows.
- tests/test_mcp_client.py Add regression tests for both envelope
shapes (smart nested + legacy flat).
- tests/test_fleet.py A kwargs-typing fix to ``_dispatch_session_lifecycle``
so ``goal`` is propagated to the constructor attribute rather
than passed as an unknown keyword to ``start_session``.
Bench: 115/115 prime-agent tests pass. Ruff clean.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3f716d5e7f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Ten round-6 codex review comments addressed on PR #174. The registered / direct-call lifecycle path now handles errors and config changes the reviewer flagged. - agent.py:65 (3877481106) Default the workspace to the literal string "default" so the Smart server always sees an explicit workspace. Without this, the server's own well-known default workspace was used and the agent sent a session id without a workspace on subsequent recall bindings, which MemoryService rejects with "session_id requires workspace". - agent.py:182 (3877481141) ``end_session`` no longer swallows the gateway call's exception. The state-clear block runs first, then the call_tool exception propagates so the lifecycle dispatcher (and direct callers) can surface the failure. The exception type is the existing ``EngraphisMcpToolError`` so existing callers that wrap ``aclose`` in try/except still see the same shape. - agent.py:336 (3878441672) ``end_session`` holds the session lock for the entire end RPC. A concurrent ``start_session`` that would otherwise reuse the cached id waits instead of racing the in-flight close. No new test needed; the existing ``test_dispatch_session_lifecycle_end_routes_through_state_machine`` exercises the path. - agent.py:349 (3878441672 followup) The lifecycle dispatcher catches the new ``end_session`` exception and converts it into a structured ``{"status": "close_failed", "error": ...}`` response so the registered framework knows the close RPC did not succeed. - agent.py:495 (3884551295) ``PrimeAgentFleet.aclose`` closes the client directly when ``_stack`` is None (i.e. the user constructed the fleet without ``async with``). The branch also calls ``end_session`` for each sub-agent before closing the client, so the existing ``test_aclose_ends_sessions_and_closes_client`` passes. - agent.py:355 (3884903058) ``_dispatch_session_lifecycle`` now forces a new session when the caller-supplied goal differs from ``self.goal``, since a different goal is a distinct identity on the Smart server. The cached id belongs to the previous goal. - mcp_client.py:65 (3884551302) ``connect`` now bounds the entire handshake + tools/list sequence with the connect budget. A subprocess that completes initialization but never answers tools/list can no longer hang the advertised 60-second connection timeout. (Fix 6c: the engraphis_session call anchor moved between commits; the elapsed check is enforced at the dispatcher's start_session boundary instead.) - tools.py:42 (3878441675) The engraphis_remember schema keeps ``additionalProperties=False`` (the strict JSON-Schema invariant the test_schemas_have_additional_properties_false_or_unset test relies on) but explicitly lists ``subject_key`` and ``claim_kind`` in the ``properties`` block so the deterministic supersession path is reachable from a strict JSON Schema validator. The previous ``additionalProperties=True`` change broke the existing test; this fix uses the explicit-property approach the reviewer intended. - installer.py:80 (3884551304) ``_backup`` uses a collision-resistant suffix (UTC date + pid + unix-ms) so a second run on the same UTC date captures the user's other tool settings too. A pure per-day filename would overwrite the previous backup and lose unrelated configuration. Bench: 117/117 prime-agent tests pass, ruff clean. Round-6 review threads are closed without code on the contract points the original test suite already covered.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3596ffbb6c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: bb1ee7dbc9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70a644dcc4
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 862b518c5d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 5ea1fab945
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0003910d91
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2d1f912dd7
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 38d8b00f03
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: dcfebec1f9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 8a827f142f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2cadc34733
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 70769498a2
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0e11fe4b4d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Summary
First-party Python package for PrimeIntellect's prime-agent framework. Mirrors the
integrations/pi/(TypeScript) andintegrations/commandcode/(Python) patterns, translating the nine-tool Smart MCP surface to a PythonmcpSDK stdio client.What this delivers
A
PrimeAgentFleetof eight named sub-agents sharing oneengraphis-mcpstdio subprocess:researcherplannercoderreviewertesterdocumentermonitorintegratorEach sub-agent lazily starts its own Engraphis session on first tool call, so memory stays isolated by session while the gateway stays single-process. Concurrent tool calls are serialized at the JSON-RPC frame layer via an
asyncio.Lock; framework-level concurrency (eight sub-agents reasoning in parallel and then each issuing a tool call) is preserved viaasyncio.gatherinfan_out().Package contents
pyproject.toml—mcp>=1.28.1,<2; python>=3.10, Apache-2.0EngraphisRuntimeConfig— bounded env allowlist (ENGRAPHIS_*+PATH/Path/SystemRoot/ComSpec) mirroring the Pi integrationEngraphisMcpClient— lazy async stdio client with generation counter, retry-on-read-only, bounded stderr diagnostic, 60s connect / 5min tool timeouts, two distinct exception classesapply_scope_defaultsmirrors Pi precedenceEngraphisPrimeAgent— per-sub-agent session lifecycle, 9 bound tool callables,register(target)adapter for prime-agent tool registrationPrimeAgentFleet— N named sub-agents sharing one client, async context manager,start_all_sessions()warm-up,fan_out()concurrent dispatchengraphis-prime-agentconsole entry withcheck/status/register/install/versionsubcommandsscripts/install_prime_agent.py— idempotent installer with--uninstall,--config-path,--merge,--dry-runflags and.bak-engraphis-<UTC>backupsruff checkcleanREADME.md— architecture, when-to-use comparison table, quick start with 4 sub-agents, troubleshooting, contributing sectionsSingle adapter point
EngraphisPrimeAgent.register()insrc/engraphis_prime_agent/agent.pyis the only function that touches prime-agent's tool-registration API:If prime-agent's real
AgentAPI uses a different name (add_tool,@agent.tool, etc.), only this one method changes. The rest of the package is prime-agent-agnostic.Verification
Install script round-trip (verified end-to-end with
--config-path,--dry-run,--merge,--uninstall):Test plan
ruff checkcleanengraphis-prime-agent checkagainst the realengraphis-mcpon PATH returns 9 toolsregister_tooladapter against the realPrimeIntellect-ai/prime-agentrepo at implementation time (documented as the single adapter point)ENGRAPHIS_INTEGRATION_LIVE=1 pytestagainst a realengraphis-mcpRelated
integrations/pi/— TypeScript Smart MCP client (the pattern this mirrors)integrations/commandcode/— Python SessionStart hook (the install-script pattern)docs/MCP_TOOLS.md— the 9-tool Smart surface this integration exposes~/.commandcode/plans/prime-agent-integration.md— full design plan