ucode-agent 1.50.0 → 1.51.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/package.json +1 -1
- package/src/core/loop.js +25 -0
- package/src/tools/index.js +13 -1
package/package.json
CHANGED
package/src/core/loop.js
CHANGED
|
@@ -1911,6 +1911,31 @@ export class Agent {
|
|
|
1911
1911
|
this.reads.set(key, seen + 1);
|
|
1912
1912
|
}
|
|
1913
1913
|
|
|
1914
|
+
// create_app again for the app this turn already made. DeepSeek scaffolded
|
|
1915
|
+
// tasker with no files, then called create_app twice more — once with no
|
|
1916
|
+
// folder or name at all — and was refused both times while the empty
|
|
1917
|
+
// starter sat there. The folder and name are known, so fill them in; with
|
|
1918
|
+
// no files there is nothing to create, and the next step is batch_write.
|
|
1919
|
+
if (call.name === 'create_app' && this.apps?.length === 1) {
|
|
1920
|
+
const made = this.apps[0];
|
|
1921
|
+
const args = (call.args ??= {});
|
|
1922
|
+
if (!args.folder) args.folder = path.relative(this.cwd, made) || '.';
|
|
1923
|
+
if (!args.name) args.name = path.basename(made);
|
|
1924
|
+
const files = args.files;
|
|
1925
|
+
const none = files == null || files === ''
|
|
1926
|
+
|| (Array.isArray(files) ? !files.length : typeof files === 'object' && !Object.keys(files).length);
|
|
1927
|
+
if (none && path.resolve(this.cwd, String(args.folder)) === made) {
|
|
1928
|
+
const show = path.relative(this.cwd, made) || '.';
|
|
1929
|
+
throw new ToolFailure({
|
|
1930
|
+
kind: 'already_made',
|
|
1931
|
+
attempted: `creating ${show}`,
|
|
1932
|
+
failed: `${show} was already created this turn, with the starter files in it.`,
|
|
1933
|
+
fix: `Do not call create_app again. Write the app into ${show} with one batch_write, `
|
|
1934
|
+
+ 'replacing the starter files with the finished ones.',
|
|
1935
|
+
});
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1914
1939
|
// Starting a second app instead of fixing the first.
|
|
1915
1940
|
//
|
|
1916
1941
|
// A traced build hit a problem in todo/, abandoned it and made todo-fixed/
|
package/src/tools/index.js
CHANGED
|
@@ -581,6 +581,18 @@ function check(name, args) {
|
|
|
581
581
|
return ['the arguments must be a JSON object'];
|
|
582
582
|
}
|
|
583
583
|
|
|
584
|
+
// One file named as "path" where the tool takes a list called "paths".
|
|
585
|
+
// DeepSeek did it to four read_files at once, a whole round trip spent being
|
|
586
|
+
// told a plural it could simply have been given.
|
|
587
|
+
for (const key of schema.required ?? []) {
|
|
588
|
+
const one = key.endsWith('s') ? key.slice(0, -1) : '';
|
|
589
|
+
if (args[key] == null && one && !schema.properties[one] && args[one] != null
|
|
590
|
+
&& schema.properties[key]?.type === 'array') {
|
|
591
|
+
args[key] = Array.isArray(args[one]) ? args[one] : [args[one]];
|
|
592
|
+
delete args[one];
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
584
596
|
for (const key of schema.required ?? []) {
|
|
585
597
|
if (args[key] === undefined || args[key] === null) problems.push(`"${key}" is required and missing`);
|
|
586
598
|
}
|
|
@@ -709,7 +721,7 @@ export function describe(name, args = {}) {
|
|
|
709
721
|
// untrue on screen while the opposite happens on disk.
|
|
710
722
|
return `Creating ${clip(args.name || args.folder, 30)} from the ` +
|
|
711
723
|
`${args.template === 'next-shadcn' ? 'Next.js' : 'HTML'} starter` +
|
|
712
|
-
`${files ? ` with ${files} file${files === 1 ? '' : 's'}` : ''}`;
|
|
724
|
+
`${files ? ` with ${files} file${files === 1 ? '' : 's'}` : ''}`;
|
|
713
725
|
}
|
|
714
726
|
case 'look_at_app':
|
|
715
727
|
return `Looking at ${clip(args.url, 40)} on a phone and a desktop`;
|