@semiont/jobs 0.5.27 → 0.5.28

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.
@@ -9390,9 +9390,9 @@ async function withTimeout(work, label, onHeartbeat) {
9390
9390
  if (heartbeat) clearInterval(heartbeat);
9391
9391
  }
9392
9392
  }
9393
- function boundedGenerate(client, prompt, maxTokens, temperature, onHeartbeat) {
9393
+ function boundedGenerateWithMetadata(client, prompt, maxTokens, temperature, onHeartbeat) {
9394
9394
  return spanned(client, "text", maxTokens, () => withTimeout(
9395
- client.generateText(prompt, maxTokens, temperature),
9395
+ client.generateTextWithMetadata(prompt, maxTokens, temperature),
9396
9396
  `${client.type}:${client.modelId}`,
9397
9397
  onHeartbeat
9398
9398
  ));
@@ -10175,6 +10175,7 @@ var SEMANTIC_MATCH_CHARS = 240;
10175
10175
  function idLabel(resourceId, annotationId) {
10176
10176
  return `[${resourceId}${annotationId ? `/${annotationId}` : ""}]`;
10177
10177
  }
10178
+ var DEFAULT_MAX_TOKENS = 500;
10178
10179
  async function generateResourceFromTopic(topic, entityTypes, client, logger2, userPrompt, locale, context, temperature, maxTokens, sourceLanguage, outputMediaType = "text/markdown", task = "resource", structure, cite = false, repair) {
10179
10180
  logger2.debug("Generating resource from topic", {
10180
10181
  topicPreview: topic.substring(0, 100),
@@ -10190,7 +10191,7 @@ async function generateResourceFromTopic(topic, entityTypes, client, logger2, us
10190
10191
  structure
10191
10192
  });
10192
10193
  const finalTemperature = temperature ?? 0.7;
10193
- const finalMaxTokens = maxTokens ?? 500;
10194
+ const finalMaxTokens = maxTokens ?? DEFAULT_MAX_TOKENS;
10194
10195
  const languageInstruction = locale && locale !== "en" ? `
10195
10196
 
10196
10197
  IMPORTANT: Write the entire resource in ${getLanguageName(locale)}.` : "";
@@ -10217,6 +10218,9 @@ The source resource and embedded context are in ${getLanguageName(sourceLanguage
10217
10218
  parts.push(`- ${label}: ${bodyItem.value}`);
10218
10219
  }
10219
10220
  }
10221
+ if (focus.userHint) {
10222
+ parts.push(`- User hint (steers what to generate): ${focus.userHint}`);
10223
+ }
10220
10224
  annotationSection = `
10221
10225
 
10222
10226
  Annotation context:
@@ -10375,16 +10379,16 @@ ${formatRequirements}`;
10375
10379
  temperature: finalTemperature,
10376
10380
  maxTokens: finalMaxTokens
10377
10381
  });
10378
- const response = await boundedGenerate(client, prompt, finalMaxTokens, finalTemperature);
10379
- logger2.debug("Got response from inference", { responseLength: response.length });
10380
- const result = parseResponse(response);
10382
+ const response = await boundedGenerateWithMetadata(client, prompt, finalMaxTokens, finalTemperature);
10383
+ logger2.debug("Got response from inference", { responseLength: response.text.length, stopReason: response.stopReason });
10384
+ const result = parseResponse(response.text);
10381
10385
  logger2.debug("Parsed response", {
10382
10386
  hasTitle: !!result.title,
10383
10387
  titleLength: result.title?.length,
10384
10388
  hasContent: !!result.content,
10385
10389
  contentLength: result.content?.length
10386
10390
  });
10387
- return result;
10391
+ return { ...result, truncated: response.stopReason === "max_tokens" };
10388
10392
  }
10389
10393
  var PINNED_CREATION_TIMESTAMP = 17e8;
10390
10394
  var MAX_COMPILE_REPAIRS = 2;
@@ -10616,7 +10620,7 @@ async function processHighlightJob(content, inferenceClient, params, buildAnnota
10616
10620
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "highlight" }, echo);
10617
10621
  return {
10618
10622
  annotations,
10619
- result: { highlightsFound: highlights.length, highlightsCreated: annotations.length }
10623
+ result: { kind: "highlight-annotation", highlightsFound: highlights.length, highlightsCreated: annotations.length }
10620
10624
  };
10621
10625
  }
10622
10626
  function detectionEcho(p) {
@@ -10656,7 +10660,7 @@ async function processCommentJob(content, inferenceClient, params, buildAnnotati
10656
10660
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "comment" }, echo);
10657
10661
  return {
10658
10662
  annotations,
10659
- result: { commentsFound: comments.length, commentsCreated: annotations.length }
10663
+ result: { kind: "comment-annotation", commentsFound: comments.length, commentsCreated: annotations.length }
10660
10664
  };
10661
10665
  }
10662
10666
  async function processAssessmentJob(content, inferenceClient, params, buildAnnotation, onProgress) {
@@ -10696,7 +10700,7 @@ async function processAssessmentJob(content, inferenceClient, params, buildAnnot
10696
10700
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "assessment" }, echo);
10697
10701
  return {
10698
10702
  annotations,
10699
- result: { assessmentsFound: assessments.length, assessmentsCreated: annotations.length }
10703
+ result: { kind: "assessment-annotation", assessmentsFound: assessments.length, assessmentsCreated: annotations.length }
10700
10704
  };
10701
10705
  }
10702
10706
  async function processReferenceJob(content, inferenceClient, params, buildAnnotation, onProgress, logger2) {
@@ -10786,7 +10790,7 @@ async function processReferenceJob(content, inferenceClient, params, buildAnnota
10786
10790
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "reference" }, { requestParams });
10787
10791
  return {
10788
10792
  annotations,
10789
- result: { totalFound, totalEmitted: annotations.length, errors }
10793
+ result: { kind: "reference-annotation", totalFound, totalEmitted: annotations.length, errors }
10790
10794
  };
10791
10795
  }
10792
10796
  async function processTagJob(content, inferenceClient, params, buildAnnotation, onProgress) {
@@ -10843,7 +10847,7 @@ async function processTagJob(content, inferenceClient, params, buildAnnotation,
10843
10847
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "tag" });
10844
10848
  return {
10845
10849
  annotations,
10846
- result: { tagsFound: tags.length, tagsCreated: annotations.length, byCategory }
10850
+ result: { kind: "tag-annotation", tagsFound: tags.length, tagsCreated: annotations.length, byCategory }
10847
10851
  };
10848
10852
  }
10849
10853
  function assertWithinOutputBudget(byteLength) {
@@ -10890,7 +10894,17 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger2
10890
10894
  }
10891
10895
  let compiled = compileTypst(source);
10892
10896
  let repairs = 0;
10893
- while ("error" in compiled && repairs < MAX_COMPILE_REPAIRS) {
10897
+ while ("error" in compiled) {
10898
+ if (generated2.truncated) {
10899
+ throw new Error(
10900
+ `Generation stopped at the maxTokens ceiling (${params.maxTokens ?? DEFAULT_MAX_TOKENS} tokens) and the cut-off Typst source does not compile \u2014 repair cannot help; raise maxTokens. Compile error: ${compiled.error}`
10901
+ );
10902
+ }
10903
+ if (repairs >= MAX_COMPILE_REPAIRS) {
10904
+ throw new Error(
10905
+ `Typst compilation failed after ${MAX_COMPILE_REPAIRS} repair attempts: ${compiled.error}`
10906
+ );
10907
+ }
10894
10908
  repairs++;
10895
10909
  logger2.warn("Typst compile failed \u2014 feeding the error back for repair", {
10896
10910
  attempt: repairs,
@@ -10922,21 +10936,19 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger2
10922
10936
  }
10923
10937
  compiled = compileTypst(source);
10924
10938
  }
10925
- if ("error" in compiled) {
10926
- throw new Error(
10927
- `Typst compilation failed after ${MAX_COMPILE_REPAIRS} repair attempts: ${compiled.error}`
10928
- );
10929
- }
10930
10939
  assertWithinOutputBudget(compiled.pdf.byteLength);
10931
10940
  onProgress(95, { code: "creating-resource" });
10941
+ onProgress(100, { code: "complete-generated", truncated: generated2.truncated });
10932
10942
  return {
10933
10943
  content: compiled.pdf,
10934
- title: generated2.title ?? title,
10944
+ title,
10935
10945
  format: outputMediaType,
10936
10946
  citations: citations2,
10937
10947
  result: {
10948
+ kind: "generation",
10938
10949
  resourceId: "",
10939
- resourceName: generated2.title ?? title
10950
+ resourceName: title,
10951
+ truncated: generated2.truncated
10940
10952
  }
10941
10953
  };
10942
10954
  }
@@ -10967,14 +10979,17 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger2
10967
10979
  onProgress(95, { code: "creating-resource" });
10968
10980
  const artifact = new TextEncoder().encode(content);
10969
10981
  assertWithinOutputBudget(artifact.byteLength);
10982
+ onProgress(100, { code: "complete-generated", truncated: generated.truncated });
10970
10983
  return {
10971
10984
  content: artifact,
10972
- title: generated.title ?? title,
10985
+ title,
10973
10986
  format: outputMediaType,
10974
10987
  citations,
10975
10988
  result: {
10989
+ kind: "generation",
10976
10990
  resourceId: "",
10977
- resourceName: generated.title ?? title
10991
+ resourceName: title,
10992
+ truncated: generated.truncated
10978
10993
  }
10979
10994
  };
10980
10995
  }
@@ -10989,7 +11004,7 @@ async function prepareDetection(mediaType, session, resourceId, userId, generato
10989
11004
  key: calculateChecksum(bytes),
10990
11005
  store
10991
11006
  });
10992
- if ("declined" in extracted) return extracted;
11007
+ if (extracted.kind === "declined") return extracted;
10993
11008
  if (!extracted.text.trim()) return { declined: "empty" };
10994
11009
  const items = extracted.items;
10995
11010
  if (items && items.length > 0) {
@@ -11109,6 +11124,7 @@ async function handleJobInner(adapter, config, job) {
11109
11124
  await emitEvent(session, "job:complete", {
11110
11125
  ...lifecycleBase,
11111
11126
  result: {
11127
+ kind: "declined",
11112
11128
  declined: true,
11113
11129
  reason: source.declined
11114
11130
  }
@@ -11304,7 +11320,7 @@ async function handleJobInner(adapter, config, job) {
11304
11320
  }
11305
11321
  await emitEvent(session, "job:complete", {
11306
11322
  ...lifecycleBase,
11307
- result: { resourceId: newResourceId, resourceName: genResult.title }
11323
+ result: { kind: "generation", resourceId: newResourceId, resourceName: genResult.title, truncated: genResult.result.truncated }
11308
11324
  });
11309
11325
  adapter.completeJob();
11310
11326
  } else {