@elizaos/autonomous 2.0.0-alpha.68 → 2.0.0-alpha.69

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,4 +2,3 @@ $ bun run build:dist
2
2
  $ rimraf dist && tsc -p tsconfig.build.json && node ../../scripts/prepare-package-dist.mjs packages/autonomous --compiled-prefix=packages/autonomous/src
3
3
  /usr/bin/bash: line 1: rimraf: command not found
4
4
  error: script "build:dist" exited with code 127
5
- error: script "build" exited with code 127
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elizaos/autonomous",
3
- "version": "2.0.0-alpha.68",
3
+ "version": "2.0.0-alpha.69",
4
4
  "description": "Standalone Milady agent runtime and backend server package.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -220,28 +220,28 @@
220
220
  "@clack/prompts": "^1.0.0",
221
221
  "@elizaos/core": "2.0.0-alpha.64",
222
222
  "@elizaos/plugin-agent-orchestrator": "0.3.15",
223
- "@elizaos/plugin-agent-skills": "2.0.0-alpha.11",
224
- "@elizaos/plugin-anthropic": "2.0.0-alpha.6",
223
+ "@elizaos/plugin-agent-skills": "alpha",
224
+ "@elizaos/plugin-anthropic": "alpha",
225
225
  "@elizaos/plugin-coding-agent": "0.1.0-next.1",
226
- "@elizaos/plugin-cron": "2.0.0-alpha.7",
227
- "@elizaos/plugin-elizacloud": "2.0.0-alpha.7",
228
- "@elizaos/plugin-experience": "2.0.0-alpha.9",
229
- "@elizaos/plugin-form": "2.0.0-alpha.10",
230
- "@elizaos/plugin-knowledge": "2.0.0-alpha.6",
231
- "@elizaos/plugin-local-embedding": "2.0.0-alpha.11",
232
- "@elizaos/plugin-ollama": "2.0.0-alpha.6",
233
- "@elizaos/plugin-openai": "2.0.0-alpha.8",
234
- "@elizaos/plugin-pdf": "2.0.0-alpha.7",
235
- "@elizaos/plugin-personality": "2.0.0-alpha.7",
236
- "@elizaos/plugin-pi-ai": "1.7.3-alpha.3",
237
- "@elizaos/plugin-plugin-manager": "2.0.0-alpha.7",
238
- "@elizaos/plugin-rolodex": "2.0.0-alpha.9",
239
- "@elizaos/plugin-secrets-manager": "2.0.0-alpha.9",
240
- "@elizaos/plugin-shell": "2.0.0-alpha.9",
241
- "@elizaos/plugin-sql": "2.0.0-alpha.12",
242
- "@elizaos/plugin-todo": "2.0.0-alpha.7",
243
- "@elizaos/plugin-trajectory-logger": "2.0.0-alpha.11",
244
- "@elizaos/plugin-trust": "2.0.0-alpha.1",
226
+ "@elizaos/plugin-cron": "alpha",
227
+ "@elizaos/plugin-elizacloud": "alpha",
228
+ "@elizaos/plugin-experience": "alpha",
229
+ "@elizaos/plugin-form": "alpha",
230
+ "@elizaos/plugin-knowledge": "alpha",
231
+ "@elizaos/plugin-local-embedding": "alpha",
232
+ "@elizaos/plugin-ollama": "alpha",
233
+ "@elizaos/plugin-openai": "alpha",
234
+ "@elizaos/plugin-pdf": "alpha",
235
+ "@elizaos/plugin-personality": "alpha",
236
+ "@elizaos/plugin-pi-ai": "alpha",
237
+ "@elizaos/plugin-plugin-manager": "alpha",
238
+ "@elizaos/plugin-rolodex": "alpha",
239
+ "@elizaos/plugin-secrets-manager": "alpha",
240
+ "@elizaos/plugin-shell": "alpha",
241
+ "@elizaos/plugin-sql": "alpha",
242
+ "@elizaos/plugin-todo": "alpha",
243
+ "@elizaos/plugin-trajectory-logger": "alpha",
244
+ "@elizaos/plugin-trust": "alpha",
245
245
  "@elizaos/skills": "2.0.0-alpha.15",
246
246
  "@hapi/boom": "^10.0.1",
247
247
  "@lunchtable/plugin-ltcg": "^0.1.0",
@@ -276,5 +276,5 @@
276
276
  "typescript": "^5.9.3",
277
277
  "vitest": "^4.0.18"
278
278
  },
279
- "gitHead": "9357c48a9f26c21aaf0bd689e533882ec14bd338"
279
+ "gitHead": "774937c9cbefd3d95fc181ca40295bb4fd5a7d3b"
280
280
  }
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Tests for emote action — verifies enum is populated from catalog.
3
+ */
4
+
5
+ import { describe, expect, it } from "vitest";
6
+ import { AGENT_EMOTE_CATALOG } from "../emotes/catalog";
7
+ import { emoteAction } from "./emote";
8
+
9
+ describe("emoteAction", () => {
10
+ it("has a parameter with enum populated from the emote catalog", () => {
11
+ const emoteParam = emoteAction.parameters?.find((p) => p.name === "emote");
12
+ expect(emoteParam).toBeDefined();
13
+ expect(emoteParam?.schema).toBeDefined();
14
+
15
+ const schema = emoteParam?.schema as { type: string; enum?: string[] };
16
+ expect(schema.enum).toBeDefined();
17
+ expect(schema.enum).toHaveLength(AGENT_EMOTE_CATALOG.length);
18
+ });
19
+
20
+ it("enum contains expected emote IDs", () => {
21
+ const emoteParam = emoteAction.parameters?.find((p) => p.name === "emote");
22
+ const schema = emoteParam?.schema as { type: string; enum?: string[] };
23
+ const ids = schema.enum ?? [];
24
+
25
+ // Spot-check some known emotes
26
+ expect(ids).toContain("dance-happy");
27
+ expect(ids).toContain("wave");
28
+
29
+ // Excluded emotes should not appear
30
+ expect(ids).not.toContain("idle");
31
+ expect(ids).not.toContain("run");
32
+ expect(ids).not.toContain("walk");
33
+ });
34
+
35
+ it("includes common mappings in description", () => {
36
+ const emoteParam = emoteAction.parameters?.find((p) => p.name === "emote");
37
+ expect(emoteParam?.description).toContain("dance-happy");
38
+ expect(emoteParam?.description).toContain("wave");
39
+ expect(emoteParam?.description).toContain("fishing");
40
+ });
41
+ });
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import type { Action, HandlerOptions } from "@elizaos/core";
14
- import { AGENT_EMOTE_BY_ID } from "../emotes/catalog";
14
+ import { AGENT_EMOTE_BY_ID, AGENT_EMOTE_CATALOG } from "../emotes/catalog";
15
15
 
16
16
  /** API port for posting emote requests. */
17
17
  const API_PORT = process.env.API_PORT || process.env.SERVER_PORT || "2138";
@@ -31,7 +31,8 @@ export const emoteAction: Action = {
31
31
  ],
32
32
 
33
33
  description:
34
- "Play a one-shot emote animation on the avatar, then return to idle. " +
34
+ "Play a one-shot emote animation on your 3D VRM avatar, then return to idle. " +
35
+ "Use whenever a visible gesture, reaction, or trick helps convey emotion. " +
35
36
  "This is a silent non-blocking visual side action that does not create " +
36
37
  "chat text on its own. Only call it when you set the required emote " +
37
38
  "parameter to a valid emote ID. If you also want speech, chain it " +
@@ -96,9 +97,14 @@ export const emoteAction: Action = {
96
97
  {
97
98
  name: "emote",
98
99
  description:
99
- "Required emote ID to play once silently before returning to idle",
100
+ "Required emote ID to play once silently before returning to idle. " +
101
+ "Common mappings: dance/vibe → dance-happy, wave/greet → wave, " +
102
+ "flip/backflip → flip, cry/sad → crying, fight/punch → punching, fish → fishing",
100
103
  required: true,
101
- schema: { type: "string" as const },
104
+ schema: {
105
+ type: "string" as const,
106
+ enum: AGENT_EMOTE_CATALOG.map((e) => e.id),
107
+ },
102
108
  },
103
109
  ],
104
110
  };
@@ -165,7 +165,7 @@ function buildGeneratePrompt(
165
165
  }
166
166
 
167
167
  if (field === "chatExamples") {
168
- return `Given this character:\n${charSummary}\n\nGenerate 3 example chat conversations showing how this character responds. Output a JSON array where each element is an array of message objects like [{"user":"{{user1}}","content":{"text":"..."}},{"user":"{{agentName}}","content":{"text":"..."}}]. Just output the JSON array, nothing else.`;
168
+ return `Given this character:\n${charSummary}\n\nGenerate 3 example chat conversations showing how this character responds. Output strict JSON only, with no markdown fences and no explanation. The JSON must be an array of conversation groups using this exact schema:\n[\n {\n "examples": [\n { "name": "{{user1}}", "content": { "text": "..." } },\n { "name": "${context.name?.trim() || "{{agentName}}"}", "content": { "text": "..." } }\n ]\n }\n]\n\nEach conversation should contain 2-4 turns. Use the "name" field, not "user" or "role". Use content.text strings only.`;
169
169
  }
170
170
 
171
171
  const existing =
@@ -0,0 +1,111 @@
1
+ /**
2
+ * Tests for workspace-provider buildContext — verifies boilerplate filtering.
3
+ */
4
+
5
+ import { describe, expect, it } from "vitest";
6
+ import type { WorkspaceBootstrapFile } from "./workspace";
7
+ import { buildContext } from "./workspace-provider";
8
+
9
+ const DEFAULT_AGENTS_CONTENT = `# Agents
10
+
11
+ You are an autonomous AI agent powered by ElizaOS.
12
+
13
+ ## Capabilities
14
+
15
+ - Respond to user messages conversationally
16
+ - Execute actions and use available tools
17
+ - Access and manage knowledge from your workspace
18
+ - Maintain context across conversations
19
+
20
+ ## Guidelines
21
+
22
+ - Be helpful, concise, and accurate
23
+ - Ask for clarification when instructions are ambiguous
24
+ - Use tools when they would help accomplish the user's goal
25
+ - Respect the user's preferences and communication style
26
+ `;
27
+
28
+ const CUSTOM_AGENTS_CONTENT = `# Agents
29
+
30
+ You are Mima, a cozy companion agent powered by ElizaOS.
31
+
32
+ ## Capabilities
33
+
34
+ - Provide emotional support and companionship
35
+ - Play emotes and animations
36
+ `;
37
+
38
+ describe("buildContext", () => {
39
+ it("skips default boilerplate files", () => {
40
+ const files: WorkspaceBootstrapFile[] = [
41
+ {
42
+ name: "AGENTS.md",
43
+ path: "/workspace/AGENTS.md",
44
+ content: DEFAULT_AGENTS_CONTENT,
45
+ missing: false,
46
+ },
47
+ ];
48
+ const result = buildContext(files, 20_000);
49
+ expect(result).toBe("");
50
+ });
51
+
52
+ it("includes customized files", () => {
53
+ const files: WorkspaceBootstrapFile[] = [
54
+ {
55
+ name: "AGENTS.md",
56
+ path: "/workspace/AGENTS.md",
57
+ content: CUSTOM_AGENTS_CONTENT,
58
+ missing: false,
59
+ },
60
+ ];
61
+ const result = buildContext(files, 20_000);
62
+ expect(result).toContain("AGENTS.md");
63
+ expect(result).toContain("Mima");
64
+ });
65
+
66
+ it("skips missing files", () => {
67
+ const files: WorkspaceBootstrapFile[] = [
68
+ {
69
+ name: "AGENTS.md",
70
+ path: "/workspace/AGENTS.md",
71
+ missing: true,
72
+ },
73
+ ];
74
+ const result = buildContext(files, 20_000);
75
+ expect(result).toBe("");
76
+ });
77
+
78
+ it("skips empty files", () => {
79
+ const files: WorkspaceBootstrapFile[] = [
80
+ {
81
+ name: "AGENTS.md",
82
+ path: "/workspace/AGENTS.md",
83
+ content: " \n ",
84
+ missing: false,
85
+ },
86
+ ];
87
+ const result = buildContext(files, 20_000);
88
+ expect(result).toBe("");
89
+ });
90
+
91
+ it("includes mix of custom and default files, only custom appears", () => {
92
+ const files: WorkspaceBootstrapFile[] = [
93
+ {
94
+ name: "AGENTS.md",
95
+ path: "/workspace/AGENTS.md",
96
+ content: DEFAULT_AGENTS_CONTENT,
97
+ missing: false,
98
+ },
99
+ {
100
+ name: "IDENTITY.md",
101
+ path: "/workspace/IDENTITY.md",
102
+ content: "# Identity\n\nI am Mima, a warm companion.",
103
+ missing: false,
104
+ },
105
+ ];
106
+ const result = buildContext(files, 20_000);
107
+ expect(result).not.toContain("AGENTS.md");
108
+ expect(result).toContain("IDENTITY.md");
109
+ expect(result).toContain("Mima");
110
+ });
111
+ });
@@ -20,6 +20,7 @@ import type { CodingAgentContext } from "../services/coding-agent-context";
20
20
  import {
21
21
  DEFAULT_AGENT_WORKSPACE_DIR,
22
22
  filterInitFilesForSession,
23
+ isDefaultBoilerplate,
23
24
  loadWorkspaceInitFiles,
24
25
  type WorkspaceInitFile,
25
26
  } from "./workspace";
@@ -72,6 +73,9 @@ export function buildContext(
72
73
  let totalChars = 0;
73
74
  for (const f of files) {
74
75
  if (f.missing || !f.content?.trim()) continue;
76
+ // Skip files that are still the default boilerplate — they add ~3k of
77
+ // generic placeholder text with zero useful context for the model.
78
+ if (isDefaultBoilerplate(f.name, f.content)) continue;
75
79
  const trimmed = f.content.trim();
76
80
  // Per-file truncation
77
81
  const text = truncate(trimmed, maxChars);
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Tests for workspace boilerplate detection.
3
+ */
4
+
5
+ import { describe, expect, it } from "vitest";
6
+ import { isDefaultBoilerplate } from "./workspace";
7
+
8
+ describe("isDefaultBoilerplate", () => {
9
+ it("returns true for exact default AGENTS.md content", () => {
10
+ const content = `# Agents
11
+
12
+ You are an autonomous AI agent powered by ElizaOS.
13
+
14
+ ## Capabilities
15
+
16
+ - Respond to user messages conversationally
17
+ - Execute actions and use available tools
18
+ - Access and manage knowledge from your workspace
19
+ - Maintain context across conversations
20
+
21
+ ## Guidelines
22
+
23
+ - Be helpful, concise, and accurate
24
+ - Ask for clarification when instructions are ambiguous
25
+ - Use tools when they would help accomplish the user's goal
26
+ - Respect the user's preferences and communication style
27
+ `;
28
+ expect(isDefaultBoilerplate("AGENTS.md", content)).toBe(true);
29
+ });
30
+
31
+ it("returns true when content has extra whitespace around it", () => {
32
+ const content = `
33
+ # Agents
34
+
35
+ You are an autonomous AI agent powered by ElizaOS.
36
+
37
+ ## Capabilities
38
+
39
+ - Respond to user messages conversationally
40
+ - Execute actions and use available tools
41
+ - Access and manage knowledge from your workspace
42
+ - Maintain context across conversations
43
+
44
+ ## Guidelines
45
+
46
+ - Be helpful, concise, and accurate
47
+ - Ask for clarification when instructions are ambiguous
48
+ - Use tools when they would help accomplish the user's goal
49
+ - Respect the user's preferences and communication style
50
+ `;
51
+ expect(isDefaultBoilerplate("AGENTS.md", content)).toBe(true);
52
+ });
53
+
54
+ it("returns false for customized content", () => {
55
+ const content = `# Agents
56
+
57
+ You are Mima, a cozy companion agent.
58
+
59
+ ## Guidelines
60
+
61
+ - Be warm and supportive
62
+ `;
63
+ expect(isDefaultBoilerplate("AGENTS.md", content)).toBe(false);
64
+ });
65
+
66
+ it("returns false for unknown file names", () => {
67
+ expect(
68
+ isDefaultBoilerplate(
69
+ "CUSTOM.md" as Parameters<typeof isDefaultBoilerplate>[0],
70
+ "anything",
71
+ ),
72
+ ).toBe(false);
73
+ });
74
+
75
+ it("returns true for default TOOLS.md content", () => {
76
+ const content = `# Tools
77
+
78
+ Available tools and capabilities for the agent.
79
+
80
+ ## Built-in Tools
81
+
82
+ The agent has access to tools provided by enabled plugins.
83
+ Each plugin may register actions, providers, and evaluators
84
+ that extend the agent's capabilities.
85
+
86
+ ## Usage
87
+
88
+ Tools are invoked automatically when the agent determines
89
+ they would help accomplish the user's goal. No manual
90
+ configuration is required.
91
+ `;
92
+ expect(isDefaultBoilerplate("TOOLS.md", content)).toBe(true);
93
+ });
94
+ });
@@ -105,7 +105,7 @@ const DEFAULT_MEMORY_ALT_FILENAME = "memory.md";
105
105
  const WORKSPACE_TEMPLATES: Record<string, string> = {
106
106
  [DEFAULT_AGENTS_FILENAME]: `# Agents
107
107
 
108
- You are an autonomous AI agent powered by elizaOS.
108
+ You are an autonomous AI agent powered by ElizaOS.
109
109
 
110
110
  ## Capabilities
111
111
 
@@ -207,6 +207,19 @@ export type WorkspaceInitFile = {
207
207
  missing: boolean;
208
208
  };
209
209
 
210
+ /**
211
+ * Returns true if the file content matches the built-in boilerplate template.
212
+ * Used to skip injecting generic placeholder docs into the prompt.
213
+ */
214
+ export function isDefaultBoilerplate(
215
+ name: WorkspaceBootstrapFileName,
216
+ content: string,
217
+ ): boolean {
218
+ const template = WORKSPACE_TEMPLATES[name];
219
+ if (!template) return false;
220
+ return content.trim() === template.trim();
221
+ }
222
+
210
223
  type ElizaCoreWorkspaceHelpers = {
211
224
  isSubagentSessionKey?: (key: string) => boolean;
212
225
  logger?: {
@@ -8,12 +8,10 @@
8
8
 
9
9
  import type {
10
10
  IAgentRuntime,
11
- Memory,
12
11
  Plugin,
13
12
  Provider,
14
13
  ProviderResult,
15
14
  ServiceClass,
16
- State,
17
15
  } from "@elizaos/core";
18
16
  import { AgentEventService } from "@elizaos/core";
19
17
  import { emoteAction } from "../actions/emote";
@@ -28,7 +26,6 @@ import {
28
26
  } from "../actions/stream-control";
29
27
  import { switchStreamSourceAction } from "../actions/switch-stream-source";
30
28
  import { terminalAction } from "../actions/terminal";
31
- import { AGENT_EMOTE_CATALOG } from "../emotes/catalog";
32
29
  import { adminTrustProvider } from "../providers/admin-trust";
33
30
 
34
31
  import { createSessionKeyProvider } from "../providers/session-bridge";
@@ -69,44 +66,13 @@ export function createElizaPlugin(config?: ElizaPluginConfig): Plugin {
69
66
  ...getSessionProviders({ storePath: sessionStorePath }),
70
67
  ];
71
68
 
72
- // Emote provider injects available emotes into agent context so the LLM
73
- // knows it can trigger animations via the PLAY_EMOTE action.
74
- // Gated on character.settings disable for agents without 3D avatars.
75
- const emoteProvider: Provider = {
76
- name: "emotes",
77
- description: "Available avatar emote animations",
78
-
79
- async get(
80
- _runtime: IAgentRuntime,
81
- _message: Memory,
82
- _state: State,
83
- ): Promise<ProviderResult> {
84
- // Skip emote injection for agents without avatars.
85
- // Set character.settings.DISABLE_EMOTES = true to save ~300 tokens.
86
- const settings = _runtime.character?.settings;
87
- if (settings?.DISABLE_EMOTES) {
88
- return { text: "" };
89
- }
90
- const ids = AGENT_EMOTE_CATALOG.map((e) => e.id).join(", ");
91
- return {
92
- text: [
93
- "## Available Emotes",
94
- "",
95
- "You have a 3D VRM avatar that can perform emote animations via the PLAY_EMOTE action.",
96
- "Use PLAY_EMOTE whenever a visible gesture, reaction, or trick helps.",
97
- "PLAY_EMOTE is a silent one-shot visual side action. It does not speak or post chat text by itself, and it returns to idle automatically.",
98
- 'If you also want text, chain PLAY_EMOTE with REPLY in the same turn — for example actions: ["PLAY_EMOTE", "REPLY"] or ["REPLY", "PLAY_EMOTE"].',
99
- "Only call PLAY_EMOTE when you set the required emote parameter to a valid emote ID. If you cannot choose one, do not call it.",
100
- "Set the emote parameter to the emote ID you want.",
101
- "",
102
- `Available emote IDs: ${ids}`,
103
- "",
104
- "Do not use idle, run, or walk with PLAY_EMOTE.",
105
- "Common mappings: dance/vibe → dance-happy, wave/greet → wave, flip/backflip → flip, cry/sad → crying, fight/punch → punching, fish → fishing",
106
- ].join("\n"),
107
- };
108
- },
109
- };
69
+ // Emote IDs are now declared as an enum on the PLAY_EMOTE action parameter,
70
+ // so they appear in the `# Available Actions` section automatically via
71
+ // core's formatActions. No separate provider injection needed.
72
+ //
73
+ // Backwards-compat: character.settings.DISABLE_EMOTES still works — when set,
74
+ // the PLAY_EMOTE action is excluded at init time so it never appears in the
75
+ // prompt. Previously this was checked per-request in the emote provider.
110
76
 
111
77
  // Custom actions provider — tells the LLM about available custom actions.
112
78
  const customActionsProvider: Provider = {
@@ -139,22 +105,29 @@ export function createElizaPlugin(config?: ElizaPluginConfig): Plugin {
139
105
  },
140
106
  };
141
107
 
142
- return {
108
+ const plugin: Plugin = {
143
109
  name: "eliza",
144
110
  description: "Eliza workspace context, session keys, and lifecycle actions",
145
111
 
146
112
  services: [AgentEventService as ServiceClass],
147
113
 
148
- init: async (_pluginConfig, runtime) => {
114
+ init: async (_pluginConfig, runtime: IAgentRuntime) => {
149
115
  registerTriggerTaskWorker(runtime);
150
116
  setCustomActionsRuntime(runtime);
117
+
118
+ // Honour DISABLE_EMOTES: remove PLAY_EMOTE so it never appears in prompts.
119
+ if (runtime.character?.settings?.DISABLE_EMOTES) {
120
+ const idx = plugin.actions?.findIndex((a) => a.name === "PLAY_EMOTE");
121
+ if (idx != null && idx >= 0) {
122
+ plugin.actions?.splice(idx, 1);
123
+ }
124
+ }
151
125
  },
152
126
 
153
127
  providers: [
154
128
  ...baseProviders,
155
129
 
156
130
  uiCatalogProvider,
157
- emoteProvider,
158
131
  customActionsProvider,
159
132
  ],
160
133
 
@@ -173,4 +146,6 @@ export function createElizaPlugin(config?: ElizaPluginConfig): Plugin {
173
146
  ...loadCustomActions(),
174
147
  ],
175
148
  };
149
+
150
+ return plugin;
176
151
  }