openmates 0.15.0-alpha.34 → 0.15.0-alpha.35

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.
@@ -706,6 +706,7 @@ import {
706
706
  chmodSync,
707
707
  existsSync as existsSync2,
708
708
  mkdirSync,
709
+ readdirSync,
709
710
  readFileSync as readFileSync2,
710
711
  rmSync,
711
712
  writeFileSync
@@ -1138,6 +1139,30 @@ function deleteLocalTeamKey(hashedEmail, teamId) {
1138
1139
  writeJsonFile(filePath, keys);
1139
1140
  }
1140
1141
  }
1142
+ function pruneLocalTeamArtifacts(hashedEmail, teamIds) {
1143
+ const stateDir = ensureStateDir();
1144
+ const allowedKeyIds = new Set(teamIds.map((teamId) => teamKeyStorageId(hashedEmail, teamId)));
1145
+ const keysFilePath = join(stateDir, LOCAL_TEAM_KEYS_FILE);
1146
+ const keys = readJsonFile(keysFilePath);
1147
+ if (keys) {
1148
+ let changed = false;
1149
+ const prefix = `${hashedEmail}:team:`;
1150
+ for (const storageId of Object.keys(keys.teams)) {
1151
+ if (storageId.startsWith(prefix) && !allowedKeyIds.has(storageId)) {
1152
+ deleteMasterKey("keychain", storageId);
1153
+ delete keys.teams[storageId];
1154
+ changed = true;
1155
+ }
1156
+ }
1157
+ if (changed) writeJsonFile(keysFilePath, keys);
1158
+ }
1159
+ const allowedCacheFiles = new Set(teamIds.map((teamId) => syncCacheFile(teamId)));
1160
+ for (const fileName of readdirSync(stateDir)) {
1161
+ if (fileName.startsWith("sync_cache.team.") && fileName.endsWith(".json") && !allowedCacheFiles.has(fileName)) {
1162
+ rmSync(join(stateDir, fileName), { force: true });
1163
+ }
1164
+ }
1165
+ }
1141
1166
  function syncCacheFile(teamId) {
1142
1167
  if (!teamId) return SYNC_CACHE_FILE;
1143
1168
  const digest = createHash3("sha256").update(teamId).digest("hex").slice(0, 32);
@@ -1628,6 +1653,9 @@ var OpenMatesWsClient = class {
1628
1653
  let recoveryJobId = null;
1629
1654
  let followUpSuggestions = [];
1630
1655
  let newChatSuggestions = [];
1656
+ let chatSummary = null;
1657
+ let chatTags = [];
1658
+ let updatedChatTitle = null;
1631
1659
  let taskProposals = [];
1632
1660
  let taskUpdateProposals = [];
1633
1661
  const taskEvents = [];
@@ -1698,6 +1726,9 @@ var OpenMatesWsClient = class {
1698
1726
  modelName,
1699
1727
  followUpSuggestions,
1700
1728
  newChatSuggestions,
1729
+ chatSummary,
1730
+ chatTags,
1731
+ updatedChatTitle,
1701
1732
  taskProposals,
1702
1733
  taskUpdateProposals,
1703
1734
  taskEvents,
@@ -1731,6 +1762,9 @@ var OpenMatesWsClient = class {
1731
1762
  modelName,
1732
1763
  followUpSuggestions,
1733
1764
  newChatSuggestions,
1765
+ chatSummary,
1766
+ chatTags,
1767
+ updatedChatTitle,
1734
1768
  taskProposals,
1735
1769
  taskUpdateProposals,
1736
1770
  taskEvents,
@@ -1753,6 +1787,9 @@ var OpenMatesWsClient = class {
1753
1787
  modelName,
1754
1788
  followUpSuggestions,
1755
1789
  newChatSuggestions,
1790
+ chatSummary,
1791
+ chatTags,
1792
+ updatedChatTitle,
1756
1793
  taskProposals,
1757
1794
  taskUpdateProposals,
1758
1795
  taskEvents,
@@ -1967,6 +2004,18 @@ var OpenMatesWsClient = class {
1967
2004
  (s) => typeof s === "string" && s.length > 0
1968
2005
  );
1969
2006
  }
2007
+ if (typeof p.chat_summary === "string" && p.chat_summary.trim()) {
2008
+ chatSummary = p.chat_summary.trim();
2009
+ }
2010
+ const rawChatTags = p.chat_tags;
2011
+ if (Array.isArray(rawChatTags) && rawChatTags.length > 0) {
2012
+ chatTags = rawChatTags.filter(
2013
+ (tag) => typeof tag === "string" && tag.trim().length > 0
2014
+ ).slice(0, 10);
2015
+ }
2016
+ if (typeof p.updated_chat_title === "string" && p.updated_chat_title.trim()) {
2017
+ updatedChatTitle = p.updated_chat_title.trim();
2018
+ }
1970
2019
  taskProposals = parseTaskProposals(p.task_proposals);
1971
2020
  taskUpdateProposals = parseTaskUpdateProposals(p.task_update_proposals);
1972
2021
  if (aiResponseDone) {
@@ -1997,6 +2046,9 @@ var OpenMatesWsClient = class {
1997
2046
  modelName,
1998
2047
  followUpSuggestions,
1999
2048
  newChatSuggestions,
2049
+ chatSummary,
2050
+ chatTags,
2051
+ updatedChatTitle,
2000
2052
  taskProposals,
2001
2053
  taskUpdateProposals,
2002
2054
  taskEvents,
@@ -5315,6 +5367,11 @@ var OpenMatesClient = class _OpenMatesClient {
5315
5367
  if (!response.ok) throw new Error(`Team list failed with HTTP ${response.status}`);
5316
5368
  const teams = response.data.teams ?? [];
5317
5369
  await Promise.all(teams.map((team) => this.cacheTeamKeyFromRecord(team)));
5370
+ const teamIds = teams.map((team) => team.team_id).filter((teamId) => typeof teamId === "string" && teamId.length > 0);
5371
+ pruneLocalTeamArtifacts(this.requireSession().hashedEmail, teamIds);
5372
+ if (this.session?.activeTeamId && !teamIds.includes(this.session.activeTeamId)) {
5373
+ this.setActiveTeamId(null);
5374
+ }
5318
5375
  return teams;
5319
5376
  }
5320
5377
  async createTeam(input) {
@@ -7245,8 +7302,9 @@ var OpenMatesClient = class _OpenMatesClient {
7245
7302
  inference_request: messagePayload
7246
7303
  };
7247
7304
  if (isNewChat) {
7305
+ const initialTitle = teamId && !shouldWaitForAi ? "New team chat" : "";
7248
7306
  preflightPayload.encrypted_chat_metadata = {
7249
- encrypted_title: await encryptWithAesGcmCombined("", chatKeyBytes),
7307
+ encrypted_title: await encryptWithAesGcmCombined(initialTitle, chatKeyBytes),
7250
7308
  encrypted_chat_key: encryptedChatKey,
7251
7309
  created_at: createdAt,
7252
7310
  updated_at: createdAt
@@ -7296,6 +7354,9 @@ var OpenMatesClient = class _OpenMatesClient {
7296
7354
  if (!params.incognito && typeof confirmedPayload.new_messages_v === "number" && Number.isSafeInteger(confirmedPayload.new_messages_v)) {
7297
7355
  terminalExpectedMessagesV = confirmedPayload.new_messages_v;
7298
7356
  }
7357
+ if (!params.incognito) {
7358
+ clearSyncCache(teamId);
7359
+ }
7299
7360
  let assistant = "";
7300
7361
  let assistantMessageId = null;
7301
7362
  let category = null;
@@ -7710,6 +7771,9 @@ var OpenMatesClient = class _OpenMatesClient {
7710
7771
  chatKeyBytes,
7711
7772
  followUpSuggestions: resp.followUpSuggestions,
7712
7773
  newChatSuggestions: resp.newChatSuggestions,
7774
+ chatSummary: resp.chatSummary,
7775
+ chatTags: resp.chatTags,
7776
+ updatedChatTitle: resp.updatedChatTitle,
7713
7777
  encryptedChatKey
7714
7778
  });
7715
7779
  const persistedTaskJobIds = await this.persistPendingTaskUpdateJobs({
@@ -8148,12 +8212,18 @@ var OpenMatesClient = class _OpenMatesClient {
8148
8212
  (suggestion) => encryptWithAesGcmCombined(suggestion, masterKey)
8149
8213
  )
8150
8214
  );
8151
- if (!encryptedFollowUps && encryptedNewChatSuggestions.length === 0) return;
8215
+ const encryptedChatSummary = params.chatSummary ? await encryptWithAesGcmCombined(params.chatSummary, params.chatKeyBytes) : "";
8216
+ const encryptedChatTags = params.chatTags.length > 0 ? await encryptWithAesGcmCombined(JSON.stringify(params.chatTags.slice(0, 10)), params.chatKeyBytes) : "";
8217
+ const encryptedUpdatedTitle = params.updatedChatTitle ? await encryptWithAesGcmCombined(params.updatedChatTitle, params.chatKeyBytes) : "";
8218
+ if (!encryptedFollowUps && encryptedNewChatSuggestions.length === 0 && !encryptedChatSummary && !encryptedChatTags && !encryptedUpdatedTitle) return;
8152
8219
  await params.ws.sendAsync("update_post_processing_metadata", {
8153
8220
  chat_id: params.chatId,
8154
8221
  ...params.teamId ? { team_id: params.teamId } : {},
8155
8222
  encrypted_follow_up_suggestions: encryptedFollowUps,
8156
8223
  encrypted_new_chat_suggestions: encryptedNewChatSuggestions,
8224
+ encrypted_chat_summary: encryptedChatSummary,
8225
+ encrypted_chat_tags: encryptedChatTags,
8226
+ encrypted_title: encryptedUpdatedTitle,
8157
8227
  encrypted_chat_key: params.encryptedChatKey ?? ""
8158
8228
  });
8159
8229
  await params.ws.waitForMessage(
@@ -18890,7 +18960,7 @@ function formatTs(ts) {
18890
18960
  // src/server.ts
18891
18961
  import { execFileSync as execFileSync2, execSync, spawn as nodeSpawn, spawnSync } from "child_process";
18892
18962
  import { createHash as createHash10, randomBytes as randomBytes5 } from "crypto";
18893
- import { chmodSync as chmodSync3, closeSync, copyFileSync, cpSync, existsSync as existsSync7, mkdirSync as mkdirSync4, mkdtempSync, openSync, readFileSync as readFileSync6, readSync, readdirSync, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
18963
+ import { chmodSync as chmodSync3, closeSync, copyFileSync, cpSync, existsSync as existsSync7, mkdirSync as mkdirSync4, mkdtempSync, openSync, readFileSync as readFileSync6, readSync, readdirSync as readdirSync2, rmSync as rmSync3, writeFileSync as writeFileSync4 } from "fs";
18894
18964
  import { createInterface as createInterface3 } from "readline";
18895
18965
  import { createInterface as createPromptInterface } from "readline/promises";
18896
18966
  import { homedir as homedir6 } from "os";
@@ -19957,7 +20027,7 @@ function hashFile(path) {
19957
20027
  function writeChecksums(rootDir) {
19958
20028
  const lines = [];
19959
20029
  const walk = (dir) => {
19960
- for (const entry of readdirSync(dir, { withFileTypes: true })) {
20030
+ for (const entry of readdirSync2(dir, { withFileTypes: true })) {
19961
20031
  const path = join4(dir, entry.name);
19962
20032
  if (entry.isDirectory()) {
19963
20033
  walk(path);
@@ -21024,7 +21094,7 @@ async function serverBackup(rest, flags) {
21024
21094
  const role = getServerRole(flags, config);
21025
21095
  if (action === "list") {
21026
21096
  const dir = roleBackupDir(installPath, role);
21027
- const files = existsSync7(dir) ? readdirSync(dir).filter((item) => item.endsWith(".tar.gz")).sort() : [];
21097
+ const files = existsSync7(dir) ? readdirSync2(dir).filter((item) => item.endsWith(".tar.gz")).sort() : [];
21028
21098
  if (flags.json === true) {
21029
21099
  printJson({ role, backupDir: dir, files });
21030
21100
  return;
@@ -56672,7 +56742,7 @@ function buildAssistantFeedbackDecision(rating) {
56672
56742
 
56673
56743
  // src/benchmark.ts
56674
56744
  import { randomUUID as randomUUID7 } from "crypto";
56675
- import { existsSync as existsSync8, mkdtempSync as mkdtempSync2, readFileSync as readFileSync7, readdirSync as readdirSync2, writeFileSync as writeFileSync5 } from "fs";
56745
+ import { existsSync as existsSync8, mkdtempSync as mkdtempSync2, readFileSync as readFileSync7, readdirSync as readdirSync3, writeFileSync as writeFileSync5 } from "fs";
56676
56746
  import { tmpdir } from "os";
56677
56747
  import { dirname as dirname4, join as join5, resolve as resolve5 } from "path";
56678
56748
  import { fileURLToPath } from "url";
@@ -57471,7 +57541,7 @@ function loadProviderPricing() {
57471
57541
  const providersDir = findProvidersDir();
57472
57542
  const pricing = /* @__PURE__ */ new Map();
57473
57543
  if (!providersDir) return pricing;
57474
- for (const fileName of readdirSync2(providersDir)) {
57544
+ for (const fileName of readdirSync3(providersDir)) {
57475
57545
  if (!fileName.endsWith(".yml")) continue;
57476
57546
  const filePath = join5(providersDir, fileName);
57477
57547
  const text = readFileSync7(filePath, "utf-8");
@@ -64406,14 +64476,18 @@ async function sendMessageStreaming(client, params, redactor) {
64406
64476
  };
64407
64477
  const preparedEmbeds = [];
64408
64478
  let finalMessage = params.message;
64479
+ const isTeamAiTrigger = params.personal !== true && (typeof params.teamId === "string" || Boolean(client.getActiveTeamId()));
64409
64480
  if (params.message.includes("@")) {
64410
64481
  try {
64411
64482
  const mentionCtx = await client.buildMentionContext();
64412
64483
  const parsed = parseMentions(params.message, mentionCtx);
64413
64484
  finalMessage = parsed.processedMessage;
64414
- if (parsed.unresolved.length > 0) {
64485
+ const unresolvedMentions = parsed.unresolved.filter(
64486
+ (mention) => !(isTeamAiTrigger && mention.original.toLowerCase() === "@openmates")
64487
+ );
64488
+ if (unresolvedMentions.length > 0) {
64415
64489
  clearTyping();
64416
- for (const u of parsed.unresolved) {
64490
+ for (const u of unresolvedMentions) {
64417
64491
  process.stderr.write(
64418
64492
  `\x1B[31mError:\x1B[0m Unknown mention ${u.original}
64419
64493
  `
@@ -64582,6 +64656,9 @@ async function sendMessageStreaming(client, params, redactor) {
64582
64656
  } catch {
64583
64657
  }
64584
64658
  }
64659
+ if (isTeamAiTrigger && params.message.toLowerCase().includes("@openmates") && !finalMessage.toLowerCase().includes("@openmates")) {
64660
+ finalMessage = `@openmates ${finalMessage}`.trim();
64661
+ }
64585
64662
  const piiResult = params.piiDetection !== false && redactor?.isInitialized ? redactor.redactWithMappings(finalMessage) : { redacted: finalMessage, mappings: [] };
64586
64663
  finalMessage = piiResult.redacted;
64587
64664
  if (!client.hasSession()) {
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getExtForLang,
4
4
  serializeToYaml
5
- } from "./chunk-ASTZUBZU.js";
5
+ } from "./chunk-CQDCPDZQ.js";
6
6
  import "./chunk-AXNRPVLE.js";
7
7
  export {
8
8
  getExtForLang,
package/dist/index.d.ts CHANGED
@@ -216,6 +216,9 @@ declare class OpenMatesWsClient {
216
216
  modelName: string | null;
217
217
  followUpSuggestions: string[];
218
218
  newChatSuggestions: string[];
219
+ chatSummary: string | null;
220
+ chatTags: string[];
221
+ updatedChatTitle: string | null;
219
222
  taskProposals: TaskProposalEvent[];
220
223
  taskUpdateProposals: TaskUpdateProposalEvent[];
221
224
  taskEvents: TaskEventFrame[];
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  reconcileAuthoritativeChats,
19
19
  renderSupportInfo,
20
20
  serializeToYaml
21
- } from "./chunk-ASTZUBZU.js";
21
+ } from "./chunk-CQDCPDZQ.js";
22
22
  import "./chunk-AXNRPVLE.js";
23
23
  export {
24
24
  APP_SKILL_METADATA,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openmates",
3
- "version": "0.15.0-alpha.34",
3
+ "version": "0.15.0-alpha.35",
4
4
  "description": "OpenMates CLI and SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",