@leemour/cli-messaging 0.46.0 → 0.48.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 +1 -1
- package/dist/cli/config-command.js +3 -1
- package/dist/cli/config-command.js.map +1 -1
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/messenger/chats-command.d.ts.map +1 -1
- package/dist/cli/messenger/chats-command.js +11 -0
- package/dist/cli/messenger/chats-command.js.map +1 -1
- package/dist/cli/messenger/hearing-command.d.ts +19 -0
- package/dist/cli/messenger/hearing-command.d.ts.map +1 -0
- package/dist/cli/messenger/hearing-command.js +41 -0
- package/dist/cli/messenger/hearing-command.js.map +1 -0
- package/dist/cli/messenger/inbox.d.ts.map +1 -1
- package/dist/cli/messenger/inbox.js +14 -5
- package/dist/cli/messenger/inbox.js.map +1 -1
- package/dist/cli/messenger/mcp-command.d.ts +1 -0
- package/dist/cli/messenger/mcp-command.d.ts.map +1 -1
- package/dist/cli/messenger/mcp-command.js +7 -4
- package/dist/cli/messenger/mcp-command.js.map +1 -1
- package/dist/cli/messenger/messages-command.d.ts.map +1 -1
- package/dist/cli/messenger/messages-command.js +14 -4
- package/dist/cli/messenger/messages-command.js.map +1 -1
- package/dist/cli/messenger/messages-delete-command.d.ts +24 -0
- package/dist/cli/messenger/messages-delete-command.d.ts.map +1 -0
- package/dist/cli/messenger/messages-delete-command.js +44 -0
- package/dist/cli/messenger/messages-delete-command.js.map +1 -0
- package/dist/cli/messenger/port.d.ts +13 -1
- package/dist/cli/messenger/port.d.ts.map +1 -1
- package/dist/cli/messenger/port.js.map +1 -1
- package/dist/cli/messenger/topics-command.d.ts +5 -0
- package/dist/cli/messenger/topics-command.d.ts.map +1 -0
- package/dist/cli/messenger/topics-command.js +27 -0
- package/dist/cli/messenger/topics-command.js.map +1 -0
- package/dist/cli/messenger/transcribe-command.d.ts.map +1 -1
- package/dist/cli/messenger/transcribe-command.js +14 -1
- package/dist/cli/messenger/transcribe-command.js.map +1 -1
- package/dist/domain/models.d.ts +25 -0
- package/dist/domain/models.d.ts.map +1 -1
- package/dist/mcp/instructions.d.ts +2 -1
- package/dist/mcp/instructions.d.ts.map +1 -1
- package/dist/mcp/instructions.js +6 -1
- package/dist/mcp/instructions.js.map +1 -1
- package/dist/mcp/server.d.ts +2 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +4 -2
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tool.d.ts +1 -1
- package/dist/mcp/tool.d.ts.map +1 -1
- package/dist/mcp/tools/chats.d.ts.map +1 -1
- package/dist/mcp/tools/chats.js +8 -0
- package/dist/mcp/tools/chats.js.map +1 -1
- package/dist/mcp/tools/inbox.d.ts.map +1 -1
- package/dist/mcp/tools/inbox.js +15 -5
- package/dist/mcp/tools/inbox.js.map +1 -1
- package/dist/mcp/tools/messages-delete.d.ts +4 -0
- package/dist/mcp/tools/messages-delete.d.ts.map +1 -0
- package/dist/mcp/tools/messages-delete.js +19 -0
- package/dist/mcp/tools/messages-delete.js.map +1 -0
- package/dist/mcp/tools/messages.d.ts.map +1 -1
- package/dist/mcp/tools/messages.js +10 -2
- package/dist/mcp/tools/messages.js.map +1 -1
- package/dist/mcp/tools/topics.d.ts +4 -0
- package/dist/mcp/tools/topics.d.ts.map +1 -0
- package/dist/mcp/tools/topics.js +27 -0
- package/dist/mcp/tools/topics.js.map +1 -0
- package/dist/mcp/tools.d.ts +2 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +5 -0
- package/dist/mcp/tools.js.map +1 -1
- package/dist/speech/hearing.d.ts +59 -0
- package/dist/speech/hearing.d.ts.map +1 -0
- package/dist/speech/hearing.js +115 -0
- package/dist/speech/hearing.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { DELETE_AT_ONCE, guardedDelete } from "../../cli/messenger/messages-delete-command.js";
|
|
3
|
+
import { APPROVE, chatOf, message, tool, WRITE } from "../tool.js";
|
|
4
|
+
export const messageDeleteTools = (messenger) => ({
|
|
5
|
+
messages_delete: tool({
|
|
6
|
+
title: "Delete messages for the owner",
|
|
7
|
+
description: `Delete up to ${DELETE_AT_ONCE} messages from the owner's view of a chat; the other people still see them. ` +
|
|
8
|
+
"Cannot be undone. Only when the owner asked for these exact messages to be deleted.",
|
|
9
|
+
input: v.object({
|
|
10
|
+
chat: chatOf(messenger),
|
|
11
|
+
messages: v.pipe(v.array(message), v.minLength(1), v.maxLength(DELETE_AT_ONCE)),
|
|
12
|
+
}),
|
|
13
|
+
annotations: WRITE,
|
|
14
|
+
_meta: APPROVE,
|
|
15
|
+
permission: "delete",
|
|
16
|
+
online: (adapter, args, { guard }) => guardedDelete(guard, adapter, { chat: args.chat, messages: args.messages, forEveryone: false }),
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
//# sourceMappingURL=messages-delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages-delete.js","sourceRoot":"","sources":["../../../src/mcp/tools/messages-delete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,gDAAgD,CAAA;AAC9F,OAAO,EAAgB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,YAAY,CAAA;AAEhF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,CAAC;IACpF,eAAe,EAAE,IAAI,CAAC;QACpB,KAAK,EAAE,+BAA+B;QACtC,WAAW,EACT,gBAAgB,cAAc,8EAA8E;YAC5G,qFAAqF;QACvF,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC;YACvB,QAAQ,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;SAChF,CAAC;QACF,WAAW,EAAE,KAAK;QAClB,KAAK,EAAE,OAAO;QACd,UAAU,EAAE,QAAQ;QACpB,MAAM,EAAE,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CACnC,aAAa,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,EAAE,CAAC;KAClG,CAAC;CACH,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/messages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/messages.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAI/D,OAAO,EAAE,KAAK,OAAO,EAA8C,MAAM,YAAY,CAAA;AAErF,eAAO,MAAM,aAAa,cAAe,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAsG1E,CAAA"}
|
|
@@ -2,6 +2,7 @@ import * as v from "valibot";
|
|
|
2
2
|
import { afterOf, oneDirection } from "../../cli/messenger/after.js";
|
|
3
3
|
import { storedChatId } from "../../cli/messenger/messages-command.js";
|
|
4
4
|
import { capability } from "../../cli/messenger/port.js";
|
|
5
|
+
import { heard, hearForTool } from "../../speech/hearing.js";
|
|
5
6
|
import { chatOf, limit, message, nameOf, READ, tool } from "../tool.js";
|
|
6
7
|
export const messagesTools = (messenger) => {
|
|
7
8
|
const chat = chatOf(messenger);
|
|
@@ -11,12 +12,13 @@ export const messagesTools = (messenger) => {
|
|
|
11
12
|
title: "Read a chat",
|
|
12
13
|
description: "Recent messages in a chat, oldest first. Does not mark anything read. For older messages pass " +
|
|
13
14
|
"`before` = the id of the first item; for newer ones, `after` = the id of the last item, or a time. " +
|
|
14
|
-
"Returns { items, limit, hasMore }.",
|
|
15
|
+
"A voice message carries `transcript` once heard; `transcribe` hears the rest. Returns { items, limit, hasMore }.",
|
|
15
16
|
input: v.object({
|
|
16
17
|
chat,
|
|
17
18
|
limit,
|
|
18
19
|
before: v.optional(v.pipe(message, v.description("only messages older than this message id"))),
|
|
19
20
|
after: v.optional(v.pipe(v.string(), v.description("only messages newer than this message id, ISO 8601 time, or 2h / 1d ago"))),
|
|
21
|
+
transcribe: v.optional(v.pipe(v.boolean(), v.description("turn voice messages not heard yet into text; can take minutes"))),
|
|
20
22
|
}),
|
|
21
23
|
annotations: READ,
|
|
22
24
|
online: async (adapter, args, defaults) => {
|
|
@@ -31,7 +33,13 @@ export const messagesTools = (messenger) => {
|
|
|
31
33
|
limit: size,
|
|
32
34
|
after: afterOf(args.after, "after"),
|
|
33
35
|
});
|
|
34
|
-
|
|
36
|
+
const hearing = await hearForTool(messenger, adapter, found.items, args.transcribe === true, defaults);
|
|
37
|
+
return {
|
|
38
|
+
items: heard(found.items, hearing),
|
|
39
|
+
limit: size,
|
|
40
|
+
hasMore: found.hasMore,
|
|
41
|
+
...(args.transcribe ? { unheard: hearing?.unheard ?? [] } : {}),
|
|
42
|
+
};
|
|
35
43
|
},
|
|
36
44
|
}),
|
|
37
45
|
messages_context: tool({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/mcp/tools/messages.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAC5B,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAA;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,yCAAyC,CAAA;AACtE,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAgB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAErF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAoB,EAA2B,EAAE;IAC7E,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,CAAA;IAC9B,OAAO;QACL,aAAa,EAAE,IAAI,CAAC;YAClB,KAAK,EAAE,aAAa;YACpB,WAAW,EACT,gGAAgG;gBAChG,qGAAqG;gBACrG,
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../src/mcp/tools/messages.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topics.d.ts","sourceRoot":"","sources":["../../../src/mcp/tools/topics.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAA;AAE/D,OAAO,EAAE,KAAK,OAAO,EAAqD,MAAM,YAAY,CAAA;AAE5F,eAAO,MAAM,WAAW,cAAe,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CA2BvE,CAAA"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import * as v from "valibot";
|
|
2
|
+
import { capability } from "../../cli/messenger/port.js";
|
|
3
|
+
import { chatOf, envelope, limit, page, paging, READ, tool } from "../tool.js";
|
|
4
|
+
export const topicsTools = (messenger) => ({
|
|
5
|
+
topics_list: tool({
|
|
6
|
+
title: "A forum group's topics",
|
|
7
|
+
description: "The topics of a forum group, newest activity first: { id, title, closed, pinned, unreadCount, " +
|
|
8
|
+
"lastMessageAt, createdAt }. A message in a topic carries its id as threadId. `search` matches titles. " +
|
|
9
|
+
"Returns { items, page, limit, hasMore }.",
|
|
10
|
+
input: v.object({
|
|
11
|
+
chat: chatOf(messenger),
|
|
12
|
+
search: v.optional(v.pipe(v.string(), v.minLength(1), v.description("words from the topic's title"))),
|
|
13
|
+
limit,
|
|
14
|
+
page,
|
|
15
|
+
}),
|
|
16
|
+
annotations: READ,
|
|
17
|
+
online: async (adapter, { chat, search, ...rest }, defaults) => {
|
|
18
|
+
const { size, number, window } = paging(rest, defaults);
|
|
19
|
+
const found = await capability(adapter, "topics", "list forum topics")(chat, {
|
|
20
|
+
...window,
|
|
21
|
+
...(search === undefined ? {} : { search }),
|
|
22
|
+
});
|
|
23
|
+
return envelope(found, number, size);
|
|
24
|
+
},
|
|
25
|
+
}),
|
|
26
|
+
});
|
|
27
|
+
//# sourceMappingURL=topics.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"topics.js","sourceRoot":"","sources":["../../../src/mcp/tools/topics.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,SAAS,CAAA;AAE5B,OAAO,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAA;AACxD,OAAO,EAAgB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,YAAY,CAAA;AAE5F,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,CAAC;IAC7E,WAAW,EAAE,IAAI,CAAC;QAChB,KAAK,EAAE,wBAAwB;QAC/B,WAAW,EACT,gGAAgG;YAChG,wGAAwG;YACxG,0CAA0C;QAC5C,KAAK,EAAE,CAAC,CAAC,MAAM,CAAC;YACd,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC;YACvB,MAAM,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,WAAW,CAAC,8BAA8B,CAAC,CAAC,CAAC;YACrG,KAAK;YACL,IAAI;SACL,CAAC;QACF,WAAW,EAAE,IAAI;QACjB,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE;YAC7D,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;YACvD,MAAM,KAAK,GAAG,MAAM,UAAU,CAC5B,OAAO,EACP,QAAQ,EACR,mBAAmB,CACpB,CAAC,IAAI,EAAE;gBACN,GAAG,MAAM;gBACT,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC;aAC5C,CAAC,CAAA;YACF,OAAO,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,CAAA;QACtC,CAAC;KACF,CAAC;CACH,CAAC,CAAA"}
|
package/dist/mcp/tools.d.ts
CHANGED
|
@@ -7,6 +7,8 @@ import type { AnyTool } from "./tool.js";
|
|
|
7
7
|
export declare const readTools: (messenger: Messenger) => Record<string, AnyTool>;
|
|
8
8
|
/** Offered only with `--allow-mark-read`, which `--allow-send` does not imply: the other side sees it. */
|
|
9
9
|
export declare const markReadTools: (messenger: Messenger) => Record<string, AnyTool>;
|
|
10
|
+
/** Offered only with `--allow-delete`: the owner's own copy, never for everyone — that is the command's alone. */
|
|
11
|
+
export declare const deleteTools: (messenger: Messenger) => Record<string, AnyTool>;
|
|
10
12
|
/** Offered only with `--allow-send`. */
|
|
11
13
|
export declare const sendTools: (messenger: Messenger) => Record<string, AnyTool>;
|
|
12
14
|
//# sourceMappingURL=tools.d.ts.map
|
package/dist/mcp/tools.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAgBxC;;;GAGG;AACH,eAAO,MAAM,SAAS,cAAe,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAUrE,CAAA;AAEF,0GAA0G;AAC1G,eAAO,MAAM,aAAa,cAAe,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAA8B,CAAA;AAEzG,kHAAkH;AAClH,eAAO,MAAM,WAAW,cAAe,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAkC,CAAA;AAE3G,wCAAwC;AACxC,eAAO,MAAM,SAAS,cAAe,SAAS,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAIrE,CAAA"}
|
package/dist/mcp/tools.js
CHANGED
|
@@ -5,11 +5,13 @@ import { contactsTools } from "./tools/contacts.js";
|
|
|
5
5
|
import { inboxTools } from "./tools/inbox.js";
|
|
6
6
|
import { messagesTools } from "./tools/messages.js";
|
|
7
7
|
import { messageActionTools } from "./tools/messages-actions.js";
|
|
8
|
+
import { messageDeleteTools } from "./tools/messages-delete.js";
|
|
8
9
|
import { messagesPhotoTools } from "./tools/messages-photo.js";
|
|
9
10
|
import { messageSendTools } from "./tools/messages-send.js";
|
|
10
11
|
import { messagesTranscribeTools } from "./tools/messages-transcribe.js";
|
|
11
12
|
import { reactionTools } from "./tools/reactions.js";
|
|
12
13
|
import { reviewTools } from "./tools/review.js";
|
|
14
|
+
import { topicsTools } from "./tools/topics.js";
|
|
13
15
|
/**
|
|
14
16
|
* The read tools, each answering what its command's `--json` prints. Named `<cli>_<command words>`,
|
|
15
17
|
* so `tg_chats_list` is `tg chats list`. A new resource is a file in `tools/` and a line here.
|
|
@@ -17,6 +19,7 @@ import { reviewTools } from "./tools/review.js";
|
|
|
17
19
|
export const readTools = (messenger) => ({
|
|
18
20
|
...inboxTools(messenger),
|
|
19
21
|
...reviewTools(messenger),
|
|
22
|
+
...topicsTools(messenger),
|
|
20
23
|
...accountTools(messenger),
|
|
21
24
|
...chatsTools(messenger),
|
|
22
25
|
...contactsTools(messenger),
|
|
@@ -26,6 +29,8 @@ export const readTools = (messenger) => ({
|
|
|
26
29
|
});
|
|
27
30
|
/** Offered only with `--allow-mark-read`, which `--allow-send` does not imply: the other side sees it. */
|
|
28
31
|
export const markReadTools = (messenger) => chatsReadTools(messenger);
|
|
32
|
+
/** Offered only with `--allow-delete`: the owner's own copy, never for everyone — that is the command's alone. */
|
|
33
|
+
export const deleteTools = (messenger) => messageDeleteTools(messenger);
|
|
29
34
|
/** Offered only with `--allow-send`. */
|
|
30
35
|
export const sendTools = (messenger) => ({
|
|
31
36
|
...messageSendTools(messenger),
|
package/dist/mcp/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,CAAC;IAC3E,GAAG,UAAU,CAAC,SAAS,CAAC;IACxB,GAAG,WAAW,CAAC,SAAS,CAAC;IACzB,GAAG,YAAY,CAAC,SAAS,CAAC;IAC1B,GAAG,UAAU,CAAC,SAAS,CAAC;IACxB,GAAG,aAAa,CAAC,SAAS,CAAC;IAC3B,GAAG,aAAa,CAAC,SAAS,CAAC;IAC3B,GAAG,kBAAkB,CAAC,SAAS,CAAC;IAChC,GAAG,uBAAuB,CAAC,SAAS,CAAC;CACtC,CAAC,CAAA;AAEF,0GAA0G;AAC1G,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;AAEzG,wCAAwC;AACxC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,CAAC;IAC3E,GAAG,gBAAgB,CAAC,SAAS,CAAC;IAC9B,GAAG,kBAAkB,CAAC,SAAS,CAAC;IAChC,GAAG,aAAa,CAAC,SAAS,CAAC;CAC5B,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAA;AAChE,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAA;AAC/D,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,gCAAgC,CAAA;AACxE,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,CAAC;IAC3E,GAAG,UAAU,CAAC,SAAS,CAAC;IACxB,GAAG,WAAW,CAAC,SAAS,CAAC;IACzB,GAAG,WAAW,CAAC,SAAS,CAAC;IACzB,GAAG,YAAY,CAAC,SAAS,CAAC;IAC1B,GAAG,UAAU,CAAC,SAAS,CAAC;IACxB,GAAG,aAAa,CAAC,SAAS,CAAC;IAC3B,GAAG,aAAa,CAAC,SAAS,CAAC;IAC3B,GAAG,kBAAkB,CAAC,SAAS,CAAC;IAChC,GAAG,uBAAuB,CAAC,SAAS,CAAC;CACtC,CAAC,CAAA;AAEF,0GAA0G;AAC1G,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;AAEzG,kHAAkH;AAClH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAA;AAE3G,wCAAwC;AACxC,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,SAAoB,EAA2B,EAAE,CAAC,CAAC;IAC3E,GAAG,gBAAgB,CAAC,SAAS,CAAC;IAC9B,GAAG,kBAAkB,CAAC,SAAS,CAAC;IAChC,GAAG,aAAa,CAAC,SAAS,CAAC;CAC5B,CAAC,CAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { Messenger } from "../cli/messenger/context.js";
|
|
2
|
+
import type { MessengerAdapter } from "../cli/messenger/port.js";
|
|
3
|
+
import type { Settings } from "../cli/settings.js";
|
|
4
|
+
import type { Message } from "../domain/models.js";
|
|
5
|
+
import { type Choice } from "./transcribe.js";
|
|
6
|
+
/** Telegram polls each voice message for up to a minute; a whole list gets this long, then says what is left. */
|
|
7
|
+
export declare const HEARING_BUDGET_MS = 120000;
|
|
8
|
+
export interface Voice {
|
|
9
|
+
chatId: string;
|
|
10
|
+
messageId: string;
|
|
11
|
+
}
|
|
12
|
+
export interface Hearing {
|
|
13
|
+
/** By `keyOf`: the text of every voice message heard now or kept from before. */
|
|
14
|
+
transcripts: Map<string, string>;
|
|
15
|
+
/** Voice messages still without text after `--transcribe`: out of time, pending, or refused. */
|
|
16
|
+
unheard: Voice[];
|
|
17
|
+
/** Why some were not heard — the first reason; the messages are still worth showing. */
|
|
18
|
+
problem?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare const keyOf: ({ chatId, messageId }: Voice) => string;
|
|
21
|
+
/** Telegram says `voice`; MAX says `audio` with Ogg in it. */
|
|
22
|
+
export declare const isVoice: (message: Message) => boolean;
|
|
23
|
+
export interface Kept {
|
|
24
|
+
get(voice: Voice): string | undefined;
|
|
25
|
+
keep(voice: Voice, text: string, source: string): void;
|
|
26
|
+
close(): void;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Transcripts already heard, per profile, in the CLI's own cache — not the store: a transcript is
|
|
30
|
+
* derived and can be heard again, and a development build's `<PREFIX>_CACHE_DIR` keeps it off the
|
|
31
|
+
* owner's files. One profile is one account, so a chat and a message id are the key.
|
|
32
|
+
*/
|
|
33
|
+
export declare const openKept: (messenger: Messenger, profile: string, env: NodeJS.ProcessEnv) => Promise<Kept>;
|
|
34
|
+
/**
|
|
35
|
+
* Kept transcripts always — they cost nothing; new ones only when `connect` is given (`--transcribe`).
|
|
36
|
+
* The messenger is asked inside one connection; a local model runs after it closes, on the bytes
|
|
37
|
+
* fetched in it. What could not be heard is in `unheard`, never a failure.
|
|
38
|
+
*/
|
|
39
|
+
export declare const hearVoices: (messenger: Messenger, messages: readonly Message[], kept: Kept, transcribe?: {
|
|
40
|
+
choice: Choice;
|
|
41
|
+
connect: <T>(work: (adapter: MessengerAdapter) => Promise<T>) => Promise<T>;
|
|
42
|
+
budgetMs?: number;
|
|
43
|
+
}) => Promise<Hearing>;
|
|
44
|
+
/** A message with its transcript, when there is one; others pass through unchanged. */
|
|
45
|
+
export declare const withTranscript: <T extends Message>(message: T, hearing: Hearing) => T & {
|
|
46
|
+
transcript?: string;
|
|
47
|
+
};
|
|
48
|
+
/** How a person sees one: the text the messenger has, then what was heard. */
|
|
49
|
+
export declare const spoken: <T extends Message & {
|
|
50
|
+
transcript?: string;
|
|
51
|
+
}>({ transcript, ...message }: T) => Message;
|
|
52
|
+
/** For an MCP tool: the same hearing, over the session's own connection. */
|
|
53
|
+
export declare const hearForTool: (messenger: Messenger, adapter: MessengerAdapter, messages: readonly Message[], transcribe: boolean, { settings, env }: {
|
|
54
|
+
settings: Pick<Settings, "configured" | "shared" | "profile">;
|
|
55
|
+
env: NodeJS.ProcessEnv;
|
|
56
|
+
}) => Promise<Hearing | undefined>;
|
|
57
|
+
/** Messages with their transcripts; `unheard` as well when `--transcribe` was asked for. */
|
|
58
|
+
export declare const heard: <T extends Message>(messages: readonly T[], hearing: Hearing | undefined) => T[];
|
|
59
|
+
//# sourceMappingURL=hearing.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hearing.d.ts","sourceRoot":"","sources":["../../src/speech/hearing.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAA;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAA;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAClD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAElD,OAAO,EAAE,KAAK,MAAM,EAAmC,MAAM,iBAAiB,CAAA;AAE9E,iHAAiH;AACjH,eAAO,MAAM,iBAAiB,SAAU,CAAA;AAExC,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,OAAO;IACtB,iFAAiF;IACjF,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAChC,gGAAgG;IAChG,OAAO,EAAE,KAAK,EAAE,CAAA;IAChB,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,eAAO,MAAM,KAAK,0BAA2B,KAAK,KAAG,MAAkC,CAAA;AAEvF,8DAA8D;AAC9D,eAAO,MAAM,OAAO,YAAa,OAAO,KAAG,OAC6C,CAAA;AAExF,MAAM,WAAW,IAAI;IACnB,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,GAAG,SAAS,CAAA;IACrC,IAAI,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IACtD,KAAK,IAAI,IAAI,CAAA;CACd;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,cAAqB,SAAS,WAAW,MAAM,OAAO,MAAM,CAAC,UAAU,KAAG,OAAO,CAAC,IAAI,CA0B1G,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,cACV,SAAS,YACV,SAAS,OAAO,EAAE,QACtB,IAAI,eACG;IACX,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,gBAAgB,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAA;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,KACA,OAAO,CAAC,OAAO,CAsCjB,CAAA;AAED,uFAAuF;AACvF,eAAO,MAAM,cAAc,GAAI,CAAC,SAAS,OAAO,WAAW,CAAC,WAAW,OAAO,KAAG,CAAC,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAGzG,CAAA;AAED,8EAA8E;AAC9E,eAAO,MAAM,MAAM,GAAI,CAAC,SAAS,OAAO,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAA;CAAE,8BAA8B,CAAC,KAAG,OAGX,CAAA;AAEzF,4EAA4E;AAC5E,eAAO,MAAM,WAAW,cACX,SAAS,WACX,gBAAgB,YACf,SAAS,OAAO,EAAE,cAChB,OAAO,qBACA;IAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,YAAY,GAAG,QAAQ,GAAG,SAAS,CAAC,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAA;CAAE,KAC3G,OAAO,CAAC,OAAO,GAAG,SAAS,CAa7B,CAAA;AAED,4FAA4F;AAC5F,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,OAAO,YAAY,SAAS,CAAC,EAAE,WAAW,OAAO,GAAG,SAAS,KAAG,CAAC,EACV,CAAA"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { chmodSync, mkdirSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { resolvePaths } from "@leemour/cli-core";
|
|
4
|
+
import { openCache } from "../store/open.js";
|
|
5
|
+
import { choose, hearLocally, hearOnline } from "./transcribe.js";
|
|
6
|
+
/** Telegram polls each voice message for up to a minute; a whole list gets this long, then says what is left. */
|
|
7
|
+
export const HEARING_BUDGET_MS = 120_000;
|
|
8
|
+
export const keyOf = ({ chatId, messageId }) => `${chatId}/${messageId}`;
|
|
9
|
+
/** Telegram says `voice`; MAX says `audio` with Ogg in it. */
|
|
10
|
+
export const isVoice = (message) => message.attachments.some(({ kind, mime }) => kind === "voice" || mime === "audio/ogg");
|
|
11
|
+
/**
|
|
12
|
+
* Transcripts already heard, per profile, in the CLI's own cache — not the store: a transcript is
|
|
13
|
+
* derived and can be heard again, and a development build's `<PREFIX>_CACHE_DIR` keeps it off the
|
|
14
|
+
* owner's files. One profile is one account, so a chat and a message id are the key.
|
|
15
|
+
*/
|
|
16
|
+
export const openKept = async (messenger, profile, env) => {
|
|
17
|
+
const directory = resolvePaths({ appName: messenger.app.appName, prefix: messenger.app.envPrefix, env }).cache;
|
|
18
|
+
mkdirSync(directory, { recursive: true, mode: 0o700 });
|
|
19
|
+
const path = join(directory, `transcripts-${profile}.db`);
|
|
20
|
+
const database = await openCache(path);
|
|
21
|
+
chmodSync(path, 0o600);
|
|
22
|
+
database.exec(`CREATE TABLE IF NOT EXISTS transcripts (
|
|
23
|
+
chat_id TEXT NOT NULL,
|
|
24
|
+
message_id TEXT NOT NULL,
|
|
25
|
+
text TEXT NOT NULL,
|
|
26
|
+
source TEXT NOT NULL,
|
|
27
|
+
heard_at TEXT NOT NULL,
|
|
28
|
+
PRIMARY KEY (chat_id, message_id)
|
|
29
|
+
)`);
|
|
30
|
+
const read = database.prepare("SELECT text FROM transcripts WHERE chat_id = ? AND message_id = ?");
|
|
31
|
+
const write = database.prepare("INSERT OR REPLACE INTO transcripts (chat_id, message_id, text, source, heard_at) VALUES (?, ?, ?, ?, ?)");
|
|
32
|
+
return {
|
|
33
|
+
get: ({ chatId, messageId }) => read.get(chatId, messageId)?.text,
|
|
34
|
+
keep: ({ chatId, messageId }, text, source) => {
|
|
35
|
+
// A pending or empty answer would stick for good; only a finished text is kept.
|
|
36
|
+
if (text.trim() !== "")
|
|
37
|
+
write.run(chatId, messageId, text, source, new Date().toISOString());
|
|
38
|
+
},
|
|
39
|
+
close: () => database.close(),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Kept transcripts always — they cost nothing; new ones only when `connect` is given (`--transcribe`).
|
|
44
|
+
* The messenger is asked inside one connection; a local model runs after it closes, on the bytes
|
|
45
|
+
* fetched in it. What could not be heard is in `unheard`, never a failure.
|
|
46
|
+
*/
|
|
47
|
+
export const hearVoices = async (messenger, messages, kept, transcribe) => {
|
|
48
|
+
const transcripts = new Map();
|
|
49
|
+
const missing = [];
|
|
50
|
+
for (const message of messages.filter(isVoice)) {
|
|
51
|
+
const voice = { chatId: message.chatId, messageId: message.id };
|
|
52
|
+
const text = kept.get(voice);
|
|
53
|
+
if (text === undefined)
|
|
54
|
+
missing.push(voice);
|
|
55
|
+
else
|
|
56
|
+
transcripts.set(keyOf(voice), text);
|
|
57
|
+
}
|
|
58
|
+
if (!transcribe || missing.length === 0)
|
|
59
|
+
return { transcripts, unheard: [] };
|
|
60
|
+
const { choice, connect, budgetMs = HEARING_BUDGET_MS } = transcribe;
|
|
61
|
+
const deadline = Date.now() + budgetMs;
|
|
62
|
+
let problem;
|
|
63
|
+
const fetched = await connect(async (adapter) => {
|
|
64
|
+
const answers = [];
|
|
65
|
+
for (const voice of missing) {
|
|
66
|
+
if (Date.now() >= deadline)
|
|
67
|
+
break;
|
|
68
|
+
try {
|
|
69
|
+
answers.push([voice, await hearOnline(messenger, adapter, voice.chatId, voice.messageId, choice)]);
|
|
70
|
+
}
|
|
71
|
+
catch (error) {
|
|
72
|
+
problem ??= error instanceof Error ? error.message : String(error);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return answers;
|
|
76
|
+
});
|
|
77
|
+
for (const [voice, answer] of fetched) {
|
|
78
|
+
try {
|
|
79
|
+
const heard = answer instanceof Uint8Array ? await hearLocally(answer, voice.messageId, choice) : answer;
|
|
80
|
+
if (heard.pending || heard.text.trim() === "")
|
|
81
|
+
continue;
|
|
82
|
+
transcripts.set(keyOf(voice), heard.text);
|
|
83
|
+
kept.keep(voice, heard.text, heard.model ?? heard.via);
|
|
84
|
+
}
|
|
85
|
+
catch (error) {
|
|
86
|
+
problem ??= error instanceof Error ? error.message : String(error);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const unheard = missing.filter((voice) => !transcripts.has(keyOf(voice)));
|
|
90
|
+
return { transcripts, unheard, ...(problem === undefined ? {} : { problem }) };
|
|
91
|
+
};
|
|
92
|
+
/** A message with its transcript, when there is one; others pass through unchanged. */
|
|
93
|
+
export const withTranscript = (message, hearing) => {
|
|
94
|
+
const transcript = hearing.transcripts.get(keyOf({ chatId: message.chatId, messageId: message.id }));
|
|
95
|
+
return transcript === undefined ? message : { ...message, transcript };
|
|
96
|
+
};
|
|
97
|
+
/** How a person sees one: the text the messenger has, then what was heard. */
|
|
98
|
+
export const spoken = ({ transcript, ...message }) => transcript === undefined
|
|
99
|
+
? message
|
|
100
|
+
: { ...message, text: [message.text, `🎤 ${transcript}`].filter(Boolean).join("\n") };
|
|
101
|
+
/** For an MCP tool: the same hearing, over the session's own connection. */
|
|
102
|
+
export const hearForTool = async (messenger, adapter, messages, transcribe, { settings, env }) => {
|
|
103
|
+
if (!messages.some(isVoice))
|
|
104
|
+
return undefined;
|
|
105
|
+
const kept = await openKept(messenger, settings.profile, env);
|
|
106
|
+
try {
|
|
107
|
+
return await hearVoices(messenger, messages, kept, transcribe ? { choice: choose(messenger, settings, {}, env), connect: (work) => work(adapter) } : undefined);
|
|
108
|
+
}
|
|
109
|
+
finally {
|
|
110
|
+
kept.close();
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
/** Messages with their transcripts; `unheard` as well when `--transcribe` was asked for. */
|
|
114
|
+
export const heard = (messages, hearing) => hearing ? messages.map((message) => withTranscript(message, hearing)) : [...messages];
|
|
115
|
+
//# sourceMappingURL=hearing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hearing.js","sourceRoot":"","sources":["../../src/speech/hearing.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@leemour/cli-messaging",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "The messenger-neutral half of a messaging CLI: domain model, message locators, rendering, name resolution, the SQLite seam, the command skeleton and shared read commands, the send guard, run records and the message store",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Viacheslav Ptsarev",
|