@aiqa/sdk 2.0.0-develop.2 → 2.0.0-develop.4
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 +7 -9
- package/dist/browser/browser.d.ts +14 -6
- package/dist/browser/browser.js +60 -3
- package/dist/browser/browser.js.map +1 -1
- package/dist/node/node.d.ts +14 -6
- package/dist/node/node.js +60 -3
- package/dist/node/node.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -165,7 +165,7 @@ while you wait.
|
|
|
165
165
|
|
|
166
166
|
`addFact()` does not throw on verification failure — an unmatched
|
|
167
167
|
fact resolves with `is_valid_answer: false` and (where the backend
|
|
168
|
-
provides it) `verification_status: "unmatched"
|
|
168
|
+
provides it) `verification_status: "unmatched"`.
|
|
169
169
|
Reject paths are reserved for transport / protocol errors.
|
|
170
170
|
|
|
171
171
|
**Parameters:**
|
|
@@ -212,8 +212,7 @@ const result = await sdk.addFact({
|
|
|
212
212
|
});
|
|
213
213
|
|
|
214
214
|
if (result.is_valid_answer) {
|
|
215
|
-
// verification_status will be "matched"
|
|
216
|
-
// customer explicitly contradicted the expected answer).
|
|
215
|
+
// verification_status will be "matched".
|
|
217
216
|
console.log("matched:", result.ai_answer);
|
|
218
217
|
} else {
|
|
219
218
|
// verification_status will be "unmatched". matched_components /
|
|
@@ -366,13 +365,13 @@ processing
|
|
|
366
365
|
(same, but for a held unmatched verdict)
|
|
367
366
|
│
|
|
368
367
|
▼
|
|
369
|
-
matched | unmatched
|
|
368
|
+
matched | unmatched ← terminal
|
|
370
369
|
```
|
|
371
370
|
|
|
372
371
|
Rules for consumers:
|
|
373
372
|
|
|
374
373
|
- **`addFact()` resolves only on a terminal state** (`matched`,
|
|
375
|
-
`unmatched
|
|
374
|
+
`unmatched`). Render progress from the
|
|
376
375
|
`FACT_VERIFIED` event, render the final verdict from the Promise
|
|
377
376
|
result.
|
|
378
377
|
- **Treat unknown `verification_status` strings as `processing`.**
|
|
@@ -453,8 +452,8 @@ interface AddFactResult {
|
|
|
453
452
|
answer_match_score?: number;
|
|
454
453
|
|
|
455
454
|
/**
|
|
456
|
-
* Top-level state at terminal resolution. Always one of `matched
|
|
457
|
-
*
|
|
455
|
+
* Top-level state at terminal resolution. Always one of `matched`
|
|
456
|
+
* or `unmatched` because the `addFact()` Promise only
|
|
458
457
|
* resolves on terminals. Optional during the rollout window for
|
|
459
458
|
* backwards compatibility with older backends.
|
|
460
459
|
*/
|
|
@@ -484,8 +483,7 @@ type VerificationStatus =
|
|
|
484
483
|
| "pending_confirmation_matched"
|
|
485
484
|
| "pending_confirmation_unmatched"
|
|
486
485
|
| "matched"
|
|
487
|
-
| "unmatched"
|
|
488
|
-
| "contradicted";
|
|
486
|
+
| "unmatched";
|
|
489
487
|
```
|
|
490
488
|
|
|
491
489
|
The enum is additive: consumers that `switch` on this value MUST
|
|
@@ -100,16 +100,15 @@ type QuestionStatus = "searching" | "asked" | "not_asked";
|
|
|
100
100
|
* - `pending_confirmation_matched` backend has a matching answer but is
|
|
101
101
|
* holding a settling window for mid-answer
|
|
102
102
|
* clarifications (e.g. spellings, "I mean…");
|
|
103
|
-
* resolves to `matched`/`unmatched
|
|
103
|
+
* resolves to `matched`/`unmatched`
|
|
104
104
|
* - `pending_confirmation_unmatched` same as above but the held verdict is
|
|
105
105
|
* `unmatched`; UI can show "we heard X but it
|
|
106
106
|
* doesn't match, waiting to confirm" instead
|
|
107
107
|
* of a hard red verdict
|
|
108
108
|
* - `matched` terminal: answer matched expected
|
|
109
109
|
* - `unmatched` terminal: budget exhausted with no match
|
|
110
|
-
* - `contradicted` terminal (future): customer contradicted expected
|
|
111
110
|
*/
|
|
112
|
-
type VerificationStatus = "processing" | "awaiting_question" | "awaiting_answer" | "partial" | "pending_confirmation_matched" | "pending_confirmation_unmatched" | "matched" | "unmatched"
|
|
111
|
+
type VerificationStatus = "processing" | "awaiting_question" | "awaiting_answer" | "partial" | "pending_confirmation_matched" | "pending_confirmation_unmatched" | "matched" | "unmatched";
|
|
113
112
|
type ApplicationFact = ApplicationFactInput & {
|
|
114
113
|
ai_answer?: any;
|
|
115
114
|
question_status: QuestionStatus;
|
|
@@ -143,8 +142,8 @@ interface AddFactResult {
|
|
|
143
142
|
answer_match_score?: number;
|
|
144
143
|
metadata?: Record<string, string>;
|
|
145
144
|
/**
|
|
146
|
-
* Top-level state at terminal resolution. Always one of `matched
|
|
147
|
-
*
|
|
145
|
+
* Top-level state at terminal resolution. Always one of `matched`
|
|
146
|
+
* or `unmatched` because the `addFact()` Promise only
|
|
148
147
|
* resolves on terminals. Optional during the rollout window for
|
|
149
148
|
* backwards compatibility with older backends.
|
|
150
149
|
*/
|
|
@@ -164,7 +163,7 @@ interface AddFactResult {
|
|
|
164
163
|
* Fires on EVERY state transition the verification queue produces —
|
|
165
164
|
* non-terminal (`partial`, `awaiting_question`, `awaiting_answer`,
|
|
166
165
|
* `pending_confirmation_matched`, `pending_confirmation_unmatched`,
|
|
167
|
-
* `processing`) AND terminal (`matched`, `unmatched
|
|
166
|
+
* `processing`) AND terminal (`matched`, `unmatched`).
|
|
168
167
|
*
|
|
169
168
|
* Subscribe with:
|
|
170
169
|
* sdk.on("FACT_VERIFIED", (payload: FactVerifiedPayload) => {...});
|
|
@@ -286,6 +285,13 @@ declare class AiQaSdk implements IAiqaSdk {
|
|
|
286
285
|
internalListeners: Map<SdkEvent, Set<(...args: any[]) => void>>;
|
|
287
286
|
internalEvents: Set<SdkEvent>;
|
|
288
287
|
private wrappersByEvent;
|
|
288
|
+
/**
|
|
289
|
+
* Trailing-debounce window (ms) applied per fact in {@link addFact}. Defaults
|
|
290
|
+
* to {@link ADD_FACT_DEBOUNCE_MS}; set to 0 to disable debouncing and send
|
|
291
|
+
* every call immediately.
|
|
292
|
+
*/
|
|
293
|
+
addFactDebounceMs: number;
|
|
294
|
+
private pendingAddFacts;
|
|
289
295
|
constructor(applicationId: string, applicationSecret: string, url?: string);
|
|
290
296
|
on(name: SdkEvent, callback: (...args: any[]) => any): void;
|
|
291
297
|
off(name: SdkEvent, callback?: (...args: any[]) => any): void;
|
|
@@ -295,6 +301,8 @@ declare class AiQaSdk implements IAiqaSdk {
|
|
|
295
301
|
getApplication(): Promise<Application>;
|
|
296
302
|
getFacts(): Promise<ApplicationFact[]>;
|
|
297
303
|
addFact(fact: ApplicationFactInput): Promise<AddFactResult>;
|
|
304
|
+
private flushAddFact;
|
|
305
|
+
private sendAddFact;
|
|
298
306
|
flagFact(factId: string): Promise<FlagFactResult>;
|
|
299
307
|
setConversationProduct(product: string): Promise<SetConversationProductResult>;
|
|
300
308
|
setConversationLanguage(language: ConversationLanguage): Promise<SetConversationLanguageResult>;
|
package/dist/browser/browser.js
CHANGED
|
@@ -3397,7 +3397,7 @@ var compareVersions = (left, right) => {
|
|
|
3397
3397
|
// package.json
|
|
3398
3398
|
var package_default = {
|
|
3399
3399
|
name: "@aiqa/sdk",
|
|
3400
|
-
version: "2.0.0-develop.
|
|
3400
|
+
version: "2.0.0-develop.3",
|
|
3401
3401
|
main: "dist/node/node.js",
|
|
3402
3402
|
module: "dist/node/node.js",
|
|
3403
3403
|
types: "dist/node/node.d.ts",
|
|
@@ -3479,6 +3479,7 @@ var package_default = {
|
|
|
3479
3479
|
var SDK_VERSION = package_default.version ?? "0.0.1";
|
|
3480
3480
|
var DEFAULT_URL = "ws://localhost:3025/ws";
|
|
3481
3481
|
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
3482
|
+
var ADD_FACT_DEBOUNCE_MS = 500;
|
|
3482
3483
|
var RUNTIME = typeof window !== "undefined" && typeof window.document !== "undefined" ? "browser" : "node";
|
|
3483
3484
|
var USER_AGENT = RUNTIME === "browser" ? typeof navigator !== "undefined" ? navigator.userAgent : "browser/unknown" : typeof process !== "undefined" ? `node ${process.version} ${process.platform}` : "node/unknown";
|
|
3484
3485
|
function isThenable(value2) {
|
|
@@ -3524,6 +3525,15 @@ var AiQaSdk = class {
|
|
|
3524
3525
|
// same fn twice registers two wrappers and two off() calls clear
|
|
3525
3526
|
// both.
|
|
3526
3527
|
this.wrappersByEvent = /* @__PURE__ */ new Map();
|
|
3528
|
+
/**
|
|
3529
|
+
* Trailing-debounce window (ms) applied per fact in {@link addFact}. Defaults
|
|
3530
|
+
* to {@link ADD_FACT_DEBOUNCE_MS}; set to 0 to disable debouncing and send
|
|
3531
|
+
* every call immediately.
|
|
3532
|
+
*/
|
|
3533
|
+
this.addFactDebounceMs = ADD_FACT_DEBOUNCE_MS;
|
|
3534
|
+
// In-flight debounce state keyed by fact id: the pending timer, the latest
|
|
3535
|
+
// payload to send when it fires, and every caller awaiting that send.
|
|
3536
|
+
this.pendingAddFacts = /* @__PURE__ */ new Map();
|
|
3527
3537
|
this.url = url2 ?? DEFAULT_URL;
|
|
3528
3538
|
this.internalListeners = /* @__PURE__ */ new Map();
|
|
3529
3539
|
this.internalEvents = /* @__PURE__ */ new Set(["authenticated"]);
|
|
@@ -3613,7 +3623,14 @@ var AiQaSdk = class {
|
|
|
3613
3623
|
const url2 = new URL(this.url);
|
|
3614
3624
|
const socketOptions = {
|
|
3615
3625
|
reconnectionDelayMax: 1e4,
|
|
3616
|
-
path: url2.pathname
|
|
3626
|
+
path: url2.pathname,
|
|
3627
|
+
// WebSocket only, skipping engine.io's default HTTP long-polling phase.
|
|
3628
|
+
// Some embedders sit behind proxies/security gateways that duplicate the
|
|
3629
|
+
// polling GETs across a fleet; the concurrent polls violate engine.io's
|
|
3630
|
+
// one-inflight-poll-per-session rule and tear the session down, so every
|
|
3631
|
+
// poll then returns "Session ID unknown" (HTTP 400) and the client never
|
|
3632
|
+
// authenticates. A single WebSocket has no repeated requests to duplicate.
|
|
3633
|
+
transports: ["websocket"]
|
|
3617
3634
|
};
|
|
3618
3635
|
this.socket = lookup2(url2.origin, socketOptions);
|
|
3619
3636
|
this.socket.on("connect", () => {
|
|
@@ -3643,6 +3660,13 @@ var AiQaSdk = class {
|
|
|
3643
3660
|
this.socket.disconnect();
|
|
3644
3661
|
}
|
|
3645
3662
|
this.wrappersByEvent.clear();
|
|
3663
|
+
for (const entry of this.pendingAddFacts.values()) {
|
|
3664
|
+
clearTimeout(entry.timer);
|
|
3665
|
+
entry.waiters.forEach(
|
|
3666
|
+
(w) => w.reject(new Error("Socket disconnected before addFact was sent"))
|
|
3667
|
+
);
|
|
3668
|
+
}
|
|
3669
|
+
this.pendingAddFacts.clear();
|
|
3646
3670
|
}
|
|
3647
3671
|
sendMessage(method, data) {
|
|
3648
3672
|
return new Promise((resolve, reject) => {
|
|
@@ -3692,7 +3716,40 @@ var AiQaSdk = class {
|
|
|
3692
3716
|
const result = await this.sendMessage("GET_FACTS" /* GET_FACTS */);
|
|
3693
3717
|
return result && result.data !== void 0 ? result.data : result;
|
|
3694
3718
|
}
|
|
3695
|
-
|
|
3719
|
+
addFact(fact) {
|
|
3720
|
+
if (this.addFactDebounceMs <= 0) {
|
|
3721
|
+
return this.sendAddFact(fact);
|
|
3722
|
+
}
|
|
3723
|
+
const key = fact.questionId ?? fact.id;
|
|
3724
|
+
return new Promise((resolve, reject) => {
|
|
3725
|
+
const existing = this.pendingAddFacts.get(key);
|
|
3726
|
+
if (existing) {
|
|
3727
|
+
clearTimeout(existing.timer);
|
|
3728
|
+
existing.latest = fact;
|
|
3729
|
+
existing.waiters.push({ resolve, reject });
|
|
3730
|
+
existing.timer = setTimeout(
|
|
3731
|
+
() => this.flushAddFact(key),
|
|
3732
|
+
this.addFactDebounceMs
|
|
3733
|
+
);
|
|
3734
|
+
return;
|
|
3735
|
+
}
|
|
3736
|
+
this.pendingAddFacts.set(key, {
|
|
3737
|
+
latest: fact,
|
|
3738
|
+
waiters: [{ resolve, reject }],
|
|
3739
|
+
timer: setTimeout(() => this.flushAddFact(key), this.addFactDebounceMs)
|
|
3740
|
+
});
|
|
3741
|
+
});
|
|
3742
|
+
}
|
|
3743
|
+
flushAddFact(key) {
|
|
3744
|
+
const entry = this.pendingAddFacts.get(key);
|
|
3745
|
+
if (!entry) return;
|
|
3746
|
+
this.pendingAddFacts.delete(key);
|
|
3747
|
+
this.sendAddFact(entry.latest).then(
|
|
3748
|
+
(result) => entry.waiters.forEach((w) => w.resolve(result)),
|
|
3749
|
+
(error) => entry.waiters.forEach((w) => w.reject(error))
|
|
3750
|
+
);
|
|
3751
|
+
}
|
|
3752
|
+
async sendAddFact(fact) {
|
|
3696
3753
|
const payload = {
|
|
3697
3754
|
...fact,
|
|
3698
3755
|
critical: fact.critical ?? false,
|