@strayl/agent 0.1.10 → 0.1.12
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/agent.js +35 -14
- package/package.json +27 -27
- package/skills/api-creation/SKILL.md +631 -631
- package/skills/authentication/SKILL.md +294 -294
- package/skills/frontend-design/SKILL.md +108 -108
- package/skills/landing-creation/SKILL.md +125 -125
- package/skills/reference/SKILL.md +149 -149
- package/skills/web-application-creation/SKILL.md +231 -231
package/dist/agent.js
CHANGED
|
@@ -7201,13 +7201,11 @@ var LLMClient = class {
|
|
|
7201
7201
|
}
|
|
7202
7202
|
}
|
|
7203
7203
|
}
|
|
7204
|
-
if (choice.finish_reason
|
|
7205
|
-
|
|
7206
|
-
|
|
7207
|
-
|
|
7208
|
-
|
|
7209
|
-
yield { type: "tool_call_complete", id: partial.id, name: partial.name, arguments: partial.arguments };
|
|
7210
|
-
}
|
|
7204
|
+
if (choice.finish_reason && !emittedToolCalls) {
|
|
7205
|
+
emittedToolCalls = true;
|
|
7206
|
+
for (const [, partial] of partialToolCalls) {
|
|
7207
|
+
if (partial.id && partial.name) {
|
|
7208
|
+
yield { type: "tool_call_complete", id: partial.id, name: partial.name, arguments: partial.arguments };
|
|
7211
7209
|
}
|
|
7212
7210
|
}
|
|
7213
7211
|
}
|
|
@@ -7222,7 +7220,7 @@ var LLMClient = class {
|
|
|
7222
7220
|
}
|
|
7223
7221
|
if (!emittedToolCalls) {
|
|
7224
7222
|
for (const [, partial] of partialToolCalls) {
|
|
7225
|
-
if (partial.id && partial.name
|
|
7223
|
+
if (partial.id && partial.name) {
|
|
7226
7224
|
yield { type: "tool_call_complete", id: partial.id, name: partial.name, arguments: partial.arguments };
|
|
7227
7225
|
}
|
|
7228
7226
|
}
|
|
@@ -7656,7 +7654,11 @@ var HITLManager = class {
|
|
|
7656
7654
|
this.idMap.set(id, safe);
|
|
7657
7655
|
return safe;
|
|
7658
7656
|
}
|
|
7659
|
-
|
|
7657
|
+
/**
|
|
7658
|
+
* Wait for HITL response, polling both file system and optional stdin drain callback.
|
|
7659
|
+
* @param onPoll - Called each poll iteration so the caller can drain stdin and write pending responses.
|
|
7660
|
+
*/
|
|
7661
|
+
async waitForResponse(id, onPoll) {
|
|
7660
7662
|
const safe = this.safeId(id);
|
|
7661
7663
|
const filePath = path2.join(this.dir, `${safe}.json`);
|
|
7662
7664
|
const maxWait = 30 * 60 * 1e3;
|
|
@@ -7665,6 +7667,7 @@ var HITLManager = class {
|
|
|
7665
7667
|
if (await this.isCancelled()) {
|
|
7666
7668
|
return { decision: "reject" };
|
|
7667
7669
|
}
|
|
7670
|
+
if (onPoll) await onPoll();
|
|
7668
7671
|
try {
|
|
7669
7672
|
const content = await fs.readFile(filePath, "utf-8");
|
|
7670
7673
|
const response = JSON.parse(content);
|
|
@@ -13401,15 +13404,16 @@ function createPlanModeMiddleware(getMode) {
|
|
|
13401
13404
|
name: "planModeFilter",
|
|
13402
13405
|
filterTools: (tools) => {
|
|
13403
13406
|
const mode2 = getMode();
|
|
13407
|
+
const getName2 = (t) => t.type === "function" ? t.function.name : "";
|
|
13404
13408
|
if (mode2 === "plan") {
|
|
13405
|
-
return tools.filter((t) => !PLAN_MODE_BLOCKED.has(t
|
|
13409
|
+
return tools.filter((t) => !PLAN_MODE_BLOCKED.has(getName2(t)));
|
|
13406
13410
|
}
|
|
13407
13411
|
if (mode2 === "implement") {
|
|
13408
13412
|
return tools.filter(
|
|
13409
|
-
(t) => !IMPL_MODE_BLOCKED.has(t
|
|
13413
|
+
(t) => !IMPL_MODE_BLOCKED.has(getName2(t)) && getName2(t) !== "enterPlanMode"
|
|
13410
13414
|
);
|
|
13411
13415
|
}
|
|
13412
|
-
return tools.filter((t) => !IMPL_MODE_BLOCKED.has(t
|
|
13416
|
+
return tools.filter((t) => !IMPL_MODE_BLOCKED.has(getName2(t)));
|
|
13413
13417
|
},
|
|
13414
13418
|
wrapToolCall: async (call, next) => {
|
|
13415
13419
|
const mode2 = getMode();
|
|
@@ -13545,6 +13549,8 @@ async function runAgent(config) {
|
|
|
13545
13549
|
const maxIterations = config.maxIterations ?? 200;
|
|
13546
13550
|
let consecutiveLLMErrors = 0;
|
|
13547
13551
|
const MAX_CONSECUTIVE_LLM_ERRORS = 5;
|
|
13552
|
+
let consecutiveNoToolCalls = 0;
|
|
13553
|
+
const MAX_NO_TOOL_RETRIES = 3;
|
|
13548
13554
|
if (config.restoreCheckpoint) {
|
|
13549
13555
|
const cp = config.restoreCheckpoint;
|
|
13550
13556
|
context.restoreMessages(cp.messages);
|
|
@@ -13717,7 +13723,15 @@ ${IMPLEMENTATION_MODE_PROMPT2}`);
|
|
|
13717
13723
|
context_left_percent: leftPercent
|
|
13718
13724
|
});
|
|
13719
13725
|
}
|
|
13720
|
-
if (completedToolCalls.length === 0)
|
|
13726
|
+
if (completedToolCalls.length === 0) {
|
|
13727
|
+
consecutiveNoToolCalls++;
|
|
13728
|
+
if (consecutiveNoToolCalls >= MAX_NO_TOOL_RETRIES) break;
|
|
13729
|
+
context.addUser(
|
|
13730
|
+
"[System] You output text without calling any tools. Do not think out loud \u2014 use your tools to take action. If you need to communicate with the user, call the askUser tool. If you need to create a plan, call the writePlan tool. Continue working on the task."
|
|
13731
|
+
);
|
|
13732
|
+
continue;
|
|
13733
|
+
}
|
|
13734
|
+
consecutiveNoToolCalls = 0;
|
|
13721
13735
|
for (const tc of completedToolCalls) {
|
|
13722
13736
|
if (stdin.isCancelled()) {
|
|
13723
13737
|
context.addToolResult(tc.id, tc.function.name, JSON.stringify({ error: "Cancelled by user." }));
|
|
@@ -13738,7 +13752,14 @@ ${IMPLEMENTATION_MODE_PROMPT2}`);
|
|
|
13738
13752
|
const toolDef = registry.get(tc.function.name);
|
|
13739
13753
|
if (toolDef?.hitl) {
|
|
13740
13754
|
emitter.emit({ type: "hitl-request", id: tc.id, safe_id: hitl.safeId(tc.id), tool: tc.function.name, args: parsedArgs });
|
|
13741
|
-
const response = await hitl.waitForResponse(tc.id)
|
|
13755
|
+
const response = await hitl.waitForResponse(tc.id, async () => {
|
|
13756
|
+
for (const cmd of stdin.drain()) {
|
|
13757
|
+
if (cmd.type === "hitl-response") {
|
|
13758
|
+
await hitl.writeResponse(cmd.id, { decision: cmd.decision, data: cmd.data });
|
|
13759
|
+
} else if (cmd.type === "cancel") {
|
|
13760
|
+
}
|
|
13761
|
+
}
|
|
13762
|
+
});
|
|
13742
13763
|
if (response.decision === "reject") {
|
|
13743
13764
|
const rejectResult = JSON.stringify({ error: "User rejected this action." });
|
|
13744
13765
|
emitter.emit({ type: "tool-result", id: tc.id, name: tc.function.name, output: rejectResult });
|
package/package.json
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@strayl/agent",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"type": "module",
|
|
5
|
-
"publishConfig": {
|
|
6
|
-
"access": "public"
|
|
7
|
-
},
|
|
8
|
-
"main": "dist/index.js",
|
|
9
|
-
"files": [
|
|
10
|
-
"dist",
|
|
11
|
-
"skills"
|
|
12
|
-
],
|
|
13
|
-
"scripts": {
|
|
14
|
-
"build": "esbuild src/index.ts --bundle --platform=node --target=node20 --format=esm --outfile=dist/agent.js --external:fsevents",
|
|
15
|
-
"dev": "tsx watch src/index.ts"
|
|
16
|
-
},
|
|
17
|
-
"dependencies": {
|
|
18
|
-
"openai": "^5.8.0",
|
|
19
|
-
"zod": "^3.25.67"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"esbuild": "^0.25.5",
|
|
23
|
-
"tsx": "^4.19.4",
|
|
24
|
-
"typescript": "^5.8.3",
|
|
25
|
-
"@types/node": "^22.15.31"
|
|
26
|
-
}
|
|
27
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@strayl/agent",
|
|
3
|
+
"version": "0.1.12",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"publishConfig": {
|
|
6
|
+
"access": "public"
|
|
7
|
+
},
|
|
8
|
+
"main": "dist/index.js",
|
|
9
|
+
"files": [
|
|
10
|
+
"dist",
|
|
11
|
+
"skills"
|
|
12
|
+
],
|
|
13
|
+
"scripts": {
|
|
14
|
+
"build": "esbuild src/index.ts --bundle --platform=node --target=node20 --format=esm --outfile=dist/agent.js --external:fsevents",
|
|
15
|
+
"dev": "tsx watch src/index.ts"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"openai": "^5.8.0",
|
|
19
|
+
"zod": "^3.25.67"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"esbuild": "^0.25.5",
|
|
23
|
+
"tsx": "^4.19.4",
|
|
24
|
+
"typescript": "^5.8.3",
|
|
25
|
+
"@types/node": "^22.15.31"
|
|
26
|
+
}
|
|
27
|
+
}
|