@opencomputer/blue 0.0.3 → 0.0.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/README.md CHANGED
@@ -14,6 +14,7 @@ control-plane contract:
14
14
  and hibernating WebSockets;
15
15
  - WorkOS device authentication for the hosted CLI;
16
16
  - a Blue model gateway that keeps the platform OpenRouter key server-side;
17
+ - managed remote Slack connections through Composio Connect Links and triggers;
17
18
  - sub-second content-addressed agent artifacts on a generic Lambda MicroVM
18
19
  runtime image;
19
20
  - an AccountDO registry for agents, immutable deployments, and aliases;
@@ -153,12 +154,40 @@ messages, and updates the status with reasoning and tool activity. The final
153
154
  reply clears the indicator automatically. Each Slack thread maps to one
154
155
  persistent local Blue session, with the mapping stored under `.blue/dev/`.
155
156
 
156
- The HTTP Events API remains available as a fallback. Set
157
+ The HTTP Events API remains available as a local fallback. Set
157
158
  `SLACK_SIGNING_SECRET` and `SLACK_BOT_TOKEN`, expose the webhook printed by
158
159
  `blue dev`, and configure it as the Slack app's Events API request URL.
159
160
 
160
- Deployed Slack delivery is not wired yet. The intended Events API route is
161
- agent-specific and owned by the hosted Blue service.
161
+ ### Remote Slack
162
+
163
+ Remote agents use Composio's managed Slack app. Slack credentials stay in
164
+ Composio; Blue stores only the connected-account and trigger IDs. First declare
165
+ Slack in the agent and deploy it:
166
+
167
+ ```bash
168
+ blue channels add slack
169
+ blue deploy
170
+ ```
171
+
172
+ `blue deploy` prints the agent's hosted landing page. Connect one Slack channel
173
+ using its Slack channel ID:
174
+
175
+ ```bash
176
+ blue channels connect slack --channel C0123456789
177
+ ```
178
+
179
+ The CLI opens a hosted Composio Connect Link. Complete Slack authorization,
180
+ invite the managed app to the selected channel when Slack requires it, then
181
+ send a message there. Each Slack thread maps to one persistent remote Blue
182
+ session. Blue resumes that session's MicroVM for later turns, posts the answer
183
+ in the same thread, and suspends the MicroVM after delivery.
184
+
185
+ Inspect and remove managed connections with:
186
+
187
+ ```bash
188
+ blue channels list
189
+ blue channels disconnect slack <connection-id>
190
+ ```
162
191
 
163
192
  ## Hosted Flow
164
193
 
@@ -183,8 +212,10 @@ boundary for agents, deployments, and sessions.
183
212
 
184
213
  `blue deploy` builds the immutable agent artifact locally, requests a
185
214
  platform-owned upload, uploads directly to the returned signed URL, and
186
- registers the deployment. Session create, resume, suspend, and terminate call
187
- the Blue runtime service. The user machine does not require AWS credentials.
215
+ registers the deployment. It also prints a public agent page with the exact CLI
216
+ and Slack interaction commands. Session create, resume, suspend, and terminate
217
+ call the Blue runtime service. The user machine does not require AWS
218
+ credentials.
188
219
 
189
220
  ### Service configuration
190
221
 
@@ -193,6 +224,8 @@ The hosted Worker requires:
193
224
  - `BLUE_WORKOS_CLIENT_ID` and optionally `BLUE_WORKOS_ISSUER` /
194
225
  `BLUE_WORKOS_JWKS_URL`;
195
226
  - `OPENROUTER_API_KEY` as a Worker secret;
227
+ - `COMPOSIO_API_KEY`, `COMPOSIO_SLACK_AUTH_CONFIG_ID`, and
228
+ `COMPOSIO_WEBHOOK_SECRET` as Worker secrets;
196
229
  - `BLUE_RUNTIME_IMAGE_ARN` and `BLUE_RUNTIME_IMAGE_VERSION`;
197
230
  - a `DEPLOYMENTS` service binding that returns signed platform artifact
198
231
  uploads;
@@ -211,8 +244,24 @@ npx wrangler secret put BLUE_RUNTIME_IMAGE_ARN \
211
244
  --config wrangler.production.jsonc
212
245
  npx wrangler secret put BLUE_RUNTIME_IMAGE_VERSION \
213
246
  --config wrangler.production.jsonc
247
+ npx wrangler secret put COMPOSIO_API_KEY \
248
+ --config wrangler.production.jsonc
249
+ npx wrangler secret put COMPOSIO_SLACK_AUTH_CONFIG_ID \
250
+ --config wrangler.production.jsonc
251
+ npx wrangler secret put COMPOSIO_WEBHOOK_SECRET \
252
+ --config wrangler.production.jsonc
214
253
  ```
215
254
 
255
+ Create one Composio webhook subscription for the project:
256
+
257
+ ```text
258
+ https://blue.opencomputer.dev/v1/webhooks/composio
259
+ ```
260
+
261
+ Enable `composio.trigger.message` and use the subscription's signing secret as
262
+ `COMPOSIO_WEBHOOK_SECRET`. Blue creates one
263
+ `SLACK_CHANNEL_MESSAGE_RECEIVED` trigger per connected agent/channel.
264
+
216
265
  Configure the platform Worker's AWS secrets plus
217
266
  `BLUE_AWS_REGION`, `BLUE_ARTIFACT_BUCKET`, `BLUE_EXECUTION_ROLE_ARN`,
218
267
  `BLUE_NETWORK_CONNECTOR_ARN`, `BLUE_S3_FILESYSTEM_ID`, and
@@ -291,11 +340,10 @@ delivery phases are in [PLAN.md](./PLAN.md).
291
340
 
292
341
  The standalone local control plane, WorkOS device login, token refresh,
293
342
  tenant-isolated Durable Object routing, signed-upload API, runtime lifecycle
294
- API, and authenticated OpenRouter proxy are implemented.
295
-
296
- The `DEPLOYMENTS` and `RUNTIMES` platform services still need to be deployed
297
- and bound before `blue deploy` and remote sessions work against
298
- `blue.opencomputer.dev`. Those services own AWS credentials, signed S3 uploads,
299
- Lambda MicroVM calls, and S3 Files access points. Versioned checkpoint
300
- replacement, deployed channels, permissions, evals, cleanup, and the web UI
301
- remain subsequent milestones.
343
+ API, authenticated OpenRouter proxy, deployed Slack routing, and local/remote
344
+ agent landing pages are implemented.
345
+
346
+ The platform services own AWS credentials, signed S3 uploads, Lambda MicroVM
347
+ calls, and S3 Files access points. Versioned checkpoint replacement,
348
+ permissions, evals, cleanup, and the unified management dashboard remain
349
+ subsequent milestones.
@@ -22,6 +22,7 @@ export interface BlueCredentials {
22
22
  updatedAt: string;
23
23
  }
24
24
  export declare function credentialsPath(): string;
25
+ export declare function openBrowser(url: string): void;
25
26
  export declare function readCredentials(): Promise<BlueCredentials | null>;
26
27
  export declare function logout(): Promise<boolean>;
27
28
  export declare function login(apiUrl?: string): Promise<BlueCredentials>;
@@ -39,7 +39,7 @@ async function readResponse(response) {
39
39
  }
40
40
  return body;
41
41
  }
42
- function openBrowser(url) {
42
+ export function openBrowser(url) {
43
43
  if (process.env.BLUE_NO_BROWSER === "1")
44
44
  return;
45
45
  const command = process.platform === "darwin"
@@ -1 +1 @@
1
- {"version":3,"file":"cli-auth.js","sourceRoot":"","sources":["../../src/auth/cli-auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli-auth.js","sourceRoot":"","sources":["../../src/auth/cli-auth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,32 @@
1
+ export interface ComposioConfiguration {
2
+ apiKey: string;
3
+ slackAuthConfigId: string;
4
+ webhookSecret: string;
5
+ }
6
+ export interface ComposioLink {
7
+ connectedAccountId: string;
8
+ redirectUrl: string;
9
+ }
10
+ export declare function composioUserId(accountId: string, connectionId: string): string;
11
+ export declare function parseComposioUserId(userId: string): {
12
+ accountId: string;
13
+ connectionId: string;
14
+ } | null;
15
+ export declare function createSlackLink(configuration: ComposioConfiguration, input: {
16
+ userId: string;
17
+ callbackUrl: string;
18
+ alias: string;
19
+ }): Promise<ComposioLink>;
20
+ export declare function createSlackTrigger(configuration: ComposioConfiguration, input: {
21
+ userId: string;
22
+ connectedAccountId: string;
23
+ channelId: string;
24
+ }): Promise<string>;
25
+ export declare function deleteSlackTrigger(configuration: ComposioConfiguration, triggerId: string): Promise<void>;
26
+ export declare function postSlackMessage(configuration: ComposioConfiguration, input: {
27
+ connectedAccountId: string;
28
+ channelId: string;
29
+ threadTimestamp: string;
30
+ text: string;
31
+ }): Promise<void>;
32
+ export declare function verifyComposioWebhook(payload: string, headers: Headers, secret: string, now?: number): Promise<boolean>;
@@ -0,0 +1,149 @@
1
+ import { isRecord } from "../protocol.js";
2
+ const COMPOSIO_API = "https://backend.composio.dev";
3
+ const SLACK_VERSION = "20260702_00";
4
+ function bytesToBase64(bytes) {
5
+ let binary = "";
6
+ for (const byte of bytes)
7
+ binary += String.fromCharCode(byte);
8
+ return btoa(binary);
9
+ }
10
+ function constantTimeEqual(left, right) {
11
+ const size = Math.max(left.length, right.length);
12
+ let difference = left.length ^ right.length;
13
+ for (let index = 0; index < size; index += 1) {
14
+ difference |=
15
+ (left.charCodeAt(index) || 0) ^ (right.charCodeAt(index) || 0);
16
+ }
17
+ return difference === 0;
18
+ }
19
+ async function request(configuration, path, init) {
20
+ const headers = new Headers(init.headers);
21
+ headers.set("content-type", "application/json");
22
+ headers.set("x-api-key", configuration.apiKey);
23
+ const response = await fetch(`${COMPOSIO_API}${path}`, {
24
+ ...init,
25
+ headers,
26
+ });
27
+ const body = await response.json().catch(() => null);
28
+ if (!response.ok) {
29
+ const error = isRecord(body) && isRecord(body.error) ? body.error : body;
30
+ const message = isRecord(error) && typeof error.message === "string"
31
+ ? error.message
32
+ : `Composio request failed with status ${String(response.status)}`;
33
+ throw new Error(message);
34
+ }
35
+ if (!isRecord(body))
36
+ throw new Error("Composio returned an invalid response");
37
+ return body;
38
+ }
39
+ export function composioUserId(accountId, connectionId) {
40
+ return `blue_${btoa(JSON.stringify({ accountId, connectionId }))
41
+ .replace(/\+/g, "-")
42
+ .replace(/\//g, "_")
43
+ .replace(/=+$/, "")}`;
44
+ }
45
+ export function parseComposioUserId(userId) {
46
+ if (!userId.startsWith("blue_"))
47
+ return null;
48
+ try {
49
+ const encoded = userId.slice(5).replace(/-/g, "+").replace(/_/g, "/");
50
+ const padded = encoded.padEnd(Math.ceil(encoded.length / 4) * 4, "=");
51
+ const parsed = JSON.parse(atob(padded));
52
+ return isRecord(parsed) &&
53
+ typeof parsed.accountId === "string" &&
54
+ typeof parsed.connectionId === "string"
55
+ ? {
56
+ accountId: parsed.accountId,
57
+ connectionId: parsed.connectionId,
58
+ }
59
+ : null;
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
65
+ export async function createSlackLink(configuration, input) {
66
+ const body = await request(configuration, "/api/v3/connected_accounts/link", {
67
+ method: "POST",
68
+ body: JSON.stringify({
69
+ auth_config_id: configuration.slackAuthConfigId,
70
+ user_id: input.userId,
71
+ callback_url: input.callbackUrl,
72
+ alias: input.alias,
73
+ }),
74
+ });
75
+ if (typeof body.connected_account_id !== "string" ||
76
+ typeof body.redirect_url !== "string") {
77
+ throw new Error("Composio did not return a Slack connection link");
78
+ }
79
+ return {
80
+ connectedAccountId: body.connected_account_id,
81
+ redirectUrl: body.redirect_url,
82
+ };
83
+ }
84
+ export async function createSlackTrigger(configuration, input) {
85
+ const body = await request(configuration, "/api/v3.1/trigger_instances/SLACK_CHANNEL_MESSAGE_RECEIVED/upsert", {
86
+ method: "POST",
87
+ body: JSON.stringify({
88
+ user_id: input.userId,
89
+ connected_account_id: input.connectedAccountId,
90
+ trigger_config: {
91
+ channel_id: input.channelId,
92
+ message_type: "all",
93
+ },
94
+ toolkit_versions: { slack: SLACK_VERSION },
95
+ }),
96
+ });
97
+ const triggerId = typeof body.trigger_id === "string"
98
+ ? body.trigger_id
99
+ : typeof body.id === "string"
100
+ ? body.id
101
+ : isRecord(body.trigger) && typeof body.trigger.id === "string"
102
+ ? body.trigger.id
103
+ : undefined;
104
+ if (!triggerId)
105
+ throw new Error("Composio did not return a trigger ID");
106
+ return triggerId;
107
+ }
108
+ export async function deleteSlackTrigger(configuration, triggerId) {
109
+ await request(configuration, `/api/v3.1/trigger_instances/manage/${encodeURIComponent(triggerId)}`, { method: "DELETE" });
110
+ }
111
+ export async function postSlackMessage(configuration, input) {
112
+ const body = await request(configuration, "/api/v3/tools/execute/SLACK_CHAT_POST_MESSAGE", {
113
+ method: "POST",
114
+ body: JSON.stringify({
115
+ connected_account_id: input.connectedAccountId,
116
+ version: SLACK_VERSION,
117
+ arguments: {
118
+ channel: input.channelId,
119
+ thread_ts: input.threadTimestamp,
120
+ text: input.text.slice(0, 35_000),
121
+ mrkdwn: true,
122
+ },
123
+ }),
124
+ });
125
+ if (body.successful === false) {
126
+ throw new Error(typeof body.error === "string"
127
+ ? body.error
128
+ : "Composio could not post the Slack reply");
129
+ }
130
+ }
131
+ export async function verifyComposioWebhook(payload, headers, secret, now = Date.now()) {
132
+ const webhookId = headers.get("webhook-id");
133
+ const timestamp = headers.get("webhook-timestamp");
134
+ const signatures = headers.get("webhook-signature");
135
+ if (!webhookId || !timestamp || !signatures)
136
+ return false;
137
+ const seconds = Number(timestamp);
138
+ if (!Number.isFinite(seconds) || Math.abs(now - seconds * 1_000) > 300_000) {
139
+ return false;
140
+ }
141
+ const key = await crypto.subtle.importKey("raw", new TextEncoder().encode(secret), { name: "HMAC", hash: "SHA-256" }, false, ["sign"]);
142
+ const signature = await crypto.subtle.sign("HMAC", key, new TextEncoder().encode(`${webhookId}.${timestamp}.${payload}`));
143
+ const expected = bytesToBase64(new Uint8Array(signature));
144
+ return signatures
145
+ .split(/\s+/)
146
+ .some((candidate) => candidate.startsWith("v1,") &&
147
+ constantTimeEqual(candidate.slice(3), expected));
148
+ }
149
+ //# sourceMappingURL=composio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"composio.js","sourceRoot":"","sources":["../../src/channels/composio.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from "node:child_process";
3
- import { mkdirSync } from "node:fs";
3
+ import { existsSync, mkdirSync } from "node:fs";
4
4
  import { basename, dirname, resolve } from "node:path";
5
5
  import process from "node:process";
6
6
  import { createInterface } from "node:readline/promises";
7
7
  import { fileURLToPath } from "node:url";
8
- import { DEFAULT_BLUE_API_URL, accessTokenFor, login, logout, readCredentials, } from "../auth/cli-auth.js";
8
+ import { DEFAULT_BLUE_API_URL, accessTokenFor, login, logout, openBrowser, readCredentials, } from "../auth/cli-auth.js";
9
9
  import { addSlackChannel, findAgentRoot, initializeAgent, prepareAgent, } from "../core/agent.js";
10
10
  import { buildAgentArtifact } from "../core/artifact.js";
11
11
  import { findDevState, requestDevManager, startDevManager, } from "../dev/manager.js";
12
12
  import { startLocalControlPlane } from "../dev/local-control-plane.js";
13
13
  import { authenticateOpenRouter, readOpenRouterCredential, } from "../openrouter/auth.js";
14
+ import { agentLandingPath } from "../landing/agent.js";
14
15
  import { BlueClient } from "../sdk/client.js";
15
16
  const DEFAULT_EDGE = DEFAULT_BLUE_API_URL;
16
17
  function argument(name) {
@@ -53,6 +54,9 @@ function hostedEdge() {
53
54
  process.env.BLUE_EDGE_URL ??
54
55
  DEFAULT_EDGE);
55
56
  }
57
+ function builtInSlackChannel(agentRoot) {
58
+ return ["slack.ts", "slack.js"].some((file) => existsSync(resolve(agentRoot, "agent", "channels", file)));
59
+ }
56
60
  function spawnRuntime(edge, sessionId, token, harness, directory) {
57
61
  const usingTypescript = import.meta.url.endsWith(".ts");
58
62
  const blueRuntimeDirectory = resolve(directory, ".blue");
@@ -507,14 +511,54 @@ async function deployAgent(edge) {
507
511
  const deployment = await client.registerDeployment({
508
512
  agentId: built.agentId,
509
513
  alias,
514
+ channels: built.channels,
510
515
  artifact: upload.artifact,
511
516
  });
517
+ const identity = await client.whoami();
518
+ const agentUrl = new URL(agentLandingPath(identity.accountId, deployment.agentId), edge).toString();
512
519
  process.stdout.write(`agent: ${deployment.agentId}\n` +
513
520
  `deployment: ${deployment.id}\n` +
514
521
  `alias: ${deployment.alias}\n` +
522
+ `url: ${agentUrl}\n` +
523
+ `channels: ${deployment.channels.join(", ") || "none"}\n` +
515
524
  `artifact: s3://${deployment.artifact.bucket}/${deployment.artifact.key}\n` +
516
525
  `ready in: ${String(built.elapsedMs)}ms\n`);
517
526
  }
527
+ async function connectRemoteSlack(edge) {
528
+ const channelId = argument("channel");
529
+ if (!channelId) {
530
+ throw new Error("A Slack channel ID is required with --channel");
531
+ }
532
+ const agentId = argument("agent") ?? (await inferDeployedAgent());
533
+ if (!agentId) {
534
+ throw new Error("Run this inside an agent repository or pass --agent");
535
+ }
536
+ const result = await (await clientFor(edge)).createSlackConnection({
537
+ agentId,
538
+ channelId,
539
+ });
540
+ process.stdout.write(`connection: ${result.connection.id}\n` +
541
+ `agent: ${result.connection.agentId}@${result.connection.alias}\n` +
542
+ `channel: ${result.connection.channelId}\n` +
543
+ `Open ${result.redirectUrl}\n`);
544
+ openBrowser(result.redirectUrl);
545
+ }
546
+ async function listRemoteChannels(edge) {
547
+ const connections = await (await clientFor(edge)).listChannelConnections();
548
+ if (connections.length === 0) {
549
+ process.stdout.write("No channel connections.\n");
550
+ return;
551
+ }
552
+ for (const connection of connections) {
553
+ process.stdout.write(`${connection.id} slack ${connection.status.padEnd(12)} ` +
554
+ `${connection.agentId}@${connection.alias} ${connection.channelId}\n`);
555
+ }
556
+ }
557
+ async function disconnectRemoteSlack(edge, connectionId) {
558
+ const connection = await (await clientFor(edge)).disconnectSlack(connectionId);
559
+ process.stdout.write(`disconnected: ${connection.id}\n` +
560
+ `agent: ${connection.agentId}@${connection.alias}\n`);
561
+ }
518
562
  function printSession(session) {
519
563
  const separator = session.deploymentId.lastIndexOf(":");
520
564
  const deployment = separator >= 0
@@ -590,6 +634,8 @@ async function dev() {
590
634
  "openrouter/anthropic/claude-sonnet-4.6";
591
635
  const local = await startLocalControlPlane({
592
636
  port,
637
+ agentId: prepared.name,
638
+ slackEnabled: builtInSlackChannel(prepared.root),
593
639
  statePath: resolve(prepared.root, ".blue", "dev", "control-plane.json"),
594
640
  openRouterApiKey: process.env.OPENROUTER_API_KEY,
595
641
  model: process.env.BLUE_MODEL,
@@ -637,6 +683,7 @@ async function demo() {
637
683
  ? Number.parseInt(requestedPort, 10)
638
684
  : undefined,
639
685
  statePath: resolve(".blue", "dev", "demo-control-plane.json"),
686
+ agentId: "demo",
640
687
  openRouterApiKey: process.env.OPENROUTER_API_KEY,
641
688
  model: argument("model") ??
642
689
  process.env.BLUE_MODEL ??
@@ -663,6 +710,9 @@ Usage:
663
710
  blue run <prompt> [--agent <agent>@<alias>]
664
711
  blue auth openrouter
665
712
  blue channels add slack [--agent-dir path]
713
+ blue channels connect slack --channel C0123456789 [--agent agent@alias]
714
+ blue channels list
715
+ blue channels disconnect slack <connection-id>
666
716
  blue deploy [--agent-dir path] [--alias production] [--edge URL]
667
717
  blue remote <prompt> [--edge URL] [--api-key key] [--keep]
668
718
  blue agents list
@@ -731,12 +781,24 @@ async function main() {
731
781
  return;
732
782
  }
733
783
  if (command === "channels") {
734
- const [action, channel] = positional(3);
735
- if (action !== "add" || channel !== "slack") {
736
- throw new Error("Use `blue channels add slack`");
784
+ const [action, channel, connectionId] = positional(3);
785
+ if (action === "add" && channel === "slack") {
786
+ process.stdout.write(`created: ${await addSlackChannel(argument("agent-dir") ?? process.cwd())}\n`);
787
+ return;
737
788
  }
738
- process.stdout.write(`created: ${await addSlackChannel(argument("agent-dir") ?? process.cwd())}\n`);
739
- return;
789
+ if (action === "connect" && channel === "slack") {
790
+ await connectRemoteSlack(hostedEdge());
791
+ return;
792
+ }
793
+ if (action === "list") {
794
+ await listRemoteChannels(hostedEdge());
795
+ return;
796
+ }
797
+ if (action === "disconnect" && channel === "slack" && connectionId) {
798
+ await disconnectRemoteSlack(hostedEdge(), connectionId);
799
+ return;
800
+ }
801
+ throw new Error("Use `blue channels add|connect|list|disconnect`");
740
802
  }
741
803
  if (command === "deploy") {
742
804
  await deployAgent(hostedEdge());