@orgloop/connector-openclaw 0.1.8 → 0.1.10
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 +19 -2
- package/dist/target.d.ts +15 -0
- package/dist/target.d.ts.map +1 -1
- package/dist/target.js +116 -9
- package/dist/target.js.map +1 -1
- package/package.json +2 -2
- package/dist/__tests__/detector.test.d.ts +0 -2
- package/dist/__tests__/detector.test.d.ts.map +0 -1
- package/dist/__tests__/detector.test.js +0 -62
- package/dist/__tests__/detector.test.js.map +0 -1
- package/dist/__tests__/target.test.d.ts +0 -2
- package/dist/__tests__/target.test.d.ts.map +0 -1
- package/dist/__tests__/target.test.js +0 -161
- package/dist/__tests__/target.test.js.map +0 -1
- package/dist/__tests__/validator.test.d.ts +0 -2
- package/dist/__tests__/validator.test.d.ts.map +0 -1
- package/dist/__tests__/validator.test.js +0 -72
- package/dist/__tests__/validator.test.js.map +0 -1
package/README.md
CHANGED
|
@@ -20,6 +20,7 @@ actors:
|
|
|
20
20
|
auth_token_env: "${OPENCLAW_TOKEN}" # optional — bearer token (env var ref)
|
|
21
21
|
default_channel: "engineering" # optional — default delivery channel
|
|
22
22
|
default_to: "team-lead" # optional — default recipient
|
|
23
|
+
lane: "main" # optional — OpenClaw lane for concurrency control
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
### Config options
|
|
@@ -31,6 +32,7 @@ actors:
|
|
|
31
32
|
| `auth_token_env` | `string` | no | — | Bearer token for auth. Supports `${ENV_VAR}` syntax |
|
|
32
33
|
| `default_channel` | `string` | no | — | Default channel for message delivery |
|
|
33
34
|
| `default_to` | `string` | no | — | Default recipient for message delivery |
|
|
35
|
+
| `lane` | `string` | no | — | OpenClaw lane for concurrency control. Can be overridden per-route. |
|
|
34
36
|
|
|
35
37
|
## Events accepted
|
|
36
38
|
|
|
@@ -48,7 +50,8 @@ The connector builds a message string from the event and sends it as:
|
|
|
48
50
|
"wakeMode": "now",
|
|
49
51
|
"deliver": true,
|
|
50
52
|
"channel": "engineering",
|
|
51
|
-
"to": "team-lead"
|
|
53
|
+
"to": "team-lead",
|
|
54
|
+
"lane": "main"
|
|
52
55
|
}
|
|
53
56
|
```
|
|
54
57
|
|
|
@@ -58,11 +61,25 @@ These fields can be set in the route's `then.config`:
|
|
|
58
61
|
|
|
59
62
|
| Field | Type | Default | Description |
|
|
60
63
|
|-------|------|---------|-------------|
|
|
61
|
-
| `session_key` | `string` | `orgloop:<source>:<type>` | OpenClaw session key |
|
|
64
|
+
| `session_key` | `string` | `orgloop:<source>:<type>` | OpenClaw session key. Supports `{{field}}` interpolation (e.g., `orgloop:github:pr:{{payload.pr_number}}`). |
|
|
65
|
+
| `thread_id` | `string` | — | Conversation thread grouping key. Supports `{{field}}` interpolation (e.g., `pr-{{payload.pr_number}}`). |
|
|
62
66
|
| `wake_mode` | `string` | `"now"` | When to wake the agent (`"now"`, etc.) |
|
|
63
67
|
| `deliver` | `boolean` | `false` | Whether to deliver the message to a channel |
|
|
68
|
+
| `channel` | `string` | — | Override the actor's `default_channel` for this route |
|
|
69
|
+
| `to` | `string` | — | Override the actor's `default_to` for this route |
|
|
70
|
+
| `lane` | `string` | — | Override the actor's `lane` for this route. Controls OpenClaw concurrency. |
|
|
64
71
|
| `launch_prompt` | `string` | — | Resolved from route's `with.prompt_file`; appended to the message |
|
|
65
72
|
|
|
73
|
+
### Template interpolation
|
|
74
|
+
|
|
75
|
+
The `session_key` and `thread_id` fields support `{{double-brace}}` interpolation from event fields. Supported paths include `payload.*`, `provenance.*`, and top-level event fields (`source`, `type`). Missing values resolve to `"unknown"`.
|
|
76
|
+
|
|
77
|
+
### Callback-first delivery
|
|
78
|
+
|
|
79
|
+
When an event's payload contains callback metadata (`payload.meta.openclaw_callback_session_key` or `payload.session.meta.openclaw_callback_session_key`), the connector delivers to that callback session first, using the callback's `agent_id` if present. If callback delivery fails, it falls back to normal routing.
|
|
80
|
+
|
|
81
|
+
This enables chained agent supervision: a supervisor dispatches work to a sub-agent, and the sub-agent's completion event automatically routes back to the originating supervisor session.
|
|
82
|
+
|
|
66
83
|
## Example route
|
|
67
84
|
|
|
68
85
|
```yaml
|
package/dist/target.d.ts
CHANGED
|
@@ -9,8 +9,23 @@ export declare class OpenClawTarget implements ActorConnector {
|
|
|
9
9
|
private agentId?;
|
|
10
10
|
private defaultChannel?;
|
|
11
11
|
private defaultTo?;
|
|
12
|
+
private lane?;
|
|
13
|
+
private httpAgent;
|
|
14
|
+
private fetch;
|
|
12
15
|
init(config: ActorConfig): Promise<void>;
|
|
13
16
|
deliver(event: OrgLoopEvent, routeConfig: RouteDeliveryConfig): Promise<DeliveryResult>;
|
|
17
|
+
/**
|
|
18
|
+
* Extract callback session key from event payload metadata.
|
|
19
|
+
* Checks: payload.meta.openclaw_callback_session_key, then payload.session.meta.openclaw_callback_session_key
|
|
20
|
+
*/
|
|
21
|
+
private resolveCallbackSessionKey;
|
|
22
|
+
/**
|
|
23
|
+
* Extract callback agent id from event payload metadata.
|
|
24
|
+
* Checks: payload.meta.openclaw_callback_agent_id, then payload.session.meta.openclaw_callback_agent_id
|
|
25
|
+
*/
|
|
26
|
+
private resolveCallbackAgentId;
|
|
27
|
+
private resolveCallbackField;
|
|
28
|
+
private postToAgent;
|
|
14
29
|
shutdown(): Promise<void>;
|
|
15
30
|
/**
|
|
16
31
|
* Build the message string for OpenClaw from an OrgLoop event.
|
package/dist/target.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACX,WAAW,EACX,cAAc,EACd,cAAc,
|
|
1
|
+
{"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACX,WAAW,EACX,cAAc,EACd,cAAc,EAEd,YAAY,EACZ,mBAAmB,EACnB,MAAM,cAAc,CAAC;AA0DtB,qBAAa,cAAe,YAAW,cAAc;IACpD,QAAQ,CAAC,EAAE,cAAc;IACzB,OAAO,CAAC,OAAO,CAA4B;IAC3C,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,OAAO,CAAC,CAAS;IACzB,OAAO,CAAC,cAAc,CAAC,CAAS;IAChC,OAAO,CAAC,SAAS,CAAC,CAAS;IAC3B,OAAO,CAAC,IAAI,CAAC,CAAS;IACtB,OAAO,CAAC,SAAS,CAA0B;IAC3C,OAAO,CAAC,KAAK,CAA6C;IAEpD,IAAI,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAgBxC,OAAO,CAAC,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,mBAAmB,GAAG,OAAO,CAAC,cAAc,CAAC;IAyD7F;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAIjC;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAI9B,OAAO,CAAC,oBAAoB;YAiBd,WAAW;IA6CnB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;IAO/B;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY;CAwCpB"}
|
package/dist/target.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenClaw actor (target) connector — delivers events to OpenClaw agent via HTTP webhook.
|
|
3
3
|
*/
|
|
4
|
+
import { closeHttpAgent, createFetchWithKeepAlive, createHttpAgent } from '@orgloop/sdk';
|
|
4
5
|
/** Resolve env var references like ${OPENCLAW_AUTH_TOKEN} */
|
|
5
6
|
function resolveEnvVar(value) {
|
|
6
7
|
const match = value.match(/^\$\{(.+)\}$/);
|
|
@@ -13,6 +14,39 @@ function resolveEnvVar(value) {
|
|
|
13
14
|
}
|
|
14
15
|
return value;
|
|
15
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a dot-path (e.g. "payload.pr_number") against a nested object.
|
|
19
|
+
* Returns undefined if any segment is missing.
|
|
20
|
+
*/
|
|
21
|
+
function resolvePath(obj, path) {
|
|
22
|
+
let current = obj;
|
|
23
|
+
for (const segment of path.split('.')) {
|
|
24
|
+
if (current == null || typeof current !== 'object')
|
|
25
|
+
return undefined;
|
|
26
|
+
current = current[segment];
|
|
27
|
+
}
|
|
28
|
+
return current;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Interpolate `{{dot.path}}` placeholders in a template string using event fields.
|
|
32
|
+
*
|
|
33
|
+
* Uses double-brace syntax to avoid collision with OrgLoop's `${...}` env var
|
|
34
|
+
* substitution in YAML config. Paths are resolved against the full event object:
|
|
35
|
+
* top-level fields, provenance.*, and payload.* are all reachable.
|
|
36
|
+
* Unresolved placeholders are replaced with "unknown" to keep session keys stable.
|
|
37
|
+
*
|
|
38
|
+
* Examples:
|
|
39
|
+
* "orgloop:pr-review:{{payload.pr_number}}" → "orgloop:pr-review:42"
|
|
40
|
+
* "orgloop:{{source}}:{{provenance.author}}" → "orgloop:github:alice"
|
|
41
|
+
*/
|
|
42
|
+
function interpolateTemplate(template, event) {
|
|
43
|
+
return template.replace(/\{\{([^}]+)\}\}/g, (_match, path) => {
|
|
44
|
+
const value = resolvePath(event, path.trim());
|
|
45
|
+
if (value === undefined || value === null)
|
|
46
|
+
return 'unknown';
|
|
47
|
+
return String(value);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
16
50
|
export class OpenClawTarget {
|
|
17
51
|
id = 'openclaw';
|
|
18
52
|
baseUrl = 'http://127.0.0.1:18789';
|
|
@@ -20,27 +54,98 @@ export class OpenClawTarget {
|
|
|
20
54
|
agentId;
|
|
21
55
|
defaultChannel;
|
|
22
56
|
defaultTo;
|
|
57
|
+
lane;
|
|
58
|
+
httpAgent = null;
|
|
59
|
+
fetch = globalThis.fetch;
|
|
23
60
|
async init(config) {
|
|
24
61
|
const cfg = config.config;
|
|
25
62
|
this.baseUrl = cfg.base_url ?? 'http://127.0.0.1:18789';
|
|
26
63
|
this.agentId = cfg.agent_id;
|
|
27
64
|
this.defaultChannel = cfg.default_channel;
|
|
28
65
|
this.defaultTo = cfg.default_to;
|
|
66
|
+
this.lane = cfg.lane;
|
|
29
67
|
if (cfg.auth_token_env) {
|
|
30
68
|
this.authToken = resolveEnvVar(cfg.auth_token_env);
|
|
31
69
|
}
|
|
70
|
+
this.httpAgent = createHttpAgent();
|
|
71
|
+
this.fetch = createFetchWithKeepAlive(this.httpAgent);
|
|
32
72
|
}
|
|
33
73
|
async deliver(event, routeConfig) {
|
|
34
74
|
const url = `${this.baseUrl}/hooks/agent`;
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
75
|
+
const rawSessionKey = routeConfig.session_key ?? `orgloop:${event.source}:${event.type}`;
|
|
76
|
+
const normalSessionKey = interpolateTemplate(rawSessionKey, event);
|
|
77
|
+
const message = this.buildMessage(event, routeConfig);
|
|
78
|
+
// #66 — Dynamic threadId from route config
|
|
79
|
+
const rawThreadId = routeConfig.thread_id;
|
|
80
|
+
const threadId = rawThreadId ? interpolateTemplate(rawThreadId, event) : undefined;
|
|
81
|
+
// #140 — Lane support: route config overrides connector-level default
|
|
82
|
+
const lane = routeConfig.lane ?? this.lane;
|
|
83
|
+
// #91 — Callback-first delivery: check event payload for callback metadata
|
|
84
|
+
const callbackSessionKey = this.resolveCallbackSessionKey(event);
|
|
85
|
+
const callbackAgentId = this.resolveCallbackAgentId(event);
|
|
86
|
+
if (callbackSessionKey) {
|
|
87
|
+
const callbackResult = await this.postToAgent(url, {
|
|
88
|
+
message,
|
|
89
|
+
sessionKey: callbackSessionKey,
|
|
90
|
+
agentId: callbackAgentId ?? this.agentId,
|
|
91
|
+
wakeMode: routeConfig.wake_mode ?? 'now',
|
|
92
|
+
deliver: routeConfig.deliver ?? false,
|
|
93
|
+
channel: routeConfig.channel ?? this.defaultChannel,
|
|
94
|
+
to: routeConfig.to ?? this.defaultTo,
|
|
95
|
+
...(lane !== undefined ? { lane } : {}),
|
|
96
|
+
...(threadId !== undefined ? { threadId } : {}),
|
|
97
|
+
...(routeConfig.model ? { model: routeConfig.model } : {}),
|
|
98
|
+
...(routeConfig.thinking ? { thinking: routeConfig.thinking } : {}),
|
|
99
|
+
...(routeConfig.timeout_seconds ? { timeoutSeconds: routeConfig.timeout_seconds } : {}),
|
|
100
|
+
});
|
|
101
|
+
if (callbackResult.status === 'delivered') {
|
|
102
|
+
return callbackResult;
|
|
103
|
+
}
|
|
104
|
+
// Callback delivery failed — fall back to normal delivery
|
|
105
|
+
}
|
|
106
|
+
return this.postToAgent(url, {
|
|
107
|
+
message,
|
|
108
|
+
sessionKey: normalSessionKey,
|
|
38
109
|
agentId: this.agentId,
|
|
39
110
|
wakeMode: routeConfig.wake_mode ?? 'now',
|
|
40
111
|
deliver: routeConfig.deliver ?? false,
|
|
41
|
-
channel: this.defaultChannel,
|
|
42
|
-
to: this.defaultTo,
|
|
43
|
-
|
|
112
|
+
channel: routeConfig.channel ?? this.defaultChannel,
|
|
113
|
+
to: routeConfig.to ?? this.defaultTo,
|
|
114
|
+
...(lane !== undefined ? { lane } : {}),
|
|
115
|
+
...(threadId !== undefined ? { threadId } : {}),
|
|
116
|
+
...(routeConfig.model ? { model: routeConfig.model } : {}),
|
|
117
|
+
...(routeConfig.thinking ? { thinking: routeConfig.thinking } : {}),
|
|
118
|
+
...(routeConfig.timeout_seconds ? { timeoutSeconds: routeConfig.timeout_seconds } : {}),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Extract callback session key from event payload metadata.
|
|
123
|
+
* Checks: payload.meta.openclaw_callback_session_key, then payload.session.meta.openclaw_callback_session_key
|
|
124
|
+
*/
|
|
125
|
+
resolveCallbackSessionKey(event) {
|
|
126
|
+
return this.resolveCallbackField(event, 'openclaw_callback_session_key');
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* Extract callback agent id from event payload metadata.
|
|
130
|
+
* Checks: payload.meta.openclaw_callback_agent_id, then payload.session.meta.openclaw_callback_agent_id
|
|
131
|
+
*/
|
|
132
|
+
resolveCallbackAgentId(event) {
|
|
133
|
+
return this.resolveCallbackField(event, 'openclaw_callback_agent_id');
|
|
134
|
+
}
|
|
135
|
+
resolveCallbackField(event, field) {
|
|
136
|
+
const payload = event.payload;
|
|
137
|
+
const meta = payload.meta;
|
|
138
|
+
if (meta?.[field] && typeof meta[field] === 'string') {
|
|
139
|
+
return meta[field];
|
|
140
|
+
}
|
|
141
|
+
const session = payload.session;
|
|
142
|
+
const sessionMeta = session?.meta;
|
|
143
|
+
if (sessionMeta?.[field] && typeof sessionMeta[field] === 'string') {
|
|
144
|
+
return sessionMeta[field];
|
|
145
|
+
}
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
async postToAgent(url, body) {
|
|
44
149
|
const headers = {
|
|
45
150
|
'Content-Type': 'application/json',
|
|
46
151
|
};
|
|
@@ -48,7 +153,7 @@ export class OpenClawTarget {
|
|
|
48
153
|
headers.Authorization = `Bearer ${this.authToken}`;
|
|
49
154
|
}
|
|
50
155
|
try {
|
|
51
|
-
const response = await fetch(url, {
|
|
156
|
+
const response = await this.fetch(url, {
|
|
52
157
|
method: 'POST',
|
|
53
158
|
headers,
|
|
54
159
|
body: JSON.stringify(body),
|
|
@@ -57,7 +162,6 @@ export class OpenClawTarget {
|
|
|
57
162
|
return { status: 'delivered' };
|
|
58
163
|
}
|
|
59
164
|
if (response.status === 429) {
|
|
60
|
-
// Rate limited — treat as error for retry
|
|
61
165
|
return {
|
|
62
166
|
status: 'error',
|
|
63
167
|
error: new Error('OpenClaw rate limited (429)'),
|
|
@@ -82,7 +186,10 @@ export class OpenClawTarget {
|
|
|
82
186
|
}
|
|
83
187
|
}
|
|
84
188
|
async shutdown() {
|
|
85
|
-
|
|
189
|
+
if (this.httpAgent) {
|
|
190
|
+
await closeHttpAgent(this.httpAgent);
|
|
191
|
+
this.httpAgent = null;
|
|
192
|
+
}
|
|
86
193
|
}
|
|
87
194
|
/**
|
|
88
195
|
* Build the message string for OpenClaw from an OrgLoop event.
|
package/dist/target.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;GAEG;AAUH,6DAA6D;AAC7D,SAAS,aAAa,CAAC,KAAa;IACnC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC1C,IAAI,KAAK,EAAE,CAAC;QACX,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACvC,IAAI,CAAC,QAAQ,EAAE,CAAC;YACf,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,KAAK,CAAC;AACd,CAAC;
|
|
1
|
+
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orgloop/connector-openclaw",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.10",
|
|
4
4
|
"description": "OrgLoop OpenClaw connector — webhook target for agent waking",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@orgloop/sdk": "0.
|
|
9
|
+
"@orgloop/sdk": "0.7.5"
|
|
10
10
|
},
|
|
11
11
|
"orgloop": {
|
|
12
12
|
"type": "connector",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detector.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/detector.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { OpenClawServiceDetector } from '../detector.js';
|
|
3
|
-
describe('OpenClawServiceDetector', () => {
|
|
4
|
-
let detector;
|
|
5
|
-
let fetchMock;
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
detector = new OpenClawServiceDetector('http://localhost:18789');
|
|
8
|
-
fetchMock = vi.fn();
|
|
9
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
10
|
-
});
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
vi.restoreAllMocks();
|
|
13
|
-
});
|
|
14
|
-
it('returns running when service responds', async () => {
|
|
15
|
-
fetchMock.mockResolvedValueOnce({
|
|
16
|
-
ok: true,
|
|
17
|
-
status: 200,
|
|
18
|
-
headers: new Headers({ server: 'openclaw/1.2.3' }),
|
|
19
|
-
});
|
|
20
|
-
const result = await detector.detect();
|
|
21
|
-
expect(result.running).toBe(true);
|
|
22
|
-
expect(result.endpoint).toBe('http://localhost:18789');
|
|
23
|
-
expect(result.details?.status).toBe(200);
|
|
24
|
-
expect(result.details?.server).toBe('openclaw/1.2.3');
|
|
25
|
-
});
|
|
26
|
-
it('returns running even on 404 (service is there)', async () => {
|
|
27
|
-
fetchMock.mockResolvedValueOnce({
|
|
28
|
-
ok: false,
|
|
29
|
-
status: 404,
|
|
30
|
-
headers: new Headers({}),
|
|
31
|
-
});
|
|
32
|
-
const result = await detector.detect();
|
|
33
|
-
expect(result.running).toBe(true);
|
|
34
|
-
expect(result.details?.status).toBe(404);
|
|
35
|
-
});
|
|
36
|
-
it('returns not running on connection refused', async () => {
|
|
37
|
-
fetchMock.mockRejectedValueOnce(new Error('connect ECONNREFUSED 127.0.0.1:18789'));
|
|
38
|
-
const result = await detector.detect();
|
|
39
|
-
expect(result.running).toBe(false);
|
|
40
|
-
expect(result.endpoint).toBe('http://localhost:18789');
|
|
41
|
-
expect(result.details?.error).toContain('ECONNREFUSED');
|
|
42
|
-
});
|
|
43
|
-
it('returns not running on timeout', async () => {
|
|
44
|
-
const abortError = new DOMException('The operation was aborted', 'AbortError');
|
|
45
|
-
fetchMock.mockRejectedValueOnce(abortError);
|
|
46
|
-
const result = await detector.detect();
|
|
47
|
-
expect(result.running).toBe(false);
|
|
48
|
-
expect(result.details?.error).toContain('timed out');
|
|
49
|
-
});
|
|
50
|
-
it('uses default base URL', () => {
|
|
51
|
-
const defaultDetector = new OpenClawServiceDetector();
|
|
52
|
-
// The constructor sets the URL; we verify by calling detect
|
|
53
|
-
fetchMock.mockResolvedValueOnce({
|
|
54
|
-
ok: true,
|
|
55
|
-
status: 200,
|
|
56
|
-
headers: new Headers({}),
|
|
57
|
-
});
|
|
58
|
-
defaultDetector.detect();
|
|
59
|
-
expect(fetchMock).toHaveBeenCalledWith('http://127.0.0.1:18789', expect.anything());
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
//# sourceMappingURL=detector.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"detector.test.js","sourceRoot":"","sources":["../../src/__tests__/detector.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"target.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/target.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
import { createTestEvent } from '@orgloop/sdk';
|
|
2
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
3
|
-
import { OpenClawTarget } from '../target.js';
|
|
4
|
-
describe('OpenClawTarget', () => {
|
|
5
|
-
let target;
|
|
6
|
-
let fetchMock;
|
|
7
|
-
beforeEach(async () => {
|
|
8
|
-
target = new OpenClawTarget();
|
|
9
|
-
await target.init({
|
|
10
|
-
id: 'openclaw-engineering-agent',
|
|
11
|
-
connector: '@orgloop/connector-openclaw',
|
|
12
|
-
config: {
|
|
13
|
-
base_url: 'http://localhost:18789',
|
|
14
|
-
agent_id: 'test-agent',
|
|
15
|
-
},
|
|
16
|
-
});
|
|
17
|
-
fetchMock = vi.fn().mockResolvedValue({
|
|
18
|
-
ok: true,
|
|
19
|
-
status: 200,
|
|
20
|
-
statusText: 'OK',
|
|
21
|
-
});
|
|
22
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
23
|
-
});
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
vi.restoreAllMocks();
|
|
26
|
-
});
|
|
27
|
-
it('sends correct OpenClaw payload shape', async () => {
|
|
28
|
-
const event = createTestEvent({
|
|
29
|
-
source: 'github',
|
|
30
|
-
type: 'resource.changed',
|
|
31
|
-
provenance: {
|
|
32
|
-
platform: 'github',
|
|
33
|
-
platform_event: 'pull_request.review_submitted',
|
|
34
|
-
author: 'alice',
|
|
35
|
-
author_type: 'team_member',
|
|
36
|
-
},
|
|
37
|
-
payload: { pr_number: 42 },
|
|
38
|
-
});
|
|
39
|
-
const routeConfig = {
|
|
40
|
-
session_key: 'hook:github:pr-review:engineering',
|
|
41
|
-
wake_mode: 'now',
|
|
42
|
-
deliver: true,
|
|
43
|
-
launch_prompt: 'Review this PR',
|
|
44
|
-
};
|
|
45
|
-
const result = await target.deliver(event, routeConfig);
|
|
46
|
-
expect(result.status).toBe('delivered');
|
|
47
|
-
expect(fetchMock).toHaveBeenCalledOnce();
|
|
48
|
-
const [url, opts] = fetchMock.mock.calls[0];
|
|
49
|
-
expect(url).toBe('http://localhost:18789/hooks/agent');
|
|
50
|
-
const body = JSON.parse(opts.body);
|
|
51
|
-
// Assert correct fields present
|
|
52
|
-
expect(body).toHaveProperty('message');
|
|
53
|
-
expect(body).toHaveProperty('sessionKey', 'hook:github:pr-review:engineering');
|
|
54
|
-
expect(body).toHaveProperty('agentId', 'test-agent');
|
|
55
|
-
expect(body).toHaveProperty('wakeMode', 'now');
|
|
56
|
-
expect(body).toHaveProperty('deliver', true);
|
|
57
|
-
// Assert old fields are NOT present
|
|
58
|
-
expect(body).not.toHaveProperty('event');
|
|
59
|
-
expect(body).not.toHaveProperty('launch_prompt');
|
|
60
|
-
expect(body).not.toHaveProperty('agent_id');
|
|
61
|
-
// Assert message contains event context and payload values
|
|
62
|
-
expect(body.message).toContain('github');
|
|
63
|
-
expect(body.message).toContain('resource.changed');
|
|
64
|
-
expect(body.message).toContain('Review this PR');
|
|
65
|
-
expect(body.message).toContain('pr_number: 42');
|
|
66
|
-
expect(body.message).toContain('Instructions:');
|
|
67
|
-
});
|
|
68
|
-
it('generates fallback sessionKey from event', async () => {
|
|
69
|
-
const event = createTestEvent({
|
|
70
|
-
source: 'linear',
|
|
71
|
-
type: 'resource.changed',
|
|
72
|
-
});
|
|
73
|
-
const routeConfig = {};
|
|
74
|
-
await target.deliver(event, routeConfig);
|
|
75
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
76
|
-
expect(body.sessionKey).toBe('orgloop:linear:resource.changed');
|
|
77
|
-
});
|
|
78
|
-
it('includes platform_event and author in message', async () => {
|
|
79
|
-
const event = createTestEvent({
|
|
80
|
-
source: 'github',
|
|
81
|
-
type: 'resource.changed',
|
|
82
|
-
provenance: {
|
|
83
|
-
platform: 'github',
|
|
84
|
-
platform_event: 'pull_request.merged',
|
|
85
|
-
author: 'bob',
|
|
86
|
-
author_type: 'team_member',
|
|
87
|
-
},
|
|
88
|
-
});
|
|
89
|
-
await target.deliver(event, {});
|
|
90
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
91
|
-
expect(body.message).toContain('pull_request.merged');
|
|
92
|
-
expect(body.message).toContain('bob');
|
|
93
|
-
});
|
|
94
|
-
it('includes full payload values and provenance context in message', async () => {
|
|
95
|
-
const event = createTestEvent({
|
|
96
|
-
source: 'linear',
|
|
97
|
-
type: 'resource.changed',
|
|
98
|
-
provenance: {
|
|
99
|
-
platform: 'linear',
|
|
100
|
-
platform_event: 'comment.created',
|
|
101
|
-
author: 'Alice',
|
|
102
|
-
author_type: 'team_member',
|
|
103
|
-
issue_id: 'ENG-42',
|
|
104
|
-
url: 'https://linear.app/team/issue/ENG-42#comment-abc',
|
|
105
|
-
},
|
|
106
|
-
payload: {
|
|
107
|
-
action: 'comment_created',
|
|
108
|
-
issue_id: 'ENG-42',
|
|
109
|
-
issue_title: 'Fix the widget',
|
|
110
|
-
comment_body: 'This needs a different approach — see the RFC.',
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
await target.deliver(event, { launch_prompt: 'Handle this Linear activity' });
|
|
114
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
115
|
-
const msg = body.message;
|
|
116
|
-
// Header
|
|
117
|
-
expect(msg).toContain('[linear] resource.changed (comment.created) by Alice');
|
|
118
|
-
// Provenance context (url, issue_id — not platform/author which are in header)
|
|
119
|
-
expect(msg).toContain('issue_id: ENG-42');
|
|
120
|
-
expect(msg).toContain('url: https://linear.app/team/issue/ENG-42#comment-abc');
|
|
121
|
-
// Payload values — the actual data the LLM needs
|
|
122
|
-
expect(msg).toContain('issue_title: Fix the widget');
|
|
123
|
-
expect(msg).toContain('comment_body: This needs a different approach — see the RFC.');
|
|
124
|
-
// Instructions
|
|
125
|
-
expect(msg).toContain('Handle this Linear activity');
|
|
126
|
-
});
|
|
127
|
-
it('defaults wakeMode to "now"', async () => {
|
|
128
|
-
const event = createTestEvent();
|
|
129
|
-
await target.deliver(event, {});
|
|
130
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
131
|
-
expect(body.wakeMode).toBe('now');
|
|
132
|
-
});
|
|
133
|
-
it('defaults deliver to false', async () => {
|
|
134
|
-
const event = createTestEvent();
|
|
135
|
-
await target.deliver(event, {});
|
|
136
|
-
const body = JSON.parse(fetchMock.mock.calls[0][1].body);
|
|
137
|
-
expect(body.deliver).toBe(false);
|
|
138
|
-
});
|
|
139
|
-
it('handles 429 rate limit', async () => {
|
|
140
|
-
fetchMock.mockResolvedValueOnce({
|
|
141
|
-
ok: false,
|
|
142
|
-
status: 429,
|
|
143
|
-
statusText: 'Too Many Requests',
|
|
144
|
-
});
|
|
145
|
-
const event = createTestEvent();
|
|
146
|
-
const result = await target.deliver(event, {});
|
|
147
|
-
expect(result.status).toBe('error');
|
|
148
|
-
expect(result.error?.message).toContain('429');
|
|
149
|
-
});
|
|
150
|
-
it('handles 4xx rejection', async () => {
|
|
151
|
-
fetchMock.mockResolvedValueOnce({
|
|
152
|
-
ok: false,
|
|
153
|
-
status: 400,
|
|
154
|
-
statusText: 'Bad Request',
|
|
155
|
-
});
|
|
156
|
-
const event = createTestEvent();
|
|
157
|
-
const result = await target.deliver(event, {});
|
|
158
|
-
expect(result.status).toBe('rejected');
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
//# sourceMappingURL=target.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"target.test.js","sourceRoot":"","sources":["../../src/__tests__/target.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validator.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/validator.test.ts"],"names":[],"mappings":""}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
-
import { OpenClawCredentialValidator } from '../validator.js';
|
|
3
|
-
describe('OpenClawCredentialValidator', () => {
|
|
4
|
-
let validator;
|
|
5
|
-
let fetchMock;
|
|
6
|
-
beforeEach(() => {
|
|
7
|
-
validator = new OpenClawCredentialValidator('http://localhost:18789');
|
|
8
|
-
fetchMock = vi.fn();
|
|
9
|
-
vi.stubGlobal('fetch', fetchMock);
|
|
10
|
-
});
|
|
11
|
-
afterEach(() => {
|
|
12
|
-
vi.restoreAllMocks();
|
|
13
|
-
});
|
|
14
|
-
it('returns valid on successful response', async () => {
|
|
15
|
-
fetchMock.mockResolvedValueOnce({
|
|
16
|
-
ok: true,
|
|
17
|
-
status: 200,
|
|
18
|
-
});
|
|
19
|
-
const result = await validator.validate('test-token');
|
|
20
|
-
expect(result.valid).toBe(true);
|
|
21
|
-
expect(fetchMock).toHaveBeenCalledWith('http://localhost:18789/hooks/agent', expect.objectContaining({
|
|
22
|
-
method: 'POST',
|
|
23
|
-
headers: expect.objectContaining({
|
|
24
|
-
Authorization: 'Bearer test-token',
|
|
25
|
-
}),
|
|
26
|
-
}));
|
|
27
|
-
});
|
|
28
|
-
it('returns invalid on 401', async () => {
|
|
29
|
-
fetchMock.mockResolvedValueOnce({
|
|
30
|
-
ok: false,
|
|
31
|
-
status: 401,
|
|
32
|
-
statusText: 'Unauthorized',
|
|
33
|
-
});
|
|
34
|
-
const result = await validator.validate('bad-token');
|
|
35
|
-
expect(result.valid).toBe(false);
|
|
36
|
-
expect(result.error).toContain('401');
|
|
37
|
-
});
|
|
38
|
-
it('returns invalid on 403', async () => {
|
|
39
|
-
fetchMock.mockResolvedValueOnce({
|
|
40
|
-
ok: false,
|
|
41
|
-
status: 403,
|
|
42
|
-
statusText: 'Forbidden',
|
|
43
|
-
});
|
|
44
|
-
const result = await validator.validate('bad-token');
|
|
45
|
-
expect(result.valid).toBe(false);
|
|
46
|
-
expect(result.error).toContain('403');
|
|
47
|
-
});
|
|
48
|
-
it('returns valid on other errors (token accepted but other issue)', async () => {
|
|
49
|
-
fetchMock.mockResolvedValueOnce({
|
|
50
|
-
ok: false,
|
|
51
|
-
status: 400,
|
|
52
|
-
statusText: 'Bad Request',
|
|
53
|
-
});
|
|
54
|
-
const result = await validator.validate('good-token');
|
|
55
|
-
// Not a 401/403, so the token was accepted
|
|
56
|
-
expect(result.valid).toBe(true);
|
|
57
|
-
});
|
|
58
|
-
it('fails open on network error', async () => {
|
|
59
|
-
fetchMock.mockRejectedValueOnce(new Error('connect ECONNREFUSED'));
|
|
60
|
-
const result = await validator.validate('any-token');
|
|
61
|
-
expect(result.valid).toBe(true);
|
|
62
|
-
expect(result.error).toContain('Could not reach OpenClaw');
|
|
63
|
-
});
|
|
64
|
-
it('fails open on timeout', async () => {
|
|
65
|
-
const abortError = new DOMException('The operation was aborted', 'AbortError');
|
|
66
|
-
fetchMock.mockRejectedValueOnce(abortError);
|
|
67
|
-
const result = await validator.validate('any-token');
|
|
68
|
-
expect(result.valid).toBe(true);
|
|
69
|
-
expect(result.error).toContain('timed out');
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
//# sourceMappingURL=validator.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"validator.test.js","sourceRoot":"","sources":["../../src/__tests__/validator.test.ts"],"names":[],"mappings":"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"}
|