@msg91comm/m91 1.1.0 → 1.2.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +241 -19
  3. package/dist/src/index.d.ts +1 -1
  4. package/dist/src/index.js +1 -1
  5. package/dist/src/integrations/claude-agent-sdk.d.ts +63 -0
  6. package/dist/src/integrations/claude-agent-sdk.d.ts.map +1 -0
  7. package/dist/src/integrations/claude-agent-sdk.js +109 -0
  8. package/dist/src/integrations/claude-agent-sdk.js.map +1 -0
  9. package/dist/src/integrations/google-adk.d.ts +47 -0
  10. package/dist/src/integrations/google-adk.d.ts.map +1 -0
  11. package/dist/src/integrations/google-adk.js +84 -0
  12. package/dist/src/integrations/google-adk.js.map +1 -0
  13. package/dist/src/integrations/index.d.ts +7 -3
  14. package/dist/src/integrations/index.d.ts.map +1 -1
  15. package/dist/src/integrations/index.js +6 -2
  16. package/dist/src/integrations/index.js.map +1 -1
  17. package/dist/src/integrations/langchain.d.ts +56 -5
  18. package/dist/src/integrations/langchain.d.ts.map +1 -1
  19. package/dist/src/integrations/langchain.js +56 -2
  20. package/dist/src/integrations/langchain.js.map +1 -1
  21. package/dist/src/integrations/mastra.d.ts +75 -0
  22. package/dist/src/integrations/mastra.d.ts.map +1 -0
  23. package/dist/src/integrations/mastra.js +109 -0
  24. package/dist/src/integrations/mastra.js.map +1 -0
  25. package/dist/src/integrations/openai-agents.d.ts +61 -0
  26. package/dist/src/integrations/openai-agents.d.ts.map +1 -0
  27. package/dist/src/integrations/openai-agents.js +127 -0
  28. package/dist/src/integrations/openai-agents.js.map +1 -0
  29. package/dist/src/integrations/specs.d.ts +42 -0
  30. package/dist/src/integrations/specs.d.ts.map +1 -1
  31. package/dist/src/integrations/specs.js +61 -0
  32. package/dist/src/integrations/specs.js.map +1 -1
  33. package/dist/src/integrations/vercel-ai.d.ts +44 -6
  34. package/dist/src/integrations/vercel-ai.d.ts.map +1 -1
  35. package/dist/src/integrations/vercel-ai.js +38 -3
  36. package/dist/src/integrations/vercel-ai.js.map +1 -1
  37. package/dist/src/integrations/zod-shapes.d.ts +19 -0
  38. package/dist/src/integrations/zod-shapes.d.ts.map +1 -0
  39. package/dist/src/integrations/zod-shapes.js +44 -0
  40. package/dist/src/integrations/zod-shapes.js.map +1 -0
  41. package/dist/src/platform.d.ts +1 -1
  42. package/dist/src/platform.d.ts.map +1 -1
  43. package/dist/src/platform.js +1 -1
  44. package/dist/src/platform.js.map +1 -1
  45. package/dist/src/url-builder.js +1 -1
  46. package/dist/src/url-builder.js.map +1 -1
  47. package/examples/basic-alert.ts +1 -1
  48. package/examples/claude-agent-sdk.ts +23 -0
  49. package/examples/deep-agents.ts +31 -0
  50. package/examples/google-adk.ts +39 -0
  51. package/examples/mastra.ts +41 -0
  52. package/examples/openai-agents.ts +33 -0
  53. package/examples/webhook-urls.ts +1 -1
  54. package/package.json +63 -11
  55. package/src/index.ts +1 -1
  56. package/src/integrations/claude-agent-sdk.ts +158 -0
  57. package/src/integrations/google-adk.ts +122 -0
  58. package/src/integrations/index.ts +7 -3
  59. package/src/integrations/langchain.ts +109 -6
  60. package/src/integrations/mastra.ts +178 -0
  61. package/src/integrations/openai-agents.ts +173 -0
  62. package/src/integrations/specs.ts +104 -0
  63. package/src/integrations/vercel-ai.ts +59 -7
  64. package/src/integrations/zod-shapes.ts +55 -0
  65. package/src/platform.ts +1 -1
  66. package/src/url-builder.ts +1 -1
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Google Agent Development Kit for TypeScript (`@google/adk`): M91 as a
3
+ * before-tool gate, and M91 as tools.
4
+ *
5
+ * **Gate.** `createM91BeforeToolCallback` goes in an `LlmAgent`'s
6
+ * `beforeToolCallback`. Calls to the tools you name ring a phone first; if the
7
+ * person rejects (or does not answer), the tool does not run and the agent
8
+ * gets the reason back as the tool's result.
9
+ *
10
+ * ```ts
11
+ * import { LlmAgent } from '@google/adk';
12
+ * import { M91Client } from '@msg91comm/m91';
13
+ * import { createM91BeforeToolCallback, createM91Tools } from '@msg91comm/m91/integrations/google-adk';
14
+ *
15
+ * const client = new M91Client(process.env.M91_SEND_LINK!);
16
+ *
17
+ * const agent = new LlmAgent({
18
+ * name: 'support_agent',
19
+ * model: 'gemini-2.5-flash',
20
+ * instruction: 'Resolve refund requests.',
21
+ * tools: [issueRefund, ...(await createM91Tools(client))],
22
+ * beforeToolCallback: createM91BeforeToolCallback(client, { tools: ['issue_refund'] }),
23
+ * });
24
+ * ```
25
+ *
26
+ * The gate waits for the answer in-process. For approvals that take hours,
27
+ * use ADK's own Tool Confirmation and resume the session when M91's answer
28
+ * arrives.
29
+ */
30
+ import { ALERT_DESCRIPTION, ALERT_TOOL_NAME, APPROVAL_DESCRIPTION, APPROVAL_TOOL_NAME, decideToolCall, needsHuman, runAlert, runApproval, } from './specs.js';
31
+ import { alertShape, approvalShape, loadZod } from './zod-shapes.js';
32
+ /**
33
+ * A `beforeToolCallback` that asks a person on their phone before the tools
34
+ * in `options.tools` run. Returning a result object skips the tool, which is
35
+ * how a rejection reaches the model.
36
+ */
37
+ export function createM91BeforeToolCallback(client, options) {
38
+ return async ({ tool, args, context }) => {
39
+ const toolName = tool.name;
40
+ if (!(await needsHuman(options, toolName, args)))
41
+ return undefined;
42
+ const callId = context.functionCallId ?? `${context.invocationId}-${toolName}`;
43
+ const decision = await decideToolCall(client, { toolName, input: args, callId }, options);
44
+ if (decision.approved)
45
+ return undefined;
46
+ return { status: 'rejected', error: decision.reason };
47
+ };
48
+ }
49
+ async function adkModule() {
50
+ try {
51
+ const specifier = '@google/adk';
52
+ return (await import(specifier));
53
+ }
54
+ catch (error) {
55
+ throw new Error('The Google ADK integration needs @google/adk. Install it with: npm install @google/adk', { cause: error });
56
+ }
57
+ }
58
+ /** The blocking approval tool, `m91_request_approval`, as an ADK `FunctionTool`. */
59
+ export async function createM91ApprovalTool(client, defaults = {}) {
60
+ const { FunctionTool } = await adkModule();
61
+ const z = await loadZod('Google ADK');
62
+ return new FunctionTool({
63
+ name: APPROVAL_TOOL_NAME,
64
+ description: APPROVAL_DESCRIPTION,
65
+ parameters: z.object(approvalShape(z)),
66
+ execute: async (args) => ({ result: await runApproval(client, args, defaults) }),
67
+ });
68
+ }
69
+ /** The fire-and-forget alert tool, `m91_send_alert`, as an ADK `FunctionTool`. */
70
+ export async function createM91AlertTool(client, defaults = {}) {
71
+ const { FunctionTool } = await adkModule();
72
+ const z = await loadZod('Google ADK');
73
+ return new FunctionTool({
74
+ name: ALERT_TOOL_NAME,
75
+ description: ALERT_DESCRIPTION,
76
+ parameters: z.object(alertShape(z)),
77
+ execute: async (args) => ({ result: await runAlert(client, args, defaults) }),
78
+ });
79
+ }
80
+ /** Both tools, for an agent's `tools` array. */
81
+ export async function createM91Tools(client, defaults = {}) {
82
+ return [await createM91ApprovalTool(client, defaults), await createM91AlertTool(client, defaults)];
83
+ }
84
+ //# sourceMappingURL=google-adk.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"google-adk.js","sourceRoot":"","sources":["../../../src/integrations/google-adk.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  * Importing a specific adapter directly is usually better —
9
9
  * `@msg91comm/m91/integrations/langchain` — because it pulls in only what you use.
10
10
  *
11
- * `langchain.ts` and `vercel-ai.ts` both export `createM91ApprovalTool`, so
11
+ * Several adapters export `createM91ApprovalTool`, so
12
12
  * they are re-exported under namespaces rather than flattened: two functions of
13
13
  * the same name doing the same job for different frameworks is exactly the pair
14
14
  * that would silently resolve to the wrong one.
@@ -16,7 +16,11 @@
16
16
  export * as langchain from './langchain.js';
17
17
  export * as langgraph from './langgraph.js';
18
18
  export * as vercelAi from './vercel-ai.js';
19
+ export * as openaiAgents from './openai-agents.js';
20
+ export * as claudeAgentSdk from './claude-agent-sdk.js';
21
+ export * as googleAdk from './google-adk.js';
22
+ export * as mastra from './mastra.js';
19
23
  export { M91InterruptNotifier, createM91ApprovalNode } from './langgraph.js';
20
- export { APPROVED, REJECTED, alertResult, errorResult } from './specs.js';
21
- export type { AlertArgs, ApprovalArgs } from './specs.js';
24
+ export { APPROVED, REJECTED, alertResult, decideToolCall, errorResult } from './specs.js';
25
+ export type { AlertArgs, ApprovalArgs, GateDecision, GateOptions, GatedCall } from './specs.js';
22
26
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1E,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC1F,YAAY,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC"}
@@ -8,7 +8,7 @@
8
8
  * Importing a specific adapter directly is usually better —
9
9
  * `@msg91comm/m91/integrations/langchain` — because it pulls in only what you use.
10
10
  *
11
- * `langchain.ts` and `vercel-ai.ts` both export `createM91ApprovalTool`, so
11
+ * Several adapters export `createM91ApprovalTool`, so
12
12
  * they are re-exported under namespaces rather than flattened: two functions of
13
13
  * the same name doing the same job for different frameworks is exactly the pair
14
14
  * that would silently resolve to the wrong one.
@@ -16,6 +16,10 @@
16
16
  export * as langchain from './langchain.js';
17
17
  export * as langgraph from './langgraph.js';
18
18
  export * as vercelAi from './vercel-ai.js';
19
+ export * as openaiAgents from './openai-agents.js';
20
+ export * as claudeAgentSdk from './claude-agent-sdk.js';
21
+ export * as googleAdk from './google-adk.js';
22
+ export * as mastra from './mastra.js';
19
23
  export { M91InterruptNotifier, createM91ApprovalNode } from './langgraph.js';
20
- export { APPROVED, REJECTED, alertResult, errorResult } from './specs.js';
24
+ export { APPROVED, REJECTED, alertResult, decideToolCall, errorResult } from './specs.js';
21
25
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAE3C,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/integrations/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,SAAS,MAAM,gBAAgB,CAAC;AAC5C,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,YAAY,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,cAAc,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,SAAS,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAC7E,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
@@ -17,7 +17,7 @@
17
17
  * await createM91AlertTool(client),
18
18
  * ...myTools,
19
19
  * ];
20
- * const agent = createReactAgent({ llm, tools });
20
+ * const agent = createAgent({ model: 'openai:gpt-5-mini', tools }); // from 'langchain'
21
21
  * ```
22
22
  *
23
23
  * The factories are **async** because `@langchain/core` is an optional peer
@@ -25,19 +25,70 @@
25
25
  * install @msg91comm/m91` at zero dependencies, which matters for a package whose job is
26
26
  * to work when everything else is on fire.
27
27
  */
28
+ import type { DynamicStructuredTool } from '@langchain/core/tools';
28
29
  import type { M91Client } from '../client.js';
29
- import { type AlertDefaults, type ApprovalDefaults } from './specs.js';
30
+ import { type AlertDefaults, type ApprovalDefaults, type GateOptions } from './specs.js';
30
31
  /**
31
32
  * The blocking approval gate, as a LangChain tool named `m91_request_approval`.
32
33
  * Returns `"approved"`, `"rejected"` or `"error: …"` — and nothing but a real
33
34
  * human approval returns `"approved"`.
34
35
  */
35
- export declare function createM91ApprovalTool(client: M91Client, defaults?: ApprovalDefaults): Promise<unknown>;
36
+ export declare function createM91ApprovalTool(client: M91Client, defaults?: ApprovalDefaults): Promise<DynamicStructuredTool>;
36
37
  /**
37
38
  * The fire-and-forget alert, as a LangChain tool named `m91_send_alert`.
38
39
  * Returns `"sent:delivered=N"` or `"error: …"`.
39
40
  */
40
- export declare function createM91AlertTool(client: M91Client, defaults?: AlertDefaults): Promise<unknown>;
41
+ export declare function createM91AlertTool(client: M91Client, defaults?: AlertDefaults): Promise<DynamicStructuredTool>;
41
42
  /** Both, in the order an agent's `tools` array usually wants them. */
42
- export declare function createM91Tools(client: M91Client, defaults?: ApprovalDefaults & AlertDefaults): Promise<unknown[]>;
43
+ export declare function createM91Tools(client: M91Client, defaults?: ApprovalDefaults & AlertDefaults): Promise<DynamicStructuredTool[]>;
44
+ /** One tool call the middleware paused on, as `HITLRequest.actionRequests` carries it. */
45
+ interface ActionRequestLike {
46
+ name: string;
47
+ args: Record<string, unknown>;
48
+ description?: string;
49
+ }
50
+ /** The payload of the interrupt `humanInTheLoopMiddleware` (and Deep Agents' `interruptOn`) raises. */
51
+ export interface HITLRequestLike {
52
+ actionRequests: ActionRequestLike[];
53
+ }
54
+ /** What the middleware expects back: one decision per action request, in order. */
55
+ export interface M91HITLResponse {
56
+ decisions: Array<{
57
+ type: 'approve';
58
+ } | {
59
+ type: 'reject';
60
+ message: string;
61
+ }>;
62
+ }
63
+ /**
64
+ * Ask a person about every tool call in a `HITLRequest`, one phone alert per
65
+ * call, and build the `{ decisions }` the middleware resumes with.
66
+ *
67
+ * `"approved"` / `"rejected"` strings (what `M91InterruptNotifier` returns) are
68
+ * **not** a valid resume value for the middleware; this is.
69
+ *
70
+ * `threadId` makes each alert's customId stable across a retry of the same
71
+ * pause, so a retried resume does not ring twice.
72
+ */
73
+ export declare function resolveHITLWithM91(request: HITLRequestLike, client: M91Client, options?: GateOptions & {
74
+ threadId?: string;
75
+ }): Promise<M91HITLResponse>;
76
+ /** The parts of a LangChain agent / Deep Agent / compiled graph this file calls. */
77
+ export interface InvokableAgentLike {
78
+ invoke(input: any, config?: any): Promise<any>;
79
+ }
80
+ /**
81
+ * `agent.invoke()`, with every `humanInTheLoopMiddleware` pause answered on a
82
+ * phone through M91 and resumed with `Command({ resume: { decisions } })`.
83
+ * Works for `createAgent` with `humanInTheLoopMiddleware` and for Deep Agents
84
+ * created with `interruptOn`. Needs a checkpointer and a `thread_id`.
85
+ */
86
+ export declare function invokeWithM91Approvals<TResult = any>(agent: InvokableAgentLike, input: unknown, config: {
87
+ configurable: {
88
+ thread_id: string;
89
+ };
90
+ } & Record<string, unknown>, client: M91Client, options?: GateOptions & {
91
+ maxRounds?: number;
92
+ }): Promise<TResult>;
93
+ export {};
43
94
  //# sourceMappingURL=langchain.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../../../src/integrations/langchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAQL,KAAK,aAAa,EAElB,KAAK,gBAAgB,EAGtB,MAAM,YAAY,CAAC;AAmBpB;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAqB,GAC9B,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,aAAkB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,sEAAsE;AACtE,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAgB,GAAG,aAAkB,GAC9C,OAAO,CAAC,OAAO,EAAE,CAAC,CAKpB"}
1
+ {"version":3,"file":"langchain.d.ts","sourceRoot":"","sources":["../../../src/integrations/langchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAEnE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAQL,KAAK,aAAa,EAElB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAIjB,MAAM,YAAY,CAAC;AAmBpB;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAqB,GAC9B,OAAO,CAAC,qBAAqB,CAAC,CAOhC;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,aAAkB,GAC3B,OAAO,CAAC,qBAAqB,CAAC,CAOhC;AAED,sEAAsE;AACtE,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAgB,GAAG,aAAkB,GAC9C,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAKlC;AAMD,0FAA0F;AAC1F,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,uGAAuG;AACvG,MAAM,WAAW,eAAe;IAC9B,cAAc,EAAE,iBAAiB,EAAE,CAAC;CACrC;AAED,mFAAmF;AACnF,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,SAAS,CAAA;KAAE,GAAG;QAAE,IAAI,EAAE,QAAQ,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CAC7E;AAMD;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,eAAe,EACxB,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAO,GAChD,OAAO,CAAC,eAAe,CAAC,CAY1B;AAED,oFAAoF;AACpF,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,KAAK,EAAE,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;CAChD;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAAC,OAAO,GAAG,GAAG,EACxD,KAAK,EAAE,kBAAkB,EACzB,KAAK,EAAE,OAAO,EACd,MAAM,EAAE;IAAE,YAAY,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACzE,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,WAAW,GAAG;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACjD,OAAO,CAAC,OAAO,CAAC,CAclB"}
@@ -17,7 +17,7 @@
17
17
  * await createM91AlertTool(client),
18
18
  * ...myTools,
19
19
  * ];
20
- * const agent = createReactAgent({ llm, tools });
20
+ * const agent = createAgent({ model: 'openai:gpt-5-mini', tools }); // from 'langchain'
21
21
  * ```
22
22
  *
23
23
  * The factories are **async** because `@langchain/core` is an optional peer
@@ -25,7 +25,7 @@
25
25
  * install @msg91comm/m91` at zero dependencies, which matters for a package whose job is
26
26
  * to work when everything else is on fire.
27
27
  */
28
- import { ALERT_DESCRIPTION, ALERT_SCHEMA, ALERT_TOOL_NAME, APPROVAL_DESCRIPTION, APPROVAL_SCHEMA, APPROVAL_TOOL_NAME, runAlert, runApproval, } from './specs.js';
28
+ import { ALERT_DESCRIPTION, ALERT_SCHEMA, ALERT_TOOL_NAME, APPROVAL_DESCRIPTION, APPROVAL_SCHEMA, APPROVAL_TOOL_NAME, decideToolCall, runAlert, runApproval, } from './specs.js';
29
29
  async function langchainTool() {
30
30
  try {
31
31
  // The specifier is a variable so TypeScript does not try to resolve an
@@ -72,4 +72,58 @@ export async function createM91Tools(client, defaults = {}) {
72
72
  await createM91AlertTool(client, defaults),
73
73
  ];
74
74
  }
75
+ function isHITLRequest(value) {
76
+ return Array.isArray(value?.actionRequests);
77
+ }
78
+ /**
79
+ * Ask a person about every tool call in a `HITLRequest`, one phone alert per
80
+ * call, and build the `{ decisions }` the middleware resumes with.
81
+ *
82
+ * `"approved"` / `"rejected"` strings (what `M91InterruptNotifier` returns) are
83
+ * **not** a valid resume value for the middleware; this is.
84
+ *
85
+ * `threadId` makes each alert's customId stable across a retry of the same
86
+ * pause, so a retried resume does not ring twice.
87
+ */
88
+ export async function resolveHITLWithM91(request, client, options = {}) {
89
+ const decisions = [];
90
+ for (const [index, action] of request.actionRequests.entries()) {
91
+ const callId = `${options.threadId ?? 'run'}-${index}`;
92
+ const decision = await decideToolCall(client, { toolName: action.name, input: action.args, callId }, options);
93
+ decisions.push(decision.approved ? { type: 'approve' } : { type: 'reject', message: decision.reason });
94
+ }
95
+ return { decisions };
96
+ }
97
+ /**
98
+ * `agent.invoke()`, with every `humanInTheLoopMiddleware` pause answered on a
99
+ * phone through M91 and resumed with `Command({ resume: { decisions } })`.
100
+ * Works for `createAgent` with `humanInTheLoopMiddleware` and for Deep Agents
101
+ * created with `interruptOn`. Needs a checkpointer and a `thread_id`.
102
+ */
103
+ export async function invokeWithM91Approvals(agent, input, config, client, options = {}) {
104
+ const { Command } = await langgraphModule();
105
+ const { maxRounds = 20, ...gate } = options;
106
+ let result = await agent.invoke(input, config);
107
+ for (let round = 0; round < maxRounds; round += 1) {
108
+ const pending = result?.__interrupt__?.[0]?.value;
109
+ if (!isHITLRequest(pending))
110
+ break;
111
+ const response = await resolveHITLWithM91(pending, client, {
112
+ ...gate,
113
+ threadId: `${config.configurable.thread_id}-${round}`,
114
+ });
115
+ result = await agent.invoke(new Command({ resume: response }), config);
116
+ }
117
+ return result;
118
+ }
119
+ async function langgraphModule() {
120
+ try {
121
+ const specifier = '@langchain/langgraph';
122
+ return (await import(specifier));
123
+ }
124
+ catch (error) {
125
+ throw new Error('Resuming a LangChain / Deep Agents interrupt needs @langchain/langgraph. Install it with: ' +
126
+ 'npm install @langchain/langgraph', { cause: error });
127
+ }
128
+ }
75
129
  //# sourceMappingURL=langchain.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../../src/integrations/langchain.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,eAAe,EACf,oBAAoB,EACpB,eAAe,EACf,kBAAkB,EAKlB,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AAEpB,KAAK,UAAU,aAAa;IAC1B,IAAI,CAAC;QACH,uEAAuE;QACvE,0EAA0E;QAC1E,2CAA2C;QAC3C,MAAM,SAAS,GAAG,uBAAuB,CAAC;QAC1C,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAwD,CAAC;QAC7F,OAAO,GAAG,CAAC,IAAI,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,oEAAoE;YAClE,6BAA6B,EAC/B,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAiB,EACjB,WAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;IACnC,OAAO,IAAI,CAAC,CAAC,IAAkB,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;QACvE,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,oBAAoB;QACjC,MAAM,EAAE,eAAe;KACxB,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAiB,EACjB,WAA0B,EAAE;IAE5B,MAAM,IAAI,GAAG,MAAM,aAAa,EAAE,CAAC;IACnC,OAAO,IAAI,CAAC,CAAC,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;QACjE,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,YAAY;KACrB,CAAC,CAAC;AACL,CAAC;AAED,sEAAsE;AACtE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAiB,EACjB,WAA6C,EAAE;IAE/C,OAAO;QACL,MAAM,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC;QAC7C,MAAM,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC;KAC3C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"langchain.js","sourceRoot":"","sources":["../../../src/integrations/langchain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Mastra (`@mastra/core`): M91 as the approver for `requireApproval` tools,
3
+ * and M91 as tools.
4
+ *
5
+ * **Approver.** Mark your risky tools `requireApproval: true`. Mastra suspends
6
+ * the run when the agent calls one; `generateWithM91Approvals` rings a phone
7
+ * for each suspended call and approves or declines it with the person's
8
+ * answer until the run finishes.
9
+ *
10
+ * ```ts
11
+ * import { Agent } from '@mastra/core/agent';
12
+ * import { createTool } from '@mastra/core/tools';
13
+ * import { M91Client } from '@msg91comm/m91';
14
+ * import { generateWithM91Approvals } from '@msg91comm/m91/integrations/mastra';
15
+ *
16
+ * const issueRefund = createTool({
17
+ * id: 'issue-refund',
18
+ * description: 'Refund an order.',
19
+ * inputSchema: z.object({ orderId: z.string(), amount: z.number() }),
20
+ * requireApproval: true,
21
+ * execute: async ({ orderId, amount }) => refunds.create(orderId, amount),
22
+ * });
23
+ *
24
+ * const agent = new Agent({ id: 'support', name: 'Support', instructions: '…',
25
+ * model: 'openai/gpt-5-mini', tools: { issueRefund } });
26
+ * const client = new M91Client(process.env.M91_SEND_LINK!);
27
+ *
28
+ * const output = await generateWithM91Approvals(agent, 'Refund ORD-40122.', client);
29
+ * console.log(output.text);
30
+ * ```
31
+ *
32
+ * Mastra keeps suspended runs in its storage, so configure a storage provider
33
+ * on your `Mastra` instance for approvals to resume.
34
+ */
35
+ import type { Tool } from '@mastra/core/tools';
36
+ import type { M91Client } from '../client.js';
37
+ import { type AlertDefaults, type ApprovalDefaults, type GateOptions } from './specs.js';
38
+ /** The parts of a Mastra `generate()` result this file reads. */
39
+ export interface MastraOutputLike {
40
+ text: string;
41
+ finishReason?: unknown;
42
+ runId?: string;
43
+ suspendPayload?: unknown;
44
+ }
45
+ /** The parts of a Mastra `Agent` this file calls. */
46
+ export interface MastraAgentLike<TOutput extends MastraOutputLike = MastraOutputLike> {
47
+ generate(prompt: any, options?: any): Promise<TOutput>;
48
+ approveToolCallGenerate(options: {
49
+ runId: string;
50
+ toolCallId?: string;
51
+ }): Promise<TOutput>;
52
+ declineToolCallGenerate(options: {
53
+ runId: string;
54
+ toolCallId?: string;
55
+ reason?: string;
56
+ }): Promise<TOutput>;
57
+ }
58
+ /**
59
+ * `agent.generate()`, with every tool approval the run suspends for answered
60
+ * on a phone through M91. Approvals for tools outside `options.tools` are
61
+ * returned still suspended, for your own code.
62
+ */
63
+ export declare function generateWithM91Approvals<TOutput extends MastraOutputLike>(agent: MastraAgentLike<TOutput>, prompt: unknown, client: M91Client, options?: GateOptions & {
64
+ generateOptions?: Record<string, unknown>;
65
+ maxRounds?: number;
66
+ }): Promise<TOutput>;
67
+ /** A Mastra tool, typed loosely enough to drop into any agent's `tools`. */
68
+ export type M91MastraTool = Tool<any, any, any, any, any, string, any>;
69
+ /** The blocking approval tool, `m91_request_approval`, as a Mastra tool. */
70
+ export declare function createM91ApprovalTool(client: M91Client, defaults?: ApprovalDefaults): Promise<M91MastraTool>;
71
+ /** The fire-and-forget alert tool, `m91_send_alert`, as a Mastra tool. */
72
+ export declare function createM91AlertTool(client: M91Client, defaults?: AlertDefaults): Promise<M91MastraTool>;
73
+ /** Both tools, keyed for an `Agent`'s `tools` object. */
74
+ export declare function createM91Tools(client: M91Client, defaults?: ApprovalDefaults & AlertDefaults): Promise<Record<string, M91MastraTool>>;
75
+ //# sourceMappingURL=mastra.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mastra.d.ts","sourceRoot":"","sources":["../../../src/integrations/mastra.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAML,KAAK,aAAa,EAElB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAKjB,MAAM,YAAY,CAAC;AAGpB,iEAAiE;AACjE,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,qDAAqD;AACrD,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,gBAAgB,GAAG,gBAAgB;IAClF,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACvD,uBAAuB,CAAC,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC3F,uBAAuB,CAAC,OAAO,EAAE;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACtB;AAeD;;;;GAIG;AACH,wBAAsB,wBAAwB,CAAC,OAAO,SAAS,gBAAgB,EAC7E,KAAK,EAAE,eAAe,CAAC,OAAO,CAAC,EAC/B,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,WAAW,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GAC5F,OAAO,CAAC,OAAO,CAAC,CAqBlB;AAiBD,4EAA4E;AAC5E,MAAM,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;AAEvE,4EAA4E;AAC5E,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAqB,GAC9B,OAAO,CAAC,aAAa,CAAC,CASxB;AAED,0EAA0E;AAC1E,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,aAAkB,GAC3B,OAAO,CAAC,aAAa,CAAC,CASxB;AAED,yDAAyD;AACzD,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAgB,GAAG,aAAkB,GAC9C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAKxC"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Mastra (`@mastra/core`): M91 as the approver for `requireApproval` tools,
3
+ * and M91 as tools.
4
+ *
5
+ * **Approver.** Mark your risky tools `requireApproval: true`. Mastra suspends
6
+ * the run when the agent calls one; `generateWithM91Approvals` rings a phone
7
+ * for each suspended call and approves or declines it with the person's
8
+ * answer until the run finishes.
9
+ *
10
+ * ```ts
11
+ * import { Agent } from '@mastra/core/agent';
12
+ * import { createTool } from '@mastra/core/tools';
13
+ * import { M91Client } from '@msg91comm/m91';
14
+ * import { generateWithM91Approvals } from '@msg91comm/m91/integrations/mastra';
15
+ *
16
+ * const issueRefund = createTool({
17
+ * id: 'issue-refund',
18
+ * description: 'Refund an order.',
19
+ * inputSchema: z.object({ orderId: z.string(), amount: z.number() }),
20
+ * requireApproval: true,
21
+ * execute: async ({ orderId, amount }) => refunds.create(orderId, amount),
22
+ * });
23
+ *
24
+ * const agent = new Agent({ id: 'support', name: 'Support', instructions: '…',
25
+ * model: 'openai/gpt-5-mini', tools: { issueRefund } });
26
+ * const client = new M91Client(process.env.M91_SEND_LINK!);
27
+ *
28
+ * const output = await generateWithM91Approvals(agent, 'Refund ORD-40122.', client);
29
+ * console.log(output.text);
30
+ * ```
31
+ *
32
+ * Mastra keeps suspended runs in its storage, so configure a storage provider
33
+ * on your `Mastra` instance for approvals to resume.
34
+ */
35
+ import { ALERT_DESCRIPTION, ALERT_TOOL_NAME, APPROVAL_DESCRIPTION, APPROVAL_TOOL_NAME, decideToolCall, needsHuman, runAlert, runApproval, } from './specs.js';
36
+ import { alertShape, approvalShape, loadZod } from './zod-shapes.js';
37
+ function pendingApproval(output) {
38
+ if (output.finishReason !== 'suspended' || !output.runId)
39
+ return null;
40
+ const payload = output.suspendPayload;
41
+ if (!payload?.toolCallId || !payload.toolName)
42
+ return null;
43
+ return { toolCallId: payload.toolCallId, toolName: payload.toolName, args: payload.args };
44
+ }
45
+ /**
46
+ * `agent.generate()`, with every tool approval the run suspends for answered
47
+ * on a phone through M91. Approvals for tools outside `options.tools` are
48
+ * returned still suspended, for your own code.
49
+ */
50
+ export async function generateWithM91Approvals(agent, prompt, client, options = {}) {
51
+ const { generateOptions, maxRounds = 20, ...gate } = options;
52
+ let output = await agent.generate(prompt, generateOptions);
53
+ for (let round = 0; round < maxRounds; round += 1) {
54
+ const pending = pendingApproval(output);
55
+ if (!pending || !(await needsHuman(gate, pending.toolName, pending.args)))
56
+ break;
57
+ const runId = output.runId;
58
+ const decision = await decideToolCall(client, { toolName: pending.toolName, input: pending.args, callId: pending.toolCallId }, gate);
59
+ output = decision.approved
60
+ ? await agent.approveToolCallGenerate({ runId, toolCallId: pending.toolCallId })
61
+ : await agent.declineToolCallGenerate({
62
+ runId,
63
+ toolCallId: pending.toolCallId,
64
+ reason: decision.reason,
65
+ });
66
+ }
67
+ return output;
68
+ }
69
+ async function mastraTools() {
70
+ try {
71
+ const specifier = '@mastra/core/tools';
72
+ return (await import(specifier));
73
+ }
74
+ catch (error) {
75
+ throw new Error('The Mastra integration needs @mastra/core. Install it with: npm install @mastra/core', {
76
+ cause: error,
77
+ });
78
+ }
79
+ }
80
+ /** The blocking approval tool, `m91_request_approval`, as a Mastra tool. */
81
+ export async function createM91ApprovalTool(client, defaults = {}) {
82
+ const { createTool } = await mastraTools();
83
+ const z = await loadZod('Mastra');
84
+ return createTool({
85
+ id: APPROVAL_TOOL_NAME,
86
+ description: APPROVAL_DESCRIPTION,
87
+ inputSchema: z.object(approvalShape(z)),
88
+ execute: async (args) => ({ result: await runApproval(client, args, defaults) }),
89
+ });
90
+ }
91
+ /** The fire-and-forget alert tool, `m91_send_alert`, as a Mastra tool. */
92
+ export async function createM91AlertTool(client, defaults = {}) {
93
+ const { createTool } = await mastraTools();
94
+ const z = await loadZod('Mastra');
95
+ return createTool({
96
+ id: ALERT_TOOL_NAME,
97
+ description: ALERT_DESCRIPTION,
98
+ inputSchema: z.object(alertShape(z)),
99
+ execute: async (args) => ({ result: await runAlert(client, args, defaults) }),
100
+ });
101
+ }
102
+ /** Both tools, keyed for an `Agent`'s `tools` object. */
103
+ export async function createM91Tools(client, defaults = {}) {
104
+ return {
105
+ [APPROVAL_TOOL_NAME]: await createM91ApprovalTool(client, defaults),
106
+ [ALERT_TOOL_NAME]: await createM91AlertTool(client, defaults),
107
+ };
108
+ }
109
+ //# sourceMappingURL=mastra.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mastra.js","sourceRoot":"","sources":["../../../src/integrations/mastra.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * OpenAI Agents SDK (`@openai/agents`): two tools, and M91 as the approver.
3
+ *
4
+ * **Approver.** Mark your risky tools `needsApproval: true`. The SDK pauses the
5
+ * run and returns `result.interruptions`; `runWithM91Approvals` rings a phone
6
+ * for each one, approves or rejects it on the run state with the person's
7
+ * answer, and resumes the same run until it finishes.
8
+ *
9
+ * ```ts
10
+ * import { Agent, tool } from '@openai/agents';
11
+ * import { M91Client } from '@msg91comm/m91';
12
+ * import { runWithM91Approvals } from '@msg91comm/m91/integrations/openai-agents';
13
+ *
14
+ * const issueRefund = tool({
15
+ * name: 'issue_refund',
16
+ * description: 'Refund an order.',
17
+ * parameters: z.object({ orderId: z.string(), amount: z.number() }),
18
+ * needsApproval: true,
19
+ * execute: async ({ orderId, amount }) => refunds.create(orderId, amount),
20
+ * });
21
+ *
22
+ * const agent = new Agent({ name: 'Support', instructions: '…', tools: [issueRefund] });
23
+ * const client = new M91Client(process.env.M91_SEND_LINK!);
24
+ *
25
+ * const result = await runWithM91Approvals(agent, 'Refund ORD-40122, it never arrived.', client);
26
+ * console.log(result.finalOutput);
27
+ * ```
28
+ *
29
+ * **Tools** (`createM91Tools`) are for when the model itself should decide to
30
+ * ask, or to wake somebody about something that happened.
31
+ *
32
+ * `@openai/agents` is an optional peer dependency, imported only when one of
33
+ * these is called.
34
+ */
35
+ import type { Agent, FunctionTool, RunResult } from '@openai/agents';
36
+ import type { M91Client } from '../client.js';
37
+ import { type AlertDefaults, type ApprovalDefaults, type GateOptions } from './specs.js';
38
+ /** The blocking approval tool, `m91_request_approval`. Returns `"approved"`, `"rejected"` or `"error: …"`. */
39
+ export declare function createM91ApprovalTool(client: M91Client, defaults?: ApprovalDefaults): Promise<FunctionTool>;
40
+ /** The fire-and-forget alert tool, `m91_send_alert`. Returns `"sent:delivered=N"` or `"error: …"`. */
41
+ export declare function createM91AlertTool(client: M91Client, defaults?: AlertDefaults): Promise<FunctionTool>;
42
+ /** Both tools, for an agent's `tools` array. */
43
+ export declare function createM91Tools(client: M91Client, defaults?: ApprovalDefaults & AlertDefaults): Promise<FunctionTool[]>;
44
+ /**
45
+ * Ask a person about every pending approval on a paused run, and record the
46
+ * answers on its state. Returns how many were decided; resume with
47
+ * `run(agent, result.state)`.
48
+ *
49
+ * Interruptions for tools outside `options.tools` are left pending for your
50
+ * own code to decide.
51
+ */
52
+ export declare function approveInterruptionsWithM91(result: Pick<RunResult<any, any>, 'interruptions' | 'state'>, client: M91Client, options?: GateOptions): Promise<number>;
53
+ /**
54
+ * `run()`, with every approval the run pauses for answered on a phone through
55
+ * M91, until the run finishes or nothing left to decide is M91's.
56
+ */
57
+ export declare function runWithM91Approvals<TAgent extends Agent<any, any>>(agent: TAgent, input: string | Parameters<typeof import('@openai/agents').run>[1], client: M91Client, options?: GateOptions & {
58
+ runOptions?: Record<string, unknown>;
59
+ maxRounds?: number;
60
+ }): Promise<RunResult<any, TAgent>>;
61
+ //# sourceMappingURL=openai-agents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai-agents.d.ts","sourceRoot":"","sources":["../../../src/integrations/openai-agents.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,YAAY,EAAE,SAAS,EAAiC,MAAM,gBAAgB,CAAC;AAEpG,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAQL,KAAK,aAAa,EAElB,KAAK,gBAAgB,EACrB,KAAK,WAAW,EAKjB,MAAM,YAAY,CAAC;AAmBpB,8GAA8G;AAC9G,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAqB,GAC9B,OAAO,CAAC,YAAY,CAAC,CAUvB;AAED,sGAAsG;AACtG,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,aAAkB,GAC3B,OAAO,CAAC,YAAY,CAAC,CASvB;AAED,gDAAgD;AAChD,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAgB,GAAG,aAAkB,GAC9C,OAAO,CAAC,YAAY,EAAE,CAAC,CAEzB;AAiBD;;;;;;;GAOG;AACH,wBAAsB,2BAA2B,CAC/C,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,EAC5D,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAajB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,MAAM,SAAS,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EACtE,KAAK,EAAE,MAAM,EACb,KAAK,EAAE,MAAM,GAAG,UAAU,CAAC,cAAc,gBAAgB,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,EAClE,MAAM,EAAE,SAAS,EACjB,OAAO,GAAE,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACvF,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,CASjC"}