exempclaw 0.4.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/LICENSE +21 -0
- package/README.md +306 -0
- package/dist/agent/agent.d.ts +91 -0
- package/dist/agent/agent.js +258 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/config.d.ts +49 -0
- package/dist/agent/config.js +58 -0
- package/dist/agent/config.js.map +1 -0
- package/dist/agent/persona.d.ts +39 -0
- package/dist/agent/persona.js +81 -0
- package/dist/agent/persona.js.map +1 -0
- package/dist/agents/registry.d.ts +21 -0
- package/dist/agents/registry.js +51 -0
- package/dist/agents/registry.js.map +1 -0
- package/dist/cli/approve.d.ts +17 -0
- package/dist/cli/approve.js +50 -0
- package/dist/cli/approve.js.map +1 -0
- package/dist/cli/chat.d.ts +16 -0
- package/dist/cli/chat.js +148 -0
- package/dist/cli/chat.js.map +1 -0
- package/dist/cli/demo.d.ts +7 -0
- package/dist/cli/demo.js +82 -0
- package/dist/cli/demo.js.map +1 -0
- package/dist/cli/init.d.ts +17 -0
- package/dist/cli/init.js +89 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/live.d.ts +10 -0
- package/dist/cli/live.js +109 -0
- package/dist/cli/live.js.map +1 -0
- package/dist/cli/offline.d.ts +23 -0
- package/dist/cli/offline.js +236 -0
- package/dist/cli/offline.js.map +1 -0
- package/dist/cli/probe.d.ts +23 -0
- package/dist/cli/probe.js +140 -0
- package/dist/cli/probe.js.map +1 -0
- package/dist/cli/render.d.ts +15 -0
- package/dist/cli/render.js +50 -0
- package/dist/cli/render.js.map +1 -0
- package/dist/cli/tui.d.ts +101 -0
- package/dist/cli/tui.js +334 -0
- package/dist/cli/tui.js.map +1 -0
- package/dist/config/index.d.ts +33 -0
- package/dist/config/index.js +48 -0
- package/dist/config/index.js.map +1 -0
- package/dist/connectors/connector.d.ts +58 -0
- package/dist/connectors/connector.js +30 -0
- package/dist/connectors/connector.js.map +1 -0
- package/dist/connectors/email/email-connector.d.ts +43 -0
- package/dist/connectors/email/email-connector.js +364 -0
- package/dist/connectors/email/email-connector.js.map +1 -0
- package/dist/connectors/github/github-connector.d.ts +52 -0
- package/dist/connectors/github/github-connector.js +271 -0
- package/dist/connectors/github/github-connector.js.map +1 -0
- package/dist/connectors/http.d.ts +34 -0
- package/dist/connectors/http.js +78 -0
- package/dist/connectors/http.js.map +1 -0
- package/dist/connectors/index.d.ts +34 -0
- package/dist/connectors/index.js +86 -0
- package/dist/connectors/index.js.map +1 -0
- package/dist/connectors/notion/notion-connector.d.ts +45 -0
- package/dist/connectors/notion/notion-connector.js +222 -0
- package/dist/connectors/notion/notion-connector.js.map +1 -0
- package/dist/connectors/slack/slack-connector.d.ts +43 -0
- package/dist/connectors/slack/slack-connector.js +291 -0
- package/dist/connectors/slack/slack-connector.js.map +1 -0
- package/dist/core/errors.d.ts +36 -0
- package/dist/core/errors.js +40 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/logger.d.ts +14 -0
- package/dist/core/logger.js +44 -0
- package/dist/core/logger.js.map +1 -0
- package/dist/core/run-log.d.ts +37 -0
- package/dist/core/run-log.js +37 -0
- package/dist/core/run-log.js.map +1 -0
- package/dist/core/usage.d.ts +22 -0
- package/dist/core/usage.js +58 -0
- package/dist/core/usage.js.map +1 -0
- package/dist/dashboard/data.d.ts +62 -0
- package/dist/dashboard/data.js +84 -0
- package/dist/dashboard/data.js.map +1 -0
- package/dist/dashboard/page.d.ts +9 -0
- package/dist/dashboard/page.js +421 -0
- package/dist/dashboard/page.js.map +1 -0
- package/dist/dashboard/server.d.ts +19 -0
- package/dist/dashboard/server.js +44 -0
- package/dist/dashboard/server.js.map +1 -0
- package/dist/demo/bootstrap.d.ts +25 -0
- package/dist/demo/bootstrap.js +60 -0
- package/dist/demo/bootstrap.js.map +1 -0
- package/dist/demo/claude.d.ts +31 -0
- package/dist/demo/claude.js +230 -0
- package/dist/demo/claude.js.map +1 -0
- package/dist/demo/demo-connector.d.ts +19 -0
- package/dist/demo/demo-connector.js +168 -0
- package/dist/demo/demo-connector.js.map +1 -0
- package/dist/demo/world.d.ts +60 -0
- package/dist/demo/world.js +117 -0
- package/dist/demo/world.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +396 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/ingest.d.ts +63 -0
- package/dist/ingest/ingest.js +258 -0
- package/dist/ingest/ingest.js.map +1 -0
- package/dist/llm/claude.d.ts +97 -0
- package/dist/llm/claude.js +163 -0
- package/dist/llm/claude.js.map +1 -0
- package/dist/memory/compaction.d.ts +22 -0
- package/dist/memory/compaction.js +79 -0
- package/dist/memory/compaction.js.map +1 -0
- package/dist/memory/file-store.d.ts +28 -0
- package/dist/memory/file-store.js +110 -0
- package/dist/memory/file-store.js.map +1 -0
- package/dist/memory/store.d.ts +32 -0
- package/dist/memory/store.js +2 -0
- package/dist/memory/store.js.map +1 -0
- package/dist/orchestrator/orchestrator.d.ts +63 -0
- package/dist/orchestrator/orchestrator.js +181 -0
- package/dist/orchestrator/orchestrator.js.map +1 -0
- package/dist/orchestrator/scheduler.d.ts +33 -0
- package/dist/orchestrator/scheduler.js +67 -0
- package/dist/orchestrator/scheduler.js.map +1 -0
- package/dist/orchestrator/seen-events.d.ts +21 -0
- package/dist/orchestrator/seen-events.js +71 -0
- package/dist/orchestrator/seen-events.js.map +1 -0
- package/dist/plugins/apply.d.ts +9 -0
- package/dist/plugins/apply.js +17 -0
- package/dist/plugins/apply.js.map +1 -0
- package/dist/plugins/define.d.ts +29 -0
- package/dist/plugins/define.js +30 -0
- package/dist/plugins/define.js.map +1 -0
- package/dist/plugins/loader.d.ts +31 -0
- package/dist/plugins/loader.js +61 -0
- package/dist/plugins/loader.js.map +1 -0
- package/dist/plugins/scaffold.d.ts +5 -0
- package/dist/plugins/scaffold.js +72 -0
- package/dist/plugins/scaffold.js.map +1 -0
- package/dist/tools/builtin.d.ts +8 -0
- package/dist/tools/builtin.js +63 -0
- package/dist/tools/builtin.js.map +1 -0
- package/dist/tools/tool.d.ts +84 -0
- package/dist/tools/tool.js +70 -0
- package/dist/tools/tool.js.map +1 -0
- package/dist/ui/agent-view.test.d.ts +1 -0
- package/dist/ui/agent-view.test.js +54 -0
- package/dist/ui/agent-view.test.js.map +1 -0
- package/dist/ui/agents-data.d.ts +7 -0
- package/dist/ui/agents-data.js +25 -0
- package/dist/ui/agents-data.js.map +1 -0
- package/dist/ui/app.d.ts +24 -0
- package/dist/ui/app.js +59 -0
- package/dist/ui/app.js.map +1 -0
- package/dist/ui/app.test.d.ts +1 -0
- package/dist/ui/app.test.js +47 -0
- package/dist/ui/app.test.js.map +1 -0
- package/dist/ui/components/key-hints.d.ts +4 -0
- package/dist/ui/components/key-hints.js +6 -0
- package/dist/ui/components/key-hints.js.map +1 -0
- package/dist/ui/components/menu.d.ts +11 -0
- package/dist/ui/components/menu.js +20 -0
- package/dist/ui/components/menu.js.map +1 -0
- package/dist/ui/create-wizard.test.d.ts +1 -0
- package/dist/ui/create-wizard.test.js +58 -0
- package/dist/ui/create-wizard.test.js.map +1 -0
- package/dist/ui/doctor-data.d.ts +6 -0
- package/dist/ui/doctor-data.js +29 -0
- package/dist/ui/doctor-data.js.map +1 -0
- package/dist/ui/history-data.d.ts +2 -0
- package/dist/ui/history-data.js +18 -0
- package/dist/ui/history-data.js.map +1 -0
- package/dist/ui/screens/agent.d.ts +8 -0
- package/dist/ui/screens/agent.js +95 -0
- package/dist/ui/screens/agent.js.map +1 -0
- package/dist/ui/screens/agents.d.ts +7 -0
- package/dist/ui/screens/agents.js +47 -0
- package/dist/ui/screens/agents.js.map +1 -0
- package/dist/ui/screens/create.d.ts +7 -0
- package/dist/ui/screens/create.js +141 -0
- package/dist/ui/screens/create.js.map +1 -0
- package/dist/ui/screens/doctor.d.ts +5 -0
- package/dist/ui/screens/doctor.js +13 -0
- package/dist/ui/screens/doctor.js.map +1 -0
- package/dist/ui/screens/history.d.ts +7 -0
- package/dist/ui/screens/history.js +50 -0
- package/dist/ui/screens/history.js.map +1 -0
- package/dist/ui/screens/home.d.ts +8 -0
- package/dist/ui/screens/home.js +35 -0
- package/dist/ui/screens/home.js.map +1 -0
- package/dist/ui/screens/plugins.d.ts +7 -0
- package/dist/ui/screens/plugins.js +40 -0
- package/dist/ui/screens/plugins.js.map +1 -0
- package/dist/ui/services.d.ts +33 -0
- package/dist/ui/services.js +67 -0
- package/dist/ui/services.js.map +1 -0
- package/dist/ui/start.d.ts +1 -0
- package/dist/ui/start.js +16 -0
- package/dist/ui/start.js.map +1 -0
- package/dist/ui/theme.d.ts +6 -0
- package/dist/ui/theme.js +26 -0
- package/dist/ui/theme.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { HttpJson } from "../http.js";
|
|
3
|
+
import { ConnectorError } from "../../core/errors.js";
|
|
4
|
+
import { defineTool } from "../../tools/tool.js";
|
|
5
|
+
/**
|
|
6
|
+
* Notion connector over the REST API (internal-integration token). Read tools
|
|
7
|
+
* cover search and page content; write tools append to or create pages.
|
|
8
|
+
* Notion has no push channel for internal integrations, so this connector
|
|
9
|
+
* contributes no inbound events.
|
|
10
|
+
*
|
|
11
|
+
* Share the relevant pages/databases with the integration in Notion, or the
|
|
12
|
+
* API will return empty results.
|
|
13
|
+
*/
|
|
14
|
+
const NOTION_VERSION = "2022-06-28";
|
|
15
|
+
export class NotionConnector {
|
|
16
|
+
fetchImpl;
|
|
17
|
+
id = "notion";
|
|
18
|
+
log;
|
|
19
|
+
api;
|
|
20
|
+
constructor(fetchImpl) {
|
|
21
|
+
this.fetchImpl = fetchImpl;
|
|
22
|
+
}
|
|
23
|
+
async init(ctx) {
|
|
24
|
+
this.log = ctx.log.child({ scope: "connector", connector: this.id });
|
|
25
|
+
const token = ctx.config.token;
|
|
26
|
+
if (!token) {
|
|
27
|
+
throw new ConnectorError(this.id, "missing NOTION_TOKEN (internal integration secret, ntn_… or secret_…)");
|
|
28
|
+
}
|
|
29
|
+
this.api = new HttpJson({
|
|
30
|
+
connector: this.id,
|
|
31
|
+
baseUrl: "https://api.notion.com/v1",
|
|
32
|
+
headers: { authorization: `Bearer ${token}`, "notion-version": NOTION_VERSION },
|
|
33
|
+
fetchImpl: this.fetchImpl,
|
|
34
|
+
});
|
|
35
|
+
this.log.info("notion connector ready");
|
|
36
|
+
}
|
|
37
|
+
tools() {
|
|
38
|
+
const search = defineTool({
|
|
39
|
+
name: "notion_search",
|
|
40
|
+
description: "Search Notion pages and databases the integration can access.",
|
|
41
|
+
schema: z.object({
|
|
42
|
+
query: z.string(),
|
|
43
|
+
limit: z.number().int().min(1).max(50).default(10),
|
|
44
|
+
}),
|
|
45
|
+
execute: async (input, ctx) => {
|
|
46
|
+
const res = await this.api.post("/search", {
|
|
47
|
+
body: { query: input.query, page_size: input.limit },
|
|
48
|
+
signal: ctx.signal,
|
|
49
|
+
});
|
|
50
|
+
if (res.results.length === 0)
|
|
51
|
+
return { content: `No Notion results for "${input.query}".` };
|
|
52
|
+
return {
|
|
53
|
+
content: res.results
|
|
54
|
+
.map((r) => `${r.object} ${r.id} "${resultTitle(r)}" (edited ${r.last_edited_time ?? "?"})`)
|
|
55
|
+
.join("\n"),
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
});
|
|
59
|
+
const getPage = defineTool({
|
|
60
|
+
name: "notion_get_page",
|
|
61
|
+
description: "Fetch a Notion page's title and content as plain text. Accepts a page id or URL.",
|
|
62
|
+
schema: z.object({ pageId: z.string() }),
|
|
63
|
+
execute: async (input, ctx) => {
|
|
64
|
+
const pageId = normalizePageId(input.pageId);
|
|
65
|
+
if (!pageId)
|
|
66
|
+
return { content: `"${input.pageId}" is not a Notion page id or URL.`, isError: true };
|
|
67
|
+
const page = await this.api.get(`/pages/${pageId}`, { signal: ctx.signal });
|
|
68
|
+
const lines = [];
|
|
69
|
+
let cursor;
|
|
70
|
+
for (let i = 0; i < 3; i++) {
|
|
71
|
+
const res = await this.api.get(`/blocks/${pageId}/children`, { query: { page_size: 100, ...(cursor ? { start_cursor: cursor } : {}) }, signal: ctx.signal });
|
|
72
|
+
for (const block of res.results)
|
|
73
|
+
lines.push(renderBlock(block));
|
|
74
|
+
if (!res.has_more || !res.next_cursor)
|
|
75
|
+
break;
|
|
76
|
+
cursor = res.next_cursor;
|
|
77
|
+
}
|
|
78
|
+
return {
|
|
79
|
+
content: [`# ${resultTitle(page)}`, page.url ?? "", "", ...lines.filter(Boolean)].join("\n"),
|
|
80
|
+
};
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
const appendBlock = defineTool({
|
|
84
|
+
name: "notion_append_block",
|
|
85
|
+
description: "Append markdown content to the end of a Notion page. Supports paragraphs, #/##/### headings, - bullets, 1. numbered lists, and > quotes. Acts outward; requires approval.",
|
|
86
|
+
outward: true,
|
|
87
|
+
schema: z.object({ pageId: z.string(), markdown: z.string().min(1) }),
|
|
88
|
+
execute: async (input, ctx) => {
|
|
89
|
+
const pageId = normalizePageId(input.pageId);
|
|
90
|
+
if (!pageId)
|
|
91
|
+
return { content: `"${input.pageId}" is not a Notion page id or URL.`, isError: true };
|
|
92
|
+
const children = markdownToBlocks(input.markdown);
|
|
93
|
+
await this.api.patch(`/blocks/${pageId}/children`, { body: { children }, signal: ctx.signal });
|
|
94
|
+
return { content: `Appended ${children.length} block(s) to page ${pageId}.` };
|
|
95
|
+
},
|
|
96
|
+
});
|
|
97
|
+
const createPage = defineTool({
|
|
98
|
+
name: "notion_create_page",
|
|
99
|
+
description: "Create a new Notion page under a parent page. Acts outward; requires approval.",
|
|
100
|
+
outward: true,
|
|
101
|
+
schema: z.object({
|
|
102
|
+
parentPageId: z.string(),
|
|
103
|
+
title: z.string().min(1),
|
|
104
|
+
markdown: z.string().default(""),
|
|
105
|
+
}),
|
|
106
|
+
execute: async (input, ctx) => {
|
|
107
|
+
const parent = normalizePageId(input.parentPageId);
|
|
108
|
+
if (!parent)
|
|
109
|
+
return { content: `"${input.parentPageId}" is not a Notion page id or URL.`, isError: true };
|
|
110
|
+
const res = await this.api.post("/pages", {
|
|
111
|
+
body: {
|
|
112
|
+
parent: { page_id: parent },
|
|
113
|
+
properties: { title: { title: [{ type: "text", text: { content: input.title } }] } },
|
|
114
|
+
...(input.markdown ? { children: markdownToBlocks(input.markdown) } : {}),
|
|
115
|
+
},
|
|
116
|
+
signal: ctx.signal,
|
|
117
|
+
});
|
|
118
|
+
return { content: `Created page ${res.id}${res.url ? ` (${res.url})` : ""}.` };
|
|
119
|
+
},
|
|
120
|
+
});
|
|
121
|
+
return [search, getPage, appendBlock, createPage];
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/** Accepts dashed/undashed UUIDs or a Notion URL; returns a dashed UUID. */
|
|
125
|
+
export function normalizePageId(input) {
|
|
126
|
+
const match = /([0-9a-f]{8})-?([0-9a-f]{4})-?([0-9a-f]{4})-?([0-9a-f]{4})-?([0-9a-f]{12})/i.exec(input.trim());
|
|
127
|
+
if (!match)
|
|
128
|
+
return null;
|
|
129
|
+
return [match[1], match[2], match[3], match[4], match[5]].join("-").toLowerCase();
|
|
130
|
+
}
|
|
131
|
+
export function resultTitle(result) {
|
|
132
|
+
if (result.title?.length)
|
|
133
|
+
return joinRichText(result.title);
|
|
134
|
+
for (const prop of Object.values(result.properties ?? {})) {
|
|
135
|
+
if (prop.type === "title" && prop.title)
|
|
136
|
+
return joinRichText(prop.title);
|
|
137
|
+
}
|
|
138
|
+
return "(untitled)";
|
|
139
|
+
}
|
|
140
|
+
function joinRichText(rich) {
|
|
141
|
+
return rich.map((r) => r.plain_text ?? "").join("") || "(untitled)";
|
|
142
|
+
}
|
|
143
|
+
/** Renders one block to a plain-text line. Unknown types become markers. */
|
|
144
|
+
export function renderBlock(block) {
|
|
145
|
+
const data = block[block.type];
|
|
146
|
+
const text = data?.rich_text ? joinRichTextLoose(data.rich_text) : "";
|
|
147
|
+
switch (block.type) {
|
|
148
|
+
case "paragraph":
|
|
149
|
+
return text;
|
|
150
|
+
case "heading_1":
|
|
151
|
+
return `# ${text}`;
|
|
152
|
+
case "heading_2":
|
|
153
|
+
return `## ${text}`;
|
|
154
|
+
case "heading_3":
|
|
155
|
+
return `### ${text}`;
|
|
156
|
+
case "bulleted_list_item":
|
|
157
|
+
return `- ${text}`;
|
|
158
|
+
case "numbered_list_item":
|
|
159
|
+
return `1. ${text}`;
|
|
160
|
+
case "to_do":
|
|
161
|
+
return `- [${data?.checked ? "x" : " "}] ${text}`;
|
|
162
|
+
case "quote":
|
|
163
|
+
return `> ${text}`;
|
|
164
|
+
case "code":
|
|
165
|
+
return `\`\`\`\n${text}\n\`\`\``;
|
|
166
|
+
case "callout":
|
|
167
|
+
case "toggle":
|
|
168
|
+
return text;
|
|
169
|
+
case "child_page":
|
|
170
|
+
return `[subpage: ${data?.title ?? block.id}]`;
|
|
171
|
+
case "divider":
|
|
172
|
+
return "---";
|
|
173
|
+
default:
|
|
174
|
+
return text ? text : `[${block.type}]`;
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
function joinRichTextLoose(rich) {
|
|
178
|
+
return rich.map((r) => r.plain_text ?? "").join("");
|
|
179
|
+
}
|
|
180
|
+
/** Converts simple markdown into Notion block objects. */
|
|
181
|
+
export function markdownToBlocks(markdown) {
|
|
182
|
+
const blocks = [];
|
|
183
|
+
for (const rawLine of markdown.split("\n")) {
|
|
184
|
+
const line = rawLine.trimEnd();
|
|
185
|
+
if (!line.trim())
|
|
186
|
+
continue;
|
|
187
|
+
if (line.startsWith("### "))
|
|
188
|
+
blocks.push(textBlock("heading_3", line.slice(4)));
|
|
189
|
+
else if (line.startsWith("## "))
|
|
190
|
+
blocks.push(textBlock("heading_2", line.slice(3)));
|
|
191
|
+
else if (line.startsWith("# "))
|
|
192
|
+
blocks.push(textBlock("heading_1", line.slice(2)));
|
|
193
|
+
else if (line.startsWith("- ") || line.startsWith("* "))
|
|
194
|
+
blocks.push(textBlock("bulleted_list_item", line.slice(2)));
|
|
195
|
+
else if (/^\d+\.\s/.test(line))
|
|
196
|
+
blocks.push(textBlock("numbered_list_item", line.replace(/^\d+\.\s/, "")));
|
|
197
|
+
else if (line.startsWith("> "))
|
|
198
|
+
blocks.push(textBlock("quote", line.slice(2)));
|
|
199
|
+
else
|
|
200
|
+
blocks.push(textBlock("paragraph", line));
|
|
201
|
+
}
|
|
202
|
+
return blocks;
|
|
203
|
+
}
|
|
204
|
+
function textBlock(type, content) {
|
|
205
|
+
return {
|
|
206
|
+
object: "block",
|
|
207
|
+
type,
|
|
208
|
+
[type]: {
|
|
209
|
+
// Notion caps a single rich_text item at 2000 chars.
|
|
210
|
+
rich_text: chunkString(content, 2000).map((part) => ({ type: "text", text: { content: part } })),
|
|
211
|
+
},
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
function chunkString(text, size) {
|
|
215
|
+
if (text.length <= size)
|
|
216
|
+
return [text];
|
|
217
|
+
const parts = [];
|
|
218
|
+
for (let i = 0; i < text.length; i += size)
|
|
219
|
+
parts.push(text.slice(i, i + size));
|
|
220
|
+
return parts;
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=notion-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"notion-connector.js","sourceRoot":"","sources":["../../../src/connectors/notion/notion-connector.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { type Connector, type ConnectorContext, type InboundEvent } from "../connector.js";
|
|
2
|
+
import { type FetchLike } from "../http.js";
|
|
3
|
+
import { type Tool } from "../../tools/tool.js";
|
|
4
|
+
export declare class SlackConnector implements Connector {
|
|
5
|
+
private readonly fetchImpl?;
|
|
6
|
+
readonly id = "slack";
|
|
7
|
+
private log;
|
|
8
|
+
private api;
|
|
9
|
+
private appToken?;
|
|
10
|
+
private selfUserId;
|
|
11
|
+
private readonly channelIds;
|
|
12
|
+
private readonly userNames;
|
|
13
|
+
constructor(fetchImpl?: FetchLike | undefined);
|
|
14
|
+
init(ctx: ConnectorContext): Promise<void>;
|
|
15
|
+
/** Calls a Web API method, unwrapping Slack's {ok, error} envelope. */
|
|
16
|
+
private call;
|
|
17
|
+
/** Resolves "#name" or a bare name to a channel id; passes ids through. */
|
|
18
|
+
private resolveChannel;
|
|
19
|
+
private userName;
|
|
20
|
+
private renderMessages;
|
|
21
|
+
tools(): Tool[];
|
|
22
|
+
/** Socket Mode loop: connect, ack envelopes, surface mentions and DMs. */
|
|
23
|
+
listen(onEvent: (event: InboundEvent) => void, signal: AbortSignal): Promise<void>;
|
|
24
|
+
/** One WebSocket session. Resolves when the socket closes or signal aborts. */
|
|
25
|
+
private runSocket;
|
|
26
|
+
}
|
|
27
|
+
/** Shapes of the Socket Mode frames we care about. */
|
|
28
|
+
export type SocketMessage = {
|
|
29
|
+
kind: "hello";
|
|
30
|
+
} | {
|
|
31
|
+
kind: "disconnect";
|
|
32
|
+
reason?: string;
|
|
33
|
+
} | {
|
|
34
|
+
kind: "event";
|
|
35
|
+
envelopeId: string;
|
|
36
|
+
eventId: string;
|
|
37
|
+
event: Record<string, unknown>;
|
|
38
|
+
} | {
|
|
39
|
+
kind: "other";
|
|
40
|
+
};
|
|
41
|
+
export declare function parseSocketMessage(raw: string): SocketMessage;
|
|
42
|
+
/** Maps a Slack event payload to an InboundEvent (or null if irrelevant). */
|
|
43
|
+
export declare function slackEventToInbound(eventId: string, event: Record<string, unknown>, selfUserId: string): InboundEvent | null;
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { sleep } from "../connector.js";
|
|
3
|
+
import { HttpJson } from "../http.js";
|
|
4
|
+
import { ConnectorError } from "../../core/errors.js";
|
|
5
|
+
import { defineTool } from "../../tools/tool.js";
|
|
6
|
+
export class SlackConnector {
|
|
7
|
+
fetchImpl;
|
|
8
|
+
id = "slack";
|
|
9
|
+
log;
|
|
10
|
+
api;
|
|
11
|
+
appToken;
|
|
12
|
+
selfUserId = "";
|
|
13
|
+
channelIds = new Map();
|
|
14
|
+
userNames = new Map();
|
|
15
|
+
constructor(fetchImpl) {
|
|
16
|
+
this.fetchImpl = fetchImpl;
|
|
17
|
+
}
|
|
18
|
+
async init(ctx) {
|
|
19
|
+
this.log = ctx.log.child({ scope: "connector", connector: this.id });
|
|
20
|
+
const botToken = ctx.config.botToken;
|
|
21
|
+
if (!botToken) {
|
|
22
|
+
throw new ConnectorError(this.id, "missing SLACK_BOT_TOKEN (bot token, xoxb-…)");
|
|
23
|
+
}
|
|
24
|
+
this.appToken = ctx.config.appToken;
|
|
25
|
+
this.api = new HttpJson({
|
|
26
|
+
connector: this.id,
|
|
27
|
+
baseUrl: "https://slack.com/api",
|
|
28
|
+
headers: { authorization: `Bearer ${botToken}` },
|
|
29
|
+
fetchImpl: this.fetchImpl,
|
|
30
|
+
});
|
|
31
|
+
const auth = await this.call("auth.test", {});
|
|
32
|
+
this.selfUserId = auth.user_id;
|
|
33
|
+
this.log.info("slack connected", { team: auth.team, botUser: auth.user });
|
|
34
|
+
}
|
|
35
|
+
/** Calls a Web API method, unwrapping Slack's {ok, error} envelope. */
|
|
36
|
+
async call(method, args, signal) {
|
|
37
|
+
// Write methods accept JSON; read methods take query params. Slack allows
|
|
38
|
+
// GET with query for all the read methods used here.
|
|
39
|
+
const isWrite = method.startsWith("chat.") || method === "auth.test";
|
|
40
|
+
const response = isWrite
|
|
41
|
+
? await this.api.post(`/${method}`, { body: args, signal })
|
|
42
|
+
: await this.api.get(`/${method}`, {
|
|
43
|
+
query: args,
|
|
44
|
+
signal,
|
|
45
|
+
});
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new ConnectorError(this.id, `${method} failed: ${response.error ?? "unknown_error"}`, {
|
|
48
|
+
retryable: response.error === "ratelimited",
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return response;
|
|
52
|
+
}
|
|
53
|
+
/** Resolves "#name" or a bare name to a channel id; passes ids through. */
|
|
54
|
+
async resolveChannel(channel, signal) {
|
|
55
|
+
const trimmed = channel.trim();
|
|
56
|
+
if (/^[CGD][A-Z0-9]{6,}$/.test(trimmed))
|
|
57
|
+
return trimmed;
|
|
58
|
+
const name = trimmed.replace(/^#/, "").toLowerCase();
|
|
59
|
+
const cached = this.channelIds.get(name);
|
|
60
|
+
if (cached)
|
|
61
|
+
return cached;
|
|
62
|
+
let cursor;
|
|
63
|
+
for (let page = 0; page < 5; page++) {
|
|
64
|
+
const res = await this.call("conversations.list", { types: "public_channel,private_channel", limit: 200, exclude_archived: true, cursor }, signal);
|
|
65
|
+
for (const ch of res.channels) {
|
|
66
|
+
if (ch.name)
|
|
67
|
+
this.channelIds.set(ch.name.toLowerCase(), ch.id);
|
|
68
|
+
}
|
|
69
|
+
const hit = this.channelIds.get(name);
|
|
70
|
+
if (hit)
|
|
71
|
+
return hit;
|
|
72
|
+
cursor = res.response_metadata?.next_cursor || undefined;
|
|
73
|
+
if (!cursor)
|
|
74
|
+
break;
|
|
75
|
+
}
|
|
76
|
+
throw new ConnectorError(this.id, `channel not found: ${channel}`);
|
|
77
|
+
}
|
|
78
|
+
async userName(userId, signal) {
|
|
79
|
+
const cached = this.userNames.get(userId);
|
|
80
|
+
if (cached)
|
|
81
|
+
return cached;
|
|
82
|
+
try {
|
|
83
|
+
const res = await this.call("users.info", { user: userId }, signal);
|
|
84
|
+
const name = res.user.profile?.display_name || res.user.profile?.real_name || res.user.name;
|
|
85
|
+
this.userNames.set(userId, name);
|
|
86
|
+
return name;
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return userId; // name resolution is best-effort
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
async renderMessages(messages, signal) {
|
|
93
|
+
const lines = [];
|
|
94
|
+
for (const msg of messages) {
|
|
95
|
+
const who = msg.bot_id ? `bot:${msg.bot_id}` : msg.user ? await this.userName(msg.user, signal) : "unknown";
|
|
96
|
+
const threadMark = msg.reply_count ? ` [thread with ${msg.reply_count} replies, thread_ts=${msg.ts}]` : "";
|
|
97
|
+
lines.push(`[ts=${msg.ts}] ${who}: ${msg.text ?? ""}${threadMark}`);
|
|
98
|
+
}
|
|
99
|
+
return lines.join("\n");
|
|
100
|
+
}
|
|
101
|
+
tools() {
|
|
102
|
+
const listChannels = defineTool({
|
|
103
|
+
name: "slack_list_channels",
|
|
104
|
+
description: "List Slack channels the agent can see (id and name).",
|
|
105
|
+
schema: z.object({ limit: z.number().int().min(1).max(200).default(50) }),
|
|
106
|
+
execute: async (input, ctx) => {
|
|
107
|
+
const res = await this.call("conversations.list", { types: "public_channel,private_channel", limit: input.limit, exclude_archived: true }, ctx.signal);
|
|
108
|
+
if (res.channels.length === 0)
|
|
109
|
+
return { content: "No channels visible." };
|
|
110
|
+
return {
|
|
111
|
+
content: res.channels
|
|
112
|
+
.map((c) => `${c.id} #${c.name ?? "?"}${c.is_member ? " (member)" : ""}`)
|
|
113
|
+
.join("\n"),
|
|
114
|
+
};
|
|
115
|
+
},
|
|
116
|
+
});
|
|
117
|
+
const readChannel = defineTool({
|
|
118
|
+
name: "slack_read_channel",
|
|
119
|
+
description: "Read recent messages from a Slack channel (newest last). Accepts a channel id or #name.",
|
|
120
|
+
schema: z.object({
|
|
121
|
+
channel: z.string(),
|
|
122
|
+
limit: z.number().int().min(1).max(100).default(20),
|
|
123
|
+
}),
|
|
124
|
+
execute: async (input, ctx) => {
|
|
125
|
+
const channel = await this.resolveChannel(input.channel, ctx.signal);
|
|
126
|
+
const res = await this.call("conversations.history", { channel, limit: input.limit }, ctx.signal);
|
|
127
|
+
if (res.messages.length === 0)
|
|
128
|
+
return { content: "No messages." };
|
|
129
|
+
const rendered = await this.renderMessages(res.messages.slice().reverse(), ctx.signal);
|
|
130
|
+
return { content: `channel=${channel}\n${rendered}` };
|
|
131
|
+
},
|
|
132
|
+
});
|
|
133
|
+
const readThread = defineTool({
|
|
134
|
+
name: "slack_read_thread",
|
|
135
|
+
description: "Read a Slack thread by its channel and root thread_ts (newest last).",
|
|
136
|
+
schema: z.object({
|
|
137
|
+
channel: z.string(),
|
|
138
|
+
threadTs: z.string().describe("The thread_ts of the root message."),
|
|
139
|
+
limit: z.number().int().min(1).max(100).default(50),
|
|
140
|
+
}),
|
|
141
|
+
execute: async (input, ctx) => {
|
|
142
|
+
const channel = await this.resolveChannel(input.channel, ctx.signal);
|
|
143
|
+
const res = await this.call("conversations.replies", { channel, ts: input.threadTs, limit: input.limit }, ctx.signal);
|
|
144
|
+
const rendered = await this.renderMessages(res.messages, ctx.signal);
|
|
145
|
+
return { content: `channel=${channel} thread_ts=${input.threadTs}\n${rendered}` };
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
const postMessage = defineTool({
|
|
149
|
+
name: "slack_post_message",
|
|
150
|
+
description: "Post a message to a Slack channel, or reply in a thread by passing threadTs. Acts outward; requires approval.",
|
|
151
|
+
outward: true,
|
|
152
|
+
schema: z.object({
|
|
153
|
+
channel: z.string().describe("Channel id or #name."),
|
|
154
|
+
text: z.string().min(1),
|
|
155
|
+
threadTs: z.string().optional().describe("thread_ts of the root message to reply under."),
|
|
156
|
+
}),
|
|
157
|
+
execute: async (input, ctx) => {
|
|
158
|
+
const channel = await this.resolveChannel(input.channel, ctx.signal);
|
|
159
|
+
const res = await this.call("chat.postMessage", {
|
|
160
|
+
channel,
|
|
161
|
+
text: input.text,
|
|
162
|
+
...(input.threadTs ? { thread_ts: input.threadTs } : {}),
|
|
163
|
+
}, ctx.signal);
|
|
164
|
+
return { content: `Posted to ${res.channel} at ts=${res.ts}.` };
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
return [listChannels, readChannel, readThread, postMessage];
|
|
168
|
+
}
|
|
169
|
+
/** Socket Mode loop: connect, ack envelopes, surface mentions and DMs. */
|
|
170
|
+
async listen(onEvent, signal) {
|
|
171
|
+
if (!this.appToken) {
|
|
172
|
+
this.log.warn("SLACK_APP_TOKEN not set — slack inbound events disabled (tools still work)");
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
const appApi = new HttpJson({
|
|
176
|
+
connector: this.id,
|
|
177
|
+
baseUrl: "https://slack.com/api",
|
|
178
|
+
headers: { authorization: `Bearer ${this.appToken}` },
|
|
179
|
+
fetchImpl: this.fetchImpl,
|
|
180
|
+
});
|
|
181
|
+
let backoffMs = 1000;
|
|
182
|
+
while (!signal.aborted) {
|
|
183
|
+
try {
|
|
184
|
+
const open = await appApi.post("/apps.connections.open", {
|
|
185
|
+
signal,
|
|
186
|
+
});
|
|
187
|
+
if (!open.ok || !open.url) {
|
|
188
|
+
throw new ConnectorError(this.id, `apps.connections.open failed: ${open.error ?? "unknown_error"}`);
|
|
189
|
+
}
|
|
190
|
+
this.log.info("slack socket connecting");
|
|
191
|
+
await this.runSocket(open.url, onEvent, signal);
|
|
192
|
+
backoffMs = 1000; // clean cycle — reset backoff
|
|
193
|
+
}
|
|
194
|
+
catch (err) {
|
|
195
|
+
if (signal.aborted)
|
|
196
|
+
break;
|
|
197
|
+
this.log.warn("slack socket error; reconnecting", { error: err.message });
|
|
198
|
+
await sleep(backoffMs, signal);
|
|
199
|
+
backoffMs = Math.min(backoffMs * 2, 30_000);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/** One WebSocket session. Resolves when the socket closes or signal aborts. */
|
|
204
|
+
runSocket(url, onEvent, signal) {
|
|
205
|
+
return new Promise((resolve, reject) => {
|
|
206
|
+
const ws = new WebSocket(url);
|
|
207
|
+
const close = () => ws.close();
|
|
208
|
+
signal.addEventListener("abort", close, { once: true });
|
|
209
|
+
const finish = (err) => {
|
|
210
|
+
signal.removeEventListener("abort", close);
|
|
211
|
+
if (err)
|
|
212
|
+
reject(err);
|
|
213
|
+
else
|
|
214
|
+
resolve();
|
|
215
|
+
};
|
|
216
|
+
ws.addEventListener("error", () => finish(new Error("websocket error")));
|
|
217
|
+
ws.addEventListener("close", () => finish());
|
|
218
|
+
ws.addEventListener("message", (msg) => {
|
|
219
|
+
const parsed = parseSocketMessage(String(msg.data));
|
|
220
|
+
if (parsed.kind === "disconnect") {
|
|
221
|
+
this.log.debug("slack socket disconnect requested", { reason: parsed.reason });
|
|
222
|
+
ws.close();
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
if (parsed.kind !== "event")
|
|
226
|
+
return;
|
|
227
|
+
// Ack immediately — Slack retries unacked envelopes.
|
|
228
|
+
ws.send(JSON.stringify({ envelope_id: parsed.envelopeId }));
|
|
229
|
+
const event = slackEventToInbound(parsed.eventId, parsed.event, this.selfUserId);
|
|
230
|
+
if (event)
|
|
231
|
+
onEvent(event);
|
|
232
|
+
});
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
export function parseSocketMessage(raw) {
|
|
237
|
+
let data;
|
|
238
|
+
try {
|
|
239
|
+
data = JSON.parse(raw);
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
return { kind: "other" };
|
|
243
|
+
}
|
|
244
|
+
if (data.type === "hello")
|
|
245
|
+
return { kind: "hello" };
|
|
246
|
+
if (data.type === "disconnect")
|
|
247
|
+
return { kind: "disconnect", reason: String(data.reason ?? "") };
|
|
248
|
+
if (data.type === "events_api" && typeof data.envelope_id === "string") {
|
|
249
|
+
const payload = (data.payload ?? {});
|
|
250
|
+
const event = (payload.event ?? {});
|
|
251
|
+
return {
|
|
252
|
+
kind: "event",
|
|
253
|
+
envelopeId: data.envelope_id,
|
|
254
|
+
eventId: String(payload.event_id ?? data.envelope_id),
|
|
255
|
+
event,
|
|
256
|
+
};
|
|
257
|
+
}
|
|
258
|
+
return { kind: "other" };
|
|
259
|
+
}
|
|
260
|
+
/** Maps a Slack event payload to an InboundEvent (or null if irrelevant). */
|
|
261
|
+
export function slackEventToInbound(eventId, event, selfUserId) {
|
|
262
|
+
const type = String(event.type ?? "");
|
|
263
|
+
const user = typeof event.user === "string" ? event.user : "";
|
|
264
|
+
if (event.bot_id || user === selfUserId || !user)
|
|
265
|
+
return null;
|
|
266
|
+
if (event.subtype)
|
|
267
|
+
return null; // edits, joins, etc.
|
|
268
|
+
const channel = String(event.channel ?? "");
|
|
269
|
+
const ts = String(event.ts ?? event.event_ts ?? "");
|
|
270
|
+
const threadTs = typeof event.thread_ts === "string" ? event.thread_ts : ts;
|
|
271
|
+
const text = String(event.text ?? "");
|
|
272
|
+
const isMention = type === "app_mention";
|
|
273
|
+
const isDm = type === "message" && event.channel_type === "im";
|
|
274
|
+
if (!isMention && !isDm)
|
|
275
|
+
return null;
|
|
276
|
+
return {
|
|
277
|
+
connector: "slack",
|
|
278
|
+
type: isMention ? "slack.mention" : "slack.dm",
|
|
279
|
+
eventId,
|
|
280
|
+
threadId: `${channel}:${threadTs}`,
|
|
281
|
+
summary: [
|
|
282
|
+
`${isMention ? "Mention" : "Direct message"} from user ${user} in channel ${channel} (ts=${ts}, thread_ts=${threadTs}).`,
|
|
283
|
+
`Reply with slack_post_message using channel="${channel}" and threadTs="${threadTs}".`,
|
|
284
|
+
"",
|
|
285
|
+
text,
|
|
286
|
+
].join("\n"),
|
|
287
|
+
payload: event,
|
|
288
|
+
receivedAt: new Date().toISOString(),
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
//# sourceMappingURL=slack-connector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slack-connector.js","sourceRoot":"","sources":["../../../src/connectors/slack/slack-connector.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,KAAK,EAA4D,MAAM,iBAAiB,CAAC;AAClG,OAAO,EAAE,QAAQ,EAAkB,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAa,MAAM,qBAAqB,CAAC;AA+B5D,MAAM,OAAO,cAAc;IASI;IARpB,EAAE,GAAG,OAAO,CAAC;IACd,GAAG,CAAU;IACb,GAAG,CAAY;IACf,QAAQ,CAAU;IAClB,UAAU,GAAG,EAAE,CAAC;IACP,UAAU,GAAG,IAAI,GAAG,EAAkB,CAAC;IACvC,SAAS,GAAG,IAAI,GAAG,EAAkB,CAAC;IAEvD,YAA6B,SAAqB;QAArB,cAAS,GAAT,SAAS,CAAY;IAAG,CAAC;IAEtD,KAAK,CAAC,IAAI,CAAC,GAAqB;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;QACrE,MAAM,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;QACrC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,6CAA6C,CAAC,CAAC;QACnF,CAAC;QACD,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;QACpC,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,CAAC;YACtB,SAAS,EAAE,IAAI,CAAC,EAAE;YAClB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,QAAQ,EAAE,EAAE;YAChD,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAkD,WAAW,EAAE,EAAE,CAAC,CAAC;QAC/F,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAC5E,CAAC;IAED,uEAAuE;IAC/D,KAAK,CAAC,IAAI,CAAI,MAAc,EAAE,IAA6B,EAAE,MAAoB;QACvF,0EAA0E;QAC1E,qDAAqD;QACrD,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,MAAM,KAAK,WAAW,CAAC;QACrE,MAAM,QAAQ,GAAG,OAAO;YACtB,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,IAAI,CAAsC,IAAI,MAAM,EAAE,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YAChG,CAAC,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,GAAG,CAAsC,IAAI,MAAM,EAAE,EAAE;gBACpE,KAAK,EAAE,IAA6D;gBACpE,MAAM;aACP,CAAC,CAAC;QACP,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACjB,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,GAAG,MAAM,YAAY,QAAQ,CAAC,KAAK,IAAI,eAAe,EAAE,EAAE;gBAC1F,SAAS,EAAE,QAAQ,CAAC,KAAK,KAAK,aAAa;aAC5C,CAAC,CAAC;QACL,CAAC;QACD,OAAO,QAAQ,CAAC;IAClB,CAAC;IAED,2EAA2E;IACnE,KAAK,CAAC,cAAc,CAAC,OAAe,EAAE,MAAoB;QAChE,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,IAAI,qBAAqB,CAAC,IAAI,CAAC,OAAO,CAAC;YAAE,OAAO,OAAO,CAAC;QACxD,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACrD,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACzC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAE1B,IAAI,MAA0B,CAAC;QAC/B,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,IAAI,GAAG,CAAC,EAAE,IAAI,EAAE,EAAE,CAAC;YACpC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,oBAAoB,EACpB,EAAE,KAAK,EAAE,gCAAgC,EAAE,KAAK,EAAE,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,EACvF,MAAM,CACP,CAAC;YACF,KAAK,MAAM,EAAE,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;gBAC9B,IAAI,EAAE,CAAC,IAAI;oBAAE,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;YACjE,CAAC;YACD,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,GAAG;gBAAE,OAAO,GAAG,CAAC;YACpB,MAAM,GAAG,GAAG,CAAC,iBAAiB,EAAE,WAAW,IAAI,SAAS,CAAC;YACzD,IAAI,CAAC,MAAM;gBAAE,MAAM;QACrB,CAAC;QACD,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,sBAAsB,OAAO,EAAE,CAAC,CAAC;IACrE,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,MAAoB;QACzD,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,YAAY,EACZ,EAAE,IAAI,EAAE,MAAM,EAAE,EAChB,MAAM,CACP,CAAC;YACF,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC;YAC5F,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,MAAM,CAAC,CAAC,iCAAiC;QAClD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,cAAc,CAAC,QAAwB,EAAE,MAAoB;QACzE,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,MAAM,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC5G,MAAM,UAAU,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,iBAAiB,GAAG,CAAC,WAAW,uBAAuB,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3G,KAAK,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,CAAC,IAAI,IAAI,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC;QACtE,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAED,KAAK;QACH,MAAM,YAAY,GAAG,UAAU,CAAC;YAC9B,IAAI,EAAE,qBAAqB;YAC3B,WAAW,EAAE,sDAAsD;YACnE,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACzE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,oBAAoB,EACpB,EAAE,KAAK,EAAE,gCAAgC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,gBAAgB,EAAE,IAAI,EAAE,EACvF,GAAG,CAAC,MAAM,CACX,CAAC;gBACF,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;gBAC1E,OAAO;oBACL,OAAO,EAAE,GAAG,CAAC,QAAQ;yBAClB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;yBACzE,IAAI,CAAC,IAAI,CAAC;iBACd,CAAC;YACJ,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,UAAU,CAAC;YAC7B,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EAAE,yFAAyF;YACtG,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;gBACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;aACpD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACrE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,uBAAuB,EACvB,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EAC/B,GAAG,CAAC,MAAM,CACX,CAAC;gBACF,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC;oBAAE,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;gBAClE,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACvF,OAAO,EAAE,OAAO,EAAE,WAAW,OAAO,KAAK,QAAQ,EAAE,EAAE,CAAC;YACxD,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,UAAU,CAAC;YAC5B,IAAI,EAAE,mBAAmB;YACzB,WAAW,EAAE,sEAAsE;YACnF,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;gBACnB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,oCAAoC,CAAC;gBACnE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;aACpD,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACrE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,uBAAuB,EACvB,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,QAAQ,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,EACnD,GAAG,CAAC,MAAM,CACX,CAAC;gBACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACrE,OAAO,EAAE,OAAO,EAAE,WAAW,OAAO,cAAc,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,EAAE,CAAC;YACpF,CAAC;SACF,CAAC,CAAC;QAEH,MAAM,WAAW,GAAG,UAAU,CAAC;YAC7B,IAAI,EAAE,oBAAoB;YAC1B,WAAW,EACT,+GAA+G;YACjH,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC;gBACf,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,sBAAsB,CAAC;gBACpD,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;gBACvB,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;aAC1F,CAAC;YACF,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE;gBAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;gBACrE,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,IAAI,CACzB,kBAAkB,EAClB;oBACE,OAAO;oBACP,IAAI,EAAE,KAAK,CAAC,IAAI;oBAChB,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACzD,EACD,GAAG,CAAC,MAAM,CACX,CAAC;gBACF,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,CAAC,OAAO,UAAU,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC;YAClE,CAAC;SACF,CAAC,CAAC;QAEH,OAAO,CAAC,YAAY,EAAE,WAAW,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;IAC9D,CAAC;IAED,0EAA0E;IAC1E,KAAK,CAAC,MAAM,CAAC,OAAsC,EAAE,MAAmB;QACtE,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACnB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4EAA4E,CAAC,CAAC;YAC5F,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC;YAC1B,SAAS,EAAE,IAAI,CAAC,EAAE;YAClB,OAAO,EAAE,uBAAuB;YAChC,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,IAAI,CAAC,QAAQ,EAAE,EAAE;YACrD,SAAS,EAAE,IAAI,CAAC,SAAS;SAC1B,CAAC,CAAC;QAEH,IAAI,SAAS,GAAG,IAAI,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,IAAI,CAAgD,wBAAwB,EAAE;oBACtG,MAAM;iBACP,CAAC,CAAC;gBACH,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;oBAC1B,MAAM,IAAI,cAAc,CAAC,IAAI,CAAC,EAAE,EAAE,iCAAiC,IAAI,CAAC,KAAK,IAAI,eAAe,EAAE,CAAC,CAAC;gBACtG,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;gBACzC,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;gBAChD,SAAS,GAAG,IAAI,CAAC,CAAC,8BAA8B;YAClD,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,MAAM,CAAC,OAAO;oBAAE,MAAM;gBAC1B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,kCAAkC,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBACrF,MAAM,KAAK,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;gBAC/B,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IACH,CAAC;IAED,+EAA+E;IACvE,SAAS,CAAC,GAAW,EAAE,OAAsC,EAAE,MAAmB;QACxF,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,MAAM,EAAE,GAAG,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAC/B,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAExD,MAAM,MAAM,GAAG,CAAC,GAAW,EAAE,EAAE;gBAC7B,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAC3C,IAAI,GAAG;oBAAE,MAAM,CAAC,GAAG,CAAC,CAAC;;oBAChB,OAAO,EAAE,CAAC;YACjB,CAAC,CAAC;YAEF,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YACzE,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;YAC7C,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;gBACrC,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC;gBACpD,IAAI,MAAM,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBACjC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mCAAmC,EAAE,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;oBAC/E,EAAE,CAAC,KAAK,EAAE,CAAC;oBACX,OAAO;gBACT,CAAC;gBACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO;oBAAE,OAAO;gBACpC,qDAAqD;gBACrD,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;gBAC5D,MAAM,KAAK,GAAG,mBAAmB,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;gBACjF,IAAI,KAAK;oBAAE,OAAO,CAAC,KAAK,CAAC,CAAC;YAC5B,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;IACL,CAAC;CACF;AASD,MAAM,UAAU,kBAAkB,CAAC,GAAW;IAC5C,IAAI,IAA6B,CAAC;IAClC,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC3B,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IACpD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY;QAAE,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,IAAI,EAAE,CAAC,EAAE,CAAC;IACjG,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,QAAQ,EAAE,CAAC;QACvE,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAA4B,CAAC;QAChE,MAAM,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAA4B,CAAC;QAC/D,OAAO;YACL,IAAI,EAAE,OAAO;YACb,UAAU,EAAE,IAAI,CAAC,WAAW;YAC5B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC;YACrD,KAAK;SACN,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3B,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,KAA8B,EAC9B,UAAkB;IAElB,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC9D,IAAI,KAAK,CAAC,MAAM,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAC9D,IAAI,KAAK,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC,CAAC,qBAAqB;IAErD,MAAM,OAAO,GAAG,MAAM,CAAC,KAAK,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC;IAC5C,MAAM,EAAE,GAAG,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,OAAO,KAAK,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;IAC5E,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;IAEtC,MAAM,SAAS,GAAG,IAAI,KAAK,aAAa,CAAC;IACzC,MAAM,IAAI,GAAG,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,YAAY,KAAK,IAAI,CAAC;IAC/D,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI;QAAE,OAAO,IAAI,CAAC;IAErC,OAAO;QACL,SAAS,EAAE,OAAO;QAClB,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,UAAU;QAC9C,OAAO;QACP,QAAQ,EAAE,GAAG,OAAO,IAAI,QAAQ,EAAE;QAClC,OAAO,EAAE;YACP,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,gBAAgB,cAAc,IAAI,eAAe,OAAO,QAAQ,EAAE,eAAe,QAAQ,IAAI;YACxH,gDAAgD,OAAO,mBAAmB,QAAQ,IAAI;YACtF,EAAE;YACF,IAAI;SACL,CAAC,IAAI,CAAC,IAAI,CAAC;QACZ,OAAO,EAAE,KAAK;QACd,UAAU,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACrC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error hierarchy. Every thrown error in Exempclaw should be (or extend)
|
|
3
|
+
* an ExempclawError so the runtime can distinguish recoverable failures
|
|
4
|
+
* (rate limits, connector outages) from programming errors.
|
|
5
|
+
*/
|
|
6
|
+
export declare class ExempclawError extends Error {
|
|
7
|
+
/** Whether retrying the same operation could plausibly succeed. */
|
|
8
|
+
readonly retryable: boolean;
|
|
9
|
+
constructor(message: string, options?: {
|
|
10
|
+
retryable?: boolean;
|
|
11
|
+
cause?: unknown;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
/** A required config value was missing or malformed. */
|
|
15
|
+
export declare class ConfigError extends ExempclawError {
|
|
16
|
+
}
|
|
17
|
+
/** A connector (email, Slack, …) failed to reach its upstream service. */
|
|
18
|
+
export declare class ConnectorError extends ExempclawError {
|
|
19
|
+
readonly connector: string;
|
|
20
|
+
constructor(connector: string, message: string, options?: {
|
|
21
|
+
retryable?: boolean;
|
|
22
|
+
cause?: unknown;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
/** A tool threw while executing. Carried back into the agent loop as a tool_result error. */
|
|
26
|
+
export declare class ToolExecutionError extends ExempclawError {
|
|
27
|
+
readonly tool: string;
|
|
28
|
+
constructor(tool: string, message: string, options?: {
|
|
29
|
+
retryable?: boolean;
|
|
30
|
+
cause?: unknown;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
/** A human (or policy) denied an outward action. Not an error condition the model can retry. */
|
|
34
|
+
export declare class ActionDeniedError extends ExempclawError {
|
|
35
|
+
constructor(message: string);
|
|
36
|
+
}
|