toolnexus 0.20.0 → 0.22.0
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/README.md +40 -0
- package/dist/agents/agent.d.ts +12 -1
- package/dist/agents/agent.js +43 -7
- package/dist/agents/compaction.d.ts +19 -0
- package/dist/agents/compaction.js +26 -4
- package/dist/agents/runtime.d.ts +5 -0
- package/dist/agents/runtime.js +13 -2
- package/dist/batteries.d.ts +223 -0
- package/dist/batteries.js +488 -0
- package/dist/builtin.d.ts +16 -0
- package/dist/builtin.js +315 -17
- package/dist/builtin_extras.d.ts +80 -0
- package/dist/builtin_extras.js +248 -0
- package/dist/classifier.d.ts +14 -0
- package/dist/classifier.js +34 -1
- package/dist/client.d.ts +91 -15
- package/dist/client.js +377 -110
- package/dist/index.d.ts +8 -0
- package/dist/index.js +11 -0
- package/dist/judge.d.ts +98 -0
- package/dist/judge.js +199 -0
- package/dist/mcp.d.ts +32 -1
- package/dist/mcp.js +184 -6
- package/dist/models.d.ts +20 -0
- package/dist/models.js +46 -0
- package/dist/promptcache.d.ts +21 -0
- package/dist/promptcache.js +59 -0
- package/dist/store.d.ts +32 -0
- package/dist/store.js +131 -0
- package/dist/tooltiers.d.ts +49 -0
- package/dist/tooltiers.js +197 -0
- package/dist/types.d.ts +19 -0
- package/package.json +2 -2
- package/src/agents/agent.ts +39 -8
- package/src/agents/compaction.ts +45 -4
- package/src/agents/runtime.ts +16 -2
- package/src/batteries.ts +614 -0
- package/src/builtin.ts +333 -18
- package/src/builtin_extras.ts +285 -0
- package/src/classifier.ts +36 -1
- package/src/client.ts +415 -115
- package/src/index.ts +31 -0
- package/src/judge.ts +305 -0
- package/src/mcp.ts +204 -7
- package/src/models.ts +56 -0
- package/src/promptcache.ts +63 -0
- package/src/store.ts +142 -0
- package/src/tooltiers.ts +221 -0
- package/src/types.ts +20 -0
package/src/agents/compaction.ts
CHANGED
|
@@ -102,6 +102,26 @@ export interface CompactorOptions {
|
|
|
102
102
|
* default. Composes with the memory builtin.
|
|
103
103
|
*/
|
|
104
104
|
flushToMemory?: boolean
|
|
105
|
+
/**
|
|
106
|
+
* Called after each compaction with what changed, so a host can tell its UI or log (SPEC §4C).
|
|
107
|
+
* Never called on a no-op. Awaited before the next model call.
|
|
108
|
+
*/
|
|
109
|
+
onCompact?: (info: CompactInfo) => void | Promise<void>
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** One compaction, for {@link CompactorOptions.onCompact}. Token counts come from `countTokens`. */
|
|
113
|
+
export interface CompactInfo {
|
|
114
|
+
tokensBefore: number
|
|
115
|
+
tokensAfter: number
|
|
116
|
+
messagesBefore: number
|
|
117
|
+
messagesAfter: number
|
|
118
|
+
/** How many messages were folded into the summary. */
|
|
119
|
+
summarized: number
|
|
120
|
+
/** The text `summarize` returned (without the header line). */
|
|
121
|
+
summary: string
|
|
122
|
+
/** The summarized messages, verbatim, so a host can persist them (the loop saves only the
|
|
123
|
+
* compacted transcript). */
|
|
124
|
+
folded: Message[]
|
|
105
125
|
}
|
|
106
126
|
|
|
107
127
|
/** The event a `beforeLLM` hook receives (§8). */
|
|
@@ -134,7 +154,8 @@ export function compactor(
|
|
|
134
154
|
|
|
135
155
|
return async (ev: BeforeLLMEvent): Promise<{ messages: Message[] } | undefined> => {
|
|
136
156
|
const msgs = ev.messages
|
|
137
|
-
|
|
157
|
+
const before = count(msgs)
|
|
158
|
+
if (before <= opts.maxTokens) return undefined // under budget → no-op
|
|
138
159
|
|
|
139
160
|
// Preserve a leading system prompt verbatim (identity / soul / skills — never summarized).
|
|
140
161
|
const headEnd = msgs[0]?.role === "system" ? 1 : 0
|
|
@@ -143,9 +164,17 @@ export function compactor(
|
|
|
143
164
|
const split = findTailStart(msgs, headEnd, keepTail, count)
|
|
144
165
|
if (split <= headEnd) return undefined // nothing safely compactible
|
|
145
166
|
|
|
146
|
-
|
|
147
|
-
if (older.length === 0) return undefined
|
|
167
|
+
let older = msgs.slice(headEnd, split)
|
|
148
168
|
const tail = msgs.slice(split)
|
|
169
|
+
// The latest user prompt is never summarized away. When the only clean boundary is the first
|
|
170
|
+
// message after the system prompt (one prompt followed by a long agentic run), keep that
|
|
171
|
+
// prompt verbatim and summarize the work after it: [system, prompt, summary].
|
|
172
|
+
let pinned: Message[] = []
|
|
173
|
+
if (split === msgs.length && headEnd < msgs.length && isBoundary(msgs[headEnd])) {
|
|
174
|
+
pinned = msgs.slice(headEnd, headEnd + 1)
|
|
175
|
+
older = msgs.slice(headEnd + 1)
|
|
176
|
+
}
|
|
177
|
+
if (older.length === 0) return undefined
|
|
149
178
|
|
|
150
179
|
const flushNote: Message[] = opts.flushToMemory
|
|
151
180
|
? [{ role: "system", content: FLUSH_TO_MEMORY_REMINDER }]
|
|
@@ -154,7 +183,19 @@ export function compactor(
|
|
|
154
183
|
const summary = await opts.summarize(older)
|
|
155
184
|
const summaryMsg: Message = { role: "system", content: `${SUMMARY_PREFIX}${summary}` }
|
|
156
185
|
|
|
157
|
-
|
|
186
|
+
const out = [...system, ...pinned, summaryMsg, ...flushNote, ...tail]
|
|
187
|
+
const after = count(out)
|
|
188
|
+
if (after >= before) return undefined // compaction would not shrink the transcript → no-op
|
|
189
|
+
await opts.onCompact?.({
|
|
190
|
+
tokensBefore: before,
|
|
191
|
+
tokensAfter: after,
|
|
192
|
+
messagesBefore: msgs.length,
|
|
193
|
+
messagesAfter: out.length,
|
|
194
|
+
summarized: older.length,
|
|
195
|
+
summary,
|
|
196
|
+
folded: older,
|
|
197
|
+
})
|
|
198
|
+
return { messages: out }
|
|
158
199
|
}
|
|
159
200
|
}
|
|
160
201
|
|
package/src/agents/runtime.ts
CHANGED
|
@@ -390,6 +390,11 @@ export interface RuntimeOptions {
|
|
|
390
390
|
/** §8 observability sink applied to EVERY agent's client, unless that agent's def
|
|
391
391
|
* sets its own `onMetric`. Resolves independently of `hooks`. Forwarded verbatim. */
|
|
392
392
|
onMetric?: (ev: MetricEvent) => void
|
|
393
|
+
/** The runtime-level §10 interpreter (SPEC §4C): answers a suspension when no agent on the
|
|
394
|
+
* handle's chain has its own `waitFor`. Absent ⇒ unchanged (the suspension goes durable). A
|
|
395
|
+
* host running an agent as a tool (`asToolWith`) sets it so the child's asks reach the same
|
|
396
|
+
* bridge as the parent turn. */
|
|
397
|
+
waitFor?: (request: Request) => Promise<Answer>
|
|
393
398
|
}
|
|
394
399
|
|
|
395
400
|
interface GateWaiter {
|
|
@@ -855,11 +860,20 @@ export class AgentRuntime {
|
|
|
855
860
|
* escalation traced (nearest interpreter wins; the Request's `data.path` names
|
|
856
861
|
* the suspended subtree that is asking). */
|
|
857
862
|
private wrapWaitFor(h: Handle): ((req: Request) => Promise<Answer>) | undefined {
|
|
858
|
-
const
|
|
863
|
+
const own = h.def.waitFor
|
|
864
|
+
let waitFor = own
|
|
865
|
+
if (!waitFor && this.opts.waitFor) {
|
|
866
|
+
// The runtime-level bridge answers only when NO agent on the chain has its own waitFor;
|
|
867
|
+
// otherwise the ask escalates to that nearest interpreter, as before.
|
|
868
|
+
let a: Handle | null = h.parent
|
|
869
|
+
while (a && !a.def.waitFor) a = a.parent
|
|
870
|
+
if (!a) waitFor = this.opts.waitFor
|
|
871
|
+
}
|
|
859
872
|
if (!waitFor) return undefined
|
|
873
|
+
const answerer = own ? h.id : this.root.id
|
|
860
874
|
return async (req: Request): Promise<Answer> => {
|
|
861
875
|
const path = Array.isArray(req.data?.path) ? (req.data!.path as string[]).join("/") : h.id
|
|
862
|
-
this.t(`${path}: escalate → ${
|
|
876
|
+
this.t(`${path}: escalate → ${answerer} answers ("nearest interpreter")`)
|
|
863
877
|
return waitFor(req)
|
|
864
878
|
}
|
|
865
879
|
}
|