@austinchen705/chatbot-intg-skill 1.0.1

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 ADDED
@@ -0,0 +1,137 @@
1
+ # @austinchen705/chatbot-intg-skill
2
+
3
+ An AI skill installer for **Claude Code**, **Codex**, and **Gemini** that guides vendors through complete AI Chatbot API integration — covering auth, chat lifecycle, escalation handling, error resilience, analysis, and debugging.
4
+
5
+ ## Install
6
+
7
+ Run directly with `npx` (no install required):
8
+
9
+ ```bash
10
+ npx @austinchen705/chatbot-intg-skill
11
+ ```
12
+
13
+ Or install globally:
14
+
15
+ ```bash
16
+ npm install -g @austinchen705/chatbot-intg-skill
17
+ chatbot-intg-skill
18
+ ```
19
+
20
+ ## Usage
21
+
22
+ ### Interactive (default)
23
+
24
+ ```bash
25
+ npx @austinchen705/chatbot-intg-skill
26
+ ```
27
+
28
+ The installer will prompt you to select the target AI coding tool:
29
+
30
+ ```
31
+ AI Chatbot Integration Skill Installer
32
+ =======================================
33
+
34
+ Install for which tools? (comma-separated)
35
+ 1) claude 2) codex 3) gemini 4) all
36
+ >
37
+ ```
38
+
39
+ ### Non-interactive (CI / scripted)
40
+
41
+ Use the `--tool` flag to skip the prompt:
42
+
43
+ ```bash
44
+ # Single tool
45
+ npx @austinchen705/chatbot-intg-skill --tool claude
46
+
47
+ # Multiple tools
48
+ npx @austinchen705/chatbot-intg-skill --tool claude,codex
49
+
50
+ # All tools
51
+ npx @austinchen705/chatbot-intg-skill --tool all
52
+ ```
53
+
54
+ ## What Gets Installed
55
+
56
+ | Tool | Skill files | Command / Instruction file |
57
+ |------|-------------|---------------------------|
58
+ | Claude Code | `.claude/skills/chatbot-intg/` | `.claude/commands/chatbot-intg.md` |
59
+ | Codex | `.codex/skills/chatbot-intg/` | `.codex/AGENTS.md` (manual step) |
60
+ | Gemini | `.gemini/skills/chatbot-intg/` | `.gemini/GEMINI.md` (manual step) |
61
+
62
+ ### Installed files
63
+
64
+ ```
65
+ SKILL.md # Phased integration workflow
66
+ resources/
67
+ chatbot_integration_spec.pdf # API spec reference (v0.7)
68
+ integration-playbook.md # Language-specific code templates
69
+ ```
70
+
71
+ ## Invoking the Skill
72
+
73
+ **Claude Code** — the command is auto-detected after install:
74
+
75
+ ```
76
+ /chatbot-intg
77
+ ```
78
+
79
+ **Codex** — add the following line to `.codex/AGENTS.md`:
80
+
81
+ ```
82
+ Read .codex/skills/chatbot-intg/SKILL.md for vendor integration workflow
83
+ ```
84
+
85
+ **Gemini** — add the following line to `.gemini/GEMINI.md`:
86
+
87
+ ```
88
+ Read .gemini/skills/chatbot-intg/SKILL.md for vendor integration workflow
89
+ ```
90
+
91
+ ## Integration Workflow
92
+
93
+ The skill guides vendors through **6 gated phases**, each requiring user confirmation before proceeding:
94
+
95
+ ```
96
+ Phase 0: Infrastructure Language + framework + logging setup
97
+ ↓ (confirm)
98
+ Phase 1: Auth & Connectivity JWT token lifecycle + auto-refresh
99
+ ↓ (confirm)
100
+ Phase 2: Core Chat Flow Session dispatch → send loop → kickout + escalation
101
+ ↓ (confirm)
102
+ Phase 3: Error Handling Unified error framework + retry + circuit breaker
103
+ ↓ (confirm)
104
+ Phase 4: Advanced (optional) Chat Analysis + MCP Server guide
105
+ ↓ (confirm)
106
+ Phase 5: Acceptance Integration test checklist + debug handbook
107
+ ```
108
+
109
+ ### Supported Languages
110
+
111
+ - Python (FastAPI / Django · httpx / requests · tenacity)
112
+ - Java (Spring Boot · OkHttp / RestTemplate · Resilience4j)
113
+ - C# (ASP.NET Core · HttpClient · Polly)
114
+ - Node.js (Express / NestJS · axios · cockatiel)
115
+
116
+ ### Covered APIs
117
+
118
+ | Method | Route | Description |
119
+ |--------|-------|-------------|
120
+ | POST | `/api/v1/auth` | Obtain JWT Token |
121
+ | POST | `/api/v1/chatbot/dispatch` | Create chat session |
122
+ | GET | `/api/v1/chatbot/usage` | Query quota |
123
+ | POST | `/api/v1/chatbot/kickout` | Close a session |
124
+ | POST | `/api/v1/chatbot/killall` | Close all sessions |
125
+ | POST | `/api/v1/chat/send` | Send message + receive AI response |
126
+ | GET | `/api/v1/chat/history/{sessionId}` | Retrieve chat history |
127
+ | POST | `/api/v1/analysis/create` | Submit conversation for analysis |
128
+ | GET | `/api/v1/analysis/{sessionId}` | Poll analysis result |
129
+
130
+ ## Requirements
131
+
132
+ - Node.js >= 14
133
+ - Run from the **root of your project** so skill files land in the right directories
134
+
135
+ ## License
136
+
137
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,162 @@
1
+ #!/usr/bin/env node
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const readline = require('readline');
6
+
7
+ const TARGETS = {
8
+ claude: {
9
+ skillDir: '.claude/skills/chatbot-intg',
10
+ commandDir: '.claude/commands',
11
+ commandFile: 'chatbot-intg.md',
12
+ instructionFile: null,
13
+ postInstall: ' Claude Code: skill auto-detected. Use /chatbot-intg to invoke.',
14
+ },
15
+ codex: {
16
+ skillDir: '.codex/skills/chatbot-intg',
17
+ commandDir: null,
18
+ commandFile: null,
19
+ instructionFile: '.codex/AGENTS.md',
20
+ postInstall: ' Codex: add to .codex/AGENTS.md:\n' +
21
+ ' "Read .codex/skills/chatbot-intg/SKILL.md for vendor integration workflow"',
22
+ },
23
+ gemini: {
24
+ skillDir: '.gemini/skills/chatbot-intg',
25
+ commandDir: null,
26
+ commandFile: null,
27
+ instructionFile: '.gemini/GEMINI.md',
28
+ postInstall: ' Gemini: add to .gemini/GEMINI.md:\n' +
29
+ ' "Read .gemini/skills/chatbot-intg/SKILL.md for vendor integration workflow"',
30
+ },
31
+ };
32
+
33
+ const COMMAND_TEMPLATE = `---
34
+ description: AI Chatbot Integration — guides vendors through complete API integration (auth, chat, escalation, error handling, analysis, debugging)
35
+ ---
36
+
37
+ # Chatbot Integration Workflow
38
+
39
+ This command launches the chatbot-intg skill to guide a vendor through full AI Chatbot API integration.
40
+
41
+ ## Startup
42
+
43
+ 1. Read \`.claude/skills/chatbot-intg/SKILL.md\` and follow the phased workflow.
44
+ 2. Read \`docs/chatbot_integration_spec.md\` as the authoritative API reference.
45
+ 3. Reference \`.claude/skills/chatbot-intg/resources/integration-playbook.md\` for language-specific code templates.
46
+
47
+ ## Execution
48
+
49
+ Begin with **Phase 0** — ask the vendor for their target language and integration scope, then proceed through each phase with user confirmation gates.
50
+ `;
51
+
52
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
53
+
54
+ function ask(question) {
55
+ return new Promise((resolve) => rl.question(question, resolve));
56
+ }
57
+
58
+ function copyDir(src, dest) {
59
+ fs.mkdirSync(dest, { recursive: true });
60
+ for (const entry of fs.readdirSync(src, { withFileTypes: true })) {
61
+ const srcPath = path.join(src, entry.name);
62
+ const destPath = path.join(dest, entry.name);
63
+ if (entry.isDirectory()) {
64
+ copyDir(srcPath, destPath);
65
+ } else {
66
+ fs.copyFileSync(srcPath, destPath);
67
+ console.log(` copied: ${destPath}`);
68
+ }
69
+ }
70
+ }
71
+
72
+ function parseArgs() {
73
+ const args = process.argv.slice(2);
74
+ const toolFlag = args.indexOf('--tool');
75
+ if (toolFlag !== -1 && args[toolFlag + 1]) {
76
+ return args[toolFlag + 1].split(',').map((s) => s.trim().toLowerCase());
77
+ }
78
+ return null;
79
+ }
80
+
81
+ async function selectTools() {
82
+ // Check --tool flag first
83
+ const fromArgs = parseArgs();
84
+ if (fromArgs) {
85
+ const valid = fromArgs.includes('all')
86
+ ? Object.keys(TARGETS)
87
+ : fromArgs.filter((t) => TARGETS[t]);
88
+ if (valid.length > 0) return valid;
89
+ }
90
+
91
+ // Interactive prompt
92
+ const answer = await ask(
93
+ ' Install for which tools? (comma-separated)\n' +
94
+ ' 1) claude 2) codex 3) gemini 4) all\n' +
95
+ ' > '
96
+ );
97
+
98
+ if (answer.toLowerCase().includes('all') || answer.includes('4')) {
99
+ return Object.keys(TARGETS);
100
+ }
101
+
102
+ const mapping = { '1': 'claude', '2': 'codex', '3': 'gemini' };
103
+ return answer
104
+ .split(',')
105
+ .map((s) => {
106
+ const trimmed = s.trim().toLowerCase();
107
+ return mapping[trimmed] || trimmed;
108
+ })
109
+ .filter((s) => TARGETS[s]);
110
+ }
111
+
112
+ async function main() {
113
+ console.log('');
114
+ console.log(' AI Chatbot Integration Skill Installer');
115
+ console.log(' =======================================');
116
+ console.log('');
117
+
118
+ const choices = await selectTools();
119
+
120
+ if (choices.length === 0) {
121
+ console.log(' No valid targets selected. Exiting.\n');
122
+ rl.close();
123
+ process.exit(1);
124
+ }
125
+
126
+ const templateDir = path.join(__dirname, '..', 'templates');
127
+ const cwd = process.cwd();
128
+
129
+ for (const tool of choices) {
130
+ const target = TARGETS[tool];
131
+ const dest = path.join(cwd, target.skillDir);
132
+
133
+ console.log(`\n [${tool}] Installing skill -> ${target.skillDir}/`);
134
+ copyDir(templateDir, dest);
135
+
136
+ // Create Claude Code command file
137
+ if (target.commandDir && target.commandFile) {
138
+ const cmdDir = path.join(cwd, target.commandDir);
139
+ const cmdFile = path.join(cmdDir, target.commandFile);
140
+ fs.mkdirSync(cmdDir, { recursive: true });
141
+ fs.writeFileSync(cmdFile, COMMAND_TEMPLATE);
142
+ console.log(` copied: ${cmdFile}`);
143
+ }
144
+ }
145
+
146
+ console.log('\n =======================================');
147
+ console.log(' Installation complete!\n');
148
+ console.log(' Next steps:\n');
149
+
150
+ for (const tool of choices) {
151
+ console.log(TARGETS[tool].postInstall);
152
+ console.log('');
153
+ }
154
+
155
+ rl.close();
156
+ }
157
+
158
+ main().catch((err) => {
159
+ console.error(' Error:', err.message);
160
+ rl.close();
161
+ process.exit(1);
162
+ });
package/package.json ADDED
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "@austinchen705/chatbot-intg-skill",
3
+ "version": "1.0.1",
4
+ "description": "AI Chatbot integration skill for Claude Code / Codex / Gemini — guides vendors through complete API integration",
5
+ "bin": {
6
+ "chatbot-intg-skill": "./bin/cli.js"
7
+ },
8
+ "files": [
9
+ "bin/",
10
+ "templates/"
11
+ ],
12
+ "keywords": [
13
+ "chatbot",
14
+ "integration",
15
+ "claude-code",
16
+ "codex",
17
+ "gemini",
18
+ "ai-skill"
19
+ ],
20
+ "license": "MIT"
21
+ }
@@ -0,0 +1,452 @@
1
+ ---
2
+ name: chatbot-intg
3
+ description: AI Chatbot Integration Skill — guides vendors through complete Chatbot API integration including auth, chat, error handling, escalation, analysis, logging, and debugging. Supports Python / Java / C# / Node.js.
4
+ ---
5
+
6
+ # AI Chatbot Integration Skill
7
+
8
+ Guides third-party vendors through complete AI Chatbot system integration. Based on `resources/chatbot_integration_spec.pdf`, this skill generates phased tasks, code templates, error handling frameworks, and debugging guides per target language.
9
+
10
+ ## Use this skill when
11
+
12
+ - A vendor needs to integrate with the AI Chatbot API (auth, chat, analysis)
13
+ - Generating integration code for a specific language (Python / Java / C# / Node.js)
14
+ - Designing error handling and resilience patterns based on the spec
15
+ - Building debug/troubleshooting workflows and logging architecture
16
+
17
+ ## Do not use this skill when
18
+
19
+ - Developing the Chatbot system internals (backend services, domain logic, database schema)
20
+ - Only looking up a single API spec or error code (use the Consult Agent directly)
21
+ - Building standalone applications unrelated to Chatbot API integration
22
+
23
+ ## Knowledge Source
24
+
25
+ - **Integration Spec:** `resources/chatbot_integration_spec.pdf` (v0.7)
26
+ - **Implementation Templates:** `resources/integration-playbook.md`
27
+
28
+ ---
29
+
30
+ ## Workflow Overview
31
+
32
+ ```
33
+ Phase 0: Infrastructure -> Language + Logging setup
34
+ | (user confirmation)
35
+ Phase 1: Auth & Connectivity -> Auth module + Token management
36
+ | (user confirmation)
37
+ Phase 2: Core Chat Flow -> Session + Chat + Escalation
38
+ | (user confirmation)
39
+ Phase 3: Error Handling -> Unified error framework + Resilience
40
+ | (user confirmation)
41
+ Phase 4: Advanced (optional) -> Chat Analysis + MCP Server guide
42
+ | (user confirmation)
43
+ Phase 5: Acceptance -> Test checklist + Debug handbook
44
+ ```
45
+
46
+ **Each Phase requires user confirmation before proceeding to the next.**
47
+
48
+ ---
49
+
50
+ ## Phase 0: Infrastructure
51
+
52
+ ### Goal
53
+ Confirm dev environment, tech stack, and establish the cross-cutting Logging approach.
54
+
55
+ ### Steps
56
+
57
+ 1. **Detect / Ask target language**
58
+ - Supported: Python / Java / C# / Node.js
59
+ - Confirm framework (e.g. Python: FastAPI/Django, Java: Spring Boot, C#: ASP.NET Core, Node.js: Express/NestJS)
60
+ - Confirm HTTP client preference (e.g. Python: httpx/requests, Java: OkHttp/RestTemplate)
61
+
62
+ 2. **Confirm integration scope**
63
+ - AI Chatbot (required): Auth + Chat + Escalation
64
+ - Chat Analysis (optional): Post-conversation quality analysis
65
+ - MCP Server (optional): Custom tool extension
66
+
67
+ 3. **Establish Logging approach**
68
+ - Ask the vendor about their existing logging setup and conventions
69
+ - Adapt all subsequent logging guidance to their architecture
70
+ - Ensure a **correlation ID** mechanism exists (or suggest adding one) to trace requests end-to-end
71
+ - All subsequent Phases will include logging points — these should follow the vendor's conventions
72
+
73
+ 4. **Suggest project structure**
74
+ - Generate recommended directory layout per language
75
+ - Generate base HTTP client wrapper
76
+
77
+ ### Output
78
+ - Language & framework confirmed
79
+ - Integration scope confirmed
80
+ - Logging approach agreed
81
+ - HTTP client base wrapper code
82
+ - Task list for subsequent Phases
83
+
84
+ ### Gate
85
+ User confirms language, scope, and infrastructure before entering Phase 1.
86
+
87
+ ---
88
+
89
+ ## Phase 1: Auth & Connectivity
90
+
91
+ ### Goal
92
+ Implement JWT Token lifecycle management so all subsequent API calls carry a valid token.
93
+
94
+ ### Knowledge Source
95
+ - Spec 2.1: Authentication
96
+ - Error codes: `AUTH_001`~`AUTH_004`, `TENANT_001`, `TENANT_003`
97
+
98
+ ### Steps
99
+
100
+ 1. **Implement AuthService / AuthClient**
101
+ - Wrap `POST /api/v1/auth`
102
+ - Secure API Key storage (env vars / secret manager — never hardcode)
103
+ - Define Request/Response DTOs
104
+
105
+ 2. **Token caching & auto-refresh**
106
+ - In-memory cache with `expiresAt`
107
+ - Auto-detect expiry and refresh proactively (recommend 5 min before expiry)
108
+ - Thread-safe design (prevent concurrent refresh storms)
109
+
110
+ 3. **Auth error handling**
111
+ - `AUTH_004` (invalid API Key) -> do NOT retry, escalate immediately
112
+ - `TENANT_003` (tenant inactive) -> do NOT retry, notify admin
113
+ - Network errors -> retry (max 3, exponential backoff)
114
+
115
+ 4. **Logging**
116
+ - Log: auth success/failure, token refresh events, error codes
117
+ - NEVER log: raw API Key, full token (log only last 8 chars)
118
+
119
+ ### Output
120
+ - AuthService complete code
121
+ - Token management module
122
+ - Auth-related error handling
123
+ - Unit test suggestions
124
+
125
+ ### Gate
126
+ User confirms Auth module can successfully obtain a token before entering Phase 2.
127
+
128
+ ---
129
+
130
+ ## Phase 2: Core Chat Flow
131
+
132
+ ### Goal
133
+ Implement the full `dispatch -> send (loop) -> kickout` conversation lifecycle.
134
+
135
+ ### Knowledge Source
136
+ - Spec 3.1: Flow Overview
137
+ - Spec 3.2.1~3.2.5: All Chatbot & Chat APIs
138
+ - Spec 6.4: EscalationReason enum
139
+ - Error codes: `CHATBOT_001`~`CHATBOT_009`, `CHAT_001`~`CHAT_019`
140
+
141
+ ### Steps
142
+
143
+ 1. **Session lifecycle management**
144
+ - `POST /api/v1/chatbot/dispatch` — create session
145
+ - Handle idempotency (same sessionId won't consume extra quota)
146
+ - Handle `timeZone` param (IANA format)
147
+ - `GET /api/v1/chatbot/usage` — check quota before dispatch
148
+ - `POST /api/v1/chatbot/kickout` — graceful close
149
+ - `POST /api/v1/chatbot/killall` — bulk close (admin use)
150
+ - **Cleanup on failure**: if unexpected error occurs after dispatch, ensure kickout is called (similar to finally/dispose pattern)
151
+
152
+ 2. **Chat message send/receive**
153
+ - `POST /api/v1/chat/send`
154
+ - Required fields: `sessionId`, `message`, `userId`, `requestId`
155
+ - `requestId` for idempotency (recommend UUID)
156
+ - Client-side validation: message length <= 10,000 chars, sessionId 3~100 chars
157
+ - Response parsing: extract `content`, `escalationReason`, `shouldTransferHuman`
158
+
159
+ 3. **Escalation handling**
160
+ - Detect `shouldTransferHuman: true`
161
+ - Handle by `escalationReason` (11 types):
162
+
163
+ | Code | Name | Recommended Action |
164
+ |------|------|-------------------|
165
+ | 1 | ConsecutiveUnableToAnswer | Transfer to agent + attach conversation summary |
166
+ | 2 | SpecialKeyword | Route to designated department |
167
+ | 3 | EmotionalAnomaly | Priority transfer + flag as high-sensitivity |
168
+ | 4 | DuplicateQuestion | Transfer to agent + flag as repeated |
169
+ | 5 | TurnLimitExceeded | Transfer to agent + inform user |
170
+ | 6 | HateSpeech | Escalate to supervisor + log incident |
171
+ | 7 | PersonalDataVerification | Route to identity verification flow |
172
+ | 8 | VendorKeyword | Handle per vendor-defined logic |
173
+ | 9 | AllAiProvidersInactive | Transfer to agent + inform AI unavailable |
174
+ | 10 | ToolsError | Transfer to agent + log tool failure |
175
+ | 11 | AiDeterminedEscalation | Transfer to agent |
176
+
177
+ - Generate EscalationHandler interface (vendor implements their own transfer logic)
178
+
179
+ 4. **Chat history**
180
+ - `GET /api/v1/chat/history/{sessionId}` — retrieve conversation history
181
+ - Useful for attaching context when transferring to human agent
182
+
183
+ 5. **Logging**
184
+ - Log each send: correlation ID, session ID, duration, status
185
+ - Log escalation events (including reason)
186
+ - Log session lifecycle (create/close/error)
187
+
188
+ ### Output
189
+ - SessionManager module
190
+ - ChatService module
191
+ - EscalationHandler interface + default implementation
192
+ - All related DTOs
193
+ - Client-side validation logic
194
+
195
+ ### Gate
196
+ User confirms full chat flow works correctly before entering Phase 3.
197
+
198
+ ---
199
+
200
+ ## Phase 3: Error Handling & Resilience
201
+
202
+ ### Goal
203
+ Build a unified error handling framework covering client validation, server business errors, and infrastructure errors.
204
+
205
+ ### Knowledge Source
206
+ - Spec 2.2: Standard responses and error codes
207
+ - Spec 6.3: Complete error code reference (8 categories)
208
+ - Spec 2.2.3: Request timeout (60 seconds)
209
+
210
+ ### Steps
211
+
212
+ 1. **Unified API response parser**
213
+ - Standard structure: `{ isSuccess, data, error: { code, message, details, reference } }`
214
+ - Abstract `ApiResponse<T>` generic class
215
+ - All API calls go through this parser
216
+
217
+ 2. **Three-layer error classification**
218
+
219
+ **Layer 1: Client-side Validation (pre-call interception)**
220
+ - sessionId length 3~100 (CHAT_014/015)
221
+ - message non-empty + length <= 10,000 (CHAT_003/013)
222
+ - requestId GUID format (CHAT_011)
223
+ - userId length <= 100 (CHAT_016)
224
+ - Basic XSS/SQLi pattern detection (INPUT_005/006)
225
+
226
+ **Layer 2: Server Business Error (API-returned business errors)**
227
+ - Classify handling strategy by error code prefix:
228
+
229
+ | Prefix | Category | Strategy |
230
+ |--------|----------|----------|
231
+ | AUTH_ | Auth error | Token refresh + retry / escalate |
232
+ | TENANT_ | Tenant error | No retry, notify admin |
233
+ | CHATBOT_ | Session error | Re-dispatch / escalate |
234
+ | CHAT_ | Chat error | Handle per specific code |
235
+ | INPUT_ | Validation error | Fix input + retry / report to user |
236
+ | ANALYSIS_ | Analysis error | Retry later / ignore |
237
+ | AI_PROVIDER_ | AI error | Fallback to human transfer |
238
+ | SYSTEM_ | System error | Retry + escalate |
239
+
240
+ **Layer 3: Infrastructure Error (network / timeout / unexpected exceptions)**
241
+ - HTTP timeout (60s) -> retry
242
+ - Connection refused -> retry + circuit breaker
243
+ - 5xx -> retry (max 3)
244
+ - Unexpected exceptions -> log + fallback response
245
+
246
+ 3. **Retry & Resilience strategy**
247
+ - Retry: exponential backoff (1s -> 2s -> 4s), max 3 attempts
248
+ - Circuit breaker: 5 consecutive failures -> open for 30 seconds
249
+ - Timeout: 60 seconds per request
250
+ - Fallback: degraded response when all APIs are unavailable
251
+ - Generate language-specific implementation (Python: tenacity, Java: Resilience4j, C#: Polly, Node.js: cockatiel)
252
+
253
+ 4. **Custom exception hierarchy**
254
+ - `ChatbotApiException` (base)
255
+ - `AuthenticationException`
256
+ - `SessionException`
257
+ - `ChatException`
258
+ - `ValidationException`
259
+ - Each exception carries `errorCode`, `message`, `details`
260
+
261
+ 5. **Logging**
262
+ - Log every error: error code, HTTP status, retry count, correlation ID
263
+ - Log circuit breaker state changes
264
+ - Log retry events
265
+
266
+ ### Output
267
+ - `ApiResponse<T>` unified parser module
268
+ - Client-side validator
269
+ - Error handler (three-layer classification logic)
270
+ - Retry / circuit breaker configuration
271
+ - Custom exception class hierarchy
272
+ - Error code lookup table (code -> handling strategy)
273
+
274
+ ### Gate
275
+ User confirms error handling framework is complete before entering Phase 4.
276
+
277
+ ---
278
+
279
+ ## Phase 4: Advanced Features (Optional)
280
+
281
+ ### Goal
282
+ Implement Chat Analysis integration and MCP Server development guide based on vendor needs.
283
+
284
+ ### T9: Chat Analysis Integration
285
+
286
+ #### Knowledge Source
287
+ - Spec 4.1~4.2: Chat Analysis flow and APIs
288
+
289
+ #### Steps
290
+
291
+ 1. **Submit analysis request**
292
+ - `POST /api/v1/analysis/create`
293
+ - Assemble `conversationMessages` (role: customer/cs/system)
294
+ - Assemble `categories` (id + description)
295
+ - Assemble `metadata` (userId, startTime, endTime, messageCount)
296
+ - Validation: at least 1 message, chronological order, timestamps cannot be in the future
297
+
298
+ 2. **Poll analysis result**
299
+ - `GET /api/v1/analysis/{sessionId}`
300
+ - Handle statuses: `pending` -> `processing` -> `completed` / `failed`
301
+ - Polling strategy: initial 5s -> increment to 30s -> max polling duration 10 min
302
+ - 202 (processing) -> continue polling
303
+ - 200 (completed) -> parse `summary` (overview, resolution, categories)
304
+
305
+ 3. **Error handling**
306
+ - `ANALYSIS_001` (not found) -> verify create was called
307
+ - `ANALYSIS_011` (in progress) -> wait for completion
308
+ - `ANALYSIS_009`/`ANALYSIS_010` -> fix input data
309
+
310
+ ### T10: MCP Server Development Guide
311
+
312
+ #### Knowledge Source
313
+ - Spec 5.1~5.4: Complete MCP Server specification
314
+
315
+ #### Steps
316
+
317
+ 1. **MCP Server architecture overview**
318
+ - Streamable HTTP transport
319
+ - Stateless design principle
320
+ - JWT authentication
321
+
322
+ 2. **Tool definition conventions**
323
+ - snake_case naming, verb-first
324
+ - Description 50~200 chars, include use cases
325
+ - Structured return values (no plain text)
326
+ - Parameter Description is strongly recommended
327
+
328
+ 3. **Example code**
329
+ - Generate MCP Server skeleton per vendor language
330
+ - C# reference: spec section 6.1
331
+ - Other languages: generate via MCP SDK
332
+
333
+ 4. **Security configuration**
334
+ - JWT verification (HS256)
335
+ - Custom Headers support
336
+ - HTTPS enforcement
337
+
338
+ ### Gate
339
+ User confirms advanced features are complete or skipped before entering Phase 5.
340
+
341
+ ---
342
+
343
+ ## Phase 5: Acceptance
344
+
345
+ ### Goal
346
+ Generate integration test checklist and debug handbook so vendors can self-diagnose issues.
347
+
348
+ ### T11: Integration Test Checklist
349
+
350
+ Generate test cases per API endpoint:
351
+
352
+ ```
353
+ Auth
354
+ [ ] Valid API Key -> obtain token
355
+ [ ] Invalid API Key -> AUTH_004
356
+ [ ] Expired token -> auto-refresh succeeds
357
+
358
+ Session
359
+ [ ] dispatch -> obtain sessionId
360
+ [ ] Duplicate dispatch (same sessionId) -> no extra quota consumed
361
+ [ ] Quota full -> CHATBOT_001
362
+ [ ] kickout -> graceful close
363
+ [ ] kickout non-existent session -> CHATBOT_002
364
+
365
+ Chat
366
+ [ ] send message -> receive AI response
367
+ [ ] Empty message -> CHAT_003
368
+ [ ] Oversized message -> CHAT_013
369
+ [ ] send without dispatch -> CHAT_019
370
+ [ ] Escalation triggered -> shouldTransferHuman = true
371
+
372
+ Resilience
373
+ [ ] API timeout -> auto-retry
374
+ [ ] Mid-request token expiry -> auto-refresh + retry
375
+ [ ] Consecutive failures -> circuit breaker activates
376
+
377
+ Analysis (if enabled)
378
+ [ ] create -> 200 OK
379
+ [ ] Duplicate create -> 202 Accepted
380
+ [ ] get result (processing) -> continue polling
381
+ [ ] get result (completed) -> parse summary
382
+ ```
383
+
384
+ ### T12: Debug Handbook
385
+
386
+ 1. **Error code quick reference**
387
+ - Generated from spec 6.3: error code -> cause -> troubleshooting steps -> solution
388
+
389
+ 2. **Common issues FAQ**
390
+ - "Token keeps expiring" -> check clock sync / proactive refresh mechanism
391
+ - "dispatch always returns CHATBOT_001" -> check for un-closed sessions (kickout)
392
+ - "send returns CHAT_019" -> must dispatch first
393
+ - "AI keeps transferring to human" -> check escalationReason, may be GuardRail or emotion detection
394
+
395
+ 3. **Log analysis guide**
396
+ - How to trace a full request chain using correlation ID
397
+ - How to distinguish client-side vs server-side issues
398
+ - How to locate retry / timeout / circuit breaker events from logs
399
+
400
+ 4. **Self-service troubleshooting flowchart**
401
+ ```
402
+ Issue occurs
403
+ -> Check errorCode
404
+ -> Look up in error code quick reference
405
+ -> Follow troubleshooting steps
406
+ -> Check related logs (filter by correlationId)
407
+ -> Determine which layer (client / server / network)
408
+ -> Apply corresponding solution
409
+ ```
410
+
411
+ ### Output
412
+ - Integration test checklist (exportable markdown)
413
+ - Debug handbook (error code reference, FAQ, log analysis guide)
414
+ - Self-service troubleshooting flowchart
415
+
416
+ ### Gate
417
+ All phases complete.
418
+
419
+ ---
420
+
421
+ ## Completion Summary
422
+
423
+ After all Phases are complete, output final summary:
424
+
425
+ ```
426
+ Chatbot Integration Complete
427
+ =============================
428
+ Language: [language]
429
+ Scope: [Chatbot / Analysis / MCP Server]
430
+ Modules:
431
+ - AuthService done
432
+ - SessionManager done
433
+ - ChatService done
434
+ - EscalationHandler done
435
+ - ErrorHandler done
436
+ - Retry/Resilience done
437
+ - Logger done
438
+ - Analysis (optional) done / skipped
439
+ - MCP Server (optional)done / skipped
440
+
441
+ Deliverables:
442
+ - Integration Test Checklist
443
+ - Debug Handbook
444
+ - Error Code Quick Reference
445
+ ```
446
+
447
+ ---
448
+
449
+ ## Resources
450
+
451
+ - `resources/integration-playbook.md` — Language-specific implementation templates and code samples
452
+ - `resources/chatbot_integration_spec.pdf` — API integration spec (v0.7)
@@ -0,0 +1,625 @@
1
+ # Integration Playbook
2
+
3
+ Language-specific implementation templates for AI Chatbot API integration.
4
+
5
+ > **Usage:** This playbook is referenced by `SKILL.md`. During each Phase, generate code based on the vendor's confirmed language and framework. The templates below provide structural patterns — adapt naming, style, and conventions to match the vendor's codebase.
6
+
7
+ ---
8
+
9
+ ## 1. HTTP Client Base Wrapper
10
+
11
+ All API calls should go through a centralized HTTP client that handles:
12
+ - Base URL configuration
13
+ - Authorization header injection
14
+ - Standard response parsing
15
+ - Correlation ID propagation
16
+ - Timeout enforcement (60s default)
17
+
18
+ ### Python (httpx)
19
+
20
+ ```python
21
+ import httpx
22
+ import uuid
23
+ from dataclasses import dataclass
24
+ from typing import TypeVar, Generic, Optional
25
+
26
+ T = TypeVar("T")
27
+
28
+ @dataclass
29
+ class ApiError:
30
+ code: str
31
+ message: str
32
+ details: Optional[str] = None
33
+ reference: Optional[str] = None
34
+
35
+ @dataclass
36
+ class ApiResponse(Generic[T]):
37
+ is_success: bool
38
+ data: Optional[T] = None
39
+ error: Optional[ApiError] = None
40
+
41
+ class ChatbotHttpClient:
42
+ def __init__(self, base_url: str, auth_service):
43
+ self._base_url = base_url.rstrip("/")
44
+ self._auth = auth_service
45
+ self._client = httpx.AsyncClient(timeout=60.0)
46
+
47
+ async def request(self, method: str, path: str, **kwargs) -> dict:
48
+ token = await self._auth.get_token()
49
+ headers = {
50
+ "Authorization": f"Bearer {token}",
51
+ "X-Correlation-Id": str(uuid.uuid4()),
52
+ **kwargs.pop("headers", {}),
53
+ }
54
+ response = await self._client.request(
55
+ method, f"{self._base_url}{path}", headers=headers, **kwargs
56
+ )
57
+ response.raise_for_status()
58
+ return response.json()
59
+ ```
60
+
61
+ ### Java (OkHttp)
62
+
63
+ ```java
64
+ public class ChatbotHttpClient {
65
+ private final String baseUrl;
66
+ private final AuthService authService;
67
+ private final OkHttpClient client;
68
+
69
+ public ChatbotHttpClient(String baseUrl, AuthService authService) {
70
+ this.baseUrl = baseUrl;
71
+ this.authService = authService;
72
+ this.client = new OkHttpClient.Builder()
73
+ .connectTimeout(60, TimeUnit.SECONDS)
74
+ .readTimeout(60, TimeUnit.SECONDS)
75
+ .build();
76
+ }
77
+
78
+ public <T> ApiResponse<T> request(String method, String path, Object body, Class<T> responseType) throws IOException {
79
+ String token = authService.getToken();
80
+ String correlationId = UUID.randomUUID().toString();
81
+
82
+ Request.Builder builder = new Request.Builder()
83
+ .url(baseUrl + path)
84
+ .header("Authorization", "Bearer " + token)
85
+ .header("X-Correlation-Id", correlationId);
86
+
87
+ // ... build request body, execute, parse response
88
+ }
89
+ }
90
+ ```
91
+
92
+ ### C# (HttpClient)
93
+
94
+ ```csharp
95
+ public class ChatbotHttpClient
96
+ {
97
+ private readonly HttpClient _httpClient;
98
+ private readonly IAuthService _authService;
99
+
100
+ public ChatbotHttpClient(HttpClient httpClient, IAuthService authService)
101
+ {
102
+ _httpClient = httpClient;
103
+ _authService = authService;
104
+ _httpClient.Timeout = TimeSpan.FromSeconds(60);
105
+ }
106
+
107
+ public async Task<ApiResponse<T>> RequestAsync<T>(HttpMethod method, string path, object? body = null)
108
+ {
109
+ var token = await _authService.GetTokenAsync();
110
+ var correlationId = Guid.NewGuid().ToString();
111
+
112
+ var request = new HttpRequestMessage(method, path);
113
+ request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
114
+ request.Headers.Add("X-Correlation-Id", correlationId);
115
+
116
+ if (body != null)
117
+ request.Content = JsonContent.Create(body);
118
+
119
+ var response = await _httpClient.SendAsync(request);
120
+ var content = await response.Content.ReadFromJsonAsync<ApiResponse<T>>();
121
+ return content!;
122
+ }
123
+ }
124
+ ```
125
+
126
+ ### Node.js (axios)
127
+
128
+ ```typescript
129
+ import axios, { AxiosInstance } from 'axios';
130
+ import { v4 as uuidv4 } from 'uuid';
131
+
132
+ interface ApiResponse<T> {
133
+ isSuccess: boolean;
134
+ data: T | null;
135
+ error: { code: string; message: string; details?: string; reference?: string } | null;
136
+ }
137
+
138
+ class ChatbotHttpClient {
139
+ private client: AxiosInstance;
140
+ private authService: AuthService;
141
+
142
+ constructor(baseUrl: string, authService: AuthService) {
143
+ this.authService = authService;
144
+ this.client = axios.create({
145
+ baseURL: baseUrl,
146
+ timeout: 60000,
147
+ });
148
+ }
149
+
150
+ async request<T>(method: string, path: string, data?: any): Promise<ApiResponse<T>> {
151
+ const token = await this.authService.getToken();
152
+ const response = await this.client.request<ApiResponse<T>>({
153
+ method,
154
+ url: path,
155
+ data,
156
+ headers: {
157
+ Authorization: `Bearer ${token}`,
158
+ 'X-Correlation-Id': uuidv4(),
159
+ },
160
+ });
161
+ return response.data;
162
+ }
163
+ }
164
+ ```
165
+
166
+ ---
167
+
168
+ ## 2. AuthService — Token Lifecycle
169
+
170
+ Key behaviors:
171
+ - Obtain token via `POST /api/v1/auth`
172
+ - Cache token in memory with `expiresAt`
173
+ - Auto-refresh 5 minutes before expiry
174
+ - Thread-safe (prevent concurrent refresh)
175
+
176
+ ### Python
177
+
178
+ ```python
179
+ import asyncio
180
+ from datetime import datetime, timezone, timedelta
181
+
182
+ class AuthService:
183
+ def __init__(self, base_url: str, api_key: str):
184
+ self._base_url = base_url
185
+ self._api_key = api_key
186
+ self._token: Optional[str] = None
187
+ self._expires_at: Optional[datetime] = None
188
+ self._lock = asyncio.Lock()
189
+
190
+ async def get_token(self) -> str:
191
+ if self._is_token_valid():
192
+ return self._token
193
+
194
+ async with self._lock:
195
+ # Double-check after acquiring lock
196
+ if self._is_token_valid():
197
+ return self._token
198
+ await self._refresh_token()
199
+ return self._token
200
+
201
+ def _is_token_valid(self) -> bool:
202
+ if not self._token or not self._expires_at:
203
+ return False
204
+ # Refresh 5 minutes before expiry
205
+ return datetime.now(timezone.utc) < self._expires_at - timedelta(minutes=5)
206
+
207
+ async def _refresh_token(self):
208
+ async with httpx.AsyncClient() as client:
209
+ response = await client.post(
210
+ f"{self._base_url}/api/v1/auth",
211
+ json={"apiKey": self._api_key},
212
+ )
213
+ response.raise_for_status()
214
+ data = response.json()["data"]
215
+ self._token = data["token"]
216
+ self._expires_at = datetime.fromisoformat(data["expiresAt"])
217
+ ```
218
+
219
+ ### C#
220
+
221
+ ```csharp
222
+ public class AuthService : IAuthService
223
+ {
224
+ private readonly string _baseUrl;
225
+ private readonly string _apiKey;
226
+ private readonly HttpClient _httpClient;
227
+ private readonly SemaphoreSlim _lock = new(1, 1);
228
+ private string? _token;
229
+ private DateTimeOffset? _expiresAt;
230
+
231
+ public async Task<string> GetTokenAsync()
232
+ {
233
+ if (IsTokenValid()) return _token!;
234
+
235
+ await _lock.WaitAsync();
236
+ try
237
+ {
238
+ if (IsTokenValid()) return _token!;
239
+ await RefreshTokenAsync();
240
+ return _token!;
241
+ }
242
+ finally { _lock.Release(); }
243
+ }
244
+
245
+ private bool IsTokenValid()
246
+ => _token != null && _expiresAt > DateTimeOffset.UtcNow.AddMinutes(5);
247
+
248
+ private async Task RefreshTokenAsync()
249
+ {
250
+ var response = await _httpClient.PostAsJsonAsync(
251
+ $"{_baseUrl}/api/v1/auth", new { apiKey = _apiKey });
252
+ response.EnsureSuccessStatusCode();
253
+ var result = await response.Content.ReadFromJsonAsync<ApiResponse<AuthData>>();
254
+ _token = result!.Data!.Token;
255
+ _expiresAt = result.Data.ExpiresAt;
256
+ }
257
+ }
258
+ ```
259
+
260
+ ---
261
+
262
+ ## 3. SessionManager
263
+
264
+ Key behaviors:
265
+ - `dispatch` -> create session (idempotent)
266
+ - Check quota via `usage` before dispatching
267
+ - `kickout` -> graceful close
268
+ - Cleanup guarantee (dispose/finally pattern)
269
+
270
+ ### Pattern (language-agnostic pseudocode)
271
+
272
+ ```
273
+ class SessionManager:
274
+ async dispatch(sessionId, timeZone?):
275
+ // 1. Check quota
276
+ usage = await client.GET("/api/v1/chatbot/usage")
277
+ if usage.isLimitReached:
278
+ throw QuotaExceededException
279
+
280
+ // 2. Dispatch
281
+ result = await client.POST("/api/v1/chatbot/dispatch", {sessionId, timeZone})
282
+ log("Session dispatched", {sessionId, remainingQuota: result.remainingQuota})
283
+ return result
284
+
285
+ async close(sessionId, reason?):
286
+ result = await client.POST("/api/v1/chatbot/kickout", {sessionId, reason})
287
+ log("Session closed", {sessionId})
288
+ return result
289
+
290
+ // Dispose pattern — ensure session is closed on error
291
+ async withSession(sessionId, callback):
292
+ try:
293
+ session = await dispatch(sessionId)
294
+ return await callback(session)
295
+ finally:
296
+ await close(sessionId, "auto-cleanup")
297
+ ```
298
+
299
+ ---
300
+
301
+ ## 4. ChatService
302
+
303
+ Key behaviors:
304
+ - Send message and parse response
305
+ - Detect escalation signals
306
+ - Client-side validation before sending
307
+
308
+ ### Pattern
309
+
310
+ ```
311
+ class ChatService:
312
+ async send(sessionId, message, userId, requestId?):
313
+ // 1. Client-side validation
314
+ validate(sessionId, message, userId)
315
+
316
+ // 2. Send
317
+ requestId = requestId ?? generateUUID()
318
+ result = await client.POST("/api/v1/chat/send", {
319
+ sessionId, message, userId, requestId
320
+ })
321
+
322
+ // 3. Check escalation
323
+ if result.shouldTransferHuman:
324
+ await escalationHandler.handle(sessionId, result.escalationReason, result.content)
325
+
326
+ return result
327
+
328
+ validate(sessionId, message, userId):
329
+ if len(sessionId) < 3 or len(sessionId) > 100:
330
+ throw ValidationException("CHAT_014/015", "sessionId length must be 3-100")
331
+ if not message or len(message) > 10000:
332
+ throw ValidationException("CHAT_003/013", "message required, max 10000 chars")
333
+ if len(userId) > 100:
334
+ throw ValidationException("CHAT_016", "userId max 100 chars")
335
+ ```
336
+
337
+ ---
338
+
339
+ ## 5. EscalationHandler
340
+
341
+ Interface pattern — vendor implements their own transfer logic.
342
+
343
+ ### C# Example
344
+
345
+ ```csharp
346
+ public interface IEscalationHandler
347
+ {
348
+ Task HandleAsync(string sessionId, int escalationReason, string aiMessage);
349
+ }
350
+
351
+ public class DefaultEscalationHandler : IEscalationHandler
352
+ {
353
+ public async Task HandleAsync(string sessionId, int escalationReason, string aiMessage)
354
+ {
355
+ // Fetch conversation history for context
356
+ var history = await _chatClient.GetHistoryAsync(sessionId);
357
+
358
+ switch (escalationReason)
359
+ {
360
+ case 3: // EmotionalAnomaly
361
+ await TransferWithPriority(sessionId, history, priority: "high");
362
+ break;
363
+ case 6: // HateSpeech
364
+ await EscalateToSupervisor(sessionId, history);
365
+ break;
366
+ case 7: // PersonalDataVerification
367
+ await RouteToVerificationFlow(sessionId, history);
368
+ break;
369
+ default:
370
+ await TransferToAgent(sessionId, history);
371
+ break;
372
+ }
373
+ }
374
+ }
375
+ ```
376
+
377
+ ---
378
+
379
+ ## 6. Error Handling Framework
380
+
381
+ ### ApiResponse<T> — Unified Response Parser
382
+
383
+ ```
384
+ class ApiResponse<T>:
385
+ isSuccess: bool
386
+ data: T?
387
+ error: ApiError?
388
+
389
+ class ApiError:
390
+ code: string // e.g. "AUTH_004"
391
+ message: string
392
+ details: string?
393
+ reference: string?
394
+ ```
395
+
396
+ ### Exception Hierarchy
397
+
398
+ ```
399
+ ChatbotApiException (base)
400
+ |-- AuthenticationException (AUTH_*)
401
+ |-- TenantException (TENANT_*)
402
+ |-- SessionException (CHATBOT_*)
403
+ |-- ChatException (CHAT_*)
404
+ |-- ValidationException (INPUT_*, VALIDATION_*)
405
+ |-- AnalysisException (ANALYSIS_*)
406
+ |-- AiProviderException (AI_PROVIDER_*)
407
+ |-- SystemException (SYSTEM_*)
408
+ ```
409
+
410
+ ### Error Code -> Strategy Mapping
411
+
412
+ ```
413
+ ERROR_CODE_STRATEGIES = {
414
+ # Auth — no retry (except network), escalate
415
+ "AUTH_001": {"retry": false, "action": "escalate"},
416
+ "AUTH_002": {"retry": false, "action": "re-authenticate"},
417
+ "AUTH_003": {"retry": true, "action": "retry_then_escalate"},
418
+ "AUTH_004": {"retry": false, "action": "escalate_invalid_key"},
419
+
420
+ # Tenant — no retry, admin notification
421
+ "TENANT_001": {"retry": false, "action": "notify_admin"},
422
+ "TENANT_003": {"retry": false, "action": "notify_admin"},
423
+
424
+ # Session — conditional retry
425
+ "CHATBOT_001": {"retry": false, "action": "check_quota_then_cleanup"},
426
+ "CHATBOT_002": {"retry": false, "action": "re_dispatch"},
427
+ "CHATBOT_003": {"retry": false, "action": "re_dispatch"},
428
+
429
+ # Chat — per-code handling
430
+ "CHAT_003": {"retry": false, "action": "fix_input"},
431
+ "CHAT_013": {"retry": false, "action": "truncate_message"},
432
+ "CHAT_019": {"retry": false, "action": "dispatch_first"},
433
+
434
+ # Input — fix and retry
435
+ "INPUT_005": {"retry": false, "action": "sanitize_input"},
436
+ "INPUT_006": {"retry": false, "action": "sanitize_input"},
437
+
438
+ # System — retry with backoff
439
+ "SYSTEM_001": {"retry": true, "action": "retry_then_escalate"},
440
+ }
441
+ ```
442
+
443
+ ---
444
+
445
+ ## 7. Retry & Resilience
446
+
447
+ ### Python (tenacity)
448
+
449
+ ```python
450
+ from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
451
+
452
+ @retry(
453
+ stop=stop_after_attempt(3),
454
+ wait=wait_exponential(multiplier=1, min=1, max=4),
455
+ retry=retry_if_exception_type((httpx.TimeoutException, httpx.NetworkError)),
456
+ )
457
+ async def call_with_retry(func, *args, **kwargs):
458
+ return await func(*args, **kwargs)
459
+ ```
460
+
461
+ ### C# (Polly)
462
+
463
+ ```csharp
464
+ var retryPolicy = Policy
465
+ .Handle<HttpRequestException>()
466
+ .Or<TaskCanceledException>()
467
+ .WaitAndRetryAsync(3, attempt => TimeSpan.FromSeconds(Math.Pow(2, attempt - 1)));
468
+
469
+ var circuitBreaker = Policy
470
+ .Handle<HttpRequestException>()
471
+ .CircuitBreakerAsync(5, TimeSpan.FromSeconds(30));
472
+
473
+ var resilience = Policy.WrapAsync(retryPolicy, circuitBreaker);
474
+ ```
475
+
476
+ ### Java (Resilience4j)
477
+
478
+ ```java
479
+ RetryConfig retryConfig = RetryConfig.custom()
480
+ .maxAttempts(3)
481
+ .waitDuration(Duration.ofSeconds(1))
482
+ .retryExceptions(IOException.class, TimeoutException.class)
483
+ .build();
484
+
485
+ CircuitBreakerConfig cbConfig = CircuitBreakerConfig.custom()
486
+ .failureRateThreshold(50)
487
+ .waitDurationInOpenState(Duration.ofSeconds(30))
488
+ .slidingWindowSize(5)
489
+ .build();
490
+ ```
491
+
492
+ ### Node.js (cockatiel)
493
+
494
+ ```typescript
495
+ import { retry, handleAll, ExponentialBackoff, circuitBreaker, SamplingBreaker, wrap } from 'cockatiel';
496
+
497
+ const retryPolicy = retry(handleAll, { maxAttempts: 3, backoff: new ExponentialBackoff() });
498
+ const breaker = circuitBreaker(handleAll, {
499
+ halfOpenAfter: 30 * 1000,
500
+ breaker: new SamplingBreaker({ threshold: 0.5, duration: 30 * 1000, minimumRps: 1 }),
501
+ });
502
+ const resilience = wrap(retryPolicy, breaker);
503
+ ```
504
+
505
+ ---
506
+
507
+ ## 8. Chat Analysis (Optional)
508
+
509
+ ### Polling Pattern
510
+
511
+ ```
512
+ class AnalysisService:
513
+ async createAnalysis(sessionId, messages, categories?, metadata?):
514
+ return await client.POST("/api/v1/analysis/create", {
515
+ sessionId, conversationMessages: messages, categories, metadata
516
+ })
517
+
518
+ async waitForResult(sessionId, maxWaitSeconds=600):
519
+ interval = 5 // start at 5 seconds
520
+ elapsed = 0
521
+
522
+ while elapsed < maxWaitSeconds:
523
+ result = await client.GET(f"/api/v1/analysis/{sessionId}")
524
+
525
+ if result.status == "completed":
526
+ return result.summary
527
+ if result.status == "failed":
528
+ throw AnalysisFailedException(result.message)
529
+
530
+ await sleep(interval)
531
+ elapsed += interval
532
+ interval = min(interval * 1.5, 30) // cap at 30 seconds
533
+
534
+ throw AnalysisTimeoutException(sessionId)
535
+ ```
536
+
537
+ ---
538
+
539
+ ## 9. Suggested Project Structures
540
+
541
+ ### Python
542
+ ```
543
+ chatbot_integration/
544
+ __init__.py
545
+ client.py # ChatbotHttpClient
546
+ auth.py # AuthService
547
+ session.py # SessionManager
548
+ chat.py # ChatService
549
+ escalation.py # EscalationHandler
550
+ analysis.py # AnalysisService (optional)
551
+ errors.py # Exception hierarchy + error strategies
552
+ models.py # DTOs / dataclasses
553
+ config.py # Configuration
554
+ tests/
555
+ test_auth.py
556
+ test_session.py
557
+ test_chat.py
558
+ ```
559
+
560
+ ### Java (Spring Boot)
561
+ ```
562
+ src/main/java/com/vendor/chatbot/
563
+ client/
564
+ ChatbotHttpClient.java
565
+ service/
566
+ AuthService.java
567
+ SessionManager.java
568
+ ChatService.java
569
+ EscalationHandler.java
570
+ AnalysisService.java
571
+ model/
572
+ ApiResponse.java
573
+ AuthData.java
574
+ ChatResponse.java
575
+ exception/
576
+ ChatbotApiException.java
577
+ (subclasses)
578
+ config/
579
+ ChatbotConfig.java
580
+ ResilienceConfig.java
581
+ ```
582
+
583
+ ### C# (ASP.NET Core)
584
+ ```
585
+ ChatbotIntegration/
586
+ Clients/
587
+ ChatbotHttpClient.cs
588
+ Services/
589
+ AuthService.cs
590
+ SessionManager.cs
591
+ ChatService.cs
592
+ IEscalationHandler.cs
593
+ AnalysisService.cs
594
+ Models/
595
+ ApiResponse.cs
596
+ DTOs/
597
+ Exceptions/
598
+ ChatbotApiException.cs
599
+ (subclasses)
600
+ Configuration/
601
+ ChatbotOptions.cs
602
+ DependencyInjection.cs
603
+ ```
604
+
605
+ ### Node.js (TypeScript)
606
+ ```
607
+ src/
608
+ client/
609
+ chatbot-http-client.ts
610
+ services/
611
+ auth.service.ts
612
+ session.service.ts
613
+ chat.service.ts
614
+ escalation.handler.ts
615
+ analysis.service.ts
616
+ models/
617
+ api-response.ts
618
+ dtos.ts
619
+ errors/
620
+ chatbot-api.error.ts
621
+ (subclasses)
622
+ config/
623
+ chatbot.config.ts
624
+ index.ts
625
+ ```