letagents 0.12.12 → 0.12.13
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/dist/mcp/git-remote.js +7 -7
- package/dist/mcp/local-state/agent-sessions.js +63 -5
- package/dist/mcp/local-state/local-chat.js +189 -48
- package/dist/mcp/local-state/storage.js +16 -9
- package/dist/mcp/server/daemon-tool-executor.js +92 -0
- package/dist/mcp/server/register-tools.js +4 -2
- package/dist/mcp/server/runtime/agent-sessions.js +14 -5
- package/dist/mcp/server/runtime/api.js +11 -3
- package/dist/mcp/server/runtime/daemon-tool-context.js +11 -0
- package/dist/mcp/server/runtime/messages.js +55 -0
- package/dist/mcp/server/runtime/room-state.js +13 -3
- package/dist/mcp/server/runtime/rooms.js +51 -30
- package/dist/mcp/server/runtime/supervisor-bridge.js +49 -8
- package/dist/mcp/server/runtime/worker-bearer.js +5 -1
- package/dist/mcp/server/runtime.js +3 -3
- package/dist/mcp/server/supervised-tool-facade.js +34 -5
- package/dist/mcp/server/tools/messages/read-tool.js +54 -97
- package/dist/mcp/server/tools/messages/reasoning-tool.js +2 -0
- package/dist/mcp/server/tools/messages/send-tool.js +2 -0
- package/dist/mcp/server/tools/messages/status-tool.js +2 -0
- package/dist/mcp/server/tools/messages/wait-tool.js +290 -68
- package/dist/mcp/server/tools/onboarding/status-tool.js +4 -4
- package/dist/mcp/server/tools/rooms/inspection-tools.js +15 -10
- package/dist/mcp/server/tools/rooms/repo-initialization-tool.js +2 -1
- package/dist/mcp/server/tools/tasks/board-tools.js +34 -2
- package/dist/mcp/sse-client.js +163 -20
- package/dist/shared/activation-routing.js +146 -23
- package/dist/shared/agent-presence.js +6 -0
- package/dist/shared/desktop-release-manifest.js +63 -0
- package/dist/shared/desktop-release.js +60 -0
- package/dist/shared/scoped-ids.js +6 -0
- package/package.json +6 -2
- package/shared/message-contracts.d.mts +32 -0
- package/shared/message-contracts.mjs +109 -0
- package/shared/routing-aliases.d.mts +18 -0
- package/shared/routing-aliases.mjs +66 -0
- package/shared/sqlite-thread-routing.d.mts +72 -0
- package/shared/sqlite-thread-routing.mjs +1038 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
const MAC_DESKTOP_BETA_VERSION = "0.1.5";
|
|
2
|
+
const MAC_DESKTOP_PUBLIC_BASE_URL = "https://downloads.letagents.chat/desktop";
|
|
3
|
+
function macDesktopAsset(architecture, sha256) {
|
|
4
|
+
const fileName = `LetAgents-${MAC_DESKTOP_BETA_VERSION}-darwin-${architecture}.dmg`;
|
|
5
|
+
return {
|
|
6
|
+
fileName,
|
|
7
|
+
publicUrl: `${MAC_DESKTOP_PUBLIC_BASE_URL}/v${MAC_DESKTOP_BETA_VERSION}/${fileName}`,
|
|
8
|
+
sha256,
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export const MAC_DESKTOP_BETA_RELEASE = {
|
|
12
|
+
version: MAC_DESKTOP_BETA_VERSION,
|
|
13
|
+
tag: `desktop-v${MAC_DESKTOP_BETA_VERSION}`,
|
|
14
|
+
assets: {
|
|
15
|
+
arm64: macDesktopAsset("arm64", "704355796cee5214a9cfbb79105a035e0e00dc3a3aa57be7d389b97cf35fc804"),
|
|
16
|
+
x64: macDesktopAsset("x64", "1e4b0b8b2c42ad8eaaf652fc887ab089445c8dd83233d763a6acdaa6617c2471"),
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
export const MAC_DESKTOP_BETA_CHECKSUM_RELEASES = [
|
|
20
|
+
MAC_DESKTOP_BETA_RELEASE,
|
|
21
|
+
{
|
|
22
|
+
version: "0.1.4",
|
|
23
|
+
assets: {
|
|
24
|
+
arm64: {
|
|
25
|
+
fileName: "LetAgents-0.1.4-darwin-arm64.dmg",
|
|
26
|
+
sha256: "27abe236232d33db10ed4533f4a7443a66f93568e9fa73a2ca472b6467fcf1cb",
|
|
27
|
+
},
|
|
28
|
+
x64: {
|
|
29
|
+
fileName: "LetAgents-0.1.4-darwin-x64.dmg",
|
|
30
|
+
sha256: "4c807ad0c799b4e46ab81d1098e5b65934d6b0b49f0a99ced2713897e1c2bc35",
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
version: "0.1.3",
|
|
36
|
+
assets: {
|
|
37
|
+
arm64: {
|
|
38
|
+
fileName: "LetAgents-0.1.3-darwin-arm64.dmg",
|
|
39
|
+
sha256: "6010454bc7375a38571d707f90c077207a7d2b49b01a1db1655b03f4def9b502",
|
|
40
|
+
},
|
|
41
|
+
x64: {
|
|
42
|
+
fileName: "LetAgents-0.1.3-darwin-x64.dmg",
|
|
43
|
+
sha256: "b7574e17ef87aebf418926478de10d9937fd1a96ca0c7a53b826a109302c5560",
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
version: "0.1.2",
|
|
49
|
+
assets: {
|
|
50
|
+
arm64: {
|
|
51
|
+
fileName: "LetAgents-0.1.2-darwin-arm64.dmg",
|
|
52
|
+
sha256: "e5355deced8383bc7d024ec60b109a38dde69dfeb6b6339352e1f5bc5c53bd43",
|
|
53
|
+
},
|
|
54
|
+
x64: {
|
|
55
|
+
fileName: "LetAgents-0.1.2-darwin-x64.dmg",
|
|
56
|
+
sha256: "67d2896b806695dae8c0224b3bc2780aee6902e897569c983ecc1bdb0330b6b0",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { POSTGRES_INTEGER_MAX, parsePositivePgIntegerScopedId as parseSharedPositivePgIntegerScopedId, } from "../../shared/message-contracts.mjs";
|
|
2
|
+
export { POSTGRES_INTEGER_MAX };
|
|
3
|
+
/** Parse the canonical `<prefix>_<positive PostgreSQL integer>` wire form. */
|
|
4
|
+
export function parsePositivePgIntegerScopedId(value, prefix) {
|
|
5
|
+
return parseSharedPositivePgIntegerScopedId(value, prefix);
|
|
6
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "letagents",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.13",
|
|
4
4
|
"description": "Let Agents Chat — MCP server for AI agent communication",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/mcp/server.js",
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"dist/mcp/**",
|
|
12
12
|
"dist/api/board-intent-payloads.js",
|
|
13
13
|
"dist/shared/**",
|
|
14
|
+
"shared/**",
|
|
14
15
|
"README.md"
|
|
15
16
|
],
|
|
16
17
|
"scripts": {
|
|
@@ -24,6 +25,9 @@
|
|
|
24
25
|
"test:orchestrator": "node --import tsx --test src/orchestrator/__tests__/*.test.ts",
|
|
25
26
|
"test:web": "node --import tsx --test src/web/tests/*.test.ts src/web/src/composables/*.test.ts",
|
|
26
27
|
"test:dependency-age": "node --test scripts/verify-dependency-age.test.mjs",
|
|
28
|
+
"test:docker-context": "node --test scripts/verify-docker-context.test.mjs",
|
|
29
|
+
"test:workflow-supply-chain": "node --test scripts/verify-workflow-supply-chain.test.mjs",
|
|
30
|
+
"test:notifications": "node --import tsx --test src/api/notifications/__tests__/*.test.ts",
|
|
27
31
|
"verify:dependency-age": "node scripts/verify-dependency-age.mjs",
|
|
28
32
|
"db:generate": "drizzle-kit generate",
|
|
29
33
|
"db:migrate": "tsx src/api/migrate.ts",
|
|
@@ -31,7 +35,7 @@
|
|
|
31
35
|
"prepublishOnly": "npm run build",
|
|
32
36
|
"dev:api": "tsx src/api/server.ts",
|
|
33
37
|
"dev:mcp": "tsx src/mcp/server.ts",
|
|
34
|
-
"dev:desktop": "npm --prefix apps/desktop run dev"
|
|
38
|
+
"dev:desktop": "node scripts/ensure-desktop-dependencies.mjs && npm --prefix apps/desktop run dev"
|
|
35
39
|
},
|
|
36
40
|
"keywords": [
|
|
37
41
|
"mcp",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const POSTGRES_INTEGER_MAX: number;
|
|
2
|
+
export const MESSAGE_SENDER_MAX_CODE_POINTS: number;
|
|
3
|
+
export const MESSAGE_SENDER_MAX_UTF8_BYTES: number;
|
|
4
|
+
export function parsePositivePgIntegerScopedId(value: unknown, prefix: string): number | null;
|
|
5
|
+
export function isMessageSenderWithinBounds(sender: unknown): sender is string;
|
|
6
|
+
export type ParsedAccountAgentRouting =
|
|
7
|
+
| { version: 1; authority: "invalid" }
|
|
8
|
+
| {
|
|
9
|
+
version: 1;
|
|
10
|
+
authority: "receipts";
|
|
11
|
+
recipientAgentKeys: string[];
|
|
12
|
+
recipientSessions: Array<{
|
|
13
|
+
agentKey: string;
|
|
14
|
+
agentSessionId: string;
|
|
15
|
+
successorAgentSessionId?: string;
|
|
16
|
+
}>;
|
|
17
|
+
controlAuthorized: boolean;
|
|
18
|
+
}
|
|
19
|
+
| {
|
|
20
|
+
version: 1;
|
|
21
|
+
authority: "legacy";
|
|
22
|
+
recipientAgentKeys: string[];
|
|
23
|
+
recipientSessions: Array<{
|
|
24
|
+
agentKey: string;
|
|
25
|
+
agentSessionId: string;
|
|
26
|
+
activationReason: string;
|
|
27
|
+
}>;
|
|
28
|
+
controlAuthorized: boolean;
|
|
29
|
+
};
|
|
30
|
+
export function parseAccountAgentRoutingEnvelope(
|
|
31
|
+
routing: unknown,
|
|
32
|
+
): ParsedAccountAgentRouting | undefined;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { normalizeRoutingSender } from "./routing-aliases.mjs";
|
|
2
|
+
|
|
3
|
+
export const POSTGRES_INTEGER_MAX = 2_147_483_647;
|
|
4
|
+
export const MESSAGE_SENDER_MAX_CODE_POINTS = 512;
|
|
5
|
+
export const MESSAGE_SENDER_MAX_UTF8_BYTES = 2_048;
|
|
6
|
+
|
|
7
|
+
/** Parse the canonical `<prefix>_<positive PostgreSQL integer>` wire form. */
|
|
8
|
+
export function parsePositivePgIntegerScopedId(value, prefix) {
|
|
9
|
+
if (typeof value !== "string" || typeof prefix !== "string" || !prefix) return null;
|
|
10
|
+
const marker = `${prefix}_`;
|
|
11
|
+
if (!value.startsWith(marker)) return null;
|
|
12
|
+
const decimal = value.slice(marker.length);
|
|
13
|
+
if (!/^[1-9]\d*$/.test(decimal)) return null;
|
|
14
|
+
const parsed = Number(decimal);
|
|
15
|
+
return Number.isSafeInteger(parsed) && parsed <= POSTGRES_INTEGER_MAX ? parsed : null;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Bound sender labels before routing projections duplicate their raw value. */
|
|
19
|
+
export function isMessageSenderWithinBounds(sender) {
|
|
20
|
+
if (typeof sender !== "string") return false;
|
|
21
|
+
let codePoints = 0;
|
|
22
|
+
for (const _character of sender) {
|
|
23
|
+
codePoints += 1;
|
|
24
|
+
if (codePoints > MESSAGE_SENDER_MAX_CODE_POINTS) return false;
|
|
25
|
+
}
|
|
26
|
+
return new TextEncoder().encode(sender).byteLength <= MESSAGE_SENDER_MAX_UTF8_BYTES;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Parse the account-scoped routing envelope shared by Desktop and MCP.
|
|
31
|
+
* Undefined means an older/local message supplied no authority. Any present
|
|
32
|
+
* malformed shape returns explicit invalid authority and must never fall back
|
|
33
|
+
* to mutable display aliases.
|
|
34
|
+
*/
|
|
35
|
+
export function parseAccountAgentRoutingEnvelope(routing) {
|
|
36
|
+
if (routing === undefined) return undefined;
|
|
37
|
+
if (!routing || typeof routing !== "object" || routing.version !== 1) {
|
|
38
|
+
return { version: 1, authority: "invalid" };
|
|
39
|
+
}
|
|
40
|
+
if (routing.authority !== "receipts" && routing.authority !== "legacy") {
|
|
41
|
+
return { version: 1, authority: "invalid" };
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
!Array.isArray(routing.recipient_agent_keys)
|
|
45
|
+
|| !routing.recipient_agent_keys.every((value) => typeof value === "string")
|
|
46
|
+
|| !Array.isArray(routing.recipient_agent_sessions)
|
|
47
|
+
) {
|
|
48
|
+
return { version: 1, authority: "invalid" };
|
|
49
|
+
}
|
|
50
|
+
const recipientAgentKeys = routing.recipient_agent_keys.map(normalizeRoutingSender);
|
|
51
|
+
if (recipientAgentKeys.some((value) => !value)) {
|
|
52
|
+
return { version: 1, authority: "invalid" };
|
|
53
|
+
}
|
|
54
|
+
const uniqueKeys = new Set(recipientAgentKeys);
|
|
55
|
+
if (uniqueKeys.size !== recipientAgentKeys.length) {
|
|
56
|
+
return { version: 1, authority: "invalid" };
|
|
57
|
+
}
|
|
58
|
+
const targetKeys = new Set();
|
|
59
|
+
const recipientSessions = [];
|
|
60
|
+
for (const value of routing.recipient_agent_sessions) {
|
|
61
|
+
if (!value || typeof value !== "object") {
|
|
62
|
+
return { version: 1, authority: "invalid" };
|
|
63
|
+
}
|
|
64
|
+
const agentKey = typeof value.agent_key === "string"
|
|
65
|
+
? normalizeRoutingSender(value.agent_key)
|
|
66
|
+
: "";
|
|
67
|
+
const agentSessionId = typeof value.agent_session_id === "string"
|
|
68
|
+
? value.agent_session_id.trim()
|
|
69
|
+
: "";
|
|
70
|
+
if (!agentKey || !agentSessionId || targetKeys.has(agentKey)) {
|
|
71
|
+
return { version: 1, authority: "invalid" };
|
|
72
|
+
}
|
|
73
|
+
targetKeys.add(agentKey);
|
|
74
|
+
if (routing.authority === "receipts") {
|
|
75
|
+
const successorAgentSessionId = value.successor_agent_session_id === undefined
|
|
76
|
+
? undefined
|
|
77
|
+
: typeof value.successor_agent_session_id === "string"
|
|
78
|
+
? value.successor_agent_session_id.trim()
|
|
79
|
+
: "";
|
|
80
|
+
if (successorAgentSessionId !== undefined && !successorAgentSessionId) {
|
|
81
|
+
return { version: 1, authority: "invalid" };
|
|
82
|
+
}
|
|
83
|
+
recipientSessions.push({
|
|
84
|
+
agentKey,
|
|
85
|
+
agentSessionId,
|
|
86
|
+
...(successorAgentSessionId ? { successorAgentSessionId } : {}),
|
|
87
|
+
});
|
|
88
|
+
} else {
|
|
89
|
+
const activationReason = typeof value.activation_reason === "string"
|
|
90
|
+
? value.activation_reason.trim()
|
|
91
|
+
: "";
|
|
92
|
+
if (!activationReason) return { version: 1, authority: "invalid" };
|
|
93
|
+
recipientSessions.push({ agentKey, agentSessionId, activationReason });
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
if (
|
|
97
|
+
targetKeys.size !== uniqueKeys.size
|
|
98
|
+
|| [...uniqueKeys].some((key) => !targetKeys.has(key))
|
|
99
|
+
) {
|
|
100
|
+
return { version: 1, authority: "invalid" };
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
version: 1,
|
|
104
|
+
authority: routing.authority,
|
|
105
|
+
recipientAgentKeys: [...uniqueKeys],
|
|
106
|
+
recipientSessions,
|
|
107
|
+
controlAuthorized: routing.control_authorized === true,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export type RoutingIdentityLike = {
|
|
2
|
+
actorLabel?: string | null;
|
|
3
|
+
actor_label?: string | null;
|
|
4
|
+
displayName?: string | null;
|
|
5
|
+
display_name?: string | null;
|
|
6
|
+
agentKey?: string | null;
|
|
7
|
+
agent_key?: string | null;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function normalizeRoutingSender(value: unknown): string;
|
|
11
|
+
export function normalizeRoutingHandle(value: unknown): string;
|
|
12
|
+
export function routingIdentityAliases(identity: RoutingIdentityLike): Set<string>;
|
|
13
|
+
export function routingSenderAliasRows(
|
|
14
|
+
sender: unknown,
|
|
15
|
+
segmentLimit?: number,
|
|
16
|
+
): Array<{ alias: string; isFull: boolean }>;
|
|
17
|
+
export function routingSenderAliases(sender: unknown, segmentLimit?: number): Set<string>;
|
|
18
|
+
export function routingAliasHash(alias: string): string;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Stable cross-engine fold: ASCII A-Z only. Unicode case conversion varies by
|
|
5
|
+
* JS/ICU/PostgreSQL version and locale, so non-ASCII aliases are deliberately
|
|
6
|
+
* case-sensitive while exact non-ASCII labels still match everywhere.
|
|
7
|
+
*/
|
|
8
|
+
function foldRoutingText(value) {
|
|
9
|
+
return String(value ?? "").replace(/[A-Z]/g, (character) =>
|
|
10
|
+
String.fromCharCode(character.charCodeAt(0) + 32));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export function normalizeRoutingSender(value) {
|
|
14
|
+
return foldRoutingText(typeof value === "string" ? value.trim() : "")
|
|
15
|
+
.replace(/\s+/g, " ");
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function normalizeRoutingHandle(value) {
|
|
19
|
+
return foldRoutingText(typeof value === "string" ? value.trim() : "")
|
|
20
|
+
.replace(/[^a-z0-9_.:/-]+/g, "");
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function routingIdentityAliasInputs(identity) {
|
|
24
|
+
const agentKey = typeof identity?.agentKey === "string"
|
|
25
|
+
? identity.agentKey
|
|
26
|
+
: typeof identity?.agent_key === "string"
|
|
27
|
+
? identity.agent_key
|
|
28
|
+
: "";
|
|
29
|
+
return Array.from(new Set([
|
|
30
|
+
identity?.actorLabel ?? identity?.actor_label,
|
|
31
|
+
identity?.displayName ?? identity?.display_name,
|
|
32
|
+
agentKey,
|
|
33
|
+
agentKey.split("/").pop(),
|
|
34
|
+
].map((value) => typeof value === "string" ? value.trim() : "").filter(Boolean)));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export function routingIdentityAliases(identity) {
|
|
38
|
+
const aliases = new Set();
|
|
39
|
+
for (const value of routingIdentityAliasInputs(identity)) {
|
|
40
|
+
const senderAlias = normalizeRoutingSender(value);
|
|
41
|
+
if (senderAlias) aliases.add(senderAlias);
|
|
42
|
+
const handleAlias = normalizeRoutingHandle(value);
|
|
43
|
+
if (handleAlias) aliases.add(handleAlias);
|
|
44
|
+
}
|
|
45
|
+
return aliases;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function routingSenderAliasRows(sender, segmentLimit = 16) {
|
|
49
|
+
const raw = typeof sender === "string" ? sender : "";
|
|
50
|
+
const fullAlias = normalizeRoutingSender(raw);
|
|
51
|
+
const byAlias = new Map();
|
|
52
|
+
if (fullAlias) byAlias.set(fullAlias, true);
|
|
53
|
+
for (const segment of raw.split("|").slice(0, Math.max(0, segmentLimit))) {
|
|
54
|
+
const alias = normalizeRoutingSender(segment);
|
|
55
|
+
if (alias && !byAlias.has(alias)) byAlias.set(alias, false);
|
|
56
|
+
}
|
|
57
|
+
return [...byAlias].map(([alias, isFull]) => ({ alias, isFull }));
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function routingSenderAliases(sender, segmentLimit = 16) {
|
|
61
|
+
return new Set(routingSenderAliasRows(sender, segmentLimit).map(({ alias }) => alias));
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
export function routingAliasHash(alias) {
|
|
65
|
+
return createHash("md5").update(alias).digest("hex");
|
|
66
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import type { RoutingIdentityLike } from "./routing-aliases.mjs";
|
|
2
|
+
|
|
3
|
+
export type SqliteRoutingDatabase = {
|
|
4
|
+
exec(sql: string): void;
|
|
5
|
+
prepare(sql: string): {
|
|
6
|
+
all(...params: unknown[]): Record<string, unknown>[];
|
|
7
|
+
get(...params: unknown[]): Record<string, unknown> | undefined;
|
|
8
|
+
run(...params: unknown[]): unknown;
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const LOCAL_THREAD_ROUTING_BACKFILL_BATCH_SIZE: number;
|
|
13
|
+
export const LOCAL_THREAD_ROUTING_LOOKUP_BATCH_SIZE: number;
|
|
14
|
+
export const LOCAL_THREAD_ROUTING_BACKFILL_TIME_BUDGET_MS: number;
|
|
15
|
+
export class LocalThreadRoutingProjectionUnavailableError extends Error {}
|
|
16
|
+
export function ensureLocalThreadRoutingProjectionSchema(database: SqliteRoutingDatabase): void;
|
|
17
|
+
export function ensureLocalThreadRoutingProjectionSchemaAsync(
|
|
18
|
+
database: SqliteRoutingDatabase,
|
|
19
|
+
options?: { maxWaitMs?: number; random?: () => number },
|
|
20
|
+
): Promise<void>;
|
|
21
|
+
export function runLocalSqliteWriteTransactionAsync<T>(
|
|
22
|
+
database: SqliteRoutingDatabase,
|
|
23
|
+
work: () => T,
|
|
24
|
+
options?: { maxWaitMs?: number; random?: () => number },
|
|
25
|
+
): Promise<T>;
|
|
26
|
+
export function projectLocalThreadRoutingMessage(
|
|
27
|
+
database: SqliteRoutingDatabase,
|
|
28
|
+
row: {
|
|
29
|
+
room_id: string;
|
|
30
|
+
number: number;
|
|
31
|
+
thread_root_number?: number | null;
|
|
32
|
+
reply_to_number?: number | null;
|
|
33
|
+
sender: string;
|
|
34
|
+
text?: string;
|
|
35
|
+
source?: string | null;
|
|
36
|
+
timestamp?: string;
|
|
37
|
+
[key: string]: unknown;
|
|
38
|
+
},
|
|
39
|
+
): void;
|
|
40
|
+
export function runLocalThreadRoutingBackfillBatch(
|
|
41
|
+
database: SqliteRoutingDatabase,
|
|
42
|
+
batchSize?: number,
|
|
43
|
+
): { processed: number; completed: boolean };
|
|
44
|
+
export function scheduleLocalThreadRoutingBackfill(
|
|
45
|
+
database: SqliteRoutingDatabase,
|
|
46
|
+
options?: {
|
|
47
|
+
onError?: (error: unknown, delayMs: number | null) => void;
|
|
48
|
+
setImmediate?: (callback: () => void) => { unref?(): void } | unknown;
|
|
49
|
+
setTimeout?: (callback: () => void, delayMs: number) => { unref?(): void } | unknown;
|
|
50
|
+
},
|
|
51
|
+
): void;
|
|
52
|
+
export function scheduleLocalThreadRoutingRootsRepair(
|
|
53
|
+
database: SqliteRoutingDatabase,
|
|
54
|
+
roomId: string,
|
|
55
|
+
rootNumbers: readonly number[],
|
|
56
|
+
): void;
|
|
57
|
+
export function invalidateLocalThreadRoutingRoots(
|
|
58
|
+
database: SqliteRoutingDatabase,
|
|
59
|
+
roomId: string,
|
|
60
|
+
rootNumbers: readonly number[],
|
|
61
|
+
): void;
|
|
62
|
+
export function getLocalThreadRoutingAgentKeysForRoots(
|
|
63
|
+
database: SqliteRoutingDatabase,
|
|
64
|
+
roomId: string,
|
|
65
|
+
rootNumbers: readonly number[],
|
|
66
|
+
identities: readonly RoutingIdentityLike[],
|
|
67
|
+
options?: {
|
|
68
|
+
foregroundTimeBudgetMs?: number;
|
|
69
|
+
scheduleOnTimeout?: boolean;
|
|
70
|
+
signal?: AbortSignal;
|
|
71
|
+
},
|
|
72
|
+
): Promise<Map<number, Set<string>>>;
|