feat: persistent typing indicator — refreshes every 4s until first stream token
This commit is contained in:
6
memories.md
Normal file
6
memories.md
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
### Self-Challenge Results (2025-07-09)
|
||||||
|
- Demonstrated full self-challenge loop: write code → write tests → run tests → all pass ✅
|
||||||
|
- 10/10 tests passed on math_utils.py (fibonacci, is_prime, factorial)
|
||||||
|
- Python 3.12 available at /usr/bin/python3, pytest 9.0.2 pre-installed
|
||||||
@@ -1026,8 +1026,15 @@ export async function initBot(config, api, tools, skills, agents) {
|
|||||||
logger.info(`${prefix} ${user}: ${text.substring(0, 80)}…`);
|
logger.info(`${prefix} ${user}: ${text.substring(0, 80)}…`);
|
||||||
|
|
||||||
await queueRequest(key, text, async () => {
|
await queueRequest(key, text, async () => {
|
||||||
await ctx.api.sendChatAction(ctx.chat.id, 'typing');
|
// ── Typing indicator: keep pinging until first stream token arrives ──
|
||||||
|
let firstTokenArrived = false;
|
||||||
|
const typingInterval = setInterval(async () => {
|
||||||
|
if (firstTokenArrived) return;
|
||||||
|
try { await ctx.api.sendChatAction(ctx.chat.id, 'typing'); } catch {}
|
||||||
|
}, 4000); // Telegram typing expires after 5s, refresh every 4s
|
||||||
|
await ctx.api.sendChatAction(ctx.chat.id, 'typing'); // initial ping
|
||||||
|
|
||||||
|
try {
|
||||||
// ── Load conversation history for this chat ──
|
// ── Load conversation history for this chat ──
|
||||||
const chatKey = conversation._key(ctx.chat.id, ctx.message?.message_thread_id);
|
const chatKey = conversation._key(ctx.chat.id, ctx.message?.message_thread_id);
|
||||||
svc.currentChatId = ctx.chat.id; // Track for TTS auto-send
|
svc.currentChatId = ctx.chat.id; // Track for TTS auto-send
|
||||||
@@ -1046,7 +1053,10 @@ export async function initBot(config, api, tools, skills, agents) {
|
|||||||
|
|
||||||
// Wrap chatWithAI with self-correction + streaming
|
// Wrap chatWithAI with self-correction + streaming
|
||||||
const chatWithCorrection = withSelfCorrection(async (msgs) => {
|
const chatWithCorrection = withSelfCorrection(async (msgs) => {
|
||||||
return await chatWithAI(msgs, { onDelta: (token) => consumer.onDelta(token) });
|
return await chatWithAI(msgs, { onDelta: (token) => {
|
||||||
|
if (!firstTokenArrived) firstTokenArrived = true;
|
||||||
|
consumer.onDelta(token);
|
||||||
|
}});
|
||||||
});
|
});
|
||||||
|
|
||||||
const result = await chatWithCorrection(messages);
|
const result = await chatWithCorrection(messages);
|
||||||
@@ -1055,6 +1065,10 @@ export async function initBot(config, api, tools, skills, agents) {
|
|||||||
await conversation.add(chatKey, 'user', text);
|
await conversation.add(chatKey, 'user', text);
|
||||||
if (result) await conversation.add(chatKey, 'assistant', result);
|
if (result) await conversation.add(chatKey, 'assistant', result);
|
||||||
|
|
||||||
|
// Stop typing indicator
|
||||||
|
firstTokenArrived = true;
|
||||||
|
clearInterval(typingInterval);
|
||||||
|
|
||||||
// Signal completion and wait for final edit
|
// Signal completion and wait for final edit
|
||||||
consumer.finish();
|
consumer.finish();
|
||||||
await runPromise;
|
await runPromise;
|
||||||
@@ -1069,6 +1083,10 @@ export async function initBot(config, api, tools, skills, agents) {
|
|||||||
|
|
||||||
// ── Self-learning: extract patterns from this interaction ──
|
// ── Self-learning: extract patterns from this interaction ──
|
||||||
await selfLearn(text, result, memory);
|
await selfLearn(text, result, memory);
|
||||||
|
} finally {
|
||||||
|
// Always stop typing indicator, even on error
|
||||||
|
clearInterval(typingInterval);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user