toolnexus 0.13.0 → 0.14.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/dist/a2a.js +8 -0
- package/dist/agents/compaction.js +23 -7
- package/package.json +1 -1
- package/src/a2a.ts +8 -0
- package/src/agents/compaction.ts +26 -7
package/dist/a2a.js
CHANGED
|
@@ -234,6 +234,14 @@ function skillTool(agentName, endpoint, skill, ag) {
|
|
|
234
234
|
};
|
|
235
235
|
}
|
|
236
236
|
catch (e) {
|
|
237
|
+
// An abort that lands WHILE an RPC is in flight surfaces as a transport error
|
|
238
|
+
// (AbortError), not through the two checks in the poll loop. Report it as the
|
|
239
|
+
// cancel it is, so a cancelled call is `canceled` regardless of whether the
|
|
240
|
+
// signal fired between polls or mid-request.
|
|
241
|
+
if (ctx?.signal?.aborted) {
|
|
242
|
+
state = "canceled";
|
|
243
|
+
return { output: `A2A task ${taskId} canceled`, isError: true, metadata: meta() };
|
|
244
|
+
}
|
|
237
245
|
return { output: e instanceof Error ? e.message : String(e), isError: true, metadata: meta() };
|
|
238
246
|
}
|
|
239
247
|
},
|
|
@@ -71,25 +71,41 @@ export function compactor(opts) {
|
|
|
71
71
|
};
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
*
|
|
74
|
+
* Does this message carry a tool result? Under the anthropic dialect a tool result is a
|
|
75
|
+
* `user` message whose content holds `tool_result` blocks, so such a message is a member
|
|
76
|
+
* of a tool group rather than a conversational boundary.
|
|
77
|
+
*/
|
|
78
|
+
function carriesToolResult(m) {
|
|
79
|
+
const content = m.content;
|
|
80
|
+
if (!Array.isArray(content))
|
|
81
|
+
return false;
|
|
82
|
+
return content.some((b) => typeof b === "object" && b !== null && b.type === "tool_result");
|
|
83
|
+
}
|
|
84
|
+
/** A valid tail boundary: a `user` turn that is not carrying a tool result. */
|
|
85
|
+
function isBoundary(m) {
|
|
86
|
+
return m.role === "user" && !carriesToolResult(m);
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Locate the index where the retained tail begins. Tool-pair safety requires the tail to
|
|
90
|
+
* start at a `user` turn that is not a tool-result carrier: the largest such tail that
|
|
91
|
+
* still fits `keepTail`. If none fits, fall back to the most recent valid boundary
|
|
77
92
|
* (favoring safety over size). Returns `msgs.length` (no tail) only when there is no
|
|
78
|
-
*
|
|
93
|
+
* valid boundary after the head at all — the whole body is then summarized, which is
|
|
94
|
+
* bounded and cannot orphan anything since nothing is retained.
|
|
79
95
|
*/
|
|
80
96
|
function findTailStart(msgs, headEnd, keepTail, count) {
|
|
81
97
|
let split = msgs.length;
|
|
82
98
|
for (let i = msgs.length - 1; i > headEnd; i--) {
|
|
83
99
|
if (count(msgs.slice(i)) > keepTail)
|
|
84
100
|
break;
|
|
85
|
-
if (msgs[i]
|
|
101
|
+
if (isBoundary(msgs[i]))
|
|
86
102
|
split = i;
|
|
87
103
|
}
|
|
88
104
|
if (split !== msgs.length)
|
|
89
105
|
return split;
|
|
90
|
-
// No
|
|
106
|
+
// No boundary fit within keepTail — extend back to the most recent valid one.
|
|
91
107
|
for (let i = msgs.length - 1; i > headEnd; i--) {
|
|
92
|
-
if (msgs[i]
|
|
108
|
+
if (isBoundary(msgs[i]))
|
|
93
109
|
return i;
|
|
94
110
|
}
|
|
95
111
|
return msgs.length;
|
package/package.json
CHANGED
package/src/a2a.ts
CHANGED
|
@@ -344,6 +344,14 @@ function skillTool(agentName: string, endpoint: string, skill: A2ASkill, ag: Age
|
|
|
344
344
|
metadata: meta(),
|
|
345
345
|
}
|
|
346
346
|
} catch (e) {
|
|
347
|
+
// An abort that lands WHILE an RPC is in flight surfaces as a transport error
|
|
348
|
+
// (AbortError), not through the two checks in the poll loop. Report it as the
|
|
349
|
+
// cancel it is, so a cancelled call is `canceled` regardless of whether the
|
|
350
|
+
// signal fired between polls or mid-request.
|
|
351
|
+
if (ctx?.signal?.aborted) {
|
|
352
|
+
state = "canceled"
|
|
353
|
+
return { output: `A2A task ${taskId} canceled`, isError: true, metadata: meta() }
|
|
354
|
+
}
|
|
347
355
|
return { output: e instanceof Error ? e.message : String(e), isError: true, metadata: meta() }
|
|
348
356
|
}
|
|
349
357
|
},
|
package/src/agents/compaction.ts
CHANGED
|
@@ -121,11 +121,30 @@ export function compactor(
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
124
|
+
* Does this message carry a tool result? Under the anthropic dialect a tool result is a
|
|
125
|
+
* `user` message whose content holds `tool_result` blocks, so such a message is a member
|
|
126
|
+
* of a tool group rather than a conversational boundary.
|
|
127
|
+
*/
|
|
128
|
+
function carriesToolResult(m: Message): boolean {
|
|
129
|
+
const content = (m as { content?: unknown }).content
|
|
130
|
+
if (!Array.isArray(content)) return false
|
|
131
|
+
return content.some(
|
|
132
|
+
(b) => typeof b === "object" && b !== null && (b as { type?: unknown }).type === "tool_result",
|
|
133
|
+
)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/** A valid tail boundary: a `user` turn that is not carrying a tool result. */
|
|
137
|
+
function isBoundary(m: Message): boolean {
|
|
138
|
+
return m.role === "user" && !carriesToolResult(m)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Locate the index where the retained tail begins. Tool-pair safety requires the tail to
|
|
143
|
+
* start at a `user` turn that is not a tool-result carrier: the largest such tail that
|
|
144
|
+
* still fits `keepTail`. If none fits, fall back to the most recent valid boundary
|
|
127
145
|
* (favoring safety over size). Returns `msgs.length` (no tail) only when there is no
|
|
128
|
-
*
|
|
146
|
+
* valid boundary after the head at all — the whole body is then summarized, which is
|
|
147
|
+
* bounded and cannot orphan anything since nothing is retained.
|
|
129
148
|
*/
|
|
130
149
|
function findTailStart(
|
|
131
150
|
msgs: Message[],
|
|
@@ -136,13 +155,13 @@ function findTailStart(
|
|
|
136
155
|
let split = msgs.length
|
|
137
156
|
for (let i = msgs.length - 1; i > headEnd; i--) {
|
|
138
157
|
if (count(msgs.slice(i)) > keepTail) break
|
|
139
|
-
if (msgs[i]
|
|
158
|
+
if (isBoundary(msgs[i])) split = i
|
|
140
159
|
}
|
|
141
160
|
if (split !== msgs.length) return split
|
|
142
161
|
|
|
143
|
-
// No
|
|
162
|
+
// No boundary fit within keepTail — extend back to the most recent valid one.
|
|
144
163
|
for (let i = msgs.length - 1; i > headEnd; i--) {
|
|
145
|
-
if (msgs[i]
|
|
164
|
+
if (isBoundary(msgs[i])) return i
|
|
146
165
|
}
|
|
147
166
|
return msgs.length
|
|
148
167
|
}
|