@msg91comm/m91 0.0.0-stage → 1.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.
Files changed (70) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/LICENSE +21 -0
  3. package/README.md +425 -2
  4. package/dist/src/client.d.ts +165 -0
  5. package/dist/src/client.d.ts.map +1 -0
  6. package/dist/src/client.js +221 -0
  7. package/dist/src/client.js.map +1 -0
  8. package/dist/src/exceptions.d.ts +114 -0
  9. package/dist/src/exceptions.d.ts.map +1 -0
  10. package/dist/src/exceptions.js +199 -0
  11. package/dist/src/exceptions.js.map +1 -0
  12. package/dist/src/http.d.ts +71 -0
  13. package/dist/src/http.d.ts.map +1 -0
  14. package/dist/src/http.js +150 -0
  15. package/dist/src/http.js.map +1 -0
  16. package/dist/src/index.d.ts +49 -0
  17. package/dist/src/index.d.ts.map +1 -0
  18. package/dist/src/index.js +45 -0
  19. package/dist/src/index.js.map +1 -0
  20. package/dist/src/integrations/index.d.ts +22 -0
  21. package/dist/src/integrations/index.d.ts.map +1 -0
  22. package/dist/src/integrations/index.js +21 -0
  23. package/dist/src/integrations/index.js.map +1 -0
  24. package/dist/src/integrations/langchain.d.ts +43 -0
  25. package/dist/src/integrations/langchain.d.ts.map +1 -0
  26. package/dist/src/integrations/langchain.js +75 -0
  27. package/dist/src/integrations/langchain.js.map +1 -0
  28. package/dist/src/integrations/langgraph.d.ts +79 -0
  29. package/dist/src/integrations/langgraph.d.ts.map +1 -0
  30. package/dist/src/integrations/langgraph.js +114 -0
  31. package/dist/src/integrations/langgraph.js.map +1 -0
  32. package/dist/src/integrations/specs.d.ts +131 -0
  33. package/dist/src/integrations/specs.d.ts.map +1 -0
  34. package/dist/src/integrations/specs.js +156 -0
  35. package/dist/src/integrations/specs.js.map +1 -0
  36. package/dist/src/integrations/vercel-ai.d.ts +36 -0
  37. package/dist/src/integrations/vercel-ai.d.ts.map +1 -0
  38. package/dist/src/integrations/vercel-ai.js +67 -0
  39. package/dist/src/integrations/vercel-ai.js.map +1 -0
  40. package/dist/src/models.d.ts +274 -0
  41. package/dist/src/models.d.ts.map +1 -0
  42. package/dist/src/models.js +383 -0
  43. package/dist/src/models.js.map +1 -0
  44. package/dist/src/platform.d.ts +176 -0
  45. package/dist/src/platform.d.ts.map +1 -0
  46. package/dist/src/platform.js +286 -0
  47. package/dist/src/platform.js.map +1 -0
  48. package/dist/src/url-builder.d.ts +65 -0
  49. package/dist/src/url-builder.d.ts.map +1 -0
  50. package/dist/src/url-builder.js +167 -0
  51. package/dist/src/url-builder.js.map +1 -0
  52. package/examples/approval-gate.ts +35 -0
  53. package/examples/basic-alert.ts +53 -0
  54. package/examples/langchain-agent.ts +65 -0
  55. package/examples/langgraph-hitl.ts +70 -0
  56. package/examples/vercel-ai-agent.ts +34 -0
  57. package/examples/webhook-urls.ts +44 -0
  58. package/package.json +83 -4
  59. package/src/client.ts +324 -0
  60. package/src/exceptions.ts +229 -0
  61. package/src/http.ts +174 -0
  62. package/src/index.ts +91 -0
  63. package/src/integrations/index.ts +23 -0
  64. package/src/integrations/langchain.ts +104 -0
  65. package/src/integrations/langgraph.ts +142 -0
  66. package/src/integrations/specs.ts +224 -0
  67. package/src/integrations/vercel-ai.ts +99 -0
  68. package/src/models.ts +660 -0
  69. package/src/platform.ts +343 -0
  70. package/src/url-builder.ts +225 -0
@@ -0,0 +1,131 @@
1
+ /**
2
+ * The tool definitions, written once and adapted per framework.
3
+ *
4
+ * A tool's name, its description and its argument docs are the entire interface
5
+ * a model has to M91 — they are the prompt. Four adapters each spelling their
6
+ * own copy is four descriptions that drift, and the drift is invisible until an
7
+ * agent on one framework behaves differently from the same agent on another.
8
+ *
9
+ * Every adapter therefore imports the schema and the `run` from here and does
10
+ * nothing but wrap it in the shape its framework expects.
11
+ */
12
+ import type { M91Client } from '../client.js';
13
+ import type { AlertResponse, Severity } from '../models.js';
14
+ export declare const APPROVED = "approved";
15
+ export declare const REJECTED = "rejected";
16
+ /**
17
+ * `error: …` — never `approved`, whatever went wrong.
18
+ *
19
+ * The message is redacted: an M91 error can carry the URL it failed on, and
20
+ * that URL has the send token in its path. A tool result goes straight into a
21
+ * model's context and from there into logs, traces and evals.
22
+ */
23
+ export declare function errorResult(error: unknown): string;
24
+ /**
25
+ * `sent:delivered=N` — plus a word when nobody was actually reached.
26
+ *
27
+ * A model that reads "sent" and stops has no way to know the channel's phones
28
+ * were all stale. Saying so in the result is the only channel back to it.
29
+ */
30
+ export declare function alertResult(alert: AlertResponse): string;
31
+ /** JSON Schema rather than zod, so nothing here needs a dependency to exist. */
32
+ export declare const APPROVAL_SCHEMA: {
33
+ readonly type: "object";
34
+ readonly properties: {
35
+ readonly title: {
36
+ readonly type: "string";
37
+ readonly description: string;
38
+ };
39
+ readonly customId: {
40
+ readonly type: "string";
41
+ readonly description: string;
42
+ };
43
+ readonly description: {
44
+ readonly type: "string";
45
+ readonly description: string;
46
+ };
47
+ readonly severity: {
48
+ readonly type: "string";
49
+ readonly enum: readonly ["LOW", "MEDIUM", "HIGH", "CRITICAL"];
50
+ readonly description: "LOW, MEDIUM, HIGH or CRITICAL. All of them ring through Do Not Disturb; HIGH and CRITICAL also place a voice call after 45 seconds of silence. An approval that blocks you is normally HIGH.";
51
+ };
52
+ readonly approveLabel: {
53
+ readonly type: "string";
54
+ readonly description: "The yes button, 24 characters or fewer.";
55
+ };
56
+ readonly rejectLabel: {
57
+ readonly type: "string";
58
+ readonly description: "The no button, 24 characters or fewer.";
59
+ };
60
+ readonly timeoutSeconds: {
61
+ readonly type: "number";
62
+ readonly description: "How long to wait for an answer before giving up. Default 300.";
63
+ };
64
+ };
65
+ readonly required: readonly ["title", "customId"];
66
+ readonly additionalProperties: false;
67
+ };
68
+ export declare const ALERT_SCHEMA: {
69
+ readonly type: "object";
70
+ readonly properties: {
71
+ readonly title: {
72
+ readonly type: "string";
73
+ readonly description: "What happened, in one line somebody can act on. 5-2000 characters.";
74
+ };
75
+ readonly customId: {
76
+ readonly type: "string";
77
+ readonly description: string;
78
+ };
79
+ readonly description: {
80
+ readonly type: "string";
81
+ readonly description: "Any detail that helps them act.";
82
+ };
83
+ readonly severity: {
84
+ readonly type: "string";
85
+ readonly enum: readonly ["LOW", "MEDIUM", "HIGH", "CRITICAL"];
86
+ readonly description: string;
87
+ };
88
+ };
89
+ readonly required: readonly ["title"];
90
+ readonly additionalProperties: false;
91
+ };
92
+ export declare const APPROVAL_TOOL_NAME = "m91_request_approval";
93
+ export declare const ALERT_TOOL_NAME = "m91_send_alert";
94
+ export declare const APPROVAL_DESCRIPTION: string;
95
+ export declare const ALERT_DESCRIPTION: string;
96
+ export interface ApprovalArgs {
97
+ title: string;
98
+ customId: string;
99
+ description?: string;
100
+ severity?: Severity;
101
+ approveLabel?: string;
102
+ rejectLabel?: string;
103
+ timeoutSeconds?: number;
104
+ }
105
+ export interface AlertArgs {
106
+ title: string;
107
+ customId?: string;
108
+ description?: string;
109
+ severity?: Severity;
110
+ }
111
+ /**
112
+ * What a deployment wants when the model does not say.
113
+ *
114
+ * Set these where the tool is built, not in the prompt. How long a person has
115
+ * to wake up, and what the buttons say, are operations decisions — a model
116
+ * choosing its own timeout is a model deciding how long somebody has to answer.
117
+ * It can still override per call when it has a reason.
118
+ */
119
+ export interface ApprovalDefaults {
120
+ severity?: Severity;
121
+ approveLabel?: string;
122
+ rejectLabel?: string;
123
+ timeoutSeconds?: number;
124
+ }
125
+ export interface AlertDefaults {
126
+ severity?: Severity;
127
+ }
128
+ /** Ask, wait, and answer in a word a model cannot misread. */
129
+ export declare function runApproval(client: M91Client, args: ApprovalArgs, defaults?: ApprovalDefaults): Promise<string>;
130
+ export declare function runAlert(client: M91Client, args: AlertArgs, defaults?: AlertDefaults): Promise<string>;
131
+ //# sourceMappingURL=specs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.d.ts","sourceRoot":"","sources":["../../../src/integrations/specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAG9C,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAE5D,eAAO,MAAM,QAAQ,aAAa,CAAC;AACnC,eAAO,MAAM,QAAQ,aAAa,CAAC;AAEnC;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIlD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAexD;AAWD,gFAAgF;AAChF,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BlB,CAAC;AAEX,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;CAkBf,CAAC;AAEX,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AACzD,eAAO,MAAM,eAAe,mBAAmB,CAAC;AAEhD,eAAO,MAAM,oBAAoB,QASW,CAAC;AAE7C,eAAO,MAAM,iBAAiB,QAQmD,CAAC;AAElF,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,EAAE,QAAQ,CAAC;CACrB;AAED,8DAA8D;AAC9D,wBAAsB,WAAW,CAC/B,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,YAAY,EAClB,QAAQ,GAAE,gBAAqB,GAC9B,OAAO,CAAC,MAAM,CAAC,CAkBjB;AAED,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,SAAS,EACf,QAAQ,GAAE,aAAkB,GAC3B,OAAO,CAAC,MAAM,CAAC,CAejB"}
@@ -0,0 +1,156 @@
1
+ /**
2
+ * The tool definitions, written once and adapted per framework.
3
+ *
4
+ * A tool's name, its description and its argument docs are the entire interface
5
+ * a model has to M91 — they are the prompt. Four adapters each spelling their
6
+ * own copy is four descriptions that drift, and the drift is invisible until an
7
+ * agent on one framework behaves differently from the same agent on another.
8
+ *
9
+ * Every adapter therefore imports the schema and the `run` from here and does
10
+ * nothing but wrap it in the shape its framework expects.
11
+ */
12
+ import { M91Error } from '../exceptions.js';
13
+ import { redact } from '../http.js';
14
+ export const APPROVED = 'approved';
15
+ export const REJECTED = 'rejected';
16
+ /**
17
+ * `error: …` — never `approved`, whatever went wrong.
18
+ *
19
+ * The message is redacted: an M91 error can carry the URL it failed on, and
20
+ * that URL has the send token in its path. A tool result goes straight into a
21
+ * model's context and from there into logs, traces and evals.
22
+ */
23
+ export function errorResult(error) {
24
+ if (error instanceof M91Error)
25
+ return `error: [${error.code}] ${redact(error.message)}`;
26
+ const message = error instanceof Error ? error.message : String(error);
27
+ return `error: ${redact(message) || 'unknown failure'}`;
28
+ }
29
+ /**
30
+ * `sent:delivered=N` — plus a word when nobody was actually reached.
31
+ *
32
+ * A model that reads "sent" and stops has no way to know the channel's phones
33
+ * were all stale. Saying so in the result is the only channel back to it.
34
+ */
35
+ export function alertResult(alert) {
36
+ if (alert.deduplicated) {
37
+ return ('sent:delivered=0 (an alert with this customId is already open and already ringing — ' +
38
+ 'nobody was disturbed a second time)');
39
+ }
40
+ if (alert.delivered === 0) {
41
+ return (`sent:delivered=0 WARNING: the alert was filed but no phone could be reached ` +
42
+ `(unregistered=${alert.unregistered.length}, noDevice=${alert.noDevice}, ` +
43
+ `pending=${alert.pending}). Nobody has been woken.`);
44
+ }
45
+ return `sent:delivered=${alert.delivered}`;
46
+ }
47
+ const SEVERITY_DOC = 'LOW, MEDIUM, HIGH or CRITICAL. All of them ring through Do Not Disturb; HIGH and ' +
48
+ 'CRITICAL also place a voice call after 45 seconds of silence.';
49
+ const CUSTOM_ID_DOC = 'A stable id for this exact request, derived from what is being decided ' +
50
+ "('refund-ORD-40122'). NEVER a timestamp, a UUID or a counter: the id is what " +
51
+ 'deduplicates a retry and what closes the alert afterwards.';
52
+ /** JSON Schema rather than zod, so nothing here needs a dependency to exist. */
53
+ export const APPROVAL_SCHEMA = {
54
+ type: 'object',
55
+ properties: {
56
+ title: {
57
+ type: 'string',
58
+ description: 'The question, as the person reads it at 3am on a lock screen. Name the action ' +
59
+ "and its consequence: 'Refund 48,000 on ORD-40122?' — not 'approve action'. " +
60
+ '5-2000 characters.',
61
+ },
62
+ customId: { type: 'string', description: CUSTOM_ID_DOC },
63
+ description: {
64
+ type: 'string',
65
+ description: 'The context the person needs to answer without asking you anything back: what ' +
66
+ 'you found, what you are about to do, and what happens if they say no.',
67
+ },
68
+ severity: {
69
+ type: 'string',
70
+ enum: ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'],
71
+ description: `${SEVERITY_DOC} An approval that blocks you is normally HIGH.`,
72
+ },
73
+ approveLabel: { type: 'string', description: 'The yes button, 24 characters or fewer.' },
74
+ rejectLabel: { type: 'string', description: 'The no button, 24 characters or fewer.' },
75
+ timeoutSeconds: {
76
+ type: 'number',
77
+ description: 'How long to wait for an answer before giving up. Default 300.',
78
+ },
79
+ },
80
+ required: ['title', 'customId'],
81
+ additionalProperties: false,
82
+ };
83
+ export const ALERT_SCHEMA = {
84
+ type: 'object',
85
+ properties: {
86
+ title: {
87
+ type: 'string',
88
+ description: 'What happened, in one line somebody can act on. 5-2000 characters.',
89
+ },
90
+ customId: {
91
+ type: 'string',
92
+ description: "A stable id for the CONDITION, not this occurrence — 'disk-full-node7'. Repeats " +
93
+ 'while it is still open wake nobody a second time. Never a timestamp.',
94
+ },
95
+ description: { type: 'string', description: 'Any detail that helps them act.' },
96
+ severity: { type: 'string', enum: ['LOW', 'MEDIUM', 'HIGH', 'CRITICAL'], description: SEVERITY_DOC },
97
+ },
98
+ required: ['title'],
99
+ additionalProperties: false,
100
+ };
101
+ export const APPROVAL_TOOL_NAME = 'm91_request_approval';
102
+ export const ALERT_TOOL_NAME = 'm91_send_alert';
103
+ export const APPROVAL_DESCRIPTION = 'Ask a human for permission and wait for their answer. Use this BEFORE any ' +
104
+ 'irreversible or consequential action: payments, refunds, deletions, deployments, ' +
105
+ "sending messages on someone's behalf, changing production data, or anything you " +
106
+ 'would want a colleague to sign off on. ' +
107
+ 'The person is woken on their phone immediately at full volume, through silent mode ' +
108
+ 'and Do Not Disturb, and called if they do not answer within 45 seconds. ' +
109
+ 'This call BLOCKS until they respond or the timeout passes. ' +
110
+ "Returns 'approved' or 'rejected'. Treat anything that is not exactly 'approved' as " +
111
+ 'a refusal and do not perform the action.';
112
+ export const ALERT_DESCRIPTION = 'Wake a human immediately about something that has already happened, without waiting ' +
113
+ 'for a reply. Use for failures, anomalies, breaches, and long jobs finishing that ' +
114
+ 'somebody is waiting on. ' +
115
+ 'The alert rings every phone on the on-call channel at full volume through silent ' +
116
+ 'mode and Do Not Disturb, and keeps ringing until somebody answers. ' +
117
+ 'Do NOT use this to ask permission — use m91_request_approval, which waits. ' +
118
+ 'Do NOT use it for anything that could wait until morning; this wakes people up. ' +
119
+ "Returns 'sent:delivered=N', where N is how many phones were actually reached.";
120
+ /** Ask, wait, and answer in a word a model cannot misread. */
121
+ export async function runApproval(client, args, defaults = {}) {
122
+ try {
123
+ const approved = await client.requestApproval(args.title, {
124
+ customId: args.customId,
125
+ description: args.description,
126
+ severity: args.severity ?? defaults.severity ?? 'HIGH',
127
+ approveLabel: args.approveLabel ?? defaults.approveLabel ?? 'Approve',
128
+ rejectLabel: args.rejectLabel ?? defaults.rejectLabel ?? 'Reject',
129
+ // `??`, not `||`: an explicit 0 means "do not wait", and `||` would turn
130
+ // that into five minutes.
131
+ timeoutMs: (args.timeoutSeconds ?? defaults.timeoutSeconds ?? 300) * 1000,
132
+ });
133
+ return approved ? APPROVED : REJECTED;
134
+ }
135
+ catch (error) {
136
+ // Returned, not thrown: a thrown tool error ends the agent run, and an
137
+ // agent that cannot ask permission should be able to say so and stop.
138
+ return errorResult(error);
139
+ }
140
+ }
141
+ export async function runAlert(client, args, defaults = {}) {
142
+ try {
143
+ return alertResult(await client.send(args.title, {
144
+ description: args.description,
145
+ severity: args.severity ?? defaults.severity ?? 'MEDIUM',
146
+ customId: args.customId,
147
+ }));
148
+ }
149
+ catch (error) {
150
+ // Includes M91DeliveryError, whose message already says nobody's phone
151
+ // rang. A model reading "error:" and retrying is right there; a model
152
+ // reading "sent" and stopping is not.
153
+ return errorResult(error);
154
+ }
155
+ }
156
+ //# sourceMappingURL=specs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"specs.js","sourceRoot":"","sources":["../../../src/integrations/specs.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAGpC,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;AACnC,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,IAAI,KAAK,YAAY,QAAQ;QAAE,OAAO,WAAW,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;IACxF,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,UAAU,MAAM,CAAC,OAAO,CAAC,IAAI,iBAAiB,EAAE,CAAC;AAC1D,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,KAAoB;IAC9C,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;QACvB,OAAO,CACL,sFAAsF;YACtF,qCAAqC,CACtC,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,CACL,8EAA8E;YAC9E,iBAAiB,KAAK,CAAC,YAAY,CAAC,MAAM,cAAc,KAAK,CAAC,QAAQ,IAAI;YAC1E,WAAW,KAAK,CAAC,OAAO,2BAA2B,CACpD,CAAC;IACJ,CAAC;IACD,OAAO,kBAAkB,KAAK,CAAC,SAAS,EAAE,CAAC;AAC7C,CAAC;AAED,MAAM,YAAY,GAChB,mFAAmF;IACnF,+DAA+D,CAAC;AAElE,MAAM,aAAa,GACjB,yEAAyE;IACzE,+EAA+E;IAC/E,4DAA4D,CAAC;AAE/D,gFAAgF;AAChF,MAAM,CAAC,MAAM,eAAe,GAAG;IAC7B,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,gFAAgF;gBAChF,6EAA6E;gBAC7E,oBAAoB;SACvB;QACD,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE;QACxD,WAAW,EAAE;YACX,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,gFAAgF;gBAChF,uEAAuE;SAC1E;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC;YAC3C,WAAW,EAAE,GAAG,YAAY,gDAAgD;SAC7E;QACD,YAAY,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,yCAAyC,EAAE;QACxF,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wCAAwC,EAAE;QACtF,cAAc,EAAE;YACd,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,+DAA+D;SAC7E;KACF;IACD,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,CAAC;IAC/B,oBAAoB,EAAE,KAAK;CACnB,CAAC;AAEX,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,IAAI,EAAE,QAAQ;IACd,UAAU,EAAE;QACV,KAAK,EAAE;YACL,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,oEAAoE;SAClF;QACD,QAAQ,EAAE;YACR,IAAI,EAAE,QAAQ;YACd,WAAW,EACT,kFAAkF;gBAClF,sEAAsE;SACzE;QACD,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,iCAAiC,EAAE;QAC/E,QAAQ,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,WAAW,EAAE,YAAY,EAAE;KACrG;IACD,QAAQ,EAAE,CAAC,OAAO,CAAC;IACnB,oBAAoB,EAAE,KAAK;CACnB,CAAC;AAEX,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AACzD,MAAM,CAAC,MAAM,eAAe,GAAG,gBAAgB,CAAC;AAEhD,MAAM,CAAC,MAAM,oBAAoB,GAC/B,4EAA4E;IAC5E,mFAAmF;IACnF,kFAAkF;IAClF,yCAAyC;IACzC,qFAAqF;IACrF,0EAA0E;IAC1E,6DAA6D;IAC7D,qFAAqF;IACrF,0CAA0C,CAAC;AAE7C,MAAM,CAAC,MAAM,iBAAiB,GAC5B,sFAAsF;IACtF,mFAAmF;IACnF,0BAA0B;IAC1B,mFAAmF;IACnF,qEAAqE;IACrE,6EAA6E;IAC7E,kFAAkF;IAClF,+EAA+E,CAAC;AAsClF,8DAA8D;AAC9D,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,MAAiB,EACjB,IAAkB,EAClB,WAA6B,EAAE;IAE/B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,EAAE;YACxD,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,IAAI,MAAM;YACtD,YAAY,EAAE,IAAI,CAAC,YAAY,IAAI,QAAQ,CAAC,YAAY,IAAI,SAAS;YACrE,WAAW,EAAE,IAAI,CAAC,WAAW,IAAI,QAAQ,CAAC,WAAW,IAAI,QAAQ;YACjE,yEAAyE;YACzE,0BAA0B;YAC1B,SAAS,EAAE,CAAC,IAAI,CAAC,cAAc,IAAI,QAAQ,CAAC,cAAc,IAAI,GAAG,CAAC,GAAG,IAAI;SAC1E,CAAC,CAAC;QACH,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uEAAuE;QACvE,sEAAsE;QACtE,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAiB,EACjB,IAAe,EACf,WAA0B,EAAE;IAE5B,IAAI,CAAC;QACH,OAAO,WAAW,CAChB,MAAM,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE;YAC5B,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ;YACxD,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CACH,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,uEAAuE;QACvE,sEAAsE;QACtE,sCAAsC;QACtC,OAAO,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;AACH,CAAC"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Vercel AI SDK tools.
3
+ *
4
+ * ```ts
5
+ * import { M91Client } from '@msg91comm/m91';
6
+ * import { createM91ApprovalTool, createM91AlertTool } from '@msg91comm/m91/integrations/vercel-ai';
7
+ *
8
+ * const client = new M91Client(process.env.M91_SEND_LINK!);
9
+ *
10
+ * const { text } = await generateText({
11
+ * model: openai('gpt-4o'),
12
+ * tools: {
13
+ * m91_request_approval: await createM91ApprovalTool(client),
14
+ * m91_send_alert: await createM91AlertTool(client),
15
+ * },
16
+ * maxSteps: 10,
17
+ * prompt: 'Look into order ORD-40122 and refund it if it checks out.',
18
+ * });
19
+ * ```
20
+ *
21
+ * The factories are **async** because `ai` is an optional peer dependency,
22
+ * imported only when one of these is called — `npm install @msg91comm/m91` stays at zero
23
+ * dependencies.
24
+ */
25
+ import type { M91Client } from '../client.js';
26
+ import { type AlertDefaults, type ApprovalDefaults } from './specs.js';
27
+ /**
28
+ * The blocking approval gate. Returns `"approved"`, `"rejected"` or
29
+ * `"error: …"`, and nothing but a real human approval returns `"approved"`.
30
+ */
31
+ export declare function createM91ApprovalTool(client: M91Client, defaults?: ApprovalDefaults): Promise<unknown>;
32
+ /** The fire-and-forget alert. Returns `"sent:delivered=N"` or `"error: …"`. */
33
+ export declare function createM91AlertTool(client: M91Client, defaults?: AlertDefaults): Promise<unknown>;
34
+ /** Both, keyed by tool name, ready to spread into `tools: {…}`. */
35
+ export declare function createM91Tools(client: M91Client, defaults?: ApprovalDefaults & AlertDefaults): Promise<Record<string, unknown>>;
36
+ //# sourceMappingURL=vercel-ai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel-ai.d.ts","sourceRoot":"","sources":["../../../src/integrations/vercel-ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAML,KAAK,aAAa,EAElB,KAAK,gBAAgB,EAGtB,MAAM,YAAY,CAAC;AAqBpB;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAqB,GAC9B,OAAO,CAAC,OAAO,CAAC,CASlB;AAED,+EAA+E;AAC/E,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,aAAkB,GAC3B,OAAO,CAAC,OAAO,CAAC,CAOlB;AAED,mEAAmE;AACnE,wBAAsB,cAAc,CAClC,MAAM,EAAE,SAAS,EACjB,QAAQ,GAAE,gBAAgB,GAAG,aAAkB,GAC9C,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAKlC"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Vercel AI SDK tools.
3
+ *
4
+ * ```ts
5
+ * import { M91Client } from '@msg91comm/m91';
6
+ * import { createM91ApprovalTool, createM91AlertTool } from '@msg91comm/m91/integrations/vercel-ai';
7
+ *
8
+ * const client = new M91Client(process.env.M91_SEND_LINK!);
9
+ *
10
+ * const { text } = await generateText({
11
+ * model: openai('gpt-4o'),
12
+ * tools: {
13
+ * m91_request_approval: await createM91ApprovalTool(client),
14
+ * m91_send_alert: await createM91AlertTool(client),
15
+ * },
16
+ * maxSteps: 10,
17
+ * prompt: 'Look into order ORD-40122 and refund it if it checks out.',
18
+ * });
19
+ * ```
20
+ *
21
+ * The factories are **async** because `ai` is an optional peer dependency,
22
+ * imported only when one of these is called — `npm install @msg91comm/m91` stays at zero
23
+ * dependencies.
24
+ */
25
+ import { ALERT_DESCRIPTION, ALERT_SCHEMA, APPROVAL_DESCRIPTION, APPROVAL_SCHEMA, runAlert, runApproval, } from './specs.js';
26
+ async function aiModule() {
27
+ try {
28
+ // A variable specifier: an optional peer dependency must not be a build
29
+ // requirement for this package.
30
+ const specifier = 'ai';
31
+ return (await import(specifier));
32
+ }
33
+ catch (error) {
34
+ throw new Error('The Vercel AI SDK integration needs the `ai` package. Install it with: npm install ai', { cause: error });
35
+ }
36
+ }
37
+ /**
38
+ * The blocking approval gate. Returns `"approved"`, `"rejected"` or
39
+ * `"error: …"`, and nothing but a real human approval returns `"approved"`.
40
+ */
41
+ export async function createM91ApprovalTool(client, defaults = {}) {
42
+ const { tool, jsonSchema } = await aiModule();
43
+ return tool({
44
+ description: APPROVAL_DESCRIPTION,
45
+ // JSON Schema rather than zod, so this adapter adds no dependency of its own
46
+ // and the argument docs stay in one file shared with every other framework.
47
+ inputSchema: jsonSchema(APPROVAL_SCHEMA),
48
+ execute: (args) => runApproval(client, args, defaults),
49
+ });
50
+ }
51
+ /** The fire-and-forget alert. Returns `"sent:delivered=N"` or `"error: …"`. */
52
+ export async function createM91AlertTool(client, defaults = {}) {
53
+ const { tool, jsonSchema } = await aiModule();
54
+ return tool({
55
+ description: ALERT_DESCRIPTION,
56
+ inputSchema: jsonSchema(ALERT_SCHEMA),
57
+ execute: (args) => runAlert(client, args, defaults),
58
+ });
59
+ }
60
+ /** Both, keyed by tool name, ready to spread into `tools: {…}`. */
61
+ export async function createM91Tools(client, defaults = {}) {
62
+ return {
63
+ m91_request_approval: await createM91ApprovalTool(client, defaults),
64
+ m91_send_alert: await createM91AlertTool(client, defaults),
65
+ };
66
+ }
67
+ //# sourceMappingURL=vercel-ai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vercel-ai.js","sourceRoot":"","sources":["../../../src/integrations/vercel-ai.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,oBAAoB,EACpB,eAAe,EAKf,QAAQ,EACR,WAAW,GACZ,MAAM,YAAY,CAAC;AAOpB,KAAK,UAAU,QAAQ;IACrB,IAAI,CAAC;QACH,wEAAwE;QACxE,gCAAgC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC;QACvB,OAAO,CAAC,MAAM,MAAM,CAAC,SAAS,CAAC,CAAwB,CAAC;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,uFAAuF,EACvF,EAAE,KAAK,EAAE,KAAK,EAAE,CACjB,CAAC;IACJ,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,MAAiB,EACjB,WAA6B,EAAE;IAE/B,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC;QACV,WAAW,EAAE,oBAAoB;QACjC,6EAA6E;QAC7E,4EAA4E;QAC5E,WAAW,EAAE,UAAU,CAAC,eAAe,CAAC;QACxC,OAAO,EAAE,CAAC,IAAkB,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;KACrE,CAAC,CAAC;AACL,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,MAAiB,EACjB,WAA0B,EAAE;IAE5B,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,GAAG,MAAM,QAAQ,EAAE,CAAC;IAC9C,OAAO,IAAI,CAAC;QACV,WAAW,EAAE,iBAAiB;QAC9B,WAAW,EAAE,UAAU,CAAC,YAAY,CAAC;QACrC,OAAO,EAAE,CAAC,IAAe,EAAE,EAAE,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,CAAC;KAC/D,CAAC,CAAC;AACL,CAAC;AAED,mEAAmE;AACnE,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,MAAiB,EACjB,WAA6C,EAAE;IAE/C,OAAO;QACL,oBAAoB,EAAE,MAAM,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC;QACnE,cAAc,EAAE,MAAM,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC;KAC3D,CAAC;AACJ,CAAC"}