@economic/agents 0.0.1-beta.1 → 0.0.1-beta.2

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.
package/README.md CHANGED
@@ -202,6 +202,18 @@ When `fastModel` is set, compaction runs automatically with a default threshold
202
202
 
203
203
  When `fastModel` is `undefined` (the default), compaction is disabled regardless of `maxMessagesBeforeCompaction`.
204
204
 
205
+ ### `getConversations` (callable)
206
+
207
+ `AIChatAgent` exposes a [callable method](https://developers.cloudflare.com/agents/api-reference/callable-methods/) via the Agents SDK `@callable()` decorator (`agents` package). From any connected client (for example the object returned by `useAgent` / `useAIChatAgent`), invoke:
208
+
209
+ ```typescript
210
+ const rows = await agent.call("getConversations");
211
+ ```
212
+
213
+ - **User scope**: `userId` is taken from the segment before the first `:` in the Durable Object name (`userId:chatId`), the same format enforced in `onConnect`.
214
+ - **Data**: Reads from `AGENT_DB`, returning all `conversations` rows whose `durable_object_name` matches `userId:%`, ordered by `updated_at` descending (newest first). Each row includes `durable_object_name`, `title`, `summary`, `created_at`, and `updated_at`.
215
+ - **No D1**: If `AGENT_DB` is not bound, the method returns `undefined` and does not throw.
216
+
205
217
  ### `getLoadedSkills()`
206
218
 
207
219
  Protected method on `AIChatAgent`. Returns skill names persisted from previous turns (read from DO SQLite). Used internally by `this.buildLLMParams()`.
@@ -546,12 +558,14 @@ No subclass code is needed — this runs automatically when `AGENT_DB` is bound
546
558
 
547
559
  ### Querying conversation lists
548
560
 
549
- To fetch all conversations for a user, ordered by most recent:
561
+ From a connected agent client, prefer the built-in callable (see **`getConversations` (callable)** under [`AIChatAgent`](#aichatagent)): `await agent.call("getConversations")`.
562
+
563
+ To query D1 directly (same logic as the callable), filter by `durable_object_name` prefix — one row per chat, keyed as `userId:chatId`:
550
564
 
551
565
  ```sql
552
- SELECT durable_object_id, title, summary, created_at, updated_at
566
+ SELECT durable_object_name, title, summary, created_at, updated_at
553
567
  FROM conversations
554
- WHERE user_id = '148583_matt'
568
+ WHERE durable_object_name LIKE '148583_matt:%'
555
569
  ORDER BY updated_at DESC;
556
570
  ```
557
571
 
@@ -563,9 +577,9 @@ If `userId` is not set on the request body, the upsert is skipped and a `console
563
577
 
564
578
  ### Classes
565
579
 
566
- | Export | Description |
567
- | ------------- | --------------------------------------------------------------------------------------------------------------------- |
568
- | `AIChatAgent` | Abstract CF Durable Object base class. Implement `onChatMessage`. Manages skill state, history replay, and audit log. |
580
+ | Export | Description |
581
+ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
582
+ | `AIChatAgent` | Abstract CF Durable Object base class. Implement `onChatMessage`. Manages skill state, history replay, audit log, and D1 `conversations` upserts. Exposes callable `getConversations` for listing a user’s conversations from the client. |
569
583
 
570
584
  ### Functions
571
585
 
package/dist/index.mjs CHANGED
@@ -39,6 +39,14 @@ function buildActivateSkillDescription(skills) {
39
39
  skills.map((s) => `• ${s.name} — ${s.description}`).join("\n")
40
40
  ].join("\n");
41
41
  }
42
+ function buildAvailableSkillList(skills) {
43
+ return [
44
+ "**Loading More Tools:**",
45
+ "Use `activate_skill` to load these categories (BE PROACTIVE on requesting tools based on the user's request AND you DON'T need to mention that you are loading more tools):",
46
+ "",
47
+ skills.map((s) => `**${s.name}**: ${s.description}`).join("\n")
48
+ ].join("\n");
49
+ }
42
50
  const LIST_CAPABILITIES_DESCRIPTION = "List all tools currently available to you, which skills are loaded, and which can still be loaded. Call this when the user asks about your capabilities or what you can do.";
43
51
  /**
44
52
  * Sentinel appended to a successful activate_skill result.
@@ -63,6 +71,7 @@ function createSkills(config) {
63
71
  const { tools: alwaysOnTools, skills } = config;
64
72
  const loadedSkills = new Set(config.initialLoadedSkills ?? []);
65
73
  const skillMap = new Map(skills.map((s) => [s.name, s]));
74
+ const availableSkillList = skills.length > 0 ? buildAvailableSkillList(skills) : "";
66
75
  const allTools = {};
67
76
  Object.assign(allTools, alwaysOnTools);
68
77
  for (const skill of skills) Object.assign(allTools, skill.tools);
@@ -80,12 +89,26 @@ function createSkills(config) {
80
89
  return names;
81
90
  }
82
91
  function getLoadedGuidance() {
83
- return [...loadedSkills].map((name) => skillMap.get(name)?.guidance).filter((g) => Boolean(g)).join("\n\n");
92
+ const sections = [...loadedSkills].flatMap((name) => {
93
+ const skill = skillMap.get(name);
94
+ if (!skill?.guidance) return [];
95
+ return [`**${skill.name}**\n${skill.guidance}`];
96
+ });
97
+ if (sections.length === 0) return "";
98
+ return [
99
+ "**Loaded skill instructions**",
100
+ "The following skills are currently active. Apply their instructions when using the corresponding tools.",
101
+ "",
102
+ sections.join("\n\n")
103
+ ].join("\n");
84
104
  }
85
105
  function getSystem() {
86
106
  const guidance = getLoadedGuidance();
87
- if (!config.systemPrompt) return guidance;
88
- return guidance ? `${config.systemPrompt}\n\n${guidance}` : config.systemPrompt;
107
+ return [
108
+ config.systemPrompt,
109
+ availableSkillList,
110
+ guidance
111
+ ].filter(Boolean).join("\n\n");
89
112
  }
90
113
  allTools[ACTIVATE_SKILL] = tool({
91
114
  description: buildActivateSkillDescription(skills),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@economic/agents",
3
- "version": "0.0.1-beta.1",
3
+ "version": "0.0.1-beta.2",
4
4
  "description": "A starter for creating a TypeScript package.",
5
5
  "license": "MIT",
6
6
  "files": [