agent-messenger 2.20.5 → 2.21.0
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/.claude-plugin/plugin.json +1 -1
- package/README.md +8 -5
- package/dist/package.json +9 -1
- package/dist/src/cli.d.ts.map +1 -1
- package/dist/src/cli.js +3 -0
- package/dist/src/cli.js.map +1 -1
- package/dist/src/platforms/webexbot/cli.d.ts +5 -0
- package/dist/src/platforms/webexbot/cli.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/cli.js +30 -0
- package/dist/src/platforms/webexbot/cli.js.map +1 -0
- package/dist/src/platforms/webexbot/client.d.ts +41 -0
- package/dist/src/platforms/webexbot/client.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/client.js +66 -0
- package/dist/src/platforms/webexbot/client.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/auth.d.ts +28 -0
- package/dist/src/platforms/webexbot/commands/auth.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/auth.js +166 -0
- package/dist/src/platforms/webexbot/commands/auth.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/index.d.ts +7 -0
- package/dist/src/platforms/webexbot/commands/index.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/index.js +7 -0
- package/dist/src/platforms/webexbot/commands/index.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/listen.d.ts +12 -0
- package/dist/src/platforms/webexbot/commands/listen.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/listen.js +85 -0
- package/dist/src/platforms/webexbot/commands/listen.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/member.d.ts +19 -0
- package/dist/src/platforms/webexbot/commands/member.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/member.js +33 -0
- package/dist/src/platforms/webexbot/commands/member.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/message.d.ts +37 -0
- package/dist/src/platforms/webexbot/commands/message.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/message.js +142 -0
- package/dist/src/platforms/webexbot/commands/message.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/shared.d.ts +9 -0
- package/dist/src/platforms/webexbot/commands/shared.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/shared.js +13 -0
- package/dist/src/platforms/webexbot/commands/shared.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/space.d.ts +28 -0
- package/dist/src/platforms/webexbot/commands/space.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/space.js +61 -0
- package/dist/src/platforms/webexbot/commands/space.js.map +1 -0
- package/dist/src/platforms/webexbot/commands/whoami.d.ts +16 -0
- package/dist/src/platforms/webexbot/commands/whoami.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/commands/whoami.js +29 -0
- package/dist/src/platforms/webexbot/commands/whoami.js.map +1 -0
- package/dist/src/platforms/webexbot/credential-manager.d.ts +17 -0
- package/dist/src/platforms/webexbot/credential-manager.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/credential-manager.js +120 -0
- package/dist/src/platforms/webexbot/credential-manager.js.map +1 -0
- package/dist/src/platforms/webexbot/index.d.ts +9 -0
- package/dist/src/platforms/webexbot/index.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/index.js +6 -0
- package/dist/src/platforms/webexbot/index.js.map +1 -0
- package/dist/src/platforms/webexbot/listener.d.ts +44 -0
- package/dist/src/platforms/webexbot/listener.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/listener.js +214 -0
- package/dist/src/platforms/webexbot/listener.js.map +1 -0
- package/dist/src/platforms/webexbot/types.d.ts +60 -0
- package/dist/src/platforms/webexbot/types.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/types.js +28 -0
- package/dist/src/platforms/webexbot/types.js.map +1 -0
- package/dist/src/platforms/webexbot/wdm-discovery.d.ts +4 -0
- package/dist/src/platforms/webexbot/wdm-discovery.d.ts.map +1 -0
- package/dist/src/platforms/webexbot/wdm-discovery.js +36 -0
- package/dist/src/platforms/webexbot/wdm-discovery.js.map +1 -0
- package/docs/content/docs/cli/meta.json +1 -0
- package/docs/content/docs/cli/webexbot.mdx +290 -0
- package/docs/content/docs/sdk/meta.json +1 -0
- package/docs/content/docs/sdk/webexbot.mdx +340 -0
- package/docs/src/app/page.tsx +115 -19
- package/package.json +9 -1
- package/skills/agent-channeltalk/SKILL.md +1 -1
- package/skills/agent-channeltalkbot/SKILL.md +1 -1
- package/skills/agent-discord/SKILL.md +1 -1
- package/skills/agent-discordbot/SKILL.md +1 -1
- package/skills/agent-instagram/SKILL.md +1 -1
- package/skills/agent-kakaotalk/SKILL.md +1 -1
- package/skills/agent-line/SKILL.md +1 -1
- package/skills/agent-slack/SKILL.md +1 -1
- package/skills/agent-slackbot/SKILL.md +1 -1
- package/skills/agent-teams/SKILL.md +1 -1
- package/skills/agent-telegram/SKILL.md +1 -1
- package/skills/agent-telegrambot/SKILL.md +1 -1
- package/skills/agent-webex/SKILL.md +1 -1
- package/skills/agent-webexbot/SKILL.md +361 -0
- package/skills/agent-webexbot/references/authentication.md +225 -0
- package/skills/agent-webexbot/references/common-patterns.md +590 -0
- package/skills/agent-wechatbot/SKILL.md +1 -1
- package/skills/agent-whatsapp/SKILL.md +1 -1
- package/skills/agent-whatsappbot/SKILL.md +1 -1
- package/src/cli.ts +4 -0
- package/src/platforms/webex/typings/webex-message-handler.d.ts +360 -29
- package/src/platforms/webexbot/cli.ts +42 -0
- package/src/platforms/webexbot/client.ts +87 -0
- package/src/platforms/webexbot/commands/auth.test.ts +185 -0
- package/src/platforms/webexbot/commands/auth.ts +210 -0
- package/src/platforms/webexbot/commands/index.ts +6 -0
- package/src/platforms/webexbot/commands/listen.test.ts +20 -0
- package/src/platforms/webexbot/commands/listen.ts +104 -0
- package/src/platforms/webexbot/commands/member.ts +51 -0
- package/src/platforms/webexbot/commands/message.ts +197 -0
- package/src/platforms/webexbot/commands/shared.ts +22 -0
- package/src/platforms/webexbot/commands/space.ts +88 -0
- package/src/platforms/webexbot/commands/whoami.ts +43 -0
- package/src/platforms/webexbot/credential-manager.test.ts +182 -0
- package/src/platforms/webexbot/credential-manager.ts +149 -0
- package/src/platforms/webexbot/index.ts +8 -0
- package/src/platforms/webexbot/listener.test.ts +234 -0
- package/src/platforms/webexbot/listener.ts +255 -0
- package/src/platforms/webexbot/types.test.ts +87 -0
- package/src/platforms/webexbot/types.ts +72 -0
- package/src/platforms/webexbot/wdm-discovery.test.ts +97 -0
- package/src/platforms/webexbot/wdm-discovery.ts +43 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, mock } from 'bun:test'
|
|
2
|
+
|
|
3
|
+
import { createWdmRewriteFetch, discoverWdmDevicesUrl } from './wdm-discovery'
|
|
4
|
+
|
|
5
|
+
const realFetch = globalThis.fetch
|
|
6
|
+
|
|
7
|
+
afterEach(() => {
|
|
8
|
+
globalThis.fetch = realFetch
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
function jsonResponse(body: unknown, ok = true, status = 200): Response {
|
|
12
|
+
return { ok, status, json: () => Promise.resolve(body) } as unknown as Response
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
describe('discoverWdmDevicesUrl', () => {
|
|
16
|
+
it('returns the U2C wdm serviceLink with /devices appended', async () => {
|
|
17
|
+
globalThis.fetch = mock(() =>
|
|
18
|
+
Promise.resolve(jsonResponse({ serviceLinks: { wdm: 'https://wdm-r.wbx2.com/wdm/api/v1' } })),
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
const url = await discoverWdmDevicesUrl('token123')
|
|
22
|
+
|
|
23
|
+
expect(url).toBe('https://wdm-r.wbx2.com/wdm/api/v1/devices')
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('strips a trailing slash before appending /devices', async () => {
|
|
27
|
+
globalThis.fetch = mock(() =>
|
|
28
|
+
Promise.resolve(jsonResponse({ serviceLinks: { wdm: 'https://wdm-r.wbx2.com/wdm/api/v1/' } })),
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
const url = await discoverWdmDevicesUrl('token123')
|
|
32
|
+
|
|
33
|
+
expect(url).toBe('https://wdm-r.wbx2.com/wdm/api/v1/devices')
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
it('throws when the catalog request fails', async () => {
|
|
37
|
+
globalThis.fetch = mock(() => Promise.resolve(jsonResponse({}, false, 401)))
|
|
38
|
+
|
|
39
|
+
await expect(discoverWdmDevicesUrl('bad')).rejects.toThrow('Failed to discover Webex WDM cluster')
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
it('throws when the catalog lacks serviceLinks.wdm', async () => {
|
|
43
|
+
globalThis.fetch = mock(() => Promise.resolve(jsonResponse({ serviceLinks: {} })))
|
|
44
|
+
|
|
45
|
+
await expect(discoverWdmDevicesUrl('token123')).rejects.toThrow('did not include serviceLinks.wdm')
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
describe('createWdmRewriteFetch', () => {
|
|
50
|
+
it('rewrites the hardcoded WDM device-registration URL to the discovered cluster', async () => {
|
|
51
|
+
const seen: string[] = []
|
|
52
|
+
globalThis.fetch = mock((url: string) => {
|
|
53
|
+
seen.push(url)
|
|
54
|
+
return Promise.resolve(jsonResponse({ ok: true }))
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
const fetchFn = createWdmRewriteFetch('https://wdm-r.wbx2.com/wdm/api/v1/devices')
|
|
58
|
+
await fetchFn({
|
|
59
|
+
url: 'https://wdm-a.wbx2.com/wdm/api/v1/devices',
|
|
60
|
+
method: 'POST',
|
|
61
|
+
headers: { Authorization: 'Bearer x' },
|
|
62
|
+
body: '{}',
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
expect(seen[0]).toBe('https://wdm-r.wbx2.com/wdm/api/v1/devices')
|
|
66
|
+
})
|
|
67
|
+
|
|
68
|
+
it('rewrites WDM device sub-paths too', async () => {
|
|
69
|
+
const seen: string[] = []
|
|
70
|
+
globalThis.fetch = mock((url: string) => {
|
|
71
|
+
seen.push(url)
|
|
72
|
+
return Promise.resolve(jsonResponse({}))
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const fetchFn = createWdmRewriteFetch('https://wdm-r.wbx2.com/wdm/api/v1/devices')
|
|
76
|
+
await fetchFn({
|
|
77
|
+
url: 'https://wdm-a.wbx2.com/wdm/api/v1/devices/abc-123',
|
|
78
|
+
method: 'DELETE',
|
|
79
|
+
headers: {},
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
expect(seen[0]).toBe('https://wdm-r.wbx2.com/wdm/api/v1/devices/abc-123')
|
|
83
|
+
})
|
|
84
|
+
|
|
85
|
+
it('leaves non-WDM URLs untouched', async () => {
|
|
86
|
+
const seen: string[] = []
|
|
87
|
+
globalThis.fetch = mock((url: string) => {
|
|
88
|
+
seen.push(url)
|
|
89
|
+
return Promise.resolve(jsonResponse({}))
|
|
90
|
+
})
|
|
91
|
+
|
|
92
|
+
const fetchFn = createWdmRewriteFetch('https://wdm-r.wbx2.com/wdm/api/v1/devices')
|
|
93
|
+
await fetchFn({ url: 'https://webexapis.com/v1/people/me', method: 'GET', headers: {} })
|
|
94
|
+
|
|
95
|
+
expect(seen[0]).toBe('https://webexapis.com/v1/people/me')
|
|
96
|
+
})
|
|
97
|
+
})
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { FetchFunction, FetchRequest, FetchResponse } from 'webex-message-handler'
|
|
2
|
+
|
|
3
|
+
import { WebexBotError } from './types'
|
|
4
|
+
|
|
5
|
+
const U2C_CATALOG_URL = 'https://u2c.wbx2.com/u2c/api/v1/catalog?format=hostmap'
|
|
6
|
+
const HARDCODED_WDM_DEVICES_URL = 'https://wdm-a.wbx2.com/wdm/api/v1/devices'
|
|
7
|
+
|
|
8
|
+
// webex-message-handler hardcodes the WDM cluster to wdm-a. A bot whose org lives
|
|
9
|
+
// on another cluster (e.g. wdm-r) registers its device on the wrong cluster, so
|
|
10
|
+
// Webex never routes conversation activities to its Mercury socket — the socket
|
|
11
|
+
// connects but no messages arrive. The U2C catalog returns the correct WDM cluster
|
|
12
|
+
// for the token; rewriting the device-registration request to it makes the bot
|
|
13
|
+
// receive real-time events.
|
|
14
|
+
export async function discoverWdmDevicesUrl(token: string): Promise<string> {
|
|
15
|
+
const response = await fetch(U2C_CATALOG_URL, { headers: { Authorization: `Bearer ${token}` } })
|
|
16
|
+
if (!response.ok) {
|
|
17
|
+
throw new WebexBotError(`Failed to discover Webex WDM cluster: HTTP ${response.status}`, 'wdm_discovery_failed')
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const catalog = (await response.json()) as { serviceLinks?: { wdm?: string } }
|
|
21
|
+
const wdm = catalog.serviceLinks?.wdm
|
|
22
|
+
if (!wdm) {
|
|
23
|
+
throw new WebexBotError('Webex U2C catalog did not include serviceLinks.wdm', 'wdm_discovery_failed')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return `${wdm.replace(/\/$/, '')}/devices`
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createWdmRewriteFetch(wdmDevicesUrl: string): FetchFunction {
|
|
30
|
+
return async (req: FetchRequest): Promise<FetchResponse> => {
|
|
31
|
+
const url = req.url.startsWith(HARDCODED_WDM_DEVICES_URL)
|
|
32
|
+
? wdmDevicesUrl + req.url.slice(HARDCODED_WDM_DEVICES_URL.length)
|
|
33
|
+
: req.url
|
|
34
|
+
|
|
35
|
+
const res = await fetch(url, { method: req.method, headers: req.headers, body: req.body })
|
|
36
|
+
return {
|
|
37
|
+
status: res.status,
|
|
38
|
+
ok: res.ok,
|
|
39
|
+
json: () => res.json(),
|
|
40
|
+
text: () => res.text(),
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|