Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ OpenCodex n'insère pas dans ce prompt de clés d'API de fournisseur, d'en-tête

Le conseil manuel est le résultat d'outil de l'appel `advisor` que le worker a lui-même émis. Ce résultat est un objet JSON. Le champ `advice` est le texte du modèle conseiller. Le champ `status` est écrit par le runtime.

Lors des tours de recherche web basés sur fetch, la boucle de recherche n'expose l'outil synthétique `advisor` et n'intercepte ses appels de consultation manuelle que si le `tool_choice` effectif l'autorise. Un choix `allowed_tools` limité à `web_search` exclut les consultations manuelles du conseiller. Activer la recherche hébergée n'élargit pas cette autorisation.

Le conseil automatique est un objet JSON cité dans un message consultatif de rôle user distinct. Seule l’instruction fixe du runtime reste dans le message developer ; le texte généré par le conseiller ne passe jamais dans developer/system. Cela fonctionne avec OpenAI Chat et Anthropic sans inventer un appel d’outil. Les guillemets empêchent la rupture structurelle et les champs falsifiés, pas toute injection en langage naturel. Un protocole dédié pourrait mieux distinguer le conseil d’une demande utilisateur. Chaque requête permet au plus trois consultations et quatre continuations du worker. À la limite, l’outil advisor est retiré ; un nouvel appel reçoit une dernière continuation avec un résultat de limite, puis un autre appel termine avec 502 advisor_continuation_limit sans nouvel envoi. La limite est partagée avec les reprises de complétion vide.

La suppression ne lit pas les chaînes du conseiller. Le dédoublonnage automatique appartient au registre du serveur. Un message developer, même s'il recopie le texte de transport, ne supprime pas le preflight.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ OpenCodex はプロバイダー API キー、Authorization ヘッダー、OAuth

手動の助言は、ワーカー自身が行った `advisor` 呼び出しに対するツール結果です。結果は JSON オブジェクトです。`advice` はアドバイザーモデルのテキストです。`status` はランタイムが書きます。

fetch ベースの Web 検索ターンでは、実際に適用される `tool_choice` が合成 `advisor` ツールを許可する場合に限り、検索ループがそのツールを公開し、手動相談の呼び出しを処理します。`allowed_tools` を `web_search` だけに制限すると、アドバイザーへの手動相談は許可されません。ホスト型検索を有効にしても、このツールの許可範囲は広がりません。

自動助言の引用済み JSON は、別の user ロールの助言メッセージで渡します。developer メッセージには固定のランタイム指示だけを残し、アドバイザーの生成文は developer/system に入りません。OpenAI Chat と Anthropic の両方で、偽のツール呼び出しなしに送れます。引用は構造の破壊やフィールドの偽造を防ぎますが、自然言語によるプロンプトインジェクションを完全には防ぎません。専用プロトコルなら通常のユーザー入力と区別しやすくなります。1 リクエストにつき相談は最大 3 回、ワーカー継続は最大 4 回です。上限で advisor ツールを除去し、再呼び出しには上限結果付きの最終継続を 1 回だけ許可します。さらに呼ばれた場合は 502 advisor_continuation_limit で終了し、追加送信しません。空の完了の再試行も同じ上限を共有します。

抑制はアドバイザーの文字列を読みません。自動の重複排除はサーバー所有の台帳だけです。転送文を写した developer メッセージも preflight を抑制しません。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ OpenCodex는 프로바이더 API 키, Authorization 헤더, OAuth 토큰, 백엔

수동 조언은 워커가 직접 호출한 `advisor`에 대한 도구 결과입니다. 결과는 JSON 객체입니다. `advice`는 어드바이저 모델의 텍스트입니다. `status`는 런타임이 씁니다.

fetch 기반 웹 검색 턴에서는 실제 적용되는 `tool_choice`가 합성 `advisor` 도구를 허용할 때만 해당 도구를 노출하고 수동 상담 호출을 가로챕니다. `allowed_tools`가 `web_search`로 제한되어 있으면 어드바이저 수동 상담은 허용되지 않습니다. 호스팅 검색을 활성화해도 이 도구 허용 범위가 넓어지지는 않습니다.

자동 조언의 인용된 JSON은 별도의 user 역할 자문 메시지로 전달합니다. developer 메시지에는 고정된 런타임 지시만 남고, Advisor가 생성한 텍스트는 developer/system에 들어가지 않습니다. OpenAI Chat과 Anthropic 모두 가짜 도구 호출 없이 이를 지원합니다. JSON 인용은 구조 탈출과 필드 위조를 막지만 자연어 프롬프트 주입을 완전히 차단하지는 않습니다. 전용 프로토콜은 일반 사용자 입력과 조언을 더 명확히 구분할 수 있습니다. 요청당 상담은 최대 3회, 워커 이어가기는 최대 4회입니다. 상담 한도에 도달하면 advisor 도구를 제거하고 반복 호출에 한도 결과를 전달하는 마지막 이어가기를 한 번만 허용합니다. 다시 호출하면 추가 전송 없이 502 advisor_continuation_limit로 끝납니다. 빈 완료 재시도도 같은 한도를 공유합니다.

억제는 어드바이저 문자열을 읽지 않습니다. 자동 중복 제거는 서버가 소유한 원장뿐입니다. 전송 문장을 복사한 developer 메시지도 preflight를 억제하지 않습니다.
Expand Down
13 changes: 9 additions & 4 deletions docs-site/src/content/docs/reference/configuration/advisor.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,15 @@ After consultation exhaustion the `advisor` tool is removed. A repeated call rec
paired limit result; if the worker calls it again, typed 502 `advisor_continuation_limit` ends the
request without another hidden worker call. The bound is shared with empty-completion retries.

Fetch-based web-search turns support the same manual consultation path. The search loop intercepts
`web_search` and `advisor` calls in worker order, so enabling hosted search does not hide the
advisor tool. Search and Advisor iterations have separate allowances, and a real client tool call
still returns control to the client. Run-turn and image/video sidecar turns remain subject to their existing limitations.
Fetch-based web-search turns support the same manual consultation path when the effective
`tool_choice` permits the synthetic `advisor` tool. The search loop exposes and intercepts
`advisor` calls only within that scope; an `allowed_tools` choice restricted to `web_search`
excludes manual Advisor consultations. Permitted `web_search` and `advisor` calls are handled in
worker order. Search and Advisor iterations have separate allowances,
and a real client tool call still returns control to the client. Run-turn and image/video sidecar turns remain subject to their existing limitations.
If the worker emits an excluded `advisor` call, the turn fails with `undeclared_tool_call`
before that call reaches the client. A normal client tool named `advisor` remains available
only while the current iteration declares and permits it; a tools-disabled recovery cannot reuse an earlier declaration.
Usage accounting includes each worker turn once, including the leg rejected by the Advisor continuation limit.

Suppression does not read Advisor strings. Automatic dedup is the server-owned ledger. A
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ OpenCodex не вставляет в этот запрос ключи API про

Ручной совет — это результат инструмента для вызова `advisor`, который сделал сам воркер. Результат — объект JSON. Поле `advice` — текст модели консультанта. Поле `status` записывает runtime.

В шагах веб-поиска через fetch цикл поиска предоставляет синтетический инструмент `advisor` и перехватывает вызовы ручной консультации только тогда, когда это разрешает применяемый `tool_choice`. Если `allowed_tools` ограничен `web_search`, ручные консультации Advisor не разрешены. Включение встроенного поиска не расширяет эти разрешения.

Автоматический совет передаётся как экранированный JSON в отдельном консультативном сообщении роли user. В developer остаётся только фиксированная инструкция runtime; сгенерированный консультантом текст никогда не попадает в developer/system. OpenAI Chat и Anthropic поддерживают это без выдуманного вызова инструмента. Экранирование предотвращает структурный выход и подделку полей, но не гарантирует защиту от инструкций на естественном языке. Отдельный протокол мог бы лучше отличать совет от запроса пользователя. На запрос разрешено не более трёх консультаций и четырёх продолжений воркера. При исчерпании консультаций инструмент advisor удаляется; повторный вызов получает одно последнее продолжение с результатом о лимите. Ещё один вызов завершает запрос с 502 advisor_continuation_limit без новой отправки. Повторы пустого завершения используют тот же лимит.

Подавление не читает строки консультанта. Автоматическая дедупликация принадлежит серверному журналу. Сообщение developer, даже скопировавшее текст транспорта, не подавляет preflight.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ OpenCodex bu isteme sağlayıcı API anahtarlarını, Authorization başlıklar

Elle danışma, worker'ın kendisinin yaptığı `advisor` çağrısının araç sonucudur. Sonuç bir JSON nesnesidir. `advice` alanı danışman modelinin metnidir. `status` alanını çalışma zamanı yazar.

fetch tabanlı web arama turlarında arama döngüsü, yalnızca geçerli `tool_choice` izin veriyorsa sentetik `advisor` aracını sunar ve elle danışma çağrılarını yakalar. `allowed_tools` seçimini `web_search` ile sınırlamak, elle danışmaya izin vermez. Barındırılan aramayı etkinleştirmek bu araç izinlerini genişletmez.

Otomatik tavsiyenin alıntılanmış JSON içeriği ayrı bir user rolü danışma mesajında taşınır. Developer mesajında yalnızca sabit çalışma zamanı yönergesi kalır; danışmanın ürettiği metin developer/system içeriğine girmez. OpenAI Chat ve Anthropic bunu sahte araç çağrısı olmadan destekler. JSON alıntılama yapısal kaçışı ve alan sahteciliğini önler; doğal dildeki saldırılara karşı kusursuz yalıtım sağlamaz. Özel bir protokol tavsiyeyi kullanıcı isteğinden daha açık ayırabilir. Her istekte en fazla üç danışma ve dört worker sürdürmesi vardır. Danışma sınırında advisor aracı kaldırılır; yinelenen çağrıya sınır sonucu ile yalnızca bir son sürdürme verilir. Sonraki çağrı yeni gönderim yapılmadan 502 advisor_continuation_limit ile biter. Boş tamamlama tekrarları da aynı sınırı paylaşır.

Bastırma, danışmanın dizelerini okumaz. Otomatik yineleme ayıklama sunucunun defterine aittir. Taşıma metnini kopyalayan bir developer iletisi de preflight'ı bastırmaz.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ OpenCodex 不会把 provider API key、Authorization 头、OAuth token、仅后

手动建议是 Worker 自己发出的 `advisor` 调用所对应的工具结果。结果是一个 JSON 对象。`advice` 是顾问模型的文本。`status` 由运行时写入。

基于 fetch 的 Web 搜索轮次中,只有实际生效的 `tool_choice` 允许合成 `advisor` 工具时,搜索循环才会提供该工具并拦截手动咨询调用。将 `allowed_tools` 限制为 `web_search` 不允许手动咨询顾问。启用托管搜索不会扩大此工具权限范围。

自动建议的 JSON 内容放在独立的 user-role 建议消息中。developer 消息只保留固定的运行时传输说明,顾问生成的文本不会进入 developer/system 内容;OpenAI Chat 和 Anthropic 均可传递它,无需伪造工具调用。JSON 转义能防止结构突破和字段伪造,但不能保证模型忽略自然语言中的恶意指令。专门的咨询结果协议可进一步区分建议与用户请求。每个请求最多进行 3 次咨询和 4 次 Advisor worker 续写。咨询额度耗尽后移除 advisor 工具,重复调用只允许一次携带上限结果的最终续写;再次调用会以 502 advisor_continuation_limit 结束,不再发送隐藏的 worker 请求。空完成重试共享此上限。

抑制不读取顾问字符串。自动去重只看服务端账本。复制了传输文本的 developer 消息也不能抑制 preflight。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ OpenCodex 不會把 provider API key、Authorization 標頭、OAuth token、僅

手動建議是 Worker 自己發出的 `advisor` 呼叫所對應的工具結果。結果是一個 JSON 物件。`advice` 是顧問模型的文字。`status` 由執行期寫入。

基於 fetch 的 Web 搜尋回合中,只有實際生效的 `tool_choice` 允許合成 `advisor` 工具時,搜尋迴圈才會提供該工具並攔截手動諮詢呼叫。將 `allowed_tools` 限制為 `web_search` 不允許手動諮詢顧問。啟用託管搜尋不會擴大此工具權限範圍。

自動建議的 JSON 內容放在獨立的 user-role 建議訊息中。developer 訊息只保留固定的執行期傳輸說明,顧問產生的文字不會進入 developer/system 內容;OpenAI Chat 與 Anthropic 都能傳遞它,不需偽造工具呼叫。JSON 跳脫能防止結構突破與欄位偽造,但不能保證模型忽略自然語言中的惡意指令。專門的諮詢結果協定可進一步區分建議與使用者請求。每個請求最多進行 3 次諮詢與 4 次 Advisor worker 續寫。諮詢額度耗盡後移除 advisor 工具,重複呼叫只允許一次攜帶上限結果的最終續寫;再次呼叫會以 502 advisor_continuation_limit 結束,不再傳送隱藏的 worker 請求。空完成重試共用此上限。

抑制不讀取顧問字串。自動去重只看伺服器端帳本。複製了傳輸文字的 developer 訊息也不能抑制 preflight。
Expand Down
9 changes: 6 additions & 3 deletions src/server/responses/sidecar-execution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
} from "../../oauth/anthropic-routing";
import { resolveWireProtocolOverride } from "../adapter-resolve";
import { bindRouteReasoningReplayScope, adapterNeedsForcedContinuation, adapterNeedsToolCallContinuation } from "./core-replay";
import { namespacedToolName } from "../../types";
import { namespacedToolName, toolChoiceToolPredicate } from "../../types";
import { providerFetch } from "./fetch-helpers";
import type { AttemptRecoveryKind } from "../../usage/log";
import { recordAdapterReasoning, recordAdapterTier } from "../request-log";
Expand Down Expand Up @@ -657,12 +657,15 @@ export async function executeResponsesSidecars(
// Placed BEFORE the runTurn early-return for non-runTurn adapters so dual-tool turns dispatch
// through web-search instead of being swallowed. runTurn adapters never enter this branch.
if (canRunWebSearch && wsPlan) {
const webSearchAdvisor = advisorPlan && !routedCompaction
const requestedTools = parsed.context.tools ?? [];
const advisorAllowed = advisorPlan
&& toolChoiceToolPredicate(parsed.options.toolChoice, [...requestedTools, advisorPlan.tool])(advisorPlan.tool);
const webSearchAdvisor = advisorPlan && advisorAllowed && !routedCompaction
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
&& typeof advisorPlan.consult === "function" && typeof advisorPlan.formatUnavailable === "function"
? advisorPlan
: undefined;
parsed.context.tools = [
...(parsed.context.tools ?? []).filter(tool => !webSearchAdvisor || (!tool.advisor && tool.name !== ADVISOR_TOOL_NAME)),
...requestedTools.filter(tool => !webSearchAdvisor || (!tool.advisor && tool.name !== ADVISOR_TOOL_NAME)),
buildWebSearchTool(),
...(webSearchAdvisor ? [webSearchAdvisor.tool] : []),
];
Expand Down
Loading
Loading