mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-11 03:13:12 +00:00
fix: normalize websearch hook output for local providers
This commit is contained in:
1 parent
39ba295d5f
commit
a5d71e3560
2 files changed
+189
-33
No files matched your search
@@ -183,23 +183,58 @@ function extractDuckDuckGoResults(html, count) {
|
||||
}
|
||||
|
||||
function formatStructuredSearchResults(query, providerName, results) {
|
||||
const lines = [
|
||||
'CCS local WebSearch evidence',
|
||||
`Provider: ${providerName}`,
|
||||
`Query: "${query}"`,
|
||||
`Result count: ${results.length}`,
|
||||
'',
|
||||
];
|
||||
|
||||
if (!results.length) {
|
||||
return `No search results found for "${query}" via ${providerName}.`;
|
||||
lines.push('No results found.');
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
const lines = [`Search results for "${query}" via ${providerName}:`, ''];
|
||||
for (const [index, result] of results.entries()) {
|
||||
lines.push(`${index + 1}. ${result.title}`);
|
||||
lines.push(` ${result.url}`);
|
||||
lines.push(` URL: ${result.url}`);
|
||||
if (result.description) {
|
||||
lines.push(` ${result.description}`);
|
||||
lines.push(` Snippet: ${result.description}`);
|
||||
}
|
||||
lines.push('');
|
||||
}
|
||||
lines.push('Use these results to answer the user directly.');
|
||||
return lines.join('\n');
|
||||
}
|
||||
|
||||
function buildSuccessHookOutput(query, providerName, content) {
|
||||
return {
|
||||
hookSpecificOutput: {
|
||||
hookEventName: 'PreToolUse',
|
||||
permissionDecision: 'deny',
|
||||
permissionDecisionReason: `CCS already retrieved WebSearch results locally via ${providerName}. Use the provided context instead of calling native WebSearch for "${query}".`,
|
||||
additionalContext: content,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function buildFailureHookOutput(query, errors) {
|
||||
const detail = errors.map((entry) => `${entry.provider}: ${entry.error}`).join(' | ');
|
||||
return {
|
||||
hookSpecificOutput: {
|
||||
hookEventName: 'PreToolUse',
|
||||
permissionDecision: 'deny',
|
||||
permissionDecisionReason: `CCS could not complete local WebSearch for "${query}". Native WebSearch is unavailable for this profile.`,
|
||||
additionalContext: `CCS local WebSearch failed for "${query}". Attempted providers: ${detail}`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function emitHookOutput(output) {
|
||||
console.log(JSON.stringify(output));
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
async function fetchWithTimeout(url, options, timeoutMs) {
|
||||
const controller = new AbortController();
|
||||
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
||||
@@ -534,34 +569,11 @@ function tryGrokSearch(query, timeoutSec = DEFAULT_TIMEOUT_SEC) {
|
||||
}
|
||||
|
||||
function outputSuccess(query, content, providerName) {
|
||||
const output = {
|
||||
decision: 'block',
|
||||
reason: `WebSearch handled via ${providerName}`,
|
||||
hookSpecificOutput: {
|
||||
hookEventName: 'PreToolUse',
|
||||
permissionDecision: 'deny',
|
||||
permissionDecisionReason: `[WebSearch Result via ${providerName}]\n\nQuery: "${query}"\n\n${content}`,
|
||||
},
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(output));
|
||||
process.exit(2);
|
||||
emitHookOutput(buildSuccessHookOutput(query, providerName, content));
|
||||
}
|
||||
|
||||
function outputAllFailedMessage(query, errors) {
|
||||
const detail = errors.map((entry) => `${entry.provider}: ${entry.error}`).join(' | ');
|
||||
const output = {
|
||||
decision: 'block',
|
||||
reason: 'WebSearch fallback failed',
|
||||
hookSpecificOutput: {
|
||||
hookEventName: 'PreToolUse',
|
||||
permissionDecision: 'deny',
|
||||
permissionDecisionReason: `WebSearch could not be completed for "${query}". ${detail}`,
|
||||
},
|
||||
};
|
||||
|
||||
console.log(JSON.stringify(output));
|
||||
process.exit(2);
|
||||
emitHookOutput(buildFailureHookOutput(query, errors));
|
||||
}
|
||||
|
||||
async function processHook(input) {
|
||||
@@ -675,6 +687,8 @@ if (require.main === module) {
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
buildFailureHookOutput,
|
||||
buildSuccessHookOutput,
|
||||
extractDuckDuckGoResults,
|
||||
formatStructuredSearchResults,
|
||||
tryExaSearch,
|
||||
|
||||
Reference in new issue
Block a user