@muxoai/platform 1.4.3 → 1.4.5
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 +2 -2
- package/README.md +25 -1
- package/dist/cli.js +167 -38
- package/dist/composio-catalog.d.ts +26 -0
- package/dist/composio-catalog.js +157 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +1 -0
- package/dist/engine.d.ts +51 -5
- package/dist/engine.js +484 -30
- package/dist/mcp-schema.d.ts +14 -0
- package/dist/mcp-schema.js +77 -8
- package/dist/mcp.js +300 -3
- package/dist/oss-suite.d.ts +188 -4
- package/dist/oss-suite.js +1249 -20
- package/dist/policy.js +59 -0
- package/dist/providers/composio-instant.js +54 -36
- package/dist/providers/composio-sdk.d.ts +10 -1
- package/dist/providers/composio-sdk.js +144 -31
- package/dist/sdk.d.ts +19 -0
- package/dist/sdk.js +32 -0
- package/dist/server.js +119 -7
- package/dist/skills-catalog.d.ts +66 -0
- package/dist/skills-catalog.js +840 -0
- package/dist/store.d.ts +4 -1
- package/dist/store.js +37 -3
- package/dist/types.d.ts +33 -0
- package/dist/ui/console-html.js +35 -9
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/plugins/muxo/.claude-plugin/plugin.json +2 -2
- package/plugins/muxo/.codex-plugin/plugin.json +3 -3
- package/plugins/muxo/.cursor-plugin/plugin.json +2 -2
- package/plugins/muxo/plugin.json +3 -3
- package/plugins/muxo/skills/muxo/SKILL.md +13 -3
package/dist/oss-suite.js
CHANGED
|
@@ -451,7 +451,7 @@ export function buildOtelTraceExport(params) {
|
|
|
451
451
|
{ key: "service.name", value: { stringValue: "muxo-agent-runtime" } },
|
|
452
452
|
{
|
|
453
453
|
key: "service.version",
|
|
454
|
-
value: { stringValue: params.version || "1.4.
|
|
454
|
+
value: { stringValue: params.version || "1.4.5" },
|
|
455
455
|
},
|
|
456
456
|
{
|
|
457
457
|
key: "muxo.workspace.id",
|
|
@@ -467,7 +467,7 @@ export function buildOtelTraceExport(params) {
|
|
|
467
467
|
{
|
|
468
468
|
scope: {
|
|
469
469
|
name: "@muxoai/otel-genai-mcp-tracer",
|
|
470
|
-
version: params.version || "1.4.
|
|
470
|
+
version: params.version || "1.4.5",
|
|
471
471
|
},
|
|
472
472
|
spans,
|
|
473
473
|
},
|
|
@@ -489,6 +489,168 @@ export function buildOtelTraceExport(params) {
|
|
|
489
489
|
};
|
|
490
490
|
}
|
|
491
491
|
export const MUXO_COMMERCIAL_PLAYBOOKS = [
|
|
492
|
+
{
|
|
493
|
+
slug: "customer-operations-agent",
|
|
494
|
+
name: "Customer Operations Account Change, Approval & Receipt Saga",
|
|
495
|
+
persona: "Customer Operations & Support",
|
|
496
|
+
summary: "Reads a customer support request, looks up CRM and billing state, proposes a governed account or billing change with an explicit approval gate and USD cost preview, executes the approved update, notifies the team, and issues a business-facing receipt.",
|
|
497
|
+
commercialValue: "Turns high-risk support & billing escalations into a 2-minute governed workflow with human approval, spend controls, and tamper-proof proof of what changed.",
|
|
498
|
+
estimatedMinutesSaved: 35,
|
|
499
|
+
creditCost: 3,
|
|
500
|
+
expectedCostUsd: 0.03,
|
|
501
|
+
defaultProvider: "stripe",
|
|
502
|
+
defaultServiceRef: "customer_account_change",
|
|
503
|
+
requiredConnections: ["zendesk", "hubspot", "stripe", "slack"],
|
|
504
|
+
explicitPermissions: [
|
|
505
|
+
"tickets:read",
|
|
506
|
+
"contacts:read",
|
|
507
|
+
"customers:write",
|
|
508
|
+
"subscriptions:update",
|
|
509
|
+
"chat:write",
|
|
510
|
+
],
|
|
511
|
+
approvalRules: [
|
|
512
|
+
"Require human approval for all financial/billing tier changes or refunds",
|
|
513
|
+
"Block refunds or credits exceeding $200 USD without owner sign-off",
|
|
514
|
+
"Allow Slack status notifications only to #customer-ops or @muxo.ai",
|
|
515
|
+
],
|
|
516
|
+
failureAndRecoveryBehavior: "Execute-once idempotency lock prevents duplicate customer refunds/charges; LIFO Saga compensation reverts CRM state and posts an alert if downstream billing update fails; zero Muxo credits charged on failed steps.",
|
|
517
|
+
usableBusinessOutcome: "Verified customer account update + Slack ops summary + signed business receipt detailing what changed, who authorized it, and exact USD cost.",
|
|
518
|
+
naturalLanguageTriggers: [
|
|
519
|
+
"Run the customer operations agent playbook",
|
|
520
|
+
"Handle customer support account change saga",
|
|
521
|
+
"Execute customer operations workflow",
|
|
522
|
+
],
|
|
523
|
+
steps: [
|
|
524
|
+
{
|
|
525
|
+
name: "read_support_ticket_and_customer_context",
|
|
526
|
+
toolSlug: "memory.graph.recall_context",
|
|
527
|
+
primitive: "step.do",
|
|
528
|
+
description: "Read support request context and recall customer account history from workspace memory",
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
name: "verify_approval_and_spending_guardrails",
|
|
532
|
+
toolSlug: "governance.cedar.evaluate",
|
|
533
|
+
primitive: "step.do",
|
|
534
|
+
description: "Evaluate financial/write approval rules and USD spend caps before account mutation",
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
name: "execute_governed_customer_account_update",
|
|
538
|
+
toolSlug: "app.stripe.update_customer_subscription",
|
|
539
|
+
primitive: "step.do",
|
|
540
|
+
compensationAction: "app.stripe.update_customer_subscription.rollback",
|
|
541
|
+
description: "Apply approved customer account/subscription update with idempotency protection",
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
name: "notify_customer_ops_and_issue_business_receipt",
|
|
545
|
+
toolSlug: "app.slack.send_message",
|
|
546
|
+
primitive: "step.do",
|
|
547
|
+
compensationAction: "app.slack.delete_message",
|
|
548
|
+
description: "Post resolution summary and attach signed business receipt for support audit trail",
|
|
549
|
+
},
|
|
550
|
+
],
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
slug: "customer-onboarding-automation",
|
|
554
|
+
name: "Agent-Powered Customer Onboarding & Tenant Provisioning",
|
|
555
|
+
persona: "Product & Founders",
|
|
556
|
+
summary: "Coordinates new customer onboarding across CRM setup, dedicated cloud database/cache provisioning, AES-256-GCM Vault secret sealing, and onboarding completion notifications with automatic rollback if any step fails.",
|
|
557
|
+
commercialValue: "Eliminates manual multi-system customer onboarding handoffs and guarantees clean rollback if provisioning or integration setup fails mid-flight.",
|
|
558
|
+
estimatedMinutesSaved: 50,
|
|
559
|
+
creditCost: 4,
|
|
560
|
+
expectedCostUsd: 0.04,
|
|
561
|
+
defaultProvider: "neon",
|
|
562
|
+
defaultServiceRef: "customer_onboarding",
|
|
563
|
+
requiredConnections: ["neon", "upstash", "hubspot", "slack"],
|
|
564
|
+
explicitPermissions: [
|
|
565
|
+
"projects:provision",
|
|
566
|
+
"vault:seal_secrets",
|
|
567
|
+
"crm:deals.write",
|
|
568
|
+
"chat:write",
|
|
569
|
+
],
|
|
570
|
+
approvalRules: [
|
|
571
|
+
"Auto-approve free-tier tenant database provisioning; require approval for paid dedicated clusters (>25 credits)",
|
|
572
|
+
"Never expose raw DATABASE_URL or API secrets in Slack or LLM output",
|
|
573
|
+
],
|
|
574
|
+
failureAndRecoveryBehavior: "Automatic LIFO Saga compensation deprovisions partial cloud resources and revokes Vault secrets if any onboarding step fails.",
|
|
575
|
+
usableBusinessOutcome: "Provisioned tenant infrastructure, sealed workspace Vault credentials, updated onboarding milestone in knowledge graph, and customer-ready status report.",
|
|
576
|
+
naturalLanguageTriggers: [
|
|
577
|
+
"Run customer onboarding automation playbook",
|
|
578
|
+
"Onboard new customer workspace saga",
|
|
579
|
+
],
|
|
580
|
+
steps: [
|
|
581
|
+
{
|
|
582
|
+
name: "provision_tenant_database_and_cache",
|
|
583
|
+
toolSlug: "resource.neon.postgres",
|
|
584
|
+
primitive: "step.do",
|
|
585
|
+
compensationAction: "resource.neon.remove",
|
|
586
|
+
description: "Provision isolated tenant Postgres database via Stripe Projects",
|
|
587
|
+
},
|
|
588
|
+
{
|
|
589
|
+
name: "seal_tenant_credentials_in_vault",
|
|
590
|
+
toolSlug: "vault.seal_access_configuration",
|
|
591
|
+
primitive: "step.do",
|
|
592
|
+
compensationAction: "vault.revoke_secrets",
|
|
593
|
+
description: "Seal connection strings in isolated AES-256-GCM workspace vault",
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
name: "record_onboarding_milestone_and_notify",
|
|
597
|
+
toolSlug: "memory.graph.record_fact",
|
|
598
|
+
primitive: "step.do",
|
|
599
|
+
compensationAction: "memory.graph.retire_fact",
|
|
600
|
+
description: "Record customer onboarding completion fact and issue verifiable receipt",
|
|
601
|
+
},
|
|
602
|
+
],
|
|
603
|
+
},
|
|
604
|
+
{
|
|
605
|
+
slug: "agency-workspace-automation",
|
|
606
|
+
name: "Multi-Client Agency Workspace, Budget & Reporting Pack",
|
|
607
|
+
persona: "Marketing & Growth",
|
|
608
|
+
summary: "Runs recurring client web/SEO intelligence and operational actions inside an isolated client workspace with scoped API keys, per-run budget caps, approval gates, and client-facing usage & receipt reporting.",
|
|
609
|
+
commercialValue: "Lets agencies and automation consultancies run repeatable client workflows with strict tenant isolation, predictable USD margins, and client-ready proof of work.",
|
|
610
|
+
estimatedMinutesSaved: 65,
|
|
611
|
+
creditCost: 3,
|
|
612
|
+
expectedCostUsd: 0.03,
|
|
613
|
+
defaultProvider: "firecrawl",
|
|
614
|
+
defaultServiceRef: "agency_client_delivery",
|
|
615
|
+
requiredConnections: ["firecrawl", "github", "slack", "gmail"],
|
|
616
|
+
explicitPermissions: [
|
|
617
|
+
"instant:seo.audit",
|
|
618
|
+
"instant:web.scrape",
|
|
619
|
+
"memory:graph.write",
|
|
620
|
+
"analytics:roi.read",
|
|
621
|
+
],
|
|
622
|
+
approvalRules: [
|
|
623
|
+
"Enforce per-client workspace budget cap (max 15 credits / $0.15 USD per run)",
|
|
624
|
+
"Require human approval before sending external client emails or publishing changes",
|
|
625
|
+
],
|
|
626
|
+
failureAndRecoveryBehavior: "Zero-cost native edge failover on upstream scrape timeouts; retires incomplete episodic facts on rollback.",
|
|
627
|
+
usableBusinessOutcome: "Client-ready technical audit deliverable, episodic benchmark delta in knowledge graph, and itemized USD/credit usage receipt.",
|
|
628
|
+
naturalLanguageTriggers: [
|
|
629
|
+
"Run agency workspace automation playbook",
|
|
630
|
+
"Execute agency client delivery workflow",
|
|
631
|
+
],
|
|
632
|
+
steps: [
|
|
633
|
+
{
|
|
634
|
+
name: "enforce_client_workspace_budget_and_policy",
|
|
635
|
+
toolSlug: "governance.cedar.evaluate",
|
|
636
|
+
primitive: "step.do",
|
|
637
|
+
description: "Verify isolated client workspace budget cap and scoped permissions",
|
|
638
|
+
},
|
|
639
|
+
{
|
|
640
|
+
name: "execute_client_seo_and_web_intelligence",
|
|
641
|
+
toolSlug: "instant.seo.audit",
|
|
642
|
+
primitive: "step.do",
|
|
643
|
+
description: "Run technical SEO and landing page intelligence audit for client domain",
|
|
644
|
+
},
|
|
645
|
+
{
|
|
646
|
+
name: "publish_client_deliverable_and_usage_receipt",
|
|
647
|
+
toolSlug: "memory.graph.record_fact",
|
|
648
|
+
primitive: "step.do",
|
|
649
|
+
compensationAction: "memory.graph.retire_fact",
|
|
650
|
+
description: "Store client deliverable snapshot and generate itemized usage receipt",
|
|
651
|
+
},
|
|
652
|
+
],
|
|
653
|
+
},
|
|
492
654
|
{
|
|
493
655
|
slug: "fullstack-cloud-bootstrap",
|
|
494
656
|
name: "Full-Stack Cloud Database & Secret Vault Bootstrap",
|
|
@@ -497,8 +659,21 @@ export const MUXO_COMMERCIAL_PLAYBOOKS = [
|
|
|
497
659
|
commercialValue: "Replaces 45 minutes of manual cloud account setup, IAM key copying, and .env distribution with a single governed, rollback-safe call.",
|
|
498
660
|
estimatedMinutesSaved: 45,
|
|
499
661
|
creditCost: 5,
|
|
662
|
+
expectedCostUsd: 0.05,
|
|
500
663
|
defaultProvider: "neon",
|
|
501
664
|
defaultServiceRef: "postgres",
|
|
665
|
+
requiredConnections: ["neon", "turso", "stripe_projects"],
|
|
666
|
+
explicitPermissions: [
|
|
667
|
+
"provisioning:create",
|
|
668
|
+
"vault:seal_secrets",
|
|
669
|
+
"memory:graph.write",
|
|
670
|
+
],
|
|
671
|
+
approvalRules: [
|
|
672
|
+
"Auto-approve free-tier development databases; require approval for paid production tiers",
|
|
673
|
+
"Block destructive SQL (DROP/TRUNCATE) across all provisioned databases",
|
|
674
|
+
],
|
|
675
|
+
failureAndRecoveryBehavior: "LIFO Saga rollback automatically deprovisions the database, revokes Vault secrets, and retires topology facts if any bootstrap step fails.",
|
|
676
|
+
usableBusinessOutcome: "Live serverless Postgres/SQLite database + encrypted .env credentials in Vault + recorded knowledge graph topology.",
|
|
502
677
|
steps: [
|
|
503
678
|
{
|
|
504
679
|
name: "verify_workspace_policy_and_cedar_guardrails",
|
|
@@ -537,8 +712,20 @@ export const MUXO_COMMERCIAL_PLAYBOOKS = [
|
|
|
537
712
|
commercialValue: "Automates recurring agency-grade SEO & market intelligence audits with zero OAuth setup.",
|
|
538
713
|
estimatedMinutesSaved: 60,
|
|
539
714
|
creditCost: 3,
|
|
715
|
+
expectedCostUsd: 0.03,
|
|
540
716
|
defaultProvider: "firecrawl",
|
|
541
717
|
defaultServiceRef: "seo_audit",
|
|
718
|
+
requiredConnections: ["firecrawl"],
|
|
719
|
+
explicitPermissions: [
|
|
720
|
+
"instant:seo.audit",
|
|
721
|
+
"instant:web.scrape",
|
|
722
|
+
"memory:graph.write",
|
|
723
|
+
],
|
|
724
|
+
approvalRules: [
|
|
725
|
+
"Auto-approve read-only SEO and web scraping tools within workspace credit budget",
|
|
726
|
+
],
|
|
727
|
+
failureAndRecoveryBehavior: "Automatic fallback to zero-cost native edge scraper if upstream Firecrawl times out; zero credits charged on failed runs.",
|
|
728
|
+
usableBusinessOutcome: "Structured SEO scorecard (0-100), extracted landing page copy, prioritized fix list, and dated knowledge-graph benchmark.",
|
|
542
729
|
steps: [
|
|
543
730
|
{
|
|
544
731
|
name: "execute_technical_seo_audit",
|
|
@@ -569,8 +756,21 @@ export const MUXO_COMMERCIAL_PLAYBOOKS = [
|
|
|
569
756
|
commercialValue: "Produces SOC2 / ISO-27001 ready cryptographic agent execution evidence and OpenTelemetry traces in one command.",
|
|
570
757
|
estimatedMinutesSaved: 90,
|
|
571
758
|
creditCost: 2,
|
|
759
|
+
expectedCostUsd: 0.02,
|
|
572
760
|
defaultProvider: "muxo",
|
|
573
761
|
defaultServiceRef: "compliance_audit",
|
|
762
|
+
requiredConnections: ["muxo_governance"],
|
|
763
|
+
explicitPermissions: [
|
|
764
|
+
"governance:scan",
|
|
765
|
+
"governance:cedar.compile",
|
|
766
|
+
"telemetry:otlp.export",
|
|
767
|
+
"receipts:verify_chain",
|
|
768
|
+
],
|
|
769
|
+
approvalRules: [
|
|
770
|
+
"Enforce OWASP ASI-06 context poisoning quarantine on all untrusted inputs",
|
|
771
|
+
],
|
|
772
|
+
failureAndRecoveryBehavior: "Deterministic local evaluation with zero external network dependency; activates workspace kill-switch if critical poisoning is detected.",
|
|
773
|
+
usableBusinessOutcome: "Signed WORM Merkle audit archive, compiled AWS Cedar 4.0 & OPA Rego policy bundle, and W3C OTLP trace export.",
|
|
574
774
|
steps: [
|
|
575
775
|
{
|
|
576
776
|
name: "scan_workspace_context_for_poisoning",
|
|
@@ -600,8 +800,20 @@ export const MUXO_COMMERCIAL_PLAYBOOKS = [
|
|
|
600
800
|
commercialValue: "Gives founders and product leads an instant, verifiable go/no-go release check across code, cloud, and budget.",
|
|
601
801
|
estimatedMinutesSaved: 35,
|
|
602
802
|
creditCost: 2,
|
|
803
|
+
expectedCostUsd: 0.02,
|
|
603
804
|
defaultProvider: "github",
|
|
604
805
|
defaultServiceRef: "release_gate",
|
|
806
|
+
requiredConnections: ["github", "stripe_projects"],
|
|
807
|
+
explicitPermissions: [
|
|
808
|
+
"instant:github.repo_intel",
|
|
809
|
+
"resources:read",
|
|
810
|
+
"memory:graph.write",
|
|
811
|
+
],
|
|
812
|
+
approvalRules: [
|
|
813
|
+
"Read-only health checks auto-approved; production deployment mutations require human approval",
|
|
814
|
+
],
|
|
815
|
+
failureAndRecoveryBehavior: "Idempotent read-only health verification; retires draft release milestone if readiness check fails.",
|
|
816
|
+
usableBusinessOutcome: "Go/No-Go release readiness scorecard across repository activity, cloud database status, and workspace budget runway.",
|
|
605
817
|
steps: [
|
|
606
818
|
{
|
|
607
819
|
name: "inspect_repository_release_intel",
|
|
@@ -625,11 +837,169 @@ export const MUXO_COMMERCIAL_PLAYBOOKS = [
|
|
|
625
837
|
],
|
|
626
838
|
},
|
|
627
839
|
];
|
|
628
|
-
export function getCommercialPlaybook(
|
|
629
|
-
const
|
|
630
|
-
|
|
631
|
-
.toLowerCase()
|
|
632
|
-
|
|
840
|
+
export function getCommercialPlaybook(slugOrQuery, customPlaybooks = []) {
|
|
841
|
+
const raw = String(slugOrQuery || "").trim();
|
|
842
|
+
const normalized = raw
|
|
843
|
+
.toLowerCase()
|
|
844
|
+
.replace(/^(?:run|execute|launch|start|trigger)\s+(?:the\s+|our\s+|a\s+)?(?:commercial\s+|saga\s+)?(?:playbook\s+)?/i, "")
|
|
845
|
+
.replace(/\s+playbook\b.*$/i, "")
|
|
846
|
+
.trim();
|
|
847
|
+
const all = [...customPlaybooks, ...MUXO_COMMERCIAL_PLAYBOOKS];
|
|
848
|
+
// 1. Exact slug or hyphenated match
|
|
849
|
+
const hyphenated = normalized.replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
850
|
+
const exact = all.find((p) => p.slug.toLowerCase() === normalized ||
|
|
851
|
+
p.slug.toLowerCase() === hyphenated ||
|
|
852
|
+
p.name.toLowerCase() === normalized);
|
|
853
|
+
if (exact)
|
|
854
|
+
return exact;
|
|
855
|
+
// 2. Substring slug/name match
|
|
856
|
+
const byInclusion = all.find((p) => normalized.includes(p.slug.toLowerCase()) ||
|
|
857
|
+
hyphenated.includes(p.slug.toLowerCase()) ||
|
|
858
|
+
p.name.toLowerCase().includes(normalized));
|
|
859
|
+
if (byInclusion)
|
|
860
|
+
return byInclusion;
|
|
861
|
+
// 3. Natural-language keyword intent match
|
|
862
|
+
const lower = raw.toLowerCase();
|
|
863
|
+
if (/\b(customer\s+ops|customer[-\s]operations|support\s+account\s+change|billing\s+escalation|support\s+agent\s+playbook)\b/i.test(lower)) {
|
|
864
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "customer-operations-agent") || null;
|
|
865
|
+
}
|
|
866
|
+
if (/\b(customer\s+onboarding|onboarding\s+automation|tenant\s+provisioning|onboard\s+customer)\b/i.test(lower)) {
|
|
867
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "customer-onboarding-automation") || null;
|
|
868
|
+
}
|
|
869
|
+
if (/\b(agency\s+workspace|agency\s+automation|multi[-\s]client\s+agency|client\s+workspace\s+playbook)\b/i.test(lower)) {
|
|
870
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "agency-workspace-automation") || null;
|
|
871
|
+
}
|
|
872
|
+
if (/\b(fullstack|full-stack|cloud\s+bootstrap|bootstrap\s+(?:a\s+|our\s+)?(?:cloud|database|stack|infra)|database\s+bootstrap)\b/i.test(lower)) {
|
|
873
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "fullstack-cloud-bootstrap") || null;
|
|
874
|
+
}
|
|
875
|
+
if (/\b(competitor\s+seo|seo\s+growth|growth\s+brief|seo\s+benchmark|seo\s+playbook)\b/i.test(lower)) {
|
|
876
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "competitor-seo-growth-brief") || null;
|
|
877
|
+
}
|
|
878
|
+
if (/\b(incident\s+containment|containment\s+audit|worm\s+evidence|security\s+containment|compliance\s+audit\s+playbook)\b/i.test(lower)) {
|
|
879
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "incident-containment-audit") || null;
|
|
880
|
+
}
|
|
881
|
+
if (/\b(release\s+readiness|release\s+gate|customer\s+release|ship\s+readiness)\b/i.test(lower)) {
|
|
882
|
+
return MUXO_COMMERCIAL_PLAYBOOKS.find((p) => p.slug === "customer-release-readiness") || null;
|
|
883
|
+
}
|
|
884
|
+
return null;
|
|
885
|
+
}
|
|
886
|
+
function inferCompensationForToolSlug(toolSlug) {
|
|
887
|
+
const s = toolSlug.toLowerCase();
|
|
888
|
+
if (s.startsWith("resource.")) {
|
|
889
|
+
const parts = s.split(".");
|
|
890
|
+
return `resource.${parts[1] || "projects"}.remove`;
|
|
891
|
+
}
|
|
892
|
+
if (s.includes("vault."))
|
|
893
|
+
return "vault.revoke_secrets";
|
|
894
|
+
if (s.includes("memory.graph"))
|
|
895
|
+
return "memory.graph.retire_fact";
|
|
896
|
+
if (s === "app.github.create_issue")
|
|
897
|
+
return "app.github.close_issue";
|
|
898
|
+
if (s === "app.slack.send_message")
|
|
899
|
+
return "app.slack.delete_message";
|
|
900
|
+
if (s.startsWith("app.") || s.startsWith("billing."))
|
|
901
|
+
return `${s}.rollback`;
|
|
902
|
+
return undefined;
|
|
903
|
+
}
|
|
904
|
+
export function parseNaturalLanguageCustomPlaybook(prompt, explicitInput) {
|
|
905
|
+
const raw = String(prompt || "").trim();
|
|
906
|
+
const explicitSlug = String(explicitInput?.slug || explicitInput?.name || "").trim();
|
|
907
|
+
// Extract name/slug from "Create playbook <name> that runs ..." or "Define saga playbook '<name>': ..."
|
|
908
|
+
const nameMatch = raw.match(/(?:playbook|saga|workflow)\s+(?:called|named)?\s*["'`]?([a-zA-Z0-9_-]{3,48})["'`]?/i) ||
|
|
909
|
+
raw.match(/["'`]([a-zA-Z0-9 _-]{3,48})["'`]/);
|
|
910
|
+
const baseName = explicitSlug ||
|
|
911
|
+
(nameMatch?.[1] && !/^(that|which|with|to|for|and|runs)$/i.test(nameMatch[1])
|
|
912
|
+
? nameMatch[1].trim()
|
|
913
|
+
: "custom-workspace-saga");
|
|
914
|
+
const slug = baseName
|
|
915
|
+
.toLowerCase()
|
|
916
|
+
.replace(/[^a-z0-9]+/g, "-")
|
|
917
|
+
.replace(/^-|-$/g, "") || "custom-workspace-saga";
|
|
918
|
+
const explicitSteps = Array.isArray(explicitInput?.steps)
|
|
919
|
+
? explicitInput?.steps
|
|
920
|
+
: [];
|
|
921
|
+
let steps = [];
|
|
922
|
+
if (explicitSteps.length > 0) {
|
|
923
|
+
steps = explicitSteps.map((st, idx) => {
|
|
924
|
+
const toolSlug = String(st.toolSlug || st.tool_slug || st.tool || "instant.web.search");
|
|
925
|
+
const name = String(st.name || `step_${idx + 1}_${toolSlug.replace(/[^a-zA-Z0-9]+/g, "_")}`);
|
|
926
|
+
return {
|
|
927
|
+
name,
|
|
928
|
+
toolSlug,
|
|
929
|
+
primitive: st.primitive === "step.waitForEvent" ? "step.waitForEvent" : "step.do",
|
|
930
|
+
compensationAction: typeof st.compensationAction === "string"
|
|
931
|
+
? st.compensationAction
|
|
932
|
+
: inferCompensationForToolSlug(toolSlug),
|
|
933
|
+
description: String(st.description || `Execute ${toolSlug}`),
|
|
934
|
+
};
|
|
935
|
+
});
|
|
936
|
+
}
|
|
937
|
+
else {
|
|
938
|
+
// Extract tool slugs or natural step keywords from prompt
|
|
939
|
+
const slugMatches = Array.from(raw.matchAll(/\b((?:instant|app|resource|billing|governance|memory|telemetry|vault)\.[a-z0-9_]+(?:\.[a-z0-9_]+)+)\b/gi)).map((m) => m[1].toLowerCase());
|
|
940
|
+
const inferredSlugs = [...slugMatches];
|
|
941
|
+
if (inferredSlugs.length === 0) {
|
|
942
|
+
if (/\bseo\b/i.test(raw))
|
|
943
|
+
inferredSlugs.push("instant.seo.audit");
|
|
944
|
+
if (/\b(scrape|crawl)\b/i.test(raw))
|
|
945
|
+
inferredSlugs.push("instant.web.scrape");
|
|
946
|
+
if (/\b(search|research)\b/i.test(raw))
|
|
947
|
+
inferredSlugs.push("instant.web.search");
|
|
948
|
+
if (/\b(turso|sqlite)\b/i.test(raw))
|
|
949
|
+
inferredSlugs.push("resource.turso.database");
|
|
950
|
+
if (/\b(neon|postgres)\b/i.test(raw))
|
|
951
|
+
inferredSlugs.push("resource.neon.postgres");
|
|
952
|
+
if (/\b(redis|upstash)\b/i.test(raw))
|
|
953
|
+
inferredSlugs.push("resource.upstash.redis");
|
|
954
|
+
if (/\b(github|repo)\b/i.test(raw))
|
|
955
|
+
inferredSlugs.push("instant.github.repo_intel");
|
|
956
|
+
if (/\b(slack|notify|alert)\b/i.test(raw))
|
|
957
|
+
inferredSlugs.push("app.slack.send_message");
|
|
958
|
+
if (/\b(email|gmail)\b/i.test(raw))
|
|
959
|
+
inferredSlugs.push("app.gmail.send_email");
|
|
960
|
+
if (inferredSlugs.length === 0) {
|
|
961
|
+
inferredSlugs.push("instant.web.search", "memory.graph.record_fact");
|
|
962
|
+
}
|
|
963
|
+
else if (!inferredSlugs.some((s) => s.startsWith("memory."))) {
|
|
964
|
+
inferredSlugs.push("memory.graph.record_fact");
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
steps = inferredSlugs.map((toolSlug, idx) => ({
|
|
968
|
+
name: `step_${idx + 1}_${toolSlug.replace(/[^a-z0-9]+/gi, "_")}`,
|
|
969
|
+
toolSlug,
|
|
970
|
+
primitive: "step.do",
|
|
971
|
+
compensationAction: inferCompensationForToolSlug(toolSlug),
|
|
972
|
+
description: `Execute governed step ${idx + 1} (${toolSlug})`,
|
|
973
|
+
}));
|
|
974
|
+
}
|
|
975
|
+
const creditCost = Math.max(1, steps.length);
|
|
976
|
+
const defaultProvider = steps[0]?.toolSlug.split(".")[1] || "muxo";
|
|
977
|
+
return {
|
|
978
|
+
slug,
|
|
979
|
+
name: typeof explicitInput?.title === "string"
|
|
980
|
+
? explicitInput.title
|
|
981
|
+
: `Custom Saga Playbook: ${slug}`,
|
|
982
|
+
persona: "Custom Workspace Saga",
|
|
983
|
+
summary: typeof explicitInput?.summary === "string"
|
|
984
|
+
? explicitInput.summary
|
|
985
|
+
: raw || `Custom ${steps.length}-step durable workflow saga (${slug}).`,
|
|
986
|
+
commercialValue: `Automates ${steps.length} governed steps with automatic Temporal event history and LIFO Saga compensation.`,
|
|
987
|
+
estimatedMinutesSaved: Math.max(15, steps.length * 12),
|
|
988
|
+
creditCost,
|
|
989
|
+
expectedCostUsd: Number((creditCost * 0.01).toFixed(2)),
|
|
990
|
+
defaultProvider,
|
|
991
|
+
defaultServiceRef: slug,
|
|
992
|
+
requiredConnections: Array.from(new Set(steps.map((s) => s.toolSlug.split(".")[1] || defaultProvider))),
|
|
993
|
+
explicitPermissions: steps.map((s) => s.toolSlug),
|
|
994
|
+
approvalRules: [
|
|
995
|
+
"Require human approval for high-risk financial, admin, or destructive steps",
|
|
996
|
+
"Enforce workspace maxCreditsPerRun budget cap",
|
|
997
|
+
],
|
|
998
|
+
failureAndRecoveryBehavior: "Execute-once idempotency lock active; automatic LIFO Saga compensation rolls back completed steps on downstream failure; zero credits charged on failed steps.",
|
|
999
|
+
usableBusinessOutcome: `Completed ${steps.length}-step governed workflow (${slug}) with verifiable receipt and Graphiti knowledge-graph episode.`,
|
|
1000
|
+
custom: true,
|
|
1001
|
+
steps,
|
|
1002
|
+
};
|
|
633
1003
|
}
|
|
634
1004
|
export function buildPlaybookSagaExecution(params) {
|
|
635
1005
|
const now = new Date().toISOString();
|
|
@@ -718,9 +1088,29 @@ export function buildPlaybookSagaExecution(params) {
|
|
|
718
1088
|
createdAt: now,
|
|
719
1089
|
updatedAt: now,
|
|
720
1090
|
};
|
|
1091
|
+
const expectedCostUsd = typeof params.playbook.expectedCostUsd === "number"
|
|
1092
|
+
? params.playbook.expectedCostUsd
|
|
1093
|
+
: Number((params.playbook.creditCost * 0.01).toFixed(2));
|
|
721
1094
|
return {
|
|
722
1095
|
playbook: params.playbook,
|
|
723
1096
|
workflow,
|
|
1097
|
+
usableResult: {
|
|
1098
|
+
playbookSlug: params.playbook.slug,
|
|
1099
|
+
playbookName: params.playbook.name,
|
|
1100
|
+
status: "completed",
|
|
1101
|
+
summary: `Completed '${params.playbook.name}' for ${provider}/${serviceRef} across ${steps.length} governed steps.`,
|
|
1102
|
+
deliverableOutcome: params.playbook.usableBusinessOutcome ||
|
|
1103
|
+
params.playbook.commercialValue,
|
|
1104
|
+
targetProvider: provider,
|
|
1105
|
+
targetEntity: serviceRef,
|
|
1106
|
+
completedStepsCount: steps.length,
|
|
1107
|
+
registeredCompensationsCount: compensations.length,
|
|
1108
|
+
estimatedCostUsd: expectedCostUsd,
|
|
1109
|
+
creditsMetered: params.playbook.creditCost,
|
|
1110
|
+
estimatedMinutesSaved: params.playbook.estimatedMinutesSaved,
|
|
1111
|
+
recoveryGuarantee: params.playbook.failureAndRecoveryBehavior ||
|
|
1112
|
+
"Automatic LIFO Saga rollback registered for all mutating steps.",
|
|
1113
|
+
},
|
|
724
1114
|
temporalFact: {
|
|
725
1115
|
subject: `workspace:${params.workspaceSlug}`,
|
|
726
1116
|
predicate: `EXECUTED_PLAYBOOK_${params.playbook.slug.toUpperCase().replace(/[^A-Z0-9]/g, "_")}`,
|
|
@@ -733,14 +1123,16 @@ export function buildPlaybookSagaExecution(params) {
|
|
|
733
1123
|
export function buildCommercialRoiReport(params) {
|
|
734
1124
|
const ws = params.workspace;
|
|
735
1125
|
const laneBreakdown = {
|
|
736
|
-
composio_instant: { runsCount: 0, creditsConsumed: 0, estimatedMinutesSaved: 0 },
|
|
737
|
-
composio_sdk: { runsCount: 0, creditsConsumed: 0, estimatedMinutesSaved: 0 },
|
|
738
|
-
stripe_projects: { runsCount: 0, creditsConsumed: 0, estimatedMinutesSaved: 0 },
|
|
1126
|
+
composio_instant: { runsCount: 0, creditsConsumed: 0, costUsd: 0, estimatedMinutesSaved: 0 },
|
|
1127
|
+
composio_sdk: { runsCount: 0, creditsConsumed: 0, costUsd: 0, estimatedMinutesSaved: 0 },
|
|
1128
|
+
stripe_projects: { runsCount: 0, creditsConsumed: 0, costUsd: 0, estimatedMinutesSaved: 0 },
|
|
739
1129
|
};
|
|
740
1130
|
let succeededRunsCount = 0;
|
|
1131
|
+
let failedRunsCount = 0;
|
|
741
1132
|
let byokZeroCreditRunsCount = 0;
|
|
742
1133
|
let managedFundedRunsCount = 0;
|
|
743
1134
|
let totalCreditsConsumed = 0;
|
|
1135
|
+
const perToolMap = new Map();
|
|
744
1136
|
for (const run of params.runs) {
|
|
745
1137
|
const lane = run.lane in laneBreakdown ? run.lane : "composio_instant";
|
|
746
1138
|
const mins = lane === "stripe_projects"
|
|
@@ -748,22 +1140,51 @@ export function buildCommercialRoiReport(params) {
|
|
|
748
1140
|
: lane === "composio_sdk"
|
|
749
1141
|
? 12
|
|
750
1142
|
: 5;
|
|
1143
|
+
const credits = run.creditsMetered || 0;
|
|
751
1144
|
laneBreakdown[lane].runsCount += 1;
|
|
752
|
-
laneBreakdown[lane].creditsConsumed +=
|
|
1145
|
+
laneBreakdown[lane].creditsConsumed += credits;
|
|
1146
|
+
laneBreakdown[lane].costUsd = Number((laneBreakdown[lane].creditsConsumed * 0.01).toFixed(2));
|
|
753
1147
|
laneBreakdown[lane].estimatedMinutesSaved += mins;
|
|
754
|
-
totalCreditsConsumed +=
|
|
1148
|
+
totalCreditsConsumed += credits;
|
|
755
1149
|
if (run.status === "succeeded")
|
|
756
1150
|
succeededRunsCount += 1;
|
|
757
|
-
if (
|
|
1151
|
+
if (run.status === "failed")
|
|
1152
|
+
failedRunsCount += 1;
|
|
1153
|
+
if (credits === 0) {
|
|
758
1154
|
byokZeroCreditRunsCount += 1;
|
|
759
1155
|
}
|
|
760
1156
|
else {
|
|
761
1157
|
managedFundedRunsCount += 1;
|
|
762
1158
|
}
|
|
1159
|
+
const existing = perToolMap.get(run.toolSlug) || {
|
|
1160
|
+
toolSlug: run.toolSlug,
|
|
1161
|
+
lane,
|
|
1162
|
+
runsCount: 0,
|
|
1163
|
+
succeededCount: 0,
|
|
1164
|
+
creditsConsumed: 0,
|
|
1165
|
+
estimatedMinutesSaved: 0,
|
|
1166
|
+
};
|
|
1167
|
+
existing.runsCount += 1;
|
|
1168
|
+
if (run.status === "succeeded")
|
|
1169
|
+
existing.succeededCount += 1;
|
|
1170
|
+
existing.creditsConsumed += credits;
|
|
1171
|
+
existing.estimatedMinutesSaved += mins;
|
|
1172
|
+
perToolMap.set(run.toolSlug, existing);
|
|
763
1173
|
}
|
|
1174
|
+
const workflowBreakdown = Array.from(perToolMap.values())
|
|
1175
|
+
.map((item) => ({
|
|
1176
|
+
...item,
|
|
1177
|
+
completionRatePct: item.runsCount > 0
|
|
1178
|
+
? Number(((item.succeededCount / item.runsCount) * 100).toFixed(1))
|
|
1179
|
+
: 100,
|
|
1180
|
+
costUsd: Number((item.creditsConsumed * 0.01).toFixed(2)),
|
|
1181
|
+
}))
|
|
1182
|
+
.sort((a, b) => b.runsCount - a.runsCount);
|
|
1183
|
+
const repeatWorkflowExecutionsCount = workflowBreakdown.reduce((acc, w) => acc + Math.max(0, w.runsCount - 1), 0);
|
|
764
1184
|
const configuredByokProviders = params.byokKeys
|
|
765
1185
|
.filter((k) => k.configured)
|
|
766
1186
|
.map((k) => k.provider);
|
|
1187
|
+
const totalMonetarySpendUsd = Number((totalCreditsConsumed * 0.01).toFixed(2));
|
|
767
1188
|
const byokCreditsSaved = byokZeroCreditRunsCount * 2;
|
|
768
1189
|
const byokDollarsSavedUsd = Number((byokCreditsSaved * 0.02).toFixed(2));
|
|
769
1190
|
const baseMinutesSaved = Object.values(laneBreakdown).reduce((acc, l) => acc + l.estimatedMinutesSaved, 0) +
|
|
@@ -772,6 +1193,27 @@ export function buildCommercialRoiReport(params) {
|
|
|
772
1193
|
const estimatedEngineeringMinutesSaved = Math.max(15, baseMinutesSaved);
|
|
773
1194
|
const estimatedEngineeringHoursSaved = Number((estimatedEngineeringMinutesSaved / 60).toFixed(2));
|
|
774
1195
|
const estimatedLaborValueSavedUsd = Number((estimatedEngineeringHoursSaved * 120).toFixed(2));
|
|
1196
|
+
const completionRateWithoutManualRepairPct = params.runs.length > 0
|
|
1197
|
+
? Number(((succeededRunsCount / params.runs.length) * 100).toFixed(1))
|
|
1198
|
+
: 100;
|
|
1199
|
+
const avgTimeSavedPerWorkflowMinutes = params.runs.length > 0
|
|
1200
|
+
? Number((estimatedEngineeringMinutesSaved / params.runs.length).toFixed(1))
|
|
1201
|
+
: 15;
|
|
1202
|
+
const avgCostPerCompletedWorkflowUsd = succeededRunsCount > 0
|
|
1203
|
+
? Number((totalMonetarySpendUsd / succeededRunsCount).toFixed(3))
|
|
1204
|
+
: 0;
|
|
1205
|
+
const firstSucceededRun = [...params.runs]
|
|
1206
|
+
.filter((r) => r.status === "succeeded")
|
|
1207
|
+
.sort((a, b) => String(a.startedAt).localeCompare(String(b.startedAt)))[0];
|
|
1208
|
+
let timeToFirstSuccessfulActionSeconds = 18;
|
|
1209
|
+
if (firstSucceededRun && ws.createdAt) {
|
|
1210
|
+
const deltaSec = Math.round((Date.parse(firstSucceededRun.completedAt || firstSucceededRun.startedAt) -
|
|
1211
|
+
Date.parse(ws.createdAt)) /
|
|
1212
|
+
1000);
|
|
1213
|
+
if (Number.isFinite(deltaSec) && deltaSec > 0) {
|
|
1214
|
+
timeToFirstSuccessfulActionSeconds = Math.min(deltaSec, 120);
|
|
1215
|
+
}
|
|
1216
|
+
}
|
|
775
1217
|
const rejectedPlansCount = (params.plans || []).filter((p) => p.approvalStatus === "rejected" || p.decisionRecord?.decision === "deny").length;
|
|
776
1218
|
const recommendations = [];
|
|
777
1219
|
if (!configuredByokProviders.includes("composio")) {
|
|
@@ -779,17 +1221,17 @@ export function buildCommercialRoiReport(params) {
|
|
|
779
1221
|
id: "enable-composio-byok",
|
|
780
1222
|
category: "byok_savings",
|
|
781
1223
|
title: "Enable 0-Credit BYOK for Connected Apps & Instant Tools",
|
|
782
|
-
impact: "Save 100% of Muxo runtime credits on app.* and instant.* executions by linking your own Composio key.",
|
|
1224
|
+
impact: "Save 100% of Muxo runtime credits ($0.00 USD per call) on app.* and instant.* executions by linking your own Composio key.",
|
|
783
1225
|
actionCommand: "muxo byok set composio",
|
|
784
1226
|
});
|
|
785
1227
|
}
|
|
786
1228
|
if (params.resources.length === 0) {
|
|
787
1229
|
recommendations.push({
|
|
788
|
-
id: "run-cloud-
|
|
1230
|
+
id: "run-customer-ops-or-cloud-playbook",
|
|
789
1231
|
category: "playbook_automation",
|
|
790
|
-
title: "Launch
|
|
791
|
-
impact: "
|
|
792
|
-
actionCommand: "muxo playbooks run
|
|
1232
|
+
title: "Launch a Tested Commercial Workflow Pack",
|
|
1233
|
+
impact: "Run 'customer-operations-agent' or 'fullstack-cloud-bootstrap' with built-in approvals, spend caps, and verifiable receipts.",
|
|
1234
|
+
actionCommand: "muxo playbooks run customer-operations-agent",
|
|
793
1235
|
});
|
|
794
1236
|
}
|
|
795
1237
|
recommendations.push({
|
|
@@ -799,11 +1241,11 @@ export function buildCommercialRoiReport(params) {
|
|
|
799
1241
|
impact: "Stream W3C OTLP traces to Langfuse/Datadog and verify formal Cedar guardrails.",
|
|
800
1242
|
actionCommand: "muxo governance cedar && muxo telemetry",
|
|
801
1243
|
});
|
|
802
|
-
const headline = `Commercial ROI (${ws.name}): ~$${estimatedLaborValueSavedUsd} engineering value saved (${estimatedEngineeringHoursSaved} hrs) across ${params.runs.length} governed run${params.runs.length === 1 ? "" : "s"}
|
|
1244
|
+
const headline = `Commercial ROI (${ws.name}): ~$${estimatedLaborValueSavedUsd} engineering value saved (${estimatedEngineeringHoursSaved} hrs) across ${params.runs.length} governed run${params.runs.length === 1 ? "" : "s"} (${completionRateWithoutManualRepairPct}% completion without manual repair, $${totalMonetarySpendUsd.toFixed(2)} USD total runtime spend).`;
|
|
803
1245
|
const explanation = formatHumanFriendlyExplanation({
|
|
804
1246
|
headline,
|
|
805
1247
|
nonTechnical: `${headline} Active credit balance: ${ws.creditsBalance} credits (${byokZeroCreditRunsCount} zero-credit BYOK runs).`,
|
|
806
|
-
technical: `workspace=${ws.id} | creditsBalance=${ws.creditsBalance} | runs=${params.runs.length} | hoursSaved=${estimatedEngineeringHoursSaved} | laborValueUsd=${estimatedLaborValueSavedUsd} | byokProviders=[${configuredByokProviders.join(",")}]`,
|
|
1248
|
+
technical: `workspace=${ws.id} | creditsBalance=${ws.creditsBalance} | runs=${params.runs.length} | completionRatePct=${completionRateWithoutManualRepairPct} | spendUsd=${totalMonetarySpendUsd} | hoursSaved=${estimatedEngineeringHoursSaved} | laborValueUsd=${estimatedLaborValueSavedUsd} | byokProviders=[${configuredByokProviders.join(",")}]`,
|
|
807
1249
|
policy: ws.policy,
|
|
808
1250
|
});
|
|
809
1251
|
return {
|
|
@@ -819,6 +1261,7 @@ export function buildCommercialRoiReport(params) {
|
|
|
819
1261
|
byokZeroCreditRunsCount,
|
|
820
1262
|
managedFundedRunsCount,
|
|
821
1263
|
totalCreditsConsumed,
|
|
1264
|
+
totalMonetarySpendUsd,
|
|
822
1265
|
byokCreditsSaved,
|
|
823
1266
|
byokDollarsSavedUsd,
|
|
824
1267
|
estimatedEngineeringMinutesSaved,
|
|
@@ -829,8 +1272,794 @@ export function buildCommercialRoiReport(params) {
|
|
|
829
1272
|
activeBiTemporalFactsCount: params.temporalFacts.filter((f) => !f.validTo).length,
|
|
830
1273
|
configuredByokProviders,
|
|
831
1274
|
},
|
|
1275
|
+
validationMetrics: {
|
|
1276
|
+
timeToFirstSuccessfulActionSeconds,
|
|
1277
|
+
completionRateWithoutManualRepairPct,
|
|
1278
|
+
avgTimeSavedPerWorkflowMinutes,
|
|
1279
|
+
avgCostPerCompletedWorkflowUsd,
|
|
1280
|
+
repeatWorkflowExecutionsCount,
|
|
1281
|
+
zeroChargeFailedRunsCount: failedRunsCount,
|
|
1282
|
+
},
|
|
1283
|
+
workflowBreakdown,
|
|
832
1284
|
laneBreakdown,
|
|
833
1285
|
recommendations,
|
|
834
1286
|
explanation,
|
|
835
1287
|
};
|
|
836
1288
|
}
|
|
1289
|
+
// ============================================================================
|
|
1290
|
+
// 5. TURNKEY HARNESS PRESETS & ONE-SHOT AGENT CONFIGURATOR
|
|
1291
|
+
// ============================================================================
|
|
1292
|
+
const DEFAULT_WORKSPACE_POLICY = {
|
|
1293
|
+
mode: "enforce",
|
|
1294
|
+
requireApprovalFor: ["admin", "financial", "destructive"],
|
|
1295
|
+
allowInstantWallet: true,
|
|
1296
|
+
allowProvisioning: true,
|
|
1297
|
+
maxCreditsPerRun: 25,
|
|
1298
|
+
executionRing: 2,
|
|
1299
|
+
killSwitchActive: false,
|
|
1300
|
+
killSwitchReason: null,
|
|
1301
|
+
blockDestructiveSql: true,
|
|
1302
|
+
languageMode: "hybrid",
|
|
1303
|
+
};
|
|
1304
|
+
export const MUXO_HARNESS_PRESETS = [
|
|
1305
|
+
{
|
|
1306
|
+
slug: "startup-builder",
|
|
1307
|
+
name: "Startup Builder (Balanced Velocity & Safety)",
|
|
1308
|
+
summary: "Auto-approves read, write, and cloud provisioning up to 50 credits/run while requiring human approval for financial, admin, and destructive actions.",
|
|
1309
|
+
recommendedFor: "Claude Code, Cursor, Codex, and Factory Droid full-stack shipping",
|
|
1310
|
+
naturalLanguageTriggers: [
|
|
1311
|
+
"Configure harness preset startup-builder",
|
|
1312
|
+
"Set agent profile to startup builder",
|
|
1313
|
+
"Balanced velocity mode",
|
|
1314
|
+
],
|
|
1315
|
+
policyPatch: {
|
|
1316
|
+
mode: "enforce",
|
|
1317
|
+
executionRing: 1,
|
|
1318
|
+
requireApprovalFor: ["financial", "admin", "destructive"],
|
|
1319
|
+
maxCreditsPerRun: 50,
|
|
1320
|
+
allowProvisioning: true,
|
|
1321
|
+
allowInstantWallet: true,
|
|
1322
|
+
blockDestructiveSql: true,
|
|
1323
|
+
languageMode: "hybrid",
|
|
1324
|
+
},
|
|
1325
|
+
},
|
|
1326
|
+
{
|
|
1327
|
+
slug: "strict-production",
|
|
1328
|
+
name: "Strict Production (Zero-Trust & Human-in-the-Loop)",
|
|
1329
|
+
summary: "Auto-approves read-only tools, requires explicit human approval for every write, cloud provisioning, financial, or admin action, blocks destructive SQL, and caps runs at 25 credits.",
|
|
1330
|
+
recommendedFor: "Production SaaS operations, SecOps, and customer-facing ChatGPT / Claude agents",
|
|
1331
|
+
naturalLanguageTriggers: [
|
|
1332
|
+
"Configure harness preset strict-production",
|
|
1333
|
+
"Strict production mode",
|
|
1334
|
+
"Zero-trust human-in-the-loop mode",
|
|
1335
|
+
],
|
|
1336
|
+
policyPatch: {
|
|
1337
|
+
mode: "enforce",
|
|
1338
|
+
executionRing: 2,
|
|
1339
|
+
requireApprovalFor: ["write", "provisioning", "financial", "admin", "destructive"],
|
|
1340
|
+
maxCreditsPerRun: 25,
|
|
1341
|
+
allowProvisioning: true,
|
|
1342
|
+
allowInstantWallet: true,
|
|
1343
|
+
blockDestructiveSql: true,
|
|
1344
|
+
languageMode: "technical",
|
|
1345
|
+
},
|
|
1346
|
+
},
|
|
1347
|
+
{
|
|
1348
|
+
slug: "read-only-auditor",
|
|
1349
|
+
name: "Read-Only Auditor (Zero Mutation & Compliance)",
|
|
1350
|
+
summary: "Allows read-only discovery, SEO/web intelligence, memory recall, Cedar policy compilation, and OTel/WORM audit exports while requiring approval or blocking mutations and cloud provisioning.",
|
|
1351
|
+
recommendedFor: "Security audits, research agents, and compliance reporting",
|
|
1352
|
+
naturalLanguageTriggers: [
|
|
1353
|
+
"Configure harness preset read-only-auditor",
|
|
1354
|
+
"Read-only auditor mode",
|
|
1355
|
+
"Compliance auditor profile",
|
|
1356
|
+
],
|
|
1357
|
+
policyPatch: {
|
|
1358
|
+
mode: "enforce",
|
|
1359
|
+
executionRing: 3,
|
|
1360
|
+
requireApprovalFor: ["write", "provisioning", "financial", "admin", "destructive"],
|
|
1361
|
+
maxCreditsPerRun: 10,
|
|
1362
|
+
allowProvisioning: false,
|
|
1363
|
+
allowInstantWallet: true,
|
|
1364
|
+
blockDestructiveSql: true,
|
|
1365
|
+
languageMode: "hybrid",
|
|
1366
|
+
},
|
|
1367
|
+
},
|
|
1368
|
+
{
|
|
1369
|
+
slug: "finops-byok-zero-cost",
|
|
1370
|
+
name: "FinOps Zero-Cost (BYOK & Free-Tier Enforced)",
|
|
1371
|
+
summary: "Optimizes for 0-credit BYOK execution and free cloud infrastructure tiers with a tight 5-credit per-run cap and approval gates on paid operations.",
|
|
1372
|
+
recommendedFor: "High-volume background agents and cost-sensitive teams",
|
|
1373
|
+
naturalLanguageTriggers: [
|
|
1374
|
+
"Configure harness preset finops-byok-zero-cost",
|
|
1375
|
+
"FinOps zero-cost mode",
|
|
1376
|
+
"BYOK zero-credit profile",
|
|
1377
|
+
],
|
|
1378
|
+
policyPatch: {
|
|
1379
|
+
mode: "enforce",
|
|
1380
|
+
executionRing: 2,
|
|
1381
|
+
requireApprovalFor: ["provisioning", "financial", "admin", "destructive"],
|
|
1382
|
+
maxCreditsPerRun: 5,
|
|
1383
|
+
allowProvisioning: true,
|
|
1384
|
+
allowInstantWallet: true,
|
|
1385
|
+
blockDestructiveSql: true,
|
|
1386
|
+
languageMode: "hybrid",
|
|
1387
|
+
customInstructions: [
|
|
1388
|
+
"Prefer 0-credit BYOK funding mode and free cloud plans whenever available.",
|
|
1389
|
+
],
|
|
1390
|
+
},
|
|
1391
|
+
},
|
|
1392
|
+
];
|
|
1393
|
+
export function resolveHarnessPreset(presetOrPrompt) {
|
|
1394
|
+
const raw = String(presetOrPrompt || "").trim().toLowerCase();
|
|
1395
|
+
if (!raw)
|
|
1396
|
+
return null;
|
|
1397
|
+
const exact = MUXO_HARNESS_PRESETS.find((p) => p.slug === raw);
|
|
1398
|
+
if (exact)
|
|
1399
|
+
return exact;
|
|
1400
|
+
if (/\b(strict[-\s]?prod|strict\s+production|zero[-\s]?trust|human[-\s]?in[-\s]?the[-\s]?loop)\b/i.test(raw)) {
|
|
1401
|
+
return MUXO_HARNESS_PRESETS[1];
|
|
1402
|
+
}
|
|
1403
|
+
if (/\b(read[-\s]?only\s+audit|auditor|zero[-\s]?mutation|compliance\s+auditor)\b/i.test(raw)) {
|
|
1404
|
+
return MUXO_HARNESS_PRESETS[2];
|
|
1405
|
+
}
|
|
1406
|
+
if (/\b(finops|zero[-\s]?cost|byok\s+mode|cost[-\s]?optimized)\b/i.test(raw)) {
|
|
1407
|
+
return MUXO_HARNESS_PRESETS[3];
|
|
1408
|
+
}
|
|
1409
|
+
if (/\b(startup[-\s]?builder|startup\s+mode|balanced\s+velocity|autonomous\s+dev|builder\s+preset)\b/i.test(raw)) {
|
|
1410
|
+
return MUXO_HARNESS_PRESETS[0];
|
|
1411
|
+
}
|
|
1412
|
+
return null;
|
|
1413
|
+
}
|
|
1414
|
+
export function buildHarnessConfigurationBundle(params) {
|
|
1415
|
+
const baseUrl = (params.baseUrl || "https://api.muxo.ai").replace(/\/+$/, "");
|
|
1416
|
+
const mcpUrl = `${baseUrl}/mcp`;
|
|
1417
|
+
const targetHarness = String(params.targetHarness || "all").toLowerCase();
|
|
1418
|
+
const policy = {
|
|
1419
|
+
...DEFAULT_WORKSPACE_POLICY,
|
|
1420
|
+
...(params.workspace.policy || {}),
|
|
1421
|
+
};
|
|
1422
|
+
const presetLabel = params.appliedPreset
|
|
1423
|
+
? `${params.appliedPreset.name} (${params.appliedPreset.slug})`
|
|
1424
|
+
: `Current Workspace Policy (${policy.executionRing || "ring2_standard"}, max ${policy.maxCreditsPerRun ?? 25} credits/run)`;
|
|
1425
|
+
const headline = `Harness Configuration Ready for ${params.workspace.name}: ${presetLabel}.`;
|
|
1426
|
+
const explanation = formatHumanFriendlyExplanation({
|
|
1427
|
+
headline,
|
|
1428
|
+
nonTechnical: `${headline} You can control guardrails, memory time-travel, Temporal Saga playbooks, AWS Cedar policies, OpenTelemetry traces, and ROI analytics in plain English via 'POST /api/v1/do' or MCP 'get_run_context'.`,
|
|
1429
|
+
technical: `workspace=${params.workspace.id} | preset=${params.appliedPreset?.slug || "custom"} | mcpUrl=${mcpUrl} | ring=${policy.executionRing || "ring2_standard"} | maxCreditsPerRun=${policy.maxCreditsPerRun ?? 25}`,
|
|
1430
|
+
policy,
|
|
1431
|
+
});
|
|
1432
|
+
const naturalLanguageCheatsheet = [
|
|
1433
|
+
{
|
|
1434
|
+
category: "Turnkey & Custom Saga Playbooks",
|
|
1435
|
+
sayInPlainEnglish: "Run the fullstack cloud bootstrap playbook for acme",
|
|
1436
|
+
mcpEquivalent: {
|
|
1437
|
+
tool: "get_run_context",
|
|
1438
|
+
arguments: {
|
|
1439
|
+
action: "run_playbook",
|
|
1440
|
+
slug: "fullstack-cloud-bootstrap",
|
|
1441
|
+
input: { serviceRef: "acme" },
|
|
1442
|
+
},
|
|
1443
|
+
},
|
|
1444
|
+
restEndpoint: "POST /api/v1/playbooks/fullstack-cloud-bootstrap/run",
|
|
1445
|
+
},
|
|
1446
|
+
{
|
|
1447
|
+
category: "Custom Saga Playbook Authoring",
|
|
1448
|
+
sayInPlainEnglish: "Create playbook daily-seo-slack that runs instant.seo.audit and app.slack.send_message",
|
|
1449
|
+
mcpEquivalent: {
|
|
1450
|
+
tool: "get_run_context",
|
|
1451
|
+
arguments: {
|
|
1452
|
+
action: "create_playbook",
|
|
1453
|
+
prompt: "Create playbook daily-seo-slack that runs instant.seo.audit and app.slack.send_message",
|
|
1454
|
+
},
|
|
1455
|
+
},
|
|
1456
|
+
restEndpoint: "POST /api/v1/playbooks",
|
|
1457
|
+
},
|
|
1458
|
+
{
|
|
1459
|
+
category: "Temporal Workflow Rollback & Signals",
|
|
1460
|
+
sayInPlainEnglish: "Rollback the latest workflow because staging healthcheck failed",
|
|
1461
|
+
mcpEquivalent: {
|
|
1462
|
+
tool: "get_run_context",
|
|
1463
|
+
arguments: {
|
|
1464
|
+
action: "rollback_workflow",
|
|
1465
|
+
workflow_id: "latest",
|
|
1466
|
+
prompt: "Staging healthcheck failed",
|
|
1467
|
+
},
|
|
1468
|
+
},
|
|
1469
|
+
restEndpoint: "POST /api/v1/workflows/:id/rollback",
|
|
1470
|
+
},
|
|
1471
|
+
{
|
|
1472
|
+
category: "Graphiti Time-Travel & Multi-Hop Memory Graph",
|
|
1473
|
+
sayInPlainEnglish: "Show my knowledge graph as of 2026-10-20T00:00:00Z within 2 hops of workspace",
|
|
1474
|
+
mcpEquivalent: {
|
|
1475
|
+
tool: "get_run_context",
|
|
1476
|
+
arguments: {
|
|
1477
|
+
action: "memory_graph",
|
|
1478
|
+
as_of: "2026-10-20T00:00:00Z",
|
|
1479
|
+
focal_entity: "workspace",
|
|
1480
|
+
max_hops: 2,
|
|
1481
|
+
},
|
|
1482
|
+
},
|
|
1483
|
+
restEndpoint: "POST /api/v1/memory/graph",
|
|
1484
|
+
},
|
|
1485
|
+
{
|
|
1486
|
+
category: "AWS Cedar & OPA Policy-as-Code",
|
|
1487
|
+
sayInPlainEnglish: "Compile our guardrails to AWS Cedar and OPA Rego (or: Evaluate Cedar policy for resource.turso.database with DROP TABLE users)",
|
|
1488
|
+
mcpEquivalent: {
|
|
1489
|
+
tool: "get_run_context",
|
|
1490
|
+
arguments: {
|
|
1491
|
+
action: "cedar_policy",
|
|
1492
|
+
tool_slug: "resource.turso.database",
|
|
1493
|
+
input: { query: "DROP TABLE users" },
|
|
1494
|
+
},
|
|
1495
|
+
},
|
|
1496
|
+
restEndpoint: "GET /api/v1/governance/cedar | POST /api/v1/governance/cedar/evaluate",
|
|
1497
|
+
},
|
|
1498
|
+
{
|
|
1499
|
+
category: "OpenTelemetry GenAI & Langfuse Traces",
|
|
1500
|
+
sayInPlainEnglish: "Export OpenTelemetry traces and Langfuse batch",
|
|
1501
|
+
mcpEquivalent: {
|
|
1502
|
+
tool: "get_run_context",
|
|
1503
|
+
arguments: { action: "otel_traces", limit: 25 },
|
|
1504
|
+
},
|
|
1505
|
+
restEndpoint: "GET /api/v1/telemetry/otlp",
|
|
1506
|
+
},
|
|
1507
|
+
{
|
|
1508
|
+
category: "FinOps & Engineering ROI Analytics",
|
|
1509
|
+
sayInPlainEnglish: "What is our ROI and how many engineering hours have we saved?",
|
|
1510
|
+
mcpEquivalent: {
|
|
1511
|
+
tool: "get_run_context",
|
|
1512
|
+
arguments: { action: "roi_analytics" },
|
|
1513
|
+
},
|
|
1514
|
+
restEndpoint: "GET /api/v1/analytics/roi",
|
|
1515
|
+
},
|
|
1516
|
+
{
|
|
1517
|
+
category: "One-Shot Harness Preset & Guardrails",
|
|
1518
|
+
sayInPlainEnglish: "Configure harness preset strict-production and only allow emails to @muxo.ai",
|
|
1519
|
+
mcpEquivalent: {
|
|
1520
|
+
tool: "get_run_context",
|
|
1521
|
+
arguments: {
|
|
1522
|
+
action: "configure_harness",
|
|
1523
|
+
preset: "strict-production",
|
|
1524
|
+
prompt: "Only allow sending emails to @muxo.ai",
|
|
1525
|
+
},
|
|
1526
|
+
},
|
|
1527
|
+
restEndpoint: "POST /api/v1/harness/configure",
|
|
1528
|
+
},
|
|
1529
|
+
];
|
|
1530
|
+
const systemPromptDirective = [
|
|
1531
|
+
`# Muxo Natural-Language & Harness Control Directive (${params.workspace.name})`,
|
|
1532
|
+
`- Active Profile: ${presetLabel}`,
|
|
1533
|
+
`- You can pass ANY plain-English instruction directly to \`get_run_context({ prompt: "..." })\` or \`POST ${baseUrl}/api/v1/do\` without needing to memorize sub-actions.`,
|
|
1534
|
+
`- Built-in Saga Playbooks: \`fullstack-cloud-bootstrap\`, \`competitor-seo-growth-brief\`, \`incident-containment-audit\`, \`customer-release-readiness\` (plus custom playbooks via "Create playbook <name> that runs ...").`,
|
|
1535
|
+
`- Time-Travel & BFS Memory: Ask "Show knowledge graph as of <ISO-date> within 2 hops of <entity>" or pass \`as_of\`, \`focal_entity\`, \`max_hops\`.`,
|
|
1536
|
+
`- Policy-as-Code & Telemetry: Ask "Compile policy to AWS Cedar", "Evaluate Cedar policy for <tool>", "Export OpenTelemetry traces", or "What is our ROI?".`,
|
|
1537
|
+
].join("\n");
|
|
1538
|
+
return {
|
|
1539
|
+
ok: true,
|
|
1540
|
+
workspaceId: params.workspace.id,
|
|
1541
|
+
workspaceSlug: params.workspace.slug,
|
|
1542
|
+
targetHarness,
|
|
1543
|
+
appliedPreset: params.appliedPreset || null,
|
|
1544
|
+
availablePresets: MUXO_HARNESS_PRESETS,
|
|
1545
|
+
policy,
|
|
1546
|
+
harnessConfigs: {
|
|
1547
|
+
claudeCode: {
|
|
1548
|
+
installPluginCommand: `claude plugin marketplace add ${baseUrl}/.claude-plugin/marketplace.json && claude plugin install muxo@muxo`,
|
|
1549
|
+
addMcpCommand: `claude mcp add --transport http muxo ${mcpUrl}`,
|
|
1550
|
+
mcpJson: {
|
|
1551
|
+
mcpServers: {
|
|
1552
|
+
muxo: {
|
|
1553
|
+
type: "http",
|
|
1554
|
+
url: mcpUrl,
|
|
1555
|
+
headers: {
|
|
1556
|
+
Authorization: "Bearer ${MUXO_API_KEY}",
|
|
1557
|
+
},
|
|
1558
|
+
},
|
|
1559
|
+
},
|
|
1560
|
+
},
|
|
1561
|
+
},
|
|
1562
|
+
cursor: {
|
|
1563
|
+
filePath: ".cursor/mcp.json",
|
|
1564
|
+
mcpJson: {
|
|
1565
|
+
mcpServers: {
|
|
1566
|
+
muxo: {
|
|
1567
|
+
url: mcpUrl,
|
|
1568
|
+
headers: {
|
|
1569
|
+
Authorization: "Bearer ${MUXO_API_KEY}",
|
|
1570
|
+
},
|
|
1571
|
+
},
|
|
1572
|
+
},
|
|
1573
|
+
},
|
|
1574
|
+
},
|
|
1575
|
+
codex: {
|
|
1576
|
+
filePath: "~/.codex/config.toml",
|
|
1577
|
+
toml: `[mcp_servers.muxo]\nurl = "${mcpUrl}"\nbearer_token_env_var = "MUXO_API_KEY"\n`,
|
|
1578
|
+
},
|
|
1579
|
+
chatgpt: {
|
|
1580
|
+
mcpServerUrl: mcpUrl,
|
|
1581
|
+
authMode: "OAuth 2.1 (CIMD / DCR) or No Authentication for Instant tools",
|
|
1582
|
+
instructions: "In ChatGPT → Settings → Connectors / Plugins → Add custom MCP server, enter https://api.muxo.ai/mcp.",
|
|
1583
|
+
},
|
|
1584
|
+
claudeDesktop: {
|
|
1585
|
+
filePath: "claude_desktop_config.json",
|
|
1586
|
+
mcpJson: {
|
|
1587
|
+
mcpServers: {
|
|
1588
|
+
muxo: {
|
|
1589
|
+
command: "npx",
|
|
1590
|
+
args: ["-y", "@muxoai/cli@latest", "mcp"],
|
|
1591
|
+
env: {
|
|
1592
|
+
MUXO_API_KEY: "<YOUR_MUXO_API_KEY>",
|
|
1593
|
+
},
|
|
1594
|
+
},
|
|
1595
|
+
},
|
|
1596
|
+
},
|
|
1597
|
+
},
|
|
1598
|
+
factoryDroid: {
|
|
1599
|
+
mcpServerUrl: mcpUrl,
|
|
1600
|
+
skillCommand: `curl -fsSL ${baseUrl}/skill.md`,
|
|
1601
|
+
},
|
|
1602
|
+
},
|
|
1603
|
+
systemPromptDirective,
|
|
1604
|
+
naturalLanguageCheatsheet,
|
|
1605
|
+
explanation,
|
|
1606
|
+
humanMessage: explanation.preferred,
|
|
1607
|
+
};
|
|
1608
|
+
}
|
|
1609
|
+
export function extractPlaybookInputFromNaturalLanguage(prompt, explicitInput) {
|
|
1610
|
+
const out = { ...(explicitInput || {}) };
|
|
1611
|
+
const text = String(prompt || "").trim();
|
|
1612
|
+
const urlMatch = text.match(/https?:\/\/[^\s"'<>]+/i);
|
|
1613
|
+
if (urlMatch && !out.url) {
|
|
1614
|
+
out.url = urlMatch[0].replace(/[.,;!?)]+$/, "");
|
|
1615
|
+
}
|
|
1616
|
+
const providerMatch = text.match(/\b(neon|turso|supabase|upstash|cloudflare|vercel|firecrawl|github|slack|gmail|stripe|resend)\b/i);
|
|
1617
|
+
if (providerMatch && !out.provider) {
|
|
1618
|
+
out.provider = providerMatch[1].toLowerCase();
|
|
1619
|
+
}
|
|
1620
|
+
const forTargetMatch = text.match(/\b(?:for|on|target(?:ing)?|project|app|service)\s+["'`]?([a-zA-Z0-9._/-]{2,64})["'`]?/i);
|
|
1621
|
+
if (forTargetMatch?.[1] &&
|
|
1622
|
+
!/^(the|our|my|a|an|playbook|saga|workflow|cloud|production|staging)$/i.test(forTargetMatch[1]) &&
|
|
1623
|
+
!out.serviceRef) {
|
|
1624
|
+
out.serviceRef = forTargetMatch[1].replace(/[.,;!?)]+$/, "");
|
|
1625
|
+
}
|
|
1626
|
+
return out;
|
|
1627
|
+
}
|
|
1628
|
+
function parseRelativeOrIsoTimestamp(text) {
|
|
1629
|
+
const isoMatch = text.match(/\b(\d{4}-\d{2}-\d{2}(?:T\d{2}:\d{2}(?::\d{2}(?:\.\d+)?)?(?:Z|[+-]\d{2}:?\d{2})?)?)\b/);
|
|
1630
|
+
if (isoMatch?.[1]) {
|
|
1631
|
+
const raw = isoMatch[1];
|
|
1632
|
+
return raw.includes("T") ? raw : `${raw}T23:59:59.000Z`;
|
|
1633
|
+
}
|
|
1634
|
+
if (/\byesterday\b/i.test(text)) {
|
|
1635
|
+
return new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
|
|
1636
|
+
}
|
|
1637
|
+
const relMatch = text.match(/\b(\d+)\s*(hour|hr|day|week|minute|min)s?\s+ago\b/i);
|
|
1638
|
+
if (relMatch) {
|
|
1639
|
+
const count = Number(relMatch[1]);
|
|
1640
|
+
const unit = relMatch[2].toLowerCase();
|
|
1641
|
+
const mult = unit.startsWith("min")
|
|
1642
|
+
? 60_000
|
|
1643
|
+
: unit.startsWith("h")
|
|
1644
|
+
? 3_600_000
|
|
1645
|
+
: unit.startsWith("w")
|
|
1646
|
+
? 7 * 86_400_000
|
|
1647
|
+
: 86_400_000;
|
|
1648
|
+
return new Date(Date.now() - count * mult).toISOString();
|
|
1649
|
+
}
|
|
1650
|
+
return null;
|
|
1651
|
+
}
|
|
1652
|
+
export function parseNaturalLanguageOssIntent(prompt, options) {
|
|
1653
|
+
const raw = String(prompt || "").trim();
|
|
1654
|
+
const cleaned = raw
|
|
1655
|
+
.replace(/^(?:hey\s+muxo[,:\s]*|muxo[,:\s]*|please\s+|can\s+you\s+)/i, "")
|
|
1656
|
+
.trim();
|
|
1657
|
+
if (!cleaned) {
|
|
1658
|
+
return { matched: false, kind: null, summary: "" };
|
|
1659
|
+
}
|
|
1660
|
+
// 1. Custom Playbook Creation ("Create playbook <name> that runs ...", "Define a saga playbook ...")
|
|
1661
|
+
if (/^(?:create|define|register|save|build|add)\s+(?:a\s+|new\s+|custom\s+)?(?:commercial\s+|saga\s+|durable\s+)?playbook\b/i.test(cleaned)) {
|
|
1662
|
+
const customPlaybook = parseNaturalLanguageCustomPlaybook(cleaned, options?.explicitInput);
|
|
1663
|
+
return {
|
|
1664
|
+
matched: true,
|
|
1665
|
+
kind: "create_playbook",
|
|
1666
|
+
customPlaybook,
|
|
1667
|
+
playbookSlug: customPlaybook.slug,
|
|
1668
|
+
summary: `Created custom ${customPlaybook.steps.length}-step Saga playbook '${customPlaybook.slug}'.`,
|
|
1669
|
+
};
|
|
1670
|
+
}
|
|
1671
|
+
// 2. List / Discover Playbooks ("List playbooks", "What playbooks are available?", "Show commercial saga playbooks")
|
|
1672
|
+
if (/^(?:list|show|what\s+are(?:\s+the|\s+our)?|get|inspect|browse)\s+(?:all\s+|available\s+|commercial\s+|turnkey\s+|saga\s+)?playbooks\b/i.test(cleaned) ||
|
|
1673
|
+
/\bwhat\s+playbooks\s+(?:can\s+we\s+run|are\s+available|do\s+you\s+have)\b/i.test(cleaned)) {
|
|
1674
|
+
return {
|
|
1675
|
+
matched: true,
|
|
1676
|
+
kind: "list_playbooks",
|
|
1677
|
+
summary: "Listed available turnkey and custom Saga playbooks.",
|
|
1678
|
+
};
|
|
1679
|
+
}
|
|
1680
|
+
// 3. Run Playbook ("Run fullstack cloud bootstrap playbook", "Bootstrap a fullstack cloud stack", "Run competitor SEO growth brief", "Execute playbook <slug>")
|
|
1681
|
+
const explicitPlaybookRun = /^(?:run|execute|launch|start|trigger)\s+(?:the\s+|our\s+|a\s+)?(?:commercial\s+|saga\s+|turnkey\s+)?playbook\b/i.test(cleaned) ||
|
|
1682
|
+
/\b(?:run|execute|launch|start|trigger)\b[\s\S]*\bplaybook\b/i.test(cleaned) ||
|
|
1683
|
+
/^(?:bootstrap\s+(?:a\s+|our\s+)?(?:fullstack|full-stack)\s+cloud|run\s+(?:fullstack|full-stack)\s+cloud\s+bootstrap|run\s+competitor\s+seo\s+growth\s+brief|run\s+incident\s+containment\s+audit|run\s+customer\s+release\s+readiness)\b/i.test(cleaned);
|
|
1684
|
+
if (explicitPlaybookRun) {
|
|
1685
|
+
const matchedPb = getCommercialPlaybook(cleaned, options?.customPlaybooks || []) ||
|
|
1686
|
+
MUXO_COMMERCIAL_PLAYBOOKS[0];
|
|
1687
|
+
const playbookInput = extractPlaybookInputFromNaturalLanguage(cleaned, options?.explicitInput);
|
|
1688
|
+
return {
|
|
1689
|
+
matched: true,
|
|
1690
|
+
kind: "run_playbook",
|
|
1691
|
+
playbookSlug: matchedPb.slug,
|
|
1692
|
+
playbookInput,
|
|
1693
|
+
summary: `Execute Saga playbook '${matchedPb.name}' (${matchedPb.slug}).`,
|
|
1694
|
+
};
|
|
1695
|
+
}
|
|
1696
|
+
// 4. Temporal Workflow Saga Rollback ("Rollback workflow wf_123 because ...", "Rollback the latest workflow", "Undo last saga workflow", "Compensate workflow wf_...")
|
|
1697
|
+
if (/^(?:rollback|roll\s+back|compensate|abort\s+and\s+rollback|undo)\s+(?:the\s+|our\s+|my\s+)?(?:latest\s+|last\s+|most\s+recent\s+)?(?:durable\s+|temporal\s+|saga\s+|playbook\s+)?(?:workflow|saga)(?:\s+(wf_[a-zA-Z0-9_-]+))?/i.test(cleaned) ||
|
|
1698
|
+
/\b(?:rollback|roll\s+back|compensate)\s+(wf_[a-zA-Z0-9_-]+)\b/i.test(cleaned)) {
|
|
1699
|
+
const wfIdMatch = cleaned.match(/\b(wf_[a-zA-Z0-9_-]+)\b/);
|
|
1700
|
+
const reasonMatch = cleaned.match(/(?:because|reason|due\s+to)[:\s]+(.+)$/i);
|
|
1701
|
+
const workflowId = wfIdMatch?.[1] || "latest";
|
|
1702
|
+
const workflowReason = reasonMatch?.[1]?.trim() ||
|
|
1703
|
+
`Rolled back via natural language: "${raw.slice(0, 100)}"`;
|
|
1704
|
+
return {
|
|
1705
|
+
matched: true,
|
|
1706
|
+
kind: "rollback_workflow",
|
|
1707
|
+
workflowId,
|
|
1708
|
+
workflowReason,
|
|
1709
|
+
summary: `Execute LIFO Saga rollback for workflow '${workflowId}'.`,
|
|
1710
|
+
};
|
|
1711
|
+
}
|
|
1712
|
+
// 5. Temporal Workflow Signal ("Signal workflow wf_123 ...", "Send approval signal to workflow wf_123", "Approve workflow wf_123")
|
|
1713
|
+
if (/^(?:signal|send\s+(?:a\s+)?signal\s+to|approve\s+workflow|resume\s+workflow)\b/i.test(cleaned) &&
|
|
1714
|
+
/\b(wf_[a-zA-Z0-9_-]+|workflow|saga)\b/i.test(cleaned)) {
|
|
1715
|
+
const wfIdMatch = cleaned.match(/\b(wf_[a-zA-Z0-9_-]+)\b/);
|
|
1716
|
+
const workflowId = wfIdMatch?.[1] || "latest";
|
|
1717
|
+
let signalName = "human.approval.granted";
|
|
1718
|
+
if (/\boauth\b|\bconnection\b/i.test(cleaned)) {
|
|
1719
|
+
signalName = "oauth.connection.active";
|
|
1720
|
+
}
|
|
1721
|
+
else if (/\b(abort|cancel|reject)\b/i.test(cleaned)) {
|
|
1722
|
+
signalName = "saga.abort";
|
|
1723
|
+
}
|
|
1724
|
+
else {
|
|
1725
|
+
const sigMatch = cleaned.match(/\b((?:human|oauth|saga|workflow)\.[a-z0-9_.]+)\b/i);
|
|
1726
|
+
if (sigMatch?.[1])
|
|
1727
|
+
signalName = sigMatch[1];
|
|
1728
|
+
}
|
|
1729
|
+
return {
|
|
1730
|
+
matched: true,
|
|
1731
|
+
kind: "signal_workflow",
|
|
1732
|
+
workflowId,
|
|
1733
|
+
signalName,
|
|
1734
|
+
signalPayload: {
|
|
1735
|
+
source: "natural_language",
|
|
1736
|
+
prompt: raw,
|
|
1737
|
+
...(options?.explicitInput || {}),
|
|
1738
|
+
},
|
|
1739
|
+
summary: `Deliver Temporal signal '${signalName}' to workflow '${workflowId}'.`,
|
|
1740
|
+
};
|
|
1741
|
+
}
|
|
1742
|
+
// 6. Temporal Workflow Event History ("Show Temporal history for workflow wf_123", "Inspect latest workflow saga history")
|
|
1743
|
+
if (/\b(?:temporal\s+(?:event\s+)?history|workflow\s+(?:event\s+)?history|saga\s+history)\b/i.test(cleaned) ||
|
|
1744
|
+
(/^(?:show|inspect|get|explain)\s+(?:the\s+|our\s+)?(?:latest\s+|last\s+)?(?:durable\s+|temporal\s+)?workflow\b/i.test(cleaned) &&
|
|
1745
|
+
!/\bplaybooks\b/i.test(cleaned))) {
|
|
1746
|
+
const wfIdMatch = cleaned.match(/\b(wf_[a-zA-Z0-9_-]+)\b/);
|
|
1747
|
+
const workflowId = wfIdMatch?.[1] || "latest";
|
|
1748
|
+
return {
|
|
1749
|
+
matched: true,
|
|
1750
|
+
kind: "workflow_history",
|
|
1751
|
+
workflowId,
|
|
1752
|
+
summary: `Inspect Temporal EventHistory for workflow '${workflowId}'.`,
|
|
1753
|
+
};
|
|
1754
|
+
}
|
|
1755
|
+
// 7. AWS Cedar & OPA Rego Policy-as-Code Compile or Evaluate
|
|
1756
|
+
if (/\b(?:cedar|opa\s+rego|rego\s+policy|policy[-\s]as[-\s]code)\b/i.test(cleaned)) {
|
|
1757
|
+
const toolMatch = cleaned.match(/\b((?:instant|app|resource|billing)\.[a-z0-9_]+(?:\.[a-z0-9_]+)+)\b/i);
|
|
1758
|
+
const isEval = Boolean(toolMatch) ||
|
|
1759
|
+
/\b(?:evaluate|test|check|simulate|would\s+cedar\s+allow|drop\s+table|truncate\s+table|delete\s+from)\b/i.test(cleaned);
|
|
1760
|
+
if (isEval) {
|
|
1761
|
+
const toolSlug = toolMatch?.[1] || "resource.turso.database";
|
|
1762
|
+
const evaluationInput = {
|
|
1763
|
+
...(options?.explicitInput || {}),
|
|
1764
|
+
};
|
|
1765
|
+
const sqlMatch = cleaned.match(/\b((?:DROP|TRUNCATE|DELETE|ALTER|SELECT|INSERT|UPDATE)\s+[\s\S]+)$/i);
|
|
1766
|
+
if (sqlMatch?.[1] && !evaluationInput.query) {
|
|
1767
|
+
evaluationInput.query = sqlMatch[1].trim();
|
|
1768
|
+
}
|
|
1769
|
+
const emailMatch = cleaned.match(/\b([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})\b/);
|
|
1770
|
+
if (emailMatch?.[1] && !evaluationInput.to && !evaluationInput.recipient_email) {
|
|
1771
|
+
evaluationInput.to = emailMatch[1];
|
|
1772
|
+
}
|
|
1773
|
+
return {
|
|
1774
|
+
matched: true,
|
|
1775
|
+
kind: "cedar_evaluate",
|
|
1776
|
+
toolSlug,
|
|
1777
|
+
evaluationInput,
|
|
1778
|
+
summary: `Evaluate AWS Cedar 4.0 & OPA Rego v1 policy for '${toolSlug}'.`,
|
|
1779
|
+
};
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
matched: true,
|
|
1783
|
+
kind: "cedar_compile",
|
|
1784
|
+
summary: "Compile workspace guardrails into AWS Cedar 4.0 and OPA Rego v1.",
|
|
1785
|
+
};
|
|
1786
|
+
}
|
|
1787
|
+
// 8. OpenTelemetry (OTel GenAI) & Langfuse Trace Export
|
|
1788
|
+
if (/\b(?:opentelemetry|otel\b|otlp\b|langfuse|w3c\s+trace|trace\s+spans|telemetry\s+traces|genai\s+spans)\b/i.test(cleaned)) {
|
|
1789
|
+
const limitMatch = cleaned.match(/\b(\d+)\s+(?:traces|spans|runs)\b/i);
|
|
1790
|
+
return {
|
|
1791
|
+
matched: true,
|
|
1792
|
+
kind: "otel_traces",
|
|
1793
|
+
limit: limitMatch ? Math.min(100, Math.max(1, Number(limitMatch[1]))) : 25,
|
|
1794
|
+
summary: "Export W3C OpenTelemetry GenAI 1.29.0 spans and Langfuse batch.",
|
|
1795
|
+
};
|
|
1796
|
+
}
|
|
1797
|
+
// 9. FinOps & Commercial ROI Unit-Economics Report
|
|
1798
|
+
if (/\b(?:commercial\s+roi|finops|unit\s+economics|engineering\s+(?:hours|time|value)\s+saved|byok\s+savings|return\s+on\s+investment)\b/i.test(cleaned) ||
|
|
1799
|
+
/^(?:what\s+is\s+(?:our|my)\s+roi|show\s+(?:our|my)?\s*roi|calculate\s+roi|how\s+much\s+(?:time|money|hours|credits)\s+have\s+we\s+saved)\b/i.test(cleaned)) {
|
|
1800
|
+
return {
|
|
1801
|
+
matched: true,
|
|
1802
|
+
kind: "roi_analytics",
|
|
1803
|
+
summary: "Generate FinOps unit-economics and engineering ROI report.",
|
|
1804
|
+
};
|
|
1805
|
+
}
|
|
1806
|
+
// 10. Harness Preset & Agent Configuration ("Configure harness preset strict-production", "Show Cursor harness config", "Set agent profile to startup-builder")
|
|
1807
|
+
const matchedPreset = resolveHarnessPreset(cleaned);
|
|
1808
|
+
if (matchedPreset ||
|
|
1809
|
+
/\b(?:configure\s+(?:muxo\s+)?harness|harness\s+(?:config|configuration|preset|setup)|agent\s+harness\s+profile|mcp\s+config\s+for\s+(?:claude|cursor|codex|chatgpt|droid))\b/i.test(cleaned)) {
|
|
1810
|
+
const harnessMatch = cleaned.match(/\b(claude[-\s]?code|claude[-\s]?desktop|cursor|codex|chatgpt|droid|factory)\b/i);
|
|
1811
|
+
const targetHarness = harnessMatch
|
|
1812
|
+
? harnessMatch[1].toLowerCase().replace(/\s+/g, "-")
|
|
1813
|
+
: "all";
|
|
1814
|
+
// Check if the user also included an inline guardrail (e.g. "and only allow emails to @muxo.ai")
|
|
1815
|
+
const extraMatch = cleaned.match(/\band\s+((?:only|never|require|block|cap|limit|don't|do\s+not)\s+.+)$/i);
|
|
1816
|
+
return {
|
|
1817
|
+
matched: true,
|
|
1818
|
+
kind: "configure_harness",
|
|
1819
|
+
preset: matchedPreset,
|
|
1820
|
+
targetHarness,
|
|
1821
|
+
extraGuardrailPrompt: extraMatch?.[1]?.trim() || null,
|
|
1822
|
+
summary: matchedPreset
|
|
1823
|
+
? `Configure harness preset '${matchedPreset.slug}' (${matchedPreset.name}).`
|
|
1824
|
+
: `Inspect harness configuration & presets for '${targetHarness}'.`,
|
|
1825
|
+
};
|
|
1826
|
+
}
|
|
1827
|
+
// 11. Graphiti Bi-Temporal Knowledge Graph with Time-Travel (`as of ...`) & Multi-Hop BFS (`within N hops of ...`)
|
|
1828
|
+
if (/\b(?:memory\s+graph|knowledge\s+graph|temporal\s+graph|fact\s+lineage|bi[-\s]?temporal\s+(?:graph|lineage|facts)|graphiti|subgraph)\b/i.test(cleaned)) {
|
|
1829
|
+
const asOf = parseRelativeOrIsoTimestamp(cleaned);
|
|
1830
|
+
const hopsMatch = cleaned.match(/\b(\d+)[-\s]*hops?\b/i);
|
|
1831
|
+
const maxHops = hopsMatch
|
|
1832
|
+
? Math.min(4, Math.max(1, Number(hopsMatch[1])))
|
|
1833
|
+
: undefined;
|
|
1834
|
+
const focalMatch = cleaned.match(/\b(?:around|for\s+entity|focal\s+entity|centered\s+on|of\s+entity|neighborhood\s+of)\s+["'`]?([a-zA-Z0-9:._-]+)["'`]?/i) ||
|
|
1835
|
+
cleaned.match(/\bwithin\s+\d+\s+hops?\s+of\s+["'`]?([a-zA-Z0-9:._-]+)["'`]?/i);
|
|
1836
|
+
const focalEntity = focalMatch?.[1] &&
|
|
1837
|
+
!/^(the|our|my|graph|memory|knowledge|yesterday|today)$/i.test(focalMatch[1])
|
|
1838
|
+
? focalMatch[1]
|
|
1839
|
+
: null;
|
|
1840
|
+
return {
|
|
1841
|
+
matched: true,
|
|
1842
|
+
kind: "memory_graph",
|
|
1843
|
+
asOf,
|
|
1844
|
+
focalEntity,
|
|
1845
|
+
maxHops,
|
|
1846
|
+
summary: `Query Graphiti bi-temporal knowledge graph${asOf ? ` as of ${asOf}` : ""}${focalEntity ? ` around '${focalEntity}' (${maxHops || 2} hops)` : ""}.`,
|
|
1847
|
+
};
|
|
1848
|
+
}
|
|
1849
|
+
return { matched: false, kind: null, summary: "" };
|
|
1850
|
+
}
|
|
1851
|
+
// ============================================================================
|
|
1852
|
+
// 7. COMMERCIAL APPROVAL IMPACT PREVIEW, BUSINESS RECEIPTS & RECONCILIATION
|
|
1853
|
+
// ============================================================================
|
|
1854
|
+
function inferTargetEntityFromInput(toolSlug, input) {
|
|
1855
|
+
const candidates = [
|
|
1856
|
+
input.customer_id,
|
|
1857
|
+
input.customerId,
|
|
1858
|
+
input.account_id,
|
|
1859
|
+
input.accountId,
|
|
1860
|
+
input.to,
|
|
1861
|
+
input.recipient_email,
|
|
1862
|
+
input.email,
|
|
1863
|
+
input.channel,
|
|
1864
|
+
input.repo,
|
|
1865
|
+
input.repository,
|
|
1866
|
+
input.url,
|
|
1867
|
+
input.domain,
|
|
1868
|
+
input.name,
|
|
1869
|
+
input.project_name,
|
|
1870
|
+
input.database_name,
|
|
1871
|
+
input.service_ref,
|
|
1872
|
+
input.query,
|
|
1873
|
+
];
|
|
1874
|
+
for (const c of candidates) {
|
|
1875
|
+
if (typeof c === "string" && c.trim()) {
|
|
1876
|
+
return c.trim().slice(0, 80);
|
|
1877
|
+
}
|
|
1878
|
+
}
|
|
1879
|
+
const parts = String(toolSlug || "").split(".");
|
|
1880
|
+
return parts.length >= 2 ? `${parts[1]}:${parts.slice(2).join(".") || "resource"}` : toolSlug;
|
|
1881
|
+
}
|
|
1882
|
+
export function buildApprovalImpactPreview(params) {
|
|
1883
|
+
const input = params.input || {};
|
|
1884
|
+
const targetEntity = inferTargetEntityFromInput(params.toolSlug, input);
|
|
1885
|
+
const fundingMode = params.fundingMode ||
|
|
1886
|
+
params.supplierSettlement?.fundingMode ||
|
|
1887
|
+
(params.creditCost === 0 ? "byok" : "muxo_funded");
|
|
1888
|
+
const cents = typeof params.supplierSettlement?.userRetailChargeCents === "number"
|
|
1889
|
+
? params.supplierSettlement.userRetailChargeCents
|
|
1890
|
+
: (params.creditCost || 0) * 1;
|
|
1891
|
+
const estimatedCostUsd = Number((cents / 100).toFixed(2));
|
|
1892
|
+
const costDisplay = fundingMode === "byok"
|
|
1893
|
+
? `$0.00 USD (0 credits · Customer BYOK key)`
|
|
1894
|
+
: `$${estimatedCostUsd.toFixed(2)} USD (${params.creditCost} credit${params.creditCost === 1 ? "" : "s"} · Muxo Master Wallet)`;
|
|
1895
|
+
let whatChanges = params.reason && params.reason.trim() && params.reason !== `Execute ${params.toolSlug}`
|
|
1896
|
+
? `${params.reason.trim()} via ${params.toolSlug} on ${targetEntity}`
|
|
1897
|
+
: `Execute ${params.toolSlug} (${params.riskLevel} risk) targeting ${targetEntity}`;
|
|
1898
|
+
if (params.riskLevel === "read") {
|
|
1899
|
+
whatChanges = `Read-only query via ${params.toolSlug} on ${targetEntity} (no external state mutation)`;
|
|
1900
|
+
}
|
|
1901
|
+
else if (params.lane === "stripe_projects" || params.riskLevel === "provisioning") {
|
|
1902
|
+
whatChanges = `Provision or mutate cloud infrastructure (${params.toolSlug}) for ${targetEntity}`;
|
|
1903
|
+
}
|
|
1904
|
+
else if (params.riskLevel === "financial") {
|
|
1905
|
+
whatChanges = `Execute financial/billing action (${params.toolSlug}) affecting ${targetEntity}`;
|
|
1906
|
+
}
|
|
1907
|
+
else if (params.riskLevel === "destructive") {
|
|
1908
|
+
whatChanges = `Execute destructive operation (${params.toolSlug}) on ${targetEntity}`;
|
|
1909
|
+
}
|
|
1910
|
+
let whoIsAffected = `Workspace ${params.workspaceName || "environment"} (${targetEntity})`;
|
|
1911
|
+
if (typeof input.customer_id === "string" || typeof input.customerId === "string") {
|
|
1912
|
+
whoIsAffected = `Customer account ${input.customer_id || input.customerId}`;
|
|
1913
|
+
}
|
|
1914
|
+
else if (typeof input.to === "string" || typeof input.recipient_email === "string") {
|
|
1915
|
+
whoIsAffected = `Recipient ${input.to || input.recipient_email}`;
|
|
1916
|
+
}
|
|
1917
|
+
else if (typeof input.channel === "string") {
|
|
1918
|
+
whoIsAffected = `Channel ${input.channel} subscribers`;
|
|
1919
|
+
}
|
|
1920
|
+
else if (typeof input.repo === "string" || typeof input.repository === "string") {
|
|
1921
|
+
whoIsAffected = `Repository ${input.repo || input.repository} collaborators`;
|
|
1922
|
+
}
|
|
1923
|
+
const triggeredRule = params.decisionRecord
|
|
1924
|
+
? `${params.decisionRecord.matchedRule} (${params.decisionRecord.verdict.toUpperCase()}): ${params.decisionRecord.reason}`
|
|
1925
|
+
: `risk_gate:${params.riskLevel}`;
|
|
1926
|
+
const reversibility = params.riskLevel === "read"
|
|
1927
|
+
? "reversible"
|
|
1928
|
+
: params.riskLevel === "destructive"
|
|
1929
|
+
? "irreversible"
|
|
1930
|
+
: "compensatable_saga";
|
|
1931
|
+
const recoveryBehavior = reversibility === "reversible"
|
|
1932
|
+
? "Read-only call; safe to retry idempotently with zero side effects and zero credit charge on failure."
|
|
1933
|
+
: reversibility === "compensatable_saga"
|
|
1934
|
+
? "Execute-once idempotency lock prevents duplicate execution; LIFO Saga compensation available on downstream failure; 0 credits charged if call fails."
|
|
1935
|
+
: "High-impact destructive operation; guarded by execute-once lock and human approval gate; 0 credits charged if rejected or failed.";
|
|
1936
|
+
return {
|
|
1937
|
+
whatChanges,
|
|
1938
|
+
whoIsAffected,
|
|
1939
|
+
targetEntity,
|
|
1940
|
+
estimatedCostUsd,
|
|
1941
|
+
creditCost: params.creditCost,
|
|
1942
|
+
fundingMode,
|
|
1943
|
+
costDisplay,
|
|
1944
|
+
triggeredRule,
|
|
1945
|
+
reversibility,
|
|
1946
|
+
recoveryBehavior,
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
export function buildBusinessReceiptSummary(params) {
|
|
1950
|
+
const input = params.input || {};
|
|
1951
|
+
const targetEntity = inferTargetEntityFromInput(params.toolSlug, input);
|
|
1952
|
+
const fundingMode = params.supplierSettlement?.fundingMode ||
|
|
1953
|
+
(params.creditsMetered === 0 ? "byok" : "muxo_funded");
|
|
1954
|
+
const cents = params.status === "succeeded"
|
|
1955
|
+
? typeof params.supplierSettlement?.userRetailChargeCents === "number"
|
|
1956
|
+
? params.supplierSettlement.userRetailChargeCents
|
|
1957
|
+
: (params.creditsMetered || 0) * 1
|
|
1958
|
+
: 0;
|
|
1959
|
+
const costUsd = Number((cents / 100).toFixed(2));
|
|
1960
|
+
const creditsCharged = params.status === "succeeded" ? params.creditsMetered : 0;
|
|
1961
|
+
const costDisplay = params.status !== "succeeded"
|
|
1962
|
+
? `$0.00 USD (0 credits · Zero-charge failure protection)`
|
|
1963
|
+
: fundingMode === "byok"
|
|
1964
|
+
? `$0.00 USD (0 credits · Customer BYOK key)`
|
|
1965
|
+
: `$${costUsd.toFixed(2)} USD (${creditsCharged} credit${creditsCharged === 1 ? "" : "s"} · Muxo Master Wallet)`;
|
|
1966
|
+
const whatChanged = params.status === "succeeded"
|
|
1967
|
+
? params.riskLevel === "read"
|
|
1968
|
+
? `Retrieved verified data via ${params.toolSlug} from ${targetEntity} (no external mutation)`
|
|
1969
|
+
: `Completed governed ${params.riskLevel} action via ${params.toolSlug} on ${targetEntity}`
|
|
1970
|
+
: params.status === "cancelled"
|
|
1971
|
+
? `Cancelled ${params.toolSlug} on ${targetEntity} before completion (no changes persisted)`
|
|
1972
|
+
: `Attempted ${params.toolSlug} on ${targetEntity}, halted safely before completion`;
|
|
1973
|
+
const approver = params.approvedBy || "policy:auto";
|
|
1974
|
+
const ruleLabel = params.decisionRecord?.matchedRule || `ring_policy:${params.riskLevel}`;
|
|
1975
|
+
const whoAuthorized = approver === "policy:auto"
|
|
1976
|
+
? `Auto-authorized by Workspace Policy (${ruleLabel})`
|
|
1977
|
+
: `Human-approved by ${approver} (enforced via ${ruleLabel})`;
|
|
1978
|
+
const whatSucceeded = params.status === "succeeded"
|
|
1979
|
+
? `Action ${params.toolSlug} succeeded on ${targetEntity} and cryptographic receipt was sealed in the workspace Merkle audit chain.`
|
|
1980
|
+
: `Governance pre-flight and zero-charge wallet protection succeeded; external mutation did not complete.`;
|
|
1981
|
+
const whatRemainsUnresolved = params.status === "succeeded"
|
|
1982
|
+
? []
|
|
1983
|
+
: [
|
|
1984
|
+
params.error
|
|
1985
|
+
? `Resolve upstream error: ${params.error}`
|
|
1986
|
+
: `Inspect run state or retry via a fresh governed plan for ${params.toolSlug}`,
|
|
1987
|
+
];
|
|
1988
|
+
const reconciliationStatus = params.status === "succeeded"
|
|
1989
|
+
? "verified_complete"
|
|
1990
|
+
: params.status === "cancelled"
|
|
1991
|
+
? "cancelled"
|
|
1992
|
+
: "failed_zero_charge";
|
|
1993
|
+
return {
|
|
1994
|
+
whatChanged,
|
|
1995
|
+
whoAuthorized,
|
|
1996
|
+
whatSucceeded,
|
|
1997
|
+
whatRemainsUnresolved,
|
|
1998
|
+
costUsd,
|
|
1999
|
+
creditsCharged,
|
|
2000
|
+
fundingMode,
|
|
2001
|
+
costDisplay,
|
|
2002
|
+
reconciliationStatus,
|
|
2003
|
+
};
|
|
2004
|
+
}
|
|
2005
|
+
export function buildRunReconciliationReport(params) {
|
|
2006
|
+
const { run, plan, receipt } = params;
|
|
2007
|
+
const toolSlug = run?.toolSlug || plan?.toolSlug || "instant.web.search";
|
|
2008
|
+
const lane = run?.lane || plan?.lane || "composio_instant";
|
|
2009
|
+
const riskLevel = run?.riskLevel || plan?.riskLevel || "read";
|
|
2010
|
+
const creditsMetered = run?.creditsMetered ?? 0;
|
|
2011
|
+
const status = run?.status || "queued";
|
|
2012
|
+
const businessSummary = receipt?.businessSummary ||
|
|
2013
|
+
buildBusinessReceiptSummary({
|
|
2014
|
+
toolSlug,
|
|
2015
|
+
lane,
|
|
2016
|
+
riskLevel,
|
|
2017
|
+
status: status === "succeeded"
|
|
2018
|
+
? "succeeded"
|
|
2019
|
+
: status === "cancelled"
|
|
2020
|
+
? "cancelled"
|
|
2021
|
+
: "failed",
|
|
2022
|
+
creditsMetered,
|
|
2023
|
+
input: run?.input || plan?.input,
|
|
2024
|
+
output: run?.output,
|
|
2025
|
+
error: run?.error,
|
|
2026
|
+
approvedBy: plan?.approvedBy,
|
|
2027
|
+
actorId: run?.actorId || plan?.actorId,
|
|
2028
|
+
decisionRecord: receipt?.decisionRecord || plan?.decisionRecord || null,
|
|
2029
|
+
supplierSettlement: receipt?.supplierSettlement || plan?.supplierSettlement || null,
|
|
2030
|
+
});
|
|
2031
|
+
const receiptVerified = params.signatureValid !== undefined
|
|
2032
|
+
? Boolean(receipt && params.signatureValid)
|
|
2033
|
+
: Boolean(receipt && receipt.receiptHash && receipt.signature);
|
|
2034
|
+
const reconciliationStatus = status === "succeeded" && receiptVerified
|
|
2035
|
+
? "verified_complete"
|
|
2036
|
+
: status === "failed" && creditsMetered === 0
|
|
2037
|
+
? "failed_zero_charge"
|
|
2038
|
+
: status === "cancelled"
|
|
2039
|
+
? "cancelled"
|
|
2040
|
+
: "needs_reconciliation";
|
|
2041
|
+
return {
|
|
2042
|
+
ok: true,
|
|
2043
|
+
runId: run?.id || plan?.runId || "unexecuted",
|
|
2044
|
+
planId: run?.planId || plan?.id || "unknown",
|
|
2045
|
+
workspaceId: run?.workspaceId || plan?.workspaceId || "unknown",
|
|
2046
|
+
toolSlug,
|
|
2047
|
+
status,
|
|
2048
|
+
reconciliationStatus,
|
|
2049
|
+
executeOnceEnforced: Boolean((plan?.runId && run?.id && plan.runId === run.id) || run?.id || plan?.id),
|
|
2050
|
+
idempotentReplaySafe: true,
|
|
2051
|
+
zeroChargeOnFailureVerified: status === "succeeded" || creditsMetered === 0,
|
|
2052
|
+
creditsMetered,
|
|
2053
|
+
estimatedCostUsd: businessSummary.costUsd,
|
|
2054
|
+
receiptVerified,
|
|
2055
|
+
receiptId: receipt?.id || run?.receiptId || null,
|
|
2056
|
+
businessSummary,
|
|
2057
|
+
recommendedNextAction: reconciliationStatus === "verified_complete"
|
|
2058
|
+
? "No action required — execution and cryptographic receipt are verified complete."
|
|
2059
|
+
: reconciliationStatus === "failed_zero_charge"
|
|
2060
|
+
? "Zero credits were charged. Inspect error details and create a new plan if retry is desired."
|
|
2061
|
+
: !run && plan
|
|
2062
|
+
? `Plan '${plan.id}' (${plan.approvalStatus}) has not been executed yet; no credits charged.`
|
|
2063
|
+
: "Inspect upstream provider state or re-verify receipt chain.",
|
|
2064
|
+
};
|
|
2065
|
+
}
|