Skip to content

Replace Qdrant memory stack with ClawMem#28

Closed
snahrup wants to merge 2 commits into
ghostwright:mainfrom
snahrup:clawmem-swap
Closed

Replace Qdrant memory stack with ClawMem#28
snahrup wants to merge 2 commits into
ghostwright:mainfrom
snahrup:clawmem-swap

Conversation

@snahrup
Copy link
Copy Markdown

@snahrup snahrup commented Apr 1, 2026

Summary

  • replace the Qdrant/Ollama memory implementation with a ClawMem-backed memory system
  • update memory config, health/status surfaces, doctor output, and prompt text for the new backend
  • remove backend-specific Qdrant/Ollama tests and replace them with ClawMem coverage
  • fix dynamic shell handler execution on this platform and harden secret key env parsing found during verification

Verification

  • bun run typecheck
  • bun test

snahrup added 2 commits April 1, 2026 01:42
Remove the raw Anthropic API dependency entirely. Judge calls now use
the Claude Agent SDK query() with native json_schema outputFormat,
tools disabled (tools: []), and maxTurns: 1 for sandboxed single-pass
evaluation. JudgeError class carries cost info on failures so the daily
cap tracks actual spend even when parsing fails. All ANTHROPIC_API_KEY
references removed from code, tests, config, and docs.

Author: Steve Nahrup
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3c48319f0

ℹ️ 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".

Comment thread package.json
"@anthropic-ai/sdk": "^0.80.0",
"@modelcontextprotocol/sdk": "^1.28.0",
"@slack/bolt": "^4.6.0",
"clawmem": "file:../ClawMem",
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Use a resolvable ClawMem dependency source

Pointing clawmem to file:../ClawMem makes installs fail for a normal clone/CI checkout where no sibling ../ClawMem repo exists, which in turn breaks runtime imports like clawmem/src/llm.ts and prevents tests/startup from running. This effectively turns the project into a non-self-contained build unless every environment is manually prepared with that external path.

Useful? React with 👍 / 👎.

Comment thread src/mcp/resources.ts
Comment on lines +40 to +43
: { clawmem: false, configured: false };

const uptimeSeconds = Math.floor((Date.now() - deps.startedAt) / 1000);
const allHealthy = memoryHealth.qdrant && memoryHealth.ollama;
const status = memoryHealth.clawmem ? "ok" : memoryHealth.configured ? "down" : "ok";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Report memory outage in MCP health fallback

When deps.memory is unavailable (for example after memory init fails and MCP is created without a ready memory instance), this fallback sets configured: false, so the status expression returns "ok" even though memory is down. That causes phantom://health to falsely report healthy state and hides a real backend failure from monitoring/clients.

Useful? React with 👍 / 👎.

@snahrup snahrup closed this by deleting the head repository Apr 1, 2026
mcheemaa added a commit that referenced this pull request May 1, 2026
…ecretNamesMirror (#110)

R7 Phase 8a (multi-agent Slack flow, dated 2026-04-30) hardens the
existing Socket Mode receiver with Prometheus-grade observability and
locks the cross-repo allowlist mirror against phantomd's
AllowedSecretNames.

Metrics surface (new /metrics endpoint):
- phantom_slack_socket_state{state} (gauge, 7 series). Exactly one
  series is 1.0 at any instant. Powers "tenant offline" alerts.
- phantom_slack_socket_reconnects_total (counter). Bolt's auto-
  reconnect runs under the hood; this measures wobble rate.
- phantom_slack_socket_connection_seconds (histogram). Connection
  lifetime from connect to disconnect; long-tail SLO.
- phantom_slack_event_dispatch_seconds{event_type} (histogram).
  End-to-end Bolt middleware time. Slack ack deadline is 3s.

Implementation:
- New SocketModeReceiver hookup (vs. socketMode: true shorthand) to
  reach receiver.client and subscribe lifecycle events. The State
  enum is verbatim from @slack/socket-mode SocketModeClient.js:
  connecting, authenticated, connected, reconnecting, disconnecting,
  disconnected.
- The unrecoverable start() error path maps to a synthetic "error"
  state on the gauge so the fleet view does not silently flatline
  when the receiver never gets past handshake.
- Dispatch timing via app.use() global middleware: try/await
  next() / finally observe(). Captures handler completion including
  any async LLM/memory work the agent does in response.
- prom-client backed; the metrics module owns its own Registry so
  Telegram/email can plug in via parallel registries without name
  collisions on the global registry.

AllowedSecretNamesMirror cross-repo invariant:
- New frozen const exported from slack-channel-factory.ts listing
  slack_bot_token + slack_app_token + slack_gateway_signing_secret.
- The phantomd side ships in the symmetric PR (phantomd #28,
  TestIsAllowedName_AcceptsSlackAppToken pins the assertion).
- Drift on either side breaks tenant boot with HTTP 404 (the
  metadata gateway maps ErrInvalidName to 404 to defeat name
  enumeration). The factory test pins the Mirror against the
  SECRET_RESPONSES test fixture so a future production-side rename
  fails loud in CI.

Tests (29 net-new):
- 24 in slack-metrics.test.ts: each metric family, the noop emitter,
  the dispatch middleware including throw-path, the lifecycle hooks
  including disconnect-without-prior-connect.
- 5 in slack-channel-factory.test.ts: AllowedSecretNamesMirror
  contains all three names, matches SECRET_RESPONSES, is frozen.
- All 2111 existing tests still green; full suite: 2111 pass / 0
  fail / 0 errors.

Bun-mock cross-suite hygiene: every test that previously mocked
@slack/bolt now also exports SocketModeReceiver in its mock object.
Without this, a test file that ran AFTER one of those partial
mocks would import the real module and hit "Export named
'SocketModeReceiver' not found" at module load time. Caught by
running the full channels/ suite together.

Net diff: 11 files, ~390 LOC. Follows R7 §3.1's "150 net-new" floor;
the rest is test mirror coverage and documentation.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant