mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-17 13:13:35 +08:00
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:
parent
fff08ee545
commit
02a2a622e8
@ -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
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user