fix: fast-lane directives bypass queue dedupe
This commit is contained in:
@@ -708,6 +708,9 @@ export async function getReplyFromConfig(
|
||||
const inlineStatusRequested =
|
||||
hasInlineStatus && allowTextCommands && command.isAuthorizedSender;
|
||||
|
||||
// Inline control directives should apply immediately, even when mixed with text.
|
||||
let directiveAck: ReplyPayload | undefined;
|
||||
|
||||
if (!command.isAuthorizedSender) {
|
||||
directives = {
|
||||
...directives,
|
||||
@@ -851,6 +854,77 @@ export async function getReplyFromConfig(
|
||||
await opts.onBlockReply(reply);
|
||||
};
|
||||
|
||||
const hasAnyDirective =
|
||||
directives.hasThinkDirective ||
|
||||
directives.hasVerboseDirective ||
|
||||
directives.hasReasoningDirective ||
|
||||
directives.hasElevatedDirective ||
|
||||
directives.hasModelDirective ||
|
||||
directives.hasQueueDirective ||
|
||||
directives.hasStatusDirective;
|
||||
|
||||
if (
|
||||
hasAnyDirective &&
|
||||
command.isAuthorizedSender &&
|
||||
!isDirectiveOnly({
|
||||
directives,
|
||||
cleanedBody: directives.cleaned,
|
||||
ctx,
|
||||
cfg,
|
||||
agentId,
|
||||
isGroup,
|
||||
})
|
||||
) {
|
||||
const resolvedDefaultThinkLevel =
|
||||
(sessionEntry?.thinkingLevel as ThinkLevel | undefined) ??
|
||||
(agentCfg?.thinkingDefault as ThinkLevel | undefined) ??
|
||||
(await modelState.resolveDefaultThinkingLevel());
|
||||
const currentThinkLevel = resolvedDefaultThinkLevel;
|
||||
const currentVerboseLevel =
|
||||
(sessionEntry?.verboseLevel as VerboseLevel | undefined) ??
|
||||
(agentCfg?.verboseDefault as VerboseLevel | undefined);
|
||||
const currentReasoningLevel =
|
||||
(sessionEntry?.reasoningLevel as ReasoningLevel | undefined) ?? "off";
|
||||
const currentElevatedLevel =
|
||||
(sessionEntry?.elevatedLevel as ElevatedLevel | undefined) ??
|
||||
(agentCfg?.elevatedDefault as ElevatedLevel | undefined);
|
||||
|
||||
directiveAck = await handleDirectiveOnly({
|
||||
cfg,
|
||||
directives,
|
||||
sessionEntry,
|
||||
sessionStore,
|
||||
sessionKey,
|
||||
storePath,
|
||||
elevatedEnabled,
|
||||
elevatedAllowed,
|
||||
elevatedFailures,
|
||||
messageProviderKey,
|
||||
defaultProvider,
|
||||
defaultModel,
|
||||
aliasIndex,
|
||||
allowedModelKeys: modelState.allowedModelKeys,
|
||||
allowedModelCatalog: modelState.allowedModelCatalog,
|
||||
resetModelOverride: modelState.resetModelOverride,
|
||||
provider,
|
||||
model,
|
||||
initialModelLabel,
|
||||
formatModelSwitchEvent,
|
||||
currentThinkLevel,
|
||||
currentVerboseLevel,
|
||||
currentReasoningLevel,
|
||||
currentElevatedLevel,
|
||||
});
|
||||
|
||||
// Refresh provider/model from session overrides applied by directives.
|
||||
if (sessionEntry?.providerOverride) {
|
||||
provider = sessionEntry.providerOverride;
|
||||
}
|
||||
if (sessionEntry?.modelOverride) {
|
||||
model = sessionEntry.modelOverride;
|
||||
}
|
||||
}
|
||||
|
||||
const inlineCommand =
|
||||
allowTextCommands && command.isAuthorizedSender
|
||||
? extractInlineSimpleCommand(cleanedBody)
|
||||
@@ -930,6 +1004,10 @@ export async function getReplyFromConfig(
|
||||
}
|
||||
}
|
||||
|
||||
if (directiveAck) {
|
||||
await sendInlineReply(directiveAck);
|
||||
}
|
||||
|
||||
const isEmptyConfig = Object.keys(cfg).length === 0;
|
||||
const skipWhenConfigEmpty = command.providerId
|
||||
? Boolean(
|
||||
|
||||
@@ -117,7 +117,7 @@ describe("followup queue deduplication", () => {
|
||||
);
|
||||
expect(first).toBe(true);
|
||||
|
||||
// Second enqueue with same prompt should be deduplicated
|
||||
// Second enqueue with same prompt should be allowed (we only dedupe with message id)
|
||||
const second = enqueueFollowupRun(
|
||||
key,
|
||||
createRun({
|
||||
@@ -127,7 +127,7 @@ describe("followup queue deduplication", () => {
|
||||
}),
|
||||
settings,
|
||||
);
|
||||
expect(second).toBe(false);
|
||||
expect(second).toBe(true);
|
||||
|
||||
// Third enqueue with different prompt should succeed
|
||||
const third = enqueueFollowupRun(
|
||||
|
||||
@@ -358,9 +358,9 @@ function isRunAlreadyQueued(
|
||||
(item) => item.messageId?.trim() === messageId && hasSameRouting(item),
|
||||
);
|
||||
}
|
||||
return queue.items.some(
|
||||
(item) => item.prompt === run.prompt && hasSameRouting(item),
|
||||
);
|
||||
// Without a provider message id, avoid prompt-based dedupe to ensure rapid
|
||||
// directive messages are not dropped.
|
||||
return false;
|
||||
}
|
||||
|
||||
export function enqueueFollowupRun(
|
||||
|
||||
Reference in New Issue
Block a user