heyio 4.3.3 → 4.3.4
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/daemon/cli.js +83 -109
- package/dist/daemon/index.js +882 -971
- package/package.json +1 -1
package/dist/daemon/cli.js
CHANGED
|
@@ -80,7 +80,7 @@ var init_constants = __esm({
|
|
|
80
80
|
"packages/shared/dist/constants.js"() {
|
|
81
81
|
"use strict";
|
|
82
82
|
APP_NAME = "io";
|
|
83
|
-
APP_VERSION = "4.3.
|
|
83
|
+
APP_VERSION = "4.3.4";
|
|
84
84
|
API_PORT = 7777;
|
|
85
85
|
API_HOST = "0.0.0.0";
|
|
86
86
|
DEFAULT_MODEL = "gpt-4.1-mini";
|
|
@@ -69533,18 +69533,21 @@ var init_manager2 = __esm({
|
|
|
69533
69533
|
});
|
|
69534
69534
|
|
|
69535
69535
|
// packages/daemon/src/squad/model-selector.ts
|
|
69536
|
-
|
|
69536
|
+
function classifyTaskComplexity(taskDescription) {
|
|
69537
|
+
const tiers = ["ultra", "premium", "standard", "fast", "trivial"];
|
|
69538
|
+
for (const tier of tiers) {
|
|
69539
|
+
if (TIER_KEYWORDS[tier].some((pattern) => pattern.test(taskDescription))) {
|
|
69540
|
+
return tier;
|
|
69541
|
+
}
|
|
69542
|
+
}
|
|
69543
|
+
return "standard";
|
|
69544
|
+
}
|
|
69537
69545
|
async function selectModelForTask(taskDescription) {
|
|
69538
69546
|
const classifierModel = await getCheapestAvailableModel();
|
|
69539
69547
|
if (!classifierModel) {
|
|
69540
69548
|
throw new Error("No models available in pricing database");
|
|
69541
69549
|
}
|
|
69542
|
-
|
|
69543
|
-
try {
|
|
69544
|
-
tier = await classifyTaskComplexity(taskDescription, classifierModel.id);
|
|
69545
|
-
} catch {
|
|
69546
|
-
return classifierModel.id;
|
|
69547
|
-
}
|
|
69550
|
+
const tier = classifyTaskComplexity(taskDescription);
|
|
69548
69551
|
const selectedModel = await getCheapestInTier(tier);
|
|
69549
69552
|
if (selectedModel) {
|
|
69550
69553
|
return selectedModel.id;
|
|
@@ -69558,46 +69561,18 @@ async function selectModelForTask(taskDescription) {
|
|
|
69558
69561
|
}
|
|
69559
69562
|
return classifierModel.id;
|
|
69560
69563
|
}
|
|
69561
|
-
|
|
69562
|
-
let client2 = null;
|
|
69563
|
-
try {
|
|
69564
|
-
client2 = new CopilotClient2();
|
|
69565
|
-
await client2.start();
|
|
69566
|
-
const session = await client2.createSession({
|
|
69567
|
-
model: modelId,
|
|
69568
|
-
onPermissionRequest: approveAll2,
|
|
69569
|
-
systemMessage: { content: CLASSIFICATION_PROMPT }
|
|
69570
|
-
});
|
|
69571
|
-
try {
|
|
69572
|
-
const response = await session.sendAndWait({ prompt: `Task: ${taskDescription}` }, 15e3);
|
|
69573
|
-
const raw = (response.text ?? "").trim().toLowerCase();
|
|
69574
|
-
const tier = VALID_TIERS.find((t) => raw.includes(t));
|
|
69575
|
-
return tier ?? "standard";
|
|
69576
|
-
} finally {
|
|
69577
|
-
await session.disconnect().catch(() => void 0);
|
|
69578
|
-
}
|
|
69579
|
-
} finally {
|
|
69580
|
-
if (client2) {
|
|
69581
|
-
await client2.stop().catch(() => void 0);
|
|
69582
|
-
}
|
|
69583
|
-
}
|
|
69584
|
-
}
|
|
69585
|
-
var VALID_TIERS, CLASSIFICATION_PROMPT;
|
|
69564
|
+
var TIER_KEYWORDS;
|
|
69586
69565
|
var init_model_selector = __esm({
|
|
69587
69566
|
"packages/daemon/src/squad/model-selector.ts"() {
|
|
69588
69567
|
"use strict";
|
|
69589
69568
|
init_registry();
|
|
69590
|
-
|
|
69591
|
-
|
|
69592
|
-
|
|
69593
|
-
|
|
69594
|
-
|
|
69595
|
-
|
|
69596
|
-
|
|
69597
|
-
- premium: Architecture changes, complex refactoring, security work, performance optimization
|
|
69598
|
-
- ultra: System-wide redesigns, critical infrastructure, cross-cutting concerns
|
|
69599
|
-
|
|
69600
|
-
Reply with ONLY the tier name (one word, lowercase). Nothing else.`;
|
|
69569
|
+
TIER_KEYWORDS = {
|
|
69570
|
+
ultra: [/system[- ]wide/i, /redesign/i, /infrastructure/i, /cross[- ]cutting/i, /migration/i],
|
|
69571
|
+
premium: [/architect/i, /security/i, /performance/i, /complex refactor/i, /optimization/i],
|
|
69572
|
+
standard: [/implement/i, /feature/i, /multi[- ]file/i, /refactor/i, /integration/i],
|
|
69573
|
+
fast: [/fix/i, /bug/i, /update/i, /documentation/i, /single[- ]file/i, /small/i],
|
|
69574
|
+
trivial: [/typo/i, /rename/i, /comment/i, /config/i, /format/i]
|
|
69575
|
+
};
|
|
69601
69576
|
}
|
|
69602
69577
|
});
|
|
69603
69578
|
|
|
@@ -69638,8 +69613,8 @@ import { mkdir as mkdir9, readFile as readFile7, readdir as readdir5, stat as st
|
|
|
69638
69613
|
import { dirname as dirname8, extname as extname3, isAbsolute, join as join11, relative as relative3, resolve as resolve4 } from "node:path";
|
|
69639
69614
|
import { promisify as promisify3 } from "node:util";
|
|
69640
69615
|
import {
|
|
69641
|
-
CopilotClient as
|
|
69642
|
-
approveAll as
|
|
69616
|
+
CopilotClient as CopilotClient2,
|
|
69617
|
+
approveAll as approveAll2,
|
|
69643
69618
|
defineTool
|
|
69644
69619
|
} from "@github/copilot-sdk";
|
|
69645
69620
|
function createEmptyUsage() {
|
|
@@ -69898,15 +69873,15 @@ async function executeAgentTask(member, task, worktreePath, options2) {
|
|
|
69898
69873
|
const mcpServerNote = options2?.mcpServers?.length ? `Available MCP server labels: ${options2.mcpServers.join(", ")}.` : "No additional MCP servers were configured for this run.";
|
|
69899
69874
|
let client2 = null;
|
|
69900
69875
|
try {
|
|
69901
|
-
client2 = new
|
|
69876
|
+
client2 = new CopilotClient2({ workingDirectory: worktreePath });
|
|
69902
69877
|
await client2.start();
|
|
69903
69878
|
const model = member.model ? stripVendorPrefix(member.model) : await selectModelForTask(task.description);
|
|
69904
|
-
const
|
|
69879
|
+
const sessionPromise = client2.createSession({
|
|
69905
69880
|
model,
|
|
69906
69881
|
workingDirectory: worktreePath,
|
|
69907
69882
|
tools,
|
|
69908
69883
|
availableTools: ["custom:*"],
|
|
69909
|
-
onPermissionRequest:
|
|
69884
|
+
onPermissionRequest: approveAll2,
|
|
69910
69885
|
systemMessage: {
|
|
69911
69886
|
content: `${member.systemPrompt}
|
|
69912
69887
|
|
|
@@ -69916,6 +69891,15 @@ ${historyContext}
|
|
|
69916
69891
|
${mcpServerNote}${options2?.instancePromptSuffix ?? ""}`
|
|
69917
69892
|
}
|
|
69918
69893
|
});
|
|
69894
|
+
const session = await Promise.race([
|
|
69895
|
+
sessionPromise,
|
|
69896
|
+
new Promise(
|
|
69897
|
+
(_, reject) => setTimeout(
|
|
69898
|
+
() => reject(new Error(`Session creation timed out after ${SESSION_CREATE_TIMEOUT_MS}ms`)),
|
|
69899
|
+
SESSION_CREATE_TIMEOUT_MS
|
|
69900
|
+
)
|
|
69901
|
+
)
|
|
69902
|
+
]);
|
|
69919
69903
|
session.on("assistant.usage", (event) => {
|
|
69920
69904
|
usageEvents.push(event.data);
|
|
69921
69905
|
mergeUsage(usage, event.data);
|
|
@@ -69954,7 +69938,7 @@ Work only inside the current worktree. Summarize the concrete changes you made,
|
|
|
69954
69938
|
}
|
|
69955
69939
|
}
|
|
69956
69940
|
}
|
|
69957
|
-
var execAsync3, MAX_FILE_SIZE, MAX_LIST_RESULTS, MAX_SEARCH_RESULTS;
|
|
69941
|
+
var execAsync3, MAX_FILE_SIZE, MAX_LIST_RESULTS, MAX_SEARCH_RESULTS, SESSION_CREATE_TIMEOUT_MS;
|
|
69958
69942
|
var init_agent = __esm({
|
|
69959
69943
|
"packages/daemon/src/execution/agent.ts"() {
|
|
69960
69944
|
"use strict";
|
|
@@ -69966,6 +69950,7 @@ var init_agent = __esm({
|
|
|
69966
69950
|
MAX_FILE_SIZE = 2e5;
|
|
69967
69951
|
MAX_LIST_RESULTS = 200;
|
|
69968
69952
|
MAX_SEARCH_RESULTS = 100;
|
|
69953
|
+
SESSION_CREATE_TIMEOUT_MS = 3e4;
|
|
69969
69954
|
}
|
|
69970
69955
|
});
|
|
69971
69956
|
|
|
@@ -70057,7 +70042,7 @@ import { exec as exec4 } from "node:child_process";
|
|
|
70057
70042
|
import { access, readFile as readFile8 } from "node:fs/promises";
|
|
70058
70043
|
import { join as join12 } from "node:path";
|
|
70059
70044
|
import { promisify as promisify4 } from "node:util";
|
|
70060
|
-
import { CopilotClient as
|
|
70045
|
+
import { CopilotClient as CopilotClient3, approveAll as approveAll3 } from "@github/copilot-sdk";
|
|
70061
70046
|
async function fileExists(path) {
|
|
70062
70047
|
try {
|
|
70063
70048
|
await access(path);
|
|
@@ -70151,13 +70136,13 @@ Return strict JSON in this shape:
|
|
|
70151
70136
|
}`;
|
|
70152
70137
|
let client2 = null;
|
|
70153
70138
|
try {
|
|
70154
|
-
client2 = new
|
|
70139
|
+
client2 = new CopilotClient3({ workingDirectory: repoPath });
|
|
70155
70140
|
await client2.start();
|
|
70156
70141
|
const model = await selectModelForTask(`Create implementation plan: ${objective.description}`);
|
|
70157
70142
|
const session = await client2.createSession({
|
|
70158
70143
|
model,
|
|
70159
70144
|
workingDirectory: repoPath,
|
|
70160
|
-
onPermissionRequest:
|
|
70145
|
+
onPermissionRequest: approveAll3,
|
|
70161
70146
|
systemMessage: {
|
|
70162
70147
|
content: `${TEAM_LEAD_PROMPT}
|
|
70163
70148
|
|
|
@@ -70277,7 +70262,7 @@ var init_pr = __esm({
|
|
|
70277
70262
|
// packages/daemon/src/execution/qa.ts
|
|
70278
70263
|
import { exec as exec6 } from "node:child_process";
|
|
70279
70264
|
import { promisify as promisify6 } from "node:util";
|
|
70280
|
-
import { CopilotClient as
|
|
70265
|
+
import { CopilotClient as CopilotClient4, approveAll as approveAll4 } from "@github/copilot-sdk";
|
|
70281
70266
|
function extractJsonObject2(content) {
|
|
70282
70267
|
const fenced = content.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
70283
70268
|
if (fenced?.[1]) {
|
|
@@ -70315,13 +70300,13 @@ Return strict JSON:
|
|
|
70315
70300
|
}`;
|
|
70316
70301
|
let client2 = null;
|
|
70317
70302
|
try {
|
|
70318
|
-
client2 = new
|
|
70303
|
+
client2 = new CopilotClient4({ workingDirectory: worktreePath });
|
|
70319
70304
|
await client2.start();
|
|
70320
70305
|
const model = qaMember.model ? stripVendorPrefix(qaMember.model) : await selectModelForTask(`QA review: ${objective.description}`);
|
|
70321
70306
|
const session = await client2.createSession({
|
|
70322
70307
|
model,
|
|
70323
70308
|
workingDirectory: worktreePath,
|
|
70324
|
-
onPermissionRequest:
|
|
70309
|
+
onPermissionRequest: approveAll4,
|
|
70325
70310
|
systemMessage: {
|
|
70326
70311
|
content: QA_PROMPT
|
|
70327
70312
|
}
|
|
@@ -70405,7 +70390,7 @@ var init_qa = __esm({
|
|
|
70405
70390
|
});
|
|
70406
70391
|
|
|
70407
70392
|
// packages/daemon/src/execution/review.ts
|
|
70408
|
-
import { CopilotClient as
|
|
70393
|
+
import { CopilotClient as CopilotClient5, approveAll as approveAll5 } from "@github/copilot-sdk";
|
|
70409
70394
|
function extractJsonObject3(content) {
|
|
70410
70395
|
const fenced = content.match(/```(?:json)?\s*([\s\S]*?)```/i);
|
|
70411
70396
|
if (fenced?.[1]) {
|
|
@@ -70450,12 +70435,12 @@ Return strict JSON:
|
|
|
70450
70435
|
}`;
|
|
70451
70436
|
let client2 = null;
|
|
70452
70437
|
try {
|
|
70453
|
-
client2 = new
|
|
70438
|
+
client2 = new CopilotClient5();
|
|
70454
70439
|
await client2.start();
|
|
70455
70440
|
const model = teamLead.model ? stripVendorPrefix(teamLead.model) : await selectModelForTask(`Code review: ${objective.description}`);
|
|
70456
70441
|
const session = await client2.createSession({
|
|
70457
70442
|
model,
|
|
70458
|
-
onPermissionRequest:
|
|
70443
|
+
onPermissionRequest: approveAll5,
|
|
70459
70444
|
systemMessage: {
|
|
70460
70445
|
content: `${TEAM_LEAD_PROMPT}
|
|
70461
70446
|
|
|
@@ -70617,60 +70602,49 @@ async function executePendingTasks(objective, members, worktreePath, mcpServers,
|
|
|
70617
70602
|
if (pendingTasks.length === 0) {
|
|
70618
70603
|
return getTasksForObjective(objective.id);
|
|
70619
70604
|
}
|
|
70620
|
-
const
|
|
70621
|
-
|
|
70622
|
-
|
|
70623
|
-
|
|
70624
|
-
const failedTask = await markTaskFailed(
|
|
70625
|
-
task.id,
|
|
70626
|
-
"No squad member matched the task assignee."
|
|
70627
|
-
);
|
|
70628
|
-
eventBus.emit(EVENT_NAMES.TASK_FAILED, {
|
|
70629
|
-
task: failedTask,
|
|
70630
|
-
agentName: "unassigned",
|
|
70631
|
-
reason: failedTask.result ?? "No assignee"
|
|
70632
|
-
});
|
|
70633
|
-
throw new Error(`Task ${task.id} has no matching assignee`);
|
|
70634
|
-
}
|
|
70635
|
-
const inProgressTask = await updateTaskStatus(
|
|
70605
|
+
for (const task of pendingTasks) {
|
|
70606
|
+
const member = members.find((candidate) => candidate.id === task.assigneeId);
|
|
70607
|
+
if (!member) {
|
|
70608
|
+
const failedTask = await markTaskFailed(
|
|
70636
70609
|
task.id,
|
|
70637
|
-
"
|
|
70638
|
-
task.result ?? void 0
|
|
70610
|
+
"No squad member matched the task assignee."
|
|
70639
70611
|
);
|
|
70640
|
-
|
|
70641
|
-
|
|
70642
|
-
|
|
70643
|
-
|
|
70644
|
-
agentId: member.id,
|
|
70645
|
-
taskId: task.id
|
|
70646
|
-
});
|
|
70647
|
-
const execution = await executeAgentTask(member, task, worktreePath, {
|
|
70648
|
-
mcpServers,
|
|
70649
|
-
instancePromptSuffix
|
|
70612
|
+
eventBus.emit(EVENT_NAMES.TASK_FAILED, {
|
|
70613
|
+
task: failedTask,
|
|
70614
|
+
agentName: "unassigned",
|
|
70615
|
+
reason: failedTask.result ?? "No assignee"
|
|
70650
70616
|
});
|
|
70651
|
-
|
|
70652
|
-
|
|
70653
|
-
|
|
70654
|
-
|
|
70655
|
-
|
|
70656
|
-
|
|
70657
|
-
|
|
70658
|
-
|
|
70659
|
-
|
|
70660
|
-
|
|
70661
|
-
|
|
70662
|
-
|
|
70663
|
-
|
|
70664
|
-
|
|
70665
|
-
|
|
70666
|
-
|
|
70617
|
+
throw new Error(`Task ${task.id} has no matching assignee`);
|
|
70618
|
+
}
|
|
70619
|
+
const inProgressTask = await updateTaskStatus(task.id, "in_progress", task.result ?? void 0);
|
|
70620
|
+
const startedTask = inProgressTask ?? task;
|
|
70621
|
+
eventBus.emit(EVENT_NAMES.TASK_STARTED, { task: startedTask, agentName: member.name });
|
|
70622
|
+
eventBus.emit(EVENT_NAMES.AGENT_EXECUTING, {
|
|
70623
|
+
squadId: objective.squadId,
|
|
70624
|
+
agentId: member.id,
|
|
70625
|
+
taskId: task.id
|
|
70626
|
+
});
|
|
70627
|
+
const execution = await executeAgentTask(member, task, worktreePath, {
|
|
70628
|
+
mcpServers,
|
|
70629
|
+
instancePromptSuffix
|
|
70630
|
+
});
|
|
70631
|
+
if (!execution.success) {
|
|
70632
|
+
const failedTask = await markTaskFailed(task.id, execution.result);
|
|
70633
|
+
eventBus.emit(EVENT_NAMES.TASK_FAILED, {
|
|
70634
|
+
task: failedTask,
|
|
70635
|
+
agentName: member.name,
|
|
70636
|
+
reason: execution.result
|
|
70667
70637
|
});
|
|
70668
|
-
|
|
70669
|
-
}
|
|
70670
|
-
|
|
70671
|
-
|
|
70672
|
-
|
|
70673
|
-
|
|
70638
|
+
throw new Error(execution.result);
|
|
70639
|
+
}
|
|
70640
|
+
const completedTask = await markTaskComplete(task.id, execution.result);
|
|
70641
|
+
await extractLearnings(member.id, member.squadId, execution.result);
|
|
70642
|
+
eventBus.emit(EVENT_NAMES.TASK_COMPLETED, { task: completedTask, agentName: member.name });
|
|
70643
|
+
eventBus.emit(EVENT_NAMES.AGENT_COMPLETED, {
|
|
70644
|
+
squadId: objective.squadId,
|
|
70645
|
+
agentId: member.id,
|
|
70646
|
+
taskId: task.id
|
|
70647
|
+
});
|
|
70674
70648
|
}
|
|
70675
70649
|
return getTasksForObjective(objective.id);
|
|
70676
70650
|
}
|