Skip to content

Commit bbaf626

Browse files
authored
Merge pull request #2045 from asterai-io/main
feat: Implement asterai plugin
2 parents eedf278 + 75e8e5a commit bbaf626

11 files changed

+449
-12
lines changed

packages/plugin-asterai/.npmignore

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
*
2+
3+
!dist/**
4+
!package.json
5+
!readme.md
6+
!tsup.config.ts

packages/plugin-asterai/README.md

+80
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# @elizaos/plugin-asterai
2+
3+
A plugin for interacting with [asterai](https://asterai.io) plugins and agents.
4+
5+
## Description
6+
7+
This plugin provides functionality to allow Eliza agents to interact with
8+
asterai plugins and agents.
9+
10+
This will expand your Eliza character's utility by giving it access to all
11+
the functionality of asterai's ecosystem of marketplace and private plugins
12+
and agents.
13+
14+
## Installation
15+
16+
```bash
17+
pnpm install @elizaos/plugin-asterai
18+
```
19+
20+
## Configuration
21+
22+
The plugin requires the following environment variables to be set:
23+
24+
```typescript
25+
ASTERAI_AGENT_ID=
26+
ASTERAI_PUBLIC_QUERY_KEY=
27+
```
28+
29+
## Usage
30+
31+
### Basic Integration
32+
33+
```typescript
34+
import { asteraiPlugin } from '@elizaos/plugin-asterai';
35+
```
36+
37+
### Example Usage
38+
39+
The plugin supports natural language for interacting with the asterai agent
40+
through your Eliza character.
41+
42+
For example, if your asterai agent can fetch weather data:
43+
44+
```typescript
45+
"Hey Eliza, how's the weather in LA?"
46+
```
47+
48+
Eliza will then query the asterai agent to fetch the information.
49+
50+
## Development Guide
51+
52+
### Setting Up Development Environment
53+
54+
1. Clone the repository
55+
2. Install dependencies:
56+
57+
```bash
58+
pnpm install
59+
```
60+
61+
3. Build the plugin:
62+
63+
```bash
64+
pnpm run build
65+
```
66+
67+
4. Run tests:
68+
69+
```bash
70+
pnpm run test
71+
```
72+
73+
## Contributing
74+
75+
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
76+
77+
## License
78+
79+
This plugin is part of the Eliza project. See the main project repository for license information.
80+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import eslintGlobalConfig from "../../eslint.config.mjs";
2+
3+
export default [...eslintGlobalConfig];

packages/plugin-asterai/package.json

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
{
2+
"name": "@elizaos/plugin-asterai",
3+
"version": "0.1.0",
4+
"type": "module",
5+
"main": "dist/index.js",
6+
"module": "dist/index.js",
7+
"types": "dist/index.d.ts",
8+
"exports": {
9+
"./package.json": "./package.json",
10+
".": {
11+
"import": {
12+
"@elizaos/source": "./src/index.ts",
13+
"types": "./dist/index.d.ts",
14+
"default": "./dist/index.js"
15+
}
16+
}
17+
},
18+
"files": [
19+
"dist"
20+
],
21+
"dependencies": {
22+
"@asterai/client": "0.1.6",
23+
"@elizaos/core": "workspace:*",
24+
"bignumber.js": "9.1.2",
25+
"bs58": "6.0.0",
26+
"elliptic": "6.6.1",
27+
"node-cache": "5.1.2",
28+
"sha3": "2.1.4",
29+
"uuid": "11.0.3",
30+
"zod": "3.23.8"
31+
},
32+
"devDependencies": {
33+
"@types/elliptic": "6.4.18",
34+
"@types/uuid": "10.0.0",
35+
"tsup": "8.3.5"
36+
},
37+
"scripts": {
38+
"lines": "find . \\( -name '*.cdc' -o -name '*.ts' \\) -not -path '*/node_modules/*' -not -path '*/tests/*' -not -path '*/deps/*' -not -path '*/dist/*' -not -path '*/imports*' | xargs wc -l",
39+
"build": "tsup --format esm --dts",
40+
"dev": "tsup --format esm --dts --watch",
41+
"lint": "eslint --fix --cache ."
42+
},
43+
"peerDependencies": {
44+
"whatwg-url": "7.1.0"
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import {
2+
elizaLogger,
3+
type Action,
4+
type ActionExample,
5+
type HandlerCallback,
6+
type IAgentRuntime,
7+
type Memory,
8+
type State,
9+
} from "@elizaos/core";
10+
import { validateAsteraiConfig } from "../environment";
11+
import {getInitAsteraiClient} from "../index.ts";
12+
13+
export const queryAction = {
14+
name: "QUERY_ASTERAI_AGENT",
15+
similes: [
16+
"MESSAGE_ASTERAI_AGENT",
17+
"TALK_TO_ASTERAI_AGENT",
18+
"SEND_MESSAGE_TO_ASTERAI_AGENT",
19+
"COMMUNICATE_WITH_ASTERAI_AGENT",
20+
],
21+
description:
22+
"Call this action to send a message to the asterai agent which " +
23+
"has access to external plugins and functionality to answer " +
24+
"the user you are assisting, to help perform a workflow task, etc.",
25+
validate: async (runtime: IAgentRuntime, _message: Memory) => {
26+
const config = await validateAsteraiConfig(runtime);
27+
getInitAsteraiClient(
28+
config.ASTERAI_AGENT_ID,
29+
config.ASTERAI_PUBLIC_QUERY_KEY
30+
);
31+
return true;
32+
},
33+
handler: async (
34+
runtime: IAgentRuntime,
35+
message: Memory,
36+
_state: State,
37+
_options: { [key: string]: unknown },
38+
callback?: HandlerCallback
39+
): Promise<boolean> => {
40+
const config = await validateAsteraiConfig(runtime);
41+
const asteraiClient = getInitAsteraiClient(
42+
config.ASTERAI_AGENT_ID,
43+
config.ASTERAI_PUBLIC_QUERY_KEY
44+
);
45+
elizaLogger.debug("called QUERY_ASTERAI_AGENT action with message:", message.content);
46+
const response = await asteraiClient.query({
47+
query: message.content.text
48+
});
49+
const textResponse = await response.text();
50+
callback({
51+
text: textResponse
52+
});
53+
return true;
54+
},
55+
examples: [
56+
[
57+
{
58+
user: "{{user1}}",
59+
content: {
60+
text: "How's the weather in LA?",
61+
},
62+
},
63+
{
64+
user: "{{user2}}",
65+
content: {
66+
text: "Let me check that for you, just a moment.",
67+
action: "QUERY_ASTERAI_AGENT",
68+
},
69+
},
70+
],
71+
] as ActionExample[][],
72+
} as Action;
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { IAgentRuntime } from "@elizaos/core";
2+
import { z } from "zod";
3+
4+
const envSchema = z.object({
5+
ASTERAI_AGENT_ID: z
6+
.string()
7+
.min(1, "ASTERAI_AGENT_ID is required"),
8+
ASTERAI_PUBLIC_QUERY_KEY: z
9+
.string()
10+
.min(1, "ASTERAI_PUBLIC_QUERY_KEY is required"),
11+
});
12+
13+
export type AsteraiConfig = z.infer<typeof envSchema>;
14+
15+
export async function validateAsteraiConfig(
16+
runtime: IAgentRuntime
17+
): Promise<AsteraiConfig> {
18+
try {
19+
const config = {
20+
ASTERAI_AGENT_ID:
21+
runtime.getSetting("ASTERAI_AGENT_ID") ||
22+
process.env.ASTERAI_AGENT_ID,
23+
ASTERAI_PUBLIC_QUERY_KEY:
24+
runtime.getSetting("ASTERAI_PUBLIC_QUERY_KEY") || process.env.ASTERAI_PUBLIC_QUERY_KEY,
25+
};
26+
27+
return envSchema.parse(config);
28+
} catch (error) {
29+
if (error instanceof z.ZodError) {
30+
const errorMessages = error.errors
31+
.map((err) => `${err.path.join(".")}: ${err.message}`)
32+
.join("\n");
33+
throw new Error(
34+
`Asterai plugin configuration validation failed:\n${errorMessages}`
35+
);
36+
}
37+
throw error;
38+
}
39+
}

packages/plugin-asterai/src/index.ts

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import {asteraiProvider} from "./providers/asterai.provider.ts";
2+
import type { Plugin } from "@elizaos/core";
3+
import { queryAction } from "./actions/query";
4+
import { AsteraiClient } from "@asterai/client";
5+
6+
export * from "./environment";
7+
export * from "./providers/asterai.provider";
8+
9+
let asteraiClient: AsteraiClient | null = null;
10+
11+
export const getInitAsteraiClient = (
12+
agentId: string,
13+
publicQueryKey: string
14+
): AsteraiClient => {
15+
if (!asteraiClient) {
16+
asteraiClient = new AsteraiClient({
17+
appId: agentId,
18+
queryKey: publicQueryKey,
19+
})
20+
}
21+
return asteraiClient;
22+
};
23+
24+
export const asteraiPlugin: Plugin = {
25+
name: "asterai",
26+
description: "asterai Plugin for Eliza",
27+
providers: [asteraiProvider],
28+
actions: [queryAction],
29+
evaluators: [],
30+
services: [],
31+
};
32+
33+
export default asteraiPlugin;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import {
2+
elizaLogger,
3+
IAgentRuntime,
4+
Memory,
5+
Provider,
6+
State, UUID,
7+
} from "@elizaos/core";
8+
import {validateAsteraiConfig} from "../environment.ts";
9+
import {getInitAsteraiClient} from "../index.ts";
10+
11+
const asteraiProvider: Provider = {
12+
get: async (
13+
runtime: IAgentRuntime,
14+
message: Memory,
15+
_state?: State
16+
): Promise<string | null> => {
17+
const hasConfiguredEnv =
18+
!!runtime.getSetting("ASTERAI_AGENT_ID") &&
19+
!!runtime.getSetting("ASTERAI_PUBLIC_QUERY_KEY");
20+
if (!hasConfiguredEnv) {
21+
elizaLogger.error(
22+
"ASTERAI_AGENT_ID or ASTERAI_PUBLIC_QUERY_KEY " +
23+
"not configured, skipping provider"
24+
);
25+
return null;
26+
}
27+
const config = await validateAsteraiConfig(runtime);
28+
const asteraiClient = getInitAsteraiClient(
29+
config.ASTERAI_AGENT_ID,
30+
config.ASTERAI_PUBLIC_QUERY_KEY
31+
);
32+
if (!asteraiClient) {
33+
elizaLogger.error("asteraiClient is not initialised");
34+
return null;
35+
}
36+
const agentId = runtime.getSetting("ASTERAI_AGENT_ID") as UUID;
37+
let agentSummaryMemory = await runtime.knowledgeManager.getMemoryById(agentId);
38+
if (!agentSummaryMemory) {
39+
// Fetch & set summary memory.
40+
const summary = await asteraiClient.fetchSummary();
41+
elizaLogger.debug("asterai agent summary fetched:", summary);
42+
await runtime.knowledgeManager.createMemory({
43+
id: agentId,
44+
userId: message.userId,
45+
agentId: message.agentId,
46+
roomId: message.roomId,
47+
createdAt: Date.now(),
48+
content: {
49+
text: summary
50+
}
51+
});
52+
agentSummaryMemory = await runtime.knowledgeManager.getMemoryById(agentId);
53+
}
54+
if (!agentSummaryMemory) {
55+
elizaLogger.error("failed to initialise agent's summary memory");
56+
return null;
57+
}
58+
return agentSummaryMemory.content.text;
59+
},
60+
};
61+
62+
// Module exports
63+
export { asteraiProvider };

packages/plugin-asterai/tsconfig.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"extends": "../core/tsconfig.json",
3+
"compilerOptions": {
4+
"outDir": "dist",
5+
"rootDir": "src"
6+
},
7+
"include": [
8+
"src/**/*.ts"
9+
]
10+
}
+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { defineConfig } from "tsup";
2+
3+
export default defineConfig({
4+
entry: ["src/index.ts"],
5+
outDir: "dist",
6+
sourcemap: true,
7+
clean: true,
8+
format: ["esm"], // Ensure you're targeting CommonJS
9+
loader: {
10+
".cdc": "text",
11+
},
12+
external: [
13+
"dotenv", // Externalize dotenv to prevent bundling
14+
"fs", // Externalize fs to use Node.js built-in module
15+
"path", // Externalize other built-ins if necessary
16+
"@reflink/reflink",
17+
"@node-llama-cpp",
18+
"https",
19+
"http",
20+
"agentkeepalive",
21+
"safe-buffer",
22+
"base-x",
23+
"bs58",
24+
"borsh",
25+
"stream",
26+
"buffer",
27+
"querystring",
28+
"amqplib",
29+
// Add other modules you want to externalize
30+
"@onflow/fcl",
31+
"@onflow/types",
32+
"sha3",
33+
"elliptic",
34+
],
35+
});

0 commit comments

Comments
 (0)