From 165cdde2d6b8c24573a38fa7e9916dde5c9be842 Mon Sep 17 00:00:00 2001 From: toki Date: Fri, 14 Aug 2026 05:46:28 +0900 Subject: [PATCH] =?UTF-8?q?docs(api):=20Gemini=20reasoning=20=EC=A0=95?= =?UTF-8?q?=EA=B7=9C=ED=99=94=20=EA=B3=84=ED=9A=8D=EC=9D=84=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=ED=95=9C=EB=8B=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CODE_REVIEW-cloud-G04.md | 103 ++++++++++ .../gemini_reasoning_compat/PLAN-local-G04.md | 186 ++++++++++++++++++ 2 files changed, 289 insertions(+) create mode 100644 agent-task/gemini_reasoning_compat/CODE_REVIEW-cloud-G04.md create mode 100644 agent-task/gemini_reasoning_compat/PLAN-local-G04.md diff --git a/agent-task/gemini_reasoning_compat/CODE_REVIEW-cloud-G04.md b/agent-task/gemini_reasoning_compat/CODE_REVIEW-cloud-G04.md new file mode 100644 index 00000000..8d1b0737 --- /dev/null +++ b/agent-task/gemini_reasoning_compat/CODE_REVIEW-cloud-G04.md @@ -0,0 +1,103 @@ + + +# Code Review Reference - API + +> **[IMPLEMENTING AGENT — READ FIRST]** Implement the plan through the existing normalization boundary, run verification, fill every implementation-owned section, leave active files in place, and report ready for review. Do not append a verdict, archive, write `complete.log`, or ask the user. + +## Overview + +date=2026-08-14 +task=gemini_reasoning_compat, plan=0, tag=API + +## For the Review Agent + +> **[REVIEW AGENT ONLY]** Compare source with the plan, rerun fresh verification, and finalize only through the code-review skill. + +## Implementation Item Completion + +| Item | Status | +|---|---| +| API-1 Correct Gemini profile levels | [ ] | +| API-2 Prove bridge inheritance and synchronize contracts | [ ] | + +## Implementation Checklist + +- [ ] Implement API-1 the Gemini portable effort levels inside the existing profile normalization. +- [ ] Implement API-2 focused config and Responses-bridge regression tests plus contract/spec synchronization. +- [ ] Run fresh local verification and the exact-source dev Gemini reasoning cycles. +- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output. + +## Review-Only Checklist + +> **[REVIEW AGENT ONLY]** Implementers must not modify this section. + +- [ ] Append PASS/WARN/FAIL and routing signals. +- [ ] Verify dimensions and finding classifications. +- [ ] Run and record fresh verification. +- [ ] Record reviewer evidence, root cause, one selected fix, targets, and acceptance commands for Required/Suggested findings. +- [ ] Archive review as `code_review_cloud_G04_0.log` and plan as `plan_local_G04_0.log`. +- [ ] Verify managed `.gitignore`; on PASS write `complete.log` and archive the task directory, otherwise write only the required next state. + +## Deviations from Plan + +_Replace with actual deviations or `None`._ + +## Key Design Decisions + +_Record actual decisions._ + +## Reviewer Checkpoints + +- Only Gemini profile levels changed; generic normalization remains the owner. +- low/medium/high are exact, xhigh/max fall to high, none fails closed. +- No direct-handler normalizer, model/caller branch, extension, `thinking_level`, or `thinking_budget` synthesis exists. +- Responses bridge inherits the mapping through `selectProviderOperation`. +- Gemini-native thinking config and thought signatures remain unchanged. + +## Verification Results + +### Profile Mapping + +```bash +go test -count=1 ./packages/go/config -run 'TestGeminiProtocolProfileReasoningEffortScale|TestProtocolProfileEffortNormalizationOverlayAndValidation' +``` + +_Paste actual stdout/stderr._ + +### Responses Bridge + +```bash +go test -count=1 ./apps/edge/internal/openai -run 'TestResponsesProtocolProfileGeminiEffortFallsBackToHigh|TestResponsesProtocolProfileBridgesToGeminiChat' +``` + +_Paste actual stdout/stderr._ + +### Full Verification + +```bash +gofmt -w packages/go/config/protocol_profile.go packages/go/config/protocol_profile_test.go apps/edge/internal/openai/responses_protocol_profile_test.go +go test -count=1 ./packages/go/config +go test -count=1 ./apps/edge/internal/openai +git diff --check +``` + +_Paste actual stdout/stderr._ + +### Contract and Dev Evidence + +```bash +rg --sort path -n 'Gemini.*reasoning_effort|xhigh|max.*high' agent-contract/inner/edge-config-runtime-refresh.md agent-contract/outer/openai-compatible-api.md agent-spec/input/openai-compatible-surface.md +``` + +_Paste document output and sanitized exact-source dev low/high/max cycle evidence. Never paste credentials or provider payloads._ + +## Section Ownership + +| Section | Owner | +|---|---| +| Fixed header/overview/instructions/checkpoints | Fixed | +| Item Completion/Implementation Checklist | Implementer checks only | +| Review-Only Checklist | Reviewer | +| Deviations/Key Decisions | Implementer | +| Verification Results | Implementer, then reviewer | +| Code Review Result | Reviewer appends | diff --git a/agent-task/gemini_reasoning_compat/PLAN-local-G04.md b/agent-task/gemini_reasoning_compat/PLAN-local-G04.md new file mode 100644 index 00000000..a7e747e7 --- /dev/null +++ b/agent-task/gemini_reasoning_compat/PLAN-local-G04.md @@ -0,0 +1,186 @@ + + +# Gemini Reasoning Normalization Plan + +## For the Implementing Agent + +기존 operation-scoped `normalization.effort` 경계만 사용한다. 구현·검증 뒤 `CODE_REVIEW-cloud-G04.md`의 구현 담당 섹션에 실제 결과를 기록하고 active pair를 둔 채 review 준비 완료를 보고한다. verdict, archive, `complete.log`, 사용자 질문은 구현 담당 범위가 아니다. + +## Background + +Gemini profile은 이미 `normalization.effort` 방식으로 reasoning grade를 처리하지만 현재 levels가 IOP 전체 등급의 identity mapping이라 Gemini Chat의 portable 상한을 넘는 `xhigh|max`도 그대로 전달한다. 별도 adapter나 `thinking_level` 변환기를 만들지 않고 profile mapping만 교정해 기존 normalization 흐름이 올바른 provider value를 선택하게 한다. + +## Analysis + +### Files Read + +- `packages/go/config/protocol_profile.go` +- `packages/go/config/protocol_profile_test.go` +- `apps/edge/internal/openai/provider_normalization.go` +- `apps/edge/internal/openai/responses_protocol_profile_test.go` +- `agent-contract/inner/edge-config-runtime-refresh.md` +- `agent-contract/outer/openai-compatible-api.md` +- `agent-spec/input/openai-compatible-surface.md` +- `agent-test/dev/rules.md` +- `agent-ops/rules/project/domain/platform-common/rules.md` + +### SDD Criteria + +not applicable. 기존 normalization profile의 작은 호환성 결함 수정이다. + +### Verification Context + +- 최신 `dev` 기준 `protocol_profile.go`의 Gemini Chat effort는 `identityEffortMapping(...)`이며 `none|low|medium|high|xhigh|max`를 모두 그대로 매핑한다. +- 공통 `MapReasoningEffort`는 exact level이 없으면 가장 가까운 명시적 하위 등급을 고르고 상향하지 않는다. 이 함수가 source of truth다. +- 진행 중인 `responses_provider_bridge`도 `selectProviderOperation`에서 동일한 profile mapping을 사용하므로 변환 코드를 추가할 필요가 없다. +- Gemini 공식 OpenAI-compatible Chat은 `reasoning_effort`를 지원한다. `thinking_level`/`thinking_budget`을 함께 보내면 안 되므로 IOP가 native field를 합성하지 않는다. +- fresh test는 `-count=1`로 실행한다. + +#### External Verification Preflight + +- runner/workdir: `ssh toki@toki-labs.com`, `/Users/toki/agent-work/iop-dev` +- clean `dev`에서 `HEAD == origin/dev == approved implementation SHA`를 확인한다. +- exact source로 dev-runtime Edge/참여 Node를 rebuild/redeploy/restart하고 `18083/18084` listener와 binary identity를 확인한다. +- existing copied CA 및 SOPS/age-managed token을 사용하며 secret 원문은 evidence에 남기지 않는다. +- Gemini direct route에서 standard Responses caller의 `low`, `high`, `max` 한 cycle씩 확인한다. extension이나 `thinking_level` 우회는 사용하지 않는다. + +### Test Coverage Gaps + +| Behavior | Existing coverage | Gap | +|---|---|---| +| nearest-lower mapping | custom OpenAI profile | built-in Gemini mapping 없음 | +| Gemini tools + effort | profile은 `WithTools=true` | xhigh/max fallback 회귀 없음 | +| Responses→Gemini | 진행 중 bridge가 공통 selector 사용 | corrected mapping 상속 assertion 없음 | + +### Symbol References + +rename/remove 없음. `MapReasoningEffort`와 `selectProviderOperation` call sites는 변경하지 않는다. + +### Split Judgment + +단일 plan이다. compact invariant는 “Gemini profile의 declared levels가 기존 공통 nearest-lower normalization을 통해 provider-supported grade만 반환한다”이다. + +### Scope Rationale + +- `provider_normalization.go`의 알고리즘과 handler/adapter에 새 정규화 경계를 추가하지 않는다. +- `thinking_level`, `thinking_budget`, model-name 분기, caller/agent 분기, extension 우회를 추가하지 않는다. +- Gemini-native `thinkingConfig`, response reasoning text, `thought_signature`는 변경하지 않는다. +- portable scale은 `low|medium|high`로 둔다. `xhigh|max`는 기존 규칙으로 `high`, `none`은 지원 mapping이 없어 fail closed한다. + +### Final Routing + +- evaluation_mode: `first-pass`; finalizer=`finalize-task-policy.sh`, mode=`pair` +- build/review closures: all true +- build scores: scope=1,state=0,blast=1,evidence=1,verification=1; route=`local/G04`, basis=`local-fit` +- review scores: scope=1,state=0,blast=1,evidence=1,verification=1; route=`cloud/G04`, basis=`official-review` +- large_indivisible_context=false +- positive loop risks: `boundary_contract`, `variant_product` (2); risk boundary=false +- recovery signals: review_rework_count=0, evidence_integrity_failure=false; capability gap 없음 +- canonical files: `PLAN-local-G04.md`, `CODE_REVIEW-cloud-G04.md` + +## Implementation Checklist + +- [ ] Implement API-1 the Gemini portable effort levels inside the existing profile normalization. +- [ ] Implement API-2 focused config and Responses-bridge regression tests plus contract/spec synchronization. +- [ ] Run fresh local verification and the exact-source dev Gemini reasoning cycles. +- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output. + +### [API-1] Correct Gemini profile levels + +#### Problem + +```go +// packages/go/config/protocol_profile.go:251 +string(OperationChatCompletions): identityEffortMapping(ProtocolEffortWireGeminiChat, true, true), +``` + +Identity mapping declares unsupported upper/disable grades instead of letting the common normalizer choose a supported lower grade or reject. + +#### Solution + +Replace only the Gemini Chat levels with explicit `low`, `medium`, `high`. Retain `Wire=gemini_openai_chat`, `WithTools=true`, and the existing token-budget fact. Do not change `MapReasoningEffort`. + +```go +// after: existing MapReasoningEffort supplies xhigh/max -> high +ProtocolEffortMappingConf{ + Wire: ProtocolEffortWireGeminiChat, + WithTools: true, + TokenBudget: true, + Levels: map[string]string{"low":"low", "medium":"medium", "high":"high"}, +} +``` + +#### Modified Files and Checklist + +- [ ] `packages/go/config/protocol_profile.go`: Gemini Chat levels only. + +#### Test Strategy + +Write `TestGeminiProtocolProfileReasoningEffortScale` in `protocol_profile_test.go`: low/medium/high exact, xhigh/max→high, none unsupported, with-tools true, and `base: gemini` inheritance. + +#### Verification + +```bash +go test -count=1 ./packages/go/config -run 'TestGeminiProtocolProfileReasoningEffortScale|TestProtocolProfileEffortNormalizationOverlayAndValidation' +``` + +Expected: all cases pass without changing generic normalization. + +### [API-2] Prove bridge inheritance and synchronize contracts + +#### Problem + +No regression test proves that Responses ingress selecting Gemini Chat consumes the corrected profile mapping; documentation does not state Gemini's portable IOP grade behavior. + +#### Solution + +After `responses_provider_bridge` is present, add a focused assertion that a Responses request with effort `max` selects Gemini Chat and sends `reasoning_effort=high`. Do not add conversion logic in the test's production path. Document that direct native provider fields remain passthrough, while profile-normalized bridges use low/medium/high with nearest-lower fallback and no synthetic native thinking field. + +#### Modified Files and Checklist + +- [ ] `packages/go/config/protocol_profile_test.go`: profile mapping coverage. +- [ ] `apps/edge/internal/openai/responses_protocol_profile_test.go`: bridge inheritance coverage only. +- [ ] `agent-contract/inner/edge-config-runtime-refresh.md`: Gemini operation-scoped levels. +- [ ] `agent-contract/outer/openai-compatible-api.md`: Responses→Gemini reasoning semantics. +- [ ] `agent-spec/input/openai-compatible-surface.md`: living implementation state/change history. + +#### Test Strategy + +Write `TestResponsesProtocolProfileGeminiEffortFallsBackToHigh`. Assert selected operation is Chat, provider body contains `reasoning_effort=high`, tools still admit the candidate, and no `thinking_level`/`thinking_budget` is synthesized. + +#### Verification + +```bash +go test -count=1 ./apps/edge/internal/openai -run 'TestResponsesProtocolProfileGeminiEffortFallsBackToHigh' +rg --sort path -n 'Gemini.*reasoning_effort|xhigh|max.*high' agent-contract/inner/edge-config-runtime-refresh.md agent-contract/outer/openai-compatible-api.md agent-spec/input/openai-compatible-surface.md +``` + +Expected: bridge test and documents agree with the profile mapping. + +## Modified Files Summary + +| File | Items | +|---|---| +| `packages/go/config/protocol_profile.go` | API-1 | +| `packages/go/config/protocol_profile_test.go` | API-1, API-2 | +| `apps/edge/internal/openai/responses_protocol_profile_test.go` | API-2 | +| `agent-contract/inner/edge-config-runtime-refresh.md` | API-2 | +| `agent-contract/outer/openai-compatible-api.md` | API-2 | +| `agent-spec/input/openai-compatible-surface.md` | API-2 | +| `agent-task/gemini_reasoning_compat/CODE_REVIEW-cloud-G04.md` | API-1, API-2 evidence | + +## Final Verification + +```bash +gofmt -w packages/go/config/protocol_profile.go packages/go/config/protocol_profile_test.go apps/edge/internal/openai/responses_protocol_profile_test.go +go test -count=1 ./packages/go/config +go test -count=1 ./apps/edge/internal/openai -run 'TestResponsesProtocolProfileGeminiEffortFallsBackToHigh|TestResponsesProtocolProfileBridgesToGeminiChat' +go test -count=1 ./apps/edge/internal/openai +git diff --check +``` + +Expected: fresh tests pass and the implementation diff contains no handler/adapter reasoning normalizer or native thinking field synthesis. + +After an approved exact commit reaches `dev`, perform the recorded dev preflight/rebuild and Gemini Responses `low`, `high`, `max` cycles. Expected: all complete, `max` uses provider effort `high`, and no extension workaround is active. + +After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.