Skip to content

docs: inline x402 types to avoid shared type bleed#37

Open
Dexploarer wants to merge 139 commits intoJejuNetwork:developfrom
Dexploarer:codex/fix-docs-a2a-elysia-type-boundary
Open

docs: inline x402 types to avoid shared type bleed#37
Dexploarer wants to merge 139 commits intoJejuNetwork:developfrom
Dexploarer:codex/fix-docs-a2a-elysia-type-boundary

Conversation

@Dexploarer
Copy link
Contributor

Summary

  • Removed @jejunetwork/shared type coupling from apps/documentation/lib/x402.ts.
  • Added local PaymentRequirements, PaymentScheme, and X402Network type definitions in documentation package.
  • Kept createPaymentRequirement behavior and exports unchanged while avoiding shared package type leakage.

Why

The previous import chain in docs pulled @jejunetwork/shared (which depends on elysia) and introduced a duplicate AnyElysia type instance during docs typecheck.

Verification

  • bun run --cwd apps/documentation typecheck

hellno and others added 30 commits January 12, 2026 21:33
…Markdown

Add support for fenced code blocks with basic JSON syntax highlighting.
No external dependencies - uses regex tokenizing with inline styles.
- Add READ_ROOM_ALERTS, SEARCH_DISCUSSIONS, POST_GITHUB_DISCUSSION actions
- Register crucible actions in getAvailableActions() so LLM can see them
- Add POST_TO_ROOM action for inter-agent room communication
- Create daily-digest character for GitHub Discussion reporting
- Update character prompts with [ACTION:...] format instructions
- Add fallback to room when GitHub posting fails
- Fix type errors (bigint conversion, SQLitClient config, logging)
- Consolidate autonomous agent config into AUTONOMOUS_AGENTS
…robing

- New action probes DWS health and inference node endpoints
- Returns actual latency, status, and node count data
- Node-monitor now uses GET_INFRA_HEALTH instead of generating fictional data
- Workflow: GET_INFRA_HEALTH → format as NODE_SNAPSHOT → POST_TO_ROOM
- Replace node-monitor, infra-analyzer, endpoint-prober with infra-monitor
- New GET_INFRA_STATUS action: probes + threshold evaluation in code
- LLM only formats alerts when status != HEALTHY
- Thresholds: P0 (unhealthy/unreachable), P1 (>5s), P2 (>2s)
- Simplified AUTONOMOUS_AGENTS: just infra-monitor + daily-digest
Crucible:
- Add code-first execution mode for autonomous agents
- InfraMonitor now runs GET_INFRA_STATUS in code, only invokes LLM for alerts
- Auto-post LLM responses to rooms (no action syntax needed)
- Add health-format.ts for templated health snapshots
- Constrain daily-digest to only use allowed actions
- Update character prompts to clarify LLM role is formatting only

Indexer:
- Add dwsUrl to IndexerConfig
- Fix entity metadata error by using symlink instead of copy for lib/model
- This ensures TypeORM and init.ts use same module instance
Implements clean duplicate avoidance for agents reading room messages:

- Add 'after' parameter to READ_ROOM_ALERTS for watermark-based filtering
- Add roomWatermarks Map to RegisteredAgent for per-room tracking
- Auto-inject watermark before READ_ROOM_ALERTS execution
- Auto-update watermark from latestTimestamp in response
- Return message IDs and timestamps for client tracking

This prevents agents like daily-digest from reprocessing the same
messages on consecutive ticks, without introducing new database
tables or breaking existing patterns.
Replace per-room watermark tracking with simpler previousTick-based
filtering. When an agent calls READ_ROOM_ALERTS, automatically use
the agent's previousTick timestamp to filter out already-seen messages.

Before: ~50 lines with roomWatermarks Map, inject/update logic
After: 3 lines using existing previousTick field

This is 80/20 - covers the daily-digest use case without overhead.
The paymaster contracts use BasePaymaster(entryPoint, owner) which requires
v0.9.0 of account-abstraction. v0.7.0 only has a single-argument constructor.

Also fixes SimpleAccountFactory import path which moved from samples/ to
accounts/ in v0.9.0.
- Fix indexer port: 4355 → 4004 (REST API with /health endpoint)
- Fix inference node parsing: endpoint returns array directly, not { nodes: [...] }
- Add oracle (4301), jns (4302), sqlit (4661) health checks
- Update health snapshot format to include all 6 services
- Increase activity message truncation limit: 100 → 250 chars
- Add GENERATE_DAILY_DIGEST action that deterministically:
  - Reads 24h of messages from infra-monitoring room
  - Parses health check and alert messages
  - Calculates uptime %, latency trends, alert counts
  - Checks for duplicate same-day digest
  - Posts to GitHub Discussions (or room fallback)
- Configure daily-digest with executionMode: 'code-first'
- Make healthyTemplate optional in CodeFirstConfig
- Update code-first execution to skip health snapshot when no template
- Fix agent registration endpoint to use AUTONOMOUS_AGENTS overrides
- Add one-shot /api/cron/agent-tick-once endpoint
- Remove duplicate autonomous/cron.ts (use cron/index.ts)
- Add crucible CLAUDE.md with architecture notes
Monitors indexer for new agent registrations and announces them to the
infra-monitoring room. Uses watermark-based deduplication to avoid
duplicate announcements.
- Add comprehensive debug logging to OAuth3 client SDK (login flow,
  wallet auth, session creation)
- Add debug logging to OAuth3Provider initialization
- Add debug logging to useJejuAuth hook
- Create useUnifiedAuth hook to bridge OAuth3 and wagmi auth systems
- Update AuthButton to trigger OAuth3 login after wagmi connection
- Add WebCrypto availability checks in storage-integration and
  threshold-encryption to prevent undefined errors
- Fix OAuth3 logout to handle 401/404 gracefully

Bazaar UI updates:
- Implement "Nocturne Bazaar" dark theme with emerald/teal accents
- Add new logo and landing background assets
- Add animated Stars component for landing page
- Update Header to use unified auth system
- Make app mobile responsive

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ndpoint

Adds auto-registration from chain when agent not in runner, fixing the
Execute button on AgentDetail which was calling the wrong endpoint.
Remove 8 LARPY/redundant autonomous agents:
- LARPY chat agents: sentinel, jimmy (project-manager), eddy (devrel),
  ruby (liaison), laura (social-media-manager)
- Redundant autonomous stubs: node-monitor, infra-analyzer, endpoint-prober

These agents had no working backend implementations - only system prompts
with placeholder action syntax. The 3 autonomous stubs were replaced by
infra-monitor's consolidated code-first execution.

Add 4 test agents to showcase capabilities:
- test-trader: demonstrates canTrade with SWAP_TOKENS action
- test-coordinator: demonstrates a2a with CALL_AGENT action
- test-voter: demonstrates canVote with voteAction
- test-computer: demonstrates compute with RUN_INFERENCE action

All test agents use llm-driven execution mode to showcase AI decision-making.

Update coreAgentIds in server.ts to only seed community-manager (Eli5)
as the sole chat-only agent for user onboarding.

Remaining agents (6 → 10):
- 3 system autonomous: infra-monitor, daily-digest, registration-watcher
- 2 capability-enabled: security-analyst (Auditor), base-watcher (BaseWatch)
- 1 chat-only: community-manager (Eli5)
- 4 test agents: test-trader, test-coordinator, test-voter, test-computer
Complete runtime state persistence for autonomous agents with minimal
storage footprint and cron schedule state tracking.

Runtime State Persistence:
- Persist only 3 minimal fields: previous_tick, last_tick, last_scheduled_run
- Restore runtime state from DB on server restart
- Best-effort persistence (log errors, don't fail ticks)
- State survives server restarts (no duplicate processing)

Cron Schedule State:
- Update lastScheduledRun when cron agents execute
- Cron mode (/agent-tick) only runs scheduled agents
- Manual mode (/agent-tick-once) runs any agent
- Manual ticks don't update schedule state

Agent ID Architecture:
- Use numeric on-chain IDs (7, 8) instead of prefixes (onchain-agent-7)
- Auto-register agents from chain on first tick
- Remove server-side bootstrap (use script instead)

Bootstrap Script:
- New localnet-only bootstrap script at scripts/bootstrap-autonomous-agents.ts
- Registers missing on-chain agents via API
- Inserts/updates SQLit config with enabled=0
- Preserves existing non-numeric legacy rows

Files Modified:
- api/autonomous/index.ts: Add runtime state persistence, restore state
  on load, implement cron vs manual mode, update lastScheduledRun
- api/server.ts: Load agents from DB with numeric IDs, restore runtime
  state, remove server-side bootstrap
- api/cron/index.ts: Add mode parameter, auto-register agents from chain
- api/sdk/database.ts: Update agent methods for runtime_state
- api/characters/index.ts: Add test-computer cron schedule for testing
- scripts/bootstrap-autonomous-agents.ts: New bootstrap script

Testing:
- Manual ticks complete successfully with inference node
- Cron mode gates execution (0 agents run when no schedules)
- Manual mode executes all agents (2 executed, 2 succeeded)
- Agents use numeric IDs with no prefixes
- Runtime state structure verified in code (minimal 3 fields)

Phase 3 Goals Achieved:
✓ Watermark preservation (previous_tick persists)
✓ Cron schedule state (last_scheduled_run persists)
✓ Minimal runtime_state (only 3 fields)
✓ Numeric agent IDs (no prefixes)
✓ Auto-registration from chain
**Problem**: Concurrent agent ticks shared agent.currentTrajectoryId state,
causing intermittent 'No current step for trajectory' errors (60-70% success rate).

**Root Cause**: When autonomous runner is running, registerAgent() auto-starts
a tick. Manual tick-once calls on the same agent create a second concurrent tick.
Both ticks overwrote each other's trajectory IDs, causing one to delete the
other's trajectory mid-execution.

**Solution**: Capture trajectory ID in local variable per tick execution instead
of using shared agent state. Each tick now owns its trajectory lifecycle.

**Changes**:
- api/autonomous/index.ts:
  - executeSingleAgentTick: Use localTrajectoryId (lines 471-521)
  - startAgentTicks: Use localTrajectoryId (lines 577-638)
  - Add UPLOAD_FILE action gating with canStore capability
  - Add storage category detection for action filtering

- api/cron/index.ts:
  - Load autonomous_config from DB when auto-registering agents (lines 304-377)
  - Merge DB capabilities with character capabilities
  - Restore runtime state (lastTick, previousTick, lastScheduledRun)

- api/characters/index.ts:
  - Add test-storage character to AUTONOMOUS_AGENTS config
  - Configure canStore capability for storage demos

- api/characters/test-coordinator.ts:
  - Fix A2A endpoint to use local endpoint for testing

- api/characters/test-storage.ts:
  - New test character demonstrating storage capability

**Validated**:
- 100% agent execution success rate (up from 60-70%)
- Zero trajectory errors across 6+ test runs
- Agents load DB configs correctly after restart
- Message posting to rooms working (postToRoom from DB)
- Capability flags (canStore, compute, a2a) loaded from DB

**Test Results**:
- TestStorage (45): SUCCESS 1688ms
- TestComputer (44): SUCCESS 3079ms
- TestCoordinator (42): SUCCESS 2361ms

Co-authored-by: Claude <claude@anthropic.com>
**Debug Logging Added**:
- api/autonomous/index.ts:
  - [ACTION_FILTER] Log capabilities passed to getAvailableActions()
  - [ACTION_FILTER] Log final actions list with count and categories
  - [PROMPT_BUILD] Log actions being added to LLM prompt

**Character Prompt Improvements**:
All test characters now have explicit directives:
- CRITICAL: MUST use capability action on every tick
- DO NOT use infrastructure actions (GET_INFRA_HEALTH, GET_INFRA_STATUS, READ_ROOM_ALERTS)
- ONLY use designated capability action
- Step-by-step instructions with exact action format

Changed files:
- api/characters/test-storage.ts: Force UPLOAD_FILE usage
- api/characters/test-computer.ts: Force RUN_INFERENCE usage
- api/characters/test-coordinator.ts: Force CALL_AGENT usage

**Purpose**:
Verify capability flags are being loaded from DB and passed to action filtering.
Ensure LLM prioritizes capability actions over infrastructure actions.
**Issue 1: UPLOAD_FILE JSON Parse Error**

Problem: LLM copied placeholder '<current_unix_ms>' literally, causing JSON parse error
Root Cause: Placeholder syntax in prompt confused LLM into literal copying
Solution: Remove timestamp field, use simple valid JSON

Changes:
- api/characters/test-storage.ts:
  - Changed from: {"capability":"storage","timestamp":<current_unix_ms>,"demo":"..."}
  - To: {"capability":"storage","demo":"TestStorage upload"}
  - Updated message examples to match

**Issue 2: CALL_AGENT Handler Rejection**

Problem: Handler returned 'Please specify an agent to call' despite correct params
Root Cause: Handler parses message TEXT using regex for 'agent X skill Y' pattern,
            NOT JSON parameters. LLM was generating JSON-style output.
Solution: Update prompt to use natural language with embedded keywords

Investigation: packages/eliza-plugin/src/actions/a2a.ts
- Handler looks for: agentMatch = text.match(/agent\s+([^\s]+)/i)
- Requires keywords in natural language, not JSON structure

Changes:
- api/characters/test-coordinator.ts:
  - Prompt now specifies: 'call agent http://localhost:4021/a2a skill echo'
  - Clarifies: parser looks for 'agent' and 'skill' keywords in text
  - Warns against JSON format {agent: ..., skill: ...}
  - Updated message examples to use natural language

**Validation**:
- UPLOAD_FILE: JSON parsing verified with standalone test
- CALL_AGENT: Format matches handler regex expectations
- Both ready for runtime testing once Crucible reloads characters
Problem: LLM was shortening URL from http://localhost:4021/a2a to http://localhost:4021
Root cause: Prompt wasn't explicit enough about preserving /a2a path

Changes:
- Added CRITICAL FORMAT REQUIREMENTS section
- Explicit instruction: 'DO NOT shorten the URL to just http://localhost:4021'
- Added exact phrase to copy: 'call agent http://localhost:4021/a2a skill echo'
- Clarified lowercase formatting (call agent, skill)
- Updated message example to match

Format requirements now spell out:
- URL MUST include /a2a at the end
- Parser uses regex to extract 'agent X' and 'skill Y'
- Natural language with keywords, not JSON
Added to style.all array:
- 'ALWAYS include the exact phrase: call agent http://localhost:4021/a2a skill echo'
- 'DO NOT modify or shorten this URL under any circumstances'
- 'DO NOT remove /a2a from the endpoint'

This reinforces the system prompt and message examples with additional
constraints in the style directives which LLMs typically respect closely.
Documents detailed investigation of CALL_AGENT action rejection issue:
- Handler regex parsing mechanism analysis
- SDK auto-append discovery (endpoint + '/a2a')
- Character prompt evolution (4 iterations)
- Test results showing params extracted but validation fails
- 5 theories about root cause
- Critical unanswered questions about text flow
- Next debugging steps with code snippets
- Working hypothesis: dual code paths for action execution

Key finding: SDK auto-appends /a2a, so URL shortening is not the
actual problem. Issue likely in how LLM text flows from autonomous
executor to eliza-plugin handler.
Added debug logging at key points in the action execution flow:
- LLM response and parsed actions (autonomous/index.ts)
- Action execution with params (autonomous/index.ts)
- Handler received text and regex extraction (eliza-plugin a2a.ts)

Also cleaned up unused TypeScript imports/schemas in eliza-plugin.

To see debug output, set LOG_LEVEL=debug in .env and restart Crucible.
Removed unused Zod schema to fix TypeScript compilation error.
…tions-1769308209911

Add Claude Code GitHub Workflow
hellno and others added 29 commits January 29, 2026 18:08
…tection

- Remove parseEther() calls on minProposalStake (values already in wei)
- Use getCurrentNetwork() for health endpoint instead of hardcoded testnet
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The issue was that Tauri's frontendDist pointed to apps/node/app/dist/
but the build script output to apps/node/dist/static/. Frontend files
need to be copied to the correct location before Tauri build.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Returns user-friendly error if stake is below 0.01 ETH minimum.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…ngManager

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add unregisterDAO(daoId) method for targeted cleanup
- Add SIGTERM/SIGINT handlers to call shutdown() on process exit
- Ensures agent runtimes are cleaned up between deploys
Contract layer:
- Add submitProposal, updateProposalStatus, setDirectorApproval to IBoardGovernance
- Add getProposalsByDAO for listing proposals
- Create BoardGovernance.sol implementing the interface
- Singleton per network design (not per-DAO)
- Quality score stored off-chain (not manipulable)
- No staking in v1

API layer:
- Create ProposalService for BoardGovernance contract calls
- Update POST /dao/:daoId/proposals to use ProposalService
- Returns on-chain proposalId and txHash

Deployment:
- Add DeployBoardGovernance.s.sol script
- Localnet: 0x8F4ec854Dd12F1fe79500a1f53D0cbB30f9b6134

Verified: cast call confirms proposal stored on-chain
- Add VoteChoice enum and Vote struct to IBoardGovernance
- Implement castVote, getVotes, getVoteCounts, hasVoted in BoardGovernance
- Add vote methods to ProposalService for API integration
- Update MockBoard with voting stubs

Validated via cast: created proposal, cast votes, verified counts
- Add directorDecided bool to Proposal struct (immutable once set)
- setDirectorApproval now reverts with AlreadyDecided if already decided
- Add isDirectorDecided read function
- Update DirectorDecision event to include timestamp
- Add submitDirectorDecision and isDirectorDecided to ProposalService

Validated via cast: decision recorded, immutability enforced
feat(crucible): autonomous agent system with security analyst and improved onboarding
Resolve conflicts in:
- apps/crucible/api/worker.ts: Use main's explicit server code
- packages/config/contracts.json: Use main's contract addresses
- bun.lock: Regenerated
fix: ARM64 compatibility and documentation improvements
…ector setup

- Keep current branch configs (bun.lock, contracts.json, dws-localnet.json)
- Use cleaner ownership transfer pattern from PR
- Keep HEAD auth implementations using @jejunetwork/auth package
- Take Stars component from PR
- Merge NETWORK config import
# Conflicts:
#	packages/contracts/src/paymaster/LiquidityPaymaster.sol
#	packages/contracts/src/services/MultiTokenPaymaster.sol
Copy link

@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: d00448d689

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


// Call completeUnstaking() to complete the unbonding and receive tokens
// This will fail if unbonding period hasn't completed
let complete_data = hex::encode(&[0x68, 0x6a, 0x4f, 0x68]); // completeUnstaking() selector

Choose a reason for hiding this comment

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

P1 Badge Call completeUnbonding with service ID

The claim_rewards command builds raw calldata for completeUnstaking() and does not use the provided service identifier, while the same file’s IServiceStaking interface defines completeUnbonding(string serviceId). In the ServiceStaking flow introduced here, the claim/finalize action will submit a transaction with the wrong ABI shape and fail on-chain, so users cannot complete unbonding from the node UI.

Useful? React with 👍 / 👎.

<button
type="button"
onClick={() => {
setStakingService('multi-service')

Choose a reason for hiding this comment

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

P1 Badge Use a valid service ID for unstake actions

This unstake shortcut sets stakingService to 'multi-service', but handleUnstake passes that value straight into unstake(serviceId, amountWei). The staking backend introduced in this change only operates on concrete service IDs (e.g. storage, compute, proxy, etc.), so clicking this button routes users to an unstake call for a non-existent stake bucket and the transaction fails.

Useful? React with 👍 / 👎.

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.

4 participants