Skip to content

docs(contact-center): add ai-docs SDD pattern documentation#4723

Merged
ciscoRankush merged 4 commits intowebex:task-refactorfrom
ciscoRankush:SPARK-775699Patterns
Feb 25, 2026
Merged

docs(contact-center): add ai-docs SDD pattern documentation#4723
ciscoRankush merged 4 commits intowebex:task-refactorfrom
ciscoRankush:SPARK-775699Patterns

Conversation

@ciscoRankush
Copy link

@ciscoRankush ciscoRankush commented Feb 19, 2026

COMPLETES #SPARK-775699

This pull request addresses

AI agents need reference documentation for the established coding patterns in the @webex/contact-center SDK so they can generate code that is consistent with existing conventions. Without pattern docs, agents
produce code that uses console.log instead of LoggerProxy, misses MetricsManager tracking, uses incorrect error handling, and deviates from established type conventions.

by making the following changes

  • Adds ai-docs/patterns/ with 5 pattern documentation files:
    • typescript-patterns.md — Type conventions, LoggerProxy usage (not console.log), error handling with getErrorDetails, constant patterns, JSDoc conventions
    • testing-patterns.md — Jest test structure, mocking patterns (LoggerProxy, services, WebSocket), test naming conventions, success/error/edge case coverage
    • event-driven-patterns.md — Event emission patterns, listener registration/cleanup, event constant usage, WebSocket event handling
    • websocket-patterns.md — WebSocket connection lifecycle, reconnection flow, silent relogin, message handling patterns
    • sdk-plugin-patterns.md — WebexPlugin extension, service registration, initialization in READY block, public API exposure via cc.ts

Change Type

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Tooling change
  • Internal code refactor

The following scenarios were tested

  1. Pattern Compliance — Verified all code examples in pattern files follow SDK conventions (LoggerProxy, not console.log; getErrorDetails for errors; MetricsManager tracking)
  2. console.log Fix — Confirmed typescript-patterns.md uses LoggerProxy.error() in error handling examples (previously had console.log which contradicted the no-console.log rule)
  3. Cross-Reference Validation — Verified pattern files are correctly referenced from template 00-master.md files via ../../patterns/ relative paths
  4. Type E Routing — Tested that architecture understanding prompts (e.g., "How does WebSocket reconnection work?") correctly route to these pattern docs via the Service Routing Table

The GAI Coding Policy And Copyright Annotation Best Practices

  • GAI was not used (or, no additional notation is required)
  • Code was generated entirely by GAI
  • GAI was used to create a draft that was subsequently customized or modified
  • Coder created a draft manually that was non-substantively modified by GAI (e.g., refactoring was performed by GAI on manually written code)
  • Tool used for AI assistance (GitHub Copilot / Other - specify)
    • Github Copilot
    • Other - Claude Code (Claude Opus 4.6)
  • This PR is related to
    • Feature
    • Defect fix
    • Tech Debt
    • Automation

I certified that

  • I have read and followed contributing guidelines
  • I discussed changes with code owners prior to submitting this pull request
  • I have not skipped any automated checks
  • All existing and new tests passed
  • I have updated the documentation accordingly

@ciscoRankush ciscoRankush requested a review from a team as a code owner February 19, 2026 09:30
@ciscoRankush ciscoRankush changed the title feat(contact-center): add ai-docs SDD pattern documentation doc(contact-center): add ai-docs SDD pattern documentation Feb 19, 2026
@Shreyas281299 Shreyas281299 added the validated If the pull request is validated for automation. label Feb 20, 2026
@Shreyas281299
Copy link
Contributor

@codex review

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb5d146901

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ciscoRankush ciscoRankush changed the title doc(contact-center): add ai-docs SDD pattern documentation docs(contact-center): add ai-docs SDD pattern documentation Feb 20, 2026
Add pattern documentation for AI agents to reference during code generation:
- typescript-patterns.md — type conventions, error handling, LoggerProxy usage
- testing-patterns.md — Jest patterns, mocking, test structure
- event-driven-patterns.md — event emission, listener patterns
- websocket-patterns.md — WebSocket connection, reconnection patterns
- sdk-plugin-patterns.md — WebexPlugin extension, service registration

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
const event2: CC_EVENTS = 'InvalidEvent'; // ❌ Compile error
```

### Response Type Pattern
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets remove this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

getOrgId: jest.fn(() => 'mockOrgId'),
},
config: config,
}) as unknown as WebexSDK;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should not use unkown, thie way LLM would put unknown everywhere

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


```bash
# Run tests with coverage
yarn workspace @webex/contact-center test --coverage
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
yarn workspace @webex/contact-center test --coverage
yarn workspace @webex/contact-center test:unit --coverage

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

### Message Reception

```
WebSocket → WebSocketManager → cc.handleWebsocketMessage → Event Emission
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mermaid diagram. This is a very speicifc flow. We can add a generic flow to explain the generic event reception

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is more machine readable statement , so lets keep it

Comment on lines +154 to +180
### From Plugin Class

```typescript
// Using WebexPlugin's emit method
this.emit(AGENT_EVENTS.AGENT_STATE_CHANGE, eventData);

// Using trigger for some events (alternative method)
this.trigger(TASK_EVENTS.TASK_INCOMING, task);
```

### From TaskManager

```typescript
// TaskManager extends EventEmitter
export default class TaskManager extends EventEmitter {
private emitTaskEvent(eventType: string, task: ITask) {
this.emit(eventType, task);
}

public handleIncomingTask(taskData: TaskData) {
const task = this.createTask(taskData);
this.emit(TASK_EVENTS.TASK_INCOMING, task);
}
}
```

---
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • We dont need subheading

What we need?

  1. How we emit events. Two ways
  2. We need to differntiate when to use trigger and when to use emit
    P.S: emit is used when the class is extendin EventEmitter and trigger is used in the other case-trigger is very speicifc for cc object as it extends WebexPlugin
  3. Code example of each way

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +184 to +224
### In Application Code

```typescript
// Subscribe to events
const cc = webex.cc;

cc.on('agent:stateChange', (event) => {
console.log('Agent state changed:', event.state);
});

cc.on('task:incoming', (task) => {
console.log('New task:', task.interactionId);
});

// Unsubscribe
const handler = (event) => { /* handle */ };
cc.on('agent:stateChange', handler);
cc.off('agent:stateChange', handler);
```

### Internal Subscription

```typescript
// In constructor
constructor() {
this.$webex.once(READY, () => {
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
this.services.connectionService.on('connectionLost', this.handleConnectionLost);

this.taskManager.on(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
this.taskManager.on(TASK_EVENTS.TASK_HYDRATE, this.handleTaskHydrate);
});
}

// Cleanup in deregister
public async deregister() {
this.taskManager.off(TASK_EVENTS.TASK_INCOMING, this.handleIncomingTask);
this.services.webSocketManager.off('message', this.handleWebsocketMessage);
}
```

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What we need?

  1. How to add/remove an event listener?
  2. Examples
    2.1 Internal event listening
    2.2 Events sent to application (from cc,task)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Comment on lines +334 to +363
## Connection Events

### Connection Lost/Reconnected

```typescript
// services/core/websocket/types.ts
export type ConnectionLostDetails = {
isConnectionLost: boolean;
isSocketReconnected: boolean;
};

// Handling in cc.ts
private async handleConnectionLost(msg: ConnectionLostDetails): Promise<void> {
if (msg.isConnectionLost) {
LoggerProxy.info('Connection lost', {
module: CC_FILE,
method: 'handleConnectionLost',
});
} else if (msg.isSocketReconnected) {
LoggerProxy.info('Connection reconnected', {
module: CC_FILE,
method: 'handleConnectionLost',
});

if (this.$config?.allowAutomatedRelogin) {
await this.silentRelogin();
}
}
}
```
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not part of SDK. Lets remove this

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

…tern docs

Apply reviewer feedback from Shreyas and Kesari plus source code validation:
- Delete sdk-plugin-patterns.md (too cc.ts-specific) and websocket-patterns.md
  (lifecycle content folded into event-driven-patterns.md)
- Fix AGENT_EVENTS/TASK_EVENTS to use enum syntax with correct values
- Fix Failure type to use Msg<T> wrapper matching actual GlobalTypes.ts
- Fix interface naming convention to acknowledge I prefix for contracts
- Fix MetricsManager mock, file tree paths, test command, and event testing patterns
- Genericize event flow, document trigger vs emit accurately, add WebSocket Lifecycle
- Remove all broken links to deleted files across AGENTS.md, RULES.md, README.md

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add 5 missing CC_AGENT_EVENTS members (AGENT_DN_REGISTERED,
  AGENT_BUDDY_AGENTS, AGENT_BUDDY_AGENTS_SUCCESS,
  AGENT_BUDDY_AGENTS_RETRIEVE_FAILED, AGENT_CONTACT_RESERVED)
  to match config/types.ts
- Fix arrow function claim: document both arrow property and
  .bind(this) patterns used in cc.ts
- Fix getActiveTasks → getAllTasks in testing-patterns.md mock

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

## Event Emission

There are **two methods** for emitting events: `trigger` and `emit`. Both work on the `cc` object (which extends `WebexPlugin`), but they should be used in different contexts.
Copy link
Contributor

@Kesari3008 Kesari3008 Feb 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

emit doesn't work on cc object because it doesn't extend event emitter class. We are adding @ts-ignore to be able to invoke it. Emphasis here should be that classes which extend EventEmitter can use emit for event emission but for classes like cc.ts can use trigger for emission

const cc = webex.cc;

// Agent events (from cc)
cc.on(AGENT_EVENTS.AGENT_STATE_CHANGE, (event) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In these examples, we should have callbacks while listening because .off won;t work if we don;t have separate callback function

… doc

emit does not work on cc object (extends WebexPlugin, not EventEmitter).
Use trigger for WebexPlugin classes, emit for EventEmitter classes.
Also adds named callbacks in examples so .off() works properly.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f5cd0f03c9

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

}

// Register with .bind(this)
this.services.connectionService.on('connectionLost', this.handleConnectionLost.bind(this));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep a stable callback when binding connectionLost listener

The on('connectionLost', this.handleConnectionLost.bind(this)) pattern creates a new function instance at registration time, but the cleanup examples later use off(..., this.handleConnectionLost). Because those are different references, the listener cannot be removed, so repeated register/deregister cycles can accumulate duplicate reconnection handlers and fire relogin logic multiple times.

Useful? React with 👍 / 👎.

// Register listeners after SDK is ready
this.$webex.once(READY, () => {
this.services.webSocketManager.on('message', this.handleWebsocketMessage);
this.services.connectionService.on('connectionLost', this.handleConnectionLost);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Bind handleConnectionLost in the internal listener example

This example subscribes this.handleConnectionLost without binding even though the handler is shown as a regular class method; with EventEmitter-style callbacks, this inside the handler will be the emitter, not the ContactCenter instance. That breaks access to instance members like $config/silentRelogin, so reconnection recovery logic can silently stop working if generated code follows this snippet.

Useful? React with 👍 / 👎.

@ciscoRankush ciscoRankush merged commit 83d401d into webex:task-refactor Feb 25, 2026
11 checks passed
this.trigger(TASK_EVENTS.TASK_HYDRATE, task);
```

> **Note**: `trigger` requires `// @ts-ignore` because WebexPlugin's TypeScript type definitions don't expose it.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be emit here, it should say that we can still use emit but with @ts-ignore. We can address this PRs which are not merged yet

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

validated If the pull request is validated for automation.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants