import React, { useState, useEffect, createContext, useContext } from 'react'; import type { ActionMessages, AppContextValue, PendingActionMessage, ChatMessages, SubtleAiImageOpts, SubtleAiCompleteOpts, GetMemoryOpts, AgentProps, ActionProps, PromptProps, ParserProps, PerceptionProps, SchedulerProps, ServerProps, } from './types'; import { AppContext, EpochContext, } from './context'; import { DefaultAgentComponents, } from './default-components'; // Note: this comment is used to remove imports before running tsdoc // END IMPORTS // const makeSymbol = () => Symbol('propsKey'); /** * Represents an agent component. * * The `Agent` component is used to register an agent with the application context. * It takes an `AgentProps` object as its props and registers the agent with the app context. * The `Agent` component should be used as a parent component for other components that need access to the agent. * * @param props The props for the `Agent` component. * @returns The rendered `Agent` component. * * @example * ```tsx * * {/* child components *\/} * * ``` */ export const Agent: React.FC = (props: AgentProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Agent component useEffect', props, appContext); return () => { // console.log('Agent component cleanup', props, appContext); appContext.unregisterAgent(symbol); }; }, [appContext]); appContext.registerAgent(symbol, props); return React.createElement(React.Fragment, {}, [ React.createElement(DefaultAgentComponents, { key: 0 }), React.createElement(React.Fragment, { key: 1 }, props.children), ]); }; export const RawAgent: React.FC = (props: AgentProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Agent component useEffect', props, appContext); return () => { // console.log('Agent component cleanup', props, appContext); appContext.unregisterAgent(symbol); }; }, [appContext]); appContext.registerAgent(symbol, props); return React.createElement(React.Fragment, {}, props.children); }; export const Action: React.FC = (props: ActionProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Action component useEffect', props, appContext); return () => { // console.log('Action component cleanup', props, appContext); appContext.unregisterAction(symbol); }; }, [appContext]); appContext.registerAction(symbol, props); return null; }; export const Prompt: React.FC = (props: PromptProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Prompt unregister', props, appContext); return () => { // console.log('Prompt register', props, appContext); appContext.unregisterPrompt(symbol); }; }, [appContext]); appContext.registerPrompt(symbol, props); return React.createElement(React.Fragment, {}, props.children); }; export const Parser: React.FC = (props: ParserProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Parser component useEffect', props, appContext); return () => { // console.log('Parser component cleanup', props, appContext); appContext.unregisterParser(symbol); }; }, [appContext]); appContext.registerParser(symbol, props); return null; }; export const Perception: React.FC = (props: PerceptionProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Perception component useEffect', props, appContext); return () => { // console.log('Perception component cleanup', props, appContext); appContext.unregisterPerception(symbol); }; }, [appContext]); appContext.registerPerception(symbol, props); return null; }; export const Scheduler: React.FC = (props: SchedulerProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Schedule component useEffect', props, appContext); return () => { // console.log('Schedule component cleanup', props, appContext); appContext.unregisterScheduler(symbol); }; }, [appContext]); appContext.registerScheduler(symbol, props); return null; }; export const Server: React.FC = (props: ServerProps) => { const [symbol, setSymbol] = useState(makeSymbol); // bind to app context const appContext = (useContext(AppContext) as unknown) as AppContextValue; useEffect(() => { // console.log('Schedule component useEffect', props, appContext); return () => { // console.log('Schedule component cleanup', props, appContext); appContext.unregisterServer(symbol); }; }, [appContext]); appContext.registerServer(symbol, props); // return React.createElement(React.Fragment, {}, props.children); return null; }; // export class ExtendableMessageEvent extends MessageEvent { private promises: Array> = []; constructor(type: string, opts: object) { super(type, opts); } waitUntil(promise: Promise) { this.promises.push(promise); } async waitForFinish() { await Promise.all(this.promises); } } export class SceneObject extends EventTarget { description: string; constructor({ description = 'A parallel virtual world populated by humans + AIs', }) { super(); this.description = description; } } export class AgentObject extends EventTarget { id: string; name: string; description: string; bio: string; model: string; address: string; ctx: AppContextValue; constructor({ id, name, description, bio, model, address, }: { id: string; name: string; description: string; bio: string; model: string; address: string; }, { context, }: { context: AppContextValue; }) { super(); this.id = id; this.name = name; this.description = description; this.bio = bio; this.model = model; this.address = address; this.ctx = context; } getActionHistory(): Promise { return this.ctx.getActionHistory(this); } async getMemory(query: string, opts?: GetMemoryOpts) { const result = await this.ctx.getMemory(this, query, opts); return result; } } export class SubtleAi { context: AppContextValue; constructor({ context, }: { context?: AppContextValue; } = {}) { this.context = context as AppContextValue; } async complete(messages: ChatMessages, opts?: SubtleAiCompleteOpts) { return await this.context.complete(messages, opts); } async generateImage(prompt: string, opts?: SubtleAiImageOpts) { return await this.context.generateImage(prompt, opts); } } export class ActiveAgentObject extends AgentObject { wallets: any; constructor( agent: AgentObject, { wallets, }: { wallets: any; } ) { super(agent, { context: agent.ctx, }); this.wallets = wallets; } async addAction(action: PendingActionMessage) { // console.log('active agent object add action 1', { // agent: this, // action, // }); await this.ctx.addAction(this, action); // console.log('active agent object add action 2'); } async addMemory(text: string, content?: any) { console.log('active agent object addMemory 1', { agent: this, text, }); const result = await this.ctx.addMemory(this, text, content); console.log('active agent object addMemory 2', result); return result; } async say(text: string) { // console.log('active agent object monologue 1', { // agent: this, // text, // }); const result = await this.ctx.say(this, text); // console.log('active agent object monologue 2', result); return result; } async monologue(text: string) { // console.log('active agent object monologue 1', { // agent: this, // text, // }); const result = await this.ctx.monologue(this, text); // console.log('active agent object monologue 2', result); return result; } async think(): Promise { return await this.ctx.think(this); } }