telegram-agent-kit 0.2.0 → 0.3.1
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
|
@@ -151,8 +151,9 @@ You implement these; the kit drives them.
|
|
|
151
151
|
| `Checkpointer` | `{ snapshot(threadId), rollback(threadId, id) }` | Per-thread snapshot/rollback for clean recovery on a failed turn. |
|
|
152
152
|
| `ThreadStore` | `{ resolve(chatKey, now), touch(chatKey, now) }` | Maps `{ chatId, agentId }` to a thread id (so two bots over one chat id don't collide). |
|
|
153
153
|
|
|
154
|
-
A `RenderEvent` is
|
|
155
|
-
|
|
154
|
+
A `RenderEvent` is either `token` or `error`: `token` text is appended to the live draft,
|
|
155
|
+
an `error` rolls the turn back, logs the message, and — if you pass `errorNotice` — tells
|
|
156
|
+
the user in the chat instead of going silent.
|
|
156
157
|
|
|
157
158
|
## API reference
|
|
158
159
|
|
|
@@ -177,6 +178,8 @@ appends `token` text to the live draft and treats an `error` event as a rollback
|
|
|
177
178
|
- `runTelegramTurn(opts)` — orchestrate one turn. Never throws out; every failure is caught and logged.
|
|
178
179
|
Accepts an optional `configurable` bag forwarded to your `AgentStream` as `context.configurable`,
|
|
179
180
|
for passing per-turn data (e.g. `pendingImages`) to the agent without widening the core input type.
|
|
181
|
+
Pass `errorNotice` (plain text, your language) to have a failed turn say so in the chat —
|
|
182
|
+
omit it and the user just sees the draft stop, which reads as being ignored.
|
|
180
183
|
- `sendReply(client, chatId, reply, opts, signal?)` / `sendText(...)` — the send path on its own.
|
|
181
184
|
- Types: `BotClient`, `AgentStream`, `Checkpointer`, `ThreadStore`, `RenderEvent`, `ChatKey`, `Logger`.
|
|
182
185
|
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
import { R as RenderEvent, A as AgentStream } from '../interfaces-
|
|
1
|
+
import { S as StreamInput, R as RenderEvent, A as AgentStream } from '../interfaces-DhF4n199.js';
|
|
2
2
|
import { RunnableConfig } from '@langchain/core/runnables';
|
|
3
3
|
import { createDeepAgent } from 'deepagents';
|
|
4
4
|
|
|
5
5
|
type Agent$1 = ReturnType<typeof createDeepAgent>;
|
|
6
|
-
|
|
7
|
-
messages: Array<{
|
|
8
|
-
role: 'user';
|
|
9
|
-
content: string;
|
|
10
|
-
}>;
|
|
11
|
-
};
|
|
12
|
-
declare function streamAgent(agent: Agent$1, input: StreamAgentInput, config: RunnableConfig, signal?: AbortSignal): AsyncIterable<RenderEvent>;
|
|
6
|
+
declare function streamAgent(agent: Agent$1, input: StreamInput, config: RunnableConfig, signal?: AbortSignal): AsyncIterable<RenderEvent>;
|
|
13
7
|
|
|
14
8
|
type Agent = Parameters<typeof streamAgent>[0];
|
|
15
9
|
/** Adapt a deepagents agent to the kit's runtime-agnostic AgentStream: merge the
|
|
@@ -19,4 +13,4 @@ type Agent = Parameters<typeof streamAgent>[0];
|
|
|
19
13
|
* the ONLY place the langgraph config shape lives. */
|
|
20
14
|
declare function toAgentStream(agent: Agent): AgentStream;
|
|
21
15
|
|
|
22
|
-
export { RenderEvent,
|
|
16
|
+
export { RenderEvent, StreamInput, streamAgent, toAgentStream };
|
package/dist/deepagents/index.js
CHANGED
|
@@ -8,20 +8,7 @@ function extractText(content) {
|
|
|
8
8
|
}
|
|
9
9
|
return "";
|
|
10
10
|
}
|
|
11
|
-
function extractToolError(output) {
|
|
12
|
-
if (typeof output !== "object" || output === null) return void 0;
|
|
13
|
-
const o = output;
|
|
14
|
-
if (o.status !== "error") return void 0;
|
|
15
|
-
const c = o.content;
|
|
16
|
-
if (typeof c === "string") return c;
|
|
17
|
-
try {
|
|
18
|
-
return JSON.stringify(c);
|
|
19
|
-
} catch {
|
|
20
|
-
return String(c);
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
11
|
async function* streamAgent(agent, input, config, signal) {
|
|
24
|
-
const toolStart = /* @__PURE__ */ new Map();
|
|
25
12
|
const iter = agent.streamEvents(input, {
|
|
26
13
|
...config,
|
|
27
14
|
signal,
|
|
@@ -33,24 +20,6 @@ async function* streamAgent(agent, input, config, signal) {
|
|
|
33
20
|
if (ev.metadata?.langgraph_node !== "model_request") continue;
|
|
34
21
|
const text = extractText(ev.data?.chunk?.content);
|
|
35
22
|
if (text) yield { type: "token", text };
|
|
36
|
-
} else if (ev.event === "on_tool_start") {
|
|
37
|
-
toolStart.set(ev.run_id, Date.now());
|
|
38
|
-
yield {
|
|
39
|
-
type: "tool_start",
|
|
40
|
-
id: ev.run_id,
|
|
41
|
-
name: ev.name ?? "unknown",
|
|
42
|
-
args: ev.data?.input
|
|
43
|
-
};
|
|
44
|
-
} else if (ev.event === "on_tool_end" || ev.event === "on_tool_error") {
|
|
45
|
-
const startedAt = toolStart.get(ev.run_id) ?? Date.now();
|
|
46
|
-
toolStart.delete(ev.run_id);
|
|
47
|
-
const error = ev.event === "on_tool_error" ? ev.data?.error instanceof Error ? ev.data.error.message : String(ev.data?.error ?? "tool error") : extractToolError(ev.data?.output);
|
|
48
|
-
yield {
|
|
49
|
-
type: "tool_end",
|
|
50
|
-
id: ev.run_id,
|
|
51
|
-
durationMs: Date.now() - startedAt,
|
|
52
|
-
...error !== void 0 ? { error } : {}
|
|
53
|
-
};
|
|
54
23
|
}
|
|
55
24
|
}
|
|
56
25
|
} 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-DhF4n199.js';
|
|
2
|
+
export { b as AgentStreamContext, R as RenderEvent, S as StreamInput } from './interfaces-DhF4n199.js';
|
|
3
3
|
|
|
4
4
|
type SendOpts = {
|
|
5
5
|
rich: boolean;
|
|
@@ -76,9 +76,12 @@ type RunTelegramTurnOpts = {
|
|
|
76
76
|
beforeTurn?: (ctx: TurnContext) => void | Promise<void>;
|
|
77
77
|
afterTurn?: (ctx: TurnContext) => void | Promise<void>;
|
|
78
78
|
};
|
|
79
|
-
makeDraftStreamer?: (deps: DraftStreamerDeps) => DraftStreamer;
|
|
80
79
|
draftConstants?: Partial<DraftConstants>;
|
|
81
80
|
configurable?: Record<string, unknown>;
|
|
81
|
+
/** Plain-text line sent to the chat when the stream errors out (model chain
|
|
82
|
+
* exhausted, graph threw). Without it the turn returns silently and the user
|
|
83
|
+
* sees only a draft that stops moving — indistinguishable from being ignored. */
|
|
84
|
+
errorNotice?: string;
|
|
82
85
|
};
|
|
83
86
|
declare function runTelegramTurn(opts: RunTelegramTurnOpts): Promise<void>;
|
|
84
87
|
|
package/dist/index.js
CHANGED
|
@@ -170,7 +170,7 @@ function renderLinks(text, autoClose) {
|
|
|
170
170
|
rest = rest.slice(m.index + m.length);
|
|
171
171
|
}
|
|
172
172
|
}
|
|
173
|
-
function
|
|
173
|
+
function renderInline(text, autoClose) {
|
|
174
174
|
let out = "";
|
|
175
175
|
let rest = text;
|
|
176
176
|
for (; ; ) {
|
|
@@ -193,9 +193,6 @@ function renderCode(text, autoClose) {
|
|
|
193
193
|
rest = rest.slice(close + 1);
|
|
194
194
|
}
|
|
195
195
|
}
|
|
196
|
-
function renderInline(line, autoClose) {
|
|
197
|
-
return renderCode(line, autoClose);
|
|
198
|
-
}
|
|
199
196
|
var FENCE_OPEN_RE = /^(`{3,}|~{3,})\s*(.*)$/;
|
|
200
197
|
var TICK_CLOSE_RE = /^`{3,}\s*$/;
|
|
201
198
|
var TILDE_CLOSE_RE = /^~{3,}\s*$/;
|
|
@@ -691,7 +688,6 @@ var NOOP_LOG = { warn: () => {
|
|
|
691
688
|
async function runTelegramTurn(opts) {
|
|
692
689
|
const now = opts.now ?? (() => Date.now());
|
|
693
690
|
const log = opts.log ?? NOOP_LOG;
|
|
694
|
-
const makeDraftStreamer = opts.makeDraftStreamer ?? createDraftStreamer;
|
|
695
691
|
const ctx = { chatKey: opts.chatKey, userText: opts.userText };
|
|
696
692
|
let rollback = null;
|
|
697
693
|
let turnCompleted = false;
|
|
@@ -718,7 +714,7 @@ async function runTelegramTurn(opts) {
|
|
|
718
714
|
const threadId = await opts.threadStore.resolve(opts.chatKey, now());
|
|
719
715
|
const checkpointId = await opts.checkpointer.snapshot(threadId);
|
|
720
716
|
rollback = { threadId, checkpointId };
|
|
721
|
-
draft =
|
|
717
|
+
draft = createDraftStreamer({
|
|
722
718
|
client: opts.client,
|
|
723
719
|
chatId: opts.chatKey.chatId,
|
|
724
720
|
draftId: opts.draftId,
|
|
@@ -728,7 +724,7 @@ async function runTelegramTurn(opts) {
|
|
|
728
724
|
});
|
|
729
725
|
draft.start();
|
|
730
726
|
let reply = "";
|
|
731
|
-
let
|
|
727
|
+
let errorMessage;
|
|
732
728
|
for await (const ev of opts.agentStream(
|
|
733
729
|
{ messages: [{ role: "user", content: opts.userText }] },
|
|
734
730
|
{ threadId, signal: opts.signal, configurable: opts.configurable }
|
|
@@ -736,15 +732,27 @@ async function runTelegramTurn(opts) {
|
|
|
736
732
|
if (ev.type === "token") {
|
|
737
733
|
reply += ev.text;
|
|
738
734
|
draft.push(reply);
|
|
739
|
-
} else if (ev.type === "error")
|
|
735
|
+
} else if (ev.type === "error") errorMessage = ev.message;
|
|
740
736
|
}
|
|
741
|
-
if (
|
|
737
|
+
if (errorMessage !== void 0) {
|
|
738
|
+
log.error("telegram turn errored", {
|
|
739
|
+
chatId: opts.chatKey.chatId,
|
|
740
|
+
err: errorMessage
|
|
741
|
+
});
|
|
742
742
|
draftTornDown = true;
|
|
743
743
|
await draft.abort().catch(() => {
|
|
744
744
|
});
|
|
745
745
|
await opts.checkpointer.rollback(rollback.threadId, rollback.checkpointId).catch(
|
|
746
746
|
(e) => log.error("telegram rollback failed", { err: String(e) })
|
|
747
747
|
);
|
|
748
|
+
if (opts.errorNotice && !opts.signal?.aborted) {
|
|
749
|
+
await opts.client.sendMessage(
|
|
750
|
+
{ chatId: opts.chatKey.chatId, text: opts.errorNotice },
|
|
751
|
+
opts.signal
|
|
752
|
+
).catch(
|
|
753
|
+
(e) => log.error("telegram error notice failed", { err: String(e) })
|
|
754
|
+
);
|
|
755
|
+
}
|
|
748
756
|
return;
|
|
749
757
|
}
|
|
750
758
|
draftTornDown = true;
|
|
@@ -5,7 +5,6 @@ type ChatKey = {
|
|
|
5
5
|
type Logger = {
|
|
6
6
|
warn(msg: string, data?: unknown): void;
|
|
7
7
|
error(msg: string, data?: unknown): void;
|
|
8
|
-
info?(msg: string, data?: unknown): void;
|
|
9
8
|
};
|
|
10
9
|
/** Raw Bot API transport primitives — one HTTP call each, NO chunking /
|
|
11
10
|
* rendering / fallback (the kit owns those). Each throws TelegramApiError
|
|
@@ -44,16 +43,6 @@ type BotClient = {
|
|
|
44
43
|
type RenderEvent = {
|
|
45
44
|
type: 'token';
|
|
46
45
|
text: string;
|
|
47
|
-
} | {
|
|
48
|
-
type: 'tool_start';
|
|
49
|
-
id: string;
|
|
50
|
-
name: string;
|
|
51
|
-
args: unknown;
|
|
52
|
-
} | {
|
|
53
|
-
type: 'tool_end';
|
|
54
|
-
id: string;
|
|
55
|
-
durationMs: number;
|
|
56
|
-
error?: string;
|
|
57
46
|
} | {
|
|
58
47
|
type: 'error';
|
|
59
48
|
message: string;
|
package/package.json
CHANGED