@muxoai/platform 1.3.0 → 1.3.2

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 (51) hide show
  1. package/.agents/plugins/marketplace.json +1 -1
  2. package/.claude-plugin/marketplace.json +19 -4
  3. package/.codex/config.toml +9 -2
  4. package/README.md +63 -20
  5. package/dist/clerk.d.ts +33 -0
  6. package/dist/clerk.js +198 -0
  7. package/dist/cli.js +1181 -99
  8. package/dist/engine.d.ts +22 -1
  9. package/dist/engine.js +284 -14
  10. package/dist/mcp.d.ts +6 -1
  11. package/dist/mcp.js +109 -22
  12. package/dist/nl.js +60 -36
  13. package/dist/policy.d.ts +9 -0
  14. package/dist/policy.js +73 -0
  15. package/dist/providers/composio-instant.d.ts +4 -0
  16. package/dist/providers/composio-instant.js +634 -534
  17. package/dist/providers/composio-sdk.d.ts +1 -0
  18. package/dist/providers/composio-sdk.js +6 -2
  19. package/dist/providers/microsoft-governance.d.ts +61 -2
  20. package/dist/providers/microsoft-governance.js +458 -24
  21. package/dist/providers/stripe-billing.js +14 -4
  22. package/dist/providers/stripe-projects.d.ts +4 -1
  23. package/dist/providers/stripe-projects.js +123 -12
  24. package/dist/providers/supermemory.d.ts +28 -5
  25. package/dist/providers/supermemory.js +183 -55
  26. package/dist/sdk.d.ts +167 -1
  27. package/dist/sdk.js +113 -2
  28. package/dist/server.js +258 -40
  29. package/dist/store.d.ts +26 -1
  30. package/dist/store.js +255 -6
  31. package/dist/types.d.ts +86 -0
  32. package/dist/ui/console-html.d.ts +16 -0
  33. package/dist/ui/console-html.js +2427 -2206
  34. package/dist/ui/design-tokens.d.ts +177 -0
  35. package/dist/ui/design-tokens.js +210 -0
  36. package/dist/version.d.ts +1 -0
  37. package/dist/version.js +1 -0
  38. package/package.json +2 -2
  39. package/plugins/muxo/.app.json +1 -1
  40. package/plugins/muxo/.claude-plugin/plugin.json +2 -2
  41. package/plugins/muxo/.codex-plugin/plugin.json +7 -5
  42. package/plugins/muxo/.mcp.json +1 -33
  43. package/plugins/muxo/assets/logo.png +0 -0
  44. package/plugins/muxo/hooks/session-start.sh +1 -1
  45. package/plugins/muxo/plugin.json +63 -6
  46. package/plugins/muxo/skills/muxo/SKILL.md +92 -14
  47. package/plugins/muxo/skills/muxo/agents/openai.yaml +12 -0
  48. package/plugins/muxo/skills/muxo/references/cli.md +4 -2
  49. package/plugins/muxo/skills/muxo/references/mcp.md +15 -9
  50. package/plugins/muxo/skills/setup/SKILL.md +8 -2
  51. package/plugins/muxo/skills/setup/agents/openai.yaml +12 -0
package/dist/engine.d.ts CHANGED
@@ -78,6 +78,7 @@ export declare class MuxoEngine {
78
78
  toolSlug: string;
79
79
  input?: Record<string, unknown>;
80
80
  reason?: string;
81
+ fundingMode?: "muxo_funded" | "byok";
81
82
  }): Promise<{
82
83
  plan: ActionPlan;
83
84
  tool: MuxoTool;
@@ -95,30 +96,50 @@ export declare class MuxoEngine {
95
96
  }>;
96
97
  getPlan(ctx: ExecutionContext, planId: string): ActionPlan;
97
98
  approvePlan(ctx: ExecutionContext, planId: string, decision?: "approved" | "rejected"): ActionPlan;
99
+ private enrichMemoryContext;
98
100
  getRunContext(ctx: ExecutionContext, query?: string): Promise<Record<string, unknown>>;
99
101
  getMemoryOverview(ctx: ExecutionContext, query?: string): Promise<{
100
102
  enabled: boolean;
101
103
  namespace: string;
104
+ fundingSource: string;
102
105
  context: MemoryContextSummary;
103
106
  recentMemories: WorkspaceMemoryRecord[];
104
107
  memories: WorkspaceMemoryRecord[];
108
+ temporalFacts: ReturnType<MuxoStore["listTemporalFacts"]>;
109
+ historicalFacts: ReturnType<MuxoStore["listTemporalFacts"]>;
105
110
  }>;
106
111
  addWorkspaceMemory(ctx: ExecutionContext, params: {
107
112
  title: string;
108
113
  content: string;
109
114
  kind?: WorkspaceMemoryRecord["kind"];
110
115
  metadata?: Record<string, unknown>;
116
+ subject?: string;
117
+ predicate?: string;
118
+ object?: string;
111
119
  }): Promise<WorkspaceMemoryRecord>;
112
120
  deleteWorkspaceMemory(ctx: ExecutionContext, idOrDocId: string): Promise<{
113
121
  deleted: boolean;
114
122
  record: WorkspaceMemoryRecord | null;
115
123
  }>;
124
+ forgetWorkspaceMemoryMatching(ctx: ExecutionContext, query: string): Promise<{
125
+ query: string;
126
+ deletedLocalCount: number;
127
+ invalidatedFactsCount: number;
128
+ deletedRemoteIds: string[];
129
+ deletedMemories: WorkspaceMemoryRecord[];
130
+ invalidatedFacts: ReturnType<MuxoStore["listTemporalFacts"]>;
131
+ }>;
132
+ activateWorkspaceKillSwitch(ctx: ExecutionContext, params: {
133
+ reason: string;
134
+ action?: "terminate" | "quarantine" | "suspend";
135
+ }): Promise<Record<string, unknown>>;
136
+ resumeWorkspaceKillSwitch(ctx: ExecutionContext): Record<string, unknown>;
116
137
  executePlanForRisk(ctx: ExecutionContext, planId: string, expectedRisk: RiskLevel): Promise<{
117
138
  run: ExecutionRun;
118
139
  receipt: ExecutionReceipt;
119
140
  }>;
120
141
  getRun(ctx: ExecutionContext, runId: string): ExecutionRun;
121
- cancelRun(ctx: ExecutionContext, runId: string): {
142
+ cancelRun(ctx: ExecutionContext, runId: string, reason?: string): {
122
143
  run: ExecutionRun;
123
144
  receipt: ExecutionReceipt | null;
124
145
  };
package/dist/engine.js CHANGED
@@ -3,7 +3,7 @@ import { ComposioInstantAdapter } from "./providers/composio-instant.js";
3
3
  import { ComposioSdkAdapter } from "./providers/composio-sdk.js";
4
4
  import { MicrosoftGovernanceAdapter } from "./providers/microsoft-governance.js";
5
5
  import { StripeBillingAdapter } from "./providers/stripe-billing.js";
6
- import { StripeProjectsAdapter } from "./providers/stripe-projects.js";
6
+ import { StripeProjectsAdapter, isPaidCloudProvisioning, } from "./providers/stripe-projects.js";
7
7
  import { SupermemoryAdapter } from "./providers/supermemory.js";
8
8
  export class MuxoEngine {
9
9
  config;
@@ -26,10 +26,14 @@ export class MuxoEngine {
26
26
  }
27
27
  // 1. get_profile
28
28
  getProfile(ctx) {
29
+ const nickname = (ctx.user.email || "").split("@")[0] ||
30
+ ctx.user.name.toLowerCase().replace(/\s+/g, ".") ||
31
+ ctx.user.id;
29
32
  return {
30
33
  id: ctx.user.id,
31
34
  name: ctx.user.name,
32
35
  email: ctx.user.email,
36
+ nickname,
33
37
  user: ctx.user,
34
38
  actorId: ctx.actorId,
35
39
  authType: ctx.authType,
@@ -392,8 +396,14 @@ export class MuxoEngine {
392
396
  resolvedInput = nl.input;
393
397
  resolvedReason = params.reason || nl.reason || nlSource;
394
398
  }
395
- const byokActive = this.store.hasByokForLane(ws.id, tool.lane, tool.slug);
396
- const effectiveCreditCost = byokActive ? 0 : tool.creditCost;
399
+ const byokActive = params.fundingMode === "muxo_funded"
400
+ ? false
401
+ : this.store.hasByokForLane(ws.id, tool.lane, tool.slug);
402
+ const isPaidResourcePlan = isPaidCloudProvisioning(tool, resolvedInput);
403
+ const baseCreditCost = isPaidResourcePlan
404
+ ? Math.max(tool.creditCost, 25)
405
+ : tool.creditCost;
406
+ const effectiveCreditCost = byokActive ? 0 : baseCreditCost;
397
407
  if (ws.monthlyActionsUsed >= ws.monthlyActionsLimit) {
398
408
  throw new Error(`Monthly action limit reached (${ws.monthlyActionsUsed}/${ws.monthlyActionsLimit}). Upgrade to Starter ($29/mo) to unlock 5,000 actions/mo.`);
399
409
  }
@@ -417,7 +427,8 @@ export class MuxoEngine {
417
427
  }
418
428
  // 2. Recall Supermemory v5 contextual brain for this workspace + tool intent
419
429
  const memoryQuery = `${tool.slug} ${tool.name} ${resolvedReason}`.trim();
420
- const memoryContext = await this.supermemory.getContextForWorkspace(ws.id, memoryQuery);
430
+ const supermemoryByok = this.store.getByokKey(ws.id, "supermemory");
431
+ const memoryContext = await this.enrichMemoryContext(ws.id, await this.supermemory.getContextForWorkspace(ws.id, memoryQuery, supermemoryByok), memoryQuery);
421
432
  const requiresHumanApproval = decisionRecord.verdict === "escalate" ||
422
433
  (ws.policy.mode === "enforce" &&
423
434
  ws.policy.requireApprovalFor.includes(tool.riskLevel));
@@ -506,6 +517,91 @@ export class MuxoEngine {
506
517
  approvedBy: ctx.user.email,
507
518
  });
508
519
  }
520
+ async enrichMemoryContext(workspaceId, ctx, query) {
521
+ const localRecords = this.store.listMemoryRecords(workspaceId, 8);
522
+ const temporalFacts = this.store.listTemporalFacts(workspaceId, {
523
+ includeHistorical: false,
524
+ query,
525
+ limit: 15,
526
+ });
527
+ const recalled = ctx.recalledMemories.length > 0
528
+ ? ctx.recalledMemories
529
+ : localRecords.slice(0, 5).map((r) => ({
530
+ documentId: r.documentId,
531
+ title: r.title,
532
+ snippet: r.content.slice(0, 240),
533
+ similarity: 1,
534
+ createdAt: r.createdAt,
535
+ }));
536
+ const staticFacts = ctx.staticFacts.length > 0
537
+ ? ctx.staticFacts
538
+ : localRecords
539
+ .filter((r) => r.kind === "fact" || r.kind === "preference")
540
+ .slice(0, 5)
541
+ .map((r) => `${r.title}: ${r.content.slice(0, 140)}`);
542
+ const dynamicContext = ctx.dynamicContext.length > 0
543
+ ? ctx.dynamicContext
544
+ : temporalFacts.slice(0, 6).map((f) => `${f.subject} ${f.predicate} ${f.object}`);
545
+ const combinedText = [
546
+ ...staticFacts,
547
+ ...dynamicContext,
548
+ ...recalled.map((m) => `${m.title}: ${m.snippet}`),
549
+ ].join("\n");
550
+ const poisonScan = this.governance.scanMemoryContent({
551
+ workspaceId,
552
+ sessionId: ctx.namespace,
553
+ role: "system",
554
+ content: combinedText,
555
+ recordInDetector: false,
556
+ });
557
+ const promptLines = [
558
+ `[Supermemory Brain — Namespace: ${ctx.namespace}]`,
559
+ ];
560
+ if (staticFacts.length > 0) {
561
+ promptLines.push(`Static Facts: ${staticFacts.join(" | ")}`);
562
+ }
563
+ if (dynamicContext.length > 0) {
564
+ promptLines.push(`Dynamic Context: ${dynamicContext.join(" | ")}`);
565
+ }
566
+ if (temporalFacts.length > 0) {
567
+ promptLines.push(`Bi-Temporal Lineage (${temporalFacts.length} active): ${temporalFacts
568
+ .slice(0, 5)
569
+ .map((f) => `${f.subject} -[${f.predicate}]-> ${f.object}`)
570
+ .join(" | ")}`);
571
+ }
572
+ if (recalled.length > 0) {
573
+ promptLines.push(`Recalled Memories: ${recalled.map((m) => `${m.title}: ${m.snippet}`).join(" | ")}`);
574
+ }
575
+ const mdLines = [`## Workspace Brain (${ctx.namespace})`];
576
+ if (staticFacts.length > 0) {
577
+ mdLines.push("### Static Facts", ...staticFacts.map((f) => `- ${f}`));
578
+ }
579
+ if (temporalFacts.length > 0) {
580
+ mdLines.push("### Bi-Temporal Resource & Fact Lineage (Active)", ...temporalFacts
581
+ .slice(0, 8)
582
+ .map((f) => `- **${f.subject}** \`${f.predicate}\` **${f.object}** _(validFrom: ${f.validFrom})_ — ${f.summary}`));
583
+ }
584
+ return {
585
+ ...ctx,
586
+ staticFacts,
587
+ dynamicContext,
588
+ recalledMemories: recalled,
589
+ relevantMemories: recalled,
590
+ formattedPromptContext: promptLines.join("\n"),
591
+ profileMarkdown: ctx.profileMarkdown || mdLines.join("\n"),
592
+ profile: {
593
+ ...ctx.profile,
594
+ static: staticFacts,
595
+ dynamic: dynamicContext,
596
+ },
597
+ temporalFacts,
598
+ contextPoisoningScan: {
599
+ safe: poisonScan.safe,
600
+ riskLevel: poisonScan.riskLevel,
601
+ findingsCount: poisonScan.findingsCount,
602
+ },
603
+ };
604
+ }
509
605
  // 9. get_run_context
510
606
  async getRunContext(ctx, query) {
511
607
  const ws = this.store.getWorkspace(ctx.workspace.id);
@@ -516,7 +612,8 @@ export class MuxoEngine {
516
612
  redactedEnv[k] =
517
613
  v.length > 8 ? `${v.slice(0, 4)}••••${v.slice(-3)}` : "••••••••";
518
614
  }
519
- const memoryContext = await this.supermemory.getContextForWorkspace(ws.id, query);
615
+ const supermemoryByok = this.store.getByokKey(ws.id, "supermemory");
616
+ const memoryContext = await this.enrichMemoryContext(ws.id, await this.supermemory.getContextForWorkspace(ws.id, query, supermemoryByok), query);
520
617
  return {
521
618
  workspaceId: ws.id,
522
619
  workspaceSlug: ws.slug,
@@ -527,33 +624,62 @@ export class MuxoEngine {
527
624
  provisionedResources: resources.filter((r) => r.status === "active"),
528
625
  environmentVariablesRedacted: redactedEnv,
529
626
  supermemoryBrain: memoryContext,
627
+ temporalFacts: memoryContext.temporalFacts || [],
530
628
  governance: this.governance.getStatus(ws),
629
+ trustScore: this.governance.getWorkspaceTrustScore(ws.id),
531
630
  envPullHint: "Run `muxo env pull` or call GET /api/v1/resources/env to write decrypted credentials to your local .env file.",
532
631
  };
533
632
  }
534
633
  // Supermemory Workspace Brain Operations
535
634
  async getMemoryOverview(ctx, query) {
536
- const context = await this.supermemory.getContextForWorkspace(ctx.workspace.id, query);
635
+ const supermemoryByok = this.store.getByokKey(ctx.workspace.id, "supermemory");
636
+ const context = await this.enrichMemoryContext(ctx.workspace.id, await this.supermemory.getContextForWorkspace(ctx.workspace.id, query, supermemoryByok), query);
537
637
  const recentMemories = this.store.listMemoryRecords(ctx.workspace.id, 25);
638
+ const allFacts = this.store.listTemporalFacts(ctx.workspace.id, {
639
+ includeHistorical: true,
640
+ query,
641
+ limit: 50,
642
+ });
538
643
  return {
539
644
  enabled: context.enabled,
540
645
  namespace: context.namespace,
646
+ fundingSource: context.fundingSource || "local_fallback",
541
647
  context,
542
648
  recentMemories,
543
649
  memories: recentMemories,
650
+ temporalFacts: allFacts.filter((f) => f.validTo === null),
651
+ historicalFacts: allFacts.filter((f) => f.validTo !== null),
544
652
  };
545
653
  }
546
654
  async addWorkspaceMemory(ctx, params) {
655
+ const ws = this.store.getWorkspace(ctx.workspace.id);
547
656
  const kind = params.kind || "fact";
657
+ // Microsoft Agent Governance OWASP ASI-06 ContextPoisoningDetector guard on memory ingestion
658
+ const poisonScan = this.governance.scanMemoryContent({
659
+ workspaceId: ws.id,
660
+ sessionId: this.supermemory.getWorkspaceNamespace(ws.id),
661
+ role: "user",
662
+ content: `${params.title}\n${params.content}`,
663
+ recordInDetector: true,
664
+ });
665
+ if (!poisonScan.safe && ws.policy.mode === "enforce") {
666
+ this.governance.recordAgentOutcome(ws.id, false, 0.1);
667
+ throw new Error(`Blocked by Microsoft ContextPoisoningDetector (OWASP ASI-06, risk=${poisonScan.riskLevel}): ${poisonScan.findings
668
+ .map((f) => `${f.patternName} (${f.description})`)
669
+ .join("; ")}`);
670
+ }
671
+ const supermemoryByok = this.store.getByokKey(ws.id, "supermemory");
548
672
  const remote = await this.supermemory.addMemory({
549
- workspaceId: ctx.workspace.id,
673
+ workspaceId: ws.id,
550
674
  title: params.title,
551
675
  content: params.content,
552
676
  kind,
553
677
  metadata: params.metadata,
678
+ apiKeyOverride: supermemoryByok,
679
+ dreaming: "instant",
554
680
  });
555
- return this.store.saveMemoryRecord({
556
- workspaceId: ctx.workspace.id,
681
+ const record = this.store.saveMemoryRecord({
682
+ workspaceId: ws.id,
557
683
  namespace: remote.namespace,
558
684
  documentId: remote.documentId,
559
685
  title: params.title,
@@ -562,18 +688,103 @@ export class MuxoEngine {
562
688
  metadata: {
563
689
  ...(params.metadata || {}),
564
690
  supermemoryStatus: remote.status,
691
+ fundingSource: remote.fundingSource,
692
+ contextPoisoningScan: {
693
+ safe: poisonScan.safe,
694
+ riskLevel: poisonScan.riskLevel,
695
+ findingsCount: poisonScan.findingsCount,
696
+ },
565
697
  },
566
698
  });
699
+ // Record bi-temporal entity/relationship lineage (auto-superseding prior facts for same subject+predicate)
700
+ const normalizedTitlePred = params.title
701
+ .trim()
702
+ .toUpperCase()
703
+ .replace(/[^A-Z0-9]+/g, "_")
704
+ .replace(/^_|_$/g, "")
705
+ .slice(0, 48);
706
+ const subject = params.subject ||
707
+ (typeof params.metadata?.subject === "string"
708
+ ? params.metadata.subject
709
+ : `workspace:${ws.slug}`);
710
+ const predicate = params.predicate ||
711
+ (typeof params.metadata?.predicate === "string"
712
+ ? params.metadata.predicate
713
+ : normalizedTitlePred || kind.toUpperCase());
714
+ const object = params.object ||
715
+ (typeof params.metadata?.object === "string"
716
+ ? params.metadata.object
717
+ : remote.sanitizedContent.slice(0, 160));
718
+ this.store.upsertTemporalFact({
719
+ workspaceId: ws.id,
720
+ subject,
721
+ predicate,
722
+ object,
723
+ summary: `${params.title}: ${remote.sanitizedContent.slice(0, 240)}`,
724
+ confidence: 0.95,
725
+ sourceKind: kind,
726
+ sourceReferenceId: record.id,
727
+ metadata: params.metadata || {},
728
+ });
729
+ return record;
567
730
  }
568
731
  async deleteWorkspaceMemory(ctx, idOrDocId) {
569
732
  const local = this.store.deleteMemoryRecord(ctx.workspace.id, idOrDocId);
570
733
  const docId = local?.documentId || idOrDocId;
571
- const remote = await this.supermemory.deleteMemory(ctx.workspace.id, docId);
734
+ const supermemoryByok = this.store.getByokKey(ctx.workspace.id, "supermemory");
735
+ const remote = await this.supermemory.deleteMemory(ctx.workspace.id, docId, supermemoryByok);
572
736
  return {
573
737
  deleted: Boolean(local || remote.deleted),
574
738
  record: local,
575
739
  };
576
740
  }
741
+ async forgetWorkspaceMemoryMatching(ctx, query) {
742
+ const localPruned = this.store.forgetMatchingMemoryRecords(ctx.workspace.id, query);
743
+ const supermemoryByok = this.store.getByokKey(ctx.workspace.id, "supermemory");
744
+ const remotePruned = await this.supermemory.forgetMatching({
745
+ workspaceId: ctx.workspace.id,
746
+ query,
747
+ apiKeyOverride: supermemoryByok,
748
+ });
749
+ return {
750
+ query,
751
+ deletedLocalCount: localPruned.deletedMemories.length,
752
+ invalidatedFactsCount: localPruned.invalidatedFacts.length,
753
+ deletedRemoteIds: remotePruned.deletedRemoteIds,
754
+ deletedMemories: localPruned.deletedMemories,
755
+ invalidatedFacts: localPruned.invalidatedFacts,
756
+ };
757
+ }
758
+ async activateWorkspaceKillSwitch(ctx, params) {
759
+ const ws = this.store.getWorkspace(ctx.workspace.id);
760
+ const result = await this.governance.activateKillSwitch(ws.id, params.reason, params.action || "quarantine");
761
+ const updatedWs = this.store.updateWorkspacePolicy(ws.id, {
762
+ ...ws.policy,
763
+ killSwitchActive: true,
764
+ killSwitchReason: params.reason,
765
+ });
766
+ return {
767
+ activated: true,
768
+ killSwitch: result,
769
+ policy: updatedWs.policy,
770
+ trustScore: this.governance.getWorkspaceTrustScore(ws.id),
771
+ };
772
+ }
773
+ resumeWorkspaceKillSwitch(ctx) {
774
+ const ws = this.store.getWorkspace(ctx.workspace.id);
775
+ const resumed = this.governance.resumeKillSwitch(ws.id);
776
+ const updatedWs = this.store.updateWorkspacePolicy(ws.id, {
777
+ ...ws.policy,
778
+ killSwitchActive: false,
779
+ killSwitchReason: null,
780
+ });
781
+ return {
782
+ ...resumed,
783
+ resumed: true,
784
+ policy: updatedWs.policy,
785
+ trustScore: this.governance.getWorkspaceTrustScore(ws.id),
786
+ };
787
+ }
577
788
  // 10-15. execute_<risk_level>
578
789
  async executePlanForRisk(ctx, planId, expectedRisk) {
579
790
  const plan = this.getPlan(ctx, planId);
@@ -596,6 +807,23 @@ export class MuxoEngine {
596
807
  }
597
808
  const ws = this.store.getWorkspace(ctx.workspace.id);
598
809
  const tool = await this.inspectTool(plan.toolSlug);
810
+ const explicitFunding = plan.supplierSettlement?.fundingMode;
811
+ const byokActive = explicitFunding === "byok"
812
+ ? true
813
+ : explicitFunding === "muxo_funded"
814
+ ? false
815
+ : this.store.hasByokForLane(ws.id, tool.lane, tool.slug);
816
+ const effectiveCreditCost = byokActive
817
+ ? 0
818
+ : plan.creditCost > 0
819
+ ? plan.creditCost
820
+ : tool.creditCost;
821
+ if (ws.monthlyActionsUsed >= ws.monthlyActionsLimit) {
822
+ throw new Error(`Monthly action limit reached (${ws.monthlyActionsUsed}/${ws.monthlyActionsLimit}). Upgrade to Starter ($29/mo) to unlock 5,000 actions/mo.`);
823
+ }
824
+ if (effectiveCreditCost > ws.creditsBalance) {
825
+ throw new Error(`Insufficient workspace credits to execute plan '${plan.id}' for ${tool.slug} (requires ${effectiveCreditCost}, available ${ws.creditsBalance}). Top up credits or configure a BYOK key.`);
826
+ }
599
827
  const execDecisionRecord = this.governance.evaluateExecution({
600
828
  workspace: ws,
601
829
  actorId: ctx.actorId,
@@ -639,25 +867,45 @@ export class MuxoEngine {
639
867
  });
640
868
  }
641
869
  else if (plan.lane === "composio_instant") {
870
+ const composioByok = byokActive
871
+ ? this.store.getByokKey(ctx.workspace.id, "composio")
872
+ : null;
873
+ const exaByok = byokActive
874
+ ? this.store.getByokKey(ctx.workspace.id, "exa")
875
+ : null;
876
+ const firecrawlByok = byokActive
877
+ ? this.store.getByokKey(ctx.workspace.id, "firecrawl")
878
+ : null;
642
879
  output = await this.composioInstant.executeTool({
643
880
  workspaceId: ctx.workspace.id,
644
881
  tool,
645
882
  input: plan.input,
883
+ composioApiKey: composioByok,
884
+ exaApiKey: exaByok,
885
+ firecrawlApiKey: firecrawlByok,
646
886
  });
647
887
  }
648
888
  else if (plan.lane === "composio_sdk") {
889
+ const composioByok = byokActive
890
+ ? this.store.getByokKey(ctx.workspace.id, "composio")
891
+ : null;
649
892
  output = await this.composioSdk.executeTool({
650
893
  workspaceId: ctx.workspace.id,
651
894
  tool,
652
895
  input: plan.input,
653
896
  connectedAccountId: activeConnId,
897
+ composioApiKey: composioByok,
654
898
  });
655
899
  }
656
900
  else if (plan.lane === "stripe_projects") {
901
+ const stripeByok = byokActive
902
+ ? this.store.getByokKey(ctx.workspace.id, "stripe")
903
+ : null;
657
904
  const projResult = await this.stripeProjects.executeTool({
658
905
  workspaceId: ctx.workspace.id,
659
906
  tool,
660
907
  input: plan.input,
908
+ stripeApiKey: stripeByok,
661
909
  });
662
910
  output = projResult.output;
663
911
  if (projResult.provisionedResource) {
@@ -671,19 +919,38 @@ export class MuxoEngine {
671
919
  throw new Error(`Unsupported execution lane: ${plan.lane}`);
672
920
  }
673
921
  const durationMs = Date.now() - startedMs;
922
+ this.governance.recordAgentOutcome(ctx.workspace.id, true, 0.05);
674
923
  const finalized = this.store.finalizeRun({
675
924
  workspaceId: ctx.workspace.id,
676
925
  runId: run.id,
677
926
  status: "succeeded",
678
927
  output,
679
928
  actionsMetered: 1,
680
- creditsMetered: plan.creditCost,
929
+ creditsMetered: effectiveCreditCost,
681
930
  durationMs,
682
931
  decisionRecord: execDecisionRecord,
683
932
  });
933
+ this.store.upsertTemporalFact({
934
+ workspaceId: ctx.workspace.id,
935
+ subject: `tool:${plan.toolSlug}`,
936
+ predicate: "LAST_EXECUTION",
937
+ object: `succeeded:${finalized.run.id}`,
938
+ summary: `Executed ${plan.toolSlug} (${plan.lane}, risk=${plan.riskLevel}) -> succeeded [receipt=${finalized.receipt.id}]`,
939
+ confidence: 1.0,
940
+ sourceKind: "execution_outcome",
941
+ sourceReferenceId: finalized.run.id,
942
+ metadata: {
943
+ runId: finalized.run.id,
944
+ receiptId: finalized.receipt.id,
945
+ toolSlug: plan.toolSlug,
946
+ lane: plan.lane,
947
+ riskLevel: plan.riskLevel,
948
+ },
949
+ });
684
950
  // Record secret-redacted post-run memory in Supermemory for stateful actions
685
951
  if (plan.riskLevel !== "read") {
686
952
  const summary = `Executed ${plan.toolSlug} (${plan.lane}, risk=${plan.riskLevel}) for reason "${plan.reason}" -> status=succeeded (receipt=${finalized.receipt.id}).`;
953
+ const supermemoryByok = this.store.getByokKey(ctx.workspace.id, "supermemory");
687
954
  this.supermemory
688
955
  .recordExecutionMemory({
689
956
  workspaceId: ctx.workspace.id,
@@ -693,6 +960,7 @@ export class MuxoEngine {
693
960
  reason: plan.reason,
694
961
  status: "succeeded",
695
962
  summary,
963
+ apiKeyOverride: supermemoryByok,
696
964
  })
697
965
  .then((docId) => {
698
966
  if (docId) {
@@ -717,6 +985,7 @@ export class MuxoEngine {
717
985
  }
718
986
  catch (err) {
719
987
  const durationMs = Date.now() - startedMs;
988
+ this.governance.recordAgentOutcome(ctx.workspace.id, false, 0.08);
720
989
  const errorMessage = String(err?.message || err || "Execution failed");
721
990
  return this.store.finalizeRun({
722
991
  workspaceId: ctx.workspace.id,
@@ -739,7 +1008,7 @@ export class MuxoEngine {
739
1008
  return run;
740
1009
  }
741
1010
  // 17. cancel_run
742
- cancelRun(ctx, runId) {
1011
+ cancelRun(ctx, runId, reason) {
743
1012
  const run = this.getRun(ctx, runId);
744
1013
  if (run.status === "succeeded" || run.status === "failed" || run.status === "cancelled") {
745
1014
  return {
@@ -751,8 +1020,8 @@ export class MuxoEngine {
751
1020
  workspaceId: ctx.workspace.id,
752
1021
  runId: run.id,
753
1022
  status: "cancelled",
754
- output: { cancelledBy: ctx.actorId },
755
- error: "Cancelled by operator",
1023
+ output: { cancelledBy: ctx.actorId, ...(reason ? { reason } : {}) },
1024
+ error: reason || "Cancelled by operator",
756
1025
  actionsMetered: 0,
757
1026
  creditsMetered: 0,
758
1027
  durationMs: Date.now() - new Date(run.startedAt).getTime(),
@@ -817,6 +1086,7 @@ export class MuxoEngine {
817
1086
  toolSlug: resolution.tool.slug,
818
1087
  input: resolution.input,
819
1088
  reason: params.prompt,
1089
+ fundingMode: params.fundingMode,
820
1090
  });
821
1091
  if (planned.authHandoff?.required) {
822
1092
  return {
package/dist/mcp.d.ts CHANGED
@@ -4,12 +4,17 @@ export interface McpToolAnnotations {
4
4
  destructiveHint: boolean;
5
5
  openWorldHint: boolean;
6
6
  }
7
+ export interface McpToolSecurityScheme {
8
+ type: "noauth" | "oauth2";
9
+ scopes?: string[];
10
+ }
7
11
  export interface McpToolDefinition {
8
12
  name: string;
9
13
  title: string;
10
14
  description: string;
11
15
  inputSchema: Record<string, unknown>;
12
16
  outputSchema?: Record<string, unknown>;
17
+ securitySchemes?: McpToolSecurityScheme[];
13
18
  annotations: McpToolAnnotations;
14
19
  _meta?: Record<string, unknown>;
15
20
  }
@@ -17,7 +22,7 @@ export interface McpToolDefinition {
17
22
  * Concise server instructions (<512 chars) per OpenAI Plugin MCP Server specification:
18
23
  * https://developers.openai.com/plugins/build/mcp-server
19
24
  */
20
- export declare const MUXO_MCP_SERVER_INSTRUCTIONS = "Muxo governs SaaS actions (Composio app.*), Instant tools (instant.*), Cloud Infrastructure (Stripe Projects resource.*), Supermemory v5 recall, and Microsoft Agent Governance Ed25519 receipts. Workflow: 1) search_tools & inspect_tool. 2) plan_action to get a plan_*. 3) If authHandoff.required is true, show redirectUrl and call wait_for_connection. 4) Execute via the matching risk tool (execute_read/write/admin/financial/provisioning/destructive). 5) Verify via get_receipt.";
25
+ export declare const MUXO_MCP_SERVER_INSTRUCTIONS = "Muxo governs SaaS actions (Connected Apps: app.*), Instant tools (instant.*), Cloud Infrastructure (resource.*), Workspace Memory recall, and verifiable audit records. Workflow: 1) search_tools & inspect_tool. 2) plan_action to get a plan_*. 3) If authHandoff.required is true, show redirectUrl and call wait_for_connection. 4) Execute via the matching risk tool (execute_read/write/admin/financial/provisioning/destructive). 5) Verify via get_receipt.";
21
26
  export declare const MUXO_MCP_TOOLS: McpToolDefinition[];
22
27
  /**
23
28
  * OpenAI Company Knowledge standard `search` and `fetch` tool definitions