feat: standardize timestamps to UTC
This commit is contained in:
@@ -4,6 +4,9 @@
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
### Breaking
|
||||||
|
- Timestamps in agent envelopes are now UTC (compact `YYYY-MM-DDTHH:mmZ`); removed `messages.timestampPrefix`. Add `agent.userTimezone` to tell the model the user’s local time (system prompt only).
|
||||||
|
|
||||||
### Fixes
|
### Fixes
|
||||||
- Onboarding: resolve CLI entrypoint when running via `npx` so gateway daemon install works without a build step.
|
- Onboarding: resolve CLI entrypoint when running via `npx` so gateway daemon install works without a build step.
|
||||||
- Linux: auto-attempt lingering during onboarding (try without sudo, fallback to sudo) and prompt on install/restart to keep the gateway alive after logout/idle. Thanks @tobiasbischoff for PR #237.
|
- Linux: auto-attempt lingering during onboarding (try without sudo, fallback to sudo) and prompt on install/restart to keep the gateway alive after logout/idle. Thanks @tobiasbischoff for PR #237.
|
||||||
|
|||||||
@@ -432,16 +432,26 @@ Default: `~/clawd`.
|
|||||||
If `agent.sandbox` is enabled, non-main sessions can override this with their
|
If `agent.sandbox` is enabled, non-main sessions can override this with their
|
||||||
own per-session workspaces under `agent.sandbox.workspaceRoot`.
|
own per-session workspaces under `agent.sandbox.workspaceRoot`.
|
||||||
|
|
||||||
|
### `agent.userTimezone`
|
||||||
|
|
||||||
|
Sets the user’s timezone for **system prompt context** (not for timestamps in
|
||||||
|
message envelopes). If unset, Clawdbot uses the host timezone at runtime.
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
agent: { userTimezone: "America/Chicago" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### `messages`
|
### `messages`
|
||||||
|
|
||||||
Controls inbound/outbound prefixes and timestamps.
|
Controls inbound/outbound prefixes.
|
||||||
|
|
||||||
```json5
|
```json5
|
||||||
{
|
{
|
||||||
messages: {
|
messages: {
|
||||||
messagePrefix: "[clawdbot]",
|
messagePrefix: "[clawdbot]",
|
||||||
responsePrefix: "🦞",
|
responsePrefix: "🦞"
|
||||||
timestampPrefix: "Europe/London"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
40
docs/timezone.md
Normal file
40
docs/timezone.md
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
summary: "Timezone handling for agents, envelopes, and prompts"
|
||||||
|
read_when:
|
||||||
|
- You need to understand how timestamps are normalized for the model
|
||||||
|
- Configuring the user timezone for system prompts
|
||||||
|
---
|
||||||
|
|
||||||
|
# Timezones
|
||||||
|
|
||||||
|
Clawdbot standardizes timestamps so the model sees a **single reference time**.
|
||||||
|
|
||||||
|
## Message envelopes (UTC)
|
||||||
|
|
||||||
|
Inbound messages are wrapped in an envelope like:
|
||||||
|
|
||||||
|
```
|
||||||
|
[Surface ... 2026-01-05T21:26Z] message text
|
||||||
|
```
|
||||||
|
|
||||||
|
The timestamp in the envelope is **always UTC**, with minutes precision.
|
||||||
|
|
||||||
|
## Tool payloads (raw provider data)
|
||||||
|
|
||||||
|
Tool calls (`discord.readMessages`, `slack.readMessages`, etc.) return **raw provider timestamps**.
|
||||||
|
These are typically UTC ISO strings (Discord) or UTC epoch strings (Slack). We do not rewrite them.
|
||||||
|
|
||||||
|
## User timezone for the system prompt
|
||||||
|
|
||||||
|
Set `agent.userTimezone` to tell the model the user's local time zone. If it is
|
||||||
|
unset, Clawdbot resolves the **host timezone at runtime** (no config write).
|
||||||
|
|
||||||
|
```json5
|
||||||
|
{
|
||||||
|
agent: { userTimezone: "America/Chicago" }
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The system prompt includes:
|
||||||
|
- `User timezone: America/Chicago`
|
||||||
|
- `Current user time: 2026-01-05 15:26`
|
||||||
@@ -116,6 +116,46 @@ function resolveGlobalLane(lane?: string) {
|
|||||||
return cleaned ? cleaned : "main";
|
return cleaned ? cleaned : "main";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveUserTimezone(configured?: string): string {
|
||||||
|
const trimmed = configured?.trim();
|
||||||
|
if (trimmed) {
|
||||||
|
try {
|
||||||
|
new Intl.DateTimeFormat("en-US", { timeZone: trimmed }).format(
|
||||||
|
new Date(),
|
||||||
|
);
|
||||||
|
return trimmed;
|
||||||
|
} catch {
|
||||||
|
// ignore invalid timezone
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const host = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
||||||
|
return host?.trim() || "UTC";
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatUserTime(date: Date, timeZone: string): string | undefined {
|
||||||
|
try {
|
||||||
|
const parts = new Intl.DateTimeFormat("en-CA", {
|
||||||
|
timeZone,
|
||||||
|
year: "numeric",
|
||||||
|
month: "2-digit",
|
||||||
|
day: "2-digit",
|
||||||
|
hour: "2-digit",
|
||||||
|
minute: "2-digit",
|
||||||
|
hourCycle: "h23",
|
||||||
|
}).formatToParts(date);
|
||||||
|
const map: Record<string, string> = {};
|
||||||
|
for (const part of parts) {
|
||||||
|
if (part.type !== "literal") map[part.type] = part.value;
|
||||||
|
}
|
||||||
|
if (!map.year || !map.month || !map.day || !map.hour || !map.minute) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
return `${map.year}-${map.month}-${map.day} ${map.hour}:${map.minute}`;
|
||||||
|
} catch {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function buildEmbeddedSandboxInfo(
|
export function buildEmbeddedSandboxInfo(
|
||||||
sandbox?: Awaited<ReturnType<typeof resolveSandboxContext>>,
|
sandbox?: Awaited<ReturnType<typeof resolveSandboxContext>>,
|
||||||
): EmbeddedSandboxInfo | undefined {
|
): EmbeddedSandboxInfo | undefined {
|
||||||
@@ -398,6 +438,10 @@ export async function runEmbeddedPiAgent(params: {
|
|||||||
};
|
};
|
||||||
const sandboxInfo = buildEmbeddedSandboxInfo(sandbox);
|
const sandboxInfo = buildEmbeddedSandboxInfo(sandbox);
|
||||||
const reasoningTagHint = provider === "ollama";
|
const reasoningTagHint = provider === "ollama";
|
||||||
|
const userTimezone = resolveUserTimezone(
|
||||||
|
params.config?.agent?.userTimezone,
|
||||||
|
);
|
||||||
|
const userTime = formatUserTime(new Date(), userTimezone);
|
||||||
const systemPrompt = buildSystemPrompt({
|
const systemPrompt = buildSystemPrompt({
|
||||||
appendPrompt: buildAgentSystemPromptAppend({
|
appendPrompt: buildAgentSystemPromptAppend({
|
||||||
workspaceDir: resolvedWorkspace,
|
workspaceDir: resolvedWorkspace,
|
||||||
@@ -408,6 +452,8 @@ export async function runEmbeddedPiAgent(params: {
|
|||||||
runtimeInfo,
|
runtimeInfo,
|
||||||
sandboxInfo,
|
sandboxInfo,
|
||||||
toolNames: tools.map((tool) => tool.name),
|
toolNames: tools.map((tool) => tool.name),
|
||||||
|
userTimezone,
|
||||||
|
userTime,
|
||||||
}),
|
}),
|
||||||
contextFiles,
|
contextFiles,
|
||||||
skills: promptSkills,
|
skills: promptSkills,
|
||||||
|
|||||||
@@ -46,4 +46,16 @@ describe("buildAgentSystemPromptAppend", () => {
|
|||||||
expect(prompt).toContain("sessions_send");
|
expect(prompt).toContain("sessions_send");
|
||||||
expect(prompt).toContain("Unavailable tools (do not call):");
|
expect(prompt).toContain("Unavailable tools (do not call):");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("includes user time when provided", () => {
|
||||||
|
const prompt = buildAgentSystemPromptAppend({
|
||||||
|
workspaceDir: "/tmp/clawd",
|
||||||
|
userTimezone: "America/Chicago",
|
||||||
|
userTime: "2026-01-05 15:26",
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(prompt).toContain("## Time");
|
||||||
|
expect(prompt).toContain("User timezone: America/Chicago");
|
||||||
|
expect(prompt).toContain("Current user time: 2026-01-05 15:26");
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ export function buildAgentSystemPromptAppend(params: {
|
|||||||
ownerNumbers?: string[];
|
ownerNumbers?: string[];
|
||||||
reasoningTagHint?: boolean;
|
reasoningTagHint?: boolean;
|
||||||
toolNames?: string[];
|
toolNames?: string[];
|
||||||
|
userTimezone?: string;
|
||||||
|
userTime?: string;
|
||||||
runtimeInfo?: {
|
runtimeInfo?: {
|
||||||
host?: string;
|
host?: string;
|
||||||
os?: string;
|
os?: string;
|
||||||
@@ -109,6 +111,8 @@ export function buildAgentSystemPromptAppend(params: {
|
|||||||
"<final>Hey there! What would you like to do next?</final>",
|
"<final>Hey there! What would you like to do next?</final>",
|
||||||
].join(" ")
|
].join(" ")
|
||||||
: undefined;
|
: undefined;
|
||||||
|
const userTimezone = params.userTimezone?.trim();
|
||||||
|
const userTime = params.userTime?.trim();
|
||||||
const runtimeInfo = params.runtimeInfo;
|
const runtimeInfo = params.runtimeInfo;
|
||||||
const runtimeLines: string[] = [];
|
const runtimeLines: string[] = [];
|
||||||
if (runtimeInfo?.host) runtimeLines.push(`Host: ${runtimeInfo.host}`);
|
if (runtimeInfo?.host) runtimeLines.push(`Host: ${runtimeInfo.host}`);
|
||||||
@@ -182,6 +186,10 @@ export function buildAgentSystemPromptAppend(params: {
|
|||||||
"Never send streaming/partial replies to external messaging surfaces; only final replies should be delivered there.",
|
"Never send streaming/partial replies to external messaging surfaces; only final replies should be delivered there.",
|
||||||
"Clawdbot handles message transport automatically; respond normally and your reply will be delivered to the current chat.",
|
"Clawdbot handles message transport automatically; respond normally and your reply will be delivered to the current chat.",
|
||||||
"",
|
"",
|
||||||
|
userTimezone || userTime ? "## Time" : "",
|
||||||
|
userTimezone ? `User timezone: ${userTimezone}` : "",
|
||||||
|
userTime ? `Current user time: ${userTime}` : "",
|
||||||
|
userTimezone || userTime ? "" : "",
|
||||||
"## Reply Tags",
|
"## Reply Tags",
|
||||||
"To request a native reply/quote on supported surfaces, include one tag in your reply:",
|
"To request a native reply/quote on supported surfaces, include one tag in your reply:",
|
||||||
"- [[reply_to_current]] replies to the triggering message.",
|
"- [[reply_to_current]] replies to the triggering message.",
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ describe("formatAgentEnvelope", () => {
|
|||||||
|
|
||||||
process.env.TZ = originalTz;
|
process.env.TZ = originalTz;
|
||||||
|
|
||||||
expect(body).toMatch(
|
expect(body).toBe(
|
||||||
/^\[WebChat user1 mac-mini 10\.0\.0\.5 2025-01-02T03:04\+00:00\{.+\}\] hello$/,
|
"[WebChat user1 mac-mini 10.0.0.5 2025-01-02T03:04Z] hello",
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("formats timestamps in local time (not UTC)", () => {
|
it("formats timestamps in UTC regardless of local timezone", () => {
|
||||||
const originalTz = process.env.TZ;
|
const originalTz = process.env.TZ;
|
||||||
process.env.TZ = "America/Los_Angeles";
|
process.env.TZ = "America/Los_Angeles";
|
||||||
|
|
||||||
@@ -37,9 +37,7 @@ describe("formatAgentEnvelope", () => {
|
|||||||
|
|
||||||
process.env.TZ = originalTz;
|
process.env.TZ = originalTz;
|
||||||
|
|
||||||
expect(body).toBe(
|
expect(body).toBe("[WebChat 2025-01-02T03:04Z] hello");
|
||||||
"[WebChat 2025-01-01T19:04-08:00{America/Los_Angeles}] hello",
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it("handles missing optional fields", () => {
|
it("handles missing optional fields", () => {
|
||||||
|
|||||||
@@ -12,25 +12,15 @@ function formatTimestamp(ts?: number | Date): string | undefined {
|
|||||||
const date = ts instanceof Date ? ts : new Date(ts);
|
const date = ts instanceof Date ? ts : new Date(ts);
|
||||||
if (Number.isNaN(date.getTime())) return undefined;
|
if (Number.isNaN(date.getTime())) return undefined;
|
||||||
|
|
||||||
const yyyy = String(date.getFullYear()).padStart(4, "0");
|
const yyyy = String(date.getUTCFullYear()).padStart(4, "0");
|
||||||
const mm = String(date.getMonth() + 1).padStart(2, "0");
|
const mm = String(date.getUTCMonth() + 1).padStart(2, "0");
|
||||||
const dd = String(date.getDate()).padStart(2, "0");
|
const dd = String(date.getUTCDate()).padStart(2, "0");
|
||||||
const hh = String(date.getHours()).padStart(2, "0");
|
const hh = String(date.getUTCHours()).padStart(2, "0");
|
||||||
const min = String(date.getMinutes()).padStart(2, "0");
|
const min = String(date.getUTCMinutes()).padStart(2, "0");
|
||||||
|
|
||||||
// getTimezoneOffset() is minutes *behind* UTC. Flip sign to get ISO offset.
|
// Compact ISO-like UTC timestamp with minutes precision.
|
||||||
const offsetMinutes = -date.getTimezoneOffset();
|
// Example: 2025-01-02T03:04Z
|
||||||
const sign = offsetMinutes >= 0 ? "+" : "-";
|
return `${yyyy}-${mm}-${dd}T${hh}:${min}Z`;
|
||||||
const absOffsetMinutes = Math.abs(offsetMinutes);
|
|
||||||
const offsetH = String(Math.floor(absOffsetMinutes / 60)).padStart(2, "0");
|
|
||||||
const offsetM = String(absOffsetMinutes % 60).padStart(2, "0");
|
|
||||||
|
|
||||||
const tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
|
|
||||||
const tzSuffix = tz ? `{${tz}}` : "";
|
|
||||||
|
|
||||||
// Compact ISO-like *local* timestamp with minutes precision.
|
|
||||||
// Example: 2025-01-02T03:04-08:00{America/Los_Angeles}
|
|
||||||
return `${yyyy}-${mm}-${dd}T${hh}:${min}${sign}${offsetH}:${offsetM}${tzSuffix}`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatAgentEnvelope(params: AgentEnvelopeParams): string {
|
export function formatAgentEnvelope(params: AgentEnvelopeParams): string {
|
||||||
|
|||||||
@@ -445,7 +445,6 @@ export type RoutingConfig = {
|
|||||||
export type MessagesConfig = {
|
export type MessagesConfig = {
|
||||||
messagePrefix?: string; // Prefix added to all inbound messages (default: "[clawdbot]" if no allowFrom, else "")
|
messagePrefix?: string; // Prefix added to all inbound messages (default: "[clawdbot]" if no allowFrom, else "")
|
||||||
responsePrefix?: string; // Prefix auto-added to all outbound replies (e.g., "🦞")
|
responsePrefix?: string; // Prefix auto-added to all outbound replies (e.g., "🦞")
|
||||||
timestampPrefix?: boolean | string; // true/false or IANA timezone string (default: true with UTC)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type BridgeBindMode = "auto" | "lan" | "tailnet" | "loopback";
|
export type BridgeBindMode = "auto" | "lan" | "tailnet" | "loopback";
|
||||||
@@ -672,6 +671,8 @@ export type ClawdbotConfig = {
|
|||||||
imageModel?: string;
|
imageModel?: string;
|
||||||
/** Agent working directory (preferred). Used as the default cwd for agent runs. */
|
/** Agent working directory (preferred). Used as the default cwd for agent runs. */
|
||||||
workspace?: string;
|
workspace?: string;
|
||||||
|
/** Optional IANA timezone for the user (used in system prompt; defaults to host timezone). */
|
||||||
|
userTimezone?: string;
|
||||||
/** Optional allowlist for /model (provider/model or model-only). */
|
/** Optional allowlist for /model (provider/model or model-only). */
|
||||||
allowedModels?: string[];
|
allowedModels?: string[];
|
||||||
/** Optional model aliases for /model (alias -> provider/model). */
|
/** Optional model aliases for /model (alias -> provider/model). */
|
||||||
|
|||||||
@@ -150,7 +150,6 @@ const MessagesSchema = z
|
|||||||
.object({
|
.object({
|
||||||
messagePrefix: z.string().optional(),
|
messagePrefix: z.string().optional(),
|
||||||
responsePrefix: z.string().optional(),
|
responsePrefix: z.string().optional(),
|
||||||
timestampPrefix: z.union([z.boolean(), z.string()]).optional(),
|
|
||||||
})
|
})
|
||||||
.optional();
|
.optional();
|
||||||
|
|
||||||
@@ -376,6 +375,7 @@ export const ClawdbotSchema = z.object({
|
|||||||
model: z.string().optional(),
|
model: z.string().optional(),
|
||||||
imageModel: z.string().optional(),
|
imageModel: z.string().optional(),
|
||||||
workspace: z.string().optional(),
|
workspace: z.string().optional(),
|
||||||
|
userTimezone: z.string().optional(),
|
||||||
allowedModels: z.array(z.string()).optional(),
|
allowedModels: z.array(z.string()).optional(),
|
||||||
modelAliases: z.record(z.string(), z.string()).optional(),
|
modelAliases: z.record(z.string(), z.string()).optional(),
|
||||||
modelFallbacks: z.array(z.string()).optional(),
|
modelFallbacks: z.array(z.string()).optional(),
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ describe("createTelegramBot", () => {
|
|||||||
expect(replySpy).toHaveBeenCalledTimes(1);
|
expect(replySpy).toHaveBeenCalledTimes(1);
|
||||||
const payload = replySpy.mock.calls[0][0];
|
const payload = replySpy.mock.calls[0][0];
|
||||||
expect(payload.Body).toMatch(
|
expect(payload.Body).toMatch(
|
||||||
/^\[Telegram Ada Lovelace \(@ada_bot\) id:1234 2025-01-09T01:00\+01:00\{Europe\/Vienna\}\]/,
|
/^\[Telegram Ada Lovelace \(@ada_bot\) id:1234 2025-01-09T00:00Z\]/,
|
||||||
);
|
);
|
||||||
expect(payload.Body).toContain("hello world");
|
expect(payload.Body).toContain("hello world");
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -465,9 +465,6 @@ describe("web auto-reply", () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
setLoadConfigMock(() => ({
|
setLoadConfigMock(() => ({
|
||||||
messages: {
|
|
||||||
timestampPrefix: "UTC",
|
|
||||||
},
|
|
||||||
session: { store: store.storePath },
|
session: { store: store.storePath },
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -500,11 +497,11 @@ describe("web auto-reply", () => {
|
|||||||
const firstArgs = resolver.mock.calls[0][0];
|
const firstArgs = resolver.mock.calls[0][0];
|
||||||
const secondArgs = resolver.mock.calls[1][0];
|
const secondArgs = resolver.mock.calls[1][0];
|
||||||
expect(firstArgs.Body).toContain(
|
expect(firstArgs.Body).toContain(
|
||||||
"[WhatsApp +1 2025-01-01T01:00+01:00{Europe/Vienna}] [clawdbot] first",
|
"[WhatsApp +1 2025-01-01T00:00Z] [clawdbot] first",
|
||||||
);
|
);
|
||||||
expect(firstArgs.Body).not.toContain("second");
|
expect(firstArgs.Body).not.toContain("second");
|
||||||
expect(secondArgs.Body).toContain(
|
expect(secondArgs.Body).toContain(
|
||||||
"[WhatsApp +1 2025-01-01T02:00+01:00{Europe/Vienna}] [clawdbot] second",
|
"[WhatsApp +1 2025-01-01T01:00Z] [clawdbot] second",
|
||||||
);
|
);
|
||||||
expect(secondArgs.Body).not.toContain("first");
|
expect(secondArgs.Body).not.toContain("first");
|
||||||
|
|
||||||
@@ -1350,7 +1347,6 @@ describe("web auto-reply", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: "[same-phone]",
|
messagePrefix: "[same-phone]",
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1475,7 +1471,6 @@ describe("web auto-reply", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: "🦞",
|
responsePrefix: "🦞",
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1520,7 +1515,6 @@ describe("web auto-reply", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: "🦞",
|
responsePrefix: "🦞",
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1565,7 +1559,6 @@ describe("web auto-reply", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: "🦞",
|
responsePrefix: "🦞",
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -1611,7 +1604,6 @@ describe("web auto-reply", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: "🦞",
|
responsePrefix: "🦞",
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ vi.mock("../config/config.js", async (importOriginal) => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ const mockLoadConfig = vi.fn().mockReturnValue({
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -480,7 +479,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -536,7 +534,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -576,7 +573,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -592,7 +588,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -628,7 +623,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -643,7 +637,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -685,7 +678,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -720,7 +712,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -737,7 +728,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -773,7 +763,6 @@ describe("web monitor inbox", () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -840,7 +829,6 @@ it("defaults to self-only when no config is present", async () => {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ const DEFAULT_CONFIG = {
|
|||||||
messages: {
|
messages: {
|
||||||
messagePrefix: undefined,
|
messagePrefix: undefined,
|
||||||
responsePrefix: undefined,
|
responsePrefix: undefined,
|
||||||
timestampPrefix: false,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user