mirror of
https://github.com/wu736139669/hapi.git
synced 2026-10-09 19:29:41 +00:00
feat: settings toggle for AGENT_NOTIFY_SUMMARY contract injection (#1376)
* feat: settings toggle for AGENT_NOTIFY_SUMMARY contract injection Add a hub-persisted, default-off Settings control so operators can opt agents into emitting the trailing AGENT_NOTIFY_SUMMARY line. Propagate the resolved flag on CLI session bootstrap and inject at call time for Claude, Codex, OpenCode, and Grok (Cursor still unsupported). Closes #1375 Co-authored-by: Cursor <cursoragent@cursor.com> * fix: lock hub settings RMW and restore abort deliveryMode Serialize settings.json updates with the shared .lock protocol and unique temp files so the new hub toggle cannot clobber CLI/relay fields under concurrency. Also supply deliveryMode on abort send-error restore so web typecheck (and CI) pass. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): wrap SettingsGeneralPage tests with QueryClientProvider The hub-settings toggle uses TanStack Query; the settings page suite was rendering without a QueryClient and blew up CI. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): defer summary-contract toggle until settings load Avoid rendering an interactive false switch while the hub GET is still in flight, which could overwrite an enabled preference on early click. Co-authored-by: Cursor <cursoragent@cursor.com> * fix(web): clarify Grok coverage for summary-contract toggle Local Grok has no instruction inject path; settings copy now matches remote-only Grok support (and still excludes Cursor). Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -4,7 +4,7 @@ import { OpencodeSession } from './session';
|
||||
import { ensureOpencodeHookPlugin } from './utils/hookPlugin';
|
||||
import { buildOpencodeEnv } from './utils/config';
|
||||
import { ensureOpencodeConfig } from './utils/opencodeConfig';
|
||||
import { TITLE_INSTRUCTION } from './utils/systemPrompt';
|
||||
import { getTitleInstruction } from './utils/systemPrompt';
|
||||
import { buildHapiMcpBridge } from '@/codex/utils/buildHapiMcpBridge';
|
||||
import type { OpencodeHookEvent } from './types';
|
||||
import type { OpencodeHookServer } from './utils/startOpencodeHookServer';
|
||||
@@ -194,7 +194,7 @@ export async function opencodeLocalLauncher(
|
||||
logger.debug(`[opencode-local]: Started hapi MCP server at ${happyServer.url}`);
|
||||
|
||||
// Generate opencode.json config with MCP server and instructions
|
||||
const { configPath } = ensureOpencodeConfig(opencodeConfigDir, bridge.mcpServers.hapi, TITLE_INSTRUCTION);
|
||||
const { configPath } = ensureOpencodeConfig(opencodeConfigDir, bridge.mcpServers.hapi, getTitleInstruction());
|
||||
opencodeConfigPath = configPath;
|
||||
} catch (error) {
|
||||
logger.debug('[opencode-local]: Failed to start hapi MCP server (change_title will be unavailable)', error);
|
||||
|
||||
@@ -15,7 +15,7 @@ import { RPC_METHODS } from '@hapi/protocol/rpcMethods';
|
||||
import { allocateFreePort, createOpencodeBackend } from './utils/opencodeBackend';
|
||||
import { captureCompactionMarkerSnapshot, fetchCompactionResult, splitProviderModel, triggerOpencodeCompact } from './utils/opencodeCompactBridge';
|
||||
import { OpencodePermissionHandler } from './utils/permissionHandler';
|
||||
import { OPENCODE_NATIVE_TOOL_INSTRUCTION, PLAN_MODE_INSTRUCTION } from './utils/systemPrompt';
|
||||
import { getOpencodeNativeToolInstruction, PLAN_MODE_INSTRUCTION } from './utils/systemPrompt';
|
||||
import { resolveThoughtLevelEffort } from './thoughtLevelEffort';
|
||||
|
||||
type OpencodeRemoteLauncherOptions = {
|
||||
@@ -565,7 +565,7 @@ class OpencodeRemoteLauncher extends RemoteLauncherBase {
|
||||
messageText = `${PLAN_MODE_INSTRUCTION}\n\n${messageText}`;
|
||||
}
|
||||
if (!this.instructionsSent) {
|
||||
messageText = `${OPENCODE_NATIVE_TOOL_INSTRUCTION}\n\n${messageText}`;
|
||||
messageText = `${getOpencodeNativeToolInstruction()}\n\n${messageText}`;
|
||||
this.instructionsSent = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { trimIdent } from '@/utils/trimIdent';
|
||||
import { buildSessionCitationSteerInstruction } from '@hapi/protocol/sessionCitation';
|
||||
import { SKILL_LOOKUP_INSTRUCTION } from '@/modules/common/skillLookupInstruction';
|
||||
import { withSessionSummaryInstruction } from '@/modules/common/sessionSummaryInstruction';
|
||||
|
||||
/**
|
||||
* Title instruction for OpenCode to call the hapi MCP tool.
|
||||
@@ -23,6 +24,10 @@ export const TITLE_INSTRUCTION = trimIdent(`
|
||||
${SKILL_LOOKUP_INSTRUCTION}
|
||||
`);
|
||||
|
||||
export function getTitleInstruction(env: NodeJS.ProcessEnv = process.env): string {
|
||||
return withSessionSummaryInstruction(TITLE_INSTRUCTION, env)
|
||||
}
|
||||
|
||||
/**
|
||||
* Tool instructions for native ACP sessions. Title updates come from ACP, so
|
||||
* advertise only the MCP tools that remain available to the model.
|
||||
@@ -37,6 +42,10 @@ export const OPENCODE_NATIVE_TOOL_INSTRUCTION = trimIdent(`
|
||||
${SKILL_LOOKUP_INSTRUCTION}
|
||||
`);
|
||||
|
||||
export function getOpencodeNativeToolInstruction(env: NodeJS.ProcessEnv = process.env): string {
|
||||
return withSessionSummaryInstruction(OPENCODE_NATIVE_TOOL_INSTRUCTION, env)
|
||||
}
|
||||
|
||||
/**
|
||||
* The system prompt to inject for OpenCode sessions.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user