telegram-agent-kit 0.4.0 → 0.5.0
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/README.md
CHANGED
|
@@ -157,9 +157,12 @@ You implement these; the kit drives them.
|
|
|
157
157
|
| `Checkpointer` | `{ snapshot(threadId), rollback(threadId, id) }` | Per-thread snapshot/rollback for clean recovery on a failed turn. |
|
|
158
158
|
| `ThreadStore` | `{ resolve(chatKey, now), touch(chatKey, now) }` | Maps `{ chatId, agentId }` to a thread id (so two bots over one chat id don't collide). |
|
|
159
159
|
|
|
160
|
-
A `RenderEvent` is
|
|
161
|
-
|
|
162
|
-
the
|
|
160
|
+
A `RenderEvent` is one of `token`, `tool_start` or `error`. `token` text is appended to
|
|
161
|
+
the live draft *and* to the reply that gets sent. `tool_start` shows a transient
|
|
162
|
+
`🔧 \`name\`…` line under the draft so the user sees which tool is running instead of a
|
|
163
|
+
frozen draft — it is cleared by the next token and **never** becomes part of the sent
|
|
164
|
+
message. An `error` rolls the turn back, logs the message, and — if you pass
|
|
165
|
+
`errorNotice` — tells the user in the chat instead of going silent.
|
|
163
166
|
|
|
164
167
|
## API reference
|
|
165
168
|
|
|
@@ -189,6 +192,7 @@ the user in the chat instead of going silent.
|
|
|
189
192
|
Pass `errorNotice` (plain text, your language) to have a failed turn say so in the chat —
|
|
190
193
|
omit it and the user just sees the draft stop, which reads as being ignored.
|
|
191
194
|
- `sendReply(client, chatId, reply, opts, signal?)` / `sendText(...)` — the send path on its own.
|
|
195
|
+
`opts` is `{ rich: boolean, log: Logger }`, with the same `rich` semantics as above.
|
|
192
196
|
- Types: `BotClient`, `AgentStream`, `Checkpointer`, `ThreadStore`, `RenderEvent`, `ChatKey`, `Logger`.
|
|
193
197
|
|
|
194
198
|
**Errors**
|
|
@@ -204,6 +208,10 @@ the user in the chat instead of going silent.
|
|
|
204
208
|
`__pregel_*` LangGraph internal-execution key — are stripped so the kit retains full control over
|
|
205
209
|
checkpoint routing and execution.
|
|
206
210
|
- `streamAgent(agent, input, config, signal?)` — lower-level event stream if you need direct control.
|
|
211
|
+
Yields tokens from the **root** agent only: a delegated agent (a `subagents` entry, or the built-in
|
|
212
|
+
`task` tool) runs its own model node and LangChain replays its events into the parent stream, so
|
|
213
|
+
without this its monologue would interleave with the reply. Naming the root agent does not change
|
|
214
|
+
what streams.
|
|
207
215
|
|
|
208
216
|
> `@langchain/core` and `deepagents` are **type-only, optional** peers. The built
|
|
209
217
|
> `/deepagents` bundle contains no runtime import of either, so the core stays
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { S as StreamInput, R as RenderEvent, A as AgentStream } from '../interfaces-
|
|
1
|
+
import { S as StreamInput, R as RenderEvent, A as AgentStream } from '../interfaces-BluM8MeB.js';
|
|
2
2
|
import { RunnableConfig } from '@langchain/core/runnables';
|
|
3
3
|
import { createDeepAgent } from 'deepagents';
|
|
4
4
|
|
package/dist/deepagents/index.js
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
// src/deepagents/stream-agent.ts
|
|
2
|
+
function isNested(ev) {
|
|
3
|
+
return ev.metadata?.checkpoint_ns?.includes("|") ?? false;
|
|
4
|
+
}
|
|
2
5
|
function extractText(content) {
|
|
3
6
|
if (typeof content === "string") return content;
|
|
4
7
|
if (Array.isArray(content)) {
|
|
@@ -18,8 +21,12 @@ async function* streamAgent(agent, input, config, signal) {
|
|
|
18
21
|
for await (const ev of iter) {
|
|
19
22
|
if (ev.event === "on_chat_model_stream") {
|
|
20
23
|
if (ev.metadata?.langgraph_node !== "model_request") continue;
|
|
24
|
+
if (isNested(ev)) continue;
|
|
21
25
|
const text = extractText(ev.data?.chunk?.content);
|
|
22
26
|
if (text) yield { type: "token", text };
|
|
27
|
+
} else if (ev.event === "on_tool_start") {
|
|
28
|
+
if (isNested(ev)) continue;
|
|
29
|
+
yield { type: "tool_start", name: ev.name ?? "unknown" };
|
|
23
30
|
}
|
|
24
31
|
}
|
|
25
32
|
} catch (err) {
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { B as BotClient, L as Logger, C as ChatKey, A as AgentStream, a as Checkpointer, T as ThreadStore } from './interfaces-
|
|
2
|
-
export { b as AgentStreamContext, R as RenderEvent, S as StreamInput } from './interfaces-
|
|
1
|
+
import { B as BotClient, L as Logger, C as ChatKey, A as AgentStream, a as Checkpointer, T as ThreadStore } from './interfaces-BluM8MeB.js';
|
|
2
|
+
export { b as AgentStreamContext, R as RenderEvent, S as StreamInput } from './interfaces-BluM8MeB.js';
|
|
3
3
|
|
|
4
4
|
type SendOpts = {
|
|
5
5
|
rich: boolean;
|
package/dist/index.js
CHANGED
|
@@ -737,6 +737,7 @@ async function runTelegramTurn(opts) {
|
|
|
737
737
|
});
|
|
738
738
|
draft.start();
|
|
739
739
|
let reply = "";
|
|
740
|
+
let status = "";
|
|
740
741
|
let errorMessage;
|
|
741
742
|
for await (const ev of opts.agentStream(
|
|
742
743
|
{ messages: [{ role: "user", content: opts.userText }] },
|
|
@@ -744,7 +745,13 @@ async function runTelegramTurn(opts) {
|
|
|
744
745
|
)) {
|
|
745
746
|
if (ev.type === "token") {
|
|
746
747
|
reply += ev.text;
|
|
748
|
+
status = "";
|
|
747
749
|
draft.push(reply);
|
|
750
|
+
} else if (ev.type === "tool_start") {
|
|
751
|
+
status = `\u{1F527} \`${ev.name}\`\u2026`;
|
|
752
|
+
draft.push(reply ? `${reply}
|
|
753
|
+
|
|
754
|
+
${status}` : status);
|
|
748
755
|
} else if (ev.type === "error") errorMessage = ev.message;
|
|
749
756
|
}
|
|
750
757
|
if (errorMessage !== void 0) {
|
|
@@ -771,6 +778,14 @@ async function runTelegramTurn(opts) {
|
|
|
771
778
|
draftTornDown = true;
|
|
772
779
|
await draft.finalize().catch(() => {
|
|
773
780
|
});
|
|
781
|
+
if (status) {
|
|
782
|
+
await opts.client.sendMessageDraft(
|
|
783
|
+
{ chatId: opts.chatKey.chatId, draftId: opts.draftId, text: reply },
|
|
784
|
+
opts.signal
|
|
785
|
+
).catch(
|
|
786
|
+
(e) => log.warn("telegram draft status clear failed", { err: String(e) })
|
|
787
|
+
);
|
|
788
|
+
}
|
|
774
789
|
turnCompleted = true;
|
|
775
790
|
if (reply.trim().length > 0) {
|
|
776
791
|
await sendReply(
|
|
@@ -43,6 +43,12 @@ type BotClient = {
|
|
|
43
43
|
type RenderEvent = {
|
|
44
44
|
type: 'token';
|
|
45
45
|
text: string;
|
|
46
|
+
}
|
|
47
|
+
/** The agent started a tool call. Surfaced in the live draft as a transient
|
|
48
|
+
* status line and NEVER folded into the reply — see runTelegramTurn. */
|
|
49
|
+
| {
|
|
50
|
+
type: 'tool_start';
|
|
51
|
+
name: string;
|
|
46
52
|
} | {
|
|
47
53
|
type: 'error';
|
|
48
54
|
message: string;
|
package/package.json
CHANGED