Commit Graph

1973 Commits

Author SHA1 Message Date
Joel Hooks 990ec0062c sync: vault content (1 files)
adrs (1):
  updated: 0147-named-agent-profiles.md
2026-02-25 17:22:44 -08:00
Joel Hooks 34e5d195a3 sync: vault content (1 files)
adrs (1):
  new: 0147-named-agent-profiles.md
2026-02-25 17:17:37 -08:00
Joel Hooks 1da23f1a1a fix(langfuse): unified metadata — production env, system-bus tags, joelclaw namespace, no OTEL cruft (ADR-0146) 2026-02-25 17:04:05 -08:00
Joel Hooks 8319e3371c sync: vault content (1 files)
adrs (1):
  updated: 0146-pi-session-langfuse-integration.md
2026-02-25 16:46:46 -08:00
Joel Hooks 2129155142 sync: vault content (1 files)
adrs (1):
  updated: 0146-pi-session-langfuse-integration.md
2026-02-25 16:42:41 -08:00
Joel Hooks 4c90afa6fe feat: gateway calls initTracing() at startup for Langfuse (ADR-0140) 2026-02-25 15:47:52 -08:00
Joel Hooks d09ae7243f fix: update lockfile for inference-router deps (vercel deploy fix) 2026-02-25 15:47:40 -08:00
Joel Hooks 0fbe1f2a6c sync: vault content (1 files)
adrs (1):
  updated: 0140-unified-joelclaw-inference-router.md
2026-02-25 15:47:03 -08:00
Joel Hooks cad8c2844c feat: Langfuse tracing in inference-router — opt-in via env vars (ADR-0140)
TracingConfig interface, initTracing(), traceRouteDecision().
routeInference() emits Langfuse traces when LANGFUSE_PUBLIC_KEY is set.
Uses same @langfuse/otel + @langfuse/tracing pattern as system-bus.
2026-02-25 15:46:50 -08:00
Joel Hooks 75b1187fd1 feat: catalog resolution emits OTEL telemetry instead of console.log (ADR-0140)
daemon.ts: catalog.resolved event with modelId/provider
config.ts: model.provider.resolved + model.provider.fallback events
2026-02-25 15:45:32 -08:00
Joel Hooks 61489086b9 chore: biome error messages explain why + DO NOT BYPASS 2026-02-25 15:12:51 -08:00
Joel Hooks caa40380c1 feat: add Biome v2 with noRestrictedImports enforcing ADR-0144 package boundaries
Relative imports to observability, model-fallback, message-store, vault-read
are errors — must use @joelclaw/* packages instead.
2026-02-25 15:07:19 -08:00
Joel Hooks 64c7c69019 sync: vault content (1 files)
adrs (1):
  new: 0145-channel-message-triage-router.md
2026-02-25 15:04:33 -08:00
Joel Hooks 632cedf57c fix(gateway): detect 429/529 errors from message_end and trigger fallback
Pi session resolves (not throws) on rate limit errors — errorMessage is
set on the message object in the message_end event, but the throw-based
fallback path (onPromptError) never sees it.

Now: message_end checks event.message.errorMessage for rate_limit (429)
and overloaded (529) patterns, calls onPromptError to trigger fallback
controller. Other API errors are logged and dropped (not routed to user).
2026-02-25 14:57:40 -08:00
Joel Hooks 291f1587b7 feat: extract telemetry to @joelclaw/telemetry — one way to emit OTEL (ADR-0144)
Canonical TelemetryEmitter interface + createGatewayEmitter factory.
~120 call sites migrated from gateway/observability.ts.
model-fallback and message-store now import TelemetryEmitter from here.
Old observability.ts deleted. 3 tests.
2026-02-25 14:34:21 -08:00
Joel Hooks d3892b2eed sync: vault content (1 files)
adrs (1):
  updated: 0144-gateway-hexagonal-architecture.md
2026-02-25 14:29:39 -08:00
Joel Hooks 0b131f9e09 refactor: DiscordChannel implements Channel (ADR-0144)
All 4 consumer channels now implement Channel interface:
- TelegramChannel, SlackChannel, DiscordChannel, IMessageChannel
Redis remains separate as EventBridge port.
2026-02-25 14:28:09 -08:00
Joel Hooks 865e10dc16 feat: wire inference-router into gateway model resolution (ADR-0140)
resolveModel() and providerForModel() now use catalog lookup from
@joelclaw/inference-router instead of hardcoded MODEL_PROVIDERS map.
Logs catalog resolution for observability. Falls back to env vars
and 'anthropic' default when catalog misses.
2026-02-25 14:26:59 -08:00
Joel Hooks 2f4de24c3a refactor: SlackChannel implements Channel (ADR-0144) 2026-02-25 14:26:34 -08:00
Joel Hooks ff36303d47 sync: vault content (1 files)
adrs (1):
  updated: 0144-gateway-hexagonal-architecture.md
2026-02-25 14:25:50 -08:00
Joel Hooks 2ae791b083 fix: remove redis from ChannelPlatform — it's an EventBridge port, not a consumer channel (ADR-0144) 2026-02-25 14:25:10 -08:00
Joel Hooks 2fbb507258 refactor: IMessageChannel + TelegramChannel implement Channel (ADR-0144)
Both channel files now export classes implementing the Channel port interface.
Backward-compat named exports preserved — daemon.ts unchanged.
No behavioral changes.
2026-02-25 14:23:43 -08:00
Joel Hooks 5aba7b21a7 sync: vault content (1 files)
adrs (1):
  updated: 0144-gateway-hexagonal-architecture.md
2026-02-25 14:21:07 -08:00
Joel Hooks 7f95f1cb0b feat: add Channel port interface (ADR-0144)
types.ts with Channel, ChannelPlatform, SendOptions, InboundMessage,
MessageHandler, ChannelRegistry. Type-only, no behavioral changes.
2026-02-25 14:20:19 -08:00
Joel Hooks 0295660e3e feat: extract vault-reader + wire AST formatter (ADR-0143/0144)
- vault-read.ts (209 lines) → @joelclaw/vault-reader, 4 tests
- AST formatter wired in telegram.ts behind USE_AST_FORMATTER flag
- Fixed TS errors: type-only import, non-null assertions, break vs lineBreak
- 31 tests green across markdown-formatter, vault-reader, message-store
2026-02-25 14:16:21 -08:00
Joel Hooks f4e569cf9e feat: extract message-store to @joelclaw/message-store (ADR-0144)
795-line message-store.ts extracted to standalone package with:
- TelemetryEmitter DI (same pattern as model-fallback)
- ioredis as peer dep
- 6 tests passing
- Gateway consumers updated to import from package
- Old file deleted
2026-02-25 14:10:53 -08:00
Joel Hooks 3f12d4e917 sync: vault content (2 files)
adrs (2):
  updated: 0144-gateway-hexagonal-architecture.md
  updated: 0143-ast-based-message-formatting.md
2026-02-25 14:08:13 -08:00
Joel Hooks 383de333dc feat(subscriptions): include entry links in gateway notifications
Subscription update notifications now include links array with
title + url for up to 5 entries. No more linkless blurbs.
2026-02-25 14:06:35 -08:00
Joel Hooks 7d1e2928f1 fix(gateway): prevent compaction/fallback race, fix iMessage backoff
Three fixes for gateway stability:

1. Proactive compaction now blocks the drain loop (awaited, not fire-and-forget).
   Pauses fallback timeout watch during compaction and resumes after with a
   fresh timeout window. Prevents false fallback triggers when compaction
   takes >90s.

2. iMessage connectAndRun() now rejects (not resolves) when socket closes
   before connecting. This preserves the exponential backoff counter —
   previously every ENOENT resolved the promise, resetting backoff to 0
   and causing 5s spam forever.

3. ModelFallbackController gains pauseTimeoutWatch()/resumeTimeoutWatch()
   for known slow operations (compaction, session migration) where no
   streaming tokens are expected.
2026-02-25 14:03:49 -08:00
Joel Hooks 48f253bf2f feat: add validate() to FormatConverter + Telegram HTML validator (ADR-0143)
- ValidationResult/ValidationError/ValidationWarning types on FormatConverter interface
- 9 Telegram-specific rules: unsupported tags, balanced tags, nested pre/links,
  max-length, entity count, valid href, empty tags, ampersand escaping
- Stack-based single-pass string scan — no DOM parsing
- TelegramConverter.validate() wired to validateTelegramHtml()
- 12/12 validator tests + 9 existing converter tests green (21/21)
2026-02-25 13:52:34 -08:00
Joel Hooks 714baf18c1 skill(codex-prompting): add no-polling rule for codex_tasks
Trust the widget. Check once at ~60s, never poll in a loop.
2026-02-25 13:52:18 -08:00
Joel Hooks 7a3e60aa46 refactor: extract model-fallback into standalone package (ADR-0144)
- New @joelclaw/model-fallback with TelemetryEmitter port (DI)
- Gateway imports from package, passes emitGatewayOtel adapter
- FallbackConfig type owned by model-fallback package
- 6/6 unit tests passing (fake timers, telemetry, recovery)
- Removed gateway/src/model-fallback.ts
2026-02-25 13:50:11 -08:00
Joel Hooks e4027e0fe9 sync: vault content (2 files)
adrs (2):
  new: 0144-gateway-hexagonal-architecture.md
  new: 0143-ast-based-message-formatting.md
2026-02-25 13:48:30 -08:00
Joel Hooks b539cfd08f refactor: extract markdown-formatter into shared package (ADR-0143)
- New @joelclaw/markdown-formatter package with FormatConverter interface
- TelegramConverter as first implementation (Telegram HTML from AST)
- Shared parser, escape, chunker modules for future platform converters
- Removed gateway-local ast-telegram.ts (moved to shared package)
- 9/9 tests passing
2026-02-25 13:46:36 -08:00
Joel Hooks 742703af98 feat(gateway): AST-based Telegram HTML formatter (ADR-0143)
Replace regex md→HTML with unified/remark AST pipeline:
- Parse markdown → mdast, walk tree → emit Telegram HTML
- Escape only text nodes (no double-escaping)
- Parser-aware chunking at node boundaries (CHUNK_MAX=4000)
- Sub-split oversized code blocks
- 9/9 tests passing
2026-02-25 13:43:14 -08:00
Joel Hooks 1150defd08 fix(telegram): protect existing HTML tags from double-escaping in mdToTelegramHtml
LLM responses containing valid Telegram HTML tags (<b>, <code>, etc.) were
being escaped to &lt;b&gt; by escapeHtml() before markdown conversion.
Now protects valid Telegram tags with placeholders before escaping, same
pattern used for code blocks and links.

Also: added shipped + all ADR status variants to site status-config.
2026-02-25 13:28:36 -08:00
Joel Hooks ed949617a3 feat(ADR-0140): complete inference router — tests, gateway alignment, Langfuse on all paths, TS clean
- 16 unit tests for inference-router (catalog + router)
- Gateway model-fallback.ts wired to inference-router catalog
- Langfuse traces every inference call (success + failure)
- Strict/permissive mode based on NODE_ENV
- All TS errors fixed across system-bus and gateway
- ADR status page: added shipped + all status variants
2026-02-25 13:26:16 -08:00
Joel Hooks 9db4b35072 feat(gateway): proactive context monitoring, iMessage backoff, router observability
Proactive context health (ADR-0141):
- After each turn_end, estimate context token usage via session entries
- At 70%: log elevated warning + OTEL event
- At 85%: force proactive compaction BEFORE the next prompt blows up
- Context health exposed in gateway status payload (entries, tokens, percent, health)

iMessage exponential backoff:
- Replace fixed 5s reconnect with exponential backoff (5s → 5min max)
- Only log first failure and every 10th attempt to reduce log spam
- Reset backoff on successful connection

Outbound router:
- Log when no channel handler found (was silently returning)
2026-02-25 13:10:43 -08:00
Joel Hooks 658b79950c feat(gateway): add telegram outbound debug logging
Logs chatId, textLength, source, and success/failure for every
outbound Telegram send. Missing observability here made it impossible
to distinguish 'response generated but not sent' from 'response sent
but Telegram didn't deliver'.
2026-02-25 13:07:41 -08:00
Joel Hooks fc4ca57404 feat(skills): add adr-skill and codex-prompting skills 2026-02-25 13:06:46 -08:00
Joel Hooks 21cfd3a746 feat(self-healing): expand self-healing router, investigator, and gateway bridge
- self-healing-router: major expansion (+520 lines)
- self-healing-investigator: enhanced diagnostics
- self-healing-gateway-bridge: new function for gateway recovery
- check-system-health: expanded health checks
- Observability triage and restart-worker updates
2026-02-25 13:06:42 -08:00
Joel Hooks 2af6a9dc79 feat(inference-router): extract inference routing to shared package (ADR-0140)
- New @joelclaw/inference-router package
- Refactored inference.ts with expanded capabilities
- Updated all system-bus functions to use new inference lib
- CLI and gateway package updates for inference-router imports
2026-02-25 13:06:37 -08:00
Joel Hooks cbaf07e967 feat(gateway): context overflow auto-recovery with compression summary
When the API returns 'prompt is too long':
1. First attempt: aggressive compaction + retry
2. If still overflowing: build compression summary from recent session
   entries (last 10 user messages, last 3 assistant responses, channel info)
3. Force new session, inject summary as first message
4. Replay the failed message into the fresh session
5. Alert Joel via Telegram

The compression summary is built locally from the JSONL entries without
an LLM call (since the whole problem is we can't reach the API with
the current context). It captures enough recent activity to maintain
conversational continuity.

Addresses the silent failure where gateway processed inbound messages
(acked from stream) but every API call 400'd for hours with zero
recovery action.
2026-02-25 13:03:02 -08:00
Joel Hooks bb3e3fb008 fix: CLI import inference-router directly instead of relative gateway path
The relative import ../../gateway/src/commands/config.ts caused CLI to
transitively resolve @joelclaw/inference-router from gateway's node_modules
context, which Bun couldn't find. Import GATEWAY_ALLOWED_MODELS directly
from the workspace package.
2026-02-25 12:53:13 -08:00
Joel Hooks 73a3accdc3 sync: vault content (1 files)
adrs (1):
  updated: 0140-unified-joelclaw-inference-router.md
2026-02-25 10:15:33 -08:00
Joel Hooks 07730ff043 sync: vault content (1 files)
adrs (1):
  updated: 0140-unified-joelclaw-inference-router.md
2026-02-25 10:04:16 -08:00
Joel Hooks 99ccccf673 sync: vault content (1 files)
adrs (1):
  updated: 0140-unified-joelclaw-inference-router.md
2026-02-25 09:35:37 -08:00
Joel Hooks ae0cb9dcaf sync: vault content (1 files)
adrs (1):
  updated: 0138-self-healing-backup-orchestrator.md
2026-02-25 09:18:27 -08:00
Joel Hooks 6a03af0d1a sync: vault content (1 files)
adrs (1):
  updated: 0138-self-healing-backup-orchestrator.md
2026-02-25 09:09:18 -08:00
Joel Hooks 0b77f83b7b sync: vault content (2 files)
adrs (2):
  updated: 0139-self-healing-sdk-investigator.md
  updated: 0138-self-healing-backup-orchestrator.md
2026-02-25 09:07:35 -08:00