Skip to content

Commit 631fae5

Browse files
committed
Fix recursion
1 parent 5317dc4 commit 631fae5

File tree

2 files changed

+101
-79
lines changed

2 files changed

+101
-79
lines changed

packages/server/agents/src/lib/Agent.ts

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class Channel extends (EventEmitter as new () => TypedEmitter<ChannelEvents>) {
106106
...data,
107107
channel: this.channelId,
108108
}
109-
return this.agent.handleChannelEvent(this.channelId, event, eventData)
109+
return super.emit(event, ...([eventData] as Parameters<ChannelEvents[K]>))
110110
}
111111
}
112112

@@ -486,33 +486,37 @@ export class Agent
486486
// Add channel method to get/create channel instance
487487
channel(channelId: string): Channel {
488488
if (!this.channels.has(channelId)) {
489-
this.channels.set(channelId, new Channel(channelId, this))
490-
}
491-
return this.channels.get(channelId)!
492-
}
489+
const channel = new Channel(channelId, this)
490+
491+
// Forward channel events to global agent events
492+
const forwardEvent = <K extends keyof ChannelEvents>(
493+
event: K,
494+
data: Parameters<ChannelEvents[K]>[0]
495+
) => {
496+
super.emit(event, ...([data] as Parameters<AgentEvents[K]>))
497+
}
498+
499+
// Set up event forwarding
500+
channel.on('message', data => forwardEvent('message', data))
501+
channel.on('messageReceived', data =>
502+
forwardEvent('messageReceived', data)
503+
)
504+
channel.on('messageStream', data => forwardEvent('messageStream', data))
505+
channel.on('eventComplete', data => forwardEvent('eventComplete', data))
506+
channel.on('error', data => forwardEvent('error', data))
493507

494-
// Internal method to handle channel events
495-
handleChannelEvent<K extends keyof AgentEvents>(
496-
channelId: string,
497-
event: K,
498-
data: Parameters<AgentEvents[K]>[0]
499-
): boolean {
500-
const channel = this.channels.get(channelId)
501-
if (channel) {
502-
super.emit(event, ...([data] as Parameters<AgentEvents[K]>)) // Global emit
503-
return channel.emit(event, data) // Channel-specific emit
508+
this.channels.set(channelId, channel)
504509
}
505-
return false
510+
return this.channels.get(channelId)!
506511
}
507512

508-
// Override emit to support channel routing
509513
emit<K extends keyof AgentEvents>(
510514
event: K,
511515
data: Parameters<AgentEvents[K]>[0]
512516
): boolean {
513517
const channelId = (data as any)?.channel
514518
if (channelId) {
515-
return this.handleChannelEvent(channelId, event, data)
519+
return this.channel(channelId).emit(event, data)
516520
}
517521
return super.emit(event, ...([data] as Parameters<AgentEvents[K]>))
518522
}

packages/server/nitroModule/src/runtimes/plugins/initializeAgent.ts

Lines changed: 79 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -9,80 +9,98 @@ import { PrismaClient } from '@magickml/server-db'
99
import { v4 as uuidv4 } from 'uuid'
1010
import fs from 'fs'
1111

12-
const prisma = new PrismaClient()
12+
// Create a single PrismaClient instance to be reused
13+
const prisma = new PrismaClient({
14+
log: ['error'],
15+
datasources: {
16+
db: {
17+
url: process.env.DATABASE_URL,
18+
},
19+
},
20+
})
1321

1422
type Config = NitroRuntimeConfig & AgentInterface
1523

1624
export default defineNitroPlugin(async nitroApp => {
17-
const app = (await initApp()) as any
18-
19-
const runtimeConfig = useRuntimeConfig<Config>()
20-
const config = { ...runtimeConfig }
21-
22-
nitroApp.agentServer = app
25+
try {
26+
const app = (await initApp()) as any
27+
const runtimeConfig = useRuntimeConfig<Config>()
28+
const config = { ...runtimeConfig }
2329

24-
let agentId: string | undefined
30+
nitroApp.agentServer = app
2531

26-
try {
27-
const configFile = fs.readFileSync('agent-config.json', 'utf8')
28-
const configData = JSON.parse(configFile)
29-
agentId = configData.AGENT_ID
30-
} catch (error) {
31-
console.error('Error reading agent-config.json:', error)
32-
}
32+
let agentId: string | undefined
3333

34-
agentId = agentId || runtimeConfig.agentId || uuidv4()
34+
try {
35+
const configFile = fs.readFileSync('agent-config.json', 'utf8')
36+
const configData = JSON.parse(configFile)
37+
agentId = configData.AGENT_ID
38+
} catch (error) {
39+
console.error('Error reading agent-config.json:', error)
40+
}
3541

36-
const existingAgent = await prisma.agents.findUnique({
37-
where: {
38-
id: agentId,
39-
},
40-
})
41-
42-
if (!existingAgent) {
43-
const agent = await prisma.agents.create({
44-
data: {
45-
id: agentId as string,
46-
name: agentId as string,
47-
enabled: true,
48-
version: '2.0',
49-
updatedAt: new Date().toISOString(),
50-
createdAt: new Date().toISOString(),
51-
isDraft: false,
52-
projectId: runtimeConfig.projectId || 'default',
53-
worldId: runtimeConfig.worldId || 'default',
54-
},
42+
agentId = agentId || runtimeConfig.agentId || uuidv4()
43+
44+
// Use a single transaction for database operations
45+
const agent = await prisma.$transaction(async tx => {
46+
const existingAgent = await tx.agents.findUnique({
47+
where: { id: agentId },
48+
})
49+
50+
if (!existingAgent) {
51+
const newAgent = await tx.agents.create({
52+
data: {
53+
id: agentId as string,
54+
name: agentId as string,
55+
enabled: true,
56+
version: '2.0',
57+
updatedAt: new Date().toISOString(),
58+
createdAt: new Date().toISOString(),
59+
isDraft: false,
60+
projectId: runtimeConfig.projectId || 'default',
61+
worldId: runtimeConfig.worldId || 'default',
62+
},
63+
})
64+
65+
const configData = { AGENT_ID: newAgent.id }
66+
fs.writeFileSync(
67+
'agent-config.json',
68+
JSON.stringify(configData, null, 2)
69+
)
70+
71+
config.agentId = newAgent.id
72+
config.id = newAgent.id
73+
74+
return newAgent
75+
}
76+
77+
config.agentId = existingAgent.id
78+
config.projectId = existingAgent.projectId || 'default'
79+
config.id = existingAgent.id
80+
81+
return existingAgent
5582
})
5683

57-
console.log('Agent created:', agent.id)
58-
console.log('AGHHHH')
84+
console.log('Agent configured:', agent.id)
5985

60-
// Double-check that the agent was created
61-
const verifyAgent = await prisma.agents.findUnique({
62-
where: { id: agent.id },
63-
})
86+
// Create agent instance
87+
const agentInstance = new Agent(config, app.get('pubsub'), app)
88+
await agentInstance.waitForInitialization()
89+
await agentInstance.spellbook.loadSpells(magickSpells)
6490

65-
if (!verifyAgent) {
66-
console.error('Agent creation failed or not immediately visible')
67-
} else {
68-
console.log('Agent verified in database')
69-
}
91+
nitroApp.agent = agentInstance
7092

71-
const configData = { AGENT_ID: agent.id }
72-
fs.writeFileSync('agent-config.json', JSON.stringify(configData, null, 2))
93+
// Add cleanup on process termination
94+
const cleanup = async () => {
95+
await prisma.$disconnect()
96+
// Add any other cleanup needed
97+
}
7398

74-
config.agentId = agent.id
75-
config.id = agent.id
76-
} else {
77-
console.log('Existing agent found:', existingAgent.id)
78-
config.agentId = existingAgent.id
79-
config.projectId = existingAgent.projectId || 'default'
80-
config.id = existingAgent.id
99+
process.on('SIGINT', cleanup)
100+
process.on('SIGTERM', cleanup)
101+
} catch (error) {
102+
console.error('Error initializing agent:', error)
103+
await prisma.$disconnect()
104+
throw error
81105
}
82-
// // use data and app to create agent
83-
const agent = new Agent(config, app.get('pubsub'), app)
84-
await agent.waitForInitialization()
85-
await agent.spellbook.loadSpells(magickSpells)
86-
87-
nitroApp.agent = agent
88106
})

0 commit comments

Comments
 (0)