Skip to content

Commit 65a421a

Browse files
authored
Merge PR #18: ARM64 compatibility
fix: ARM64 compatibility and documentation improvements
2 parents 28e37ff + 2c7c809 commit 65a421a

File tree

123 files changed

+13895
-1254
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

123 files changed

+13895
-1254
lines changed

.github/workflows/claude-code-review.yml

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ name: Claude Code Review
22

33
on:
44
pull_request:
5-
types: [opened, synchronize]
5+
types: [opened, synchronize, ready_for_review, reopened]
66
# Optional: Only run on specific file changes
77
# paths:
88
# - "src/**/*.ts"
@@ -36,22 +36,9 @@ jobs:
3636
uses: anthropics/claude-code-action@v1
3737
with:
3838
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
39-
prompt: |
40-
REPO: ${{ github.repository }}
41-
PR NUMBER: ${{ github.event.pull_request.number }}
42-
43-
Please review this pull request and provide feedback on:
44-
- Code quality and best practices
45-
- Potential bugs or issues
46-
- Performance considerations
47-
- Security concerns
48-
- Test coverage
49-
50-
Use the repository's CLAUDE.md for guidance on style and conventions. Be constructive and helpful in your feedback.
51-
52-
Use `gh pr comment` with your Bash tool to leave your review as a comment on the PR.
53-
39+
plugin_marketplaces: 'https://github.com/anthropics/claude-code.git'
40+
plugins: 'code-review@claude-code-plugins'
41+
prompt: '/code-review:code-review ${{ github.repository }}/pull/${{ github.event.pull_request.number }}'
5442
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
55-
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
56-
claude_args: '--allowed-tools "Bash(gh issue view:*),Bash(gh search:*),Bash(gh issue list:*),Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh pr list:*)"'
43+
# or https://code.claude.com/docs/en/cli-reference for available options
5744

.github/workflows/claude.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ jobs:
4545

4646
# Optional: Add claude_args to customize behavior and configuration
4747
# See https://github.com/anthropics/claude-code-action/blob/main/docs/usage.md
48-
# or https://docs.claude.com/en/docs/claude-code/cli-reference for available options
48+
# or https://code.claude.com/docs/en/cli-reference for available options
4949
# claude_args: '--allowed-tools Bash(gh pr:*)'
5050

apps/crucible/api/sdk/eliza-runtime.ts

Lines changed: 202 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,12 @@ import {
1717
} from '../client/dws'
1818
import { ROOMS } from '../constants'
1919
import { createLogger, type Logger } from './logger'
20+
import {
21+
createMemoryPersistence,
22+
type MemoryPersistenceService,
23+
type CommitResult,
24+
createWalletSigner,
25+
} from './memory-persistence'
2026

2127
// Store the original Eliza action handlers
2228
type ElizaActionHandler = Action['handler']
@@ -45,6 +51,16 @@ export interface RuntimeConfig {
4551
privateKey?: Hex
4652
/** Network to connect to */
4753
network?: NetworkType
54+
/** On-chain agent ID (bigint) for memory persistence */
55+
onChainAgentId?: bigint
56+
/** Character CID on IPFS */
57+
characterCid?: string
58+
/** Current state CID on IPFS */
59+
stateCid?: string
60+
/** Enable memory persistence to L2/IPFS (default: true if configured) */
61+
enableMemoryPersistence?: boolean
62+
/** Snapshot interval in ms (default: 60000) */
63+
memorySnapshotIntervalMs?: number
4864
}
4965

5066
export interface RuntimeMessage {
@@ -138,6 +154,9 @@ export class CrucibleAgentRuntime {
138154
// Jeju service instance
139155
private jejuService: StandaloneJejuService | null = null
140156

157+
// Memory persistence service for L2/IPFS commits
158+
private memoryPersistence: MemoryPersistenceService | null = null
159+
141160
constructor(config: RuntimeConfig) {
142161
this.config = config
143162
this.log = config.logger ?? createLogger(`Runtime:${config.agentId}`)
@@ -216,10 +235,71 @@ export class CrucibleAgentRuntime {
216235
await this.loadJejuPlugin()
217236
}
218237

238+
// Initialize memory persistence if configured
239+
if (
240+
this.config.enableMemoryPersistence !== false &&
241+
this.config.onChainAgentId &&
242+
this.config.characterCid &&
243+
this.config.stateCid &&
244+
this.jejuService
245+
) {
246+
try {
247+
const { loadDeployedContracts } = await import('@jejunetwork/config')
248+
const network =
249+
this.config.network ?? (getCurrentNetwork() as NetworkType)
250+
const contracts = loadDeployedContracts(network)
251+
const { createStorage } = await import('./storage')
252+
const { createKMSSigner } = await import('./kms-signer')
253+
254+
if (contracts.identityRegistry) {
255+
// Create storage service
256+
const storage = createStorage({
257+
apiUrl: getDWSEndpoint(),
258+
ipfsGateway: getDWSEndpoint().replace('/api', '/ipfs'),
259+
})
260+
261+
// Create signer from Jeju service wallet client
262+
const signer = createWalletSigner(
263+
this.jejuService.sdk.walletClient,
264+
this.jejuService.sdk.publicClient,
265+
)
266+
267+
this.memoryPersistence = createMemoryPersistence({
268+
agentId: this.config.onChainAgentId,
269+
characterCid: this.config.characterCid,
270+
stateCid: this.config.stateCid,
271+
identityRegistry: contracts.identityRegistry as `0x${string}`,
272+
storage,
273+
publicClient: this.jejuService.sdk.publicClient,
274+
signer,
275+
snapshotIntervalMs: this.config.memorySnapshotIntervalMs ?? 60000,
276+
enablePeriodicSnapshots: true,
277+
enableEventCommits: true,
278+
logger: this.log,
279+
})
280+
281+
await this.memoryPersistence.start()
282+
this.log.info('Memory persistence started', {
283+
agentId: this.config.onChainAgentId.toString(),
284+
snapshotInterval: this.config.memorySnapshotIntervalMs ?? 60000,
285+
})
286+
} else {
287+
this.log.warn(
288+
'IdentityRegistry not deployed - memory persistence disabled',
289+
)
290+
}
291+
} catch (err) {
292+
this.log.warn('Failed to initialize memory persistence', {
293+
error: err instanceof Error ? err.message : String(err),
294+
})
295+
}
296+
}
297+
219298
this.log.info('Agent runtime initialized', {
220299
agentId: this.config.agentId,
221300
characterName: this.config.character.name,
222301
actions: jejuActions.length,
302+
memoryPersistence: this.memoryPersistence !== null,
223303
})
224304

225305
this.initialized = true
@@ -438,6 +518,16 @@ export class CrucibleAgentRuntime {
438518
textLength: userText.length,
439519
})
440520

521+
// Record user message for persistence
522+
if (this.memoryPersistence) {
523+
this.memoryPersistence.recordMessage({
524+
roomId: message.roomId,
525+
userId: message.userId,
526+
content: userText,
527+
role: 'user',
528+
})
529+
}
530+
441531
// Determine model based on network and character preferences
442532
const network = getCurrentNetwork()
443533
const modelPrefs = this.config.character.modelPreferences
@@ -475,6 +565,21 @@ export class CrucibleAgentRuntime {
475565
? `${cleanText}\n\n${actionResultText}`
476566
: cleanText
477567

568+
// Record response and trigger event-based commit for action
569+
if (this.memoryPersistence) {
570+
this.memoryPersistence.recordMessage({
571+
roomId: message.roomId,
572+
userId: this.config.agentId,
573+
content: combinedText,
574+
role: 'assistant',
575+
action,
576+
})
577+
// Trigger immediate commit on action execution
578+
this.memoryPersistence.onActionExecuted(action, execResult.success).catch(err => {
579+
this.log.warn('Failed to commit after action', { error: String(err) })
580+
})
581+
}
582+
478583
return {
479584
text: combinedText,
480585
action,
@@ -494,6 +599,17 @@ export class CrucibleAgentRuntime {
494599
}
495600
}
496601

602+
// Record response message for persistence (no action case)
603+
if (this.memoryPersistence) {
604+
this.memoryPersistence.recordMessage({
605+
roomId: message.roomId,
606+
userId: this.config.agentId,
607+
content: cleanText,
608+
role: 'assistant',
609+
action,
610+
})
611+
}
612+
497613
return {
498614
text: cleanText,
499615
action,
@@ -1871,6 +1987,66 @@ _Generated by daily-digest agent at ${now.toISOString()}_`
18711987
return { success: false, error: errorMsg }
18721988
}
18731989
}
1990+
1991+
// ============================================
1992+
// Memory Persistence Methods
1993+
// ============================================
1994+
1995+
/**
1996+
* Get memory persistence stats
1997+
*/
1998+
getMemoryPersistenceStats(): {
1999+
enabled: boolean
2000+
pendingMessages: number
2001+
totalCommits: number
2002+
totalMessagesCommitted: number
2003+
lastCommitTime: number
2004+
currentStateCid: string | null
2005+
} | null {
2006+
if (!this.memoryPersistence) {
2007+
return { enabled: false, pendingMessages: 0, totalCommits: 0, totalMessagesCommitted: 0, lastCommitTime: 0, currentStateCid: null }
2008+
}
2009+
const stats = this.memoryPersistence.getStats()
2010+
return {
2011+
enabled: true,
2012+
...stats,
2013+
}
2014+
}
2015+
2016+
/**
2017+
* Manually trigger a memory commit
2018+
*/
2019+
async commitMemory(): Promise<CommitResult | null> {
2020+
if (!this.memoryPersistence) {
2021+
return null
2022+
}
2023+
return this.memoryPersistence.commit()
2024+
}
2025+
2026+
/**
2027+
* Notify session end (triggers commit)
2028+
*/
2029+
async onSessionEnd(roomId: string): Promise<CommitResult | null> {
2030+
if (!this.memoryPersistence) {
2031+
return null
2032+
}
2033+
return this.memoryPersistence.onSessionEnd(roomId)
2034+
}
2035+
2036+
/**
2037+
* Shutdown the runtime (commits pending memories)
2038+
*/
2039+
async shutdown(): Promise<CommitResult | null> {
2040+
let result: CommitResult | null = null
2041+
if (this.memoryPersistence) {
2042+
result = await this.memoryPersistence.stop()
2043+
this.log.info('Memory persistence stopped', {
2044+
committed: result?.messagesCommitted ?? 0,
2045+
})
2046+
}
2047+
this.initialized = false
2048+
return result
2049+
}
18742050
}
18752051

18762052
/**
@@ -1912,8 +2088,33 @@ export class CrucibleRuntimeManager {
19122088
}
19132089

19142090
async shutdown(): Promise<void> {
2091+
// Shutdown all runtimes and commit pending memories
2092+
const shutdownPromises = Array.from(this.runtimes.values()).map(
2093+
async (runtime) => {
2094+
try {
2095+
const result = await runtime.shutdown()
2096+
return { agentId: runtime.getAgentId(), result }
2097+
} catch (err) {
2098+
this.log.error('Failed to shutdown runtime', {
2099+
agentId: runtime.getAgentId(),
2100+
error: String(err),
2101+
})
2102+
return { agentId: runtime.getAgentId(), result: null }
2103+
}
2104+
},
2105+
)
2106+
2107+
const results = await Promise.all(shutdownPromises)
2108+
const totalCommitted = results.reduce(
2109+
(sum, r) => sum + (r.result?.messagesCommitted ?? 0),
2110+
0,
2111+
)
2112+
19152113
this.runtimes.clear()
1916-
this.log.info('All runtimes shut down')
2114+
this.log.info('All runtimes shut down', {
2115+
runtimes: results.length,
2116+
totalMessagesCommitted: totalCommitted,
2117+
})
19172118
}
19182119
}
19192120

0 commit comments

Comments
 (0)