@yolk-sdk/connectors 0.0.1-canary.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 +195 -0
- package/dist/action.d.mts +37 -0
- package/dist/action.d.mts.map +1 -0
- package/dist/action.mjs +24 -0
- package/dist/action.mjs.map +1 -0
- package/dist/agent.d.mts +21 -0
- package/dist/agent.d.mts.map +1 -0
- package/dist/agent.mjs +66 -0
- package/dist/agent.mjs.map +1 -0
- package/dist/config.d.mts +10 -0
- package/dist/config.d.mts.map +1 -0
- package/dist/config.mjs +21 -0
- package/dist/config.mjs.map +1 -0
- package/dist/connector.d.mts +27 -0
- package/dist/connector.d.mts.map +1 -0
- package/dist/connector.mjs +32 -0
- package/dist/connector.mjs.map +1 -0
- package/dist/credential.d.mts +62 -0
- package/dist/credential.d.mts.map +1 -0
- package/dist/credential.mjs +62 -0
- package/dist/credential.mjs.map +1 -0
- package/dist/error.d.mts +17 -0
- package/dist/error.d.mts.map +1 -0
- package/dist/error.mjs +22 -0
- package/dist/error.mjs.map +1 -0
- package/dist/figma/index.d.mts +48 -0
- package/dist/figma/index.d.mts.map +1 -0
- package/dist/figma/index.mjs +97 -0
- package/dist/figma/index.mjs.map +1 -0
- package/dist/google/calendar.d.mts +53 -0
- package/dist/google/calendar.d.mts.map +1 -0
- package/dist/google/calendar.mjs +111 -0
- package/dist/google/calendar.mjs.map +1 -0
- package/dist/google/gmail.d.mts +53 -0
- package/dist/google/gmail.d.mts.map +1 -0
- package/dist/google/gmail.mjs +103 -0
- package/dist/google/gmail.mjs.map +1 -0
- package/dist/google/index.d.mts +14 -0
- package/dist/google/index.d.mts.map +1 -0
- package/dist/google/index.mjs +15 -0
- package/dist/google/index.mjs.map +1 -0
- package/dist/google/oauth.d.mts +18 -0
- package/dist/google/oauth.d.mts.map +1 -0
- package/dist/google/oauth.mjs +25 -0
- package/dist/google/oauth.mjs.map +1 -0
- package/dist/google/shared.d.mts +20 -0
- package/dist/google/shared.d.mts.map +1 -0
- package/dist/google/shared.mjs +36 -0
- package/dist/google/shared.mjs.map +1 -0
- package/dist/http.d.mts +32 -0
- package/dist/http.d.mts.map +1 -0
- package/dist/http.mjs +36 -0
- package/dist/http.mjs.map +1 -0
- package/dist/index.d.mts +9 -0
- package/dist/index.mjs +9 -0
- package/dist/integration.d.mts +24 -0
- package/dist/integration.d.mts.map +1 -0
- package/dist/integration.mjs +22 -0
- package/dist/integration.mjs.map +1 -0
- package/dist/linkedin-search/index.d.mts +60 -0
- package/dist/linkedin-search/index.d.mts.map +1 -0
- package/dist/linkedin-search/index.mjs +162 -0
- package/dist/linkedin-search/index.mjs.map +1 -0
- package/dist/notion/index.d.mts +69 -0
- package/dist/notion/index.d.mts.map +1 -0
- package/dist/notion/index.mjs +169 -0
- package/dist/notion/index.mjs.map +1 -0
- package/dist/r2-storage/index.d.mts +48 -0
- package/dist/r2-storage/index.d.mts.map +1 -0
- package/dist/r2-storage/index.mjs +91 -0
- package/dist/r2-storage/index.mjs.map +1 -0
- package/dist/result.d.mts +32 -0
- package/dist/result.d.mts.map +1 -0
- package/dist/result.mjs +23 -0
- package/dist/result.mjs.map +1 -0
- package/dist/telegram/index.d.mts +34 -0
- package/dist/telegram/index.d.mts.map +1 -0
- package/dist/telegram/index.mjs +109 -0
- package/dist/telegram/index.mjs.map +1 -0
- package/dist/todoist/index.d.mts +70 -0
- package/dist/todoist/index.d.mts.map +1 -0
- package/dist/todoist/index.mjs +176 -0
- package/dist/todoist/index.mjs.map +1 -0
- package/package.json +96 -0
- package/src/action.ts +75 -0
- package/src/agent.ts +120 -0
- package/src/config.ts +28 -0
- package/src/connector.ts +62 -0
- package/src/credential.ts +86 -0
- package/src/error.ts +20 -0
- package/src/figma/index.ts +121 -0
- package/src/google/calendar.ts +145 -0
- package/src/google/gmail.ts +127 -0
- package/src/google/index.ts +46 -0
- package/src/google/oauth.ts +26 -0
- package/src/google/shared.ts +56 -0
- package/src/http.ts +51 -0
- package/src/index.ts +36 -0
- package/src/integration.ts +28 -0
- package/src/linkedin-search/index.ts +217 -0
- package/src/notion/index.ts +234 -0
- package/src/r2-storage/index.ts +118 -0
- package/src/result.ts +35 -0
- package/src/telegram/index.ts +144 -0
- package/src/todoist/index.ts +227 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/telegram/index.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { defineAction } from '../action.ts'\nimport { requiredStringConfig } from '../config.ts'\nimport { defineConnector } from '../connector.ts'\nimport { CredentialSlot, resolveCredential } from '../credential.ts'\nimport { ConnectorHttpClient, ConnectorHttpRequest } from '../http.ts'\nimport { ActionResult, ProviderFailure } from '../result.ts'\nimport type { ConnectorIntegration } from '../integration.ts'\n\nexport const telegramConnectorId = 'telegram'\nexport const telegramBotTokenSlotId = 'telegram.bot_token'\nexport const telegramApiBaseUrl = 'https://api.telegram.org'\n\nexport const TelegramBotTokenSlot = CredentialSlot.make({\n id: telegramBotTokenSlotId,\n kind: 'api_key'\n})\n\nconst resolveTelegramBotToken = (integration: ConnectorIntegration) =>\n Effect.gen(function* () {\n const credential = yield* resolveCredential(integration, TelegramBotTokenSlot)\n\n switch (credential._tag) {\n case 'ApiKeyCredential':\n return credential.key\n case 'BearerTokenCredential':\n return credential.token\n case 'OAuthCredential':\n return credential.accessToken\n }\n })\n\nconst isSuccessStatus = (status: number) => status >= 200 && status < 300\n\nconst telegramProviderFailure = (input: {\n readonly code: string\n readonly message: string\n readonly status: number\n readonly body: string\n}) =>\n ActionResult.failure(\n new ProviderFailure({\n code: input.code,\n message: input.message,\n status: input.status,\n underlying: input.body\n })\n )\n\nexport class TelegramSendMessageInput extends Schema.Class<TelegramSendMessageInput>(\n 'TelegramSendMessageInput'\n)({\n message: Schema.String,\n disableWebPagePreview: Schema.optional(Schema.Boolean)\n}) {}\n\nexport class TelegramSendMessageOutput extends Schema.Class<TelegramSendMessageOutput>(\n 'TelegramSendMessageOutput'\n)({\n sent: Schema.Boolean,\n chatId: Schema.String\n}) {}\n\nexport class TelegramValidateOutput extends Schema.Class<TelegramValidateOutput>('TelegramValidateOutput')({\n ok: Schema.Boolean,\n chatId: Schema.String\n}) {}\n\nexport const telegramSendMessageAction = defineAction({\n id: 'telegram.send_message',\n description: 'Send a Telegram message to the configured chat.',\n inputSchema: TelegramSendMessageInput,\n outputSchema: TelegramSendMessageOutput,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const botToken = yield* resolveTelegramBotToken(integration)\n const chatId = yield* requiredStringConfig(integration, 'chatId')\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${telegramApiBaseUrl}/bot${botToken}/sendMessage`,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({\n chat_id: chatId,\n text: input.message,\n disable_web_page_preview: input.disableWebPagePreview ?? true\n })\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return telegramProviderFailure({\n code: response.status === 429 ? 'telegram_rate_limited' : 'telegram_send_failed',\n message: 'Telegram send message failed',\n status: response.status,\n body: response.body\n })\n }\n\n return ActionResult.success(TelegramSendMessageOutput.make({ sent: true, chatId }))\n })\n})\n\nexport const telegramValidateAction = defineAction({\n id: 'telegram.validate',\n description: 'Validate the Telegram bot token and configured chat.',\n inputSchema: Schema.Struct({}),\n outputSchema: TelegramValidateOutput,\n execute: ({ integration }) =>\n Effect.gen(function* () {\n const botToken = yield* resolveTelegramBotToken(integration)\n const chatId = yield* requiredStringConfig(integration, 'chatId')\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${telegramApiBaseUrl}/bot${botToken}/getChat`,\n headers: { 'content-type': 'application/json' },\n body: JSON.stringify({ chat_id: chatId })\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return telegramProviderFailure({\n code: 'telegram_validate_failed',\n message: 'Telegram validation failed',\n status: response.status,\n body: response.body\n })\n }\n\n return ActionResult.success(TelegramValidateOutput.make({ ok: true, chatId }))\n })\n})\n\nexport const telegramActions = [telegramSendMessageAction, telegramValidateAction]\n\nexport const TelegramConnector = defineConnector({\n id: telegramConnectorId,\n description: 'Telegram bot connector actions.',\n actions: telegramActions\n})\n"],"mappings":"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"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { ConnectorError } from "../error.mjs";
|
|
2
|
+
import { CredentialResolver, CredentialSlot } from "../credential.mjs";
|
|
3
|
+
import { ConnectorAction } from "../action.mjs";
|
|
4
|
+
import { Connector } from "../connector.mjs";
|
|
5
|
+
import { ConnectorHttpClient } from "../http.mjs";
|
|
6
|
+
import * as Schema from "effect/Schema";
|
|
7
|
+
|
|
8
|
+
//#region src/todoist/index.d.ts
|
|
9
|
+
declare const todoistConnectorId = "todoist";
|
|
10
|
+
declare const todoistApiTokenSlotId = "todoist.api_token";
|
|
11
|
+
declare const todoistApiBaseUrl = "https://api.todoist.com/rest/v2";
|
|
12
|
+
declare const TodoistApiTokenSlot: CredentialSlot;
|
|
13
|
+
declare const todoistAuthorizationHeaders: (token: string) => {
|
|
14
|
+
authorization: string;
|
|
15
|
+
};
|
|
16
|
+
declare const TodoistTask_base: Schema.Class<TodoistTask, Schema.Struct<{
|
|
17
|
+
readonly id: Schema.String;
|
|
18
|
+
readonly content: Schema.String;
|
|
19
|
+
readonly description: Schema.optional<Schema.String>;
|
|
20
|
+
readonly projectId: Schema.optional<Schema.String>;
|
|
21
|
+
readonly sectionId: Schema.optional<Schema.String>;
|
|
22
|
+
readonly parentId: Schema.optional<Schema.String>;
|
|
23
|
+
readonly labels: Schema.optional<Schema.$Array<Schema.String>>;
|
|
24
|
+
readonly priority: Schema.optional<Schema.Number>;
|
|
25
|
+
readonly due: Schema.optional<Schema.Unknown>;
|
|
26
|
+
readonly url: Schema.optional<Schema.String>;
|
|
27
|
+
}>, {}>;
|
|
28
|
+
declare class TodoistTask extends TodoistTask_base {}
|
|
29
|
+
declare const TodoistListTasksInput_base: Schema.Class<TodoistListTasksInput, Schema.Struct<{
|
|
30
|
+
readonly projectId: Schema.optional<Schema.String>;
|
|
31
|
+
readonly sectionId: Schema.optional<Schema.String>;
|
|
32
|
+
readonly parentId: Schema.optional<Schema.String>;
|
|
33
|
+
readonly label: Schema.optional<Schema.String>;
|
|
34
|
+
readonly filter: Schema.optional<Schema.String>;
|
|
35
|
+
}>, {}>;
|
|
36
|
+
declare class TodoistListTasksInput extends TodoistListTasksInput_base {}
|
|
37
|
+
declare const TodoistListTasksOutput_base: Schema.Class<TodoistListTasksOutput, Schema.Struct<{
|
|
38
|
+
readonly tasks: Schema.$Array<typeof TodoistTask>;
|
|
39
|
+
}>, {}>;
|
|
40
|
+
declare class TodoistListTasksOutput extends TodoistListTasksOutput_base {}
|
|
41
|
+
declare const TodoistCreateTaskInput_base: Schema.Class<TodoistCreateTaskInput, Schema.Struct<{
|
|
42
|
+
readonly content: Schema.String;
|
|
43
|
+
readonly description: Schema.optional<Schema.String>;
|
|
44
|
+
readonly projectId: Schema.optional<Schema.String>;
|
|
45
|
+
readonly sectionId: Schema.optional<Schema.String>;
|
|
46
|
+
readonly parentId: Schema.optional<Schema.String>;
|
|
47
|
+
readonly labels: Schema.optional<Schema.$Array<Schema.String>>;
|
|
48
|
+
readonly priority: Schema.optional<Schema.Number>;
|
|
49
|
+
readonly dueString: Schema.optional<Schema.String>;
|
|
50
|
+
readonly dueDate: Schema.optional<Schema.String>;
|
|
51
|
+
readonly dueDatetime: Schema.optional<Schema.String>;
|
|
52
|
+
}>, {}>;
|
|
53
|
+
declare class TodoistCreateTaskInput extends TodoistCreateTaskInput_base {}
|
|
54
|
+
declare const TodoistCloseTaskInput_base: Schema.Class<TodoistCloseTaskInput, Schema.Struct<{
|
|
55
|
+
readonly id: Schema.String;
|
|
56
|
+
}>, {}>;
|
|
57
|
+
declare class TodoistCloseTaskInput extends TodoistCloseTaskInput_base {}
|
|
58
|
+
declare const TodoistCloseTaskOutput_base: Schema.Class<TodoistCloseTaskOutput, Schema.Struct<{
|
|
59
|
+
readonly id: Schema.String;
|
|
60
|
+
readonly closed: Schema.Boolean;
|
|
61
|
+
}>, {}>;
|
|
62
|
+
declare class TodoistCloseTaskOutput extends TodoistCloseTaskOutput_base {}
|
|
63
|
+
declare const todoistListTasksAction: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>;
|
|
64
|
+
declare const todoistCreateTaskAction: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>;
|
|
65
|
+
declare const todoistCloseTaskAction: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>;
|
|
66
|
+
declare const todoistActions: ConnectorAction<ConnectorHttpClient | CredentialResolver, ConnectorError>[];
|
|
67
|
+
declare const TodoistConnector: Connector<ConnectorHttpClient | CredentialResolver, ConnectorError>;
|
|
68
|
+
//#endregion
|
|
69
|
+
export { TodoistApiTokenSlot, TodoistCloseTaskInput, TodoistCloseTaskOutput, TodoistConnector, TodoistCreateTaskInput, TodoistListTasksInput, TodoistListTasksOutput, TodoistTask, todoistActions, todoistApiBaseUrl, todoistApiTokenSlotId, todoistAuthorizationHeaders, todoistCloseTaskAction, todoistConnectorId, todoistCreateTaskAction, todoistListTasksAction };
|
|
70
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/todoist/index.ts"],"mappings":";;;;;;;;cASa,kBAAA;AAAA,cACA,qBAAA;AAAA,cACA,iBAAA;AAAA,cAEA,mBAAA,EAAmB,cAG9B;AAAA,cAEW,2BAAA,GAA+B,KAAA;EAAA,aAAA;AAAA;AAAA,cAE1C,gBAAA;;;;;;;;;;;;cAiCW,WAAA,SAAoB,gBAW/B;AAAA,cAAG,0BAAA;;;;;;;cAEQ,qBAAA,SAA8B,0BAMzC;AAAA,cAAG,2BAAA;;;cAEQ,sBAAA,SAA+B,2BAE1C;AAAA,cAAG,2BAAA;;;;;;;;;;;;cAEQ,sBAAA,SAA+B,2BAW1C;AAAA,cAAG,0BAAA;;;cAEQ,qBAAA,SAA8B,0BAEzC;AAAA,cAAG,2BAAA;;;;cAEQ,sBAAA,SAA+B,2BAG1C;AAAA,cAQW,sBAAA,EAAsB,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cAsCtB,uBAAA,EAAuB,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cA8CvB,sBAAA,EAAsB,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cA8BtB,cAAA,EAAc,eAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA;AAAA,cAEd,gBAAA,EAAgB,SAAA,CAAA,mBAAA,GAAA,kBAAA,EAAA,cAAA"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
import { defineAction } from "../action.mjs";
|
|
2
|
+
import { defineConnector } from "../connector.mjs";
|
|
3
|
+
import { CredentialSlot, resolveCredential } from "../credential.mjs";
|
|
4
|
+
import { ConnectorHttpClient, ConnectorHttpRequest, decodeJsonResponse } from "../http.mjs";
|
|
5
|
+
import { ActionResult, ProviderFailure } from "../result.mjs";
|
|
6
|
+
import { Effect } from "effect";
|
|
7
|
+
import * as Schema from "effect/Schema";
|
|
8
|
+
//#region src/todoist/index.ts
|
|
9
|
+
const todoistConnectorId = "todoist";
|
|
10
|
+
const todoistApiTokenSlotId = "todoist.api_token";
|
|
11
|
+
const todoistApiBaseUrl = "https://api.todoist.com/rest/v2";
|
|
12
|
+
const TodoistApiTokenSlot = CredentialSlot.make({
|
|
13
|
+
id: todoistApiTokenSlotId,
|
|
14
|
+
kind: "api_key"
|
|
15
|
+
});
|
|
16
|
+
const todoistAuthorizationHeaders = (token) => ({ authorization: `Bearer ${token}` });
|
|
17
|
+
const isSuccessStatus = (status) => status >= 200 && status < 300;
|
|
18
|
+
const todoistProviderFailure = (input) => ActionResult.failure(new ProviderFailure({
|
|
19
|
+
code: input.code,
|
|
20
|
+
message: input.message,
|
|
21
|
+
status: input.status,
|
|
22
|
+
underlying: input.body
|
|
23
|
+
}));
|
|
24
|
+
const resolveTodoistToken = (integration) => Effect.gen(function* () {
|
|
25
|
+
const credential = yield* resolveCredential(integration, TodoistApiTokenSlot);
|
|
26
|
+
switch (credential._tag) {
|
|
27
|
+
case "ApiKeyCredential": return credential.key;
|
|
28
|
+
case "BearerTokenCredential": return credential.token;
|
|
29
|
+
case "OAuthCredential": return credential.accessToken;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
var TodoistTask = class extends Schema.Class("TodoistTask")({
|
|
33
|
+
id: Schema.String,
|
|
34
|
+
content: Schema.String,
|
|
35
|
+
description: Schema.optional(Schema.String),
|
|
36
|
+
projectId: Schema.optional(Schema.String),
|
|
37
|
+
sectionId: Schema.optional(Schema.String),
|
|
38
|
+
parentId: Schema.optional(Schema.String),
|
|
39
|
+
labels: Schema.optional(Schema.Array(Schema.String)),
|
|
40
|
+
priority: Schema.optional(Schema.Number),
|
|
41
|
+
due: Schema.optional(Schema.Unknown),
|
|
42
|
+
url: Schema.optional(Schema.String)
|
|
43
|
+
}) {};
|
|
44
|
+
var TodoistListTasksInput = class extends Schema.Class("TodoistListTasksInput")({
|
|
45
|
+
projectId: Schema.optional(Schema.String),
|
|
46
|
+
sectionId: Schema.optional(Schema.String),
|
|
47
|
+
parentId: Schema.optional(Schema.String),
|
|
48
|
+
label: Schema.optional(Schema.String),
|
|
49
|
+
filter: Schema.optional(Schema.String)
|
|
50
|
+
}) {};
|
|
51
|
+
var TodoistListTasksOutput = class extends Schema.Class("TodoistListTasksOutput")({ tasks: Schema.Array(TodoistTask) }) {};
|
|
52
|
+
var TodoistCreateTaskInput = class extends Schema.Class("TodoistCreateTaskInput")({
|
|
53
|
+
content: Schema.String,
|
|
54
|
+
description: Schema.optional(Schema.String),
|
|
55
|
+
projectId: Schema.optional(Schema.String),
|
|
56
|
+
sectionId: Schema.optional(Schema.String),
|
|
57
|
+
parentId: Schema.optional(Schema.String),
|
|
58
|
+
labels: Schema.optional(Schema.Array(Schema.String)),
|
|
59
|
+
priority: Schema.optional(Schema.Number),
|
|
60
|
+
dueString: Schema.optional(Schema.String),
|
|
61
|
+
dueDate: Schema.optional(Schema.String),
|
|
62
|
+
dueDatetime: Schema.optional(Schema.String)
|
|
63
|
+
}) {};
|
|
64
|
+
var TodoistCloseTaskInput = class extends Schema.Class("TodoistCloseTaskInput")({ id: Schema.String }) {};
|
|
65
|
+
var TodoistCloseTaskOutput = class extends Schema.Class("TodoistCloseTaskOutput")({
|
|
66
|
+
id: Schema.String,
|
|
67
|
+
closed: Schema.Boolean
|
|
68
|
+
}) {};
|
|
69
|
+
const appendSearchParam = (params, key, value) => {
|
|
70
|
+
if (value !== void 0 && value.trim() !== "") params.set(key, value);
|
|
71
|
+
};
|
|
72
|
+
const todoistListTasksAction = defineAction({
|
|
73
|
+
id: "todoist.list_tasks",
|
|
74
|
+
description: "List Todoist active tasks.",
|
|
75
|
+
inputSchema: TodoistListTasksInput,
|
|
76
|
+
outputSchema: TodoistListTasksOutput,
|
|
77
|
+
execute: ({ integration, input }) => Effect.gen(function* () {
|
|
78
|
+
const token = yield* resolveTodoistToken(integration);
|
|
79
|
+
const http = yield* ConnectorHttpClient;
|
|
80
|
+
const params = new URLSearchParams();
|
|
81
|
+
appendSearchParam(params, "project_id", input.projectId);
|
|
82
|
+
appendSearchParam(params, "section_id", input.sectionId);
|
|
83
|
+
appendSearchParam(params, "parent_id", input.parentId);
|
|
84
|
+
appendSearchParam(params, "label", input.label);
|
|
85
|
+
appendSearchParam(params, "filter", input.filter);
|
|
86
|
+
const query = params.toString();
|
|
87
|
+
const response = yield* http.request(ConnectorHttpRequest.make({
|
|
88
|
+
method: "GET",
|
|
89
|
+
url: `${todoistApiBaseUrl}/tasks${query === "" ? "" : `?${query}`}`,
|
|
90
|
+
headers: todoistAuthorizationHeaders(token)
|
|
91
|
+
}));
|
|
92
|
+
if (!isSuccessStatus(response.status)) return todoistProviderFailure({
|
|
93
|
+
code: "todoist_list_tasks_failed",
|
|
94
|
+
message: "Todoist list tasks failed",
|
|
95
|
+
status: response.status,
|
|
96
|
+
body: response.body
|
|
97
|
+
});
|
|
98
|
+
const tasks = yield* decodeJsonResponse(Schema.Array(TodoistTask), response);
|
|
99
|
+
return ActionResult.success(TodoistListTasksOutput.make({ tasks }));
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
const todoistCreateTaskAction = defineAction({
|
|
103
|
+
id: "todoist.create_task",
|
|
104
|
+
description: "Create a Todoist task.",
|
|
105
|
+
inputSchema: TodoistCreateTaskInput,
|
|
106
|
+
outputSchema: TodoistTask,
|
|
107
|
+
execute: ({ integration, input }) => Effect.gen(function* () {
|
|
108
|
+
const token = yield* resolveTodoistToken(integration);
|
|
109
|
+
const response = yield* (yield* ConnectorHttpClient).request(ConnectorHttpRequest.make({
|
|
110
|
+
method: "POST",
|
|
111
|
+
url: `${todoistApiBaseUrl}/tasks`,
|
|
112
|
+
headers: {
|
|
113
|
+
...todoistAuthorizationHeaders(token),
|
|
114
|
+
"content-type": "application/json"
|
|
115
|
+
},
|
|
116
|
+
body: JSON.stringify({
|
|
117
|
+
content: input.content,
|
|
118
|
+
description: input.description,
|
|
119
|
+
project_id: input.projectId,
|
|
120
|
+
section_id: input.sectionId,
|
|
121
|
+
parent_id: input.parentId,
|
|
122
|
+
labels: input.labels,
|
|
123
|
+
priority: input.priority,
|
|
124
|
+
due_string: input.dueString,
|
|
125
|
+
due_date: input.dueDate,
|
|
126
|
+
due_datetime: input.dueDatetime
|
|
127
|
+
})
|
|
128
|
+
}));
|
|
129
|
+
if (!isSuccessStatus(response.status)) return todoistProviderFailure({
|
|
130
|
+
code: "todoist_create_task_failed",
|
|
131
|
+
message: "Todoist create task failed",
|
|
132
|
+
status: response.status,
|
|
133
|
+
body: response.body
|
|
134
|
+
});
|
|
135
|
+
const output = yield* decodeJsonResponse(TodoistTask, response);
|
|
136
|
+
return ActionResult.success(output);
|
|
137
|
+
})
|
|
138
|
+
});
|
|
139
|
+
const todoistCloseTaskAction = defineAction({
|
|
140
|
+
id: "todoist.close_task",
|
|
141
|
+
description: "Close a Todoist task.",
|
|
142
|
+
inputSchema: TodoistCloseTaskInput,
|
|
143
|
+
outputSchema: TodoistCloseTaskOutput,
|
|
144
|
+
execute: ({ integration, input }) => Effect.gen(function* () {
|
|
145
|
+
const token = yield* resolveTodoistToken(integration);
|
|
146
|
+
const response = yield* (yield* ConnectorHttpClient).request(ConnectorHttpRequest.make({
|
|
147
|
+
method: "POST",
|
|
148
|
+
url: `${todoistApiBaseUrl}/tasks/${encodeURIComponent(input.id)}/close`,
|
|
149
|
+
headers: todoistAuthorizationHeaders(token)
|
|
150
|
+
}));
|
|
151
|
+
if (!isSuccessStatus(response.status)) return todoistProviderFailure({
|
|
152
|
+
code: "todoist_close_task_failed",
|
|
153
|
+
message: "Todoist close task failed",
|
|
154
|
+
status: response.status,
|
|
155
|
+
body: response.body
|
|
156
|
+
});
|
|
157
|
+
return ActionResult.success(TodoistCloseTaskOutput.make({
|
|
158
|
+
id: input.id,
|
|
159
|
+
closed: true
|
|
160
|
+
}));
|
|
161
|
+
})
|
|
162
|
+
});
|
|
163
|
+
const todoistActions = [
|
|
164
|
+
todoistListTasksAction,
|
|
165
|
+
todoistCreateTaskAction,
|
|
166
|
+
todoistCloseTaskAction
|
|
167
|
+
];
|
|
168
|
+
const TodoistConnector = defineConnector({
|
|
169
|
+
id: todoistConnectorId,
|
|
170
|
+
description: "Todoist task connector actions.",
|
|
171
|
+
actions: todoistActions
|
|
172
|
+
});
|
|
173
|
+
//#endregion
|
|
174
|
+
export { TodoistApiTokenSlot, TodoistCloseTaskInput, TodoistCloseTaskOutput, TodoistConnector, TodoistCreateTaskInput, TodoistListTasksInput, TodoistListTasksOutput, TodoistTask, todoistActions, todoistApiBaseUrl, todoistApiTokenSlotId, todoistAuthorizationHeaders, todoistCloseTaskAction, todoistConnectorId, todoistCreateTaskAction, todoistListTasksAction };
|
|
175
|
+
|
|
176
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/todoist/index.ts"],"sourcesContent":["import { Effect } from 'effect'\nimport * as Schema from 'effect/Schema'\nimport { defineAction } from '../action.ts'\nimport { defineConnector } from '../connector.ts'\nimport { CredentialSlot, resolveCredential } from '../credential.ts'\nimport { ConnectorHttpClient, ConnectorHttpRequest, decodeJsonResponse } from '../http.ts'\nimport { ActionResult, ProviderFailure } from '../result.ts'\nimport type { ConnectorIntegration } from '../integration.ts'\n\nexport const todoistConnectorId = 'todoist'\nexport const todoistApiTokenSlotId = 'todoist.api_token'\nexport const todoistApiBaseUrl = 'https://api.todoist.com/rest/v2'\n\nexport const TodoistApiTokenSlot = CredentialSlot.make({\n id: todoistApiTokenSlotId,\n kind: 'api_key'\n})\n\nexport const todoistAuthorizationHeaders = (token: string) => ({\n authorization: `Bearer ${token}`\n})\n\nconst isSuccessStatus = (status: number) => status >= 200 && status < 300\n\nconst todoistProviderFailure = (input: {\n readonly code: string\n readonly message: string\n readonly status: number\n readonly body: string\n}) =>\n ActionResult.failure(\n new ProviderFailure({\n code: input.code,\n message: input.message,\n status: input.status,\n underlying: input.body\n })\n )\n\nconst resolveTodoistToken = (integration: ConnectorIntegration) =>\n Effect.gen(function* () {\n const credential = yield* resolveCredential(integration, TodoistApiTokenSlot)\n\n switch (credential._tag) {\n case 'ApiKeyCredential':\n return credential.key\n case 'BearerTokenCredential':\n return credential.token\n case 'OAuthCredential':\n return credential.accessToken\n }\n })\n\nexport class TodoistTask extends Schema.Class<TodoistTask>('TodoistTask')({\n id: Schema.String,\n content: Schema.String,\n description: Schema.optional(Schema.String),\n projectId: Schema.optional(Schema.String),\n sectionId: Schema.optional(Schema.String),\n parentId: Schema.optional(Schema.String),\n labels: Schema.optional(Schema.Array(Schema.String)),\n priority: Schema.optional(Schema.Number),\n due: Schema.optional(Schema.Unknown),\n url: Schema.optional(Schema.String)\n}) {}\n\nexport class TodoistListTasksInput extends Schema.Class<TodoistListTasksInput>('TodoistListTasksInput')({\n projectId: Schema.optional(Schema.String),\n sectionId: Schema.optional(Schema.String),\n parentId: Schema.optional(Schema.String),\n label: Schema.optional(Schema.String),\n filter: Schema.optional(Schema.String)\n}) {}\n\nexport class TodoistListTasksOutput extends Schema.Class<TodoistListTasksOutput>('TodoistListTasksOutput')({\n tasks: Schema.Array(TodoistTask)\n}) {}\n\nexport class TodoistCreateTaskInput extends Schema.Class<TodoistCreateTaskInput>('TodoistCreateTaskInput')({\n content: Schema.String,\n description: Schema.optional(Schema.String),\n projectId: Schema.optional(Schema.String),\n sectionId: Schema.optional(Schema.String),\n parentId: Schema.optional(Schema.String),\n labels: Schema.optional(Schema.Array(Schema.String)),\n priority: Schema.optional(Schema.Number),\n dueString: Schema.optional(Schema.String),\n dueDate: Schema.optional(Schema.String),\n dueDatetime: Schema.optional(Schema.String)\n}) {}\n\nexport class TodoistCloseTaskInput extends Schema.Class<TodoistCloseTaskInput>('TodoistCloseTaskInput')({\n id: Schema.String\n}) {}\n\nexport class TodoistCloseTaskOutput extends Schema.Class<TodoistCloseTaskOutput>('TodoistCloseTaskOutput')({\n id: Schema.String,\n closed: Schema.Boolean\n}) {}\n\nconst appendSearchParam = (params: URLSearchParams, key: string, value: string | undefined) => {\n if (value !== undefined && value.trim() !== '') {\n params.set(key, value)\n }\n}\n\nexport const todoistListTasksAction = defineAction({\n id: 'todoist.list_tasks',\n description: 'List Todoist active tasks.',\n inputSchema: TodoistListTasksInput,\n outputSchema: TodoistListTasksOutput,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const token = yield* resolveTodoistToken(integration)\n const http = yield* ConnectorHttpClient\n const params = new URLSearchParams()\n appendSearchParam(params, 'project_id', input.projectId)\n appendSearchParam(params, 'section_id', input.sectionId)\n appendSearchParam(params, 'parent_id', input.parentId)\n appendSearchParam(params, 'label', input.label)\n appendSearchParam(params, 'filter', input.filter)\n const query = params.toString()\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'GET',\n url: `${todoistApiBaseUrl}/tasks${query === '' ? '' : `?${query}`}`,\n headers: todoistAuthorizationHeaders(token)\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return todoistProviderFailure({\n code: 'todoist_list_tasks_failed',\n message: 'Todoist list tasks failed',\n status: response.status,\n body: response.body\n })\n }\n\n const tasks = yield* decodeJsonResponse(Schema.Array(TodoistTask), response)\n return ActionResult.success(TodoistListTasksOutput.make({ tasks }))\n })\n})\n\nexport const todoistCreateTaskAction = defineAction({\n id: 'todoist.create_task',\n description: 'Create a Todoist task.',\n inputSchema: TodoistCreateTaskInput,\n outputSchema: TodoistTask,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const token = yield* resolveTodoistToken(integration)\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${todoistApiBaseUrl}/tasks`,\n headers: {\n ...todoistAuthorizationHeaders(token),\n 'content-type': 'application/json'\n },\n body: JSON.stringify({\n content: input.content,\n description: input.description,\n project_id: input.projectId,\n section_id: input.sectionId,\n parent_id: input.parentId,\n labels: input.labels,\n priority: input.priority,\n due_string: input.dueString,\n due_date: input.dueDate,\n due_datetime: input.dueDatetime\n })\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return todoistProviderFailure({\n code: 'todoist_create_task_failed',\n message: 'Todoist create task failed',\n status: response.status,\n body: response.body\n })\n }\n\n const output = yield* decodeJsonResponse(TodoistTask, response)\n return ActionResult.success(output)\n })\n})\n\nexport const todoistCloseTaskAction = defineAction({\n id: 'todoist.close_task',\n description: 'Close a Todoist task.',\n inputSchema: TodoistCloseTaskInput,\n outputSchema: TodoistCloseTaskOutput,\n execute: ({ integration, input }) =>\n Effect.gen(function* () {\n const token = yield* resolveTodoistToken(integration)\n const http = yield* ConnectorHttpClient\n const response = yield* http.request(\n ConnectorHttpRequest.make({\n method: 'POST',\n url: `${todoistApiBaseUrl}/tasks/${encodeURIComponent(input.id)}/close`,\n headers: todoistAuthorizationHeaders(token)\n })\n )\n\n if (!isSuccessStatus(response.status)) {\n return todoistProviderFailure({\n code: 'todoist_close_task_failed',\n message: 'Todoist close task failed',\n status: response.status,\n body: response.body\n })\n }\n\n return ActionResult.success(TodoistCloseTaskOutput.make({ id: input.id, closed: true }))\n })\n})\n\nexport const todoistActions = [todoistListTasksAction, todoistCreateTaskAction, todoistCloseTaskAction]\n\nexport const TodoistConnector = defineConnector({\n id: todoistConnectorId,\n description: 'Todoist task connector actions.',\n actions: todoistActions\n})\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@yolk-sdk/connectors",
|
|
3
|
+
"version": "0.0.1-canary.0",
|
|
4
|
+
"description": "Effect-native connector, integration, credential, and action primitives for Yolk hosts.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"sideEffects": false,
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/magoz/yolk-sdk.git",
|
|
11
|
+
"directory": "packages/connectors"
|
|
12
|
+
},
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/magoz/yolk-sdk/issues"
|
|
15
|
+
},
|
|
16
|
+
"homepage": "https://github.com/magoz/yolk-sdk#readme",
|
|
17
|
+
"keywords": [
|
|
18
|
+
"connectors",
|
|
19
|
+
"integrations",
|
|
20
|
+
"agents",
|
|
21
|
+
"tools",
|
|
22
|
+
"effect"
|
|
23
|
+
],
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=22"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
"./package.json": "./package.json",
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.mts",
|
|
31
|
+
"import": "./dist/index.mjs",
|
|
32
|
+
"default": "./dist/index.mjs"
|
|
33
|
+
},
|
|
34
|
+
"./agent": {
|
|
35
|
+
"types": "./dist/agent.d.mts",
|
|
36
|
+
"import": "./dist/agent.mjs",
|
|
37
|
+
"default": "./dist/agent.mjs"
|
|
38
|
+
},
|
|
39
|
+
"./figma": {
|
|
40
|
+
"types": "./dist/figma/index.d.mts",
|
|
41
|
+
"import": "./dist/figma/index.mjs",
|
|
42
|
+
"default": "./dist/figma/index.mjs"
|
|
43
|
+
},
|
|
44
|
+
"./google": {
|
|
45
|
+
"types": "./dist/google/index.d.mts",
|
|
46
|
+
"import": "./dist/google/index.mjs",
|
|
47
|
+
"default": "./dist/google/index.mjs"
|
|
48
|
+
},
|
|
49
|
+
"./linkedin-search": {
|
|
50
|
+
"types": "./dist/linkedin-search/index.d.mts",
|
|
51
|
+
"import": "./dist/linkedin-search/index.mjs",
|
|
52
|
+
"default": "./dist/linkedin-search/index.mjs"
|
|
53
|
+
},
|
|
54
|
+
"./notion": {
|
|
55
|
+
"types": "./dist/notion/index.d.mts",
|
|
56
|
+
"import": "./dist/notion/index.mjs",
|
|
57
|
+
"default": "./dist/notion/index.mjs"
|
|
58
|
+
},
|
|
59
|
+
"./r2-storage": {
|
|
60
|
+
"types": "./dist/r2-storage/index.d.mts",
|
|
61
|
+
"import": "./dist/r2-storage/index.mjs",
|
|
62
|
+
"default": "./dist/r2-storage/index.mjs"
|
|
63
|
+
},
|
|
64
|
+
"./telegram": {
|
|
65
|
+
"types": "./dist/telegram/index.d.mts",
|
|
66
|
+
"import": "./dist/telegram/index.mjs",
|
|
67
|
+
"default": "./dist/telegram/index.mjs"
|
|
68
|
+
},
|
|
69
|
+
"./todoist": {
|
|
70
|
+
"types": "./dist/todoist/index.d.mts",
|
|
71
|
+
"import": "./dist/todoist/index.mjs",
|
|
72
|
+
"default": "./dist/todoist/index.mjs"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"files": [
|
|
76
|
+
"src/**/*.ts",
|
|
77
|
+
"!src/**/*.test.ts",
|
|
78
|
+
"!src/**/*.test.tsx",
|
|
79
|
+
"dist/**/*",
|
|
80
|
+
"README.md"
|
|
81
|
+
],
|
|
82
|
+
"publishConfig": {
|
|
83
|
+
"access": "public",
|
|
84
|
+
"provenance": true
|
|
85
|
+
},
|
|
86
|
+
"dependencies": {
|
|
87
|
+
"effect": "4.0.0-beta.65",
|
|
88
|
+
"@yolk-sdk/agent": "^0.0.1-canary.0"
|
|
89
|
+
},
|
|
90
|
+
"scripts": {
|
|
91
|
+
"build": "tsdown",
|
|
92
|
+
"check": "tsc -p tsconfig.json --noEmit",
|
|
93
|
+
"test": "vitest run --passWithNoTests",
|
|
94
|
+
"test:run": "vitest run --passWithNoTests"
|
|
95
|
+
}
|
|
96
|
+
}
|
package/src/action.ts
ADDED
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Effect } from 'effect'
|
|
2
|
+
import * as Schema from 'effect/Schema'
|
|
3
|
+
import { ConnectorError } from './error.ts'
|
|
4
|
+
import type { ActionResult } from './result.ts'
|
|
5
|
+
import type { ConnectorIntegration } from './integration.ts'
|
|
6
|
+
|
|
7
|
+
type ActionInputSchema = Schema.Schema<unknown> & { readonly DecodingServices: never }
|
|
8
|
+
type ActionOutputSchema = Schema.Schema<unknown>
|
|
9
|
+
|
|
10
|
+
export type ActionExecutionInput<Input> = {
|
|
11
|
+
readonly integration: ConnectorIntegration
|
|
12
|
+
readonly input: Input
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type UnknownActionExecutionInput = {
|
|
16
|
+
readonly integration: ConnectorIntegration
|
|
17
|
+
readonly input: unknown
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export type ConnectorAction<Env = never, Error = never> = {
|
|
21
|
+
readonly id: string
|
|
22
|
+
readonly description?: string
|
|
23
|
+
readonly inputSchema: ActionInputSchema
|
|
24
|
+
readonly outputSchema: ActionOutputSchema
|
|
25
|
+
readonly execute: (
|
|
26
|
+
input: UnknownActionExecutionInput
|
|
27
|
+
) => Effect.Effect<ActionResult<unknown>, Error | ConnectorError, Env>
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type DefineActionOptions<
|
|
31
|
+
InputSchema extends ActionInputSchema,
|
|
32
|
+
Output,
|
|
33
|
+
Env,
|
|
34
|
+
Error
|
|
35
|
+
> = {
|
|
36
|
+
readonly id: string
|
|
37
|
+
readonly description?: string
|
|
38
|
+
readonly inputSchema: InputSchema
|
|
39
|
+
readonly outputSchema: Schema.Schema<Output>
|
|
40
|
+
readonly execute: (
|
|
41
|
+
input: ActionExecutionInput<InputSchema['Type']>
|
|
42
|
+
) => Effect.Effect<ActionResult<Output>, Error | ConnectorError, Env>
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const validationError = (actionId: string, error: unknown) =>
|
|
46
|
+
new ConnectorError({
|
|
47
|
+
cause: 'validation_failed',
|
|
48
|
+
message: `Invalid input for action: ${actionId}`,
|
|
49
|
+
actionId,
|
|
50
|
+
underlying: error
|
|
51
|
+
})
|
|
52
|
+
|
|
53
|
+
export const defineAction = <
|
|
54
|
+
InputSchema extends ActionInputSchema,
|
|
55
|
+
Output,
|
|
56
|
+
Env = never,
|
|
57
|
+
Error = never
|
|
58
|
+
>(
|
|
59
|
+
options: DefineActionOptions<InputSchema, Output, Env, Error>
|
|
60
|
+
): ConnectorAction<Env, Error> => ({
|
|
61
|
+
id: options.id,
|
|
62
|
+
description: options.description,
|
|
63
|
+
inputSchema: options.inputSchema,
|
|
64
|
+
outputSchema: options.outputSchema,
|
|
65
|
+
execute: input =>
|
|
66
|
+
Schema.decodeUnknownEffect(options.inputSchema)(input.input).pipe(
|
|
67
|
+
Effect.mapError(error => validationError(options.id, error)),
|
|
68
|
+
Effect.flatMap(params =>
|
|
69
|
+
options.execute({
|
|
70
|
+
integration: input.integration,
|
|
71
|
+
input: params
|
|
72
|
+
})
|
|
73
|
+
)
|
|
74
|
+
)
|
|
75
|
+
})
|
package/src/agent.ts
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { Effect } from 'effect'
|
|
2
|
+
import type { Layer } from 'effect'
|
|
3
|
+
import * as Schema from 'effect/Schema'
|
|
4
|
+
import { ToolError } from '@yolk-sdk/agent/loop'
|
|
5
|
+
import { makeTool, type ToolAccess, type ToolModule, type ToolRegistration } from '@yolk-sdk/agent/tools'
|
|
6
|
+
import { ToolResult } from '@yolk-sdk/agent/protocol'
|
|
7
|
+
import type { Connector } from './connector.ts'
|
|
8
|
+
import type { ConnectorIntegration } from './integration.ts'
|
|
9
|
+
import type { ProviderFailure } from './result.ts'
|
|
10
|
+
|
|
11
|
+
export type ConnectorIntegrationResolver<Context> =
|
|
12
|
+
| ConnectorIntegration
|
|
13
|
+
| ((context: Context) => Effect.Effect<ConnectorIntegration, ToolError>)
|
|
14
|
+
|
|
15
|
+
export type ConnectorToolAccessResolver = ToolAccess | ((actionId: string) => ToolAccess)
|
|
16
|
+
|
|
17
|
+
export type MakeConnectorToolModuleOptions<Context, Env> = {
|
|
18
|
+
readonly integration: ConnectorIntegrationResolver<Context>
|
|
19
|
+
readonly layer: Layer.Layer<Env>
|
|
20
|
+
readonly moduleId?: string
|
|
21
|
+
readonly namePrefix?: string
|
|
22
|
+
readonly access?: ConnectorToolAccessResolver
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const resolveIntegration = <Context>(resolver: ConnectorIntegrationResolver<Context>, context: Context) => {
|
|
26
|
+
if (typeof resolver === 'function') {
|
|
27
|
+
return resolver(context)
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return Effect.succeed(resolver)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const resolveAccess = (resolver: ConnectorToolAccessResolver | undefined, actionId: string): ToolAccess => {
|
|
34
|
+
if (typeof resolver === 'function') {
|
|
35
|
+
return resolver(actionId)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return resolver ?? 'read'
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const unknownToMessage = (error: unknown) => {
|
|
42
|
+
if (error instanceof Error) {
|
|
43
|
+
return error.message
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return String(error)
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const failureContent = (failure: ProviderFailure) => `${failure.code}: ${failure.message}`
|
|
50
|
+
|
|
51
|
+
const successContent = (value: unknown) => {
|
|
52
|
+
if (typeof value === 'string') {
|
|
53
|
+
return value
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return JSON.stringify(value)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const toolName = (prefix: string | undefined, actionId: string) =>
|
|
60
|
+
prefix === undefined ? actionId : `${prefix}.${actionId}`
|
|
61
|
+
|
|
62
|
+
export const makeConnectorToolRegistration = <Context, Env = never, Error = never>(
|
|
63
|
+
connector: Connector<Env, Error>,
|
|
64
|
+
actionId: string,
|
|
65
|
+
options: MakeConnectorToolModuleOptions<Context, Env>
|
|
66
|
+
): ToolRegistration<Context> => {
|
|
67
|
+
const action = connector.actions.find(item => item.id === actionId)
|
|
68
|
+
const name = toolName(options.namePrefix, actionId)
|
|
69
|
+
|
|
70
|
+
return makeTool({
|
|
71
|
+
name,
|
|
72
|
+
description: action?.description ?? `Invoke connector action ${actionId}.`,
|
|
73
|
+
parameters: action?.inputSchema ?? Schema.Unknown,
|
|
74
|
+
access: resolveAccess(options.access, actionId),
|
|
75
|
+
invalidParamsMessage: error => `Invalid ${name} arguments: ${unknownToMessage(error)}`,
|
|
76
|
+
execute: ({ call, context, params }) =>
|
|
77
|
+
resolveIntegration(options.integration, context).pipe(
|
|
78
|
+
Effect.flatMap(integration =>
|
|
79
|
+
connector.invoke({
|
|
80
|
+
integration,
|
|
81
|
+
action: actionId,
|
|
82
|
+
input: params
|
|
83
|
+
}).pipe(Effect.provide(options.layer))
|
|
84
|
+
),
|
|
85
|
+
Effect.map(result => {
|
|
86
|
+
switch (result._tag) {
|
|
87
|
+
case 'Success':
|
|
88
|
+
return ToolResult.make({
|
|
89
|
+
toolCallId: call.id,
|
|
90
|
+
content: successContent(result.value),
|
|
91
|
+
structuredContent: result.value
|
|
92
|
+
})
|
|
93
|
+
case 'Failure':
|
|
94
|
+
return ToolResult.make({
|
|
95
|
+
toolCallId: call.id,
|
|
96
|
+
content: failureContent(result.error),
|
|
97
|
+
isError: true,
|
|
98
|
+
structuredContent: result.error
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
}),
|
|
102
|
+
Effect.mapError(
|
|
103
|
+
error =>
|
|
104
|
+
new ToolError({
|
|
105
|
+
tool: name,
|
|
106
|
+
message: unknownToMessage(error),
|
|
107
|
+
cause: 'execution'
|
|
108
|
+
})
|
|
109
|
+
)
|
|
110
|
+
)
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export const makeConnectorToolModule = <Context, Env = never, Error = never>(
|
|
115
|
+
connector: Connector<Env, Error>,
|
|
116
|
+
options: MakeConnectorToolModuleOptions<Context, Env>
|
|
117
|
+
): ToolModule<Context> => ({
|
|
118
|
+
id: options.moduleId ?? connector.id,
|
|
119
|
+
tools: connector.actions.map(action => makeConnectorToolRegistration(connector, action.id, options))
|
|
120
|
+
})
|
package/src/config.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Effect } from 'effect'
|
|
2
|
+
import { ConnectorError } from './error.ts'
|
|
3
|
+
import type { ConnectorIntegration } from './integration.ts'
|
|
4
|
+
|
|
5
|
+
const configValue = (integration: ConnectorIntegration, key: string) =>
|
|
6
|
+
Object.getOwnPropertyDescriptor(integration.config, key)?.value
|
|
7
|
+
|
|
8
|
+
export const requiredStringConfig = (integration: ConnectorIntegration, key: string) => {
|
|
9
|
+
const value = configValue(integration, key)
|
|
10
|
+
|
|
11
|
+
if (typeof value === 'string' && value.trim() !== '') {
|
|
12
|
+
return Effect.succeed(value)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return Effect.fail(
|
|
16
|
+
new ConnectorError({
|
|
17
|
+
cause: 'validation_failed',
|
|
18
|
+
message: `Missing integration config: ${key}`,
|
|
19
|
+
connectorId: integration.connectorId
|
|
20
|
+
})
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const optionalStringConfig = (integration: ConnectorIntegration, key: string) => {
|
|
25
|
+
const value = configValue(integration, key)
|
|
26
|
+
|
|
27
|
+
return typeof value === 'string' && value.trim() !== '' ? value : undefined
|
|
28
|
+
}
|