@semiont/backend 0.4.6 → 0.4.9
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/index.js +380 -194
- package/dist/index.js.map +1 -1
- package/dist/openapi.json +172 -0
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -268,6 +268,21 @@ var init_jwt = __esm({
|
|
|
268
268
|
throw error;
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
+
static generateMediaToken(resourceId21, userId14) {
|
|
272
|
+
const payload = { purpose: "media", sub: resourceId21, userId: userId14 };
|
|
273
|
+
return jwt.sign(payload, this.getSecret(), { expiresIn: "5m" });
|
|
274
|
+
}
|
|
275
|
+
static verifyMediaToken(token, resourceId21) {
|
|
276
|
+
let decoded;
|
|
277
|
+
try {
|
|
278
|
+
decoded = jwt.verify(token, this.getSecret());
|
|
279
|
+
} catch (error) {
|
|
280
|
+
if (error instanceof jwt.TokenExpiredError) throw new Error("Media token expired");
|
|
281
|
+
throw new Error("Invalid media token");
|
|
282
|
+
}
|
|
283
|
+
if (decoded["purpose"] !== "media") throw new Error("Invalid media token");
|
|
284
|
+
if (decoded["sub"] !== resourceId21) throw new Error("Media token resource mismatch");
|
|
285
|
+
}
|
|
271
286
|
static isAllowedDomain(email) {
|
|
272
287
|
const parts = email.split("@");
|
|
273
288
|
if (parts.length !== 2 || !parts[0] || !parts[1]) {
|
|
@@ -9976,6 +9991,79 @@ function makeMeaningConfigFrom(config2) {
|
|
|
9976
9991
|
|
|
9977
9992
|
// src/index.ts
|
|
9978
9993
|
init_logger();
|
|
9994
|
+
var rootRouter = new Hono();
|
|
9995
|
+
rootRouter.get("/", (c) => {
|
|
9996
|
+
const config2 = c.get("config");
|
|
9997
|
+
const projectName = config2._metadata?.projectName ?? "";
|
|
9998
|
+
const projectVersion = config2._metadata?.projectVersion ?? "";
|
|
9999
|
+
const siteName = config2.site?.siteName ?? "";
|
|
10000
|
+
const html = `<!DOCTYPE html>
|
|
10001
|
+
<html lang="en">
|
|
10002
|
+
<head>
|
|
10003
|
+
<meta charset="UTF-8">
|
|
10004
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10005
|
+
<title>Semiont</title>
|
|
10006
|
+
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
10007
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
10008
|
+
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&display=swap" rel="stylesheet">
|
|
10009
|
+
<style>
|
|
10010
|
+
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
10011
|
+
body {
|
|
10012
|
+
background: #0a0a0f;
|
|
10013
|
+
color: #e0e0e0;
|
|
10014
|
+
font-family: 'Orbitron', sans-serif;
|
|
10015
|
+
min-height: 100vh;
|
|
10016
|
+
display: flex;
|
|
10017
|
+
flex-direction: column;
|
|
10018
|
+
align-items: center;
|
|
10019
|
+
justify-content: center;
|
|
10020
|
+
gap: 1rem;
|
|
10021
|
+
}
|
|
10022
|
+
h1 {
|
|
10023
|
+
font-size: 4rem;
|
|
10024
|
+
font-weight: 700;
|
|
10025
|
+
letter-spacing: 0.2em;
|
|
10026
|
+
color: #00e5ff;
|
|
10027
|
+
text-transform: uppercase;
|
|
10028
|
+
}
|
|
10029
|
+
h2 {
|
|
10030
|
+
font-size: 1.2rem;
|
|
10031
|
+
font-weight: 400;
|
|
10032
|
+
letter-spacing: 0.4em;
|
|
10033
|
+
color: #888;
|
|
10034
|
+
text-transform: uppercase;
|
|
10035
|
+
}
|
|
10036
|
+
.meta {
|
|
10037
|
+
margin-top: 2rem;
|
|
10038
|
+
font-size: 0.75rem;
|
|
10039
|
+
letter-spacing: 0.15em;
|
|
10040
|
+
color: #555;
|
|
10041
|
+
display: flex;
|
|
10042
|
+
flex-direction: column;
|
|
10043
|
+
align-items: center;
|
|
10044
|
+
gap: 0.3rem;
|
|
10045
|
+
}
|
|
10046
|
+
a {
|
|
10047
|
+
color: #00e5ff;
|
|
10048
|
+
text-decoration: none;
|
|
10049
|
+
letter-spacing: 0.15em;
|
|
10050
|
+
font-size: 0.75rem;
|
|
10051
|
+
}
|
|
10052
|
+
a:hover { text-decoration: underline; }
|
|
10053
|
+
</style>
|
|
10054
|
+
</head>
|
|
10055
|
+
<body>
|
|
10056
|
+
<h1>SEMIONT</h1>
|
|
10057
|
+
<h2>knowledge base</h2>
|
|
10058
|
+
<div class="meta">
|
|
10059
|
+
${siteName ? `<span>${siteName}</span>` : ""}
|
|
10060
|
+
${projectName ? `<span>project: ${projectName}${projectVersion ? " v" + projectVersion : ""}</span>` : ""}
|
|
10061
|
+
<a href="/api/health">/api/health</a>
|
|
10062
|
+
</div>
|
|
10063
|
+
</body>
|
|
10064
|
+
</html>`;
|
|
10065
|
+
return c.html(html);
|
|
10066
|
+
});
|
|
9979
10067
|
var globalForPrisma = global;
|
|
9980
10068
|
var DatabaseConnection = class {
|
|
9981
10069
|
static instance = null;
|
|
@@ -11542,6 +11630,10 @@ var openapi_default = {
|
|
|
11542
11630
|
GatherResourceStreamRequest: {
|
|
11543
11631
|
type: "object",
|
|
11544
11632
|
properties: {
|
|
11633
|
+
correlationId: {
|
|
11634
|
+
type: "string",
|
|
11635
|
+
description: "Client-generated correlation ID to thread the response back to the originating request"
|
|
11636
|
+
},
|
|
11545
11637
|
depth: {
|
|
11546
11638
|
type: "integer",
|
|
11547
11639
|
minimum: 1,
|
|
@@ -11567,6 +11659,10 @@ var openapi_default = {
|
|
|
11567
11659
|
GatherAnnotationStreamRequest: {
|
|
11568
11660
|
type: "object",
|
|
11569
11661
|
properties: {
|
|
11662
|
+
correlationId: {
|
|
11663
|
+
type: "string",
|
|
11664
|
+
description: "Client-generated correlation ID to thread the response back to the originating request"
|
|
11665
|
+
},
|
|
11570
11666
|
contextWindow: {
|
|
11571
11667
|
type: "integer",
|
|
11572
11668
|
minimum: 100,
|
|
@@ -13392,6 +13488,9 @@ var openapi_default = {
|
|
|
13392
13488
|
isAdmin: {
|
|
13393
13489
|
type: "boolean"
|
|
13394
13490
|
},
|
|
13491
|
+
isModerator: {
|
|
13492
|
+
type: "boolean"
|
|
13493
|
+
},
|
|
13395
13494
|
isActive: {
|
|
13396
13495
|
type: "boolean"
|
|
13397
13496
|
},
|
|
@@ -13419,6 +13518,7 @@ var openapi_default = {
|
|
|
13419
13518
|
"domain",
|
|
13420
13519
|
"provider",
|
|
13421
13520
|
"isAdmin",
|
|
13521
|
+
"isModerator",
|
|
13422
13522
|
"isActive",
|
|
13423
13523
|
"termsAcceptedAt",
|
|
13424
13524
|
"lastLogin",
|
|
@@ -13490,6 +13590,30 @@ var openapi_default = {
|
|
|
13490
13590
|
],
|
|
13491
13591
|
description: "W3C Web Annotation body purpose vocabulary - https://www.w3.org/TR/annotation-vocab/#motivation"
|
|
13492
13592
|
},
|
|
13593
|
+
MediaTokenRequest: {
|
|
13594
|
+
type: "object",
|
|
13595
|
+
properties: {
|
|
13596
|
+
resourceId: {
|
|
13597
|
+
type: "string",
|
|
13598
|
+
description: "The resource ID to generate a media token for"
|
|
13599
|
+
}
|
|
13600
|
+
},
|
|
13601
|
+
required: [
|
|
13602
|
+
"resourceId"
|
|
13603
|
+
]
|
|
13604
|
+
},
|
|
13605
|
+
MediaTokenResponse: {
|
|
13606
|
+
type: "object",
|
|
13607
|
+
properties: {
|
|
13608
|
+
token: {
|
|
13609
|
+
type: "string",
|
|
13610
|
+
description: "Short-lived media token for use as ?token= query parameter on resource URLs"
|
|
13611
|
+
}
|
|
13612
|
+
},
|
|
13613
|
+
required: [
|
|
13614
|
+
"token"
|
|
13615
|
+
]
|
|
13616
|
+
},
|
|
13493
13617
|
GatheredContext: {
|
|
13494
13618
|
type: "object",
|
|
13495
13619
|
description: "Context gathered for an annotation. Includes source document excerpts, metadata, and graph-derived context. Used by both Find (bind) and Generate (yield) flows.",
|
|
@@ -13633,6 +13757,37 @@ var openapi_default = {
|
|
|
13633
13757
|
"annotation",
|
|
13634
13758
|
"sourceResource"
|
|
13635
13759
|
]
|
|
13760
|
+
},
|
|
13761
|
+
MatchSearchStreamRequest: {
|
|
13762
|
+
type: "object",
|
|
13763
|
+
properties: {
|
|
13764
|
+
correlationId: {
|
|
13765
|
+
type: "string",
|
|
13766
|
+
description: "Client-generated correlation ID to thread the response back to the originating request"
|
|
13767
|
+
},
|
|
13768
|
+
referenceId: {
|
|
13769
|
+
type: "string",
|
|
13770
|
+
description: "Annotation ID of the reference to search candidates for"
|
|
13771
|
+
},
|
|
13772
|
+
context: {
|
|
13773
|
+
$ref: "#/components/schemas/GatheredContext",
|
|
13774
|
+
description: "Gathered context for the reference annotation"
|
|
13775
|
+
},
|
|
13776
|
+
limit: {
|
|
13777
|
+
type: "integer",
|
|
13778
|
+
minimum: 1,
|
|
13779
|
+
maximum: 20,
|
|
13780
|
+
description: "Maximum number of candidate results to return (default: 10)"
|
|
13781
|
+
},
|
|
13782
|
+
useSemanticScoring: {
|
|
13783
|
+
type: "boolean",
|
|
13784
|
+
description: "Enable semantic similarity scoring in addition to keyword matching (default: true)"
|
|
13785
|
+
}
|
|
13786
|
+
},
|
|
13787
|
+
required: [
|
|
13788
|
+
"referenceId",
|
|
13789
|
+
"context"
|
|
13790
|
+
]
|
|
13636
13791
|
}
|
|
13637
13792
|
}
|
|
13638
13793
|
}
|
|
@@ -13860,8 +14015,33 @@ var OAuthService = class {
|
|
|
13860
14015
|
return user;
|
|
13861
14016
|
}
|
|
13862
14017
|
};
|
|
14018
|
+
|
|
14019
|
+
// src/middleware/auth.ts
|
|
14020
|
+
init_jwt();
|
|
14021
|
+
var MEDIA_TOKEN_PATH = /^\/api\/resources\/([^/]+)$/;
|
|
13863
14022
|
var authMiddleware = async (c, next) => {
|
|
13864
14023
|
const logger2 = c.get("logger");
|
|
14024
|
+
if (c.req.method === "GET") {
|
|
14025
|
+
const mediaTokenParam = c.req.query("token");
|
|
14026
|
+
const match = c.req.path.match(MEDIA_TOKEN_PATH);
|
|
14027
|
+
const resourceId21 = match?.[1];
|
|
14028
|
+
if (mediaTokenParam && resourceId21) {
|
|
14029
|
+
try {
|
|
14030
|
+
JWTService.verifyMediaToken(mediaTokenParam, resourceId21);
|
|
14031
|
+
c.set("token", mediaTokenParam);
|
|
14032
|
+
await next();
|
|
14033
|
+
return;
|
|
14034
|
+
} catch (error) {
|
|
14035
|
+
logger2.warn("Authentication failed: Invalid media token", {
|
|
14036
|
+
type: "auth_failed",
|
|
14037
|
+
reason: "invalid_media_token",
|
|
14038
|
+
path: c.req.path,
|
|
14039
|
+
error: error instanceof Error ? error.message : String(error)
|
|
14040
|
+
});
|
|
14041
|
+
return c.json({ error: "Unauthorized" }, 401);
|
|
14042
|
+
}
|
|
14043
|
+
}
|
|
14044
|
+
}
|
|
13865
14045
|
const authHeader = c.req.header("Authorization");
|
|
13866
14046
|
let tokenStr;
|
|
13867
14047
|
if (authHeader?.startsWith("Bearer ")) {
|
|
@@ -14195,6 +14375,7 @@ authRouter.get("/api/users/me", authMiddleware, async (c) => {
|
|
|
14195
14375
|
domain: user.domain,
|
|
14196
14376
|
provider: user.provider,
|
|
14197
14377
|
isAdmin: user.isAdmin,
|
|
14378
|
+
isModerator: user.isModerator,
|
|
14198
14379
|
isActive: user.isActive,
|
|
14199
14380
|
termsAcceptedAt: user.termsAcceptedAt?.toISOString() || null,
|
|
14200
14381
|
lastLogin: user.lastLogin?.toISOString() || null,
|
|
@@ -14260,6 +14441,20 @@ authRouter.post("/api/tokens/mcp-generate", authMiddleware, async (c) => {
|
|
|
14260
14441
|
return c.json({ error: "Failed to generate refresh token" }, 401);
|
|
14261
14442
|
}
|
|
14262
14443
|
});
|
|
14444
|
+
authRouter.post("/api/tokens/media", authMiddleware, async (c) => {
|
|
14445
|
+
const user = c.get("user");
|
|
14446
|
+
let body;
|
|
14447
|
+
try {
|
|
14448
|
+
body = await c.req.json();
|
|
14449
|
+
} catch {
|
|
14450
|
+
return c.json({ error: "Invalid request body" }, 400);
|
|
14451
|
+
}
|
|
14452
|
+
if (!body.resourceId || typeof body.resourceId !== "string") {
|
|
14453
|
+
return c.json({ error: "resourceId is required" }, 400);
|
|
14454
|
+
}
|
|
14455
|
+
const token = JWTService.generateMediaToken(body.resourceId, user.id);
|
|
14456
|
+
return c.json({ token }, 200);
|
|
14457
|
+
});
|
|
14263
14458
|
authRouter.post("/api/users/accept-terms", authMiddleware, async (c) => {
|
|
14264
14459
|
const user = c.get("user");
|
|
14265
14460
|
await OAuthService.acceptTerms(userId(user.id));
|
|
@@ -14753,7 +14948,7 @@ function registerCreateResource(router) {
|
|
|
14753
14948
|
const arrayBuffer = await file.arrayBuffer();
|
|
14754
14949
|
const contentBuffer = Buffer.from(arrayBuffer);
|
|
14755
14950
|
const eventBus2 = c.get("eventBus");
|
|
14756
|
-
const
|
|
14951
|
+
const resourceId21 = await ResourceOperations.createResource(
|
|
14757
14952
|
{
|
|
14758
14953
|
name,
|
|
14759
14954
|
content: contentBuffer,
|
|
@@ -14766,7 +14961,7 @@ function registerCreateResource(router) {
|
|
|
14766
14961
|
userId(userToDid(user)),
|
|
14767
14962
|
eventBus2
|
|
14768
14963
|
);
|
|
14769
|
-
return c.json({ resourceId:
|
|
14964
|
+
return c.json({ resourceId: resourceId21 }, 202);
|
|
14770
14965
|
});
|
|
14771
14966
|
}
|
|
14772
14967
|
|
|
@@ -15126,7 +15321,7 @@ var nanoid = (size = 21) => {
|
|
|
15126
15321
|
async function writeTypedSSE(stream, options) {
|
|
15127
15322
|
await stream.writeSSE({
|
|
15128
15323
|
event: options.event,
|
|
15129
|
-
data: options.data,
|
|
15324
|
+
data: JSON.stringify(options.data),
|
|
15130
15325
|
id: options.id
|
|
15131
15326
|
});
|
|
15132
15327
|
}
|
|
@@ -15210,16 +15405,13 @@ function registerAnnotateReferencesStream(router, jobQueue) {
|
|
|
15210
15405
|
logger2.info("[EventBus] Received mark:progress event", { progress, resourceId: id });
|
|
15211
15406
|
try {
|
|
15212
15407
|
await writeTypedSSE(stream, {
|
|
15213
|
-
data:
|
|
15408
|
+
data: {
|
|
15214
15409
|
status: progress.status || "scanning",
|
|
15215
15410
|
resourceId: resourceId(id),
|
|
15216
15411
|
currentEntityType: progress.currentEntityType,
|
|
15217
|
-
|
|
15218
|
-
|
|
15219
|
-
|
|
15220
|
-
message: progress.message || (progress.currentEntityType ? `Scanning for ${progress.currentEntityType}...` : "Processing..."),
|
|
15221
|
-
percentage: progress.percentage
|
|
15222
|
-
}),
|
|
15412
|
+
percentage: progress.percentage,
|
|
15413
|
+
message: progress.message || (progress.currentEntityType ? `Scanning for ${progress.currentEntityType}...` : "Processing...")
|
|
15414
|
+
},
|
|
15223
15415
|
event: "mark:progress",
|
|
15224
15416
|
id: String(Date.now())
|
|
15225
15417
|
});
|
|
@@ -15237,15 +15429,13 @@ function registerAnnotateReferencesStream(router, jobQueue) {
|
|
|
15237
15429
|
try {
|
|
15238
15430
|
const result = event.payload.result;
|
|
15239
15431
|
await writeTypedSSE(stream, {
|
|
15240
|
-
data:
|
|
15432
|
+
data: {
|
|
15241
15433
|
motivation: "linking",
|
|
15242
15434
|
status: "complete",
|
|
15243
15435
|
resourceId: resourceId(id),
|
|
15244
|
-
totalEntityTypes: entityTypes.length,
|
|
15245
|
-
processedEntityTypes: entityTypes.length,
|
|
15246
15436
|
foundCount: result?.totalFound,
|
|
15247
15437
|
message: result?.totalFound !== void 0 ? `Detection complete! Found ${result.totalFound} entities` : "Detection complete!"
|
|
15248
|
-
}
|
|
15438
|
+
},
|
|
15249
15439
|
event: "mark:assist-finished",
|
|
15250
15440
|
id: String(Date.now())
|
|
15251
15441
|
});
|
|
@@ -15262,13 +15452,10 @@ function registerAnnotateReferencesStream(router, jobQueue) {
|
|
|
15262
15452
|
logger2.info("Detection failed", { error: event.payload.error });
|
|
15263
15453
|
try {
|
|
15264
15454
|
await writeTypedSSE(stream, {
|
|
15265
|
-
data:
|
|
15266
|
-
status: "error",
|
|
15455
|
+
data: {
|
|
15267
15456
|
resourceId: resourceId(id),
|
|
15268
|
-
totalEntityTypes: entityTypes.length,
|
|
15269
|
-
processedEntityTypes: 0,
|
|
15270
15457
|
message: event.payload.error || "Detection failed"
|
|
15271
|
-
}
|
|
15458
|
+
},
|
|
15272
15459
|
event: "mark:assist-failed",
|
|
15273
15460
|
id: String(Date.now())
|
|
15274
15461
|
});
|
|
@@ -15398,11 +15585,11 @@ function registerAnnotateHighlightsStream(router, jobQueue) {
|
|
|
15398
15585
|
logger2.info("Detection started");
|
|
15399
15586
|
try {
|
|
15400
15587
|
await writeTypedSSE(stream, {
|
|
15401
|
-
data:
|
|
15588
|
+
data: {
|
|
15402
15589
|
status: "started",
|
|
15403
15590
|
resourceId: resourceId(id),
|
|
15404
15591
|
message: "Starting detection..."
|
|
15405
|
-
}
|
|
15592
|
+
},
|
|
15406
15593
|
event: "mark:progress",
|
|
15407
15594
|
id: String(Date.now())
|
|
15408
15595
|
});
|
|
@@ -15418,13 +15605,12 @@ function registerAnnotateHighlightsStream(router, jobQueue) {
|
|
|
15418
15605
|
logger2.info("Detection progress", { progress });
|
|
15419
15606
|
try {
|
|
15420
15607
|
await writeTypedSSE(stream, {
|
|
15421
|
-
data:
|
|
15608
|
+
data: {
|
|
15422
15609
|
status: progress.status || "analyzing",
|
|
15423
15610
|
resourceId: resourceId(id),
|
|
15424
|
-
stage: progress.status === "analyzing" || progress.status === "creating" ? progress.status : void 0,
|
|
15425
15611
|
percentage: progress.percentage,
|
|
15426
15612
|
message: progress.message || "Processing..."
|
|
15427
|
-
}
|
|
15613
|
+
},
|
|
15428
15614
|
event: "mark:progress",
|
|
15429
15615
|
id: String(Date.now())
|
|
15430
15616
|
});
|
|
@@ -15442,7 +15628,7 @@ function registerAnnotateHighlightsStream(router, jobQueue) {
|
|
|
15442
15628
|
try {
|
|
15443
15629
|
const result = event.payload.result;
|
|
15444
15630
|
await writeTypedSSE(stream, {
|
|
15445
|
-
data:
|
|
15631
|
+
data: {
|
|
15446
15632
|
motivation: "highlighting",
|
|
15447
15633
|
status: "complete",
|
|
15448
15634
|
resourceId: resourceId(id),
|
|
@@ -15450,7 +15636,7 @@ function registerAnnotateHighlightsStream(router, jobQueue) {
|
|
|
15450
15636
|
foundCount: result?.highlightsFound,
|
|
15451
15637
|
createdCount: result?.highlightsCreated,
|
|
15452
15638
|
message: result?.highlightsCreated !== void 0 ? `Complete! Created ${result.highlightsCreated} highlights` : "Highlight detection complete!"
|
|
15453
|
-
}
|
|
15639
|
+
},
|
|
15454
15640
|
event: "mark:assist-finished",
|
|
15455
15641
|
id: String(Date.now())
|
|
15456
15642
|
});
|
|
@@ -15467,11 +15653,10 @@ function registerAnnotateHighlightsStream(router, jobQueue) {
|
|
|
15467
15653
|
logger2.info("Detection failed", { error: event.payload.error });
|
|
15468
15654
|
try {
|
|
15469
15655
|
await writeTypedSSE(stream, {
|
|
15470
|
-
data:
|
|
15471
|
-
status: "error",
|
|
15656
|
+
data: {
|
|
15472
15657
|
resourceId: resourceId(id),
|
|
15473
15658
|
message: event.payload.error || "Highlight detection failed"
|
|
15474
|
-
}
|
|
15659
|
+
},
|
|
15475
15660
|
event: "mark:assist-failed",
|
|
15476
15661
|
id: String(Date.now())
|
|
15477
15662
|
});
|
|
@@ -15601,11 +15786,11 @@ function registerAnnotateAssessmentsStream(router, jobQueue) {
|
|
|
15601
15786
|
logger2.info("Detection started");
|
|
15602
15787
|
try {
|
|
15603
15788
|
await writeTypedSSE(stream, {
|
|
15604
|
-
data:
|
|
15789
|
+
data: {
|
|
15605
15790
|
status: "started",
|
|
15606
15791
|
resourceId: resourceId(id),
|
|
15607
15792
|
message: "Starting detection..."
|
|
15608
|
-
}
|
|
15793
|
+
},
|
|
15609
15794
|
event: "mark:progress",
|
|
15610
15795
|
id: String(Date.now())
|
|
15611
15796
|
});
|
|
@@ -15621,13 +15806,12 @@ function registerAnnotateAssessmentsStream(router, jobQueue) {
|
|
|
15621
15806
|
logger2.info("Detection progress", { progress });
|
|
15622
15807
|
try {
|
|
15623
15808
|
await writeTypedSSE(stream, {
|
|
15624
|
-
data:
|
|
15809
|
+
data: {
|
|
15625
15810
|
status: progress.status || "analyzing",
|
|
15626
15811
|
resourceId: resourceId(id),
|
|
15627
|
-
stage: progress.status === "analyzing" || progress.status === "creating" ? progress.status : void 0,
|
|
15628
15812
|
percentage: progress.percentage,
|
|
15629
15813
|
message: progress.message || "Processing..."
|
|
15630
|
-
}
|
|
15814
|
+
},
|
|
15631
15815
|
event: "mark:progress",
|
|
15632
15816
|
id: String(Date.now())
|
|
15633
15817
|
});
|
|
@@ -15649,7 +15833,7 @@ function registerAnnotateAssessmentsStream(router, jobQueue) {
|
|
|
15649
15833
|
try {
|
|
15650
15834
|
const result = event.payload.result;
|
|
15651
15835
|
await writeTypedSSE(stream, {
|
|
15652
|
-
data:
|
|
15836
|
+
data: {
|
|
15653
15837
|
motivation: "assessing",
|
|
15654
15838
|
status: "complete",
|
|
15655
15839
|
resourceId: resourceId(id),
|
|
@@ -15657,7 +15841,7 @@ function registerAnnotateAssessmentsStream(router, jobQueue) {
|
|
|
15657
15841
|
foundCount: result?.assessmentsFound,
|
|
15658
15842
|
createdCount: result?.assessmentsCreated,
|
|
15659
15843
|
message: result?.assessmentsCreated !== void 0 ? `Complete! Created ${result.assessmentsCreated} assessments` : "Assessment detection complete!"
|
|
15660
|
-
}
|
|
15844
|
+
},
|
|
15661
15845
|
event: "mark:assist-finished",
|
|
15662
15846
|
id: String(Date.now())
|
|
15663
15847
|
});
|
|
@@ -15674,11 +15858,10 @@ function registerAnnotateAssessmentsStream(router, jobQueue) {
|
|
|
15674
15858
|
logger2.info("Detection failed", { error: event.payload.error });
|
|
15675
15859
|
try {
|
|
15676
15860
|
await writeTypedSSE(stream, {
|
|
15677
|
-
data:
|
|
15678
|
-
status: "error",
|
|
15861
|
+
data: {
|
|
15679
15862
|
resourceId: resourceId(id),
|
|
15680
15863
|
message: event.payload.error || "Assessment detection failed"
|
|
15681
|
-
}
|
|
15864
|
+
},
|
|
15682
15865
|
event: "mark:assist-failed",
|
|
15683
15866
|
id: String(Date.now())
|
|
15684
15867
|
});
|
|
@@ -15808,11 +15991,11 @@ function registerAnnotateCommentsStream(router, jobQueue) {
|
|
|
15808
15991
|
logger2.info("Detection started");
|
|
15809
15992
|
try {
|
|
15810
15993
|
await writeTypedSSE(stream, {
|
|
15811
|
-
data:
|
|
15994
|
+
data: {
|
|
15812
15995
|
status: "started",
|
|
15813
15996
|
resourceId: resourceId(id),
|
|
15814
15997
|
message: "Starting detection..."
|
|
15815
|
-
}
|
|
15998
|
+
},
|
|
15816
15999
|
event: "mark:progress",
|
|
15817
16000
|
id: String(Date.now())
|
|
15818
16001
|
});
|
|
@@ -15828,13 +16011,12 @@ function registerAnnotateCommentsStream(router, jobQueue) {
|
|
|
15828
16011
|
logger2.info("Detection progress", { progress });
|
|
15829
16012
|
try {
|
|
15830
16013
|
await writeTypedSSE(stream, {
|
|
15831
|
-
data:
|
|
16014
|
+
data: {
|
|
15832
16015
|
status: progress.status || "analyzing",
|
|
15833
16016
|
resourceId: resourceId(id),
|
|
15834
|
-
stage: progress.status === "analyzing" || progress.status === "creating" ? progress.status : void 0,
|
|
15835
16017
|
percentage: progress.percentage,
|
|
15836
16018
|
message: progress.message || "Processing..."
|
|
15837
|
-
}
|
|
16019
|
+
},
|
|
15838
16020
|
event: "mark:progress",
|
|
15839
16021
|
id: String(Date.now())
|
|
15840
16022
|
});
|
|
@@ -15852,7 +16034,7 @@ function registerAnnotateCommentsStream(router, jobQueue) {
|
|
|
15852
16034
|
try {
|
|
15853
16035
|
const result = event.payload.result;
|
|
15854
16036
|
await writeTypedSSE(stream, {
|
|
15855
|
-
data:
|
|
16037
|
+
data: {
|
|
15856
16038
|
motivation: "commenting",
|
|
15857
16039
|
status: "complete",
|
|
15858
16040
|
resourceId: resourceId(id),
|
|
@@ -15860,7 +16042,7 @@ function registerAnnotateCommentsStream(router, jobQueue) {
|
|
|
15860
16042
|
foundCount: result?.commentsFound,
|
|
15861
16043
|
createdCount: result?.commentsCreated,
|
|
15862
16044
|
message: result?.commentsCreated !== void 0 ? `Complete! Created ${result.commentsCreated} comments` : "Comment detection complete!"
|
|
15863
|
-
}
|
|
16045
|
+
},
|
|
15864
16046
|
event: "mark:assist-finished",
|
|
15865
16047
|
id: String(Date.now())
|
|
15866
16048
|
});
|
|
@@ -15877,11 +16059,10 @@ function registerAnnotateCommentsStream(router, jobQueue) {
|
|
|
15877
16059
|
logger2.info("Detection failed", { error: event.payload.error });
|
|
15878
16060
|
try {
|
|
15879
16061
|
await writeTypedSSE(stream, {
|
|
15880
|
-
data:
|
|
15881
|
-
status: "error",
|
|
16062
|
+
data: {
|
|
15882
16063
|
resourceId: resourceId(id),
|
|
15883
16064
|
message: event.payload.error || "Comment detection failed"
|
|
15884
|
-
}
|
|
16065
|
+
},
|
|
15885
16066
|
event: "mark:assist-failed",
|
|
15886
16067
|
id: String(Date.now())
|
|
15887
16068
|
});
|
|
@@ -16185,12 +16366,12 @@ function registerAnnotateTagsStream(router, jobQueue) {
|
|
|
16185
16366
|
logger2.info("Detection started");
|
|
16186
16367
|
try {
|
|
16187
16368
|
await writeTypedSSE(stream, {
|
|
16188
|
-
data:
|
|
16369
|
+
data: {
|
|
16189
16370
|
status: "started",
|
|
16190
16371
|
resourceId: resourceId(id),
|
|
16191
16372
|
totalCategories: categories.length,
|
|
16192
16373
|
message: "Starting detection..."
|
|
16193
|
-
}
|
|
16374
|
+
},
|
|
16194
16375
|
event: "mark:progress",
|
|
16195
16376
|
id: String(Date.now())
|
|
16196
16377
|
});
|
|
@@ -16206,16 +16387,15 @@ function registerAnnotateTagsStream(router, jobQueue) {
|
|
|
16206
16387
|
logger2.info("Detection progress", { progress });
|
|
16207
16388
|
try {
|
|
16208
16389
|
await writeTypedSSE(stream, {
|
|
16209
|
-
data:
|
|
16390
|
+
data: {
|
|
16210
16391
|
status: progress.status || "analyzing",
|
|
16211
16392
|
resourceId: resourceId(id),
|
|
16212
|
-
stage: progress.status === "analyzing" || progress.status === "creating" ? progress.status : void 0,
|
|
16213
16393
|
percentage: progress.percentage,
|
|
16214
16394
|
currentCategory: progress.currentCategory,
|
|
16215
16395
|
processedCategories: progress.processedCategories,
|
|
16216
16396
|
totalCategories: progress.totalCategories,
|
|
16217
16397
|
message: progress.message || "Processing..."
|
|
16218
|
-
}
|
|
16398
|
+
},
|
|
16219
16399
|
event: "mark:progress",
|
|
16220
16400
|
id: String(Date.now())
|
|
16221
16401
|
});
|
|
@@ -16233,7 +16413,7 @@ function registerAnnotateTagsStream(router, jobQueue) {
|
|
|
16233
16413
|
try {
|
|
16234
16414
|
const result = event.payload.result;
|
|
16235
16415
|
await writeTypedSSE(stream, {
|
|
16236
|
-
data:
|
|
16416
|
+
data: {
|
|
16237
16417
|
motivation: "tagging",
|
|
16238
16418
|
status: "complete",
|
|
16239
16419
|
resourceId: resourceId(id),
|
|
@@ -16242,7 +16422,7 @@ function registerAnnotateTagsStream(router, jobQueue) {
|
|
|
16242
16422
|
createdCount: result?.tagsCreated,
|
|
16243
16423
|
byCategory: result?.byCategory,
|
|
16244
16424
|
message: result?.tagsCreated !== void 0 ? `Complete! Created ${result.tagsCreated} tags` : "Tag detection complete!"
|
|
16245
|
-
}
|
|
16425
|
+
},
|
|
16246
16426
|
event: "mark:assist-finished",
|
|
16247
16427
|
id: String(Date.now())
|
|
16248
16428
|
});
|
|
@@ -16259,11 +16439,10 @@ function registerAnnotateTagsStream(router, jobQueue) {
|
|
|
16259
16439
|
logger2.info("Detection failed", { error: event.payload.error });
|
|
16260
16440
|
try {
|
|
16261
16441
|
await writeTypedSSE(stream, {
|
|
16262
|
-
data:
|
|
16263
|
-
status: "error",
|
|
16442
|
+
data: {
|
|
16264
16443
|
resourceId: resourceId(id),
|
|
16265
16444
|
message: event.payload.error || "Tag detection failed"
|
|
16266
|
-
}
|
|
16445
|
+
},
|
|
16267
16446
|
event: "mark:assist-failed",
|
|
16268
16447
|
id: String(Date.now())
|
|
16269
16448
|
});
|
|
@@ -16337,118 +16516,122 @@ function registerGetReferencedBy(router) {
|
|
|
16337
16516
|
});
|
|
16338
16517
|
}
|
|
16339
16518
|
init_logger();
|
|
16340
|
-
function
|
|
16341
|
-
router.post(
|
|
16342
|
-
|
|
16343
|
-
|
|
16344
|
-
|
|
16345
|
-
|
|
16346
|
-
|
|
16347
|
-
|
|
16348
|
-
|
|
16349
|
-
throw new HTTPException(401, { message: "Authentication required" });
|
|
16350
|
-
}
|
|
16351
|
-
const body = await c.req.json();
|
|
16352
|
-
const { referenceId, context, limit, useSemanticScoring } = body;
|
|
16353
|
-
if (!referenceId || !context) {
|
|
16354
|
-
throw new HTTPException(400, { message: "referenceId and context are required" });
|
|
16355
|
-
}
|
|
16356
|
-
const eventBus2 = c.get("eventBus");
|
|
16357
|
-
const { knowledgeSystem: { kb } } = c.get("makeMeaning");
|
|
16358
|
-
const resource = await ResourceContext.getResourceMetadata(resourceId(id), kb);
|
|
16359
|
-
if (!resource) {
|
|
16360
|
-
throw new HTTPException(404, { message: "Resource not found" });
|
|
16361
|
-
}
|
|
16362
|
-
const correlationId = crypto.randomUUID();
|
|
16363
|
-
logger2.info("Starting bind search stream", { referenceId, correlationId });
|
|
16364
|
-
c.header("X-Accel-Buffering", "no");
|
|
16365
|
-
c.header("Cache-Control", "no-cache, no-transform");
|
|
16366
|
-
return streamSSE(c, async (stream) => {
|
|
16367
|
-
let isStreamClosed = false;
|
|
16368
|
-
const subscriptions = [];
|
|
16369
|
-
let closeStreamCallback = null;
|
|
16370
|
-
const streamPromise = new Promise((resolve) => {
|
|
16371
|
-
closeStreamCallback = resolve;
|
|
16519
|
+
function registerMatchSearchStream(router) {
|
|
16520
|
+
router.post(
|
|
16521
|
+
"/resources/:id/match-search-stream",
|
|
16522
|
+
validateRequestBody("MatchSearchStreamRequest"),
|
|
16523
|
+
async (c) => {
|
|
16524
|
+
const { id } = c.req.param();
|
|
16525
|
+
const logger2 = getLogger().child({
|
|
16526
|
+
component: "match-search-stream",
|
|
16527
|
+
resourceId: id
|
|
16372
16528
|
});
|
|
16373
|
-
const
|
|
16374
|
-
|
|
16375
|
-
|
|
16376
|
-
|
|
16377
|
-
|
|
16378
|
-
};
|
|
16379
|
-
|
|
16380
|
-
|
|
16381
|
-
|
|
16382
|
-
|
|
16383
|
-
|
|
16384
|
-
|
|
16385
|
-
|
|
16386
|
-
|
|
16387
|
-
|
|
16388
|
-
|
|
16389
|
-
|
|
16390
|
-
|
|
16391
|
-
|
|
16392
|
-
|
|
16393
|
-
|
|
16394
|
-
|
|
16395
|
-
id: String(Date.now())
|
|
16396
|
-
});
|
|
16397
|
-
} catch (error) {
|
|
16398
|
-
logger2.warn("Client disconnected during results");
|
|
16399
|
-
}
|
|
16400
|
-
cleanup();
|
|
16401
|
-
})
|
|
16402
|
-
);
|
|
16403
|
-
subscriptions.push(
|
|
16404
|
-
eventBus2.get("match:search-failed").subscribe(async (event) => {
|
|
16405
|
-
if (event.correlationId !== correlationId) return;
|
|
16406
|
-
if (isStreamClosed) return;
|
|
16407
|
-
logger2.error("Bind search failed", { referenceId, error: event.error });
|
|
16408
|
-
try {
|
|
16409
|
-
await writeTypedSSE(stream, {
|
|
16410
|
-
data: JSON.stringify({
|
|
16411
|
-
referenceId: event.referenceId,
|
|
16412
|
-
error: event.error.message
|
|
16413
|
-
}),
|
|
16414
|
-
event: "match:search-failed",
|
|
16415
|
-
id: String(Date.now())
|
|
16416
|
-
});
|
|
16417
|
-
} catch (error) {
|
|
16418
|
-
logger2.warn("Client disconnected during error");
|
|
16419
|
-
}
|
|
16420
|
-
cleanup();
|
|
16421
|
-
})
|
|
16422
|
-
);
|
|
16423
|
-
eventBus2.get("match:search-requested").next({
|
|
16424
|
-
correlationId,
|
|
16425
|
-
referenceId,
|
|
16426
|
-
context,
|
|
16427
|
-
limit,
|
|
16428
|
-
useSemanticScoring
|
|
16429
|
-
});
|
|
16430
|
-
c.req.raw.signal.addEventListener("abort", () => {
|
|
16431
|
-
logger2.info("Client disconnected from bind search stream");
|
|
16432
|
-
cleanup();
|
|
16529
|
+
const user = c.get("user");
|
|
16530
|
+
if (!user) {
|
|
16531
|
+
throw new HTTPException(401, { message: "Authentication required" });
|
|
16532
|
+
}
|
|
16533
|
+
const body = c.get("validatedBody");
|
|
16534
|
+
const { referenceId, context, limit, useSemanticScoring } = body;
|
|
16535
|
+
const correlationId = body.correlationId ?? crypto.randomUUID();
|
|
16536
|
+
const eventBus2 = c.get("eventBus");
|
|
16537
|
+
const { knowledgeSystem: { kb } } = c.get("makeMeaning");
|
|
16538
|
+
const resource = await ResourceContext.getResourceMetadata(resourceId(id), kb);
|
|
16539
|
+
if (!resource) {
|
|
16540
|
+
throw new HTTPException(404, { message: "Resource not found" });
|
|
16541
|
+
}
|
|
16542
|
+
logger2.info("Starting match search stream", { referenceId, correlationId });
|
|
16543
|
+
c.header("X-Accel-Buffering", "no");
|
|
16544
|
+
c.header("Cache-Control", "no-cache, no-transform");
|
|
16545
|
+
return streamSSE(c, async (stream) => {
|
|
16546
|
+
let isStreamClosed = false;
|
|
16547
|
+
const subscriptions = [];
|
|
16548
|
+
let closeStreamCallback = null;
|
|
16549
|
+
const streamPromise = new Promise((resolve) => {
|
|
16550
|
+
closeStreamCallback = resolve;
|
|
16433
16551
|
});
|
|
16434
|
-
|
|
16552
|
+
const cleanup = () => {
|
|
16553
|
+
if (isStreamClosed) return;
|
|
16554
|
+
isStreamClosed = true;
|
|
16555
|
+
subscriptions.forEach((sub) => sub.unsubscribe());
|
|
16556
|
+
if (closeStreamCallback) closeStreamCallback();
|
|
16557
|
+
};
|
|
16435
16558
|
try {
|
|
16436
|
-
|
|
16437
|
-
|
|
16438
|
-
|
|
16439
|
-
|
|
16440
|
-
|
|
16441
|
-
|
|
16442
|
-
|
|
16559
|
+
subscriptions.push(
|
|
16560
|
+
eventBus2.get("match:search-results").subscribe(async (event) => {
|
|
16561
|
+
if (event.correlationId !== correlationId) return;
|
|
16562
|
+
if (isStreamClosed) return;
|
|
16563
|
+
logger2.info("Match search completed", {
|
|
16564
|
+
referenceId,
|
|
16565
|
+
resultCount: event.response.length
|
|
16566
|
+
});
|
|
16567
|
+
try {
|
|
16568
|
+
await writeTypedSSE(stream, {
|
|
16569
|
+
data: {
|
|
16570
|
+
correlationId: event.correlationId,
|
|
16571
|
+
referenceId: event.referenceId,
|
|
16572
|
+
response: event.response
|
|
16573
|
+
},
|
|
16574
|
+
event: "match:search-results",
|
|
16575
|
+
id: String(Date.now())
|
|
16576
|
+
});
|
|
16577
|
+
} catch {
|
|
16578
|
+
logger2.warn("Client disconnected during results");
|
|
16579
|
+
}
|
|
16580
|
+
cleanup();
|
|
16581
|
+
})
|
|
16582
|
+
);
|
|
16583
|
+
subscriptions.push(
|
|
16584
|
+
eventBus2.get("match:search-failed").subscribe(async (event) => {
|
|
16585
|
+
if (event.correlationId !== correlationId) return;
|
|
16586
|
+
if (isStreamClosed) return;
|
|
16587
|
+
logger2.error("Match search failed", { referenceId, error: event.error });
|
|
16588
|
+
try {
|
|
16589
|
+
await writeTypedSSE(stream, {
|
|
16590
|
+
data: {
|
|
16591
|
+
correlationId: event.correlationId,
|
|
16592
|
+
referenceId: event.referenceId,
|
|
16593
|
+
error: event.error
|
|
16594
|
+
},
|
|
16595
|
+
event: "match:search-failed",
|
|
16596
|
+
id: String(Date.now())
|
|
16597
|
+
});
|
|
16598
|
+
} catch {
|
|
16599
|
+
logger2.warn("Client disconnected during error");
|
|
16600
|
+
}
|
|
16601
|
+
cleanup();
|
|
16602
|
+
})
|
|
16603
|
+
);
|
|
16604
|
+
eventBus2.get("match:search-requested").next({
|
|
16605
|
+
correlationId,
|
|
16606
|
+
referenceId,
|
|
16607
|
+
context,
|
|
16608
|
+
limit,
|
|
16609
|
+
useSemanticScoring
|
|
16443
16610
|
});
|
|
16444
|
-
|
|
16445
|
-
|
|
16611
|
+
c.req.raw.signal.addEventListener("abort", () => {
|
|
16612
|
+
logger2.info("Client disconnected from match search stream");
|
|
16613
|
+
cleanup();
|
|
16614
|
+
});
|
|
16615
|
+
} catch (error) {
|
|
16616
|
+
try {
|
|
16617
|
+
await writeTypedSSE(stream, {
|
|
16618
|
+
data: {
|
|
16619
|
+
correlationId,
|
|
16620
|
+
referenceId,
|
|
16621
|
+
error: error instanceof Error ? error.message : "Search failed"
|
|
16622
|
+
},
|
|
16623
|
+
event: "match:search-failed",
|
|
16624
|
+
id: String(Date.now())
|
|
16625
|
+
});
|
|
16626
|
+
} catch {
|
|
16627
|
+
logger2.warn("Could not send error to client");
|
|
16628
|
+
}
|
|
16629
|
+
cleanup();
|
|
16446
16630
|
}
|
|
16447
|
-
|
|
16448
|
-
}
|
|
16449
|
-
|
|
16450
|
-
|
|
16451
|
-
});
|
|
16631
|
+
return streamPromise;
|
|
16632
|
+
});
|
|
16633
|
+
}
|
|
16634
|
+
);
|
|
16452
16635
|
}
|
|
16453
16636
|
function registerTokenRoutes(router) {
|
|
16454
16637
|
router.get("/api/clone-tokens/:token", async (c) => {
|
|
@@ -16928,13 +17111,13 @@ function registerYieldResourceStream(router, jobQueue) {
|
|
|
16928
17111
|
logger2.info("Generation started");
|
|
16929
17112
|
try {
|
|
16930
17113
|
await writeTypedSSE(stream, {
|
|
16931
|
-
data:
|
|
17114
|
+
data: {
|
|
16932
17115
|
status: "started",
|
|
16933
17116
|
referenceId: reference.id,
|
|
16934
17117
|
resourceName,
|
|
16935
17118
|
percentage: 0,
|
|
16936
17119
|
message: "Starting..."
|
|
16937
|
-
}
|
|
17120
|
+
},
|
|
16938
17121
|
event: "yield:progress",
|
|
16939
17122
|
id: String(Date.now())
|
|
16940
17123
|
});
|
|
@@ -16950,13 +17133,13 @@ function registerYieldResourceStream(router, jobQueue) {
|
|
|
16950
17133
|
logger2.info("Generation progress", { progress });
|
|
16951
17134
|
try {
|
|
16952
17135
|
await writeTypedSSE(stream, {
|
|
16953
|
-
data:
|
|
17136
|
+
data: {
|
|
16954
17137
|
status: progress.status,
|
|
16955
17138
|
referenceId: reference.id,
|
|
16956
17139
|
resourceName,
|
|
16957
17140
|
percentage: progress.percentage || 0,
|
|
16958
17141
|
message: progress.message || `${progress.status}...`
|
|
16959
|
-
}
|
|
17142
|
+
},
|
|
16960
17143
|
event: "yield:progress",
|
|
16961
17144
|
id: String(Date.now())
|
|
16962
17145
|
});
|
|
@@ -16972,7 +17155,7 @@ function registerYieldResourceStream(router, jobQueue) {
|
|
|
16972
17155
|
logger2.info("Generation completed");
|
|
16973
17156
|
try {
|
|
16974
17157
|
await writeTypedSSE(stream, {
|
|
16975
|
-
data:
|
|
17158
|
+
data: {
|
|
16976
17159
|
status: "complete",
|
|
16977
17160
|
referenceId: reference.id,
|
|
16978
17161
|
resourceName,
|
|
@@ -16980,7 +17163,7 @@ function registerYieldResourceStream(router, jobQueue) {
|
|
|
16980
17163
|
sourceResourceId: resourceIdParam,
|
|
16981
17164
|
percentage: 100,
|
|
16982
17165
|
message: "Draft resource created! Ready for review."
|
|
16983
|
-
}
|
|
17166
|
+
},
|
|
16984
17167
|
event: "yield:finished",
|
|
16985
17168
|
id: String(Date.now())
|
|
16986
17169
|
});
|
|
@@ -17012,12 +17195,12 @@ function registerYieldResourceStream(router, jobQueue) {
|
|
|
17012
17195
|
} catch (error) {
|
|
17013
17196
|
try {
|
|
17014
17197
|
await writeTypedSSE(stream, {
|
|
17015
|
-
data:
|
|
17198
|
+
data: {
|
|
17016
17199
|
status: "error",
|
|
17017
17200
|
referenceId: reference.id,
|
|
17018
17201
|
percentage: 0,
|
|
17019
17202
|
message: error instanceof Error ? error.message : "Generation failed"
|
|
17020
|
-
}
|
|
17203
|
+
},
|
|
17021
17204
|
event: "yield:failed",
|
|
17022
17205
|
id: String(Date.now())
|
|
17023
17206
|
});
|
|
@@ -17050,12 +17233,7 @@ function registerGatherAnnotationStream(router) {
|
|
|
17050
17233
|
if (!user) {
|
|
17051
17234
|
throw new HTTPException(401, { message: "Authentication required" });
|
|
17052
17235
|
}
|
|
17053
|
-
|
|
17054
|
-
annotationId: annotationId(annotationIdParam),
|
|
17055
|
-
resourceId: resourceId(resourceIdParam),
|
|
17056
|
-
options: { includeSourceContext: true, includeTargetContext: true, contextWindow }
|
|
17057
|
-
});
|
|
17058
|
-
logger2.info("Emitted gather:requested", { annotationId: annotationIdParam, contextWindow });
|
|
17236
|
+
const correlationId = body.correlationId ?? crypto.randomUUID();
|
|
17059
17237
|
c.header("X-Accel-Buffering", "no");
|
|
17060
17238
|
c.header("Cache-Control", "no-cache, no-transform");
|
|
17061
17239
|
return streamSSE(c, async (stream) => {
|
|
@@ -17075,7 +17253,7 @@ function registerGatherAnnotationStream(router) {
|
|
|
17075
17253
|
if (isStreamClosed) return;
|
|
17076
17254
|
try {
|
|
17077
17255
|
await writeTypedSSE(stream, {
|
|
17078
|
-
data:
|
|
17256
|
+
data: { message: event.message, percentage: event.percentage },
|
|
17079
17257
|
event: "gather:annotation-progress",
|
|
17080
17258
|
id: String(Date.now())
|
|
17081
17259
|
});
|
|
@@ -17086,11 +17264,11 @@ function registerGatherAnnotationStream(router) {
|
|
|
17086
17264
|
);
|
|
17087
17265
|
subscriptions.push(
|
|
17088
17266
|
eventBus2.get("gather:complete").subscribe(async (event) => {
|
|
17089
|
-
if (event.
|
|
17267
|
+
if (event.correlationId !== correlationId) return;
|
|
17090
17268
|
if (isStreamClosed) return;
|
|
17091
17269
|
try {
|
|
17092
17270
|
await writeTypedSSE(stream, {
|
|
17093
|
-
data:
|
|
17271
|
+
data: { correlationId: event.correlationId, annotationId: event.annotationId, response: event.response },
|
|
17094
17272
|
event: "gather:annotation-finished",
|
|
17095
17273
|
id: String(Date.now())
|
|
17096
17274
|
});
|
|
@@ -17101,11 +17279,11 @@ function registerGatherAnnotationStream(router) {
|
|
|
17101
17279
|
);
|
|
17102
17280
|
subscriptions.push(
|
|
17103
17281
|
eventBus2.get("gather:failed").subscribe(async (event) => {
|
|
17104
|
-
if (event.
|
|
17282
|
+
if (event.correlationId !== correlationId) return;
|
|
17105
17283
|
if (isStreamClosed) return;
|
|
17106
17284
|
try {
|
|
17107
17285
|
await writeTypedSSE(stream, {
|
|
17108
|
-
data:
|
|
17286
|
+
data: { correlationId: event.correlationId, annotationId: event.annotationId, error: event.error },
|
|
17109
17287
|
event: "gather:failed",
|
|
17110
17288
|
id: String(Date.now())
|
|
17111
17289
|
});
|
|
@@ -17114,6 +17292,13 @@ function registerGatherAnnotationStream(router) {
|
|
|
17114
17292
|
cleanup();
|
|
17115
17293
|
})
|
|
17116
17294
|
);
|
|
17295
|
+
eventBus2.get("gather:requested").next({
|
|
17296
|
+
correlationId,
|
|
17297
|
+
annotationId: annotationId(annotationIdParam),
|
|
17298
|
+
resourceId: resourceId(resourceIdParam),
|
|
17299
|
+
options: { includeSourceContext: true, includeTargetContext: true, contextWindow }
|
|
17300
|
+
});
|
|
17301
|
+
logger2.info("Emitted gather:requested", { annotationId: annotationIdParam, correlationId, contextWindow });
|
|
17117
17302
|
keepAliveInterval = setInterval(async () => {
|
|
17118
17303
|
if (isStreamClosed) {
|
|
17119
17304
|
clearInterval(keepAliveInterval);
|
|
@@ -17137,14 +17322,14 @@ function registerGatherAnnotationStream(router) {
|
|
|
17137
17322
|
}
|
|
17138
17323
|
function registerGetAnnotationHistory(router) {
|
|
17139
17324
|
router.get("/resources/:resourceId/annotations/:annotationId/history", async (c) => {
|
|
17140
|
-
const { resourceId:
|
|
17325
|
+
const { resourceId: resourceId21, annotationId: annotationId7 } = c.req.param();
|
|
17141
17326
|
const eventBus2 = c.get("eventBus");
|
|
17142
17327
|
const correlationId = crypto.randomUUID();
|
|
17143
17328
|
try {
|
|
17144
17329
|
const response = await eventBusRequest(
|
|
17145
17330
|
eventBus2,
|
|
17146
17331
|
"browse:annotation-history-requested",
|
|
17147
|
-
{ correlationId, resourceId: resourceId(
|
|
17332
|
+
{ correlationId, resourceId: resourceId(resourceId21), annotationId: annotationId(annotationId7) },
|
|
17148
17333
|
"browse:annotation-history-result",
|
|
17149
17334
|
"browse:annotation-history-failed"
|
|
17150
17335
|
);
|
|
@@ -17178,7 +17363,7 @@ function createResourcesRouter(jobQueue) {
|
|
|
17178
17363
|
registerAnnotateCommentsStream(resourcesRouter2, jobQueue);
|
|
17179
17364
|
registerAnnotateTagsStream(resourcesRouter2, jobQueue);
|
|
17180
17365
|
registerGetReferencedBy(resourcesRouter2);
|
|
17181
|
-
|
|
17366
|
+
registerMatchSearchStream(resourcesRouter2);
|
|
17182
17367
|
registerGetResourceAnnotations(resourcesRouter2);
|
|
17183
17368
|
registerCreateAnnotation(resourcesRouter2);
|
|
17184
17369
|
registerGetAnnotation(resourcesRouter2);
|
|
@@ -17239,8 +17424,8 @@ operationsRouter.get("/api/annotations/:id/context", async (c) => {
|
|
|
17239
17424
|
const { id } = c.req.param();
|
|
17240
17425
|
const query = c.req.query();
|
|
17241
17426
|
const { knowledgeSystem: { kb } } = c.get("makeMeaning");
|
|
17242
|
-
const
|
|
17243
|
-
if (!
|
|
17427
|
+
const resourceId21 = query.resourceId;
|
|
17428
|
+
if (!resourceId21) {
|
|
17244
17429
|
throw new HTTPException(400, { message: "resourceId query parameter is required" });
|
|
17245
17430
|
}
|
|
17246
17431
|
const contextBefore = query.contextBefore ? Number(query.contextBefore) : 100;
|
|
@@ -17254,7 +17439,7 @@ operationsRouter.get("/api/annotations/:id/context", async (c) => {
|
|
|
17254
17439
|
try {
|
|
17255
17440
|
const response = await AnnotationContext.getAnnotationContext(
|
|
17256
17441
|
annotationId(id),
|
|
17257
|
-
resourceId(
|
|
17442
|
+
resourceId(resourceId21),
|
|
17258
17443
|
contextBefore,
|
|
17259
17444
|
contextAfter,
|
|
17260
17445
|
kb
|
|
@@ -17280,14 +17465,14 @@ operationsRouter.get("/api/annotations/:id/summary", async (c) => {
|
|
|
17280
17465
|
const { id } = c.req.param();
|
|
17281
17466
|
const query = c.req.query();
|
|
17282
17467
|
const { knowledgeSystem: { gatherer } } = c.get("makeMeaning");
|
|
17283
|
-
const
|
|
17284
|
-
if (!
|
|
17468
|
+
const resourceId21 = query.resourceId;
|
|
17469
|
+
if (!resourceId21) {
|
|
17285
17470
|
throw new HTTPException(400, { message: "resourceId query parameter is required" });
|
|
17286
17471
|
}
|
|
17287
17472
|
try {
|
|
17288
17473
|
const response = await gatherer.generateAnnotationSummary(
|
|
17289
17474
|
annotationId(id),
|
|
17290
|
-
resourceId(
|
|
17475
|
+
resourceId(resourceId21)
|
|
17291
17476
|
);
|
|
17292
17477
|
return c.json(response);
|
|
17293
17478
|
} catch (error) {
|
|
@@ -17774,6 +17959,7 @@ app.use("*", async (c, next) => {
|
|
|
17774
17959
|
c.set("makeMeaning", makeMeaning);
|
|
17775
17960
|
await next();
|
|
17776
17961
|
});
|
|
17962
|
+
app.route("/", rootRouter);
|
|
17777
17963
|
app.route("/", healthRouter);
|
|
17778
17964
|
app.route("/", authRouter);
|
|
17779
17965
|
app.route("/", statusRouter);
|