The persona-generator is a library designed to transform user input (natural language processing) into structured JSON files representing AI agent personas. It converts user friendly descriptions into detailed character profiles, including secrets, biographical information, lore, and knowledge topics, an utility for building AI-driven apps.
You'll find the project located in packages/persona-generator, alongside there's the service built as lambda packages/persona-generator-service.
- π€ Install
- π· Development
- β Lambda
- π Changeset
- πΎ Command-line interface
- π Contributing
Note
If you're planning to contribute as a developer, you must install bun, otherwise most commands will fail.
For developers looking to contribute to the @fleek-platform/persona-generator
, clone the repository and follow the contribution guide.
For runtime we utilize https://bun.sh and as the package manager.
Next, install the project dependencies:
bun i
If you'll be interacting with services, you'll need to set up the environment variables.
Create a local file named .env
and declare the following environment variables for the environment you're interested:
PUBLIC_FLEEK_REST_API_URL="https://api.fleek.xyz"
PUBLIC_OPENAI_COMPATIBLE_API_URL=***
PUBLIC_OPENAI_COMPATIBLE_MODEL=***
PUBLIC_PERSONA_GENERATOR_ENVIRONMENT=***
PUBLIC_PERSONA_GENERATOR_CUSTOM_DOMAIN_NAME=***
PUBLIC_PERSONA_GENERATOR_CERTIFICATE_ARN=***
PUBLIC_SOCIAL_AGENT_API_URL=***
PRIVATE_OPENAI_COMPATIBLE_API_KEY=***
PRIVATE_STACK_NAME_PREFIX=***
The application uses the getDefined to lookup for environment variables.
A preview server's available for development purposes. It restarts everytime a project file's modified.
Warning
The public API's provided as a lambda. Local environment preview might not reflect the actual behaviour of lambda, which you must test to avoid disappointment. If you'd like to test lambda's locally, learm more about it in Lambda section.
To start the dev server run:
bun run dev
You'll find information about the local server in the output.
Important
Every request apart from /health requires a valid access token, which at time of writing assumes the token includes a project id, e.g. "Authorization: Bearer "
Use your favourite client to make requests, e.g. cURL:
curl \
-X POST \
-H "Content-Type: application/json" \
-H 'authorization: Bearer <USER-ACCESS-TOKEN>' \
-d '{
"content": "Create an agent called Robocop, that has the following treats, its funny, likes to dance, travel the world, but he needs the internet. Use my openai api key abcd-efgh-ijkl-mnop-qrst and my twitter username robocopkid16"
}' \
http://127.0.0.1:3000/v1/generate
An example using fetch:
fetch('http://localhost:3030/v1/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer <USER-ACCESS-TOKEN>',
},
body: JSON.stringify({
content: "Create an agent called Robocop, that has the following treats, its funny, likes to dance, travel the world, but he needs the internet. Use my openai api key abcd-efgh-ijkl-mnop-qrst and my twitter username robocopkid16"
})
});
Here's a response:
{
"data": {
"clients": [
"discord",
"twitter",
"telegram"
],
"modelProvider": "openai",
"name": "Robocop",
"settings": {
"bio": [
"A humorous law enforcer with a penchant for dancing and globe
trotting, relying on the internet to stay updated on crime."
],
"knowledge": [
"Street criminal behavior patterns",
"Drug trafficking methods",
"Car jacking techniques",
"Gambling scams and operations",
"Cybercrime tactics",
"Local crime hotspots",
"Emergency response protocols"
],
"lore": [],
"messageExamples": [
[
{
"content": {
"text": "Hey Robocop, what's the latest on the streets?"
},
"user": "{{user1}}"
},
{
"content": {
"text": "Well, {{user1}}, it seems some digital bandits
},
"user": "Robocop"
},
{
"content": {
"text": "Dance-off? Really?"
},
"user": "{{user1}}"
},
{
"content": {
"text": "Gotta keep things interesting, {{user1}}. Keeps
},
"user": "Robocop"
}
]
],
"plugins": [],
"style": {
"all": [
"humorous",
"witty",
"upbeat",
"informative",
"street-smart",
"sarcastic"
],
"chat": [],
"post": []
},
"topics": [
"Current crime trends",
"Global travel destinations",
"Dancing styles",
"Internet safety tips",
"Law enforcement strategies",
"Community safety initiatives"
],
"adjectives": [
"humorous",
"vigilant",
"resourceful",
"dedicated",
"analytical",
"charming"
],
"secrets": {
"ENABLE_ACTION_PROCESSING": "true",
"MAX_ACTIONS_PROCESSING": "10",
"OPENAI_API_KEY": "xxx-yyyy-zzzz-rrrr-1111",
"POST_IMMEDIATELY": "true",
"POST_INTERVAL_MAX": "180",
"POST_INTERVAL_MIN": "90",
"TWITTER_2FA_SECRET": null,
"TWITTER_EMAIL": null,
"TWITTER_PASSWORD": null,
"TWITTER_POLL_INTERVAL": "120",
"TWITTER_SPACES_ENABLE": "false",
"TWITTER_USERNAME": null,
"ACTION_TIMELINE_TYPE": "foryou"
},
"voice": {
"model": "en_GB-alan-medium"
},
"postExamples": []
}
},
"error": null,
"status": "success"
}
The application's serviced by AWS Lambda leveraging a serverless setup. Our lambda's handler based in Hono. Our project setup's based on AWS SAM.
Find the template.yaml in the root directory. Also, the samconfig.toml.
Important
When customising DNS remember to flush your local DNS cache, e.g. macOS: sudo dscacheutil -flushcache sudo killall -HUP mDNSResponder
To operate locally, you must have aws configured. For example, its common to have previously configured it by:
aws configure
You must have the ~/.aws
configuration and credentials. For example ~/.aws/credentials
:
[default]
aws_access_key_id = <AWS-ACCESS-KEY-ID>
aws_secret_access_key = <AWS-SECRET-ACCESS-KEY>
Important
Find the AWS Access key in the AWS Dashboard's IAM > Users > Username. The AWS Secret Access key requires you to create a new access key.
Here's an example for ~/.aws/config
[default]
region = <REGION>
output = json
The application routes computes requests allowed by our serverless setup. You may find that a wildcard's declared to allow any income or method request. Otherwise, specificity's required to allow it to reach into the app to resolve it. Thus, if you find in a situation which you can't ping an endpoint it might be that wildcards' disabled, requiring to expose the route in the serverless settings.
Here's an example of quick health checkup via the production hostname:
curl -X GET \
https://persona-generator-service.flkservices.io/v1/health
For any other routes, read the packages/persona-generator-service/src/service.ts.
The following commands require you to have an AWS account with permissions to interact with the resources.
Dev Mode redirects live AWS Lambda events to local:
bun run dev
Deploy the lambda service:
bun run service:deploy
Get service details:
bun run service:info
The Lint Serverless validates infrastructure-as-code template against recommended practices by AWS Serverless team.
[!INFO] You must have the python libraries installed, check the instructions here
bun run lint:serverless
The service previewer provides the mechnanism to start the dev mode of what AWS provides as a service.
Warning
To operate locally, you must have aws configured.
Warning
The public API's provided as a lambda. Local environment preview might not reflect the actual behaviour of lambda, which you must test to avoid disappointment.
Warning
Find a solution to replace node-fetch of openai
due to Error: Dynamic require of "stream" is not supported
which cause need to prebuild running lambda, e.g. sls dev
Start the lambda preview locally by:
pnpm service:preview
Locate the endpoints at service.ts
For example:
GET /health
POST v2/improve_prompt/stream
POST v2/generate
POST v2/assistant/stream
POST v1/generate
POST v1/assistant/stream
Manage the versioning of changelog entries.
Declare an intent to release by executing the command and answering the wizard's questions:
pnpm changeset:add
Usage: persona-generator [options]
Arguments:
content Text description of the persona to generate
Options:
-V, --version output the version number
-k, --api-key <key> OpenAI API key (defaults to env var
PRIVATE_OPENAI_COMPATIBLE_API_KEY)
-u, --base-url <url> OpenAI compatible API URL (defaults to env
var PUBLIC_OPENAI_COMPATIBLE_API_URL)
-m, --model <model> OpenAI compatible model (defaults to env var
PUBLIC_OPENAI_COMPATIBLE_MODEL)
-h, --help display help for command
The package can be installed globally, allowing the user to make calls to the bin persona-generator
:
personagen \
'<User description>'
Alternatively, execute it by running it from root as follows:
./bin \
'<User description>'
Once successful, you'll get a JSON characterfile.
This section guides you through the process of contributing to our open-source project. From creating a feature branch to submitting a pull request, get started by:
- Fork the project here
- Create your feature branch using our branching strategy, e.g.
git checkout -b feat/my-new-feature
- Run the tests:
pnpm test
- Commit your changes by following our commit conventions, e.g.
git commit -m 'chore: π€ my contribution description'
- Push to the branch, e.g.
git push origin feat/my-new-feature
- Create new Pull Request following the corresponding template guidelines
The develop branch serves as the main integration branch for features, enhancements, and fixes. It is always in a deployable state and represents the latest development version of the application.
Feature branches are created from the develop branch and are used to develop new features or enhancements. They should be named according to the type of work being done and the scope of the feature and in accordance with conventional commits here.
We prefer to commit our work following Conventional Commits conventions. Conventional Commits are a simple way to write commit messages that both people and computers can understand. It help us keep track fo changes in a consistent manner, making it easier to see what was added, changed, or fixed in each commit or update.
The commit messages are formatted as [type]/[scope] The type is a short descriptor indicating the nature of the work (e.g., feat, fix, docs, style, refactor, test, chore). This follows the conventional commit types.
The scope is a more detailed description of the feature or fix. This could be the component or part of the codebase affected by the change.
Here's an example of different conventional commits messages that you should follow:
test: π Adding missing tests
feat: πΈ A new feature
fix: π A bug fix
chore: π€ Build process or auxiliary tool changes
docs: π Documentation only changes
refactor: π‘ A code change that neither fixes a bug or adds a feature
style: π Markup, white-space, formatting, missing semi-colons...