agent-messenger 2.23.0 → 2.23.2
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/dist/package.json +1 -1
- package/dist/src/platforms/webex/client.d.ts +18 -0
- package/dist/src/platforms/webex/client.d.ts.map +1 -1
- package/dist/src/platforms/webex/client.js +178 -37
- package/dist/src/platforms/webex/client.js.map +1 -1
- package/dist/src/platforms/webex/commands/auth.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/auth.js +10 -6
- package/dist/src/platforms/webex/commands/auth.js.map +1 -1
- package/dist/src/platforms/webex/commands/member.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/member.js +3 -0
- package/dist/src/platforms/webex/commands/member.js.map +1 -1
- package/dist/src/platforms/webex/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/message.js +3 -0
- package/dist/src/platforms/webex/commands/message.js.map +1 -1
- package/dist/src/platforms/webex/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/snapshot.js +3 -1
- package/dist/src/platforms/webex/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/webex/commands/space.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/space.js +5 -0
- package/dist/src/platforms/webex/commands/space.js.map +1 -1
- package/dist/src/platforms/webex/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/webex/commands/whoami.js +3 -0
- package/dist/src/platforms/webex/commands/whoami.js.map +1 -1
- package/dist/src/platforms/webex/id-normalizer.d.ts +7 -0
- package/dist/src/platforms/webex/id-normalizer.d.ts.map +1 -1
- package/dist/src/platforms/webex/id-normalizer.js +16 -0
- package/dist/src/platforms/webex/id-normalizer.js.map +1 -1
- package/dist/src/platforms/webex/index.d.ts +4 -2
- package/dist/src/platforms/webex/index.d.ts.map +1 -1
- package/dist/src/platforms/webex/index.js +2 -1
- package/dist/src/platforms/webex/index.js.map +1 -1
- package/dist/src/platforms/webexbot/client.d.ts +0 -4
- package/dist/src/platforms/webexbot/client.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/client.js +8 -65
- package/dist/src/platforms/webexbot/client.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/file.d.ts +2 -0
- package/dist/src/platforms/webexbot/commands/file.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/file.js +3 -0
- package/dist/src/platforms/webexbot/commands/file.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/member.d.ts +2 -0
- package/dist/src/platforms/webexbot/commands/member.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/member.js +3 -0
- package/dist/src/platforms/webexbot/commands/member.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/message.d.ts +4 -0
- package/dist/src/platforms/webexbot/commands/message.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/message.js +7 -0
- package/dist/src/platforms/webexbot/commands/message.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/snapshot.d.ts +2 -0
- package/dist/src/platforms/webexbot/commands/snapshot.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/snapshot.js +10 -2
- package/dist/src/platforms/webexbot/commands/snapshot.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/space.d.ts +4 -0
- package/dist/src/platforms/webexbot/commands/space.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/space.js +5 -0
- package/dist/src/platforms/webexbot/commands/space.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/user.d.ts +3 -0
- package/dist/src/platforms/webexbot/commands/user.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/user.js +4 -0
- package/dist/src/platforms/webexbot/commands/user.js.map +1 -1
- package/dist/src/platforms/webexbot/commands/whoami.d.ts +2 -0
- package/dist/src/platforms/webexbot/commands/whoami.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/commands/whoami.js +3 -0
- package/dist/src/platforms/webexbot/commands/whoami.js.map +1 -1
- package/dist/src/platforms/webexbot/index.d.ts +2 -2
- package/dist/src/platforms/webexbot/index.d.ts.map +1 -1
- package/dist/src/platforms/webexbot/index.js +1 -1
- package/dist/src/platforms/webexbot/index.js.map +1 -1
- package/dist/src/tui/adapters/types.d.ts +3 -0
- package/dist/src/tui/adapters/types.d.ts.map +1 -1
- package/dist/src/tui/adapters/webex-adapter.d.ts.map +1 -1
- package/dist/src/tui/adapters/webex-adapter.js +4 -0
- package/dist/src/tui/adapters/webex-adapter.js.map +1 -1
- package/docs/content/docs/cli/webex.mdx +2 -2
- package/package.json +1 -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 +3 -3
- package/skills/agent-webexbot/SKILL.md +2 -2
- package/skills/agent-webexbot/references/common-patterns.md +1 -1
- 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/platforms/webex/client.test.ts +94 -6
- package/src/platforms/webex/client.ts +194 -32
- package/src/platforms/webex/commands/auth.test.ts +3 -1
- package/src/platforms/webex/commands/auth.ts +12 -7
- package/src/platforms/webex/commands/member.test.ts +18 -8
- package/src/platforms/webex/commands/member.ts +3 -0
- package/src/platforms/webex/commands/message.test.ts +31 -23
- package/src/platforms/webex/commands/message.ts +3 -0
- package/src/platforms/webex/commands/snapshot.test.ts +18 -10
- package/src/platforms/webex/commands/snapshot.ts +3 -1
- package/src/platforms/webex/commands/space.test.ts +36 -17
- package/src/platforms/webex/commands/space.ts +5 -0
- package/src/platforms/webex/commands/whoami.test.ts +14 -6
- package/src/platforms/webex/commands/whoami.ts +3 -0
- package/src/platforms/webex/id-normalizer.test.ts +37 -0
- package/src/platforms/webex/id-normalizer.ts +21 -0
- package/src/platforms/webex/index.test.ts +4 -0
- package/src/platforms/webex/index.ts +4 -2
- package/src/platforms/webexbot/client.ts +8 -74
- package/src/platforms/webexbot/commands/file.ts +5 -0
- package/src/platforms/webexbot/commands/member.ts +5 -0
- package/src/platforms/webexbot/commands/message.ts +11 -0
- package/src/platforms/webexbot/commands/snapshot.ts +12 -2
- package/src/platforms/webexbot/commands/space.ts +9 -0
- package/src/platforms/webexbot/commands/user.test.ts +11 -5
- package/src/platforms/webexbot/commands/user.ts +7 -0
- package/src/platforms/webexbot/commands/whoami.ts +5 -0
- package/src/platforms/webexbot/index.ts +2 -2
- package/src/tui/adapters/types.ts +3 -0
- package/src/tui/adapters/webex-adapter.ts +4 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-webex
|
|
3
3
|
description: Interact with Cisco Webex - send messages, read spaces, manage memberships
|
|
4
|
-
version: 2.23.
|
|
4
|
+
version: 2.23.2
|
|
5
5
|
allowed-tools: Bash(agent-webex:*)
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
|
@@ -328,12 +328,12 @@ agent-webex snapshot --full
|
|
|
328
328
|
|
|
329
329
|
Default returns brief JSON with:
|
|
330
330
|
|
|
331
|
-
- Spaces (id, title) — only spaces you're a member of
|
|
331
|
+
- Spaces (id, ref, title) — only spaces you're a member of
|
|
332
332
|
- Hint for next commands
|
|
333
333
|
|
|
334
334
|
With `--full`, returns:
|
|
335
335
|
|
|
336
|
-
- Spaces (id, title, type, lastActivity)
|
|
336
|
+
- Spaces (id, ref, title, type, lastActivity)
|
|
337
337
|
|
|
338
338
|
For messages or members, use `message list <space-id>` or `member list <space-id>`.
|
|
339
339
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-webexbot
|
|
3
3
|
description: Interact with Cisco Webex using bot tokens - send messages, reply in threads, upload and download files, look up people, read spaces, manage memberships, stream real-time events
|
|
4
|
-
version: 2.23.
|
|
4
|
+
version: 2.23.2
|
|
5
5
|
allowed-tools: Bash(agent-webexbot:*)
|
|
6
6
|
metadata:
|
|
7
7
|
openclaw:
|
|
@@ -246,7 +246,7 @@ agent-webexbot file download <content-url-or-id> ./downloaded-report.pdf
|
|
|
246
246
|
Get a workspace overview for AI agents.
|
|
247
247
|
|
|
248
248
|
```bash
|
|
249
|
-
# Brief snapshot (bot identity + space
|
|
249
|
+
# Brief snapshot (bot identity + space ids/refs/titles)
|
|
250
250
|
agent-webexbot snapshot
|
|
251
251
|
|
|
252
252
|
# Full snapshot (includes space type and last activity)
|
|
@@ -331,7 +331,7 @@ agent-webexbot user info "$PERSON_ID" | jq '{displayName, emails, type}'
|
|
|
331
331
|
```bash
|
|
332
332
|
#!/bin/bash
|
|
333
333
|
|
|
334
|
-
# Brief: bot identity + space
|
|
334
|
+
# Brief: bot identity + space ids/refs/titles
|
|
335
335
|
agent-webexbot snapshot
|
|
336
336
|
|
|
337
337
|
# Full: includes space type and last activity
|
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, it } from 'bun:test'
|
|
1
|
+
import { afterEach, beforeEach, describe, expect, it, spyOn } from 'bun:test'
|
|
2
2
|
|
|
3
3
|
import * as jose from 'node-jose'
|
|
4
4
|
|
|
5
5
|
import { WebexClient } from './client'
|
|
6
6
|
import { WebexEncryptionService } from './encryption'
|
|
7
|
+
import { toRestId } from './id-normalizer'
|
|
7
8
|
import { WebexError } from './types'
|
|
8
9
|
|
|
9
10
|
describe('WebexClient', () => {
|
|
@@ -444,6 +445,92 @@ describe('WebexClient', () => {
|
|
|
444
445
|
})
|
|
445
446
|
})
|
|
446
447
|
|
|
448
|
+
describe('id ref resolution', () => {
|
|
449
|
+
const roomUuid = '12345678-1234-1234-1234-1234567890ab'
|
|
450
|
+
const personUuid = '22222222-2222-2222-2222-222222222222'
|
|
451
|
+
const messageUuid = '33333333-3333-3333-3333-333333333333'
|
|
452
|
+
const usRoomId = toRestId(roomUuid, 'ROOM')
|
|
453
|
+
const clusteredRoomId = Buffer.from(`ciscospark://urn:TEAM:us-west-2_r/ROOM/${roomUuid}`).toString('base64url')
|
|
454
|
+
|
|
455
|
+
const isRoomsList = (url: string) => new URL(url).pathname === '/v1/rooms'
|
|
456
|
+
|
|
457
|
+
it('resolves a bare room uuid to the real clustered id before sending', async () => {
|
|
458
|
+
mockResponse({ items: [{ id: clusteredRoomId, title: 'Team', type: 'group' }] })
|
|
459
|
+
mockResponse({ id: 'msg-1', roomId: clusteredRoomId, roomType: 'group' })
|
|
460
|
+
|
|
461
|
+
const client = await new WebexClient().login({ token: 'test-token' })
|
|
462
|
+
await client.sendMessage(roomUuid, 'hello')
|
|
463
|
+
|
|
464
|
+
expect(isRoomsList(fetchCalls[0].url)).toBe(true)
|
|
465
|
+
expect(JSON.parse(fetchCalls[1].options?.body as string).roomId).toBe(clusteredRoomId)
|
|
466
|
+
})
|
|
467
|
+
|
|
468
|
+
it('rewrites a us-cluster room id to the real clustered id for memberships', async () => {
|
|
469
|
+
mockResponse({ items: [{ id: clusteredRoomId, title: 'Team', type: 'group' }] })
|
|
470
|
+
mockResponse({ items: [{ id: 'm1', roomId: clusteredRoomId, personId: 'p1' }] })
|
|
471
|
+
|
|
472
|
+
const client = await new WebexClient().login({ token: 'test-token' })
|
|
473
|
+
await client.listMemberships(usRoomId)
|
|
474
|
+
|
|
475
|
+
const membershipsUrl = new URL(fetchCalls[1].url)
|
|
476
|
+
expect(membershipsUrl.pathname).toBe('/v1/memberships')
|
|
477
|
+
expect(membershipsUrl.searchParams.get('roomId')).toBe(clusteredRoomId)
|
|
478
|
+
})
|
|
479
|
+
|
|
480
|
+
it('passes an already-clustered room id through without a lookup', async () => {
|
|
481
|
+
mockResponse({ id: 'msg-1', roomId: clusteredRoomId, roomType: 'group' })
|
|
482
|
+
|
|
483
|
+
const client = await new WebexClient().login({ token: 'test-token' })
|
|
484
|
+
await client.sendMessage(clusteredRoomId, 'hello')
|
|
485
|
+
|
|
486
|
+
expect(fetchCalls).toHaveLength(1)
|
|
487
|
+
expect(JSON.parse(fetchCalls[0].options?.body as string).roomId).toBe(clusteredRoomId)
|
|
488
|
+
})
|
|
489
|
+
|
|
490
|
+
it('fails open to the reconstructed room id and warns when no room matches', async () => {
|
|
491
|
+
const warnSpy = spyOn(console, 'warn').mockImplementation(() => {})
|
|
492
|
+
try {
|
|
493
|
+
mockResponse({ items: [] })
|
|
494
|
+
mockResponse({ id: 'msg-1', roomId: usRoomId, roomType: 'group' })
|
|
495
|
+
|
|
496
|
+
const client = await new WebexClient().login({ token: 'test-token' })
|
|
497
|
+
await client.sendMessage(roomUuid, 'hello')
|
|
498
|
+
|
|
499
|
+
expect(JSON.parse(fetchCalls[1].options?.body as string).roomId).toBe(usRoomId)
|
|
500
|
+
expect(warnSpy).toHaveBeenCalled()
|
|
501
|
+
} finally {
|
|
502
|
+
warnSpy.mockRestore()
|
|
503
|
+
}
|
|
504
|
+
})
|
|
505
|
+
|
|
506
|
+
it('resolves a person email through the people search endpoint', async () => {
|
|
507
|
+
const personId = toRestId(personUuid, 'PEOPLE')
|
|
508
|
+
mockResponse({ items: [{ id: personId, emails: ['alice@example.com'], displayName: 'Alice', type: 'person' }] })
|
|
509
|
+
|
|
510
|
+
const client = await new WebexClient().login({ token: 'test-token' })
|
|
511
|
+
const person = await client.getPerson('alice@example.com')
|
|
512
|
+
|
|
513
|
+
expect(person.id).toBe(personId)
|
|
514
|
+
const url = new URL(fetchCalls[0].url)
|
|
515
|
+
expect(url.pathname).toBe('/v1/people')
|
|
516
|
+
expect(url.searchParams.get('email')).toBe('alice@example.com')
|
|
517
|
+
})
|
|
518
|
+
|
|
519
|
+
it('reconstructs bare person and message uuids for REST calls', async () => {
|
|
520
|
+
const personId = toRestId(personUuid, 'PEOPLE')
|
|
521
|
+
const messageId = toRestId(messageUuid, 'MESSAGE')
|
|
522
|
+
mockResponse({ id: personId, emails: ['alice@example.com'], displayName: 'Alice', type: 'person' })
|
|
523
|
+
mockResponse({ id: messageId, roomId: usRoomId, text: 'hi' })
|
|
524
|
+
|
|
525
|
+
const client = await new WebexClient().login({ token: 'test-token' })
|
|
526
|
+
await client.getPerson(personUuid)
|
|
527
|
+
await client.getMessage(messageUuid)
|
|
528
|
+
|
|
529
|
+
expect(fetchCalls[0].url).toBe(`https://webexapis.com/v1/people/${personId}`)
|
|
530
|
+
expect(fetchCalls[1].url).toBe(`https://webexapis.com/v1/messages/${messageId}`)
|
|
531
|
+
})
|
|
532
|
+
})
|
|
533
|
+
|
|
447
534
|
describe('rate limiting', () => {
|
|
448
535
|
it('retries on 429 with Retry-After header', async () => {
|
|
449
536
|
mockResponse({ message: 'Rate limited' }, 429, { 'Retry-After': '0.1' })
|
|
@@ -519,6 +606,7 @@ describe('WebexClient', () => {
|
|
|
519
606
|
const CONV_BASE = 'https://conv-r.wbx2.com/conversation/api/v1'
|
|
520
607
|
const TEST_ROOM_ID = Buffer.from('ciscospark://urn:TEAM:us-west-2_r/ROOM/abc123-def456').toString('base64')
|
|
521
608
|
const TEST_CONV_UUID = 'abc123-def456'
|
|
609
|
+
const TEST_ACTIVITY_ID = toRestId('activity-123', 'MESSAGE')
|
|
522
610
|
|
|
523
611
|
const mockActivity = (text: string, overrides?: Partial<Record<string, unknown>>) => ({
|
|
524
612
|
id: 'activity-123',
|
|
@@ -605,7 +693,7 @@ describe('WebexClient', () => {
|
|
|
605
693
|
const client = await createExtractedClient()
|
|
606
694
|
const message = await client.sendMessage(TEST_ROOM_ID, 'Hello world')
|
|
607
695
|
|
|
608
|
-
expect(message.id).toBe(
|
|
696
|
+
expect(message.id).toBe(TEST_ACTIVITY_ID)
|
|
609
697
|
expect(message.text).toBe('Hello world')
|
|
610
698
|
expect(message.personEmail).toBe('test@example.com')
|
|
611
699
|
expect(message.created).toBe('2026-01-01T00:00:00.000Z')
|
|
@@ -670,7 +758,7 @@ describe('WebexClient', () => {
|
|
|
670
758
|
const client = await createExtractedClient()
|
|
671
759
|
const messages = await client.listMessages(TEST_ROOM_ID)
|
|
672
760
|
|
|
673
|
-
expect(messages[0].id).toBe(
|
|
761
|
+
expect(messages[0].id).toBe(TEST_ACTIVITY_ID)
|
|
674
762
|
expect(messages[0].text).toBe('Hello')
|
|
675
763
|
expect(messages[0].personEmail).toBe('test@example.com')
|
|
676
764
|
expect(messages[0].created).toBe('2026-01-01T00:00:00.000Z')
|
|
@@ -713,7 +801,7 @@ describe('WebexClient', () => {
|
|
|
713
801
|
const client = await createExtractedClient()
|
|
714
802
|
const message = await client.getMessage('activity-123')
|
|
715
803
|
|
|
716
|
-
expect(message.id).toBe(
|
|
804
|
+
expect(message.id).toBe(TEST_ACTIVITY_ID)
|
|
717
805
|
expect(message.text).toBe('Hello')
|
|
718
806
|
expect(message.personEmail).toBe('test@example.com')
|
|
719
807
|
})
|
|
@@ -843,7 +931,7 @@ describe('WebexClient', () => {
|
|
|
843
931
|
|
|
844
932
|
const client = await createExtractedClient()
|
|
845
933
|
const message = await client.editMessage('activity-123', TEST_ROOM_ID, 'Edited text')
|
|
846
|
-
expect(message.id).toBe(
|
|
934
|
+
expect(message.id).toBe(TEST_ACTIVITY_ID)
|
|
847
935
|
})
|
|
848
936
|
|
|
849
937
|
it('throws when server returns activity linked to a different parent', async () => {
|
|
@@ -916,7 +1004,7 @@ describe('WebexClient', () => {
|
|
|
916
1004
|
expect(fetchCalls[0].url).toContain('/rooms?type=direct&max=100')
|
|
917
1005
|
expect(fetchCalls[1].url).toContain('/memberships?roomId=')
|
|
918
1006
|
expect(fetchCalls[2].url).toBe(`${CONV_BASE}/activities`)
|
|
919
|
-
expect(message.id).toBe(
|
|
1007
|
+
expect(message.id).toBe(TEST_ACTIVITY_ID)
|
|
920
1008
|
})
|
|
921
1009
|
|
|
922
1010
|
it('throws WebexError when no existing direct conversation found', async () => {
|