@windyroad/voice-tone 0.9.2-preview.1255 → 0.9.3-preview.1264

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.
@@ -145,5 +145,5 @@
145
145
  }
146
146
  },
147
147
  "name": "wr-voice-tone",
148
- "version": "0.9.2"
148
+ "version": "0.9.3"
149
149
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wr-voice-tone",
3
- "version": "0.9.2",
3
+ "version": "0.9.3",
4
4
  "description": "Voice, tone, and external-communications governance",
5
5
  "author": {
6
6
  "name": "Windy Road Technology",
@@ -88,24 +88,43 @@ print(hashlib.sha256((draft + '\n' + surface).encode('utf-8')).hexdigest())
88
88
  derive_external_comms_key_from_prompt() {
89
89
  local prompt="$1"
90
90
  [ -n "$prompt" ] || { echo ""; return 0; }
91
- # Extract SURFACE + <draft> body in one pass. The two fields are emitted
92
- # \x1f-separated (ASCII unit separator) so a body containing newlines — or
93
- # an empty body — round-trips through command substitution intact (only
94
- # trailing newlines are dropped, which compute_external_comms_key rstrips
95
- # anyway). Empty output when either marker is absent → empty key.
91
+ # Extract the last valid SURFACE + <draft> pair. Codex completion payloads
92
+ # may prefix the caller prompt with the custom agent's developer
93
+ # instructions, which themselves mention illustrative <draft> markers.
94
+ # A pair is valid only when the draft envelope follows the SURFACE line
95
+ # without intervening non-whitespace prose, and the SURFACE line is not
96
+ # itself inside another draft envelope. Scanning valid candidates from
97
+ # right to left selects the caller's trailing prompt rather than a decoy
98
+ # in the prefixed instructions.
99
+ #
100
+ # The two fields are emitted \x1f-separated (ASCII unit separator) so a
101
+ # body containing newlines — or an empty body — round-trips through command
102
+ # substitution intact (only trailing newlines are dropped, which
103
+ # compute_external_comms_key rstrips anyway). Empty output when no valid
104
+ # pair is present → empty key.
96
105
  local extracted
97
106
  extracted=$(printf '%s' "$prompt" | python3 -c "
98
107
  import sys, re
99
108
  text = sys.stdin.read()
100
- # DRAFT: non-greedy match between <draft>...</draft>, tolerating an optional
101
- # newline immediately after <draft> and before </draft>.
102
- draft_match = re.search(r'<draft>\n?(.*?)\n?</draft>', text, re.DOTALL)
103
- # SURFACE: anchored to line start (MULTILINE) so prose like 'context says
104
- # SURFACE: x' does not match. Surface name is a single letter+word/hyphen token.
105
- surface_match = re.search(r'^SURFACE:\s*([A-Za-z][\w-]*)', text, re.MULTILINE)
106
- if not draft_match or not surface_match:
107
- sys.exit(0)
108
- sys.stdout.write(surface_match.group(1) + '\x1f' + draft_match.group(1))
109
+ surface_pattern = re.compile(
110
+ r'^SURFACE:\s*([A-Za-z][\w-]*)[^\r\n]*(?:\r?\n|$)',
111
+ re.MULTILINE,
112
+ )
113
+ for surface_match in reversed(list(surface_pattern.finditer(text))):
114
+ prefix = text[:surface_match.start()]
115
+ # Reject a SURFACE line quoted inside an existing draft body.
116
+ if prefix.rfind('<draft>') > prefix.rfind('</draft>'):
117
+ continue
118
+ remainder = text[surface_match.end():]
119
+ draft_match = re.match(
120
+ r'[ \t\r\n]*<draft>\r?\n?(.*?)\r?\n?</draft>',
121
+ remainder,
122
+ re.DOTALL,
123
+ )
124
+ if not draft_match:
125
+ continue
126
+ sys.stdout.write(surface_match.group(1) + '\x1f' + draft_match.group(1))
127
+ break
109
128
  " 2>/dev/null) || extracted=""
110
129
  [ -n "$extracted" ] || { echo ""; return 0; }
111
130
  local surface="${extracted%%$'\x1f'*}"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@windyroad/voice-tone",
3
- "version": "0.9.2-preview.1255",
3
+ "version": "0.9.3-preview.1264",
4
4
  "description": "Voice and tone enforcement for user-facing copy",
5
5
  "bin": {
6
6
  "windyroad-voice-tone": "./bin/install.mjs"