@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.
- package/.agents/plugins/marketplace.json +1 -1
- package/.claude-plugin/marketplace.json +19 -4
- package/.codex/config.toml +9 -2
- package/README.md +63 -20
- package/dist/clerk.d.ts +33 -0
- package/dist/clerk.js +198 -0
- package/dist/cli.js +1181 -99
- package/dist/engine.d.ts +22 -1
- package/dist/engine.js +284 -14
- package/dist/mcp.d.ts +6 -1
- package/dist/mcp.js +109 -22
- package/dist/nl.js +60 -36
- package/dist/policy.d.ts +9 -0
- package/dist/policy.js +73 -0
- package/dist/providers/composio-instant.d.ts +4 -0
- package/dist/providers/composio-instant.js +634 -534
- package/dist/providers/composio-sdk.d.ts +1 -0
- package/dist/providers/composio-sdk.js +6 -2
- package/dist/providers/microsoft-governance.d.ts +61 -2
- package/dist/providers/microsoft-governance.js +458 -24
- package/dist/providers/stripe-billing.js +14 -4
- package/dist/providers/stripe-projects.d.ts +4 -1
- package/dist/providers/stripe-projects.js +123 -12
- package/dist/providers/supermemory.d.ts +28 -5
- package/dist/providers/supermemory.js +183 -55
- package/dist/sdk.d.ts +167 -1
- package/dist/sdk.js +113 -2
- package/dist/server.js +258 -40
- package/dist/store.d.ts +26 -1
- package/dist/store.js +255 -6
- package/dist/types.d.ts +86 -0
- package/dist/ui/console-html.d.ts +16 -0
- package/dist/ui/console-html.js +2427 -2206
- package/dist/ui/design-tokens.d.ts +177 -0
- package/dist/ui/design-tokens.js +210 -0
- package/dist/version.d.ts +1 -0
- package/dist/version.js +1 -0
- package/package.json +2 -2
- 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/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 =
|
|
396
|
-
|
|
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
|
|
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
|
|
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
|
|
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:
|
|
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
|
-
|
|
556
|
-
workspaceId:
|
|
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
|
|
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:
|
|
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 (
|
|
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
|