feat(h5): inject direct-chat history on agent escalation and defer ambiguous routing.

Phase B appends snapshot context when leaving h5direct sessions so Goose no longer starts blind. Phase C lets the 0.72 fallback return null on gated chat text so the existing LLM router can run, flags default off.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
john
2026-08-28 20:45:34 +08:00
parent 6f48cad4c2
commit 5f3980e0df
9 changed files with 654 additions and 3 deletions
+25
View File
@@ -22,7 +22,17 @@ import {
} from './conversation-display.mjs';
import { isGoalRunIntent } from './goal-run-intent.mjs';
import { pgvectorMemoryBackendInternals } from './memory-v2-pgvector.mjs';
import {
isChatSessionDeferEnabledForUser,
resolveChatSessionDeferPolicy,
shouldDeferChatSessionRoutingToLlm,
} from './chat-task-intent-config.mjs';
export { shouldDeferChatSessionRoutingToLlm } from './chat-task-intent-config.mjs';
export {
resolveChatSessionDeferPolicy,
isChatSessionDeferEnabledForUser,
} from './chat-task-intent-config.mjs';
export { matchDirectChatFaqRule, DIRECT_CHAT_FAQ_RULES, FAQ_EXCLUSION_PATTERNS, isExplicitTextOnlyRequest } from './chat-intent-router-rules.mjs';
export const CHAT_INTENT_ROUTE = {
@@ -1208,6 +1218,8 @@ export function classifyWithRules({
includeIntentPatterns = true,
activeTaskContext = null,
grantedSkills = [],
chatSessionDeferEnabled = false,
chatSessionDeferMinTextLength = 12,
} = {}) {
const decisionContext = {
text,
@@ -1363,6 +1375,14 @@ export function classifyWithRules({
) {
return null;
}
if (shouldDeferChatSessionRoutingToLlm({
enabled: chatSessionDeferEnabled,
text: normalized,
minTextLength: chatSessionDeferMinTextLength,
isExplicitDirectChatOnlyText,
})) {
return null;
}
return finalizeRouterClassification(normalizeClassification({
route: CHAT_INTENT_ROUTE.DIRECT_CHAT,
confidence: 0.72,
@@ -1398,6 +1418,8 @@ export function createChatIntentRouter(options = {}) {
'fallbackRoute',
]),
});
const chatSessionDeferPolicy = options.chatSessionDeferPolicy
?? resolveChatSessionDeferPolicy(env);
function isLlmRouterEligibleForUser(userId) {
return isChatLlmRouterEligible({
@@ -1723,6 +1745,7 @@ export function createChatIntentRouter(options = {}) {
}, decisionContext);
};
const llmRouterEligible = isLlmRouterEligibleForUser(userId);
const chatSessionDeferEnabled = isChatSessionDeferEnabledForUser(userId, chatSessionDeferPolicy);
const ruleResult = classifyWithRules({
text,
forceDeepReasoning,
@@ -1733,6 +1756,8 @@ export function createChatIntentRouter(options = {}) {
includeIntentPatterns: true,
activeTaskContext,
grantedSkills,
chatSessionDeferEnabled,
chatSessionDeferMinTextLength: chatSessionDeferPolicy.minTextLength,
});
if (ruleResult) return finalizeWithCoercion(ruleResult);