fix: lint errors
This commit is contained in:
committed by
Peter Steinberger
parent
0e1dcf9cb4
commit
eb7656d68c
@@ -91,14 +91,7 @@ export type SessionConfig = {
|
|||||||
export type LoggingConfig = {
|
export type LoggingConfig = {
|
||||||
level?: "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace";
|
level?: "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace";
|
||||||
file?: string;
|
file?: string;
|
||||||
consoleLevel?:
|
consoleLevel?: "silent" | "fatal" | "error" | "warn" | "info" | "debug" | "trace";
|
||||||
| "silent"
|
|
||||||
| "fatal"
|
|
||||||
| "error"
|
|
||||||
| "warn"
|
|
||||||
| "info"
|
|
||||||
| "debug"
|
|
||||||
| "trace";
|
|
||||||
consoleStyle?: "pretty" | "compact" | "json";
|
consoleStyle?: "pretty" | "compact" | "json";
|
||||||
/** Redact sensitive tokens in tool summaries. Default: "tools". */
|
/** Redact sensitive tokens in tool summaries. Default: "tools". */
|
||||||
redactSensitive?: "off" | "tools";
|
redactSensitive?: "off" | "tools";
|
||||||
@@ -122,9 +115,7 @@ export type WebConfig = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Provider docking: allowlists keyed by provider id (and internal "webchat").
|
// Provider docking: allowlists keyed by provider id (and internal "webchat").
|
||||||
export type AgentElevatedAllowFromConfig = Partial<
|
export type AgentElevatedAllowFromConfig = Partial<Record<string, Array<string | number>>>;
|
||||||
Record<string, Array<string | number>>
|
|
||||||
>;
|
|
||||||
|
|
||||||
export type IdentityConfig = {
|
export type IdentityConfig = {
|
||||||
name?: string;
|
name?: string;
|
||||||
@@ -495,11 +486,7 @@ export type DiscordGuildChannelConfig = {
|
|||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type DiscordReactionNotificationMode =
|
export type DiscordReactionNotificationMode = "off" | "own" | "all" | "allowlist";
|
||||||
| "off"
|
|
||||||
| "own"
|
|
||||||
| "all"
|
|
||||||
| "allowlist";
|
|
||||||
|
|
||||||
export type DiscordGuildEntry = {
|
export type DiscordGuildEntry = {
|
||||||
slug?: string;
|
slug?: string;
|
||||||
@@ -614,11 +601,7 @@ export type SlackChannelConfig = {
|
|||||||
systemPrompt?: string;
|
systemPrompt?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SignalReactionNotificationMode =
|
export type SignalReactionNotificationMode = "off" | "own" | "all" | "allowlist";
|
||||||
| "off"
|
|
||||||
| "own"
|
|
||||||
| "all"
|
|
||||||
| "allowlist";
|
|
||||||
|
|
||||||
export type SlackReactionNotificationMode = "off" | "own" | "all" | "allowlist";
|
export type SlackReactionNotificationMode = "off" | "own" | "all" | "allowlist";
|
||||||
|
|
||||||
|
|||||||
@@ -87,16 +87,8 @@ const QueueModeSchema = z.union([
|
|||||||
z.literal("queue"),
|
z.literal("queue"),
|
||||||
z.literal("interrupt"),
|
z.literal("interrupt"),
|
||||||
]);
|
]);
|
||||||
const QueueDropSchema = z.union([
|
const QueueDropSchema = z.union([z.literal("old"), z.literal("new"), z.literal("summarize")]);
|
||||||
z.literal("old"),
|
const ReplyToModeSchema = z.union([z.literal("off"), z.literal("first"), z.literal("all")]);
|
||||||
z.literal("new"),
|
|
||||||
z.literal("summarize"),
|
|
||||||
]);
|
|
||||||
const ReplyToModeSchema = z.union([
|
|
||||||
z.literal("off"),
|
|
||||||
z.literal("first"),
|
|
||||||
z.literal("all"),
|
|
||||||
]);
|
|
||||||
|
|
||||||
// GroupPolicySchema: controls how group messages are handled
|
// GroupPolicySchema: controls how group messages are handled
|
||||||
// Used with .default("allowlist").optional() pattern:
|
// Used with .default("allowlist").optional() pattern:
|
||||||
@@ -116,18 +108,12 @@ const BlockStreamingChunkSchema = z.object({
|
|||||||
minChars: z.number().int().positive().optional(),
|
minChars: z.number().int().positive().optional(),
|
||||||
maxChars: z.number().int().positive().optional(),
|
maxChars: z.number().int().positive().optional(),
|
||||||
breakPreference: z
|
breakPreference: z
|
||||||
.union([
|
.union([z.literal("paragraph"), z.literal("newline"), z.literal("sentence")])
|
||||||
z.literal("paragraph"),
|
|
||||||
z.literal("newline"),
|
|
||||||
z.literal("sentence"),
|
|
||||||
])
|
|
||||||
.optional(),
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const HumanDelaySchema = z.object({
|
const HumanDelaySchema = z.object({
|
||||||
mode: z
|
mode: z.union([z.literal("off"), z.literal("natural"), z.literal("custom")]).optional(),
|
||||||
.union([z.literal("off"), z.literal("natural"), z.literal("custom")])
|
|
||||||
.optional(),
|
|
||||||
minMs: z.number().int().nonnegative().optional(),
|
minMs: z.number().int().nonnegative().optional(),
|
||||||
maxMs: z.number().int().nonnegative().optional(),
|
maxMs: z.number().int().nonnegative().optional(),
|
||||||
});
|
});
|
||||||
@@ -135,12 +121,8 @@ const HumanDelaySchema = z.object({
|
|||||||
const CliBackendSchema = z.object({
|
const CliBackendSchema = z.object({
|
||||||
command: z.string(),
|
command: z.string(),
|
||||||
args: z.array(z.string()).optional(),
|
args: z.array(z.string()).optional(),
|
||||||
output: z
|
output: z.union([z.literal("json"), z.literal("text"), z.literal("jsonl")]).optional(),
|
||||||
.union([z.literal("json"), z.literal("text"), z.literal("jsonl")])
|
resumeOutput: z.union([z.literal("json"), z.literal("text"), z.literal("jsonl")]).optional(),
|
||||||
.optional(),
|
|
||||||
resumeOutput: z
|
|
||||||
.union([z.literal("json"), z.literal("text"), z.literal("jsonl")])
|
|
||||||
.optional(),
|
|
||||||
input: z.union([z.literal("arg"), z.literal("stdin")]).optional(),
|
input: z.union([z.literal("arg"), z.literal("stdin")]).optional(),
|
||||||
maxPromptArgChars: z.number().int().positive().optional(),
|
maxPromptArgChars: z.number().int().positive().optional(),
|
||||||
env: z.record(z.string(), z.string()).optional(),
|
env: z.record(z.string(), z.string()).optional(),
|
||||||
@@ -150,14 +132,10 @@ const CliBackendSchema = z.object({
|
|||||||
sessionArg: z.string().optional(),
|
sessionArg: z.string().optional(),
|
||||||
sessionArgs: z.array(z.string()).optional(),
|
sessionArgs: z.array(z.string()).optional(),
|
||||||
resumeArgs: z.array(z.string()).optional(),
|
resumeArgs: z.array(z.string()).optional(),
|
||||||
sessionMode: z
|
sessionMode: z.union([z.literal("always"), z.literal("existing"), z.literal("none")]).optional(),
|
||||||
.union([z.literal("always"), z.literal("existing"), z.literal("none")])
|
|
||||||
.optional(),
|
|
||||||
sessionIdFields: z.array(z.string()).optional(),
|
sessionIdFields: z.array(z.string()).optional(),
|
||||||
systemPromptArg: z.string().optional(),
|
systemPromptArg: z.string().optional(),
|
||||||
systemPromptMode: z
|
systemPromptMode: z.union([z.literal("append"), z.literal("replace")]).optional(),
|
||||||
.union([z.literal("append"), z.literal("replace")])
|
|
||||||
.optional(),
|
|
||||||
systemPromptWhen: z
|
systemPromptWhen: z
|
||||||
.union([z.literal("first"), z.literal("always"), z.literal("never")])
|
.union([z.literal("first"), z.literal("always"), z.literal("never")])
|
||||||
.optional(),
|
.optional(),
|
||||||
@@ -236,9 +214,7 @@ const TranscribeAudioSchema = z
|
|||||||
})
|
})
|
||||||
.optional();
|
.optional();
|
||||||
|
|
||||||
const HexColorSchema = z
|
const HexColorSchema = z.string().regex(/^#?[0-9a-fA-F]{6}$/, "expected hex color (RRGGBB)");
|
||||||
.string()
|
|
||||||
.regex(/^#?[0-9a-fA-F]{6}$/, "expected hex color (RRGGBB)");
|
|
||||||
|
|
||||||
const ExecutableTokenSchema = z
|
const ExecutableTokenSchema = z
|
||||||
.string()
|
.string()
|
||||||
@@ -312,8 +288,7 @@ const TelegramAccountSchemaBase = z.object({
|
|||||||
.optional(),
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const TelegramAccountSchema = TelegramAccountSchemaBase.superRefine(
|
const TelegramAccountSchema = TelegramAccountSchemaBase.superRefine((value, ctx) => {
|
||||||
(value, ctx) => {
|
|
||||||
requireOpenAllowFrom({
|
requireOpenAllowFrom({
|
||||||
policy: value.dmPolicy,
|
policy: value.dmPolicy,
|
||||||
allowFrom: value.allowFrom,
|
allowFrom: value.allowFrom,
|
||||||
@@ -322,8 +297,7 @@ const TelegramAccountSchema = TelegramAccountSchemaBase.superRefine(
|
|||||||
message:
|
message:
|
||||||
'channels.telegram.dmPolicy="open" requires channels.telegram.allowFrom to include "*"',
|
'channels.telegram.dmPolicy="open" requires channels.telegram.allowFrom to include "*"',
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const TelegramConfigSchema = TelegramAccountSchemaBase.extend({
|
const TelegramConfigSchema = TelegramAccountSchemaBase.extend({
|
||||||
accounts: z.record(z.string(), TelegramAccountSchema.optional()).optional(),
|
accounts: z.record(z.string(), TelegramAccountSchema.optional()).optional(),
|
||||||
@@ -372,9 +346,7 @@ const DiscordGuildSchema = z.object({
|
|||||||
requireMention: z.boolean().optional(),
|
requireMention: z.boolean().optional(),
|
||||||
reactionNotifications: z.enum(["off", "own", "all", "allowlist"]).optional(),
|
reactionNotifications: z.enum(["off", "own", "all", "allowlist"]).optional(),
|
||||||
users: z.array(z.union([z.string(), z.number()])).optional(),
|
users: z.array(z.union([z.string(), z.number()])).optional(),
|
||||||
channels: z
|
channels: z.record(z.string(), DiscordGuildChannelSchema.optional()).optional(),
|
||||||
.record(z.string(), DiscordGuildChannelSchema.optional())
|
|
||||||
.optional(),
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const DiscordAccountSchema = z.object({
|
const DiscordAccountSchema = z.object({
|
||||||
@@ -527,18 +499,15 @@ const SignalAccountSchemaBase = z.object({
|
|||||||
reactionAllowlist: z.array(z.union([z.string(), z.number()])).optional(),
|
reactionAllowlist: z.array(z.union([z.string(), z.number()])).optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const SignalAccountSchema = SignalAccountSchemaBase.superRefine(
|
const SignalAccountSchema = SignalAccountSchemaBase.superRefine((value, ctx) => {
|
||||||
(value, ctx) => {
|
|
||||||
requireOpenAllowFrom({
|
requireOpenAllowFrom({
|
||||||
policy: value.dmPolicy,
|
policy: value.dmPolicy,
|
||||||
allowFrom: value.allowFrom,
|
allowFrom: value.allowFrom,
|
||||||
ctx,
|
ctx,
|
||||||
path: ["allowFrom"],
|
path: ["allowFrom"],
|
||||||
message:
|
message: 'channels.signal.dmPolicy="open" requires channels.signal.allowFrom to include "*"',
|
||||||
'channels.signal.dmPolicy="open" requires channels.signal.allowFrom to include "*"',
|
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const SignalConfigSchema = SignalAccountSchemaBase.extend({
|
const SignalConfigSchema = SignalAccountSchemaBase.extend({
|
||||||
accounts: z.record(z.string(), SignalAccountSchema.optional()).optional(),
|
accounts: z.record(z.string(), SignalAccountSchema.optional()).optional(),
|
||||||
@@ -548,8 +517,7 @@ const SignalConfigSchema = SignalAccountSchemaBase.extend({
|
|||||||
allowFrom: value.allowFrom,
|
allowFrom: value.allowFrom,
|
||||||
ctx,
|
ctx,
|
||||||
path: ["allowFrom"],
|
path: ["allowFrom"],
|
||||||
message:
|
message: 'channels.signal.dmPolicy="open" requires channels.signal.allowFrom to include "*"',
|
||||||
'channels.signal.dmPolicy="open" requires channels.signal.allowFrom to include "*"',
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -559,9 +527,7 @@ const IMessageAccountSchemaBase = z.object({
|
|||||||
enabled: z.boolean().optional(),
|
enabled: z.boolean().optional(),
|
||||||
cliPath: ExecutableTokenSchema.optional(),
|
cliPath: ExecutableTokenSchema.optional(),
|
||||||
dbPath: z.string().optional(),
|
dbPath: z.string().optional(),
|
||||||
service: z
|
service: z.union([z.literal("imessage"), z.literal("sms"), z.literal("auto")]).optional(),
|
||||||
.union([z.literal("imessage"), z.literal("sms"), z.literal("auto")])
|
|
||||||
.optional(),
|
|
||||||
region: z.string().optional(),
|
region: z.string().optional(),
|
||||||
dmPolicy: DmPolicySchema.optional().default("pairing"),
|
dmPolicy: DmPolicySchema.optional().default("pairing"),
|
||||||
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
allowFrom: z.array(z.union([z.string(), z.number()])).optional(),
|
||||||
@@ -587,8 +553,7 @@ const IMessageAccountSchemaBase = z.object({
|
|||||||
.optional(),
|
.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
const IMessageAccountSchema = IMessageAccountSchemaBase.superRefine(
|
const IMessageAccountSchema = IMessageAccountSchemaBase.superRefine((value, ctx) => {
|
||||||
(value, ctx) => {
|
|
||||||
requireOpenAllowFrom({
|
requireOpenAllowFrom({
|
||||||
policy: value.dmPolicy,
|
policy: value.dmPolicy,
|
||||||
allowFrom: value.allowFrom,
|
allowFrom: value.allowFrom,
|
||||||
@@ -597,8 +562,7 @@ const IMessageAccountSchema = IMessageAccountSchemaBase.superRefine(
|
|||||||
message:
|
message:
|
||||||
'channels.imessage.dmPolicy="open" requires channels.imessage.allowFrom to include "*"',
|
'channels.imessage.dmPolicy="open" requires channels.imessage.allowFrom to include "*"',
|
||||||
});
|
});
|
||||||
},
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const IMessageConfigSchema = IMessageAccountSchemaBase.extend({
|
const IMessageConfigSchema = IMessageAccountSchemaBase.extend({
|
||||||
accounts: z.record(z.string(), IMessageAccountSchema.optional()).optional(),
|
accounts: z.record(z.string(), IMessageAccountSchema.optional()).optional(),
|
||||||
@@ -696,24 +660,18 @@ const WhatsAppAccountSchema = z
|
|||||||
.object({
|
.object({
|
||||||
emoji: z.string().optional(),
|
emoji: z.string().optional(),
|
||||||
direct: z.boolean().optional().default(true),
|
direct: z.boolean().optional().default(true),
|
||||||
group: z
|
group: z.enum(["always", "mentions", "never"]).optional().default("mentions"),
|
||||||
.enum(["always", "mentions", "never"])
|
|
||||||
.optional()
|
|
||||||
.default("mentions"),
|
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
})
|
})
|
||||||
.superRefine((value, ctx) => {
|
.superRefine((value, ctx) => {
|
||||||
if (value.dmPolicy !== "open") return;
|
if (value.dmPolicy !== "open") return;
|
||||||
const allow = (value.allowFrom ?? [])
|
const allow = (value.allowFrom ?? []).map((v) => String(v).trim()).filter(Boolean);
|
||||||
.map((v) => String(v).trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
if (allow.includes("*")) return;
|
if (allow.includes("*")) return;
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
path: ["allowFrom"],
|
path: ["allowFrom"],
|
||||||
message:
|
message: 'channels.whatsapp.accounts.*.dmPolicy="open" requires allowFrom to include "*"',
|
||||||
'channels.whatsapp.accounts.*.dmPolicy="open" requires allowFrom to include "*"',
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -755,18 +713,13 @@ const WhatsAppConfigSchema = z
|
|||||||
.object({
|
.object({
|
||||||
emoji: z.string().optional(),
|
emoji: z.string().optional(),
|
||||||
direct: z.boolean().optional().default(true),
|
direct: z.boolean().optional().default(true),
|
||||||
group: z
|
group: z.enum(["always", "mentions", "never"]).optional().default("mentions"),
|
||||||
.enum(["always", "mentions", "never"])
|
|
||||||
.optional()
|
|
||||||
.default("mentions"),
|
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
})
|
})
|
||||||
.superRefine((value, ctx) => {
|
.superRefine((value, ctx) => {
|
||||||
if (value.dmPolicy !== "open") return;
|
if (value.dmPolicy !== "open") return;
|
||||||
const allow = (value.allowFrom ?? [])
|
const allow = (value.allowFrom ?? []).map((v) => String(v).trim()).filter(Boolean);
|
||||||
.map((v) => String(v).trim())
|
|
||||||
.filter(Boolean);
|
|
||||||
if (allow.includes("*")) return;
|
if (allow.includes("*")) return;
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
@@ -816,11 +769,7 @@ const SessionSchema = z
|
|||||||
.object({
|
.object({
|
||||||
channel: z.string().optional(),
|
channel: z.string().optional(),
|
||||||
chatType: z
|
chatType: z
|
||||||
.union([
|
.union([z.literal("direct"), z.literal("group"), z.literal("room")])
|
||||||
z.literal("direct"),
|
|
||||||
z.literal("group"),
|
|
||||||
z.literal("room"),
|
|
||||||
])
|
|
||||||
.optional(),
|
.optional(),
|
||||||
keyPrefix: z.string().optional(),
|
keyPrefix: z.string().optional(),
|
||||||
})
|
})
|
||||||
@@ -845,9 +794,7 @@ const MessagesSchema = z
|
|||||||
groupChat: GroupChatSchema,
|
groupChat: GroupChatSchema,
|
||||||
queue: QueueSchema,
|
queue: QueueSchema,
|
||||||
ackReaction: z.string().optional(),
|
ackReaction: z.string().optional(),
|
||||||
ackReactionScope: z
|
ackReactionScope: z.enum(["group-mentions", "group-all", "direct", "all"]).optional(),
|
||||||
.enum(["group-mentions", "group-all", "direct", "all"])
|
|
||||||
.optional(),
|
|
||||||
removeAckAfterReply: z.boolean().optional(),
|
removeAckAfterReply: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
.optional();
|
.optional();
|
||||||
@@ -972,12 +919,7 @@ const ToolPolicySchema = z
|
|||||||
.optional();
|
.optional();
|
||||||
|
|
||||||
const ToolProfileSchema = z
|
const ToolProfileSchema = z
|
||||||
.union([
|
.union([z.literal("minimal"), z.literal("coding"), z.literal("messaging"), z.literal("full")])
|
||||||
z.literal("minimal"),
|
|
||||||
z.literal("coding"),
|
|
||||||
z.literal("messaging"),
|
|
||||||
z.literal("full"),
|
|
||||||
])
|
|
||||||
.optional();
|
.optional();
|
||||||
|
|
||||||
// Provider docking: allowlists keyed by provider id (no schema updates when adding providers).
|
// Provider docking: allowlists keyed by provider id (no schema updates when adding providers).
|
||||||
@@ -987,18 +929,10 @@ const ElevatedAllowFromSchema = z
|
|||||||
|
|
||||||
const AgentSandboxSchema = z
|
const AgentSandboxSchema = z
|
||||||
.object({
|
.object({
|
||||||
mode: z
|
mode: z.union([z.literal("off"), z.literal("non-main"), z.literal("all")]).optional(),
|
||||||
.union([z.literal("off"), z.literal("non-main"), z.literal("all")])
|
workspaceAccess: z.union([z.literal("none"), z.literal("ro"), z.literal("rw")]).optional(),
|
||||||
.optional(),
|
sessionToolsVisibility: z.union([z.literal("spawned"), z.literal("all")]).optional(),
|
||||||
workspaceAccess: z
|
scope: z.union([z.literal("session"), z.literal("agent"), z.literal("shared")]).optional(),
|
||||||
.union([z.literal("none"), z.literal("ro"), z.literal("rw")])
|
|
||||||
.optional(),
|
|
||||||
sessionToolsVisibility: z
|
|
||||||
.union([z.literal("spawned"), z.literal("all")])
|
|
||||||
.optional(),
|
|
||||||
scope: z
|
|
||||||
.union([z.literal("session"), z.literal("agent"), z.literal("shared")])
|
|
||||||
.optional(),
|
|
||||||
perSession: z.boolean().optional(),
|
perSession: z.boolean().optional(),
|
||||||
workspaceRoot: z.string().optional(),
|
workspaceRoot: z.string().optional(),
|
||||||
docker: SandboxDockerSchema,
|
docker: SandboxDockerSchema,
|
||||||
@@ -1181,11 +1115,7 @@ const BindingsSchema = z
|
|||||||
accountId: z.string().optional(),
|
accountId: z.string().optional(),
|
||||||
peer: z
|
peer: z
|
||||||
.object({
|
.object({
|
||||||
kind: z.union([
|
kind: z.union([z.literal("dm"), z.literal("group"), z.literal("channel")]),
|
||||||
z.literal("dm"),
|
|
||||||
z.literal("group"),
|
|
||||||
z.literal("channel"),
|
|
||||||
]),
|
|
||||||
id: z.string(),
|
id: z.string(),
|
||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
@@ -1221,9 +1151,7 @@ const HookMappingSchema = z
|
|||||||
})
|
})
|
||||||
.optional(),
|
.optional(),
|
||||||
action: z.union([z.literal("wake"), z.literal("agent")]).optional(),
|
action: z.union([z.literal("wake"), z.literal("agent")]).optional(),
|
||||||
wakeMode: z
|
wakeMode: z.union([z.literal("now"), z.literal("next-heartbeat")]).optional(),
|
||||||
.union([z.literal("now"), z.literal("next-heartbeat")])
|
|
||||||
.optional(),
|
|
||||||
name: z.string().optional(),
|
name: z.string().optional(),
|
||||||
sessionKey: z.string().optional(),
|
sessionKey: z.string().optional(),
|
||||||
messageTemplate: z.string().optional(),
|
messageTemplate: z.string().optional(),
|
||||||
@@ -1274,9 +1202,7 @@ const HooksGmailSchema = z
|
|||||||
.optional(),
|
.optional(),
|
||||||
tailscale: z
|
tailscale: z
|
||||||
.object({
|
.object({
|
||||||
mode: z
|
mode: z.union([z.literal("off"), z.literal("serve"), z.literal("funnel")]).optional(),
|
||||||
.union([z.literal("off"), z.literal("serve"), z.literal("funnel")])
|
|
||||||
.optional(),
|
|
||||||
path: z.string().optional(),
|
path: z.string().optional(),
|
||||||
target: z.string().optional(),
|
target: z.string().optional(),
|
||||||
})
|
})
|
||||||
@@ -1328,11 +1254,7 @@ const AgentDefaultsSchema = z
|
|||||||
contextPruning: z
|
contextPruning: z
|
||||||
.object({
|
.object({
|
||||||
mode: z
|
mode: z
|
||||||
.union([
|
.union([z.literal("off"), z.literal("adaptive"), z.literal("aggressive")])
|
||||||
z.literal("off"),
|
|
||||||
z.literal("adaptive"),
|
|
||||||
z.literal("aggressive"),
|
|
||||||
])
|
|
||||||
.optional(),
|
.optional(),
|
||||||
keepLastAssistants: z.number().int().nonnegative().optional(),
|
keepLastAssistants: z.number().int().nonnegative().optional(),
|
||||||
softTrimRatio: z.number().min(0).max(1).optional(),
|
softTrimRatio: z.number().min(0).max(1).optional(),
|
||||||
@@ -1361,9 +1283,7 @@ const AgentDefaultsSchema = z
|
|||||||
.optional(),
|
.optional(),
|
||||||
compaction: z
|
compaction: z
|
||||||
.object({
|
.object({
|
||||||
mode: z
|
mode: z.union([z.literal("default"), z.literal("safeguard")]).optional(),
|
||||||
.union([z.literal("default"), z.literal("safeguard")])
|
|
||||||
.optional(),
|
|
||||||
reserveTokensFloor: z.number().int().nonnegative().optional(),
|
reserveTokensFloor: z.number().int().nonnegative().optional(),
|
||||||
memoryFlush: z
|
memoryFlush: z
|
||||||
.object({
|
.object({
|
||||||
@@ -1387,12 +1307,8 @@ const AgentDefaultsSchema = z
|
|||||||
.optional(),
|
.optional(),
|
||||||
verboseDefault: z.union([z.literal("off"), z.literal("on")]).optional(),
|
verboseDefault: z.union([z.literal("off"), z.literal("on")]).optional(),
|
||||||
elevatedDefault: z.union([z.literal("off"), z.literal("on")]).optional(),
|
elevatedDefault: z.union([z.literal("off"), z.literal("on")]).optional(),
|
||||||
blockStreamingDefault: z
|
blockStreamingDefault: z.union([z.literal("off"), z.literal("on")]).optional(),
|
||||||
.union([z.literal("off"), z.literal("on")])
|
blockStreamingBreak: z.union([z.literal("text_end"), z.literal("message_end")]).optional(),
|
||||||
.optional(),
|
|
||||||
blockStreamingBreak: z
|
|
||||||
.union([z.literal("text_end"), z.literal("message_end")])
|
|
||||||
.optional(),
|
|
||||||
blockStreamingChunk: BlockStreamingChunkSchema.optional(),
|
blockStreamingChunk: BlockStreamingChunkSchema.optional(),
|
||||||
blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
|
blockStreamingCoalesce: BlockStreamingCoalesceSchema.optional(),
|
||||||
humanDelay: HumanDelaySchema.optional(),
|
humanDelay: HumanDelaySchema.optional(),
|
||||||
@@ -1426,22 +1342,10 @@ const AgentDefaultsSchema = z
|
|||||||
.optional(),
|
.optional(),
|
||||||
sandbox: z
|
sandbox: z
|
||||||
.object({
|
.object({
|
||||||
mode: z
|
mode: z.union([z.literal("off"), z.literal("non-main"), z.literal("all")]).optional(),
|
||||||
.union([z.literal("off"), z.literal("non-main"), z.literal("all")])
|
workspaceAccess: z.union([z.literal("none"), z.literal("ro"), z.literal("rw")]).optional(),
|
||||||
.optional(),
|
sessionToolsVisibility: z.union([z.literal("spawned"), z.literal("all")]).optional(),
|
||||||
workspaceAccess: z
|
scope: z.union([z.literal("session"), z.literal("agent"), z.literal("shared")]).optional(),
|
||||||
.union([z.literal("none"), z.literal("ro"), z.literal("rw")])
|
|
||||||
.optional(),
|
|
||||||
sessionToolsVisibility: z
|
|
||||||
.union([z.literal("spawned"), z.literal("all")])
|
|
||||||
.optional(),
|
|
||||||
scope: z
|
|
||||||
.union([
|
|
||||||
z.literal("session"),
|
|
||||||
z.literal("agent"),
|
|
||||||
z.literal("shared"),
|
|
||||||
])
|
|
||||||
.optional(),
|
|
||||||
perSession: z.boolean().optional(),
|
perSession: z.boolean().optional(),
|
||||||
workspaceRoot: z.string().optional(),
|
workspaceRoot: z.string().optional(),
|
||||||
docker: SandboxDockerSchema,
|
docker: SandboxDockerSchema,
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -17,15 +17,8 @@ import {
|
|||||||
resolveChannelGroupPolicy,
|
resolveChannelGroupPolicy,
|
||||||
resolveChannelGroupRequireMention,
|
resolveChannelGroupRequireMention,
|
||||||
} from "../config/group-policy.js";
|
} from "../config/group-policy.js";
|
||||||
import {
|
import { loadSessionStore, resolveStorePath } from "../config/sessions.js";
|
||||||
loadSessionStore,
|
|
||||||
resolveStorePath,
|
|
||||||
updateLastRoute,
|
|
||||||
} from "../config/sessions.js";
|
|
||||||
import { danger, logVerbose, shouldLogVerbose } from "../globals.js";
|
import { danger, logVerbose, shouldLogVerbose } from "../globals.js";
|
||||||
import { recordChannelActivity } from "../infra/channel-activity.js";
|
|
||||||
import { createDedupeCache } from "../infra/dedupe.js";
|
|
||||||
import { formatErrorMessage } from "../infra/errors.js";
|
|
||||||
import { enqueueSystemEvent } from "../infra/system-events.js";
|
import { enqueueSystemEvent } from "../infra/system-events.js";
|
||||||
import { getChildLogger } from "../logging.js";
|
import { getChildLogger } from "../logging.js";
|
||||||
import { resolveAgentRoute } from "../routing/resolve-route.js";
|
import { resolveAgentRoute } from "../routing/resolve-route.js";
|
||||||
@@ -47,12 +40,6 @@ import {
|
|||||||
type TelegramUpdateKeyContext,
|
type TelegramUpdateKeyContext,
|
||||||
} from "./bot-updates.js";
|
} from "./bot-updates.js";
|
||||||
import { resolveTelegramFetch } from "./fetch.js";
|
import { resolveTelegramFetch } from "./fetch.js";
|
||||||
import {
|
|
||||||
readTelegramAllowFromStore,
|
|
||||||
upsertTelegramPairingRequest,
|
|
||||||
} from "./pairing-store.js";
|
|
||||||
import { wasSentByBot } from "./sent-message-cache.js";
|
|
||||||
import { resolveTelegramVoiceSend } from "./voice.js";
|
|
||||||
|
|
||||||
export type TelegramBotOptions = {
|
export type TelegramBotOptions = {
|
||||||
token: string;
|
token: string;
|
||||||
@@ -334,23 +321,18 @@ export function createTelegramBot(opts: TelegramBotOptions) {
|
|||||||
// Detect added reactions
|
// Detect added reactions
|
||||||
const oldEmojis = new Set(
|
const oldEmojis = new Set(
|
||||||
reaction.old_reaction
|
reaction.old_reaction
|
||||||
.filter(
|
.filter((r): r is { type: "emoji"; emoji: string } => r.type === "emoji")
|
||||||
(r): r is { type: "emoji"; emoji: string } => r.type === "emoji",
|
|
||||||
)
|
|
||||||
.map((r) => r.emoji),
|
.map((r) => r.emoji),
|
||||||
);
|
);
|
||||||
const addedReactions = reaction.new_reaction
|
const addedReactions = reaction.new_reaction
|
||||||
.filter(
|
.filter((r): r is { type: "emoji"; emoji: string } => r.type === "emoji")
|
||||||
(r): r is { type: "emoji"; emoji: string } => r.type === "emoji",
|
|
||||||
)
|
|
||||||
.filter((r) => !oldEmojis.has(r.emoji));
|
.filter((r) => !oldEmojis.has(r.emoji));
|
||||||
|
|
||||||
if (addedReactions.length === 0) return;
|
if (addedReactions.length === 0) return;
|
||||||
|
|
||||||
// Build sender label
|
// Build sender label
|
||||||
const senderName = user
|
const senderName = user
|
||||||
? [user.first_name, user.last_name].filter(Boolean).join(" ").trim() ||
|
? [user.first_name, user.last_name].filter(Boolean).join(" ").trim() || user.username
|
||||||
user.username
|
|
||||||
: undefined;
|
: undefined;
|
||||||
const senderUsername = user?.username ? `@${user.username}` : undefined;
|
const senderUsername = user?.username ? `@${user.username}` : undefined;
|
||||||
let senderLabel = senderName;
|
let senderLabel = senderName;
|
||||||
@@ -373,11 +355,8 @@ export function createTelegramBot(opts: TelegramBotOptions) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Resolve agent route for session
|
// Resolve agent route for session
|
||||||
const isGroup =
|
const isGroup = reaction.chat.type === "group" || reaction.chat.type === "supergroup";
|
||||||
reaction.chat.type === "group" || reaction.chat.type === "supergroup";
|
const peerId = isGroup ? buildTelegramGroupPeerId(chatId, resolvedThreadId) : String(chatId);
|
||||||
const peerId = isGroup
|
|
||||||
? buildTelegramGroupPeerId(chatId, resolvedThreadId)
|
|
||||||
: String(chatId);
|
|
||||||
const route = resolveAgentRoute({
|
const route = resolveAgentRoute({
|
||||||
cfg,
|
cfg,
|
||||||
channel: "telegram",
|
channel: "telegram",
|
||||||
@@ -396,9 +375,7 @@ export function createTelegramBot(opts: TelegramBotOptions) {
|
|||||||
logVerbose(`telegram: reaction event enqueued: ${text}`);
|
logVerbose(`telegram: reaction event enqueued: ${text}`);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
runtime.error?.(
|
runtime.error?.(danger(`telegram reaction handler failed: ${String(err)}`));
|
||||||
danger(`telegram reaction handler failed: ${String(err)}`),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -34,10 +34,7 @@ export function createTelegramRunnerOptions(cfg: ClawdbotConfig): RunOptions<unk
|
|||||||
// Match grammY defaults
|
// Match grammY defaults
|
||||||
timeout: 30,
|
timeout: 30,
|
||||||
// Request reaction updates from Telegram
|
// Request reaction updates from Telegram
|
||||||
allowed_updates: [
|
allowed_updates: ["message", "message_reaction"],
|
||||||
"message",
|
|
||||||
"message_reaction",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
// Suppress grammY getUpdates stack traces; we log concise errors ourselves.
|
// Suppress grammY getUpdates stack traces; we log concise errors ourselves.
|
||||||
silent: true,
|
silent: true,
|
||||||
|
|||||||
@@ -24,8 +24,7 @@ export function resolveTelegramReactionLevel(params: {
|
|||||||
cfg: params.cfg,
|
cfg: params.cfg,
|
||||||
accountId: params.accountId,
|
accountId: params.accountId,
|
||||||
});
|
});
|
||||||
const level = (account.config.reactionLevel ??
|
const level = (account.config.reactionLevel ?? "ack") as TelegramReactionLevel;
|
||||||
"ack") as TelegramReactionLevel;
|
|
||||||
|
|
||||||
switch (level) {
|
switch (level) {
|
||||||
case "off":
|
case "off":
|
||||||
|
|||||||
@@ -18,10 +18,7 @@ import { resolveTelegramAccount } from "./accounts.js";
|
|||||||
import { resolveTelegramFetch } from "./fetch.js";
|
import { resolveTelegramFetch } from "./fetch.js";
|
||||||
import { markdownToTelegramHtml } from "./format.js";
|
import { markdownToTelegramHtml } from "./format.js";
|
||||||
import { recordSentMessage } from "./sent-message-cache.js";
|
import { recordSentMessage } from "./sent-message-cache.js";
|
||||||
import {
|
import { parseTelegramTarget, stripTelegramInternalPrefixes } from "./targets.js";
|
||||||
parseTelegramTarget,
|
|
||||||
stripTelegramInternalPrefixes,
|
|
||||||
} from "./targets.js";
|
|
||||||
import { resolveTelegramVoiceSend } from "./voice.js";
|
import { resolveTelegramVoiceSend } from "./voice.js";
|
||||||
|
|
||||||
type TelegramSendOpts = {
|
type TelegramSendOpts = {
|
||||||
|
|||||||
@@ -1,9 +1,5 @@
|
|||||||
import { afterEach, describe, expect, it } from "vitest";
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
import {
|
import { clearSentMessageCache, recordSentMessage, wasSentByBot } from "./sent-message-cache.js";
|
||||||
clearSentMessageCache,
|
|
||||||
recordSentMessage,
|
|
||||||
wasSentByBot,
|
|
||||||
} from "./sent-message-cache.js";
|
|
||||||
|
|
||||||
describe("sent-message-cache", () => {
|
describe("sent-message-cache", () => {
|
||||||
afterEach(() => {
|
afterEach(() => {
|
||||||
|
|||||||
@@ -29,10 +29,7 @@ function cleanupExpired(entry: CacheEntry): void {
|
|||||||
/**
|
/**
|
||||||
* Record a message ID as sent by the bot.
|
* Record a message ID as sent by the bot.
|
||||||
*/
|
*/
|
||||||
export function recordSentMessage(
|
export function recordSentMessage(chatId: number | string, messageId: number): void {
|
||||||
chatId: number | string,
|
|
||||||
messageId: number,
|
|
||||||
): void {
|
|
||||||
const key = getChatKey(chatId);
|
const key = getChatKey(chatId);
|
||||||
let entry = sentMessages.get(key);
|
let entry = sentMessages.get(key);
|
||||||
if (!entry) {
|
if (!entry) {
|
||||||
@@ -50,10 +47,7 @@ export function recordSentMessage(
|
|||||||
/**
|
/**
|
||||||
* Check if a message was sent by the bot.
|
* Check if a message was sent by the bot.
|
||||||
*/
|
*/
|
||||||
export function wasSentByBot(
|
export function wasSentByBot(chatId: number | string, messageId: number): boolean {
|
||||||
chatId: number | string,
|
|
||||||
messageId: number,
|
|
||||||
): boolean {
|
|
||||||
const key = getChatKey(chatId);
|
const key = getChatKey(chatId);
|
||||||
const entry = sentMessages.get(key);
|
const entry = sentMessages.get(key);
|
||||||
if (!entry) return false;
|
if (!entry) return false;
|
||||||
|
|||||||
@@ -63,10 +63,7 @@ export async function startTelegramWebhook(opts: {
|
|||||||
|
|
||||||
await bot.api.setWebhook(publicUrl, {
|
await bot.api.setWebhook(publicUrl, {
|
||||||
secret_token: opts.secret,
|
secret_token: opts.secret,
|
||||||
allowed_updates: [
|
allowed_updates: ["message", "message_reaction"],
|
||||||
"message",
|
|
||||||
"message_reaction",
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
await new Promise<void>((resolve) => server.listen(port, host, resolve));
|
await new Promise<void>((resolve) => server.listen(port, host, resolve));
|
||||||
|
|||||||
Reference in New Issue
Block a user