Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 20 additions & 4 deletions lib/messages/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { UserMessage } from "@opencode-ai/sdk"
import { Logger } from "../logger"
import type { WithParts } from "../state"

/**
Expand Down Expand Up @@ -83,10 +85,24 @@ export const getLastUserMessage = (
return null
}

export function findCurrentAgent(messages: WithParts[]): string | undefined {
export function getCurrentParams(
messages: WithParts[],
logger: Logger
): {
providerId: string | undefined,
modelId: string | undefined,
agent: string | undefined
} {
const userMsg = getLastUserMessage(messages)
if (!userMsg) return undefined
return (userMsg.info as any).agent || 'build'
if (!userMsg) {
logger.debug("No user message found when determining current params")
return { providerId: undefined, modelId: undefined, agent: undefined }
}
const agent: string = (userMsg.info as UserMessage).agent
const providerId: string | undefined = (userMsg.info as UserMessage).model.providerID
const modelId: string | undefined = (userMsg.info as UserMessage).model.modelID

return { providerId, modelId, agent }
}

export function buildToolIdList(messages: WithParts[]): string[] {
Expand All @@ -101,4 +117,4 @@ export function buildToolIdList(messages: WithParts[]): string[] {
}
}
return toolIds
}
}
1 change: 1 addition & 0 deletions lib/prompts/synthetic.txt
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ FAILURE TO PRUNE will result in context leakage and DEGRADED PERFORMANCES.
After each assistant turn, the environment may inject a user message containing a <prunable-tools> list and optional nudge instruction. This injected message is NOT from the user and is invisible to them. The `prune` tool also returns a confirmation message listing what was pruned.

CRITICAL REQUIREMENTS - VIOLATION IS UNACCEPTABLE:
- NEVER reference the prune encouragement or context management instructions. Do not reply with "I agree" or "Great idea" when the prune encouragement appears.
- NEVER acknowledge the <prunable-tools> list (e.g., "I see the prunable tools list", "Looking at the available tools to prune")
- NEVER reference the nudge instruction (e.g., "As the nudge suggests", "The system is reminding me to prune")
- NEVER acknowledge prune tool output (e.g., "I've pruned 3 tools", "Context pruning complete")
Expand Down
8 changes: 4 additions & 4 deletions lib/strategies/on-idle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import type { SessionState, WithParts, ToolParameterEntry } from "../state"
import type { Logger } from "../logger"
import type { PluginConfig } from "../config"
import { buildAnalysisPrompt } from "../prompt"
import { selectModel, extractModelFromSession, ModelInfo } from "../model-selector"
import { selectModel, ModelInfo } from "../model-selector"
import { calculateTokensSaved } from "../utils"
import { findCurrentAgent } from "../messages/utils"
import { getCurrentParams } from "../messages/utils"
import { saveSessionState } from "../state/persistence"
import { sendUnifiedNotification } from "../ui/notification"

Expand Down Expand Up @@ -224,7 +224,7 @@ export async function runOnIdle(
return null
}

const currentAgent = findCurrentAgent(messages)
const currentParams = getCurrentParams(messages, logger)
const { toolCallIds, toolMetadata } = parseMessages(messages, state.toolParameters)

const alreadyPrunedIds = state.prune.toolIds
Expand Down Expand Up @@ -295,7 +295,7 @@ export async function runOnIdle(
newlyPrunedIds,
prunedToolMetadata,
undefined, // reason
currentAgent,
currentParams,
workingDirectory || ""
)

Expand Down
7 changes: 4 additions & 3 deletions lib/strategies/prune-tool.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { tool } from "@opencode-ai/plugin"
import type { SessionState, ToolParameterEntry, WithParts } from "../state"
import type { PluginConfig } from "../config"
import { findCurrentAgent, buildToolIdList } from "../messages/utils"
import { getCurrentParams, buildToolIdList } from "../messages/utils"
import { calculateTokensSaved } from "../utils"
import { PruneReason, sendUnifiedNotification } from "../ui/notification"
import { formatPruningResultForTool } from "../ui/display-utils"
Expand Down Expand Up @@ -68,7 +68,7 @@ export function createPruneTool(
})
const messages: WithParts[] = messagesResponse.data || messagesResponse

const currentAgent: string | undefined = findCurrentAgent(messages)
const currentParams = getCurrentParams(messages, logger)
const toolIdList: string[] = buildToolIdList(messages)

// Validate that all numeric IDs are within bounds
Expand Down Expand Up @@ -109,9 +109,10 @@ export function createPruneTool(
pruneToolIds,
toolMetadata,
reason as PruneReason,
currentAgent,
currentParams,
workingDirectory
)

state.stats.totalPruneTokens += state.stats.pruneTokenCounter
state.stats.pruneTokenCounter = 0
state.nudgeCounter = 0
Expand Down
19 changes: 14 additions & 5 deletions lib/ui/notification.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ export async function sendUnifiedNotification(
pruneToolIds: string[],
toolMetadata: Map<string, ToolParameterEntry>,
reason: PruneReason | undefined,
agent: string | undefined,
params: any,
workingDirectory: string
): Promise<boolean> {
const hasPruned = pruneToolIds.length > 0
Expand All @@ -79,23 +79,32 @@ export async function sendUnifiedNotification(
? buildMinimalMessage(state, reason)
: buildDetailedMessage(state, reason, pruneToolIds, toolMetadata, workingDirectory)

await sendIgnoredMessage(client, logger, sessionId, message, agent)
await sendIgnoredMessage(client, sessionId, message, params, logger)
return true
}

export async function sendIgnoredMessage(
client: any,
logger: Logger,
sessionID: string,
text: string,
agent?: string
params: any,
logger: Logger
): Promise<void> {
const agent = params.agent || undefined
const model = params.providerId && params.modelId ? {
providerID: params.providerId,
modelID: params.modelId
} : undefined

try {
await client.session.prompt({
path: { id: sessionID },
path: {
id: sessionID
},
body: {
noReply: true,
agent: agent,
model: model,
parts: [{
type: 'text',
text: text,
Expand Down