picocode-core 0.9.177 → 0.9.179
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/src/controller.js +3 -1
- package/src/derive.js +21 -2
- package/src/tool-trimming.js +25 -3
- package/src/tools/index.js +11 -1
package/package.json
CHANGED
package/src/controller.js
CHANGED
|
@@ -11,7 +11,7 @@ import { createAgentManager } from './agents.js'
|
|
|
11
11
|
import { runDeliberation, validateDeliberation } from './deliberation.js'
|
|
12
12
|
import { deliberationsFromEvents } from './deliberation-history.js'
|
|
13
13
|
import { compactionPrompt, formatCompactSummary, summarySections, compactionKeepFrom } from './compaction.js'
|
|
14
|
-
import { completedToolCalls, TOOL_TRIM_VERSION } from './tool-trimming.js'
|
|
14
|
+
import { completedToolCalls, retrieveToolResult, TOOL_TRIM_VERSION } from './tool-trimming.js'
|
|
15
15
|
import { createToolset } from './tools/index.js'
|
|
16
16
|
import { defaultTitle } from './tools/recorder.js'
|
|
17
17
|
import { scanUserTools } from './user-tools.js'
|
|
@@ -603,6 +603,7 @@ export function createController({ boot }) {
|
|
|
603
603
|
const context = await createAgentContext(boot, { userTools: userToolScan.tools })
|
|
604
604
|
const { tools, recorder } = createToolset({
|
|
605
605
|
...context.tools,
|
|
606
|
+
toolResult: (id) => retrieveToolResult(state.events, id),
|
|
606
607
|
sessionId: state.session?.id,
|
|
607
608
|
sessionFile: state.session?.file,
|
|
608
609
|
wakeups: boot.wakeups,
|
|
@@ -1217,6 +1218,7 @@ export function createController({ boot }) {
|
|
|
1217
1218
|
return createToolset({
|
|
1218
1219
|
cwd: boot.cwd,
|
|
1219
1220
|
env: boot.env,
|
|
1221
|
+
toolResult: (id) => retrieveToolResult(state.events, id),
|
|
1220
1222
|
hostTools: boot.hostTools ?? [],
|
|
1221
1223
|
tracker: boot.tracker,
|
|
1222
1224
|
skills: boot.skills,
|
package/src/derive.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { continuationMessage } from './compaction.js'
|
|
2
2
|
import { applySteering } from './steer.js'
|
|
3
|
-
import { annotateToolContext, applyToolTrims } from './tool-trimming.js'
|
|
3
|
+
import { annotateToolContext, applyToolTrims, toolResultArchive } from './tool-trimming.js'
|
|
4
4
|
|
|
5
5
|
const DROPPING_MODES = ['both', 'chat', 'summary']
|
|
6
6
|
|
|
@@ -183,6 +183,14 @@ export function deriveState(events) {
|
|
|
183
183
|
toolTrimVersions: new Map(),
|
|
184
184
|
}
|
|
185
185
|
|
|
186
|
+
const references = toolResultArchive(events).references
|
|
187
|
+
const historyTokens = () => Math.ceil(JSON.stringify(applyToolTrims(
|
|
188
|
+
elideStaleToolResults(state.providerHistory), state.trimmedToolIds,
|
|
189
|
+
state.toolTrimVersions, state.toolItems, references,
|
|
190
|
+
)).length / 4)
|
|
191
|
+
let measuredBaseline = null
|
|
192
|
+
let contextEdited = false
|
|
193
|
+
|
|
186
194
|
for (const event of effectiveEvents) {
|
|
187
195
|
if (event.type === 'usage') {
|
|
188
196
|
if (!dropped.has(event.id)) {
|
|
@@ -194,6 +202,8 @@ export function deriveState(events) {
|
|
|
194
202
|
if (event.data.lastPrompt !== undefined) {
|
|
195
203
|
state.lastPromptTokens = event.data.lastPrompt
|
|
196
204
|
state.lastPromptModel = event.data.model
|
|
205
|
+
measuredBaseline = { tokens: event.data.lastPrompt, history: historyTokens() }
|
|
206
|
+
contextEdited = false
|
|
197
207
|
}
|
|
198
208
|
}
|
|
199
209
|
continue
|
|
@@ -238,6 +248,8 @@ export function deriveState(events) {
|
|
|
238
248
|
if (!canceledUndoTargets.has(event.id)) foldRewind(state, event)
|
|
239
249
|
break
|
|
240
250
|
case 'compact': {
|
|
251
|
+
measuredBaseline = null
|
|
252
|
+
contextEdited = false
|
|
241
253
|
const { summary, keepFrom, sessionFile } = event.data
|
|
242
254
|
if (keepFrom !== undefined || sessionFile) {
|
|
243
255
|
const idx = keepFrom ? state.historyEventIds.indexOf(keepFrom) : -1
|
|
@@ -260,6 +272,7 @@ export function deriveState(events) {
|
|
|
260
272
|
break
|
|
261
273
|
}
|
|
262
274
|
case 'tool_trim':
|
|
275
|
+
contextEdited = true
|
|
263
276
|
for (const callId of event.data.callIds || []) {
|
|
264
277
|
state.trimmedToolIds.add(callId)
|
|
265
278
|
state.toolTrimVersions.set(callId, event.data.version?.algorithm || 'tool-trim-v1')
|
|
@@ -267,10 +280,13 @@ export function deriveState(events) {
|
|
|
267
280
|
state.lastPromptTokens = 0
|
|
268
281
|
break
|
|
269
282
|
case 'tool_restore':
|
|
283
|
+
contextEdited = true
|
|
270
284
|
for (const callId of event.data.callIds || []) state.trimmedToolIds.delete(callId)
|
|
271
285
|
state.lastPromptTokens = 0
|
|
272
286
|
break
|
|
273
287
|
case 'clear':
|
|
288
|
+
measuredBaseline = null
|
|
289
|
+
contextEdited = false
|
|
274
290
|
state.transcript = []
|
|
275
291
|
state.providerHistory = []
|
|
276
292
|
state.historyEventIds = []
|
|
@@ -303,8 +319,11 @@ export function deriveState(events) {
|
|
|
303
319
|
}
|
|
304
320
|
}
|
|
305
321
|
|
|
322
|
+
state.estimatedPromptTokens = contextEdited && measuredBaseline
|
|
323
|
+
? Math.max(0, measuredBaseline.tokens + historyTokens() - measuredBaseline.history)
|
|
324
|
+
: null
|
|
306
325
|
const effectiveHistory = elideStaleToolResults(state.providerHistory)
|
|
307
|
-
state.providerHistory = applyToolTrims(effectiveHistory, state.trimmedToolIds, state.toolTrimVersions, state.toolItems)
|
|
326
|
+
state.providerHistory = applyToolTrims(effectiveHistory, state.trimmedToolIds, state.toolTrimVersions, state.toolItems, toolResultArchive(events).references)
|
|
308
327
|
annotateToolContext(state, state.providerHistory, state.trimmedToolIds)
|
|
309
328
|
return state
|
|
310
329
|
}
|
package/src/tool-trimming.js
CHANGED
|
@@ -92,7 +92,28 @@ export function completedToolCalls(history) {
|
|
|
92
92
|
return new Map([...callsIn(history)].filter(([, entry]) => entry.result))
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
export function
|
|
95
|
+
export function toolResultArchive(events) {
|
|
96
|
+
const history = events.filter((event) => event.type === 'message').map((event) => event.data.message)
|
|
97
|
+
const references = new Map()
|
|
98
|
+
for (const message of history) {
|
|
99
|
+
for (const call of message.tool_calls || []) {
|
|
100
|
+
if (!references.has(call.id)) references.set(call.id, `t${references.size + 1}`)
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
const results = new Map()
|
|
104
|
+
for (const [callId, entry] of completedToolCalls(history)) {
|
|
105
|
+
results.set(references.get(callId), { callId, name: entry.call.function.name, arguments: entry.call.function.arguments, result: entry.result.content })
|
|
106
|
+
}
|
|
107
|
+
return { references, results }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export function retrieveToolResult(events, id) {
|
|
111
|
+
const result = toolResultArchive(events).results.get(id)
|
|
112
|
+
if (!result) throw new Error(`no saved tool result with id ${id}`)
|
|
113
|
+
return structuredClone(result)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export function applyToolTrims(history, trimmedIds, versions = new Map(), toolItems = new Map(), references = new Map()) {
|
|
96
117
|
if (!trimmedIds.size) return history
|
|
97
118
|
const completed = completedToolCalls(history)
|
|
98
119
|
const callMessages = new Map()
|
|
@@ -112,8 +133,9 @@ export function applyToolTrims(history, trimmedIds, versions = new Map(), toolIt
|
|
|
112
133
|
try { args = JSON.parse(call.function.arguments) } catch { args = {} }
|
|
113
134
|
const description = item?.description || args?.description || call.function.name
|
|
114
135
|
call.function.arguments = JSON.stringify({ description })
|
|
115
|
-
const
|
|
116
|
-
|
|
136
|
+
const error = item?.status === 'error' ? `error: ${item.error || 'tool failed'}\n` : ''
|
|
137
|
+
const reference = references.get(id)
|
|
138
|
+
resultMessages.set(entry.resultIndex, { ...entry.result, content: `${error}[compacted; retrieve with tool_result(${JSON.stringify({ id: reference })})]` })
|
|
117
139
|
} else {
|
|
118
140
|
call.function.arguments = trimArguments(call.function.arguments)
|
|
119
141
|
resultMessages.set(entry.resultIndex, { ...entry.result, content: trimResult(entry.result.content) })
|
package/src/tools/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { createGlob } from './glob.js'
|
|
|
7
7
|
import { createGrep } from './grep.js'
|
|
8
8
|
import { createView } from './view.js'
|
|
9
9
|
|
|
10
|
-
export function createToolset({ cwd, env, tracker, skills, shells, sessionId, sessionFile, wakeups, memory, agents, deliberations, onAgentsCollected, askUser, mcpTools = [], userTools = [], hostTools = [], signal, maxToolCalls, maxAgentStarts, requireAgentPlan = false, allowNames, onToolUpdate, viewer }) {
|
|
10
|
+
export function createToolset({ toolResult, cwd, env, tracker, skills, shells, sessionId, sessionFile, wakeups, memory, agents, deliberations, onAgentsCollected, askUser, mcpTools = [], userTools = [], hostTools = [], signal, maxToolCalls, maxAgentStarts, requireAgentPlan = false, allowNames, onToolUpdate, viewer }) {
|
|
11
11
|
const recorder = createRecorder(onToolUpdate)
|
|
12
12
|
let agentStarts = 0
|
|
13
13
|
let plannedAgentStarts = requireAgentPlan ? null : maxAgentStarts
|
|
@@ -22,6 +22,16 @@ export function createToolset({ cwd, env, tracker, skills, shells, sessionId, se
|
|
|
22
22
|
createGrep(deps),
|
|
23
23
|
]
|
|
24
24
|
|
|
25
|
+
if (toolResult) local.push({
|
|
26
|
+
name: 'tool_result',
|
|
27
|
+
description: 'Retrieve the original arguments and result of a compacted tool call using its retrieval ID. This reads saved data without rerunning the tool or restoring other calls.',
|
|
28
|
+
schema: {
|
|
29
|
+
description: describeParam,
|
|
30
|
+
id: { type: 'string', description: 'retrieval ID shown in the compacted result, such as t42' },
|
|
31
|
+
},
|
|
32
|
+
execute: ({ id }) => toolResult(id),
|
|
33
|
+
})
|
|
34
|
+
|
|
25
35
|
if (viewer) local.push(createView({ ...deps, viewer }))
|
|
26
36
|
|
|
27
37
|
if (shells) {
|