@inetafrica/open-claudia 2.2.1 → 2.2.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/CHANGELOG.md +3 -0
- package/core/actions.js +2 -0
- package/core/handlers.js +2 -0
- package/core/router.js +24 -4
- package/core/runner.js +22 -3
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## v2.2.3
|
|
4
|
+
- Queue drain now batches: when multiple messages are received while a task is running, they're delivered as one combined follow-up turn instead of N isolated turns. The model sees them together (numbered, with HH:MM:SS queue timestamps), in context of what it just finished, so it can plan across them. A single queued message still delivers as before — no behavior change for the common case.
|
|
5
|
+
|
|
3
6
|
## v2.0.1
|
|
4
7
|
- Kazee owner detection: `envelope.channelId` is the chat-document id, but `KAZEE_OWNER_USER_ID` is the Kazee user id. `isChatOwner`/`isChatAuthorized` now also short-circuit when the inbound user id matches the configured transport owner, so the owner running `/auth` (or anything else) on a fresh Kazee install is recognized immediately instead of being queued as a non-owner request.
|
|
5
8
|
- `chatContext` now carries `userId` and `transport` in addition to `chatId`; new `currentUserId()` / `currentTransport()` exports.
|
package/core/actions.js
CHANGED
|
@@ -113,6 +113,7 @@ async function handleAction(envelope) {
|
|
|
113
113
|
state.pendingVaultUnlock = false;
|
|
114
114
|
state.pendingVaultAction = null;
|
|
115
115
|
state.pendingVaultUnlockAt = 0;
|
|
116
|
+
state.pendingVaultUnlockAttempts = 0;
|
|
116
117
|
return send("Cancelled.");
|
|
117
118
|
}
|
|
118
119
|
if (action === "create") {
|
|
@@ -120,6 +121,7 @@ async function handleAction(envelope) {
|
|
|
120
121
|
if (vault.exists()) return send("Vault already exists.");
|
|
121
122
|
state.pendingVaultUnlock = true;
|
|
122
123
|
state.pendingVaultUnlockAt = Date.now();
|
|
124
|
+
state.pendingVaultUnlockAttempts = 3;
|
|
123
125
|
state.pendingVaultAction = { type: "create" };
|
|
124
126
|
return send("Pick a vault password and send it next.\n(Message will be deleted. Send /vault cancel to abort.)", {
|
|
125
127
|
keyboard: { inline_keyboard: [[{ text: "Cancel", callback_data: "vault:cancel" }]] },
|
package/core/handlers.js
CHANGED
|
@@ -883,6 +883,7 @@ const PASSWORD_PROMPT_KB = { inline_keyboard: [[{ text: "Cancel", callback_data:
|
|
|
883
883
|
function armVaultPrompt(state, action) {
|
|
884
884
|
state.pendingVaultUnlock = true;
|
|
885
885
|
state.pendingVaultUnlockAt = Date.now();
|
|
886
|
+
state.pendingVaultUnlockAttempts = 3;
|
|
886
887
|
state.pendingVaultAction = action;
|
|
887
888
|
}
|
|
888
889
|
|
|
@@ -925,6 +926,7 @@ register({
|
|
|
925
926
|
state.pendingVaultUnlock = false;
|
|
926
927
|
state.pendingVaultAction = null;
|
|
927
928
|
state.pendingVaultUnlockAt = 0;
|
|
929
|
+
state.pendingVaultUnlockAttempts = 0;
|
|
928
930
|
return send("Cancelled.");
|
|
929
931
|
}
|
|
930
932
|
|
package/core/router.js
CHANGED
|
@@ -246,17 +246,19 @@ async function handleText(envelope) {
|
|
|
246
246
|
state.pendingVaultUnlock = false;
|
|
247
247
|
state.pendingVaultAction = null;
|
|
248
248
|
state.pendingVaultUnlockAt = 0;
|
|
249
|
+
state.pendingVaultUnlockAttempts = 0;
|
|
249
250
|
await send("Vault prompt timed out. Re-run the command.");
|
|
250
251
|
return;
|
|
251
252
|
}
|
|
252
253
|
const password = envelope.text;
|
|
253
254
|
await deleteMessage(envelope.messageId);
|
|
254
255
|
const action = state.pendingVaultAction;
|
|
255
|
-
state.pendingVaultUnlock = false;
|
|
256
|
-
state.pendingVaultAction = null;
|
|
257
|
-
state.pendingVaultUnlockAt = 0;
|
|
258
256
|
|
|
259
257
|
if (action && action.type === "create") {
|
|
258
|
+
state.pendingVaultUnlock = false;
|
|
259
|
+
state.pendingVaultAction = null;
|
|
260
|
+
state.pendingVaultUnlockAt = 0;
|
|
261
|
+
state.pendingVaultUnlockAttempts = 0;
|
|
260
262
|
if (vault.exists()) { await send("Vault was created in another flow — re-run /vault."); return; }
|
|
261
263
|
vault.create(password);
|
|
262
264
|
await send("Vault created and unlocked.\n\nUse /vault set <name> <value>");
|
|
@@ -265,9 +267,27 @@ async function handleText(envelope) {
|
|
|
265
267
|
|
|
266
268
|
const ok = vault.unlock(password);
|
|
267
269
|
if (!ok) {
|
|
268
|
-
|
|
270
|
+
const left = (state.pendingVaultUnlockAttempts || 1) - 1;
|
|
271
|
+
if (left > 0) {
|
|
272
|
+
state.pendingVaultUnlockAttempts = left;
|
|
273
|
+
state.pendingVaultUnlockAt = Date.now();
|
|
274
|
+
await send(`Wrong password. ${left} attempt${left === 1 ? "" : "s"} left.\nSend the password again or /vault cancel.`, {
|
|
275
|
+
keyboard: { inline_keyboard: [[{ text: "Cancel", callback_data: "vault:cancel" }]] },
|
|
276
|
+
});
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
state.pendingVaultUnlock = false;
|
|
280
|
+
state.pendingVaultAction = null;
|
|
281
|
+
state.pendingVaultUnlockAt = 0;
|
|
282
|
+
state.pendingVaultUnlockAttempts = 0;
|
|
283
|
+
await send("Too many wrong attempts. Re-run /vault to try again.");
|
|
269
284
|
return;
|
|
270
285
|
}
|
|
286
|
+
|
|
287
|
+
state.pendingVaultUnlock = false;
|
|
288
|
+
state.pendingVaultAction = null;
|
|
289
|
+
state.pendingVaultUnlockAt = 0;
|
|
290
|
+
state.pendingVaultUnlockAttempts = 0;
|
|
271
291
|
if (action.type === "list") {
|
|
272
292
|
const entries = vault.list();
|
|
273
293
|
const keys = Object.keys(entries);
|
package/core/runner.js
CHANGED
|
@@ -390,7 +390,7 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
|
|
|
390
390
|
const { settings } = state;
|
|
391
391
|
|
|
392
392
|
if (state.runningProcess) {
|
|
393
|
-
state.messageQueue.push({ prompt, replyToMsgId, opts });
|
|
393
|
+
state.messageQueue.push({ prompt, replyToMsgId, opts, queuedAt: Date.now() });
|
|
394
394
|
await send(state.isCompacting ? "Compacting context, will pick this up next…" : "Queued.", { replyTo: replyToMsgId });
|
|
395
395
|
return;
|
|
396
396
|
}
|
|
@@ -676,8 +676,27 @@ async function runClaude(prompt, cwd, replyToMsgId, opts = {}) {
|
|
|
676
676
|
}
|
|
677
677
|
|
|
678
678
|
if (state.messageQueue.length > 0 && state.currentSession) {
|
|
679
|
-
const
|
|
680
|
-
|
|
679
|
+
const drained = state.messageQueue.splice(0);
|
|
680
|
+
if (drained.length === 1) {
|
|
681
|
+
const only = drained[0];
|
|
682
|
+
await runClaude(only.prompt, state.currentSession.dir, only.replyToMsgId, only.opts);
|
|
683
|
+
} else {
|
|
684
|
+
const fmtTime = (ts) => {
|
|
685
|
+
const d = new Date(ts);
|
|
686
|
+
const hh = String(d.getHours()).padStart(2, "0");
|
|
687
|
+
const mm = String(d.getMinutes()).padStart(2, "0");
|
|
688
|
+
const ss = String(d.getSeconds()).padStart(2, "0");
|
|
689
|
+
return `${hh}:${mm}:${ss}`;
|
|
690
|
+
};
|
|
691
|
+
const numbered = drained.map((m, i) => `[${i + 1}] (${fmtTime(m.queuedAt || Date.now())}) ${m.prompt}`).join("\n\n");
|
|
692
|
+
const batched =
|
|
693
|
+
`While you were working the user sent these ${drained.length} follow-up messages (oldest first):\n\n` +
|
|
694
|
+
`${numbered}\n\n` +
|
|
695
|
+
`Treat each as a distinct follow-up request. Add them to your plan and handle them; ` +
|
|
696
|
+
`if any contradicts an earlier one, prefer the newer one and call out the conflict.`;
|
|
697
|
+
const last = drained[drained.length - 1];
|
|
698
|
+
await runClaude(batched, state.currentSession.dir, last.replyToMsgId, last.opts);
|
|
699
|
+
}
|
|
681
700
|
}
|
|
682
701
|
}));
|
|
683
702
|
|
package/package.json
CHANGED