Release macOS 1.0.4: exclude prompt and source wrappers from document output
Browse files- macos/AFFECTOR-ARC-Desktop-source.zip +2 -2
- macos/AFFECTOR-ARC-macOS15.zip +2 -2
- macos/README.md +7 -3
- macos/remote_agent.py +25 -2
macos/AFFECTOR-ARC-Desktop-source.zip
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:96dc1ac1c32a42d54c003dd95f300e3fd570b8bce59749f0d5b58a9380af96a4
|
| 3 |
+
size 37053
|
macos/AFFECTOR-ARC-macOS15.zip
CHANGED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:06fe963daab36aacf1764ce1c5b674e7933471c27968571ae68d76474af44d9d
|
| 3 |
+
size 389942
|
macos/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
# AFFECTOR ARC for macOS 15+ — version 1.0.
|
| 2 |
|
| 3 |
Native SwiftUI frontend for Apple Silicon Macs. It manages SSH, Hugging Face source updates, Slurm GPU setup, document rewriting, shape conversion/editing, job monitoring, and output downloads.
|
| 4 |
|
|
@@ -6,7 +6,11 @@ Native SwiftUI frontend for Apple Silicon Macs. It manages SSH, Hugging Face sou
|
|
| 6 |
- **AFFECTOR-ARC-Desktop-source.zip**: full editable Swift project, tests, remote agent, and build instructions.
|
| 7 |
- **remote_agent.py**: stdlib SSH request agent bundled with the app; no listening server.
|
| 8 |
|
| 9 |
-
## Changes in 1.0.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
- Keep TINKERCLIFFS CONNECTED fixed while connected, including during job polling.
|
| 12 |
- Retain transformed text when changing tabs or job-list selection.
|
|
@@ -16,7 +20,7 @@ Native SwiftUI frontend for Apple Silicon Macs. It manages SSH, Hugging Face sou
|
|
| 16 |
- Keep diagnostics and review counts in Jobs + results. The transformed-text field stays empty until generated text is available.
|
| 17 |
- Use a normal-width system font for ARC at the same size and weight; preserve AFFECTOR.
|
| 18 |
|
| 19 |
-
The installed app was visually verified with a completed ARC rewrite. Swift core and result-recovery tests and all
|
| 20 |
|
| 21 |
## Connection
|
| 22 |
|
|
|
|
| 1 |
+
# AFFECTOR ARC for macOS 15+ — version 1.0.4
|
| 2 |
|
| 3 |
Native SwiftUI frontend for Apple Silicon Macs. It manages SSH, Hugging Face source updates, Slurm GPU setup, document rewriting, shape conversion/editing, job monitoring, and output downloads.
|
| 4 |
|
|
|
|
| 6 |
- **AFFECTOR-ARC-Desktop-source.zip**: full editable Swift project, tests, remote agent, and build instructions.
|
| 7 |
- **remote_agent.py**: stdlib SSH request agent bundled with the app; no listening server.
|
| 8 |
|
| 9 |
+
## Changes in 1.0.4
|
| 10 |
+
|
| 11 |
+
Separate an explicit rewritten/attempt section from source/prompt wrappers emitted inside a model response. Exclude reasoning blocks, trailing diagnostics, and known prompt-commentary-only responses from the document field. Keep raw responses in the report. Verified against job 8680066 and inspected the installed app's displayed text.
|
| 12 |
+
|
| 13 |
+
## Changes retained from 1.0.3
|
| 14 |
|
| 15 |
- Keep TINKERCLIFFS CONNECTED fixed while connected, including during job polling.
|
| 16 |
- Retain transformed text when changing tabs or job-list selection.
|
|
|
|
| 20 |
- Keep diagnostics and review counts in Jobs + results. The transformed-text field stays empty until generated text is available.
|
| 21 |
- Use a normal-width system font for ARC at the same size and weight; preserve AFFECTOR.
|
| 22 |
|
| 23 |
+
The installed app was visually verified with a completed ARC rewrite. Swift core and result-recovery tests and all 14 remote-agent tests pass. Initial live GPU setup passed the seven upstream tests on an NVIDIA A100-SXM4-80GB, and a sample rewrite completed successfully.
|
| 24 |
|
| 25 |
## Connection
|
| 26 |
|
macos/remote_agent.py
CHANGED
|
@@ -100,9 +100,28 @@ def scheduler(q, root, kind, payload=None):
|
|
| 100 |
record={'id':identity,'job_id':jid,'kind':kind,'created_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'release':release.name,'directory':str(d),'account':account,'partition':partition}
|
| 101 |
atomic(d/'job.json',record); return record
|
| 102 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 103 |
def transformed_text(report):
|
| 104 |
records=report.get('records')
|
| 105 |
-
if not isinstance(records,dict):return report.get('text','')
|
| 106 |
spans=report.get('spans',[]);source=report.get('input','');parts=[];previous=None
|
| 107 |
for index in sorted(int(k) for k in records if str(k).isdigit()):
|
| 108 |
record=records[str(index)];text=record.get('text','')
|
|
@@ -113,7 +132,11 @@ def transformed_text(report):
|
|
| 113 |
a,b=spans[previous][1],spans[index][0]
|
| 114 |
if 0<=a<=b<=len(source) and not source[a:b].strip():gap=source[a:b]
|
| 115 |
parts.append(gap)
|
| 116 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 117 |
return ''.join(parts)
|
| 118 |
|
| 119 |
def dispatch(q):
|
|
|
|
| 100 |
record={'id':identity,'job_id':jid,'kind':kind,'created_at':datetime.datetime.now(datetime.timezone.utc).isoformat(),'release':release.name,'directory':str(d),'account':account,'partition':partition}
|
| 101 |
atomic(d/'job.json',record); return record
|
| 102 |
|
| 103 |
+
|
| 104 |
+
def response_text(text):
|
| 105 |
+
if not isinstance(text,str):return ''
|
| 106 |
+
text=re.sub(r'<think>[\s\S]*?</think>\s*','',text,flags=re.I)
|
| 107 |
+
if re.search(r'<think>',text,re.I):return ''
|
| 108 |
+
label=r'(?:transformed(?:\s+(?:text|passage|document))?|rewritten(?:\s+(?:text|passage|document))?|rewrite|revised(?:\s+(?:text|passage|document))?|final(?:\s+(?:answer|text))?|attempt|output)'
|
| 109 |
+
pattern=r'(?im)^\s*(?:\#{1,6}\s*)?(?:here is (?:the |a )?)?(?:\*\*)?'+label+r'(?:\*\*)?\s*:\s*(?:\*\*)?[^\S\r\n]*'
|
| 110 |
+
matches=list(re.finditer(pattern,text))
|
| 111 |
+
if matches:
|
| 112 |
+
text=text[matches[-1].end():]
|
| 113 |
+
suffix=re.search(r'(?im)^\s*(?:\#{1,6}\s*)?(?:\*\*)?(?:original(?:\s+(?:text|target|passage))?|source(?:\s+text)?|prompt|target|instructions?|explanation|notes?)(?:\*\*)?\s*:',text)
|
| 114 |
+
if suffix:text=text[:suffix.start()]
|
| 115 |
+
elif re.search(r'(?im)^\s*(?:\#{1,6}\s*)?(?:\*\*)?(?:original(?:\s+(?:text|target|passage))?|source\s+text|prompt|target)(?:\*\*)?\s*:',text):return ''
|
| 116 |
+
text=text.strip()
|
| 117 |
+
if text.startswith('```') and text.endswith('```'):
|
| 118 |
+
lines=text.splitlines();text='\n'.join(lines[1:-1]).strip()
|
| 119 |
+
if re.match(r"(?is)^(?:the prompt (?:asks|requests|requires|instructs)|this is (?:a |an )?prohibited attempt|i (?:cannot|can't|am unable to) (?:rewrite|comply with|fulfill this request))\b",text):return ''
|
| 120 |
+
return text
|
| 121 |
+
|
| 122 |
def transformed_text(report):
|
| 123 |
records=report.get('records')
|
| 124 |
+
if not isinstance(records,dict):return response_text(report.get('text',''))
|
| 125 |
spans=report.get('spans',[]);source=report.get('input','');parts=[];previous=None
|
| 126 |
for index in sorted(int(k) for k in records if str(k).isdigit()):
|
| 127 |
record=records[str(index)];text=record.get('text','')
|
|
|
|
| 132 |
a,b=spans[previous][1],spans[index][0]
|
| 133 |
if 0<=a<=b<=len(source) and not source[a:b].strip():gap=source[a:b]
|
| 134 |
parts.append(gap)
|
| 135 |
+
clean=response_text(text)
|
| 136 |
+
if not clean:
|
| 137 |
+
if previous is not None:parts.pop()
|
| 138 |
+
continue
|
| 139 |
+
parts.append(clean);previous=index
|
| 140 |
return ''.join(parts)
|
| 141 |
|
| 142 |
def dispatch(q):
|