@bluefly/openstandardagents 0.2.7 → 0.2.9

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.
Files changed (327) hide show
  1. package/.devfile.yaml +1 -1
  2. package/.env.example +1 -1
  3. package/.github/AGENTS.md +245 -0
  4. package/.github/agents/github-issue-triage.ossa.yaml +99 -0
  5. package/.github/agents/github-pr-triage.ossa.yaml +137 -0
  6. package/.github/workflows/issue-sync-to-gitlab.yml +138 -0
  7. package/.github/workflows/pr-triage-to-gitlab.yml +164 -0
  8. package/.version.json +2 -2
  9. package/.wiki-config.json +24 -0
  10. package/CHANGELOG.md +44 -18
  11. package/CODEOWNERS +75 -0
  12. package/CONTRIBUTING.md +103 -4
  13. package/README.md +178 -243
  14. package/dist/index.d.ts +1 -0
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +2 -0
  17. package/dist/index.js.map +1 -1
  18. package/dist/repositories/schema.repository.d.ts +6 -1
  19. package/dist/repositories/schema.repository.d.ts.map +1 -1
  20. package/dist/repositories/schema.repository.js +49 -27
  21. package/dist/repositories/schema.repository.js.map +1 -1
  22. package/dist/services/migration.service.d.ts +4 -3
  23. package/dist/services/migration.service.d.ts.map +1 -1
  24. package/dist/services/migration.service.js +11 -10
  25. package/dist/services/migration.service.js.map +1 -1
  26. package/dist/services/release-automation/release.service.js +1 -1
  27. package/dist/services/release-automation/release.service.js.map +1 -1
  28. package/dist/services/release-automation/schemas/release.schema.js +1 -1
  29. package/dist/services/release-automation/webhook.service.js +3 -3
  30. package/dist/services/release-automation/webhook.service.js.map +1 -1
  31. package/dist/services/runtime/claude/claude-adapter.d.ts +1 -1
  32. package/dist/services/runtime/claude/claude-adapter.d.ts.map +1 -1
  33. package/dist/services/runtime/claude/claude-adapter.js +2 -2
  34. package/dist/services/runtime/claude/claude-adapter.js.map +1 -1
  35. package/dist/spec/v0.2.8/CHANGELOG.md +401 -0
  36. package/dist/spec/v0.2.8/README.md +72 -0
  37. package/dist/spec/v0.2.8/migrations/v0.2.3-to-v0.2.4.md +599 -0
  38. package/dist/spec/v0.2.8/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
  39. package/dist/spec/v0.2.8/migrations/v0.2.6-to-v0.2.8.md +81 -0
  40. package/{spec/v0.2.6-dev/ossa-0.2.5.schema.json → dist/spec/v0.2.8/ossa-0.2.8.schema.json} +1509 -52
  41. package/dist/spec/v0.2.8/ossa-0.2.8.yaml +581 -0
  42. package/dist/spec/v0.2.9/a2a-protocol.md +1337 -0
  43. package/dist/spec/v0.2.9/agent.md +1946 -0
  44. package/dist/spec/v0.2.9/capabilities/index.yaml +25 -0
  45. package/dist/spec/v0.2.9/capabilities/memory.yaml +251 -0
  46. package/dist/spec/v0.2.9/capability-schema.md +576 -0
  47. package/dist/spec/v0.2.9/compliance-profiles.md +533 -0
  48. package/dist/spec/v0.2.9/conformance-testing.md +1527 -0
  49. package/dist/spec/v0.2.9/gitlab-duo-integration.md +621 -0
  50. package/dist/spec/v0.2.9/ossa-0.2.9.schema.json +3699 -0
  51. package/dist/spec/v0.2.9/runtime-semantics.md +464 -0
  52. package/dist/spec/v0.2.9/security-model.md +1245 -0
  53. package/dist/spec/v0.2.9/semantic-conventions.md +347 -0
  54. package/dist/spec/v0.2.9/types.ts +522 -0
  55. package/dist/types/index.d.ts +3 -2
  56. package/dist/types/index.d.ts.map +1 -1
  57. package/dist/types/policy.d.ts +377 -0
  58. package/dist/types/policy.d.ts.map +1 -0
  59. package/dist/types/policy.js +84 -0
  60. package/dist/types/policy.js.map +1 -0
  61. package/dist/utils/index.d.ts +6 -0
  62. package/dist/utils/index.d.ts.map +1 -0
  63. package/dist/utils/index.js +6 -0
  64. package/dist/utils/index.js.map +1 -0
  65. package/dist/utils/version.d.ts +68 -0
  66. package/dist/utils/version.d.ts.map +1 -0
  67. package/dist/utils/version.js +156 -0
  68. package/dist/utils/version.js.map +1 -0
  69. package/docs/specs/policy-dsl.md +925 -0
  70. package/eslint-report.json +1 -0
  71. package/examples/adk-integration/code-review-workflow.yml +1 -1
  72. package/examples/adk-integration/customer-support.yml +1 -1
  73. package/examples/adk-integration/data-pipeline.yml +1 -1
  74. package/examples/advanced/reasoning-agent.yaml +136 -0
  75. package/examples/advanced/workflows/hybrid-model-strategy.yaml +1 -1
  76. package/examples/agent-manifests/critics/critic-agent.yaml +1 -1
  77. package/examples/agent-manifests/governors/governor-agent.yaml +1 -1
  78. package/examples/agent-manifests/integrators/integrator-agent.yaml +1 -1
  79. package/examples/agent-manifests/judges/judge-agent.yaml +1 -1
  80. package/examples/agent-manifests/monitors/monitor-agent.yaml +1 -1
  81. package/examples/agent-manifests/orchestrators/orchestrator-agent.yaml +1 -1
  82. package/examples/agent-manifests/sample-compliant-agent.yaml +1 -1
  83. package/examples/agent-manifests/workers/worker-agent.yaml +1 -1
  84. package/examples/agents-md/code-agent.ossa.json +100 -0
  85. package/examples/agents-md/monorepo-agent.ossa.yaml +180 -0
  86. package/examples/anthropic/claude-assistant.ossa.json +1 -1
  87. package/examples/autogen/multi-agent.ossa.json +1 -1
  88. package/examples/claude-code/code-reviewer.ossa.yaml +78 -0
  89. package/examples/claude-code/ossa-validator.ossa.yaml +80 -0
  90. package/examples/common_npm/agent-router.ossa.yaml +1 -0
  91. package/examples/common_npm/agent-router.v0.2.2.ossa.yaml +1 -1
  92. package/examples/crewai/research-team.ossa.json +1 -1
  93. package/examples/cursor/code-review-agent.ossa.json +1 -1
  94. package/examples/drupal/gitlab-ml-recommender.ossa.yaml +1 -0
  95. package/examples/drupal/gitlab-ml-recommender.v0.2.2.ossa.yaml +1 -1
  96. package/examples/extensions/agents-md-v1.yml +175 -0
  97. package/examples/extensions/drupal-v1.yml +1 -1
  98. package/examples/extensions/kagent-v1.yml +1 -1
  99. package/examples/getting-started/hello-world-complete.ossa.yaml +1 -1
  100. package/examples/integration-patterns/agent-to-agent-orchestration.ossa.yaml +4 -4
  101. package/examples/kagent/compliance-validator.ossa.yaml +1 -1
  102. package/examples/kagent/cost-optimizer.ossa.yaml +1 -1
  103. package/examples/kagent/documentation-agent.ossa.yaml +1 -1
  104. package/examples/kagent/k8s-troubleshooter-v1.ossa.yaml +1 -0
  105. package/examples/kagent/k8s-troubleshooter-v1.v0.2.2.ossa.yaml +1 -1
  106. package/examples/kagent/k8s-troubleshooter.ossa.yaml +1 -1
  107. package/examples/kagent/security-scanner.ossa.yaml +1 -1
  108. package/examples/langchain/chain-agent.ossa.json +1 -1
  109. package/examples/langflow/workflow-agent.ossa.json +1 -1
  110. package/examples/langgraph/state-machine-agent.ossa.json +1 -1
  111. package/examples/llamaindex/rag-agent.ossa.json +1 -1
  112. package/examples/migration-guides/from-langchain-to-ossa.yaml +4 -4
  113. package/examples/multi-agent/README.md +74 -0
  114. package/examples/multi-agent/conditional-router.ossa.yaml +42 -0
  115. package/examples/multi-agent/parallel-execution.ossa.yaml +54 -0
  116. package/examples/multi-agent/sequential-pipeline.ossa.yaml +45 -0
  117. package/examples/openai/basic-agent.ossa.yaml +1 -1
  118. package/examples/openai/multi-tool-agent.ossa.json +1 -1
  119. package/examples/openai/swarm-agent.ossa.json +1 -1
  120. package/examples/production/document-analyzer-openai.yml +1 -1
  121. package/examples/quickstart/support-agent.ossa.yaml +1 -1
  122. package/examples/spec-examples/audit-agent.yml +1 -1
  123. package/examples/spec-examples/chat-agent.yml +1 -1
  124. package/examples/spec-examples/compliance-agent.yml +1 -1
  125. package/examples/spec-examples/monitoring-agent.yml +1 -1
  126. package/examples/spec-examples/workflow-agent.yml +1 -1
  127. package/examples/templates/ossa-compliance.yaml +1 -1
  128. package/examples/vercel/edge-agent.ossa.json +1 -1
  129. package/gl-code-quality-report.json +62 -0
  130. package/llms-ctx-full.txt +39 -0
  131. package/llms-ctx.txt +39 -0
  132. package/llms.txt +47 -0
  133. package/package.json +6 -3
  134. package/scripts/README.md +25 -0
  135. package/scripts/compliance-audit.ts +796 -0
  136. package/scripts/eslint-to-codequality.cjs +34 -0
  137. package/scripts/generate-agents-catalog.ts +2 -1
  138. package/scripts/generate-api-docs.ts +2 -1
  139. package/scripts/generate-examples-docs.ts +2 -1
  140. package/scripts/generate-llms-ctx.sh +17 -0
  141. package/scripts/generate-schema-docs.ts +31 -10
  142. package/scripts/sync-version.js +4 -12
  143. package/scripts/validate-schema.ts +2 -1
  144. package/spec/v0.2.8/CHANGELOG.md +401 -0
  145. package/spec/v0.2.8/README.md +72 -0
  146. package/spec/v0.2.8/migrations/v0.2.3-to-v0.2.4.md +599 -0
  147. package/spec/v0.2.8/migrations/v0.2.5-RC-to-v0.2.6.md +65 -0
  148. package/spec/v0.2.8/migrations/v0.2.6-to-v0.2.8.md +81 -0
  149. package/spec/{v0.2.6-dev/ossa-0.2.6-dev.schema.json → v0.2.8/ossa-0.2.8.schema.json} +1509 -52
  150. package/spec/v0.2.8/ossa-0.2.8.yaml +581 -0
  151. package/spec/v0.2.9/a2a-protocol.md +1337 -0
  152. package/spec/v0.2.9/agent.md +1946 -0
  153. package/spec/v0.2.9/capabilities/index.yaml +25 -0
  154. package/spec/v0.2.9/capabilities/memory.yaml +251 -0
  155. package/spec/v0.2.9/capability-schema.md +576 -0
  156. package/spec/v0.2.9/compliance-profiles.md +533 -0
  157. package/spec/v0.2.9/conformance-testing.md +1527 -0
  158. package/spec/v0.2.9/gitlab-duo-integration.md +621 -0
  159. package/spec/v0.2.9/ossa-0.2.9.schema.json +3699 -0
  160. package/spec/v0.2.9/runtime-semantics.md +464 -0
  161. package/spec/v0.2.9/security-model.md +1245 -0
  162. package/spec/v0.2.9/semantic-conventions.md +347 -0
  163. package/spec/v0.2.9/types.ts +522 -0
  164. package/test-results/junit.xml +337 -0
  165. package/.github/workflows/pr-comment.yml +0 -33
  166. package/bin/validate-ossa-0.2.5-RC.ts +0 -244
  167. package/dist/spec/v0.2.6-dev/ossa-0.2.5.schema.json +0 -1696
  168. package/dist/spec/v0.2.6-dev/ossa-0.2.6-dev.schema.json +0 -1696
  169. package/scripts/lib/exec.ts +0 -37
  170. package/scripts/lib/file-ops.ts +0 -58
  171. package/scripts/lib/version.ts +0 -83
  172. package/website/.lighthouserc.ts +0 -24
  173. package/website/.prettierrc +0 -10
  174. package/website/DESIGN_SYSTEM_IMPLEMENTATION.md +0 -445
  175. package/website/Dockerfile +0 -30
  176. package/website/app/about/page.tsx +0 -304
  177. package/website/app/blog/[slug]/page.tsx +0 -208
  178. package/website/app/blog/page.tsx +0 -249
  179. package/website/app/design-guide/page.tsx +0 -511
  180. package/website/app/docs/[[...slug]]/page.tsx +0 -847
  181. package/website/app/docs/core-concepts/project-structure/page.tsx +0 -349
  182. package/website/app/ecosystem/page.tsx +0 -410
  183. package/website/app/examples/page.tsx +0 -133
  184. package/website/app/globals.scss +0 -370
  185. package/website/app/layout.tsx +0 -106
  186. package/website/app/license/page.tsx +0 -183
  187. package/website/app/not-found.tsx +0 -18
  188. package/website/app/page.tsx +0 -686
  189. package/website/app/page.tsx.bak +0 -679
  190. package/website/app/page.tsx.bak2 +0 -649
  191. package/website/app/playground/page.tsx +0 -487
  192. package/website/app/robots.ts +0 -19
  193. package/website/app/rss.xml/route.ts +0 -74
  194. package/website/app/schema/page.tsx +0 -1001
  195. package/website/app/sitemap.ts +0 -56
  196. package/website/app/specification/page.tsx +0 -287
  197. package/website/components/InstallCommand.tsx +0 -96
  198. package/website/components/Logo.tsx +0 -97
  199. package/website/components/StructuredData.tsx +0 -65
  200. package/website/components/docs/DocsSearch.tsx +0 -104
  201. package/website/components/docs/DocsSidebar.tsx +0 -155
  202. package/website/components/docs/MarkdownContent.tsx +0 -401
  203. package/website/components/docs/VersionSelector.tsx +0 -105
  204. package/website/components/examples/ExamplesViewer.tsx +0 -293
  205. package/website/components/layout/Footer.tsx +0 -116
  206. package/website/components/layout/Header.tsx +0 -172
  207. package/website/components/schema/SchemaComponentsAccordion.tsx +0 -84
  208. package/website/components/schema/SchemaExplorer.tsx +0 -213
  209. package/website/components/ui/Badge.tsx +0 -82
  210. package/website/components/ui/Button.tsx +0 -116
  211. package/website/components/ui/Card.tsx +0 -167
  212. package/website/components/ui/Checkbox.tsx +0 -141
  213. package/website/components/ui/Input.tsx +0 -169
  214. package/website/components/ui/Radio.tsx +0 -141
  215. package/website/components/ui/Select.tsx +0 -182
  216. package/website/components/ui/Tag.tsx +0 -158
  217. package/website/components/ui/Textarea.tsx +0 -195
  218. package/website/components/ui/index.ts +0 -11
  219. package/website/content/blog/OpenAPI-AI-Agents-Standard.md +0 -285
  220. package/website/content/blog/Why-Formal-Standards-Matter-Now.md +0 -198
  221. package/website/content/blog/gitlab-kubernetes-agent-ecosystem.md +0 -286
  222. package/website/content/blog/introducing-ossa-framework.md +0 -328
  223. package/website/content/blog/ossa-production-results.md +0 -279
  224. package/website/content/blog/welcome-to-ossa.md +0 -43
  225. package/website/content/blog/why-ai-agents-need-open-standard.md +0 -98
  226. package/website/content/docs/00-home.md +0 -153
  227. package/website/content/docs/adapters/openai-adapter.md +0 -693
  228. package/website/content/docs/agents/catalog.md +0 -28
  229. package/website/content/docs/aiflow-framework-integration-with-ossa.md +0 -107
  230. package/website/content/docs/api-reference/index.md +0 -38
  231. package/website/content/docs/api-reference/ossa-core-api.md +0 -634
  232. package/website/content/docs/api-reference/ossa-registry-api.md +0 -515
  233. package/website/content/docs/api-reference/unified-agent-gateway.md +0 -599
  234. package/website/content/docs/architecture/execution-flow.md +0 -335
  235. package/website/content/docs/architecture/multi-agent-systems.md +0 -737
  236. package/website/content/docs/architecture/overview.md +0 -121
  237. package/website/content/docs/architecture/stack-integration.md +0 -461
  238. package/website/content/docs/changelog.md +0 -246
  239. package/website/content/docs/cli-reference/index.md +0 -111
  240. package/website/content/docs/cli-reference/ossa-agents.md +0 -70
  241. package/website/content/docs/cli-reference/ossa-export.md +0 -56
  242. package/website/content/docs/cli-reference/ossa-generate.md +0 -66
  243. package/website/content/docs/cli-reference/ossa-gitlab-agent.md +0 -57
  244. package/website/content/docs/cli-reference/ossa-import.md +0 -56
  245. package/website/content/docs/cli-reference/ossa-init.md +0 -57
  246. package/website/content/docs/cli-reference/ossa-migrate.md +0 -62
  247. package/website/content/docs/cli-reference/ossa-run.md +0 -66
  248. package/website/content/docs/cli-reference/ossa-schema.md +0 -57
  249. package/website/content/docs/cli-reference/ossa-setup.md +0 -57
  250. package/website/content/docs/cli-reference/ossa-validate.md +0 -66
  251. package/website/content/docs/configuration/index.md +0 -97
  252. package/website/content/docs/contributing.md +0 -599
  253. package/website/content/docs/deployment/github-mirroring.md +0 -924
  254. package/website/content/docs/documentation.md +0 -100
  255. package/website/content/docs/ecosystem/framework-support.md +0 -1361
  256. package/website/content/docs/ecosystem/overview.md +0 -366
  257. package/website/content/docs/errors/index.md +0 -10
  258. package/website/content/docs/examples/aiflow-framework-integration-with-ossa.md +0 -107
  259. package/website/content/docs/examples/catalog.md +0 -300
  260. package/website/content/docs/for-audiences/students-researchers.md +0 -122
  261. package/website/content/docs/getting-started/index.md +0 -92
  262. package/website/content/docs/getting-started/installation.md +0 -155
  263. package/website/content/docs/getting-started/running-agents.md +0 -309
  264. package/website/content/docs/getting-started.md +0 -91
  265. package/website/content/docs/integrations/aiflow.md +0 -104
  266. package/website/content/docs/integrations/drupal.md +0 -105
  267. package/website/content/docs/migration-guides/agent-schema-comparison.md +0 -232
  268. package/website/content/docs/migration-guides/anthropic-mcp-to-ossa.md +0 -1750
  269. package/website/content/docs/migration-guides/crewai-to-ossa.md +0 -274
  270. package/website/content/docs/migration-guides/drupal-eca-to-ossa.md +0 -2017
  271. package/website/content/docs/migration-guides/general-agent-schema.yml +0 -247
  272. package/website/content/docs/migration-guides/index.md +0 -133
  273. package/website/content/docs/migration-guides/langchain-to-ossa.md +0 -1714
  274. package/website/content/docs/migration-guides/langflow-to-ossa.md +0 -2075
  275. package/website/content/docs/migration-guides/migration-manifest.json +0 -64
  276. package/website/content/docs/migration-guides/openai-to-ossa.md +0 -1202
  277. package/website/content/docs/openapi-extensions/examples.md +0 -550
  278. package/website/content/docs/openapi-extensions/index.md +0 -551
  279. package/website/content/docs/openapi-extensions/operation-extensions.md +0 -457
  280. package/website/content/docs/openapi-extensions/root-extensions.md +0 -410
  281. package/website/content/docs/ossa-compliant-badge.md +0 -251
  282. package/website/content/docs/pre-release/index.md +0 -175
  283. package/website/content/docs/quick-reference.md +0 -17
  284. package/website/content/docs/readme.md +0 -35
  285. package/website/content/docs/releases/v0.2.6.md +0 -99
  286. package/website/content/docs/schema-reference/agent-capabilities.md +0 -50
  287. package/website/content/docs/schema-reference/agent-id.md +0 -52
  288. package/website/content/docs/schema-reference/agent-name.md +0 -50
  289. package/website/content/docs/schema-reference/agent-role.md +0 -54
  290. package/website/content/docs/schema-reference/agent-spec.md +0 -406
  291. package/website/content/docs/schema-reference/agent-version.md +0 -50
  292. package/website/content/docs/schema-reference/autonomy.md +0 -568
  293. package/website/content/docs/schema-reference/constraints.md +0 -543
  294. package/website/content/docs/schema-reference/index.md +0 -45
  295. package/website/content/docs/schema-reference/llm-config.md +0 -445
  296. package/website/content/docs/schema-reference/observability.md +0 -654
  297. package/website/content/docs/schema-reference/ossa-manifest.md +0 -309
  298. package/website/content/docs/schema-reference/taxonomy.md +0 -509
  299. package/website/content/docs/schema-reference/tools.md +0 -628
  300. package/website/content/docs/templates/blog-post.md +0 -43
  301. package/website/content/docs/types-reference/index.md +0 -105
  302. package/website/content/docs/use-cases/00-index.md +0 -395
  303. package/website/content/docs/use-cases/cicd-code-review.md +0 -1236
  304. package/website/content/docs/use-cases/customer-support.md +0 -1234
  305. package/website/content/docs/use-cases/enterprise-compliance.md +0 -1208
  306. package/website/content/docs/use-cases/research-multi-agent.md +0 -1161
  307. package/website/content/docs/versioning.md +0 -288
  308. package/website/dev.sh +0 -53
  309. package/website/docker-compose.dev.yml +0 -36
  310. package/website/lib/version.ts +0 -35
  311. package/website/lib/versions.json +0 -103
  312. package/website/next.config.ts +0 -18
  313. package/website/nginx.conf +0 -32
  314. package/website/package-lock.json +0 -9679
  315. package/website/package.json +0 -59
  316. package/website/postcss.config.mjs +0 -9
  317. package/website/scripts/fetch-versions.js +0 -166
  318. package/website/scripts/generate-examples-index.js +0 -163
  319. package/website/scripts/merge-docs-to-wiki.ts +0 -207
  320. package/website/scripts/sync-version.js +0 -72
  321. package/website/scripts/sync-wiki.ts +0 -322
  322. package/website/scripts/upload-wiki.ts +0 -199
  323. package/website/styles/_spacing.scss +0 -453
  324. package/website/styles/_tokens.scss +0 -245
  325. package/website/styles/_typography.scss +0 -361
  326. package/website/styles/_variables.scss +0 -287
  327. package/website/tailwind.config.ts +0 -170
@@ -1,1234 +0,0 @@
1
- # Customer Support Ticket Triage Agent
2
-
3
- ## Problem Statement
4
-
5
- Customer support teams face overwhelming ticket volumes:
6
- - **Response time bottlenecks**: Average first response time 4-8 hours
7
- - **Misrouted tickets**: 30% of tickets assigned to wrong team/person
8
- - **Inconsistent prioritization**: Critical issues buried under low-priority requests
9
- - **Knowledge gaps**: Support agents spend 40% of time searching for answers
10
- - **Escalation delays**: High-value customers wait in same queue as free-tier users
11
- - **No 24/7 coverage**: After-hours tickets pile up until next business day
12
-
13
- **Solution**: An OSSA-powered support agent that automatically triages tickets, assigns priority and routing, surfaces relevant knowledge base articles, suggests responses, and escalates critical issues to human agents—reducing response time from hours to seconds.
14
-
15
- ## Architecture Overview
16
-
17
- ```mermaid
18
- graph TB
19
- subgraph "Input Channels"
20
- Email[Email Support]
21
- Chat[Live Chat]
22
- Form[Web Form]
23
- API[API Tickets]
24
- end
25
-
26
- subgraph "Triage Agent"
27
- Classifier[Ticket Classifier]
28
- Priority[Priority Scorer]
29
- Router[Routing Engine]
30
- KB[Knowledge Base Search]
31
- Sentiment[Sentiment Analysis]
32
- end
33
-
34
- subgraph "AI Processing"
35
- LLM[GPT-4/Claude]
36
- Embeddings[Vector Embeddings]
37
- Intent[Intent Detection]
38
- Entity[Entity Extraction]
39
- end
40
-
41
- subgraph "Actions"
42
- AutoReply[Auto-Reply]
43
- Escalate[Escalate to Human]
44
- Assign[Assign to Team]
45
- Suggest[Suggest Response]
46
- end
47
-
48
- subgraph "Integrations"
49
- Zendesk[Zendesk]
50
- Intercom[Intercom]
51
- Slack[Slack Alerts]
52
- CRM[CRM Sync]
53
- end
54
-
55
- Email --> Classifier
56
- Chat --> Classifier
57
- Form --> Classifier
58
- API --> Classifier
59
-
60
- Classifier --> LLM
61
- Classifier --> Priority
62
- Classifier --> Router
63
- Classifier --> KB
64
-
65
- LLM --> Intent
66
- LLM --> Entity
67
- LLM --> Sentiment
68
-
69
- Priority --> AutoReply
70
- Priority --> Escalate
71
- Router --> Assign
72
- KB --> Suggest
73
-
74
- AutoReply --> Zendesk
75
- Escalate --> Slack
76
- Assign --> Zendesk
77
- Suggest --> Zendesk
78
- Assign --> CRM
79
-
80
- style Classifier fill:#e1f5ff
81
- style LLM fill:#ffe1f5
82
- style Escalate fill:#ffe1e1
83
- style AutoReply fill:#e1ffe1
84
- ```
85
-
86
- ## OSSA Manifest
87
-
88
- ```yaml
89
- apiVersion: ossa/v0.2.x
90
- kind: Agent
91
- metadata:
92
- name: support-triage-agent
93
- namespace: customer-support
94
- labels:
95
- app: support
96
- tier: customer-facing
97
- criticality: high
98
- annotations:
99
- support.ossa.io/sla-critical: "15m"
100
- support.ossa.io/sla-high: "2h"
101
- support.ossa.io/sla-normal: "24h"
102
- support.ossa.io/auto-reply-enabled: "true"
103
- cost.ossa.io/budget-monthly: "500.00"
104
-
105
- spec:
106
- type: worker
107
- description: |
108
- Intelligent customer support ticket triage agent.
109
- Automatically classifies, prioritizes, routes, and responds to
110
- customer support tickets with knowledge base integration.
111
-
112
- runtime:
113
- type: docker
114
- image: registry.example.com/agents/support-triage:2.5.0
115
- command: ["/app/triage-agent"]
116
- args:
117
- - "--mode=realtime"
118
- - "--auto-reply=smart"
119
- - "--escalation-threshold=0.85"
120
- resources:
121
- limits:
122
- cpu: "2000m"
123
- memory: "4Gi"
124
- requests:
125
- cpu: "500m"
126
- memory: "1Gi"
127
- env:
128
- - name: LOG_LEVEL
129
- value: "info"
130
- - name: AI_MODEL
131
- value: "gpt-4-turbo-preview"
132
- - name: KNOWLEDGE_BASE_PROVIDER
133
- value: "pinecone"
134
- - name: ENABLE_AUTO_REPLY
135
- value: "true"
136
- - name: ENABLE_SENTIMENT_ANALYSIS
137
- value: "true"
138
- - name: MAX_AUTO_REPLY_CONFIDENCE
139
- value: "0.95"
140
-
141
- capabilities:
142
- - name: triage_ticket
143
- description: |
144
- Comprehensive ticket triage including classification,
145
- prioritization, routing, knowledge base search, and
146
- response suggestion.
147
- input_schema:
148
- type: object
149
- required: [ticket_id, subject, body, customer_id]
150
- properties:
151
- ticket_id:
152
- type: string
153
- description: "Unique ticket identifier"
154
- subject:
155
- type: string
156
- description: "Ticket subject line"
157
- body:
158
- type: string
159
- description: "Full ticket content"
160
- customer_id:
161
- type: string
162
- description: "Customer identifier"
163
- customer_tier:
164
- type: string
165
- enum: [free, basic, pro, enterprise]
166
- default: basic
167
- channel:
168
- type: string
169
- enum: [email, chat, form, api, phone]
170
- default: email
171
- attachments:
172
- type: array
173
- items:
174
- type: object
175
- properties:
176
- filename: {type: string}
177
- url: {type: string}
178
- content_type: {type: string}
179
- metadata:
180
- type: object
181
- description: "Additional ticket metadata"
182
- output_schema:
183
- type: object
184
- required: [ticket_id, category, priority, routing, action]
185
- properties:
186
- ticket_id:
187
- type: string
188
- category:
189
- type: string
190
- enum: [
191
- billing,
192
- technical,
193
- feature_request,
194
- bug_report,
195
- account_management,
196
- general_inquiry,
197
- complaint,
198
- feedback
199
- ]
200
- subcategory:
201
- type: string
202
- priority:
203
- type: string
204
- enum: [critical, high, normal, low]
205
- priority_score:
206
- type: number
207
- minimum: 0
208
- maximum: 100
209
- routing:
210
- type: object
211
- required: [team, suggested_agent]
212
- properties:
213
- team:
214
- type: string
215
- enum: [billing, engineering, sales, success, general]
216
- suggested_agent:
217
- type: string
218
- skills_required:
219
- type: array
220
- items: {type: string}
221
- sentiment:
222
- type: object
223
- properties:
224
- score:
225
- type: number
226
- minimum: -1
227
- maximum: 1
228
- label:
229
- type: string
230
- enum: [very_negative, negative, neutral, positive, very_positive]
231
- angry:
232
- type: boolean
233
- frustrated:
234
- type: boolean
235
- intent:
236
- type: array
237
- items:
238
- type: string
239
- description: "Detected customer intents"
240
- entities:
241
- type: object
242
- description: "Extracted entities (product names, error codes, etc.)"
243
- knowledge_base_matches:
244
- type: array
245
- items:
246
- type: object
247
- properties:
248
- article_id: {type: string}
249
- title: {type: string}
250
- url: {type: string}
251
- relevance_score: {type: number}
252
- snippet: {type: string}
253
- suggested_response:
254
- type: string
255
- description: "AI-generated response suggestion"
256
- confidence:
257
- type: number
258
- minimum: 0
259
- maximum: 1
260
- description: "Confidence in triage decisions"
261
- action:
262
- type: string
263
- enum: [auto_reply, escalate, assign, pending_info]
264
- escalation_reason:
265
- type: string
266
- sla_deadline:
267
- type: string
268
- format: date-time
269
- tags:
270
- type: array
271
- items: {type: string}
272
- timestamp:
273
- type: string
274
- format: date-time
275
-
276
- - name: search_knowledge_base
277
- description: |
278
- Search knowledge base for relevant articles using
279
- semantic search with vector embeddings.
280
- input_schema:
281
- type: object
282
- required: [query]
283
- properties:
284
- query:
285
- type: string
286
- description: "Search query"
287
- category:
288
- type: string
289
- description: "Filter by category"
290
- limit:
291
- type: integer
292
- default: 5
293
- minimum: 1
294
- maximum: 20
295
- output_schema:
296
- type: object
297
- properties:
298
- results:
299
- type: array
300
- items:
301
- type: object
302
- required: [id, title, content, score]
303
- properties:
304
- id: {type: string}
305
- title: {type: string}
306
- content: {type: string}
307
- url: {type: string}
308
- category: {type: string}
309
- score: {type: number}
310
- last_updated: {type: string, format: date-time}
311
-
312
- - name: generate_response
313
- description: |
314
- Generate contextual response suggestion based on
315
- ticket content and knowledge base.
316
- input_schema:
317
- type: object
318
- required: [ticket_content, knowledge_articles]
319
- properties:
320
- ticket_content:
321
- type: string
322
- knowledge_articles:
323
- type: array
324
- items:
325
- type: object
326
- customer_history:
327
- type: array
328
- items:
329
- type: object
330
- tone:
331
- type: string
332
- enum: [professional, friendly, empathetic, concise]
333
- default: professional
334
- output_schema:
335
- type: object
336
- properties:
337
- response:
338
- type: string
339
- confidence:
340
- type: number
341
- reasoning:
342
- type: string
343
- follow_up_actions:
344
- type: array
345
- items: {type: string}
346
-
347
- - name: escalate_ticket
348
- description: |
349
- Escalate ticket to human agent with context and reasoning.
350
- input_schema:
351
- type: object
352
- required: [ticket_id, reason]
353
- properties:
354
- ticket_id:
355
- type: string
356
- reason:
357
- type: string
358
- enum: [
359
- high_value_customer,
360
- angry_customer,
361
- complex_issue,
362
- low_confidence,
363
- legal_concern,
364
- security_incident
365
- ]
366
- urgency:
367
- type: string
368
- enum: [immediate, high, normal]
369
- suggested_team:
370
- type: string
371
- context:
372
- type: string
373
- output_schema:
374
- type: object
375
- properties:
376
- escalated:
377
- type: boolean
378
- assigned_to:
379
- type: string
380
- notification_sent:
381
- type: boolean
382
- escalation_id:
383
- type: string
384
-
385
- - name: analyze_sentiment
386
- description: |
387
- Analyze customer sentiment and emotional tone.
388
- input_schema:
389
- type: object
390
- required: [text]
391
- properties:
392
- text:
393
- type: string
394
- output_schema:
395
- type: object
396
- properties:
397
- sentiment_score:
398
- type: number
399
- minimum: -1
400
- maximum: 1
401
- sentiment_label:
402
- type: string
403
- emotions:
404
- type: object
405
- properties:
406
- angry: {type: number}
407
- frustrated: {type: number}
408
- confused: {type: number}
409
- satisfied: {type: number}
410
- urgency_indicators:
411
- type: array
412
- items: {type: string}
413
-
414
- policies:
415
- sla:
416
- critical: 15 # minutes
417
- high: 120 # minutes
418
- normal: 1440 # minutes (24 hours)
419
- low: 2880 # minutes (48 hours)
420
-
421
- auto_reply:
422
- enabled: true
423
- conditions:
424
- min_confidence: 0.95
425
- max_complexity: low
426
- exclude_categories: [complaint, legal, security]
427
- exclude_tiers: [enterprise]
428
- exclude_angry_customers: true
429
- approval_required: false
430
- human_review_sample_rate: 0.10 # Review 10% of auto-replies
431
-
432
- escalation:
433
- automatic_triggers:
434
- - condition: customer_tier == "enterprise"
435
- action: escalate_immediately
436
- - condition: sentiment_score < -0.7
437
- action: escalate_to_senior
438
- - condition: contains_keywords("refund", "cancel", "lawyer")
439
- action: escalate_to_manager
440
- - condition: confidence < 0.6
441
- action: assign_to_human
442
- notification_channels:
443
- critical: [slack, email, sms]
444
- high: [slack, email]
445
- normal: [email]
446
-
447
- routing:
448
- teams:
449
- billing:
450
- keywords: [payment, invoice, refund, subscription, billing]
451
- skills: [payments, accounting]
452
- engineering:
453
- keywords: [bug, error, crash, not working, technical]
454
- skills: [debugging, api, integration]
455
- sales:
456
- keywords: [upgrade, pricing, demo, trial, enterprise]
457
- skills: [sales, product_knowledge]
458
- success:
459
- keywords: [onboarding, training, best practices]
460
- skills: [customer_success, training]
461
-
462
- cost_management:
463
- budget:
464
- monthly_limit_usd: 500.00
465
- per_ticket_limit_usd: 0.50
466
- alert_threshold: 0.85
467
- optimization:
468
- cache_kb_searches: true
469
- batch_processing: true
470
- use_cheaper_model_when_possible: true
471
-
472
- integration:
473
- protocol: webhook
474
- api_version: v1
475
-
476
- webhooks:
477
- zendesk:
478
- url: https://support-triage.example.com/webhooks/zendesk
479
- events:
480
- - ticket.created
481
- - ticket.updated
482
- secret_env: ZENDESK_WEBHOOK_SECRET
483
-
484
- intercom:
485
- url: https://support-triage.example.com/webhooks/intercom
486
- events:
487
- - conversation.created
488
- - conversation.admin.replied
489
- secret_env: INTERCOM_WEBHOOK_SECRET
490
-
491
- apis:
492
- zendesk:
493
- base_url: https://example.zendesk.com/api/v2
494
- auth:
495
- type: bearer
496
- token_env: ZENDESK_API_TOKEN
497
-
498
- intercom:
499
- base_url: https://api.intercom.io
500
- auth:
501
- type: bearer
502
- token_env: INTERCOM_ACCESS_TOKEN
503
-
504
- slack:
505
- base_url: https://slack.com/api
506
- auth:
507
- type: bearer
508
- token_env: SLACK_BOT_TOKEN
509
-
510
- endpoints:
511
- triage:
512
- path: /v1/triage/ticket
513
- method: POST
514
- rate_limit: 1000/hour
515
-
516
- search_kb:
517
- path: /v1/knowledge-base/search
518
- method: GET
519
- rate_limit: 5000/hour
520
-
521
- escalate:
522
- path: /v1/escalate
523
- method: POST
524
- rate_limit: 500/hour
525
-
526
- monitoring:
527
- health_check:
528
- endpoint: http://localhost:8080/health
529
- interval_seconds: 30
530
-
531
- metrics:
532
- enabled: true
533
- exporter: prometheus
534
- custom_metrics:
535
- - tickets_triaged_total
536
- - tickets_auto_replied_total
537
- - tickets_escalated_total
538
- - average_confidence_score
539
- - average_response_time_seconds
540
- - sla_compliance_rate
541
- - customer_satisfaction_score
542
-
543
- traces:
544
- enabled: true
545
- exporter: jaeger
546
-
547
- logs:
548
- level: info
549
- format: json
550
-
551
- metadata:
552
- version: 2.5.0
553
- author:
554
- name: Support Team
555
- email: support@example.com
556
- license: Proprietary
557
- tags:
558
- - customer-support
559
- - ticket-triage
560
- - automation
561
- - ai-assistant
562
- documentation_url: https://docs.example.com/agents/support-triage
563
- ```
564
-
565
- ## Implementation (TypeScript)
566
-
567
- ```typescript
568
- /**
569
- * Customer Support Ticket Triage Agent
570
- *
571
- * Production-ready OSSA agent for intelligent support ticket triage,
572
- * classification, routing, and automated responses.
573
- */
574
-
575
- import { Agent, OSSARuntime } from '@ossa/runtime';
576
- import { OpenAI } from 'openai';
577
- import { Pinecone } from '@pinecone-database/pinecone';
578
- import axios from 'axios';
579
-
580
- interface TriageInput {
581
- ticketId: string;
582
- subject: string;
583
- body: string;
584
- customerId: string;
585
- customerTier?: 'free' | 'basic' | 'pro' | 'enterprise';
586
- channel?: string;
587
- attachments?: Array<{filename: string; url: string; contentType: string}>;
588
- metadata?: Record<string, any>;
589
- }
590
-
591
- interface TriageResult {
592
- ticketId: string;
593
- category: string;
594
- subcategory?: string;
595
- priority: 'critical' | 'high' | 'normal' | 'low';
596
- priorityScore: number;
597
- routing: {
598
- team: string;
599
- suggestedAgent?: string;
600
- skillsRequired: string[];
601
- };
602
- sentiment: {
603
- score: number;
604
- label: string;
605
- angry: boolean;
606
- frustrated: boolean;
607
- };
608
- intent: string[];
609
- entities: Record<string, any>;
610
- knowledgeBaseMatches: Array<{
611
- articleId: string;
612
- title: string;
613
- url: string;
614
- relevanceScore: number;
615
- snippet: string;
616
- }>;
617
- suggestedResponse?: string;
618
- confidence: number;
619
- action: 'auto_reply' | 'escalate' | 'assign' | 'pending_info';
620
- escalationReason?: string;
621
- slaDeadline: Date;
622
- tags: string[];
623
- timestamp: Date;
624
- }
625
-
626
- export class SupportTriageAgent extends Agent {
627
- private openai: OpenAI;
628
- private pinecone: Pinecone;
629
- private zendeskBaseUrl: string;
630
- private zendeskToken: string;
631
-
632
- constructor(runtime: OSSARuntime) {
633
- super(runtime);
634
-
635
- this.openai = new OpenAI({
636
- apiKey: process.env.OPENAI_API_KEY,
637
- });
638
-
639
- this.pinecone = new Pinecone({
640
- apiKey: process.env.PINECONE_API_KEY || '',
641
- });
642
-
643
- this.zendeskBaseUrl = process.env.ZENDESK_BASE_URL || '';
644
- this.zendeskToken = process.env.ZENDESK_API_TOKEN || '';
645
- }
646
-
647
- /**
648
- * Main triage capability
649
- */
650
- async triageTicket(input: TriageInput): Promise<TriageResult> {
651
- const startTime = Date.now();
652
-
653
- this.logger.info(`Starting triage for ticket ${input.ticketId}`);
654
-
655
- try {
656
- // Run classification, sentiment, and KB search in parallel
657
- const [classification, sentiment, kbMatches] = await Promise.all([
658
- this.classifyTicket(input),
659
- this.analyzeSentiment(input.body),
660
- this.searchKnowledgeBase(input.subject + ' ' + input.body),
661
- ]);
662
-
663
- // Calculate priority
664
- const priority = this.calculatePriority({
665
- classification,
666
- sentiment,
667
- customerTier: input.customerTier || 'basic',
668
- });
669
-
670
- // Determine routing
671
- const routing = this.determineRouting(classification, input);
672
-
673
- // Extract intents and entities
674
- const { intent, entities } = await this.extractIntentAndEntities(input.body);
675
-
676
- // Generate response suggestion if confidence is high
677
- let suggestedResponse: string | undefined;
678
- let confidence = classification.confidence;
679
-
680
- if (confidence > 0.9 && kbMatches.length > 0) {
681
- suggestedResponse = await this.generateResponse({
682
- ticketContent: input.body,
683
- knowledgeArticles: kbMatches,
684
- tone: this.selectTone(sentiment),
685
- });
686
- }
687
-
688
- // Determine action
689
- const action = this.determineAction({
690
- confidence,
691
- sentiment,
692
- customerTier: input.customerTier,
693
- category: classification.category,
694
- });
695
-
696
- // Calculate SLA deadline
697
- const slaDeadline = this.calculateSlaDeadline(priority.level);
698
-
699
- // Build result
700
- const result: TriageResult = {
701
- ticketId: input.ticketId,
702
- category: classification.category,
703
- subcategory: classification.subcategory,
704
- priority: priority.level,
705
- priorityScore: priority.score,
706
- routing,
707
- sentiment,
708
- intent,
709
- entities,
710
- knowledgeBaseMatches: kbMatches,
711
- suggestedResponse,
712
- confidence,
713
- action,
714
- escalationReason: action === 'escalate' ? this.getEscalationReason(sentiment, input.customerTier) : undefined,
715
- slaDeadline,
716
- tags: this.generateTags(classification, sentiment, input),
717
- timestamp: new Date(),
718
- };
719
-
720
- // Execute action
721
- await this.executeAction(result);
722
-
723
- // Record metrics
724
- const duration = Date.now() - startTime;
725
- this.metrics.histogram('triage_duration_seconds', duration / 1000);
726
- this.metrics.counter('tickets_triaged_total', { category: result.category, action: result.action });
727
- this.metrics.gauge('average_confidence_score', confidence);
728
-
729
- this.logger.info(`Triage completed for ticket ${input.ticketId}: ${action}`);
730
-
731
- return result;
732
-
733
- } catch (error) {
734
- this.logger.error(`Triage failed for ticket ${input.ticketId}:`, error);
735
- this.metrics.counter('triage_errors_total');
736
- throw error;
737
- }
738
- }
739
-
740
- /**
741
- * Classify ticket using GPT-4
742
- */
743
- private async classifyTicket(input: TriageInput): Promise<{
744
- category: string;
745
- subcategory?: string;
746
- confidence: number;
747
- }> {
748
- const prompt = `
749
- Classify the following customer support ticket into one of these categories:
750
- - billing (payment issues, invoices, refunds, subscriptions)
751
- - technical (bugs, errors, crashes, not working)
752
- - feature_request (new features, enhancements)
753
- - bug_report (software bugs, defects)
754
- - account_management (login, password, settings)
755
- - general_inquiry (questions, how-to)
756
- - complaint (dissatisfaction, problems)
757
- - feedback (suggestions, comments)
758
-
759
- Ticket:
760
- Subject: ${input.subject}
761
- Body: ${input.body}
762
-
763
- Return JSON: {"category": "...", "subcategory": "...", "confidence": 0.0-1.0, "reasoning": "..."}
764
- `.trim();
765
-
766
- const response = await this.openai.chat.completions.create({
767
- model: 'gpt-4-turbo-preview',
768
- messages: [
769
- { role: 'system', content: 'You are an expert customer support ticket classifier.' },
770
- { role: 'user', content: prompt },
771
- ],
772
- response_format: { type: 'json_object' },
773
- });
774
-
775
- const result = JSON.parse(response.choices[0].message.content || '{}');
776
-
777
- return {
778
- category: result.category,
779
- subcategory: result.subcategory,
780
- confidence: result.confidence,
781
- };
782
- }
783
-
784
- /**
785
- * Analyze sentiment
786
- */
787
- private async analyzeSentiment(text: string): Promise<{
788
- score: number;
789
- label: string;
790
- angry: boolean;
791
- frustrated: boolean;
792
- }> {
793
- const prompt = `
794
- Analyze the sentiment and emotional tone of this customer message:
795
-
796
- "${text}"
797
-
798
- Return JSON: {
799
- "score": -1.0 to 1.0,
800
- "label": "very_negative" | "negative" | "neutral" | "positive" | "very_positive",
801
- "angry": boolean,
802
- "frustrated": boolean
803
- }
804
- `.trim();
805
-
806
- const response = await this.openai.chat.completions.create({
807
- model: 'gpt-4-turbo-preview',
808
- messages: [{ role: 'user', content: prompt }],
809
- response_format: { type: 'json_object' },
810
- });
811
-
812
- return JSON.parse(response.choices[0].message.content || '{}');
813
- }
814
-
815
- /**
816
- * Search knowledge base using vector embeddings
817
- */
818
- private async searchKnowledgeBase(query: string, limit: number = 5): Promise<any[]> {
819
- // Generate embedding for query
820
- const embeddingResponse = await this.openai.embeddings.create({
821
- model: 'text-embedding-ada-002',
822
- input: query,
823
- });
824
-
825
- const queryEmbedding = embeddingResponse.data[0].embedding;
826
-
827
- // Search Pinecone
828
- const index = this.pinecone.Index('support-kb');
829
- const searchResults = await index.query({
830
- vector: queryEmbedding,
831
- topK: limit,
832
- includeMetadata: true,
833
- });
834
-
835
- return searchResults.matches?.map(match => ({
836
- articleId: match.id,
837
- title: match.metadata?.title,
838
- url: match.metadata?.url,
839
- relevanceScore: match.score,
840
- snippet: match.metadata?.snippet,
841
- })) || [];
842
- }
843
-
844
- /**
845
- * Generate response suggestion
846
- */
847
- private async generateResponse(params: {
848
- ticketContent: string;
849
- knowledgeArticles: any[];
850
- tone: string;
851
- }): Promise<string> {
852
- const kbContext = params.knowledgeArticles
853
- .map(a => `Article: ${a.title}\n${a.snippet}`)
854
- .join('\n\n');
855
-
856
- const prompt = `
857
- You are a customer support agent. Generate a helpful response to this customer ticket.
858
-
859
- Customer message:
860
- ${params.ticketContent}
861
-
862
- Relevant knowledge base articles:
863
- ${kbContext}
864
-
865
- Tone: ${params.tone}
866
-
867
- Generate a response that:
868
- 1. Addresses the customer's question/issue
869
- 2. References the knowledge base articles
870
- 3. Is clear, concise, and helpful
871
- 4. Uses the specified tone
872
- `.trim();
873
-
874
- const response = await this.openai.chat.completions.create({
875
- model: 'gpt-4-turbo-preview',
876
- messages: [
877
- { role: 'system', content: 'You are a helpful, empathetic customer support agent.' },
878
- { role: 'user', content: prompt },
879
- ],
880
- });
881
-
882
- return response.choices[0].message.content || '';
883
- }
884
-
885
- /**
886
- * Extract intent and entities
887
- */
888
- private async extractIntentAndEntities(text: string): Promise<{
889
- intent: string[];
890
- entities: Record<string, any>;
891
- }> {
892
- const prompt = `
893
- Extract the customer's intents and entities from this message:
894
-
895
- "${text}"
896
-
897
- Return JSON: {
898
- "intent": ["intent1", "intent2"],
899
- "entities": {
900
- "product": "...",
901
- "error_code": "...",
902
- "date": "...",
903
- ...
904
- }
905
- }
906
- `.trim();
907
-
908
- const response = await this.openai.chat.completions.create({
909
- model: 'gpt-4-turbo-preview',
910
- messages: [{ role: 'user', content: prompt }],
911
- response_format: { type: 'json_object' },
912
- });
913
-
914
- return JSON.parse(response.choices[0].message.content || '{}');
915
- }
916
-
917
- /**
918
- * Calculate priority
919
- */
920
- private calculatePriority(params: {
921
- classification: any;
922
- sentiment: any;
923
- customerTier: string;
924
- }): { level: 'critical' | 'high' | 'normal' | 'low'; score: number } {
925
- let score = 50; // Base score
926
-
927
- // Customer tier bonus
928
- const tierBonus = { free: 0, basic: 10, pro: 20, enterprise: 40 };
929
- score += tierBonus[params.customerTier] || 0;
930
-
931
- // Category urgency
932
- if (params.classification.category === 'bug_report') score += 20;
933
- if (params.classification.category === 'billing') score += 15;
934
- if (params.classification.category === 'technical') score += 10;
935
-
936
- // Sentiment impact
937
- if (params.sentiment.angry) score += 30;
938
- if (params.sentiment.frustrated) score += 15;
939
- if (params.sentiment.score < -0.5) score += 20;
940
-
941
- // Determine level
942
- let level: 'critical' | 'high' | 'normal' | 'low';
943
- if (score >= 80) level = 'critical';
944
- else if (score >= 60) level = 'high';
945
- else if (score >= 40) level = 'normal';
946
- else level = 'low';
947
-
948
- return { level, score };
949
- }
950
-
951
- /**
952
- * Determine routing
953
- */
954
- private determineRouting(classification: any, input: TriageInput): any {
955
- const categoryToTeam = {
956
- billing: 'billing',
957
- technical: 'engineering',
958
- feature_request: 'product',
959
- bug_report: 'engineering',
960
- account_management: 'success',
961
- general_inquiry: 'general',
962
- complaint: 'success',
963
- feedback: 'product',
964
- };
965
-
966
- return {
967
- team: categoryToTeam[classification.category] || 'general',
968
- skillsRequired: this.getRequiredSkills(classification.category),
969
- };
970
- }
971
-
972
- /**
973
- * Determine action
974
- */
975
- private determineAction(params: {
976
- confidence: number;
977
- sentiment: any;
978
- customerTier?: string;
979
- category: string;
980
- }): 'auto_reply' | 'escalate' | 'assign' | 'pending_info' {
981
- // Never auto-reply to enterprise customers
982
- if (params.customerTier === 'enterprise') return 'escalate';
983
-
984
- // Never auto-reply to angry customers
985
- if (params.sentiment.angry) return 'escalate';
986
-
987
- // Never auto-reply to complaints or legal issues
988
- if (['complaint', 'legal'].includes(params.category)) return 'escalate';
989
-
990
- // Auto-reply if high confidence
991
- if (params.confidence >= 0.95) return 'auto_reply';
992
-
993
- // Escalate if low confidence
994
- if (params.confidence < 0.6) return 'escalate';
995
-
996
- // Otherwise assign to human
997
- return 'assign';
998
- }
999
-
1000
- /**
1001
- * Execute action
1002
- */
1003
- private async executeAction(result: TriageResult): Promise<void> {
1004
- if (result.action === 'auto_reply' && result.suggestedResponse) {
1005
- await this.sendAutoReply(result.ticketId, result.suggestedResponse);
1006
- this.metrics.counter('tickets_auto_replied_total');
1007
- } else if (result.action === 'escalate') {
1008
- await this.escalateTicket(result.ticketId, result.escalationReason || 'Unknown');
1009
- this.metrics.counter('tickets_escalated_total');
1010
- } else if (result.action === 'assign') {
1011
- await this.assignTicket(result.ticketId, result.routing.team);
1012
- }
1013
- }
1014
-
1015
- /**
1016
- * Send auto-reply via Zendesk
1017
- */
1018
- private async sendAutoReply(ticketId: string, response: string): Promise<void> {
1019
- await axios.put(
1020
- `${this.zendeskBaseUrl}/tickets/${ticketId}.json`,
1021
- {
1022
- ticket: {
1023
- comment: {
1024
- body: response,
1025
- public: true,
1026
- author_id: 'support-bot',
1027
- },
1028
- status: 'solved',
1029
- },
1030
- },
1031
- {
1032
- headers: {
1033
- 'Authorization': `Bearer ${this.zendeskToken}`,
1034
- 'Content-Type': 'application/json',
1035
- },
1036
- }
1037
- );
1038
- }
1039
-
1040
- /**
1041
- * Escalate ticket
1042
- */
1043
- private async escalateTicket(ticketId: string, reason: string): Promise<void> {
1044
- // Send Slack notification
1045
- await this.sendSlackAlert({
1046
- ticketId,
1047
- message: `🚨 Ticket escalated: ${reason}`,
1048
- urgency: 'high',
1049
- });
1050
-
1051
- // Update ticket priority in Zendesk
1052
- await axios.put(
1053
- `${this.zendeskBaseUrl}/tickets/${ticketId}.json`,
1054
- {
1055
- ticket: {
1056
- priority: 'urgent',
1057
- tags: ['escalated', 'needs-human'],
1058
- },
1059
- },
1060
- {
1061
- headers: {
1062
- 'Authorization': `Bearer ${this.zendeskToken}`,
1063
- 'Content-Type': 'application/json',
1064
- },
1065
- }
1066
- );
1067
- }
1068
-
1069
- /**
1070
- * Assign ticket to team
1071
- */
1072
- private async assignTicket(ticketId: string, team: string): Promise<void> {
1073
- // Update ticket in Zendesk
1074
- await axios.put(
1075
- `${this.zendeskBaseUrl}/tickets/${ticketId}.json`,
1076
- {
1077
- ticket: {
1078
- group_id: this.getTeamGroupId(team),
1079
- tags: ['triaged', `team-${team}`],
1080
- },
1081
- },
1082
- {
1083
- headers: {
1084
- 'Authorization': `Bearer ${this.zendeskToken}`,
1085
- 'Content-Type': 'application/json',
1086
- },
1087
- }
1088
- );
1089
- }
1090
-
1091
- // Helper methods
1092
- private selectTone(sentiment: any): string {
1093
- if (sentiment.angry || sentiment.frustrated) return 'empathetic';
1094
- if (sentiment.score > 0.5) return 'friendly';
1095
- return 'professional';
1096
- }
1097
-
1098
- private getEscalationReason(sentiment: any, customerTier?: string): string {
1099
- if (customerTier === 'enterprise') return 'high_value_customer';
1100
- if (sentiment.angry) return 'angry_customer';
1101
- return 'low_confidence';
1102
- }
1103
-
1104
- private calculateSlaDeadline(priority: string): Date {
1105
- const slaMinutes = { critical: 15, high: 120, normal: 1440, low: 2880 };
1106
- const minutes = slaMinutes[priority] || 1440;
1107
- return new Date(Date.now() + minutes * 60 * 1000);
1108
- }
1109
-
1110
- private generateTags(classification: any, sentiment: any, input: TriageInput): string[] {
1111
- const tags = [classification.category];
1112
- if (sentiment.angry) tags.push('angry');
1113
- if (sentiment.frustrated) tags.push('frustrated');
1114
- if (input.customerTier) tags.push(`tier-${input.customerTier}`);
1115
- return tags;
1116
- }
1117
-
1118
- private getRequiredSkills(category: string): string[] {
1119
- const skillsMap = {
1120
- billing: ['payments', 'accounting'],
1121
- technical: ['debugging', 'api'],
1122
- feature_request: ['product_knowledge'],
1123
- bug_report: ['debugging', 'qa'],
1124
- };
1125
- return skillsMap[category] || [];
1126
- }
1127
-
1128
- private getTeamGroupId(team: string): string {
1129
- // Map team names to Zendesk group IDs
1130
- return '12345';
1131
- }
1132
-
1133
- private async sendSlackAlert(params: any): Promise<void> {
1134
- // Send Slack notification
1135
- this.logger.info(`Slack alert: ${params.message}`);
1136
- }
1137
- }
1138
-
1139
- // Entry point
1140
- async function main() {
1141
- const runtime = new OSSARuntime({
1142
- manifestPath: '/etc/ossa/manifest.yaml',
1143
- });
1144
-
1145
- const agent = new SupportTriageAgent(runtime);
1146
- await agent.start();
1147
- }
1148
-
1149
- main().catch(console.error);
1150
- ```
1151
-
1152
- ## Deployment Instructions
1153
-
1154
- ### Step 1: Deploy to Kubernetes
1155
-
1156
- ```bash
1157
- kubectl apply -f - <<EOF
1158
- apiVersion: apps/v1
1159
- kind: Deployment
1160
- metadata:
1161
- name: support-triage-agent
1162
- namespace: customer-support
1163
- spec:
1164
- replicas: 3
1165
- selector:
1166
- matchLabels:
1167
- app: support-triage
1168
- template:
1169
- metadata:
1170
- labels:
1171
- app: support-triage
1172
- spec:
1173
- containers:
1174
- - name: agent
1175
- image: registry.example.com/agents/support-triage:2.5.0
1176
- env:
1177
- - name: OPENAI_API_KEY
1178
- valueFrom:
1179
- secretKeyRef:
1180
- name: ai-keys
1181
- key: openai
1182
- - name: ZENDESK_API_TOKEN
1183
- valueFrom:
1184
- secretKeyRef:
1185
- name: support-keys
1186
- key: zendesk
1187
- - name: PINECONE_API_KEY
1188
- valueFrom:
1189
- secretKeyRef:
1190
- name: ai-keys
1191
- key: pinecone
1192
- resources:
1193
- requests:
1194
- cpu: 500m
1195
- memory: 1Gi
1196
- limits:
1197
- cpu: 2000m
1198
- memory: 4Gi
1199
- ports:
1200
- - containerPort: 8080
1201
- EOF
1202
- ```
1203
-
1204
- ### Step 2: Configure Zendesk Webhook
1205
-
1206
- ```bash
1207
- # In Zendesk Admin → Extensions → Webhooks
1208
- # Create webhook pointing to: https://support-triage.example.com/webhooks/zendesk
1209
- # Events: Ticket Created, Ticket Updated
1210
- ```
1211
-
1212
- ## Production Checklist
1213
-
1214
- - [ ] Knowledge base indexed in Pinecone
1215
- - [ ] Auto-reply confidence threshold tested
1216
- - [ ] Escalation rules validated with support team
1217
- - [ ] SLA deadlines configured per tier
1218
- - [ ] Slack alerts configured
1219
- - [ ] Human review sample rate set
1220
- - [ ] Cost monitoring enabled
1221
- - [ ] Sentiment analysis accuracy tested
1222
- - [ ] Team routing rules validated
1223
-
1224
- ## Cost Management
1225
-
1226
- - **Monthly budget**: $500
1227
- - **Per-ticket limit**: $0.50
1228
- - **Optimization**: Cache KB searches, batch processing, use cheaper models when possible
1229
-
1230
- ## Further Reading
1231
-
1232
- - [Zendesk API Documentation](https://developer.zendesk.com/)
1233
- - [OpenAI Embeddings Guide](https://platform.openai.com/docs/guides/embeddings)
1234
- - [OSSA Runtime Documentation](https://openstandardagents.org/docs/runtime)