@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.
package/dist/index.d.ts CHANGED
@@ -136,6 +136,7 @@ interface DetectionProgress {
136
136
  * Detection job result
137
137
  */
138
138
  interface DetectionResult {
139
+ kind: 'reference-annotation';
139
140
  totalFound: number;
140
141
  totalEmitted: number;
141
142
  errors: number;
@@ -153,8 +154,11 @@ interface YieldProgress {
153
154
  * Generation job result
154
155
  */
155
156
  interface GenerationResult {
157
+ kind: 'generation';
156
158
  resourceId: ResourceId;
157
159
  resourceName: string;
160
+ /** True when the model stopped at the maxTokens ceiling — the artifact is cut off, not complete (GENERATE-FROM-RESOURCE D6). */
161
+ truncated: boolean;
158
162
  }
159
163
  /**
160
164
  * Highlight detection job progress
@@ -168,6 +172,7 @@ interface HighlightDetectionProgress {
168
172
  * Highlight detection job result
169
173
  */
170
174
  interface HighlightDetectionResult {
175
+ kind: 'highlight-annotation';
171
176
  highlightsFound: number;
172
177
  highlightsCreated: number;
173
178
  }
@@ -183,6 +188,7 @@ interface AssessmentDetectionProgress {
183
188
  * Assessment detection job result
184
189
  */
185
190
  interface AssessmentDetectionResult {
191
+ kind: 'assessment-annotation';
186
192
  assessmentsFound: number;
187
193
  assessmentsCreated: number;
188
194
  }
@@ -198,6 +204,7 @@ interface CommentDetectionProgress {
198
204
  * Comment detection job result
199
205
  */
200
206
  interface CommentDetectionResult {
207
+ kind: 'comment-annotation';
201
208
  commentsFound: number;
202
209
  commentsCreated: number;
203
210
  }
@@ -216,6 +223,7 @@ interface TagDetectionProgress {
216
223
  * Tag detection job result
217
224
  */
218
225
  interface TagDetectionResult {
226
+ kind: 'tag-annotation';
219
227
  tagsFound: number;
220
228
  tagsCreated: number;
221
229
  byCategory: Record<string, number>;
@@ -654,6 +662,7 @@ declare function generateResourceFromTopic(topic: string, entityTypes: string[],
654
662
  }): Promise<{
655
663
  title: string;
656
664
  content: string;
665
+ truncated: boolean;
657
666
  }>;
658
667
 
659
668
  /**
package/dist/index.js CHANGED
@@ -468,9 +468,9 @@ async function withTimeout(work, label, onHeartbeat) {
468
468
  if (heartbeat) clearInterval(heartbeat);
469
469
  }
470
470
  }
471
- function boundedGenerate(client, prompt, maxTokens, temperature, onHeartbeat) {
471
+ function boundedGenerateWithMetadata(client, prompt, maxTokens, temperature, onHeartbeat) {
472
472
  return spanned(client, "text", maxTokens, () => withTimeout(
473
- client.generateText(prompt, maxTokens, temperature),
473
+ client.generateTextWithMetadata(prompt, maxTokens, temperature),
474
474
  `${client.type}:${client.modelId}`,
475
475
  onHeartbeat
476
476
  ));
@@ -1253,6 +1253,7 @@ var SEMANTIC_MATCH_CHARS = 240;
1253
1253
  function idLabel(resourceId, annotationId) {
1254
1254
  return `[${resourceId}${annotationId ? `/${annotationId}` : ""}]`;
1255
1255
  }
1256
+ var DEFAULT_MAX_TOKENS = 500;
1256
1257
  async function generateResourceFromTopic(topic, entityTypes, client, logger, userPrompt, locale, context, temperature, maxTokens, sourceLanguage, outputMediaType = "text/markdown", task = "resource", structure, cite = false, repair) {
1257
1258
  logger.debug("Generating resource from topic", {
1258
1259
  topicPreview: topic.substring(0, 100),
@@ -1268,7 +1269,7 @@ async function generateResourceFromTopic(topic, entityTypes, client, logger, use
1268
1269
  structure
1269
1270
  });
1270
1271
  const finalTemperature = temperature ?? 0.7;
1271
- const finalMaxTokens = maxTokens ?? 500;
1272
+ const finalMaxTokens = maxTokens ?? DEFAULT_MAX_TOKENS;
1272
1273
  const languageInstruction = locale && locale !== "en" ? `
1273
1274
 
1274
1275
  IMPORTANT: Write the entire resource in ${getLanguageName(locale)}.` : "";
@@ -1295,6 +1296,9 @@ The source resource and embedded context are in ${getLanguageName(sourceLanguage
1295
1296
  parts.push(`- ${label}: ${bodyItem.value}`);
1296
1297
  }
1297
1298
  }
1299
+ if (focus.userHint) {
1300
+ parts.push(`- User hint (steers what to generate): ${focus.userHint}`);
1301
+ }
1298
1302
  annotationSection = `
1299
1303
 
1300
1304
  Annotation context:
@@ -1453,16 +1457,16 @@ ${formatRequirements}`;
1453
1457
  temperature: finalTemperature,
1454
1458
  maxTokens: finalMaxTokens
1455
1459
  });
1456
- const response = await boundedGenerate(client, prompt, finalMaxTokens, finalTemperature);
1457
- logger.debug("Got response from inference", { responseLength: response.length });
1458
- const result = parseResponse(response);
1460
+ const response = await boundedGenerateWithMetadata(client, prompt, finalMaxTokens, finalTemperature);
1461
+ logger.debug("Got response from inference", { responseLength: response.text.length, stopReason: response.stopReason });
1462
+ const result = parseResponse(response.text);
1459
1463
  logger.debug("Parsed response", {
1460
1464
  hasTitle: !!result.title,
1461
1465
  titleLength: result.title?.length,
1462
1466
  hasContent: !!result.content,
1463
1467
  contentLength: result.content?.length
1464
1468
  });
1465
- return result;
1469
+ return { ...result, truncated: response.stopReason === "max_tokens" };
1466
1470
  }
1467
1471
  var PINNED_CREATION_TIMESTAMP = 17e8;
1468
1472
  var MAX_COMPILE_REPAIRS = 2;
@@ -1602,7 +1606,7 @@ async function processHighlightJob(content, inferenceClient, params, buildAnnota
1602
1606
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "highlight" }, echo);
1603
1607
  return {
1604
1608
  annotations,
1605
- result: { highlightsFound: highlights.length, highlightsCreated: annotations.length }
1609
+ result: { kind: "highlight-annotation", highlightsFound: highlights.length, highlightsCreated: annotations.length }
1606
1610
  };
1607
1611
  }
1608
1612
  function detectionEcho(p) {
@@ -1642,7 +1646,7 @@ async function processCommentJob(content, inferenceClient, params, buildAnnotati
1642
1646
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "comment" }, echo);
1643
1647
  return {
1644
1648
  annotations,
1645
- result: { commentsFound: comments.length, commentsCreated: annotations.length }
1649
+ result: { kind: "comment-annotation", commentsFound: comments.length, commentsCreated: annotations.length }
1646
1650
  };
1647
1651
  }
1648
1652
  async function processAssessmentJob(content, inferenceClient, params, buildAnnotation, onProgress) {
@@ -1682,7 +1686,7 @@ async function processAssessmentJob(content, inferenceClient, params, buildAnnot
1682
1686
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "assessment" }, echo);
1683
1687
  return {
1684
1688
  annotations,
1685
- result: { assessmentsFound: assessments.length, assessmentsCreated: annotations.length }
1689
+ result: { kind: "assessment-annotation", assessmentsFound: assessments.length, assessmentsCreated: annotations.length }
1686
1690
  };
1687
1691
  }
1688
1692
  async function processReferenceJob(content, inferenceClient, params, buildAnnotation, onProgress, logger) {
@@ -1772,7 +1776,7 @@ async function processReferenceJob(content, inferenceClient, params, buildAnnota
1772
1776
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "reference" }, { requestParams });
1773
1777
  return {
1774
1778
  annotations,
1775
- result: { totalFound, totalEmitted: annotations.length, errors }
1779
+ result: { kind: "reference-annotation", totalFound, totalEmitted: annotations.length, errors }
1776
1780
  };
1777
1781
  }
1778
1782
  async function processTagJob(content, inferenceClient, params, buildAnnotation, onProgress) {
@@ -1829,7 +1833,7 @@ async function processTagJob(content, inferenceClient, params, buildAnnotation,
1829
1833
  onProgress(100, { code: "complete-created", count: annotations.length, kind: "tag" });
1830
1834
  return {
1831
1835
  annotations,
1832
- result: { tagsFound: tags.length, tagsCreated: annotations.length, byCategory }
1836
+ result: { kind: "tag-annotation", tagsFound: tags.length, tagsCreated: annotations.length, byCategory }
1833
1837
  };
1834
1838
  }
1835
1839
  function assertWithinOutputBudget(byteLength) {
@@ -1876,7 +1880,17 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger)
1876
1880
  }
1877
1881
  let compiled = compileTypst(source);
1878
1882
  let repairs = 0;
1879
- while ("error" in compiled && repairs < MAX_COMPILE_REPAIRS) {
1883
+ while ("error" in compiled) {
1884
+ if (generated2.truncated) {
1885
+ throw new Error(
1886
+ `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}`
1887
+ );
1888
+ }
1889
+ if (repairs >= MAX_COMPILE_REPAIRS) {
1890
+ throw new Error(
1891
+ `Typst compilation failed after ${MAX_COMPILE_REPAIRS} repair attempts: ${compiled.error}`
1892
+ );
1893
+ }
1880
1894
  repairs++;
1881
1895
  logger.warn("Typst compile failed \u2014 feeding the error back for repair", {
1882
1896
  attempt: repairs,
@@ -1908,21 +1922,19 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger)
1908
1922
  }
1909
1923
  compiled = compileTypst(source);
1910
1924
  }
1911
- if ("error" in compiled) {
1912
- throw new Error(
1913
- `Typst compilation failed after ${MAX_COMPILE_REPAIRS} repair attempts: ${compiled.error}`
1914
- );
1915
- }
1916
1925
  assertWithinOutputBudget(compiled.pdf.byteLength);
1917
1926
  onProgress(95, { code: "creating-resource" });
1927
+ onProgress(100, { code: "complete-generated", truncated: generated2.truncated });
1918
1928
  return {
1919
1929
  content: compiled.pdf,
1920
- title: generated2.title ?? title,
1930
+ title,
1921
1931
  format: outputMediaType,
1922
1932
  citations: citations2,
1923
1933
  result: {
1934
+ kind: "generation",
1924
1935
  resourceId: "",
1925
- resourceName: generated2.title ?? title
1936
+ resourceName: title,
1937
+ truncated: generated2.truncated
1926
1938
  }
1927
1939
  };
1928
1940
  }
@@ -1953,14 +1965,17 @@ async function processGenerationJob(inferenceClient, params, onProgress, logger)
1953
1965
  onProgress(95, { code: "creating-resource" });
1954
1966
  const artifact = new TextEncoder().encode(content);
1955
1967
  assertWithinOutputBudget(artifact.byteLength);
1968
+ onProgress(100, { code: "complete-generated", truncated: generated.truncated });
1956
1969
  return {
1957
1970
  content: artifact,
1958
- title: generated.title ?? title,
1971
+ title,
1959
1972
  format: outputMediaType,
1960
1973
  citations,
1961
1974
  result: {
1975
+ kind: "generation",
1962
1976
  resourceId: "",
1963
- resourceName: generated.title ?? title
1977
+ resourceName: title,
1978
+ truncated: generated.truncated
1964
1979
  }
1965
1980
  };
1966
1981
  }