update
This commit is contained in:
1 parent
806200b3d1
commit
5547c29491
216 files changed
+5043
-3352
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import log from "electron-log/main.js";
|
||||
import { z } from "zod";
|
||||
import { canControlAgent } from "../agent-permissions";
|
||||
import { requireParam, type AgentApiServer } from "./server-core";
|
||||
@@ -82,7 +83,12 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
|
||||
server.addRoute("GET", "/api/agents/:agentId/skills", (_req, res, params, token) => {
|
||||
const agentId = requireParam(params, "agentId");
|
||||
let agent;
|
||||
try { agent = db.getAgent(agentId); } catch { agent = null; }
|
||||
try {
|
||||
agent = db.getAgent(agentId);
|
||||
} catch (error) {
|
||||
log.warn(`[api/agent-skills:GET] getAgent(${agentId}) failed: ${error instanceof Error ? error.message : String(error)}`);
|
||||
agent = null;
|
||||
}
|
||||
if (!agent || agent.companyId !== token.companyId) {
|
||||
server.json(res, 404, { error: "Agent not found in your company" });
|
||||
return;
|
||||
@@ -109,7 +115,12 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
|
||||
return;
|
||||
}
|
||||
let agent;
|
||||
try { agent = db.getAgent(agentId); } catch { agent = null; }
|
||||
try {
|
||||
agent = db.getAgent(agentId);
|
||||
} catch (error) {
|
||||
log.warn(`[api/agent-skills:POST] getAgent(${agentId}) failed: ${error instanceof Error ? error.message : String(error)}`);
|
||||
agent = null;
|
||||
}
|
||||
if (!agent || agent.companyId !== token.companyId) {
|
||||
server.json(res, 404, { error: "Agent not found in your company" });
|
||||
return;
|
||||
@@ -128,7 +139,12 @@ export function registerAgentControlRoutes(server: AgentApiServer) {
|
||||
const agentId = requireParam(params, "agentId");
|
||||
const skillId = requireParam(params, "skillId");
|
||||
let agent;
|
||||
try { agent = db.getAgent(agentId); } catch { agent = null; }
|
||||
try {
|
||||
agent = db.getAgent(agentId);
|
||||
} catch (error) {
|
||||
log.warn(`[api/agent-skills:DELETE] getAgent(${agentId}) failed: ${error instanceof Error ? error.message : String(error)}`);
|
||||
agent = null;
|
||||
}
|
||||
if (!agent || agent.companyId !== token.companyId) {
|
||||
server.json(res, 404, { error: "Agent not found in your company" });
|
||||
return;
|
||||
|
||||
@@ -166,7 +166,16 @@ export function registerAgentRoutes(server: AgentApiServer) {
|
||||
}
|
||||
const directReports = db.getDirectReports(agent.id, token.companyId);
|
||||
const reportsTo = agent.reportsTo;
|
||||
const manager = reportsTo ? (() => { try { return db.getAgent(reportsTo); } catch { return null; } })() : null;
|
||||
const manager = reportsTo
|
||||
? (() => {
|
||||
try {
|
||||
return db.getAgent(reportsTo);
|
||||
} catch (error) {
|
||||
log.warn(`[api/agents] manager lookup failed for ${reportsTo}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
return null;
|
||||
}
|
||||
})()
|
||||
: null;
|
||||
server.json(res, 200, {
|
||||
...agent,
|
||||
manager: manager ? { id: manager.id, name: manager.name, role: manager.role } : null,
|
||||
@@ -285,7 +294,11 @@ export function registerAgentRoutes(server: AgentApiServer) {
|
||||
server.json(res, 409, { error: `A hire request for "${input.name}" is already pending approval.` });
|
||||
return;
|
||||
}
|
||||
} catch { /* invalid payloadJson, skip */ }
|
||||
} catch (error) {
|
||||
log.warn(
|
||||
`[api/agents] invalid pending-hire payloadJson for company ${companyId}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const managerLabel = resolvedReportsTo
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import log from "electron-log/main.js";
|
||||
import { z } from "zod";
|
||||
import { IMPORTANT_DOC_TYPE_SET } from "@shared/document-categories";
|
||||
import { requireParam, type AgentApiServer } from "./server-core";
|
||||
@@ -109,7 +110,11 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
if (run.companyId === token.companyId) {
|
||||
taskId = run.taskId;
|
||||
}
|
||||
} catch { /* run may have finished or been deleted */ }
|
||||
} catch (error) {
|
||||
log.warn(
|
||||
`[api/documents] getRun(${token.runId}) failed while deriving taskId: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
// Fire document creation automation rules
|
||||
callbacks.onDocumentCreated(token.companyId, token.agentId, projectId, id, docTitle, docType, taskId);
|
||||
@@ -143,11 +148,19 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
if (agent.heartbeatEnabled) {
|
||||
db.setHeartbeat(token.agentId, false, agent.heartbeatIntervalSec || 120);
|
||||
}
|
||||
} catch { /* best effort */ }
|
||||
} catch (error) {
|
||||
log.warn(
|
||||
`[api/documents] heartbeat pause for agent ${token.agentId} failed: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
onDomainChanged();
|
||||
}
|
||||
}
|
||||
} catch { /* deliverable review gate is best-effort */ }
|
||||
} catch (error) {
|
||||
log.warn(
|
||||
`[api/documents] deliverable review gate failed for company ${token.companyId}, document ${id}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
server.json(res, 201, { id });
|
||||
@@ -258,7 +271,10 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
|
||||
const products = db.listWorkProductsForTask(task.id, task.companyId);
|
||||
server.json(res, 200, products);
|
||||
} catch { server.json(res, 404, { error: "Task not found" }); }
|
||||
} catch (error) {
|
||||
log.warn(`[api/work-products] list failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
server.json(res, 404, { error: "Task not found" });
|
||||
}
|
||||
});
|
||||
|
||||
server.addRoute("POST", "/api/issues/:issueId/work-products", (_req, res, params, token, body) => {
|
||||
@@ -286,7 +302,10 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
});
|
||||
onDomainChanged();
|
||||
server.json(res, 201, { id });
|
||||
} catch { server.json(res, 404, { error: "Task not found" }); }
|
||||
} catch (error) {
|
||||
log.warn(`[api/work-products] create failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
server.json(res, 404, { error: "Task not found" });
|
||||
}
|
||||
});
|
||||
|
||||
server.addRoute("PATCH", "/api/work-products/:workProductId", (_req, res, params, token, body) => {
|
||||
@@ -317,7 +336,10 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
if (task.companyId !== token.companyId) { server.json(res, 404, { error: "Task not found" }); return; }
|
||||
const links = db.listDocumentsForTask(task.id, task.companyId);
|
||||
server.json(res, 200, links);
|
||||
} catch { server.json(res, 404, { error: "Task not found" }); }
|
||||
} catch (error) {
|
||||
log.warn(`[api/task-documents] list failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
server.json(res, 404, { error: "Task not found" });
|
||||
}
|
||||
});
|
||||
|
||||
server.addRoute("PUT", "/api/issues/:issueId/documents/:key", (_req, res, params, token, body) => {
|
||||
@@ -337,7 +359,10 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
const linkId = db.linkDocumentToTask(task.id, documentId, task.companyId, key);
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { id: linkId, key });
|
||||
} catch { server.json(res, 404, { error: "Task not found" }); }
|
||||
} catch (error) {
|
||||
log.warn(`[api/task-documents] link failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
server.json(res, 404, { error: "Task not found" });
|
||||
}
|
||||
});
|
||||
|
||||
server.addRoute("DELETE", "/api/issues/:issueId/documents/:key", (_req, res, params, token) => {
|
||||
@@ -348,6 +373,9 @@ export function registerFileRoutes(server: AgentApiServer) {
|
||||
db.unlinkDocumentFromTask(task.id, key, task.companyId);
|
||||
onDomainChanged();
|
||||
server.json(res, 200, { unlinked: true });
|
||||
} catch { server.json(res, 404, { error: "Task not found" }); }
|
||||
} catch (error) {
|
||||
log.warn(`[api/task-documents] unlink failed for issue ${params.issueId}: ${error instanceof Error ? error.message : String(error)}`);
|
||||
server.json(res, 404, { error: "Task not found" });
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import log from "electron-log/main.js";
|
||||
import { z } from "zod";
|
||||
import { taskInputSchema } from "@shared/contracts";
|
||||
import { IMPORTANT_DOC_TYPES } from "@shared/document-categories";
|
||||
import { canAssignTask, canUpdateTask } from "../agent-permissions";
|
||||
import { inferTaskType } from "../connector-matching";
|
||||
import { isHeartbeatTaskTitle } from "../orchestration/heartbeat-task";
|
||||
import { validateTaskCreation } from "../task-quality-gates";
|
||||
import { requireParam, type AgentApiServer } from "./server-core";
|
||||
|
||||
@@ -221,7 +221,11 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
if (parentTask.assigneeAgentId && parentTask.assigneeAgentId !== token.agentId) {
|
||||
onWakeAgent(parentTask.assigneeAgentId, task.companyId, "subtask_completed");
|
||||
}
|
||||
} catch { /* parent task may have been deleted */ }
|
||||
} catch (error) {
|
||||
log.warn(
|
||||
`[api/tasks] parent task lookup failed for ${task.parentId}: ${error instanceof Error ? error.message : String(error)}`,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
const chain = db.getChainOfCommand(token.agentId);
|
||||
if (chain.length > 0) {
|
||||
@@ -304,8 +308,9 @@ export function registerTaskRoutes(server: AgentApiServer) {
|
||||
server.json(res, 403, { error: "Current agent is not allowed to assign this task to the selected agent" });
|
||||
return;
|
||||
}
|
||||
const isHeartbeat = isHeartbeatTaskTitle(input.title);
|
||||
const taskValidation = validateTaskCreation({ title: input.title, description: input.description ?? "" }, isHeartbeat);
|
||||
// Agent-authored tasks are never heartbeat tasks; the is_heartbeat flag
|
||||
// is set only by acquireHeartbeatTask in the orchestrator.
|
||||
const taskValidation = validateTaskCreation({ title: input.title, description: input.description ?? "" }, false);
|
||||
if (!taskValidation.valid) {
|
||||
server.json(res, 422, { error: taskValidation.errors.join("; ") });
|
||||
return;
|
||||
|
||||
Reference in new issue
Block a user