openmates 0.14.8-alpha.18 → 0.14.8-alpha.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/{chunk-PY7I7PSY.js → chunk-TWDG63SO.js} +240 -587
- package/dist/cli.js +1 -1
- package/dist/index.d.ts +4 -9
- package/dist/index.js +1 -1
- package/package.json +1 -1
|
@@ -1214,42 +1214,6 @@ function websocketProtocolError(envelope) {
|
|
|
1214
1214
|
}
|
|
1215
1215
|
return null;
|
|
1216
1216
|
}
|
|
1217
|
-
function errorFrameBelongsToAiResponse(envelope, userMessageId, chatId, recoveryTurnId) {
|
|
1218
|
-
if (envelope.type === "client_update_required") return true;
|
|
1219
|
-
if (envelope.type !== "error") return true;
|
|
1220
|
-
const payload = envelope.payload && typeof envelope.payload === "object" ? envelope.payload : {};
|
|
1221
|
-
let scoped = false;
|
|
1222
|
-
const errorChatId = typeof payload.chat_id === "string" ? payload.chat_id : null;
|
|
1223
|
-
if (errorChatId) {
|
|
1224
|
-
scoped = true;
|
|
1225
|
-
if (errorChatId !== chatId) return false;
|
|
1226
|
-
}
|
|
1227
|
-
const errorMessageId = typeof payload.user_message_id === "string" ? payload.user_message_id : typeof payload.userMessageId === "string" ? payload.userMessageId : typeof payload.message_id === "string" ? payload.message_id : null;
|
|
1228
|
-
if (errorMessageId) {
|
|
1229
|
-
scoped = true;
|
|
1230
|
-
if (errorMessageId !== userMessageId) return false;
|
|
1231
|
-
}
|
|
1232
|
-
const errorTurnId = typeof payload.turn_id === "string" ? payload.turn_id : null;
|
|
1233
|
-
if (errorTurnId) {
|
|
1234
|
-
scoped = true;
|
|
1235
|
-
if (recoveryTurnId !== errorTurnId) return false;
|
|
1236
|
-
}
|
|
1237
|
-
if (typeof payload.job_id === "string") {
|
|
1238
|
-
scoped = true;
|
|
1239
|
-
}
|
|
1240
|
-
return !scoped || Boolean(errorChatId || errorMessageId || errorTurnId);
|
|
1241
|
-
}
|
|
1242
|
-
function scopedErrorMissesPredicate(envelope, predicate) {
|
|
1243
|
-
if (envelope.type !== "error" || !predicate) return false;
|
|
1244
|
-
const payload = envelope.payload && typeof envelope.payload === "object" ? envelope.payload : {};
|
|
1245
|
-
const hasScope = typeof payload.turn_id === "string" || typeof payload.chat_id === "string" || typeof payload.message_id === "string" || typeof payload.user_message_id === "string" || typeof payload.userMessageId === "string" || typeof payload.job_id === "string";
|
|
1246
|
-
if (!hasScope) return false;
|
|
1247
|
-
try {
|
|
1248
|
-
return !predicate(payload);
|
|
1249
|
-
} catch {
|
|
1250
|
-
return false;
|
|
1251
|
-
}
|
|
1252
|
-
}
|
|
1253
1217
|
function parseTaskProposals(value) {
|
|
1254
1218
|
if (!Array.isArray(value)) return [];
|
|
1255
1219
|
return value.flatMap((item) => {
|
|
@@ -1314,21 +1278,6 @@ function parsePendingTaskUpdateJobs(value) {
|
|
|
1314
1278
|
return [job];
|
|
1315
1279
|
});
|
|
1316
1280
|
}
|
|
1317
|
-
function parseAvailableRecoveryJobs(value) {
|
|
1318
|
-
if (!Array.isArray(value)) return [];
|
|
1319
|
-
return value.flatMap((item) => {
|
|
1320
|
-
if (!item || typeof item !== "object" || Array.isArray(item)) return [];
|
|
1321
|
-
const raw = item;
|
|
1322
|
-
if (typeof raw.job_id !== "string" || typeof raw.chat_id !== "string" || typeof raw.turn_id !== "string" || typeof raw.assistant_message_id !== "string" || typeof raw.chat_key_version !== "number") return [];
|
|
1323
|
-
return [{
|
|
1324
|
-
job_id: raw.job_id,
|
|
1325
|
-
chat_id: raw.chat_id,
|
|
1326
|
-
turn_id: raw.turn_id,
|
|
1327
|
-
assistant_message_id: raw.assistant_message_id,
|
|
1328
|
-
chat_key_version: raw.chat_key_version
|
|
1329
|
-
}];
|
|
1330
|
-
});
|
|
1331
|
-
}
|
|
1332
1281
|
var OpenMatesWsClient = class {
|
|
1333
1282
|
socket;
|
|
1334
1283
|
passiveTaskUpdateJobs = /* @__PURE__ */ new Map();
|
|
@@ -1429,7 +1378,6 @@ var OpenMatesWsClient = class {
|
|
|
1429
1378
|
if (typeof parsed.type === "string") seenTypes.add(parsed.type);
|
|
1430
1379
|
const protocolError = websocketProtocolError(parsed);
|
|
1431
1380
|
if (protocolError) {
|
|
1432
|
-
if (scopedErrorMissesPredicate(parsed, predicate)) return;
|
|
1433
1381
|
cleanup();
|
|
1434
1382
|
reject(protocolError);
|
|
1435
1383
|
return;
|
|
@@ -1634,7 +1582,6 @@ var OpenMatesWsClient = class {
|
|
|
1634
1582
|
return;
|
|
1635
1583
|
}
|
|
1636
1584
|
if (!aiResponseDone || !postProcessingDone) return;
|
|
1637
|
-
if (options?.recoveryTurnId && !recoveryJobId) return;
|
|
1638
1585
|
if (pendingSubChatHandlers.size > 0) return;
|
|
1639
1586
|
if (pendingMemoryRequestHandlers.size > 0) return;
|
|
1640
1587
|
if (processingEmbedIds.size > 0 && !asyncEmbedTimer) {
|
|
@@ -1751,9 +1698,6 @@ var OpenMatesWsClient = class {
|
|
|
1751
1698
|
const type = parsed.type;
|
|
1752
1699
|
const protocolError = websocketProtocolError(parsed);
|
|
1753
1700
|
if (protocolError) {
|
|
1754
|
-
if (!errorFrameBelongsToAiResponse(parsed, userMessageId, chatId, options?.recoveryTurnId)) {
|
|
1755
|
-
return;
|
|
1756
|
-
}
|
|
1757
1701
|
cleanup();
|
|
1758
1702
|
reject(protocolError);
|
|
1759
1703
|
return;
|
|
@@ -1796,17 +1740,6 @@ var OpenMatesWsClient = class {
|
|
|
1796
1740
|
maybeResolve();
|
|
1797
1741
|
return;
|
|
1798
1742
|
}
|
|
1799
|
-
if (type === "recovery_jobs_available") {
|
|
1800
|
-
const job = parseAvailableRecoveryJobs(p.jobs).find(
|
|
1801
|
-
(candidate) => candidate.chat_id === chatId && (!options?.recoveryTurnId || candidate.turn_id === options.recoveryTurnId)
|
|
1802
|
-
);
|
|
1803
|
-
if (!job) return;
|
|
1804
|
-
recoveryJobId = job.job_id;
|
|
1805
|
-
messageId = job.assistant_message_id;
|
|
1806
|
-
if (aiResponseDone) maybeResolve();
|
|
1807
|
-
else scheduleResolve(latestContent);
|
|
1808
|
-
return;
|
|
1809
|
-
}
|
|
1810
1743
|
if (type === "ai_message_update") {
|
|
1811
1744
|
const msgId = p.user_message_id ?? p.userMessageId;
|
|
1812
1745
|
if (msgId !== userMessageId && p.chat_id !== chatId) return;
|
|
@@ -1990,9 +1923,6 @@ function extractMentionTokens(message) {
|
|
|
1990
1923
|
function isFilePath(token) {
|
|
1991
1924
|
return token.startsWith("/") || token.startsWith("./") || token.startsWith("~/") || token.startsWith("../");
|
|
1992
1925
|
}
|
|
1993
|
-
function isTaskShortIdMention(token) {
|
|
1994
|
-
return /^TASK-[A-Za-z0-9_-]+[.,;:!?)]?$/.test(token);
|
|
1995
|
-
}
|
|
1996
1926
|
function normalize(name) {
|
|
1997
1927
|
return name.toLowerCase().replace(/\s+/g, "-").replace(/[^a-z0-9._-]/g, "");
|
|
1998
1928
|
}
|
|
@@ -2172,9 +2102,6 @@ function parseMentions(message, context) {
|
|
|
2172
2102
|
filePaths.push(token);
|
|
2173
2103
|
continue;
|
|
2174
2104
|
}
|
|
2175
|
-
if (isTaskShortIdMention(token)) {
|
|
2176
|
-
continue;
|
|
2177
|
-
}
|
|
2178
2105
|
const resolved_ = resolveToken(token, context);
|
|
2179
2106
|
if (resolved_) {
|
|
2180
2107
|
resolved.push(resolved_);
|
|
@@ -3076,28 +3003,18 @@ async function buildTaskEventSystemMessage(params) {
|
|
|
3076
3003
|
if (params.event.task_update_job_id) message.task_update_job_id = params.event.task_update_job_id;
|
|
3077
3004
|
return message;
|
|
3078
3005
|
}
|
|
3079
|
-
function taskUpdateJobBelongsToActiveTurn(job, activeChatId, taskEvents) {
|
|
3080
|
-
void activeChatId;
|
|
3081
|
-
return taskEvents.some((event) => event.task_update_job_id === job.job_id);
|
|
3082
|
-
}
|
|
3083
3006
|
function buildTaskUpdateJobPersistPayload(params) {
|
|
3084
|
-
|
|
3085
|
-
assertTaskPersistPayloadEncrypted(encryptedTaskPayload);
|
|
3007
|
+
assertTaskPersistPayloadEncrypted(params.encryptedTaskPayload);
|
|
3086
3008
|
return {
|
|
3087
3009
|
protocol_version: 1,
|
|
3088
3010
|
job_id: params.jobId,
|
|
3089
3011
|
lease_token: params.leaseToken,
|
|
3090
3012
|
lease_generation: params.leaseGeneration,
|
|
3091
3013
|
expected_task_version: params.expectedTaskVersion,
|
|
3092
|
-
encrypted_task_payload: encryptedTaskPayload,
|
|
3014
|
+
encrypted_task_payload: { ...params.encryptedTaskPayload },
|
|
3093
3015
|
encrypted_task_event_message: params.encryptedTaskEventMessage ?? null
|
|
3094
3016
|
};
|
|
3095
3017
|
}
|
|
3096
|
-
function pruneAbsentTaskPersistFields(payload) {
|
|
3097
|
-
return Object.fromEntries(
|
|
3098
|
-
Object.entries(payload).filter(([, value]) => value !== void 0 && value !== null)
|
|
3099
|
-
);
|
|
3100
|
-
}
|
|
3101
3018
|
function formatTaskEventSystemContent(event) {
|
|
3102
3019
|
const taskLabel = event.short_id || event.task_id;
|
|
3103
3020
|
const title = event.title ? ` "${event.title}"` : "";
|
|
@@ -3594,8 +3511,7 @@ var CLOUD_API_URL = "https://api.openmates.org";
|
|
|
3594
3511
|
var DEFAULT_API_URL = process.env.OPENMATES_API_URL ?? CLOUD_API_URL;
|
|
3595
3512
|
var SETTINGS_GET_RATE_LIMIT_RETRY_MS = 61e3;
|
|
3596
3513
|
var SKILL_TASK_POLL_INTERVAL_MS = 2e3;
|
|
3597
|
-
var SKILL_TASK_POLL_TIMEOUT_MS =
|
|
3598
|
-
var SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS = 500;
|
|
3514
|
+
var SKILL_TASK_POLL_TIMEOUT_MS = 3e5;
|
|
3599
3515
|
function normalizeOrigin(url) {
|
|
3600
3516
|
url.pathname = "";
|
|
3601
3517
|
url.search = "";
|
|
@@ -5073,7 +4989,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5073
4989
|
if (encryptedEmbeds.length > 0) {
|
|
5074
4990
|
messagePayload.encrypted_embeds = encryptedEmbeds;
|
|
5075
4991
|
}
|
|
5076
|
-
let precollectedResponse = params.precollectResponse && params.incognito ? ws.collectAiResponse(messageId, chatId, { onStream: params.onStream
|
|
4992
|
+
let precollectedResponse = params.precollectResponse && params.incognito ? ws.collectAiResponse(messageId, chatId, { onStream: params.onStream }) : null;
|
|
5077
4993
|
if (!params.incognito && chatKeyBytes && encryptedChatKey) {
|
|
5078
4994
|
const protocolVersion = 1;
|
|
5079
4995
|
const chatKeyVersion = 1;
|
|
@@ -5128,10 +5044,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5128
5044
|
updated_at: createdAt
|
|
5129
5045
|
};
|
|
5130
5046
|
}
|
|
5131
|
-
const preflightAck = ws.waitForMessage(
|
|
5132
|
-
"chat_turn_preflight_ack",
|
|
5133
|
-
(payload) => payload.turn_id === turnId
|
|
5134
|
-
);
|
|
5047
|
+
const preflightAck = ws.waitForMessage("chat_turn_preflight_ack");
|
|
5135
5048
|
let ackPayload;
|
|
5136
5049
|
try {
|
|
5137
5050
|
await ws.sendAsync("chat_turn_preflight", preflightPayload);
|
|
@@ -5154,9 +5067,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5154
5067
|
}
|
|
5155
5068
|
if (params.precollectResponse && !params.incognito) {
|
|
5156
5069
|
precollectedResponse = ws.collectAiResponse(messageId, chatId, {
|
|
5157
|
-
onStream: params.onStream
|
|
5158
|
-
timeoutMs: params.responseTimeoutMs,
|
|
5159
|
-
recoveryTurnId: savedTurnId
|
|
5070
|
+
onStream: params.onStream
|
|
5160
5071
|
});
|
|
5161
5072
|
}
|
|
5162
5073
|
const confirmed = ws.waitForMessage(
|
|
@@ -5168,7 +5079,10 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5168
5079
|
2e4
|
|
5169
5080
|
);
|
|
5170
5081
|
await ws.sendAsync("chat_message_added", messagePayload);
|
|
5171
|
-
await confirmed;
|
|
5082
|
+
const confirmedPayload = (await confirmed).payload;
|
|
5083
|
+
if (typeof confirmedPayload.new_messages_v === "number" && Number.isSafeInteger(confirmedPayload.new_messages_v)) {
|
|
5084
|
+
terminalExpectedMessagesV = confirmedPayload.new_messages_v + 1;
|
|
5085
|
+
}
|
|
5172
5086
|
let assistant = "";
|
|
5173
5087
|
let assistantMessageId = null;
|
|
5174
5088
|
let category = null;
|
|
@@ -5340,22 +5254,219 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5340
5254
|
`The assistant requested memories (${event.requestedKeys.join(", ")}). Rerun with --auto-approve-memories to explicitly approve requested memory categories from the CLI, or continue this chat in the web app to approve or reject the request.`
|
|
5341
5255
|
);
|
|
5342
5256
|
};
|
|
5257
|
+
const persistEncryptedSystemMessage = async (systemMessage, targetChatId = chatId) => {
|
|
5258
|
+
await ws.sendAsync("chat_system_message_added", {
|
|
5259
|
+
chat_id: targetChatId,
|
|
5260
|
+
message: systemMessage
|
|
5261
|
+
});
|
|
5262
|
+
await ws.waitForMessage(
|
|
5263
|
+
"system_message_confirmed",
|
|
5264
|
+
(payload) => payload.message_id === systemMessage.message_id,
|
|
5265
|
+
2e4
|
|
5266
|
+
);
|
|
5267
|
+
};
|
|
5343
5268
|
const persistedTaskEventIds = /* @__PURE__ */ new Set();
|
|
5344
5269
|
const persistTaskEventSystemMessages = async (events) => {
|
|
5345
5270
|
if (!chatKeyBytes || events.length === 0) return;
|
|
5346
5271
|
for (const event of events) {
|
|
5347
5272
|
if (persistedTaskEventIds.has(event.event_id)) continue;
|
|
5348
|
-
await
|
|
5349
|
-
|
|
5350
|
-
|
|
5351
|
-
|
|
5352
|
-
|
|
5353
|
-
|
|
5354
|
-
|
|
5355
|
-
|
|
5273
|
+
await persistEncryptedSystemMessage(await buildTaskEventSystemMessage({
|
|
5274
|
+
chatKey: chatKeyBytes,
|
|
5275
|
+
userMessageId: messageId,
|
|
5276
|
+
event
|
|
5277
|
+
}));
|
|
5278
|
+
persistedTaskEventIds.add(event.event_id);
|
|
5279
|
+
}
|
|
5280
|
+
};
|
|
5281
|
+
const persistPendingTaskUpdateJobs = async (jobs, events) => {
|
|
5282
|
+
const persistedJobIds = /* @__PURE__ */ new Set();
|
|
5283
|
+
if (jobs.length === 0) return persistedJobIds;
|
|
5284
|
+
const masterKey = this.getMasterKeyBytes();
|
|
5285
|
+
let decryptedTasksCache = null;
|
|
5286
|
+
const eventByJobId = new Map(events.map((event) => [event.task_update_job_id, event]));
|
|
5287
|
+
const buildTaskKeyWrappersForChat = async (task, targetChatId, createdAt2) => {
|
|
5288
|
+
const encryptedTaskKey = task.encrypted.encrypted_task_key;
|
|
5289
|
+
if (!encryptedTaskKey) throw new Error(`Task ${task.taskId} is missing encrypted task key.`);
|
|
5290
|
+
const taskKey = await decryptBytesWithAesGcm(encryptedTaskKey, masterKey);
|
|
5291
|
+
if (!taskKey) throw new Error(`Failed to decrypt task key for ${task.taskId}.`);
|
|
5292
|
+
const targetChatKey = await resolveChatKey(targetChatId);
|
|
5293
|
+
const existingProjectWrappers = await listProjectTaskKeyWrappers(task.taskId, createdAt2);
|
|
5294
|
+
const linkedProjectIds = task.linkedProjectIds ?? [];
|
|
5295
|
+
if (linkedProjectIds.length > existingProjectWrappers.length) {
|
|
5296
|
+
throw new Error(`Task ${task.taskId} is missing project key wrappers required for move persistence.`);
|
|
5297
|
+
}
|
|
5298
|
+
return [
|
|
5299
|
+
{
|
|
5300
|
+
key_type: "master",
|
|
5301
|
+
encrypted_task_key: await encryptBytesWithAesGcm(taskKey, masterKey),
|
|
5302
|
+
created_at: createdAt2
|
|
5303
|
+
},
|
|
5304
|
+
{
|
|
5305
|
+
key_type: "chat",
|
|
5306
|
+
hashed_chat_id: computeSHA256(targetChatId),
|
|
5307
|
+
encrypted_task_key: await encryptBytesWithAesGcm(taskKey, targetChatKey),
|
|
5308
|
+
created_at: createdAt2
|
|
5309
|
+
},
|
|
5310
|
+
...existingProjectWrappers
|
|
5311
|
+
];
|
|
5312
|
+
};
|
|
5313
|
+
const listProjectTaskKeyWrappers = async (taskId, createdAt2) => {
|
|
5314
|
+
const response = await this.http.get(
|
|
5315
|
+
`/v1/user-tasks/${encodeURIComponent(taskId)}/key-wrappers`,
|
|
5316
|
+
this.getCliRequestHeaders()
|
|
5317
|
+
);
|
|
5318
|
+
if (!response.ok) {
|
|
5319
|
+
throw new Error(`User task key wrapper list failed with HTTP ${response.status}`);
|
|
5320
|
+
}
|
|
5321
|
+
return (response.data.key_wrappers ?? []).filter((wrapper) => wrapper.key_type === "project").map((wrapper) => ({
|
|
5322
|
+
key_type: "project",
|
|
5323
|
+
hashed_project_id: wrapper.hashed_project_id,
|
|
5324
|
+
encrypted_task_key: wrapper.encrypted_task_key,
|
|
5325
|
+
created_at: typeof wrapper.created_at === "number" ? wrapper.created_at : createdAt2,
|
|
5326
|
+
expires_at: wrapper.expires_at ?? null
|
|
5327
|
+
}));
|
|
5328
|
+
};
|
|
5329
|
+
const resolveChatKey = async (targetChatId) => {
|
|
5330
|
+
if (targetChatId === chatId && chatKeyBytes) return chatKeyBytes;
|
|
5331
|
+
const cache = loadSyncCache() ?? await this.ensureSynced();
|
|
5332
|
+
const targetChat = cache.chats.find((chat) => String(chat.details.id ?? "") === targetChatId);
|
|
5333
|
+
const encryptedTargetChatKey = typeof targetChat?.details.encrypted_chat_key === "string" ? targetChat.details.encrypted_chat_key : null;
|
|
5334
|
+
if (!encryptedTargetChatKey) {
|
|
5335
|
+
throw new Error(`Encrypted chat key not found for task move target '${targetChatId}'. Sync and try again.`);
|
|
5336
|
+
}
|
|
5337
|
+
const targetChatKey = await decryptBytesWithAesGcm(encryptedTargetChatKey, masterKey);
|
|
5338
|
+
if (!targetChatKey) {
|
|
5339
|
+
throw new Error(`Failed to decrypt chat key for task move target '${targetChatId}'.`);
|
|
5340
|
+
}
|
|
5341
|
+
return targetChatKey;
|
|
5342
|
+
};
|
|
5343
|
+
const taskEventTypeForOperation = (operation) => {
|
|
5344
|
+
switch (operation) {
|
|
5345
|
+
case "create":
|
|
5346
|
+
return "created";
|
|
5347
|
+
case "move":
|
|
5348
|
+
return "moved";
|
|
5349
|
+
case "update":
|
|
5350
|
+
return "updated";
|
|
5351
|
+
default:
|
|
5352
|
+
return operation || "updated";
|
|
5353
|
+
}
|
|
5354
|
+
};
|
|
5355
|
+
for (const job of jobs) {
|
|
5356
|
+
const claimPromise = ws.waitForMessage(
|
|
5357
|
+
"task_update_job_claimed",
|
|
5358
|
+
(payload) => payload.job_id === job.job_id,
|
|
5359
|
+
2e4
|
|
5360
|
+
);
|
|
5361
|
+
await ws.sendAsync("task_update_job_claim", {
|
|
5362
|
+
protocol_version: 1,
|
|
5363
|
+
job_id: job.job_id
|
|
5364
|
+
});
|
|
5365
|
+
const claim = (await claimPromise).payload;
|
|
5366
|
+
const privatePatch = claim.private_patch ?? {};
|
|
5367
|
+
const safeMetadata = claim.safe_metadata ?? {};
|
|
5368
|
+
const sourceChatId = claim.chat_id ?? job.chat_id ?? chatId;
|
|
5369
|
+
const sourceChatKey = await resolveChatKey(sourceChatId);
|
|
5370
|
+
const event = eventByJobId.get(job.job_id) ?? {
|
|
5371
|
+
event_id: `task-event-${job.job_id}`,
|
|
5372
|
+
chat_id: sourceChatId,
|
|
5373
|
+
task_id: claim.task_id,
|
|
5374
|
+
event_type: taskEventTypeForOperation(claim.operation),
|
|
5375
|
+
title: typeof privatePatch.title === "string" ? privatePatch.title : null,
|
|
5376
|
+
status: typeof safeMetadata.status === "string" ? safeMetadata.status : null,
|
|
5377
|
+
created_at: typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : Math.floor(Date.now() / 1e3),
|
|
5378
|
+
task_update_job_id: job.job_id
|
|
5379
|
+
};
|
|
5380
|
+
const eventMessage = await buildTaskEventSystemMessage({
|
|
5381
|
+
chatKey: sourceChatKey,
|
|
5382
|
+
userMessageId: claim.message_id ?? messageId,
|
|
5383
|
+
event
|
|
5384
|
+
});
|
|
5385
|
+
const confirmTaskEventPersisted = async () => {
|
|
5386
|
+
const confirmedPromise = ws.waitForMessage(
|
|
5387
|
+
"task_update_job_event_confirmed",
|
|
5388
|
+
(payload) => payload.job_id === job.job_id,
|
|
5389
|
+
2e4
|
|
5390
|
+
);
|
|
5391
|
+
await ws.sendAsync("task_update_job_event_confirmed", {
|
|
5392
|
+
protocol_version: 1,
|
|
5393
|
+
job_id: job.job_id,
|
|
5394
|
+
event_system_message_id: eventMessage.message_id
|
|
5395
|
+
});
|
|
5396
|
+
await confirmedPromise;
|
|
5397
|
+
};
|
|
5398
|
+
if (claim.state === "TASK_PERSISTED") {
|
|
5399
|
+
await persistEncryptedSystemMessage(eventMessage, sourceChatId);
|
|
5400
|
+
persistedTaskEventIds.add(event.event_id);
|
|
5401
|
+
await confirmTaskEventPersisted();
|
|
5402
|
+
persistedJobIds.add(job.job_id);
|
|
5403
|
+
continue;
|
|
5404
|
+
}
|
|
5405
|
+
if (!claim.lease_token || !Number.isSafeInteger(claim.lease_generation)) {
|
|
5406
|
+
throw new Error("Task update job claim returned an invalid lease.");
|
|
5407
|
+
}
|
|
5408
|
+
let encryptedTaskPayload;
|
|
5409
|
+
if (claim.operation === "create") {
|
|
5410
|
+
const input = await buildCreateUserTaskInput(masterKey, {
|
|
5411
|
+
title: typeof privatePatch.title === "string" ? privatePatch.title : "Untitled task",
|
|
5412
|
+
description: typeof privatePatch.description === "string" ? privatePatch.description : "",
|
|
5413
|
+
status: typeof safeMetadata.status === "string" ? safeMetadata.status : "todo",
|
|
5414
|
+
assign: typeof safeMetadata.assignee_type === "string" ? safeMetadata.assignee_type : "user",
|
|
5415
|
+
chatId: typeof safeMetadata.primary_chat_id === "string" ? safeMetadata.primary_chat_id : claim.chat_id ?? chatId
|
|
5416
|
+
});
|
|
5417
|
+
encryptedTaskPayload = {
|
|
5418
|
+
...input,
|
|
5419
|
+
task_id: claim.task_id,
|
|
5420
|
+
position: typeof safeMetadata.position === "number" ? safeMetadata.position : input.position,
|
|
5421
|
+
created_at: typeof safeMetadata.created_at === "number" ? safeMetadata.created_at : input.created_at,
|
|
5422
|
+
updated_at: typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : input.updated_at
|
|
5423
|
+
};
|
|
5424
|
+
} else {
|
|
5425
|
+
if (!decryptedTasksCache) {
|
|
5426
|
+
decryptedTasksCache = await decryptUserTasks(await this.listUserTasks(), masterKey);
|
|
5427
|
+
}
|
|
5428
|
+
const task = findTask(decryptedTasksCache, claim.task_id);
|
|
5429
|
+
const patch = await buildUpdateUserTaskInput(task, masterKey, {
|
|
5430
|
+
title: typeof privatePatch.title === "string" ? privatePatch.title : void 0,
|
|
5431
|
+
description: typeof privatePatch.description === "string" ? privatePatch.description : void 0,
|
|
5432
|
+
status: typeof safeMetadata.status === "string" ? safeMetadata.status : void 0,
|
|
5433
|
+
assign: typeof safeMetadata.assignee_type === "string" ? safeMetadata.assignee_type : void 0,
|
|
5434
|
+
chatId: typeof safeMetadata.primary_chat_id === "string" ? safeMetadata.primary_chat_id : void 0
|
|
5435
|
+
});
|
|
5436
|
+
encryptedTaskPayload = {
|
|
5437
|
+
...patch,
|
|
5438
|
+
updated_at: typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : patch.updated_at
|
|
5439
|
+
};
|
|
5440
|
+
if (typeof safeMetadata.primary_chat_id === "string") {
|
|
5441
|
+
encryptedTaskPayload.key_wrappers = await buildTaskKeyWrappersForChat(
|
|
5442
|
+
task,
|
|
5443
|
+
safeMetadata.primary_chat_id,
|
|
5444
|
+
typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : Math.floor(Date.now() / 1e3)
|
|
5445
|
+
);
|
|
5446
|
+
}
|
|
5447
|
+
}
|
|
5448
|
+
const encryptedEventMessage = eventMessage.encrypted_content;
|
|
5449
|
+
const persistedPromise = ws.waitForMessage(
|
|
5450
|
+
"task_update_job_persisted",
|
|
5451
|
+
(payload) => payload.job_id === job.job_id,
|
|
5452
|
+
2e4
|
|
5356
5453
|
);
|
|
5454
|
+
await ws.sendAsync("task_update_job_persist", buildTaskUpdateJobPersistPayload({
|
|
5455
|
+
jobId: job.job_id,
|
|
5456
|
+
leaseToken: claim.lease_token,
|
|
5457
|
+
leaseGeneration: claim.lease_generation,
|
|
5458
|
+
expectedTaskVersion: claim.expected_task_version,
|
|
5459
|
+
encryptedTaskPayload,
|
|
5460
|
+
encryptedTaskEventMessage: encryptedEventMessage
|
|
5461
|
+
}));
|
|
5462
|
+
await persistedPromise;
|
|
5463
|
+
await persistEncryptedSystemMessage(eventMessage, sourceChatId);
|
|
5357
5464
|
persistedTaskEventIds.add(event.event_id);
|
|
5465
|
+
await confirmTaskEventPersisted();
|
|
5466
|
+
persistedJobIds.add(job.job_id);
|
|
5358
5467
|
}
|
|
5468
|
+
clearSyncCache();
|
|
5469
|
+
return persistedJobIds;
|
|
5359
5470
|
};
|
|
5360
5471
|
const streamOpts = {
|
|
5361
5472
|
onStream: params.onStream,
|
|
@@ -5364,11 +5475,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5364
5475
|
};
|
|
5365
5476
|
if (params.incognito) {
|
|
5366
5477
|
try {
|
|
5367
|
-
const resp = await (precollectedResponse ?? ws.collectAiResponse(messageId, chatId,
|
|
5368
|
-
...streamOpts,
|
|
5369
|
-
timeoutMs: params.responseTimeoutMs,
|
|
5370
|
-
recoveryTurnId: savedTurnId
|
|
5371
|
-
}));
|
|
5478
|
+
const resp = await (precollectedResponse ?? ws.collectAiResponse(messageId, chatId, streamOpts));
|
|
5372
5479
|
assistantMessageId = resp.messageId;
|
|
5373
5480
|
assistant = resp.content;
|
|
5374
5481
|
category = resp.category;
|
|
@@ -5399,10 +5506,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5399
5506
|
}
|
|
5400
5507
|
} else {
|
|
5401
5508
|
try {
|
|
5402
|
-
const resp = await (precollectedResponse ?? ws.collectAiResponse(messageId, chatId,
|
|
5403
|
-
...streamOpts,
|
|
5404
|
-
timeoutMs: params.responseTimeoutMs
|
|
5405
|
-
}));
|
|
5509
|
+
const resp = await (precollectedResponse ?? ws.collectAiResponse(messageId, chatId, streamOpts));
|
|
5406
5510
|
assistantMessageId = resp.messageId;
|
|
5407
5511
|
assistant = resp.content;
|
|
5408
5512
|
category = resp.category;
|
|
@@ -5547,15 +5651,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5547
5651
|
newChatSuggestions: resp.newChatSuggestions,
|
|
5548
5652
|
encryptedChatKey
|
|
5549
5653
|
});
|
|
5550
|
-
const persistedTaskJobIds = await
|
|
5551
|
-
ws,
|
|
5552
|
-
jobs: pendingTaskUpdateJobs,
|
|
5553
|
-
events: taskEvents,
|
|
5554
|
-
activeChatId: chatId,
|
|
5555
|
-
activeChatKeyBytes: chatKeyBytes,
|
|
5556
|
-
fallbackUserMessageId: messageId,
|
|
5557
|
-
requireActiveTurnEvent: true
|
|
5558
|
-
});
|
|
5654
|
+
const persistedTaskJobIds = await persistPendingTaskUpdateJobs(pendingTaskUpdateJobs, taskEvents);
|
|
5559
5655
|
pendingTaskUpdateJobs = pendingTaskUpdateJobs.filter((job) => !persistedTaskJobIds.has(job.job_id));
|
|
5560
5656
|
await persistTaskEventSystemMessages(taskEvents);
|
|
5561
5657
|
clearSyncCache();
|
|
@@ -5582,224 +5678,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
5582
5678
|
appSettingsMemoryRequests
|
|
5583
5679
|
};
|
|
5584
5680
|
}
|
|
5585
|
-
async persistEncryptedSystemMessage(ws, systemMessage, targetChatId) {
|
|
5586
|
-
await ws.sendAsync("chat_system_message_added", {
|
|
5587
|
-
chat_id: targetChatId,
|
|
5588
|
-
message: systemMessage
|
|
5589
|
-
});
|
|
5590
|
-
await ws.waitForMessage(
|
|
5591
|
-
"system_message_confirmed",
|
|
5592
|
-
(payload) => payload.message_id === systemMessage.message_id,
|
|
5593
|
-
2e4
|
|
5594
|
-
);
|
|
5595
|
-
}
|
|
5596
|
-
async persistPendingTaskUpdateJobs(params) {
|
|
5597
|
-
const handledJobIds = /* @__PURE__ */ new Set();
|
|
5598
|
-
if (params.jobs.length === 0) return handledJobIds;
|
|
5599
|
-
const masterKey = this.getMasterKeyBytes();
|
|
5600
|
-
let decryptedTasksCache = null;
|
|
5601
|
-
const eventByJobId = new Map(params.events.map((event) => [event.task_update_job_id, event]));
|
|
5602
|
-
const resolveChatKey = async (targetChatId) => {
|
|
5603
|
-
if (targetChatId === params.activeChatId && params.activeChatKeyBytes) return params.activeChatKeyBytes;
|
|
5604
|
-
const findChat = (chats) => chats?.find((chat) => String(chat.details.id ?? "") === targetChatId);
|
|
5605
|
-
const targetChat = findChat(params.syncedChats) ?? findChat(loadSyncCache()?.chats);
|
|
5606
|
-
const encryptedTargetChatKey = typeof targetChat?.details.encrypted_chat_key === "string" ? targetChat.details.encrypted_chat_key : null;
|
|
5607
|
-
if (!encryptedTargetChatKey) {
|
|
5608
|
-
throw new Error(`Encrypted chat key not found for task update job target '${targetChatId}'. Sync and try again.`);
|
|
5609
|
-
}
|
|
5610
|
-
const targetChatKey = await decryptBytesWithAesGcm(encryptedTargetChatKey, masterKey);
|
|
5611
|
-
if (!targetChatKey) {
|
|
5612
|
-
throw new Error(`Failed to decrypt chat key for task update job target '${targetChatId}'.`);
|
|
5613
|
-
}
|
|
5614
|
-
return targetChatKey;
|
|
5615
|
-
};
|
|
5616
|
-
const listProjectTaskKeyWrappers = async (taskId, createdAt) => {
|
|
5617
|
-
const response = await this.http.get(
|
|
5618
|
-
`/v1/user-tasks/${encodeURIComponent(taskId)}/key-wrappers`,
|
|
5619
|
-
this.getCliRequestHeaders()
|
|
5620
|
-
);
|
|
5621
|
-
if (!response.ok) {
|
|
5622
|
-
throw new Error(`User task key wrapper list failed with HTTP ${response.status}`);
|
|
5623
|
-
}
|
|
5624
|
-
return (response.data.key_wrappers ?? []).filter((wrapper) => wrapper.key_type === "project").map((wrapper) => ({
|
|
5625
|
-
key_type: "project",
|
|
5626
|
-
hashed_project_id: wrapper.hashed_project_id,
|
|
5627
|
-
encrypted_task_key: wrapper.encrypted_task_key,
|
|
5628
|
-
created_at: typeof wrapper.created_at === "number" ? wrapper.created_at : createdAt,
|
|
5629
|
-
expires_at: wrapper.expires_at ?? null
|
|
5630
|
-
}));
|
|
5631
|
-
};
|
|
5632
|
-
const buildTaskKeyWrappersForChat = async (task, targetChatId, createdAt) => {
|
|
5633
|
-
const encryptedTaskKey = task.encrypted.encrypted_task_key;
|
|
5634
|
-
if (!encryptedTaskKey) throw new Error(`Task ${task.taskId} is missing encrypted task key.`);
|
|
5635
|
-
const taskKey = await decryptBytesWithAesGcm(encryptedTaskKey, masterKey);
|
|
5636
|
-
if (!taskKey) throw new Error(`Failed to decrypt task key for ${task.taskId}.`);
|
|
5637
|
-
const targetChatKey = await resolveChatKey(targetChatId);
|
|
5638
|
-
const existingProjectWrappers = await listProjectTaskKeyWrappers(task.taskId, createdAt);
|
|
5639
|
-
const linkedProjectIds = task.linkedProjectIds ?? [];
|
|
5640
|
-
if (linkedProjectIds.length > existingProjectWrappers.length) {
|
|
5641
|
-
throw new Error(`Task ${task.taskId} is missing project key wrappers required for move persistence.`);
|
|
5642
|
-
}
|
|
5643
|
-
return [
|
|
5644
|
-
{
|
|
5645
|
-
key_type: "master",
|
|
5646
|
-
encrypted_task_key: await encryptBytesWithAesGcm(taskKey, masterKey),
|
|
5647
|
-
created_at: createdAt
|
|
5648
|
-
},
|
|
5649
|
-
{
|
|
5650
|
-
key_type: "chat",
|
|
5651
|
-
hashed_chat_id: computeSHA256(targetChatId),
|
|
5652
|
-
encrypted_task_key: await encryptBytesWithAesGcm(taskKey, targetChatKey),
|
|
5653
|
-
created_at: createdAt
|
|
5654
|
-
},
|
|
5655
|
-
...existingProjectWrappers
|
|
5656
|
-
];
|
|
5657
|
-
};
|
|
5658
|
-
const findTaskForUpdateJob = async (claim) => {
|
|
5659
|
-
const chatIds = [claim.source_task_chat_id, claim.chat_id, claim.safe_metadata?.primary_chat_id].filter((value) => typeof value === "string" && value.length > 0);
|
|
5660
|
-
for (const candidateChatId of [...new Set(chatIds)]) {
|
|
5661
|
-
const scopedTasks = await decryptUserTasks(await this.listUserTasks({ chatId: candidateChatId }), masterKey);
|
|
5662
|
-
try {
|
|
5663
|
-
return findTask(scopedTasks, claim.task_id);
|
|
5664
|
-
} catch (error) {
|
|
5665
|
-
if (!(error instanceof Error) || !error.message.includes("was not found")) throw error;
|
|
5666
|
-
}
|
|
5667
|
-
}
|
|
5668
|
-
if (!decryptedTasksCache) {
|
|
5669
|
-
decryptedTasksCache = await decryptUserTasks(await this.listUserTasks({ limit: 1e3 }), masterKey);
|
|
5670
|
-
}
|
|
5671
|
-
return findTask(decryptedTasksCache, claim.task_id);
|
|
5672
|
-
};
|
|
5673
|
-
const taskEventTypeForOperation = (operation) => {
|
|
5674
|
-
switch (operation) {
|
|
5675
|
-
case "create":
|
|
5676
|
-
return "created";
|
|
5677
|
-
case "move":
|
|
5678
|
-
return "moved";
|
|
5679
|
-
case "update":
|
|
5680
|
-
return "updated";
|
|
5681
|
-
default:
|
|
5682
|
-
return operation || "updated";
|
|
5683
|
-
}
|
|
5684
|
-
};
|
|
5685
|
-
for (const job of params.jobs) {
|
|
5686
|
-
if (params.requireActiveTurnEvent && params.activeChatId && !taskUpdateJobBelongsToActiveTurn(job, params.activeChatId, params.events)) {
|
|
5687
|
-
handledJobIds.add(job.job_id);
|
|
5688
|
-
continue;
|
|
5689
|
-
}
|
|
5690
|
-
const claimPromise = params.ws.waitForMessage(
|
|
5691
|
-
"task_update_job_claimed",
|
|
5692
|
-
(payload) => payload.job_id === job.job_id,
|
|
5693
|
-
2e4
|
|
5694
|
-
);
|
|
5695
|
-
await params.ws.sendAsync("task_update_job_claim", {
|
|
5696
|
-
protocol_version: 1,
|
|
5697
|
-
job_id: job.job_id
|
|
5698
|
-
});
|
|
5699
|
-
const claim = (await claimPromise).payload;
|
|
5700
|
-
const privatePatch = claim.private_patch ?? {};
|
|
5701
|
-
const safeMetadata = claim.safe_metadata ?? {};
|
|
5702
|
-
const sourceChatId = claim.chat_id ?? job.chat_id ?? params.activeChatId;
|
|
5703
|
-
if (!sourceChatId) throw new Error(`Task update job ${job.job_id} is missing a source chat id.`);
|
|
5704
|
-
const sourceChatKey = await resolveChatKey(sourceChatId);
|
|
5705
|
-
const event = eventByJobId.get(job.job_id) ?? {
|
|
5706
|
-
event_id: `task-event-${job.job_id}`,
|
|
5707
|
-
chat_id: sourceChatId,
|
|
5708
|
-
task_id: claim.task_id,
|
|
5709
|
-
event_type: taskEventTypeForOperation(claim.operation),
|
|
5710
|
-
title: typeof privatePatch.title === "string" ? privatePatch.title : null,
|
|
5711
|
-
status: typeof safeMetadata.status === "string" ? safeMetadata.status : null,
|
|
5712
|
-
created_at: typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : Math.floor(Date.now() / 1e3),
|
|
5713
|
-
task_update_job_id: job.job_id
|
|
5714
|
-
};
|
|
5715
|
-
const userMessageId = claim.message_id ?? params.fallbackUserMessageId;
|
|
5716
|
-
if (!userMessageId) throw new Error(`Task update job ${job.job_id} is missing a user message id.`);
|
|
5717
|
-
const eventMessage = await buildTaskEventSystemMessage({
|
|
5718
|
-
chatKey: sourceChatKey,
|
|
5719
|
-
userMessageId,
|
|
5720
|
-
event
|
|
5721
|
-
});
|
|
5722
|
-
const confirmTaskEventPersisted = async () => {
|
|
5723
|
-
const confirmedPromise = params.ws.waitForMessage(
|
|
5724
|
-
"task_update_job_event_confirmed",
|
|
5725
|
-
(payload) => payload.job_id === job.job_id,
|
|
5726
|
-
2e4
|
|
5727
|
-
);
|
|
5728
|
-
await params.ws.sendAsync("task_update_job_event_confirmed", {
|
|
5729
|
-
protocol_version: 1,
|
|
5730
|
-
job_id: job.job_id,
|
|
5731
|
-
event_system_message_id: eventMessage.message_id
|
|
5732
|
-
});
|
|
5733
|
-
await confirmedPromise;
|
|
5734
|
-
};
|
|
5735
|
-
if (claim.state === "TASK_PERSISTED") {
|
|
5736
|
-
await this.persistEncryptedSystemMessage(params.ws, eventMessage, sourceChatId);
|
|
5737
|
-
await confirmTaskEventPersisted();
|
|
5738
|
-
handledJobIds.add(job.job_id);
|
|
5739
|
-
continue;
|
|
5740
|
-
}
|
|
5741
|
-
if (!claim.lease_token || !Number.isSafeInteger(claim.lease_generation)) {
|
|
5742
|
-
throw new Error("Task update job claim returned an invalid lease.");
|
|
5743
|
-
}
|
|
5744
|
-
let encryptedTaskPayload;
|
|
5745
|
-
if (claim.operation === "create") {
|
|
5746
|
-
const input = await buildCreateUserTaskInput(masterKey, {
|
|
5747
|
-
title: typeof privatePatch.title === "string" ? privatePatch.title : "Untitled task",
|
|
5748
|
-
description: typeof privatePatch.description === "string" ? privatePatch.description : "",
|
|
5749
|
-
status: typeof safeMetadata.status === "string" ? safeMetadata.status : "todo",
|
|
5750
|
-
assign: typeof safeMetadata.assignee_type === "string" ? safeMetadata.assignee_type : "user",
|
|
5751
|
-
chatId: typeof safeMetadata.primary_chat_id === "string" ? safeMetadata.primary_chat_id : claim.chat_id ?? params.activeChatId
|
|
5752
|
-
});
|
|
5753
|
-
encryptedTaskPayload = {
|
|
5754
|
-
...input,
|
|
5755
|
-
task_id: claim.task_id,
|
|
5756
|
-
position: typeof safeMetadata.position === "number" ? safeMetadata.position : input.position,
|
|
5757
|
-
created_at: typeof safeMetadata.created_at === "number" ? safeMetadata.created_at : input.created_at,
|
|
5758
|
-
updated_at: typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : input.updated_at
|
|
5759
|
-
};
|
|
5760
|
-
} else {
|
|
5761
|
-
const task = await findTaskForUpdateJob(claim);
|
|
5762
|
-
const patch = await buildUpdateUserTaskInput(task, masterKey, {
|
|
5763
|
-
title: typeof privatePatch.title === "string" ? privatePatch.title : void 0,
|
|
5764
|
-
description: typeof privatePatch.description === "string" ? privatePatch.description : void 0,
|
|
5765
|
-
status: typeof safeMetadata.status === "string" ? safeMetadata.status : void 0,
|
|
5766
|
-
assign: typeof safeMetadata.assignee_type === "string" ? safeMetadata.assignee_type : void 0,
|
|
5767
|
-
chatId: typeof safeMetadata.primary_chat_id === "string" ? safeMetadata.primary_chat_id : void 0
|
|
5768
|
-
});
|
|
5769
|
-
encryptedTaskPayload = {
|
|
5770
|
-
...patch,
|
|
5771
|
-
version: claim.expected_task_version,
|
|
5772
|
-
updated_at: typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : patch.updated_at
|
|
5773
|
-
};
|
|
5774
|
-
if (typeof safeMetadata.primary_chat_id === "string") {
|
|
5775
|
-
encryptedTaskPayload.key_wrappers = await buildTaskKeyWrappersForChat(
|
|
5776
|
-
task,
|
|
5777
|
-
safeMetadata.primary_chat_id,
|
|
5778
|
-
typeof safeMetadata.updated_at === "number" ? safeMetadata.updated_at : Math.floor(Date.now() / 1e3)
|
|
5779
|
-
);
|
|
5780
|
-
}
|
|
5781
|
-
}
|
|
5782
|
-
const persistedPromise = params.ws.waitForMessage(
|
|
5783
|
-
"task_update_job_persisted",
|
|
5784
|
-
(payload) => payload.job_id === job.job_id,
|
|
5785
|
-
2e4
|
|
5786
|
-
);
|
|
5787
|
-
await params.ws.sendAsync("task_update_job_persist", buildTaskUpdateJobPersistPayload({
|
|
5788
|
-
jobId: job.job_id,
|
|
5789
|
-
leaseToken: claim.lease_token,
|
|
5790
|
-
leaseGeneration: claim.lease_generation,
|
|
5791
|
-
expectedTaskVersion: claim.expected_task_version,
|
|
5792
|
-
encryptedTaskPayload,
|
|
5793
|
-
encryptedTaskEventMessage: eventMessage.encrypted_content
|
|
5794
|
-
}));
|
|
5795
|
-
await persistedPromise;
|
|
5796
|
-
await this.persistEncryptedSystemMessage(params.ws, eventMessage, sourceChatId);
|
|
5797
|
-
await confirmTaskEventPersisted();
|
|
5798
|
-
handledJobIds.add(job.job_id);
|
|
5799
|
-
}
|
|
5800
|
-
clearSyncCache();
|
|
5801
|
-
return handledJobIds;
|
|
5802
|
-
}
|
|
5803
5681
|
async persistStreamedEmbeds(params) {
|
|
5804
5682
|
const finalized = new Map(
|
|
5805
5683
|
params.embeds.filter((embed) => {
|
|
@@ -6041,28 +5919,14 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
6041
5919
|
}
|
|
6042
5920
|
async pollTaskUntilComplete(taskId, headers) {
|
|
6043
5921
|
const started = Date.now();
|
|
6044
|
-
let lastTransientError = null;
|
|
6045
5922
|
while (Date.now() - started < SKILL_TASK_POLL_TIMEOUT_MS) {
|
|
6046
|
-
|
|
6047
|
-
|
|
6048
|
-
|
|
6049
|
-
|
|
6050
|
-
headers
|
|
6051
|
-
);
|
|
6052
|
-
} catch (error) {
|
|
6053
|
-
lastTransientError = error instanceof Error ? error.message : String(error);
|
|
6054
|
-
await new Promise((resolve7) => setTimeout(resolve7, SKILL_TASK_POLL_INTERVAL_MS));
|
|
6055
|
-
continue;
|
|
6056
|
-
}
|
|
5923
|
+
const response = await this.http.get(
|
|
5924
|
+
`/v1/tasks/${encodeURIComponent(taskId)}`,
|
|
5925
|
+
headers
|
|
5926
|
+
);
|
|
6057
5927
|
if (!response.ok) {
|
|
6058
|
-
if (response.status >= SKILL_TASK_POLL_TRANSIENT_ERROR_STATUS) {
|
|
6059
|
-
lastTransientError = `HTTP ${response.status}`;
|
|
6060
|
-
await new Promise((resolve7) => setTimeout(resolve7, SKILL_TASK_POLL_INTERVAL_MS));
|
|
6061
|
-
continue;
|
|
6062
|
-
}
|
|
6063
5928
|
throw new Error(`Task polling failed with HTTP ${response.status}`);
|
|
6064
5929
|
}
|
|
6065
|
-
lastTransientError = null;
|
|
6066
5930
|
if (response.data.status === "completed") {
|
|
6067
5931
|
return response.data;
|
|
6068
5932
|
}
|
|
@@ -6071,11 +5935,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
6071
5935
|
}
|
|
6072
5936
|
await new Promise((resolve7) => setTimeout(resolve7, SKILL_TASK_POLL_INTERVAL_MS));
|
|
6073
5937
|
}
|
|
6074
|
-
if (lastTransientError) {
|
|
6075
|
-
throw new Error(
|
|
6076
|
-
`Task ${taskId} did not complete within ${SKILL_TASK_POLL_TIMEOUT_MS / 1e3}s; last polling error: ${lastTransientError}`
|
|
6077
|
-
);
|
|
6078
|
-
}
|
|
6079
5938
|
throw new Error(`Task ${taskId} did not complete within ${SKILL_TASK_POLL_TIMEOUT_MS / 1e3}s`);
|
|
6080
5939
|
}
|
|
6081
5940
|
wrapResolvedSkillResult(original, result) {
|
|
@@ -6725,8 +6584,6 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
6725
6584
|
if (filters.status) params.set("status", filters.status);
|
|
6726
6585
|
if (filters.chatId) params.set("chat_id", filters.chatId);
|
|
6727
6586
|
if (filters.projectId) params.set("project_id", filters.projectId);
|
|
6728
|
-
const limit = filters.limit;
|
|
6729
|
-
if (Number.isSafeInteger(limit) && limit !== void 0 && limit > 0) params.set("limit", String(limit));
|
|
6730
6587
|
const query = params.toString();
|
|
6731
6588
|
const response = await this.http.get(
|
|
6732
6589
|
`/v1/user-tasks${query ? `?${query}` : ""}`,
|
|
@@ -6916,14 +6773,12 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
6916
6773
|
// -------------------------------------------------------------------------
|
|
6917
6774
|
// Settings (generic passthrough)
|
|
6918
6775
|
// -------------------------------------------------------------------------
|
|
6919
|
-
async settingsGet(path
|
|
6920
|
-
|
|
6776
|
+
async settingsGet(path) {
|
|
6777
|
+
this.requireSession();
|
|
6921
6778
|
const normalizedPath = this.normalizePath(path);
|
|
6922
|
-
const headers = this.getCliRequestHeaders();
|
|
6923
|
-
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
6924
6779
|
let response = await this.http.get(
|
|
6925
6780
|
normalizedPath,
|
|
6926
|
-
|
|
6781
|
+
this.getCliRequestHeaders()
|
|
6927
6782
|
);
|
|
6928
6783
|
if (response.status === 429) {
|
|
6929
6784
|
process.stderr.write(
|
|
@@ -6931,7 +6786,7 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
6931
6786
|
`
|
|
6932
6787
|
);
|
|
6933
6788
|
await new Promise((resolve7) => setTimeout(resolve7, SETTINGS_GET_RATE_LIMIT_RETRY_MS));
|
|
6934
|
-
response = await this.http.get(normalizedPath,
|
|
6789
|
+
response = await this.http.get(normalizedPath, this.getCliRequestHeaders());
|
|
6935
6790
|
}
|
|
6936
6791
|
if (!response.ok) {
|
|
6937
6792
|
throw new Error(`Settings GET failed with HTTP ${response.status}`);
|
|
@@ -6969,54 +6824,48 @@ var OpenMatesClient = class _OpenMatesClient {
|
|
|
6969
6824
|
crypto: material
|
|
6970
6825
|
};
|
|
6971
6826
|
}
|
|
6972
|
-
async settingsPost(path, body
|
|
6973
|
-
|
|
6827
|
+
async settingsPost(path, body) {
|
|
6828
|
+
this.requireSession();
|
|
6974
6829
|
const normalizedPath = this.normalizePath(path);
|
|
6975
6830
|
if (BLOCKED_SETTINGS_MUTATE_PATHS.has(normalizedPath)) {
|
|
6976
6831
|
throw new Error(`Blocked operation: ${normalizedPath}`);
|
|
6977
6832
|
}
|
|
6978
|
-
const headers = this.getCliRequestHeaders();
|
|
6979
|
-
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
6980
6833
|
const response = await this.http.post(
|
|
6981
6834
|
normalizedPath,
|
|
6982
6835
|
body,
|
|
6983
|
-
|
|
6836
|
+
this.getCliRequestHeaders()
|
|
6984
6837
|
);
|
|
6985
6838
|
if (!response.ok) {
|
|
6986
6839
|
throw new Error(`Settings POST failed with HTTP ${response.status}`);
|
|
6987
6840
|
}
|
|
6988
6841
|
return response.data;
|
|
6989
6842
|
}
|
|
6990
|
-
async settingsDelete(path, body
|
|
6991
|
-
|
|
6843
|
+
async settingsDelete(path, body) {
|
|
6844
|
+
this.requireSession();
|
|
6992
6845
|
const normalizedPath = this.normalizePath(path);
|
|
6993
6846
|
if (BLOCKED_SETTINGS_MUTATE_PATHS.has(normalizedPath)) {
|
|
6994
6847
|
throw new Error(`Blocked operation: ${normalizedPath}`);
|
|
6995
6848
|
}
|
|
6996
|
-
const headers = this.getCliRequestHeaders();
|
|
6997
|
-
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
6998
6849
|
const response = await this.http.delete(
|
|
6999
6850
|
normalizedPath,
|
|
7000
6851
|
body,
|
|
7001
|
-
|
|
6852
|
+
this.getCliRequestHeaders()
|
|
7002
6853
|
);
|
|
7003
6854
|
if (!response.ok) {
|
|
7004
6855
|
throw new Error(`Settings DELETE failed with HTTP ${response.status}`);
|
|
7005
6856
|
}
|
|
7006
6857
|
return response.data;
|
|
7007
6858
|
}
|
|
7008
|
-
async settingsPatch(path, body
|
|
7009
|
-
|
|
6859
|
+
async settingsPatch(path, body) {
|
|
6860
|
+
this.requireSession();
|
|
7010
6861
|
const normalizedPath = this.normalizePath(path);
|
|
7011
6862
|
if (BLOCKED_SETTINGS_MUTATE_PATHS.has(normalizedPath)) {
|
|
7012
6863
|
throw new Error(`Blocked operation: ${normalizedPath}`);
|
|
7013
6864
|
}
|
|
7014
|
-
const headers = this.getCliRequestHeaders();
|
|
7015
|
-
if (apiKey) headers.Authorization = `Bearer ${apiKey}`;
|
|
7016
6865
|
const response = await this.http.patch(
|
|
7017
6866
|
normalizedPath,
|
|
7018
6867
|
body,
|
|
7019
|
-
|
|
6868
|
+
this.getCliRequestHeaders()
|
|
7020
6869
|
);
|
|
7021
6870
|
if (!response.ok) {
|
|
7022
6871
|
throw new Error(`Settings PATCH failed with HTTP ${response.status}`);
|
|
@@ -7647,13 +7496,7 @@ Required: ${schema.required.join(", ")}`
|
|
|
7647
7496
|
* Get the session for file upload authentication.
|
|
7648
7497
|
*/
|
|
7649
7498
|
getSession() {
|
|
7650
|
-
|
|
7651
|
-
const currentCookies = this.http.getCookieMap();
|
|
7652
|
-
if (JSON.stringify(session.cookies) !== JSON.stringify(currentCookies)) {
|
|
7653
|
-
session.cookies = currentCookies;
|
|
7654
|
-
saveSession(session);
|
|
7655
|
-
}
|
|
7656
|
-
return session;
|
|
7499
|
+
return this.requireSession();
|
|
7657
7500
|
}
|
|
7658
7501
|
// ── Share link creation ──────────────────────────────────────────────
|
|
7659
7502
|
/**
|
|
@@ -8157,7 +8000,6 @@ Required: ${schema.required.join(", ")}`
|
|
|
8157
8000
|
let totalChatCount = 0;
|
|
8158
8001
|
let reconciliation = { authoritative: false };
|
|
8159
8002
|
const pendingAIResponses = [];
|
|
8160
|
-
let pendingTaskUpdateJobs = [];
|
|
8161
8003
|
try {
|
|
8162
8004
|
ws.send("phased_sync_request", {
|
|
8163
8005
|
phase: "all",
|
|
@@ -8206,7 +8048,6 @@ Required: ${schema.required.join(", ")}`
|
|
|
8206
8048
|
pendingAIResponses.push(frame.payload);
|
|
8207
8049
|
}
|
|
8208
8050
|
}
|
|
8209
|
-
pendingTaskUpdateJobs = ws.drainPassiveTaskUpdateJobs();
|
|
8210
8051
|
for (const chat of chats) {
|
|
8211
8052
|
const id = typeof chat.details.id === "string" ? chat.details.id : "";
|
|
8212
8053
|
const msgs = messagesByChatId.get(id);
|
|
@@ -8283,26 +8124,11 @@ Required: ${schema.required.join(", ")}`
|
|
|
8283
8124
|
chats.sort(
|
|
8284
8125
|
(a, b) => (typeof b.details.last_edited_overall_timestamp === "number" ? b.details.last_edited_overall_timestamp : 0) - (typeof a.details.last_edited_overall_timestamp === "number" ? a.details.last_edited_overall_timestamp : 0)
|
|
8285
8126
|
);
|
|
8286
|
-
let persistedTaskJobIds = /* @__PURE__ */ new Set();
|
|
8287
8127
|
try {
|
|
8288
8128
|
await this.persistPendingAIResponsesFromSync(ws, chats, pendingAIResponses);
|
|
8289
|
-
persistedTaskJobIds = await this.persistPendingTaskUpdateJobs({
|
|
8290
|
-
ws,
|
|
8291
|
-
jobs: pendingTaskUpdateJobs,
|
|
8292
|
-
events: [],
|
|
8293
|
-
activeChatId: null,
|
|
8294
|
-
activeChatKeyBytes: null,
|
|
8295
|
-
fallbackUserMessageId: null,
|
|
8296
|
-
syncedChats: chats,
|
|
8297
|
-
requireActiveTurnEvent: false
|
|
8298
|
-
});
|
|
8299
8129
|
} finally {
|
|
8300
8130
|
ws.close();
|
|
8301
8131
|
}
|
|
8302
|
-
if (persistedTaskJobIds.size > 0) {
|
|
8303
|
-
clearSyncCache();
|
|
8304
|
-
return this.ensureSynced(true, refreshChatIds);
|
|
8305
|
-
}
|
|
8306
8132
|
const cache = {
|
|
8307
8133
|
syncedAt: Date.now(),
|
|
8308
8134
|
totalChatCount,
|
|
@@ -23689,76 +23515,6 @@ var privateWorkspaceDemoVideoChat = {
|
|
|
23689
23515
|
}
|
|
23690
23516
|
};
|
|
23691
23517
|
|
|
23692
|
-
// ../ui/src/demo_chats/data/example_chats/reference-image-3d-model.ts
|
|
23693
|
-
var MODEL3D_POSTER_DATA_URL = "data:image/webp;base64,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";
|
|
23694
|
-
var referenceImage3DModelChat = {
|
|
23695
|
-
chat_id: "example-reference-image-3d-model",
|
|
23696
|
-
slug: "reference-image-3d-model",
|
|
23697
|
-
title: "example_chats.reference_image_3d_model.title",
|
|
23698
|
-
summary: "example_chats.reference_image_3d_model.summary",
|
|
23699
|
-
icon: "3dmodels",
|
|
23700
|
-
category: "design",
|
|
23701
|
-
keywords: ["3D model generation", "image to 3D", "Hi3D", "GLB", "product design"],
|
|
23702
|
-
follow_up_suggestions: [],
|
|
23703
|
-
messages: [
|
|
23704
|
-
{
|
|
23705
|
-
id: "c79b9ff0-7d58-4ed7-b860-4c427cdab6bd",
|
|
23706
|
-
role: "user",
|
|
23707
|
-
content: "example_chats.reference_image_3d_model.message_1",
|
|
23708
|
-
created_at: 1784071246
|
|
23709
|
-
},
|
|
23710
|
-
{
|
|
23711
|
-
id: "fbf595b9-2f71-4a7a-b544-56529bf9a38d",
|
|
23712
|
-
role: "assistant",
|
|
23713
|
-
content: "example_chats.reference_image_3d_model.message_2",
|
|
23714
|
-
created_at: 1784071268,
|
|
23715
|
-
category: "design",
|
|
23716
|
-
model_name: "Gemini 3 Flash"
|
|
23717
|
-
}
|
|
23718
|
-
],
|
|
23719
|
-
embeds: [
|
|
23720
|
-
{
|
|
23721
|
-
embed_id: "85716124-48d5-4c4c-9919-3126b733b41e",
|
|
23722
|
-
type: "app_skill_use",
|
|
23723
|
-
content: `app_id: models3d
|
|
23724
|
-
skill_id: generate
|
|
23725
|
-
type: model3d
|
|
23726
|
-
status: finished
|
|
23727
|
-
input_mode: image
|
|
23728
|
-
prompt: "Create a textured 3D GLB model from the uploaded reference image."
|
|
23729
|
-
provider: Hi3D
|
|
23730
|
-
provider_model: Hi3D
|
|
23731
|
-
poster_url: "${MODEL3D_POSTER_DATA_URL}"
|
|
23732
|
-
files:
|
|
23733
|
-
master:
|
|
23734
|
-
size_bytes: 25847448
|
|
23735
|
-
format: glb
|
|
23736
|
-
mime_type: model/gltf-binary
|
|
23737
|
-
poster:
|
|
23738
|
-
size_bytes: 20690
|
|
23739
|
-
format: webp
|
|
23740
|
-
mime_type: image/webp
|
|
23741
|
-
preview:
|
|
23742
|
-
size_bytes: 25847448
|
|
23743
|
-
format: glb
|
|
23744
|
-
mime_type: model/gltf-binary
|
|
23745
|
-
optimized: false
|
|
23746
|
-
fallback_reason: preview_optimization_failed
|
|
23747
|
-
generated_at: "2026-07-14T23:20:46+00:00"
|
|
23748
|
-
provenance:
|
|
23749
|
-
ai_generated: true
|
|
23750
|
-
labeling: static_public_fixture`,
|
|
23751
|
-
parent_embed_id: null,
|
|
23752
|
-
embed_ids: null
|
|
23753
|
-
}
|
|
23754
|
-
],
|
|
23755
|
-
metadata: {
|
|
23756
|
-
featured: true,
|
|
23757
|
-
order: 38,
|
|
23758
|
-
app_skill_examples: ["models3d.generate"]
|
|
23759
|
-
}
|
|
23760
|
-
};
|
|
23761
|
-
|
|
23762
23518
|
// ../ui/src/demo_chats/data/example_chats/upcoming-reminders-list.ts
|
|
23763
23519
|
var upcomingRemindersListChat = {
|
|
23764
23520
|
chat_id: "example-upcoming-reminders-list",
|
|
@@ -28356,7 +28112,6 @@ var ALL_EXAMPLE_CHATS = [
|
|
|
28356
28112
|
berlinDermatologyAppointmentsChat,
|
|
28357
28113
|
productLaunchSynthLoopChat,
|
|
28358
28114
|
privateWorkspaceDemoVideoChat,
|
|
28359
|
-
referenceImage3DModelChat,
|
|
28360
28115
|
upcomingRemindersListChat,
|
|
28361
28116
|
cancelTestReminderChat,
|
|
28362
28117
|
fediverseActivitypubSocialSearchChat,
|
|
@@ -36996,20 +36751,6 @@ Like [Denis Villeneuve](wiki:Denis_Villeneuve)\u2019s work, *Contact* avoids the
|
|
|
36996
36751
|
text: '```json\n{"type": "app_skill_use", "embed_id": "11ff377e-a0a2-40ed-81c3-9556b68142f3", "app_id": "videos", "skill_id": "search", "query": "retrieval augmented generation explained for beginners", "provider": "Brave"}\n```\n\nI\'ve found some excellent beginner-friendly videos that explain Retrieval-Augmented Generation (RAG). Here is a curated selection to get you started:\n\n[!](embed:youtube.com-OCK)\n[!](embed:youtube.com-20R)\n[!](embed:youtube.com-8SW)\n[!](embed:youtube.com-Fn4)\n[!](embed:youtube.com-rgp)\n\n### Which one should you watch first?\n\nI highly recommend starting with **[What is Retrieval-Augmented Generation (RAG)?](embed:youtube.com-OCK)** by **IBM Technology**.\n\n**Why this one first?**\n* **Conciseness:** At just 6 and a half minutes, it provides the most efficient "conceptual hook" without getting bogged down in implementation details.\n* **High-Level Clarity:** IBM\u2019s explanations are famous for being professional and easy to follow. They focus on the *why* (fixing LLM hallucinations and outdated data) before diving into the *what*.\n* **Authoritative:** It establishes a solid foundation from a reputable industry leader, which helps you better understand the more technical or "hands-on" videos later.\n\n### What to watch next?\n\nOnce you have the concept down, here are two paths depending on your interest:\n\n1. **For a better intuitive understanding:** Watch **[RAG Explained in 12 Minutes](embed:youtube.com-20R)** by **Aishwarya Srinivasan**. She uses a brilliant "Open-Book Exam" analogy that makes the whole process click instantly for most beginners.\n2. **For a technical overview:** If you want to see the "moving parts" (like vector databases and embeddings), check out **[RAG Explained For Beginners](embed:youtube.com-8SW)** by **KodeKloud**. It breaks the process down into a simple 3-step framework: Retrieval, Augmentation, and Generation.\n\nIf you\'re interested in building a RAG system yourself, I can help you find documentation for popular tools like [LangChain](wiki:LangChain) or LlamaIndex. Would you like to see how a simple RAG implementation looks in code?\n\n**Further exploration:**\n* [Check out more AI tutorials](/#settings/apps/videos)\n* [Search for RAG documentation](/#settings/apps/code)'
|
|
36997
36752
|
}
|
|
36998
36753
|
},
|
|
36999
|
-
reference_image_3d_model: {
|
|
37000
|
-
title: {
|
|
37001
|
-
text: "Reference Image to 3D Model"
|
|
37002
|
-
},
|
|
37003
|
-
summary: {
|
|
37004
|
-
text: "A 3D generation example that turns a reference image into a textured GLB model preview."
|
|
37005
|
-
},
|
|
37006
|
-
message_1: {
|
|
37007
|
-
text: "@skill:models3d:generate Turn this reference image into a textured 3D GLB model suitable for a product mockup."
|
|
37008
|
-
},
|
|
37009
|
-
message_2: {
|
|
37010
|
-
text: '```json\n{"type":"app_skill_use","embed_id":"85716124-48d5-4c4c-9919-3126b733b41e","app_id":"models3d","skill_id":"generate"}\n```\n\nI generated a textured GLB model from the reference image and attached the 3D model preview above.'
|
|
37011
|
-
}
|
|
37012
|
-
},
|
|
37013
36754
|
right_to_repair_laws_eu_us: {
|
|
37014
36755
|
title: {
|
|
37015
36756
|
text: "Right-to-Repair Laws in the EU and US"
|
|
@@ -47399,84 +47140,6 @@ As of mid-2026, the severe supply shocks from the 2024\u20132025 avian flu have
|
|
|
47399
47140
|
first_invites: {
|
|
47400
47141
|
text: "First invites in Jan/Feb 2025"
|
|
47401
47142
|
}
|
|
47402
|
-
},
|
|
47403
|
-
workflows: {
|
|
47404
|
-
template_share: {
|
|
47405
|
-
title: {
|
|
47406
|
-
text: "Share as template"
|
|
47407
|
-
},
|
|
47408
|
-
create_link: {
|
|
47409
|
-
text: "Create template link"
|
|
47410
|
-
},
|
|
47411
|
-
import: {
|
|
47412
|
-
text: "Import template"
|
|
47413
|
-
},
|
|
47414
|
-
complete_bindings: {
|
|
47415
|
-
text: "Complete requirements and enable"
|
|
47416
|
-
},
|
|
47417
|
-
revoked: {
|
|
47418
|
-
text: "Template access revoked."
|
|
47419
|
-
}
|
|
47420
|
-
},
|
|
47421
|
-
version_history: {
|
|
47422
|
-
title: {
|
|
47423
|
-
text: "Definition history"
|
|
47424
|
-
},
|
|
47425
|
-
retention: {
|
|
47426
|
-
text: "Keeps up to {max} definitions"
|
|
47427
|
-
},
|
|
47428
|
-
retention_loading: {
|
|
47429
|
-
text: "Loading retention..."
|
|
47430
|
-
},
|
|
47431
|
-
loading: {
|
|
47432
|
-
text: "Loading definition history..."
|
|
47433
|
-
},
|
|
47434
|
-
empty: {
|
|
47435
|
-
text: "No definition history is available yet."
|
|
47436
|
-
},
|
|
47437
|
-
version: {
|
|
47438
|
-
text: "Version {version}"
|
|
47439
|
-
},
|
|
47440
|
-
current: {
|
|
47441
|
-
text: "Current"
|
|
47442
|
-
},
|
|
47443
|
-
restored: {
|
|
47444
|
-
text: "Restored"
|
|
47445
|
-
},
|
|
47446
|
-
inspecting: {
|
|
47447
|
-
text: "Loading definition..."
|
|
47448
|
-
},
|
|
47449
|
-
inspecting_version: {
|
|
47450
|
-
text: "Version {version} graph"
|
|
47451
|
-
},
|
|
47452
|
-
nodes: {
|
|
47453
|
-
text: "nodes"
|
|
47454
|
-
},
|
|
47455
|
-
restore_as_new: {
|
|
47456
|
-
text: "Restore version {version} as new current version"
|
|
47457
|
-
},
|
|
47458
|
-
restore_explanation: {
|
|
47459
|
-
text: "This creates a new current version. The selected and existing versions remain unchanged."
|
|
47460
|
-
},
|
|
47461
|
-
confirm_restore: {
|
|
47462
|
-
text: "Create new current version"
|
|
47463
|
-
},
|
|
47464
|
-
restoring: {
|
|
47465
|
-
text: "Restoring..."
|
|
47466
|
-
},
|
|
47467
|
-
restore_success: {
|
|
47468
|
-
text: "Restored version {version} as a new current version."
|
|
47469
|
-
},
|
|
47470
|
-
load_failed: {
|
|
47471
|
-
text: "Failed to load definition history."
|
|
47472
|
-
},
|
|
47473
|
-
inspect_failed: {
|
|
47474
|
-
text: "Failed to load the selected definition."
|
|
47475
|
-
},
|
|
47476
|
-
restore_failed: {
|
|
47477
|
-
text: "Failed to restore the selected definition."
|
|
47478
|
-
}
|
|
47479
|
-
}
|
|
47480
47143
|
}
|
|
47481
47144
|
};
|
|
47482
47145
|
|
|
@@ -51057,10 +50720,6 @@ function parsePositiveIntegerFlag(value, flagName) {
|
|
|
51057
50720
|
}
|
|
51058
50721
|
return parsed;
|
|
51059
50722
|
}
|
|
51060
|
-
function parseResponseTimeoutMs(flags) {
|
|
51061
|
-
const seconds = parsePositiveIntegerFlag(flags["response-timeout-seconds"], "--response-timeout-seconds");
|
|
51062
|
-
return seconds === void 0 ? void 0 : seconds * 1e3;
|
|
51063
|
-
}
|
|
51064
50723
|
function parseRemoteAccessSourceType(value) {
|
|
51065
50724
|
if (value === void 0) return "local_folder";
|
|
51066
50725
|
if (value === "local_folder" || value === "local_git_repository") {
|
|
@@ -51204,7 +50863,6 @@ async function handleChats(client, subcommand, rest, flags, redactor) {
|
|
|
51204
50863
|
autoApproveMemories: flags["auto-approve-memories"] === true,
|
|
51205
50864
|
acceptTaskProposals: flags["accept-task-proposals"] === true,
|
|
51206
50865
|
piiDetection: flags["no-pii-detection"] !== true,
|
|
51207
|
-
responseTimeoutMs: parseResponseTimeoutMs(flags),
|
|
51208
50866
|
anonymousLearningMode: client.hasSession() ? void 0 : parseAnonymousLearningModeFlags(flags)
|
|
51209
50867
|
},
|
|
51210
50868
|
redactor
|
|
@@ -51280,8 +50938,7 @@ Run 'openmates chats show ` + chatId + "' to check if suggestions have been save
|
|
|
51280
50938
|
autoApproveSubChats: flags["auto-approve"] === true,
|
|
51281
50939
|
autoApproveMemories: flags["auto-approve-memories"] === true,
|
|
51282
50940
|
acceptTaskProposals: flags["accept-task-proposals"] === true,
|
|
51283
|
-
piiDetection: flags["no-pii-detection"] !== true
|
|
51284
|
-
responseTimeoutMs: parseResponseTimeoutMs(flags)
|
|
50941
|
+
piiDetection: flags["no-pii-detection"] !== true
|
|
51285
50942
|
},
|
|
51286
50943
|
redactor
|
|
51287
50944
|
);
|
|
@@ -51310,8 +50967,7 @@ Run 'openmates chats show ` + chatId + "' to check if suggestions have been save
|
|
|
51310
50967
|
autoApproveSubChats: flags["auto-approve"] === true,
|
|
51311
50968
|
autoApproveMemories: flags["auto-approve-memories"] === true,
|
|
51312
50969
|
acceptTaskProposals: flags["accept-task-proposals"] === true,
|
|
51313
|
-
piiDetection: flags["no-pii-detection"] !== true
|
|
51314
|
-
responseTimeoutMs: parseResponseTimeoutMs(flags)
|
|
50970
|
+
piiDetection: flags["no-pii-detection"] !== true
|
|
51315
50971
|
},
|
|
51316
50972
|
redactor
|
|
51317
50973
|
);
|
|
@@ -51332,8 +50988,7 @@ Run 'openmates chats show ` + chatId + "' to check if suggestions have been save
|
|
|
51332
50988
|
json: flags.json === true,
|
|
51333
50989
|
autoApproveSubChats: flags["auto-approve"] === true,
|
|
51334
50990
|
autoApproveMemories: flags["auto-approve-memories"] === true,
|
|
51335
|
-
piiDetection: flags["no-pii-detection"] !== true
|
|
51336
|
-
responseTimeoutMs: parseResponseTimeoutMs(flags)
|
|
50991
|
+
piiDetection: flags["no-pii-detection"] !== true
|
|
51337
50992
|
},
|
|
51338
50993
|
redactor
|
|
51339
50994
|
);
|
|
@@ -53534,7 +53189,6 @@ async function handleSettings(client, subcommand, rest, flags) {
|
|
|
53534
53189
|
return;
|
|
53535
53190
|
}
|
|
53536
53191
|
const tokens = [subcommand, ...rest].filter((token) => token !== "help");
|
|
53537
|
-
const apiKey = resolveApiKey(flags) ?? void 0;
|
|
53538
53192
|
if (rest.includes("help") || Boolean(flags.help)) {
|
|
53539
53193
|
printSettingsHelp(client, tokens);
|
|
53540
53194
|
return;
|
|
@@ -53700,7 +53354,7 @@ async function handleSettings(client, subcommand, rest, flags) {
|
|
|
53700
53354
|
if (Object.keys(body).length === 0) {
|
|
53701
53355
|
throw new Error("Provide --simple <model-id|auto> and/or --complex <model-id|auto>.");
|
|
53702
53356
|
}
|
|
53703
|
-
await printSettingsMutationResult(client.settingsPost("ai-model-defaults", body
|
|
53357
|
+
await printSettingsMutationResult(client.settingsPost("ai-model-defaults", body), flags);
|
|
53704
53358
|
return;
|
|
53705
53359
|
}
|
|
53706
53360
|
if (matches(tokens, ["privacy", "auto-delete", "chats", "set"])) {
|
|
@@ -54736,7 +54390,6 @@ async function sendMessageStreaming(client, params, redactor) {
|
|
|
54736
54390
|
onSubChatApprovalRequest,
|
|
54737
54391
|
autoApproveSubChats: params.autoApproveSubChats,
|
|
54738
54392
|
autoApproveMemories: params.autoApproveMemories,
|
|
54739
|
-
responseTimeoutMs: params.responseTimeoutMs,
|
|
54740
54393
|
learningMode,
|
|
54741
54394
|
preparedEmbeds: preparedEmbeds.length > 0 ? preparedEmbeds : void 0,
|
|
54742
54395
|
piiMappings: piiResult.mappings.map((mapping) => ({
|
package/dist/cli.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1205,8 +1205,6 @@ declare class OpenMatesClient {
|
|
|
1205
1205
|
learningMode?: LearningModeContext;
|
|
1206
1206
|
/** Start collecting before send for latency-sensitive benchmark turns. */
|
|
1207
1207
|
precollectResponse?: boolean;
|
|
1208
|
-
/** Override the WebSocket AI response collection timeout for long-running turns. */
|
|
1209
|
-
responseTimeoutMs?: number;
|
|
1210
1208
|
}): Promise<{
|
|
1211
1209
|
status: "completed" | "waiting_for_user";
|
|
1212
1210
|
chatId: string;
|
|
@@ -1235,8 +1233,6 @@ declare class OpenMatesClient {
|
|
|
1235
1233
|
entryCount: number;
|
|
1236
1234
|
}>;
|
|
1237
1235
|
}>;
|
|
1238
|
-
private persistEncryptedSystemMessage;
|
|
1239
|
-
private persistPendingTaskUpdateJobs;
|
|
1240
1236
|
private persistStreamedEmbeds;
|
|
1241
1237
|
private persistPostProcessingMetadata;
|
|
1242
1238
|
/**
|
|
@@ -1368,7 +1364,6 @@ declare class OpenMatesClient {
|
|
|
1368
1364
|
status?: UserTaskStatus;
|
|
1369
1365
|
chatId?: string;
|
|
1370
1366
|
projectId?: string;
|
|
1371
|
-
limit?: number;
|
|
1372
1367
|
}): Promise<UserTaskRecord[]>;
|
|
1373
1368
|
createUserTask(input: UserTaskCreateInput): Promise<UserTaskRecord>;
|
|
1374
1369
|
extractUserTaskProposals(input: {
|
|
@@ -1402,11 +1397,11 @@ declare class OpenMatesClient {
|
|
|
1402
1397
|
createPlanCriterion(planId: string, input: UserPlanCriterionRecord): Promise<UserPlanCriterionRecord>;
|
|
1403
1398
|
createPlanVerification(planId: string, input: UserPlanVerificationRecord & Record<string, unknown>): Promise<UserPlanVerificationRecord>;
|
|
1404
1399
|
addPlanVerificationEvidence(planId: string, verificationId: string, input: Partial<UserPlanVerificationRecord>): Promise<UserPlanVerificationRecord>;
|
|
1405
|
-
settingsGet(path: string
|
|
1400
|
+
settingsGet(path: string): Promise<unknown>;
|
|
1406
1401
|
createApiKey(options: ApiKeyCreateOptions): Promise<CreatedApiKeyResult>;
|
|
1407
|
-
settingsPost(path: string, body: Record<string, unknown
|
|
1408
|
-
settingsDelete(path: string, body?: Record<string, unknown
|
|
1409
|
-
settingsPatch(path: string, body: Record<string, unknown
|
|
1402
|
+
settingsPost(path: string, body: Record<string, unknown>): Promise<unknown>;
|
|
1403
|
+
settingsDelete(path: string, body?: Record<string, unknown>): Promise<unknown>;
|
|
1404
|
+
settingsPatch(path: string, body: Record<string, unknown>): Promise<unknown>;
|
|
1410
1405
|
redeemGiftCard(code: string): Promise<{
|
|
1411
1406
|
success: boolean;
|
|
1412
1407
|
credits_added: number;
|
package/dist/index.js
CHANGED