openmates 0.15.0-alpha.17 → 0.15.0-alpha.19

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.
@@ -1338,9 +1338,11 @@ var OpenMatesWsClient = class {
1338
1338
  const token = options.wsToken || options.refreshToken || "";
1339
1339
  const query = new URLSearchParams({
1340
1340
  sessionId: options.sessionId,
1341
- token,
1342
- client_capabilities: "task_update_jobs"
1341
+ token
1343
1342
  });
1343
+ if (options.taskUpdateJobs !== false) {
1344
+ query.set("client_capabilities", "task_update_jobs");
1345
+ }
1344
1346
  const wsHeaders = {};
1345
1347
  if (options.userAgent) {
1346
1348
  wsHeaders["User-Agent"] = options.userAgent;
@@ -3980,6 +3982,13 @@ function taskUpdateJobBelongsToActiveTurn(job, activeChatId, taskEvents) {
3980
3982
  void activeChatId;
3981
3983
  return taskEvents.some((event) => event.task_update_job_id === job.job_id);
3982
3984
  }
3985
+ function messageExplicitlyRequestsTasksAppSkill(message) {
3986
+ return /@skill:tasks:(create|search)\b/i.test(message) || /@tasks-(create|search)\b/i.test(message);
3987
+ }
3988
+ function isStaleTaskUpdateJobError(error) {
3989
+ if (!(error instanceof WebSocketProtocolError)) return false;
3990
+ return error.message.includes("Task update job already committed") || error.message.includes("Task update job expired") || error.message.includes("Task update job not found") || error.message.includes("Task update job is leased by another device");
3991
+ }
3983
3992
  function buildTaskUpdateJobPersistPayload(params) {
3984
3993
  const encryptedTaskPayload = pruneAbsentTaskPersistFields(params.encryptedTaskPayload);
3985
3994
  assertTaskPersistPayloadEncrypted(encryptedTaskPayload);
@@ -5928,7 +5937,10 @@ var OpenMatesClient = class _OpenMatesClient {
5928
5937
  }
5929
5938
  }
5930
5939
  }
5931
- const { ws, session, ownerId } = await this.openWsClient();
5940
+ const explicitTasksAppSkill = messageExplicitlyRequestsTasksAppSkill(params.message);
5941
+ const { ws, session, ownerId } = await this.openWsClient({
5942
+ taskUpdateJobs: !explicitTasksAppSkill
5943
+ });
5932
5944
  if (!params.incognito && !ownerId) {
5933
5945
  ws.close();
5934
5946
  throw new Error("Authenticated user identity is required for saved chat recovery.");
@@ -5982,9 +5994,10 @@ var OpenMatesClient = class _OpenMatesClient {
5982
5994
  }
5983
5995
  }
5984
5996
  }
5997
+ const clientCapabilities = explicitTasksAppSkill ? [] : ["task_update_jobs"];
5985
5998
  const messagePayload = {
5986
5999
  chat_id: chatId,
5987
- client_capabilities: ["task_update_jobs"],
6000
+ client_capabilities: clientCapabilities,
5988
6001
  is_incognito: Boolean(params.incognito),
5989
6002
  message: {
5990
6003
  message_id: messageId,
@@ -6724,15 +6737,27 @@ var OpenMatesClient = class _OpenMatesClient {
6724
6737
  (payload) => payload.job_id === job.job_id,
6725
6738
  2e4
6726
6739
  );
6727
- await params.ws.sendAsync("task_update_job_claim", {
6728
- protocol_version: 1,
6729
- job_id: job.job_id
6730
- });
6731
- const claim = (await claimPromise).payload;
6740
+ let claim;
6741
+ try {
6742
+ await params.ws.sendAsync("task_update_job_claim", {
6743
+ protocol_version: 1,
6744
+ job_id: job.job_id
6745
+ });
6746
+ claim = (await claimPromise).payload;
6747
+ } catch (error) {
6748
+ if (isStaleTaskUpdateJobError(error)) {
6749
+ handledJobIds.add(job.job_id);
6750
+ continue;
6751
+ }
6752
+ throw error;
6753
+ }
6732
6754
  const privatePatch = claim.private_patch ?? {};
6733
6755
  const safeMetadata = claim.safe_metadata ?? {};
6734
6756
  const sourceChatId = claim.chat_id ?? job.chat_id ?? params.activeChatId;
6735
- if (!sourceChatId) throw new Error(`Task update job ${job.job_id} is missing a source chat id.`);
6757
+ if (!sourceChatId) {
6758
+ handledJobIds.add(job.job_id);
6759
+ continue;
6760
+ }
6736
6761
  const sourceChatKey = await resolveChatKey(sourceChatId);
6737
6762
  const event = eventByJobId.get(job.job_id) ?? {
6738
6763
  event_id: `task-event-${job.job_id}`,
@@ -8770,6 +8795,21 @@ Required: ${schema.required.join(", ")}`
8770
8795
  const chatKeyBytes = await decryptBytesWithAesGcm(encChatKey, masterKey);
8771
8796
  if (!chatKeyBytes)
8772
8797
  throw new Error("Failed to decrypt chat key. Try logging in again.");
8798
+ const metadataResponse = await this.http.post(
8799
+ "/v1/share/chat/metadata",
8800
+ {
8801
+ chat_id: resolvedId,
8802
+ title: null,
8803
+ summary: null,
8804
+ share_cta_text: null,
8805
+ is_shared: true
8806
+ }
8807
+ );
8808
+ if (!metadataResponse.ok || metadataResponse.data.success !== true) {
8809
+ const detail = metadataResponse.data.detail;
8810
+ const message = typeof detail === "string" ? detail : `HTTP ${metadataResponse.status}`;
8811
+ throw new Error(`Failed to mark chat as shared: ${message}`);
8812
+ }
8773
8813
  const blob = await generateChatShareBlob(
8774
8814
  resolvedId,
8775
8815
  chatKeyBytes,
@@ -9195,7 +9235,7 @@ Required: ${schema.required.join(", ")}`
9195
9235
  }
9196
9236
  return session;
9197
9237
  }
9198
- makeWsClient(session) {
9238
+ makeWsClient(session, options = {}) {
9199
9239
  return new OpenMatesWsClient({
9200
9240
  apiUrl: session.apiUrl,
9201
9241
  sessionId: randomUUID5(),
@@ -9204,7 +9244,8 @@ Required: ${schema.required.join(", ")}`
9204
9244
  // Same User-Agent as login so OS-based device fingerprint hash matches.
9205
9245
  userAgent: this.getCliUserAgent(),
9206
9246
  // Node.js ws library doesn't auto-send cookies on upgrade requests.
9207
- cookies: session.cookies
9247
+ cookies: session.cookies,
9248
+ taskUpdateJobs: options.taskUpdateJobs
9208
9249
  });
9209
9250
  }
9210
9251
  /**
@@ -9212,10 +9253,10 @@ Required: ${schema.required.join(", ")}`
9212
9253
  * Combines refreshWsToken() + makeWsClient() + ws.open() into one call
9213
9254
  * so every WebSocket usage gets a fresh HMAC token automatically.
9214
9255
  */
9215
- async openWsClient() {
9256
+ async openWsClient(options = {}) {
9216
9257
  const ownerId = await this.refreshWsToken();
9217
9258
  const session = this.requireSession();
9218
- const ws = this.makeWsClient(session);
9259
+ const ws = this.makeWsClient(session, options);
9219
9260
  await ws.open();
9220
9261
  return { ws, session, ownerId };
9221
9262
  }
@@ -35072,6 +35113,49 @@ skill_id: "search"`,
35072
35113
  }
35073
35114
  };
35074
35115
 
35116
+ // ../ui/src/demo_chats/data/example_chats/example-chat-publishing-workflow.ts
35117
+ var exampleChatPublishingWorkflowChat = {
35118
+ chat_id: "example-example-chat-publishing-workflow",
35119
+ slug: "example-chat-publishing-workflow",
35120
+ title: "example_chats.example_chat_publishing_workflow.title",
35121
+ summary: "example_chats.example_chat_publishing_workflow.summary",
35122
+ icon: "workflow",
35123
+ category: "software_development",
35124
+ keywords: ["workflow automation", "example chats", "publishing checklist", "OpenMates workflows"],
35125
+ follow_up_suggestions: [],
35126
+ messages: [
35127
+ {
35128
+ "id": "5c8fc179-335f-4674-9eac-c889d086df5b",
35129
+ "role": "user",
35130
+ "content": "example_chats.example_chat_publishing_workflow.message_1",
35131
+ "created_at": 1784232219
35132
+ },
35133
+ {
35134
+ "id": "a46d1b5e-7150-582e-94a8-108d05ecc5ad",
35135
+ "role": "assistant",
35136
+ "content": "example_chats.example_chat_publishing_workflow.message_2",
35137
+ "created_at": 1784232234,
35138
+ "user_message_id": "5c8fc179-335f-4674-9eac-c889d086df5b",
35139
+ "category": "software_development",
35140
+ "model_name": "Gemini 3 Flash"
35141
+ }
35142
+ ],
35143
+ embeds: [
35144
+ {
35145
+ "embed_id": "53d32845-0b88-47c0-ace0-db90ae95d89b",
35146
+ "type": "app_skill_use",
35147
+ "content": "app_id: workflows\nskill_id: create-or-modify\nresult_count: 0\nembed_ids[0]:\nstatus: finished\nembed_id: 53d32845-0b88-47c0-ace0-db90ae95d89b\ngraph_enabled: false\ngraph_nodes[4]{data_title,type,id}:\n Manual trigger,manual_trigger,trigger1\n verify the real CLI source chats,manual_action,step1\n scaffold the example chat files,manual_action,step2\n run the deployed example-chat Playwright check,manual_action,step3\ngraph_edges[3]{source,id,target}:\n trigger1,e1-2,step1\n step1,e2-3,step2\n step2,e3-4,step3\ntitle: Example chat publishing checklist",
35148
+ "parent_embed_id": null,
35149
+ "embed_ids": []
35150
+ }
35151
+ ],
35152
+ metadata: {
35153
+ featured: true,
35154
+ order: 111,
35155
+ app_skill_examples: ["workflows.create-or-modify"]
35156
+ }
35157
+ };
35158
+
35075
35159
  // ../ui/src/demo_chats/exampleChatData.ts
35076
35160
  var ALL_EXAMPLE_CHATS = [
35077
35161
  giganticAirplanesChat,
@@ -35165,7 +35249,8 @@ var ALL_EXAMPLE_CHATS = [
35165
35249
  urbanSportsFitnessStudiosBerlinChat,
35166
35250
  urbanSportsYogaClassesBerlinChat,
35167
35251
  habitGardenWebApplicationChat,
35168
- printableBenchyPhoneStandModelsChat
35252
+ printableBenchyPhoneStandModelsChat,
35253
+ exampleChatPublishingWorkflowChat
35169
35254
  ].sort((a, b) => a.metadata.order - b.metadata.order);
35170
35255
 
35171
35256
  // ../ui/src/i18n/locales/en.json
@@ -37002,7 +37087,7 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
37002
37087
  }
37003
37088
  },
37004
37089
  search: {
37005
- text: "Search 3D models",
37090
+ text: "Search",
37006
37091
  description: {
37007
37092
  text: "Find existing 3D models in public model catalogs."
37008
37093
  }
@@ -39904,6 +39989,100 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
39904
39989
  text: "Set up 2FA"
39905
39990
  }
39906
39991
  },
39992
+ inactive_account_deletion_reminder: {
39993
+ subject_14d: {
39994
+ text: "Your inactive OpenMates account will be deleted in 14 days"
39995
+ },
39996
+ headline_14d: {
39997
+ text: "Your account is scheduled for deletion"
39998
+ },
39999
+ deletion_time_14d: {
40000
+ text: "in 14 days"
40001
+ },
40002
+ wait_time_14d: {
40003
+ text: "14 days"
40004
+ },
40005
+ reminder_info_14d: {
40006
+ text: "If you take no action, you will be reminded again 7 days before deletion and 1 day before deletion."
40007
+ },
40008
+ subject_7d: {
40009
+ text: "Your inactive OpenMates account will be deleted in 7 days"
40010
+ },
40011
+ headline_7d: {
40012
+ text: "Your account will be deleted soon"
40013
+ },
40014
+ deletion_time_7d: {
40015
+ text: "in 7 days"
40016
+ },
40017
+ wait_time_7d: {
40018
+ text: "7 days"
40019
+ },
40020
+ reminder_info_7d: {
40021
+ text: "If you take no action, you will receive one final reminder 1 day before deletion."
40022
+ },
40023
+ subject_1d: {
40024
+ text: "Your inactive OpenMates account will be deleted tomorrow"
40025
+ },
40026
+ headline_1d: {
40027
+ text: "Final reminder before account deletion"
40028
+ },
40029
+ deletion_time_1d: {
40030
+ text: "tomorrow"
40031
+ },
40032
+ wait_time_1d: {
40033
+ text: "1 day"
40034
+ },
40035
+ greeting: {
40036
+ text: "Hey{greeting_name},"
40037
+ },
40038
+ intro: {
40039
+ text: "We noticed that this OpenMates account has been inactive and currently has no credits, no usage, no active payment state, and no saved chats."
40040
+ },
40041
+ scheduled: {
40042
+ text: "Your inactive account is scheduled for deletion {deletion_time_text}."
40043
+ },
40044
+ keep_account: {
40045
+ text: 'If you want to keep the account, log in to <a href="{finish_setup_link}" style="color: #4867CD; text-decoration: underline;">OpenMates.org</a> and start using it again before then. Adding credits, creating a chat, or using OpenMates will remove the account from this cleanup flow.'
40046
+ },
40047
+ delete_now: {
40048
+ text: 'If you do not want to keep the account, you can delete it now from your account settings: <a href="{direct_delete_account_link}" style="color: #4867CD; text-decoration: underline;">delete account</a>.'
40049
+ },
40050
+ signoff: {
40051
+ text: "Thank you,"
40052
+ },
40053
+ creator_title: {
40054
+ text: "Creator of OpenMates"
40055
+ }
40056
+ },
40057
+ inactive_account_deleted: {
40058
+ subject: {
40059
+ text: "Your inactive OpenMates account has been deleted"
40060
+ },
40061
+ header: {
40062
+ text: "Your OpenMates account was deleted"
40063
+ },
40064
+ greeting: {
40065
+ text: "Hey{greeting_name},"
40066
+ },
40067
+ deleted_notice: {
40068
+ text: "Your inactive OpenMates account has now been deleted because it remained inactive after the staged deletion reminders."
40069
+ },
40070
+ no_action: {
40071
+ text: "No further action is needed."
40072
+ },
40073
+ signup_again: {
40074
+ text: 'If you want to use OpenMates again later, you can create a new account at <a href="{signup_link}" style="color: #4867CD; text-decoration: underline;">OpenMates.org</a>.'
40075
+ },
40076
+ newsletter: {
40077
+ text: "This does not change your newsletter preferences. You can manage them anytime in the newsletter settings."
40078
+ },
40079
+ signoff: {
40080
+ text: "Thank you,"
40081
+ },
40082
+ creator_title: {
40083
+ text: "Creator of OpenMates"
40084
+ }
40085
+ },
39907
40086
  incomplete_signup_deletion_reminder: {
39908
40087
  subject_14d: {
39909
40088
  text: "Complete your OpenMates signup before your account is deleted"
@@ -42632,6 +42811,20 @@ Only output the final Markdown table. Do NOT include explanations, notes, or any
42632
42811
  text: "[ai] Analyze potential impacts on encryption and privacy"
42633
42812
  }
42634
42813
  },
42814
+ example_chat_publishing_workflow: {
42815
+ title: {
42816
+ text: "Example chat publishing workflow"
42817
+ },
42818
+ summary: {
42819
+ text: "Create a reusable manual workflow for publishing public OpenMates example chats."
42820
+ },
42821
+ message_1: {
42822
+ text: "@skill:workflows:create-or-modify Create exactly one disabled manual workflow titled Example chat publishing checklist. It should have a manual trigger and three manual steps: verify the real CLI source chats, scaffold the example chat files, and run the deployed example-chat Playwright check. After the workflow tool call, reply with exactly one sentence: Created the workflow. Do not include markdown links, embed links, bullets, next steps, reminders, schedules, or extra embeds."
42823
+ },
42824
+ message_2: {
42825
+ text: '```json\n{"type": "app_skill_use", "embed_id": "53d32845-0b88-47c0-ace0-db90ae95d89b", "app_id": "workflows", "skill_id": "create-or-modify"}\n```\n\nCreated the workflow.'
42826
+ }
42827
+ },
42635
42828
  family_stays_kyoto: {
42636
42829
  title: {
42637
42830
  text: "Family Stays In Kyoto"
package/dist/cli.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  getExtForLang,
4
4
  serializeToYaml
5
- } from "./chunk-ZAPNQ2KT.js";
5
+ } from "./chunk-DZ2UKCQZ.js";
6
6
  import "./chunk-AXNRPVLE.js";
7
7
  export {
8
8
  getExtForLang,
package/dist/index.d.ts CHANGED
@@ -161,6 +161,7 @@ declare class OpenMatesWsClient {
161
161
  refreshToken: string | null;
162
162
  userAgent?: string;
163
163
  cookies?: Record<string, string>;
164
+ taskUpdateJobs?: boolean;
164
165
  });
165
166
  open(timeoutMs?: number): Promise<void>;
166
167
  close(): void;
package/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  reconcileAuthoritativeChats,
19
19
  renderSupportInfo,
20
20
  serializeToYaml
21
- } from "./chunk-ZAPNQ2KT.js";
21
+ } from "./chunk-DZ2UKCQZ.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.17",
3
+ "version": "0.15.0-alpha.19",
4
4
  "description": "OpenMates CLI and SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",