@semiont/jobs 0.6.8 → 0.6.10
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/README.md +16 -16
- package/dist/index.d.ts +146 -153
- package/dist/index.js +47 -79
- package/dist/index.js.map +1 -1
- package/dist/worker-main.js +106 -149
- package/dist/worker-main.js.map +1 -1
- package/package.json +8 -8
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { replyChannelsFor, deriveViews, GENERATABLE_MEDIA_TYPES, estimateTokens, isObject, isString, reconcileSelector, getLocaleEnglishName, isResourceId, busRequest, BusRequestError, cutChunk, chunkText } from '@semiont/core';
|
|
2
2
|
import { withSpan, recordAnchorOutcome, recordDetectionCall } from '@semiont/observability';
|
|
3
3
|
import { StructuredReadError } from '@semiont/inference';
|
|
4
4
|
import { execFileSync } from 'child_process';
|
|
@@ -3764,9 +3764,9 @@ var require_mapOneOrManyArgs = __commonJS({
|
|
|
3764
3764
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3765
3765
|
exports.mapOneOrManyArgs = void 0;
|
|
3766
3766
|
var map_1 = require_map();
|
|
3767
|
-
var
|
|
3767
|
+
var isArray = Array.isArray;
|
|
3768
3768
|
function callOrApply(fn, args) {
|
|
3769
|
-
return
|
|
3769
|
+
return isArray(args) ? fn.apply(void 0, __spreadArray([], __read(args))) : fn(args);
|
|
3770
3770
|
}
|
|
3771
3771
|
function mapOneOrManyArgs(fn) {
|
|
3772
3772
|
return map_1.map(function(args) {
|
|
@@ -3911,14 +3911,14 @@ var require_argsArgArrayOrObject = __commonJS({
|
|
|
3911
3911
|
"../../node_modules/rxjs/dist/cjs/internal/util/argsArgArrayOrObject.js"(exports) {
|
|
3912
3912
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3913
3913
|
exports.argsArgArrayOrObject = void 0;
|
|
3914
|
-
var
|
|
3914
|
+
var isArray = Array.isArray;
|
|
3915
3915
|
var getPrototypeOf = Object.getPrototypeOf;
|
|
3916
3916
|
var objectProto = Object.prototype;
|
|
3917
3917
|
var getKeys = Object.keys;
|
|
3918
3918
|
function argsArgArrayOrObject(args) {
|
|
3919
3919
|
if (args.length === 1) {
|
|
3920
3920
|
var first_1 = args[0];
|
|
3921
|
-
if (
|
|
3921
|
+
if (isArray(first_1)) {
|
|
3922
3922
|
return { args: first_1, keys: null };
|
|
3923
3923
|
}
|
|
3924
3924
|
if (isPOJO(first_1)) {
|
|
@@ -4666,9 +4666,9 @@ var require_argsOrArgArray = __commonJS({
|
|
|
4666
4666
|
"../../node_modules/rxjs/dist/cjs/internal/util/argsOrArgArray.js"(exports) {
|
|
4667
4667
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4668
4668
|
exports.argsOrArgArray = void 0;
|
|
4669
|
-
var
|
|
4669
|
+
var isArray = Array.isArray;
|
|
4670
4670
|
function argsOrArgArray(args) {
|
|
4671
|
-
return args.length === 1 &&
|
|
4671
|
+
return args.length === 1 && isArray(args[0]) ? args[0] : args;
|
|
4672
4672
|
}
|
|
4673
4673
|
exports.argsOrArgArray = argsOrArgArray;
|
|
4674
4674
|
}
|
|
@@ -9203,7 +9203,8 @@ var require_cjs = __commonJS({
|
|
|
9203
9203
|
} });
|
|
9204
9204
|
}
|
|
9205
9205
|
});
|
|
9206
|
-
|
|
9206
|
+
|
|
9207
|
+
// src/types.ts
|
|
9207
9208
|
function isPendingJob(job) {
|
|
9208
9209
|
return job.status === "pending";
|
|
9209
9210
|
}
|
|
@@ -9759,7 +9760,8 @@ Example format:
|
|
|
9759
9760
|
/**
|
|
9760
9761
|
* Build a prompt for detecting structural tags
|
|
9761
9762
|
*
|
|
9762
|
-
* @param content - The
|
|
9763
|
+
* @param content - The text content to analyze — a chunk sized by the
|
|
9764
|
+
* caller from derived provider limits; NEVER re-truncated here
|
|
9763
9765
|
* @param category - The specific category to detect
|
|
9764
9766
|
* @param schemaName - Human-readable schema name
|
|
9765
9767
|
* @param schemaDescription - Schema description
|
|
@@ -10187,7 +10189,7 @@ ${piece}
|
|
|
10187
10189
|
}
|
|
10188
10190
|
if (items.length * YIELD_COLLAPSE_BAND < counted) {
|
|
10189
10191
|
throw new YieldCollapseError(
|
|
10190
|
-
`Extraction found ${items.length} entities where a count call reports ~${counted} mentions (band \xD7${YIELD_COLLAPSE_BAND}) on a ${piece.length}-char chunk \u2014 silent yield collapse
|
|
10192
|
+
`Extraction found ${items.length} entities where a count call reports ~${counted} mentions (band \xD7${YIELD_COLLAPSE_BAND}) on a ${piece.length}-char chunk \u2014 silent yield collapse: deterministic \u2014 a same-size retry returns the identical under-report.`,
|
|
10191
10193
|
[...items],
|
|
10192
10194
|
{ found: items.length, counted, pieceChars: piece.length }
|
|
10193
10195
|
);
|
|
@@ -10562,8 +10564,6 @@ function compileTypst(source) {
|
|
|
10562
10564
|
rmSync(dir, { recursive: true, force: true });
|
|
10563
10565
|
}
|
|
10564
10566
|
}
|
|
10565
|
-
|
|
10566
|
-
// src/workers/generation/citation-resolver.ts
|
|
10567
10567
|
var CITATION_TOKEN = /\[\[([^\s[\]/]+)(?:\/([^\s[\]/]+))?\]\]/g;
|
|
10568
10568
|
function collectContextResourceIds(context) {
|
|
10569
10569
|
const ids = /* @__PURE__ */ new Set();
|
|
@@ -10589,7 +10589,7 @@ function resolveCitationTokens(content, validResourceIds, logger) {
|
|
|
10589
10589
|
const annotationId = match[2];
|
|
10590
10590
|
clean += content.slice(last, match.index).replace(/[ \t]+$/, "");
|
|
10591
10591
|
last = match.index + token.length;
|
|
10592
|
-
if (!validResourceIds.has(citedResourceId)) {
|
|
10592
|
+
if (!isResourceId(citedResourceId) || !validResourceIds.has(citedResourceId)) {
|
|
10593
10593
|
logger.warn("Citation token references an id absent from the provided context \u2014 dropped", {
|
|
10594
10594
|
resourceId: citedResourceId
|
|
10595
10595
|
});
|
|
@@ -10738,9 +10738,8 @@ async function processCommentJob(content, inferenceClient, params, buildAnnotati
|
|
|
10738
10738
|
found += comments.length;
|
|
10739
10739
|
const fresh = dedupe(comments.map(
|
|
10740
10740
|
(c) => (
|
|
10741
|
-
//
|
|
10742
|
-
//
|
|
10743
|
-
// consumers that do language-aware rendering rely on them.
|
|
10741
|
+
// Format and language go on the body TextualBody: optional in the
|
|
10742
|
+
// schema, but consumers that do language-aware rendering rely on them.
|
|
10744
10743
|
buildAnnotation("commenting", c, [
|
|
10745
10744
|
{ type: "TextualBody", value: c.comment, purpose: "commenting", format: "text/plain", language: bodyLanguage }
|
|
10746
10745
|
])
|
|
@@ -10781,8 +10780,7 @@ async function processAssessmentJob(content, inferenceClient, params, buildAnnot
|
|
|
10781
10780
|
const fresh = dedupe(assessments.map(
|
|
10782
10781
|
(a) => (
|
|
10783
10782
|
// Single-object body with purpose aligned to motivation, matching the
|
|
10784
|
-
//
|
|
10785
|
-
// persisted assessments. Do not switch to an array or to
|
|
10783
|
+
// majority of persisted assessments. Do not switch to an array or to
|
|
10786
10784
|
// purpose='describing' — that loses the "this is an assessment, not
|
|
10787
10785
|
// a description" signal and breaks existing readers that access
|
|
10788
10786
|
// `body.value` directly on the object.
|
|
@@ -10850,11 +10848,11 @@ async function processReferenceJob(content, inferenceClient, params, buildAnnota
|
|
|
10850
10848
|
params.includeDescriptiveReferences ?? false,
|
|
10851
10849
|
logger,
|
|
10852
10850
|
params.sourceLanguage,
|
|
10853
|
-
// Liveness heartbeat
|
|
10854
|
-
//
|
|
10855
|
-
//
|
|
10856
|
-
//
|
|
10857
|
-
//
|
|
10851
|
+
// Liveness heartbeat: fires at chunk boundaries and every ~15 s while a
|
|
10852
|
+
// call is in flight, so a long single-chunk call is not silent. It
|
|
10853
|
+
// repeats the current position rather than inventing an advance — the
|
|
10854
|
+
// stall watchdog, janitor and client timeout need a signal, not a
|
|
10855
|
+
// monotone.
|
|
10858
10856
|
() => emitTypeProgress(entityTypeName),
|
|
10859
10857
|
(verdict) => {
|
|
10860
10858
|
underReported = {
|
|
@@ -11011,7 +11009,7 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger)
|
|
|
11011
11009
|
`Unsupported outputMediaType for generation: ${outputMediaType}. Generation produces ${GENERATABLE_MEDIA_TYPES.join(" or ")}.`
|
|
11012
11010
|
);
|
|
11013
11011
|
}
|
|
11014
|
-
const title = params.title
|
|
11012
|
+
const title = params.title;
|
|
11015
11013
|
const entityTypes = (params.entityTypes ?? []).map(String);
|
|
11016
11014
|
if (outputMediaType === "application/pdf") {
|
|
11017
11015
|
onProgress(5, { code: "generating-resource" });
|
|
@@ -11091,12 +11089,7 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger)
|
|
|
11091
11089
|
title,
|
|
11092
11090
|
format: outputMediaType,
|
|
11093
11091
|
citations: citations2,
|
|
11094
|
-
|
|
11095
|
-
kind: "generation",
|
|
11096
|
-
resourceId: "",
|
|
11097
|
-
resourceName: title,
|
|
11098
|
-
truncated: generated2.truncated
|
|
11099
|
-
}
|
|
11092
|
+
truncated: generated2.truncated
|
|
11100
11093
|
};
|
|
11101
11094
|
}
|
|
11102
11095
|
onProgress(5, { code: "generating-resource" });
|
|
@@ -11132,30 +11125,12 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger)
|
|
|
11132
11125
|
title,
|
|
11133
11126
|
format: outputMediaType,
|
|
11134
11127
|
citations,
|
|
11135
|
-
|
|
11136
|
-
kind: "generation",
|
|
11137
|
-
resourceId: "",
|
|
11138
|
-
resourceName: title,
|
|
11139
|
-
truncated: generated.truncated
|
|
11140
|
-
}
|
|
11128
|
+
truncated: generated.truncated
|
|
11141
11129
|
};
|
|
11142
11130
|
}
|
|
11143
11131
|
|
|
11144
11132
|
// src/job-claim-adapter.ts
|
|
11145
11133
|
var import_rxjs = __toESM(require_cjs());
|
|
11146
|
-
function readUnitCursors(raw, completedUnits) {
|
|
11147
|
-
if (!isObject(raw)) return {};
|
|
11148
|
-
const done = new Set(completedUnits);
|
|
11149
|
-
const cursors = {};
|
|
11150
|
-
for (const [unit, value] of Object.entries(raw)) {
|
|
11151
|
-
if (done.has(unit) || !isObject(value)) continue;
|
|
11152
|
-
const { next, size, found, emitted } = value;
|
|
11153
|
-
if (!isNumber(next) || !isNumber(size) || next < 0 || size < 1) continue;
|
|
11154
|
-
if (!isNumber(found) || !isNumber(emitted) || found < 0 || emitted < 0) continue;
|
|
11155
|
-
cursors[unit] = { next, size, found, emitted };
|
|
11156
|
-
}
|
|
11157
|
-
return cursors;
|
|
11158
|
-
}
|
|
11159
11134
|
function createJobClaimAdapter(options) {
|
|
11160
11135
|
const { bus, jobTypes } = options;
|
|
11161
11136
|
const activeJob$ = new import_rxjs.BehaviorSubject(null);
|
|
@@ -11174,9 +11149,9 @@ function createJobClaimAdapter(options) {
|
|
|
11174
11149
|
let activeSince = null;
|
|
11175
11150
|
const iso = (t) => t === null ? null : new Date(t).toISOString();
|
|
11176
11151
|
const claimNext = async () => {
|
|
11177
|
-
let
|
|
11152
|
+
let claimed;
|
|
11178
11153
|
try {
|
|
11179
|
-
|
|
11154
|
+
claimed = await busRequest(bus, "job:claim", { types: jobTypes }, 1e4);
|
|
11180
11155
|
} catch (error) {
|
|
11181
11156
|
if (error instanceof BusRequestError) {
|
|
11182
11157
|
if (error.code === "bus.none-pending") return { declined: true };
|
|
@@ -11184,25 +11159,19 @@ function createJobClaimAdapter(options) {
|
|
|
11184
11159
|
}
|
|
11185
11160
|
return { refused: { code: null, message: error instanceof Error ? error.message : String(error) } };
|
|
11186
11161
|
}
|
|
11187
|
-
|
|
11188
|
-
return { refused: { code: null, message: "claimed record carries no job id or type" } };
|
|
11189
|
-
}
|
|
11190
|
-
const completedUnits = isArray(record.metadata?.completedUnits) ? record.metadata.completedUnits.filter(isString) : [];
|
|
11191
|
-
const unitCursors = readUnitCursors(record.metadata?.unitCursors, completedUnits);
|
|
11192
|
-
const params = record.params ?? {};
|
|
11162
|
+
const { metadata, params } = claimed;
|
|
11193
11163
|
return {
|
|
11194
11164
|
job: {
|
|
11195
|
-
jobId:
|
|
11196
|
-
type:
|
|
11197
|
-
resourceId:
|
|
11198
|
-
userId: record.metadata?.userId ?? "",
|
|
11165
|
+
jobId: metadata.id,
|
|
11166
|
+
type: metadata.type,
|
|
11167
|
+
resourceId: params.resourceId,
|
|
11199
11168
|
params,
|
|
11200
|
-
|
|
11201
|
-
|
|
11202
|
-
|
|
11203
|
-
|
|
11204
|
-
retryCount:
|
|
11205
|
-
maxRetries:
|
|
11169
|
+
// Both appear on the record once an attempt has checkpointed, and a
|
|
11170
|
+
// finished unit has no cursor: the dispatcher drops it at the merge.
|
|
11171
|
+
completedUnits: metadata.completedUnits ?? [],
|
|
11172
|
+
unitCursors: metadata.unitCursors ?? {},
|
|
11173
|
+
retryCount: metadata.retryCount,
|
|
11174
|
+
maxRetries: metadata.maxRetries
|
|
11206
11175
|
}
|
|
11207
11176
|
};
|
|
11208
11177
|
};
|
|
@@ -11319,26 +11288,25 @@ var WORKER_AWAITED_OPERATIONS = [
|
|
|
11319
11288
|
"job:claim",
|
|
11320
11289
|
"browse:resource-requested",
|
|
11321
11290
|
// Canonical geometry for a geometry-bearing detection: the consult behind
|
|
11322
|
-
// `ConsultAnchoredText
|
|
11323
|
-
//
|
|
11324
|
-
// (.plans/WORKER-ANCHORED-TEXT-CHANNEL.md); the census below now fails the
|
|
11291
|
+
// `ConsultAnchoredText`, answered by the Smelter. Without it every PDF
|
|
11292
|
+
// detection job fails at the transport probe; the census below fails the
|
|
11325
11293
|
// BUILD when this list and the declared awaits drift.
|
|
11326
11294
|
"browse:anchored-text-requested",
|
|
11327
|
-
// Durability acknowledgement for a unit's annotations
|
|
11328
|
-
//
|
|
11329
|
-
//
|
|
11330
|
-
//
|
|
11295
|
+
// Durability acknowledgement for a unit's annotations. The worker AWAITS
|
|
11296
|
+
// this one — a unit may not advance until its annotations are in the event
|
|
11297
|
+
// log — so its replies must be in the narrow channel set or every commit
|
|
11298
|
+
// fails fast with `bus.unsubscribed`.
|
|
11331
11299
|
"mark:commit",
|
|
11332
|
-
// The durability probe for a commit whose acknowledgement never routed
|
|
11333
|
-
//
|
|
11334
|
-
//
|
|
11335
|
-
//
|
|
11300
|
+
// The durability probe for a commit whose acknowledgement never routed.
|
|
11301
|
+
// SINGULAR by design: the annotation LIST channel is the multi-MB fan-out
|
|
11302
|
+
// this narrowing exists to keep out, and a rare error path is no reason to
|
|
11303
|
+
// let it in.
|
|
11336
11304
|
"browse:annotation-requested"
|
|
11337
11305
|
];
|
|
11338
11306
|
var WORKER_CONSUMED_BROADCASTS = [
|
|
11339
11307
|
// The queue announcement the claim adapter races for.
|
|
11340
11308
|
"job:queued",
|
|
11341
|
-
// Cooperative cancellation of the ACTIVE job
|
|
11309
|
+
// Cooperative cancellation of the ACTIVE job: it stops at a unit boundary.
|
|
11342
11310
|
"job:cancel-requested"
|
|
11343
11311
|
];
|
|
11344
11312
|
var WORKER_CHANNELS = [
|