@happyvertical/smrt-support 0.39.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/AGENTS.md +270 -0
  2. package/CLAUDE.md +1 -0
  3. package/LICENSE +7 -0
  4. package/dist/__smrt-register__.d.ts +2 -0
  5. package/dist/__smrt-register__.d.ts.map +1 -0
  6. package/dist/index.d.ts +5 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +4358 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/manifest.json +6770 -0
  11. package/dist/models/index.d.ts +17 -0
  12. package/dist/models/index.d.ts.map +1 -0
  13. package/dist/models/service-time-entry.d.ts +75 -0
  14. package/dist/models/service-time-entry.d.ts.map +1 -0
  15. package/dist/models/support-ai-run.d.ts +45 -0
  16. package/dist/models/support-ai-run.d.ts.map +1 -0
  17. package/dist/models/support-case-event.d.ts +25 -0
  18. package/dist/models/support-case-event.d.ts.map +1 -0
  19. package/dist/models/support-case.d.ts +125 -0
  20. package/dist/models/support-case.d.ts.map +1 -0
  21. package/dist/models/support-channel-binding.d.ts +47 -0
  22. package/dist/models/support-channel-binding.d.ts.map +1 -0
  23. package/dist/models/support-compensation-plan.d.ts +42 -0
  24. package/dist/models/support-compensation-plan.d.ts.map +1 -0
  25. package/dist/models/support-interaction.d.ts +49 -0
  26. package/dist/models/support-interaction.d.ts.map +1 -0
  27. package/dist/models/support-plan.d.ts +92 -0
  28. package/dist/models/support-plan.d.ts.map +1 -0
  29. package/dist/models/support-policy.d.ts +84 -0
  30. package/dist/models/support-policy.d.ts.map +1 -0
  31. package/dist/models/support-service-target.d.ts +90 -0
  32. package/dist/models/support-service-target.d.ts.map +1 -0
  33. package/dist/models/support-settlement.d.ts +58 -0
  34. package/dist/models/support-settlement.d.ts.map +1 -0
  35. package/dist/models/support-specialist.d.ts +71 -0
  36. package/dist/models/support-specialist.d.ts.map +1 -0
  37. package/dist/models/support-work-link.d.ts +31 -0
  38. package/dist/models/support-work-link.d.ts.map +1 -0
  39. package/dist/permissions.d.ts +32 -0
  40. package/dist/permissions.d.ts.map +1 -0
  41. package/dist/services/coverage-calendar.d.ts +53 -0
  42. package/dist/services/coverage-calendar.d.ts.map +1 -0
  43. package/dist/services/human-handoff-service.d.ts +113 -0
  44. package/dist/services/human-handoff-service.d.ts.map +1 -0
  45. package/dist/services/index.d.ts +15 -0
  46. package/dist/services/index.d.ts.map +1 -0
  47. package/dist/services/keyed-mutex.d.ts +22 -0
  48. package/dist/services/keyed-mutex.d.ts.map +1 -0
  49. package/dist/services/service-target-engine.d.ts +133 -0
  50. package/dist/services/service-target-engine.d.ts.map +1 -0
  51. package/dist/services/service-time-entry-service.d.ts +73 -0
  52. package/dist/services/service-time-entry-service.d.ts.map +1 -0
  53. package/dist/services/support-ai-workflow.d.ts +178 -0
  54. package/dist/services/support-ai-workflow.d.ts.map +1 -0
  55. package/dist/services/support-case-service.d.ts +162 -0
  56. package/dist/services/support-case-service.d.ts.map +1 -0
  57. package/dist/services/support-intake-service.d.ts +106 -0
  58. package/dist/services/support-intake-service.d.ts.map +1 -0
  59. package/dist/services/support-plan-admin-service.d.ts +45 -0
  60. package/dist/services/support-plan-admin-service.d.ts.map +1 -0
  61. package/dist/services/support-routing-service.d.ts +117 -0
  62. package/dist/services/support-routing-service.d.ts.map +1 -0
  63. package/dist/services/time-entry-approval-service.d.ts +162 -0
  64. package/dist/services/time-entry-approval-service.d.ts.map +1 -0
  65. package/dist/smrt-knowledge.json +4242 -0
  66. package/dist/svelte/components/CaseDetail.svelte +277 -0
  67. package/dist/svelte/components/CaseDetail.svelte.d.ts +10 -0
  68. package/dist/svelte/components/CaseDetail.svelte.d.ts.map +1 -0
  69. package/dist/svelte/components/CaseQueue.svelte +148 -0
  70. package/dist/svelte/components/CaseQueue.svelte.d.ts +12 -0
  71. package/dist/svelte/components/CaseQueue.svelte.d.ts.map +1 -0
  72. package/dist/svelte/components/RoutingRationale.svelte +131 -0
  73. package/dist/svelte/components/RoutingRationale.svelte.d.ts +11 -0
  74. package/dist/svelte/components/RoutingRationale.svelte.d.ts.map +1 -0
  75. package/dist/svelte/components/TargetList.svelte +127 -0
  76. package/dist/svelte/components/TargetList.svelte.d.ts +9 -0
  77. package/dist/svelte/components/TargetList.svelte.d.ts.map +1 -0
  78. package/dist/svelte/components/TimeEntryApprovalQueue.svelte +226 -0
  79. package/dist/svelte/components/TimeEntryApprovalQueue.svelte.d.ts +11 -0
  80. package/dist/svelte/components/TimeEntryApprovalQueue.svelte.d.ts.map +1 -0
  81. package/dist/svelte/components/__tests__/CaseDetail.test.js +86 -0
  82. package/dist/svelte/components/__tests__/CaseQueue.test.js +67 -0
  83. package/dist/svelte/components/__tests__/RoutingRationale.test.js +69 -0
  84. package/dist/svelte/components/__tests__/TargetList.test.js +84 -0
  85. package/dist/svelte/components/__tests__/TimeEntryApprovalQueue.test.js +105 -0
  86. package/dist/svelte/index.d.ts +25 -0
  87. package/dist/svelte/index.d.ts.map +1 -0
  88. package/dist/svelte/index.js +18 -0
  89. package/dist/svelte/types.d.ts +129 -0
  90. package/dist/svelte/types.d.ts.map +1 -0
  91. package/dist/svelte/types.js +182 -0
  92. package/dist/types.d.ts +130 -0
  93. package/dist/types.d.ts.map +1 -0
  94. package/dist/types.js +109 -0
  95. package/dist/types.js.map +1 -0
  96. package/package.json +86 -0
@@ -0,0 +1,133 @@
1
+ import { SmrtObjectOptions } from '@happyvertical/smrt-core';
2
+ import { SmrtJobCollection } from '@happyvertical/smrt-jobs';
3
+ import { SupportCase } from '../models/support-case.js';
4
+ import { SupportInteraction } from '../models/support-interaction.js';
5
+ import { SupportEscalationCollection, SupportServiceTarget, SupportServiceTargetCollection } from '../models/support-service-target.js';
6
+ import { EscalationStep, ServiceTargetMinutes, SupportCaseStatus } from '../types.js';
7
+ import { CoverageCalendar } from './coverage-calendar.js';
8
+ import { SupportCaseService } from './support-case-service.js';
9
+ /** Queue name for support escalation jobs. */
10
+ export declare const SUPPORT_JOB_QUEUE = "support";
11
+ /** Priority for escalation jobs (`high` — breaches are time-critical). */
12
+ export declare const ESCALATION_JOB_PRIORITY = 75;
13
+ /** Severity assumed when a case has not been assigned one yet. */
14
+ export declare const DEFAULT_SEVERITY_KEY = "sev3";
15
+ /** The plan terms a case's clocks run against (snapshot-first). */
16
+ export interface ResolvedTargetPlanTerms {
17
+ calendar: CoverageCalendar;
18
+ pauseStatuses: string[];
19
+ escalationPolicy: EscalationStep[];
20
+ targetsForSeverity(severity: string): ServiceTargetMinutes;
21
+ }
22
+ /** Options for {@link ServiceTargetEngine.create}. */
23
+ export interface ServiceTargetEngineOptions extends SmrtObjectOptions {
24
+ /** Share an existing case service (and its collections) with the engine. */
25
+ caseService?: SupportCaseService;
26
+ /**
27
+ * Whether to enqueue real `_smrt_jobs` escalation rows (default `true`).
28
+ * Disable only where a jobs table is unavailable by design.
29
+ */
30
+ scheduleJobs?: boolean;
31
+ }
32
+ /**
33
+ * The clock engine. Construct with {@link ServiceTargetEngine.create}.
34
+ */
35
+ export declare class ServiceTargetEngine {
36
+ readonly caseService: SupportCaseService;
37
+ readonly targets: SupportServiceTargetCollection;
38
+ readonly escalations: SupportEscalationCollection;
39
+ readonly jobs: SmrtJobCollection;
40
+ readonly scheduleJobs: boolean;
41
+ private readonly options;
42
+ private routing?;
43
+ protected constructor(deps: {
44
+ options: SmrtObjectOptions;
45
+ caseService: SupportCaseService;
46
+ targets: SupportServiceTargetCollection;
47
+ escalations: SupportEscalationCollection;
48
+ jobs: SmrtJobCollection;
49
+ scheduleJobs: boolean;
50
+ });
51
+ static create(options: ServiceTargetEngineOptions): Promise<ServiceTargetEngine>;
52
+ private resolveCase;
53
+ private requireId;
54
+ private getRoutingService;
55
+ /**
56
+ * Resolve the plan terms governing a case's clocks: the frozen
57
+ * `planSnapshot` when present, else the loaded plan, else conservative
58
+ * defaults (24×7 calendar, default target minutes, pause on
59
+ * `waiting_on_client`, empty escalation policy).
60
+ */
61
+ resolvePlanTerms(supportCase: SupportCase): Promise<ResolvedTargetPlanTerms>;
62
+ /**
63
+ * Start the case's Service Target clocks (idempotent: target types that
64
+ * already have an active clock are skipped). One clock per non-null
65
+ * configured minutes for the case severity — the `update` clock only when
66
+ * the plan configures `updateMinutes`. A first start creates cycle 0;
67
+ * starting again after clocks settled (e.g. a reopen) creates the next
68
+ * cycle, preserving the settled rows.
69
+ */
70
+ startTargetsForCase(caseRef: SupportCase | string, opts?: {
71
+ at?: Date;
72
+ }): Promise<SupportServiceTarget[]>;
73
+ private startTargets;
74
+ private startTarget;
75
+ /**
76
+ * Enqueue the one-shot escalation job for a clock at `runAt` and record
77
+ * its id on the target (`escalationJobId`) so satisfying can cancel it.
78
+ */
79
+ private scheduleEscalationJob;
80
+ /**
81
+ * Cancel a clock's pending escalation job, tolerating jobs that already
82
+ * ran, were cancelled, or are missing (at-least-once semantics).
83
+ */
84
+ private cancelEscalationJob;
85
+ /**
86
+ * React to a recorded interaction. Outbound specialist/agent interactions
87
+ * satisfy the acknowledgement clock (first outbound of any kind), the
88
+ * response clock (first substantive outbound — the same trigger), and the
89
+ * active update-cycle clock (which then restarts at the next cycle from
90
+ * the interaction instant). Inbound client interactions never satisfy
91
+ * clocks.
92
+ */
93
+ onInteractionRecorded(caseRef: SupportCase | string, interaction: SupportInteraction): Promise<SupportServiceTarget[]>;
94
+ private satisfyTarget;
95
+ /**
96
+ * React to a case lifecycle transition:
97
+ * - to `resolved` — satisfy the resolution clock, cancel every other
98
+ * active clock (and its job);
99
+ * - to `closed` — cancel all remaining active clocks;
100
+ * - reopen (`resolved`/`closed` → an open status) — start fresh clocks on
101
+ * the next cycle for every type;
102
+ * - entering a plan pause status — freeze pending clocks (FR-29b: only
103
+ * when the plan says so);
104
+ * - leaving a pause status — resume paused clocks with `dueAt` recomputed
105
+ * from the remaining covered minutes and a fresh escalation job.
106
+ */
107
+ onCaseTransition(caseRef: SupportCase | string, from: SupportCaseStatus, to: SupportCaseStatus, opts?: {
108
+ at?: Date;
109
+ }): Promise<void>;
110
+ private settleTargetsForTerminal;
111
+ private pauseTargets;
112
+ private resumeTargets;
113
+ /**
114
+ * Escalate a breached clock through the plan's escalation policy: write
115
+ * the {@link SupportEscalation} audit row, apply the step action
116
+ * (`notify` records the profiles to notify; `reassign` routes to the next
117
+ * eligible specialist, excluding the current assignee), bump the case
118
+ * escalation level, transition the case to `escalated` (unless already
119
+ * resolved/closed), and schedule the next policy step when it declares a
120
+ * `delayMinutes`.
121
+ */
122
+ escalateForBreach(target: SupportServiceTarget, opts?: {
123
+ at?: Date;
124
+ }): Promise<void>;
125
+ /**
126
+ * Continue a delayed escalation on an already-breached clock: consumes the
127
+ * pending-level marker and escalates the next policy step, unless the case
128
+ * has since left its open states.
129
+ */
130
+ continueEscalation(target: SupportServiceTarget, at: Date): Promise<boolean>;
131
+ }
132
+ export default ServiceTargetEngine;
133
+ //# sourceMappingURL=service-target-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-target-engine.d.ts","sourceRoot":"","sources":["../../src/services/service-target-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,73 @@
1
+ import { SmrtObjectOptions } from '@happyvertical/smrt-core';
2
+ import { ServiceTimeEntry, ServiceTimeEntryCollection } from '../models/service-time-entry.js';
3
+ import { ServiceTimeEntrySource, SupportParticipantKind, TimeEntryEvidence } from '../types.js';
4
+ import { SupportCaseService } from './support-case-service.js';
5
+ /** Options for {@link ServiceTimeEntryService.create}. */
6
+ export interface ServiceTimeEntryServiceOptions extends SmrtObjectOptions {
7
+ /** Share an existing case facade (otherwise one is created internally). */
8
+ caseService?: SupportCaseService;
9
+ }
10
+ /** Input for {@link ServiceTimeEntryService.record} — all four sources. */
11
+ export interface RecordServiceTimeEntryInput {
12
+ tenantId?: string | null;
13
+ /** Support Case context (either this or the work ref pair is required). */
14
+ caseId?: string | null;
15
+ /** Polymorphic work context: qualified class name + id, together. */
16
+ workRefType?: string | null;
17
+ workRefId?: string | null;
18
+ /** Specialist role record, when the deliverer is a Support Specialist. */
19
+ specialistId?: string | null;
20
+ participantKind: SupportParticipantKind;
21
+ /** Delivering human Participant — required when `participantKind: 'human'`. */
22
+ participantProfileId?: string | null;
23
+ /** Delivering agent identity — required when `participantKind: 'agent'`. */
24
+ agentRef?: string;
25
+ source: ServiceTimeEntrySource;
26
+ description?: string;
27
+ startedAt?: Date;
28
+ endedAt?: Date;
29
+ /** Explicit duration; derived from `endedAt − startedAt` when omitted. */
30
+ durationSeconds?: number;
31
+ evidence?: TimeEntryEvidence[];
32
+ metadata?: Record<string, unknown>;
33
+ }
34
+ /** Input for {@link ServiceTimeEntryService.submit}. */
35
+ export interface SubmitServiceTimeEntryInput {
36
+ byProfileId?: string | null;
37
+ }
38
+ /**
39
+ * The write facade for recording and submitting Service Time Entries.
40
+ * Construct with {@link ServiceTimeEntryService.create}.
41
+ */
42
+ export declare class ServiceTimeEntryService {
43
+ readonly entries: ServiceTimeEntryCollection;
44
+ readonly caseService: SupportCaseService;
45
+ protected constructor(collections: {
46
+ entries: ServiceTimeEntryCollection;
47
+ caseService: SupportCaseService;
48
+ });
49
+ static create(options: ServiceTimeEntryServiceOptions): Promise<ServiceTimeEntryService>;
50
+ /** Load an entry or throw a descriptive error. */
51
+ getEntry(entryRef: ServiceTimeEntry | string): Promise<ServiceTimeEntry>;
52
+ /**
53
+ * Record one Service Time Entry as a `draft`. One validation contract for
54
+ * all four sources (FR-40):
55
+ *
56
+ * - a work context is required: `caseId` and/or the `workRefType`/`workRefId`
57
+ * pair (a case-attached entry copies the case's tenant unless given);
58
+ * - the participant must be coherent: `human` needs `participantProfileId`,
59
+ * `agent` needs `agentRef`;
60
+ * - `timer` entries need both period bounds; every entry needs a positive
61
+ * duration — explicit `durationSeconds` or derived `endedAt − startedAt`.
62
+ *
63
+ * Case-attached entries append a `time_recorded` audit event.
64
+ */
65
+ record(input: RecordServiceTimeEntryInput): Promise<ServiceTimeEntry>;
66
+ /**
67
+ * Submit a `draft` (or resubmit a `rejected`) entry for approval, stamping
68
+ * the submitter. Approval itself is `TimeEntryApprovalService`'s job.
69
+ */
70
+ submit(entryRef: ServiceTimeEntry | string, input?: SubmitServiceTimeEntryInput): Promise<ServiceTimeEntry>;
71
+ }
72
+ export default ServiceTimeEntryService;
73
+ //# sourceMappingURL=service-time-entry-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service-time-entry-service.d.ts","sourceRoot":"","sources":["../../src/services/service-time-entry-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EACL,KAAK,gBAAgB,EACrB,0BAA0B,EAC3B,MAAM,iCAAiC,CAAC;AAEzC,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EACtB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,0DAA0D;AAC1D,MAAM,WAAW,8BAA+B,SAAQ,iBAAiB;IACvE,2EAA2E;IAC3E,WAAW,CAAC,EAAE,kBAAkB,CAAC;CAClC;AAED,2EAA2E;AAC3E,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,2EAA2E;IAC3E,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,eAAe,EAAE,sBAAsB,CAAC;IACxC,+EAA+E;IAC/E,oBAAoB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;IAC/B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,OAAO,CAAC,EAAE,IAAI,CAAC;IACf,0EAA0E;IAC1E,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,wDAAwD;AACxD,MAAM,WAAW,2BAA2B;IAC1C,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED;;;GAGG;AACH,qBAAa,uBAAuB;IAClC,QAAQ,CAAC,OAAO,EAAE,0BAA0B,CAAC;IAC7C,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IAEzC,SAAS,aAAa,WAAW,EAAE;QACjC,OAAO,EAAE,0BAA0B,CAAC;QACpC,WAAW,EAAE,kBAAkB,CAAC;KACjC;WAKY,MAAM,CACjB,OAAO,EAAE,8BAA8B,GACtC,OAAO,CAAC,uBAAuB,CAAC;IAOnC,kDAAkD;IAC5C,QAAQ,CACZ,QAAQ,EAAE,gBAAgB,GAAG,MAAM,GAClC,OAAO,CAAC,gBAAgB,CAAC;IAW5B;;;;;;;;;;;;OAYG;IACG,MAAM,CAAC,KAAK,EAAE,2BAA2B,GAAG,OAAO,CAAC,gBAAgB,CAAC;IA0G3E;;;OAGG;IACG,MAAM,CACV,QAAQ,EAAE,gBAAgB,GAAG,MAAM,EACnC,KAAK,GAAE,2BAAgC,GACtC,OAAO,CAAC,gBAAgB,CAAC;CAa7B;AAED,eAAe,uBAAuB,CAAC"}
@@ -0,0 +1,178 @@
1
+ import { SmrtObjectOptions } from '@happyvertical/smrt-core';
2
+ import { SupportAiRun, SupportAiRunCollection } from '../models/support-ai-run.js';
3
+ import { SupportCase } from '../models/support-case.js';
4
+ import { SupportInteractionCollection } from '../models/support-interaction.js';
5
+ import { SupportPolicyCollection } from '../models/support-policy.js';
6
+ import { HumanHandoffTrigger } from '../types.js';
7
+ import { HumanHandoffService } from './human-handoff-service.js';
8
+ import { SupportCaseService } from './support-case-service.js';
9
+ import { IntakeResult } from './support-intake-service.js';
10
+ /** One knowledge source consulted while drafting an automated answer. */
11
+ export interface KnowledgeSnippet {
12
+ /** Source kind, e.g. `fact`, `article`, `document`. */
13
+ kind: string;
14
+ /** Source reference (id, slug, or URL) for the audit trail. */
15
+ ref: string;
16
+ label?: string;
17
+ content: string;
18
+ }
19
+ /** Classification returned by {@link SupportAiBoundary.classify}. */
20
+ export interface SupportAiClassifyResult {
21
+ /** One of the offered severity keys, or `''` when undetermined. */
22
+ severity: string;
23
+ /** Short free-vocabulary category, or `''` when undetermined. */
24
+ category: string;
25
+ /** Whether the matter is sensitive (always triggers a Human Handoff). */
26
+ sensitive: boolean;
27
+ /** Confidence in `[0, 1]`. */
28
+ confidence: number;
29
+ /** Model identifier, when the boundary knows it. */
30
+ model?: string;
31
+ }
32
+ /** Draft answer returned by {@link SupportAiBoundary.answer}. */
33
+ export interface SupportAiAnswerResult {
34
+ reply: string;
35
+ /** Confidence in `[0, 1]`; below the policy threshold → Human Handoff. */
36
+ confidence: number;
37
+ /** Whether the reply would fully resolve the request (FR-28a). */
38
+ proposedResolution: boolean;
39
+ /** Model identifier, when the boundary knows it. */
40
+ model?: string;
41
+ }
42
+ /**
43
+ * THE AI seam: the only thing tests mock. The default implementation
44
+ * ({@link createDefaultAiBoundary}) delegates to the case's own `do()` AI
45
+ * operation from `smrt-core`.
46
+ */
47
+ export interface SupportAiBoundary {
48
+ classify(input: {
49
+ subject: string;
50
+ body: string;
51
+ severityKeys: string[];
52
+ sensitiveCategories: string[];
53
+ }): Promise<SupportAiClassifyResult>;
54
+ answer(input: {
55
+ subject: string;
56
+ body: string;
57
+ knowledge: KnowledgeSnippet[];
58
+ caseSummary: string;
59
+ }): Promise<SupportAiAnswerResult>;
60
+ }
61
+ /**
62
+ * The knowledge seam: retrieve the snippets an automated answer may cite.
63
+ * The default provider returns nothing, keeping this package dependency-free
64
+ * — apps plug `smrt-facts` / `smrt-content`-backed providers.
65
+ */
66
+ export interface SupportKnowledgeProvider {
67
+ retrieve(input: {
68
+ subject: string;
69
+ body: string;
70
+ projectId: string | null;
71
+ tenantId: string | null;
72
+ }): Promise<KnowledgeSnippet[]>;
73
+ }
74
+ /** Notification passed to `onHandoff` after each handoff attempt. */
75
+ export interface SupportHandoffNotice {
76
+ supportCase: SupportCase;
77
+ trigger: HumanHandoffTrigger;
78
+ /** True when the no-repeat guarantee deduped this trigger. */
79
+ alreadyActive: boolean;
80
+ }
81
+ /** Options for {@link SupportAiWorkflow.create}. */
82
+ export interface SupportAiWorkflowOptions extends SmrtObjectOptions {
83
+ /** The AI seam; omitted → {@link createDefaultAiBoundary} per case. */
84
+ boundary?: SupportAiBoundary;
85
+ /** The knowledge seam; omitted → a no-op provider. */
86
+ knowledge?: SupportKnowledgeProvider;
87
+ /** Handoff engine to share; omitted → one is created lazily. */
88
+ handoffService?: HumanHandoffService;
89
+ /** Called after every handoff attempt (app notification seam). */
90
+ onHandoff?: (notice: SupportHandoffNotice) => Promise<void>;
91
+ }
92
+ /**
93
+ * Numeric rank of a severity key by its numeric suffix (`sev1` → 1; lower is
94
+ * more severe). Returns `NaN` for keys without a numeric suffix, which makes
95
+ * every comparison false — auto-resolution fails closed and the
96
+ * high-severity trigger stays quiet for unknown vocabularies.
97
+ */
98
+ export declare function severityRank(severityKey: string | null | undefined): number;
99
+ /**
100
+ * The Automated Support Response pipeline. Construct with
101
+ * {@link SupportAiWorkflow.create}; wire {@link processIntake} into
102
+ * `SupportIntakeService`'s `onCaseIntake` hook.
103
+ */
104
+ export declare class SupportAiWorkflow {
105
+ readonly caseService: SupportCaseService;
106
+ readonly policies: SupportPolicyCollection;
107
+ readonly aiRuns: SupportAiRunCollection;
108
+ readonly interactions: SupportInteractionCollection;
109
+ readonly handoffs: HumanHandoffService;
110
+ private readonly boundary;
111
+ private readonly knowledge;
112
+ private readonly onHandoff?;
113
+ protected constructor(deps: {
114
+ caseService: SupportCaseService;
115
+ policies: SupportPolicyCollection;
116
+ aiRuns: SupportAiRunCollection;
117
+ interactions: SupportInteractionCollection;
118
+ handoffs: HumanHandoffService;
119
+ boundary: SupportAiBoundary | null;
120
+ knowledge: SupportKnowledgeProvider;
121
+ onHandoff?: (notice: SupportHandoffNotice) => Promise<void>;
122
+ });
123
+ static create(options: SupportAiWorkflowOptions): Promise<SupportAiWorkflow>;
124
+ /**
125
+ * Entry point for `SupportIntakeService.onCaseIntake`: run one automated
126
+ * pass over the case an inbound interaction created or joined.
127
+ */
128
+ processIntake(result: IntakeResult): Promise<SupportAiRun[]>;
129
+ /**
130
+ * Run one Automated Support Response pass over a case: acknowledge →
131
+ * classify → answer → troubleshoot → resolve, each gated by the resolved
132
+ * policy and audited as a {@link SupportAiRun}. Cases with `aiEnabled`
133
+ * off, or no longer open, are left untouched.
134
+ */
135
+ processCase(caseId: string, opts?: {
136
+ interactionId?: string | null;
137
+ }): Promise<SupportAiRun[]>;
138
+ /** Acknowledge phase: post the templated receipt once per case. */
139
+ private runAcknowledge;
140
+ /** Why autonomous resolution must not run, or `null` when it may. */
141
+ private resolveSkipReason;
142
+ /** Resolve the governing policy: matching row, else built-in defaults. */
143
+ private resolveEffectivePolicy;
144
+ /**
145
+ * Prior boundary-consuming answer attempts. Low-confidence answers consume
146
+ * the boundary too (`handed_off`), so they count toward the attempt budget
147
+ * — only `skipped` runs (which never called the boundary) are free.
148
+ */
149
+ private countAnswerAttempts;
150
+ /** The request text a pass reasons over: triggering interaction, else the
151
+ * case description. */
152
+ private requestBodyOf;
153
+ /** Severity vocabulary: the case's plan snapshot, else the defaults. */
154
+ private severityKeysOf;
155
+ /** One-line case summary handed to the answer boundary. */
156
+ private caseSummaryOf;
157
+ /** Route a trigger through the handoff engine and notify the app seam. */
158
+ private triggerHandoff;
159
+ /** Append one audit run plus its `ai_run` case event. */
160
+ private writeRun;
161
+ /** The persisted id of a saved case. */
162
+ private caseIdOf;
163
+ }
164
+ /**
165
+ * The default knowledge provider: retrieves nothing. Keeps the package
166
+ * dependency-free; apps supply providers backed by `smrt-facts`,
167
+ * `smrt-content`, or their own corpus.
168
+ */
169
+ export declare function createNoopKnowledgeProvider(): SupportKnowledgeProvider;
170
+ /**
171
+ * The default AI boundary: delegates to the case's own `do()` AI operation
172
+ * (smrt-core) asking for strict JSON, parsed defensively — a malformed
173
+ * classification comes back sensitive with zero confidence, failing toward
174
+ * the human.
175
+ */
176
+ export declare function createDefaultAiBoundary(getCase: () => SupportCase): SupportAiBoundary;
177
+ export default SupportAiWorkflow;
178
+ //# sourceMappingURL=support-ai-workflow.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-ai-workflow.d.ts","sourceRoot":"","sources":["../../src/services/support-ai-workflow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,162 @@
1
+ import { SmrtObjectOptions } from '@happyvertical/smrt-core';
2
+ import { SupportCase, SupportCaseCollection } from '../models/support-case.js';
3
+ import { SupportCaseEvent, SupportCaseEventCollection } from '../models/support-case-event.js';
4
+ import { SupportInteraction, SupportInteractionCollection } from '../models/support-interaction.js';
5
+ import { SupportPlan, SupportPlanCollection } from '../models/support-plan.js';
6
+ import { SupportWorkLink, SupportWorkLinkCollection } from '../models/support-work-link.js';
7
+ import { SupportActorKind, SupportCaseEventType, SupportCaseStatus, SupportChannelKind, SupportInteractionDirection, SupportWorkLinkKind } from '../types.js';
8
+ export interface OpenCaseInput {
9
+ tenantId?: string | null;
10
+ subject: string;
11
+ description?: string;
12
+ priority?: string;
13
+ severity?: string;
14
+ channelKind?: SupportChannelKind | '';
15
+ clientProfileId?: string | null;
16
+ openedByProfileId?: string | null;
17
+ projectId?: string | null;
18
+ bindingId?: string | null;
19
+ threadKey?: string;
20
+ planId?: string | null;
21
+ preferredSpecialistId?: string | null;
22
+ metadata?: Record<string, unknown>;
23
+ }
24
+ export interface RecordInteractionInput {
25
+ direction: SupportInteractionDirection;
26
+ channelKind: SupportChannelKind;
27
+ actorKind: SupportActorKind;
28
+ authorProfileId?: string | null;
29
+ body: string;
30
+ occurredAt?: Date;
31
+ sourceType?: string | null;
32
+ sourceId?: string | null;
33
+ /** Idempotency key; generated (`manual:<uuid>`) when omitted. */
34
+ sourceKey?: string;
35
+ /** RFC 822 Message-ID for email interactions (keyed reply threading). */
36
+ rfcMessageId?: string;
37
+ metadata?: Record<string, unknown>;
38
+ }
39
+ export interface CaseActor {
40
+ actorKind: SupportActorKind;
41
+ actorProfileId?: string | null;
42
+ }
43
+ export interface CaseTimelineItem {
44
+ kind: 'interaction' | 'event';
45
+ occurredAt: Date;
46
+ interaction?: SupportInteraction;
47
+ event?: SupportCaseEvent;
48
+ }
49
+ /**
50
+ * The write facade. Construct with {@link SupportCaseService.create}.
51
+ */
52
+ export declare class SupportCaseService {
53
+ readonly cases: SupportCaseCollection;
54
+ readonly interactions: SupportInteractionCollection;
55
+ readonly events: SupportCaseEventCollection;
56
+ readonly workLinks: SupportWorkLinkCollection;
57
+ readonly plans: SupportPlanCollection;
58
+ protected constructor(collections: {
59
+ cases: SupportCaseCollection;
60
+ interactions: SupportInteractionCollection;
61
+ events: SupportCaseEventCollection;
62
+ workLinks: SupportWorkLinkCollection;
63
+ plans: SupportPlanCollection;
64
+ });
65
+ static create(options: SmrtObjectOptions): Promise<SupportCaseService>;
66
+ /** Load a case or throw a descriptive error. */
67
+ getCase(caseId: string): Promise<SupportCase>;
68
+ /** The persisted id of a saved case (all facade entry points save first). */
69
+ private caseIdOf;
70
+ /**
71
+ * Open a new Support Case. Applies the plan snapshot when a plan is given
72
+ * and writes the `created` audit event.
73
+ */
74
+ openCase(input: OpenCaseInput): Promise<SupportCase>;
75
+ /**
76
+ * Capture the plan terms onto the case (`planSnapshot`) so later plan edits
77
+ * never rewrite what this case was handled under. A tenant-owned plan only
78
+ * applies to that tenant's cases (global NULL-tenant template plans apply
79
+ * anywhere) — a foreign plan would snapshot another tenant's pricing,
80
+ * approval, and escalation terms.
81
+ */
82
+ applyPlan(supportCase: SupportCase, plan: SupportPlan): Promise<void>;
83
+ /**
84
+ * Record a channel interaction on a case (idempotent on `sourceKey`).
85
+ * Inbound client activity un-parks `waiting_on_client` cases; the first
86
+ * outbound reply stamps `acknowledgedAt`/`firstRespondedAt`.
87
+ */
88
+ recordInteraction(caseRef: SupportCase | string, input: RecordInteractionInput): Promise<SupportInteraction>;
89
+ /** Transition a case's lifecycle status (guarded by the model). */
90
+ transition(caseRef: SupportCase | string, to: SupportCaseStatus, actor: CaseActor & {
91
+ reason?: string;
92
+ }): Promise<SupportCase>;
93
+ /** Assign (or reassign) a case to a specialist. */
94
+ assign(caseRef: SupportCase | string, input: CaseActor & {
95
+ specialistId: string;
96
+ rationale?: Record<string, unknown>;
97
+ }): Promise<SupportCase>;
98
+ /** Resolve a case with a resolution summary. */
99
+ resolve(caseRef: SupportCase | string, input: CaseActor & {
100
+ summary: string;
101
+ resolutionKind?: 'automated' | 'human' | 'delivery';
102
+ }): Promise<SupportCase>;
103
+ /** Close a resolved case. */
104
+ close(caseRef: SupportCase | string, actor: CaseActor & {
105
+ reason?: string;
106
+ }): Promise<SupportCase>;
107
+ /**
108
+ * Reopen a resolved/closed case, preserving the prior resolution in the
109
+ * reopen event (FR-29b) and bumping `reopenCount`.
110
+ */
111
+ reopen(caseRef: SupportCase | string, actor: CaseActor & {
112
+ reason?: string;
113
+ to?: SupportCaseStatus;
114
+ }): Promise<SupportCase>;
115
+ /**
116
+ * Record that the Client explicitly requested a human (FR-28b). The actual
117
+ * handoff (routing + context transfer) is performed by the handoff service;
118
+ * this stamps the request and its audit event.
119
+ */
120
+ requestHuman(caseRef: SupportCase | string, input: {
121
+ byProfileId?: string | null;
122
+ note?: string;
123
+ }): Promise<SupportCase>;
124
+ /**
125
+ * Link separately tracked work to the case (Support Work Item or a
126
+ * Delivery Handoff's Development Work Item). Support keeps the Case as the
127
+ * canonical client record; the linked item's execution belongs to its
128
+ * owning domain (FR-29a).
129
+ */
130
+ linkWork(caseRef: SupportCase | string, input: CaseActor & {
131
+ linkKind: SupportWorkLinkKind;
132
+ targetType: string;
133
+ targetId: string;
134
+ targetLabel?: string;
135
+ externalUrl?: string;
136
+ metadata?: Record<string, unknown>;
137
+ }): Promise<SupportWorkLink>;
138
+ /**
139
+ * Record a status echo reported back from the domain owning a linked work
140
+ * item (Delivery Operations reports progress; Support never drives it).
141
+ */
142
+ recordWorkStatus(linkId: string, input: {
143
+ status: string;
144
+ note?: string;
145
+ }): Promise<SupportWorkLink>;
146
+ /** Append an audit event to a case. */
147
+ recordEvent(caseRef: SupportCase | string, eventType: SupportCaseEventType, input: {
148
+ actorKind: SupportActorKind;
149
+ actorProfileId?: string | null;
150
+ summary: string;
151
+ payload?: Record<string, unknown>;
152
+ occurredAt?: Date;
153
+ }): Promise<SupportCaseEvent>;
154
+ /**
155
+ * The merged case timeline: interactions and audit events in one
156
+ * chronological stream (the queue/detail UI's data shape, and the context
157
+ * package a Human Handoff transfers).
158
+ */
159
+ getTimeline(caseId: string): Promise<CaseTimelineItem[]>;
160
+ }
161
+ export default SupportCaseService;
162
+ //# sourceMappingURL=support-case-service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"support-case-service.d.ts","sourceRoot":"","sources":["../../src/services/support-case-service.ts"],"names":[],"mappings":"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"}