getpatter 0.4.3 → 0.5.0
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 +136 -162
- package/dist/carrier-config-CPG5CROM.mjs +84 -0
- package/dist/{chunk-35EVXMGB.mjs → chunk-757NVN4L.mjs} +396 -458
- package/dist/cli.js +92 -5
- package/dist/index.d.mts +901 -241
- package/dist/index.d.ts +901 -241
- package/dist/index.js +1763 -921
- package/dist/index.mjs +1240 -419
- package/dist/{test-mode-RH65MMSP.mjs → test-mode-YFOL2HYH.mjs} +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -33,9 +33,15 @@ var MetricsStore = class extends import_events.EventEmitter {
|
|
|
33
33
|
maxCalls;
|
|
34
34
|
calls = [];
|
|
35
35
|
activeCalls = /* @__PURE__ */ new Map();
|
|
36
|
-
|
|
36
|
+
/**
|
|
37
|
+
* Accepts either a numeric ``maxCalls`` (legacy positional — matches the
|
|
38
|
+
* original TS API) or an options object ``{ maxCalls }`` to align with the
|
|
39
|
+
* Python SDK's keyword-argument style. Plain literals also work:
|
|
40
|
+
* ``new MetricsStore()`` / ``new MetricsStore(100)`` / ``new MetricsStore({ maxCalls: 100 })``.
|
|
41
|
+
*/
|
|
42
|
+
constructor(maxCallsOrOpts = 500) {
|
|
37
43
|
super();
|
|
38
|
-
this.maxCalls = maxCalls;
|
|
44
|
+
this.maxCalls = typeof maxCallsOrOpts === "number" ? maxCallsOrOpts : maxCallsOrOpts.maxCalls ?? 500;
|
|
39
45
|
}
|
|
40
46
|
publish(eventType, data) {
|
|
41
47
|
this.emit("sse", { type: eventType, data });
|
|
@@ -43,22 +49,100 @@ var MetricsStore = class extends import_events.EventEmitter {
|
|
|
43
49
|
recordCallStart(data) {
|
|
44
50
|
const callId = data.call_id || "";
|
|
45
51
|
if (!callId) return;
|
|
52
|
+
const existing = this.activeCalls.get(callId);
|
|
53
|
+
if (existing) {
|
|
54
|
+
existing.caller = data.caller || existing.caller;
|
|
55
|
+
existing.callee = data.callee || existing.callee;
|
|
56
|
+
existing.direction = data.direction || existing.direction;
|
|
57
|
+
existing.status = "in-progress";
|
|
58
|
+
existing.turns = existing.turns || [];
|
|
59
|
+
} else {
|
|
60
|
+
const record = {
|
|
61
|
+
call_id: callId,
|
|
62
|
+
caller: data.caller || "",
|
|
63
|
+
callee: data.callee || "",
|
|
64
|
+
direction: data.direction || "inbound",
|
|
65
|
+
started_at: Date.now() / 1e3,
|
|
66
|
+
status: "in-progress",
|
|
67
|
+
turns: []
|
|
68
|
+
};
|
|
69
|
+
this.activeCalls.set(callId, record);
|
|
70
|
+
}
|
|
71
|
+
this.publish("call_start", {
|
|
72
|
+
call_id: callId,
|
|
73
|
+
caller: data.caller || "",
|
|
74
|
+
callee: data.callee || "",
|
|
75
|
+
direction: data.direction || "inbound"
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Pre-register an outbound call before any webhook fires. Lets the
|
|
80
|
+
* dashboard surface attempts that never reach media (no-answer, busy,
|
|
81
|
+
* carrier-rejected). Mirrors the Python ``record_call_initiated``.
|
|
82
|
+
*/
|
|
83
|
+
recordCallInitiated(data) {
|
|
84
|
+
const callId = data.call_id || "";
|
|
85
|
+
if (!callId) return;
|
|
86
|
+
if (this.activeCalls.has(callId)) return;
|
|
46
87
|
const record = {
|
|
47
88
|
call_id: callId,
|
|
48
89
|
caller: data.caller || "",
|
|
49
90
|
callee: data.callee || "",
|
|
50
|
-
direction: data.direction || "
|
|
91
|
+
direction: data.direction || "outbound",
|
|
51
92
|
started_at: Date.now() / 1e3,
|
|
93
|
+
status: "initiated",
|
|
52
94
|
turns: []
|
|
53
95
|
};
|
|
54
96
|
this.activeCalls.set(callId, record);
|
|
55
|
-
this.publish("
|
|
97
|
+
this.publish("call_initiated", {
|
|
56
98
|
call_id: callId,
|
|
57
99
|
caller: record.caller,
|
|
58
100
|
callee: record.callee,
|
|
59
|
-
direction: record.direction
|
|
101
|
+
direction: record.direction,
|
|
102
|
+
status: record.status
|
|
60
103
|
});
|
|
61
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Update the status of an active or completed call. Terminal states
|
|
107
|
+
* (completed, no-answer, busy, failed, canceled, webhook_error) move the
|
|
108
|
+
* row from active to completed so the UI freezes the live duration timer.
|
|
109
|
+
*/
|
|
110
|
+
updateCallStatus(callId, status, extra = {}) {
|
|
111
|
+
if (!callId || !status) return;
|
|
112
|
+
const TERMINAL = /* @__PURE__ */ new Set(["completed", "no-answer", "busy", "failed", "canceled", "webhook_error"]);
|
|
113
|
+
const active = this.activeCalls.get(callId);
|
|
114
|
+
if (active) {
|
|
115
|
+
active.status = status;
|
|
116
|
+
Object.assign(active, extra);
|
|
117
|
+
if (TERMINAL.has(status)) {
|
|
118
|
+
const entry = {
|
|
119
|
+
call_id: callId,
|
|
120
|
+
caller: active.caller || "",
|
|
121
|
+
callee: active.callee || "",
|
|
122
|
+
direction: active.direction || "outbound",
|
|
123
|
+
started_at: active.started_at || 0,
|
|
124
|
+
ended_at: Date.now() / 1e3,
|
|
125
|
+
status,
|
|
126
|
+
metrics: null,
|
|
127
|
+
...extra
|
|
128
|
+
};
|
|
129
|
+
this.activeCalls.delete(callId);
|
|
130
|
+
this.calls.push(entry);
|
|
131
|
+
if (this.calls.length > this.maxCalls) {
|
|
132
|
+
this.calls = this.calls.slice(-this.maxCalls);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
} else {
|
|
136
|
+
for (let i = this.calls.length - 1; i >= 0; i--) {
|
|
137
|
+
if (this.calls[i].call_id === callId) {
|
|
138
|
+
this.calls[i].status = status;
|
|
139
|
+
Object.assign(this.calls[i], extra);
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
this.publish("call_status", { call_id: callId, status, ...extra });
|
|
145
|
+
}
|
|
62
146
|
recordTurn(data) {
|
|
63
147
|
const callId = data.call_id || "";
|
|
64
148
|
const turn = data.turn;
|
|
@@ -75,6 +159,8 @@ var MetricsStore = class extends import_events.EventEmitter {
|
|
|
75
159
|
if (!callId) return;
|
|
76
160
|
const active = this.activeCalls.get(callId);
|
|
77
161
|
this.activeCalls.delete(callId);
|
|
162
|
+
const activeStatus = active?.status;
|
|
163
|
+
const resolvedStatus = activeStatus && activeStatus !== "in-progress" ? activeStatus : "completed";
|
|
78
164
|
const entry = {
|
|
79
165
|
call_id: callId,
|
|
80
166
|
caller: data.caller || active?.caller || "",
|
|
@@ -83,6 +169,7 @@ var MetricsStore = class extends import_events.EventEmitter {
|
|
|
83
169
|
started_at: active?.started_at || 0,
|
|
84
170
|
ended_at: Date.now() / 1e3,
|
|
85
171
|
transcript: data.transcript || [],
|
|
172
|
+
status: resolvedStatus,
|
|
86
173
|
metrics: metrics ?? null
|
|
87
174
|
};
|
|
88
175
|
this.calls.push(entry);
|