@muxoai/platform 1.2.3 → 1.3.1
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/.agents/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +19 -4
- package/.codex/config.toml +9 -2
- package/README.md +72 -28
- package/dist/cli.js +1047 -43
- package/dist/engine.d.ts +29 -0
- package/dist/engine.js +221 -16
- package/dist/mcp.d.ts +6 -1
- package/dist/mcp.js +120 -26
- package/dist/nl.d.ts +34 -0
- package/dist/nl.js +601 -0
- package/dist/providers/composio-instant.d.ts +1 -0
- package/dist/providers/composio-instant.js +6 -5
- package/dist/providers/composio-sdk.d.ts +1 -0
- package/dist/providers/composio-sdk.js +6 -2
- package/dist/providers/stripe-billing.d.ts +13 -3
- package/dist/providers/stripe-billing.js +250 -36
- package/dist/providers/stripe-projects.js +61 -4
- package/dist/providers/supermemory.d.ts +2 -0
- package/dist/providers/supermemory.js +58 -40
- package/dist/sdk.d.ts +77 -1
- package/dist/sdk.js +46 -0
- package/dist/server.js +202 -29
- package/dist/store.d.ts +19 -2
- package/dist/store.js +216 -11
- package/dist/types.d.ts +14 -2
- package/dist/ui/console-html.js +329 -119
- package/package.json +1 -1
- package/plugins/muxo/.app.json +1 -1
- package/plugins/muxo/.claude-plugin/plugin.json +2 -2
- package/plugins/muxo/.codex-plugin/plugin.json +7 -5
- package/plugins/muxo/.mcp.json +1 -33
- package/plugins/muxo/assets/logo.png +0 -0
- package/plugins/muxo/hooks/session-start.sh +1 -1
- package/plugins/muxo/plugin.json +63 -6
- package/plugins/muxo/skills/muxo/SKILL.md +92 -14
- package/plugins/muxo/skills/muxo/agents/openai.yaml +12 -0
- package/plugins/muxo/skills/muxo/references/cli.md +4 -2
- package/plugins/muxo/skills/muxo/references/mcp.md +15 -9
- package/plugins/muxo/skills/setup/SKILL.md +8 -2
- package/plugins/muxo/skills/setup/agents/openai.yaml +12 -0
package/dist/store.js
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import { DatabaseSync } from "node:sqlite";
|
|
2
2
|
import crypto from "node:crypto";
|
|
3
|
+
export const BYOK_PROVIDER_CATALOG = {
|
|
4
|
+
openai: { category: "llm", envVarName: "OPENAI_API_KEY", label: "OpenAI (GPT-4o / o3-mini)" },
|
|
5
|
+
anthropic: { category: "llm", envVarName: "ANTHROPIC_API_KEY", label: "Anthropic (Claude 3.7 Sonnet)" },
|
|
6
|
+
gemini: { category: "llm", envVarName: "GEMINI_API_KEY", label: "Google Gemini" },
|
|
7
|
+
openrouter: { category: "llm", envVarName: "OPENROUTER_API_KEY", label: "OpenRouter (Universal LLM)" },
|
|
8
|
+
composio: { category: "supplier", envVarName: "COMPOSIO_API_KEY", label: "Composio SDK & Instant" },
|
|
9
|
+
stripe: { category: "supplier", envVarName: "STRIPE_SECRET_KEY", label: "Stripe Projects & Billing" },
|
|
10
|
+
supermemory: { category: "supplier", envVarName: "SUPERMEMORY_API_KEY", label: "Supermemory v5 Knowledge Graph" },
|
|
11
|
+
firecrawl: { category: "supplier", envVarName: "FIRECRAWL_API_KEY", label: "Firecrawl Web Scrape & Crawl" },
|
|
12
|
+
exa: { category: "supplier", envVarName: "EXA_API_KEY", label: "Exa Semantic Web Search" },
|
|
13
|
+
};
|
|
3
14
|
const DEFAULT_POLICY = {
|
|
4
15
|
mode: "enforce",
|
|
5
16
|
requireApprovalFor: ["admin", "financial", "provisioning", "destructive"],
|
|
@@ -201,6 +212,17 @@ export class MuxoStore {
|
|
|
201
212
|
event_id TEXT PRIMARY KEY,
|
|
202
213
|
processed_at TEXT NOT NULL
|
|
203
214
|
);
|
|
215
|
+
|
|
216
|
+
CREATE TABLE IF NOT EXISTS byok_keys (
|
|
217
|
+
workspace_id TEXT NOT NULL,
|
|
218
|
+
provider TEXT NOT NULL,
|
|
219
|
+
category TEXT NOT NULL,
|
|
220
|
+
env_var_name TEXT NOT NULL,
|
|
221
|
+
key_preview TEXT NOT NULL,
|
|
222
|
+
encrypted_secret_hex TEXT NOT NULL,
|
|
223
|
+
updated_at TEXT NOT NULL,
|
|
224
|
+
PRIMARY KEY (workspace_id, provider)
|
|
225
|
+
);
|
|
204
226
|
`);
|
|
205
227
|
// Backwards-compatible column migrations for existing databases
|
|
206
228
|
for (const stmt of [
|
|
@@ -311,10 +333,16 @@ export class MuxoStore {
|
|
|
311
333
|
description: "Free Plan initial monthly allowance (1,000 actions + 250 trial credits)",
|
|
312
334
|
});
|
|
313
335
|
const sessionToken = this.createSession(userId, workspaceId);
|
|
336
|
+
const defaultKey = this.createApiKey({
|
|
337
|
+
workspaceId,
|
|
338
|
+
name: "Default Live Key",
|
|
339
|
+
environment: "live",
|
|
340
|
+
});
|
|
314
341
|
return {
|
|
315
342
|
user: this.getUser(userId),
|
|
316
343
|
workspace: this.getWorkspace(workspaceId),
|
|
317
344
|
sessionToken,
|
|
345
|
+
apiKey: defaultKey.secretKey,
|
|
318
346
|
};
|
|
319
347
|
}
|
|
320
348
|
loginUser(email, password) {
|
|
@@ -560,8 +588,146 @@ export class MuxoStore {
|
|
|
560
588
|
for (const row of rows) {
|
|
561
589
|
Object.assign(merged, this.decryptSecrets(workspaceId, row.encrypted_secrets_hex));
|
|
562
590
|
}
|
|
591
|
+
const byokRows = this.db
|
|
592
|
+
.prepare("SELECT encrypted_secret_hex FROM byok_keys WHERE workspace_id = ?")
|
|
593
|
+
.all(workspaceId);
|
|
594
|
+
for (const row of byokRows) {
|
|
595
|
+
Object.assign(merged, this.decryptSecrets(workspaceId, row.encrypted_secret_hex));
|
|
596
|
+
}
|
|
563
597
|
return merged;
|
|
564
598
|
}
|
|
599
|
+
// --- BYOK (Bring Your Own Key) Encrypted Vault ---
|
|
600
|
+
normalizeByokProvider(providerInput) {
|
|
601
|
+
const raw = providerInput.trim().toLowerCase();
|
|
602
|
+
for (const [slug, meta] of Object.entries(BYOK_PROVIDER_CATALOG)) {
|
|
603
|
+
if (raw === slug || raw === meta.envVarName.toLowerCase()) {
|
|
604
|
+
return { provider: slug, category: meta.category, envVarName: meta.envVarName };
|
|
605
|
+
}
|
|
606
|
+
}
|
|
607
|
+
const clean = raw.replace(/[^a-z0-9_]/g, "");
|
|
608
|
+
const envVarName = raw.endsWith("_key") || raw.endsWith("_token")
|
|
609
|
+
? raw.toUpperCase()
|
|
610
|
+
: `${clean.toUpperCase()}_API_KEY`;
|
|
611
|
+
return {
|
|
612
|
+
provider: clean || "custom",
|
|
613
|
+
category: "supplier",
|
|
614
|
+
envVarName,
|
|
615
|
+
};
|
|
616
|
+
}
|
|
617
|
+
setByokKey(workspaceId, providerInput, secretKey) {
|
|
618
|
+
const trimmed = secretKey.trim();
|
|
619
|
+
if (!trimmed) {
|
|
620
|
+
throw new Error("BYOK secretKey must not be empty");
|
|
621
|
+
}
|
|
622
|
+
const { provider, category, envVarName } = this.normalizeByokProvider(providerInput);
|
|
623
|
+
const now = new Date().toISOString();
|
|
624
|
+
const keyPreview = trimmed.length <= 8
|
|
625
|
+
? `${trimmed.slice(0, 2)}***`
|
|
626
|
+
: `${trimmed.slice(0, 6)}...${trimmed.slice(-4)}`;
|
|
627
|
+
const encryptedHex = this.encryptSecrets(workspaceId, { [envVarName]: trimmed });
|
|
628
|
+
this.db
|
|
629
|
+
.prepare(`INSERT INTO byok_keys (
|
|
630
|
+
workspace_id, provider, category, env_var_name, key_preview, encrypted_secret_hex, updated_at
|
|
631
|
+
) VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
632
|
+
ON CONFLICT(workspace_id, provider) DO UPDATE SET
|
|
633
|
+
category = excluded.category,
|
|
634
|
+
env_var_name = excluded.env_var_name,
|
|
635
|
+
key_preview = excluded.key_preview,
|
|
636
|
+
encrypted_secret_hex = excluded.encrypted_secret_hex,
|
|
637
|
+
updated_at = excluded.updated_at`)
|
|
638
|
+
.run(workspaceId, provider, category, envVarName, keyPreview, encryptedHex, now);
|
|
639
|
+
return {
|
|
640
|
+
provider,
|
|
641
|
+
providerSlug: provider,
|
|
642
|
+
category,
|
|
643
|
+
envVarName,
|
|
644
|
+
keyPreview,
|
|
645
|
+
configured: true,
|
|
646
|
+
updatedAt: now,
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
getByokKey(workspaceId, providerInput) {
|
|
650
|
+
const { provider, envVarName } = this.normalizeByokProvider(providerInput);
|
|
651
|
+
const row = this.db
|
|
652
|
+
.prepare("SELECT encrypted_secret_hex FROM byok_keys WHERE workspace_id = ? AND provider = ?")
|
|
653
|
+
.get(workspaceId, provider);
|
|
654
|
+
if (!row)
|
|
655
|
+
return null;
|
|
656
|
+
const dec = this.decryptSecrets(workspaceId, row.encrypted_secret_hex);
|
|
657
|
+
return dec[envVarName] || Object.values(dec)[0] || null;
|
|
658
|
+
}
|
|
659
|
+
deleteByokKey(workspaceId, providerInput) {
|
|
660
|
+
const { provider } = this.normalizeByokProvider(providerInput);
|
|
661
|
+
const res = this.db
|
|
662
|
+
.prepare("DELETE FROM byok_keys WHERE workspace_id = ? AND provider = ?")
|
|
663
|
+
.run(workspaceId, provider);
|
|
664
|
+
return Number(res.changes || 0) > 0;
|
|
665
|
+
}
|
|
666
|
+
listByokKeys(workspaceId) {
|
|
667
|
+
const rows = this.db
|
|
668
|
+
.prepare("SELECT provider, category, env_var_name, key_preview, updated_at FROM byok_keys WHERE workspace_id = ? ORDER BY updated_at DESC")
|
|
669
|
+
.all(workspaceId);
|
|
670
|
+
const configuredMap = new Map();
|
|
671
|
+
for (const r of rows) {
|
|
672
|
+
const p = String(r.provider);
|
|
673
|
+
configuredMap.set(p, {
|
|
674
|
+
provider: p,
|
|
675
|
+
providerSlug: p,
|
|
676
|
+
category: String(r.category),
|
|
677
|
+
envVarName: String(r.env_var_name),
|
|
678
|
+
keyPreview: String(r.key_preview),
|
|
679
|
+
configured: true,
|
|
680
|
+
updatedAt: String(r.updated_at),
|
|
681
|
+
});
|
|
682
|
+
}
|
|
683
|
+
const result = [];
|
|
684
|
+
for (const [slug, meta] of Object.entries(BYOK_PROVIDER_CATALOG)) {
|
|
685
|
+
const existing = configuredMap.get(slug);
|
|
686
|
+
if (existing) {
|
|
687
|
+
result.push(existing);
|
|
688
|
+
configuredMap.delete(slug);
|
|
689
|
+
}
|
|
690
|
+
else {
|
|
691
|
+
result.push({
|
|
692
|
+
provider: slug,
|
|
693
|
+
providerSlug: slug,
|
|
694
|
+
category: meta.category,
|
|
695
|
+
envVarName: meta.envVarName,
|
|
696
|
+
keyPreview: "",
|
|
697
|
+
configured: false,
|
|
698
|
+
updatedAt: "",
|
|
699
|
+
});
|
|
700
|
+
}
|
|
701
|
+
}
|
|
702
|
+
for (const extra of configuredMap.values()) {
|
|
703
|
+
result.push(extra);
|
|
704
|
+
}
|
|
705
|
+
return result;
|
|
706
|
+
}
|
|
707
|
+
hasByokForLane(workspaceId, lane, toolSlug) {
|
|
708
|
+
const slug = (toolSlug || "").toLowerCase();
|
|
709
|
+
if (slug.startsWith("billing."))
|
|
710
|
+
return false;
|
|
711
|
+
if (lane === "composio_sdk") {
|
|
712
|
+
return Boolean(this.getByokKey(workspaceId, "composio"));
|
|
713
|
+
}
|
|
714
|
+
if (lane === "composio_instant") {
|
|
715
|
+
if (this.getByokKey(workspaceId, "composio"))
|
|
716
|
+
return true;
|
|
717
|
+
if ((slug.includes("scrape") || slug.includes("crawl") || slug.includes("seo")) &&
|
|
718
|
+
this.getByokKey(workspaceId, "firecrawl")) {
|
|
719
|
+
return true;
|
|
720
|
+
}
|
|
721
|
+
if (slug.includes("search") && this.getByokKey(workspaceId, "exa")) {
|
|
722
|
+
return true;
|
|
723
|
+
}
|
|
724
|
+
return false;
|
|
725
|
+
}
|
|
726
|
+
if (lane === "stripe_projects") {
|
|
727
|
+
return Boolean(this.getByokKey(workspaceId, "stripe"));
|
|
728
|
+
}
|
|
729
|
+
return false;
|
|
730
|
+
}
|
|
565
731
|
// --- Plans ---
|
|
566
732
|
createPlan(params) {
|
|
567
733
|
const id = `plan_${crypto.randomBytes(8).toString("hex")}`;
|
|
@@ -627,7 +793,8 @@ export class MuxoStore {
|
|
|
627
793
|
SET monthly_actions_used = ?, credits_balance = ?, updated_at = ?
|
|
628
794
|
WHERE id = ?`)
|
|
629
795
|
.run(newActionsUsed, newCreditsBalance, now, params.workspaceId);
|
|
630
|
-
const
|
|
796
|
+
const byokUsed = this.hasByokForLane(params.workspaceId, run.lane, run.toolSlug);
|
|
797
|
+
const settlement = this.computeSupplierSettlement(run.lane, run.toolSlug, params.creditsMetered, byokUsed ? "settled_by_customer_byok" : "settled_by_muxo_master_wallet", params.workspaceId);
|
|
631
798
|
this.addLedgerEntry({
|
|
632
799
|
workspaceId: params.workspaceId,
|
|
633
800
|
kind: "run_deduction",
|
|
@@ -635,7 +802,9 @@ export class MuxoStore {
|
|
|
635
802
|
creditsDelta: -params.creditsMetered,
|
|
636
803
|
balanceAfter: newCreditsBalance,
|
|
637
804
|
referenceId: run.id,
|
|
638
|
-
description:
|
|
805
|
+
description: byokUsed
|
|
806
|
+
? `Executed ${run.toolSlug} (${run.lane}) — BYOK 0-credit execution (Customer's own ${settlement.supplierName} key)`
|
|
807
|
+
: `Executed ${run.toolSlug} (${run.lane}) — User paid Muxo ${params.creditsMetered} credits ($${(settlement.userRetailChargeCents / 100).toFixed(2)}) -> Muxo paid ${settlement.supplierName} ($${(settlement.supplierWholesalePayableCents / 100).toFixed(2)})`,
|
|
639
808
|
});
|
|
640
809
|
}
|
|
641
810
|
const receipt = this.issueReceipt({
|
|
@@ -774,7 +943,8 @@ export class MuxoStore {
|
|
|
774
943
|
if (!ws)
|
|
775
944
|
throw new Error(`Workspace ${params.workspaceId} not found`);
|
|
776
945
|
const now = new Date().toISOString();
|
|
777
|
-
const
|
|
946
|
+
const bonus = params.bonusCredits !== undefined ? Number(params.bonusCredits) : 1000;
|
|
947
|
+
const newCredits = ws.creditsBalance + bonus;
|
|
778
948
|
this.db
|
|
779
949
|
.prepare(`UPDATE workspaces
|
|
780
950
|
SET tier = 'starter',
|
|
@@ -789,10 +959,10 @@ export class MuxoStore {
|
|
|
789
959
|
workspaceId: params.workspaceId,
|
|
790
960
|
kind: "subscription_upgrade",
|
|
791
961
|
actionsDelta: 4000,
|
|
792
|
-
creditsDelta:
|
|
962
|
+
creditsDelta: bonus,
|
|
793
963
|
balanceAfter: newCredits,
|
|
794
964
|
referenceId: params.referenceId,
|
|
795
|
-
description:
|
|
965
|
+
description: `Upgraded to Starter Plan ($29/mo — 5,000 actions/mo + ${bonus} credits)`,
|
|
796
966
|
});
|
|
797
967
|
return this.getWorkspace(params.workspaceId);
|
|
798
968
|
}
|
|
@@ -840,12 +1010,35 @@ export class MuxoStore {
|
|
|
840
1010
|
createdAt: now,
|
|
841
1011
|
};
|
|
842
1012
|
}
|
|
843
|
-
computeSupplierSettlement(lane, toolSlug, creditCost, settlementStatus = "settled_by_muxo_master_wallet") {
|
|
1013
|
+
computeSupplierSettlement(lane, toolSlug, creditCost, settlementStatus = "settled_by_muxo_master_wallet", workspaceId) {
|
|
1014
|
+
const useByok = settlementStatus === "settled_by_customer_byok" ||
|
|
1015
|
+
settlementStatus === "planned_customer_byok" ||
|
|
1016
|
+
(Number(creditCost || 0) === 0 && workspaceId
|
|
1017
|
+
? this.hasByokForLane(workspaceId, lane, toolSlug)
|
|
1018
|
+
: false);
|
|
1019
|
+
const upstreamProvider = toolSlug.split(".")[1] || lane;
|
|
1020
|
+
if (useByok) {
|
|
1021
|
+
const isPlanned = settlementStatus === "planned_muxo_master_wallet" ||
|
|
1022
|
+
settlementStatus === "planned_customer_byok";
|
|
1023
|
+
return {
|
|
1024
|
+
fundingMode: "byok",
|
|
1025
|
+
supplier: lane,
|
|
1026
|
+
supplierName: "Customer BYOK Upstream Key (0% Muxo Markup)",
|
|
1027
|
+
upstreamProvider,
|
|
1028
|
+
userChargeCredits: 0,
|
|
1029
|
+
userRetailChargeCents: 0,
|
|
1030
|
+
supplierWholesalePayableCents: 0,
|
|
1031
|
+
muxoNetMarginCents: 0,
|
|
1032
|
+
settlementStatus: isPlanned
|
|
1033
|
+
? "planned_customer_byok"
|
|
1034
|
+
: "settled_by_customer_byok",
|
|
1035
|
+
masterAccountRef: "customer_byok_vault",
|
|
1036
|
+
};
|
|
1037
|
+
}
|
|
844
1038
|
const userChargeCredits = Math.max(0, Number(creditCost || 0));
|
|
845
1039
|
const userRetailChargeCents = Math.round(userChargeCredits * 100) / 100;
|
|
846
1040
|
const supplierWholesalePayableCents = Math.round(userRetailChargeCents * 0.6 * 100) / 100;
|
|
847
1041
|
const muxoNetMarginCents = Math.round((userRetailChargeCents - supplierWholesalePayableCents) * 100) / 100;
|
|
848
|
-
const upstreamProvider = toolSlug.split(".")[1] || lane;
|
|
849
1042
|
const supplierMeta = {
|
|
850
1043
|
composio_instant: {
|
|
851
1044
|
supplierName: "Composio Instant Wholesale Wallet",
|
|
@@ -878,6 +1071,9 @@ export class MuxoStore {
|
|
|
878
1071
|
const ws = this.getWorkspace(workspaceId);
|
|
879
1072
|
const ledger = this.listLedgerEntries(workspaceId, 500);
|
|
880
1073
|
const runs = this.listRuns(workspaceId, 500).filter((r) => r.status === "succeeded");
|
|
1074
|
+
const byokProviders = this.listByokKeys(workspaceId)
|
|
1075
|
+
.filter((k) => k.configured)
|
|
1076
|
+
.map((k) => k.provider);
|
|
881
1077
|
const totalCreditsPurchasedOrGranted = ledger
|
|
882
1078
|
.filter((e) => e.creditsDelta > 0)
|
|
883
1079
|
.reduce((acc, e) => acc + e.creditsDelta, 0);
|
|
@@ -909,7 +1105,9 @@ export class MuxoStore {
|
|
|
909
1105
|
let totalSupplierWholesalePaidCents = 0;
|
|
910
1106
|
let totalMuxoNetMarginCents = 0;
|
|
911
1107
|
for (const run of runs) {
|
|
912
|
-
const s = this.computeSupplierSettlement(run.lane, run.toolSlug, run.creditsMetered,
|
|
1108
|
+
const s = this.computeSupplierSettlement(run.lane, run.toolSlug, run.creditsMetered, run.creditsMetered === 0 && this.hasByokForLane(workspaceId, run.lane, run.toolSlug)
|
|
1109
|
+
? "settled_by_customer_byok"
|
|
1110
|
+
: "settled_by_muxo_master_wallet", workspaceId);
|
|
913
1111
|
const bucket = bySupplier[run.lane] || bySupplier.composio_instant;
|
|
914
1112
|
bucket.runsCount += 1;
|
|
915
1113
|
bucket.creditsConsumed += s.userChargeCredits;
|
|
@@ -930,6 +1128,8 @@ export class MuxoStore {
|
|
|
930
1128
|
return {
|
|
931
1129
|
workspaceId,
|
|
932
1130
|
fundingModel: "user_pays_muxo_muxo_pays_suppliers",
|
|
1131
|
+
activeFundingMode: byokProviders.length > 0 ? "byok_hybrid" : "muxo_funded",
|
|
1132
|
+
byokProviders,
|
|
933
1133
|
creditPriceCents: 1,
|
|
934
1134
|
totalCreditsPurchasedOrGranted,
|
|
935
1135
|
totalCreditsConsumed,
|
|
@@ -952,7 +1152,12 @@ export class MuxoStore {
|
|
|
952
1152
|
if (kind === "run_deduction" && refId) {
|
|
953
1153
|
const run = this.getRun(workspaceId, refId);
|
|
954
1154
|
if (run) {
|
|
955
|
-
|
|
1155
|
+
const isByokEntry = creditsDelta === 0 &&
|
|
1156
|
+
(String(r.description || "").includes("BYOK") ||
|
|
1157
|
+
this.hasByokForLane(workspaceId, run.lane, run.toolSlug));
|
|
1158
|
+
supplierSettlement = this.computeSupplierSettlement(run.lane, run.toolSlug, Math.abs(creditsDelta), isByokEntry
|
|
1159
|
+
? "settled_by_customer_byok"
|
|
1160
|
+
: "settled_by_muxo_master_wallet", workspaceId);
|
|
956
1161
|
}
|
|
957
1162
|
}
|
|
958
1163
|
return {
|
|
@@ -1203,7 +1408,7 @@ export class MuxoStore {
|
|
|
1203
1408
|
: null,
|
|
1204
1409
|
supplierSettlement: this.computeSupplierSettlement(lane, toolSlug, creditCost, approvalStatus === "executed"
|
|
1205
1410
|
? "settled_by_muxo_master_wallet"
|
|
1206
|
-
: "planned_muxo_master_wallet"),
|
|
1411
|
+
: "planned_muxo_master_wallet", String(row.workspace_id)),
|
|
1207
1412
|
createdAt: String(row.created_at),
|
|
1208
1413
|
expiresAt: String(row.expires_at),
|
|
1209
1414
|
};
|
|
@@ -1253,7 +1458,7 @@ export class MuxoStore {
|
|
|
1253
1458
|
decisionRecord: row.decision_record_json
|
|
1254
1459
|
? JSON.parse(String(row.decision_record_json))
|
|
1255
1460
|
: null,
|
|
1256
|
-
supplierSettlement: this.computeSupplierSettlement(lane, toolSlug, creditsMetered, "settled_by_muxo_master_wallet"),
|
|
1461
|
+
supplierSettlement: this.computeSupplierSettlement(lane, toolSlug, creditsMetered, "settled_by_muxo_master_wallet", String(row.workspace_id)),
|
|
1257
1462
|
issuedAt: String(row.issued_at),
|
|
1258
1463
|
};
|
|
1259
1464
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ export interface MuxoTool {
|
|
|
62
62
|
providerUrl?: string;
|
|
63
63
|
metadata?: Record<string, unknown>;
|
|
64
64
|
}
|
|
65
|
+
export type ToolDescriptor = MuxoTool;
|
|
65
66
|
export interface ConnectionRecord {
|
|
66
67
|
id: string;
|
|
67
68
|
workspaceId: string;
|
|
@@ -168,8 +169,17 @@ export interface WorkspaceMemoryRecord {
|
|
|
168
169
|
metadata: Record<string, unknown>;
|
|
169
170
|
createdAt: string;
|
|
170
171
|
}
|
|
172
|
+
export interface ByokKeyRecord {
|
|
173
|
+
provider: string;
|
|
174
|
+
providerSlug?: string;
|
|
175
|
+
category: "llm" | "supplier";
|
|
176
|
+
envVarName: string;
|
|
177
|
+
keyPreview: string;
|
|
178
|
+
configured: boolean;
|
|
179
|
+
updatedAt: string;
|
|
180
|
+
}
|
|
171
181
|
export interface SupplierSettlement {
|
|
172
|
-
fundingMode: "muxo_funded";
|
|
182
|
+
fundingMode: "muxo_funded" | "byok";
|
|
173
183
|
supplier: ProviderLane;
|
|
174
184
|
supplierName: string;
|
|
175
185
|
upstreamProvider: string;
|
|
@@ -177,12 +187,14 @@ export interface SupplierSettlement {
|
|
|
177
187
|
userRetailChargeCents: number;
|
|
178
188
|
supplierWholesalePayableCents: number;
|
|
179
189
|
muxoNetMarginCents: number;
|
|
180
|
-
settlementStatus: "settled_by_muxo_master_wallet" | "planned_muxo_master_wallet";
|
|
190
|
+
settlementStatus: "settled_by_muxo_master_wallet" | "planned_muxo_master_wallet" | "settled_by_customer_byok" | "planned_customer_byok";
|
|
181
191
|
masterAccountRef: string;
|
|
182
192
|
}
|
|
183
193
|
export interface SupplierSettlementSummary {
|
|
184
194
|
workspaceId: string;
|
|
185
195
|
fundingModel: "user_pays_muxo_muxo_pays_suppliers";
|
|
196
|
+
activeFundingMode?: "muxo_funded" | "byok_hybrid";
|
|
197
|
+
byokProviders?: string[];
|
|
186
198
|
creditPriceCents: number;
|
|
187
199
|
totalCreditsPurchasedOrGranted: number;
|
|
188
200
|
totalCreditsConsumed: number;
|