@semiont/backend 0.4.12 → 0.4.13
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 +225 -37
- package/dist/index.js.map +1 -1
- package/dist/openapi.json +49 -0
- package/package.json +5 -5
package/dist/index.js
CHANGED
|
@@ -268,11 +268,11 @@ var init_jwt = __esm({
|
|
|
268
268
|
throw error;
|
|
269
269
|
}
|
|
270
270
|
}
|
|
271
|
-
static generateMediaToken(
|
|
272
|
-
const payload = { purpose: "media", sub:
|
|
271
|
+
static generateMediaToken(resourceId22, userId15) {
|
|
272
|
+
const payload = { purpose: "media", sub: resourceId22, userId: userId15 };
|
|
273
273
|
return jwt.sign(payload, this.getSecret(), { expiresIn: "5m" });
|
|
274
274
|
}
|
|
275
|
-
static verifyMediaToken(token,
|
|
275
|
+
static verifyMediaToken(token, resourceId22) {
|
|
276
276
|
let decoded;
|
|
277
277
|
try {
|
|
278
278
|
decoded = jwt.verify(token, this.getSecret());
|
|
@@ -281,7 +281,7 @@ var init_jwt = __esm({
|
|
|
281
281
|
throw new Error("Invalid media token");
|
|
282
282
|
}
|
|
283
283
|
if (decoded["purpose"] !== "media") throw new Error("Invalid media token");
|
|
284
|
-
if (decoded["sub"] !==
|
|
284
|
+
if (decoded["sub"] !== resourceId22) throw new Error("Media token resource mismatch");
|
|
285
285
|
}
|
|
286
286
|
static isAllowedDomain(email) {
|
|
287
287
|
const parts = email.split("@");
|
|
@@ -9982,7 +9982,9 @@ function makeMeaningConfigFrom(config2) {
|
|
|
9982
9982
|
const meta = config2._metadata;
|
|
9983
9983
|
return {
|
|
9984
9984
|
services: {
|
|
9985
|
-
graph: config2.services?.graph
|
|
9985
|
+
graph: config2.services?.graph,
|
|
9986
|
+
vectors: config2.services?.vectors,
|
|
9987
|
+
embedding: config2.services?.embedding
|
|
9986
9988
|
},
|
|
9987
9989
|
actors: meta?.actors,
|
|
9988
9990
|
workers: meta?.workers
|
|
@@ -10003,15 +10005,17 @@ rootRouter.get("/", (c) => {
|
|
|
10003
10005
|
<meta charset="UTF-8">
|
|
10004
10006
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
10005
10007
|
<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=Inter:wght@400;500&family=Orbitron:wght@700&display=swap" rel="stylesheet">
|
|
10009
10008
|
<style>
|
|
10010
10009
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
10010
|
+
@keyframes fadeIn {
|
|
10011
|
+
from { opacity: 0; transform: translateY(0.5rem); }
|
|
10012
|
+
to { opacity: 1; transform: translateY(0); }
|
|
10013
|
+
}
|
|
10011
10014
|
body {
|
|
10015
|
+
animation: fadeIn 0.4s ease-out;
|
|
10012
10016
|
background: #ffffff;
|
|
10013
10017
|
color: #111827;
|
|
10014
|
-
font-family:
|
|
10018
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
|
|
10015
10019
|
min-height: 100vh;
|
|
10016
10020
|
display: flex;
|
|
10017
10021
|
flex-direction: column;
|
|
@@ -10020,22 +10024,33 @@ rootRouter.get("/", (c) => {
|
|
|
10020
10024
|
gap: 0.75rem;
|
|
10021
10025
|
}
|
|
10022
10026
|
h1 {
|
|
10023
|
-
font-
|
|
10024
|
-
font-
|
|
10025
|
-
|
|
10026
|
-
|
|
10027
|
-
color: #0066cc;
|
|
10027
|
+
font-size: 2.5rem;
|
|
10028
|
+
font-weight: 800;
|
|
10029
|
+
letter-spacing: 0.2em;
|
|
10030
|
+
color: #0f172a;
|
|
10028
10031
|
}
|
|
10029
10032
|
h2 {
|
|
10030
|
-
font-family: 'Inter', sans-serif;
|
|
10031
10033
|
font-size: 0.9rem;
|
|
10032
10034
|
font-weight: 500;
|
|
10033
10035
|
letter-spacing: 0.3em;
|
|
10034
10036
|
color: #6b7280;
|
|
10035
10037
|
text-transform: uppercase;
|
|
10036
10038
|
}
|
|
10039
|
+
.tagline {
|
|
10040
|
+
font-size: 0.85rem;
|
|
10041
|
+
font-weight: 400;
|
|
10042
|
+
letter-spacing: 0.2em;
|
|
10043
|
+
color: #9ca3af;
|
|
10044
|
+
text-transform: lowercase;
|
|
10045
|
+
font-style: italic;
|
|
10046
|
+
}
|
|
10047
|
+
hr {
|
|
10048
|
+
width: 4rem;
|
|
10049
|
+
border: none;
|
|
10050
|
+
border-top: 2px solid #e5e7eb;
|
|
10051
|
+
margin: 1rem 0;
|
|
10052
|
+
}
|
|
10037
10053
|
.meta {
|
|
10038
|
-
margin-top: 1.5rem;
|
|
10039
10054
|
font-size: 0.8rem;
|
|
10040
10055
|
color: #9ca3af;
|
|
10041
10056
|
display: flex;
|
|
@@ -10043,22 +10058,49 @@ rootRouter.get("/", (c) => {
|
|
|
10043
10058
|
align-items: center;
|
|
10044
10059
|
gap: 0.25rem;
|
|
10045
10060
|
}
|
|
10046
|
-
|
|
10061
|
+
nav {
|
|
10062
|
+
display: flex;
|
|
10063
|
+
gap: 1.5rem;
|
|
10064
|
+
margin-top: 0.5rem;
|
|
10065
|
+
}
|
|
10066
|
+
nav a {
|
|
10047
10067
|
color: #0066cc;
|
|
10048
10068
|
text-decoration: none;
|
|
10049
|
-
font-size: 0.
|
|
10069
|
+
font-size: 0.85rem;
|
|
10070
|
+
padding: 0.4rem 0.75rem;
|
|
10071
|
+
border: 1px solid #e5e7eb;
|
|
10072
|
+
border-radius: 0.375rem;
|
|
10073
|
+
transition: background 0.15s, border-color 0.15s;
|
|
10074
|
+
}
|
|
10075
|
+
nav a:hover {
|
|
10076
|
+
background: #f3f4f6;
|
|
10077
|
+
border-color: #0066cc;
|
|
10078
|
+
}
|
|
10079
|
+
@media (prefers-color-scheme: dark) {
|
|
10080
|
+
body { background: #111827; color: #f3f4f6; }
|
|
10081
|
+
h1 { color: #e2e8f0; }
|
|
10082
|
+
h2 { color: #9ca3af; }
|
|
10083
|
+
.tagline { color: #6b7280; }
|
|
10084
|
+
hr { border-top-color: #374151; }
|
|
10085
|
+
.meta { color: #6b7280; }
|
|
10086
|
+
nav a { color: #60a5fa; border-color: #374151; }
|
|
10087
|
+
nav a:hover { background: #1f2937; border-color: #60a5fa; }
|
|
10050
10088
|
}
|
|
10051
|
-
a:hover { text-decoration: underline; }
|
|
10052
10089
|
</style>
|
|
10053
10090
|
</head>
|
|
10054
10091
|
<body>
|
|
10055
10092
|
<h1>SEMIONT</h1>
|
|
10056
10093
|
<h2>knowledge base</h2>
|
|
10094
|
+
<p class="tagline">make meaning</p>
|
|
10095
|
+
<hr>
|
|
10057
10096
|
<div class="meta">
|
|
10058
10097
|
${siteName ? `<span>${siteName}</span>` : ""}
|
|
10059
10098
|
${projectName ? `<span>${projectName}${projectVersion ? " v" + projectVersion : ""}</span>` : ""}
|
|
10060
|
-
<a href="/api/health">/api/health</a>
|
|
10061
10099
|
</div>
|
|
10100
|
+
<nav>
|
|
10101
|
+
<a href="/api/docs">API Docs</a>
|
|
10102
|
+
<a href="/api/health">Health</a>
|
|
10103
|
+
</nav>
|
|
10062
10104
|
</body>
|
|
10063
10105
|
</html>`;
|
|
10064
10106
|
return c.html(html);
|
|
@@ -13062,6 +13104,39 @@ var openapi_default = {
|
|
|
13062
13104
|
}
|
|
13063
13105
|
}
|
|
13064
13106
|
},
|
|
13107
|
+
SemanticMatch: {
|
|
13108
|
+
type: "object",
|
|
13109
|
+
properties: {
|
|
13110
|
+
text: {
|
|
13111
|
+
type: "string",
|
|
13112
|
+
description: "The chunk text that matched"
|
|
13113
|
+
},
|
|
13114
|
+
resourceId: {
|
|
13115
|
+
type: "string",
|
|
13116
|
+
description: "Source resource ID"
|
|
13117
|
+
},
|
|
13118
|
+
annotationId: {
|
|
13119
|
+
type: "string",
|
|
13120
|
+
description: "Source annotation ID, if the match is from an annotation"
|
|
13121
|
+
},
|
|
13122
|
+
score: {
|
|
13123
|
+
type: "number",
|
|
13124
|
+
description: "Cosine similarity score (0-1)"
|
|
13125
|
+
},
|
|
13126
|
+
entityTypes: {
|
|
13127
|
+
type: "array",
|
|
13128
|
+
items: {
|
|
13129
|
+
type: "string"
|
|
13130
|
+
},
|
|
13131
|
+
description: "Entity types on the matched passage"
|
|
13132
|
+
}
|
|
13133
|
+
},
|
|
13134
|
+
required: [
|
|
13135
|
+
"text",
|
|
13136
|
+
"resourceId",
|
|
13137
|
+
"score"
|
|
13138
|
+
]
|
|
13139
|
+
},
|
|
13065
13140
|
ResourceLLMContextResponse: {
|
|
13066
13141
|
type: "object",
|
|
13067
13142
|
properties: {
|
|
@@ -13750,6 +13825,22 @@ var openapi_default = {
|
|
|
13750
13825
|
description: "LLM-generated summary of the annotation's relationships in the knowledge graph"
|
|
13751
13826
|
}
|
|
13752
13827
|
}
|
|
13828
|
+
},
|
|
13829
|
+
semanticContext: {
|
|
13830
|
+
type: "object",
|
|
13831
|
+
description: "Semantically similar passages from across the knowledge base, found via vector search",
|
|
13832
|
+
properties: {
|
|
13833
|
+
similar: {
|
|
13834
|
+
type: "array",
|
|
13835
|
+
items: {
|
|
13836
|
+
$ref: "#/components/schemas/SemanticMatch"
|
|
13837
|
+
},
|
|
13838
|
+
description: "Passages ranked by cosine similarity to the focal text"
|
|
13839
|
+
}
|
|
13840
|
+
},
|
|
13841
|
+
required: [
|
|
13842
|
+
"similar"
|
|
13843
|
+
]
|
|
13753
13844
|
}
|
|
13754
13845
|
},
|
|
13755
13846
|
required: [
|
|
@@ -14003,10 +14094,10 @@ var OAuthService = class {
|
|
|
14003
14094
|
}
|
|
14004
14095
|
return user;
|
|
14005
14096
|
}
|
|
14006
|
-
static async acceptTerms(
|
|
14097
|
+
static async acceptTerms(userId15) {
|
|
14007
14098
|
const prisma2 = DatabaseConnection.getClient();
|
|
14008
14099
|
const user = await prisma2.user.update({
|
|
14009
|
-
where: { id:
|
|
14100
|
+
where: { id: userId15 },
|
|
14010
14101
|
data: {
|
|
14011
14102
|
termsAcceptedAt: /* @__PURE__ */ new Date()
|
|
14012
14103
|
}
|
|
@@ -14023,10 +14114,10 @@ var authMiddleware = async (c, next) => {
|
|
|
14023
14114
|
if (c.req.method === "GET") {
|
|
14024
14115
|
const mediaTokenParam = c.req.query("token");
|
|
14025
14116
|
const match = c.req.path.match(MEDIA_TOKEN_PATH);
|
|
14026
|
-
const
|
|
14027
|
-
if (mediaTokenParam &&
|
|
14117
|
+
const resourceId22 = match?.[1];
|
|
14118
|
+
if (mediaTokenParam && resourceId22) {
|
|
14028
14119
|
try {
|
|
14029
|
-
JWTService.verifyMediaToken(mediaTokenParam,
|
|
14120
|
+
JWTService.verifyMediaToken(mediaTokenParam, resourceId22);
|
|
14030
14121
|
c.set("token", mediaTokenParam);
|
|
14031
14122
|
await next();
|
|
14032
14123
|
return;
|
|
@@ -14947,7 +15038,7 @@ function registerCreateResource(router) {
|
|
|
14947
15038
|
const arrayBuffer = await file.arrayBuffer();
|
|
14948
15039
|
const contentBuffer = Buffer.from(arrayBuffer);
|
|
14949
15040
|
const eventBus2 = c.get("eventBus");
|
|
14950
|
-
const
|
|
15041
|
+
const resourceId22 = await ResourceOperations.createResource(
|
|
14951
15042
|
{
|
|
14952
15043
|
name,
|
|
14953
15044
|
content: contentBuffer,
|
|
@@ -14960,7 +15051,7 @@ function registerCreateResource(router) {
|
|
|
14960
15051
|
userId(userToDid(user)),
|
|
14961
15052
|
eventBus2
|
|
14962
15053
|
);
|
|
14963
|
-
return c.json({ resourceId:
|
|
15054
|
+
return c.json({ resourceId: resourceId22 }, 202);
|
|
14964
15055
|
});
|
|
14965
15056
|
}
|
|
14966
15057
|
var SSE_STREAM_CONNECTED = "stream-connected";
|
|
@@ -16724,7 +16815,7 @@ function registerGetEvents(router) {
|
|
|
16724
16815
|
const queryParams = c.req.query();
|
|
16725
16816
|
const eventBus2 = c.get("eventBus");
|
|
16726
16817
|
const type = queryParams.type;
|
|
16727
|
-
const
|
|
16818
|
+
const userId15 = queryParams.userId;
|
|
16728
16819
|
const limit = queryParams.limit ? Number(queryParams.limit) : 100;
|
|
16729
16820
|
if (type && !isValidEventType(type)) {
|
|
16730
16821
|
throw new HTTPException(400, { message: `Invalid event type. Must be one of: ${eventTypes.join(", ")}` });
|
|
@@ -16737,7 +16828,7 @@ function registerGetEvents(router) {
|
|
|
16737
16828
|
const response = await eventBusRequest(
|
|
16738
16829
|
eventBus2,
|
|
16739
16830
|
"browse:events-requested",
|
|
16740
|
-
{ correlationId, resourceId: resourceId(id), type, userId:
|
|
16831
|
+
{ correlationId, resourceId: resourceId(id), type, userId: userId15, limit },
|
|
16741
16832
|
"browse:events-result",
|
|
16742
16833
|
"browse:events-failed"
|
|
16743
16834
|
);
|
|
@@ -16961,6 +17052,102 @@ function registerUpdateAnnotationBody(router) {
|
|
|
16961
17052
|
);
|
|
16962
17053
|
}
|
|
16963
17054
|
init_logger();
|
|
17055
|
+
var BIND_TIMEOUT_MS = 1e4;
|
|
17056
|
+
function registerBindAnnotationStream(router) {
|
|
17057
|
+
router.post(
|
|
17058
|
+
"/resources/:resourceId/annotations/:annotationId/bind-stream",
|
|
17059
|
+
validateRequestBody("BindAnnotationStreamRequest"),
|
|
17060
|
+
async (c) => {
|
|
17061
|
+
const { resourceId: resourceIdParam, annotationId: annotationIdParam } = c.req.param();
|
|
17062
|
+
const request = c.get("validatedBody");
|
|
17063
|
+
const user = c.get("user");
|
|
17064
|
+
if (!user) {
|
|
17065
|
+
throw new HTTPException(401, { message: "Authentication required" });
|
|
17066
|
+
}
|
|
17067
|
+
const eventBus2 = c.get("eventBus");
|
|
17068
|
+
const { knowledgeSystem: { kb: { eventStore } } } = c.get("makeMeaning");
|
|
17069
|
+
const logger2 = getLogger().child({
|
|
17070
|
+
component: "bind-annotation-stream",
|
|
17071
|
+
resourceId: resourceIdParam,
|
|
17072
|
+
annotationId: annotationIdParam
|
|
17073
|
+
});
|
|
17074
|
+
logger2.info("Starting bind stream", { operationCount: request.operations.length });
|
|
17075
|
+
const rId = resourceId(resourceIdParam);
|
|
17076
|
+
const aid = annotationId(annotationIdParam);
|
|
17077
|
+
return streamSSE(c, async (stream) => {
|
|
17078
|
+
let isStreamClosed = false;
|
|
17079
|
+
let closeStreamCallback = null;
|
|
17080
|
+
let timeoutHandle = null;
|
|
17081
|
+
let subscription = null;
|
|
17082
|
+
const streamPromise = new Promise((resolve) => {
|
|
17083
|
+
closeStreamCallback = resolve;
|
|
17084
|
+
});
|
|
17085
|
+
const cleanup = () => {
|
|
17086
|
+
if (isStreamClosed) return;
|
|
17087
|
+
isStreamClosed = true;
|
|
17088
|
+
if (timeoutHandle) clearTimeout(timeoutHandle);
|
|
17089
|
+
if (subscription) subscription.unsubscribe();
|
|
17090
|
+
if (closeStreamCallback) closeStreamCallback();
|
|
17091
|
+
};
|
|
17092
|
+
try {
|
|
17093
|
+
subscription = eventStore.bus.subscriptions.subscribe(rId, async (storedEvent) => {
|
|
17094
|
+
if (isStreamClosed) return;
|
|
17095
|
+
if (storedEvent.event.type !== "annotation.body.updated") return;
|
|
17096
|
+
if (storedEvent.event.payload?.annotationId !== annotationIdParam) return;
|
|
17097
|
+
logger2.info("Bind completed", { annotationId: annotationIdParam });
|
|
17098
|
+
try {
|
|
17099
|
+
await stream.writeSSE({
|
|
17100
|
+
data: JSON.stringify({ annotationId: String(aid) }),
|
|
17101
|
+
event: "bind:finished",
|
|
17102
|
+
id: String(Date.now())
|
|
17103
|
+
});
|
|
17104
|
+
} catch {
|
|
17105
|
+
logger2.warn("Client disconnected before bind:finished");
|
|
17106
|
+
}
|
|
17107
|
+
cleanup();
|
|
17108
|
+
});
|
|
17109
|
+
timeoutHandle = setTimeout(async () => {
|
|
17110
|
+
if (isStreamClosed) return;
|
|
17111
|
+
logger2.warn("Bind timed out", { timeoutMs: BIND_TIMEOUT_MS });
|
|
17112
|
+
try {
|
|
17113
|
+
await stream.writeSSE({
|
|
17114
|
+
data: JSON.stringify({ error: "Bind operation timed out" }),
|
|
17115
|
+
event: "bind:failed",
|
|
17116
|
+
id: String(Date.now())
|
|
17117
|
+
});
|
|
17118
|
+
} catch {
|
|
17119
|
+
}
|
|
17120
|
+
cleanup();
|
|
17121
|
+
}, BIND_TIMEOUT_MS);
|
|
17122
|
+
c.req.raw.signal.addEventListener("abort", () => {
|
|
17123
|
+
logger2.info("Client disconnected from bind stream");
|
|
17124
|
+
cleanup();
|
|
17125
|
+
});
|
|
17126
|
+
eventBus2.get("mark:update-body").next({
|
|
17127
|
+
annotationId: aid,
|
|
17128
|
+
resourceId: rId,
|
|
17129
|
+
userId: userId(userToDid(user)),
|
|
17130
|
+
operations: request.operations
|
|
17131
|
+
});
|
|
17132
|
+
logger2.info("Emitted mark:update-body");
|
|
17133
|
+
} catch (error) {
|
|
17134
|
+
logger2.error("Bind stream error", { error: error instanceof Error ? error.message : String(error) });
|
|
17135
|
+
try {
|
|
17136
|
+
await stream.writeSSE({
|
|
17137
|
+
data: JSON.stringify({ error: error instanceof Error ? error.message : "Bind failed" }),
|
|
17138
|
+
event: "bind:failed",
|
|
17139
|
+
id: String(Date.now())
|
|
17140
|
+
});
|
|
17141
|
+
} catch {
|
|
17142
|
+
}
|
|
17143
|
+
cleanup();
|
|
17144
|
+
}
|
|
17145
|
+
return streamPromise;
|
|
17146
|
+
});
|
|
17147
|
+
}
|
|
17148
|
+
);
|
|
17149
|
+
}
|
|
17150
|
+
init_logger();
|
|
16964
17151
|
function registerYieldResourceStream(router, jobQueue) {
|
|
16965
17152
|
router.post(
|
|
16966
17153
|
"/resources/:resourceId/annotations/:annotationId/yield-resource-stream",
|
|
@@ -17276,14 +17463,14 @@ function registerGatherAnnotationStream(router) {
|
|
|
17276
17463
|
}
|
|
17277
17464
|
function registerGetAnnotationHistory(router) {
|
|
17278
17465
|
router.get("/resources/:resourceId/annotations/:annotationId/history", async (c) => {
|
|
17279
|
-
const { resourceId:
|
|
17466
|
+
const { resourceId: resourceId22, annotationId: annotationId8 } = c.req.param();
|
|
17280
17467
|
const eventBus2 = c.get("eventBus");
|
|
17281
17468
|
const correlationId = crypto.randomUUID();
|
|
17282
17469
|
try {
|
|
17283
17470
|
const response = await eventBusRequest(
|
|
17284
17471
|
eventBus2,
|
|
17285
17472
|
"browse:annotation-history-requested",
|
|
17286
|
-
{ correlationId, resourceId: resourceId(
|
|
17473
|
+
{ correlationId, resourceId: resourceId(resourceId22), annotationId: annotationId(annotationId8) },
|
|
17287
17474
|
"browse:annotation-history-result",
|
|
17288
17475
|
"browse:annotation-history-failed"
|
|
17289
17476
|
);
|
|
@@ -17322,6 +17509,7 @@ function createResourcesRouter(jobQueue) {
|
|
|
17322
17509
|
registerCreateAnnotation(resourcesRouter2);
|
|
17323
17510
|
registerGetAnnotation(resourcesRouter2);
|
|
17324
17511
|
registerUpdateAnnotationBody(resourcesRouter2);
|
|
17512
|
+
registerBindAnnotationStream(resourcesRouter2);
|
|
17325
17513
|
registerYieldResourceStream(resourcesRouter2, jobQueue);
|
|
17326
17514
|
registerGatherAnnotationStream(resourcesRouter2);
|
|
17327
17515
|
registerGetAnnotationHistory(resourcesRouter2);
|
|
@@ -17372,8 +17560,8 @@ operationsRouter.get("/api/annotations/:id/context", async (c) => {
|
|
|
17372
17560
|
const { id } = c.req.param();
|
|
17373
17561
|
const query = c.req.query();
|
|
17374
17562
|
const { knowledgeSystem: { kb } } = c.get("makeMeaning");
|
|
17375
|
-
const
|
|
17376
|
-
if (!
|
|
17563
|
+
const resourceId22 = query.resourceId;
|
|
17564
|
+
if (!resourceId22) {
|
|
17377
17565
|
throw new HTTPException(400, { message: "resourceId query parameter is required" });
|
|
17378
17566
|
}
|
|
17379
17567
|
const contextBefore = query.contextBefore ? Number(query.contextBefore) : 100;
|
|
@@ -17387,7 +17575,7 @@ operationsRouter.get("/api/annotations/:id/context", async (c) => {
|
|
|
17387
17575
|
try {
|
|
17388
17576
|
const response = await AnnotationContext.getAnnotationContext(
|
|
17389
17577
|
annotationId(id),
|
|
17390
|
-
resourceId(
|
|
17578
|
+
resourceId(resourceId22),
|
|
17391
17579
|
contextBefore,
|
|
17392
17580
|
contextAfter,
|
|
17393
17581
|
kb
|
|
@@ -17413,14 +17601,14 @@ operationsRouter.get("/api/annotations/:id/summary", async (c) => {
|
|
|
17413
17601
|
const { id } = c.req.param();
|
|
17414
17602
|
const query = c.req.query();
|
|
17415
17603
|
const { knowledgeSystem: { gatherer } } = c.get("makeMeaning");
|
|
17416
|
-
const
|
|
17417
|
-
if (!
|
|
17604
|
+
const resourceId22 = query.resourceId;
|
|
17605
|
+
if (!resourceId22) {
|
|
17418
17606
|
throw new HTTPException(400, { message: "resourceId query parameter is required" });
|
|
17419
17607
|
}
|
|
17420
17608
|
try {
|
|
17421
17609
|
const response = await gatherer.generateAnnotationSummary(
|
|
17422
17610
|
annotationId(id),
|
|
17423
|
-
resourceId(
|
|
17611
|
+
resourceId(resourceId22)
|
|
17424
17612
|
);
|
|
17425
17613
|
return c.json(response);
|
|
17426
17614
|
} catch (error) {
|