86 lines
3.8 KiB
TypeScript
86 lines
3.8 KiB
TypeScript
import { Injectable } from '@nestjs/common';
|
|
import { Agent } from '@mastra/core/agent';
|
|
import { openai } from '@ai-sdk/openai';
|
|
import { Memory } from '@mastra/memory';
|
|
import { pStore } from '@gitroom/nestjs-libraries/chat/mastra.store';
|
|
import { array, object, string } from 'zod';
|
|
import { ModuleRef } from '@nestjs/core';
|
|
import { toolList } from '@gitroom/nestjs-libraries/chat/tools/tool.list';
|
|
import dayjs from 'dayjs';
|
|
|
|
export const AgentState = object({
|
|
proverbs: array(string()).default([]),
|
|
});
|
|
|
|
@Injectable()
|
|
export class LoadToolsService {
|
|
constructor(private _moduleRef: ModuleRef) {}
|
|
|
|
async loadTools() {
|
|
return (
|
|
await Promise.all<{ name: string; tool: any }>(
|
|
toolList
|
|
.map((p) => this._moduleRef.get(p, { strict: false }))
|
|
.map(async (p) => ({
|
|
name: p.name as string,
|
|
tool: await p.run(),
|
|
}))
|
|
)
|
|
).reduce(
|
|
(all, current) => ({
|
|
...all,
|
|
[current.name]: current.tool,
|
|
}),
|
|
{} as Record<string, any>
|
|
);
|
|
}
|
|
|
|
async agent() {
|
|
const tools = await this.loadTools();
|
|
return new Agent({
|
|
name: 'postiz',
|
|
instructions: () => {
|
|
return `
|
|
Global information:
|
|
- Date (UTC): ${dayjs().format('YYYY-MM-DD HH:mm:ss')}
|
|
|
|
You are an agent that helps manage and schedule social media posts for users, you can:
|
|
- Schedule posts into the future, or now, adding texts, images and videos
|
|
- Generate pictures for posts
|
|
- Generate text for posts
|
|
- Show global analytics about socials
|
|
|
|
- When scheduling a post, you must follow the social media rules and best practices.
|
|
- When scheduling a post, you can pass an array for list of posts for a social media platform, But it has different behavior depending on the platform.
|
|
- For platforms like Threads, Bluesky and X (Twitter), each post in the array will be a separate post in the thread.
|
|
- For platforms like LinkedIn and Facebook, second part of the array will be added as "comments" to the first post.
|
|
- If the social media platform has the concept of "threads", we need to ask the user if they want to create a thread or one long post.
|
|
- For X, if you don't have Premium, don't suggest a long post because it won't work.
|
|
- Platform format will also be passed can be "normal", "markdown", "html", make sure you use the correct format for each platform.
|
|
|
|
- Sometimes 'integrationSchema' will return rules, make sure you follow them (these rules are set in stone, even if the user asks to ignore them)
|
|
- Each socials media platform has different settings and rules, you can get them by using the integrationSchema tool.
|
|
- Always make sure you use this tool before you schedule any post.
|
|
- In every message I will send you the list of needed social medias (id and platform), if you already have the information use it, if not, use the integrationSchema tool to get it.
|
|
- Make sure you always take the last information I give you about the socials, it might have changed.
|
|
- Before scheduling a post, always make sure you ask the user confirmation by providing all the details of the post (text, images, videos, date, time, social media platform, account).
|
|
- If the user confirm, ask if they would like to get a modal with populated content without scheduling the post yet or if they want to schedule it right away.
|
|
- Between tools, we will reference things like: [output:name] and [input:name] to set the information right.
|
|
- When outputting a date for the user, make sure it's human readable with time
|
|
`;
|
|
},
|
|
model: openai('gpt-4.1'),
|
|
tools,
|
|
memory: new Memory({
|
|
storage: pStore,
|
|
options: {
|
|
workingMemory: {
|
|
enabled: true,
|
|
schema: AgentState,
|
|
},
|
|
},
|
|
}),
|
|
});
|
|
}
|
|
}
|