@paperclipai/server 0.3.0 → 0.3.1-canary.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/dist/adapters/registry.d.ts.map +1 -1
- package/dist/adapters/registry.js +12 -0
- package/dist/adapters/registry.js.map +1 -1
- package/dist/app.d.ts +1 -0
- package/dist/app.d.ts.map +1 -1
- package/dist/app.js +9 -2
- package/dist/app.js.map +1 -1
- package/dist/attachment-types.d.ts +33 -0
- package/dist/attachment-types.d.ts.map +1 -0
- package/dist/attachment-types.js +61 -0
- package/dist/attachment-types.js.map +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -2
- package/dist/index.js.map +1 -1
- package/dist/log-redaction.d.ts +10 -0
- package/dist/log-redaction.d.ts.map +1 -0
- package/dist/log-redaction.js +110 -0
- package/dist/log-redaction.js.map +1 -0
- package/dist/middleware/logger.d.ts.map +1 -1
- package/dist/middleware/logger.js +1 -0
- package/dist/middleware/logger.js.map +1 -1
- package/dist/routes/activity.d.ts.map +1 -1
- package/dist/routes/activity.js +12 -21
- package/dist/routes/activity.js.map +1 -1
- package/dist/routes/agents.d.ts.map +1 -1
- package/dist/routes/agents.js +102 -3
- package/dist/routes/agents.js.map +1 -1
- package/dist/routes/approvals.d.ts.map +1 -1
- package/dist/routes/approvals.js +87 -83
- package/dist/routes/approvals.js.map +1 -1
- package/dist/routes/assets.d.ts.map +1 -1
- package/dist/routes/assets.js +5 -12
- package/dist/routes/assets.js.map +1 -1
- package/dist/routes/issues.d.ts.map +1 -1
- package/dist/routes/issues.js +16 -11
- package/dist/routes/issues.js.map +1 -1
- package/dist/routes/sidebar-badges.d.ts.map +1 -1
- package/dist/routes/sidebar-badges.js +1 -4
- package/dist/routes/sidebar-badges.js.map +1 -1
- package/dist/services/activity-log.d.ts.map +1 -1
- package/dist/services/activity-log.js +4 -2
- package/dist/services/activity-log.js.map +1 -1
- package/dist/services/approvals.d.ts +30 -24
- package/dist/services/approvals.d.ts.map +1 -1
- package/dist/services/approvals.js +51 -42
- package/dist/services/approvals.js.map +1 -1
- package/dist/services/company-portability.d.ts.map +1 -1
- package/dist/services/company-portability.js +5 -1
- package/dist/services/company-portability.js.map +1 -1
- package/dist/services/dashboard.d.ts +0 -1
- package/dist/services/dashboard.d.ts.map +1 -1
- package/dist/services/dashboard.js +0 -7
- package/dist/services/dashboard.js.map +1 -1
- package/dist/services/execution-workspace-policy.d.ts +19 -0
- package/dist/services/execution-workspace-policy.d.ts.map +1 -0
- package/dist/services/execution-workspace-policy.js +117 -0
- package/dist/services/execution-workspace-policy.js.map +1 -0
- package/dist/services/goals.d.ts +26 -0
- package/dist/services/goals.d.ts.map +1 -1
- package/dist/services/goals.js +26 -1
- package/dist/services/goals.js.map +1 -1
- package/dist/services/heartbeat-run-summary.d.ts +2 -0
- package/dist/services/heartbeat-run-summary.d.ts.map +1 -0
- package/dist/services/heartbeat-run-summary.js +30 -0
- package/dist/services/heartbeat-run-summary.js.map +1 -0
- package/dist/services/heartbeat.d.ts +30 -996
- package/dist/services/heartbeat.d.ts.map +1 -1
- package/dist/services/heartbeat.js +236 -47
- package/dist/services/heartbeat.js.map +1 -1
- package/dist/services/index.d.ts +1 -0
- package/dist/services/index.d.ts.map +1 -1
- package/dist/services/index.js +1 -0
- package/dist/services/index.js.map +1 -1
- package/dist/services/issue-goal-fallback.d.ts +15 -0
- package/dist/services/issue-goal-fallback.d.ts.map +1 -0
- package/dist/services/issue-goal-fallback.js +15 -0
- package/dist/services/issue-goal-fallback.js.map +1 -0
- package/dist/services/issues.d.ts +5 -278
- package/dist/services/issues.d.ts.map +1 -1
- package/dist/services/issues.js +52 -14
- package/dist/services/issues.js.map +1 -1
- package/dist/services/projects.d.ts +4 -2
- package/dist/services/projects.d.ts.map +1 -1
- package/dist/services/projects.js +49 -6
- package/dist/services/projects.js.map +1 -1
- package/dist/services/workspace-runtime.d.ts +126 -0
- package/dist/services/workspace-runtime.d.ts.map +1 -0
- package/dist/services/workspace-runtime.js +852 -0
- package/dist/services/workspace-runtime.js.map +1 -0
- package/dist/ui-branding.d.ts +4 -0
- package/dist/ui-branding.d.ts.map +1 -0
- package/dist/ui-branding.js +37 -0
- package/dist/ui-branding.js.map +1 -0
- package/package.json +11 -10
- package/skills/paperclip/SKILL.md +23 -19
- package/ui-dist/assets/{_basePickBy-BYrQlacK.js → _basePickBy-B0xbZITw.js} +1 -1
- package/ui-dist/assets/{_baseUniq-DOSawgF3.js → _baseUniq-Cfd5u3qc.js} +1 -1
- package/ui-dist/assets/{arc-CG7T0hfG.js → arc-7Xbu8tBF.js} +1 -1
- package/ui-dist/assets/{architectureDiagram-VXUJARFQ-Bcn7ytDO.js → architectureDiagram-VXUJARFQ-C8F7ZRYc.js} +1 -1
- package/ui-dist/assets/{blockDiagram-VD42YOAC-BQGrx2lv.js → blockDiagram-VD42YOAC-Dp08a65A.js} +1 -1
- package/ui-dist/assets/{c4Diagram-YG6GDRKO-owH9Kb3t.js → c4Diagram-YG6GDRKO-BJfslTgZ.js} +1 -1
- package/ui-dist/assets/channel-BViQDbSq.js +1 -0
- package/ui-dist/assets/{chunk-4BX2VUAB-DY1UIe4g.js → chunk-4BX2VUAB-BhaYWH7e.js} +1 -1
- package/ui-dist/assets/{chunk-55IACEB6-CnWFPfPQ.js → chunk-55IACEB6-BOzJUsYW.js} +1 -1
- package/ui-dist/assets/{chunk-B4BG7PRW-DhlLW80l.js → chunk-B4BG7PRW-CbVcziyE.js} +1 -1
- package/ui-dist/assets/{chunk-DI55MBZ5-DPt7dj6c.js → chunk-DI55MBZ5-DghPtP3y.js} +1 -1
- package/ui-dist/assets/{chunk-FMBD7UC4-GQwzgYa4.js → chunk-FMBD7UC4-CB095Kfn.js} +1 -1
- package/ui-dist/assets/{chunk-QN33PNHL-BFHLVk5s.js → chunk-QN33PNHL-DfpzfDqJ.js} +1 -1
- package/ui-dist/assets/{chunk-QZHKN3VN-CLe3KEAf.js → chunk-QZHKN3VN-Df3d5z1y.js} +1 -1
- package/ui-dist/assets/{chunk-TZMSLE5B-BhccYB4e.js → chunk-TZMSLE5B-B6tX6bZI.js} +1 -1
- package/ui-dist/assets/classDiagram-2ON5EDUG-CjMCmxMT.js +1 -0
- package/ui-dist/assets/classDiagram-v2-WZHVMYZB-CjMCmxMT.js +1 -0
- package/ui-dist/assets/clone-Dbn9wtE1.js +1 -0
- package/ui-dist/assets/{cose-bilkent-S5V4N54A-DqECYL1w.js → cose-bilkent-S5V4N54A-38wg_s9V.js} +1 -1
- package/ui-dist/assets/{dagre-6UL2VRFP-DXeQqIJ2.js → dagre-6UL2VRFP-DPVj3XLS.js} +1 -1
- package/ui-dist/assets/{diagram-PSM6KHXK-DNu3Ctuy.js → diagram-PSM6KHXK-BJh89zUA.js} +1 -1
- package/ui-dist/assets/{diagram-QEK2KX5R-1wUR_z9S.js → diagram-QEK2KX5R-Bw0m_j10.js} +1 -1
- package/ui-dist/assets/{diagram-S2PKOQOG-D3IK8rZb.js → diagram-S2PKOQOG-D7_M2F3u.js} +1 -1
- package/ui-dist/assets/{erDiagram-Q2GNP2WA-DU3L0RbU.js → erDiagram-Q2GNP2WA-CLsjqTWP.js} +1 -1
- package/ui-dist/assets/{flowDiagram-NV44I4VS-CN46A5Ez.js → flowDiagram-NV44I4VS-BZZ7ezVB.js} +1 -1
- package/ui-dist/assets/{ganttDiagram-JELNMOA3-DGbOi1Wz.js → ganttDiagram-JELNMOA3-KzsFuwBt.js} +1 -1
- package/ui-dist/assets/{gitGraphDiagram-V2S2FVAM-D98N7SOj.js → gitGraphDiagram-V2S2FVAM-DSHtY7Vu.js} +1 -1
- package/ui-dist/assets/{graph-Cf7LCNJy.js → graph-luIG1UAS.js} +1 -1
- package/ui-dist/assets/{index-CP1BgxcV.js → index-00kuG4sI.js} +1 -1
- package/ui-dist/assets/{index-DiXE2gv-.js → index-1gX09-Fl.js} +1 -1
- package/ui-dist/assets/{index-CqG5WZHq.js → index-B1ZMzzs0.js} +1 -1
- package/ui-dist/assets/index-BHP9dico.js +1006 -0
- package/ui-dist/assets/{index-cx0y6-1h.js → index-B_3g3Rie.js} +1 -1
- package/ui-dist/assets/{index-CI56poQD.js → index-BeeKMqNU.js} +1 -1
- package/ui-dist/assets/{index-BfG2u5u0.js → index-BfB4lKJN.js} +1 -1
- package/ui-dist/assets/index-BfNaDZnn.css +1 -0
- package/ui-dist/assets/{index-DZdNKByU.js → index-Bv4xCjxl.js} +1 -1
- package/ui-dist/assets/{index--K1VLoF-.js → index-C2SZYIDA.js} +1 -1
- package/ui-dist/assets/{index-DB5nKqAA.js → index-C8XyGAr9.js} +1 -1
- package/ui-dist/assets/{index-C2-SE7P0.js → index-CaR9XM4h.js} +1 -1
- package/ui-dist/assets/{index-DujThSls.js → index-CbGtsjW7.js} +1 -1
- package/ui-dist/assets/{index-D0EsfNYg.js → index-CeDCs_2i.js} +1 -1
- package/ui-dist/assets/{index-OkxoZoQy.js → index-DBy0vJy3.js} +1 -1
- package/ui-dist/assets/{index-BoAYxRAO.js → index-DJf8diAA.js} +1 -1
- package/ui-dist/assets/{index-N1SX_i0z.js → index-DcfLFstG.js} +1 -1
- package/ui-dist/assets/{index-DXgtGequ.js → index-DnIPDZLp.js} +1 -1
- package/ui-dist/assets/{index-Cick_QSL.js → index-DoTq-BeR.js} +1 -1
- package/ui-dist/assets/{index-0BSerEC2.js → index-Ds7vLTSK.js} +1 -1
- package/ui-dist/assets/{index-Beb2ZlSv.js → index-RUBFVv6t.js} +1 -1
- package/ui-dist/assets/{index-TFF7cXd7.js → index-itc7BfMy.js} +1 -1
- package/ui-dist/assets/{index-BD6My-aI.js → index-nFjLambq.js} +1 -1
- package/ui-dist/assets/{index-B-xuGUs-.js → index-uR3zjYaD.js} +1 -1
- package/ui-dist/assets/{infoDiagram-HS3SLOUP-D_b1CK0Y.js → infoDiagram-HS3SLOUP-CDEfWpme.js} +1 -1
- package/ui-dist/assets/{journeyDiagram-XKPGCS4Q-4oCVXUve.js → journeyDiagram-XKPGCS4Q-i7nsbg_Y.js} +1 -1
- package/ui-dist/assets/{kanban-definition-3W4ZIXB7-0VcjP_qf.js → kanban-definition-3W4ZIXB7-DDlx1qVE.js} +1 -1
- package/ui-dist/assets/{layout-BQcYXlNv.js → layout-C7AtmJzX.js} +1 -1
- package/ui-dist/assets/{linear-nz0Lfiys.js → linear-C5jHT-WP.js} +1 -1
- package/ui-dist/assets/{mermaid.core-BaxvgwjG.js → mermaid.core-C8YQ4fcY.js} +4 -4
- package/ui-dist/assets/{mindmap-definition-VGOIOE7T-BnW6nEhl.js → mindmap-definition-VGOIOE7T-B9m9PuUg.js} +1 -1
- package/ui-dist/assets/{pieDiagram-ADFJNKIX-O1tvU_18.js → pieDiagram-ADFJNKIX-SvKywCSE.js} +1 -1
- package/ui-dist/assets/{quadrantDiagram-AYHSOK5B-BfM2aQbf.js → quadrantDiagram-AYHSOK5B-QfBPm7Y1.js} +1 -1
- package/ui-dist/assets/{requirementDiagram-UZGBJVZJ-rXVZupag.js → requirementDiagram-UZGBJVZJ-DnfQQuwi.js} +1 -1
- package/ui-dist/assets/{sankeyDiagram-TZEHDZUN-BNgaPVo6.js → sankeyDiagram-TZEHDZUN-DvLkjzIW.js} +1 -1
- package/ui-dist/assets/{sequenceDiagram-WL72ISMW--KnZ0qRV.js → sequenceDiagram-WL72ISMW-5Lq2rWBc.js} +1 -1
- package/ui-dist/assets/{stateDiagram-FKZM4ZOC-DlGdC88b.js → stateDiagram-FKZM4ZOC-DcYPHDyi.js} +1 -1
- package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-nv50YYrl.js +1 -0
- package/ui-dist/assets/{timeline-definition-IT6M3QCI-CCwriy0-.js → timeline-definition-IT6M3QCI-lrN4JmWa.js} +1 -1
- package/ui-dist/assets/{treemap-GDKQZRPO-C-79yojr.js → treemap-GDKQZRPO-DFJKIBTQ.js} +1 -1
- package/ui-dist/assets/{xychartDiagram-PRI3JC2R-Dj0jcMBZ.js → xychartDiagram-PRI3JC2R-CT47vtdm.js} +1 -1
- package/ui-dist/index.html +4 -2
- package/ui-dist/worktree-favicon-16x16.png +0 -0
- package/ui-dist/worktree-favicon-32x32.png +0 -0
- package/ui-dist/worktree-favicon.ico +0 -0
- package/ui-dist/worktree-favicon.svg +9 -0
- package/skills/release/SKILL.md +0 -261
- package/skills/release-changelog/SKILL.md +0 -178
- package/ui-dist/assets/channel-DdXqC9Qy.js +0 -1
- package/ui-dist/assets/classDiagram-2ON5EDUG-ZV36NLFv.js +0 -1
- package/ui-dist/assets/classDiagram-v2-WZHVMYZB-ZV36NLFv.js +0 -1
- package/ui-dist/assets/clone-CvxIjPQa.js +0 -1
- package/ui-dist/assets/index-BYw6Loly.js +0 -900
- package/ui-dist/assets/index-nfAtmpEH.css +0 -1
- package/ui-dist/assets/stateDiagram-v2-4FDKWEC3-CuVnpOfP.js +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/services/heartbeat.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"heartbeat.d.ts","sourceRoot":"","sources":["../../src/services/heartbeat.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { and, asc, desc, eq, gt, inArray, sql } from "drizzle-orm";
|
|
4
|
-
import { agents, agentRuntimeState, agentTaskSessions, agentWakeupRequests, heartbeatRunEvents, heartbeatRuns,
|
|
4
|
+
import { agents, agentRuntimeState, agentTaskSessions, agentWakeupRequests, heartbeatRunEvents, heartbeatRuns, issues, projects, projectWorkspaces, } from "@paperclipai/db";
|
|
5
5
|
import { conflict, notFound } from "../errors.js";
|
|
6
6
|
import { logger } from "../middleware/logger.js";
|
|
7
7
|
import { publishLiveEvent } from "./live-events.js";
|
|
@@ -9,14 +9,50 @@ import { getRunLogStore } from "./run-log-store.js";
|
|
|
9
9
|
import { getServerAdapter, runningProcesses } from "../adapters/index.js";
|
|
10
10
|
import { createLocalAgentJwt } from "../agent-auth-jwt.js";
|
|
11
11
|
import { parseObject, asBoolean, asNumber, appendWithCap, MAX_EXCERPT_BYTES } from "../adapters/utils.js";
|
|
12
|
+
import { costService } from "./costs.js";
|
|
12
13
|
import { secretService } from "./secrets.js";
|
|
13
14
|
import { resolveDefaultAgentWorkspaceDir } from "../home-paths.js";
|
|
15
|
+
import { summarizeHeartbeatRunResultJson } from "./heartbeat-run-summary.js";
|
|
16
|
+
import { buildWorkspaceReadyComment, ensureRuntimeServicesForRun, persistAdapterManagedRuntimeServices, realizeExecutionWorkspace, releaseRuntimeServicesForRun, } from "./workspace-runtime.js";
|
|
17
|
+
import { issueService } from "./issues.js";
|
|
18
|
+
import { buildExecutionWorkspaceAdapterConfig, parseIssueExecutionWorkspaceSettings, parseProjectExecutionWorkspacePolicy, resolveExecutionWorkspaceMode, } from "./execution-workspace-policy.js";
|
|
19
|
+
import { redactCurrentUserText, redactCurrentUserValue } from "../log-redaction.js";
|
|
14
20
|
const MAX_LIVE_LOG_CHUNK_BYTES = 8 * 1024;
|
|
15
21
|
const HEARTBEAT_MAX_CONCURRENT_RUNS_DEFAULT = 1;
|
|
16
22
|
const HEARTBEAT_MAX_CONCURRENT_RUNS_MAX = 10;
|
|
17
23
|
const DEFERRED_WAKE_CONTEXT_KEY = "_paperclipWakeContext";
|
|
18
24
|
const startLocksByAgent = new Map();
|
|
19
25
|
const REPO_ONLY_CWD_SENTINEL = "/__paperclip_repo_only__";
|
|
26
|
+
const heartbeatRunListColumns = {
|
|
27
|
+
id: heartbeatRuns.id,
|
|
28
|
+
companyId: heartbeatRuns.companyId,
|
|
29
|
+
agentId: heartbeatRuns.agentId,
|
|
30
|
+
invocationSource: heartbeatRuns.invocationSource,
|
|
31
|
+
triggerDetail: heartbeatRuns.triggerDetail,
|
|
32
|
+
status: heartbeatRuns.status,
|
|
33
|
+
startedAt: heartbeatRuns.startedAt,
|
|
34
|
+
finishedAt: heartbeatRuns.finishedAt,
|
|
35
|
+
error: heartbeatRuns.error,
|
|
36
|
+
wakeupRequestId: heartbeatRuns.wakeupRequestId,
|
|
37
|
+
exitCode: heartbeatRuns.exitCode,
|
|
38
|
+
signal: heartbeatRuns.signal,
|
|
39
|
+
usageJson: heartbeatRuns.usageJson,
|
|
40
|
+
resultJson: heartbeatRuns.resultJson,
|
|
41
|
+
sessionIdBefore: heartbeatRuns.sessionIdBefore,
|
|
42
|
+
sessionIdAfter: heartbeatRuns.sessionIdAfter,
|
|
43
|
+
logStore: heartbeatRuns.logStore,
|
|
44
|
+
logRef: heartbeatRuns.logRef,
|
|
45
|
+
logBytes: heartbeatRuns.logBytes,
|
|
46
|
+
logSha256: heartbeatRuns.logSha256,
|
|
47
|
+
logCompressed: heartbeatRuns.logCompressed,
|
|
48
|
+
stdoutExcerpt: sql `NULL`.as("stdoutExcerpt"),
|
|
49
|
+
stderrExcerpt: sql `NULL`.as("stderrExcerpt"),
|
|
50
|
+
errorCode: heartbeatRuns.errorCode,
|
|
51
|
+
externalRunId: heartbeatRuns.externalRunId,
|
|
52
|
+
contextSnapshot: heartbeatRuns.contextSnapshot,
|
|
53
|
+
createdAt: heartbeatRuns.createdAt,
|
|
54
|
+
updatedAt: heartbeatRuns.updatedAt,
|
|
55
|
+
};
|
|
20
56
|
function appendExcerpt(prev, chunk) {
|
|
21
57
|
return appendWithCap(prev, chunk, MAX_EXCERPT_BYTES);
|
|
22
58
|
}
|
|
@@ -294,6 +330,7 @@ function resolveNextSessionState(input) {
|
|
|
294
330
|
export function heartbeatService(db) {
|
|
295
331
|
const runLogStore = getRunLogStore();
|
|
296
332
|
const secretsSvc = secretService(db);
|
|
333
|
+
const issuesSvc = issueService(db);
|
|
297
334
|
async function getAgent(agentId) {
|
|
298
335
|
return db
|
|
299
336
|
.select()
|
|
@@ -551,6 +588,8 @@ export function heartbeatService(db) {
|
|
|
551
588
|
.where(eq(agentWakeupRequests.id, wakeupRequestId));
|
|
552
589
|
}
|
|
553
590
|
async function appendRunEvent(run, seq, event) {
|
|
591
|
+
const sanitizedMessage = event.message ? redactCurrentUserText(event.message) : event.message;
|
|
592
|
+
const sanitizedPayload = event.payload ? redactCurrentUserValue(event.payload) : event.payload;
|
|
554
593
|
await db.insert(heartbeatRunEvents).values({
|
|
555
594
|
companyId: run.companyId,
|
|
556
595
|
runId: run.id,
|
|
@@ -560,8 +599,8 @@ export function heartbeatService(db) {
|
|
|
560
599
|
stream: event.stream,
|
|
561
600
|
level: event.level,
|
|
562
601
|
color: event.color,
|
|
563
|
-
message:
|
|
564
|
-
payload:
|
|
602
|
+
message: sanitizedMessage,
|
|
603
|
+
payload: sanitizedPayload,
|
|
565
604
|
});
|
|
566
605
|
publishLiveEvent({
|
|
567
606
|
companyId: run.companyId,
|
|
@@ -574,8 +613,8 @@ export function heartbeatService(db) {
|
|
|
574
613
|
stream: event.stream ?? null,
|
|
575
614
|
level: event.level ?? null,
|
|
576
615
|
color: event.color ?? null,
|
|
577
|
-
message:
|
|
578
|
-
payload:
|
|
616
|
+
message: sanitizedMessage ?? null,
|
|
617
|
+
payload: sanitizedPayload ?? null,
|
|
579
618
|
},
|
|
580
619
|
});
|
|
581
620
|
}
|
|
@@ -739,8 +778,8 @@ export function heartbeatService(db) {
|
|
|
739
778
|
})
|
|
740
779
|
.where(eq(agentRuntimeState.agentId, agent.id));
|
|
741
780
|
if (additionalCostCents > 0 || hasTokenUsage) {
|
|
742
|
-
|
|
743
|
-
|
|
781
|
+
const costs = costService(db);
|
|
782
|
+
await costs.createEvent(agent.companyId, {
|
|
744
783
|
agentId: agent.id,
|
|
745
784
|
provider: result.provider ?? "unknown",
|
|
746
785
|
model: result.model ?? "unknown",
|
|
@@ -750,15 +789,6 @@ export function heartbeatService(db) {
|
|
|
750
789
|
occurredAt: new Date(),
|
|
751
790
|
});
|
|
752
791
|
}
|
|
753
|
-
if (additionalCostCents > 0) {
|
|
754
|
-
await db
|
|
755
|
-
.update(agents)
|
|
756
|
-
.set({
|
|
757
|
-
spentMonthlyCents: sql `${agents.spentMonthlyCents} + ${additionalCostCents}`,
|
|
758
|
-
updatedAt: new Date(),
|
|
759
|
-
})
|
|
760
|
-
.where(eq(agents.id, agent.id));
|
|
761
|
-
}
|
|
762
792
|
}
|
|
763
793
|
async function startNextQueuedRunForAgent(agentId) {
|
|
764
794
|
return withAgentStartLock(agentId, async () => {
|
|
@@ -832,8 +862,10 @@ export function heartbeatService(db) {
|
|
|
832
862
|
const issueAssigneeConfig = issueId
|
|
833
863
|
? await db
|
|
834
864
|
.select({
|
|
865
|
+
projectId: issues.projectId,
|
|
835
866
|
assigneeAgentId: issues.assigneeAgentId,
|
|
836
867
|
assigneeAdapterOverrides: issues.assigneeAdapterOverrides,
|
|
868
|
+
executionWorkspaceSettings: issues.executionWorkspaceSettings,
|
|
837
869
|
})
|
|
838
870
|
.from(issues)
|
|
839
871
|
.where(and(eq(issues.id, issueId), eq(issues.companyId, agent.companyId)))
|
|
@@ -842,6 +874,16 @@ export function heartbeatService(db) {
|
|
|
842
874
|
const issueAssigneeOverrides = issueAssigneeConfig && issueAssigneeConfig.assigneeAgentId === agent.id
|
|
843
875
|
? parseIssueAssigneeAdapterOverrides(issueAssigneeConfig.assigneeAdapterOverrides)
|
|
844
876
|
: null;
|
|
877
|
+
const issueExecutionWorkspaceSettings = parseIssueExecutionWorkspaceSettings(issueAssigneeConfig?.executionWorkspaceSettings);
|
|
878
|
+
const contextProjectId = readNonEmptyString(context.projectId);
|
|
879
|
+
const executionProjectId = issueAssigneeConfig?.projectId ?? contextProjectId;
|
|
880
|
+
const projectExecutionWorkspacePolicy = executionProjectId
|
|
881
|
+
? await db
|
|
882
|
+
.select({ executionWorkspacePolicy: projects.executionWorkspacePolicy })
|
|
883
|
+
.from(projects)
|
|
884
|
+
.where(and(eq(projects.id, executionProjectId), eq(projects.companyId, agent.companyId)))
|
|
885
|
+
.then((rows) => parseProjectExecutionWorkspacePolicy(rows[0]?.executionWorkspacePolicy))
|
|
886
|
+
: null;
|
|
845
887
|
const taskSession = taskKey
|
|
846
888
|
? await getTaskSession(agent.companyId, agent.id, agent.adapterType, taskKey)
|
|
847
889
|
: null;
|
|
@@ -849,15 +891,64 @@ export function heartbeatService(db) {
|
|
|
849
891
|
const sessionResetReason = describeSessionResetReason(context);
|
|
850
892
|
const taskSessionForRun = resetTaskSession ? null : taskSession;
|
|
851
893
|
const previousSessionParams = normalizeSessionParams(sessionCodec.deserialize(taskSessionForRun?.sessionParamsJson ?? null));
|
|
852
|
-
const
|
|
894
|
+
const config = parseObject(agent.adapterConfig);
|
|
895
|
+
const executionWorkspaceMode = resolveExecutionWorkspaceMode({
|
|
896
|
+
projectPolicy: projectExecutionWorkspacePolicy,
|
|
897
|
+
issueSettings: issueExecutionWorkspaceSettings,
|
|
898
|
+
legacyUseProjectWorkspace: issueAssigneeOverrides?.useProjectWorkspace ?? null,
|
|
899
|
+
});
|
|
900
|
+
const resolvedWorkspace = await resolveWorkspaceForRun(agent, context, previousSessionParams, { useProjectWorkspace: executionWorkspaceMode !== "agent_default" });
|
|
901
|
+
const workspaceManagedConfig = buildExecutionWorkspaceAdapterConfig({
|
|
902
|
+
agentConfig: config,
|
|
903
|
+
projectPolicy: projectExecutionWorkspacePolicy,
|
|
904
|
+
issueSettings: issueExecutionWorkspaceSettings,
|
|
905
|
+
mode: executionWorkspaceMode,
|
|
906
|
+
legacyUseProjectWorkspace: issueAssigneeOverrides?.useProjectWorkspace ?? null,
|
|
907
|
+
});
|
|
908
|
+
const mergedConfig = issueAssigneeOverrides?.adapterConfig
|
|
909
|
+
? { ...workspaceManagedConfig, ...issueAssigneeOverrides.adapterConfig }
|
|
910
|
+
: workspaceManagedConfig;
|
|
911
|
+
const { config: resolvedConfig, secretKeys } = await secretsSvc.resolveAdapterConfigForRuntime(agent.companyId, mergedConfig);
|
|
912
|
+
const issueRef = issueId
|
|
913
|
+
? await db
|
|
914
|
+
.select({
|
|
915
|
+
id: issues.id,
|
|
916
|
+
identifier: issues.identifier,
|
|
917
|
+
title: issues.title,
|
|
918
|
+
})
|
|
919
|
+
.from(issues)
|
|
920
|
+
.where(and(eq(issues.id, issueId), eq(issues.companyId, agent.companyId)))
|
|
921
|
+
.then((rows) => rows[0] ?? null)
|
|
922
|
+
: null;
|
|
923
|
+
const executionWorkspace = await realizeExecutionWorkspace({
|
|
924
|
+
base: {
|
|
925
|
+
baseCwd: resolvedWorkspace.cwd,
|
|
926
|
+
source: resolvedWorkspace.source,
|
|
927
|
+
projectId: resolvedWorkspace.projectId,
|
|
928
|
+
workspaceId: resolvedWorkspace.workspaceId,
|
|
929
|
+
repoUrl: resolvedWorkspace.repoUrl,
|
|
930
|
+
repoRef: resolvedWorkspace.repoRef,
|
|
931
|
+
},
|
|
932
|
+
config: resolvedConfig,
|
|
933
|
+
issue: issueRef,
|
|
934
|
+
agent: {
|
|
935
|
+
id: agent.id,
|
|
936
|
+
name: agent.name,
|
|
937
|
+
companyId: agent.companyId,
|
|
938
|
+
},
|
|
939
|
+
});
|
|
853
940
|
const runtimeSessionResolution = resolveRuntimeSessionParamsForWorkspace({
|
|
854
941
|
agentId: agent.id,
|
|
855
942
|
previousSessionParams,
|
|
856
|
-
resolvedWorkspace
|
|
943
|
+
resolvedWorkspace: {
|
|
944
|
+
...resolvedWorkspace,
|
|
945
|
+
cwd: executionWorkspace.cwd,
|
|
946
|
+
},
|
|
857
947
|
});
|
|
858
948
|
const runtimeSessionParams = runtimeSessionResolution.sessionParams;
|
|
859
949
|
const runtimeWorkspaceWarnings = [
|
|
860
950
|
...resolvedWorkspace.warnings,
|
|
951
|
+
...executionWorkspace.warnings,
|
|
861
952
|
...(runtimeSessionResolution.warning ? [runtimeSessionResolution.warning] : []),
|
|
862
953
|
...(resetTaskSession && sessionResetReason
|
|
863
954
|
? [
|
|
@@ -868,16 +959,32 @@ export function heartbeatService(db) {
|
|
|
868
959
|
: []),
|
|
869
960
|
];
|
|
870
961
|
context.paperclipWorkspace = {
|
|
871
|
-
cwd:
|
|
872
|
-
source:
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
962
|
+
cwd: executionWorkspace.cwd,
|
|
963
|
+
source: executionWorkspace.source,
|
|
964
|
+
mode: executionWorkspaceMode,
|
|
965
|
+
strategy: executionWorkspace.strategy,
|
|
966
|
+
projectId: executionWorkspace.projectId,
|
|
967
|
+
workspaceId: executionWorkspace.workspaceId,
|
|
968
|
+
repoUrl: executionWorkspace.repoUrl,
|
|
969
|
+
repoRef: executionWorkspace.repoRef,
|
|
970
|
+
branchName: executionWorkspace.branchName,
|
|
971
|
+
worktreePath: executionWorkspace.worktreePath,
|
|
877
972
|
};
|
|
878
973
|
context.paperclipWorkspaces = resolvedWorkspace.workspaceHints;
|
|
879
|
-
|
|
880
|
-
|
|
974
|
+
const runtimeServiceIntents = (() => {
|
|
975
|
+
const runtimeConfig = parseObject(resolvedConfig.workspaceRuntime);
|
|
976
|
+
return Array.isArray(runtimeConfig.services)
|
|
977
|
+
? runtimeConfig.services.filter((value) => typeof value === "object" && value !== null)
|
|
978
|
+
: [];
|
|
979
|
+
})();
|
|
980
|
+
if (runtimeServiceIntents.length > 0) {
|
|
981
|
+
context.paperclipRuntimeServiceIntents = runtimeServiceIntents;
|
|
982
|
+
}
|
|
983
|
+
else {
|
|
984
|
+
delete context.paperclipRuntimeServiceIntents;
|
|
985
|
+
}
|
|
986
|
+
if (executionWorkspace.projectId && !readNonEmptyString(context.projectId)) {
|
|
987
|
+
context.projectId = executionWorkspace.projectId;
|
|
881
988
|
}
|
|
882
989
|
const runtimeSessionFallback = taskKey || resetTaskSession ? null : runtime.sessionId;
|
|
883
990
|
const previousSessionDisplayId = truncateDisplayId(taskSessionForRun?.sessionDisplayId ??
|
|
@@ -901,6 +1008,7 @@ export function heartbeatService(db) {
|
|
|
901
1008
|
.set({
|
|
902
1009
|
startedAt,
|
|
903
1010
|
sessionIdBefore: runtimeForAdapter.sessionDisplayId ?? runtimeForAdapter.sessionId,
|
|
1011
|
+
contextSnapshot: context,
|
|
904
1012
|
updatedAt: new Date(),
|
|
905
1013
|
})
|
|
906
1014
|
.where(eq(heartbeatRuns.id, run.id))
|
|
@@ -946,40 +1054,76 @@ export function heartbeatService(db) {
|
|
|
946
1054
|
})
|
|
947
1055
|
.where(eq(heartbeatRuns.id, runId));
|
|
948
1056
|
const onLog = async (stream, chunk) => {
|
|
1057
|
+
const sanitizedChunk = redactCurrentUserText(chunk);
|
|
949
1058
|
if (stream === "stdout")
|
|
950
|
-
stdoutExcerpt = appendExcerpt(stdoutExcerpt,
|
|
1059
|
+
stdoutExcerpt = appendExcerpt(stdoutExcerpt, sanitizedChunk);
|
|
951
1060
|
if (stream === "stderr")
|
|
952
|
-
stderrExcerpt = appendExcerpt(stderrExcerpt,
|
|
1061
|
+
stderrExcerpt = appendExcerpt(stderrExcerpt, sanitizedChunk);
|
|
1062
|
+
const ts = new Date().toISOString();
|
|
953
1063
|
if (handle) {
|
|
954
1064
|
await runLogStore.append(handle, {
|
|
955
1065
|
stream,
|
|
956
|
-
chunk,
|
|
957
|
-
ts
|
|
1066
|
+
chunk: sanitizedChunk,
|
|
1067
|
+
ts,
|
|
958
1068
|
});
|
|
959
1069
|
}
|
|
960
|
-
const payloadChunk =
|
|
961
|
-
?
|
|
962
|
-
:
|
|
1070
|
+
const payloadChunk = sanitizedChunk.length > MAX_LIVE_LOG_CHUNK_BYTES
|
|
1071
|
+
? sanitizedChunk.slice(sanitizedChunk.length - MAX_LIVE_LOG_CHUNK_BYTES)
|
|
1072
|
+
: sanitizedChunk;
|
|
963
1073
|
publishLiveEvent({
|
|
964
1074
|
companyId: run.companyId,
|
|
965
1075
|
type: "heartbeat.run.log",
|
|
966
1076
|
payload: {
|
|
967
1077
|
runId: run.id,
|
|
968
1078
|
agentId: run.agentId,
|
|
1079
|
+
ts,
|
|
969
1080
|
stream,
|
|
970
1081
|
chunk: payloadChunk,
|
|
971
|
-
truncated: payloadChunk.length !==
|
|
1082
|
+
truncated: payloadChunk.length !== sanitizedChunk.length,
|
|
972
1083
|
},
|
|
973
1084
|
});
|
|
974
1085
|
};
|
|
975
1086
|
for (const warning of runtimeWorkspaceWarnings) {
|
|
976
1087
|
await onLog("stderr", `[paperclip] ${warning}\n`);
|
|
977
1088
|
}
|
|
978
|
-
const
|
|
979
|
-
const
|
|
980
|
-
|
|
981
|
-
:
|
|
982
|
-
|
|
1089
|
+
const adapterEnv = Object.fromEntries(Object.entries(parseObject(resolvedConfig.env)).filter((entry) => typeof entry[0] === "string" && typeof entry[1] === "string"));
|
|
1090
|
+
const runtimeServices = await ensureRuntimeServicesForRun({
|
|
1091
|
+
db,
|
|
1092
|
+
runId: run.id,
|
|
1093
|
+
agent: {
|
|
1094
|
+
id: agent.id,
|
|
1095
|
+
name: agent.name,
|
|
1096
|
+
companyId: agent.companyId,
|
|
1097
|
+
},
|
|
1098
|
+
issue: issueRef,
|
|
1099
|
+
workspace: executionWorkspace,
|
|
1100
|
+
config: resolvedConfig,
|
|
1101
|
+
adapterEnv,
|
|
1102
|
+
onLog,
|
|
1103
|
+
});
|
|
1104
|
+
if (runtimeServices.length > 0) {
|
|
1105
|
+
context.paperclipRuntimeServices = runtimeServices;
|
|
1106
|
+
context.paperclipRuntimePrimaryUrl =
|
|
1107
|
+
runtimeServices.find((service) => readNonEmptyString(service.url))?.url ?? null;
|
|
1108
|
+
await db
|
|
1109
|
+
.update(heartbeatRuns)
|
|
1110
|
+
.set({
|
|
1111
|
+
contextSnapshot: context,
|
|
1112
|
+
updatedAt: new Date(),
|
|
1113
|
+
})
|
|
1114
|
+
.where(eq(heartbeatRuns.id, run.id));
|
|
1115
|
+
}
|
|
1116
|
+
if (issueId && (executionWorkspace.created || runtimeServices.some((service) => !service.reused))) {
|
|
1117
|
+
try {
|
|
1118
|
+
await issuesSvc.addComment(issueId, buildWorkspaceReadyComment({
|
|
1119
|
+
workspace: executionWorkspace,
|
|
1120
|
+
runtimeServices,
|
|
1121
|
+
}), { agentId: agent.id });
|
|
1122
|
+
}
|
|
1123
|
+
catch (err) {
|
|
1124
|
+
await onLog("stderr", `[paperclip] Failed to post workspace-ready comment: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
983
1127
|
const onAdapterMeta = async (meta) => {
|
|
984
1128
|
if (meta.env && secretKeys.size > 0) {
|
|
985
1129
|
for (const key of secretKeys) {
|
|
@@ -1017,6 +1161,48 @@ export function heartbeatService(db) {
|
|
|
1017
1161
|
onMeta: onAdapterMeta,
|
|
1018
1162
|
authToken: authToken ?? undefined,
|
|
1019
1163
|
});
|
|
1164
|
+
const adapterManagedRuntimeServices = adapterResult.runtimeServices
|
|
1165
|
+
? await persistAdapterManagedRuntimeServices({
|
|
1166
|
+
db,
|
|
1167
|
+
adapterType: agent.adapterType,
|
|
1168
|
+
runId: run.id,
|
|
1169
|
+
agent: {
|
|
1170
|
+
id: agent.id,
|
|
1171
|
+
name: agent.name,
|
|
1172
|
+
companyId: agent.companyId,
|
|
1173
|
+
},
|
|
1174
|
+
issue: issueRef,
|
|
1175
|
+
workspace: executionWorkspace,
|
|
1176
|
+
reports: adapterResult.runtimeServices,
|
|
1177
|
+
})
|
|
1178
|
+
: [];
|
|
1179
|
+
if (adapterManagedRuntimeServices.length > 0) {
|
|
1180
|
+
const combinedRuntimeServices = [
|
|
1181
|
+
...runtimeServices,
|
|
1182
|
+
...adapterManagedRuntimeServices,
|
|
1183
|
+
];
|
|
1184
|
+
context.paperclipRuntimeServices = combinedRuntimeServices;
|
|
1185
|
+
context.paperclipRuntimePrimaryUrl =
|
|
1186
|
+
combinedRuntimeServices.find((service) => readNonEmptyString(service.url))?.url ?? null;
|
|
1187
|
+
await db
|
|
1188
|
+
.update(heartbeatRuns)
|
|
1189
|
+
.set({
|
|
1190
|
+
contextSnapshot: context,
|
|
1191
|
+
updatedAt: new Date(),
|
|
1192
|
+
})
|
|
1193
|
+
.where(eq(heartbeatRuns.id, run.id));
|
|
1194
|
+
if (issueId) {
|
|
1195
|
+
try {
|
|
1196
|
+
await issuesSvc.addComment(issueId, buildWorkspaceReadyComment({
|
|
1197
|
+
workspace: executionWorkspace,
|
|
1198
|
+
runtimeServices: adapterManagedRuntimeServices,
|
|
1199
|
+
}), { agentId: agent.id });
|
|
1200
|
+
}
|
|
1201
|
+
catch (err) {
|
|
1202
|
+
await onLog("stderr", `[paperclip] Failed to post adapter-managed runtime comment: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
1203
|
+
}
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1020
1206
|
const nextSessionState = resolveNextSessionState({
|
|
1021
1207
|
codec: sessionCodec,
|
|
1022
1208
|
adapterResult,
|
|
@@ -1060,7 +1246,7 @@ export function heartbeatService(db) {
|
|
|
1060
1246
|
finishedAt: new Date(),
|
|
1061
1247
|
error: outcome === "succeeded"
|
|
1062
1248
|
? null
|
|
1063
|
-
: adapterResult.errorMessage ?? (outcome === "timed_out" ? "Timed out" : "Adapter failed"),
|
|
1249
|
+
: redactCurrentUserText(adapterResult.errorMessage ?? (outcome === "timed_out" ? "Timed out" : "Adapter failed")),
|
|
1064
1250
|
errorCode: outcome === "timed_out"
|
|
1065
1251
|
? "timeout"
|
|
1066
1252
|
: outcome === "cancelled"
|
|
@@ -1125,7 +1311,7 @@ export function heartbeatService(db) {
|
|
|
1125
1311
|
await finalizeAgentStatus(agent.id, outcome);
|
|
1126
1312
|
}
|
|
1127
1313
|
catch (err) {
|
|
1128
|
-
const message = err instanceof Error ? err.message : "Unknown adapter failure";
|
|
1314
|
+
const message = redactCurrentUserText(err instanceof Error ? err.message : "Unknown adapter failure");
|
|
1129
1315
|
logger.error({ err, runId }, "heartbeat execution failed");
|
|
1130
1316
|
let logSummary = null;
|
|
1131
1317
|
if (handle) {
|
|
@@ -1182,6 +1368,7 @@ export function heartbeatService(db) {
|
|
|
1182
1368
|
await finalizeAgentStatus(agent.id, "failed");
|
|
1183
1369
|
}
|
|
1184
1370
|
finally {
|
|
1371
|
+
await releaseRuntimeServicesForRun(run.id);
|
|
1185
1372
|
await startNextQueuedRunForAgent(agent.id);
|
|
1186
1373
|
}
|
|
1187
1374
|
}
|
|
@@ -1678,18 +1865,19 @@ export function heartbeatService(db) {
|
|
|
1678
1865
|
return newRun;
|
|
1679
1866
|
}
|
|
1680
1867
|
return {
|
|
1681
|
-
list: (companyId, agentId, limit) => {
|
|
1868
|
+
list: async (companyId, agentId, limit) => {
|
|
1682
1869
|
const query = db
|
|
1683
|
-
.select()
|
|
1870
|
+
.select(heartbeatRunListColumns)
|
|
1684
1871
|
.from(heartbeatRuns)
|
|
1685
1872
|
.where(agentId
|
|
1686
1873
|
? and(eq(heartbeatRuns.companyId, companyId), eq(heartbeatRuns.agentId, agentId))
|
|
1687
1874
|
: eq(heartbeatRuns.companyId, companyId))
|
|
1688
1875
|
.orderBy(desc(heartbeatRuns.createdAt));
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1876
|
+
const rows = limit ? await query.limit(limit) : await query;
|
|
1877
|
+
return rows.map((row) => ({
|
|
1878
|
+
...row,
|
|
1879
|
+
resultJson: summarizeHeartbeatRunResultJson(row.resultJson),
|
|
1880
|
+
}));
|
|
1693
1881
|
},
|
|
1694
1882
|
getRun,
|
|
1695
1883
|
getRuntimeState: async (agentId) => {
|
|
@@ -1772,6 +1960,7 @@ export function heartbeatService(db) {
|
|
|
1772
1960
|
store: run.logStore,
|
|
1773
1961
|
logRef: run.logRef,
|
|
1774
1962
|
...result,
|
|
1963
|
+
content: redactCurrentUserText(result.content),
|
|
1775
1964
|
};
|
|
1776
1965
|
},
|
|
1777
1966
|
invoke: async (agentId, source = "on_demand", contextSnapshot = {}, triggerDetail = "manual", actor) => enqueueWakeup(agentId, {
|