@sembl/core 0.2.0 → 0.3.0

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.cts CHANGED
@@ -836,6 +836,19 @@ interface CoerceOptions {
836
836
  * event.
837
837
  */
838
838
  onInvalidField?: InvalidFieldPolicy;
839
+ /**
840
+ * Extra guidance for this extraction that is not part of the schema: facts
841
+ * about the source ("prices on this site are in cents"), context the model
842
+ * cannot see ("the property is in Portugal, so assume EUR"), or judgement
843
+ * calls ("guest counts exclude infants"). Rendered as its own section at
844
+ * the end of the system prompt, so it stays on the instruction side of the
845
+ * data boundary that source blocks are excluded from — a hint placed inside
846
+ * a source would be ignored by design.
847
+ *
848
+ * Reaches every call of the run, repairs included, and is part of what a
849
+ * recording is keyed on.
850
+ */
851
+ instructions?: string | readonly string[];
839
852
  /**
840
853
  * Cap on the total characters of source text sent to the model, applied
841
854
  * after `preprocess`. Sources over the cap are cut per `truncate`, each
@@ -988,6 +1001,8 @@ interface SemblGlobalConfig {
988
1001
  maxRepairAttempts?: number;
989
1002
  /** What to do with a present field that fails validation. Default "throw". */
990
1003
  onInvalidField?: InvalidFieldPolicy;
1004
+ /** Extra guidance rendered into every system prompt. */
1005
+ instructions?: string | readonly string[];
991
1006
  /** Cap on total source characters sent to the model. Unbounded by default. */
992
1007
  maxInputChars?: number;
993
1008
  /** Which part of an over-budget source to cut. Default "tail". */
@@ -1011,6 +1026,8 @@ interface SemblCallConfig {
1011
1026
  maxRepairAttempts?: number;
1012
1027
  /** Override the invalid-field policy for this call */
1013
1028
  onInvalidField?: InvalidFieldPolicy;
1029
+ /** Guidance for this call. Replaces, rather than extends, the global list. */
1030
+ instructions?: string | readonly string[];
1014
1031
  /** Override the input character budget for this call */
1015
1032
  maxInputChars?: number;
1016
1033
  /** Override the truncation policy for this call */
@@ -1028,6 +1045,7 @@ interface ResolvedConfig {
1028
1045
  traceSinks?: TraceSink[];
1029
1046
  maxRepairAttempts?: number;
1030
1047
  onInvalidField?: InvalidFieldPolicy;
1048
+ instructions?: string | readonly string[];
1031
1049
  maxInputChars?: number;
1032
1050
  truncate?: TruncatePolicy;
1033
1051
  preprocess?: PreprocessSource;
@@ -1116,7 +1134,18 @@ declare function sembl(input: CoerceInput | Record<string, unknown>, config?: Se
1116
1134
  interface PromptOptions {
1117
1135
  /** Legal values for dynamic enum sources, from `resolveEnumSources` */
1118
1136
  resolvedEnums?: ResolvedEnums;
1137
+ /**
1138
+ * Caller-supplied guidance for this extraction, rendered as its own section
1139
+ * of the system prompt. Blank entries are dropped.
1140
+ */
1141
+ instructions?: string | readonly string[];
1119
1142
  }
1143
+ /**
1144
+ * Normalise the `instructions` option to a list of non-empty lines. Throws
1145
+ * for anything that is not a string or a list of strings, since a hint that
1146
+ * silently rendered as "[object Object]" would be worse than none.
1147
+ */
1148
+ declare function normalizeInstructions(instructions: string | readonly string[] | undefined): string[];
1120
1149
  /**
1121
1150
  * Build a system prompt that provides semantic context for the target schema.
1122
1151
  * This assembles the semantic hierarchy so the LLM understands the meaning
@@ -1162,4 +1191,4 @@ declare class ConsoleSink implements TraceSink {
1162
1191
  write(span: TraceSpan): void;
1163
1192
  }
1164
1193
 
1165
- export { type BudgetResult, CoerceError, type CoerceInput, type CoerceManyOptions, type CoerceManyResult, type CoerceOptions, Coercible, ConsoleSink, Constrain, type DeepPartial, type DefinedSchema, Describe, type EnumResolution, EnumResolutionError, type EnumResolver, type EnumSourceFailure, type EnumSourceUsage, type FieldBuilder, type FieldConfidence, type FieldConstraints, type FieldDescriptor, type FieldProvenance, type FieldType, type FieldValidationIssue, type Infer, type InferFields, type InvalidFieldPolicy, type IssueResolution, type JsonSchemaDialect, type JsonSchemaOptions, PROVENANCE_INSTRUCTIONS, type PreprocessSource, type PromptOptions, type ProvenanceOptions, type ProvenanceResult, type Provider, type ProviderConfig, type ProviderRequest, type ProviderResponse, type ProviderUsage, type ResolveIssuesOptions, type ResolveIssuesResult, type ResolvedEnums, type ResolvedIssue, type RetryOptions, type RuntimeSchema, SOURCE_INSTRUCTIONS, Schema, type SchemaBundle, SchemaRegistry, type SemblCallConfig, SemblConfig, type SemblGlobalConfig, type Source, type TraceContext, type TraceEvent, type TraceSink, type TraceSpan, Tracer, type TruncatePolicy, type TruncationRecord, type ValidationOptions, ValuesFrom, budgetSources, buildPrompt, buildRepairInput, bundleOf, coerce, coerceMany, coerceWithProvenance, collectEnumSources, defineSchema, field, isCoerceInput, isSource, partialCoerce, partialCoerceWithProvenance, provenanceInstructions, renderSources, resolveEnumSources, resolveIssues, runtimeSchemaToJsonSchema, sembl, splitProvenance, toOpenAIJsonSchema, toProvenanceSchema, toSources, validatePartial, validateStrict };
1194
+ export { type BudgetResult, CoerceError, type CoerceInput, type CoerceManyOptions, type CoerceManyResult, type CoerceOptions, Coercible, ConsoleSink, Constrain, type DeepPartial, type DefinedSchema, Describe, type EnumResolution, EnumResolutionError, type EnumResolver, type EnumSourceFailure, type EnumSourceUsage, type FieldBuilder, type FieldConfidence, type FieldConstraints, type FieldDescriptor, type FieldProvenance, type FieldType, type FieldValidationIssue, type Infer, type InferFields, type InvalidFieldPolicy, type IssueResolution, type JsonSchemaDialect, type JsonSchemaOptions, PROVENANCE_INSTRUCTIONS, type PreprocessSource, type PromptOptions, type ProvenanceOptions, type ProvenanceResult, type Provider, type ProviderConfig, type ProviderRequest, type ProviderResponse, type ProviderUsage, type ResolveIssuesOptions, type ResolveIssuesResult, type ResolvedEnums, type ResolvedIssue, type RetryOptions, type RuntimeSchema, SOURCE_INSTRUCTIONS, Schema, type SchemaBundle, SchemaRegistry, type SemblCallConfig, SemblConfig, type SemblGlobalConfig, type Source, type TraceContext, type TraceEvent, type TraceSink, type TraceSpan, Tracer, type TruncatePolicy, type TruncationRecord, type ValidationOptions, ValuesFrom, budgetSources, buildPrompt, buildRepairInput, bundleOf, coerce, coerceMany, coerceWithProvenance, collectEnumSources, defineSchema, field, isCoerceInput, isSource, normalizeInstructions, partialCoerce, partialCoerceWithProvenance, provenanceInstructions, renderSources, resolveEnumSources, resolveIssues, runtimeSchemaToJsonSchema, sembl, splitProvenance, toOpenAIJsonSchema, toProvenanceSchema, toSources, validatePartial, validateStrict };
package/dist/index.d.ts CHANGED
@@ -836,6 +836,19 @@ interface CoerceOptions {
836
836
  * event.
837
837
  */
838
838
  onInvalidField?: InvalidFieldPolicy;
839
+ /**
840
+ * Extra guidance for this extraction that is not part of the schema: facts
841
+ * about the source ("prices on this site are in cents"), context the model
842
+ * cannot see ("the property is in Portugal, so assume EUR"), or judgement
843
+ * calls ("guest counts exclude infants"). Rendered as its own section at
844
+ * the end of the system prompt, so it stays on the instruction side of the
845
+ * data boundary that source blocks are excluded from — a hint placed inside
846
+ * a source would be ignored by design.
847
+ *
848
+ * Reaches every call of the run, repairs included, and is part of what a
849
+ * recording is keyed on.
850
+ */
851
+ instructions?: string | readonly string[];
839
852
  /**
840
853
  * Cap on the total characters of source text sent to the model, applied
841
854
  * after `preprocess`. Sources over the cap are cut per `truncate`, each
@@ -988,6 +1001,8 @@ interface SemblGlobalConfig {
988
1001
  maxRepairAttempts?: number;
989
1002
  /** What to do with a present field that fails validation. Default "throw". */
990
1003
  onInvalidField?: InvalidFieldPolicy;
1004
+ /** Extra guidance rendered into every system prompt. */
1005
+ instructions?: string | readonly string[];
991
1006
  /** Cap on total source characters sent to the model. Unbounded by default. */
992
1007
  maxInputChars?: number;
993
1008
  /** Which part of an over-budget source to cut. Default "tail". */
@@ -1011,6 +1026,8 @@ interface SemblCallConfig {
1011
1026
  maxRepairAttempts?: number;
1012
1027
  /** Override the invalid-field policy for this call */
1013
1028
  onInvalidField?: InvalidFieldPolicy;
1029
+ /** Guidance for this call. Replaces, rather than extends, the global list. */
1030
+ instructions?: string | readonly string[];
1014
1031
  /** Override the input character budget for this call */
1015
1032
  maxInputChars?: number;
1016
1033
  /** Override the truncation policy for this call */
@@ -1028,6 +1045,7 @@ interface ResolvedConfig {
1028
1045
  traceSinks?: TraceSink[];
1029
1046
  maxRepairAttempts?: number;
1030
1047
  onInvalidField?: InvalidFieldPolicy;
1048
+ instructions?: string | readonly string[];
1031
1049
  maxInputChars?: number;
1032
1050
  truncate?: TruncatePolicy;
1033
1051
  preprocess?: PreprocessSource;
@@ -1116,7 +1134,18 @@ declare function sembl(input: CoerceInput | Record<string, unknown>, config?: Se
1116
1134
  interface PromptOptions {
1117
1135
  /** Legal values for dynamic enum sources, from `resolveEnumSources` */
1118
1136
  resolvedEnums?: ResolvedEnums;
1137
+ /**
1138
+ * Caller-supplied guidance for this extraction, rendered as its own section
1139
+ * of the system prompt. Blank entries are dropped.
1140
+ */
1141
+ instructions?: string | readonly string[];
1119
1142
  }
1143
+ /**
1144
+ * Normalise the `instructions` option to a list of non-empty lines. Throws
1145
+ * for anything that is not a string or a list of strings, since a hint that
1146
+ * silently rendered as "[object Object]" would be worse than none.
1147
+ */
1148
+ declare function normalizeInstructions(instructions: string | readonly string[] | undefined): string[];
1120
1149
  /**
1121
1150
  * Build a system prompt that provides semantic context for the target schema.
1122
1151
  * This assembles the semantic hierarchy so the LLM understands the meaning
@@ -1162,4 +1191,4 @@ declare class ConsoleSink implements TraceSink {
1162
1191
  write(span: TraceSpan): void;
1163
1192
  }
1164
1193
 
1165
- export { type BudgetResult, CoerceError, type CoerceInput, type CoerceManyOptions, type CoerceManyResult, type CoerceOptions, Coercible, ConsoleSink, Constrain, type DeepPartial, type DefinedSchema, Describe, type EnumResolution, EnumResolutionError, type EnumResolver, type EnumSourceFailure, type EnumSourceUsage, type FieldBuilder, type FieldConfidence, type FieldConstraints, type FieldDescriptor, type FieldProvenance, type FieldType, type FieldValidationIssue, type Infer, type InferFields, type InvalidFieldPolicy, type IssueResolution, type JsonSchemaDialect, type JsonSchemaOptions, PROVENANCE_INSTRUCTIONS, type PreprocessSource, type PromptOptions, type ProvenanceOptions, type ProvenanceResult, type Provider, type ProviderConfig, type ProviderRequest, type ProviderResponse, type ProviderUsage, type ResolveIssuesOptions, type ResolveIssuesResult, type ResolvedEnums, type ResolvedIssue, type RetryOptions, type RuntimeSchema, SOURCE_INSTRUCTIONS, Schema, type SchemaBundle, SchemaRegistry, type SemblCallConfig, SemblConfig, type SemblGlobalConfig, type Source, type TraceContext, type TraceEvent, type TraceSink, type TraceSpan, Tracer, type TruncatePolicy, type TruncationRecord, type ValidationOptions, ValuesFrom, budgetSources, buildPrompt, buildRepairInput, bundleOf, coerce, coerceMany, coerceWithProvenance, collectEnumSources, defineSchema, field, isCoerceInput, isSource, partialCoerce, partialCoerceWithProvenance, provenanceInstructions, renderSources, resolveEnumSources, resolveIssues, runtimeSchemaToJsonSchema, sembl, splitProvenance, toOpenAIJsonSchema, toProvenanceSchema, toSources, validatePartial, validateStrict };
1194
+ export { type BudgetResult, CoerceError, type CoerceInput, type CoerceManyOptions, type CoerceManyResult, type CoerceOptions, Coercible, ConsoleSink, Constrain, type DeepPartial, type DefinedSchema, Describe, type EnumResolution, EnumResolutionError, type EnumResolver, type EnumSourceFailure, type EnumSourceUsage, type FieldBuilder, type FieldConfidence, type FieldConstraints, type FieldDescriptor, type FieldProvenance, type FieldType, type FieldValidationIssue, type Infer, type InferFields, type InvalidFieldPolicy, type IssueResolution, type JsonSchemaDialect, type JsonSchemaOptions, PROVENANCE_INSTRUCTIONS, type PreprocessSource, type PromptOptions, type ProvenanceOptions, type ProvenanceResult, type Provider, type ProviderConfig, type ProviderRequest, type ProviderResponse, type ProviderUsage, type ResolveIssuesOptions, type ResolveIssuesResult, type ResolvedEnums, type ResolvedIssue, type RetryOptions, type RuntimeSchema, SOURCE_INSTRUCTIONS, Schema, type SchemaBundle, SchemaRegistry, type SemblCallConfig, SemblConfig, type SemblGlobalConfig, type Source, type TraceContext, type TraceEvent, type TraceSink, type TraceSpan, Tracer, type TruncatePolicy, type TruncationRecord, type ValidationOptions, ValuesFrom, budgetSources, buildPrompt, buildRepairInput, bundleOf, coerce, coerceMany, coerceWithProvenance, collectEnumSources, defineSchema, field, isCoerceInput, isSource, normalizeInstructions, partialCoerce, partialCoerceWithProvenance, provenanceInstructions, renderSources, resolveEnumSources, resolveIssues, runtimeSchemaToJsonSchema, sembl, splitProvenance, toOpenAIJsonSchema, toProvenanceSchema, toSources, validatePartial, validateStrict };
package/dist/index.js CHANGED
@@ -443,6 +443,14 @@ var SOURCE_INSTRUCTIONS = [
443
443
  ].join("\n");
444
444
 
445
445
  // src/coerce/prompt-builder.ts
446
+ function normalizeInstructions(instructions) {
447
+ if (instructions === void 0) return [];
448
+ const list = typeof instructions === "string" ? [instructions] : instructions;
449
+ if (!Array.isArray(list) || list.some((entry) => typeof entry !== "string")) {
450
+ throw new RangeError("instructions must be a string or an array of strings");
451
+ }
452
+ return list.map((entry) => entry.trim()).filter((entry) => entry.length > 0);
453
+ }
446
454
  function describeConstraints(constraints) {
447
455
  if (!constraints) {
448
456
  return [];
@@ -565,6 +573,14 @@ function buildPrompt(schema, bundle, options = {}) {
565
573
  lines.push("- Interpret the user's input semantically \u2014 infer meaning, don't just pattern match.");
566
574
  lines.push("- Respect every stated limit exactly; truncate or drop lower-priority content to stay within it.");
567
575
  lines.push("- Return only the structured JSON output matching the schema.");
576
+ const instructions = normalizeInstructions(options.instructions);
577
+ if (instructions.length > 0) {
578
+ lines.push("");
579
+ lines.push("Additional guidance for this extraction:");
580
+ for (const instruction of instructions) {
581
+ lines.push(`- ${instruction}`);
582
+ }
583
+ }
568
584
  return lines.join("\n");
569
585
  }
570
586
 
@@ -1239,6 +1255,7 @@ async function runCoercion(input, options, { mode, provenance }) {
1239
1255
  `maxRepairAttempts must be a non-negative integer, got ${String(options.maxRepairAttempts)}`
1240
1256
  );
1241
1257
  }
1258
+ const instructions = normalizeInstructions(options.instructions);
1242
1259
  const onInvalidField = options.onInvalidField ?? "throw";
1243
1260
  if (!INVALID_FIELD_POLICIES.includes(onInvalidField)) {
1244
1261
  throw new RangeError(
@@ -1269,11 +1286,12 @@ async function runCoercion(input, options, { mode, provenance }) {
1269
1286
  rootSpan
1270
1287
  );
1271
1288
  const promptSpan = tracer.startSpan("buildPrompt", {}, rootSpan);
1272
- const basePrompt = buildPrompt(schema, bundle, { resolvedEnums });
1289
+ const basePrompt = buildPrompt(schema, bundle, { resolvedEnums, instructions });
1273
1290
  const systemPrompt = provenance ? `${basePrompt}
1274
1291
  ${provenanceInstructions({ sourceLabels })}` : basePrompt;
1275
1292
  tracer.addEvent(promptSpan, "promptBuilt", {
1276
- promptLength: systemPrompt.length
1293
+ promptLength: systemPrompt.length,
1294
+ instructionCount: instructions.length
1277
1295
  });
1278
1296
  tracer.endSpan(promptSpan);
1279
1297
  const request = provenance ? toProvenanceSchema(schema, bundle, { sourceLabels }) : { schema, bundle };
@@ -1559,6 +1577,7 @@ function resolveConfig(callConfig) {
1559
1577
  traceSinks: callConfig?.traceSinks ?? global.traceSinks,
1560
1578
  maxRepairAttempts: callConfig?.maxRepairAttempts ?? global.maxRepairAttempts,
1561
1579
  onInvalidField: callConfig?.onInvalidField ?? global.onInvalidField,
1580
+ instructions: callConfig?.instructions ?? global.instructions,
1562
1581
  maxInputChars: callConfig?.maxInputChars ?? global.maxInputChars,
1563
1582
  truncate: callConfig?.truncate ?? global.truncate,
1564
1583
  preprocess: callConfig?.preprocess ?? global.preprocess
@@ -1592,6 +1611,7 @@ var Coercible = class _Coercible {
1592
1611
  traceSinks: this._config.traceSinks,
1593
1612
  maxRepairAttempts: this._config.maxRepairAttempts,
1594
1613
  onInvalidField: this._config.onInvalidField,
1614
+ instructions: this._config.instructions,
1595
1615
  maxInputChars: this._config.maxInputChars,
1596
1616
  truncate: this._config.truncate,
1597
1617
  preprocess: this._config.preprocess
@@ -1676,6 +1696,7 @@ export {
1676
1696
  field,
1677
1697
  isCoerceInput,
1678
1698
  isSource,
1699
+ normalizeInstructions,
1679
1700
  partialCoerce,
1680
1701
  partialCoerceWithProvenance,
1681
1702
  provenanceInstructions,