managed-deepagents 0.5.4-dev.2 → 0.5.4-dev.20
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 +76 -18
- package/dist/channels/manifest.d.ts +2 -0
- package/dist/channels/manifest.d.ts.map +1 -1
- package/dist/channels/slack/index.d.ts +25 -71
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +47 -115
- package/dist/channels/slack/index.js.map +1 -1
- package/dist/channels/trigger/client.d.ts +30 -0
- package/dist/channels/trigger/client.d.ts.map +1 -0
- package/dist/channels/trigger/client.js +118 -0
- package/dist/channels/trigger/client.js.map +1 -0
- package/dist/channels/trigger/http.d.ts +24 -0
- package/dist/channels/trigger/http.d.ts.map +1 -0
- package/dist/channels/trigger/http.js +138 -0
- package/dist/channels/trigger/http.js.map +1 -0
- package/dist/channels/trigger/types.d.ts +46 -0
- package/dist/channels/trigger/types.d.ts.map +1 -0
- package/dist/channels/trigger/types.js +28 -0
- package/dist/channels/trigger/types.js.map +1 -0
- package/dist/channels/trigger/uuid.d.ts +3 -0
- package/dist/channels/trigger/uuid.d.ts.map +1 -0
- package/dist/channels/trigger/uuid.js +22 -0
- package/dist/channels/trigger/uuid.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/ingress/index.d.ts +20 -0
- package/dist/ingress/index.d.ts.map +1 -1
- package/dist/ingress/index.js +44 -1
- package/dist/ingress/index.js.map +1 -1
- package/dist/namespaces.d.ts +8 -6
- package/dist/namespaces.d.ts.map +1 -1
- package/dist/namespaces.js +1 -1
- package/dist/namespaces.js.map +1 -1
- package/dist/runtime/auth.d.ts +3 -0
- package/dist/runtime/auth.d.ts.map +1 -1
- package/dist/runtime/auth.js +20 -10
- package/dist/runtime/auth.js.map +1 -1
- package/dist/runtime/backend.d.ts +0 -1
- package/dist/runtime/backend.d.ts.map +1 -1
- package/dist/runtime/backend.js +39 -8
- package/dist/runtime/backend.js.map +1 -1
- package/dist/runtime/channel.d.ts +5 -4
- package/dist/runtime/channel.d.ts.map +1 -1
- package/dist/runtime/channel.js.map +1 -1
- package/dist/runtime/identity-http.d.ts +3 -3
- package/dist/runtime/identity-http.d.ts.map +1 -1
- package/dist/runtime/identity-http.js +53 -12
- package/dist/runtime/identity-http.js.map +1 -1
- package/dist/runtime/index.d.ts.map +1 -1
- package/dist/runtime/index.js +1 -2
- package/dist/runtime/index.js.map +1 -1
- package/dist/runtime/sandbox-manager.d.ts +41 -45
- package/dist/runtime/sandbox-manager.d.ts.map +1 -1
- package/dist/runtime/sandbox-manager.js +143 -135
- package/dist/runtime/sandbox-manager.js.map +1 -1
- package/dist/runtime/sandbox-names.d.ts +9 -0
- package/dist/runtime/sandbox-names.d.ts.map +1 -0
- package/dist/runtime/sandbox-names.js +9 -0
- package/dist/runtime/sandbox-names.js.map +1 -0
- package/dist/runtime/types.d.ts +0 -5
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/sandbox.d.ts +61 -15
- package/dist/sandbox.d.ts.map +1 -1
- package/dist/sandbox.js +25 -7
- package/dist/sandbox.js.map +1 -1
- package/package.json +8 -7
- package/dist/runtime/sandbox-stream-retry.d.ts +0 -18
- package/dist/runtime/sandbox-stream-retry.d.ts.map +0 -1
- package/dist/runtime/sandbox-stream-retry.js +0 -90
- package/dist/runtime/sandbox-stream-retry.js.map +0 -1
- package/dist/runtime/setup-script.d.ts +0 -18
- package/dist/runtime/setup-script.d.ts.map +0 -1
- package/dist/runtime/setup-script.js +0 -49
- package/dist/runtime/setup-script.js.map +0 -1
package/README.md
CHANGED
|
@@ -45,26 +45,34 @@ per-platform optional dependencies, so install only downloads the binary for you
|
|
|
45
45
|
OS and CPU architecture. This npm-installed CLI scaffolds and compiles TypeScript
|
|
46
46
|
projects only and vendors the TypeScript runtime bundled with this package.
|
|
47
47
|
|
|
48
|
-
To start a new project, run `mda init
|
|
48
|
+
To start a new project, run `mda init`. In a terminal, the CLI asks you to name
|
|
49
|
+
the agent:
|
|
49
50
|
|
|
50
51
|
```bash
|
|
51
52
|
mda init
|
|
52
53
|
```
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
55
|
+
Run `mda init -i` to initialize your agent interactively and optionally hand it
|
|
56
|
+
off to a coding agent to build:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
mda init -i
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Choose a coding agent to continue in the new project, or select **View raw
|
|
63
|
+
prompt** to copy the setup instructions.
|
|
64
|
+
|
|
65
|
+
For coding agents and other headless use, pass the project name:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
mda init my-agent
|
|
69
|
+
```
|
|
59
70
|
|
|
60
71
|
`mda init` can shape the project up front — `--instructions "..."` (or
|
|
61
72
|
`--instructions-file <path>`) writes the system prompt, `--model <spec>` picks
|
|
62
73
|
the model, `--memory agent` opts into deployment-shared durable memory, and
|
|
63
74
|
`--no-sandbox` leaves out the sandbox. Every new project includes an
|
|
64
75
|
`identity.ts` that explicitly selects `auth.langsmithApiKey()` authentication.
|
|
65
|
-
Managed Deep Agent evals are Harbor tasks under `evals/tasks/`. Optionally create
|
|
66
|
-
a minimal source task under `evals/scaffold/` with `mda evals init <name>`, then
|
|
67
|
-
package the managed agent and scaffolded tasks with `mda evals compile`.
|
|
68
76
|
|
|
69
77
|
`mda init my-agent --gateway` runs the agent on
|
|
70
78
|
[LangSmith Gateway](https://docs.langchain.com/langsmith/gateway) — a model
|
|
@@ -72,6 +80,40 @@ LangSmith hosts, billed to your workspace's Gateway Credits, authenticated with
|
|
|
72
80
|
a LangSmith API key instead of a model provider key of your own. It is mutually
|
|
73
81
|
exclusive with `--model`, which names a provider you hold the key for.
|
|
74
82
|
|
|
83
|
+
## Evaluate
|
|
84
|
+
|
|
85
|
+
Managed Deep Agent evals run in Harbor. Install `uv` and Docker before running
|
|
86
|
+
them.
|
|
87
|
+
|
|
88
|
+
1. From the project root, initialize the eval workspace:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
mda evals init -i
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
2. Follow the coding-agent prompt to author tasks directly under
|
|
95
|
+
`evals/<task>/`. The CLI creates the user-owned `evals/harbor-job.json` once
|
|
96
|
+
and preserves later edits. `.mda/evals/` is generated.
|
|
97
|
+
A task may include an authored `evals/<task>/identity.json` fixture. It
|
|
98
|
+
requires a non-empty `user.id`; `user.kind`, `user.email`, and top-level
|
|
99
|
+
`groups`, `claims`, and `source.provider` are optional. Keep it with the
|
|
100
|
+
task, not in generated `.mda/evals/`.
|
|
101
|
+
3. Export `LANGSMITH_API_KEY`, `LANGSMITH_WORKSPACE_ID` when your credentials
|
|
102
|
+
require it, and the model or tool credential variables used by the agent.
|
|
103
|
+
4. From the same project root, run the pinned Harbor 0.21.0 command included at
|
|
104
|
+
the end of the coding-agent prompt. The command loads `MDAJobPlugin` and
|
|
105
|
+
`LangSmithPlugin`. It uses POSIX syntax on macOS/Linux and PowerShell on
|
|
106
|
+
native Windows.
|
|
107
|
+
5. From the same project root, inspect results:
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
uv run --python 3.12 --with 'harbor[langsmith]==0.21.0' harbor view .mda/evals/jobs
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
`MDAJobPlugin` compiles a fresh eval artifact at every Harbor job start.
|
|
114
|
+
This POC keeps MDA's custom Harbor adapter; migration to Harbor's built-in
|
|
115
|
+
LangGraph agent is deferred.
|
|
116
|
+
|
|
75
117
|
## Define an Agent
|
|
76
118
|
|
|
77
119
|
Create an `agent.ts` that exports a named `agent` definition:
|
|
@@ -173,14 +215,30 @@ out:
|
|
|
173
215
|
import { defineSandbox } from "managed-deepagents";
|
|
174
216
|
|
|
175
217
|
export const sandbox = defineSandbox({
|
|
176
|
-
scope: "thread",
|
|
177
218
|
idleTtlSeconds: 600,
|
|
178
219
|
});
|
|
179
220
|
```
|
|
180
221
|
|
|
181
|
-
If `sandbox/setup.sh` exists,
|
|
182
|
-
|
|
183
|
-
lifecycle.
|
|
222
|
+
If `sandbox/setup.sh` exists, `mda deploy` / `mda dev` bake it into a recipe
|
|
223
|
+
snapshot once; thread sandboxes clone that snapshot and do not re-run setup.
|
|
224
|
+
MDA owns sandbox naming, image/snapshot selection, reuse, and lifecycle.
|
|
225
|
+
|
|
226
|
+
Private published images can declare registry credentials by environment
|
|
227
|
+
variable name; MDA creates or updates the deployment-owned Host registry:
|
|
228
|
+
|
|
229
|
+
```ts
|
|
230
|
+
export const sandbox = defineSandbox({
|
|
231
|
+
dockerImage: "ghcr.io/acme/agent-base:1",
|
|
232
|
+
registry: {
|
|
233
|
+
url: "ghcr.io",
|
|
234
|
+
username: "octocat",
|
|
235
|
+
passwordEnv: "GHCR_TOKEN",
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Put `GHCR_TOKEN` in the project `.env` or process environment. Its value is
|
|
241
|
+
used only to reconcile the registry and never enters the build or snapshot.
|
|
184
242
|
|
|
185
243
|
## MCP Connectors
|
|
186
244
|
|
|
@@ -270,11 +328,11 @@ to skip the prompt in scripts. Agent memory and thread history are not
|
|
|
270
328
|
recoverable afterwards.
|
|
271
329
|
|
|
272
330
|
Sandboxes are matched by name: the runtime names each one
|
|
273
|
-
`{deployment}--{digest}
|
|
274
|
-
existing sandbox instead of stranding it.
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
331
|
+
`{deployment}--{digest}` of the thread id, which also lets a restarted
|
|
332
|
+
deployment re-adopt its existing sandbox instead of stranding it. Recipe changes
|
|
333
|
+
(`setup.sh` or bake base) produce a new deploy-time snapshot; live threads keep
|
|
334
|
+
their boxes until reclaim. Sandboxes created before this behavior existed are
|
|
335
|
+
unnamed and are left to
|
|
278
336
|
LangSmith's idle-stop and retention window.
|
|
279
337
|
|
|
280
338
|
Before deploying, make sure your model provider key such as `OPENAI_API_KEY`
|
|
@@ -20,6 +20,8 @@ export interface ChannelManifest {
|
|
|
20
20
|
name: string;
|
|
21
21
|
/** Adapter key used by the runtime registry. */
|
|
22
22
|
provider: string;
|
|
23
|
+
/** Optional provider-neutral ingress transport discriminator. */
|
|
24
|
+
readonly transport?: "trigger_server";
|
|
23
25
|
/** Whether the managed runner should auto-reply after invoke. */
|
|
24
26
|
autoReply: boolean;
|
|
25
27
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/channels/manifest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,2EAA2E;AAC3E,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,gEAAgE;IAChE,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,cAAc,EAAE,UAAU,CAAC;CAC5B"}
|
|
1
|
+
{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../src/channels/manifest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,2EAA2E;AAC3E,MAAM,MAAM,UAAU,GAAG;IAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,CAAC;AAE/D;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,QAAQ,CAAC,SAAS,CAAC,EAAE,gBAAgB,CAAC;IACtC,iEAAiE;IACjE,SAAS,EAAE,OAAO,CAAC;IACnB;;;OAGG;IACH,mBAAmB,EAAE,SAAS,MAAM,EAAE,CAAC;IACvC,gEAAgE;IAChE,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,sEAAsE;IACtE,cAAc,EAAE,UAAU,CAAC;CAC5B"}
|
|
@@ -1,57 +1,34 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `channels.slack` — Slack Events ingress, messaging, and deploy requirements.
|
|
3
|
-
*
|
|
4
|
-
* Files under `channels/` export a named `channel` created with
|
|
5
|
-
* `channels.slack(...)`.
|
|
6
|
-
*
|
|
7
|
-
* Event Subscriptions and OAuth scopes are configured on the developer's Slack
|
|
8
|
-
* app (api.slack.com/apps). This authoring surface only covers MDA runtime
|
|
9
|
-
* behavior that the Slack app manifest cannot express.
|
|
10
|
-
*/
|
|
1
|
+
/** Trigger Server-backed Slack channel authoring surface. */
|
|
11
2
|
import type { ChannelManifest } from "../manifest.js";
|
|
12
3
|
import { type Channel } from "../../runtime/channel.js";
|
|
13
4
|
export type { ChannelManifest } from "../manifest.js";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
* (Event Subscriptions); MDA accepts any of these when they arrive.
|
|
20
|
-
*/
|
|
21
|
-
export type SlackChannelTrigger = "app_mention" | "direct_message" | "thread_reply";
|
|
22
|
-
export type SlackMentionBehavior = "strip" | "preserve";
|
|
23
|
-
export type SlackConversationMapping = "thread" | "conversation" | "message";
|
|
24
|
-
export interface SlackChannelFilters {
|
|
25
|
-
includeConversations?: readonly string[];
|
|
26
|
-
excludeConversations?: readonly string[];
|
|
27
|
-
/** Fully-qualified mapped actor IDs such as `slack:T123:U456`. */
|
|
28
|
-
includeUsers?: readonly string[];
|
|
29
|
-
excludeUsers?: readonly string[];
|
|
30
|
-
/**
|
|
31
|
-
* Slack Connect shared conversations. Phase 1 rejects `true`.
|
|
32
|
-
* @default false
|
|
33
|
-
*/
|
|
34
|
-
allowSharedConversations?: boolean;
|
|
5
|
+
export interface SlackChannelConfig {
|
|
6
|
+
name: string;
|
|
7
|
+
description?: string;
|
|
8
|
+
triggerOnAllMessages?: boolean;
|
|
9
|
+
allowBotTriggers?: boolean;
|
|
35
10
|
}
|
|
36
|
-
export interface
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
/** @default "conversation" */
|
|
40
|
-
directMessage?: SlackConversationMapping;
|
|
11
|
+
export interface TriggerSlackAppConfig {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
41
14
|
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
export interface SlackChannelConfig {
|
|
47
|
-
/** @default true */
|
|
48
|
-
autoReply?: boolean;
|
|
49
|
-
/** @default "strip" */
|
|
50
|
-
mentionBehavior?: SlackMentionBehavior;
|
|
51
|
-
filters?: SlackChannelFilters;
|
|
52
|
-
conversation?: SlackConversationPolicy;
|
|
15
|
+
export interface RequiredTriggerSlackChannelConfig {
|
|
16
|
+
app: TriggerSlackAppConfig;
|
|
17
|
+
triggerOnAllMessages: boolean;
|
|
18
|
+
allowBotTriggers: boolean;
|
|
53
19
|
}
|
|
54
|
-
/**
|
|
20
|
+
/** Branded Trigger-backed Slack declaration. */
|
|
21
|
+
export type SlackChannel = Channel & RequiredTriggerSlackChannelConfig & {
|
|
22
|
+
kind: "slack";
|
|
23
|
+
transport: "trigger_server";
|
|
24
|
+
};
|
|
25
|
+
/** Declare a Slack channel whose ingress and callbacks use Trigger Server. */
|
|
26
|
+
export declare function slackChannel(config: SlackChannelConfig): SlackChannel;
|
|
27
|
+
/** Build deploy/runtime requirements for a file-derived channel instance. */
|
|
28
|
+
export declare function toSlackRequirements(name: string, definition: RequiredTriggerSlackChannelConfig | SlackChannel): ChannelManifest;
|
|
29
|
+
export type SlackChannelTrigger = "app_mention" | "direct_message" | "thread_reply";
|
|
30
|
+
export type SlackMentionBehavior = "strip" | "preserve";
|
|
31
|
+
export type SlackConversationMapping = "thread" | "conversation" | "message";
|
|
55
32
|
export interface RequiredSlackChannelConfig {
|
|
56
33
|
autoReply: boolean;
|
|
57
34
|
mentionBehavior: SlackMentionBehavior;
|
|
@@ -67,29 +44,6 @@ export interface RequiredSlackChannelConfig {
|
|
|
67
44
|
directMessage: SlackConversationMapping;
|
|
68
45
|
};
|
|
69
46
|
}
|
|
70
|
-
/** Branded Slack channel declaration. */
|
|
71
|
-
export type SlackChannel = Channel & RequiredSlackChannelConfig & {
|
|
72
|
-
kind: "slack";
|
|
73
|
-
};
|
|
74
|
-
/**
|
|
75
|
-
* Recommended bot token scopes for a BYO Slack app that handles Phase 1
|
|
76
|
-
* events (`app_mention`, DMs, and channel/group thread replies). Configure
|
|
77
|
-
* these under OAuth & Permissions on api.slack.com/apps — MDA does not
|
|
78
|
-
* provision the app.
|
|
79
|
-
*/
|
|
80
|
-
export declare const RECOMMENDED_SLACK_SCOPES: readonly ["app_mentions:read", "channels:history", "chat:write", "groups:history", "im:history"];
|
|
81
|
-
/**
|
|
82
|
-
* Declare a managed Slack channel. Files under `channels/*.ts` export a named
|
|
83
|
-
* `channel` created with `channels.slack(...)`.
|
|
84
|
-
*
|
|
85
|
-
* Subscribe to bot events and add OAuth scopes on your Slack app at
|
|
86
|
-
* api.slack.com/apps.
|
|
87
|
-
*/
|
|
88
|
-
export declare function slackChannel(config?: SlackChannelConfig): SlackChannel;
|
|
89
|
-
/** Recommended Slack OAuth scopes for a BYO app handling Phase 1 events. */
|
|
90
|
-
export declare function requiredSlackScopes(): string[];
|
|
91
|
-
/** Build deploy/runtime requirements for a file-derived channel name. */
|
|
92
|
-
export declare function toSlackRequirements(name: string, definition: RequiredSlackChannelConfig | SlackChannel): ChannelManifest;
|
|
93
47
|
export { decodeSlackEscaping, normalizeSlackEvent, verifySlackRequest, } from "./normalize.js";
|
|
94
48
|
export type { NormalizeSlackEventInput, NormalizeSlackEventResult, SlackInstallationContext, SlackSignatureHeaders, } from "./normalize.js";
|
|
95
49
|
export { createSlackWebApiTransport, setSlackAssistantStatus, DEFAULT_ASSISTANT_STATUS, DEFAULT_LOADING_MESSAGES, SLACK_API_BASE_ENV, } from "./transport.js";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,143 +1,75 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `channels.slack` — Slack Events ingress, messaging, and deploy requirements.
|
|
3
|
-
*
|
|
4
|
-
* Files under `channels/` export a named `channel` created with
|
|
5
|
-
* `channels.slack(...)`.
|
|
6
|
-
*
|
|
7
|
-
* Event Subscriptions and OAuth scopes are configured on the developer's Slack
|
|
8
|
-
* app (api.slack.com/apps). This authoring surface only covers MDA runtime
|
|
9
|
-
* behavior that the Slack app manifest cannot express.
|
|
10
|
-
*/
|
|
1
|
+
/** Trigger Server-backed Slack channel authoring surface. */
|
|
11
2
|
import { z } from "zod";
|
|
3
|
+
import { handleTriggerChannelEventRequest } from "../trigger/http.js";
|
|
12
4
|
import { CHANNEL_BRAND, } from "../../runtime/channel.js";
|
|
13
|
-
import { handleSlackEventsRequest } from "./http.js";
|
|
14
|
-
import { createSlackWebApiTransport } from "./transport.js";
|
|
15
|
-
/** Env vars deploy must ensure for Slack Events + auto-reply. */
|
|
16
|
-
export const SLACK_CHANNEL_REQUIRED_ENV = [
|
|
17
|
-
"SLACK_SIGNING_SECRET",
|
|
18
|
-
"SLACK_BOT_TOKEN",
|
|
19
|
-
];
|
|
20
|
-
/**
|
|
21
|
-
* Recommended bot token scopes for a BYO Slack app that handles Phase 1
|
|
22
|
-
* events (`app_mention`, DMs, and channel/group thread replies). Configure
|
|
23
|
-
* these under OAuth & Permissions on api.slack.com/apps — MDA does not
|
|
24
|
-
* provision the app.
|
|
25
|
-
*/
|
|
26
|
-
export const RECOMMENDED_SLACK_SCOPES = [
|
|
27
|
-
"app_mentions:read",
|
|
28
|
-
"channels:history",
|
|
29
|
-
"chat:write",
|
|
30
|
-
"groups:history",
|
|
31
|
-
"im:history",
|
|
32
|
-
];
|
|
33
|
-
/** Slack IDs and mapped actor IDs, e.g. `C123` or `slack:T123:U456`. */
|
|
34
|
-
const identifiers = z
|
|
35
|
-
.array(z
|
|
36
|
-
.string("must be a list of non-empty strings")
|
|
37
|
-
.refine((entry) => entry.trim().length > 0, "must be a list of non-empty strings"))
|
|
38
|
-
.optional();
|
|
39
|
-
const conversationMapping = z.enum(["thread", "conversation", "message"], {
|
|
40
|
-
error: 'must be "thread", "conversation", or "message"',
|
|
41
|
-
});
|
|
42
5
|
const slackChannelConfig = z
|
|
43
6
|
.object({
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
.
|
|
47
|
-
.
|
|
48
|
-
|
|
49
|
-
.object({
|
|
50
|
-
includeConversations: identifiers,
|
|
51
|
-
excludeConversations: identifiers,
|
|
52
|
-
includeUsers: identifiers,
|
|
53
|
-
excludeUsers: identifiers,
|
|
54
|
-
allowSharedConversations: z
|
|
55
|
-
.literal(false, { error: "is not supported in Phase 1" })
|
|
56
|
-
.default(false),
|
|
7
|
+
name: z
|
|
8
|
+
.string()
|
|
9
|
+
.min(1)
|
|
10
|
+
.refine((value) => [...value].length <= 35, {
|
|
11
|
+
message: "Must contain at most 35 characters",
|
|
57
12
|
})
|
|
58
|
-
.
|
|
59
|
-
|
|
60
|
-
.object({
|
|
61
|
-
appMention: conversationMapping.default("thread"),
|
|
62
|
-
directMessage: conversationMapping.default("conversation"),
|
|
13
|
+
.regex(/^[a-zA-Z0-9_.\- ]+$/, {
|
|
14
|
+
message: "Must contain only letters, numbers, spaces, underscores, dashes, and periods",
|
|
63
15
|
})
|
|
64
|
-
.
|
|
16
|
+
.refine((value) => !value.startsWith(" ") &&
|
|
17
|
+
!value.startsWith("-") &&
|
|
18
|
+
!value.endsWith(" ") &&
|
|
19
|
+
!value.endsWith("-"), { message: "Must not start or end with a space or dash" }),
|
|
20
|
+
description: z
|
|
21
|
+
.string()
|
|
22
|
+
.refine((value) => [...value].length <= 139, {
|
|
23
|
+
message: "Must contain at most 139 characters",
|
|
24
|
+
})
|
|
25
|
+
.default(""),
|
|
26
|
+
triggerOnAllMessages: z.boolean().default(false),
|
|
27
|
+
allowBotTriggers: z.boolean().default(false),
|
|
65
28
|
})
|
|
66
|
-
.strict()
|
|
67
|
-
.prefault({});
|
|
29
|
+
.strict();
|
|
68
30
|
function hide(target, key, value) {
|
|
69
31
|
Object.defineProperty(target, key, { value, enumerable: false });
|
|
70
32
|
}
|
|
71
|
-
/**
|
|
72
|
-
* Declare a managed Slack channel. Files under `channels/*.ts` export a named
|
|
73
|
-
* `channel` created with `channels.slack(...)`.
|
|
74
|
-
*
|
|
75
|
-
* Subscribe to bot events and add OAuth scopes on your Slack app at
|
|
76
|
-
* api.slack.com/apps.
|
|
77
|
-
*/
|
|
33
|
+
/** Declare a Slack channel whose ingress and callbacks use Trigger Server. */
|
|
78
34
|
export function slackChannel(config) {
|
|
79
|
-
const
|
|
80
|
-
if (
|
|
81
|
-
|
|
82
|
-
"under Event Subscriptions on your Slack app (api.slack.com/apps).");
|
|
83
|
-
}
|
|
84
|
-
const validate = slackChannelConfig["~standard"].validate;
|
|
85
|
-
const result = validate(config ?? {});
|
|
86
|
-
if (result instanceof Promise) {
|
|
87
|
-
throw new TypeError("channels.slack(...) needs a schema that validates synchronously");
|
|
88
|
-
}
|
|
89
|
-
if (result.issues) {
|
|
90
|
-
const message = result.issues
|
|
35
|
+
const result = slackChannelConfig.safeParse(config);
|
|
36
|
+
if (!result.success) {
|
|
37
|
+
const message = result.error.issues
|
|
91
38
|
.map((issue) => {
|
|
92
|
-
const path =
|
|
93
|
-
|
|
94
|
-
? segment.key
|
|
95
|
-
: segment))
|
|
96
|
-
.join(".");
|
|
97
|
-
return path.length > 0 ? `${path}: ${issue.message}` : issue.message;
|
|
39
|
+
const path = issue.path.join(".");
|
|
40
|
+
return path ? `${path}: ${issue.message}` : issue.message;
|
|
98
41
|
})
|
|
99
42
|
.join("; ");
|
|
100
43
|
throw new Error(`channels.slack(...) ${message}`);
|
|
101
44
|
}
|
|
102
|
-
const
|
|
103
|
-
const self = {
|
|
45
|
+
const { name, description, ...options } = result.data;
|
|
46
|
+
const self = {
|
|
47
|
+
kind: "slack",
|
|
48
|
+
transport: "trigger_server",
|
|
49
|
+
app: { name, description },
|
|
50
|
+
...options,
|
|
51
|
+
};
|
|
104
52
|
hide(self, CHANNEL_BRAND, true);
|
|
105
|
-
hide(self, "events", (ctx) =>
|
|
106
|
-
name: ctx.name,
|
|
107
|
-
config: {
|
|
108
|
-
autoReply: self.autoReply,
|
|
109
|
-
mentionBehavior: self.mentionBehavior,
|
|
110
|
-
filters: self.filters,
|
|
111
|
-
conversation: self.conversation,
|
|
112
|
-
},
|
|
113
|
-
rawBody: ctx.rawBody,
|
|
114
|
-
}));
|
|
115
|
-
hide(self, "messaging", (env) => {
|
|
116
|
-
const token = env.SLACK_BOT_TOKEN;
|
|
117
|
-
if (!token)
|
|
118
|
-
return undefined;
|
|
119
|
-
return createSlackWebApiTransport({ botToken: token });
|
|
120
|
-
});
|
|
53
|
+
hide(self, "events", (ctx) => handleTriggerChannelEventRequest(ctx.request, { rawBody: ctx.rawBody }));
|
|
121
54
|
hide(self, "requirements", (name) => toSlackRequirements(name, self));
|
|
122
55
|
return self;
|
|
123
56
|
}
|
|
124
|
-
/**
|
|
125
|
-
export function requiredSlackScopes() {
|
|
126
|
-
return [...RECOMMENDED_SLACK_SCOPES];
|
|
127
|
-
}
|
|
128
|
-
/** Build deploy/runtime requirements for a file-derived channel name. */
|
|
57
|
+
/** Build deploy/runtime requirements for a file-derived channel instance. */
|
|
129
58
|
export function toSlackRequirements(name, definition) {
|
|
130
|
-
const config = definition;
|
|
131
59
|
return {
|
|
132
60
|
name,
|
|
133
61
|
provider: "slack",
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
62
|
+
transport: "trigger_server",
|
|
63
|
+
autoReply: true,
|
|
64
|
+
requiredPermissions: [],
|
|
65
|
+
requiredEnv: [],
|
|
137
66
|
providerConfig: {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
67
|
+
app: {
|
|
68
|
+
name: definition.app.name,
|
|
69
|
+
description: definition.app.description,
|
|
70
|
+
},
|
|
71
|
+
triggerOnAllMessages: definition.triggerOnAllMessages,
|
|
72
|
+
allowBotTriggers: definition.allowBotTriggers,
|
|
141
73
|
},
|
|
142
74
|
};
|
|
143
75
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channels/slack/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/channels/slack/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { TriggerChannelActionRequest, TriggerChannelActionResponse, TriggerChannelRuntimeEventRequest, TriggerChannelRuntimeEventResponse } from "./types.js";
|
|
2
|
+
export declare const LANGSMITH_MDA_TRIGGER_SERVER_URL_ENV = "LANGSMITH_MDA_TRIGGER_SERVER_URL";
|
|
3
|
+
export declare const TRIGGER_HTTP_TIMEOUT_MS = 30000;
|
|
4
|
+
type TriggerClientOperation = "actions" | "events";
|
|
5
|
+
export interface TriggerClientLike {
|
|
6
|
+
postAction(channelId: string, body: TriggerChannelActionRequest): Promise<TriggerChannelActionResponse>;
|
|
7
|
+
postRuntimeEvent(channelId: string, body: TriggerChannelRuntimeEventRequest): Promise<TriggerChannelRuntimeEventResponse>;
|
|
8
|
+
}
|
|
9
|
+
export interface TriggerClientOptions {
|
|
10
|
+
userId?: string;
|
|
11
|
+
env?: NodeJS.ProcessEnv;
|
|
12
|
+
fetch?: typeof fetch;
|
|
13
|
+
timeoutMs?: number;
|
|
14
|
+
}
|
|
15
|
+
/** Fixed-message callback error safe for logs and diagnostics. */
|
|
16
|
+
export declare class TriggerClientError extends Error {
|
|
17
|
+
readonly operation: TriggerClientOperation;
|
|
18
|
+
readonly status?: number | undefined;
|
|
19
|
+
constructor(operation: TriggerClientOperation, status?: number | undefined);
|
|
20
|
+
}
|
|
21
|
+
/** Minimal Trigger Server client authenticated by the hosted server key. */
|
|
22
|
+
export declare class TriggerClient implements TriggerClientLike {
|
|
23
|
+
#private;
|
|
24
|
+
constructor(options?: TriggerClientOptions);
|
|
25
|
+
postAction(channelId: string, body: TriggerChannelActionRequest): Promise<TriggerChannelActionResponse>;
|
|
26
|
+
postRuntimeEvent(channelId: string, body: TriggerChannelRuntimeEventRequest): Promise<TriggerChannelRuntimeEventResponse>;
|
|
27
|
+
}
|
|
28
|
+
export declare function createTriggerClient(options?: TriggerClientOptions): TriggerClient | undefined;
|
|
29
|
+
export {};
|
|
30
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/channels/trigger/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,2BAA2B,EAC3B,4BAA4B,EAC5B,iCAAiC,EACjC,kCAAkC,EACnC,MAAM,YAAY,CAAC;AAGpB,eAAO,MAAM,oCAAoC,qCACb,CAAC;AACrC,eAAO,MAAM,uBAAuB,QAA2B,CAAC;AAEhE,KAAK,sBAAsB,GAAG,SAAS,GAAG,QAAQ,CAAC;AAEnD,MAAM,WAAW,iBAAiB;IAChC,UAAU,CACR,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,4BAA4B,CAAC,CAAC;IACzC,gBAAgB,CACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,kCAAkC,CAAC,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,KAAK,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,kEAAkE;AAClE,qBAAa,kBAAmB,SAAQ,KAAK;IAEzC,QAAQ,CAAC,SAAS,EAAE,sBAAsB;IAC1C,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM;IAF1B,YACW,SAAS,EAAE,sBAAsB,EACjC,MAAM,CAAC,EAAE,MAAM,YAAA,EAQzB;CACF;AAED,4EAA4E;AAC5E,qBAAa,aAAc,YAAW,iBAAiB;;IAOrD,YAAY,OAAO,GAAE,oBAAyB,EAW7C;IAEK,UAAU,CACd,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,2BAA2B,GAChC,OAAO,CAAC,4BAA4B,CAAC,CAMvC;IAEK,gBAAgB,CACpB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,iCAAiC,GACtC,OAAO,CAAC,kCAAkC,CAAC,CAM7C;CAoCF;AAED,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,oBAAyB,GACjC,aAAa,GAAG,SAAS,CAM3B"}
|