@muxoai/sdk 1.4.3 → 1.4.4
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 +15 -1
- package/dist/cli.js +167 -38
- package/dist/composio-catalog.d.ts +25 -0
- package/dist/composio-catalog.js +145 -0
- package/dist/config.d.ts +1 -0
- package/dist/config.js +1 -0
- package/dist/engine.d.ts +49 -5
- package/dist/engine.js +464 -26
- package/dist/mcp-schema.d.ts +14 -0
- package/dist/mcp-schema.js +65 -8
- package/dist/mcp.js +264 -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 +105 -2
- package/dist/skills-catalog.d.ts +66 -0
- package/dist/skills-catalog.js +801 -0
- package/dist/types.d.ts +32 -0
- package/dist/ui/console-html.js +23 -8
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
- package/plugins/muxo/.claude-plugin/plugin.json +1 -1
- package/plugins/muxo/.codex-plugin/plugin.json +2 -2
- package/plugins/muxo/.cursor-plugin/plugin.json +1 -1
- package/plugins/muxo/plugin.json +2 -2
- package/plugins/muxo/skills/muxo/SKILL.md +13 -3
package/dist/policy.js
CHANGED
|
@@ -1436,6 +1436,65 @@ export function buildLlmPolicyAndGovernanceBrief(policy = DEFAULT_WORKSPACE_POLI
|
|
|
1436
1436
|
prompt: "Remember our default GitHub repo is muxo-ai/muxo",
|
|
1437
1437
|
},
|
|
1438
1438
|
},
|
|
1439
|
+
{
|
|
1440
|
+
intent: "Run a turnkey or custom Temporal Saga playbook (or pass plain English in prompt)",
|
|
1441
|
+
mcpTool: "get_run_context",
|
|
1442
|
+
arguments: {
|
|
1443
|
+
action: "run_playbook",
|
|
1444
|
+
slug: "fullstack-cloud-bootstrap",
|
|
1445
|
+
prompt: "Run the fullstack cloud bootstrap playbook for acme",
|
|
1446
|
+
},
|
|
1447
|
+
},
|
|
1448
|
+
{
|
|
1449
|
+
intent: "Create a custom multi-step Saga playbook in plain English",
|
|
1450
|
+
mcpTool: "get_run_context",
|
|
1451
|
+
arguments: {
|
|
1452
|
+
action: "create_playbook",
|
|
1453
|
+
prompt: "Create playbook daily-growth-check that runs instant.seo.audit and app.slack.send_message",
|
|
1454
|
+
},
|
|
1455
|
+
},
|
|
1456
|
+
{
|
|
1457
|
+
intent: "Rollback or signal a Temporal workflow Saga in plain English",
|
|
1458
|
+
mcpTool: "get_run_context",
|
|
1459
|
+
arguments: {
|
|
1460
|
+
action: "rollback_workflow",
|
|
1461
|
+
workflow_id: "latest",
|
|
1462
|
+
prompt: "Rollback the latest workflow because staging healthcheck failed",
|
|
1463
|
+
},
|
|
1464
|
+
},
|
|
1465
|
+
{
|
|
1466
|
+
intent: "Time-travel or k-hop BFS traverse the Graphiti Bi-Temporal Knowledge Graph",
|
|
1467
|
+
mcpTool: "get_run_context",
|
|
1468
|
+
arguments: {
|
|
1469
|
+
action: "memory_graph",
|
|
1470
|
+
as_of: "2026-10-20T00:00:00Z",
|
|
1471
|
+
focal_entity: "workspace",
|
|
1472
|
+
max_hops: 2,
|
|
1473
|
+
},
|
|
1474
|
+
},
|
|
1475
|
+
{
|
|
1476
|
+
intent: "Compile or evaluate AWS Cedar 4.0 & OPA Rego v1 Policy-as-Code",
|
|
1477
|
+
mcpTool: "get_run_context",
|
|
1478
|
+
arguments: {
|
|
1479
|
+
action: "cedar_policy",
|
|
1480
|
+
tool_slug: "resource.turso.database",
|
|
1481
|
+
input: { query: "SELECT 1" },
|
|
1482
|
+
},
|
|
1483
|
+
},
|
|
1484
|
+
{
|
|
1485
|
+
intent: "Export OpenTelemetry GenAI 1.29.0 spans, Langfuse batch, or FinOps ROI",
|
|
1486
|
+
mcpTool: "get_run_context",
|
|
1487
|
+
arguments: { action: "roi_analytics" },
|
|
1488
|
+
},
|
|
1489
|
+
{
|
|
1490
|
+
intent: "One-shot configure a turnkey harness preset (startup-builder, strict-production, read-only-auditor, finops-byok-zero-cost)",
|
|
1491
|
+
mcpTool: "get_run_context",
|
|
1492
|
+
arguments: {
|
|
1493
|
+
action: "configure_harness",
|
|
1494
|
+
preset: "strict-production",
|
|
1495
|
+
harness: "claude-code",
|
|
1496
|
+
},
|
|
1497
|
+
},
|
|
1439
1498
|
],
|
|
1440
1499
|
};
|
|
1441
1500
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import vm from "node:vm";
|
|
2
2
|
import { Composio } from "@composio/core";
|
|
3
|
+
import { callComposioMcpGatewayRpc } from "../composio-catalog.js";
|
|
3
4
|
const INSTANT_TOOLS = [
|
|
4
5
|
{
|
|
5
6
|
slug: "instant.web.search",
|
|
@@ -1024,44 +1025,61 @@ export class ComposioInstantAdapter {
|
|
|
1024
1025
|
};
|
|
1025
1026
|
let evalResult = null;
|
|
1026
1027
|
let executionEngine = "cloudflare_sandbox_vm_isolate";
|
|
1027
|
-
|
|
1028
|
-
const
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
Boolean,
|
|
1037
|
-
RegExp,
|
|
1038
|
-
Map,
|
|
1039
|
-
Set,
|
|
1040
|
-
Buffer: {
|
|
1041
|
-
from: (str, enc) => Buffer.from(str, enc),
|
|
1042
|
-
},
|
|
1043
|
-
env: Object.freeze({ ...vaultBindings }),
|
|
1044
|
-
console: {
|
|
1045
|
-
log: (...args) => logs.push(redactSecrets(args.map((a) => String(a)).join(" "))),
|
|
1046
|
-
info: (...args) => logs.push(redactSecrets(args.map((a) => String(a)).join(" "))),
|
|
1047
|
-
},
|
|
1048
|
-
});
|
|
1049
|
-
const wrappedCode = code.includes("return ") && !code.trim().startsWith("(")
|
|
1050
|
-
? `(() => { ${code} })()`
|
|
1051
|
-
: code;
|
|
1052
|
-
const rawOut = vm.runInContext(wrappedCode, sandboxContext, {
|
|
1053
|
-
timeout: 1500,
|
|
1028
|
+
if (input.useRemoteWorkbench === true && this.config.composioApiKey) {
|
|
1029
|
+
const gwRes = await callComposioMcpGatewayRpc("COMPOSIO_REMOTE_WORKBENCH", {
|
|
1030
|
+
code_to_execute: code,
|
|
1031
|
+
thought: String(input.thought || "Muxo governed workbench execution"),
|
|
1032
|
+
}, {
|
|
1033
|
+
apiKey: this.config.composioApiKey,
|
|
1034
|
+
gatewayUrl: this.config.composioMcpGatewayUrl,
|
|
1035
|
+
isReadOnly: false,
|
|
1036
|
+
timeoutMs: 8000,
|
|
1054
1037
|
});
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
? JSON.parse(redactSecrets(JSON.stringify(rawOut)))
|
|
1060
|
-
: null;
|
|
1038
|
+
if (gwRes.ok && gwRes.data) {
|
|
1039
|
+
executionEngine = "composio_remote_workbench";
|
|
1040
|
+
evalResult = JSON.parse(redactSecrets(JSON.stringify(gwRes.data)));
|
|
1041
|
+
}
|
|
1061
1042
|
}
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1043
|
+
if (evalResult === null) {
|
|
1044
|
+
try {
|
|
1045
|
+
const sandboxContext = vm.createContext({
|
|
1046
|
+
Math,
|
|
1047
|
+
Date,
|
|
1048
|
+
JSON,
|
|
1049
|
+
Array,
|
|
1050
|
+
Object,
|
|
1051
|
+
String,
|
|
1052
|
+
Number,
|
|
1053
|
+
Boolean,
|
|
1054
|
+
RegExp,
|
|
1055
|
+
Map,
|
|
1056
|
+
Set,
|
|
1057
|
+
Buffer: {
|
|
1058
|
+
from: (str, enc) => Buffer.from(str, enc),
|
|
1059
|
+
},
|
|
1060
|
+
env: Object.freeze({ ...vaultBindings }),
|
|
1061
|
+
console: {
|
|
1062
|
+
log: (...args) => logs.push(redactSecrets(args.map((a) => String(a)).join(" "))),
|
|
1063
|
+
info: (...args) => logs.push(redactSecrets(args.map((a) => String(a)).join(" "))),
|
|
1064
|
+
},
|
|
1065
|
+
});
|
|
1066
|
+
const wrappedCode = code.includes("return ") && !code.trim().startsWith("(")
|
|
1067
|
+
? `(() => { ${code} })()`
|
|
1068
|
+
: code;
|
|
1069
|
+
const rawOut = vm.runInContext(wrappedCode, sandboxContext, {
|
|
1070
|
+
timeout: 1500,
|
|
1071
|
+
});
|
|
1072
|
+
evalResult =
|
|
1073
|
+
typeof rawOut === "string"
|
|
1074
|
+
? redactSecrets(rawOut)
|
|
1075
|
+
: rawOut !== undefined
|
|
1076
|
+
? JSON.parse(redactSecrets(JSON.stringify(rawOut)))
|
|
1077
|
+
: null;
|
|
1078
|
+
}
|
|
1079
|
+
catch (err) {
|
|
1080
|
+
executionEngine = "isolated_workbench_ast_guard";
|
|
1081
|
+
evalResult = redactSecrets(String(err?.message || "Completed expression analysis"));
|
|
1082
|
+
}
|
|
1065
1083
|
}
|
|
1066
1084
|
return {
|
|
1067
1085
|
provider: "composio_instant",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Composio } from "@composio/core";
|
|
2
2
|
import type { MuxoConfig } from "../config.js";
|
|
3
3
|
import type { MuxoTool, RiskLevel } from "../types.js";
|
|
4
|
-
import { parseComposioWebhookEnvelope, type ComposioToolkitMetadata, type ComposioTriggerEventRecord, type ComposioTriggerSubscription, type ComposioTriggerType, type ComposioWebhookEventType } from "../composio-catalog.js";
|
|
4
|
+
import { parseComposioWebhookEnvelope, type ComposioMcpGatewayMetaTool, type ComposioMcpGatewayResult, type ComposioToolkitMetadata, type ComposioTriggerEventRecord, type ComposioTriggerSubscription, type ComposioTriggerType, type ComposioWebhookEventType } from "../composio-catalog.js";
|
|
5
5
|
export type { ComposioToolkitMetadata, ComposioTriggerEventRecord, ComposioTriggerSubscription, ComposioTriggerType, ComposioWebhookEventType, };
|
|
6
6
|
export declare class ComposioSdkAdapter {
|
|
7
7
|
private readonly config;
|
|
@@ -16,12 +16,20 @@ export declare class ComposioSdkAdapter {
|
|
|
16
16
|
private get headers();
|
|
17
17
|
private getHeaders;
|
|
18
18
|
getComposioClient(composioApiKey?: string | null): Composio | null;
|
|
19
|
+
callComposioMcpGateway(metaTool: ComposioMcpGatewayMetaTool | string, toolArgs: Record<string, unknown>, options?: {
|
|
20
|
+
workspaceId?: string;
|
|
21
|
+
composioApiKey?: string | null;
|
|
22
|
+
gatewayUrl?: string | null;
|
|
23
|
+
isReadOnly?: boolean;
|
|
24
|
+
timeoutMs?: number;
|
|
25
|
+
}): Promise<ComposioMcpGatewayResult>;
|
|
19
26
|
getSdkInfo(composioApiKey?: string | null): {
|
|
20
27
|
sdkPackage: "@composio/core";
|
|
21
28
|
sdkVersion: string;
|
|
22
29
|
configured: boolean;
|
|
23
30
|
usingCustomerByok: boolean;
|
|
24
31
|
baseUrl: string;
|
|
32
|
+
mcpGatewayUrl: string;
|
|
25
33
|
curatedToolCount: number;
|
|
26
34
|
cachedToolCount: number;
|
|
27
35
|
capabilities: string[];
|
|
@@ -158,5 +166,6 @@ export declare class ComposioSdkAdapter {
|
|
|
158
166
|
input: Record<string, unknown>;
|
|
159
167
|
connectedAccountId?: string | null;
|
|
160
168
|
composioApiKey?: string | null;
|
|
169
|
+
mcpGatewayUrl?: string | null;
|
|
161
170
|
}): Promise<Record<string, unknown>>;
|
|
162
171
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Composio } from "@composio/core";
|
|
2
2
|
import { matchAppToolSlug } from "../mcp-schema.js";
|
|
3
|
-
import { composioAuthConfigScopes, COMPOSIO_V3_WEBHOOK_EVENTS, ensureOAuthCallbackParams, ENTERPRISE_TOOLKITS_CATALOG, filterComposioToolkits, getComposioTriggerType, getSampleActionSchema, isStripeProjectsExclusiveProvider, listComposioTriggerTypes, parseComposioWebhookEnvelope, verifyComposioWebhookSignature, wrapMuxoConnectUrl, } from "../composio-catalog.js";
|
|
3
|
+
import { callComposioMcpGatewayRpc, canUseComposioMcpGatewayForExecution, composioAuthConfigScopes, COMPOSIO_V3_WEBHOOK_EVENTS, ensureOAuthCallbackParams, ENTERPRISE_TOOLKITS_CATALOG, filterComposioToolkits, getComposioTriggerType, getSampleActionSchema, isStripeProjectsExclusiveProvider, listComposioTriggerTypes, parseComposioWebhookEnvelope, verifyComposioWebhookSignature, wrapMuxoConnectUrl, } from "../composio-catalog.js";
|
|
4
4
|
const CURATED_APP_TOOLS = [
|
|
5
5
|
{
|
|
6
6
|
slug: "app.github.list_repos",
|
|
@@ -468,6 +468,20 @@ export class ComposioSdkAdapter {
|
|
|
468
468
|
return null;
|
|
469
469
|
}
|
|
470
470
|
}
|
|
471
|
+
async callComposioMcpGateway(metaTool, toolArgs, options) {
|
|
472
|
+
const apiKey = this.resolveApiKey(options?.composioApiKey);
|
|
473
|
+
const gatewayUrl = options?.gatewayUrl ||
|
|
474
|
+
this.config.composioMcpGatewayUrl ||
|
|
475
|
+
"https://connect.composio.dev/mcp";
|
|
476
|
+
return callComposioMcpGatewayRpc(metaTool, toolArgs, {
|
|
477
|
+
apiKey,
|
|
478
|
+
gatewayUrl,
|
|
479
|
+
workspaceId: options?.workspaceId,
|
|
480
|
+
usingCustomerByok: Boolean(options?.composioApiKey && options.composioApiKey.trim()),
|
|
481
|
+
isReadOnly: options?.isReadOnly,
|
|
482
|
+
timeoutMs: options?.timeoutMs,
|
|
483
|
+
});
|
|
484
|
+
}
|
|
471
485
|
getSdkInfo(composioApiKey) {
|
|
472
486
|
const apiKey = this.resolveApiKey(composioApiKey);
|
|
473
487
|
return {
|
|
@@ -476,6 +490,7 @@ export class ComposioSdkAdapter {
|
|
|
476
490
|
configured: Boolean(apiKey),
|
|
477
491
|
usingCustomerByok: Boolean(composioApiKey && composioApiKey.trim()),
|
|
478
492
|
baseUrl: this.config.composioBaseUrl,
|
|
493
|
+
mcpGatewayUrl: this.config.composioMcpGatewayUrl || "https://connect.composio.dev/mcp",
|
|
479
494
|
curatedToolCount: CURATED_APP_TOOLS.length,
|
|
480
495
|
cachedToolCount: this.liveToolsCache.size,
|
|
481
496
|
capabilities: [
|
|
@@ -491,6 +506,11 @@ export class ComposioSdkAdapter {
|
|
|
491
506
|
"triggers.create",
|
|
492
507
|
"triggers.subscribe",
|
|
493
508
|
"triggers.verifyWebhook",
|
|
509
|
+
"mcpGateway.COMPOSIO_SEARCH_TOOLS",
|
|
510
|
+
"mcpGateway.COMPOSIO_GET_TOOL_SCHEMAS",
|
|
511
|
+
"mcpGateway.COMPOSIO_MANAGE_CONNECTIONS",
|
|
512
|
+
"mcpGateway.COMPOSIO_MULTI_EXECUTE_TOOL",
|
|
513
|
+
"mcpGateway.COMPOSIO_REMOTE_WORKBENCH",
|
|
494
514
|
],
|
|
495
515
|
};
|
|
496
516
|
}
|
|
@@ -901,6 +921,33 @@ export class ComposioSdkAdapter {
|
|
|
901
921
|
merged.set(tool.slug, tool);
|
|
902
922
|
}
|
|
903
923
|
}
|
|
924
|
+
if (merged.size === 0 &&
|
|
925
|
+
q &&
|
|
926
|
+
canUseComposioMcpGatewayForExecution({
|
|
927
|
+
apiKey,
|
|
928
|
+
gatewayUrl: this.config.composioMcpGatewayUrl,
|
|
929
|
+
usingCustomerByok: Boolean(composioApiKey),
|
|
930
|
+
isReadOnly: false,
|
|
931
|
+
})) {
|
|
932
|
+
const gwSearch = await this.callComposioMcpGateway("COMPOSIO_SEARCH_TOOLS", {
|
|
933
|
+
queries: [
|
|
934
|
+
{
|
|
935
|
+
use_case: tk ? `${tk}: ${q}` : q,
|
|
936
|
+
...(tk ? { known_fields: `toolkit:${tk}` } : {}),
|
|
937
|
+
},
|
|
938
|
+
],
|
|
939
|
+
session: { generate_id: true },
|
|
940
|
+
}, { composioApiKey, isReadOnly: true, timeoutMs: 3500 });
|
|
941
|
+
const gwTools = Array.isArray(gwSearch.data?.tools)
|
|
942
|
+
? gwSearch.data?.tools
|
|
943
|
+
: [];
|
|
944
|
+
for (const gwItem of gwTools) {
|
|
945
|
+
const tool = this.mapRawComposioItemToMuxoTool(gwItem);
|
|
946
|
+
if (tool && !merged.has(tool.slug)) {
|
|
947
|
+
merged.set(tool.slug, tool);
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
}
|
|
904
951
|
return Array.from(merged.values()).slice(0, limit);
|
|
905
952
|
}
|
|
906
953
|
catch {
|
|
@@ -935,7 +982,23 @@ export class ComposioSdkAdapter {
|
|
|
935
982
|
}
|
|
936
983
|
}
|
|
937
984
|
catch {
|
|
938
|
-
// Fall through to searchTools
|
|
985
|
+
// Fall through to MCP Gateway schema lookup / searchTools
|
|
986
|
+
}
|
|
987
|
+
}
|
|
988
|
+
if (canUseComposioMcpGatewayForExecution({
|
|
989
|
+
apiKey,
|
|
990
|
+
gatewayUrl: this.config.composioMcpGatewayUrl,
|
|
991
|
+
usingCustomerByok: Boolean(composioApiKey),
|
|
992
|
+
isReadOnly: false,
|
|
993
|
+
})) {
|
|
994
|
+
const gwSchema = await this.callComposioMcpGateway("COMPOSIO_GET_TOOL_SCHEMAS", { tool_slugs: [upstreamCandidate] }, { composioApiKey, isReadOnly: true, timeoutMs: 3000 });
|
|
995
|
+
const schemaList = Array.isArray(gwSchema.data?.tools)
|
|
996
|
+
? gwSchema.data?.tools
|
|
997
|
+
: [];
|
|
998
|
+
if (schemaList[0]) {
|
|
999
|
+
const mapped = this.mapRawComposioItemToMuxoTool(schemaList[0]);
|
|
1000
|
+
if (mapped)
|
|
1001
|
+
return mapped;
|
|
939
1002
|
}
|
|
940
1003
|
}
|
|
941
1004
|
}
|
|
@@ -1331,10 +1394,57 @@ export class ComposioSdkAdapter {
|
|
|
1331
1394
|
if (!effectiveApiKey) {
|
|
1332
1395
|
return buildConnectedAccountFallback();
|
|
1333
1396
|
}
|
|
1334
|
-
|
|
1335
|
-
const
|
|
1397
|
+
const isReadOnly = params.tool.riskLevel === "read";
|
|
1398
|
+
const gatewayUrl = params.mcpGatewayUrl ||
|
|
1399
|
+
this.config.composioMcpGatewayUrl ||
|
|
1400
|
+
"https://connect.composio.dev/mcp";
|
|
1401
|
+
const preferMcpGateway = Boolean(params.mcpGatewayUrl) ||
|
|
1402
|
+
effectiveApiKey.startsWith("ck_") ||
|
|
1403
|
+
gatewayUrl.includes("mcp.composio.dev/t/");
|
|
1404
|
+
let writeTierAttempted = false;
|
|
1405
|
+
// Tier 1: Upstream Composio MCP Gateway (when BYOK consumer/team gateway is configured, or read-only)
|
|
1406
|
+
if (preferMcpGateway &&
|
|
1407
|
+
canUseComposioMcpGatewayForExecution({
|
|
1408
|
+
apiKey: effectiveApiKey,
|
|
1409
|
+
gatewayUrl,
|
|
1410
|
+
usingCustomerByok: Boolean(params.composioApiKey),
|
|
1411
|
+
isReadOnly,
|
|
1412
|
+
})) {
|
|
1413
|
+
if (!isReadOnly)
|
|
1414
|
+
writeTierAttempted = true;
|
|
1415
|
+
const gwExec = await this.callComposioMcpGateway("COMPOSIO_MULTI_EXECUTE_TOOL", {
|
|
1416
|
+
tools: [
|
|
1417
|
+
{
|
|
1418
|
+
tool_slug: params.tool.upstreamSlug,
|
|
1419
|
+
arguments: params.input,
|
|
1420
|
+
},
|
|
1421
|
+
],
|
|
1422
|
+
sync_response_to_workbench: false,
|
|
1423
|
+
}, {
|
|
1424
|
+
workspaceId: params.workspaceId,
|
|
1425
|
+
composioApiKey: params.composioApiKey,
|
|
1426
|
+
gatewayUrl,
|
|
1427
|
+
isReadOnly,
|
|
1428
|
+
timeoutMs: 20000,
|
|
1429
|
+
});
|
|
1430
|
+
if (gwExec.ok && gwExec.data) {
|
|
1431
|
+
return {
|
|
1432
|
+
provider: "composio_sdk",
|
|
1433
|
+
sdk: "composio_mcp_gateway",
|
|
1434
|
+
gatewayUrl: gwExec.gatewayUrl,
|
|
1435
|
+
tool: params.tool.slug,
|
|
1436
|
+
upstreamTool: params.tool.upstreamSlug,
|
|
1437
|
+
connectedAccountId: params.connectedAccountId,
|
|
1438
|
+
data: gwExec.data,
|
|
1439
|
+
};
|
|
1440
|
+
}
|
|
1441
|
+
}
|
|
1442
|
+
// Tier 2: Official @composio/core SDK tool execution (skip if a non-idempotent write was already attempted)
|
|
1443
|
+
const sdk = !writeTierAttempted ? this.getComposioClient(params.composioApiKey) : null;
|
|
1336
1444
|
if (sdk) {
|
|
1337
1445
|
try {
|
|
1446
|
+
if (!isReadOnly)
|
|
1447
|
+
writeTierAttempted = true;
|
|
1338
1448
|
const sdkExec = await Promise.race([
|
|
1339
1449
|
sdk.tools.execute(params.tool.upstreamSlug, {
|
|
1340
1450
|
userId: params.workspaceId,
|
|
@@ -1359,36 +1469,39 @@ export class ComposioSdkAdapter {
|
|
|
1359
1469
|
}
|
|
1360
1470
|
}
|
|
1361
1471
|
catch {
|
|
1362
|
-
//
|
|
1472
|
+
// Only fall through to REST v3 for read-only calls; never double-submit writes
|
|
1363
1473
|
}
|
|
1364
1474
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1475
|
+
// Tier 3: Composio v3 REST API (skip if a non-idempotent write was already attempted in Tier 1/2)
|
|
1476
|
+
if (!writeTierAttempted) {
|
|
1477
|
+
const body = {
|
|
1478
|
+
user_id: params.workspaceId,
|
|
1479
|
+
arguments: params.input,
|
|
1480
|
+
};
|
|
1481
|
+
if (params.connectedAccountId && params.connectedAccountId.startsWith("ca_")) {
|
|
1482
|
+
body.connected_account_id = params.connectedAccountId;
|
|
1483
|
+
}
|
|
1484
|
+
try {
|
|
1485
|
+
const res = await fetch(`${this.config.composioBaseUrl}/tools/execute/${encodeURIComponent(params.tool.upstreamSlug)}`, {
|
|
1486
|
+
method: "POST",
|
|
1487
|
+
headers: this.getHeaders(params.composioApiKey),
|
|
1488
|
+
body: JSON.stringify(body),
|
|
1489
|
+
signal: AbortSignal.timeout(25000),
|
|
1490
|
+
});
|
|
1491
|
+
const payload = (await res.json().catch(() => ({})));
|
|
1492
|
+
if (res.ok && !payload.error && payload.successful !== false) {
|
|
1493
|
+
return {
|
|
1494
|
+
provider: "composio_sdk",
|
|
1495
|
+
tool: params.tool.slug,
|
|
1496
|
+
upstreamTool: params.tool.upstreamSlug,
|
|
1497
|
+
connectedAccountId: params.connectedAccountId,
|
|
1498
|
+
data: payload.data ?? payload,
|
|
1499
|
+
};
|
|
1500
|
+
}
|
|
1501
|
+
}
|
|
1502
|
+
catch {
|
|
1503
|
+
// Fall through to connected account execution result when callback handoff was completed via Muxo /oauth/callback
|
|
1388
1504
|
}
|
|
1389
|
-
}
|
|
1390
|
-
catch {
|
|
1391
|
-
// Fall through to connected account execution result when callback handoff was completed via Muxo /oauth/callback
|
|
1392
1505
|
}
|
|
1393
1506
|
return buildConnectedAccountFallback();
|
|
1394
1507
|
}
|
package/dist/sdk.d.ts
CHANGED
|
@@ -246,6 +246,7 @@ export declare class MuxoClient {
|
|
|
246
246
|
run: ExecutionRun;
|
|
247
247
|
receipt: ExecutionReceipt;
|
|
248
248
|
}>;
|
|
249
|
+
reconcileRun(runOrPlanId: string): Promise<Record<string, unknown>>;
|
|
249
250
|
exec(toolSlug: string, input?: Record<string, unknown>, options?: {
|
|
250
251
|
reason?: string;
|
|
251
252
|
approve?: boolean;
|
|
@@ -969,6 +970,24 @@ export declare class MuxoClient {
|
|
|
969
970
|
}): Promise<Record<string, unknown>>;
|
|
970
971
|
getOtelTraces(limit?: number): Promise<Record<string, unknown>>;
|
|
971
972
|
listPlaybooks(): Promise<Record<string, unknown>>;
|
|
973
|
+
createPlaybook(params: {
|
|
974
|
+
prompt?: string;
|
|
975
|
+
slug?: string;
|
|
976
|
+
name?: string;
|
|
977
|
+
steps?: Array<string | Record<string, unknown>>;
|
|
978
|
+
[key: string]: unknown;
|
|
979
|
+
}): Promise<Record<string, unknown>>;
|
|
972
980
|
runPlaybook(slug: string, input?: Record<string, unknown>): Promise<Record<string, unknown>>;
|
|
981
|
+
configureHarness(params?: {
|
|
982
|
+
preset?: string;
|
|
983
|
+
harness?: string;
|
|
984
|
+
prompt?: string;
|
|
985
|
+
}): Promise<Record<string, unknown>>;
|
|
973
986
|
getRoiAnalytics(): Promise<Record<string, unknown>>;
|
|
987
|
+
listSkills(filter?: {
|
|
988
|
+
category?: string;
|
|
989
|
+
provider?: string;
|
|
990
|
+
query?: string;
|
|
991
|
+
}): Promise<Record<string, unknown>>;
|
|
992
|
+
getSkill(slug: string): Promise<Record<string, unknown>>;
|
|
974
993
|
}
|
package/dist/sdk.js
CHANGED
|
@@ -189,6 +189,9 @@ export class MuxoClient {
|
|
|
189
189
|
body: reason ? { reason } : {},
|
|
190
190
|
});
|
|
191
191
|
}
|
|
192
|
+
async reconcileRun(runOrPlanId) {
|
|
193
|
+
return this.request(`/api/v1/runs/${encodeURIComponent(runOrPlanId)}/reconcile`);
|
|
194
|
+
}
|
|
192
195
|
async exec(toolSlug, input = {}, options = {}) {
|
|
193
196
|
const planned = await this.planAction({
|
|
194
197
|
toolSlug,
|
|
@@ -787,13 +790,42 @@ export class MuxoClient {
|
|
|
787
790
|
async listPlaybooks() {
|
|
788
791
|
return this.request("/api/v1/playbooks");
|
|
789
792
|
}
|
|
793
|
+
async createPlaybook(params) {
|
|
794
|
+
return this.request("/api/v1/playbooks", {
|
|
795
|
+
method: "POST",
|
|
796
|
+
body: params,
|
|
797
|
+
});
|
|
798
|
+
}
|
|
790
799
|
async runPlaybook(slug, input) {
|
|
791
800
|
return this.request(`/api/v1/playbooks/${encodeURIComponent(slug)}/run`, {
|
|
792
801
|
method: "POST",
|
|
793
802
|
body: { input: input || {} },
|
|
794
803
|
});
|
|
795
804
|
}
|
|
805
|
+
async configureHarness(params) {
|
|
806
|
+
if (!params || Object.keys(params).length === 0) {
|
|
807
|
+
return this.request("/api/v1/harness/configure");
|
|
808
|
+
}
|
|
809
|
+
return this.request("/api/v1/harness/configure", {
|
|
810
|
+
method: "POST",
|
|
811
|
+
body: params,
|
|
812
|
+
});
|
|
813
|
+
}
|
|
796
814
|
async getRoiAnalytics() {
|
|
797
815
|
return this.request("/api/v1/analytics/roi");
|
|
798
816
|
}
|
|
817
|
+
async listSkills(filter) {
|
|
818
|
+
const qs = new URLSearchParams();
|
|
819
|
+
if (filter?.category)
|
|
820
|
+
qs.set("category", filter.category);
|
|
821
|
+
if (filter?.provider)
|
|
822
|
+
qs.set("provider", filter.provider);
|
|
823
|
+
if (filter?.query)
|
|
824
|
+
qs.set("q", filter.query);
|
|
825
|
+
const suffix = qs.toString() ? `?${qs.toString()}` : "";
|
|
826
|
+
return this.request(`/api/v1/skills${suffix}`);
|
|
827
|
+
}
|
|
828
|
+
async getSkill(slug) {
|
|
829
|
+
return this.request(`/api/v1/skills/${encodeURIComponent(slug)}`);
|
|
830
|
+
}
|
|
799
831
|
}
|