@economic/agents 2.3.22 → 2.3.24

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/dist/index.d.mts CHANGED
@@ -128,7 +128,7 @@ declare abstract class Agent<RequestContext extends Record<string, unknown> = Re
128
128
  * `updated_at`, so instances can be ordered by recency of activity.
129
129
  * Best-effort and non-blocking — never allowed to interfere with a turn.
130
130
  */
131
- protected touchInstance(): Promise<void>;
131
+ protected registerInstanceActivity(): Promise<void>;
132
132
  /**
133
133
  * Resolves the analytics/telemetry agent name to the entry-point agent: the
134
134
  * top-level DO registered in the `agent` catalog table.
@@ -239,6 +239,8 @@ type Chat = {
239
239
  summary?: string;
240
240
  created_at: number;
241
241
  updated_at: number;
242
+ positive_feedback_count: number;
243
+ negative_feedback_count: number;
242
244
  };
243
245
  declare const DELETE_CHAT_CALLBACK: "deleteChatCallback";
244
246
  //#endregion
@@ -252,7 +254,9 @@ declare abstract class Assistant<State = unknown> extends Agent$1<Cloudflare.Env
252
254
  createChat(): Promise<string>;
253
255
  deleteChat(id: string): Promise<void>;
254
256
  getChats(): Promise<Chat[]>;
257
+ getChatAgentClassName(): Promise<string>;
255
258
  recordChatTurn(durableObjectName: string, messages: UIMessage[]): Promise<void>;
259
+ recordChatFeedback(durableObjectName: string, messageId: string, rating: number): Promise<void>;
256
260
  private [DELETE_CHAT_CALLBACK];
257
261
  private scheduleChatForAutoDeletion;
258
262
  /**
package/dist/index.mjs CHANGED
@@ -170,7 +170,7 @@ var Agent = class extends Think {
170
170
  return;
171
171
  }
172
172
  const token = extractTokenFromConnectRequest(ctx.request);
173
- if (token && this.getUserContext) this.userContext = await this.getUserContext(token);
173
+ if (token && this.getUserContext) connection.setState({ userContext: await this.getUserContext(token) });
174
174
  }
175
175
  }
176
176
  sendConnectionStatus(connection, "connected");
@@ -178,9 +178,10 @@ var Agent = class extends Think {
178
178
  _toolsForCurrentTurn = {};
179
179
  _toolContextForCurrentTurn;
180
180
  getToolContextForCurrentTurn(requestContext = {}) {
181
+ const connectionState = getCurrentAgent().connection?.state;
181
182
  return {
182
183
  ...requestContext,
183
- _userContext: this.userContext
184
+ _userContext: connectionState?.userContext
184
185
  };
185
186
  }
186
187
  /**
@@ -191,7 +192,7 @@ var Agent = class extends Think {
191
192
  * `returned.tools` into your own `TurnConfig.tools` if you return tools.
192
193
  */
193
194
  async beforeTurn(ctx) {
194
- this.touchInstance();
195
+ this.registerInstanceActivity();
195
196
  this._toolContextForCurrentTurn = this.getToolContextForCurrentTurn(ctx.body);
196
197
  this._toolsForCurrentTurn = ctx.tools;
197
198
  const activeSkillName = this._getLastActivatedSkillName(ctx.messages);
@@ -348,7 +349,7 @@ var Agent = class extends Think {
348
349
  * `updated_at`, so instances can be ordered by recency of activity.
349
350
  * Best-effort and non-blocking — never allowed to interfere with a turn.
350
351
  */
351
- async touchInstance() {
352
+ async registerInstanceActivity() {
352
353
  try {
353
354
  await touchAgentInstance(this.env.AGENTS_DB, {
354
355
  ...this.getRegisteredInstanceKey(),
@@ -388,12 +389,33 @@ function ensureChatsTableExists(sql) {
388
389
  summary TEXT,
389
390
  created_at INTEGER NOT NULL,
390
391
  updated_at INTEGER NOT NULL,
392
+ positive_feedback_count INTEGER NOT NULL DEFAULT 0,
393
+ negative_feedback_count INTEGER NOT NULL DEFAULT 0,
391
394
  PRIMARY KEY (durable_object_name)
392
395
  )`;
396
+ ensureChatsFeedbackColumnsExist(sql);
397
+ ensureChatMessageFeedbackTableExists(sql);
393
398
  } catch (error) {
394
399
  console.error("[Agent] Failed to create chats table", error);
395
400
  }
396
401
  }
402
+ function ensureChatsFeedbackColumnsExist(sql) {
403
+ try {
404
+ sql`ALTER TABLE chats ADD COLUMN positive_feedback_count INTEGER NOT NULL DEFAULT 0`;
405
+ } catch {}
406
+ try {
407
+ sql`ALTER TABLE chats ADD COLUMN negative_feedback_count INTEGER NOT NULL DEFAULT 0`;
408
+ } catch {}
409
+ }
410
+ function ensureChatMessageFeedbackTableExists(sql) {
411
+ sql`CREATE TABLE IF NOT EXISTS chat_message_feedback (
412
+ chat_id TEXT NOT NULL,
413
+ message_id TEXT NOT NULL,
414
+ rating INTEGER NOT NULL,
415
+ updated_at INTEGER NOT NULL,
416
+ PRIMARY KEY (chat_id, message_id)
417
+ )`;
418
+ }
397
419
  function registerChat(sql, durableObjectName, dateTime) {
398
420
  sql`INSERT INTO chats (durable_object_name, created_at, updated_at)
399
421
  VALUES (${durableObjectName}, ${dateTime}, ${dateTime})`;
@@ -415,6 +437,7 @@ function registerChatWithMetadata(sql, durableObjectName, metadata) {
415
437
  }
416
438
  function deleteChat(sql, durableObjectName) {
417
439
  sql`DELETE FROM chats WHERE durable_object_name = ${durableObjectName}`;
440
+ sql`DELETE FROM chat_message_feedback WHERE chat_id = ${durableObjectName}`;
418
441
  }
419
442
  function getChat(sql, durableObjectName) {
420
443
  return sql`SELECT * FROM chats WHERE durable_object_name = ${durableObjectName}`[0] ?? null;
@@ -422,6 +445,23 @@ function getChat(sql, durableObjectName) {
422
445
  async function getChats(sql) {
423
446
  return sql`SELECT * FROM chats ORDER BY updated_at DESC`;
424
447
  }
448
+ function recordChatFeedback(sql, durableObjectName, messageId, rating, dateTime = Date.now()) {
449
+ sql`INSERT INTO chat_message_feedback (chat_id, message_id, rating, updated_at)
450
+ VALUES (${durableObjectName}, ${messageId}, ${rating}, ${dateTime})
451
+ ON CONFLICT (chat_id, message_id) DO UPDATE SET
452
+ rating = excluded.rating,
453
+ updated_at = excluded.updated_at`;
454
+ const positiveRows = sql`SELECT COUNT(*) AS count
455
+ FROM chat_message_feedback
456
+ WHERE chat_id = ${durableObjectName} AND rating > 0`;
457
+ const negativeRows = sql`SELECT COUNT(*) AS count
458
+ FROM chat_message_feedback
459
+ WHERE chat_id = ${durableObjectName} AND rating < 0`;
460
+ sql`UPDATE chats
461
+ SET positive_feedback_count = ${Number(positiveRows[0]?.count ?? 0)},
462
+ negative_feedback_count = ${Number(negativeRows[0]?.count ?? 0)}
463
+ WHERE durable_object_name = ${durableObjectName}`;
464
+ }
425
465
  function getDeleteChatScheduleIds(schedules) {
426
466
  return schedules.filter((schedule) => schedule.callback === DELETE_CHAT_CALLBACK).map((schedule) => schedule.id);
427
467
  }
@@ -717,6 +757,11 @@ var Assistant = class extends Agent$1 {
717
757
  callable(),
718
758
  2,
719
759
  "getChats"
760
+ ],
761
+ [
762
+ callable(),
763
+ 2,
764
+ "getChatAgentClassName"
720
765
  ]
721
766
  ], 0, void 0, Agent$1).e;
722
767
  }
@@ -774,10 +819,16 @@ var Assistant = class extends Agent$1 {
774
819
  async getChats() {
775
820
  return getChats(this.sql.bind(this));
776
821
  }
822
+ async getChatAgentClassName() {
823
+ return this.agent.name;
824
+ }
777
825
  async recordChatTurn(durableObjectName, messages) {
778
826
  summariseChatWithAI(this.sql.bind(this), durableObjectName, messages, this.fastModel);
779
827
  this.scheduleChatForAutoDeletion(durableObjectName);
780
828
  }
829
+ async recordChatFeedback(durableObjectName, messageId, rating) {
830
+ recordChatFeedback(this.sql.bind(this), durableObjectName, messageId, rating);
831
+ }
781
832
  async [DELETE_CHAT_CALLBACK](durableObjectName) {
782
833
  await this.deleteChat(durableObjectName);
783
834
  }
@@ -1092,11 +1143,21 @@ var ChatAgent = class extends Agent {
1092
1143
  */
1093
1144
  async submitMessageFeedback(messageId, rating, comment) {
1094
1145
  const result = submitMessageFeedback(this.sql.bind(this), messageId, rating, comment);
1146
+ const parent = await this.getParentAgent();
1095
1147
  recordFeedbackAnalytics(this.env.AGENTS_ANALYTICS, {
1096
1148
  agentName: this.getTelemetryAgentName(),
1097
1149
  durableObjectName: this.name,
1098
1150
  actorId: this.getTelemetryActorId()
1099
1151
  }, messageId, rating);
1152
+ if (parent?.recordChatFeedback) try {
1153
+ await parent.recordChatFeedback(this.name, messageId, rating);
1154
+ } catch (error) {
1155
+ console.error("[ChatAgent] Failed to update parent chat feedback summary", {
1156
+ durableObjectName: this.name,
1157
+ messageId,
1158
+ error
1159
+ });
1160
+ }
1100
1161
  return result;
1101
1162
  }
1102
1163
  /**
@@ -1120,11 +1181,23 @@ var ChatAgent = class extends Agent {
1120
1181
  */
1121
1182
  async importLegacyMessages(messages, feedback = []) {
1122
1183
  let parentId = null;
1184
+ const parent = await this.getParentAgent();
1123
1185
  for (const message of messages) {
1124
1186
  await this.appendMessageToHistory(message, parentId);
1125
1187
  parentId = message.id;
1126
1188
  }
1127
- for (const item of feedback) submitMessageFeedback(this.sql.bind(this), item.messageId, item.rating, item.comment);
1189
+ for (const item of feedback) {
1190
+ submitMessageFeedback(this.sql.bind(this), item.messageId, item.rating, item.comment);
1191
+ try {
1192
+ await parent?.recordChatFeedback?.(this.name, item.messageId, item.rating);
1193
+ } catch (error) {
1194
+ console.error("[ChatAgent] Failed to import parent chat feedback summary", {
1195
+ durableObjectName: this.name,
1196
+ messageId: item.messageId,
1197
+ error
1198
+ });
1199
+ }
1200
+ }
1128
1201
  }
1129
1202
  };
1130
1203
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@economic/agents",
3
- "version": "2.3.22",
3
+ "version": "2.3.24",
4
4
  "description": "A starter for creating a TypeScript package.",
5
5
  "license": "MIT",
6
6
  "files": [
@@ -25,10 +25,10 @@
25
25
  "dependencies": {
26
26
  "@ai-sdk/anthropic": "^3.0.77",
27
27
  "@ai-sdk/google": "^3.0.73",
28
- "@cloudflare/ai-chat": "^0.8.5",
29
- "@cloudflare/think": ">=0.9.0",
28
+ "@cloudflare/ai-chat": "^0.9.3",
29
+ "@cloudflare/think": "^0.12.1",
30
30
  "@opentelemetry/sdk-trace-base": "^2.8.0",
31
- "agents": ">=0.16.0 <1.0.0",
31
+ "agents": "^0.17.3",
32
32
  "ai": "^6.0.197",
33
33
  "jose": "^6.2.3",
34
34
  "nanoid": "^5.1.11"
@@ -36,7 +36,7 @@
36
36
  "devDependencies": {
37
37
  "@babel/core": "^7.29.7",
38
38
  "@babel/plugin-proposal-decorators": "^7.29.7",
39
- "@cloudflare/workers-types": "^4.20260616.1",
39
+ "@cloudflare/workers-types": "^4.20260701.1",
40
40
  "@rolldown/plugin-babel": "^0.2.3",
41
41
  "@types/node": "^25.6.0",
42
42
  "@typescript/native-preview": "7.0.0-dev.20260412.1",
@@ -45,10 +45,10 @@
45
45
  "vitest": "^4.1.4"
46
46
  },
47
47
  "peerDependencies": {
48
- "@cloudflare/think": ">=0.9.0",
49
- "@cloudflare/vite-plugin": "^1.42.0",
50
- "@cloudflare/worker-bundler": ">=0.2.1",
51
- "agents": ">=0.16.0 <1.0.0",
48
+ "@cloudflare/think": "^0.12.1",
49
+ "@cloudflare/vite-plugin": "^1.42.4",
50
+ "@cloudflare/worker-bundler": "^0.2.1",
51
+ "agents": "^0.17.3",
52
52
  "vite": ">=8.0.0"
53
53
  }
54
54
  }