opencode icon indicating copy to clipboard operation
opencode copied to clipboard

tweak: include anthropic spoof for providers including "anthropic" in name

Open Gardelll opened this issue 1 month ago • 10 comments

Prefix compaction/summarize/title system instruction with PROMPT_ANTHROPIC_SPOOF to support proxied Anthropic provider.

Gardelll avatar Dec 06 '25 11:12 Gardelll

The anthropic spoof is there solely for coding max/pro plans, are you running opencode through a proxy to your max plan? Because you may not really want that spoof unless you're doing that

rekram1-node avatar Dec 06 '25 19:12 rekram1-node

The anthropic spoof is there solely for coding max/pro plans, are you running opencode through a proxy to your max plan? Because you may not really want that spoof unless you're doing that

Yes, it sounds unsafe, but there is indeed such a need.

Gardelll avatar Dec 06 '25 19:12 Gardelll

I don't know if we should be including it all the time, for example: google-vertex-anthropic is a valid provider, no reason to attach it in that case

rekram1-node avatar Dec 06 '25 20:12 rekram1-node

that is the only provider I see this being an issue for, but fr? You have a proxy setup that uses claude code subscriptions?

rekram1-node avatar Dec 06 '25 20:12 rekram1-node

I don't know if we should be including it all the time, for example: google-vertex-anthropic is a valid provider, no reason to attach it in that case

Maybe we should use another option to include this spoof for custom providers?

that is the only provider I see this being an issue for, but fr? You have a proxy setup that uses claude code subscriptions?

I am using a config like this to bypass regional restrictions:

"anthropic-proxy": {
  "npm": "@ai-sdk/anthropic",
  "name": "ProxiedClaudeCode",
  "options": {
    "baseURL": "https://proxied-claude-endpoint/v1",
    "headers": {
      // claude code cli headers
    }
  },
  "models": {
    // ...
  }
}

It is working fine but excludes title generation, etc.

Gardelll avatar Dec 06 '25 20:12 Gardelll

ig this is fine, should prolly just exclude the case I mentioned

rekram1-node avatar Dec 06 '25 21:12 rekram1-node

I tested this out, and also had Opus 4.5 do a local review and it noticed that this PR was missing a case; this patch should apply to the tip of this PR.

diff --git i/packages/opencode/src/session/system.ts w/packages/opencode/src/session/system.ts
index 5996f6c2b..ed15b35d1 100644
--- i/packages/opencode/src/session/system.ts
+++ w/packages/opencode/src/session/system.ts
@@ -25,7 +25,7 @@ export namespace SystemPrompt {
   }
 
   export function header(providerID: string) {
-    if (providerID.includes("anthropic")) return [PROMPT_ANTHROPIC_SPOOF.trim()]
+    if (shouldIncludeAnthropicSpoof(providerID)) return [PROMPT_ANTHROPIC_SPOOF.trim()]
     return []
   }

On top of that, I think it'd be more elegant if we did it this way:

diff --git a/packages/opencode/src/session/system.ts b/packages/opencode/src/session/system.ts
index ed15b35d1..1fc7f61a4 100644
--- a/packages/opencode/src/session/system.ts
+++ b/packages/opencode/src/session/system.ts
@@ -20,13 +20,15 @@ import PROMPT_CODEX from "./prompt/codex.txt"
 import type { Provider } from "@/provider/provider"
 
 export namespace SystemPrompt {
-  function shouldIncludeAnthropicSpoof(providerID: string) {
-    return providerID !== "google-vertex-anthropic" && providerID.includes("anthropic")
+  function providerSpoof(providerID: string) {
+    if (providerID !== "google-vertex-anthropic" && providerID.includes("anthropic")) {
+      return [PROMPT_ANTHROPIC_SPOOF.trim()]
+    }
+    return []
   }
 
   export function header(providerID: string) {
-    if (shouldIncludeAnthropicSpoof(providerID)) return [PROMPT_ANTHROPIC_SPOOF.trim()]
-    return []
+    return [...providerSpoof(providerID)]
   }
 
   export function provider(model: Provider.Model) {
@@ -124,23 +126,14 @@ export namespace SystemPrompt {
   }
 
   export function compaction(providerID: string) {
-    if (shouldIncludeAnthropicSpoof(providerID)) {
-      return [PROMPT_ANTHROPIC_SPOOF.trim(), PROMPT_COMPACTION]
-    }
-    return [PROMPT_COMPACTION]
+    return [...providerSpoof(providerID), PROMPT_COMPACTION]
   }
 
   export function summarize(providerID: string) {
-    if (shouldIncludeAnthropicSpoof(providerID)) {
-      return [PROMPT_ANTHROPIC_SPOOF.trim(), PROMPT_SUMMARIZE]
-    }
-    return [PROMPT_SUMMARIZE]
+    return [...providerSpoof(providerID), PROMPT_SUMMARIZE]
   }
 
   export function title(providerID: string) {
-    if (shouldIncludeAnthropicSpoof(providerID)) {
-      return [PROMPT_ANTHROPIC_SPOOF.trim(), PROMPT_TITLE]
-    }
-    return [PROMPT_TITLE]
+    return [...providerSpoof(providerID), PROMPT_TITLE]
   }
 }

cgwalters avatar Dec 17 '25 14:12 cgwalters

FTR my interest in this PR is because we have this system prompt in our projects https://github.com/bootc-dev/infra/blob/dbc0159ca4b672e83cd3442917a5e8e0bfcb183d/common/AGENTS.md#attribution and I was really confused why most of the time OpenCode emitted Assisted-by: Claude Code

cgwalters avatar Dec 17 '25 14:12 cgwalters

This feature has been implemented in a different, unified way. However, special handling for google-vertex-anthropic is still lacking.

Gardelll avatar Dec 20 '25 18:12 Gardelll