-
Notifications
You must be signed in to change notification settings - Fork 7
test(agent-003): add vitest unit tests for helper math #99
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
brawlaphant
wants to merge
3
commits into
regen-network:main
from
brawlaphant:test/agent-003-unit-tests
Closed
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| # Required: Anthropic API key for Claude-powered narrative reports | ||
| ANTHROPIC_API_KEY=sk-ant-... | ||
|
|
||
| # Regen LCD endpoint (defaults to public endpoint if not set) | ||
| REGEN_LCD_URL=https://regen.api.chandrastation.com | ||
|
|
||
| # Optional: Discord webhook for posting market reports and alerts | ||
| DISCORD_WEBHOOK_URL= | ||
|
|
||
| # Optional: polling interval in seconds (default: 300 = 5 minutes) | ||
| POLL_INTERVAL_SECONDS=300 | ||
|
|
||
| # Optional: Claude model to use (default: claude-sonnet-4-5-20250929) | ||
| ANTHROPIC_MODEL=claude-sonnet-4-5-20250929 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| node_modules/ | ||
| dist/ | ||
| *.db | ||
| *.db-shm | ||
| *.db-wal | ||
| .env |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,103 @@ | ||
| # AGENT-003: Regen Market Monitor | ||
|
|
||
| **Layer 1 (fully automated, read-only, informational) agent that watches the Regen ecocredit marketplace, detects price anomalies, tracks liquidity health, and summarizes retirement demand.** | ||
|
|
||
| Mirrors the AGENT-002 Governance Analyst structure: the same OODA executor, the same standalone Node.js process shape, the same SQLite-backed local state. The scope is marketplace intelligence rather than governance. | ||
|
|
||
| ## What it does | ||
|
|
||
| | Workflow | Trigger | Output | | ||
| |----------|---------|--------| | ||
| | **WF-MM-01** Price Anomaly Detection | New sell orders (SellOrderCreated / SellOrderFilled) | z-score anomaly alerts per severity, deduped | | ||
| | **WF-MM-02** Liquidity Monitoring | Periodic (every poll cycle) | Per-class liquidity health snapshot + trend vs previous | | ||
| | **WF-MM-03** Retirement Pattern Analysis | Periodic (every poll cycle) | Retirement volume, demand index, compliance metadata | | ||
|
|
||
| Each workflow is an **OODA loop** (Observe → Orient → Decide → Act) and persists both executions and domain state to SQLite. Numeric decisions (median, z-score, severity classification, health tier) are computed **deterministically**; Claude is only used for the narrative layer. | ||
|
|
||
| ## Architecture | ||
|
|
||
| ``` | ||
| Regen Ledger (LCD REST API) | ||
| ↓ observe | ||
| AGENT-003 (OODA engine) | ||
| ↓ orient (deterministic) | ||
| ↓ decide (deterministic) | ||
| Local SQLite (state) | ||
| ↓ act (narrative via Claude) | ||
| Console / Discord webhook | ||
| ``` | ||
|
|
||
| **No MCP dependency.** Talks directly to any Cosmos LCD endpoint. When Ledger MCP becomes available, the `LedgerClient` can be swapped behind the same interface. | ||
|
|
||
| **No ElizaOS dependency.** Standalone Node.js process. The ElizaOS character for AGENT-003 lives at `agents/packages/agents/src/characters/market-monitor.ts`; this package shares the same system prompt text and the same threshold constants so downstream tooling has a single source of truth. | ||
|
|
||
| ## Quick start | ||
|
|
||
| ```bash | ||
| # 1. Install | ||
| cd agent-003-market-monitor | ||
| npm install | ||
|
|
||
| # 2. Configure | ||
| cp .env.example .env | ||
| # Edit .env — at minimum set ANTHROPIC_API_KEY | ||
|
|
||
| # 3. Run (single analysis pass) | ||
| npm run analyze | ||
|
|
||
| # 4. Run (continuous polling) | ||
| npm start | ||
|
|
||
| # 5. Run (dev mode with auto-reload) | ||
| npm run dev | ||
| ``` | ||
|
|
||
| ## Configuration | ||
|
|
||
| | Variable | Required | Default | Description | | ||
| |----------|----------|---------|-------------| | ||
| | `ANTHROPIC_API_KEY` | Yes | — | Claude API key | | ||
| | `REGEN_LCD_URL` | No | `https://regen.api.chandrastation.com` | Cosmos LCD endpoint | | ||
| | `DISCORD_WEBHOOK_URL` | No | — | Discord webhook for posting reports | | ||
| | `POLL_INTERVAL_SECONDS` | No | `300` | Polling interval (seconds) | | ||
| | `ANTHROPIC_MODEL` | No | `claude-sonnet-4-5-20250929` | Claude model to use | | ||
|
|
||
| Thresholds live in `src/config.ts` under `market.*` and mirror the character definition at `agents/packages/agents/src/characters/market-monitor.ts`. | ||
|
|
||
| ## How it maps to the framework specs | ||
|
|
||
| | Framework Spec | Implementation | | ||
| |----------------|---------------| | ||
| | Phase 2.2 WF-MM-01 | `src/workflows/price-anomaly-detection.ts` | | ||
| | Phase 2.2 WF-MM-02 | `src/workflows/liquidity-monitor.ts` | | ||
| | Phase 2.2 WF-MM-03 | `src/workflows/retirement-tracking.ts` | | ||
| | Phase 2.4 OODA executor | `src/ooda.ts` | | ||
| | Phase 2.4 Agent character | `agents/packages/agents/src/characters/market-monitor.ts` | | ||
| | Phase 2.5 Workflow executions table | `src/store.ts` (SQLite) | | ||
| | Phase 3.2 Ledger MCP client | `src/ledger.ts` (direct LCD) | | ||
|
|
||
| ## Design decisions | ||
|
|
||
| 1. **Deterministic numbers, narrative-only LLM calls.** Anomaly classification, liquidity health scoring, and demand index computation are all deterministic. Claude is only invoked to write the narrative report from those numbers. This keeps the agent cheap, reproducible, and auditable. | ||
|
|
||
| 2. **Sell-order-as-trade proxy (MVP).** Until Ledger MCP exposes filled-trade events, the agent treats open sell orders as trade observations for the z-score baseline. An unusually high or low ask price is still a market structure signal worth surfacing, and the code path swaps cleanly when real trade events become available. | ||
|
|
||
| 3. **Batch supply delta as retirement source (MVP).** The MVP reads `retired_amount` from each batch supply and aggregates per class. A follow-up PR will plug in a real tx-stream client for `MsgRetire` once the LCD event endpoint is available. | ||
|
|
||
| 4. **Batch fan-out capped at 100.** WF-MM-03 caps the per-cycle batch fan-out to the most recent 100 batches so the agent doesn't hammer the LCD on a mainnet with thousands of historical batches. New retirement activity lands in new batches and will be picked up next cycle. | ||
|
|
||
| 5. **Dedupe by trade + severity.** WF-MM-01 only alerts once per `(trade_id, severity)` tuple. A trade that later escalates from WARNING to CRITICAL still fires a new alert; a trade that stays at the same severity does not. | ||
|
|
||
| 6. **Standalone over ElizaOS.** ElizaOS plugin API may change. A standalone process proves the workflow logic works independently of any runtime framework, matching AGENT-002's approach. | ||
|
|
||
| ## Governance layer | ||
|
|
||
| This agent operates at **Layer 1 only**: | ||
|
|
||
| - Read-only access to on-chain state | ||
| - Cannot submit proposals | ||
| - Cannot create, modify, or cancel sell orders | ||
| - Cannot execute transactions | ||
| - Informational output only | ||
|
|
||
| This matches the framework's principle of starting with the lowest-risk, highest-value capability. Raising the automation layer is a separate governance decision. | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The default model name
claude-sonnet-4-5-20250929mentioned in the configuration table appears to be a typo, with a future date. This could be confusing for users. Please update it to a valid model name to ensure clarity in the documentation.