Skip to content

Commit

Permalink
Merge pull request #30 from statelyai/davidkpiano/api-continued
Browse files Browse the repository at this point in the history
API improvements, continued
  • Loading branch information
davidkpiano committed Jun 1, 2024
2 parents 25fae30 + 2e0cdcb commit 276d118
Show file tree
Hide file tree
Showing 32 changed files with 3,918 additions and 4,521 deletions.
80 changes: 80 additions & 0 deletions examples/chatbot.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { z } from 'zod';
import { createAgent } from '../src';
import { openai } from '@ai-sdk/openai';
import { assign, createActor, log, setup } from 'xstate';
import { getFromTerminal } from './helpers/helpers';
import { fromDecision } from '../src';

const agent = createAgent({
name: 'chatbot',
model: openai('gpt-4-turbo'),
events: {
'agent.respond': z.object({
response: z.string().describe('The response from the agent'),
}),
'agent.endConversation': z.object({}).describe('Stop the conversation'),
},
});

const machine = setup({
types: {
context: {} as {
conversation: string[];
},
events: agent.eventTypes,
},
actors: { agent: fromDecision(agent), getFromTerminal },
}).createMachine({
initial: 'waiting',
context: {
conversation: [],
},
states: {
waiting: {
invoke: {
src: 'getFromTerminal',
input: 'User:',
onDone: {
actions: assign({
conversation: (x) =>
x.context.conversation.concat('User: ' + x.event.output),
}),
target: 'responding',
},
},
},
responding: {
invoke: {
src: 'agent',
input: (x) => ({
context: {
conversation: x.context.conversation,
},
goal: 'Respond to the user, unless they want to end the conversation.',
}),
},
on: {
'agent.respond': {
actions: [
assign({
conversation: (x) =>
x.context.conversation.concat('Assistant: ' + x.event.response),
}),
log((x) => `Agent: ${x.event.response}`),
],
target: 'waiting',
},
'agent.endConversation': 'finished',
},
},
finished: {
type: 'final',
},
},
exit: () => {
console.log('End of conversation.');
process.exit();
},
});

createActor(machine).start();
117 changes: 117 additions & 0 deletions examples/email.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { z } from 'zod';
import { createAgent, fromDecision } from '../src';
import { openai } from '@ai-sdk/openai';
import { assign, createActor, setup } from 'xstate';
import { getFromTerminal } from './helpers/helpers';

const agent = createAgent({
name: 'email',
model: openai('gpt-4'),
events: {
askForClarification: z.object({
questions: z.array(z.string()).describe('The questions to ask the agent'),
}),
submitEmail: z.object({
email: z.string().describe('The email to submit'),
}),
},
});

const machine = setup({
types: {
events: agent.eventTypes,
input: {} as {
email: string;
instructions: string;
},
context: {} as {
email: string;
instructions: string;
clarifications: string[];
replyEmail: string | null;
},
},
actors: { agent: fromDecision(agent), getFromTerminal },
}).createMachine({
initial: 'checking',
context: (x) => ({
email: x.input.email,
instructions: x.input.instructions,
clarifications: [],
replyEmail: null,
}),
states: {
checking: {
invoke: {
src: 'agent',
input: (x) => ({
context: {
email: x.context.email,
instructions: x.context.instructions,
clarifications: x.context.clarifications,
},
goal: 'Your goal is to respond to the email given the instructions and the provided clarifications. If not enough information is provided, ask for clarification. Otherwise, create and submit a response email.',
}),
},
on: {
askForClarification: {
actions: (x) => console.log(x.event.questions.join('\n')),
target: 'clarifying',
},
submitEmail: {
target: 'submitting',
},
},
},
clarifying: {
invoke: {
src: 'getFromTerminal',
input: `Please provide answers to the questions above`,
onDone: {
actions: assign({
clarifications: (x) =>
x.context.clarifications.concat(x.event.output),
}),
target: 'checking',
},
},
},
submitting: {
invoke: {
src: 'agent',
input: ({ context }) => ({
context: {
email: context.email,
instructions: context.instructions,
clarifications: context.clarifications,
},
goal: `Create and submit an email based on the instructions.`,
}),
},
on: {
submitEmail: {
actions: assign({
replyEmail: ({ event }) => event.email,
}),
target: 'done',
},
},
},
done: {
type: 'final',
entry: (x) => console.log(x.context.replyEmail),
},
},
exit: () => {
console.log('End of conversation.');
process.exit();
},
});

createActor(machine, {
input: {
email: 'That sounds great! When are you available?',
instructions:
'Tell them when I am available. Address them by his full (first and last) name.',
},
}).start();
5 changes: 3 additions & 2 deletions examples/example.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { z } from 'zod';
import { createAgent } from '../src';
import { createAgent, fromDecision, fromText } from '../src';
import { openai } from '@ai-sdk/openai';
import { assign, createActor, setup } from 'xstate';

const agent = createAgent({
name: 'example',
model: openai('gpt-4-turbo'),
events: {
'agent.englishSummary': z.object({
Expand All @@ -19,7 +20,7 @@ const machine = setup({
types: {
events: agent.eventTypes,
},
actors: { agent: agent.fromDecision(), summarizer: agent.fromText() },
actors: { agent: fromDecision(agent), summarizer: fromText(agent) },
}).createMachine({
initial: 'summarizing',
context: {
Expand Down
5 changes: 3 additions & 2 deletions examples/goal.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { z } from 'zod';
import { createAgent } from '../src';
import { createAgent, fromDecision } from '../src';
import { openai } from '@ai-sdk/openai';
import { assign, createActor, log, setup } from 'xstate';
import { getFromTerminal } from './helpers/helpers';

const agent = createAgent({
name: 'goal',
model: openai('gpt-4-turbo'),
events: {
'agent.createGoal': z.object({
Expand All @@ -16,7 +17,7 @@ const agent = createAgent({
},
});

const decider = agent.fromDecision();
const decider = fromDecision(agent);

const machine = setup({
types: {
Expand Down
19 changes: 12 additions & 7 deletions examples/joke.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { assign, createActor, fromCallback, log, setup } from 'xstate';
import { createAgent } from '../src';
import { createAgent, fromDecision } from '../src';
import { loadingAnimation } from './helpers/loader';
import { z } from 'zod';
import { openai } from '@ai-sdk/openai';
Expand Down Expand Up @@ -45,6 +45,7 @@ const loader = fromCallback(({ input }: { input: string }) => {
});

const agent = createAgent({
name: 'joke-teller',
model: openai('gpt-4-turbo'),
events: {
askForTopic: z.object({
Expand All @@ -59,12 +60,12 @@ const agent = createAgent({
explanation: z.string(),
}),
'agent.continue': z.object({}).describe('Continue'),
'agent.irrelevantJoke': z
'agent.markAsIrrelevant': z
.object({
explanation: z.string(),
})
.describe('Explains why the joke was irrelevant'),
'agent.relevantJoke': z.object({}).describe('The joke was relevant'),
'agent.markAsRelevant': z.object({}).describe('The joke was relevant'),
},
});

Expand All @@ -80,7 +81,7 @@ const jokeMachine = setup({
events: agent.eventTypes,
},
actors: {
agent: agent.fromDecision(),
agent: fromDecision(agent),
loader,
getFromTerminal,
},
Expand Down Expand Up @@ -129,7 +130,7 @@ const jokeMachine = setup({
assign({
jokes: ({ context, event }) => [...context.jokes, event.joke],
}),
log(({ event }) => event.joke),
log((x) => x.event.joke),
],
target: 'relevance',
},
Expand All @@ -147,12 +148,12 @@ const jokeMachine = setup({
}),
},
on: {
'agent.irrelevantJoke': {
'agent.markAsIrrelevant': {
actions: log((x) => 'Irrelevant joke: ' + x.event.explanation),
target: 'waitingForTopic',
description: 'Continue',
},
'agent.relevantJoke': {
'agent.markAsRelevant': {
actions: log('Joke was relevant'),
target: 'rateJoke',
},
Expand Down Expand Up @@ -223,4 +224,8 @@ const jokeMachine = setup({

const actor = createActor(jokeMachine);

agent.onMessage((msg) => {
console.log(msg);
});

actor.start();
7 changes: 4 additions & 3 deletions examples/multi.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { createAgent } from '../src';
import { createAgent, fromDecision } from '../src';
import { z } from 'zod';
import { assign, createActor, log, setup } from 'xstate';
import { getFromTerminal } from './helpers/helpers';
import { openai } from '@ai-sdk/openai';

const agent = createAgent({
name: 'multi',
model: openai('gpt-4-1106-preview'),
events: {
'agent.respond': z.object({
Expand All @@ -22,7 +23,7 @@ const machine = setup({
},
actors: {
getFromTerminal,
agent: agent.fromDecision(),
agent: fromDecision(agent),
},
}).createMachine({
initial: 'asking',
Expand Down Expand Up @@ -68,7 +69,7 @@ const machine = setup({
invoke: {
src: 'agent',
input: ({ context }) => ({
model: 'gpt-3.5-turbo-16k-0613',
model: openai('gpt-3.5-turbo-16k-0613'),
context,
goal: 'Debate the topic, and take the negative position. Respond directly to the last message of the discourse. Keep it short.',
}),
Expand Down
5 changes: 3 additions & 2 deletions examples/number.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { createAgent } from '../src';
import { createAgent, fromDecision } from '../src';
import { assign, createActor, log, setup } from 'xstate';
import { z } from 'zod';
import { openai } from '@ai-sdk/openai';
import { getFromTerminal } from './helpers/helpers';

const agent = createAgent({
name: 'number-guesser',
model: openai('gpt-3.5-turbo-1106'),
events: {
'agent.guess': z.object({
Expand All @@ -22,7 +23,7 @@ const machine = setup({
events: agent.eventTypes,
},
actors: {
agent: agent.fromDecision(),
agent: fromDecision(agent),
getFromTerminal,
},
}).createMachine({
Expand Down
5 changes: 3 additions & 2 deletions examples/raffle.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { z } from 'zod';
import { createAgent } from '../src';
import { createAgent, fromDecision } from '../src';
import { openai } from '@ai-sdk/openai';
import { assign, createActor, log, setup } from 'xstate';
import { getFromTerminal } from './helpers/helpers';

const agent = createAgent({
name: 'raffle-chooser',
model: openai('gpt-4-turbo'),
events: {
'agent.collectEntries': z.object({}).describe('Collect more entries'),
Expand All @@ -28,7 +29,7 @@ const machine = setup({
},
events: {} as typeof agent.eventTypes | { type: 'draw' },
},
actors: { agent: agent.fromDecision(), getFromTerminal },
actors: { agent: fromDecision(agent), getFromTerminal },
}).createMachine({
context: {
lastInput: null,
Expand Down

0 comments on commit 276d118

Please sign in to comment.