Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/apis/agentcoinfun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
AgentWallet,
AgentWalletKind,
AgentWalletSchema,
ChatStatusBody,
CreateMessage,
ErrorResponseSchema,
HydratedMessage,
Expand Down Expand Up @@ -162,6 +163,19 @@ export class AgentcoinAPI {
return hydratedMessage
}

async sendStatus(newMessage: ChatStatusBody, options: { cookie: string }): Promise<void> {
const response = await fetch(`${AGENTCOIN_FUN_API_URL}/api/chat/status`, {
method: 'POST',
headers: { 'Content-Type': 'application/json', Cookie: options.cookie },
body: JSON.stringify(toJsonTree(newMessage))
})
if (response.status !== 200) {
const error = await response.json()
const parsed = ErrorResponseSchema.parse(error)
throw new Error(parsed.error)
}
}

async getDefaultWallet(
identity: Identity,
kind: AgentWalletKind,
Expand Down
44 changes: 34 additions & 10 deletions src/clients/agentcoin/agentcoinfun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
SentinelCommand,
SentinelCommandSchema,
ServiceKind,
UserDmEventSchema
MessageEventSchema
} from '@/common/types'
import * as fs from 'fs'

Expand Down Expand Up @@ -117,17 +117,30 @@ export class AgentcoinClient {
this.socket.on(eventName, async (data: unknown) => {
elizaLogger.info('Agentcoin client received event', data)
try {
const event = UserDmEventSchema.parse(data)
const event = MessageEventSchema.parse(data)
const channel = event.channel

if (channel.kind !== ChatChannelKind.DM) {
elizaLogger.info('Agentcoin client received msg for unknown channel', channel)
return
}

// validate channel
if (channel.firstIdentity !== identity && channel.secondIdentity !== identity) {
elizaLogger.info('Agentcoin client received msg for unknown channel', channel)
return
}

// process message if allowed
await this.processMessage(channel, [event.message])
switch (event.kind) {
case 'message': {
// process message if allowed
await this.processMessage(channel, event.data)
break
}
case 'status':
console.log('received status', event)
break
}
} catch (error) {
console.error('Error processing message from agentcoin client', error)
elizaLogger.error('Error processing message from agentcoin client', error)
Expand Down Expand Up @@ -267,6 +280,14 @@ export class AgentcoinClient {
return
}

const identity = await this.agentcoinService.getIdentity()

if (message.sender === identity) {
return
}

await this.agentcoinService.sendStatus(channel, 'thinking')

// `message` event
let shouldContinue = await this.runtime.handle('message', {
text: message.text,
Expand All @@ -277,12 +298,7 @@ export class AgentcoinClient {

if (!shouldContinue) {
elizaLogger.info('AgentcoinClient received message event but it was suppressed')
return
}

const identity = await this.agentcoinService.getIdentity()

if (message.sender === identity) {
await this.agentcoinService.sendStatus(channel, 'idle')
return
}

Expand Down Expand Up @@ -322,9 +338,12 @@ export class AgentcoinClient {

if (!shouldContinue) {
elizaLogger.info('AgentcoinClient received prellm event but it was suppressed')
await this.agentcoinService.sendStatus(channel, 'idle')
return
}

await this.agentcoinService.sendStatus(channel, 'typing')

const response = await generateMessageResponse({
runtime: this.runtime,
context,
Expand All @@ -341,10 +360,12 @@ export class AgentcoinClient {

if (!shouldContinue) {
elizaLogger.info('AgentcoinClient received postllm event but it was suppressed')
await this.agentcoinService.sendStatus(channel, 'idle')
return
}

if (isNull(response.text) || response.text.trim().length === 0) {
await this.agentcoinService.sendStatus(channel, 'idle')
return
}

Expand All @@ -370,6 +391,8 @@ export class AgentcoinClient {
return
}

await this.agentcoinService.sendStatus(channel, 'thinking')

// `preaction` event
shouldContinue = await this.runtime.handle('preaction', {
state,
Expand All @@ -379,6 +402,7 @@ export class AgentcoinClient {

if (!shouldContinue) {
elizaLogger.info('AgentcoinClient received preaction event but it was suppressed')
await this.agentcoinService.sendStatus(channel, 'idle')
return
}

Expand Down
43 changes: 36 additions & 7 deletions src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,13 +216,6 @@ export const KnowledgeSchema = z.object({

export type Knowledge = z.infer<typeof KnowledgeSchema>

export const UserDmEventSchema = z.object({
channel: DMChannelSchema,
message: HydratedMessageSchema
})

export type UserEvent = z.infer<typeof UserDmEventSchema>

// Character schema

export const CharacterMessageSchema = z.object({
Expand Down Expand Up @@ -367,3 +360,39 @@ export enum ServiceKind {
config = 'config-service',
agent = 'agent-service'
}

export const MessageStatusEnumSchema = z.enum(['idle', 'thinking', 'typing'])
export type MessageStatusEnum = z.infer<typeof MessageStatusEnumSchema>

export const MessageStatusSchema = z.object({
status: MessageStatusEnumSchema,
user: UserSchema,
createdAt: z.preprocess((arg) => (isRequiredString(arg) ? new Date(arg) : arg), z.date())
})

export type MessageStatus = z.infer<typeof MessageStatusSchema>

export const ChatStatusBodySchema = z.object({
channel: ChatChannelSchema,
status: MessageStatusEnumSchema
})

export type ChatStatusBody = z.infer<typeof ChatStatusBodySchema>

export const MessageEventKindSchema = z.enum(['message', 'status'])
export type MessageEventKind = z.infer<typeof MessageEventKindSchema>

export const MessageEventSchema = z.discriminatedUnion('kind', [
z.object({
kind: z.literal('message'),
data: HydratedMessageSchema.array(),
channel: DMChannelSchema
}),
z.object({
kind: z.literal('status'),
data: MessageStatusSchema,
channel: ChatChannelSchema
})
])

export type MessageEvent = z.infer<typeof MessageEventSchema>
14 changes: 14 additions & 0 deletions src/services/agentcoinfun.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import {
AgentProvisionResponse,
AgentProvisionResponseSchema,
AgentRegistrationSchema,
ChatChannel,
CreateMessage,
HydratedMessage,
Identity,
MessageStatusEnum,
ServiceKind,
User
} from '@/common/types'
Expand Down Expand Up @@ -48,6 +50,18 @@ export class AgentcoinService extends Service implements IAgentcoinService {
return this.cachedIdentity
}

async sendStatus(channel: ChatChannel, status: MessageStatusEnum): Promise<void> {
const cookie = await this.getCookie()

await this.api.sendStatus(
{
channel,
status
},
{ cookie }
)
}

async sendMessage(message: CreateMessage): Promise<HydratedMessage> {
const cookie = await this.getCookie()

Expand Down