@wardby/cli 0.3.0 → 0.4.1
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/.env.example +22 -3
- package/README.md +11 -9
- package/dist/cli-help.d.ts +1 -1
- package/dist/cli-help.js +1 -0
- package/dist/cli.js +68 -10
- package/dist/coding/base-commit.d.ts +6 -0
- package/dist/coding/base-commit.js +12 -0
- package/dist/coding/protocol.d.ts +17 -1
- package/dist/coding/protocol.js +17 -6
- package/dist/coding/provider.d.ts +6 -1
- package/dist/coding/provider.js +16 -9
- package/dist/config/providers.d.ts +25 -0
- package/dist/config/providers.js +71 -0
- package/dist/core/attribution.d.ts +101 -0
- package/dist/core/attribution.js +208 -0
- package/dist/core/budget-groups.d.ts +17 -10
- package/dist/core/budget-groups.js +15 -12
- package/dist/core/coding-queue.d.ts +3 -0
- package/dist/core/coding-queue.js +6 -2
- package/dist/core/coding-service-status.d.ts +11 -0
- package/dist/core/coding-service-status.js +17 -0
- package/dist/core/cost-report.d.ts +88 -0
- package/dist/core/cost-report.js +248 -0
- package/dist/core/dispatch.d.ts +42 -2
- package/dist/core/dispatch.js +144 -26
- package/dist/core/engine-native.js +17 -4
- package/dist/core/glob.d.ts +10 -0
- package/dist/core/glob.js +33 -0
- package/dist/core/host-events.d.ts +24 -1
- package/dist/core/host-events.js +341 -1
- package/dist/core/host-status.d.ts +19 -2
- package/dist/core/host-status.js +47 -30
- package/dist/core/issue-bridge.d.ts +60 -0
- package/dist/core/issue-bridge.js +189 -0
- package/dist/core/issue-dedupe.d.ts +70 -0
- package/dist/core/issue-dedupe.js +255 -0
- package/dist/core/issue-events.d.ts +42 -0
- package/dist/core/issue-events.js +155 -0
- package/dist/core/issue-status.d.ts +29 -0
- package/dist/core/issue-status.js +241 -0
- package/dist/core/issue-tracker-tools.d.ts +64 -0
- package/dist/core/issue-tracker-tools.js +850 -0
- package/dist/core/model-usage.d.ts +10 -0
- package/dist/core/model-usage.js +24 -0
- package/dist/core/reconciler.d.ts +8 -4
- package/dist/core/reconciler.js +15 -4
- package/dist/core/review-host-tools.js +10 -3
- package/dist/core/run-pricing.d.ts +61 -0
- package/dist/core/run-pricing.js +56 -0
- package/dist/core/runner.d.ts +5 -2
- package/dist/core/runner.js +178 -27
- package/dist/core/scheduler.d.ts +4 -1
- package/dist/core/scheduler.js +3 -2
- package/dist/core/self-defects.d.ts +80 -0
- package/dist/core/self-defects.js +180 -0
- package/dist/core/tool-names.js +3 -0
- package/dist/core/webhooks.d.ts +9 -1
- package/dist/core/webhooks.js +19 -1
- package/dist/env.js +6 -1
- package/dist/generated/prisma/browser.d.ts +66 -0
- package/dist/generated/prisma/client.d.ts +66 -0
- package/dist/generated/prisma/commonInputTypes.d.ts +122 -52
- package/dist/generated/prisma/enums.d.ts +7 -0
- package/dist/generated/prisma/enums.js +6 -0
- package/dist/generated/prisma/internal/class.d.ts +99 -0
- package/dist/generated/prisma/internal/class.js +4 -4
- package/dist/generated/prisma/internal/prismaNamespace.d.ts +826 -1
- package/dist/generated/prisma/internal/prismaNamespace.js +135 -2
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.d.ts +142 -0
- package/dist/generated/prisma/internal/prismaNamespaceBrowser.js +135 -2
- package/dist/generated/prisma/models/Agent.d.ts +389 -1
- package/dist/generated/prisma/models/AgentIssueProject.d.ts +1838 -0
- package/dist/generated/prisma/models/AgentIssueProject.js +1 -0
- package/dist/generated/prisma/models/AgentRepository.d.ts +1 -1
- package/dist/generated/prisma/models/AuthUser.d.ts +1 -1
- package/dist/generated/prisma/models/CodingProxySession.d.ts +73 -1
- package/dist/generated/prisma/models/CodingRun.d.ts +130 -1
- package/dist/generated/prisma/models/CodingRunServiceStatus.d.ts +1404 -0
- package/dist/generated/prisma/models/CodingRunServiceStatus.js +1 -0
- package/dist/generated/prisma/models/IssueFingerprint.d.ts +1183 -0
- package/dist/generated/prisma/models/IssueFingerprint.js +1 -0
- package/dist/generated/prisma/models/IssuePullRequest.d.ts +1255 -0
- package/dist/generated/prisma/models/IssuePullRequest.js +1 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.d.ts +1322 -0
- package/dist/generated/prisma/models/ModelCatalogEntry.js +1 -0
- package/dist/generated/prisma/models/Run.d.ts +933 -1
- package/dist/generated/prisma/models/RunAttribution.d.ts +1259 -0
- package/dist/generated/prisma/models/RunAttribution.js +1 -0
- package/dist/generated/prisma/models/RunIssueStatus.d.ts +1199 -0
- package/dist/generated/prisma/models/RunIssueStatus.js +1 -0
- package/dist/generated/prisma/models/RunModelUsage.d.ts +1316 -0
- package/dist/generated/prisma/models/RunModelUsage.js +1 -0
- package/dist/generated/prisma/models/WorkItem.d.ts +1408 -0
- package/dist/generated/prisma/models/WorkItem.js +1 -0
- package/dist/generated/prisma/models.d.ts +9 -0
- package/dist/help-index.json +355 -16
- package/dist/import/neutral-schema.d.ts +16 -16
- package/dist/knowledge/check.d.ts +13 -0
- package/dist/knowledge/check.js +69 -0
- package/dist/knowledge/cli.d.ts +14 -0
- package/dist/knowledge/cli.js +67 -0
- package/dist/knowledge/concept.d.ts +54 -0
- package/dist/knowledge/concept.js +78 -0
- package/dist/knowledge/note.d.ts +11 -0
- package/dist/knowledge/note.js +39 -0
- package/dist/knowledge/relevance.d.ts +11 -0
- package/dist/knowledge/relevance.js +14 -0
- package/dist/knowledge/span-hash.d.ts +3 -0
- package/dist/knowledge/span-hash.js +16 -0
- package/dist/mcp/auth/access.d.ts +4 -2
- package/dist/mcp/auth/ownership.d.ts +9 -9
- package/dist/mcp/auth/resource-server.d.ts +3 -1
- package/dist/mcp/auth/resource-server.js +18 -3
- package/dist/mcp/auth/self-hosted/credentials.d.ts +3 -3
- package/dist/mcp/auth/self-hosted/session.d.ts +5 -5
- package/dist/mcp/context.d.ts +3 -0
- package/dist/mcp/host-events/deliveries.d.ts +9 -0
- package/dist/mcp/host-events/deliveries.js +17 -0
- package/dist/mcp/host-events/github-ingress.d.ts +4 -2
- package/dist/mcp/host-events/github-ingress.js +4 -13
- package/dist/mcp/host-events/jira-ingress.d.ts +29 -0
- package/dist/mcp/host-events/jira-ingress.js +92 -0
- package/dist/mcp/index.d.ts +2 -0
- package/dist/mcp/index.js +87 -9
- package/dist/mcp/server.js +5 -2
- package/dist/mcp/tools/agents.js +74 -3
- package/dist/mcp/tools/cost-report.d.ts +8 -0
- package/dist/mcp/tools/cost-report.js +60 -0
- package/dist/mcp/tools/issue-projects.d.ts +2 -0
- package/dist/mcp/tools/issue-projects.js +238 -0
- package/dist/mcp/tools/model-catalog.d.ts +22 -0
- package/dist/mcp/tools/model-catalog.js +423 -0
- package/dist/mcp/tools/repositories.js +2 -1
- package/dist/mcp/tools/tools.d.ts +2 -2
- package/dist/mcp/tools/trigger.js +33 -5
- package/dist/mcp/transport/streamable-http.d.ts +5 -0
- package/dist/mcp/transport/streamable-http.js +23 -1
- package/dist/mcp/webhooks/ingress.d.ts +2 -1
- package/dist/mcp/webhooks/ingress.js +9 -2
- package/dist/providers/auth/self-hosted.d.ts +8 -1
- package/dist/providers/auth/self-hosted.js +39 -2
- package/dist/providers/coding-proxy/memory-ledger.d.ts +1 -1
- package/dist/providers/coding-proxy/memory-ledger.js +10 -1
- package/dist/providers/coding-proxy/metering.d.ts +2 -1
- package/dist/providers/coding-proxy/metering.js +13 -2
- package/dist/providers/coding-proxy/prisma-ledger.js +59 -6
- package/dist/providers/coding-proxy/proxy.d.ts +12 -2
- package/dist/providers/coding-proxy/proxy.js +92 -30
- package/dist/providers/coding-proxy/types.d.ts +18 -1
- package/dist/providers/coding-proxy/types.js +12 -1
- package/dist/providers/engine/types.d.ts +19 -0
- package/dist/providers/executor/composition.js +9 -1
- package/dist/providers/executor/container.d.ts +30 -2
- package/dist/providers/executor/container.js +98 -17
- package/dist/providers/executor/dbos.d.ts +2 -0
- package/dist/providers/executor/dbos.js +7 -5
- package/dist/providers/executor/routing.d.ts +6 -0
- package/dist/providers/executor/routing.js +5 -0
- package/dist/providers/executor/types.d.ts +12 -0
- package/dist/providers/issue-tracker/adf.d.ts +31 -0
- package/dist/providers/issue-tracker/adf.js +181 -0
- package/dist/providers/issue-tracker/index.d.ts +5 -0
- package/dist/providers/issue-tracker/index.js +12 -0
- package/dist/providers/issue-tracker/jira-client.d.ts +41 -0
- package/dist/providers/issue-tracker/jira-client.js +151 -0
- package/dist/providers/issue-tracker/jira-events.d.ts +3 -0
- package/dist/providers/issue-tracker/jira-events.js +98 -0
- package/dist/providers/issue-tracker/jira.d.ts +116 -0
- package/dist/providers/issue-tracker/jira.js +502 -0
- package/dist/providers/issue-tracker/types.d.ts +269 -0
- package/dist/providers/issue-tracker/types.js +16 -0
- package/dist/providers/jobs/docker.d.ts +5 -1
- package/dist/providers/jobs/docker.js +61 -33
- package/dist/providers/jobs/kubernetes.d.ts +3 -0
- package/dist/providers/jobs/kubernetes.js +44 -4
- package/dist/providers/jobs/service-state.d.ts +22 -0
- package/dist/providers/jobs/service-state.js +17 -0
- package/dist/providers/llm/anthropic.d.ts +3 -3
- package/dist/providers/llm/anthropic.js +3 -9
- package/dist/providers/llm/bedrock.d.ts +3 -3
- package/dist/providers/llm/bedrock.js +3 -9
- package/dist/providers/llm/catalog-lookup.d.ts +10 -0
- package/dist/providers/llm/catalog-lookup.js +15 -0
- package/dist/providers/llm/catalog-shipped.d.ts +18 -0
- package/dist/providers/llm/catalog-shipped.js +197 -0
- package/dist/providers/llm/catalog-store.d.ts +58 -0
- package/dist/providers/llm/catalog-store.js +138 -0
- package/dist/providers/llm/catalog-types.d.ts +66 -0
- package/dist/providers/llm/catalog-types.js +64 -0
- package/dist/providers/llm/catalog.d.ts +61 -0
- package/dist/providers/llm/catalog.js +147 -0
- package/dist/providers/llm/claude-provider.d.ts +10 -14
- package/dist/providers/llm/claude-provider.js +11 -6
- package/dist/providers/llm/index.d.ts +9 -6
- package/dist/providers/llm/index.js +8 -5
- package/dist/providers/llm/openai.d.ts +14 -5
- package/dist/providers/llm/openai.js +24 -14
- package/dist/providers/llm/pricing-core.d.ts +5 -3
- package/dist/providers/llm/registration.js +8 -12
- package/dist/providers/llm/routing.d.ts +18 -17
- package/dist/providers/llm/routing.js +40 -24
- package/dist/providers/review-host/github-events.js +47 -1
- package/dist/providers/review-host/github.js +7 -6
- package/dist/providers/review-host/types.d.ts +25 -0
- package/dist/providers/vcs/git.js +2 -22
- package/dist/providers/vcs/github.d.ts +20 -0
- package/dist/providers/vcs/github.js +28 -2
- package/dist/providers/vcs/types.d.ts +6 -0
- package/dist/quickstart/index.d.ts +8 -0
- package/dist/quickstart/index.js +34 -34
- package/dist/serve.js +8 -2
- package/dist/viewer/api-schema.d.ts +2757 -0
- package/dist/viewer/api-schema.js +165 -0
- package/dist/viewer/build-schemas.d.ts +2 -0
- package/dist/viewer/build-schemas.js +18 -0
- package/dist/viewer/event-bus.d.ts +38 -0
- package/dist/viewer/event-bus.js +232 -0
- package/dist/viewer/graph.d.ts +40 -0
- package/dist/viewer/graph.js +243 -0
- package/dist/viewer/http.d.ts +30 -0
- package/dist/viewer/http.js +133 -0
- package/dist/viewer/run-detail.d.ts +4 -0
- package/dist/viewer/run-detail.js +61 -0
- package/dist/wardby-bin.js +5 -0
- package/docs/README.md +10 -0
- package/docs/agent-recipes.md +383 -0
- package/docs/code-review-agents.md +29 -2
- package/docs/coding-agent-setup.md +3 -0
- package/docs/coding-worker-isolation.md +39 -5
- package/docs/getting-started-gke.md +28 -11
- package/docs/getting-started-identity-provider.md +49 -38
- package/docs/getting-started.md +14 -0
- package/docs/jira-agents.md +649 -0
- package/docs/knowledge.md +387 -0
- package/docs/models.md +221 -0
- package/docs/security-deployment.md +19 -9
- package/docs/viewer-api.md +142 -0
- package/help/admin-viewer.md +39 -0
- package/help/agent-recipes.md +173 -0
- package/help/architecture-agent.md +189 -0
- package/help/builder-agent.md +80 -0
- package/help/code-review-agents.md +6 -0
- package/help/cost-attribution.md +67 -0
- package/help/creating-agents.md +22 -0
- package/help/deploy-gke.md +6 -0
- package/help/errors/model-unavailable.md +63 -0
- package/help/getting-started.md +1 -0
- package/help/github.md +18 -0
- package/help/identity-and-access.md +8 -3
- package/help/jira.md +135 -0
- package/help/knowledge.md +47 -0
- package/help/models.md +90 -0
- package/help/operating-agents.md +7 -1
- package/help/troubleshooting/budgets.md +6 -0
- package/package.json +5 -2
- package/prisma/migrations/20260930000000_jira_issue_projects/migration.sql +34 -0
- package/prisma/migrations/20261001000000_jira_phase2_allowlists/migration.sql +3 -0
- package/prisma/migrations/20261001010000_jira_link_types_allowlist/migration.sql +2 -0
- package/prisma/migrations/20261002000000_jira_coding_bridge/migration.sql +28 -0
- package/prisma/migrations/20261002010000_jira_issue_creation/migration.sql +25 -0
- package/prisma/migrations/20261003000000_issue_cost_attribution/migration.sql +56 -0
- package/prisma/migrations/20261003010000_coding_run_service_status/migration.sql +23 -0
- package/prisma/migrations/20261003020000_viewer_notify/migration.sql +54 -0
- package/prisma/migrations/20261003030000_viewer_notify_fixes/migration.sql +47 -0
- package/prisma/migrations/20261003040000_viewer_indexes/migration.sql +12 -0
- package/prisma/migrations/20261004000000_model_catalog/migration.sql +26 -0
- package/prisma/schema.prisma +258 -2
- package/dist/mcp/tools/models.d.ts +0 -8
- package/dist/mcp/tools/models.js +0 -15
- package/dist/providers/llm/pricing-anthropic.d.ts +0 -14
- package/dist/providers/llm/pricing-anthropic.js +0 -48
- package/dist/providers/llm/pricing-bedrock-claude.d.ts +0 -20
- package/dist/providers/llm/pricing-bedrock-claude.js +0 -46
- package/dist/providers/llm/pricing.d.ts +0 -30
- package/dist/providers/llm/pricing.js +0 -74
package/dist/core/scheduler.d.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
import type { Agent } from "#prisma";
|
|
10
10
|
import type { Executor } from "../providers/executor/types.js";
|
|
11
11
|
import { type DispatchDb } from "./dispatch.js";
|
|
12
|
+
import type { SelfDefectSink } from "./self-defects.js";
|
|
12
13
|
export type SchedulerDb = DispatchDb;
|
|
13
14
|
/**
|
|
14
15
|
* Per spec: "Executor throws synchronously on start → the run is marked
|
|
@@ -25,7 +26,7 @@ export declare function findDueCandidates(db: Pick<SchedulerDb, "agent">, now: D
|
|
|
25
26
|
* Returns the new run's id, or null if the agent wasn't (or is no longer)
|
|
26
27
|
* due, or another tick already holds its row lock.
|
|
27
28
|
*/
|
|
28
|
-
export declare function claimDueRun(db: SchedulerDb, executor: Executor, agentId: string, now: Date): Promise<string | null>;
|
|
29
|
+
export declare function claimDueRun(db: SchedulerDb, executor: Executor, agentId: string, now: Date, selfDefects?: SelfDefectSink): Promise<string | null>;
|
|
29
30
|
export interface SchedulerOptions {
|
|
30
31
|
executor: Executor;
|
|
31
32
|
db?: SchedulerDb;
|
|
@@ -39,6 +40,8 @@ export interface SchedulerOptions {
|
|
|
39
40
|
* failing hook cannot stop scheduled agents from firing.
|
|
40
41
|
*/
|
|
41
42
|
onLeaderTick?: () => Promise<void>;
|
|
43
|
+
/** Files a self-defect when a scheduled run's executor fails to start it. Optional. */
|
|
44
|
+
selfDefects?: SelfDefectSink;
|
|
42
45
|
}
|
|
43
46
|
export interface SchedulerHandle {
|
|
44
47
|
stop(): void;
|
package/dist/core/scheduler.js
CHANGED
|
@@ -39,11 +39,12 @@ export async function findDueCandidates(db, now) {
|
|
|
39
39
|
* Returns the new run's id, or null if the agent wasn't (or is no longer)
|
|
40
40
|
* due, or another tick already holds its row lock.
|
|
41
41
|
*/
|
|
42
|
-
export async function claimDueRun(db, executor, agentId, now) {
|
|
42
|
+
export async function claimDueRun(db, executor, agentId, now, selfDefects) {
|
|
43
43
|
const dispatched = await dispatchRun({
|
|
44
44
|
db,
|
|
45
45
|
executor,
|
|
46
46
|
agentId,
|
|
47
|
+
selfDefects,
|
|
47
48
|
trigger: "scheduled",
|
|
48
49
|
now,
|
|
49
50
|
lockAgent: true,
|
|
@@ -88,7 +89,7 @@ export function startScheduler(options) {
|
|
|
88
89
|
const due = await findDueCandidates(db, now());
|
|
89
90
|
for (const agent of due) {
|
|
90
91
|
try {
|
|
91
|
-
const runId = await claimDueRun(db, options.executor, agent.id, now());
|
|
92
|
+
const runId = await claimDueRun(db, options.executor, agent.id, now(), options.selfDefects);
|
|
92
93
|
if (runId) {
|
|
93
94
|
log(`firing agent "${agent.name}" -> run ${runId}`);
|
|
94
95
|
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Self-defects: when a run of an opted-in agent (Agent.defectProjectKey +
|
|
3
|
+
* defectIssueType) ends failed, lost or budget_exhausted, the control plane
|
|
4
|
+
* (no model involved) files a defect for it through fileIssue, deduped by a
|
|
5
|
+
* structural fingerprint so a recurring failure becomes "seen again" comments
|
|
6
|
+
* on one issue rather than a new issue per run.
|
|
7
|
+
*
|
|
8
|
+
* fingerprint self:<agentId>:<status>:<category>
|
|
9
|
+
* category CodingRun.failureCategory, else the leading `code:` token of
|
|
10
|
+
* Run.error, else "unknown" — only ever a closed-shape token
|
|
11
|
+
* (lower-case letters/underscore), never the error's free text
|
|
12
|
+
*
|
|
13
|
+
* Fails closed: the agent needs a live write link to defectProjectKey whose
|
|
14
|
+
* creatableIssueTypes includes defectIssueType; otherwise it logs and skips.
|
|
15
|
+
* Self-defects are not counted against the link's maxNewIssuesPerRun: that cap
|
|
16
|
+
* bounds what a run's model may create, while this is a control-plane action
|
|
17
|
+
* whose volume the fingerprint dedupe already bounds (one open issue per
|
|
18
|
+
* agent/status/category).
|
|
19
|
+
*
|
|
20
|
+
* Filed by whichever write made the run's row terminal (its update count says so, so a run files once): the
|
|
21
|
+
* runner, the container store, the reconciler, the coding queue's timeout, a failed executor start
|
|
22
|
+
* (markRunFailedFromExecutorError) and DBOS recovery's mark-failed.
|
|
23
|
+
*
|
|
24
|
+
* Best effort and never throws. No recursion: this is only ever called after a
|
|
25
|
+
* run's row is final, outside any run, and a failure to file only logs — it
|
|
26
|
+
* never fails a run, so it can never trigger another filing.
|
|
27
|
+
*/
|
|
28
|
+
import type { PrismaClient } from "#prisma";
|
|
29
|
+
import { type IssueTrackerRegistry } from "../providers/issue-tracker/types.js";
|
|
30
|
+
import { type FileIssueInput, type FileIssueResult } from "./issue-dedupe.js";
|
|
31
|
+
/** Run statuses that file a defect; succeeded, cancelled and refused never do. */
|
|
32
|
+
export declare const SELF_DEFECT_STATUSES: ReadonlySet<string>;
|
|
33
|
+
/** How long a caller waits for the filing; past this it carries on in the background (and still only logs). */
|
|
34
|
+
export declare const SELF_DEFECT_WAIT_MS = 15000;
|
|
35
|
+
export type SelfDefectDb = Pick<PrismaClient, "agent" | "agentIssueProject" | "codingRun" | "$transaction">;
|
|
36
|
+
/** The finished run, as its final row has it. */
|
|
37
|
+
export interface SelfDefectRun {
|
|
38
|
+
id: string;
|
|
39
|
+
agentId: string;
|
|
40
|
+
status: string;
|
|
41
|
+
error: string | null;
|
|
42
|
+
finishedAt: Date | null;
|
|
43
|
+
}
|
|
44
|
+
export interface SelfDefectOptions {
|
|
45
|
+
/** Injected for tests; defaults to issue-dedupe's fileIssue on `db`. */
|
|
46
|
+
fileIssue?: (input: FileIssueInput) => Promise<FileIssueResult>;
|
|
47
|
+
waitMs?: number;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Where a write that ends a run files its self-defect: the database to read the run and file through, and the
|
|
51
|
+
* configured issue trackers. Absent, or with no tracker configured, the write files nothing and makes no extra query.
|
|
52
|
+
*/
|
|
53
|
+
export interface SelfDefectSink {
|
|
54
|
+
db: SelfDefectDb & Pick<PrismaClient, "run">;
|
|
55
|
+
issueTrackers?: IssueTrackerRegistry;
|
|
56
|
+
/** Injected for tests; the wait defaults to SELF_DEFECT_SHORT_WAIT_MS. */
|
|
57
|
+
options?: SelfDefectOptions;
|
|
58
|
+
}
|
|
59
|
+
/** The bound for callers on a dispatch, queue or executor path: past it the filing carries on detached. */
|
|
60
|
+
export declare const SELF_DEFECT_SHORT_WAIT_MS = 2000;
|
|
61
|
+
/** True when at least one issue tracker is configured (no Jira site configured yields an empty registry). */
|
|
62
|
+
export declare function hasIssueTrackers(trackers: IssueTrackerRegistry | undefined): trackers is IssueTrackerRegistry;
|
|
63
|
+
/**
|
|
64
|
+
* The leading `code:` token of a run error (lower-cased) when it is a safe category (CATEGORY_PATTERN), else
|
|
65
|
+
* "unknown". Never any of the free text after it.
|
|
66
|
+
*/
|
|
67
|
+
export declare function errorClass(error: string | null | undefined): string;
|
|
68
|
+
export declare function selfDefectFingerprint(agentId: string, status: string, category: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Files (or re-sights) the defect for a finished run. Resolves to the filing's
|
|
71
|
+
* result, or null when nothing was filed (not a filing status, not opted in,
|
|
72
|
+
* no live link, an error, or still in flight after `waitMs`). Never throws.
|
|
73
|
+
*/
|
|
74
|
+
export declare function fileSelfDefect(db: SelfDefectDb, trackers: IssueTrackerRegistry | undefined, run: SelfDefectRun, opts?: SelfDefectOptions): Promise<FileIssueResult | null>;
|
|
75
|
+
/**
|
|
76
|
+
* For a write that just made `runId` terminal (its update count said so, so this files once): reads the final row
|
|
77
|
+
* and files its self-defect, waiting at most SELF_DEFECT_SHORT_WAIT_MS. No-op, with no query, without a configured
|
|
78
|
+
* tracker. Never throws.
|
|
79
|
+
*/
|
|
80
|
+
export declare function fileSelfDefectForRun(sink: SelfDefectSink | undefined, runId: string): Promise<FileIssueResult | null>;
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import { agentFooter } from "../providers/issue-tracker/jira.js";
|
|
2
|
+
import { ISSUE_TRACKER_PROVIDERS, } from "../providers/issue-tracker/types.js";
|
|
3
|
+
import { fileIssue } from "./issue-dedupe.js";
|
|
4
|
+
import { propertyKey } from "./issue-tracker-tools.js";
|
|
5
|
+
import { logger } from "./logger.js";
|
|
6
|
+
const log = logger.child({ module: "self-defects" });
|
|
7
|
+
/** Run statuses that file a defect; succeeded, cancelled and refused never do. */
|
|
8
|
+
export const SELF_DEFECT_STATUSES = new Set(["failed", "lost", "budget_exhausted"]);
|
|
9
|
+
/** How long a caller waits for the filing; past this it carries on in the background (and still only logs). */
|
|
10
|
+
export const SELF_DEFECT_WAIT_MS = 15_000;
|
|
11
|
+
const SUMMARY_MAX_LENGTH = 255;
|
|
12
|
+
/**
|
|
13
|
+
* What a category may look like to be published in the issue and fingerprint: lower-case letters and underscores,
|
|
14
|
+
* at most 32. No digits, dots or dashes, so secret-shaped (ghp_…, sk-ant-…), host-shaped (db.internal.corp) and
|
|
15
|
+
* id-shaped (run-8f3a…) prefixes never reach Jira and fingerprints stay a small closed set.
|
|
16
|
+
*/
|
|
17
|
+
const CATEGORY_PATTERN = /^[a-z][a-z_]{0,31}$/;
|
|
18
|
+
/** The bound for callers on a dispatch, queue or executor path: past it the filing carries on detached. */
|
|
19
|
+
export const SELF_DEFECT_SHORT_WAIT_MS = 2_000;
|
|
20
|
+
/** True when at least one issue tracker is configured (no Jira site configured yields an empty registry). */
|
|
21
|
+
export function hasIssueTrackers(trackers) {
|
|
22
|
+
return !!trackers && Object.values(trackers).some(Boolean);
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* The leading `code:` token of a run error (lower-cased) when it is a safe category (CATEGORY_PATTERN), else
|
|
26
|
+
* "unknown". Never any of the free text after it.
|
|
27
|
+
*/
|
|
28
|
+
export function errorClass(error) {
|
|
29
|
+
const match = /^([^:\s]{1,64}):/.exec(error ?? "");
|
|
30
|
+
return safeCategory(match?.[1]) ?? "unknown";
|
|
31
|
+
}
|
|
32
|
+
export function selfDefectFingerprint(agentId, status, category) {
|
|
33
|
+
return `self:${agentId}:${status}:${category}`;
|
|
34
|
+
}
|
|
35
|
+
function safeCategory(value) {
|
|
36
|
+
const lowered = value?.trim().toLowerCase();
|
|
37
|
+
return lowered && CATEGORY_PATTERN.test(lowered) ? lowered : null;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Files (or re-sights) the defect for a finished run. Resolves to the filing's
|
|
41
|
+
* result, or null when nothing was filed (not a filing status, not opted in,
|
|
42
|
+
* no live link, an error, or still in flight after `waitMs`). Never throws.
|
|
43
|
+
*/
|
|
44
|
+
export async function fileSelfDefect(db, trackers, run, opts = {}) {
|
|
45
|
+
if (!SELF_DEFECT_STATUSES.has(run.status) || !trackers)
|
|
46
|
+
return null;
|
|
47
|
+
const filing = attempt(db, trackers, run, opts).catch((err) => {
|
|
48
|
+
log.warn({ err, runId: run.id, agentId: run.agentId }, "could not file the run's self-defect");
|
|
49
|
+
return null;
|
|
50
|
+
});
|
|
51
|
+
const waitMs = opts.waitMs ?? SELF_DEFECT_WAIT_MS;
|
|
52
|
+
let timer;
|
|
53
|
+
const timedOut = new Promise((resolve) => {
|
|
54
|
+
timer = setTimeout(() => {
|
|
55
|
+
log.warn({ runId: run.id, waitMs }, "self-defect filing still in progress; no longer waiting for it");
|
|
56
|
+
resolve(null);
|
|
57
|
+
}, waitMs);
|
|
58
|
+
timer.unref?.();
|
|
59
|
+
});
|
|
60
|
+
try {
|
|
61
|
+
return await Promise.race([filing, timedOut]);
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
clearTimeout(timer);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* For a write that just made `runId` terminal (its update count said so, so this files once): reads the final row
|
|
69
|
+
* and files its self-defect, waiting at most SELF_DEFECT_SHORT_WAIT_MS. No-op, with no query, without a configured
|
|
70
|
+
* tracker. Never throws.
|
|
71
|
+
*/
|
|
72
|
+
export async function fileSelfDefectForRun(sink, runId) {
|
|
73
|
+
if (!sink || !hasIssueTrackers(sink.issueTrackers))
|
|
74
|
+
return null;
|
|
75
|
+
let row;
|
|
76
|
+
try {
|
|
77
|
+
row = await sink.db.run.findUnique({
|
|
78
|
+
where: { id: runId },
|
|
79
|
+
select: { id: true, agentId: true, status: true, error: true, finishedAt: true },
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
catch (err) {
|
|
83
|
+
log.warn({ err, runId }, "could not read the run to file its self-defect");
|
|
84
|
+
return null;
|
|
85
|
+
}
|
|
86
|
+
if (!row)
|
|
87
|
+
return null;
|
|
88
|
+
return fileSelfDefect(sink.db, sink.issueTrackers, row, {
|
|
89
|
+
waitMs: SELF_DEFECT_SHORT_WAIT_MS,
|
|
90
|
+
...sink.options,
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async function attempt(db, trackers, run, opts) {
|
|
94
|
+
const configured = ISSUE_TRACKER_PROVIDERS.filter((p) => trackers[p]);
|
|
95
|
+
if (configured.length === 0)
|
|
96
|
+
return null;
|
|
97
|
+
const agent = await db.agent.findUnique({
|
|
98
|
+
where: { id: run.agentId },
|
|
99
|
+
select: { id: true, name: true, defectProjectKey: true, defectIssueType: true },
|
|
100
|
+
});
|
|
101
|
+
if (!agent?.defectProjectKey || !agent.defectIssueType)
|
|
102
|
+
return null;
|
|
103
|
+
const projectKey = agent.defectProjectKey;
|
|
104
|
+
const issueType = agent.defectIssueType;
|
|
105
|
+
let tracker;
|
|
106
|
+
let link;
|
|
107
|
+
for (const provider of configured) {
|
|
108
|
+
// Live, read now: an unlink, downgrade or allowlist change since the run started applies here.
|
|
109
|
+
const row = await db.agentIssueProject.findUnique({
|
|
110
|
+
where: { agentId_provider_projectKey: { agentId: agent.id, provider, projectKey } },
|
|
111
|
+
select: {
|
|
112
|
+
provider: true,
|
|
113
|
+
projectKey: true,
|
|
114
|
+
access: true,
|
|
115
|
+
commentVisibilityRole: true,
|
|
116
|
+
creatableIssueTypes: true,
|
|
117
|
+
},
|
|
118
|
+
});
|
|
119
|
+
if (!row)
|
|
120
|
+
continue;
|
|
121
|
+
const typeAllowed = row.creatableIssueTypes.some((t) => t.trim().toLowerCase() === issueType.trim().toLowerCase());
|
|
122
|
+
if (row.access !== "write" || !typeAllowed) {
|
|
123
|
+
log.warn({ runId: run.id, agentId: agent.id, projectKey, access: row.access, typeAllowed }, "self-defects skipped: the agent's link to the defect project is not writable or does not allow the issue type");
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
tracker = trackers[provider];
|
|
127
|
+
link = row;
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
if (!tracker || !link) {
|
|
131
|
+
log.warn({ runId: run.id, agentId: agent.id, projectKey }, "self-defects skipped: no link to the defect project");
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
let codingCategory = null;
|
|
135
|
+
try {
|
|
136
|
+
const coding = await db.codingRun.findUnique({ where: { runId: run.id }, select: { failureCategory: true } });
|
|
137
|
+
codingCategory = safeCategory(coding?.failureCategory);
|
|
138
|
+
}
|
|
139
|
+
catch (err) {
|
|
140
|
+
log.debug({ err, runId: run.id }, "no coding failure category for the self-defect");
|
|
141
|
+
}
|
|
142
|
+
const category = codingCategory ?? errorClass(run.error);
|
|
143
|
+
const finished = (run.finishedAt ?? new Date()).toISOString();
|
|
144
|
+
const summary = `wardby agent "${agent.name}": ${run.status}${category === "unknown" ? "" : ` (${category})`}`;
|
|
145
|
+
const description = [
|
|
146
|
+
`A run of wardby agent "${agent.name}" ended ${run.status}.`,
|
|
147
|
+
"",
|
|
148
|
+
`- Run: ${run.id}`,
|
|
149
|
+
`- Agent: ${agent.id}`,
|
|
150
|
+
`- Status: ${run.status}`,
|
|
151
|
+
`- Failure category: ${category}`,
|
|
152
|
+
`- Finished: ${finished}`,
|
|
153
|
+
"",
|
|
154
|
+
"Filed by wardby itself. The run's error text is not included; see the run in wardby for details.",
|
|
155
|
+
].join("\n");
|
|
156
|
+
const file = opts.fileIssue ?? ((input) => fileIssue({ db }, input));
|
|
157
|
+
// Not subject to maxNewIssuesPerRun (control plane; dedupe bounds volume), so createAllowed stays at its default.
|
|
158
|
+
const result = await file({
|
|
159
|
+
agentId: agent.id,
|
|
160
|
+
runId: run.id,
|
|
161
|
+
link,
|
|
162
|
+
tracker,
|
|
163
|
+
fingerprint: selfDefectFingerprint(agent.id, run.status, category),
|
|
164
|
+
create: {
|
|
165
|
+
issueType,
|
|
166
|
+
summary: summary.length > SUMMARY_MAX_LENGTH ? `${summary.slice(0, SUMMARY_MAX_LENGTH - 1)}…` : summary,
|
|
167
|
+
descriptionMarkdown: description,
|
|
168
|
+
properties: { [propertyKey(agent.id, "self-defect")]: { runId: run.id } },
|
|
169
|
+
},
|
|
170
|
+
footerMarkdown: agentFooter(agent.id),
|
|
171
|
+
seenAgainMarkdown: `Run ${run.id} ended ${run.status} at ${finished}.\n\n${agentFooter(agent.id)}`,
|
|
172
|
+
});
|
|
173
|
+
if ("error" in result) {
|
|
174
|
+
log.warn({ runId: run.id, agentId: agent.id, error: result.error }, "self-defect filing failed");
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
log.info({ runId: run.id, agentId: agent.id, outcome: result.outcome, issueKey: result.issueKey }, "self-defect filed");
|
|
178
|
+
}
|
|
179
|
+
return result;
|
|
180
|
+
}
|
package/dist/core/tool-names.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { MEMORY_TOOL_NAMES } from "./memory-tools.js";
|
|
2
2
|
import { SUBAGENT_MEMORY_TOOL_NAMES } from "./subagent-memory-tools.js";
|
|
3
|
+
import { ISSUE_TRACKER_TOOL_NAMES } from "./issue-tracker-tools.js";
|
|
3
4
|
/** The runner's synthesized sub-agent tools are `delegate_to_<boundName>`. */
|
|
4
5
|
export const DELEGATE_TOOL_PREFIX = "delegate_to_";
|
|
5
6
|
/**
|
|
@@ -13,6 +14,8 @@ export function reservedToolNameReason(name) {
|
|
|
13
14
|
if (SUBAGENT_MEMORY_TOOL_NAMES.has(name)) {
|
|
14
15
|
return `Tool name "${name}" is reserved for the built-in sub-agent memory tools.`;
|
|
15
16
|
}
|
|
17
|
+
if (ISSUE_TRACKER_TOOL_NAMES.has(name))
|
|
18
|
+
return `Tool name "${name}" is reserved for the built-in Jira tools.`;
|
|
16
19
|
if (name.startsWith(DELEGATE_TOOL_PREFIX)) {
|
|
17
20
|
return `Tool names starting with "${DELEGATE_TOOL_PREFIX}" are reserved for sub-agent delegation tools.`;
|
|
18
21
|
}
|
package/dist/core/webhooks.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { PrismaClient, Webhook } from "#prisma";
|
|
2
2
|
import type { Executor } from "../providers/executor/types.js";
|
|
3
|
+
import type { IssueTrackerRegistry } from "../providers/issue-tracker/types.js";
|
|
3
4
|
export type WebhookMetadata = Pick<Webhook, "id" | "agentId" | "status" | "ownerId" | "createdAt" | "lastFiredAt">;
|
|
4
5
|
/** Creates a webhook and returns the raw secret ONCE — only its hash is ever stored. */
|
|
5
6
|
export declare function createWebhook(agentId: string, ownerId: string, db: PrismaClient): Promise<{
|
|
@@ -21,10 +22,17 @@ export type ResolveWebhookRunResult = {
|
|
|
21
22
|
} | {
|
|
22
23
|
ok: false;
|
|
23
24
|
reason: "not_found" | "invalid_secret" | "disabled";
|
|
25
|
+
} | {
|
|
26
|
+
ok: false;
|
|
27
|
+
reason: "invalid_issue";
|
|
28
|
+
message: string;
|
|
24
29
|
};
|
|
25
30
|
/**
|
|
26
31
|
* Validates the presented secret and, if valid + enabled, enqueues a run via
|
|
27
32
|
* the exact same `createRun` path `trigger_agent`/the scheduler use — the
|
|
28
33
|
* budget guardrail applies identically regardless of what triggered the run.
|
|
29
34
|
*/
|
|
30
|
-
export declare function resolveWebhookRun(id: string, presentedSecret: string, db: PrismaClient, executor: Executor, codingTask?: string
|
|
35
|
+
export declare function resolveWebhookRun(id: string, presentedSecret: string, db: PrismaClient, executor: Executor, codingTask?: string, opts?: {
|
|
36
|
+
issue?: unknown;
|
|
37
|
+
issueTrackers?: IssueTrackerRegistry;
|
|
38
|
+
}): Promise<ResolveWebhookRunResult>;
|
package/dist/core/webhooks.js
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* is always 32 bytes, so there's no length-mismatch case to special-case).
|
|
10
10
|
*/
|
|
11
11
|
import { createHash, randomBytes, timingSafeEqual } from "node:crypto";
|
|
12
|
+
import { AttributionError, explicitAttribution, RESPONSE_PATH_SNAPSHOT_BUDGET, } from "./attribution.js";
|
|
12
13
|
import { dispatchRun } from "./dispatch.js";
|
|
13
14
|
import { atLeast, effectiveAccess } from "./grants.js";
|
|
14
15
|
function hashSecret(secret) {
|
|
@@ -66,7 +67,7 @@ export async function deleteWebhook(id, db) {
|
|
|
66
67
|
* the exact same `createRun` path `trigger_agent`/the scheduler use — the
|
|
67
68
|
* budget guardrail applies identically regardless of what triggered the run.
|
|
68
69
|
*/
|
|
69
|
-
export async function resolveWebhookRun(id, presentedSecret, db, executor, codingTask) {
|
|
70
|
+
export async function resolveWebhookRun(id, presentedSecret, db, executor, codingTask, opts = {}) {
|
|
70
71
|
const webhook = await db.webhook.findUnique({ where: { id } });
|
|
71
72
|
if (!webhook)
|
|
72
73
|
return { ok: false, reason: "not_found" };
|
|
@@ -80,12 +81,29 @@ export async function resolveWebhookRun(id, presentedSecret, db, executor, codin
|
|
|
80
81
|
if (codingTask !== undefined && !taskAllowed(agent.kind, agent.codingProfile)) {
|
|
81
82
|
return { ok: false, reason: "disabled" };
|
|
82
83
|
}
|
|
84
|
+
// An invalid or unlinked issue refuses the call before any run exists.
|
|
85
|
+
let attribution;
|
|
86
|
+
if (opts.issue !== undefined) {
|
|
87
|
+
try {
|
|
88
|
+
attribution = await explicitAttribution(db, opts.issueTrackers, agent.id, opts.issue, {
|
|
89
|
+
...RESPONSE_PATH_SNAPSHOT_BUDGET,
|
|
90
|
+
field: "wardbyIssue",
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
catch (err) {
|
|
94
|
+
if (err instanceof AttributionError)
|
|
95
|
+
return { ok: false, reason: "invalid_issue", message: err.message };
|
|
96
|
+
throw err;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
83
99
|
let rejected = "disabled";
|
|
84
100
|
const dispatched = await dispatchRun({
|
|
85
101
|
db,
|
|
86
102
|
executor,
|
|
103
|
+
selfDefects: { db, issueTrackers: opts.issueTrackers },
|
|
87
104
|
agentId: agent.id,
|
|
88
105
|
trigger: "webhook",
|
|
106
|
+
attribution,
|
|
89
107
|
// Coding agents keep the existing per-agent opt-in (allowWebhookTaskOverride);
|
|
90
108
|
// a native agent's system prompt has no per-run input at all otherwise, so
|
|
91
109
|
// accepting task text over an authenticated webhook call needs no separate
|
package/dist/env.js
CHANGED
|
@@ -17,4 +17,9 @@ const projectDir = resolve(process.env.WARDBY_PROJECT_DIR || process.cwd());
|
|
|
17
17
|
// process variable, preserving explicit shell/container configuration as the
|
|
18
18
|
// highest-priority source in either mode.
|
|
19
19
|
dotenvFlow.config({ path: join(projectDir, ".wardby"), silent: true });
|
|
20
|
-
|
|
20
|
+
// The application's own .env files are optional: dotenv-flow reports "no .env*
|
|
21
|
+
// files" as a failure, so only load when some exist. Not `silent: true`, which
|
|
22
|
+
// would also hide parse errors in a real .env.
|
|
23
|
+
if (dotenvFlow.listFiles({ path: projectDir, node_env: process.env.NODE_ENV }).length > 0) {
|
|
24
|
+
dotenvFlow.config({ path: projectDir });
|
|
25
|
+
}
|
|
@@ -122,6 +122,18 @@ export type CodingRun = Prisma.CodingRunModel;
|
|
|
122
122
|
* "external" is reserved.
|
|
123
123
|
*/
|
|
124
124
|
export type CodingService = Prisma.CodingServiceModel;
|
|
125
|
+
/**
|
|
126
|
+
* Model CodingRunServiceStatus
|
|
127
|
+
* Live start-up state of one coding-run service (one row per run x
|
|
128
|
+
* service), written by the job launcher as it observes the service, for
|
|
129
|
+
* display only (the viewer). The run's CodingRun.services
|
|
130
|
+
* snapshot says what was started; this says how far each one got.
|
|
131
|
+
* `attempts` is the readiness probes made so far, known only where wardby
|
|
132
|
+
* runs the probe itself (Docker); `reason` is a fixed identifier
|
|
133
|
+
* (image_unavailable, start_failed, exited, probe_failed, timed_out),
|
|
134
|
+
* never probe output.
|
|
135
|
+
*/
|
|
136
|
+
export type CodingRunServiceStatus = Prisma.CodingRunServiceStatusModel;
|
|
125
137
|
/**
|
|
126
138
|
* Model CodingProxySession
|
|
127
139
|
* Trusted-boundary state for one coding run. Only a capability digest and an
|
|
@@ -326,3 +338,57 @@ export type HostIdentity = Prisma.HostIdentityModel;
|
|
|
326
338
|
* Lives 10 minutes.
|
|
327
339
|
*/
|
|
328
340
|
export type HostIdentityLinkRequest = Prisma.HostIdentityLinkRequestModel;
|
|
341
|
+
/**
|
|
342
|
+
* Model AgentIssueProject
|
|
343
|
+
* Which issue-tracker projects (Jira today) a native agent may act on, and
|
|
344
|
+
* which issue events trigger it. Admin-approved in phase 1 (no way to verify
|
|
345
|
+
* an owner's Jira access). See
|
|
346
|
+
* docs/private/2026-09-30-jira-issue-tracker-design.md §3.
|
|
347
|
+
*/
|
|
348
|
+
export type AgentIssueProject = Prisma.AgentIssueProjectModel;
|
|
349
|
+
/**
|
|
350
|
+
* Model IssueFingerprint
|
|
351
|
+
* Dedupe record: an issue wardby created for a fingerprint (several over time — regressions).
|
|
352
|
+
*/
|
|
353
|
+
export type IssueFingerprint = Prisma.IssueFingerprintModel;
|
|
354
|
+
/**
|
|
355
|
+
* Model IssuePullRequest
|
|
356
|
+
* A pull request wardby opened for a tracker issue (the Jira -> code bridge). Provider-neutral on both sides.
|
|
357
|
+
* Deliberately no foreign keys to Agent or Run: audit-style rows that survive agent/run deletion.
|
|
358
|
+
*/
|
|
359
|
+
export type IssuePullRequest = Prisma.IssuePullRequestModel;
|
|
360
|
+
/**
|
|
361
|
+
* Model RunIssueStatus
|
|
362
|
+
* The status comment wardby posts on the Jira issue whose event started this
|
|
363
|
+
* run ("working on it"), edited with the outcome when the run ends.
|
|
364
|
+
*/
|
|
365
|
+
export type RunIssueStatus = Prisma.RunIssueStatusModel;
|
|
366
|
+
/**
|
|
367
|
+
* Model WorkItem
|
|
368
|
+
* Latest known state of an issue/epic in an external tracker (Jira, later
|
|
369
|
+
* Linear). Shared by every run attributed to it; titles are refreshed by the
|
|
370
|
+
* next snapshot, so reports always show current names.
|
|
371
|
+
*/
|
|
372
|
+
export type WorkItem = Prisma.WorkItemModel;
|
|
373
|
+
/**
|
|
374
|
+
* Model RunAttribution
|
|
375
|
+
* Which work item a run's cost belongs to, with its parent frozen as of
|
|
376
|
+
* dispatch. Written in dispatchRun's persist transaction; child runs copy
|
|
377
|
+
* their parent's row (source "inherited"). Control-plane data only.
|
|
378
|
+
*/
|
|
379
|
+
export type RunAttribution = Prisma.RunAttributionModel;
|
|
380
|
+
/**
|
|
381
|
+
* Model RunModelUsage
|
|
382
|
+
* Per-run, per-model usage by priced token kind. Sum of costUsd over a
|
|
383
|
+
* run's rows equals Run.costUsd (to Run.costUsd's 6 decimal places).
|
|
384
|
+
*/
|
|
385
|
+
export type RunModelUsage = Prisma.RunModelUsageModel;
|
|
386
|
+
/**
|
|
387
|
+
* Model ModelCatalogEntry
|
|
388
|
+
* A deployment's override of the shipped model catalog
|
|
389
|
+
* (src/providers/llm/catalog-shipped.ts), written by set_model /
|
|
390
|
+
* disable_model (models:admin). A row fully replaces the shipped entry with
|
|
391
|
+
* the same key; enabled=false removes the model; a row with no shipped match
|
|
392
|
+
* adds one. Rates are the provider's exact published numbers (sourceUrl).
|
|
393
|
+
*/
|
|
394
|
+
export type ModelCatalogEntry = Prisma.ModelCatalogEntryModel;
|
|
@@ -141,6 +141,18 @@ export type CodingRun = Prisma.CodingRunModel;
|
|
|
141
141
|
* "external" is reserved.
|
|
142
142
|
*/
|
|
143
143
|
export type CodingService = Prisma.CodingServiceModel;
|
|
144
|
+
/**
|
|
145
|
+
* Model CodingRunServiceStatus
|
|
146
|
+
* Live start-up state of one coding-run service (one row per run x
|
|
147
|
+
* service), written by the job launcher as it observes the service, for
|
|
148
|
+
* display only (the viewer). The run's CodingRun.services
|
|
149
|
+
* snapshot says what was started; this says how far each one got.
|
|
150
|
+
* `attempts` is the readiness probes made so far, known only where wardby
|
|
151
|
+
* runs the probe itself (Docker); `reason` is a fixed identifier
|
|
152
|
+
* (image_unavailable, start_failed, exited, probe_failed, timed_out),
|
|
153
|
+
* never probe output.
|
|
154
|
+
*/
|
|
155
|
+
export type CodingRunServiceStatus = Prisma.CodingRunServiceStatusModel;
|
|
144
156
|
/**
|
|
145
157
|
* Model CodingProxySession
|
|
146
158
|
* Trusted-boundary state for one coding run. Only a capability digest and an
|
|
@@ -345,3 +357,57 @@ export type HostIdentity = Prisma.HostIdentityModel;
|
|
|
345
357
|
* Lives 10 minutes.
|
|
346
358
|
*/
|
|
347
359
|
export type HostIdentityLinkRequest = Prisma.HostIdentityLinkRequestModel;
|
|
360
|
+
/**
|
|
361
|
+
* Model AgentIssueProject
|
|
362
|
+
* Which issue-tracker projects (Jira today) a native agent may act on, and
|
|
363
|
+
* which issue events trigger it. Admin-approved in phase 1 (no way to verify
|
|
364
|
+
* an owner's Jira access). See
|
|
365
|
+
* docs/private/2026-09-30-jira-issue-tracker-design.md §3.
|
|
366
|
+
*/
|
|
367
|
+
export type AgentIssueProject = Prisma.AgentIssueProjectModel;
|
|
368
|
+
/**
|
|
369
|
+
* Model IssueFingerprint
|
|
370
|
+
* Dedupe record: an issue wardby created for a fingerprint (several over time — regressions).
|
|
371
|
+
*/
|
|
372
|
+
export type IssueFingerprint = Prisma.IssueFingerprintModel;
|
|
373
|
+
/**
|
|
374
|
+
* Model IssuePullRequest
|
|
375
|
+
* A pull request wardby opened for a tracker issue (the Jira -> code bridge). Provider-neutral on both sides.
|
|
376
|
+
* Deliberately no foreign keys to Agent or Run: audit-style rows that survive agent/run deletion.
|
|
377
|
+
*/
|
|
378
|
+
export type IssuePullRequest = Prisma.IssuePullRequestModel;
|
|
379
|
+
/**
|
|
380
|
+
* Model RunIssueStatus
|
|
381
|
+
* The status comment wardby posts on the Jira issue whose event started this
|
|
382
|
+
* run ("working on it"), edited with the outcome when the run ends.
|
|
383
|
+
*/
|
|
384
|
+
export type RunIssueStatus = Prisma.RunIssueStatusModel;
|
|
385
|
+
/**
|
|
386
|
+
* Model WorkItem
|
|
387
|
+
* Latest known state of an issue/epic in an external tracker (Jira, later
|
|
388
|
+
* Linear). Shared by every run attributed to it; titles are refreshed by the
|
|
389
|
+
* next snapshot, so reports always show current names.
|
|
390
|
+
*/
|
|
391
|
+
export type WorkItem = Prisma.WorkItemModel;
|
|
392
|
+
/**
|
|
393
|
+
* Model RunAttribution
|
|
394
|
+
* Which work item a run's cost belongs to, with its parent frozen as of
|
|
395
|
+
* dispatch. Written in dispatchRun's persist transaction; child runs copy
|
|
396
|
+
* their parent's row (source "inherited"). Control-plane data only.
|
|
397
|
+
*/
|
|
398
|
+
export type RunAttribution = Prisma.RunAttributionModel;
|
|
399
|
+
/**
|
|
400
|
+
* Model RunModelUsage
|
|
401
|
+
* Per-run, per-model usage by priced token kind. Sum of costUsd over a
|
|
402
|
+
* run's rows equals Run.costUsd (to Run.costUsd's 6 decimal places).
|
|
403
|
+
*/
|
|
404
|
+
export type RunModelUsage = Prisma.RunModelUsageModel;
|
|
405
|
+
/**
|
|
406
|
+
* Model ModelCatalogEntry
|
|
407
|
+
* A deployment's override of the shipped model catalog
|
|
408
|
+
* (src/providers/llm/catalog-shipped.ts), written by set_model /
|
|
409
|
+
* disable_model (models:admin). A row fully replaces the shipped entry with
|
|
410
|
+
* the same key; enabled=false removes the model; a row with no shipped match
|
|
411
|
+
* adds one. Rates are the provider's exact published numbers (sourceUrl).
|
|
412
|
+
*/
|
|
413
|
+
export type ModelCatalogEntry = Prisma.ModelCatalogEntryModel;
|