@chatcops/core 0.4.0 → 0.6.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/dist/agent/chat.d.ts +13 -0
- package/dist/agent/chat.d.ts.map +1 -0
- package/dist/agent/chat.js +42 -0
- package/dist/agent/chat.js.map +1 -0
- package/dist/agent/errors.d.ts +14 -0
- package/dist/agent/errors.d.ts.map +1 -0
- package/dist/agent/errors.js +24 -0
- package/dist/agent/errors.js.map +1 -0
- package/dist/agent/index.d.ts +5 -0
- package/dist/agent/index.d.ts.map +1 -0
- package/dist/agent/index.js +5 -0
- package/dist/agent/index.js.map +1 -0
- package/dist/agent/run-turn.d.ts +79 -0
- package/dist/agent/run-turn.d.ts.map +1 -0
- package/dist/agent/run-turn.js +400 -0
- package/dist/agent/run-turn.js.map +1 -0
- package/dist/agent/tool-registry.d.ts +30 -0
- package/dist/agent/tool-registry.d.ts.map +1 -0
- package/dist/agent/tool-registry.js +66 -0
- package/dist/agent/tool-registry.js.map +1 -0
- package/dist/analytics/collector.d.ts +2 -0
- package/dist/analytics/collector.d.ts.map +1 -1
- package/dist/analytics/collector.js +16 -10
- package/dist/analytics/collector.js.map +1 -1
- package/dist/analytics/index.d.ts +2 -0
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +2 -0
- package/dist/analytics/index.js.map +1 -1
- package/dist/analytics/names.d.ts +21 -0
- package/dist/analytics/names.d.ts.map +1 -0
- package/dist/analytics/names.js +41 -0
- package/dist/analytics/names.js.map +1 -0
- package/dist/analytics/sink.d.ts +27 -0
- package/dist/analytics/sink.d.ts.map +1 -0
- package/dist/analytics/sink.js +109 -0
- package/dist/analytics/sink.js.map +1 -0
- package/dist/conversation/index.d.ts +1 -0
- package/dist/conversation/index.d.ts.map +1 -1
- package/dist/conversation/index.js.map +1 -1
- package/dist/conversation/manager.d.ts +65 -6
- package/dist/conversation/manager.d.ts.map +1 -1
- package/dist/conversation/manager.js +110 -34
- package/dist/conversation/manager.js.map +1 -1
- package/dist/conversation/store.d.ts +6 -5
- package/dist/conversation/store.d.ts.map +1 -1
- package/dist/conversation/store.js +4 -0
- package/dist/conversation/store.js.map +1 -1
- package/dist/index.d.ts +21 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2
- package/dist/index.js.map +1 -1
- package/dist/knowledge/base.d.ts +8 -0
- package/dist/knowledge/base.d.ts.map +1 -1
- package/dist/knowledge/tokenize.d.ts.map +1 -1
- package/dist/knowledge/tokenize.js +4 -4
- package/dist/knowledge/tokenize.js.map +1 -1
- package/dist/limits/budget.d.ts +84 -0
- package/dist/limits/budget.d.ts.map +1 -0
- package/dist/limits/budget.js +114 -0
- package/dist/limits/budget.js.map +1 -0
- package/dist/limits/rate-limit.d.ts +53 -0
- package/dist/limits/rate-limit.d.ts.map +1 -0
- package/dist/limits/rate-limit.js +68 -0
- package/dist/limits/rate-limit.js.map +1 -0
- package/dist/logger.d.ts +36 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +40 -0
- package/dist/logger.js.map +1 -0
- package/dist/parts.d.ts +9 -0
- package/dist/parts.d.ts.map +1 -0
- package/dist/parts.js +17 -0
- package/dist/parts.js.map +1 -0
- package/dist/protocol/ai-sdk.d.ts +27 -0
- package/dist/protocol/ai-sdk.d.ts.map +1 -0
- package/dist/protocol/ai-sdk.js +127 -0
- package/dist/protocol/ai-sdk.js.map +1 -0
- package/dist/protocol/errors.d.ts +10 -0
- package/dist/protocol/errors.d.ts.map +1 -0
- package/dist/protocol/errors.js +42 -0
- package/dist/protocol/errors.js.map +1 -0
- package/dist/protocol/index.d.ts +9 -0
- package/dist/protocol/index.d.ts.map +1 -0
- package/dist/protocol/index.js +6 -0
- package/dist/protocol/index.js.map +1 -0
- package/dist/protocol/legacy.d.ts +18 -0
- package/dist/protocol/legacy.d.ts.map +1 -0
- package/dist/protocol/legacy.js +41 -0
- package/dist/protocol/legacy.js.map +1 -0
- package/dist/protocol/sse.d.ts +10 -0
- package/dist/protocol/sse.d.ts.map +1 -0
- package/dist/protocol/sse.js +15 -0
- package/dist/protocol/sse.js.map +1 -0
- package/dist/protocol/v1.d.ts +140 -0
- package/dist/protocol/v1.d.ts.map +1 -0
- package/dist/protocol/v1.js +15 -0
- package/dist/protocol/v1.js.map +1 -0
- package/dist/providers/base.d.ts +13 -28
- package/dist/providers/base.d.ts.map +1 -1
- package/dist/providers/base.js +36 -47
- package/dist/providers/base.js.map +1 -1
- package/dist/providers/claude.d.ts +41 -6
- package/dist/providers/claude.d.ts.map +1 -1
- package/dist/providers/claude.js +223 -96
- package/dist/providers/claude.js.map +1 -1
- package/dist/providers/gemini.d.ts +18 -3
- package/dist/providers/gemini.d.ts.map +1 -1
- package/dist/providers/gemini.js +208 -91
- package/dist/providers/gemini.js.map +1 -1
- package/dist/providers/history.d.ts +52 -0
- package/dist/providers/history.d.ts.map +1 -0
- package/dist/providers/history.js +212 -0
- package/dist/providers/history.js.map +1 -0
- package/dist/providers/index.d.ts +5 -5
- package/dist/providers/index.d.ts.map +1 -1
- package/dist/providers/index.js +5 -4
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/openai.d.ts +28 -6
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +213 -113
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/registry.d.ts +7 -0
- package/dist/providers/registry.d.ts.map +1 -0
- package/dist/providers/registry.js +12 -0
- package/dist/providers/registry.js.map +1 -0
- package/dist/providers/schema.d.ts +16 -0
- package/dist/providers/schema.d.ts.map +1 -0
- package/dist/providers/schema.js +80 -0
- package/dist/providers/schema.js.map +1 -0
- package/dist/providers/tool-execution.d.ts +13 -0
- package/dist/providers/tool-execution.d.ts.map +1 -1
- package/dist/providers/tool-execution.js +49 -13
- package/dist/providers/tool-execution.js.map +1 -1
- package/dist/providers/types.d.ts +89 -0
- package/dist/providers/types.d.ts.map +1 -0
- package/dist/providers/types.js +2 -0
- package/dist/providers/types.js.map +1 -0
- package/dist/retrieval/citations.d.ts +44 -0
- package/dist/retrieval/citations.d.ts.map +1 -0
- package/dist/retrieval/citations.js +97 -0
- package/dist/retrieval/citations.js.map +1 -0
- package/dist/retrieval/cohere-reranker.d.ts +13 -0
- package/dist/retrieval/cohere-reranker.d.ts.map +1 -0
- package/dist/retrieval/cohere-reranker.js +33 -0
- package/dist/retrieval/cohere-reranker.js.map +1 -0
- package/dist/retrieval/gemini-embedder.d.ts +26 -0
- package/dist/retrieval/gemini-embedder.d.ts.map +1 -0
- package/dist/retrieval/gemini-embedder.js +36 -0
- package/dist/retrieval/gemini-embedder.js.map +1 -0
- package/dist/retrieval/http.d.ts +20 -0
- package/dist/retrieval/http.d.ts.map +1 -0
- package/dist/retrieval/http.js +68 -0
- package/dist/retrieval/http.js.map +1 -0
- package/dist/retrieval/index.d.ts +14 -0
- package/dist/retrieval/index.d.ts.map +1 -0
- package/dist/retrieval/index.js +13 -0
- package/dist/retrieval/index.js.map +1 -0
- package/dist/retrieval/knowledge.d.ts +16 -0
- package/dist/retrieval/knowledge.d.ts.map +1 -0
- package/dist/retrieval/knowledge.js +21 -0
- package/dist/retrieval/knowledge.js.map +1 -0
- package/dist/retrieval/openai-embedder.d.ts +25 -0
- package/dist/retrieval/openai-embedder.d.ts.map +1 -0
- package/dist/retrieval/openai-embedder.js +30 -0
- package/dist/retrieval/openai-embedder.js.map +1 -0
- package/dist/retrieval/query.d.ts +8 -0
- package/dist/retrieval/query.d.ts.map +1 -0
- package/dist/retrieval/query.js +19 -0
- package/dist/retrieval/query.js.map +1 -0
- package/dist/retrieval/retrievers.d.ts +30 -0
- package/dist/retrieval/retrievers.d.ts.map +1 -0
- package/dist/retrieval/retrievers.js +89 -0
- package/dist/retrieval/retrievers.js.map +1 -0
- package/dist/retrieval/sources.d.ts +16 -0
- package/dist/retrieval/sources.d.ts.map +1 -0
- package/dist/retrieval/sources.js +37 -0
- package/dist/retrieval/sources.js.map +1 -0
- package/dist/retrieval/types.d.ts +50 -0
- package/dist/retrieval/types.d.ts.map +1 -0
- package/dist/retrieval/types.js +2 -0
- package/dist/retrieval/types.js.map +1 -0
- package/dist/retrieval/voyage-embedder.d.ts +33 -0
- package/dist/retrieval/voyage-embedder.d.ts.map +1 -0
- package/dist/retrieval/voyage-embedder.js +33 -0
- package/dist/retrieval/voyage-embedder.js.map +1 -0
- package/dist/retrieval/voyage-reranker.d.ts +13 -0
- package/dist/retrieval/voyage-reranker.d.ts.map +1 -0
- package/dist/retrieval/voyage-reranker.js +38 -0
- package/dist/retrieval/voyage-reranker.js.map +1 -0
- package/dist/retrieval/workers-ai-embedder.d.ts +21 -0
- package/dist/retrieval/workers-ai-embedder.d.ts.map +1 -0
- package/dist/retrieval/workers-ai-embedder.js +42 -0
- package/dist/retrieval/workers-ai-embedder.js.map +1 -0
- package/dist/retrieval/workers-ai-reranker.d.ts +11 -0
- package/dist/retrieval/workers-ai-reranker.d.ts.map +1 -0
- package/dist/retrieval/workers-ai-reranker.js +54 -0
- package/dist/retrieval/workers-ai-reranker.js.map +1 -0
- package/dist/storage/adapt.d.ts +15 -0
- package/dist/storage/adapt.d.ts.map +1 -0
- package/dist/storage/adapt.js +83 -0
- package/dist/storage/adapt.js.map +1 -0
- package/dist/storage/errors.d.ts +18 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +28 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/index.d.ts +6 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +5 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/memory-vectors.d.ts +22 -0
- package/dist/storage/memory-vectors.d.ts.map +1 -0
- package/dist/storage/memory-vectors.js +140 -0
- package/dist/storage/memory-vectors.js.map +1 -0
- package/dist/storage/memory.d.ts +24 -0
- package/dist/storage/memory.d.ts.map +1 -0
- package/dist/storage/memory.js +265 -0
- package/dist/storage/memory.js.map +1 -0
- package/dist/storage/types.d.ts +188 -0
- package/dist/storage/types.d.ts.map +1 -0
- package/dist/storage/types.js +2 -0
- package/dist/storage/types.js.map +1 -0
- package/dist/testing/conformance.d.ts +30 -0
- package/dist/testing/conformance.d.ts.map +1 -0
- package/dist/testing/conformance.js +505 -0
- package/dist/testing/conformance.js.map +1 -0
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +5 -0
- package/dist/testing/index.js.map +1 -0
- package/dist/testing/provider.d.ts +47 -0
- package/dist/testing/provider.d.ts.map +1 -0
- package/dist/testing/provider.js +83 -0
- package/dist/testing/provider.js.map +1 -0
- package/dist/tools/base.d.ts +14 -4
- package/dist/tools/base.d.ts.map +1 -1
- package/dist/tools/base.js +4 -2
- package/dist/tools/base.js.map +1 -1
- package/dist/tools/lead-capture.d.ts +4 -2
- package/dist/tools/lead-capture.d.ts.map +1 -1
- package/dist/tools/lead-capture.js +7 -2
- package/dist/tools/lead-capture.js.map +1 -1
- package/dist/types.d.ts +146 -7
- package/dist/types.d.ts.map +1 -1
- package/package.json +51 -3
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { CounterStore } from '../storage/types.js';
|
|
2
|
+
export interface RateLimitRule {
|
|
3
|
+
/** Maximum requests allowed per window. */
|
|
4
|
+
limit: number;
|
|
5
|
+
windowMs: number;
|
|
6
|
+
}
|
|
7
|
+
export interface RateLimitResult {
|
|
8
|
+
allowed: boolean;
|
|
9
|
+
/** Requests left in the current window, never below 0. */
|
|
10
|
+
remaining: number;
|
|
11
|
+
/** When denied: how long until a request would be allowed again. */
|
|
12
|
+
retryAfterMs?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface RateLimiterOptions {
|
|
15
|
+
/** Key namespace; defaults to 'rl'. */
|
|
16
|
+
prefix?: string;
|
|
17
|
+
/** Seam for tests; defaults to Date.now. */
|
|
18
|
+
now?: () => number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Sliding-window rate limiter built on two fixed-window counters.
|
|
22
|
+
*
|
|
23
|
+
* Two fixed windows — the current one and the previous one — give a smooth
|
|
24
|
+
* sliding estimate without needing per-request timestamps:
|
|
25
|
+
*
|
|
26
|
+
* estimate = prev × (1 − elapsed/windowMs) + current
|
|
27
|
+
*
|
|
28
|
+
* where `elapsed` is how far we are into the current window. At the boundary
|
|
29
|
+
* the previous window fades out linearly, so the effective limit never exceeds
|
|
30
|
+
* `limit` over any rolling window.
|
|
31
|
+
*
|
|
32
|
+
* retryAfterMs formula
|
|
33
|
+
* --------------------
|
|
34
|
+
* We want the smallest t (in ms from now) such that the estimate drops to
|
|
35
|
+
* `limit`. All denied requests have already been counted, so `current` won't
|
|
36
|
+
* change. As time advances by t, `elapsed` increases by t and `prev`'s weight
|
|
37
|
+
* shrinks:
|
|
38
|
+
*
|
|
39
|
+
* prev × (1 − (elapsed + t)/windowMs) + current ≤ limit
|
|
40
|
+
* prev × (1 − (elapsed + t)/windowMs) ≤ limit − current
|
|
41
|
+
*
|
|
42
|
+
* Rearranging (prev > 0 required, otherwise we'd already be under the limit):
|
|
43
|
+
*
|
|
44
|
+
* 1 − (elapsed + t)/windowMs ≤ (limit − current) / prev
|
|
45
|
+
* t ≥ windowMs × (1 − (limit − current) / prev) − elapsed
|
|
46
|
+
* t ≥ windowMs − elapsed − windowMs × (limit − current) / prev
|
|
47
|
+
*
|
|
48
|
+
* Clamped to [1, windowMs] to keep the estimate positive and bounded.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createRateLimiter(counters: CounterStore, rule: RateLimitRule, options?: RateLimiterOptions): {
|
|
51
|
+
check(key: string): Promise<RateLimitResult>;
|
|
52
|
+
};
|
|
53
|
+
//# sourceMappingURL=rate-limit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.d.ts","sourceRoot":"","sources":["../../src/limits/rate-limit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,MAAM,WAAW,aAAa;IAC5B,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,CAAC;IACjB,0DAA0D;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,oEAAoE;IACpE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,uCAAuC;IACvC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,EACtB,IAAI,EAAE,aAAa,EACnB,OAAO,GAAE,kBAAuB,GAC/B;IAAE,KAAK,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;CAAE,CA0ClD"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sliding-window rate limiter built on two fixed-window counters.
|
|
3
|
+
*
|
|
4
|
+
* Two fixed windows — the current one and the previous one — give a smooth
|
|
5
|
+
* sliding estimate without needing per-request timestamps:
|
|
6
|
+
*
|
|
7
|
+
* estimate = prev × (1 − elapsed/windowMs) + current
|
|
8
|
+
*
|
|
9
|
+
* where `elapsed` is how far we are into the current window. At the boundary
|
|
10
|
+
* the previous window fades out linearly, so the effective limit never exceeds
|
|
11
|
+
* `limit` over any rolling window.
|
|
12
|
+
*
|
|
13
|
+
* retryAfterMs formula
|
|
14
|
+
* --------------------
|
|
15
|
+
* We want the smallest t (in ms from now) such that the estimate drops to
|
|
16
|
+
* `limit`. All denied requests have already been counted, so `current` won't
|
|
17
|
+
* change. As time advances by t, `elapsed` increases by t and `prev`'s weight
|
|
18
|
+
* shrinks:
|
|
19
|
+
*
|
|
20
|
+
* prev × (1 − (elapsed + t)/windowMs) + current ≤ limit
|
|
21
|
+
* prev × (1 − (elapsed + t)/windowMs) ≤ limit − current
|
|
22
|
+
*
|
|
23
|
+
* Rearranging (prev > 0 required, otherwise we'd already be under the limit):
|
|
24
|
+
*
|
|
25
|
+
* 1 − (elapsed + t)/windowMs ≤ (limit − current) / prev
|
|
26
|
+
* t ≥ windowMs × (1 − (limit − current) / prev) − elapsed
|
|
27
|
+
* t ≥ windowMs − elapsed − windowMs × (limit − current) / prev
|
|
28
|
+
*
|
|
29
|
+
* Clamped to [1, windowMs] to keep the estimate positive and bounded.
|
|
30
|
+
*/
|
|
31
|
+
export function createRateLimiter(counters, rule, options = {}) {
|
|
32
|
+
if (rule.limit <= 0)
|
|
33
|
+
throw new Error('limit must be greater than 0');
|
|
34
|
+
if (rule.windowMs <= 0)
|
|
35
|
+
throw new Error('windowMs must be greater than 0');
|
|
36
|
+
const prefix = options.prefix ?? 'rl';
|
|
37
|
+
const now = options.now ?? Date.now;
|
|
38
|
+
return {
|
|
39
|
+
async check(key) {
|
|
40
|
+
const t = now();
|
|
41
|
+
const index = Math.floor(t / rule.windowMs);
|
|
42
|
+
const elapsed = t - index * rule.windowMs;
|
|
43
|
+
// Increment the current window. TTL is 2× so the previous window
|
|
44
|
+
// stays readable for the whole next window period.
|
|
45
|
+
const currentKey = `${prefix}:${key}:${index}`;
|
|
46
|
+
const [currentEntry, prevEntry] = await Promise.all([
|
|
47
|
+
counters.increment(currentKey, 1, 2 * rule.windowMs),
|
|
48
|
+
counters.get(`${prefix}:${key}:${index - 1}`),
|
|
49
|
+
]);
|
|
50
|
+
const current = currentEntry.value;
|
|
51
|
+
const prev = prevEntry?.value ?? 0;
|
|
52
|
+
// Sliding-window estimate: blend the previous window's tail.
|
|
53
|
+
const estimate = prev * (1 - elapsed / rule.windowMs) + current;
|
|
54
|
+
if (estimate <= rule.limit) {
|
|
55
|
+
return { allowed: true, remaining: Math.max(0, Math.floor(rule.limit - estimate)) };
|
|
56
|
+
}
|
|
57
|
+
// Time (ms) until the estimate would drop back to limit.
|
|
58
|
+
// Derived above; prev > 0 whenever estimate > limit and decay is possible.
|
|
59
|
+
// When prev = 0 the counter only resets at the window boundary, so we wait
|
|
60
|
+
// out the remainder of the current window.
|
|
61
|
+
const retryAfterMs = prev > 0
|
|
62
|
+
? Math.min(rule.windowMs, Math.max(1, Math.ceil(rule.windowMs - elapsed - (rule.windowMs * (rule.limit - current)) / prev)))
|
|
63
|
+
: Math.max(1, rule.windowMs - elapsed);
|
|
64
|
+
return { allowed: false, remaining: 0, retryAfterMs };
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=rate-limit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rate-limit.js","sourceRoot":"","sources":["../../src/limits/rate-limit.ts"],"names":[],"mappings":"AAuBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,iBAAiB,CAC/B,QAAsB,EACtB,IAAmB,EACnB,UAA8B,EAAE;IAEhC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,8BAA8B,CAAC,CAAC;IACrE,IAAI,IAAI,CAAC,QAAQ,IAAI,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IAE3E,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC;IAEpC,OAAO;QACL,KAAK,CAAC,KAAK,CAAC,GAAW;YACrB,MAAM,CAAC,GAAG,GAAG,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,CAAC,GAAG,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC;YAE1C,iEAAiE;YACjE,mDAAmD;YACnD,MAAM,UAAU,GAAG,GAAG,MAAM,IAAI,GAAG,IAAI,KAAK,EAAE,CAAC;YAC/C,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAClD,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC;gBACpD,QAAQ,CAAC,GAAG,CAAC,GAAG,MAAM,IAAI,GAAG,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;aAC9C,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,YAAY,CAAC,KAAK,CAAC;YACnC,MAAM,IAAI,GAAG,SAAS,EAAE,KAAK,IAAI,CAAC,CAAC;YAEnC,6DAA6D;YAC7D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,OAAO,CAAC;YAEhE,IAAI,QAAQ,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC3B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,EAAE,CAAC;YACtF,CAAC;YAED,yDAAyD;YACzD,2EAA2E;YAC3E,2EAA2E;YAC3E,2CAA2C;YAC3C,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC;gBAC3B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,QAAQ,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;gBAC5H,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC;YAEzC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,EAAE,YAAY,EAAE,CAAC;QACxD,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Extra details for a log line. An `error` field is printed in full. */
|
|
2
|
+
export type LogFields = Record<string, unknown>;
|
|
3
|
+
/**
|
|
4
|
+
* Where ChatCops writes what it notices: startup notes, refused requests and
|
|
5
|
+
* every error it catches instead of throwing. `event` is a stable name to
|
|
6
|
+
* filter or alert on (`provider_error`, `tool_error`, `webhook_failed`, …),
|
|
7
|
+
* and `message` is for people.
|
|
8
|
+
*/
|
|
9
|
+
export interface Logger {
|
|
10
|
+
debug(event: string, message: string, fields?: LogFields): void;
|
|
11
|
+
info(event: string, message: string, fields?: LogFields): void;
|
|
12
|
+
warn(event: string, message: string, fields?: LogFields): void;
|
|
13
|
+
error(event: string, message: string, fields?: LogFields): void;
|
|
14
|
+
}
|
|
15
|
+
type Level = keyof Logger;
|
|
16
|
+
/**
|
|
17
|
+
* The default: `[chatcops] message` on the console, with an `error` field
|
|
18
|
+
* printed after it so its stack shows. Other fields are left out, to keep
|
|
19
|
+
* the lines short.
|
|
20
|
+
*/
|
|
21
|
+
export declare function consoleLogger(): Logger;
|
|
22
|
+
export interface JsonLoggerOptions {
|
|
23
|
+
/** Where each line goes. Default `console.error`, which is stderr on Node and the log on Workers. */
|
|
24
|
+
write?: (line: string) => void;
|
|
25
|
+
/** Lines below this level are dropped. Default `info`. */
|
|
26
|
+
level?: Level;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One JSON object per line (`{ time, level, event, message, ...fields }`), for
|
|
30
|
+
* log tools that parse them. Errors become `{ name, message, stack }`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function jsonLogger(options?: JsonLoggerOptions): Logger;
|
|
33
|
+
/** A logger that writes nothing, for tests. */
|
|
34
|
+
export declare function silentLogger(): Logger;
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEhD;;;;;GAKG;AACH,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAChE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IAC/D,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;CACjE;AAED,KAAK,KAAK,GAAG,MAAM,MAAM,CAAC;AAG1B;;;;GAIG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAOtC;AAED,MAAM,WAAW,iBAAiB;IAChC,qGAAqG;IACrG,KAAK,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,0DAA0D;IAC1D,KAAK,CAAC,EAAE,KAAK,CAAC;CACf;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CASlE;AAMD,+CAA+C;AAC/C,wBAAgB,YAAY,IAAI,MAAM,CAGrC"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
const LEVELS = ['debug', 'info', 'warn', 'error'];
|
|
2
|
+
/**
|
|
3
|
+
* The default: `[chatcops] message` on the console, with an `error` field
|
|
4
|
+
* printed after it so its stack shows. Other fields are left out, to keep
|
|
5
|
+
* the lines short.
|
|
6
|
+
*/
|
|
7
|
+
export function consoleLogger() {
|
|
8
|
+
const write = (level) => (_event, message, fields) => {
|
|
9
|
+
const line = `[chatcops] ${message}`;
|
|
10
|
+
if (fields?.error !== undefined)
|
|
11
|
+
console[level](line, fields.error);
|
|
12
|
+
else
|
|
13
|
+
console[level](line);
|
|
14
|
+
};
|
|
15
|
+
return Object.fromEntries(LEVELS.map((level) => [level, write(level)]));
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* One JSON object per line (`{ time, level, event, message, ...fields }`), for
|
|
19
|
+
* log tools that parse them. Errors become `{ name, message, stack }`.
|
|
20
|
+
*/
|
|
21
|
+
export function jsonLogger(options = {}) {
|
|
22
|
+
const write = options.write ?? ((line) => console.error(line));
|
|
23
|
+
const min = LEVELS.indexOf(options.level ?? 'info');
|
|
24
|
+
const log = (level) => (event, message, fields = {}) => {
|
|
25
|
+
if (LEVELS.indexOf(level) < min)
|
|
26
|
+
return;
|
|
27
|
+
const entries = Object.entries(fields).map(([key, value]) => [key, value instanceof Error ? describeError(value) : value]);
|
|
28
|
+
write(JSON.stringify({ time: new Date().toISOString(), level, event, message, ...Object.fromEntries(entries) }));
|
|
29
|
+
};
|
|
30
|
+
return Object.fromEntries(LEVELS.map((level) => [level, log(level)]));
|
|
31
|
+
}
|
|
32
|
+
function describeError(error) {
|
|
33
|
+
return { name: error.name, message: error.message, ...(error.stack ? { stack: error.stack } : {}) };
|
|
34
|
+
}
|
|
35
|
+
/** A logger that writes nothing, for tests. */
|
|
36
|
+
export function silentLogger() {
|
|
37
|
+
const nothing = () => { };
|
|
38
|
+
return { debug: nothing, info: nothing, warn: nothing, error: nothing };
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAiBA,MAAM,MAAM,GAAY,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;AAE3D;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,KAAK,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC,MAAc,EAAE,OAAe,EAAE,MAAkB,EAAE,EAAE;QACtF,MAAM,IAAI,GAAG,cAAc,OAAO,EAAE,CAAC;QACrC,IAAI,MAAM,EAAE,KAAK,KAAK,SAAS;YAAE,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;;YAC/D,OAAO,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAsB,CAAC;AAC/F,CAAC;AASD;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,UAA6B,EAAE;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,CAAC,IAAY,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC;IACpD,MAAM,GAAG,GAAG,CAAC,KAAY,EAAE,EAAE,CAAC,CAAC,KAAa,EAAE,OAAe,EAAE,SAAoB,EAAE,EAAE,EAAE;QACvF,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG;YAAE,OAAO;QACxC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAC3H,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;IACnH,CAAC,CAAC;IACF,OAAO,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAsB,CAAC;AAC7F,CAAC;AAED,SAAS,aAAa,CAAC,KAAY;IACjC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AACtG,CAAC;AAED,+CAA+C;AAC/C,MAAM,UAAU,YAAY;IAC1B,MAAM,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IACzB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC1E,CAAC"}
|
package/dist/parts.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChatMessage, MessagePart } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The parts of a message. Messages saved before parts existed only have
|
|
4
|
+
* `content`, which counts as a single text part (none when it's empty).
|
|
5
|
+
*/
|
|
6
|
+
export declare function partsOf(message: Pick<ChatMessage, 'content' | 'parts'>): MessagePart[];
|
|
7
|
+
/** The text parts joined, which is what `ChatMessage.content` holds. */
|
|
8
|
+
export declare function messageText(parts: readonly MessagePart[]): string;
|
|
9
|
+
//# sourceMappingURL=parts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.d.ts","sourceRoot":"","sources":["../src/parts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAY,MAAM,YAAY,CAAC;AAErE;;;GAGG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,WAAW,EAAE,CAGtF;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,WAAW,EAAE,GAAG,MAAM,CAKjE"}
|
package/dist/parts.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The parts of a message. Messages saved before parts existed only have
|
|
3
|
+
* `content`, which counts as a single text part (none when it's empty).
|
|
4
|
+
*/
|
|
5
|
+
export function partsOf(message) {
|
|
6
|
+
if (message.parts)
|
|
7
|
+
return message.parts;
|
|
8
|
+
return message.content ? [{ type: 'text', text: message.content }] : [];
|
|
9
|
+
}
|
|
10
|
+
/** The text parts joined, which is what `ChatMessage.content` holds. */
|
|
11
|
+
export function messageText(parts) {
|
|
12
|
+
return parts
|
|
13
|
+
.filter((part) => part.type === 'text')
|
|
14
|
+
.map((part) => part.text)
|
|
15
|
+
.join('');
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=parts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parts.js","sourceRoot":"","sources":["../src/parts.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,OAAO,CAAC,OAA+C;IACrE,IAAI,OAAO,CAAC,KAAK;QAAE,OAAO,OAAO,CAAC,KAAK,CAAC;IACxC,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;AAC1E,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,WAAW,CAAC,KAA6B;IACvD,OAAO,KAAK;SACT,MAAM,CAAC,CAAC,IAAI,EAAoB,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,MAAM,CAAC;SACxD,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;SACxB,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { WirePart } from './v1.js';
|
|
2
|
+
/**
|
|
3
|
+
* The AI SDK's UI message stream (what `useChat` reads), so an app built on
|
|
4
|
+
* the AI SDK can point at a ChatCops server. Only the mapping lives here, with
|
|
5
|
+
* no dependency on the `ai` package; `chatcopsAiSdkHandler` in
|
|
6
|
+
* `@chatcops/server` serves it. A contract test pins it to an `ai` version.
|
|
7
|
+
*/
|
|
8
|
+
/** One UI message stream chunk. See `UIMessageChunk` in the `ai` package. */
|
|
9
|
+
export type AiSdkChunk = {
|
|
10
|
+
type: string;
|
|
11
|
+
} & Record<string, unknown>;
|
|
12
|
+
/** The stream header `useChat` checks for. */
|
|
13
|
+
export declare const AI_SDK_STREAM_HEADER = "x-vercel-ai-ui-message-stream";
|
|
14
|
+
/**
|
|
15
|
+
* Turns protocol v1 parts into UI message stream chunks, one reply at a
|
|
16
|
+
* time: it remembers which tools ran on the server and whether the reply was
|
|
17
|
+
* filtered.
|
|
18
|
+
*/
|
|
19
|
+
export declare function aiSdkEncoder(): (part: WirePart) => AiSdkChunk[];
|
|
20
|
+
/**
|
|
21
|
+
* The ChatCops request for a `useChat` request (`{ id, messages, trigger,
|
|
22
|
+
* messageId }`). Only the last user message is read: the server keeps the
|
|
23
|
+
* history, so a client can't add turns the model never wrote. `pageContext`,
|
|
24
|
+
* `locale` and `userData` pass through from the request body.
|
|
25
|
+
*/
|
|
26
|
+
export declare function fromAiSdkRequest(body: unknown): Record<string, unknown>;
|
|
27
|
+
//# sourceMappingURL=ai-sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.d.ts","sourceRoot":"","sources":["../../src/protocol/ai-sdk.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAoB,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE1D;;;;;GAKG;AAEH,6EAA6E;AAC7E,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAEpE,8CAA8C;AAC9C,eAAO,MAAM,oBAAoB,kCAAkC,CAAC;AAWpE;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,CAAC,IAAI,EAAE,QAAQ,KAAK,UAAU,EAAE,CA+D/D;AAQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAwBvE"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/** The stream header `useChat` checks for. */
|
|
2
|
+
export const AI_SDK_STREAM_HEADER = 'x-vercel-ai-ui-message-stream';
|
|
3
|
+
const FINISH_REASONS = {
|
|
4
|
+
stop: 'stop',
|
|
5
|
+
length: 'length',
|
|
6
|
+
error: 'error',
|
|
7
|
+
'client-tool-calls': 'tool-calls',
|
|
8
|
+
'approval-required': 'tool-calls',
|
|
9
|
+
handoff: 'other',
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Turns protocol v1 parts into UI message stream chunks, one reply at a
|
|
13
|
+
* time: it remembers which tools ran on the server and whether the reply was
|
|
14
|
+
* filtered.
|
|
15
|
+
*/
|
|
16
|
+
export function aiSdkEncoder() {
|
|
17
|
+
const serverTools = new Set();
|
|
18
|
+
let filtered = false;
|
|
19
|
+
return (part) => {
|
|
20
|
+
switch (part.type) {
|
|
21
|
+
case 'start':
|
|
22
|
+
return [
|
|
23
|
+
{ type: 'start', messageId: part.messageId, messageMetadata: { conversationId: part.conversationId } },
|
|
24
|
+
{ type: 'start-step' },
|
|
25
|
+
];
|
|
26
|
+
case 'text-start':
|
|
27
|
+
case 'text-end':
|
|
28
|
+
return [{ type: part.type, id: part.id }];
|
|
29
|
+
case 'text-delta':
|
|
30
|
+
return [{ type: 'text-delta', id: part.id, delta: part.delta }];
|
|
31
|
+
case 'source':
|
|
32
|
+
return [{ type: 'source-url', sourceId: part.sourceId, url: part.url, ...(part.title ? { title: part.title } : {}) }];
|
|
33
|
+
case 'tool-call': {
|
|
34
|
+
// A tool the server ran: `useChat` must not run it or wait for its output.
|
|
35
|
+
const server = part.executor === 'server';
|
|
36
|
+
if (server)
|
|
37
|
+
serverTools.add(part.toolCallId);
|
|
38
|
+
return [
|
|
39
|
+
{
|
|
40
|
+
type: 'tool-input-available',
|
|
41
|
+
toolCallId: part.toolCallId,
|
|
42
|
+
toolName: part.toolName,
|
|
43
|
+
input: part.input ?? {},
|
|
44
|
+
...(server ? { providerExecuted: true } : {}),
|
|
45
|
+
...(part.title ? { title: part.title } : {}),
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
}
|
|
49
|
+
case 'tool-result': {
|
|
50
|
+
const executed = serverTools.has(part.toolCallId) ? { providerExecuted: true } : {};
|
|
51
|
+
return part.error !== undefined
|
|
52
|
+
? [{ type: 'tool-output-error', toolCallId: part.toolCallId, errorText: part.error, ...executed }]
|
|
53
|
+
: [{ type: 'tool-output-available', toolCallId: part.toolCallId, output: part.output ?? null, ...executed }];
|
|
54
|
+
}
|
|
55
|
+
case 'lead-captured':
|
|
56
|
+
return [{ type: 'data-lead-captured', data: part.lead }];
|
|
57
|
+
case 'suggestions':
|
|
58
|
+
return [{ type: 'data-suggestions', data: part.items }];
|
|
59
|
+
case 'handoff':
|
|
60
|
+
case 'agent-message': {
|
|
61
|
+
const { type, ...data } = part;
|
|
62
|
+
return [{ type: `data-${type}`, data }];
|
|
63
|
+
}
|
|
64
|
+
case 'error':
|
|
65
|
+
if (part.code === 'content_filtered')
|
|
66
|
+
filtered = true;
|
|
67
|
+
return [{ type: 'error', errorText: part.message ?? part.code }];
|
|
68
|
+
case 'finish': {
|
|
69
|
+
if (part.reason === 'aborted')
|
|
70
|
+
return [{ type: 'abort', reason: 'aborted' }];
|
|
71
|
+
const finishReason = filtered ? 'content-filter' : FINISH_REASONS[part.reason];
|
|
72
|
+
return [
|
|
73
|
+
{ type: 'finish-step' },
|
|
74
|
+
{ type: 'finish', finishReason, ...(part.usage ? { messageMetadata: { usage: part.usage } } : {}) },
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
default:
|
|
78
|
+
return [];
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* The ChatCops request for a `useChat` request (`{ id, messages, trigger,
|
|
84
|
+
* messageId }`). Only the last user message is read: the server keeps the
|
|
85
|
+
* history, so a client can't add turns the model never wrote. `pageContext`,
|
|
86
|
+
* `locale` and `userData` pass through from the request body.
|
|
87
|
+
*/
|
|
88
|
+
export function fromAiSdkRequest(body) {
|
|
89
|
+
if (body === null || typeof body !== 'object')
|
|
90
|
+
return {};
|
|
91
|
+
const { id, messages, trigger, messageId, pageContext, locale, userData } = body;
|
|
92
|
+
const list = Array.isArray(messages) ? messages : [];
|
|
93
|
+
const lastUser = [...list].reverse().find((message) => message?.role === 'user');
|
|
94
|
+
const request = { conversationId: id, message: textOf(lastUser) };
|
|
95
|
+
if (trigger === 'regenerate-message') {
|
|
96
|
+
if (typeof messageId !== 'string') {
|
|
97
|
+
request.regenerate = true;
|
|
98
|
+
}
|
|
99
|
+
else if (list.some((message) => message?.id === messageId)) {
|
|
100
|
+
// `regenerate({ messageId })` on a user message keeps it in `messages`.
|
|
101
|
+
request.regenerate = true;
|
|
102
|
+
request.messageId = messageId;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
request.regenerate = { assistantMessageId: messageId };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else if (typeof lastUser?.id === 'string') {
|
|
109
|
+
request.messageId = lastUser.id;
|
|
110
|
+
}
|
|
111
|
+
if (pageContext !== undefined)
|
|
112
|
+
request.pageContext = pageContext;
|
|
113
|
+
if (locale !== undefined)
|
|
114
|
+
request.locale = locale;
|
|
115
|
+
if (userData !== undefined)
|
|
116
|
+
request.userData = userData;
|
|
117
|
+
return request;
|
|
118
|
+
}
|
|
119
|
+
function textOf(message) {
|
|
120
|
+
if (!Array.isArray(message?.parts))
|
|
121
|
+
return '';
|
|
122
|
+
return message.parts
|
|
123
|
+
.filter((part) => part?.type === 'text' && typeof part.text === 'string')
|
|
124
|
+
.map((part) => part.text)
|
|
125
|
+
.join('\n\n');
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=ai-sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../../src/protocol/ai-sdk.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { WireErrorCode, WireErrorBody } from './v1.js';
|
|
3
|
+
export declare function statusForError(code: WireErrorCode): number;
|
|
4
|
+
export declare function errorBody(code: WireErrorCode, options?: {
|
|
5
|
+
message?: string;
|
|
6
|
+
retryAfterMs?: number;
|
|
7
|
+
}): WireErrorBody;
|
|
8
|
+
/** "Invalid request: message, pageContext.url". Field paths only, never values. */
|
|
9
|
+
export declare function describeInvalidRequest(error: z.ZodError): string;
|
|
10
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAqB5D,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,GAAG,MAAM,CAE1D;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,aAAa,EACnB,OAAO,CAAC,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,CAAA;CAAE,GACpD,aAAa,CASf;AAED,mFAAmF;AACnF,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,CAAC,CAAC,QAAQ,GAAG,MAAM,CAQhE"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
const STATUS_BY_CODE = {
|
|
2
|
+
invalid_request: 400,
|
|
3
|
+
content_filtered: 400,
|
|
4
|
+
session_required: 401,
|
|
5
|
+
token_expired: 401,
|
|
6
|
+
conversation_mismatch: 401,
|
|
7
|
+
turnstile_failed: 401,
|
|
8
|
+
origin_not_allowed: 403,
|
|
9
|
+
conversation_busy: 409,
|
|
10
|
+
payload_too_large: 413,
|
|
11
|
+
rate_limited: 429,
|
|
12
|
+
budget_exceeded: 429,
|
|
13
|
+
tool_error: 500,
|
|
14
|
+
internal_error: 500,
|
|
15
|
+
provider_error: 502,
|
|
16
|
+
provider_unavailable: 503,
|
|
17
|
+
timeout: 504,
|
|
18
|
+
};
|
|
19
|
+
export function statusForError(code) {
|
|
20
|
+
return STATUS_BY_CODE[code];
|
|
21
|
+
}
|
|
22
|
+
export function errorBody(code, options) {
|
|
23
|
+
const error = { code };
|
|
24
|
+
if (options?.message !== undefined) {
|
|
25
|
+
error.message = options.message;
|
|
26
|
+
}
|
|
27
|
+
if (options?.retryAfterMs !== undefined) {
|
|
28
|
+
error.retryAfterMs = options.retryAfterMs;
|
|
29
|
+
}
|
|
30
|
+
return { error };
|
|
31
|
+
}
|
|
32
|
+
/** "Invalid request: message, pageContext.url". Field paths only, never values. */
|
|
33
|
+
export function describeInvalidRequest(error) {
|
|
34
|
+
const paths = new Set();
|
|
35
|
+
for (const issue of error.issues) {
|
|
36
|
+
paths.add(issue.path.length > 0 ? issue.path.join('.') : '(root)');
|
|
37
|
+
}
|
|
38
|
+
return paths.size > 0
|
|
39
|
+
? `Invalid request: ${Array.from(paths).join(', ')}`
|
|
40
|
+
: 'Invalid request';
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/protocol/errors.ts"],"names":[],"mappings":"AAGA,MAAM,cAAc,GAAkC;IACpD,eAAe,EAAE,GAAG;IACpB,gBAAgB,EAAE,GAAG;IACrB,gBAAgB,EAAE,GAAG;IACrB,aAAa,EAAE,GAAG;IAClB,qBAAqB,EAAE,GAAG;IAC1B,gBAAgB,EAAE,GAAG;IACrB,kBAAkB,EAAE,GAAG;IACvB,iBAAiB,EAAE,GAAG;IACtB,iBAAiB,EAAE,GAAG;IACtB,YAAY,EAAE,GAAG;IACjB,eAAe,EAAE,GAAG;IACpB,UAAU,EAAE,GAAG;IACf,cAAc,EAAE,GAAG;IACnB,cAAc,EAAE,GAAG;IACnB,oBAAoB,EAAE,GAAG;IACzB,OAAO,EAAE,GAAG;CACb,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,IAAmB;IAChD,OAAO,cAAc,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED,MAAM,UAAU,SAAS,CACvB,IAAmB,EACnB,OAAqD;IAErD,MAAM,KAAK,GAA2B,EAAE,IAAI,EAAE,CAAC;IAC/C,IAAI,OAAO,EAAE,OAAO,KAAK,SAAS,EAAE,CAAC;QACnC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAClC,CAAC;IACD,IAAI,OAAO,EAAE,YAAY,KAAK,SAAS,EAAE,CAAC;QACxC,KAAK,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC5C,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,CAAC;AACnB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,sBAAsB,CAAC,KAAiB;IACtD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;QACjC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,GAAG,CAAC;QACnB,CAAC,CAAC,oBAAoB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpD,CAAC,CAAC,iBAAiB,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { PROTOCOL_VERSION } from './v1.js';
|
|
2
|
+
export { encodeSSE, SSE_PING, SSE_DONE, SSE_HEADERS } from './sse.js';
|
|
3
|
+
export { statusForError, errorBody, describeInvalidRequest } from './errors.js';
|
|
4
|
+
export { toLegacyChunk } from './legacy.js';
|
|
5
|
+
export { aiSdkEncoder, fromAiSdkRequest, AI_SDK_STREAM_HEADER } from './ai-sdk.js';
|
|
6
|
+
export type { AiSdkChunk } from './ai-sdk.js';
|
|
7
|
+
export type { LegacyChunk } from './legacy.js';
|
|
8
|
+
export type { WirePart, WirePartType, WireErrorCode, WireFinishReason, WireAgent, WireErrorBody, ChatRequestV1, ClientToolManifest, } from './v1.js';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/protocol/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AACnF,YAAY,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,SAAS,EACT,aAAa,EACb,aAAa,EACb,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { PROTOCOL_VERSION } from './v1.js';
|
|
2
|
+
export { encodeSSE, SSE_PING, SSE_DONE, SSE_HEADERS } from './sse.js';
|
|
3
|
+
export { statusForError, errorBody, describeInvalidRequest } from './errors.js';
|
|
4
|
+
export { toLegacyChunk } from './legacy.js';
|
|
5
|
+
export { aiSdkEncoder, fromAiSdkRequest, AI_SDK_STREAM_HEADER } from './ai-sdk.js';
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/protocol/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAChF,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { WirePart } from './v1.js';
|
|
2
|
+
/**
|
|
3
|
+
* One chunk of the stream servers before 0.6 send, and widgets before 0.6
|
|
4
|
+
* read: `data: {"content":"Hi"}`, `data: {"done":true}` and so on.
|
|
5
|
+
*/
|
|
6
|
+
export interface LegacyChunk {
|
|
7
|
+
content?: string;
|
|
8
|
+
done?: boolean;
|
|
9
|
+
error?: string;
|
|
10
|
+
/** Seconds. */
|
|
11
|
+
retryAfter?: number;
|
|
12
|
+
leadCaptured?: boolean;
|
|
13
|
+
leadData?: Record<string, unknown>;
|
|
14
|
+
suggestedActions?: string[];
|
|
15
|
+
}
|
|
16
|
+
/** The chunk an old widget expects for this part, or null for parts it has no use for. */
|
|
17
|
+
export declare function toLegacyChunk(part: WirePart): LegacyChunk | null;
|
|
18
|
+
//# sourceMappingURL=legacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["../../src/protocol/legacy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,0FAA0F;AAC1F,wBAAgB,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,WAAW,GAAG,IAAI,CAkBhE"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/** The chunk an old widget expects for this part, or null for parts it has no use for. */
|
|
2
|
+
export function toLegacyChunk(part) {
|
|
3
|
+
switch (part.type) {
|
|
4
|
+
case 'text-delta':
|
|
5
|
+
return { content: part.delta };
|
|
6
|
+
case 'lead-captured':
|
|
7
|
+
return { leadCaptured: true, leadData: part.lead };
|
|
8
|
+
case 'suggestions':
|
|
9
|
+
return { suggestedActions: part.items };
|
|
10
|
+
case 'error':
|
|
11
|
+
return legacyError(part);
|
|
12
|
+
case 'finish':
|
|
13
|
+
// After an error the error chunk already went out, and after an abort
|
|
14
|
+
// nobody is listening.
|
|
15
|
+
return part.reason === 'error' || part.reason === 'aborted' ? null : { done: true };
|
|
16
|
+
default:
|
|
17
|
+
// Parts old widgets have no use for, and parts added after this was written.
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function legacyError(part) {
|
|
22
|
+
switch (part.code) {
|
|
23
|
+
case 'rate_limited': {
|
|
24
|
+
const { retryAfterMs } = part;
|
|
25
|
+
if (retryAfterMs === undefined || !Number.isFinite(retryAfterMs) || retryAfterMs <= 0) {
|
|
26
|
+
return { error: 'rate_limit' };
|
|
27
|
+
}
|
|
28
|
+
return { error: 'rate_limit', retryAfter: Math.ceil(retryAfterMs / 1000) };
|
|
29
|
+
}
|
|
30
|
+
case 'timeout':
|
|
31
|
+
return { error: 'timeout' };
|
|
32
|
+
case 'internal_error':
|
|
33
|
+
return { error: 'internal_error' };
|
|
34
|
+
case 'invalid_request':
|
|
35
|
+
// What 0.5 servers send for a request they can't read.
|
|
36
|
+
return { error: 'Invalid request' };
|
|
37
|
+
default:
|
|
38
|
+
return { error: 'provider_error' };
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=legacy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy.js","sourceRoot":"","sources":["../../src/protocol/legacy.ts"],"names":[],"mappings":"AAiBA,0FAA0F;AAC1F,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,YAAY;YACf,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QACjC,KAAK,eAAe;YAClB,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,aAAa;YAChB,OAAO,EAAE,gBAAgB,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1C,KAAK,OAAO;YACV,OAAO,WAAW,CAAC,IAAI,CAAC,CAAC;QAC3B,KAAK,QAAQ;YACX,sEAAsE;YACtE,uBAAuB;YACvB,OAAO,IAAI,CAAC,MAAM,KAAK,OAAO,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QACtF;YACE,6EAA6E;YAC7E,OAAO,IAAI,CAAC;IAChB,CAAC;AACH,CAAC;AAED,SAAS,WAAW,CAAC,IAA0C;IAC7D,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,cAAc,CAAC,CAAC,CAAC;YACpB,MAAM,EAAE,YAAY,EAAE,GAAG,IAAI,CAAC;YAC9B,IAAI,YAAY,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,YAAY,IAAI,CAAC,EAAE,CAAC;gBACtF,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC;YACjC,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,EAAE,CAAC;QAC7E,CAAC;QACD,KAAK,SAAS;YACZ,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;QAC9B,KAAK,gBAAgB;YACnB,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;QACrC,KAAK,iBAAiB;YACpB,uDAAuD;YACvD,OAAO,EAAE,KAAK,EAAE,iBAAiB,EAAE,CAAC;QACtC;YACE,OAAO,EAAE,KAAK,EAAE,gBAAgB,EAAE,CAAC;IACvC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { WirePart } from './v1.js';
|
|
2
|
+
/** One event: `data: <json>` and a blank line. */
|
|
3
|
+
export declare function encodeSSE(part: WirePart | Record<string, unknown>): string;
|
|
4
|
+
/** A comment line that keeps the connection busy while nothing else is sent. */
|
|
5
|
+
export declare const SSE_PING = ": ping\n\n";
|
|
6
|
+
/** Ends the stream. */
|
|
7
|
+
export declare const SSE_DONE = "data: [DONE]\n\n";
|
|
8
|
+
/** Standard HTTP headers for an SSE response. */
|
|
9
|
+
export declare const SSE_HEADERS: Readonly<Record<string, string>>;
|
|
10
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../src/protocol/sse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAExC,kDAAkD;AAClD,wBAAgB,SAAS,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAE1E;AAED,gFAAgF;AAChF,eAAO,MAAM,QAAQ,eAAe,CAAC;AAErC,uBAAuB;AACvB,eAAO,MAAM,QAAQ,qBAAqB,CAAC;AAE3C,iDAAiD;AACjD,eAAO,MAAM,WAAW,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAIvD,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/** One event: `data: <json>` and a blank line. */
|
|
2
|
+
export function encodeSSE(part) {
|
|
3
|
+
return `data: ${JSON.stringify(part)}\n\n`;
|
|
4
|
+
}
|
|
5
|
+
/** A comment line that keeps the connection busy while nothing else is sent. */
|
|
6
|
+
export const SSE_PING = ': ping\n\n';
|
|
7
|
+
/** Ends the stream. */
|
|
8
|
+
export const SSE_DONE = 'data: [DONE]\n\n';
|
|
9
|
+
/** Standard HTTP headers for an SSE response. */
|
|
10
|
+
export const SSE_HEADERS = Object.freeze({
|
|
11
|
+
'Content-Type': 'text/event-stream; charset=utf-8',
|
|
12
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
13
|
+
'X-Accel-Buffering': 'no',
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../src/protocol/sse.ts"],"names":[],"mappings":"AAEA,kDAAkD;AAClD,MAAM,UAAU,SAAS,CAAC,IAAwC;IAChE,OAAO,SAAS,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC;AAC7C,CAAC;AAED,gFAAgF;AAChF,MAAM,CAAC,MAAM,QAAQ,GAAG,YAAY,CAAC;AAErC,uBAAuB;AACvB,MAAM,CAAC,MAAM,QAAQ,GAAG,kBAAkB,CAAC;AAE3C,iDAAiD;AACjD,MAAM,CAAC,MAAM,WAAW,GAAqC,MAAM,CAAC,MAAM,CAAC;IACzE,cAAc,EAAE,kCAAkC;IAClD,eAAe,EAAE,wBAAwB;IACzC,mBAAmB,EAAE,IAAI;CAC1B,CAAC,CAAC"}
|