@semiont/jobs 0.6.6 → 0.6.8
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 +27 -64
- package/dist/index.d.ts +215 -522
- package/dist/index.js +9281 -974
- package/dist/index.js.map +1 -1
- package/dist/worker-main.js +26 -27
- package/dist/worker-main.js.map +1 -1
- package/package.json +9 -10
package/dist/worker-main.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { replyChannelsFor, createTomlConfigLoader, didToAgent, baseUrl, STARTUP_FETCH_RETRY, retryWithBackoff, serviceAccountToken, isTransientFetchError, isObject, isString, isNumber, RETRY_RULES, resourceId, getPrimaryMediaType, isGenerationJobParams, capabilitiesOf, assembleAnnotation, findClaimSpan, busRequest, BusRequestError, isArray, textSourceOf, yieldsGeometryOf, decodeRepresentation, GENERATABLE_MEDIA_TYPES, locate, createFragmentSelector, deriveViews, annotationId, estimateTokens, reconcileSelector, getLocaleEnglishName, cutChunk, chunkText } from '@semiont/core';
|
|
1
|
+
import { JOB_TYPES, replyChannelsFor, createTomlConfigLoader, didToAgent, baseUrl, STARTUP_FETCH_RETRY, retryWithBackoff, serviceAccountToken, isTransientFetchError, isObject, isString, isNumber, RETRY_RULES, resourceId, getPrimaryMediaType, isGenerationJobParams, capabilitiesOf, assembleAnnotation, findClaimSpan, busRequest, BusRequestError, isArray, textSourceOf, yieldsGeometryOf, decodeRepresentation, GENERATABLE_MEDIA_TYPES, locate, createFragmentSelector, deriveViews, annotationId, estimateTokens, reconcileSelector, getLocaleEnglishName, cutChunk, chunkText } from '@semiont/core';
|
|
2
2
|
import { archivistContentReads, extractPdfTextLayer, withinByteBudget, MAX_PDF_BYTES } from '@semiont/content';
|
|
3
3
|
import { withSpan, SpanKind, recordJobOutcome, recordAnchorOutcome, recordDetectionCall } from '@semiont/observability';
|
|
4
|
-
import { createInferenceClient, StructuredReadError } from '@semiont/inference';
|
|
4
|
+
import { createInferenceClient, answerLimitsRequests, StructuredReadError } from '@semiont/inference';
|
|
5
5
|
import { execFileSync } from 'child_process';
|
|
6
6
|
import { existsSync, readFileSync, mkdtempSync, writeFileSync, rmSync } from 'fs';
|
|
7
7
|
import { homedir, hostname, tmpdir } from 'os';
|
|
@@ -9384,18 +9384,9 @@ function createJobClaimAdapter(options) {
|
|
|
9384
9384
|
function willRetryAfter(metadata, failureClass) {
|
|
9385
9385
|
return failureClass !== "deterministic" && metadata.retryCount < metadata.maxRetries;
|
|
9386
9386
|
}
|
|
9387
|
-
|
|
9388
|
-
// src/types.ts
|
|
9389
|
-
var JOB_TYPES = /* @__PURE__ */ new Set([
|
|
9390
|
-
"reference-annotation",
|
|
9391
|
-
"generation",
|
|
9392
|
-
"highlight-annotation",
|
|
9393
|
-
"assessment-annotation",
|
|
9394
|
-
"comment-annotation",
|
|
9395
|
-
"tag-annotation"
|
|
9396
|
-
]);
|
|
9387
|
+
var KNOWN_JOB_TYPES = new Set(JOB_TYPES);
|
|
9397
9388
|
function isJobType(value) {
|
|
9398
|
-
return
|
|
9389
|
+
return KNOWN_JOB_TYPES.has(value);
|
|
9399
9390
|
}
|
|
9400
9391
|
function asJobParams(params) {
|
|
9401
9392
|
if (typeof params.resourceId !== "string") {
|
|
@@ -12016,6 +12007,9 @@ var WORKER_CONSUMED_BROADCASTS = [
|
|
|
12016
12007
|
// Cooperative cancellation of the ACTIVE job (JOB-RESTART-SAFETY P4).
|
|
12017
12008
|
"job:cancel-requested"
|
|
12018
12009
|
];
|
|
12010
|
+
var WORKER_ANSWERED_OPERATIONS = [
|
|
12011
|
+
"job:limits-requested"
|
|
12012
|
+
];
|
|
12019
12013
|
var WORKER_CHANNELS = [
|
|
12020
12014
|
...replyChannelsFor(WORKER_AWAITED_OPERATIONS),
|
|
12021
12015
|
...WORKER_CONSUMED_BROADCASTS
|
|
@@ -12059,7 +12053,7 @@ async function authenticateAgent(opts) {
|
|
|
12059
12053
|
);
|
|
12060
12054
|
}
|
|
12061
12055
|
async function startAgentWorker(opts) {
|
|
12062
|
-
const { group, gatewayBaseUrl: gatewayBaseUrl2, credential: credential2, contentReads: contentReads2, logger: logger2 } = opts;
|
|
12056
|
+
const { group, gatewayBaseUrl: gatewayBaseUrl2, credential: credential2, contentReads: contentReads2, reportsLimitsOf, logger: logger2 } = opts;
|
|
12063
12057
|
const { inference } = group;
|
|
12064
12058
|
const { protocol, host, port } = parseGatewayUrl(gatewayBaseUrl2);
|
|
12065
12059
|
const { token: initialToken, did } = await authenticateAgent({
|
|
@@ -12091,8 +12085,9 @@ async function startAgentWorker(opts) {
|
|
|
12091
12085
|
token$,
|
|
12092
12086
|
tokenRefresher: () => session.refresh().then((t) => t ?? null),
|
|
12093
12087
|
// Only the reply channels this process awaits — not the full bridged
|
|
12094
|
-
// set. See WORKER_AWAITED_OPERATIONS.
|
|
12095
|
-
|
|
12088
|
+
// set. See WORKER_AWAITED_OPERATIONS. The agent that reports its pool's
|
|
12089
|
+
// limits also subscribes the requests it answers.
|
|
12090
|
+
channels: reportsLimitsOf.length > 0 ? [...WORKER_CHANNELS, ...WORKER_ANSWERED_OPERATIONS] : WORKER_CHANNELS
|
|
12096
12091
|
});
|
|
12097
12092
|
const content = new HttpContentTransport(transport);
|
|
12098
12093
|
const client = new SemiontClient(transport, content, transport);
|
|
@@ -12136,6 +12131,7 @@ async function startAgentWorker(opts) {
|
|
|
12136
12131
|
contentReads: contentReads2,
|
|
12137
12132
|
logger: logger2
|
|
12138
12133
|
});
|
|
12134
|
+
const limitsResponder = reportsLimitsOf.length > 0 ? answerLimitsRequests(transport, "job:limits-requested", reportsLimitsOf, logger2) : void 0;
|
|
12139
12135
|
logger2.info("Agent ready", {
|
|
12140
12136
|
did,
|
|
12141
12137
|
provider: inference.type,
|
|
@@ -12152,19 +12148,12 @@ async function startAgentWorker(opts) {
|
|
|
12152
12148
|
...adapter.vitals()
|
|
12153
12149
|
}),
|
|
12154
12150
|
dispose: async () => {
|
|
12151
|
+
limitsResponder?.unsubscribe();
|
|
12155
12152
|
adapter.dispose();
|
|
12156
12153
|
await session.dispose();
|
|
12157
12154
|
}
|
|
12158
12155
|
};
|
|
12159
12156
|
}
|
|
12160
|
-
var ALL_JOB_TYPES = [
|
|
12161
|
-
"reference-annotation",
|
|
12162
|
-
"generation",
|
|
12163
|
-
"highlight-annotation",
|
|
12164
|
-
"assessment-annotation",
|
|
12165
|
-
"comment-annotation",
|
|
12166
|
-
"tag-annotation"
|
|
12167
|
-
];
|
|
12168
12157
|
var configPath = join(homedir(), ".semiontconfig");
|
|
12169
12158
|
var tomlReader = {
|
|
12170
12159
|
readIfExists: (p) => existsSync(p) ? readFileSync(p, "utf-8") : null
|
|
@@ -12172,7 +12161,8 @@ var tomlReader = {
|
|
|
12172
12161
|
var envConfig = createTomlConfigLoader(
|
|
12173
12162
|
tomlReader,
|
|
12174
12163
|
configPath,
|
|
12175
|
-
process.env
|
|
12164
|
+
process.env,
|
|
12165
|
+
"worker"
|
|
12176
12166
|
)(null);
|
|
12177
12167
|
var workerInferenceMap = envConfig._metadata?.workers;
|
|
12178
12168
|
if (!workerInferenceMap || Object.keys(workerInferenceMap).length === 0) {
|
|
@@ -12220,7 +12210,7 @@ function toClientConfig(w) {
|
|
|
12220
12210
|
};
|
|
12221
12211
|
}
|
|
12222
12212
|
var groups = /* @__PURE__ */ new Map();
|
|
12223
|
-
for (const jobType of
|
|
12213
|
+
for (const jobType of JOB_TYPES) {
|
|
12224
12214
|
const inference = resolveWorker(jobType);
|
|
12225
12215
|
const key = clientKey(inference);
|
|
12226
12216
|
let group = groups.get(key);
|
|
@@ -12247,8 +12237,17 @@ async function main() {
|
|
|
12247
12237
|
}))
|
|
12248
12238
|
});
|
|
12249
12239
|
const workers = await Promise.all(
|
|
12240
|
+
// The first agent reports every group's limits: the gateway delivers only
|
|
12241
|
+
// the first reply to a request, so one agent answers for the pool.
|
|
12250
12242
|
Array.from(groups.values()).map(
|
|
12251
|
-
(group) => startAgentWorker({
|
|
12243
|
+
(group, i, all) => startAgentWorker({
|
|
12244
|
+
group,
|
|
12245
|
+
gatewayBaseUrl,
|
|
12246
|
+
credential,
|
|
12247
|
+
contentReads,
|
|
12248
|
+
logger,
|
|
12249
|
+
reportsLimitsOf: i === 0 ? all.map((g) => g.client) : []
|
|
12250
|
+
})
|
|
12252
12251
|
)
|
|
12253
12252
|
);
|
|
12254
12253
|
const health = createServer((req, res) => {
|