fix: replace remaining em-dash mojibake in claude.ts

25 occurrences of corrupted em-dash (鈥?) were still present in
code comments from the initial import. Restored to proper em-dash
(—) with trailing space.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
言志伟 2026-04-17 14:57:14 +08:00
parent fff08ee545
commit 02a2a622e8

View File

@ -281,7 +281,7 @@ export function getExtraBodyParams(betaHeaders?: string[]): JsonObject {
const parsed = safeParseJSON(extraBodyStr)
// We expect an object with key-value pairs to spread into API parameters
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
// Shallow clone 鈥?safeParseJSON is LRU-cached and returns the same
// Shallow clone safeParseJSON is LRU-cached and returns the same
// object reference for the same string. Mutating `result` below
// would poison the cache, causing stale values to persist.
result = { ...(parsed as JsonObject) }
@ -384,15 +384,15 @@ export function getCacheControl({
* GrowthBook config shape: { allowlist: string[] }
* Patterns support trailing '*' for prefix matching.
* Examples:
* - { allowlist: ["repl_main_thread*", "sdk"] } ?main thread + SDK only
* - { allowlist: ["repl_main_thread*", "sdk", "agent:*"] } ?also subagents
* - { allowlist: ["*"] } ?all sources
* - { allowlist: ["repl_main_thread*", "sdk"] } main thread + SDK only
* - { allowlist: ["repl_main_thread*", "sdk", "agent:*"] } also subagents
* - { allowlist: ["*"] } all sources
*
* The allowlist is cached in STATE for session stability ?prevents mixed
* The allowlist is cached in STATE for session stability prevents mixed
* TTLs when GrowthBook's disk cache updates mid-request.
*/
function should1hCacheTTL(querySource?: QuerySource): boolean {
// 3P Bedrock users get 1h TTL when opted in via env var 鈥?they manage their own billing
// 3P Bedrock users get 1h TTL when opted in via env var they manage their own billing
// No GrowthBook gating needed since 3P users don't have GrowthBook configured
if (
getAPIProvider() === 'bedrock' &&
@ -401,7 +401,7 @@ function should1hCacheTTL(querySource?: QuerySource): boolean {
return true
}
// Latch eligibility in bootstrap state for session stability 鈥?prevents
// Latch eligibility in bootstrap state for session stability prevents
// mid-session overage flips from changing the cache_control TTL, which
// would bust the server-side prompt cache (~20K tokens per flip).
let userEligible = getPromptCache1hEligible()
@ -413,7 +413,7 @@ function should1hCacheTTL(querySource?: QuerySource): boolean {
}
if (!userEligible) return false
// Cache allowlist in bootstrap state for session stability 鈥?prevents mixed
// Cache allowlist in bootstrap state for session stability prevents mixed
// TTLs when GrowthBook's disk cache updates mid-request
let allowlist = getPromptCache1hAllowlist()
if (allowlist === null) {
@ -466,7 +466,7 @@ function configureEffortParams(
}
}
// output_config.task_budget 鈥?API-side token budget awareness for the model.
// output_config.task_budget API-side token budget awareness for the model.
// Stainless SDK types don't yet include task_budget on BetaOutputConfig, so we
// define the wire shape locally and cast. The API validates on receipt; see
// api/api/schemas/messages/request/output_config.py:12-39 in the monorepo.
@ -701,7 +701,7 @@ export type Options = {
advisorModel?: string
addNotification?: (notif: Notification) => void
// API-side task budget (output_config.task_budget). Distinct from the
// tokenBudget.ts +500k auto-continue feature 鈥?this one is sent to the API
// tokenBudget.ts +500k auto-continue feature this one is sent to the API
// so the model can pace itself. `remaining` is computed by the caller
// (query.ts decrements across the agentic loop).
taskBudget?: { total: number; remaining?: number }
@ -802,7 +802,7 @@ function shouldDeferLspTool(tool: Tool): boolean {
* (~5min) so a hung fallback to a wedged backend surfaces a clean
* APIConnectionTimeoutError instead of stalling past SIGKILL.
*
* Otherwise defaults to 300s ?long enough for slow backends without
* Otherwise defaults to 300s long enough for slow backends without
* approaching the API's 10-minute non-streaming boundary.
*/
function getNonstreamingFallbackTimeoutMs(): number {
@ -873,7 +873,7 @@ export async function* executeNonStreamingRequest(
},
)
} catch (err) {
// User aborts are not errors 鈥?re-throw immediately without logging
// User aborts are not errors re-throw immediately without logging
if (err instanceof APIUserAbortError) throw err
// Instrumentation: record when the non-streaming request errors (including
@ -1073,7 +1073,7 @@ async function* queryModel(
return
}
// Check cheap conditions first 鈥?the off-switch await blocks on GrowthBook
// Check cheap conditions first the off-switch await blocks on GrowthBook
// init (~10ms). For non-Opus models (haiku, sonnet) this skips the await
// entirely. Subscribers don't hit this path at all.
if (
@ -1173,7 +1173,7 @@ async function* queryModel(
'query',
)
// Precompute once 鈥?isDeferredTool does 2 GrowthBook lookups per call
// Precompute once isDeferredTool does 2 GrowthBook lookups per call
const deferredToolNames = new Set<string>()
if (useToolSearch) {
for (const t of tools) {
@ -1348,7 +1348,7 @@ async function* queryModel(
// tool_uses and strips orphaned tool_results referencing non-existent tool_uses.
messagesForAPI = ensureToolResultPairing(messagesForAPI)
// Strip advisor blocks 鈥?the API rejects them without the beta header.
// Strip advisor blocks the API rejects them without the beta header.
if (!betas.includes(ADVISOR_BETA_HEADER)) {
messagesForAPI = stripAdvisorBlocks(messagesForAPI)
}
@ -1736,7 +1736,7 @@ async function* queryModel(
)
}
// Only send temperature when thinking is disabled 鈥?the API requires
// Only send temperature when thinking is disabled the API requires
// temperature: 1 when thinking is enabled, which is already the default.
const temperature = !hasThinking
? (options.temperatureOverride ?? 1)
@ -1778,7 +1778,7 @@ async function* queryModel(
// Compute log scalars synchronously so the fire-and-forget .then() closure
// captures only primitives instead of paramsFromContext's full closure scope
// (messagesForAPI, system, allTools, betas 鈥?the entire request-building
// (messagesForAPI, system, allTools, betas the entire request-building
// context), which would otherwise be pinned until the promise resolves.
{
const queryParams = paramsFromContext({
@ -1857,7 +1857,7 @@ async function* queryModel(
// Generate and track client request ID so timeouts (which return no
// server request ID) can still be correlated with server logs.
// First-party only 鈥?3P providers don't log it (inc-4029 class).
// First-party only 3P providers don't log it (inc-4029 class).
clientRequestId =
getAPIProvider() === 'firstParty' && isFirstPartyAnthropicBaseUrl()
? randomUUID()
@ -2329,7 +2329,7 @@ async function* queryModel(
max_tokens: maxOutputTokens,
output_tokens: usage.output_tokens,
})
// Reuse the max_output_tokens recovery path 鈥?from the model's
// Reuse the max_output_tokens recovery path from the model's
// perspective, both mean "response was cut off, continue from
// where you left off."
yield createAssistantAPIErrorMessage({
@ -2646,7 +2646,7 @@ async function* queryModel(
} catch (errorFromRetry) {
// FallbackTriggeredError must propagate to query.ts, which performs the
// actual model switch. Swallowing it here would turn the fallback into a
// no-op 鈥?the user would just see "Model fallback triggered: X -> Y" as
// no-op the user would just see "Model fallback triggered: X -> Y" as
// an error message with no actual retry on the fallback model.
if (errorFromRetry instanceof FallbackTriggeredError) {
throw errorFromRetry
@ -2665,7 +2665,7 @@ async function* queryModel(
if (is404StreamCreationError) {
// 404 is thrown at .withResponse() before streamRequestId is assigned,
// and CannotRetryError means every retry failed 鈥?so grab the failed
// and CannotRetryError means every retry failed so grab the failed
// request's ID from the error header instead.
const failedRequestId =
(errorFromRetry.originalError as APIError).requestID ?? 'unknown'
@ -2886,7 +2886,7 @@ async function* queryModel(
// Track the last requestId for the main conversation chain so shutdown
// can send a cache eviction hint to inference. Exclude backgrounded
// sessions (Ctrl+B) which share the repl_main_thread querySource but
// run inside an agent context 鈥?they are independent conversation chains
// run inside an agent context they are independent conversation chains
// whose cache should not be evicted when the foreground session clears.
if (
streamRequestId &&
@ -3067,7 +3067,7 @@ export function accumulateUsage(
totalUsage.cache_creation.ephemeral_5m_input_tokens +
messageUsage.cache_creation.ephemeral_5m_input_tokens,
},
// See comment in updateUsage 鈥?field is not on NonNullableUsage to keep
// See comment in updateUsage field is not on NonNullableUsage to keep
// the string out of external builds.
...(feature('CACHED_MICROCOMPACT')
? {
@ -3128,7 +3128,7 @@ export function addCacheBreakpoints(
// local-attention KV pages at any cached prefix position NOT in
// cache_store_int_token_boundaries. With two markers the second-to-last
// position is protected and its locals survive an extra turn even though
// nothing will ever resume from there 鈥?with one marker they're freed
// nothing will ever resume from there with one marker they're freed
// immediately. For fire-and-forget forks (skipCacheWrite) we shift the
// marker to the second-to-last message: that's the last shared-prefix
// point, so the write is a no-op merge on mycro (entry already exists)
@ -3227,7 +3227,7 @@ export function addCacheBreakpoints(
// Add cache_reference to tool_result blocks that are strictly before
// the last cache_control marker. The API requires cache_reference to
// appear "before or on" the last cache_control 鈥?we use strict "before"
// appear "before or on" the last cache_control we use strict "before"
// to avoid edge cases where cache_edits splicing shifts block indices.
//
// Create new objects instead of mutating in-place to avoid contaminating