mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-06 23:20:53 +01:00
Reconcile Claude protocol with merged runtime prerequisite
Co-Authored-By: Paperclip <noreply@paperclip.ing> * commit 'd67e3507b23041212fa26302ce6de078c5ebcc05': feat(runner): qualify Codex platform packages and cache hosted builds (#16028) fix(ui): default human task replies to the latest assigning agent (#15594) refactor(server): move provider setup, inventory and delivery into channel folders (#16058) fix(apps): show user avatars and center access rows (#15577) fix(issues): preserve human handoffs from the active agent run (#16082) # Conflicts: # doc/plans/2026-10-06-default-agent-runner.md # maps/agent-access-map/runs-adapters.md # maps/feature-map/runs-adapters.md # packages/paperclip-runner/README.md # server/src/__tests__/dev-runner-native-binary.test.ts
This commit is contained in:
commit
abcd8261d2
58 files changed
+4036
-2462
No files matched your search
@@ -1286,7 +1286,7 @@ export class PaperclipRunnerToolAuthority {
|
||||
agentId: this.binding.agentId, runId: this.binding.runId, issueId: child.id,
|
||||
action: "issue.created", entityType: "issue", entityId: child.id,
|
||||
details: { identifier: child.identifier, title: child.title, parentId: child.parentId,
|
||||
assigneeAgentId: child.assigneeAgentId, status: childStatus, source: "paperclip_runner_protocol" },
|
||||
assigneeAgentId: child.assigneeAgentId, assigneeUserId: child.assigneeUserId, status: childStatus, source: "paperclip_runner_protocol" },
|
||||
});
|
||||
publication = activity.publication;
|
||||
}
|
||||
@@ -1486,7 +1486,8 @@ export class PaperclipRunnerToolAuthority {
|
||||
agentId: this.binding.agentId, runId: this.binding.runId, issueId: taskId,
|
||||
action: "issue.reassigned", entityType: "issue", entityId: taskId,
|
||||
details: { source: "paperclip_runner_protocol", reassignmentKey: durableKey, inputFingerprint: fingerprint,
|
||||
previousAssigneeAgentId: target.assigneeAgentId, assigneeAgentId, reason, changed, receipt },
|
||||
previousAssigneeAgentId: target.assigneeAgentId, previousAssigneeUserId: target.assigneeUserId,
|
||||
assigneeAgentId, assigneeUserId, reason, changed, receipt },
|
||||
});
|
||||
publication = activity.publication;
|
||||
return receipt;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { randomUUID } from "node:crypto";
|
||||
import { afterAll, beforeAll, describe, expect, it, vi } from "vitest";
|
||||
import { eq, and } from "drizzle-orm";
|
||||
import { activityLog, agents, companies, createDb, heartbeatRuns, issues, issueComments } from "@paperclipai/db";
|
||||
import { activityLog, agents, authUsers, companyMemberships, companies, createDb, heartbeatRuns, issues, issueComments } from "@paperclipai/db";
|
||||
import { startEmbeddedPostgresTestDatabase } from "../../__tests__/helpers/embedded-postgres.js";
|
||||
import { issueService } from "../issues.js";
|
||||
import { PaperclipRunnerToolAuthority } from "./paperclip-runner-tool-authority.js";
|
||||
@@ -49,6 +49,24 @@ describe("runner task reassignment", () => {
|
||||
expect(await db.select().from(issueComments).where(eq(issueComments.issueId, f.targetId))).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("records human assignment fields for native creation and reassignment", async () => {
|
||||
const f = await fixture();
|
||||
const person = randomUUID();
|
||||
await db.insert(authUsers).values({ id: person, name: "Reviewer", email: `${person}@example.test`, createdAt: new Date(), updatedAt: new Date() });
|
||||
await db.insert(companyMemberships).values({ companyId: f.companyId, principalType: "user", principalId: person, status: "active", membershipRole: "operator" });
|
||||
await f.authority.execute({ ...f.call, arguments: { ...f.call.arguments, assigneeActorId: null, assigneeUserId: person } });
|
||||
const [reassigned] = await db.select().from(activityLog).where(and(eq(activityLog.entityId, f.targetId), eq(activityLog.action, "issue.reassigned")));
|
||||
expect(reassigned).toMatchObject({ actorType: "agent", actorId: f.agentId, details: {
|
||||
previousAssigneeAgentId: f.agentId, previousAssigneeUserId: null,
|
||||
assigneeAgentId: null, assigneeUserId: person, changed: true,
|
||||
} });
|
||||
const created = await f.authority.execute({ tool: "create_task", callId: "human-child", arguments: {
|
||||
title: "Review result", assigneeUserId: person, idempotencyKey: "human-child",
|
||||
} }) as { task: { id: string } };
|
||||
const [creation] = await db.select().from(activityLog).where(and(eq(activityLog.entityId, created.task.id), eq(activityLog.action, "issue.created")));
|
||||
expect(creation).toMatchObject({ actorType: "agent", actorId: f.agentId, details: { assigneeAgentId: null, assigneeUserId: person } });
|
||||
});
|
||||
|
||||
it.each(["blocked", "backlog"])("preserves %s and does not wake work prematurely", async status => {
|
||||
const f = await fixture(status);
|
||||
await f.authority.execute(f.call);
|
||||
|
||||
Reference in new issue
Block a user