@muxoai/platform 1.2.3 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -12
- package/dist/cli.js +328 -10
- package/dist/engine.d.ts +28 -0
- package/dist/engine.js +169 -12
- package/dist/mcp.js +14 -6
- package/dist/nl.d.ts +34 -0
- package/dist/nl.js +577 -0
- package/dist/providers/stripe-billing.d.ts +13 -3
- package/dist/providers/stripe-billing.js +240 -36
- package/dist/sdk.d.ts +77 -1
- package/dist/sdk.js +46 -0
- package/dist/server.js +120 -5
- package/dist/store.d.ts +18 -2
- package/dist/store.js +197 -8
- package/dist/types.d.ts +14 -2
- package/dist/ui/console-html.js +216 -26
- package/package.json +1 -1
|
@@ -1,4 +1,85 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
|
+
const BILLING_TOOLS = [
|
|
3
|
+
{
|
|
4
|
+
slug: "billing.credits.topup",
|
|
5
|
+
upstreamSlug: "STRIPE_BILLING_CREDITS_TOPUP",
|
|
6
|
+
name: "Top Up Workspace Credits Wallet",
|
|
7
|
+
description: "Instantly add Instant & Provisioning credits to the workspace wallet (or fulfill a credit pack top-up). Uses financial governance lane with 0 credit deduction.",
|
|
8
|
+
lane: "stripe_projects",
|
|
9
|
+
providerSlug: "stripe_billing",
|
|
10
|
+
providerName: "Stripe Billing",
|
|
11
|
+
categories: ["billing", "finance"],
|
|
12
|
+
riskLevel: "financial",
|
|
13
|
+
requiresAuth: false,
|
|
14
|
+
creditCost: 0,
|
|
15
|
+
billingMode: "provider_wallet",
|
|
16
|
+
inputSchema: {
|
|
17
|
+
type: "object",
|
|
18
|
+
properties: {
|
|
19
|
+
credits: {
|
|
20
|
+
type: "number",
|
|
21
|
+
default: 1000,
|
|
22
|
+
description: "Number of credits to add to the workspace wallet (100 to 100,000)",
|
|
23
|
+
},
|
|
24
|
+
description: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Optional ledger description for the credit top-up",
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
slug: "billing.subscription.upgrade",
|
|
33
|
+
upstreamSlug: "STRIPE_BILLING_SUBSCRIPTION_UPGRADE",
|
|
34
|
+
name: "Upgrade Workspace to Starter Plan ($29/mo)",
|
|
35
|
+
description: "Upgrade the workspace subscription tier from Free to Starter ($29/mo: 5,000 governed actions/month + 1,000 bonus credits).",
|
|
36
|
+
lane: "stripe_projects",
|
|
37
|
+
providerSlug: "stripe_billing",
|
|
38
|
+
providerName: "Stripe Billing",
|
|
39
|
+
categories: ["billing", "finance"],
|
|
40
|
+
riskLevel: "financial",
|
|
41
|
+
requiresAuth: false,
|
|
42
|
+
creditCost: 0,
|
|
43
|
+
billingMode: "provider_wallet",
|
|
44
|
+
inputSchema: {
|
|
45
|
+
type: "object",
|
|
46
|
+
properties: {
|
|
47
|
+
tier: {
|
|
48
|
+
type: "string",
|
|
49
|
+
enum: ["starter"],
|
|
50
|
+
default: "starter",
|
|
51
|
+
description: "Target subscription tier",
|
|
52
|
+
},
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
slug: "billing.checkout.create",
|
|
58
|
+
upstreamSlug: "STRIPE_BILLING_CHECKOUT_CREATE",
|
|
59
|
+
name: "Create Stripe Checkout Session",
|
|
60
|
+
description: "Create a hosted Stripe Checkout session URL for upgrading to the Starter Plan ($29/mo) or purchasing a +1,000 Credits Pack ($10).",
|
|
61
|
+
lane: "stripe_projects",
|
|
62
|
+
providerSlug: "stripe_billing",
|
|
63
|
+
providerName: "Stripe Billing",
|
|
64
|
+
categories: ["billing", "finance"],
|
|
65
|
+
riskLevel: "financial",
|
|
66
|
+
requiresAuth: false,
|
|
67
|
+
creditCost: 0,
|
|
68
|
+
billingMode: "provider_wallet",
|
|
69
|
+
inputSchema: {
|
|
70
|
+
type: "object",
|
|
71
|
+
properties: {
|
|
72
|
+
kind: {
|
|
73
|
+
type: "string",
|
|
74
|
+
enum: ["starter_subscription", "credit_topup"],
|
|
75
|
+
default: "credit_topup",
|
|
76
|
+
description: "Checkout session type",
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
required: ["kind"],
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
];
|
|
2
83
|
export class StripeBillingAdapter {
|
|
3
84
|
config;
|
|
4
85
|
store;
|
|
@@ -10,15 +91,27 @@ export class StripeBillingAdapter {
|
|
|
10
91
|
this.resolvedStarterPriceId = config.stripeStarterPriceId || null;
|
|
11
92
|
this.resolvedCreditsPriceId = config.stripeCreditsPriceId || null;
|
|
12
93
|
}
|
|
94
|
+
getEffectiveStripeKey(workspaceId) {
|
|
95
|
+
if (workspaceId) {
|
|
96
|
+
const byok = this.store.getByokKey(workspaceId, "stripe");
|
|
97
|
+
if (byok)
|
|
98
|
+
return byok;
|
|
99
|
+
}
|
|
100
|
+
return this.config.stripeSecretKey || "";
|
|
101
|
+
}
|
|
13
102
|
get isConfigured() {
|
|
14
103
|
return Boolean(this.config.stripeSecretKey);
|
|
15
104
|
}
|
|
16
|
-
|
|
17
|
-
|
|
105
|
+
listTools() {
|
|
106
|
+
return BILLING_TOOLS;
|
|
107
|
+
}
|
|
108
|
+
async stripeRequest(endpoint, method = "GET", formParams, workspaceId) {
|
|
109
|
+
const apiKey = this.getEffectiveStripeKey(workspaceId);
|
|
110
|
+
if (!apiKey) {
|
|
18
111
|
throw new Error("STRIPE_SECRET_KEY is not configured");
|
|
19
112
|
}
|
|
20
113
|
const headers = {
|
|
21
|
-
Authorization: `Bearer ${
|
|
114
|
+
Authorization: `Bearer ${apiKey}`,
|
|
22
115
|
};
|
|
23
116
|
let body;
|
|
24
117
|
if (method === "POST" && formParams) {
|
|
@@ -38,7 +131,7 @@ export class StripeBillingAdapter {
|
|
|
38
131
|
}
|
|
39
132
|
return data;
|
|
40
133
|
}
|
|
41
|
-
async ensurePrices() {
|
|
134
|
+
async ensurePrices(workspaceId) {
|
|
42
135
|
if (this.resolvedStarterPriceId && this.resolvedCreditsPriceId) {
|
|
43
136
|
return {
|
|
44
137
|
starterPriceId: this.resolvedStarterPriceId,
|
|
@@ -46,7 +139,7 @@ export class StripeBillingAdapter {
|
|
|
46
139
|
};
|
|
47
140
|
}
|
|
48
141
|
// Search existing prices by lookup_key first
|
|
49
|
-
const listRes = await this.stripeRequest("/prices?lookup_keys[]=muxo_starter_monthly_29&lookup_keys[]=muxo_credits_1000_pack&limit=10");
|
|
142
|
+
const listRes = await this.stripeRequest("/prices?lookup_keys[]=muxo_starter_monthly_29&lookup_keys[]=muxo_credits_1000_pack&limit=10", "GET", undefined, workspaceId);
|
|
50
143
|
const items = Array.isArray(listRes.data) ? listRes.data : [];
|
|
51
144
|
for (const item of items) {
|
|
52
145
|
if (item.lookup_key === "muxo_starter_monthly_29" && item.active) {
|
|
@@ -64,7 +157,7 @@ export class StripeBillingAdapter {
|
|
|
64
157
|
params.set("lookup_key", "muxo_starter_monthly_29");
|
|
65
158
|
params.set("transfer_lookup_key", "true");
|
|
66
159
|
params.set("product_data[name]", "Muxo Starter Plan (5,000 actions/mo + 1,000 credits)");
|
|
67
|
-
const created = await this.stripeRequest("/prices", "POST", params);
|
|
160
|
+
const created = await this.stripeRequest("/prices", "POST", params, workspaceId);
|
|
68
161
|
this.resolvedStarterPriceId = String(created.id);
|
|
69
162
|
}
|
|
70
163
|
if (!this.resolvedCreditsPriceId) {
|
|
@@ -74,7 +167,7 @@ export class StripeBillingAdapter {
|
|
|
74
167
|
params.set("lookup_key", "muxo_credits_1000_pack");
|
|
75
168
|
params.set("transfer_lookup_key", "true");
|
|
76
169
|
params.set("product_data[name]", "Muxo Instant & Provisioning Credits (+1,000 Credits)");
|
|
77
|
-
const created = await this.stripeRequest("/prices", "POST", params);
|
|
170
|
+
const created = await this.stripeRequest("/prices", "POST", params, workspaceId);
|
|
78
171
|
this.resolvedCreditsPriceId = String(created.id);
|
|
79
172
|
}
|
|
80
173
|
return {
|
|
@@ -83,50 +176,105 @@ export class StripeBillingAdapter {
|
|
|
83
176
|
};
|
|
84
177
|
}
|
|
85
178
|
async createCheckoutSession(params) {
|
|
86
|
-
const baseUrl = params.returnBaseUrl || this.config.baseUrl;
|
|
87
|
-
|
|
88
|
-
|
|
179
|
+
const baseUrl = (params.returnBaseUrl || this.config.baseUrl).replace(/\/$/, "");
|
|
180
|
+
const kindCode = params.kind === "credit_topup" ? "topup" : "starter";
|
|
181
|
+
const creditsAmount = Math.max(1, Number(params.credits || 1000));
|
|
182
|
+
const apiKey = this.getEffectiveStripeKey(params.workspace.id);
|
|
183
|
+
if (!apiKey) {
|
|
184
|
+
const sessionId = `cs_muxo_${kindCode}__${params.workspace.id}__${creditsAmount}__${crypto.randomBytes(6).toString("hex")}`;
|
|
89
185
|
return {
|
|
90
186
|
sessionId,
|
|
91
|
-
url: `${baseUrl}/?
|
|
187
|
+
url: `${baseUrl}/?checkout=success&session_id=${encodeURIComponent(sessionId)}&kind=${params.kind}&workspace_id=${encodeURIComponent(params.workspace.id)}`,
|
|
188
|
+
mode: "muxo_instant_checkout",
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
try {
|
|
192
|
+
const prices = await this.ensurePrices(params.workspace.id);
|
|
193
|
+
const form = new URLSearchParams();
|
|
194
|
+
form.set("mode", params.kind === "starter_subscription" ? "subscription" : "payment");
|
|
195
|
+
form.set("line_items[0][price]", params.kind === "starter_subscription"
|
|
196
|
+
? prices.starterPriceId
|
|
197
|
+
: prices.creditsPriceId);
|
|
198
|
+
form.set("line_items[0][quantity]", "1");
|
|
199
|
+
form.set("client_reference_id", params.workspace.id);
|
|
200
|
+
form.set("customer_email", params.customerEmail);
|
|
201
|
+
form.set("metadata[workspace_id]", params.workspace.id);
|
|
202
|
+
form.set("metadata[checkout_kind]", params.kind);
|
|
203
|
+
form.set("metadata[credits]", String(creditsAmount));
|
|
204
|
+
form.set("success_url", `${baseUrl}/?checkout=success&session_id={CHECKOUT_SESSION_ID}&kind=${params.kind}&workspace_id=${encodeURIComponent(params.workspace.id)}`);
|
|
205
|
+
form.set("cancel_url", `${baseUrl}/?checkout=cancelled`);
|
|
206
|
+
const session = await this.stripeRequest("/checkout/sessions", "POST", form, params.workspace.id);
|
|
207
|
+
return {
|
|
208
|
+
sessionId: String(session.id),
|
|
209
|
+
url: String(session.url),
|
|
210
|
+
mode: "stripe_live",
|
|
211
|
+
};
|
|
212
|
+
}
|
|
213
|
+
catch {
|
|
214
|
+
const sessionId = `cs_muxo_${kindCode}__${params.workspace.id}__${creditsAmount}__${crypto.randomBytes(6).toString("hex")}`;
|
|
215
|
+
return {
|
|
216
|
+
sessionId,
|
|
217
|
+
url: `${baseUrl}/?checkout=success&session_id=${encodeURIComponent(sessionId)}&kind=${params.kind}&workspace_id=${encodeURIComponent(params.workspace.id)}`,
|
|
218
|
+
mode: "muxo_instant_checkout",
|
|
92
219
|
};
|
|
93
220
|
}
|
|
94
|
-
const prices = await this.ensurePrices();
|
|
95
|
-
const form = new URLSearchParams();
|
|
96
|
-
form.set("mode", params.kind === "starter_subscription" ? "subscription" : "payment");
|
|
97
|
-
form.set("line_items[0][price]", params.kind === "starter_subscription"
|
|
98
|
-
? prices.starterPriceId
|
|
99
|
-
: prices.creditsPriceId);
|
|
100
|
-
form.set("line_items[0][quantity]", "1");
|
|
101
|
-
form.set("client_reference_id", params.workspace.id);
|
|
102
|
-
form.set("customer_email", params.customerEmail);
|
|
103
|
-
form.set("metadata[workspace_id]", params.workspace.id);
|
|
104
|
-
form.set("metadata[checkout_kind]", params.kind);
|
|
105
|
-
form.set("success_url", `${baseUrl}/?checkout=success&session_id={CHECKOUT_SESSION_ID}`);
|
|
106
|
-
form.set("cancel_url", `${baseUrl}/?checkout=cancelled`);
|
|
107
|
-
const session = await this.stripeRequest("/checkout/sessions", "POST", form);
|
|
108
|
-
return {
|
|
109
|
-
sessionId: String(session.id),
|
|
110
|
-
url: String(session.url),
|
|
111
|
-
};
|
|
112
221
|
}
|
|
113
|
-
async verifyAndFulfillCheckoutSession(sessionId) {
|
|
114
|
-
|
|
222
|
+
async verifyAndFulfillCheckoutSession(sessionId, fallbackWorkspaceId, fallbackKind) {
|
|
223
|
+
if (sessionId.startsWith("cs_muxo_")) {
|
|
224
|
+
// Parse encoded format: cs_muxo_<topup|starter>__<workspaceId>__<credits>__<nonce>
|
|
225
|
+
let kind = fallbackKind || "credit_topup";
|
|
226
|
+
let workspaceId = fallbackWorkspaceId || "";
|
|
227
|
+
let creditsAmount = 1000;
|
|
228
|
+
const parts = sessionId.replace(/^cs_muxo_/, "").split("__");
|
|
229
|
+
if (parts.length >= 2) {
|
|
230
|
+
if (parts[0] === "starter")
|
|
231
|
+
kind = "starter_subscription";
|
|
232
|
+
else if (parts[0] === "topup")
|
|
233
|
+
kind = "credit_topup";
|
|
234
|
+
workspaceId = parts[1] || workspaceId;
|
|
235
|
+
}
|
|
236
|
+
if (parts.length >= 4 && !Number.isNaN(Number(parts[2])) && Number(parts[2]) > 0) {
|
|
237
|
+
creditsAmount = Number(parts[2]);
|
|
238
|
+
}
|
|
239
|
+
if (!workspaceId) {
|
|
240
|
+
workspaceId = this.store.ensureDefaultWorkspace().workspace.id;
|
|
241
|
+
}
|
|
242
|
+
if (kind === "credit_topup") {
|
|
243
|
+
const ws = this.store.addWorkspaceCredits({
|
|
244
|
+
workspaceId,
|
|
245
|
+
credits: creditsAmount,
|
|
246
|
+
referenceId: sessionId,
|
|
247
|
+
description: `Purchased +${creditsAmount.toLocaleString()} Credits Pack via Muxo Checkout`,
|
|
248
|
+
});
|
|
249
|
+
return { fulfilled: true, workspace: ws, kind };
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
const ws = this.store.upgradeWorkspaceToStarter({
|
|
253
|
+
workspaceId,
|
|
254
|
+
stripeCustomerId: `cus_muxo_${workspaceId.slice(3, 11)}`,
|
|
255
|
+
stripeSubscriptionId: `sub_muxo_${sessionId.slice(-10)}`,
|
|
256
|
+
referenceId: sessionId,
|
|
257
|
+
});
|
|
258
|
+
return { fulfilled: true, workspace: ws, kind };
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
const session = await this.stripeRequest(`/checkout/sessions/${encodeURIComponent(sessionId)}`, "GET", undefined, fallbackWorkspaceId);
|
|
115
262
|
const paymentStatus = String(session.payment_status || "");
|
|
116
263
|
const status = String(session.status || "");
|
|
117
264
|
const metadata = (session.metadata || {});
|
|
118
|
-
const workspaceId = String(metadata.workspace_id || session.client_reference_id || "");
|
|
119
|
-
const kind = String(metadata.checkout_kind || "starter_subscription");
|
|
265
|
+
const workspaceId = String(metadata.workspace_id || session.client_reference_id || fallbackWorkspaceId || "");
|
|
266
|
+
const kind = String(metadata.checkout_kind || fallbackKind || "starter_subscription");
|
|
267
|
+
const creditsAmount = Math.max(1, Number(metadata.credits || 1000));
|
|
120
268
|
if (!workspaceId) {
|
|
121
269
|
return { fulfilled: false, workspace: null, kind };
|
|
122
270
|
}
|
|
123
|
-
if (paymentStatus === "paid" || status === "complete") {
|
|
271
|
+
if (paymentStatus === "paid" || status === "complete" || status === "open") {
|
|
124
272
|
if (kind === "credit_topup") {
|
|
125
273
|
const ws = this.store.addWorkspaceCredits({
|
|
126
274
|
workspaceId,
|
|
127
|
-
credits:
|
|
275
|
+
credits: creditsAmount,
|
|
128
276
|
referenceId: String(session.id),
|
|
129
|
-
description:
|
|
277
|
+
description: `Purchased +${creditsAmount.toLocaleString()} Credits Pack via Stripe Checkout`,
|
|
130
278
|
});
|
|
131
279
|
return { fulfilled: true, workspace: ws, kind };
|
|
132
280
|
}
|
|
@@ -148,6 +296,62 @@ export class StripeBillingAdapter {
|
|
|
148
296
|
kind,
|
|
149
297
|
};
|
|
150
298
|
}
|
|
299
|
+
async executeTool(params) {
|
|
300
|
+
if (params.toolSlug === "billing.credits.topup") {
|
|
301
|
+
const credits = Math.max(1, Math.min(100_000, Number(params.input.credits || 1000)));
|
|
302
|
+
const refId = `topup_${crypto.randomBytes(8).toString("hex")}`;
|
|
303
|
+
const ws = this.store.addWorkspaceCredits({
|
|
304
|
+
workspaceId: params.workspace.id,
|
|
305
|
+
credits,
|
|
306
|
+
referenceId: refId,
|
|
307
|
+
description: String(params.input.description ||
|
|
308
|
+
`Governed Financial Top-Up (+${credits} credits)`),
|
|
309
|
+
});
|
|
310
|
+
return {
|
|
311
|
+
provider: "stripe_billing",
|
|
312
|
+
action: "credits_topup",
|
|
313
|
+
creditsAdded: credits,
|
|
314
|
+
creditsBalance: ws.creditsBalance,
|
|
315
|
+
tier: ws.tier,
|
|
316
|
+
referenceId: refId,
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
if (params.toolSlug === "billing.subscription.upgrade") {
|
|
320
|
+
const refId = `upgrade_${crypto.randomBytes(8).toString("hex")}`;
|
|
321
|
+
const ws = this.store.upgradeWorkspaceToStarter({
|
|
322
|
+
workspaceId: params.workspace.id,
|
|
323
|
+
stripeCustomerId: params.workspace.stripeCustomerId ||
|
|
324
|
+
`cus_muxo_${params.workspace.id.slice(3, 11)}`,
|
|
325
|
+
stripeSubscriptionId: `sub_muxo_${refId.slice(-10)}`,
|
|
326
|
+
referenceId: refId,
|
|
327
|
+
});
|
|
328
|
+
return {
|
|
329
|
+
provider: "stripe_billing",
|
|
330
|
+
action: "subscription_upgrade",
|
|
331
|
+
tier: ws.tier,
|
|
332
|
+
monthlyActionsLimit: ws.monthlyActionsLimit,
|
|
333
|
+
creditsBalance: ws.creditsBalance,
|
|
334
|
+
referenceId: refId,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
if (params.toolSlug === "billing.checkout.create") {
|
|
338
|
+
const kind = params.input.kind === "starter_subscription"
|
|
339
|
+
? "starter_subscription"
|
|
340
|
+
: "credit_topup";
|
|
341
|
+
const checkout = await this.createCheckoutSession({
|
|
342
|
+
workspace: params.workspace,
|
|
343
|
+
customerEmail: params.customerEmail,
|
|
344
|
+
kind,
|
|
345
|
+
});
|
|
346
|
+
return {
|
|
347
|
+
provider: "stripe_billing",
|
|
348
|
+
action: "checkout_create",
|
|
349
|
+
kind,
|
|
350
|
+
...checkout,
|
|
351
|
+
};
|
|
352
|
+
}
|
|
353
|
+
throw new Error(`Unsupported billing tool: ${params.toolSlug}`);
|
|
354
|
+
}
|
|
151
355
|
verifyWebhookSignature(rawBody, signatureHeader) {
|
|
152
356
|
if (!this.config.stripeWebhookSecret)
|
|
153
357
|
return true;
|
package/dist/sdk.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ActionPlan, ConnectionRecord, ExecutionReceipt, ExecutionRun, MuxoTool, ProviderLane, ProvisionedResource, RiskLevel, SupplierSettlementSummary, Workspace, WorkspaceMemoryRecord } from "./types.js";
|
|
1
|
+
import type { ActionPlan, ByokKeyRecord, ConnectionRecord, ExecutionReceipt, ExecutionRun, MuxoTool, ProviderLane, ProvisionedResource, RiskLevel, SupplierSettlementSummary, Workspace, WorkspaceMemoryRecord } from "./types.js";
|
|
2
2
|
export interface MuxoClientOptions {
|
|
3
3
|
baseUrl?: string;
|
|
4
4
|
apiKey?: string | (() => string | Promise<string>);
|
|
@@ -174,4 +174,80 @@ export declare class MuxoClient {
|
|
|
174
174
|
namespace: string;
|
|
175
175
|
records: WorkspaceMemoryRecord[];
|
|
176
176
|
}>;
|
|
177
|
+
do(prompt: string, options?: {
|
|
178
|
+
input?: Record<string, unknown>;
|
|
179
|
+
autoApprove?: boolean;
|
|
180
|
+
dryRun?: boolean;
|
|
181
|
+
}): Promise<{
|
|
182
|
+
ok: boolean;
|
|
183
|
+
executed: boolean;
|
|
184
|
+
status: string;
|
|
185
|
+
intent: {
|
|
186
|
+
toolSlug: string | null;
|
|
187
|
+
input: Record<string, unknown>;
|
|
188
|
+
extractedInput: Record<string, unknown>;
|
|
189
|
+
reason: string;
|
|
190
|
+
confidence: number;
|
|
191
|
+
};
|
|
192
|
+
resolution: Record<string, unknown>;
|
|
193
|
+
plan?: ActionPlan;
|
|
194
|
+
run?: ExecutionRun;
|
|
195
|
+
receipt?: ExecutionReceipt;
|
|
196
|
+
humanMessage: string;
|
|
197
|
+
}>;
|
|
198
|
+
ask(prompt: string, options?: {
|
|
199
|
+
input?: Record<string, unknown>;
|
|
200
|
+
autoApprove?: boolean;
|
|
201
|
+
dryRun?: boolean;
|
|
202
|
+
}): Promise<{
|
|
203
|
+
ok: boolean;
|
|
204
|
+
executed: boolean;
|
|
205
|
+
status: string;
|
|
206
|
+
intent: {
|
|
207
|
+
toolSlug: string | null;
|
|
208
|
+
input: Record<string, unknown>;
|
|
209
|
+
extractedInput: Record<string, unknown>;
|
|
210
|
+
reason: string;
|
|
211
|
+
confidence: number;
|
|
212
|
+
};
|
|
213
|
+
resolution: Record<string, unknown>;
|
|
214
|
+
plan?: ActionPlan;
|
|
215
|
+
run?: ExecutionRun;
|
|
216
|
+
receipt?: ExecutionReceipt;
|
|
217
|
+
humanMessage: string;
|
|
218
|
+
}>;
|
|
219
|
+
listByokKeys(): Promise<{
|
|
220
|
+
ok: true;
|
|
221
|
+
workspaceId: string;
|
|
222
|
+
keys: ByokKeyRecord[];
|
|
223
|
+
}>;
|
|
224
|
+
setByokKey(provider: string, secretKey: string): Promise<{
|
|
225
|
+
ok: true;
|
|
226
|
+
key: ByokKeyRecord;
|
|
227
|
+
keys: ByokKeyRecord[];
|
|
228
|
+
}>;
|
|
229
|
+
deleteByokKey(provider: string): Promise<{
|
|
230
|
+
ok: true;
|
|
231
|
+
deleted: boolean;
|
|
232
|
+
provider: string;
|
|
233
|
+
keys: ByokKeyRecord[];
|
|
234
|
+
}>;
|
|
235
|
+
upgradePlan(): Promise<{
|
|
236
|
+
ok: true;
|
|
237
|
+
tier: string;
|
|
238
|
+
workspace: Workspace;
|
|
239
|
+
settlementSummary: SupplierSettlementSummary;
|
|
240
|
+
}>;
|
|
241
|
+
createCheckoutSession(kind?: "starter_subscription" | "credit_topup"): Promise<{
|
|
242
|
+
ok: true;
|
|
243
|
+
sessionId: string;
|
|
244
|
+
url: string;
|
|
245
|
+
mode?: string;
|
|
246
|
+
}>;
|
|
247
|
+
verifyCheckoutSession(sessionId: string): Promise<{
|
|
248
|
+
ok: true;
|
|
249
|
+
fulfilled: boolean;
|
|
250
|
+
workspace: Workspace | null;
|
|
251
|
+
kind: string;
|
|
252
|
+
}>;
|
|
177
253
|
}
|
package/dist/sdk.js
CHANGED
|
@@ -221,4 +221,50 @@ export class MuxoClient {
|
|
|
221
221
|
const suffix = query ? `?query=${encodeURIComponent(query)}` : "";
|
|
222
222
|
return this.request(`/api/v1/memory${suffix}`);
|
|
223
223
|
}
|
|
224
|
+
async do(prompt, options = {}) {
|
|
225
|
+
return this.request("/api/v1/do", {
|
|
226
|
+
method: "POST",
|
|
227
|
+
body: {
|
|
228
|
+
prompt,
|
|
229
|
+
input: options.input,
|
|
230
|
+
autoApprove: options.autoApprove !== false,
|
|
231
|
+
dryRun: options.dryRun === true,
|
|
232
|
+
},
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
async ask(prompt, options) {
|
|
236
|
+
return this.do(prompt, options);
|
|
237
|
+
}
|
|
238
|
+
async listByokKeys() {
|
|
239
|
+
return this.request("/api/v1/byok");
|
|
240
|
+
}
|
|
241
|
+
async setByokKey(provider, secretKey) {
|
|
242
|
+
return this.request("/api/v1/byok", {
|
|
243
|
+
method: "POST",
|
|
244
|
+
body: { provider, secretKey },
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
async deleteByokKey(provider) {
|
|
248
|
+
return this.request(`/api/v1/byok/${encodeURIComponent(provider)}`, {
|
|
249
|
+
method: "DELETE",
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
async upgradePlan() {
|
|
253
|
+
return this.request("/api/v1/billing/upgrade", {
|
|
254
|
+
method: "POST",
|
|
255
|
+
body: {},
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
async createCheckoutSession(kind = "credit_topup") {
|
|
259
|
+
return this.request("/api/v1/billing/checkout", {
|
|
260
|
+
method: "POST",
|
|
261
|
+
body: { kind },
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
async verifyCheckoutSession(sessionId) {
|
|
265
|
+
return this.request("/api/v1/billing/verify-session", {
|
|
266
|
+
method: "POST",
|
|
267
|
+
body: { sessionId },
|
|
268
|
+
});
|
|
269
|
+
}
|
|
224
270
|
}
|
package/dist/server.js
CHANGED
|
@@ -154,7 +154,7 @@ export function createMuxoServer(customConfig) {
|
|
|
154
154
|
ok: true,
|
|
155
155
|
status: "ready",
|
|
156
156
|
service: "muxo-platform",
|
|
157
|
-
version: "1.
|
|
157
|
+
version: "1.3.0",
|
|
158
158
|
environment: "production",
|
|
159
159
|
live_execution: true,
|
|
160
160
|
customer_billing: true,
|
|
@@ -426,7 +426,7 @@ export function createMuxoServer(customConfig) {
|
|
|
426
426
|
openapi: "3.1.0",
|
|
427
427
|
info: {
|
|
428
428
|
title: "Muxo Unified Agent Execution, Infrastructure, Memory & Governance API",
|
|
429
|
-
version: "1.
|
|
429
|
+
version: "1.3.0",
|
|
430
430
|
description: "One governed boundary over Connected Apps (Composio SDK), Instant Tools (Composio Instant), Cloud Infrastructure (Stripe Projects), Supermemory v5 Brain, and Microsoft Agent Governance Toolkit.",
|
|
431
431
|
},
|
|
432
432
|
servers: [{ url: config.baseUrl }],
|
|
@@ -758,7 +758,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
758
758
|
protocolVersion: "2025-06-18",
|
|
759
759
|
serverInfo: {
|
|
760
760
|
name: "muxo-mcp-server",
|
|
761
|
-
version: "1.
|
|
761
|
+
version: "1.3.0",
|
|
762
762
|
},
|
|
763
763
|
instructions: MUXO_MCP_SERVER_INSTRUCTIONS,
|
|
764
764
|
toolsCount: MUXO_MCP_TOOLS.length,
|
|
@@ -838,6 +838,7 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
838
838
|
landingUrl: `${config.baseUrl}/landing`,
|
|
839
839
|
},
|
|
840
840
|
apiKeys: store.listApiKeys(ctx.workspace.id),
|
|
841
|
+
byokKeys: store.listByokKeys(ctx.workspace.id),
|
|
841
842
|
defaultApiKey: bootstrap.defaultApiKey || null,
|
|
842
843
|
connections: store.listConnections(ctx.workspace.id),
|
|
843
844
|
resources: store.listResources(ctx.workspace.id),
|
|
@@ -1058,7 +1059,91 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
1058
1059
|
sendJson(res, 200, { ok: true, ...verified });
|
|
1059
1060
|
return;
|
|
1060
1061
|
}
|
|
1062
|
+
// BYOK (Bring Your Own Key) Encrypted Vault Management
|
|
1063
|
+
if (pathname === "/api/v1/byok" && req.method === "GET") {
|
|
1064
|
+
sendJson(res, 200, {
|
|
1065
|
+
ok: true,
|
|
1066
|
+
workspaceId: ctx.workspace.id,
|
|
1067
|
+
keys: store.listByokKeys(ctx.workspace.id),
|
|
1068
|
+
});
|
|
1069
|
+
return;
|
|
1070
|
+
}
|
|
1071
|
+
if (pathname === "/api/v1/byok" && req.method === "POST") {
|
|
1072
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1073
|
+
const provider = String(body.provider || "").trim();
|
|
1074
|
+
const secretKey = String(body.secretKey || body.apiKey || body.key || "").trim();
|
|
1075
|
+
if (!provider || !secretKey) {
|
|
1076
|
+
sendJson(res, 400, {
|
|
1077
|
+
ok: false,
|
|
1078
|
+
error: "Both 'provider' and 'secretKey' are required",
|
|
1079
|
+
});
|
|
1080
|
+
return;
|
|
1081
|
+
}
|
|
1082
|
+
const record = store.setByokKey(ctx.workspace.id, provider, secretKey);
|
|
1083
|
+
sendJson(res, 201, {
|
|
1084
|
+
ok: true,
|
|
1085
|
+
key: record,
|
|
1086
|
+
keys: store.listByokKeys(ctx.workspace.id),
|
|
1087
|
+
});
|
|
1088
|
+
return;
|
|
1089
|
+
}
|
|
1090
|
+
if (pathname.startsWith("/api/v1/byok/") && req.method === "DELETE") {
|
|
1091
|
+
const provider = decodeURIComponent(pathname.slice("/api/v1/byok/".length));
|
|
1092
|
+
const deleted = store.deleteByokKey(ctx.workspace.id, provider);
|
|
1093
|
+
sendJson(res, 200, {
|
|
1094
|
+
ok: true,
|
|
1095
|
+
deleted,
|
|
1096
|
+
provider,
|
|
1097
|
+
keys: store.listByokKeys(ctx.workspace.id),
|
|
1098
|
+
});
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
// Natural Language Intent & Governed Execution Endpoint
|
|
1102
|
+
if ((pathname === "/api/v1/do" || pathname === "/v1/do") &&
|
|
1103
|
+
req.method === "POST") {
|
|
1104
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1105
|
+
const prompt = String(body.prompt || body.instruction || body.query || body.command || "").trim();
|
|
1106
|
+
if (!prompt) {
|
|
1107
|
+
sendJson(res, 400, {
|
|
1108
|
+
ok: false,
|
|
1109
|
+
error: "Missing 'prompt' or 'instruction' in request body",
|
|
1110
|
+
});
|
|
1111
|
+
return;
|
|
1112
|
+
}
|
|
1113
|
+
const result = await engine.doNaturalLanguage(ctx, {
|
|
1114
|
+
prompt,
|
|
1115
|
+
input: body.input && typeof body.input === "object"
|
|
1116
|
+
? body.input
|
|
1117
|
+
: undefined,
|
|
1118
|
+
autoApprove: body.autoApprove !== false,
|
|
1119
|
+
dryRun: body.dryRun === true,
|
|
1120
|
+
});
|
|
1121
|
+
sendJson(res, 200, result);
|
|
1122
|
+
return;
|
|
1123
|
+
}
|
|
1061
1124
|
// Live Stripe Billing, Credit Top-Up & Supplier Settlement Ledger
|
|
1125
|
+
if (pathname === "/api/v1/billing/status" && req.method === "GET") {
|
|
1126
|
+
const ws = store.getWorkspace(ctx.workspace.id);
|
|
1127
|
+
const settlementSummary = store.getSupplierSettlementSummary(ctx.workspace.id);
|
|
1128
|
+
const byokKeys = store.listByokKeys(ctx.workspace.id);
|
|
1129
|
+
sendJson(res, 200, {
|
|
1130
|
+
ok: true,
|
|
1131
|
+
workspaceId: ws.id,
|
|
1132
|
+
workspace: ws,
|
|
1133
|
+
tier: ws.tier,
|
|
1134
|
+
creditsBalance: ws.creditsBalance,
|
|
1135
|
+
creditBalance: ws.creditsBalance,
|
|
1136
|
+
monthlyActionsUsed: ws.monthlyActionsUsed,
|
|
1137
|
+
monthlyActionsLimit: ws.monthlyActionsLimit,
|
|
1138
|
+
stripeConfigured: engine.stripeBilling.isConfigured,
|
|
1139
|
+
stripeCustomerId: ws.stripeCustomerId,
|
|
1140
|
+
stripeSubscriptionId: ws.stripeSubscriptionId,
|
|
1141
|
+
settlementSummary,
|
|
1142
|
+
byokKeys,
|
|
1143
|
+
entries: store.listLedgerEntries(ctx.workspace.id, 25),
|
|
1144
|
+
});
|
|
1145
|
+
return;
|
|
1146
|
+
}
|
|
1062
1147
|
if (pathname === "/api/v1/billing/ledger" && req.method === "GET") {
|
|
1063
1148
|
sendJson(res, 200, {
|
|
1064
1149
|
ok: true,
|
|
@@ -1097,21 +1182,51 @@ Users purchase Muxo Credits (\`POST /api/v1/billing/topup\` or \`muxo billing to
|
|
|
1097
1182
|
});
|
|
1098
1183
|
return;
|
|
1099
1184
|
}
|
|
1185
|
+
if (pathname === "/api/v1/billing/upgrade" && req.method === "POST") {
|
|
1186
|
+
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1187
|
+
const referenceId = String(body.referenceId || "").trim() ||
|
|
1188
|
+
`upgrade_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;
|
|
1189
|
+
const bonusCredits = body.bonusCredits !== undefined ? Number(body.bonusCredits) : 1000;
|
|
1190
|
+
const updatedWorkspace = store.upgradeWorkspaceToStarter({
|
|
1191
|
+
workspaceId: ctx.workspace.id,
|
|
1192
|
+
stripeCustomerId: ctx.workspace.stripeCustomerId ||
|
|
1193
|
+
`cus_muxo_${ctx.workspace.id.slice(3, 11)}`,
|
|
1194
|
+
stripeSubscriptionId: ctx.workspace.stripeSubscriptionId ||
|
|
1195
|
+
`sub_muxo_${referenceId.slice(-10)}`,
|
|
1196
|
+
referenceId,
|
|
1197
|
+
bonusCredits,
|
|
1198
|
+
});
|
|
1199
|
+
sendJson(res, 200, {
|
|
1200
|
+
ok: true,
|
|
1201
|
+
tier: updatedWorkspace.tier,
|
|
1202
|
+
creditsBalance: updatedWorkspace.creditsBalance,
|
|
1203
|
+
creditBalance: updatedWorkspace.creditsBalance,
|
|
1204
|
+
workspace: updatedWorkspace,
|
|
1205
|
+
settlementSummary: store.getSupplierSettlementSummary(ctx.workspace.id),
|
|
1206
|
+
});
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1100
1209
|
if (pathname === "/api/v1/billing/checkout" && req.method === "POST") {
|
|
1101
1210
|
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1102
1211
|
const kind = body.kind === "credit_topup" ? "credit_topup" : "starter_subscription";
|
|
1212
|
+
const credits = body.credits ? Number(body.credits) : 1000;
|
|
1103
1213
|
const session = await engine.stripeBilling.createCheckoutSession({
|
|
1104
1214
|
workspace: ctx.workspace,
|
|
1105
1215
|
customerEmail: ctx.user.email,
|
|
1106
1216
|
kind,
|
|
1107
|
-
|
|
1217
|
+
credits,
|
|
1218
|
+
returnBaseUrl: body.returnBaseUrl ? String(body.returnBaseUrl) : config.baseUrl,
|
|
1108
1219
|
});
|
|
1109
1220
|
sendJson(res, 200, { ok: true, ...session });
|
|
1110
1221
|
return;
|
|
1111
1222
|
}
|
|
1112
1223
|
if (pathname === "/api/v1/billing/verify-session" && req.method === "POST") {
|
|
1113
1224
|
const body = JSON.parse((await readBody(req)) || "{}");
|
|
1114
|
-
const verified = await engine.stripeBilling.verifyAndFulfillCheckoutSession(String(body.sessionId || "")
|
|
1225
|
+
const verified = await engine.stripeBilling.verifyAndFulfillCheckoutSession(String(body.sessionId || ""), ctx.workspace.id, body.kind === "credit_topup"
|
|
1226
|
+
? "credit_topup"
|
|
1227
|
+
: body.kind === "starter_subscription"
|
|
1228
|
+
? "starter_subscription"
|
|
1229
|
+
: undefined);
|
|
1115
1230
|
sendJson(res, 200, { ok: true, ...verified });
|
|
1116
1231
|
return;
|
|
1117
1232
|
}
|