style: fix biome lint
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
import { resolveClawdisAgentDir } from "./agent-paths.js";
|
|
||||||
import { type ClawdisConfig, loadConfig } from "../config/config.js";
|
import { type ClawdisConfig, loadConfig } from "../config/config.js";
|
||||||
|
import { resolveClawdisAgentDir } from "./agent-paths.js";
|
||||||
import { ensureClawdisModelsJson } from "./models-config.js";
|
import { ensureClawdisModelsJson } from "./models-config.js";
|
||||||
|
|
||||||
export type ModelCatalogEntry = {
|
export type ModelCatalogEntry = {
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ vi.mock("../agents/model-catalog.js", () => ({
|
|||||||
loadModelCatalog: vi.fn(),
|
loadModelCatalog: vi.fn(),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
|
|
||||||
import { loadModelCatalog } from "../agents/model-catalog.js";
|
import { loadModelCatalog } from "../agents/model-catalog.js";
|
||||||
|
import { runEmbeddedPiAgent } from "../agents/pi-embedded.js";
|
||||||
import {
|
import {
|
||||||
loadSessionStore,
|
loadSessionStore,
|
||||||
resolveSessionKey,
|
resolveSessionKey,
|
||||||
@@ -277,10 +277,7 @@ describe("directive parsing", () => {
|
|||||||
provider: "anthropic",
|
provider: "anthropic",
|
||||||
model: "claude-opus-4-5",
|
model: "claude-opus-4-5",
|
||||||
workspace: path.join(home, "clawd"),
|
workspace: path.join(home, "clawd"),
|
||||||
allowedModels: [
|
allowedModels: ["anthropic/claude-opus-4-5", "openai/gpt-4.1-mini"],
|
||||||
"anthropic/claude-opus-4-5",
|
|
||||||
"openai/gpt-4.1-mini",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
session: { store: storePath },
|
session: { store: storePath },
|
||||||
},
|
},
|
||||||
@@ -316,7 +313,7 @@ describe("directive parsing", () => {
|
|||||||
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
const text = Array.isArray(res) ? res[0]?.text : res?.text;
|
||||||
expect(text).toContain("Model set to openai/gpt-4.1-mini");
|
expect(text).toContain("Model set to openai/gpt-4.1-mini");
|
||||||
const store = loadSessionStore(storePath);
|
const store = loadSessionStore(storePath);
|
||||||
const entry = store["main"];
|
const entry = store.main;
|
||||||
expect(entry.modelOverride).toBe("gpt-4.1-mini");
|
expect(entry.modelOverride).toBe("gpt-4.1-mini");
|
||||||
expect(entry.providerOverride).toBe("openai");
|
expect(entry.providerOverride).toBe("openai");
|
||||||
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
expect(runEmbeddedPiAgent).not.toHaveBeenCalled();
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import {
|
|||||||
normalizeGroupActivation,
|
normalizeGroupActivation,
|
||||||
parseActivationCommand,
|
parseActivationCommand,
|
||||||
} from "./group-activation.js";
|
} from "./group-activation.js";
|
||||||
|
import { extractModelDirective } from "./model.js";
|
||||||
import { buildStatusMessage } from "./status.js";
|
import { buildStatusMessage } from "./status.js";
|
||||||
import type { MsgContext, TemplateContext } from "./templating.js";
|
import type { MsgContext, TemplateContext } from "./templating.js";
|
||||||
import {
|
import {
|
||||||
@@ -52,7 +53,6 @@ import {
|
|||||||
type ThinkLevel,
|
type ThinkLevel,
|
||||||
type VerboseLevel,
|
type VerboseLevel,
|
||||||
} from "./thinking.js";
|
} from "./thinking.js";
|
||||||
import { extractModelDirective } from "./model.js";
|
|
||||||
import { SILENT_REPLY_TOKEN } from "./tokens.js";
|
import { SILENT_REPLY_TOKEN } from "./tokens.js";
|
||||||
import { isAudio, transcribeInboundAudio } from "./transcription.js";
|
import { isAudio, transcribeInboundAudio } from "./transcription.js";
|
||||||
import type { GetReplyOptions, ReplyPayload } from "./types.js";
|
import type { GetReplyOptions, ReplyPayload } from "./types.js";
|
||||||
@@ -199,9 +199,7 @@ export async function getReplyFromConfig(
|
|||||||
const configuredTypingSeconds =
|
const configuredTypingSeconds =
|
||||||
agentCfg?.typingIntervalSeconds ?? sessionCfg?.typingIntervalSeconds;
|
agentCfg?.typingIntervalSeconds ?? sessionCfg?.typingIntervalSeconds;
|
||||||
const typingIntervalSeconds =
|
const typingIntervalSeconds =
|
||||||
typeof configuredTypingSeconds === "number"
|
typeof configuredTypingSeconds === "number" ? configuredTypingSeconds : 6;
|
||||||
? configuredTypingSeconds
|
|
||||||
: 6;
|
|
||||||
const typingIntervalMs = typingIntervalSeconds * 1000;
|
const typingIntervalMs = typingIntervalSeconds * 1000;
|
||||||
const cleanupTyping = () => {
|
const cleanupTyping = () => {
|
||||||
if (typingTimer) {
|
if (typingTimer) {
|
||||||
@@ -393,7 +391,8 @@ export async function getReplyFromConfig(
|
|||||||
const hasStoredOverride = Boolean(
|
const hasStoredOverride = Boolean(
|
||||||
sessionEntry?.modelOverride || sessionEntry?.providerOverride,
|
sessionEntry?.modelOverride || sessionEntry?.providerOverride,
|
||||||
);
|
);
|
||||||
const needsModelCatalog = hasModelDirective || hasAllowlist || hasStoredOverride;
|
const needsModelCatalog =
|
||||||
|
hasModelDirective || hasAllowlist || hasStoredOverride;
|
||||||
let allowedModelKeys = new Set<string>();
|
let allowedModelKeys = new Set<string>();
|
||||||
let allowedModelCatalog: Awaited<ReturnType<typeof loadModelCatalog>> = [];
|
let allowedModelCatalog: Awaited<ReturnType<typeof loadModelCatalog>> = [];
|
||||||
let resetModelOverride = false;
|
let resetModelOverride = false;
|
||||||
@@ -467,7 +466,8 @@ export async function getReplyFromConfig(
|
|||||||
}
|
}
|
||||||
for (const entry of allowedModelCatalog) {
|
for (const entry of allowedModelCatalog) {
|
||||||
const label = `${entry.provider}/${entry.id}`;
|
const label = `${entry.provider}/${entry.id}`;
|
||||||
const suffix = entry.name && entry.name !== entry.id ? ` — ${entry.name}` : "";
|
const suffix =
|
||||||
|
entry.name && entry.name !== entry.id ? ` — ${entry.name}` : "";
|
||||||
lines.push(`- ${label}${suffix}`);
|
lines.push(`- ${label}${suffix}`);
|
||||||
}
|
}
|
||||||
cleanupTyping();
|
cleanupTyping();
|
||||||
@@ -585,7 +585,8 @@ export async function getReplyFromConfig(
|
|||||||
const key = modelKey(parsed.provider, parsed.model);
|
const key = modelKey(parsed.provider, parsed.model);
|
||||||
if (allowedModelKeys.size === 0 || allowedModelKeys.has(key)) {
|
if (allowedModelKeys.size === 0 || allowedModelKeys.has(key)) {
|
||||||
const isDefault =
|
const isDefault =
|
||||||
parsed.provider === defaultProvider && parsed.model === defaultModel;
|
parsed.provider === defaultProvider &&
|
||||||
|
parsed.model === defaultModel;
|
||||||
if (isDefault) {
|
if (isDefault) {
|
||||||
delete sessionEntry.providerOverride;
|
delete sessionEntry.providerOverride;
|
||||||
delete sessionEntry.modelOverride;
|
delete sessionEntry.modelOverride;
|
||||||
@@ -767,46 +768,41 @@ export async function getReplyFromConfig(
|
|||||||
const shouldInjectGroupIntro =
|
const shouldInjectGroupIntro =
|
||||||
isGroupChat &&
|
isGroupChat &&
|
||||||
(isFirstTurnInSession || sessionEntry?.groupActivationNeedsSystemIntro);
|
(isFirstTurnInSession || sessionEntry?.groupActivationNeedsSystemIntro);
|
||||||
const groupIntro =
|
const groupIntro = shouldInjectGroupIntro
|
||||||
shouldInjectGroupIntro
|
? (() => {
|
||||||
? (() => {
|
const activation =
|
||||||
const activation =
|
normalizeGroupActivation(sessionEntry?.groupActivation) ??
|
||||||
normalizeGroupActivation(sessionEntry?.groupActivation) ??
|
defaultGroupActivation();
|
||||||
defaultGroupActivation();
|
const subject = sessionCtx.GroupSubject?.trim();
|
||||||
const subject = sessionCtx.GroupSubject?.trim();
|
const members = sessionCtx.GroupMembers?.trim();
|
||||||
const members = sessionCtx.GroupMembers?.trim();
|
const subjectLine = subject
|
||||||
const subjectLine = subject
|
? `You are replying inside the WhatsApp group "${subject}".`
|
||||||
? `You are replying inside the WhatsApp group "${subject}".`
|
: "You are replying inside a WhatsApp group chat.";
|
||||||
: "You are replying inside a WhatsApp group chat.";
|
const membersLine = members ? `Group members: ${members}.` : undefined;
|
||||||
const membersLine = members
|
const activationLine =
|
||||||
? `Group members: ${members}.`
|
activation === "always"
|
||||||
|
? "Activation: always-on (you receive every group message)."
|
||||||
|
: "Activation: trigger-only (you are invoked only when explicitly mentioned; recent context may be included).";
|
||||||
|
const silenceLine =
|
||||||
|
activation === "always"
|
||||||
|
? `If no response is needed, reply with exactly "${SILENT_REPLY_TOKEN}" (no other text) so Clawdis stays silent.`
|
||||||
: undefined;
|
: undefined;
|
||||||
const activationLine =
|
const cautionLine =
|
||||||
activation === "always"
|
activation === "always"
|
||||||
? "Activation: always-on (you receive every group message)."
|
? "Be extremely selective: reply only when you are directly addressed, asked a question, or can add clear value. Otherwise stay silent."
|
||||||
: "Activation: trigger-only (you are invoked only when explicitly mentioned; recent context may be included).";
|
: undefined;
|
||||||
const silenceLine =
|
return [
|
||||||
activation === "always"
|
subjectLine,
|
||||||
? `If no response is needed, reply with exactly "${SILENT_REPLY_TOKEN}" (no other text) so Clawdis stays silent.`
|
membersLine,
|
||||||
: undefined;
|
activationLine,
|
||||||
const cautionLine =
|
silenceLine,
|
||||||
activation === "always"
|
cautionLine,
|
||||||
? "Be extremely selective: reply only when you are directly addressed, asked a question, or can add clear value. Otherwise stay silent."
|
]
|
||||||
: undefined;
|
.filter(Boolean)
|
||||||
return [
|
.join(" ")
|
||||||
subjectLine,
|
.concat(" Address the specific sender noted in the message context.");
|
||||||
membersLine,
|
})()
|
||||||
activationLine,
|
: "";
|
||||||
silenceLine,
|
|
||||||
cautionLine,
|
|
||||||
]
|
|
||||||
.filter(Boolean)
|
|
||||||
.join(" ")
|
|
||||||
.concat(
|
|
||||||
" Address the specific sender noted in the message context.",
|
|
||||||
);
|
|
||||||
})()
|
|
||||||
: "";
|
|
||||||
const baseBody = sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
|
const baseBody = sessionCtx.BodyStripped ?? sessionCtx.Body ?? "";
|
||||||
const rawBodyTrimmed = (ctx.Body ?? "").trim();
|
const rawBodyTrimmed = (ctx.Body ?? "").trim();
|
||||||
const baseBodyTrimmedRaw = baseBody.trim();
|
const baseBodyTrimmedRaw = baseBody.trim();
|
||||||
|
|||||||
@@ -116,14 +116,11 @@ export function registerGatewayCli(program: Command) {
|
|||||||
}
|
}
|
||||||
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
|
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
|
||||||
const authMode =
|
const authMode =
|
||||||
authModeRaw === "token" ||
|
authModeRaw === "token" || authModeRaw === "password"
|
||||||
authModeRaw === "password"
|
|
||||||
? authModeRaw
|
? authModeRaw
|
||||||
: null;
|
: null;
|
||||||
if (authModeRaw && !authMode) {
|
if (authModeRaw && !authMode) {
|
||||||
defaultRuntime.error(
|
defaultRuntime.error('Invalid --auth (use "token" or "password")');
|
||||||
'Invalid --auth (use "token" or "password")',
|
|
||||||
);
|
|
||||||
defaultRuntime.exit(1);
|
defaultRuntime.exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -334,14 +331,11 @@ export function registerGatewayCli(program: Command) {
|
|||||||
}
|
}
|
||||||
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
|
const authModeRaw = opts.auth ? String(opts.auth) : undefined;
|
||||||
const authMode =
|
const authMode =
|
||||||
authModeRaw === "token" ||
|
authModeRaw === "token" || authModeRaw === "password"
|
||||||
authModeRaw === "password"
|
|
||||||
? authModeRaw
|
? authModeRaw
|
||||||
: null;
|
: null;
|
||||||
if (authModeRaw && !authMode) {
|
if (authModeRaw && !authMode) {
|
||||||
defaultRuntime.error(
|
defaultRuntime.error('Invalid --auth (use "token" or "password")');
|
||||||
'Invalid --auth (use "token" or "password")',
|
|
||||||
);
|
|
||||||
defaultRuntime.exit(1);
|
defaultRuntime.exit(1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -535,12 +535,7 @@ const ClawdisSchema = z.object({
|
|||||||
.optional(),
|
.optional(),
|
||||||
auth: z
|
auth: z
|
||||||
.object({
|
.object({
|
||||||
mode: z
|
mode: z.union([z.literal("token"), z.literal("password")]).optional(),
|
||||||
.union([
|
|
||||||
z.literal("token"),
|
|
||||||
z.literal("password"),
|
|
||||||
])
|
|
||||||
.optional(),
|
|
||||||
password: z.string().optional(),
|
password: z.string().optional(),
|
||||||
allowTailscale: z.boolean().optional(),
|
allowTailscale: z.boolean().optional(),
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ import {
|
|||||||
} from "../agents/defaults.js";
|
} from "../agents/defaults.js";
|
||||||
import {
|
import {
|
||||||
loadModelCatalog,
|
loadModelCatalog,
|
||||||
resetModelCatalogCacheForTest,
|
|
||||||
type ModelCatalogEntry,
|
type ModelCatalogEntry,
|
||||||
|
resetModelCatalogCacheForTest,
|
||||||
} from "../agents/model-catalog.js";
|
} from "../agents/model-catalog.js";
|
||||||
import { installSkill } from "../agents/skills-install.js";
|
import { installSkill } from "../agents/skills-install.js";
|
||||||
import { buildWorkspaceSkillStatus } from "../agents/skills-status.js";
|
import { buildWorkspaceSkillStatus } from "../agents/skills-status.js";
|
||||||
@@ -1393,11 +1393,7 @@ export async function startGatewayServer(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const { e164, jid } = readWebSelfId();
|
const { e164, jid } = readWebSelfId();
|
||||||
const identity = e164
|
const identity = e164 ? e164 : jid ? `jid ${jid}` : "unknown";
|
||||||
? e164
|
|
||||||
: jid
|
|
||||||
? `jid ${jid}`
|
|
||||||
: "unknown";
|
|
||||||
logWhatsApp.info(`starting provider (${identity})`);
|
logWhatsApp.info(`starting provider (${identity})`);
|
||||||
whatsappAbort = new AbortController();
|
whatsappAbort = new AbortController();
|
||||||
whatsappRuntime = {
|
whatsappRuntime = {
|
||||||
|
|||||||
Reference in New Issue
Block a user