@nodaro/prompts 1.34.0 → 1.36.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.
@@ -42,6 +42,7 @@ import {
42
42
  import { REF_BINDING } from "./ref-binding.js"
43
43
  import { resolveRefIdTokens } from "./ref-id-tokens.js"
44
44
  import { insertBeforeStyleSection } from "./prompt-style-section.js"
45
+ import { tidyReferenceTokenGaps, unboundReferenceTokenText } from "./unbound-reference-tokens.js"
45
46
 
46
47
  // The binding surface string and the id-addressed token resolver live in their
47
48
  // own modules (see them for the contracts); re-exported here so every existing
@@ -76,19 +77,22 @@ const REFERENCE_TOKEN_RE = /\{(image|video|audio):(\d+)(?::([a-zA-Z0-9_ -]+))?\}
76
77
  * - `N < 1` or `N > counts[kind]` (out of range / no such reference) → drop to
77
78
  * the bare `label` (or empty if label-less). This is the legacy
78
79
  * `stripVideoImageTokens` strip behavior: drop the token, keep the label text.
80
+ * The rendering is `unboundReferenceTokenText` — shared with the image prompt
81
+ * builder, which applies the same rule to its own unwired `{image:N}` tokens.
79
82
  * - in range, label present → `REF_BINDING[kind](label, N)`
80
83
  * (e.g. `the person from @image_2`).
81
84
  * - in range, no label → the bare `@${kind}_${N}` (the ref-only default): the
82
85
  * binding lands with no descriptive wrapper.
83
86
  *
84
87
  * Runs of 2+ HORIZONTAL whitespace (left behind by a dropped label-less token)
85
- * collapse to one space, the result is trimmed, and an empty result becomes
86
- * `undefined` — matching the `stripVideoImageTokens` contract so this can replace
87
- * it cleanly. The collapse class is `[^\S\r\n]` (NOT `\s`) on purpose: Task 2.4
88
- * applies this to the FULLY-ASSEMBLED core prompt, which carries `\n\n` block
89
- * separators between the "Use these characters:" directive block and the body —
90
- * a `\s{2,}` collapse would silently merge those paragraphs. Horizontal-only
91
- * collapse preserves newline structure while still tidying the dropped-token gap.
88
+ * collapse to one space, the result is trimmed (`tidyReferenceTokenGaps`, also
89
+ * shared with the image builder), and an empty result becomes `undefined` —
90
+ * matching the `stripVideoImageTokens` contract so this can replace it cleanly.
91
+ * The collapse class is `[^\S\r\n]` (NOT `\s`) on purpose: the core applies this
92
+ * to the FULLY-ASSEMBLED prompt, which carries `\n\n` block separators between
93
+ * the "Use these characters:" directive block and the body — a `\s{2,}` collapse
94
+ * would silently merge those paragraphs. Horizontal-only collapse preserves
95
+ * newline structure while still tidying the dropped-token gap.
92
96
  * The `kind` is lowercased before indexing `counts`/`REF_BINDING`, so a
93
97
  * case-variant token (`{Image:1}`) resolves to the same binding rather than
94
98
  * mis-classifying as out-of-range.
@@ -98,19 +102,15 @@ export function resolveReferenceTokens(
98
102
  counts: ReferenceCounts,
99
103
  ): string | undefined {
100
104
  if (!prompt) return prompt
101
- return (
102
- prompt
103
- .replace(REFERENCE_TOKEN_RE, (_match, rawKind: string, nStr: string, label?: string) => {
104
- const kind = rawKind.toLowerCase() as keyof ReferenceCounts
105
- const n = parseInt(nStr, 10)
106
- if (n < 1 || n > counts[kind]) return label ?? ""
107
- if (label) return REF_BINDING[kind](label, n)
108
- return `@${kind}_${n}`
109
- })
110
- // Horizontal whitespace only — preserve `\n` / `\n\n` block separators.
111
- .replace(/[^\S\r\n]{2,}/g, " ")
112
- .trim() || undefined
113
- )
105
+ return tidyReferenceTokenGaps(
106
+ prompt.replace(REFERENCE_TOKEN_RE, (_match, rawKind: string, nStr: string, label?: string) => {
107
+ const kind = rawKind.toLowerCase() as keyof ReferenceCounts
108
+ const n = parseInt(nStr, 10)
109
+ if (n < 1 || n > counts[kind]) return unboundReferenceTokenText(label)
110
+ if (label) return REF_BINDING[kind](label, n)
111
+ return `@${kind}_${n}`
112
+ }),
113
+ ) || undefined
114
114
  }
115
115
 
116
116