refactor(schedule): simplify request zone authority
This commit is contained in:
54
packages/context/time-context/src/request-zone.ts
Normal file
54
packages/context/time-context/src/request-zone.ts
Normal file
@@ -0,0 +1,54 @@
|
||||
/** Request-zone derivation shared by time-context rendering and Schedule tools. */
|
||||
|
||||
import type { UserMessage } from '@deepseek-ai/dsh-llm'
|
||||
|
||||
/** Client-zone facts derived from the user-rpc messages in one open turn. */
|
||||
export type ClientTimeZoneContext =
|
||||
| { readonly kind: 'resolved'; readonly timeZone: string }
|
||||
| { readonly kind: 'mixed'; readonly timeZones: string[] }
|
||||
| { readonly kind: 'missing' }
|
||||
|
||||
/** Read the Host-validated client zone from one ordinary user-rpc message. */
|
||||
function clientTimeZone(message: UserMessage): string | undefined {
|
||||
const source = message.source
|
||||
return source.kind === 'user'
|
||||
&& 'clientTimeZone' in source
|
||||
&& typeof source.clientTimeZone === 'string'
|
||||
? source.clientTimeZone
|
||||
: undefined
|
||||
}
|
||||
|
||||
/**
|
||||
* Derive the unique, mixed, or missing client zone from entered request input.
|
||||
* @param messages - User messages belonging to the current open turn.
|
||||
* @returns A sorted, duplicate-free request-zone context.
|
||||
*/
|
||||
export function deriveClientTimeZoneContext(messages: readonly UserMessage[]): ClientTimeZoneContext {
|
||||
const timeZones = [...new Set(messages.flatMap((message) => {
|
||||
const timeZone = clientTimeZone(message)
|
||||
return timeZone === undefined ? [] : [timeZone]
|
||||
}))].sort()
|
||||
const [timeZone, ...remaining] = timeZones
|
||||
if (timeZone === undefined) return { kind: 'missing' }
|
||||
if (remaining.length === 0) return { kind: 'resolved', timeZone }
|
||||
return { kind: 'mixed', timeZones }
|
||||
}
|
||||
|
||||
/**
|
||||
* Render Session and request-zone facts for the model-visible time reading.
|
||||
* @param sessionTimeZone - Immutable Session zone, or `undefined` for legacy Sessions.
|
||||
* @param client - Client zones derived from the current open turn.
|
||||
* @returns The two policy lines appended to a time-context reading.
|
||||
*/
|
||||
export function renderTimeZoneContext(
|
||||
sessionTimeZone: string | undefined,
|
||||
client: ClientTimeZoneContext,
|
||||
): string {
|
||||
const session = sessionTimeZone ?? 'unavailable'
|
||||
const request = client.kind === 'resolved'
|
||||
? client.timeZone
|
||||
: client.kind === 'mixed'
|
||||
? `mixed ${JSON.stringify(client.timeZones)}`
|
||||
: 'missing'
|
||||
return `Session time zone: ${session}.\nClient time zone for this request: ${request}.`
|
||||
}
|
||||
Reference in New Issue
Block a user