@economic/agents 2.10.1 → 2.10.3

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
@@ -383,6 +383,8 @@ declare abstract class Assistant<State = unknown> extends Agent$1<Cloudflare.Env
383
383
  * Best-effort and non-blocking.
384
384
  */
385
385
  private touchInstance;
386
+ private syncChatToGlobalList;
387
+ private deleteChatFromGlobalList;
386
388
  observability?: Observability;
387
389
  }
388
390
  //#endregion
package/dist/index.mjs CHANGED
@@ -1480,6 +1480,11 @@ function registerChat(sql, durableObjectName, dateTime) {
1480
1480
  VALUES (${durableObjectName}, ${dateTime}, ${dateTime})
1481
1481
  ON CONFLICT (durable_object_name) DO NOTHING`;
1482
1482
  }
1483
+ function touchChat(sql, durableObjectName, dateTime = Date.now()) {
1484
+ sql`UPDATE chats
1485
+ SET updated_at = ${dateTime}
1486
+ WHERE durable_object_name = ${durableObjectName}`;
1487
+ }
1483
1488
  /**
1484
1489
  * Sets a chat's title on the user's behalf. Marks the title as user-set so
1485
1490
  * the AI summariser stops overwriting it (it keeps updating the summary).
@@ -1522,21 +1527,21 @@ function recordChatFeedback(sql, durableObjectName, messageId, rating, dateTime
1522
1527
  WHERE chat_id = ${durableObjectName} AND rating < 0`;
1523
1528
  sql`UPDATE chats
1524
1529
  SET positive_feedback_count = ${Number(positiveRows[0]?.count ?? 0)},
1525
- negative_feedback_count = ${Number(negativeRows[0]?.count ?? 0)}
1530
+ negative_feedback_count = ${Number(negativeRows[0]?.count ?? 0)},
1531
+ updated_at = ${dateTime}
1526
1532
  WHERE durable_object_name = ${durableObjectName}`;
1527
1533
  }
1528
1534
  function getDeleteChatScheduleIds(schedules, durableObjectName) {
1529
1535
  return schedules.filter((schedule) => schedule.callback === "deleteChatCallback" && schedule.payload === durableObjectName).map((schedule) => schedule.id);
1530
1536
  }
1531
- /**
1532
- * Number of recent messages passed to `generateSummary` for rolling
1533
- * summarization. Keeping this bounded prevents the prompt growing
1534
- * unboundedly regardless of chat length.
1535
- */
1536
- const CHAT_RECENT_MESSAGES_COUNT = 20;
1537
+ const CHAT_SUMMARY_TURN_INTERVAL = 5;
1538
+ function isChatSummaryDue(messages) {
1539
+ const completedTurns = messages.filter((message) => message.role === "user").length;
1540
+ return completedTurns > 0 && completedTurns % CHAT_SUMMARY_TURN_INTERVAL === 0;
1541
+ }
1537
1542
  async function summariseChatWithAI(sql, durableObjectName, messages, model) {
1538
1543
  const chat = getChat(sql, durableObjectName);
1539
- if (!(!chat || !chat.title || messages.length % CHAT_RECENT_MESSAGES_COUNT === 0)) return;
1544
+ if (!(!chat || !chat.title || isChatSummaryDue(messages))) return;
1540
1545
  let systemPrompt = `
1541
1546
  You are a helpful assistant that summarises chats.
1542
1547
  You will be given a list of messages and you need to generate a title and summary for the chat.
@@ -1587,6 +1592,24 @@ function getChatRetentionMs(days) {
1587
1592
  return Math.floor(days * 24 * 60 * 60 * 1e3);
1588
1593
  }
1589
1594
  //#endregion
1595
+ //#region src/server/features/global-chats.ts
1596
+ async function upsertGlobalChat(db, chat) {
1597
+ await db.prepare(`INSERT INTO agent_chats (
1598
+ agent_name, assistant_name, chat_id, title, summary, created_at, updated_at,
1599
+ positive_feedback_count, negative_feedback_count
1600
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
1601
+ ON CONFLICT (agent_name, assistant_name, chat_id) DO UPDATE SET
1602
+ title = excluded.title,
1603
+ summary = excluded.summary,
1604
+ updated_at = excluded.updated_at,
1605
+ positive_feedback_count = excluded.positive_feedback_count,
1606
+ negative_feedback_count = excluded.negative_feedback_count`).bind(chat.agentName, chat.assistantName, chat.chatId, chat.title, chat.summary, chat.createdAt, chat.updatedAt, chat.positiveFeedbackCount, chat.negativeFeedbackCount).run();
1607
+ }
1608
+ async function deleteGlobalChat(db, agentName, assistantName, chatId) {
1609
+ await db.prepare(`DELETE FROM agent_chats
1610
+ WHERE agent_name = ? AND assistant_name = ? AND chat_id = ?`).bind(agentName, assistantName, chatId).run();
1611
+ }
1612
+ //#endregion
1590
1613
  //#region src/server/agents/Assistant.ts
1591
1614
  let _initProto$1;
1592
1615
  function _applyDecs$1(e, t, n, r, o, i) {
@@ -1824,9 +1847,11 @@ var Assistant = class extends Agent$1 {
1824
1847
  async deleteChat(id) {
1825
1848
  await this.deleteSubAgent(this.agent, id);
1826
1849
  deleteChat(this.sql.bind(this), id);
1850
+ await this.deleteChatFromGlobalList(id);
1827
1851
  }
1828
1852
  async renameChat(id, title) {
1829
1853
  renameChat(this.sql.bind(this), id, title);
1854
+ await this.syncChatToGlobalList(id);
1830
1855
  }
1831
1856
  async getChats() {
1832
1857
  return getChats(this.sql.bind(this));
@@ -1836,8 +1861,10 @@ var Assistant = class extends Agent$1 {
1836
1861
  }
1837
1862
  async registerChat(durableObjectName) {
1838
1863
  registerChat(this.sql.bind(this), durableObjectName, Date.now());
1864
+ await this.syncChatToGlobalList(durableObjectName);
1839
1865
  }
1840
1866
  async recordChatTurn(durableObjectName, messages) {
1867
+ touchChat(this.sql.bind(this), durableObjectName);
1841
1868
  this.keepAliveWhile(async () => {
1842
1869
  await Promise.all([summariseChatWithAI(this.sql.bind(this), durableObjectName, messages, this.fastModel), this.scheduleChatForAutoDeletion(durableObjectName).catch((error) => {
1843
1870
  console.error("[Assistant] Failed to reschedule chat deletion", {
@@ -1845,6 +1872,7 @@ var Assistant = class extends Agent$1 {
1845
1872
  error
1846
1873
  });
1847
1874
  })]);
1875
+ await this.syncChatToGlobalList(durableObjectName);
1848
1876
  }).catch((error) => {
1849
1877
  console.error("[Assistant] Failed to record chat metadata", {
1850
1878
  durableObjectName,
@@ -1854,6 +1882,7 @@ var Assistant = class extends Agent$1 {
1854
1882
  }
1855
1883
  async recordChatFeedback(durableObjectName, messageId, rating) {
1856
1884
  recordChatFeedback(this.sql.bind(this), durableObjectName, messageId, rating);
1885
+ await this.syncChatToGlobalList(durableObjectName);
1857
1886
  }
1858
1887
  async [DELETE_CHAT_CALLBACK](durableObjectName) {
1859
1888
  await this.deleteChat(durableObjectName);
@@ -1909,6 +1938,38 @@ var Assistant = class extends Agent$1 {
1909
1938
  console.error("[Assistant] Failed to update agent_registry activity", error);
1910
1939
  }
1911
1940
  }
1941
+ async syncChatToGlobalList(durableObjectName) {
1942
+ const chat = getChat(this.sql.bind(this), durableObjectName);
1943
+ if (!chat) return;
1944
+ try {
1945
+ await upsertGlobalChat(this.env.AGENTS_DB, {
1946
+ agentName: this.constructor.name,
1947
+ assistantName: this.name,
1948
+ chatId: chat.durable_object_name,
1949
+ title: chat.title ?? null,
1950
+ summary: chat.summary ?? null,
1951
+ createdAt: chat.created_at,
1952
+ updatedAt: chat.updated_at,
1953
+ positiveFeedbackCount: chat.positive_feedback_count,
1954
+ negativeFeedbackCount: chat.negative_feedback_count
1955
+ });
1956
+ } catch (error) {
1957
+ console.error("[Assistant] Failed to sync chat to agent_chats", {
1958
+ durableObjectName,
1959
+ error
1960
+ });
1961
+ }
1962
+ }
1963
+ async deleteChatFromGlobalList(durableObjectName) {
1964
+ try {
1965
+ await deleteGlobalChat(this.env.AGENTS_DB, this.constructor.name, this.name, durableObjectName);
1966
+ } catch (error) {
1967
+ console.error("[Assistant] Failed to delete chat from agent_chats", {
1968
+ durableObjectName,
1969
+ error
1970
+ });
1971
+ }
1972
+ }
1912
1973
  observability = createWorkerObservability({ getIdentity: () => ({
1913
1974
  agentName: this.constructor.name,
1914
1975
  agentClass: this.constructor.name
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@economic/agents",
3
- "version": "2.10.1",
3
+ "version": "2.10.3",
4
4
  "description": "A starter for creating a TypeScript package.",
5
5
  "license": "MIT",
6
6
  "files": [