@letsping/adapters 0.1.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.
@@ -0,0 +1,19 @@
1
+ import { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import { z } from 'zod';
3
+
4
+ interface AdapterOptions<T extends z.ZodType> {
5
+ name: string;
6
+ description: string;
7
+ schema: T;
8
+ apiKey: string;
9
+ service?: string;
10
+ priority?: "low" | "medium" | "high" | "critical";
11
+ timeout?: number;
12
+ }
13
+ /**
14
+ * Creates a LangChain Tool that pauses execution for human approval.
15
+ * Compatible with LangGraph and standard Agents.
16
+ */
17
+ declare function createLetsPingTool<T extends z.ZodType>(options: AdapterOptions<T>): DynamicStructuredTool<any>;
18
+
19
+ export { createLetsPingTool };
@@ -0,0 +1,19 @@
1
+ import { DynamicStructuredTool } from '@langchain/core/tools';
2
+ import { z } from 'zod';
3
+
4
+ interface AdapterOptions<T extends z.ZodType> {
5
+ name: string;
6
+ description: string;
7
+ schema: T;
8
+ apiKey: string;
9
+ service?: string;
10
+ priority?: "low" | "medium" | "high" | "critical";
11
+ timeout?: number;
12
+ }
13
+ /**
14
+ * Creates a LangChain Tool that pauses execution for human approval.
15
+ * Compatible with LangGraph and standard Agents.
16
+ */
17
+ declare function createLetsPingTool<T extends z.ZodType>(options: AdapterOptions<T>): DynamicStructuredTool<any>;
18
+
19
+ export { createLetsPingTool };
@@ -0,0 +1,73 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/langchain.ts
21
+ var langchain_exports = {};
22
+ __export(langchain_exports, {
23
+ createLetsPingTool: () => createLetsPingTool
24
+ });
25
+ module.exports = __toCommonJS(langchain_exports);
26
+ var import_tools = require("@langchain/core/tools");
27
+ var import_sdk = require("@letsping/sdk");
28
+ function createLetsPingTool(options) {
29
+ if (!options.apiKey) {
30
+ throw new Error("LetsPing Adapter Error: 'apiKey' is required.");
31
+ }
32
+ const lp = new import_sdk.LetsPing(options.apiKey);
33
+ return new import_tools.DynamicStructuredTool({
34
+ name: options.name,
35
+ description: `${options.description} [SYSTEM NOTE: This tool pauses execution until a human approves the request via LetsPing. Do not expect an immediate result.]`,
36
+ schema: options.schema,
37
+ func: async (args) => {
38
+ try {
39
+ const decision = await lp.ask({
40
+ service: options.service || "langchain-agent",
41
+ action: options.name,
42
+ priority: options.priority || "medium",
43
+ payload: args,
44
+ schema: options.schema,
45
+ timeoutMs: options.timeout
46
+ });
47
+ if (decision.status === "REJECTED") {
48
+ return JSON.stringify({
49
+ status: "REJECTED",
50
+ message: "The human operator denied this request. Do not proceed with the action.",
51
+ metadata: decision.metadata
52
+ });
53
+ }
54
+ return JSON.stringify({
55
+ status: "APPROVED",
56
+ approved_input: decision.patched_payload || decision.payload,
57
+ metadata: decision.metadata
58
+ });
59
+ } catch (error) {
60
+ return JSON.stringify({
61
+ status: "ERROR",
62
+ error: error.message || "Unknown error during LetsPing approval process",
63
+ suggestion: "Inform the user that the request for approval failed or timed out."
64
+ });
65
+ }
66
+ }
67
+ });
68
+ }
69
+ // Annotate the CommonJS export names for ESM import in node:
70
+ 0 && (module.exports = {
71
+ createLetsPingTool
72
+ });
73
+ //# sourceMappingURL=langchain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langchain.ts"],"sourcesContent":["import { DynamicStructuredTool } from \"@langchain/core/tools\";\r\nimport { LetsPing } from \"@letsping/sdk\";\r\nimport { z } from \"zod\";\r\n\r\ninterface AdapterOptions<T extends z.ZodType> {\r\n name: string;\r\n description: string;\r\n schema: T;\r\n apiKey: string;\r\n service?: string;\r\n priority?: \"low\" | \"medium\" | \"high\" | \"critical\";\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Creates a LangChain Tool that pauses execution for human approval.\r\n * Compatible with LangGraph and standard Agents.\r\n */\r\nexport function createLetsPingTool<T extends z.ZodType>(options: AdapterOptions<T>) {\r\n if (!options.apiKey) {\r\n throw new Error(\"LetsPing Adapter Error: 'apiKey' is required.\");\r\n }\r\n\r\n const lp = new LetsPing(options.apiKey);\r\n\r\n return new DynamicStructuredTool({\r\n name: options.name,\r\n description: `${options.description} [SYSTEM NOTE: This tool pauses execution until a human approves the request via LetsPing. Do not expect an immediate result.]`,\r\n schema: options.schema as any,\r\n func: async (args: any) => {\r\n try {\r\n const decision = await lp.ask({\r\n service: options.service || \"langchain-agent\",\r\n action: options.name,\r\n priority: options.priority || \"medium\",\r\n payload: args,\r\n schema: options.schema,\r\n timeoutMs: options.timeout\r\n });\r\n\r\n if (decision.status === \"REJECTED\") {\r\n return JSON.stringify({\r\n status: \"REJECTED\",\r\n message: \"The human operator denied this request. Do not proceed with the action.\",\r\n metadata: decision.metadata\r\n });\r\n }\r\n\r\n return JSON.stringify({\r\n status: \"APPROVED\",\r\n approved_input: decision.patched_payload || decision.payload,\r\n metadata: decision.metadata\r\n });\r\n\r\n } catch (error: any) {\r\n return JSON.stringify({\r\n status: \"ERROR\",\r\n error: error.message || \"Unknown error during LetsPing approval process\",\r\n suggestion: \"Inform the user that the request for approval failed or timed out.\"\r\n });\r\n }\r\n }\r\n });\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,mBAAsC;AACtC,iBAAyB;AAiBlB,SAAS,mBAAwC,SAA4B;AAChF,MAAI,CAAC,QAAQ,QAAQ;AACjB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACnE;AAEA,QAAM,KAAK,IAAI,oBAAS,QAAQ,MAAM;AAEtC,SAAO,IAAI,mCAAsB;AAAA,IAC7B,MAAM,QAAQ;AAAA,IACd,aAAa,GAAG,QAAQ,WAAW;AAAA,IACnC,QAAQ,QAAQ;AAAA,IAChB,MAAM,OAAO,SAAc;AACvB,UAAI;AACA,cAAM,WAAW,MAAM,GAAG,IAAI;AAAA,UAC1B,SAAS,QAAQ,WAAW;AAAA,UAC5B,QAAQ,QAAQ;AAAA,UAChB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,QAAQ,QAAQ;AAAA,UAChB,WAAW,QAAQ;AAAA,QACvB,CAAC;AAED,YAAI,SAAS,WAAW,YAAY;AAChC,iBAAO,KAAK,UAAU;AAAA,YAClB,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU,SAAS;AAAA,UACvB,CAAC;AAAA,QACL;AAEA,eAAO,KAAK,UAAU;AAAA,UAClB,QAAQ;AAAA,UACR,gBAAgB,SAAS,mBAAmB,SAAS;AAAA,UACrD,UAAU,SAAS;AAAA,QACvB,CAAC;AAAA,MAEL,SAAS,OAAY;AACjB,eAAO,KAAK,UAAU;AAAA,UAClB,QAAQ;AAAA,UACR,OAAO,MAAM,WAAW;AAAA,UACxB,YAAY;AAAA,QAChB,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ,CAAC;AACL;","names":[]}
@@ -0,0 +1,48 @@
1
+ // src/langchain.ts
2
+ import { DynamicStructuredTool } from "@langchain/core/tools";
3
+ import { LetsPing } from "@letsping/sdk";
4
+ function createLetsPingTool(options) {
5
+ if (!options.apiKey) {
6
+ throw new Error("LetsPing Adapter Error: 'apiKey' is required.");
7
+ }
8
+ const lp = new LetsPing(options.apiKey);
9
+ return new DynamicStructuredTool({
10
+ name: options.name,
11
+ description: `${options.description} [SYSTEM NOTE: This tool pauses execution until a human approves the request via LetsPing. Do not expect an immediate result.]`,
12
+ schema: options.schema,
13
+ func: async (args) => {
14
+ try {
15
+ const decision = await lp.ask({
16
+ service: options.service || "langchain-agent",
17
+ action: options.name,
18
+ priority: options.priority || "medium",
19
+ payload: args,
20
+ schema: options.schema,
21
+ timeoutMs: options.timeout
22
+ });
23
+ if (decision.status === "REJECTED") {
24
+ return JSON.stringify({
25
+ status: "REJECTED",
26
+ message: "The human operator denied this request. Do not proceed with the action.",
27
+ metadata: decision.metadata
28
+ });
29
+ }
30
+ return JSON.stringify({
31
+ status: "APPROVED",
32
+ approved_input: decision.patched_payload || decision.payload,
33
+ metadata: decision.metadata
34
+ });
35
+ } catch (error) {
36
+ return JSON.stringify({
37
+ status: "ERROR",
38
+ error: error.message || "Unknown error during LetsPing approval process",
39
+ suggestion: "Inform the user that the request for approval failed or timed out."
40
+ });
41
+ }
42
+ }
43
+ });
44
+ }
45
+ export {
46
+ createLetsPingTool
47
+ };
48
+ //# sourceMappingURL=langchain.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/langchain.ts"],"sourcesContent":["import { DynamicStructuredTool } from \"@langchain/core/tools\";\r\nimport { LetsPing } from \"@letsping/sdk\";\r\nimport { z } from \"zod\";\r\n\r\ninterface AdapterOptions<T extends z.ZodType> {\r\n name: string;\r\n description: string;\r\n schema: T;\r\n apiKey: string;\r\n service?: string;\r\n priority?: \"low\" | \"medium\" | \"high\" | \"critical\";\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Creates a LangChain Tool that pauses execution for human approval.\r\n * Compatible with LangGraph and standard Agents.\r\n */\r\nexport function createLetsPingTool<T extends z.ZodType>(options: AdapterOptions<T>) {\r\n if (!options.apiKey) {\r\n throw new Error(\"LetsPing Adapter Error: 'apiKey' is required.\");\r\n }\r\n\r\n const lp = new LetsPing(options.apiKey);\r\n\r\n return new DynamicStructuredTool({\r\n name: options.name,\r\n description: `${options.description} [SYSTEM NOTE: This tool pauses execution until a human approves the request via LetsPing. Do not expect an immediate result.]`,\r\n schema: options.schema as any,\r\n func: async (args: any) => {\r\n try {\r\n const decision = await lp.ask({\r\n service: options.service || \"langchain-agent\",\r\n action: options.name,\r\n priority: options.priority || \"medium\",\r\n payload: args,\r\n schema: options.schema,\r\n timeoutMs: options.timeout\r\n });\r\n\r\n if (decision.status === \"REJECTED\") {\r\n return JSON.stringify({\r\n status: \"REJECTED\",\r\n message: \"The human operator denied this request. Do not proceed with the action.\",\r\n metadata: decision.metadata\r\n });\r\n }\r\n\r\n return JSON.stringify({\r\n status: \"APPROVED\",\r\n approved_input: decision.patched_payload || decision.payload,\r\n metadata: decision.metadata\r\n });\r\n\r\n } catch (error: any) {\r\n return JSON.stringify({\r\n status: \"ERROR\",\r\n error: error.message || \"Unknown error during LetsPing approval process\",\r\n suggestion: \"Inform the user that the request for approval failed or timed out.\"\r\n });\r\n }\r\n }\r\n });\r\n}"],"mappings":";AAAA,SAAS,6BAA6B;AACtC,SAAS,gBAAgB;AAiBlB,SAAS,mBAAwC,SAA4B;AAChF,MAAI,CAAC,QAAQ,QAAQ;AACjB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACnE;AAEA,QAAM,KAAK,IAAI,SAAS,QAAQ,MAAM;AAEtC,SAAO,IAAI,sBAAsB;AAAA,IAC7B,MAAM,QAAQ;AAAA,IACd,aAAa,GAAG,QAAQ,WAAW;AAAA,IACnC,QAAQ,QAAQ;AAAA,IAChB,MAAM,OAAO,SAAc;AACvB,UAAI;AACA,cAAM,WAAW,MAAM,GAAG,IAAI;AAAA,UAC1B,SAAS,QAAQ,WAAW;AAAA,UAC5B,QAAQ,QAAQ;AAAA,UAChB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,QAAQ,QAAQ;AAAA,UAChB,WAAW,QAAQ;AAAA,QACvB,CAAC;AAED,YAAI,SAAS,WAAW,YAAY;AAChC,iBAAO,KAAK,UAAU;AAAA,YAClB,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU,SAAS;AAAA,UACvB,CAAC;AAAA,QACL;AAEA,eAAO,KAAK,UAAU;AAAA,UAClB,QAAQ;AAAA,UACR,gBAAgB,SAAS,mBAAmB,SAAS;AAAA,UACrD,UAAU,SAAS;AAAA,QACvB,CAAC;AAAA,MAEL,SAAS,OAAY;AACjB,eAAO,KAAK,UAAU;AAAA,UAClB,QAAQ;AAAA,UACR,OAAO,MAAM,WAAW;AAAA,UACxB,YAAY;AAAA,QAChB,CAAC;AAAA,MACL;AAAA,IACJ;AAAA,EACJ,CAAC;AACL;","names":[]}
@@ -0,0 +1,101 @@
1
+ import * as ai from 'ai';
2
+ import { z } from 'zod';
3
+
4
+ interface AdapterOptions<T extends z.ZodType> {
5
+ name: string;
6
+ description: string;
7
+ schema: T;
8
+ apiKey: string;
9
+ service?: string;
10
+ priority?: "low" | "medium" | "high" | "critical";
11
+ timeout?: number;
12
+ }
13
+ /**
14
+ * Creates a Vercel AI SDK Tool that pauses execution for human approval.
15
+ * @example
16
+ * const tools = {
17
+ * refund: letsPing({
18
+ * name: "refund_user",
19
+ * description: "Refund a user transaction",
20
+ * schema: z.object({ amount: z.number() }),
21
+ * apiKey: process.env.LETSPING_API_KEY!
22
+ * })
23
+ * }
24
+ */
25
+ declare function letsPing<T extends z.ZodType>(options: AdapterOptions<T>): ai.CoreTool<T, {
26
+ status: string;
27
+ message: string;
28
+ metadata: {
29
+ resolved_at: string;
30
+ actor_id: string;
31
+ method?: string;
32
+ } | undefined;
33
+ rejection_reason: any;
34
+ original_input?: undefined;
35
+ approved_input?: undefined;
36
+ error?: undefined;
37
+ suggestion?: undefined;
38
+ } | {
39
+ status: string;
40
+ original_input: T extends ai.Schema<any> ? T["_type"] : T extends z.ZodTypeAny ? z.TypeOf<T> : never;
41
+ approved_input: any;
42
+ metadata: {
43
+ resolved_at: string;
44
+ actor_id: string;
45
+ method?: string;
46
+ } | undefined;
47
+ message?: undefined;
48
+ rejection_reason?: undefined;
49
+ error?: undefined;
50
+ suggestion?: undefined;
51
+ } | {
52
+ status: string;
53
+ error: any;
54
+ suggestion: string;
55
+ message?: undefined;
56
+ metadata?: undefined;
57
+ rejection_reason?: undefined;
58
+ original_input?: undefined;
59
+ approved_input?: undefined;
60
+ }> & {
61
+ execute: (args: T extends ai.Schema<any> ? T["_type"] : T extends z.ZodTypeAny ? z.TypeOf<T> : never, options: {
62
+ abortSignal?: AbortSignal;
63
+ }) => PromiseLike<{
64
+ status: string;
65
+ message: string;
66
+ metadata: {
67
+ resolved_at: string;
68
+ actor_id: string;
69
+ method?: string;
70
+ } | undefined;
71
+ rejection_reason: any;
72
+ original_input?: undefined;
73
+ approved_input?: undefined;
74
+ error?: undefined;
75
+ suggestion?: undefined;
76
+ } | {
77
+ status: string;
78
+ original_input: T extends ai.Schema<any> ? T["_type"] : T extends z.ZodTypeAny ? z.TypeOf<T> : never;
79
+ approved_input: any;
80
+ metadata: {
81
+ resolved_at: string;
82
+ actor_id: string;
83
+ method?: string;
84
+ } | undefined;
85
+ message?: undefined;
86
+ rejection_reason?: undefined;
87
+ error?: undefined;
88
+ suggestion?: undefined;
89
+ } | {
90
+ status: string;
91
+ error: any;
92
+ suggestion: string;
93
+ message?: undefined;
94
+ metadata?: undefined;
95
+ rejection_reason?: undefined;
96
+ original_input?: undefined;
97
+ approved_input?: undefined;
98
+ }>;
99
+ };
100
+
101
+ export { letsPing };
@@ -0,0 +1,101 @@
1
+ import * as ai from 'ai';
2
+ import { z } from 'zod';
3
+
4
+ interface AdapterOptions<T extends z.ZodType> {
5
+ name: string;
6
+ description: string;
7
+ schema: T;
8
+ apiKey: string;
9
+ service?: string;
10
+ priority?: "low" | "medium" | "high" | "critical";
11
+ timeout?: number;
12
+ }
13
+ /**
14
+ * Creates a Vercel AI SDK Tool that pauses execution for human approval.
15
+ * @example
16
+ * const tools = {
17
+ * refund: letsPing({
18
+ * name: "refund_user",
19
+ * description: "Refund a user transaction",
20
+ * schema: z.object({ amount: z.number() }),
21
+ * apiKey: process.env.LETSPING_API_KEY!
22
+ * })
23
+ * }
24
+ */
25
+ declare function letsPing<T extends z.ZodType>(options: AdapterOptions<T>): ai.CoreTool<T, {
26
+ status: string;
27
+ message: string;
28
+ metadata: {
29
+ resolved_at: string;
30
+ actor_id: string;
31
+ method?: string;
32
+ } | undefined;
33
+ rejection_reason: any;
34
+ original_input?: undefined;
35
+ approved_input?: undefined;
36
+ error?: undefined;
37
+ suggestion?: undefined;
38
+ } | {
39
+ status: string;
40
+ original_input: T extends ai.Schema<any> ? T["_type"] : T extends z.ZodTypeAny ? z.TypeOf<T> : never;
41
+ approved_input: any;
42
+ metadata: {
43
+ resolved_at: string;
44
+ actor_id: string;
45
+ method?: string;
46
+ } | undefined;
47
+ message?: undefined;
48
+ rejection_reason?: undefined;
49
+ error?: undefined;
50
+ suggestion?: undefined;
51
+ } | {
52
+ status: string;
53
+ error: any;
54
+ suggestion: string;
55
+ message?: undefined;
56
+ metadata?: undefined;
57
+ rejection_reason?: undefined;
58
+ original_input?: undefined;
59
+ approved_input?: undefined;
60
+ }> & {
61
+ execute: (args: T extends ai.Schema<any> ? T["_type"] : T extends z.ZodTypeAny ? z.TypeOf<T> : never, options: {
62
+ abortSignal?: AbortSignal;
63
+ }) => PromiseLike<{
64
+ status: string;
65
+ message: string;
66
+ metadata: {
67
+ resolved_at: string;
68
+ actor_id: string;
69
+ method?: string;
70
+ } | undefined;
71
+ rejection_reason: any;
72
+ original_input?: undefined;
73
+ approved_input?: undefined;
74
+ error?: undefined;
75
+ suggestion?: undefined;
76
+ } | {
77
+ status: string;
78
+ original_input: T extends ai.Schema<any> ? T["_type"] : T extends z.ZodTypeAny ? z.TypeOf<T> : never;
79
+ approved_input: any;
80
+ metadata: {
81
+ resolved_at: string;
82
+ actor_id: string;
83
+ method?: string;
84
+ } | undefined;
85
+ message?: undefined;
86
+ rejection_reason?: undefined;
87
+ error?: undefined;
88
+ suggestion?: undefined;
89
+ } | {
90
+ status: string;
91
+ error: any;
92
+ suggestion: string;
93
+ message?: undefined;
94
+ metadata?: undefined;
95
+ rejection_reason?: undefined;
96
+ original_input?: undefined;
97
+ approved_input?: undefined;
98
+ }>;
99
+ };
100
+
101
+ export { letsPing };
package/dist/vercel.js ADDED
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/vercel.ts
21
+ var vercel_exports = {};
22
+ __export(vercel_exports, {
23
+ letsPing: () => letsPing
24
+ });
25
+ module.exports = __toCommonJS(vercel_exports);
26
+ var import_ai = require("ai");
27
+ var import_sdk = require("@letsping/sdk");
28
+ function letsPing(options) {
29
+ if (!options.apiKey) {
30
+ throw new Error("LetsPing Adapter Error: 'apiKey' is required.");
31
+ }
32
+ const lp = new import_sdk.LetsPing(options.apiKey);
33
+ return (0, import_ai.tool)({
34
+ description: `${options.description} [SYSTEM NOTE: This tool pauses execution to wait for human approval. Do not expect an immediate result.]`,
35
+ parameters: options.schema,
36
+ execute: async (args) => {
37
+ try {
38
+ const decision = await lp.ask({
39
+ service: options.service || "vercel-ai-sdk",
40
+ action: options.name,
41
+ priority: options.priority || "medium",
42
+ payload: args,
43
+ schema: options.schema,
44
+ timeoutMs: options.timeout
45
+ });
46
+ if (decision.status === "REJECTED") {
47
+ return {
48
+ status: "REJECTED",
49
+ message: "The human operator explicitly denied this action. Do not proceed.",
50
+ metadata: decision.metadata,
51
+ rejection_reason: decision.rejection_reason || "No reason provided"
52
+ };
53
+ }
54
+ return {
55
+ status: "APPROVED",
56
+ original_input: args,
57
+ approved_input: decision.patched_payload || decision.payload,
58
+ metadata: decision.metadata
59
+ };
60
+ } catch (error) {
61
+ return {
62
+ status: "ERROR",
63
+ error: error.message || "Control plane unreachable or request timed out.",
64
+ suggestion: "Inform the user that the request for approval failed."
65
+ };
66
+ }
67
+ }
68
+ });
69
+ }
70
+ // Annotate the CommonJS export names for ESM import in node:
71
+ 0 && (module.exports = {
72
+ letsPing
73
+ });
74
+ //# sourceMappingURL=vercel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vercel.ts"],"sourcesContent":["import { tool as createVercelTool } from \"ai\";\r\nimport { LetsPing } from \"@letsping/sdk\";\r\nimport { z } from \"zod\";\r\n\r\ninterface AdapterOptions<T extends z.ZodType> {\r\n name: string;\r\n description: string;\r\n schema: T;\r\n apiKey: string;\r\n service?: string;\r\n priority?: \"low\" | \"medium\" | \"high\" | \"critical\";\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Creates a Vercel AI SDK Tool that pauses execution for human approval.\r\n * @example\r\n * const tools = {\r\n * refund: letsPing({\r\n * name: \"refund_user\",\r\n * description: \"Refund a user transaction\",\r\n * schema: z.object({ amount: z.number() }),\r\n * apiKey: process.env.LETSPING_API_KEY!\r\n * })\r\n * }\r\n */\r\nexport function letsPing<T extends z.ZodType>(options: AdapterOptions<T>) {\r\n if (!options.apiKey) {\r\n throw new Error(\"LetsPing Adapter Error: 'apiKey' is required.\");\r\n }\r\n\r\n const lp = new LetsPing(options.apiKey);\r\n\r\n return createVercelTool({\r\n description: `${options.description} [SYSTEM NOTE: This tool pauses execution to wait for human approval. Do not expect an immediate result.]`,\r\n parameters: options.schema,\r\n execute: async (args) => {\r\n try {\r\n const decision = await lp.ask({\r\n service: options.service || \"vercel-ai-sdk\",\r\n action: options.name,\r\n priority: options.priority || \"medium\",\r\n payload: args,\r\n schema: options.schema,\r\n timeoutMs: options.timeout\r\n });\r\n\r\n if (decision.status === \"REJECTED\") {\r\n return {\r\n status: \"REJECTED\",\r\n message: \"The human operator explicitly denied this action. Do not proceed.\",\r\n metadata: decision.metadata,\r\n rejection_reason: (decision as any).rejection_reason || \"No reason provided\"\r\n };\r\n }\r\n\r\n return {\r\n status: \"APPROVED\",\r\n original_input: args,\r\n approved_input: decision.patched_payload || decision.payload,\r\n metadata: decision.metadata\r\n };\r\n\r\n } catch (error: any) {\r\n return {\r\n status: \"ERROR\",\r\n error: error.message || \"Control plane unreachable or request timed out.\",\r\n suggestion: \"Inform the user that the request for approval failed.\"\r\n };\r\n }\r\n },\r\n });\r\n}"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,gBAAyC;AACzC,iBAAyB;AAyBlB,SAAS,SAA8B,SAA4B;AACtE,MAAI,CAAC,QAAQ,QAAQ;AACjB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACnE;AAEA,QAAM,KAAK,IAAI,oBAAS,QAAQ,MAAM;AAEtC,aAAO,UAAAA,MAAiB;AAAA,IACpB,aAAa,GAAG,QAAQ,WAAW;AAAA,IACnC,YAAY,QAAQ;AAAA,IACpB,SAAS,OAAO,SAAS;AACrB,UAAI;AACA,cAAM,WAAW,MAAM,GAAG,IAAI;AAAA,UAC1B,SAAS,QAAQ,WAAW;AAAA,UAC5B,QAAQ,QAAQ;AAAA,UAChB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,QAAQ,QAAQ;AAAA,UAChB,WAAW,QAAQ;AAAA,QACvB,CAAC;AAED,YAAI,SAAS,WAAW,YAAY;AAChC,iBAAO;AAAA,YACH,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU,SAAS;AAAA,YACnB,kBAAmB,SAAiB,oBAAoB;AAAA,UAC5D;AAAA,QACJ;AAEA,eAAO;AAAA,UACH,QAAQ;AAAA,UACR,gBAAgB;AAAA,UAChB,gBAAgB,SAAS,mBAAmB,SAAS;AAAA,UACrD,UAAU,SAAS;AAAA,QACvB;AAAA,MAEJ,SAAS,OAAY;AACjB,eAAO;AAAA,UACH,QAAQ;AAAA,UACR,OAAO,MAAM,WAAW;AAAA,UACxB,YAAY;AAAA,QAChB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,CAAC;AACL;","names":["createVercelTool"]}
@@ -0,0 +1,49 @@
1
+ // src/vercel.ts
2
+ import { tool as createVercelTool } from "ai";
3
+ import { LetsPing } from "@letsping/sdk";
4
+ function letsPing(options) {
5
+ if (!options.apiKey) {
6
+ throw new Error("LetsPing Adapter Error: 'apiKey' is required.");
7
+ }
8
+ const lp = new LetsPing(options.apiKey);
9
+ return createVercelTool({
10
+ description: `${options.description} [SYSTEM NOTE: This tool pauses execution to wait for human approval. Do not expect an immediate result.]`,
11
+ parameters: options.schema,
12
+ execute: async (args) => {
13
+ try {
14
+ const decision = await lp.ask({
15
+ service: options.service || "vercel-ai-sdk",
16
+ action: options.name,
17
+ priority: options.priority || "medium",
18
+ payload: args,
19
+ schema: options.schema,
20
+ timeoutMs: options.timeout
21
+ });
22
+ if (decision.status === "REJECTED") {
23
+ return {
24
+ status: "REJECTED",
25
+ message: "The human operator explicitly denied this action. Do not proceed.",
26
+ metadata: decision.metadata,
27
+ rejection_reason: decision.rejection_reason || "No reason provided"
28
+ };
29
+ }
30
+ return {
31
+ status: "APPROVED",
32
+ original_input: args,
33
+ approved_input: decision.patched_payload || decision.payload,
34
+ metadata: decision.metadata
35
+ };
36
+ } catch (error) {
37
+ return {
38
+ status: "ERROR",
39
+ error: error.message || "Control plane unreachable or request timed out.",
40
+ suggestion: "Inform the user that the request for approval failed."
41
+ };
42
+ }
43
+ }
44
+ });
45
+ }
46
+ export {
47
+ letsPing
48
+ };
49
+ //# sourceMappingURL=vercel.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/vercel.ts"],"sourcesContent":["import { tool as createVercelTool } from \"ai\";\r\nimport { LetsPing } from \"@letsping/sdk\";\r\nimport { z } from \"zod\";\r\n\r\ninterface AdapterOptions<T extends z.ZodType> {\r\n name: string;\r\n description: string;\r\n schema: T;\r\n apiKey: string;\r\n service?: string;\r\n priority?: \"low\" | \"medium\" | \"high\" | \"critical\";\r\n timeout?: number;\r\n}\r\n\r\n/**\r\n * Creates a Vercel AI SDK Tool that pauses execution for human approval.\r\n * @example\r\n * const tools = {\r\n * refund: letsPing({\r\n * name: \"refund_user\",\r\n * description: \"Refund a user transaction\",\r\n * schema: z.object({ amount: z.number() }),\r\n * apiKey: process.env.LETSPING_API_KEY!\r\n * })\r\n * }\r\n */\r\nexport function letsPing<T extends z.ZodType>(options: AdapterOptions<T>) {\r\n if (!options.apiKey) {\r\n throw new Error(\"LetsPing Adapter Error: 'apiKey' is required.\");\r\n }\r\n\r\n const lp = new LetsPing(options.apiKey);\r\n\r\n return createVercelTool({\r\n description: `${options.description} [SYSTEM NOTE: This tool pauses execution to wait for human approval. Do not expect an immediate result.]`,\r\n parameters: options.schema,\r\n execute: async (args) => {\r\n try {\r\n const decision = await lp.ask({\r\n service: options.service || \"vercel-ai-sdk\",\r\n action: options.name,\r\n priority: options.priority || \"medium\",\r\n payload: args,\r\n schema: options.schema,\r\n timeoutMs: options.timeout\r\n });\r\n\r\n if (decision.status === \"REJECTED\") {\r\n return {\r\n status: \"REJECTED\",\r\n message: \"The human operator explicitly denied this action. Do not proceed.\",\r\n metadata: decision.metadata,\r\n rejection_reason: (decision as any).rejection_reason || \"No reason provided\"\r\n };\r\n }\r\n\r\n return {\r\n status: \"APPROVED\",\r\n original_input: args,\r\n approved_input: decision.patched_payload || decision.payload,\r\n metadata: decision.metadata\r\n };\r\n\r\n } catch (error: any) {\r\n return {\r\n status: \"ERROR\",\r\n error: error.message || \"Control plane unreachable or request timed out.\",\r\n suggestion: \"Inform the user that the request for approval failed.\"\r\n };\r\n }\r\n },\r\n });\r\n}"],"mappings":";AAAA,SAAS,QAAQ,wBAAwB;AACzC,SAAS,gBAAgB;AAyBlB,SAAS,SAA8B,SAA4B;AACtE,MAAI,CAAC,QAAQ,QAAQ;AACjB,UAAM,IAAI,MAAM,+CAA+C;AAAA,EACnE;AAEA,QAAM,KAAK,IAAI,SAAS,QAAQ,MAAM;AAEtC,SAAO,iBAAiB;AAAA,IACpB,aAAa,GAAG,QAAQ,WAAW;AAAA,IACnC,YAAY,QAAQ;AAAA,IACpB,SAAS,OAAO,SAAS;AACrB,UAAI;AACA,cAAM,WAAW,MAAM,GAAG,IAAI;AAAA,UAC1B,SAAS,QAAQ,WAAW;AAAA,UAC5B,QAAQ,QAAQ;AAAA,UAChB,UAAU,QAAQ,YAAY;AAAA,UAC9B,SAAS;AAAA,UACT,QAAQ,QAAQ;AAAA,UAChB,WAAW,QAAQ;AAAA,QACvB,CAAC;AAED,YAAI,SAAS,WAAW,YAAY;AAChC,iBAAO;AAAA,YACH,QAAQ;AAAA,YACR,SAAS;AAAA,YACT,UAAU,SAAS;AAAA,YACnB,kBAAmB,SAAiB,oBAAoB;AAAA,UAC5D;AAAA,QACJ;AAEA,eAAO;AAAA,UACH,QAAQ;AAAA,UACR,gBAAgB;AAAA,UAChB,gBAAgB,SAAS,mBAAmB,SAAS;AAAA,UACrD,UAAU,SAAS;AAAA,QACvB;AAAA,MAEJ,SAAS,OAAY;AACjB,eAAO;AAAA,UACH,QAAQ;AAAA,UACR,OAAO,MAAM,WAAW;AAAA,UACxB,YAAY;AAAA,QAChB;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ,CAAC;AACL;","names":[]}
package/package.json ADDED
@@ -0,0 +1,44 @@
1
+ {
2
+ "name": "@letsping/adapters",
3
+ "version": "0.1.0",
4
+ "description": "Drop-in Human-in-the-Loop adapters for Vercel AI SDK and LangChain",
5
+ "files": [
6
+ "dist"
7
+ ],
8
+ "exports": {
9
+ "./vercel": {
10
+ "types": "./dist/vercel.d.ts",
11
+ "import": "./dist/vercel.js",
12
+ "require": "./dist/vercel.js"
13
+ },
14
+ "./langchain": {
15
+ "types": "./dist/langchain.d.ts",
16
+ "import": "./dist/langchain.js",
17
+ "require": "./dist/langchain.js"
18
+ }
19
+ },
20
+ "scripts": {
21
+ "build": "tsup",
22
+ "dev": "tsup --watch",
23
+ "clean": "rm -rf dist .turbo"
24
+ },
25
+ "peerDependencies": {
26
+ "@langchain/core": ">=0.1.0",
27
+ "ai": ">=2.0.0",
28
+ "zod": ">=3.0.0"
29
+ },
30
+ "dependencies": {
31
+ "@letsping/sdk": "^0.1.0"
32
+ },
33
+ "devDependencies": {
34
+ "tsup": "^8.0.0",
35
+ "typescript": "^5.0.0",
36
+ "@types/node": "^20.0.0",
37
+ "ai": "^3.0.0",
38
+ "@langchain/core": "^0.1.0",
39
+ "zod": "^3.0.0"
40
+ },
41
+ "publishConfig": {
42
+ "access": "public"
43
+ }
44
+ }