mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-18 00:23:25 -06:00
edecdbd05e
* refactor(config): consolidate media model lists * refactor(config): unify memory configuration * refactor(config): consolidate TTS ownership * refactor(config): move typing policy to agents * refactor(config): retire product-level config surfaces * refactor(config): share scoped tool policy type * chore(config): refresh generated baselines * fix(config): honor agent typing overrides * fix(config): migrate sibling config consumers * refactor(infra): keep base64url decoder private * fix(config): strip invalid legacy TTS values * chore(config): refresh rebased baseline hash * fix(doctor): route legacy messages.tts.realtime voice to talk during tts move * refactor(config): polish final layout names * refactor(config): freeze retired tuning defaults * feat(config): add fast mode default symmetry * refactor(config): key agent entries by id * docs(config): update final layout reference * test(config): cover final layout migrations * chore(config): refresh final layout baselines * fix(config): align final layout runtime readers * fix(config): align remaining readers * fix(config): stabilize final layout migrations * fix(config): finalize config projection proof * fix(config): address final layout review * docs(release): preserve historical config names * fix(config): complete keyed agent migration * fix(config): close final migration gaps * fix(config): finish full-branch review * fix(config): complete runtime secret detection * fix(config): close final review findings * fix(config): finish canonical docs and heartbeat migration * fix(config): integrate latest main after rebase * refactor(env): isolate test-only controls * refactor(env): isolate build and development controls * refactor(env): collapse process identity indirection * refactor(env): remove duplicate config and temp aliases * docs(env): define the operator-facing allowlist * ci(env): ratchet production variable count * fix(env): remove stale provider helper import * fix(env): make ratchet sorting explicit * test(env): keep test seam in dead-code audit * test(env): cover ratchet growth and boundary; document surface budgets * docs(config): document tier-eval consolidations * docs(config): clarify speech preference ownership * test(memory): align retired tuning fixtures * refactor(memory): freeze engine heuristics * refactor(config): apply tier-eval tranche * refactor(tts): move persona shaping to providers * refactor(compaction): move prompt policy to providers * test(config): align hookified prompt fixtures * chore(deadcode): classify test-only exports * chore(github): remove unused spawn helper * chore(deadcode): classify queue diagnostics * chore(deadcode): remove unused lane snapshot export * chore(plugin-sdk): ratchet consolidated surface * fix(config): integrate latest main after rebase
76 lines
3.0 KiB
TypeScript
76 lines
3.0 KiB
TypeScript
/**
|
|
* Formats cron-style current-time prompt text with local and UTC references.
|
|
*/
|
|
import { resolveDateTimestampMs } from "@openclaw/normalization-core/number-coercion";
|
|
import { formatUserTime, resolveUserTimeFormat, resolveUserTimezone } from "./date-time.js";
|
|
|
|
type CronStyleNow = {
|
|
userTimezone: string;
|
|
formattedTime: string;
|
|
timeLine: string;
|
|
};
|
|
|
|
type TimeConfigLike = {
|
|
agents?: {
|
|
defaults?: {
|
|
userTimezone?: string;
|
|
timeFormat?: "auto" | "12" | "24";
|
|
};
|
|
};
|
|
};
|
|
|
|
/** Resolve localized and UTC current-time text for agent prompts. */
|
|
export function resolveCronStyleNow(cfg: TimeConfigLike, nowMs: number): CronStyleNow {
|
|
const userTimezone = resolveUserTimezone(cfg.agents?.defaults?.userTimezone);
|
|
const userTimeFormat = resolveUserTimeFormat(undefined);
|
|
const timestampMs = resolveDateTimestampMs(nowMs);
|
|
const date = new Date(timestampMs);
|
|
const formattedTime = formatUserTime(date, userTimezone, userTimeFormat) ?? date.toISOString();
|
|
const utcTime = date.toISOString().replace("T", " ").slice(0, 16) + " UTC";
|
|
const timeLine = `Current time: ${formattedTime} (${userTimezone})\nReference UTC: ${utcTime}`;
|
|
return { userTimezone, formattedTime, timeLine };
|
|
}
|
|
|
|
/**
|
|
* Append a fresh current-time block, or refresh a previously helper-injected one,
|
|
* so heartbeat/cron prompts flowing through this helper repeatedly never leak a
|
|
* stale `Current time:` value (issue #44993).
|
|
*/
|
|
// Matches the helper's own injected two-line `Current time: ...\nReference UTC: ...` block.
|
|
// Upstream #42654 split the helper output across two lines:
|
|
// Line 1: `Current time: <formattedTime> (<userTimezone>)`
|
|
// Line 2: `Reference UTC: YYYY-MM-DD HH:MM UTC`
|
|
// The natural-language `formattedTime` portion is locale/format-dependent (e.g.
|
|
// `Thursday, April 30th, 2026 - 10:00 AM` from `formatUserTime`, or an ISO fallback),
|
|
// so we anchor on the helper-only deterministic shape: `(<TZ>)` on line 1 immediately
|
|
// followed by `Reference UTC: <ISO UTC>` on line 2. The `(TZ)` group rejects parens (so
|
|
// timezone IDs like `Asia/Seoul` are accepted), and the strict `Reference UTC:` prefix
|
|
// plus ISO+UTC tail rejects user-authored reminder lines that happen to start with
|
|
// `Current time:` but lack the helper's exact two-line tail format.
|
|
const CURRENT_TIME_LINE_RE =
|
|
/^Current time: .+? \([^)]+\)\nReference UTC: \d{4}-\d{2}-\d{2} \d{2}:\d{2} UTC$/gm;
|
|
|
|
export function appendCronStyleCurrentTimeLine(text: string, cfg: TimeConfigLike, nowMs: number) {
|
|
const base = text.trimEnd();
|
|
if (!base) {
|
|
return base;
|
|
}
|
|
const { timeLine } = resolveCronStyleNow(cfg, nowMs);
|
|
if (!CURRENT_TIME_LINE_RE.test(base)) {
|
|
return `${base}\n${timeLine}`;
|
|
}
|
|
CURRENT_TIME_LINE_RE.lastIndex = 0;
|
|
let replaced = false;
|
|
const refreshed = base.replace(CURRENT_TIME_LINE_RE, () => {
|
|
if (replaced) {
|
|
return "";
|
|
}
|
|
replaced = true;
|
|
return timeLine;
|
|
});
|
|
return refreshed
|
|
.replace(/\n{3,}/g, "\n\n")
|
|
.replace(/\n\n+(?=Current time:)/g, "\n")
|
|
.trimEnd();
|
|
}
|