Skip to content

Commit d97d089

Browse files
committed
v67: answer current questions, recover incomplete chat without actions and verify private HTTPS readiness
1 parent f7a301c commit d97d089

15 files changed

Lines changed: 642 additions & 16 deletions

‎SYNTA_V67.md‎

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Synta v67
2+
3+
Current-activity questions such as "to co dokładnie robisz, szczegóły, teraz"
4+
read recorded jobs, their complete assignments, record age, plans and recent
5+
action receipts directly. They do not enter a model work loop or change plans.
6+
Loss complaints return financial evidence without inventing a market cause.
7+
Replay reproducibility is distinct from independent price validation.
8+
9+
A standalone work request no longer inherits three previous conversations.
10+
Only an explicit "do it" follow-up can carry the previous exchange. The current
11+
request takes priority. Long prose ending mid-sentence is rejected even when a
12+
JSON grammar reports stop. One bounded, concise recovery may summarize genuine
13+
receipts, without rerunning tools or applying proposed control actions. Unknown
14+
finish reasons cannot authorize tool execution. This is a targeted validation
15+
rule, not a guarantee that every plausible complete answer is factually correct.
16+
17+
Upgrade archives old informational questions that created short/mid plans,
18+
restores a plan only if that exact version is still current, and requeues the
19+
question through the repaired route. Later operator plans and goals are retained.
20+
Previously executed tools cannot be undone by changing a response record.
21+
22+
Remote setup now distinguishes configured URLs from ready routing. A phone
23+
sign-in is insufficient: Tailscale HTTPS/Serve must be approved by the owner.
24+
The installer checks the gateway, exact private proxy, DNS origin and existing
25+
LAN dashboard before reporting readiness. It retains owner-only authentication
26+
and refuses public Funnel. Local checks do not prove the iPhone can reach it.
27+
28+
Adaptive GPU status includes the request source, actor, request ID, model and
29+
start/end timestamps. It separates Debian requests from Windows local/startup
30+
checks. These are transport receipts, not evidence of training or useful output.
31+
Existing CPU/RTX admission controls remain: browsers allowed, one inference,
32+
65/35/20 percent active-time targets, host load/temperature/RAM/VRAM/observed
33+
power checks. No global hardware limits or clocks are changed.
34+
35+
Validation includes question routing, recovery without tool duplication, exact
36+
plan restoration, standalone context isolation, missing Serve readiness and
37+
GPU proxy receipts. Full regression and lint results accompany publication.
38+
Actual Windows tasks, phone access and thermals cannot be tested on this host.

‎pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ name = "rlms"
33
authors = [
44
{name = "Alex Zhang", email = "altzhang@mit.edu"},
55
]
6-
version = "0.1.3+v100.66"
6+
version = "0.1.3+v100.67"
77
description = "Recursive Language Models."
88
readme = "README.md"
99
license = "MIT"

‎rlm/v100/agent.py‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ def native_turn(
101101
max_tokens=payload["max_tokens"],
102102
total_completion_tokens=completion_tokens,
103103
)
104+
if choice.get("finish_reason") not in ("stop", "eos", "tool_calls", "length"):
105+
raise ValueError(
106+
"Model response has an unconfirmed finish reason; no answer or tool action accepted"
107+
)
104108
if choice.get("finish_reason") != "length":
105109
return choice["message"]
106110
if attempts >= 3 or payload["max_tokens"] >= ceiling:

‎rlm/v100/chat_facts.py‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def language(message: str) -> str:
2020
def requested(message: str) -> bool:
2121
return bool(
2222
re.search(
23-
r"zarab|zarob|strateg|income|profit|backtest|minus|paper|opportunit|candidate|brier|kandydat|drawdown|obsunie|odchylen|glitch",
23+
r"zarab|zarob|tracisz|przegrywasz|strateg|income|profit|backtest|minus|paper|opportunit|candidate|brier|kandydat|drawdown|obsunie|odchylen|glitch",
2424
normalized(message),
2525
)
2626
)
@@ -75,6 +75,11 @@ def response(root: Path, message: str) -> dict:
7575
)
7676
else:
7777
lines.append("Audit: unavailable; no source integrity claim accepted")
78+
lines.append(
79+
"Powtarzalność obliczeń nie potwierdza prawdziwości cen u niezależnego dostawcy ani przyczyny strat. Nie mam podstaw, aby przypisać je konkretnemu trendowi bez analizy śladu transakcji. Ta odpowiedź nie zmienia strategii ani planu."
80+
if pl
81+
else "Replay reproducibility does not establish independent price accuracy or a cause of losses. A causal explanation needs execution-trace analysis. This answer changes no strategy or plan."
82+
)
7883
for row in value.get("recent_exploratory_backtests", []):
7984
net = row.get("development_test", {}).get("net_return")
8085
lines.append(

‎rlm/v100/chat_progress.py‎

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import json
44
import re
5+
import time
56
from pathlib import Path
67

78
from rlm.v100.chat_goals import normalized
@@ -11,7 +12,7 @@ def requested(message: str) -> bool:
1112
text = normalized(message)
1213
return bool(
1314
re.search(
14-
r"co (?:teraz |aktualnie )?robisz|jaki (?:jest )?(?:postep|progres)|czego sie nauczyl|czy .*uczysz sie|czy uczysz sie|learn.*continuously|what have you learned|what are you doing",
15+
r"co (?:(?:teraz|aktualnie|dokladnie|konkretnie|obecnie) )*robisz|co .*robicie|jaki (?:jest )?(?:postep|progres)|czego sie nauczyl|czy .*uczysz sie|czy uczysz sie|learn.*continuously|what have you learned|what (?:exactly )?are you doing",
1516
text,
1617
)
1718
) and not re.search(r"\b(?:zmien|dodaj|napraw|zrob|wdroz|zaimplementuj)\b", text)
@@ -118,10 +119,72 @@ def metric(value):
118119
+ str(error)[:200]
119120
)
120121
lines.append(wording("Przebieg: ", "Run: ") + str(evidence["run"]))
122+
from rlm.v100.drones import inspect
123+
from rlm.v100.live_status import recent_events
124+
from rlm.v100.planning import read
125+
126+
jobs = inspect(root)
127+
now = time.time()
128+
lines.append(wording("Odczyt statusu UTC: ", "Status read UTC: ") + str(now))
129+
for row in jobs:
130+
if row["state"] not in ("running", "queued"):
131+
continue
132+
age = max(0, now - row["updated"]) if row["updated"] else None
133+
lines.append(
134+
f"{row['kind']} / {row['branch']} / {row['id']}: {row['state']} | "
135+
+ wording("wiek zapisu: ", "record age: ")
136+
+ (f"{age:.0f}s" if age is not None else "unknown")
137+
+ "\n"
138+
+ row["assignment"]
139+
)
140+
if not any(row["state"] == "running" for row in jobs):
141+
lines.append(
142+
wording(
143+
"Brak dronów oznaczonych jako wykonujące zadanie.", "No drones recorded as running."
144+
)
145+
)
146+
plans = read(root)
147+
for horizon in ("short", "mid"):
148+
plan = plans.get(horizon) or {}
149+
lines.append(
150+
f"Plan {horizon} [{plan.get('id', 'unknown')}]: {plan.get('text', 'unavailable')}"
151+
)
152+
events = recent_events(root, 200)
153+
observed = [
154+
event
155+
for event in events
156+
if event.get("kind")
157+
in (
158+
"inference-start",
159+
"inference-finished",
160+
"inference-failed",
161+
"tool-start",
162+
"tool-result",
163+
)
164+
][-8:]
165+
lines.append(
166+
wording(
167+
"Ostatnie zapisane akcje (historia, nie dowód bieżącej pracy):",
168+
"Latest recorded actions (history, not proof of current work):",
169+
)
170+
)
171+
for event in observed:
172+
lines.append(
173+
f"{event.get('time')} | {event.get('actor')} | {event.get('kind')} | {event.get('tool', '')} | {event.get('summary', '')}"
174+
)
175+
if not observed:
176+
lines.append(
177+
wording(
178+
"Brak zarejestrowanych akcji w odczytanym oknie.",
179+
"No recorded actions in the read window.",
180+
)
181+
)
121182
return {
122183
"answer": "\n".join(lines),
123184
"actions": [],
124185
"applied": [],
125186
"evidence": evidence,
187+
"observed_jobs": jobs,
188+
"observed_actions": observed,
126189
"responder": {"model": "controller-status", "delegated_while_master_busy": False},
127190
}

‎rlm/v100/chat_recovery.py‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
"""Upgrade-only repair of plans created while answering an informational question."""
2+
3+
import json
4+
import re
5+
from pathlib import Path
6+
7+
from rlm.v100.common import atomic_json
8+
9+
10+
def repair(root: Path) -> dict:
11+
from rlm.v100.mission import status
12+
from rlm.v100.mission_chat import connect, conversation_question
13+
14+
if status(root)["running"]:
15+
raise ValueError("Stop the mission before recovering chat-created plans")
16+
directory = root / "research/state/chat-question-repairs"
17+
repaired = []
18+
with connect(root) as db:
19+
rows = db.execute(
20+
"SELECT * FROM requests WHERE state='completed' ORDER BY rowid DESC LIMIT 500"
21+
).fetchall()
22+
for row in rows:
23+
if not conversation_question(row["message"]):
24+
continue
25+
response = json.loads(row["response"])
26+
receipts = [
27+
r for r in response.get("applied", []) if r.get("horizon") in ("short", "mid")
28+
]
29+
if not receipts:
30+
continue
31+
if not re.fullmatch(r"[a-f0-9]{32}", row["id"]):
32+
raise ValueError("Invalid archived question identity")
33+
archive = directory / (row["id"] + ".json")
34+
if archive.exists():
35+
continue
36+
path = root / "research/plans/current.json"
37+
plans = json.loads(path.read_text()) if path.exists() else {}
38+
restored = []
39+
for receipt in receipts:
40+
horizon, identity = receipt["horizon"], receipt.get("id", "")
41+
if (
42+
not re.fullmatch(r"[a-f0-9]{32}", identity)
43+
or plans.get(horizon, {}).get("id") != identity
44+
):
45+
continue
46+
version = json.loads((root / "research/plans" / (identity + ".json")).read_text())
47+
previous = version.get("previous") or {}
48+
# A later goal change must not resurrect an unrelated earlier goal's plan.
49+
if previous.get("goal_id") not in (None, plans[horizon].get("goal_id")):
50+
continue
51+
plans[horizon] = previous
52+
restored.append(horizon)
53+
atomic_json(
54+
archive,
55+
{
56+
"request": dict(row),
57+
"restored_plans": restored,
58+
"scope": "Question-created plan reverted only if its exact ID is still active; later plans and original evidence retained.",
59+
},
60+
)
61+
if restored:
62+
atomic_json(
63+
archive.with_name(row["id"] + "-plans-before.json"),
64+
json.loads(path.read_text()),
65+
)
66+
atomic_json(path, plans)
67+
db.execute(
68+
"UPDATE requests SET state='queued',response=NULL,attempts=0,error=NULL,updated=0,wait_started=0 WHERE id=?",
69+
(row["id"],),
70+
)
71+
repaired.append({"id": row["id"], "restored_plans": restored, "archive": str(archive)})
72+
return {"requeued_questions": repaired, "long_term_goal_changed": False}

‎rlm/v100/chat_resources.py‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ def status(root: Path) -> dict:
8181
"active_request_target_percent": client.helper_duty_percent,
8282
"scope": "Inference/vision helper, request pacing; not a hard GPU utilization/power cap",
8383
}
84+
if profile.get("resources", {}).get("require_adaptive_windows_guard"):
85+
value["helper"]["admission"] = client.remote_request("/api/synta-resources")
8486
except (OSError, ValueError, RuntimeError, requests.RequestException) as error:
8587
value["helper"] = {"reachable": False, "error": str(error)[:300]}
8688
return value

0 commit comments

Comments
 (0)