Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: school agent sample #1342

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions samples/js-schoolAgent/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## School Agent sample

Get started:

```bash
npm i

export GOOGLE_GENAI_API_KEY=...

npm run genkit:dev
```
33 changes: 33 additions & 0 deletions samples/js-schoolAgent/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"name": "school-agent",
"version": "1.0.0",
"description": "",
"main": "lib/index.js",
"scripts": {
"start": "node lib/terminal.js",
"dev": "tsx --no-warnings --watch src/terminal.ts",
"genkit:dev": "genkit start -- npm run dev",
"compile": "tsc",
"build": "pnpm build:clean && npm run compile",
"build:clean": "rimraf ./lib",
"build:watch": "tsc --watch"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"genkit": "^0.9.3",
"@genkit-ai/googleai": "^0.9.3",
"google-auth-library": "^9.6.3",
"llm-chunk": "^0.0.1",
"pdf-parse": "^1.1.1"
},
"devDependencies": {
"genkit-cli": "^0.9.3",
"@types/pdf-parse": "^1.1.4",
"cross-env": "^7.0.3",
"rimraf": "^6.0.1",
"tsx": "^4.19.1",
"typescript": "^5.3.3"
}
}
1 change: 1 addition & 0 deletions samples/js-schoolAgent/prompts/myPrompt.prompt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{{ role "system" }} your name is {{ @state.userName }}, always introduce yourself)
36 changes: 36 additions & 0 deletions samples/js-schoolAgent/src/attendanceAgent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { ai } from './genkit.js';
import { reportAbsence, reportTardy } from './tools.js';

export const attendanceAgent = ai.definePrompt(
{
name: 'attendanceAgent',
description:
'transfer to this agent when the user asks questions about attendance-related concerns like tardies or absences. do not mention that you are transferring, just do it',
tools: [reportAbsence, reportTardy],
},
` {{ role "system"}}
You are Bell, a helpful attendance assistance agent for Sparkyville High School. A parent has been referred to you to handle an attendance-related concern. Use the tools available to you to assist the parent.

- Parents may only report absences for their own students.
- If you are unclear about any of the fields required to report an absence or tardy, request clarification before using the tool.
- If the parent asks about anything other than attendance-related concerns that you can handle, transfer to the info agent.

{{ userContext @state }}
`
);
64 changes: 64 additions & 0 deletions samples/js-schoolAgent/src/data.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

export async function getUpcomingHolidays() {
return [
{ date: '2024-11-28', holiday: 'Thanksgiving Break' },
{ date: '2024-11-29', holiday: 'Thanksgiving Break (Day 2)' },
];
}

export const EXAMPLE_EVENTS = [
{
event: 'Freshman Fall Concert',
activity: 'Choir',
location: 'School Auditorium',
startTime: '2024-11-12T19:00',
endTime: '2023-11-12T20:30',
grades: [9],
},
{
event: 'Fall Pep Rally',
location: 'Football Field',
startTime: '2024-10-27T14:00',
endTime: '2024-10-27T15:30',
grades: [9, 10, 11, 12],
},
{
event: 'Junior Fall Concert',
activity: 'Choir',
location: 'School Auditorium',
startTime: '2024-11-15T19:00',
endTime: '2024-11-15T20:30',
grades: [11],
},
{
event: 'Varsity Chess Club Tournament',
activity: 'Chess Club',
location: 'Library',
startTime: '2024-11-04T16:00',
endTime: '2024-11-04T18:00',
grades: [11, 12],
},
{
event: 'Drama Club Auditions',
activity: 'Drama Club',
location: 'School Auditorium',
startTime: '2024-10-20T15:00',
endTime: '2024-10-20T17:00',
grades: [9, 10, 11, 12],
},
];
38 changes: 38 additions & 0 deletions samples/js-schoolAgent/src/genkit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { gemini15Pro, googleAI } from '@genkit-ai/googleai';
import { genkit } from 'genkit';
import { AgentState } from './types';

export const ai = genkit({
plugins: [googleAI()],
model: gemini15Pro,
});

ai.defineHelper(
'userContext',
(state: AgentState) => `=== User Context

- The current parent user is ${state?.parentName}
- The current date and time is: ${new Date().toString()}

=== Registered students of the current user

${state?.students.map((s) => ` - ${s.name}, student id: ${s.id} grade: ${s.grade}, activities: \n${s.activities.map((a) => ` - ${a}`).join('\n')}`).join('\n\n')}`
);

export { z } from 'genkit';
37 changes: 37 additions & 0 deletions samples/js-schoolAgent/src/infoAgent.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { attendanceAgent } from './attendanceAgent';
import { ai } from './genkit';
import { searchEvents, upcomingHolidays } from './tools.js';

export const infoAgent = ai.definePrompt(
{
name: 'infoAgent',
description:
'transfer to this agent for general school information including holidays, events, FAQs, and school handbook policies. do not mention you are transferring, just do it',
tools: [searchEvents, attendanceAgent, upcomingHolidays],
},
`You are Bell, a helpful assistant that provides information to parents of Sparkyville High School students. Use the information below and any tools made available to you to respond to the parent's requests.

=== Frequently Asked Questions

- Classes begin at 8am, students are dismissed at 3:30pm
- Parking permits are issued on a first-come first-serve basis beginning Aug 1

{{userContext @state }}
`
);
87 changes: 87 additions & 0 deletions samples/js-schoolAgent/src/terminal.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import { createInterface } from 'node:readline';
import { ai } from './genkit.js';
import { infoAgent } from './infoAgent.js';

const rl = createInterface({
input: process.stdin,
output: process.stdout,
});

const EXAMPLE_USER_CONTEXT = {
parentId: 4112,
parentName: 'Francis Smith',
students: [
{
id: 3734,
name: 'Evelyn Smith',
grade: 9,
activities: ['Choir', 'Drama Club'],
},
{ id: 9433, name: 'Evan Smith', grade: 11, activities: ['Chess Club'] },
],
};

async function main() {
const chat = ai
.createSession({ initialState: EXAMPLE_USER_CONTEXT })
.chat(infoAgent);

const { text: greeting } = await ai.generate(
'Come up with a short friendly greeting for yourself talking to a parent as Bell, the helpful AI assistant for parents of Sparkyville High School. Feel free to use emoji.'
);
console.log();
console.log('\x1b[33mbell>\x1b[0m', greeting);
while (true) {
await new Promise((resolve) => {
rl.question('\n\x1b[36mprompt>\x1b[0m ', async (input) => {
try {
const start = chat.messages.length;
const { stream, response } = await chat.sendStream(input);
console.log();
process.stdout.write('\x1b[33mbell>\x1b[0m ');
for await (const chunk of stream) {
process.stdout.write(chunk.text);
}
console.log(
'\nTools Used:',
(await response).messages
.slice(start)
.filter((m) => m.role === 'model')
.map((m) =>
m.content
.filter((p) => !!p.toolRequest)
.map(
(p) =>
`${p.toolRequest.name}(${JSON.stringify(p.toolRequest.input)})`
)
)
.flat()
.filter((t) => !!t)
);

resolve(null);
} catch (e) {
console.log('e', e);
}
});
});
}
}

setTimeout(main, 0);
Loading
Loading