@flowajs/chat-service 0.0.1
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/LICENSE +21 -0
- package/README.md +210 -0
- package/dist/artifact.d.ts +87 -0
- package/dist/artifact.d.ts.map +1 -0
- package/dist/artifact.js +99 -0
- package/dist/artifact.js.map +1 -0
- package/dist/audit.d.ts +28 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +73 -0
- package/dist/audit.js.map +1 -0
- package/dist/auth/jwt.d.ts +18 -0
- package/dist/auth/jwt.d.ts.map +1 -0
- package/dist/auth/jwt.js +23 -0
- package/dist/auth/jwt.js.map +1 -0
- package/dist/auth/oidc.d.ts +30 -0
- package/dist/auth/oidc.d.ts.map +1 -0
- package/dist/auth/oidc.js +58 -0
- package/dist/auth/oidc.js.map +1 -0
- package/dist/chat.d.ts +161 -0
- package/dist/chat.d.ts.map +1 -0
- package/dist/chat.js +636 -0
- package/dist/chat.js.map +1 -0
- package/dist/cli.d.ts +6 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +47 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +80 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/instrumentation.d.ts +31 -0
- package/dist/instrumentation.d.ts.map +1 -0
- package/dist/instrumentation.js +151 -0
- package/dist/instrumentation.js.map +1 -0
- package/dist/llm/anthropic.d.ts +22 -0
- package/dist/llm/anthropic.d.ts.map +1 -0
- package/dist/llm/anthropic.js +40 -0
- package/dist/llm/anthropic.js.map +1 -0
- package/dist/llm/bedrock.d.ts +34 -0
- package/dist/llm/bedrock.d.ts.map +1 -0
- package/dist/llm/bedrock.js +54 -0
- package/dist/llm/bedrock.js.map +1 -0
- package/dist/llm/factory.d.ts +3 -0
- package/dist/llm/factory.d.ts.map +1 -0
- package/dist/llm/factory.js +59 -0
- package/dist/llm/factory.js.map +1 -0
- package/dist/llm/google-gla.d.ts +22 -0
- package/dist/llm/google-gla.d.ts.map +1 -0
- package/dist/llm/google-gla.js +29 -0
- package/dist/llm/google-gla.js.map +1 -0
- package/dist/llm/google-vertex.d.ts +21 -0
- package/dist/llm/google-vertex.d.ts.map +1 -0
- package/dist/llm/google-vertex.js +28 -0
- package/dist/llm/google-vertex.js.map +1 -0
- package/dist/llm/interface.d.ts +45 -0
- package/dist/llm/interface.d.ts.map +1 -0
- package/dist/llm/interface.js +2 -0
- package/dist/llm/interface.js.map +1 -0
- package/dist/llm/openai.d.ts +19 -0
- package/dist/llm/openai.d.ts.map +1 -0
- package/dist/llm/openai.js +25 -0
- package/dist/llm/openai.js.map +1 -0
- package/dist/prompts.d.ts +7 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +17 -0
- package/dist/prompts.js.map +1 -0
- package/dist/server.d.ts +39 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +106 -0
- package/dist/server.js.map +1 -0
- package/dist/session.d.ts +68 -0
- package/dist/session.d.ts.map +1 -0
- package/dist/session.js +245 -0
- package/dist/session.js.map +1 -0
- package/dist/storage/factory.d.ts +28 -0
- package/dist/storage/factory.d.ts.map +1 -0
- package/dist/storage/factory.js +33 -0
- package/dist/storage/factory.js.map +1 -0
- package/dist/storage/fs.d.ts +14 -0
- package/dist/storage/fs.d.ts.map +1 -0
- package/dist/storage/fs.js +116 -0
- package/dist/storage/fs.js.map +1 -0
- package/dist/storage/gcs.d.ts +27 -0
- package/dist/storage/gcs.d.ts.map +1 -0
- package/dist/storage/gcs.js +81 -0
- package/dist/storage/gcs.js.map +1 -0
- package/dist/storage/interface.d.ts +33 -0
- package/dist/storage/interface.d.ts.map +1 -0
- package/dist/storage/interface.js +12 -0
- package/dist/storage/interface.js.map +1 -0
- package/dist/storage/s3.d.ts +29 -0
- package/dist/storage/s3.d.ts.map +1 -0
- package/dist/storage/s3.js +109 -0
- package/dist/storage/s3.js.map +1 -0
- package/dist/storage-keys.d.ts +33 -0
- package/dist/storage-keys.d.ts.map +1 -0
- package/dist/storage-keys.js +76 -0
- package/dist/storage-keys.js.map +1 -0
- package/dist/telemetry.d.ts +29 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +116 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/yaml.d.ts +42 -0
- package/dist/yaml.d.ts.map +1 -0
- package/dist/yaml.js +121 -0
- package/dist/yaml.js.map +1 -0
- package/package.json +124 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { S3Client } from "@aws-sdk/client-s3";
|
|
2
|
+
import { type Storage } from "./interface.js";
|
|
3
|
+
/**
|
|
4
|
+
* Env-driven form: chat-service constructs the S3 client with no explicit
|
|
5
|
+
* config; the AWS SDK resolves credentials, region, and endpoint from its
|
|
6
|
+
* standard env vars (`AWS_REGION`, `AWS_ENDPOINT_URL_S3`, the
|
|
7
|
+
* `fromNodeProviderChain` chain, etc.). For S3-compat providers
|
|
8
|
+
* (Cloudflare R2, Backblaze B2, MinIO, DigitalOcean Spaces, Wasabi,
|
|
9
|
+
* Hetzner, etc.), set `AWS_ENDPOINT_URL_S3` and `AWS_REGION` in the
|
|
10
|
+
* environment. For knobs the SDK doesn't expose via env vars (e.g.
|
|
11
|
+
* `forcePathStyle`, custom retry policy), use the `{ client }`
|
|
12
|
+
* programmatic form below.
|
|
13
|
+
*/
|
|
14
|
+
export interface S3StorageConfigOptions {
|
|
15
|
+
bucket: string;
|
|
16
|
+
prefix?: string;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Programmatic form: caller hands in a pre-built `S3Client`. Use this
|
|
20
|
+
* when the deployment needs custom credential minting (OIDC->STS, etc.)
|
|
21
|
+
* that the default chain does not cover.
|
|
22
|
+
*/
|
|
23
|
+
export interface S3StorageClientOptions {
|
|
24
|
+
client: S3Client;
|
|
25
|
+
bucket: string;
|
|
26
|
+
prefix?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function createS3Storage(options: S3StorageConfigOptions | S3StorageClientOptions): Storage;
|
|
29
|
+
//# sourceMappingURL=s3.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.d.ts","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,QAAQ,EACT,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,gBAAgB,CAAC;AAEpE;;;;;;;;;;GAUG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;GAIG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAgB,eAAe,CAC7B,OAAO,EAAE,sBAAsB,GAAG,sBAAsB,GACvD,OAAO,CAaT"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
import { GetObjectCommand, ListObjectsV2Command, PutObjectCommand, S3Client, } from "@aws-sdk/client-s3";
|
|
2
|
+
import { StorageConflictError } from "./interface.js";
|
|
3
|
+
export function createS3Storage(options) {
|
|
4
|
+
if ("client" in options) {
|
|
5
|
+
return makeStorage({
|
|
6
|
+
client: options.client,
|
|
7
|
+
bucket: options.bucket,
|
|
8
|
+
prefix: options.prefix ?? "",
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
return makeStorage({
|
|
12
|
+
client: new S3Client(),
|
|
13
|
+
bucket: options.bucket,
|
|
14
|
+
prefix: options.prefix ?? "",
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
function makeStorage({ client, bucket, prefix }) {
|
|
18
|
+
function fullKey(key) {
|
|
19
|
+
return prefix + key;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
prefix,
|
|
23
|
+
async read(key) {
|
|
24
|
+
try {
|
|
25
|
+
const response = await client.send(new GetObjectCommand({ Bucket: bucket, Key: fullKey(key) }));
|
|
26
|
+
const bytes = await response.Body?.transformToByteArray();
|
|
27
|
+
return bytes ? Buffer.from(bytes) : null;
|
|
28
|
+
}
|
|
29
|
+
catch (error) {
|
|
30
|
+
if (error.name === "NoSuchKey")
|
|
31
|
+
return null;
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async readText(key) {
|
|
36
|
+
try {
|
|
37
|
+
const response = await client.send(new GetObjectCommand({ Bucket: bucket, Key: fullKey(key) }));
|
|
38
|
+
return (await response.Body?.transformToString()) ?? null;
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
if (error.name === "NoSuchKey")
|
|
42
|
+
return null;
|
|
43
|
+
throw error;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
async readJson(key) {
|
|
47
|
+
const text = await this.readText(key);
|
|
48
|
+
return text ? JSON.parse(text) : null;
|
|
49
|
+
},
|
|
50
|
+
async write(key, body) {
|
|
51
|
+
await client.send(new PutObjectCommand({
|
|
52
|
+
Bucket: bucket,
|
|
53
|
+
Key: fullKey(key),
|
|
54
|
+
Body: body,
|
|
55
|
+
}));
|
|
56
|
+
},
|
|
57
|
+
async writeJson(key, value) {
|
|
58
|
+
await client.send(new PutObjectCommand({
|
|
59
|
+
Bucket: bucket,
|
|
60
|
+
Key: fullKey(key),
|
|
61
|
+
Body: JSON.stringify(value),
|
|
62
|
+
ContentType: "application/json",
|
|
63
|
+
}));
|
|
64
|
+
},
|
|
65
|
+
async writeIfAbsent(key, body) {
|
|
66
|
+
try {
|
|
67
|
+
await client.send(new PutObjectCommand({
|
|
68
|
+
Bucket: bucket,
|
|
69
|
+
Key: fullKey(key),
|
|
70
|
+
Body: body,
|
|
71
|
+
IfNoneMatch: "*",
|
|
72
|
+
}));
|
|
73
|
+
}
|
|
74
|
+
catch (error) {
|
|
75
|
+
const status = error
|
|
76
|
+
.$metadata?.httpStatusCode;
|
|
77
|
+
if (status === 412) {
|
|
78
|
+
throw new StorageConflictError(key);
|
|
79
|
+
}
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
82
|
+
},
|
|
83
|
+
async exists(key) {
|
|
84
|
+
const buf = await this.read(key);
|
|
85
|
+
return buf !== null;
|
|
86
|
+
},
|
|
87
|
+
async list(listPrefix) {
|
|
88
|
+
const out = [];
|
|
89
|
+
let continuationToken;
|
|
90
|
+
do {
|
|
91
|
+
const response = await client.send(new ListObjectsV2Command({
|
|
92
|
+
Bucket: bucket,
|
|
93
|
+
Prefix: fullKey(listPrefix),
|
|
94
|
+
ContinuationToken: continuationToken,
|
|
95
|
+
}));
|
|
96
|
+
for (const obj of response.Contents ?? []) {
|
|
97
|
+
if (obj.Key) {
|
|
98
|
+
out.push(obj.Key.slice(prefix.length));
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
continuationToken = response.IsTruncated
|
|
102
|
+
? response.NextContinuationToken
|
|
103
|
+
: undefined;
|
|
104
|
+
} while (continuationToken);
|
|
105
|
+
return out.sort();
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=s3.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3.js","sourceRoot":"","sources":["../../src/storage/s3.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { type Storage } from "./storage/interface.js";
|
|
2
|
+
/** Percent-encode a DOI for storage keys (matches Python's urllib.parse.quote(doi, safe='')). */
|
|
3
|
+
export declare function encodeDoi(doi: string): string;
|
|
4
|
+
export declare function loadQueryResult(storage: Storage, variantId: string): Promise<{
|
|
5
|
+
dois: string[];
|
|
6
|
+
} | null>;
|
|
7
|
+
export declare function loadAggregate(storage: Storage, variantId: string): Promise<unknown>;
|
|
8
|
+
export declare function loadExtraction(storage: Storage, variantId: string, doi: string): Promise<unknown>;
|
|
9
|
+
export declare function loadMarkdown(storage: Storage, doi: string): Promise<string | null>;
|
|
10
|
+
export declare function loadPaperMetadata(storage: Storage, doi: string): Promise<Record<string, unknown> | null>;
|
|
11
|
+
export declare function auditLogKey(variantId: string, sessionId: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* An edit draft as it lives in storage: the bare artifact JSON, plus its
|
|
14
|
+
* version number parsed from the object key.
|
|
15
|
+
*/
|
|
16
|
+
export interface EditDraft {
|
|
17
|
+
version: number;
|
|
18
|
+
/** The artifact JSON body as written, verbatim. */
|
|
19
|
+
artifactText: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* List all edit draft versions for a (variant, category), sorted by version
|
|
23
|
+
* number ascending. Returns empty array if no drafts exist.
|
|
24
|
+
*/
|
|
25
|
+
export declare function listEditDrafts(storage: Storage, variantId: string, category: string): Promise<EditDraft[]>;
|
|
26
|
+
/**
|
|
27
|
+
* Write an edit draft version with atomic create-only semantics. If the
|
|
28
|
+
* target version key already exists (concurrent writer beat us), increment
|
|
29
|
+
* the version and retry up to `maxRetries` times. The returned version may
|
|
30
|
+
* therefore be higher than `intendedVersion`.
|
|
31
|
+
*/
|
|
32
|
+
export declare function writeEditDraft(storage: Storage, variantId: string, category: string, artifactText: string, intendedVersion: number, maxRetries?: number): Promise<number>;
|
|
33
|
+
//# sourceMappingURL=storage-keys.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-keys.d.ts","sourceRoot":"","sources":["../src/storage-keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,wBAAwB,CAAC;AAE5E,iGAAiG;AACjG,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK7C;AAED,wBAAsB,eAAe,CACnC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,IAAI,CAAC,CAIpC;AAED,wBAAsB,aAAa,CACjC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,OAAO,CAAC,CAIlB;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAExB;AAED,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,OAAO,EAChB,GAAG,EAAE,MAAM,GACV,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC,CAEzC;AAMD,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAExE;AAMD;;;GAGG;AACH,MAAM,WAAW,SAAS;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,YAAY,EAAE,MAAM,CAAC;CACtB;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,SAAS,EAAE,CAAC,CAmBtB;AAED;;;;;GAKG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,eAAe,EAAE,MAAM,EACvB,UAAU,SAAI,GACb,OAAO,CAAC,MAAM,CAAC,CAkBjB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { StorageConflictError } from "./storage/interface.js";
|
|
2
|
+
/** Percent-encode a DOI for storage keys (matches Python's urllib.parse.quote(doi, safe='')). */
|
|
3
|
+
export function encodeDoi(doi) {
|
|
4
|
+
return encodeURIComponent(doi).replace(/[!'()*]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
5
|
+
}
|
|
6
|
+
export async function loadQueryResult(storage, variantId) {
|
|
7
|
+
return storage.readJson(`assessments/${variantId}/query.json`);
|
|
8
|
+
}
|
|
9
|
+
export async function loadAggregate(storage, variantId) {
|
|
10
|
+
return storage.readJson(`assessments/${variantId}/aggregation.json`);
|
|
11
|
+
}
|
|
12
|
+
export async function loadExtraction(storage, variantId, doi) {
|
|
13
|
+
return storage.readJson(`assessments/${variantId}/extractions/${encodeDoi(doi)}.json`);
|
|
14
|
+
}
|
|
15
|
+
export async function loadMarkdown(storage, doi) {
|
|
16
|
+
return storage.readText(`papers/${encodeDoi(doi)}/markdown.md`);
|
|
17
|
+
}
|
|
18
|
+
export async function loadPaperMetadata(storage, doi) {
|
|
19
|
+
return storage.readJson(`papers/${encodeDoi(doi)}/metadata.json`);
|
|
20
|
+
}
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
// Audit log keys
|
|
23
|
+
// ---------------------------------------------------------------------------
|
|
24
|
+
export function auditLogKey(variantId, sessionId) {
|
|
25
|
+
return `chat-sessions/${variantId}/${sessionId}.json`;
|
|
26
|
+
}
|
|
27
|
+
function editDraftPrefix(variantId, category) {
|
|
28
|
+
return `edit-drafts/${variantId}/${category}/artifact-v`;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* List all edit draft versions for a (variant, category), sorted by version
|
|
32
|
+
* number ascending. Returns empty array if no drafts exist.
|
|
33
|
+
*/
|
|
34
|
+
export async function listEditDrafts(storage, variantId, category) {
|
|
35
|
+
const prefix = editDraftPrefix(variantId, category);
|
|
36
|
+
const keys = (await storage.list(prefix))
|
|
37
|
+
.filter((k) => k.startsWith(prefix) && k.endsWith(".json"))
|
|
38
|
+
.sort((a, b) => {
|
|
39
|
+
const vA = parseInt(a.slice(prefix.length, -5), 10);
|
|
40
|
+
const vB = parseInt(b.slice(prefix.length, -5), 10);
|
|
41
|
+
return vA - vB;
|
|
42
|
+
});
|
|
43
|
+
const drafts = await Promise.all(keys.map(async (key) => {
|
|
44
|
+
const artifactText = await storage.readText(key);
|
|
45
|
+
if (artifactText === null)
|
|
46
|
+
return null;
|
|
47
|
+
const version = parseInt(key.slice(prefix.length, -5), 10);
|
|
48
|
+
return { version, artifactText };
|
|
49
|
+
}));
|
|
50
|
+
return drafts.filter((d) => d !== null);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Write an edit draft version with atomic create-only semantics. If the
|
|
54
|
+
* target version key already exists (concurrent writer beat us), increment
|
|
55
|
+
* the version and retry up to `maxRetries` times. The returned version may
|
|
56
|
+
* therefore be higher than `intendedVersion`.
|
|
57
|
+
*/
|
|
58
|
+
export async function writeEditDraft(storage, variantId, category, artifactText, intendedVersion, maxRetries = 3) {
|
|
59
|
+
let version = intendedVersion;
|
|
60
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
61
|
+
const key = `${editDraftPrefix(variantId, category)}${version}.json`;
|
|
62
|
+
try {
|
|
63
|
+
await storage.writeIfAbsent(key, artifactText);
|
|
64
|
+
return version;
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
if (error instanceof StorageConflictError && attempt < maxRetries) {
|
|
68
|
+
version++;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
throw new Error(`Failed to write edit draft after ${maxRetries + 1} attempts`);
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=storage-keys.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage-keys.js","sourceRoot":"","sources":["../src/storage-keys.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry helpers. Pure — no side effects at module load.
|
|
3
|
+
* The SDK is bootstrapped in instrumentation.ts (loaded via --import);
|
|
4
|
+
* if it hasn't run, metrics.getMeter() returns a no-op meter.
|
|
5
|
+
*/
|
|
6
|
+
export declare function recordTokenUsage({ model, tokenType, count, }: {
|
|
7
|
+
model: string;
|
|
8
|
+
tokenType: "input" | "output";
|
|
9
|
+
count: number;
|
|
10
|
+
}): void;
|
|
11
|
+
export interface ToolMetricsContext {
|
|
12
|
+
/** Provider name (`anthropic`, `aws.bedrock`, `gcp.gemini`, `openai`). */
|
|
13
|
+
providerName: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Wrap a tool's `execute` with duration instrumentation. The provider name
|
|
17
|
+
* is parameterized so each provider self-labels its own metrics.
|
|
18
|
+
*/
|
|
19
|
+
export declare function withToolMetrics<Args, Result>(context: ToolMetricsContext, name: string, execute: (args: Args) => Promise<Result>): (args: Args) => Promise<Result>;
|
|
20
|
+
export type ValidationRule = "paper_id_duplicate" | "paper_id_unknown_in_mapping" | "claim_paper_missing" | "claims_not_contiguous" | "claims_group_order" | "cite_unknown_paper_id" | "cite_missing_quote" | "cite_quote_mismatch";
|
|
21
|
+
export declare function recordValidationError(rule: ValidationRule): void;
|
|
22
|
+
export declare function recordToolValidationFailure(tool: "str_replace" | "insert" | "write"): void;
|
|
23
|
+
export declare function recordStorageWriteFailure(): void;
|
|
24
|
+
export declare function recordCachedInputTokens({ model, type, count, }: {
|
|
25
|
+
model: string;
|
|
26
|
+
type: "read" | "write";
|
|
27
|
+
count: number;
|
|
28
|
+
}): void;
|
|
29
|
+
//# sourceMappingURL=telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.d.ts","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAsBH,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EACL,SAAS,EACT,KAAK,GACN,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAC;IAC9B,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAKP;AAsBD,MAAM,WAAW,kBAAkB;IACjC,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;CACtB;AAYD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAC1C,OAAO,EAAE,kBAAkB,EAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,GACvC,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,CA2BjC;AAcD,MAAM,MAAM,cAAc,GACtB,oBAAoB,GACpB,6BAA6B,GAC7B,qBAAqB,GACrB,uBAAuB,GACvB,oBAAoB,GACpB,uBAAuB,GACvB,oBAAoB,GACpB,qBAAqB,CAAC;AAE1B,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,CAEhE;AAUD,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,aAAa,GAAG,QAAQ,GAAG,OAAO,GACvC,IAAI,CAEN;AAUD,wBAAgB,yBAAyB,IAAI,IAAI,CAEhD;AAcD,wBAAgB,uBAAuB,CAAC,EACtC,KAAK,EACL,IAAI,EACJ,KAAK,GACN,EAAE;IACD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,GAAG,IAAI,CAKP"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Telemetry helpers. Pure — no side effects at module load.
|
|
3
|
+
* The SDK is bootstrapped in instrumentation.ts (loaded via --import);
|
|
4
|
+
* if it hasn't run, metrics.getMeter() returns a no-op meter.
|
|
5
|
+
*/
|
|
6
|
+
import { metrics } from "@opentelemetry/api";
|
|
7
|
+
const meter = metrics.getMeter("chat-service");
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// Token usage histogram
|
|
10
|
+
// https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-metrics/
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const tokenHistogram = meter.createHistogram("gen_ai.client.token.usage", {
|
|
13
|
+
description: "Number of input and output tokens used",
|
|
14
|
+
unit: "{token}",
|
|
15
|
+
advice: {
|
|
16
|
+
explicitBucketBoundaries: [
|
|
17
|
+
1, 4, 16, 64, 256, 1024, 4096, 16384, 65536, 262144, 1048576, 4194304,
|
|
18
|
+
16777216, 67108864,
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
export function recordTokenUsage({ model, tokenType, count, }) {
|
|
23
|
+
tokenHistogram.record(count, {
|
|
24
|
+
"gen_ai.token.type": tokenType,
|
|
25
|
+
"gen_ai.response.model": model,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
// Tool-execution duration histogram
|
|
30
|
+
// Reuses the shared operation-duration histogram with
|
|
31
|
+
// gen_ai.operation.name="execute_tool" per OTel GenAI semconv.
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
const operationDurationHistogram = meter.createHistogram("gen_ai.client.operation.duration", {
|
|
34
|
+
description: "GenAI operation duration.",
|
|
35
|
+
unit: "s",
|
|
36
|
+
advice: {
|
|
37
|
+
explicitBucketBoundaries: [
|
|
38
|
+
0.01, 0.02, 0.04, 0.08, 0.16, 0.32, 0.64, 1.28, 2.56, 5.12, 10.24,
|
|
39
|
+
20.48, 40.96, 81.92,
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
// Tools in chat.ts signal curator-visible failures by returning
|
|
44
|
+
// `{ error: "..." }` or `{ is_error: true }` rather than throwing.
|
|
45
|
+
function isToolErrorResult(result) {
|
|
46
|
+
if (result === null || typeof result !== "object" || Array.isArray(result)) {
|
|
47
|
+
return false;
|
|
48
|
+
}
|
|
49
|
+
const r = result;
|
|
50
|
+
return Boolean(r.error) || r.is_error === true;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Wrap a tool's `execute` with duration instrumentation. The provider name
|
|
54
|
+
* is parameterized so each provider self-labels its own metrics.
|
|
55
|
+
*/
|
|
56
|
+
export function withToolMetrics(context, name, execute) {
|
|
57
|
+
const baseAttrs = {
|
|
58
|
+
"gen_ai.operation.name": "execute_tool",
|
|
59
|
+
"gen_ai.provider.name": context.providerName,
|
|
60
|
+
"gen_ai.tool.name": name,
|
|
61
|
+
};
|
|
62
|
+
return async (args) => {
|
|
63
|
+
const start = performance.now();
|
|
64
|
+
try {
|
|
65
|
+
const result = await execute(args);
|
|
66
|
+
const duration = (performance.now() - start) / 1000;
|
|
67
|
+
operationDurationHistogram.record(duration, isToolErrorResult(result)
|
|
68
|
+
? { ...baseAttrs, "error.type": "tool_error" }
|
|
69
|
+
: baseAttrs);
|
|
70
|
+
return result;
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
const duration = (performance.now() - start) / 1000;
|
|
74
|
+
operationDurationHistogram.record(duration, {
|
|
75
|
+
...baseAttrs,
|
|
76
|
+
"error.type": "exception",
|
|
77
|
+
});
|
|
78
|
+
throw err;
|
|
79
|
+
}
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
// ---------------------------------------------------------------------------
|
|
83
|
+
// Validation + storage failure counters
|
|
84
|
+
// ---------------------------------------------------------------------------
|
|
85
|
+
const validationErrorCounter = meter.createCounter("chat_validation_errors_total", {
|
|
86
|
+
description: "Count of individual rule violations found by validateArtifactContent",
|
|
87
|
+
});
|
|
88
|
+
export function recordValidationError(rule) {
|
|
89
|
+
validationErrorCounter.add(1, { rule });
|
|
90
|
+
}
|
|
91
|
+
const toolValidationFailureCounter = meter.createCounter("chat_tool_validation_failures_total", {
|
|
92
|
+
description: "Count of tool invocations rejected by validateAndCommit (parse, schema, or content-validation errors)",
|
|
93
|
+
});
|
|
94
|
+
export function recordToolValidationFailure(tool) {
|
|
95
|
+
toolValidationFailureCounter.add(1, { tool });
|
|
96
|
+
}
|
|
97
|
+
const storageWriteFailureCounter = meter.createCounter("chat_storage_write_failures_total", {
|
|
98
|
+
description: "Count of writeEditDraft failures that terminated the chat stream with an error",
|
|
99
|
+
});
|
|
100
|
+
export function recordStorageWriteFailure() {
|
|
101
|
+
storageWriteFailureCounter.add(1);
|
|
102
|
+
}
|
|
103
|
+
// ---------------------------------------------------------------------------
|
|
104
|
+
// Cached-input-tokens counter
|
|
105
|
+
// ---------------------------------------------------------------------------
|
|
106
|
+
const cachedInputTokensCounter = meter.createCounter("gen_ai.client.token.cached_input", {
|
|
107
|
+
description: "Input tokens served from / written to provider prompt cache",
|
|
108
|
+
unit: "{token}",
|
|
109
|
+
});
|
|
110
|
+
export function recordCachedInputTokens({ model, type, count, }) {
|
|
111
|
+
cachedInputTokensCounter.add(count, {
|
|
112
|
+
"gen_ai.cache.type": type,
|
|
113
|
+
"gen_ai.response.model": model,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
|
package/dist/yaml.d.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** YAML serialization for artifact editing — eliminates JSON escaping issues. */
|
|
2
|
+
import type { Artifact } from "./artifact.js";
|
|
3
|
+
type Bbox = {
|
|
4
|
+
page: number;
|
|
5
|
+
top: number;
|
|
6
|
+
left: number;
|
|
7
|
+
bottom: number;
|
|
8
|
+
right: number;
|
|
9
|
+
};
|
|
10
|
+
export type BboxCache = Map<string, Bbox[]>;
|
|
11
|
+
/** Extract (paperId, quote) → bboxes lookup from an artifact JSON string. */
|
|
12
|
+
export declare function buildBboxCache(jsonStr: string): BboxCache;
|
|
13
|
+
/** Reattach cached bboxes to citations with matching (paperId, quote). Generic
|
|
14
|
+
* over the artifact type so deployment-specific fields survive the rebuild. */
|
|
15
|
+
export declare function reattachBboxes<T extends Artifact>(artifact: T, cache: BboxCache): T;
|
|
16
|
+
/** Convert an artifact JSON string to YAML, stripping bboxes from claim citations. */
|
|
17
|
+
export declare function artifactToYaml(jsonStr: string): string;
|
|
18
|
+
/** Parse a YAML artifact string back to a JS object. */
|
|
19
|
+
export declare function parseArtifactYaml(yamlStr: string): unknown;
|
|
20
|
+
/** Add 1-indexed line numbers to YAML for display. */
|
|
21
|
+
export declare function addLineNumbers(yamlStr: string): string;
|
|
22
|
+
/**
|
|
23
|
+
* Extract a line range from YAML and return with line numbers.
|
|
24
|
+
* Uses 1-indexed lines; end=-1 means end of file.
|
|
25
|
+
*/
|
|
26
|
+
export declare function viewRange(yamlStr: string, start: number, end: number): string;
|
|
27
|
+
/**
|
|
28
|
+
* Find lines containing a literal substring. Returns matches with one line
|
|
29
|
+
* of context either side; adjacent or overlapping blocks are merged and
|
|
30
|
+
* separated by "--".
|
|
31
|
+
*/
|
|
32
|
+
export declare function searchArtifact(yamlStr: string, pattern: string): {
|
|
33
|
+
output: string;
|
|
34
|
+
count: number;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Insert text after a specific line number (1-indexed).
|
|
38
|
+
* Line 0 means insert at the beginning.
|
|
39
|
+
*/
|
|
40
|
+
export declare function insertAtLine(yamlStr: string, insertLine: number, insertText: string): string;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=yaml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.d.ts","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAGjF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAM9C,KAAK,IAAI,GAAG;IACV,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;AAM5C,6EAA6E;AAC7E,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAWzD;AAED;gFACgF;AAChF,wBAAgB,cAAc,CAAC,CAAC,SAAS,QAAQ,EAC/C,QAAQ,EAAE,CAAC,EACX,KAAK,EAAE,SAAS,GACf,CAAC,CAWH;AAMD,sFAAsF;AACtF,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAatD;AAED,wDAAwD;AACxD,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1D;AAMD,sDAAsD;AACtD,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtD;AAED;;;GAGG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAS7E;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA0BnC;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GACjB,MAAM,CAKR"}
|
package/dist/yaml.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/** YAML serialization for artifact editing — eliminates JSON escaping issues. */
|
|
2
|
+
import yaml from "yaml";
|
|
3
|
+
function cacheKey(paperId, quote) {
|
|
4
|
+
return `${paperId}\n${quote}`;
|
|
5
|
+
}
|
|
6
|
+
/** Extract (paperId, quote) → bboxes lookup from an artifact JSON string. */
|
|
7
|
+
export function buildBboxCache(jsonStr) {
|
|
8
|
+
const cache = new Map();
|
|
9
|
+
const art = JSON.parse(jsonStr);
|
|
10
|
+
for (const claim of art.claims ?? []) {
|
|
11
|
+
for (const citation of claim.citations ?? []) {
|
|
12
|
+
if (citation.bboxes?.length) {
|
|
13
|
+
cache.set(cacheKey(claim.paper_id, citation.quote), citation.bboxes);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
return cache;
|
|
18
|
+
}
|
|
19
|
+
/** Reattach cached bboxes to citations with matching (paperId, quote). Generic
|
|
20
|
+
* over the artifact type so deployment-specific fields survive the rebuild. */
|
|
21
|
+
export function reattachBboxes(artifact, cache) {
|
|
22
|
+
return {
|
|
23
|
+
...artifact,
|
|
24
|
+
claims: artifact.claims.map((claim) => ({
|
|
25
|
+
...claim,
|
|
26
|
+
citations: claim.citations.map((citation) => {
|
|
27
|
+
const bboxes = cache.get(cacheKey(claim.paper_id, citation.quote));
|
|
28
|
+
return bboxes ? { ...citation, bboxes } : citation;
|
|
29
|
+
}),
|
|
30
|
+
})),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// YAML serialization
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
/** Convert an artifact JSON string to YAML, stripping bboxes from claim citations. */
|
|
37
|
+
export function artifactToYaml(jsonStr) {
|
|
38
|
+
const art = JSON.parse(jsonStr);
|
|
39
|
+
if (Array.isArray(art.claims)) {
|
|
40
|
+
art.claims = art.claims.map((claim) => {
|
|
41
|
+
const citations = Array.isArray(claim.citations)
|
|
42
|
+
? claim.citations.map(({ bboxes: _bboxes, ...rest }) => rest)
|
|
43
|
+
: claim.citations;
|
|
44
|
+
return { ...claim, citations };
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
return yaml.stringify(art, { lineWidth: 0 });
|
|
48
|
+
}
|
|
49
|
+
/** Parse a YAML artifact string back to a JS object. */
|
|
50
|
+
export function parseArtifactYaml(yamlStr) {
|
|
51
|
+
return yaml.parse(yamlStr);
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Line-numbered display (mirrors Claude's text editor tool)
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
/** Add 1-indexed line numbers to YAML for display. */
|
|
57
|
+
export function addLineNumbers(yamlStr) {
|
|
58
|
+
const lines = yamlStr.split("\n");
|
|
59
|
+
const width = String(lines.length).length;
|
|
60
|
+
return lines
|
|
61
|
+
.map((line, i) => `${String(i + 1).padStart(width)}\t${line}`)
|
|
62
|
+
.join("\n");
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Extract a line range from YAML and return with line numbers.
|
|
66
|
+
* Uses 1-indexed lines; end=-1 means end of file.
|
|
67
|
+
*/
|
|
68
|
+
export function viewRange(yamlStr, start, end) {
|
|
69
|
+
const lines = yamlStr.split("\n");
|
|
70
|
+
const s = Math.max(1, start);
|
|
71
|
+
const e = end === -1 ? lines.length : Math.min(end, lines.length);
|
|
72
|
+
const width = String(e).length;
|
|
73
|
+
return lines
|
|
74
|
+
.slice(s - 1, e)
|
|
75
|
+
.map((line, i) => `${String(s + i).padStart(width)}\t${line}`)
|
|
76
|
+
.join("\n");
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Find lines containing a literal substring. Returns matches with one line
|
|
80
|
+
* of context either side; adjacent or overlapping blocks are merged and
|
|
81
|
+
* separated by "--".
|
|
82
|
+
*/
|
|
83
|
+
export function searchArtifact(yamlStr, pattern) {
|
|
84
|
+
if (!pattern)
|
|
85
|
+
return { output: "", count: 0 };
|
|
86
|
+
const lines = yamlStr.split("\n");
|
|
87
|
+
const hits = [];
|
|
88
|
+
for (let i = 0; i < lines.length; i++) {
|
|
89
|
+
if (lines[i]?.includes(pattern))
|
|
90
|
+
hits.push(i);
|
|
91
|
+
}
|
|
92
|
+
if (hits.length === 0)
|
|
93
|
+
return { output: "", count: 0 };
|
|
94
|
+
const ranges = [];
|
|
95
|
+
for (const i of hits) {
|
|
96
|
+
const start = Math.max(0, i - 1);
|
|
97
|
+
const end = Math.min(lines.length - 1, i + 1);
|
|
98
|
+
const last = ranges[ranges.length - 1];
|
|
99
|
+
if (last && start <= last[1] + 1)
|
|
100
|
+
last[1] = Math.max(last[1], end);
|
|
101
|
+
else
|
|
102
|
+
ranges.push([start, end]);
|
|
103
|
+
}
|
|
104
|
+
const width = String(lines.length).length;
|
|
105
|
+
const blocks = ranges.map(([s, e]) => lines
|
|
106
|
+
.slice(s, e + 1)
|
|
107
|
+
.map((line, i) => `${String(s + 1 + i).padStart(width)}\t${line}`)
|
|
108
|
+
.join("\n"));
|
|
109
|
+
return { output: blocks.join("\n--\n"), count: hits.length };
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Insert text after a specific line number (1-indexed).
|
|
113
|
+
* Line 0 means insert at the beginning.
|
|
114
|
+
*/
|
|
115
|
+
export function insertAtLine(yamlStr, insertLine, insertText) {
|
|
116
|
+
const lines = yamlStr.split("\n");
|
|
117
|
+
const idx = Math.max(0, Math.min(insertLine, lines.length));
|
|
118
|
+
lines.splice(idx, 0, ...insertText.split("\n"));
|
|
119
|
+
return lines.join("\n");
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=yaml.js.map
|
package/dist/yaml.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"yaml.js","sourceRoot":"","sources":["../src/yaml.ts"],"names":[],"mappings":"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"}
|