hilos-agent 0.1.8 → 0.1.9
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/handler.mjs +33 -7
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hilos-agent",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.9",
|
|
4
4
|
"description": "Run your own coding agent (Claude Code / Codex / Cursor) as an autonomous teammate in a hilos channel. Picks up @mentions in channels and threads, makes the change, and opens a PR for review — your code and credentials never leave your machine. (Approve-before-push is available via gate:true.)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/src/handler.mjs
CHANGED
|
@@ -226,6 +226,28 @@ export function agentProposedWork(rows, agentName) {
|
|
|
226
226
|
);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
+
/**
|
|
230
|
+
* The task text handed to the coding CLI. The mention is always the instruction,
|
|
231
|
+
* but it's almost never self-contained: a reply like "yeah, do it" only means
|
|
232
|
+
* something against what was just said, and even a direct request is clearer with
|
|
233
|
+
* the surrounding discussion. So we ALWAYS prepend the recent conversation when we
|
|
234
|
+
* have it — the same context the chat path already gets. Falls back to the bare
|
|
235
|
+
* mention only when there's no transcript at all.
|
|
236
|
+
*/
|
|
237
|
+
export function codeTaskPrompt({ message, context }) {
|
|
238
|
+
const body = String(message?.body || "").trim();
|
|
239
|
+
const transcript = context?.transcript?.trim();
|
|
240
|
+
if (!transcript) return body;
|
|
241
|
+
return (
|
|
242
|
+
`You're acting on a request in a team chat. Recent conversation (oldest first):\n` +
|
|
243
|
+
`${transcript}\n\n` +
|
|
244
|
+
`The latest message is your instruction: "${body}". Do what it asks, using the ` +
|
|
245
|
+
`conversation above for context — it often carries the actual spec (e.g. a reply ` +
|
|
246
|
+
`like "go for it" refers to what was just discussed). Make the change directly; ` +
|
|
247
|
+
`it will be opened as a PR for review.`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
229
251
|
/** owner/name from a GitHub remote URL (https or ssh), or null. */
|
|
230
252
|
export function normalizeRemote(url) {
|
|
231
253
|
const m = String(url || "")
|
|
@@ -393,16 +415,20 @@ export async function handleTask({ message, channelId, tool, me, caps = {} }, cf
|
|
|
393
415
|
const { memory: workspaceMemory = null } = await tool("get_workspace_memory", {}).catch(() => ({
|
|
394
416
|
memory: null,
|
|
395
417
|
}));
|
|
418
|
+
// The conversation the agent is replying within — fetched ONCE and handed to
|
|
419
|
+
// BOTH the chat reply and the coding prompt. Context is always crucial: a reply
|
|
420
|
+
// like "yeah, do it" only means something against what was just said, and even
|
|
421
|
+
// a direct request is clearer with the surrounding discussion. The chat path
|
|
422
|
+
// always had this; the code path used to run on the bare mention alone (so
|
|
423
|
+
// "go for it" reached the agent with no spec → nothing built). Now both share it.
|
|
424
|
+
const context = await fetchContext({ channelId, tool, parentId });
|
|
396
425
|
// Chat vs code. A clear action verb → code. With a repo linked, a bare
|
|
397
426
|
// affirmation ("go", "ship it") that follows a plan the agent just proposed
|
|
398
427
|
// ALSO means "execute it" → code path. Otherwise (greeting/question/no repo) →
|
|
399
|
-
// a conversational reply.
|
|
400
|
-
// reply so it isn't fetched twice.
|
|
428
|
+
// a conversational reply.
|
|
401
429
|
let isCode = looksLikeCodeTask(message.body);
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
context = await fetchContext({ channelId, tool, parentId });
|
|
405
|
-
if (agentProposedWork(context.rows, me?.agentName)) isCode = true;
|
|
430
|
+
if (!isCode && repoLink && isAffirmation(message.body) && agentProposedWork(context.rows, me?.agentName)) {
|
|
431
|
+
isCode = true;
|
|
406
432
|
}
|
|
407
433
|
if (!repoLink || !isCode) {
|
|
408
434
|
await respondConversationally({ message, channelId, tool, me, cfg, repoLink, parentId, workspaceMemory, signal, context, caps });
|
|
@@ -630,7 +656,7 @@ export async function handleTask({ message, channelId, tool, me, caps = {} }, cf
|
|
|
630
656
|
return { status: "cancelled", branch };
|
|
631
657
|
};
|
|
632
658
|
|
|
633
|
-
const staged = await runAndStage(message
|
|
659
|
+
const staged = await runAndStage(codeTaskPrompt({ message, context }));
|
|
634
660
|
if (staged.aborted) return await postStopped();
|
|
635
661
|
if (staged.empty) {
|
|
636
662
|
let body;
|