57 lines
2.2 KiB
TypeScript
57 lines
2.2 KiB
TypeScript
/** 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'
|
|
&& 'rpcId' in source
|
|
&& typeof source.rpcId === 'string'
|
|
&& '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}.`
|
|
}
|