@konneal/engine 0.2.81 → 0.2.82
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/{ask-M2JPJFEM.js → ask-QLY2CODU.js} +1 -1
- package/dist/{chunk-YWMM5XTC.js → chunk-DH3WDTZX.js} +4 -7
- package/dist/pipeline.d.ts +1 -1
- package/dist/worker_public/src/index.js +2 -2
- package/package.json +1 -1
- package/workers/worker_public/src/ask.ts +11 -8
- package/workers/worker_public/src/pipeline.ts +4 -1
|
@@ -2906,16 +2906,13 @@ ${q.query}`.replace("\n\n\n\n", "\n\n") }];
|
|
|
2906
2906
|
const wantsMarkings = /\b(mark(ing|ings)?|nameplate|label|inscription|engrav|sticker|plate)\b|certificat/i.test(q.query);
|
|
2907
2907
|
const last = messages[messages.length - 1];
|
|
2908
2908
|
const note = wantsMarkings ? "\n\n(The user attached a photo with this question. First transcribe every inscription you can actually read in the image \u2014 names, model references, accuracy classes, numeric values with their units, certificate or approval numbers \u2014 quoting them verbatim. Then answer the question from the numbered passages, citing the requirement each interpretation rests on. If an inscription is unreadable, say so; never invent a marking.)" : "\n\n(The user attached an image with this question; interpret it directly when answering.)";
|
|
2909
|
-
if (
|
|
2909
|
+
if (typeof last.content === "string") {
|
|
2910
|
+
last.content = last.content + note;
|
|
2911
|
+
} else {
|
|
2910
2912
|
const textPart = last.content.find((p) => p.type === "text");
|
|
2911
2913
|
if (textPart) textPart.text += note;
|
|
2912
|
-
last.content = [...last.content, { type: "image_url", image_url: { url: withImage } }];
|
|
2913
|
-
} else {
|
|
2914
|
-
last.content = [
|
|
2915
|
-
{ type: "text", text: last.content + note },
|
|
2916
|
-
{ type: "image_url", image_url: { url: withImage } }
|
|
2917
|
-
];
|
|
2918
2914
|
}
|
|
2915
|
+
messages.push({ role: "user", content: [{ type: "image_url", image_url: { url: withImage } }] });
|
|
2919
2916
|
console.log("user image attached to generation");
|
|
2920
2917
|
}
|
|
2921
2918
|
const queryHash = await sha256Hex(q.query);
|
package/dist/pipeline.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
modelGroundingBlock,
|
|
7
7
|
scoreFaithfulness,
|
|
8
8
|
scoreJudge
|
|
9
|
-
} from "../../chunk-
|
|
9
|
+
} from "../../chunk-DH3WDTZX.js";
|
|
10
10
|
import {
|
|
11
11
|
handleSearch
|
|
12
12
|
} from "../../chunk-KO6DRI7C.js";
|
|
@@ -959,7 +959,7 @@ async function handleMcp(env, ctx, req, tier, key) {
|
|
|
959
959
|
// stream:false forces the JSON lane (anon defaults to SSE)
|
|
960
960
|
body: JSON.stringify({ ...args, stream: false })
|
|
961
961
|
});
|
|
962
|
-
const res = name === "ask" ? await (await import("../../ask-
|
|
962
|
+
const res = name === "ask" ? await (await import("../../ask-QLY2CODU.js")).handleAsk(env, ctx, inner, tier, key) : await (await import("../../search-LVUQLA3C.js")).handleSearch(env, ctx, inner, tier, key);
|
|
963
963
|
return res.json().catch(() => ({ error: { message: "tool transport failed", status: res.status } }));
|
|
964
964
|
});
|
|
965
965
|
if (out.ok && "accepted" in out) return new Response(null, { status: 202 });
|
package/package.json
CHANGED
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"playwright": "^1.62.1",
|
|
28
28
|
"yaml": "^2.9.1"
|
|
29
29
|
},
|
|
30
|
-
"version": "0.2.
|
|
30
|
+
"version": "0.2.82",
|
|
31
31
|
"description": "The Konneal engine: the publisher-agnostic build pipeline and API plane for standards intelligence (retrieval, answer contract, verdicts, evaluation).",
|
|
32
32
|
"license": "BSD-3-Clause",
|
|
33
33
|
"type": "module",
|
|
@@ -85,7 +85,7 @@ function embedWarm(env: Env, text: string): Promise<number[] | null> {
|
|
|
85
85
|
* AI 8005s that scale with payload size), and only the ONE pinned
|
|
86
86
|
* figure attaches (the type-intent pin already chose the answering
|
|
87
87
|
* object; a second base64 blob doubles the flake surface for nothing). */
|
|
88
|
-
async function attachFigureImages(env: Env, messages: { role: string; content:
|
|
88
|
+
async function attachFigureImages(env: Env, messages: { role: string; content: any }[], usedHits: Hit[], query: string): Promise<void> {
|
|
89
89
|
// Attach only when the question WANTS the drawing (names a figure-ish
|
|
90
90
|
// artifact) or the pinned figure sits in the top prose passage's own
|
|
91
91
|
// clause (it IS the answering object) — a plain definition question
|
|
@@ -1264,16 +1264,19 @@ let convEntities: Array<{ entity: string; kind: string }> = [];
|
|
|
1264
1264
|
? "\n\n(The user attached a photo with this question. First transcribe every inscription you can actually read in the image — names, model references, accuracy classes, numeric values with their units, certificate or approval numbers — quoting them verbatim. Then answer the question from the numbered passages, citing the requirement each interpretation rests on. If an inscription is unreadable, say so; never invent a marking.)"
|
|
1265
1265
|
: "\n\n(The user attached an image with this question; interpret it directly when answering.)";
|
|
1266
1266
|
|
|
1267
|
-
|
|
1267
|
+
// the image rides its OWN SHORT TRAILING MESSAGE — never inside the
|
|
1268
|
+
// passage-bearing user message. Long text + image parts in ONE message
|
|
1269
|
+
// is the documented instability shape (2026-09-09); it was reintroduced
|
|
1270
|
+
// here, and the live "blindness" on photo answers (2026-10-03) was this
|
|
1271
|
+
// violation, not the model: the probe and extraction calls, which keep
|
|
1272
|
+
// the image on its own message, read the same plate every time.
|
|
1273
|
+
if (typeof last.content === "string") {
|
|
1274
|
+
last.content = last.content + note;
|
|
1275
|
+
} else {
|
|
1268
1276
|
const textPart = last.content.find((p: any) => p.type === "text");
|
|
1269
1277
|
if (textPart) textPart.text += note;
|
|
1270
|
-
last.content = [...last.content, { type: "image_url", image_url: { url: withImage } }] as unknown as string;
|
|
1271
|
-
} else {
|
|
1272
|
-
last.content = [
|
|
1273
|
-
{ type: "text", text: last.content + note },
|
|
1274
|
-
{ type: "image_url", image_url: { url: withImage } },
|
|
1275
|
-
] as unknown as string;
|
|
1276
1278
|
}
|
|
1279
|
+
messages.push({ role: "user", content: [{ type: "image_url", image_url: { url: withImage } }] });
|
|
1277
1280
|
console.log("user image attached to generation");
|
|
1278
1281
|
}
|
|
1279
1282
|
const queryHash = await sha256Hex(q.query);
|
|
@@ -180,7 +180,10 @@ function clipToTokens(s: string, maxTok: number): string {
|
|
|
180
180
|
}
|
|
181
181
|
|
|
182
182
|
export interface BuiltMessages {
|
|
183
|
-
|
|
183
|
+
// content is string OR an OpenAI-style parts array — the image parts
|
|
184
|
+
// ride their OWN trailing user message (never inside a passage-bearing
|
|
185
|
+
// one), so the type admits both shapes
|
|
186
|
+
messages: { role: string; content: string | any[] }[];
|
|
184
187
|
usedHits: Hit[]; // passages actually included (citations must match these)
|
|
185
188
|
}
|
|
186
189
|
|