fix: resolve responsePrefix templates for routed replies (#928) (thanks @sebslight)
This commit is contained in:
parent
f32fc1d5d0
commit
3f0603df54
@ -6,6 +6,7 @@
|
|||||||
- Docs: clarify per-agent auth stores, sandboxed skill binaries, and elevated semantics.
|
- Docs: clarify per-agent auth stores, sandboxed skill binaries, and elevated semantics.
|
||||||
- Docs: add FAQ entries for missing provider auth after adding agents and Gemini thinking signature errors.
|
- Docs: add FAQ entries for missing provider auth after adding agents and Gemini thinking signature errors.
|
||||||
- Agents: add optional auth-profile copy prompt on `agents add` and improve auth error messaging.
|
- Agents: add optional auth-profile copy prompt on `agents add` and improve auth error messaging.
|
||||||
|
- Messages: add responsePrefix template variables (model/provider/identity/think), including routed replies. (#928) — thanks @sebslight.
|
||||||
- Security: add `clawdbot security audit` (`--deep`, `--fix`) and surface it in `status --all` and `doctor`.
|
- Security: add `clawdbot security audit` (`--deep`, `--fix`) and surface it in `status --all` and `doctor`.
|
||||||
- Security: add `clawdbot security audit` (`--deep`, `--fix`) and surface it in `status --all` and `doctor` (includes browser control exposure checks).
|
- Security: add `clawdbot security audit` (`--deep`, `--fix`) and surface it in `status --all` and `doctor` (includes browser control exposure checks).
|
||||||
- Plugins: add Zalo channel plugin with gateway HTTP hooks and onboarding install prompt. (#854) — thanks @longmaba.
|
- Plugins: add Zalo channel plugin with gateway HTTP hooks and onboarding install prompt. (#854) — thanks @longmaba.
|
||||||
|
|||||||
@ -1,12 +1,18 @@
|
|||||||
|
import { resolveSessionAgentId } from "../../agents/agent-scope.js";
|
||||||
|
import { resolveIdentityName } from "../../agents/identity.js";
|
||||||
import type { ClawdbotConfig } from "../../config/config.js";
|
import type { ClawdbotConfig } from "../../config/config.js";
|
||||||
import { logVerbose } from "../../globals.js";
|
import { logVerbose } from "../../globals.js";
|
||||||
import { getReplyFromConfig } from "../reply.js";
|
import { getReplyFromConfig } from "../reply.js";
|
||||||
import type { MsgContext } from "../templating.js";
|
import type { MsgContext } from "../templating.js";
|
||||||
import type { GetReplyOptions, ReplyPayload } from "../types.js";
|
import type { GetReplyOptions, ModelSelectedContext, ReplyPayload } from "../types.js";
|
||||||
import { tryFastAbortFromMessage } from "./abort.js";
|
import { tryFastAbortFromMessage } from "./abort.js";
|
||||||
import { shouldSkipDuplicateInbound } from "./inbound-dedupe.js";
|
import { shouldSkipDuplicateInbound } from "./inbound-dedupe.js";
|
||||||
import type { ReplyDispatcher, ReplyDispatchKind } from "./reply-dispatcher.js";
|
import type { ReplyDispatcher, ReplyDispatchKind } from "./reply-dispatcher.js";
|
||||||
import { isRoutableChannel, routeReply } from "./route-reply.js";
|
import { isRoutableChannel, routeReply } from "./route-reply.js";
|
||||||
|
import {
|
||||||
|
applyModelSelectionToResponsePrefixContext,
|
||||||
|
createResponsePrefixContext,
|
||||||
|
} from "./response-prefix-template.js";
|
||||||
|
|
||||||
export type DispatchFromConfigResult = {
|
export type DispatchFromConfigResult = {
|
||||||
queuedFinal: boolean;
|
queuedFinal: boolean;
|
||||||
@ -39,6 +45,23 @@ export async function dispatchReplyFromConfig(params: {
|
|||||||
const shouldRouteToOriginating =
|
const shouldRouteToOriginating =
|
||||||
isRoutableChannel(originatingChannel) && originatingTo && originatingChannel !== currentSurface;
|
isRoutableChannel(originatingChannel) && originatingTo && originatingChannel !== currentSurface;
|
||||||
|
|
||||||
|
const sessionAgentId = resolveSessionAgentId({
|
||||||
|
sessionKey: ctx.SessionKey,
|
||||||
|
config: cfg,
|
||||||
|
});
|
||||||
|
const responsePrefixContext = shouldRouteToOriginating
|
||||||
|
? createResponsePrefixContext(resolveIdentityName(cfg, sessionAgentId))
|
||||||
|
: undefined;
|
||||||
|
const onModelSelected =
|
||||||
|
responsePrefixContext || params.replyOptions?.onModelSelected
|
||||||
|
? (selection: ModelSelectedContext) => {
|
||||||
|
if (responsePrefixContext) {
|
||||||
|
applyModelSelectionToResponsePrefixContext(responsePrefixContext, selection);
|
||||||
|
}
|
||||||
|
params.replyOptions?.onModelSelected?.(selection);
|
||||||
|
}
|
||||||
|
: undefined;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper to send a payload via route-reply (async).
|
* Helper to send a payload via route-reply (async).
|
||||||
* Only used when actually routing to a different provider.
|
* Only used when actually routing to a different provider.
|
||||||
@ -61,6 +84,7 @@ export async function dispatchReplyFromConfig(params: {
|
|||||||
accountId: ctx.AccountId,
|
accountId: ctx.AccountId,
|
||||||
threadId: ctx.MessageThreadId,
|
threadId: ctx.MessageThreadId,
|
||||||
cfg,
|
cfg,
|
||||||
|
responsePrefixContext,
|
||||||
abortSignal,
|
abortSignal,
|
||||||
});
|
});
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
@ -82,6 +106,7 @@ export async function dispatchReplyFromConfig(params: {
|
|||||||
accountId: ctx.AccountId,
|
accountId: ctx.AccountId,
|
||||||
threadId: ctx.MessageThreadId,
|
threadId: ctx.MessageThreadId,
|
||||||
cfg,
|
cfg,
|
||||||
|
responsePrefixContext,
|
||||||
});
|
});
|
||||||
queuedFinal = result.ok;
|
queuedFinal = result.ok;
|
||||||
if (result.ok) routedFinalCount += 1;
|
if (result.ok) routedFinalCount += 1;
|
||||||
@ -103,6 +128,7 @@ export async function dispatchReplyFromConfig(params: {
|
|||||||
ctx,
|
ctx,
|
||||||
{
|
{
|
||||||
...params.replyOptions,
|
...params.replyOptions,
|
||||||
|
onModelSelected,
|
||||||
onToolResult: (payload: ReplyPayload) => {
|
onToolResult: (payload: ReplyPayload) => {
|
||||||
if (shouldRouteToOriginating) {
|
if (shouldRouteToOriginating) {
|
||||||
// Fire-and-forget for streaming tool results when routing.
|
// Fire-and-forget for streaming tool results when routing.
|
||||||
@ -140,6 +166,7 @@ export async function dispatchReplyFromConfig(params: {
|
|||||||
accountId: ctx.AccountId,
|
accountId: ctx.AccountId,
|
||||||
threadId: ctx.MessageThreadId,
|
threadId: ctx.MessageThreadId,
|
||||||
cfg,
|
cfg,
|
||||||
|
responsePrefixContext,
|
||||||
});
|
});
|
||||||
if (!result.ok) {
|
if (!result.ok) {
|
||||||
logVerbose(
|
logVerbose(
|
||||||
|
|||||||
@ -18,6 +18,16 @@ export type ResponsePrefixContext = {
|
|||||||
identityName?: string;
|
identityName?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export type ModelSelectionInfo = {
|
||||||
|
provider: string;
|
||||||
|
model: string;
|
||||||
|
thinkLevel?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export function createResponsePrefixContext(identityName?: string): ResponsePrefixContext {
|
||||||
|
return identityName ? { identityName } : {};
|
||||||
|
}
|
||||||
|
|
||||||
// Regex pattern for template variables: {variableName} or {variable.name}
|
// Regex pattern for template variables: {variableName} or {variable.name}
|
||||||
const TEMPLATE_VAR_PATTERN = /\{([a-zA-Z][a-zA-Z0-9.]*)\}/g;
|
const TEMPLATE_VAR_PATTERN = /\{([a-zA-Z][a-zA-Z0-9.]*)\}/g;
|
||||||
|
|
||||||
@ -86,6 +96,16 @@ export function extractShortModelName(fullModel: string): string {
|
|||||||
return modelPart.replace(/-\d{8}$/, "").replace(/-latest$/, "");
|
return modelPart.replace(/-\d{8}$/, "").replace(/-latest$/, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function applyModelSelectionToResponsePrefixContext(
|
||||||
|
context: ResponsePrefixContext,
|
||||||
|
selection: ModelSelectionInfo,
|
||||||
|
): void {
|
||||||
|
context.provider = selection.provider;
|
||||||
|
context.model = extractShortModelName(selection.model);
|
||||||
|
context.modelFull = `${selection.provider}/${selection.model}`;
|
||||||
|
context.thinkingLevel = selection.thinkLevel ?? "off";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a template string contains any template variables.
|
* Check if a template string contains any template variables.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -111,6 +111,28 @@ describe("routeReply", () => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("resolves responsePrefix template variables when context is provided", async () => {
|
||||||
|
mocks.sendMessageSlack.mockClear();
|
||||||
|
const cfg = {
|
||||||
|
messages: { responsePrefix: "[{model} | {identity.name}]" },
|
||||||
|
} as unknown as ClawdbotConfig;
|
||||||
|
await routeReply({
|
||||||
|
payload: { text: "hi" },
|
||||||
|
channel: "slack",
|
||||||
|
to: "channel:C123",
|
||||||
|
cfg,
|
||||||
|
responsePrefixContext: {
|
||||||
|
model: "gpt-5.2",
|
||||||
|
identityName: "Clawdbot",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(mocks.sendMessageSlack).toHaveBeenCalledWith(
|
||||||
|
"channel:C123",
|
||||||
|
"[gpt-5.2 | Clawdbot] hi",
|
||||||
|
expect.any(Object),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it("does not derive responsePrefix from agent identity when routing", async () => {
|
it("does not derive responsePrefix from agent identity when routing", async () => {
|
||||||
mocks.sendMessageSlack.mockClear();
|
mocks.sendMessageSlack.mockClear();
|
||||||
const cfg = {
|
const cfg = {
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import { INTERNAL_MESSAGE_CHANNEL } from "../../utils/message-channel.js";
|
|||||||
import type { OriginatingChannelType } from "../templating.js";
|
import type { OriginatingChannelType } from "../templating.js";
|
||||||
import type { ReplyPayload } from "../types.js";
|
import type { ReplyPayload } from "../types.js";
|
||||||
import { normalizeReplyPayload } from "./normalize-reply.js";
|
import { normalizeReplyPayload } from "./normalize-reply.js";
|
||||||
|
import type { ResponsePrefixContext } from "./response-prefix-template.js";
|
||||||
|
|
||||||
export type RouteReplyParams = {
|
export type RouteReplyParams = {
|
||||||
/** The reply payload to send. */
|
/** The reply payload to send. */
|
||||||
@ -31,6 +32,8 @@ export type RouteReplyParams = {
|
|||||||
threadId?: number;
|
threadId?: number;
|
||||||
/** Config for provider-specific settings. */
|
/** Config for provider-specific settings. */
|
||||||
cfg: ClawdbotConfig;
|
cfg: ClawdbotConfig;
|
||||||
|
/** Optional response prefix template context (model/provider/identity). */
|
||||||
|
responsePrefixContext?: ResponsePrefixContext;
|
||||||
/** Optional abort signal for cooperative cancellation. */
|
/** Optional abort signal for cooperative cancellation. */
|
||||||
abortSignal?: AbortSignal;
|
abortSignal?: AbortSignal;
|
||||||
};
|
};
|
||||||
@ -69,6 +72,7 @@ export async function routeReply(params: RouteReplyParams): Promise<RouteReplyRe
|
|||||||
: cfg.messages?.responsePrefix;
|
: cfg.messages?.responsePrefix;
|
||||||
const normalized = normalizeReplyPayload(payload, {
|
const normalized = normalizeReplyPayload(payload, {
|
||||||
responsePrefix,
|
responsePrefix,
|
||||||
|
responsePrefixContext: params.responsePrefixContext,
|
||||||
});
|
});
|
||||||
if (!normalized) return { ok: true };
|
if (!normalized) return { ok: true };
|
||||||
|
|
||||||
|
|||||||
@ -5,8 +5,8 @@ import {
|
|||||||
resolveIdentityName,
|
resolveIdentityName,
|
||||||
} from "../../agents/identity.js";
|
} from "../../agents/identity.js";
|
||||||
import {
|
import {
|
||||||
extractShortModelName,
|
applyModelSelectionToResponsePrefixContext,
|
||||||
type ResponsePrefixContext,
|
createResponsePrefixContext,
|
||||||
} from "../../auto-reply/reply/response-prefix-template.js";
|
} from "../../auto-reply/reply/response-prefix-template.js";
|
||||||
import { formatAgentEnvelope, formatThreadStarterEnvelope } from "../../auto-reply/envelope.js";
|
import { formatAgentEnvelope, formatThreadStarterEnvelope } from "../../auto-reply/envelope.js";
|
||||||
import { dispatchReplyFromConfig } from "../../auto-reply/reply/dispatch-from-config.js";
|
import { dispatchReplyFromConfig } from "../../auto-reply/reply/dispatch-from-config.js";
|
||||||
@ -286,10 +286,7 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext)
|
|||||||
? deliverTarget.slice("channel:".length)
|
? deliverTarget.slice("channel:".length)
|
||||||
: message.channelId;
|
: message.channelId;
|
||||||
|
|
||||||
// Create mutable context for response prefix template interpolation
|
const prefixContext = createResponsePrefixContext(resolveIdentityName(cfg, route.agentId));
|
||||||
let prefixContext: ResponsePrefixContext = {
|
|
||||||
identityName: resolveIdentityName(cfg, route.agentId),
|
|
||||||
};
|
|
||||||
|
|
||||||
const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({
|
const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({
|
||||||
responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix,
|
responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix,
|
||||||
@ -329,11 +326,7 @@ export async function processDiscordMessage(ctx: DiscordMessagePreflightContext)
|
|||||||
? !discordConfig.blockStreaming
|
? !discordConfig.blockStreaming
|
||||||
: undefined,
|
: undefined,
|
||||||
onModelSelected: (ctx) => {
|
onModelSelected: (ctx) => {
|
||||||
// Mutate the object directly instead of reassigning to ensure the closure sees updates
|
applyModelSelectionToResponsePrefixContext(prefixContext, ctx);
|
||||||
prefixContext.provider = ctx.provider;
|
|
||||||
prefixContext.model = extractShortModelName(ctx.model);
|
|
||||||
prefixContext.modelFull = `${ctx.provider}/${ctx.model}`;
|
|
||||||
prefixContext.thinkingLevel = ctx.thinkLevel ?? "off";
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
resolveIdentityName,
|
resolveIdentityName,
|
||||||
} from "../../agents/identity.js";
|
} from "../../agents/identity.js";
|
||||||
import {
|
import {
|
||||||
extractShortModelName,
|
applyModelSelectionToResponsePrefixContext,
|
||||||
type ResponsePrefixContext,
|
createResponsePrefixContext,
|
||||||
} from "../../auto-reply/reply/response-prefix-template.js";
|
} from "../../auto-reply/reply/response-prefix-template.js";
|
||||||
import { resolveTextChunkLimit } from "../../auto-reply/chunk.js";
|
import { resolveTextChunkLimit } from "../../auto-reply/chunk.js";
|
||||||
import { hasControlCommand } from "../../auto-reply/command-detection.js";
|
import { hasControlCommand } from "../../auto-reply/command-detection.js";
|
||||||
@ -350,10 +350,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P
|
|||||||
|
|
||||||
let didSendReply = false;
|
let didSendReply = false;
|
||||||
|
|
||||||
// Create mutable context for response prefix template interpolation
|
const prefixContext = createResponsePrefixContext(resolveIdentityName(cfg, route.agentId));
|
||||||
let prefixContext: ResponsePrefixContext = {
|
|
||||||
identityName: resolveIdentityName(cfg, route.agentId),
|
|
||||||
};
|
|
||||||
|
|
||||||
const dispatcher = createReplyDispatcher({
|
const dispatcher = createReplyDispatcher({
|
||||||
responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix,
|
responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix,
|
||||||
@ -386,11 +383,7 @@ export async function monitorIMessageProvider(opts: MonitorIMessageOpts = {}): P
|
|||||||
? !accountInfo.config.blockStreaming
|
? !accountInfo.config.blockStreaming
|
||||||
: undefined,
|
: undefined,
|
||||||
onModelSelected: (ctx) => {
|
onModelSelected: (ctx) => {
|
||||||
// Mutate the object directly instead of reassigning to ensure the closure sees updates
|
applyModelSelectionToResponsePrefixContext(prefixContext, ctx);
|
||||||
prefixContext.provider = ctx.provider;
|
|
||||||
prefixContext.model = extractShortModelName(ctx.model);
|
|
||||||
prefixContext.modelFull = `${ctx.provider}/${ctx.model}`;
|
|
||||||
prefixContext.thinkingLevel = ctx.thinkLevel ?? "off";
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
resolveIdentityName,
|
resolveIdentityName,
|
||||||
} from "../../agents/identity.js";
|
} from "../../agents/identity.js";
|
||||||
import {
|
import {
|
||||||
extractShortModelName,
|
applyModelSelectionToResponsePrefixContext,
|
||||||
type ResponsePrefixContext,
|
createResponsePrefixContext,
|
||||||
} from "../../auto-reply/reply/response-prefix-template.js";
|
} from "../../auto-reply/reply/response-prefix-template.js";
|
||||||
import { formatAgentEnvelope } from "../../auto-reply/envelope.js";
|
import { formatAgentEnvelope } from "../../auto-reply/envelope.js";
|
||||||
import { dispatchReplyFromConfig } from "../../auto-reply/reply/dispatch-from-config.js";
|
import { dispatchReplyFromConfig } from "../../auto-reply/reply/dispatch-from-config.js";
|
||||||
@ -319,10 +319,9 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
|
|||||||
|
|
||||||
let didSendReply = false;
|
let didSendReply = false;
|
||||||
|
|
||||||
// Create mutable context for response prefix template interpolation
|
const prefixContext = createResponsePrefixContext(
|
||||||
let prefixContext: ResponsePrefixContext = {
|
resolveIdentityName(deps.cfg, route.agentId),
|
||||||
identityName: resolveIdentityName(deps.cfg, route.agentId),
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const dispatcher = createReplyDispatcher({
|
const dispatcher = createReplyDispatcher({
|
||||||
responsePrefix: resolveEffectiveMessagesConfig(deps.cfg, route.agentId).responsePrefix,
|
responsePrefix: resolveEffectiveMessagesConfig(deps.cfg, route.agentId).responsePrefix,
|
||||||
@ -354,11 +353,7 @@ export function createSignalEventHandler(deps: SignalEventHandlerDeps) {
|
|||||||
disableBlockStreaming:
|
disableBlockStreaming:
|
||||||
typeof deps.blockStreaming === "boolean" ? !deps.blockStreaming : undefined,
|
typeof deps.blockStreaming === "boolean" ? !deps.blockStreaming : undefined,
|
||||||
onModelSelected: (ctx) => {
|
onModelSelected: (ctx) => {
|
||||||
// Mutate the object directly instead of reassigning to ensure the closure sees updates
|
applyModelSelectionToResponsePrefixContext(prefixContext, ctx);
|
||||||
prefixContext.provider = ctx.provider;
|
|
||||||
prefixContext.model = extractShortModelName(ctx.model);
|
|
||||||
prefixContext.modelFull = `${ctx.provider}/${ctx.model}`;
|
|
||||||
prefixContext.thinkingLevel = ctx.thinkLevel ?? "off";
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -4,8 +4,8 @@ import {
|
|||||||
resolveIdentityName,
|
resolveIdentityName,
|
||||||
} from "../../../agents/identity.js";
|
} from "../../../agents/identity.js";
|
||||||
import {
|
import {
|
||||||
extractShortModelName,
|
applyModelSelectionToResponsePrefixContext,
|
||||||
type ResponsePrefixContext,
|
createResponsePrefixContext,
|
||||||
} from "../../../auto-reply/reply/response-prefix-template.js";
|
} from "../../../auto-reply/reply/response-prefix-template.js";
|
||||||
import { dispatchReplyFromConfig } from "../../../auto-reply/reply/dispatch-from-config.js";
|
import { dispatchReplyFromConfig } from "../../../auto-reply/reply/dispatch-from-config.js";
|
||||||
import { clearHistoryEntries } from "../../../auto-reply/reply/history.js";
|
import { clearHistoryEntries } from "../../../auto-reply/reply/history.js";
|
||||||
@ -68,10 +68,7 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
|||||||
|
|
||||||
let didSendReply = false;
|
let didSendReply = false;
|
||||||
|
|
||||||
// Create mutable context for response prefix template interpolation
|
const prefixContext = createResponsePrefixContext(resolveIdentityName(cfg, route.agentId));
|
||||||
let prefixContext: ResponsePrefixContext = {
|
|
||||||
identityName: resolveIdentityName(cfg, route.agentId),
|
|
||||||
};
|
|
||||||
|
|
||||||
const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({
|
const { dispatcher, replyOptions, markDispatchIdle } = createReplyDispatcherWithTyping({
|
||||||
responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix,
|
responsePrefix: resolveEffectiveMessagesConfig(cfg, route.agentId).responsePrefix,
|
||||||
@ -117,11 +114,7 @@ export async function dispatchPreparedSlackMessage(prepared: PreparedSlackMessag
|
|||||||
? !account.config.blockStreaming
|
? !account.config.blockStreaming
|
||||||
: undefined,
|
: undefined,
|
||||||
onModelSelected: (ctx) => {
|
onModelSelected: (ctx) => {
|
||||||
// Mutate the object directly instead of reassigning to ensure the closure sees updates
|
applyModelSelectionToResponsePrefixContext(prefixContext, ctx);
|
||||||
prefixContext.provider = ctx.provider;
|
|
||||||
prefixContext.model = extractShortModelName(ctx.model);
|
|
||||||
prefixContext.modelFull = `${ctx.provider}/${ctx.model}`;
|
|
||||||
prefixContext.thinkingLevel = ctx.thinkLevel ?? "off";
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
// @ts-nocheck
|
// @ts-nocheck
|
||||||
import { resolveEffectiveMessagesConfig, resolveIdentityName } from "../agents/identity.js";
|
import { resolveEffectiveMessagesConfig, resolveIdentityName } from "../agents/identity.js";
|
||||||
import {
|
import {
|
||||||
extractShortModelName,
|
applyModelSelectionToResponsePrefixContext,
|
||||||
type ResponsePrefixContext,
|
createResponsePrefixContext,
|
||||||
} from "../auto-reply/reply/response-prefix-template.js";
|
} from "../auto-reply/reply/response-prefix-template.js";
|
||||||
import { EmbeddedBlockChunker } from "../agents/pi-embedded-block-chunker.js";
|
import { EmbeddedBlockChunker } from "../agents/pi-embedded-block-chunker.js";
|
||||||
import { clearHistoryEntries } from "../auto-reply/reply/history.js";
|
import { clearHistoryEntries } from "../auto-reply/reply/history.js";
|
||||||
@ -118,10 +118,7 @@ export const dispatchTelegramMessage = async ({
|
|||||||
Boolean(draftStream) ||
|
Boolean(draftStream) ||
|
||||||
(typeof telegramCfg.blockStreaming === "boolean" ? !telegramCfg.blockStreaming : undefined);
|
(typeof telegramCfg.blockStreaming === "boolean" ? !telegramCfg.blockStreaming : undefined);
|
||||||
|
|
||||||
// Create mutable context for response prefix template interpolation
|
const prefixContext = createResponsePrefixContext(resolveIdentityName(cfg, route.agentId));
|
||||||
let prefixContext: ResponsePrefixContext = {
|
|
||||||
identityName: resolveIdentityName(cfg, route.agentId),
|
|
||||||
};
|
|
||||||
|
|
||||||
let didSendReply = false;
|
let didSendReply = false;
|
||||||
const { queuedFinal } = await dispatchReplyWithBufferedBlockDispatcher({
|
const { queuedFinal } = await dispatchReplyWithBufferedBlockDispatcher({
|
||||||
@ -162,11 +159,7 @@ export const dispatchTelegramMessage = async ({
|
|||||||
: undefined,
|
: undefined,
|
||||||
disableBlockStreaming,
|
disableBlockStreaming,
|
||||||
onModelSelected: (ctx) => {
|
onModelSelected: (ctx) => {
|
||||||
// Mutate the object directly instead of reassigning to ensure the closure sees updates
|
applyModelSelectionToResponsePrefixContext(prefixContext, ctx);
|
||||||
prefixContext.provider = ctx.provider;
|
|
||||||
prefixContext.model = extractShortModelName(ctx.model);
|
|
||||||
prefixContext.modelFull = `${ctx.provider}/${ctx.model}`;
|
|
||||||
prefixContext.thinkingLevel = ctx.thinkLevel ?? "off";
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
import { resolveEffectiveMessagesConfig, resolveIdentityName } from "../../../agents/identity.js";
|
import { resolveEffectiveMessagesConfig, resolveIdentityName } from "../../../agents/identity.js";
|
||||||
import {
|
import {
|
||||||
extractShortModelName,
|
applyModelSelectionToResponsePrefixContext,
|
||||||
type ResponsePrefixContext,
|
createResponsePrefixContext,
|
||||||
} from "../../../auto-reply/reply/response-prefix-template.js";
|
} from "../../../auto-reply/reply/response-prefix-template.js";
|
||||||
import { resolveTextChunkLimit } from "../../../auto-reply/chunk.js";
|
import { resolveTextChunkLimit } from "../../../auto-reply/chunk.js";
|
||||||
import { formatAgentEnvelope } from "../../../auto-reply/envelope.js";
|
import { formatAgentEnvelope } from "../../../auto-reply/envelope.js";
|
||||||
@ -177,10 +177,9 @@ export async function processMessage(params: {
|
|||||||
params.route.agentId,
|
params.route.agentId,
|
||||||
).responsePrefix;
|
).responsePrefix;
|
||||||
|
|
||||||
// Create mutable context for response prefix template interpolation
|
const prefixContext = createResponsePrefixContext(
|
||||||
let prefixContext: ResponsePrefixContext = {
|
resolveIdentityName(params.cfg, params.route.agentId),
|
||||||
identityName: resolveIdentityName(params.cfg, params.route.agentId),
|
);
|
||||||
};
|
|
||||||
|
|
||||||
const { queuedFinal } = await dispatchReplyWithBufferedBlockDispatcher({
|
const { queuedFinal } = await dispatchReplyWithBufferedBlockDispatcher({
|
||||||
ctx: {
|
ctx: {
|
||||||
@ -278,11 +277,7 @@ export async function processMessage(params: {
|
|||||||
? !params.cfg.channels.whatsapp.blockStreaming
|
? !params.cfg.channels.whatsapp.blockStreaming
|
||||||
: undefined,
|
: undefined,
|
||||||
onModelSelected: (ctx) => {
|
onModelSelected: (ctx) => {
|
||||||
// Mutate the object directly instead of reassigning to ensure the closure sees updates
|
applyModelSelectionToResponsePrefixContext(prefixContext, ctx);
|
||||||
prefixContext.provider = ctx.provider;
|
|
||||||
prefixContext.model = extractShortModelName(ctx.model);
|
|
||||||
prefixContext.modelFull = `${ctx.provider}/${ctx.model}`;
|
|
||||||
prefixContext.thinkingLevel = ctx.thinkLevel ?? "off";
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user