neoagent 2.5.2-beta.1 → 2.5.2-beta.10

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.
@@ -123,20 +123,25 @@ async function buildArtifactFromCandidate(candidate, fallbackKind = 'artifact')
123
123
  artifact.size = (await fs.promises.stat(artifact.path)).size;
124
124
  } catch (error) {
125
125
  console.warn('[deliverables] Failed to stat artifact candidate:', artifact.path, error?.message || error);
126
+ return null;
126
127
  }
127
128
  }
128
129
  return artifact.path || artifact.uri ? artifact : null;
129
130
  }
130
131
 
131
- function scanStringForCandidates(text) {
132
+ function scanStringForCandidates(text, { explicit = false } = {}) {
132
133
  const input = String(text || '');
133
134
  const matches = [];
134
- const regexes = [
135
- /\/api\/artifacts\/[A-Za-z0-9%_-]+\/content/g,
136
- /\/[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
137
- /[A-Za-z]:\\[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
138
- /https?:\/\/[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
139
- ];
135
+ const regexes = explicit
136
+ ? [
137
+ /\/api\/artifacts\/[A-Za-z0-9%_-]+\/content/g,
138
+ /\/[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
139
+ /[A-Za-z]:\\[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
140
+ /https?:\/\/[^\s"'`]+?\.(?:pptx?|pdf|docx?|md|txt|html?|csv|tsv|xlsx?|json|png|jpe?g|gif|webp|svg|mp4|mov|m4v|webm)\b/g,
141
+ ]
142
+ : [
143
+ /\/api\/artifacts\/[A-Za-z0-9%_-]+\/content/g,
144
+ ];
140
145
  for (const regex of regexes) {
141
146
  const found = input.match(regex);
142
147
  if (found) matches.push(...found);
@@ -147,9 +152,13 @@ function scanStringForCandidates(text) {
147
152
  async function extractArtifactsFromResult(toolName, result) {
148
153
  const artifacts = [];
149
154
  const seen = new Set();
155
+ const seenCandidates = new Set();
150
156
  const fallbackKind = inferArtifactKind(toolName, 'artifact');
151
157
 
152
158
  async function pushCandidate(candidate) {
159
+ const candidateKey = String(candidate || '').trim();
160
+ if (!candidateKey || seenCandidates.has(candidateKey)) return;
161
+ seenCandidates.add(candidateKey);
153
162
  const artifact = await buildArtifactFromCandidate(candidate, fallbackKind);
154
163
  if (!artifact) return;
155
164
  const key = `${artifact.kind}:${artifact.path || artifact.uri}`;
@@ -161,8 +170,9 @@ async function extractArtifactsFromResult(toolName, result) {
161
170
  async function visit(value, keyHint = '') {
162
171
  if (value == null) return;
163
172
  if (typeof value === 'string') {
164
- if (CANDIDATE_KEYS.includes(keyHint)) await pushCandidate(value);
165
- for (const candidate of scanStringForCandidates(value)) {
173
+ const explicit = CANDIDATE_KEYS.includes(keyHint);
174
+ if (explicit) await pushCandidate(value);
175
+ for (const candidate of scanStringForCandidates(value, { explicit })) {
166
176
  await pushCandidate(candidate);
167
177
  }
168
178
  return;