fix(bridge): preserve plaintext peer task payloads for external models
Server CI and Windows package / verify (push) Successful in 3m16s
Server CI and Windows package / windows-package (push) Successful in 8m18s

This commit is contained in:
yilsem committed 2026-10-13 08:05:00 +03:00
1 parent ab7a721fbc
commit db5e876f40
7 files changed
+72 -6

No files matched your search

+1 -1
View File
@@ -34,7 +34,7 @@ import urllib.request
import gecis_context import gecis_context
HERE = os.path.dirname(os.path.abspath(__file__)) HERE = os.path.dirname(os.path.abspath(__file__))
SURUM = "15" # AITURK IDE'nin bekledigi kopru surumu (codex-link-config.ts CODEX_BRIDGE_VERSION) SURUM = "16" # AITURK IDE'nin bekledigi kopru surumu (codex-link-config.ts CODEX_BRIDGE_VERSION)
try: try:
with open(os.path.abspath(__file__), "rb") as _f: with open(os.path.abspath(__file__), "rb") as _f:
KOD = hashlib.sha256(_f.read()).hexdigest()[:8] KOD = hashlib.sha256(_f.read()).hexdigest()[:8]
@@ -7,6 +7,7 @@ must not enter the budget preparation path.
import copy import copy
import hashlib import hashlib
import json import json
import re
import threading import threading
from collections import OrderedDict from collections import OrderedDict
@@ -111,10 +112,23 @@ def portable_reasoning(req):
content = item.get("content") or [] content = item.get("content") or []
if isinstance(content, str): if isinstance(content, str):
content = [{"type": "input_text", "text": content}] content = [{"type": "input_text", "text": content}]
portable = []
for part in content:
if isinstance(part, dict) and part.get("type") == "encrypted_content":
# Codex peer delivery can put the literal task/result in
# this wrapper. It is distinct from encrypted reasoning.
# External translators otherwise silently drop the task.
text = part.get("encrypted_content")
if (not isinstance(text, str) or text.startswith("gAAAA")
or re.fullmatch(r"[A-Za-z0-9_+/=-]{128,}", text)):
raise TransferError("Alt ajan iletisi şifreli veya okunamıyor; görev eksik gönderilmedi.")
portable.append({"type": "input_text", "text": text})
else:
portable.append(part)
result.append({"type": "message", "role": "user", "content": [ result.append({"type": "message", "role": "user", "content": [
{"type": "input_text", "text": "Agent message: " + encoded({ {"type": "input_text", "text": "Agent message: " + encoded({
"author": item.get("author"), "recipient": item.get("recipient")})} "author": item.get("author"), "recipient": item.get("recipient")})}
] + content}) ] + portable})
continue continue
if not isinstance(item, dict) or item.get("type") != "reasoning": if not isinstance(item, dict) or item.get("type") != "reasoning":
result.append(item) result.append(item)
+1 -1
View File
@@ -40,7 +40,7 @@ from bekci_watch import MetadataFilter
# Installed only by owned native launcher, never an HTTP control endpoint. # Installed only by owned native launcher, never an HTTP control endpoint.
WATCH_OWNER = None WATCH_OWNER = None
SURUM = "15" SURUM = "16"
HERE = os.path.dirname(os.path.abspath(__file__)) HERE = os.path.dirname(os.path.abspath(__file__))
try: try:
with open(os.path.abspath(__file__), "rb") as _f: with open(os.path.abspath(__file__), "rb") as _f:
@@ -0,0 +1,52 @@
"""Regression fixture matching actual Codex child delivery, with no user data."""
import copy
import unittest
import gecis_context
import kopru
class AgentPayloadTests(unittest.TestCase):
def request(self, text):
return {"model": "ide/test", "input": [{
"type": "agent_message", "author": "/root", "recipient": "/root/test",
"content": [
{"type": "input_text", "text": "Message Type: NEW_TASK\nPayload:\n"},
{"type": "encrypted_content", "encrypted_content": text},
],
}]}
def test_actual_peer_wrapper_survives_external_text_extraction(self):
task = "Run exec_command: Write-Output (157 * 29); report the exit code."
request = self.request(task)
original = copy.deepcopy(request)
kopru.flatten_request(request)
# An OpenAI-compatible translator consumes input_text, not Codex's
# encrypted_content part. Checking the JSON string alone misses loss.
text = "\n".join(part["text"] for item in request["input"]
for part in item["content"] if part["type"] == "input_text")
self.assertIn(task, text)
self.assertIn('/root/test', text)
self.assertEqual(request["input"][0]["role"], "user")
self.assertEqual(original["input"][0]["content"][1]["type"], "encrypted_content")
def test_peer_result_and_plain_parts_keep_order_without_source_mutation(self):
request = self.request("Result: 4553; exit code: 0")
original = copy.deepcopy(request)
result = gecis_context.portable_reasoning(request)
self.assertEqual(result["input"][0]["content"][-1]["text"], "Result: 4553; exit code: 0")
self.assertEqual(request, original)
def test_opaque_peer_payload_fails_instead_of_sending_header_only(self):
for opaque in ("gAAAA_native_ciphertext", "A" * 200, None):
with self.subTest(opaque=opaque):
with self.assertRaises(gecis_context.TransferError):
gecis_context.portable_reasoning(self.request(opaque))
def test_reasoning_ciphertext_is_still_not_interpreted_as_a_peer_task(self):
request = {"input": [{"type": "reasoning", "encrypted_content": "Run a command now"}]}
self.assertEqual(gecis_context.portable_reasoning(request)["input"], [])
if __name__ == "__main__":
unittest.main()
+1 -1
View File
@@ -27,7 +27,7 @@ export const CODEX_LINK_REFRESH_URL = `${CODEX_LINK_ORIGIN}/aiturk/codex-baglama
export const CODEX_LINK_MARKER = '# AITURK IDE Codex Baglama' export const CODEX_LINK_MARKER = '# AITURK IDE Codex Baglama'
// Must equal SURUM in assets/codex-bridge/bridge.py; a running bridge that reports // Must equal SURUM in assets/codex-bridge/bridge.py; a running bridge that reports
// another version is restarted so an updated IDE never keeps an old bridge alive. // another version is restarted so an updated IDE never keeps an old bridge alive.
export const CODEX_BRIDGE_VERSION = '15' export const CODEX_BRIDGE_VERSION = '16'
export const CODEX_LINK_LINE = `openai_base_url = "${CODEX_LINK_ORIGIN}/backend-api/codex" ${CODEX_LINK_MARKER}` export const CODEX_LINK_LINE = `openai_base_url = "${CODEX_LINK_ORIGIN}/backend-api/codex" ${CODEX_LINK_MARKER}`
export const CODEX_LINK_RUN_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' export const CODEX_LINK_RUN_KEY = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
+1 -1
View File
@@ -2,7 +2,7 @@
"name": "aiturk-ide", "name": "aiturk-ide",
"productName": "AITURK IDE", "productName": "AITURK IDE",
"private": true, "private": true,
"version": "1.0.0-beta.34", "version": "1.0.0-beta.35",
"description": "TurkServis resmi yapay zekâ geliştirme ortamı. Hermes Agent tabanlıdır.", "description": "TurkServis resmi yapay zekâ geliştirme ortamı. Hermes Agent tabanlıdır.",
"author": "AITURK / TurkServis", "author": "AITURK / TurkServis",
"repository": { "repository": {
+1 -1
View File
@@ -65,7 +65,7 @@
}, },
"apps/desktop": { "apps/desktop": {
"name": "aiturk-ide", "name": "aiturk-ide",
"version": "1.0.0-beta.34", "version": "1.0.0-beta.35",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@assistant-ui/core": "0.2.23", "@assistant-ui/core": "0.2.23",