pi-anthropic-oauth 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-anthropic-oauth",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Claude Pro/Max OAuth extension for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/convert.ts CHANGED
@@ -54,6 +54,24 @@ export function convertPiMessagesToAnthropic(
54
54
  isOAuth: boolean,
55
55
  ): MessageParam[] {
56
56
  const params: MessageParam[] = [];
57
+ const toolIdMap = new Map<string, string>();
58
+ const usedToolIds = new Set<string>();
59
+
60
+ const getAnthropicToolId = (id: string): string => {
61
+ const existing = toolIdMap.get(id);
62
+ if (existing) return existing;
63
+
64
+ let base = sanitizeSurrogates(id).replace(/[^a-zA-Z0-9_-]/g, "_");
65
+ if (!base) base = "tool";
66
+ let candidate = base;
67
+ let suffix = 1;
68
+ while (usedToolIds.has(candidate)) {
69
+ candidate = `${base}_${suffix++}`;
70
+ }
71
+ usedToolIds.add(candidate);
72
+ toolIdMap.set(id, candidate);
73
+ return candidate;
74
+ };
57
75
 
58
76
  for (let i = 0; i < messages.length; i++) {
59
77
  const message = messages[i];
@@ -81,19 +99,11 @@ export function convertPiMessagesToAnthropic(
81
99
  if (block.type === "text" && block.text.trim()) {
82
100
  blocks.push({ type: "text", text: sanitizeSurrogates(block.text) });
83
101
  } else if (block.type === "thinking" && block.thinking.trim()) {
84
- if (block.thinkingSignature) {
85
- blocks.push({
86
- type: "thinking" as never,
87
- thinking: sanitizeSurrogates(block.thinking),
88
- signature: block.thinkingSignature,
89
- });
90
- } else {
91
- blocks.push({ type: "text", text: sanitizeSurrogates(block.thinking) });
92
- }
102
+ blocks.push({ type: "text", text: sanitizeSurrogates(block.thinking) });
93
103
  } else if (block.type === "toolCall") {
94
104
  blocks.push({
95
105
  type: "tool_use",
96
- id: block.id,
106
+ id: getAnthropicToolId(block.id),
97
107
  name: isOAuth ? toClaudeCodeToolName(block.name) : block.name,
98
108
  input: block.arguments,
99
109
  });
@@ -107,7 +117,7 @@ export function convertPiMessagesToAnthropic(
107
117
  const toolResults = [
108
118
  {
109
119
  type: "tool_result" as const,
110
- tool_use_id: message.toolCallId,
120
+ tool_use_id: getAnthropicToolId(message.toolCallId),
111
121
  content: convertToolResultContentToAnthropic(message.content),
112
122
  is_error: message.isError,
113
123
  },
@@ -118,7 +128,7 @@ export function convertPiMessagesToAnthropic(
118
128
  const nextMessage = messages[j] as ToolResultMessage;
119
129
  toolResults.push({
120
130
  type: "tool_result" as const,
121
- tool_use_id: nextMessage.toolCallId,
131
+ tool_use_id: getAnthropicToolId(nextMessage.toolCallId),
122
132
  content: convertToolResultContentToAnthropic(nextMessage.content),
123
133
  is_error: nextMessage.isError,
124
134
  });
package/src/stream.ts CHANGED
@@ -111,10 +111,13 @@ export function streamAnthropicOAuth(
111
111
  dangerouslyAllowBrowser: true,
112
112
  });
113
113
 
114
+ const maxTokens =
115
+ options?.maxTokens || Math.floor(model.maxTokens / 3);
116
+
114
117
  const params: MessageCreateParamsStreaming = {
115
118
  model: model.id,
116
119
  messages: convertPiMessagesToAnthropic(context.messages, isOAuth),
117
- max_tokens: options?.maxTokens || Math.floor(model.maxTokens / 3),
120
+ max_tokens: maxTokens,
118
121
  stream: true,
119
122
  };
120
123
 
@@ -123,7 +126,7 @@ export function streamAnthropicOAuth(
123
126
  if (context.tools?.length)
124
127
  params.tools = convertPiToolsToAnthropic(context.tools, isOAuth);
125
128
 
126
- if (options?.reasoning && model.reasoning) {
129
+ if (options?.reasoning && model.reasoning && maxTokens > 1) {
127
130
  const defaultBudgets: Record<string, number> = {
128
131
  minimal: 1024,
129
132
  low: 4096,
@@ -135,10 +138,12 @@ export function streamAnthropicOAuth(
135
138
  options.thinkingBudgets?.[
136
139
  options.reasoning as keyof typeof options.thinkingBudgets
137
140
  ];
141
+ const requestedBudget =
142
+ customBudget ?? defaultBudgets[options.reasoning] ?? 10240;
143
+
138
144
  params.thinking = {
139
145
  type: "enabled",
140
- budget_tokens:
141
- customBudget ?? defaultBudgets[options.reasoning] ?? 10240,
146
+ budget_tokens: Math.min(requestedBudget, maxTokens - 1),
142
147
  };
143
148
  }
144
149