@usepipr/sdk 0.4.3 → 0.6.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/index.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { $ as AutoResolveUserRepliesOptions, A as Task, At as reviewResultSchema, B as AgentExtension, Bt as SchemaParseResult, C as PriorReview, Ct as ReviewFinding, D as ReviewRecipeOptions, Dt as parseReviewResult, E as ReviewEntrypoints, Et as parseReviewFinding, F as ToolRunOptions, Ft as JsonSchema, G as JsonPromptOptions, H as AgentTool, I as defaultReviewActions, It as JsonSchemaDefinition, J as PromptText, K as Markdown, L as defaultReviewEntrypoints, Lt as JsonValue, M as TaskContext, Mt as reviewSummarySchema, N as TaskDefinition, Nt as JsonObject, O as Reviewer, Ot as parseReviewSummary, P as TaskHandler, Pt as JsonPrimitive, Q as AutoResolveOptions, R as Agent, Rt as Schema, S as PriorInlineFinding, St as RuntimeLimits, T as ReviewCommentContext, Tt as ReviewSummary, U as BuiltinSchemaCatalog, V as AgentPromptContext, Vt as ZodSchema, W as BuiltinToolCatalog, X as AggregateCheckOptions, Y as PromptValue, Z as AutoResolveAllowedActors, _ as PiRunner, _t as DiffManifestOptions, a as md, at as PiprConfigOptions, b as PlatformInfo, bt as RangeKind, c as ChangeRequestContext, ct as SecretOptions, d as CheckHandle, et as ChangeRequestAction, f as CommandContext, ft as CommentableRange, g as DefaultReviewInput, gt as DiffManifestLimits, h as CommentValue, ht as DiffManifestFile, i as schemas, it as ModelProfile, j as TaskCheckOptions, jt as reviewSchemaExample, k as ReviewerOptions, kt as reviewFindingSchema, l as ChangeRequestInfo, lt as SecretRef, m as CommandRegistrationOptions, mt as DiffManifest, n as jsonSchema, nt as DurationInput, o as definePipr, ot as PublicationOptions, p as CommandOptions, pt as DiffHunk, q as PromptSource, r as schema, rt as ModelOptions, s as definePlugin, st as RepositoryPermission, t as z, tt as ChecksOptions, u as ChangeRequestRegistrationOptions, v as PiprBuilder, vt as FileStatus, w as RepositoryInfo, wt as ReviewResult, x as PluginToolDefinition, xt as ReviewSide, y as PiprPlugin, yt as PathFilter, z as AgentDefinition, zt as SchemaDefinition } from "./index-D_XmBHeL.mjs";
2
- export { type Agent, type AgentDefinition, type AgentExtension, type AgentPromptContext, type AgentTool, type AggregateCheckOptions, type AutoResolveAllowedActors, type AutoResolveOptions, type AutoResolveUserRepliesOptions, type BuiltinSchemaCatalog, type BuiltinToolCatalog, type ChangeRequestAction, type ChangeRequestContext, type ChangeRequestInfo, type ChangeRequestRegistrationOptions, type CheckHandle, type ChecksOptions, type CommandContext, type CommandOptions, type CommandRegistrationOptions, type CommentValue, type CommentableRange, type DefaultReviewInput, type DiffHunk, type DiffManifest, type DiffManifestFile, type DiffManifestLimits, type DiffManifestOptions, type DurationInput, type FileStatus, type JsonObject, type JsonPrimitive, type JsonPromptOptions, type JsonSchema, type JsonSchemaDefinition, type JsonValue, type Markdown, type ModelOptions, type ModelProfile, type PathFilter, type PiRunner, type PiprBuilder, type PiprConfigOptions, type PiprPlugin, type PlatformInfo, type PluginToolDefinition, type PriorInlineFinding, type PriorReview, type PromptSource, type PromptText, type PromptValue, type PublicationOptions, type RangeKind, type RepositoryInfo, type RepositoryPermission, type ReviewCommentContext, type ReviewEntrypoints, type ReviewFinding, type ReviewRecipeOptions, type ReviewResult, type ReviewSide, type ReviewSummary, type Reviewer, type ReviewerOptions, type RuntimeLimits, type Schema, type SchemaDefinition, type SchemaParseResult, type SecretOptions, type SecretRef, type Task, type TaskCheckOptions, type TaskContext, type TaskDefinition, type TaskHandler, type ToolRunOptions, type ZodSchema, defaultReviewActions, defaultReviewEntrypoints, definePipr, definePlugin, jsonSchema, md, parseReviewFinding, parseReviewResult, parseReviewSummary, reviewFindingSchema, reviewResultSchema, reviewSchemaExample, reviewSummarySchema, schema, schemas, z };
1
+ import { $ as AutoResolveOptions, $t as SchemaParseResult, A as ReviewRecipeOptions, At as PiprRunTrigger, B as AgentDefinition, Bt as parseReviewSummary, C as PluginToolDefinition, Ct as PathFilter, D as ReviewCommentContext, Dt as PiprResult, E as RepositoryInfo, Et as RuntimeLimits, F as TaskHandler, Ft as ReviewResult, G as BuiltinToolCatalog, Gt as reviewSummarySchema, H as AgentPromptContext, Ht as reviewFindingsResultSchema, I as ToolRunOptions, It as ReviewSummary, J as PromptSource, Jt as JsonSchema, K as JsonPromptOptions, Kt as JsonObject, L as defaultReviewActions, Lt as parseReviewFinding, M as TaskCheckOptions, Mt as piprResultSchema, N as TaskContext, Nt as ReviewFinding, O as ReviewEntrypoints, Ot as PiprRunContext, P as TaskDefinition, Pt as ReviewFindingsResult, Q as AutoResolveAllowedActors, Qt as SchemaDefinition, R as defaultReviewEntrypoints, Rt as parseReviewFindingsResult, S as PlatformInfo, St as FileStatus, T as PriorReview, Tt as ReviewSide, U as AgentTool, Ut as reviewResultSchema, V as AgentExtension, Vt as reviewFindingSchema, W as BuiltinSchemaCatalog, Wt as reviewSchemaExample, X as PromptValue, Xt as JsonValue, Y as PromptText, Yt as JsonSchemaDefinition, Z as AggregateCheckOptions, Zt as Schema, _ as DefaultReviewSummaryInput, _t as DiffHunk, a as md, at as ModelProfile, b as PiprBuilder, bt as DiffManifestLimits, c as ChangeRequestContext, ct as PublicationOptions, d as CheckHandle, dt as SecretRef, en as ZodSchema, et as AutoResolveUserRepliesOptions, f as CommandContext, g as DefaultReviewInput, gt as CommentableRange, h as CommentValue, ht as ChangedFile, i as schemas, it as ModelOptions, j as Task, jt as parsePiprResult, k as ReviewInstructions, kt as PiprRunSummary, l as ChangeRequestInfo, lt as RepositoryPermission, m as CommandRegistrationOptions, mt as modelThinkingLevels, n as jsonSchema, nt as ChecksOptions, o as definePipr, ot as ModelThinkingLevel, p as CommandOptions, q as Markdown, qt as JsonPrimitive, r as schema, rt as DurationInput, s as definePlugin, st as PiprConfigOptions, t as z, tt as ChangeRequestAction, u as ChangeRequestRegistrationOptions, ut as SecretOptions, v as DefaultReviewSummaryManifest, vt as DiffManifest, w as PriorInlineFinding, wt as RangeKind, x as PiprPlugin, xt as DiffManifestOptions, y as PiRunner, yt as DiffManifestFile, z as Agent, zt as parseReviewResult } from "./index-Bdey1nho.mjs";
2
+ export { type Agent, type AgentDefinition, type AgentExtension, type AgentPromptContext, type AgentTool, type AggregateCheckOptions, type AutoResolveAllowedActors, type AutoResolveOptions, type AutoResolveUserRepliesOptions, type BuiltinSchemaCatalog, type BuiltinToolCatalog, type ChangeRequestAction, type ChangeRequestContext, type ChangeRequestInfo, type ChangeRequestRegistrationOptions, type ChangedFile, type CheckHandle, type ChecksOptions, type CommandContext, type CommandOptions, type CommandRegistrationOptions, type CommentValue, type CommentableRange, type DefaultReviewInput, type DefaultReviewSummaryInput, type DefaultReviewSummaryManifest, type DiffHunk, type DiffManifest, type DiffManifestFile, type DiffManifestLimits, type DiffManifestOptions, type DurationInput, type FileStatus, type JsonObject, type JsonPrimitive, type JsonPromptOptions, type JsonSchema, type JsonSchemaDefinition, type JsonValue, type Markdown, type ModelOptions, type ModelProfile, type ModelThinkingLevel, type PathFilter, type PiRunner, type PiprBuilder, type PiprConfigOptions, type PiprPlugin, type PiprResult, type PiprRunContext, type PiprRunSummary, type PiprRunTrigger, type PlatformInfo, type PluginToolDefinition, type PriorInlineFinding, type PriorReview, type PromptSource, type PromptText, type PromptValue, type PublicationOptions, type RangeKind, type RepositoryInfo, type RepositoryPermission, type ReviewCommentContext, type ReviewEntrypoints, type ReviewFinding, type ReviewFindingsResult, type ReviewInstructions, type ReviewRecipeOptions, type ReviewResult, type ReviewSide, type ReviewSummary, type RuntimeLimits, type Schema, type SchemaDefinition, type SchemaParseResult, type SecretOptions, type SecretRef, type Task, type TaskCheckOptions, type TaskContext, type TaskDefinition, type TaskHandler, type ToolRunOptions, type ZodSchema, defaultReviewActions, defaultReviewEntrypoints, definePipr, definePlugin, jsonSchema, md, modelThinkingLevels, parsePiprResult, parseReviewFinding, parseReviewFindingsResult, parseReviewResult, parseReviewSummary, piprResultSchema, reviewFindingSchema, reviewFindingsResultSchema, reviewResultSchema, reviewSchemaExample, reviewSummarySchema, schema, schemas, z };
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as configFactoryBrand, i as builtinReadOnlyToolBrand, o as assertSupportedCommandRestCapture, r as renderPromptValue } from "./config-Ct0Qfa_b.mjs";
1
+ import { a as serializePromptJson, i as renderPromptValue, o as configFactoryBrand, r as modelThinkingLevels, s as assertSupportedCommandRestCapture } from "./config-CpCLnuAf.mjs";
2
2
  import { z, z as z$1 } from "zod";
3
3
  //#region src/prompt.ts
4
4
  /** Creates trimmed Markdown from a template literal with common indentation removed. */
@@ -18,6 +18,110 @@ function stripCommonIndent(value) {
18
18
  return lines.map((line) => line.slice(indent)).join("\n");
19
19
  }
20
20
  //#endregion
21
+ //#region src/runtime-handles.ts
22
+ const taskRecords = /* @__PURE__ */ new WeakMap();
23
+ const agentRecords = /* @__PURE__ */ new WeakMap();
24
+ const toolRecords = /* @__PURE__ */ new WeakMap();
25
+ function createTaskHandle(definition) {
26
+ const handle = {
27
+ kind: "pipr.task",
28
+ name: definition.name
29
+ };
30
+ const record = {
31
+ name: definition.name,
32
+ check: definition.check,
33
+ ...definition.local === false ? { local: false } : {},
34
+ handler: definition.run
35
+ };
36
+ taskRecords.set(handle, record);
37
+ return {
38
+ handle,
39
+ record
40
+ };
41
+ }
42
+ function runtimeTaskForHandle(task) {
43
+ const record = taskRecords.get(task);
44
+ if (!record) throw new Error("Expected a task handle created by pipr.task");
45
+ return record;
46
+ }
47
+ function createAgentHandle(definition) {
48
+ const handle = {
49
+ kind: "pipr.agent",
50
+ name: definition.name,
51
+ extend(patch) {
52
+ return createAgentHandle({
53
+ ...definition,
54
+ ...patch,
55
+ instructions: patch.instructions === void 0 ? definition.instructions : {
56
+ kind: "pipr.prompt",
57
+ value: `${renderPromptValue(definition.instructions)}\n\n${renderPromptValue(patch.instructions)}`.trim()
58
+ }
59
+ }).handle;
60
+ }
61
+ };
62
+ const record = {
63
+ name: definition.name,
64
+ definition: runtimeAgentDefinition(definition)
65
+ };
66
+ agentRecords.set(handle, record);
67
+ return {
68
+ handle,
69
+ record
70
+ };
71
+ }
72
+ function runtimeAgentForHandle(agent) {
73
+ const record = agentRecords.get(agent);
74
+ if (!record) throw new Error("Expected an agent handle created by pipr.agent");
75
+ return record;
76
+ }
77
+ function createToolHandle(definition) {
78
+ const handle = {
79
+ kind: "pipr.tool",
80
+ name: definition.name
81
+ };
82
+ const record = {
83
+ name: definition.name,
84
+ description: definition.description,
85
+ input: definition.input,
86
+ output: definition.output,
87
+ run: definition.run,
88
+ toModelOutput: definition.toModelOutput
89
+ };
90
+ toolRecords.set(handle, record);
91
+ return {
92
+ handle,
93
+ record
94
+ };
95
+ }
96
+ function createBuiltinReadOnlyToolHandle() {
97
+ const handle = {
98
+ kind: "pipr.tool",
99
+ name: "readOnly"
100
+ };
101
+ const record = {
102
+ name: "readOnly",
103
+ builtinReadOnly: true
104
+ };
105
+ toolRecords.set(handle, record);
106
+ return {
107
+ handle,
108
+ record
109
+ };
110
+ }
111
+ function runtimeToolForHandle(tool) {
112
+ const record = toolRecords.get(tool);
113
+ if (!record) throw new Error("Expected a tool handle created by pipr.tool");
114
+ return record;
115
+ }
116
+ function runtimeAgentDefinition(definition) {
117
+ return {
118
+ ...definition,
119
+ prompt: definition.prompt,
120
+ output: definition.output,
121
+ tools: definition.tools?.map(runtimeToolForHandle)
122
+ };
123
+ }
124
+ //#endregion
21
125
  //#region src/review-contract.ts
22
126
  const nonEmptyStringSchema = z$1.string().min(1);
23
127
  const positiveIntegerSchema = z$1.number().int().positive();
@@ -36,6 +140,8 @@ const reviewFindingSchema = z$1.strictObject({
36
140
  endLine: positiveIntegerSchema,
37
141
  suggestedFix: nonEmptyStringSchema.optional()
38
142
  });
143
+ /** Zod schema for Pipr's core inline-finding result. */
144
+ const reviewFindingsResultSchema = z$1.strictObject({ inlineFindings: z$1.array(reviewFindingSchema) });
39
145
  /** Zod schema for Pipr's core change request review result. */
40
146
  const reviewResultSchema = z$1.strictObject({
41
147
  summary: reviewSummarySchema,
@@ -45,6 +151,10 @@ const reviewResultSchema = z$1.strictObject({
45
151
  function parseReviewResult(value) {
46
152
  return reviewResultSchema.parse(value);
47
153
  }
154
+ /** Parses model output for Pipr's inline-finding schema. */
155
+ function parseReviewFindingsResult(value) {
156
+ return reviewFindingsResultSchema.parse(value);
157
+ }
48
158
  /** Parses a review summary value. */
49
159
  function parseReviewSummary(value) {
50
160
  return reviewSummarySchema.parse(value);
@@ -89,6 +199,7 @@ function jsonSchema(definition) {
89
199
  }
90
200
  /** Built-in schemas available as reusable agent output contracts. */
91
201
  const schemas = {
202
+ inlineFindings: createZodSchema("core/inline-findings", reviewFindingsResultSchema),
92
203
  review: createZodSchema(coreReviewOutputSchemaId, reviewResultSchema),
93
204
  summary: createZodSchema("core/summary", reviewSummarySchema)
94
205
  };
@@ -173,20 +284,17 @@ function createBuilder() {
173
284
  const commands = [];
174
285
  const tools = [];
175
286
  const publication = {};
287
+ const readOnlyTool = createBuiltinReadOnlyToolHandle();
176
288
  let checks;
177
289
  let limits;
178
290
  const api = {
179
- tools: { readOnly: [{
180
- kind: "pipr.tool",
181
- name: "readOnly",
182
- [builtinReadOnlyToolBrand]: true
183
- }] },
291
+ tools: { readOnly: [readOnlyTool.handle] },
184
292
  schemas,
185
293
  on: { changeRequest(options) {
186
294
  if (!Array.isArray(options.actions) || !options.task) throw new Error("pipr.on.changeRequest requires { actions, task }");
187
295
  changeRequestTriggers.push({
188
296
  actions: [...options.actions],
189
- task: options.task
297
+ task: runtimeTaskForHandle(options.task)
190
298
  });
191
299
  } },
192
300
  secret(options) {
@@ -200,39 +308,32 @@ function createBuilder() {
200
308
  model(options) {
201
309
  if (!options || typeof options.provider !== "string" || typeof options.model !== "string") throw new Error("pipr.model requires { provider, model }");
202
310
  if (!options.provider || !options.model) throw new Error("pipr.model requires provider and model");
311
+ if (options.thinking !== void 0 && !modelThinkingLevels.includes(options.thinking)) throw new Error(`pipr.model received unsupported thinking level '${options.thinking}'`);
203
312
  const profile = {
204
313
  kind: "pipr.model",
205
314
  id: options.id ?? `${options.provider}/${options.model}`,
206
315
  provider: options.provider,
207
316
  model: options.model,
208
317
  apiKey: options.apiKey,
209
- options: options.options
318
+ thinking: options.thinking
210
319
  };
211
320
  models.push(profile);
212
321
  return profile;
213
322
  },
214
323
  agent(definition) {
215
- const agent = createAgent(definition);
216
- agents.push(agent);
217
- return agent;
324
+ const agent = createAgentHandle(definition);
325
+ agents.push(agent.record);
326
+ return agent.handle;
218
327
  },
219
328
  task(definition) {
220
329
  if (!definition.name || typeof definition.run !== "function") throw new Error("pipr.task requires { name, run }");
221
- const task = {
222
- kind: "pipr.task",
223
- name: definition.name,
224
- check: definition.check,
225
- ...definition.local === false ? { local: false } : {},
226
- handler: definition.run
227
- };
228
- tasks.push(task);
229
- return task;
230
- },
231
- reviewer(options) {
232
- return createReviewer(api, options);
330
+ const task = createTaskHandle(definition);
331
+ tasks.push(task.record);
332
+ return task.handle;
233
333
  },
234
334
  review(options) {
235
335
  assertKnownReviewRecipeOptions(options);
336
+ if (!options.model || !models.includes(options.model)) throw new Error("pipr.review requires a registered model.");
236
337
  registerReviewRecipe(api, options);
237
338
  },
238
339
  config(options) {
@@ -253,7 +354,7 @@ function createBuilder() {
253
354
  permission: options.permission ?? "write",
254
355
  description: options.description,
255
356
  parse: options.parse,
256
- task: options.task
357
+ task: runtimeTaskForHandle(options.task)
257
358
  });
258
359
  },
259
360
  use(plugin) {
@@ -263,13 +364,12 @@ function createBuilder() {
263
364
  if (definition.name === "readOnly") throw new Error("Tool name 'readOnly' is reserved for pipr built-in tools");
264
365
  const run = definition.run;
265
366
  if (!run) throw new Error(`Tool '${definition.name}' must define run`);
266
- const tool = {
267
- kind: "pipr.tool",
367
+ const tool = createToolHandle({
268
368
  ...definition,
269
369
  run
270
- };
271
- tools.push(tool);
272
- return tool;
370
+ });
371
+ tools.push(tool.record);
372
+ return tool.handle;
273
373
  },
274
374
  schema,
275
375
  jsonSchema,
@@ -291,7 +391,7 @@ function createBuilder() {
291
391
  };
292
392
  },
293
393
  json(value, options) {
294
- const text = JSON.stringify(value, null, options?.pretty === false ? 0 : 2);
394
+ const text = serializePromptJson(value, options?.pretty !== false);
295
395
  if (options?.maxCharacters !== void 0 && text.length > options.maxCharacters) throw new Error(`JSON prompt value exceeded ${options.maxCharacters} characters`);
296
396
  return {
297
397
  kind: "pipr.prompt",
@@ -306,6 +406,7 @@ function createBuilder() {
306
406
  assertUnique(commands.map((command) => command.pattern), "command");
307
407
  assertModelIdentity(models);
308
408
  return {
409
+ resolveAgent: runtimeAgentForHandle,
309
410
  models,
310
411
  agents,
311
412
  tasks,
@@ -321,7 +422,7 @@ function createBuilder() {
321
422
  }
322
423
  function registerReviewRecipe(api, options) {
323
424
  const id = options.id;
324
- registerReviewRecipeEntrypoints(api, createReviewRecipeTask(api, id, options.reviewer ?? createReviewer(api, reviewRecipeReviewerOptions(options, id)), options), options);
425
+ registerReviewRecipeEntrypoints(api, createReviewRecipeTask(api, id, createReviewFindingsAgent(api, options), createReviewSummaryAgent(api, options), options), options);
325
426
  }
326
427
  const reviewRecipeOptionKeys = /* @__PURE__ */ new Set([
327
428
  "id",
@@ -330,12 +431,9 @@ const reviewRecipeOptionKeys = /* @__PURE__ */ new Set([
330
431
  "check",
331
432
  "timeout",
332
433
  "paths",
333
- "reviewer",
334
- "name",
335
434
  "model",
336
435
  "fallbacks",
337
436
  "instructions",
338
- "prompt",
339
437
  "tools"
340
438
  ]);
341
439
  const reviewRecipeEntrypointKeys = /* @__PURE__ */ new Set(["changeRequest", "command"]);
@@ -370,6 +468,7 @@ const aggregateCheckOptionsSchema = z$1.union([z$1.literal(false), z$1.strictObj
370
468
  })]);
371
469
  const checksOptionsSchema = z$1.strictObject({ aggregate: aggregateCheckOptionsSchema.optional() });
372
470
  const diffManifestLimitsSchema = z$1.strictObject({
471
+ maxShards: z$1.number().int().positive().optional(),
373
472
  fullMaxBytes: z$1.number().int().positive().optional(),
374
473
  fullMaxEstimatedTokens: z$1.number().int().positive().optional(),
375
474
  condensedMaxBytes: z$1.number().int().positive().optional(),
@@ -378,6 +477,7 @@ const diffManifestLimitsSchema = z$1.strictObject({
378
477
  });
379
478
  const runtimeLimitsSchema = z$1.strictObject({
380
479
  timeoutSeconds: z$1.number().int().positive().max(3600).optional(),
480
+ maxAgentRuns: z$1.number().int().positive().optional(),
381
481
  diffManifest: diffManifestLimitsSchema.optional()
382
482
  });
383
483
  const piprConfigOptionsSchema = z$1.strictObject({
@@ -388,12 +488,17 @@ const piprConfigOptionsSchema = z$1.strictObject({
388
488
  function assertKnownReviewRecipeOptions(options) {
389
489
  const unknownKeys = Object.keys(options).filter((key) => !reviewRecipeOptionKeys.has(key));
390
490
  if (unknownKeys.length > 0) throw new Error(`pipr.review received unsupported option fields: ${unknownKeys.join(", ")}.`);
491
+ const instructions = options.instructions;
492
+ if (!instructions || typeof instructions !== "object" || !isPromptSource(instructions.findings) || !isPromptSource(instructions.summary)) throw new Error("pipr.review instructions require both findings and summary.");
391
493
  const entrypoints = options.entrypoints;
392
494
  if (entrypoints && typeof entrypoints === "object") {
393
495
  const unknownEntrypointKeys = Object.keys(entrypoints).filter((key) => !reviewRecipeEntrypointKeys.has(key));
394
496
  if (unknownEntrypointKeys.length > 0) throw new Error(`pipr.review entrypoints received unsupported fields: ${unknownEntrypointKeys.join(", ")}.`);
395
497
  }
396
498
  }
499
+ function isPromptSource(value) {
500
+ return typeof value === "string" && value.length > 0 || typeof value === "object" && value !== null;
501
+ }
397
502
  function assertKnownPiprConfigOptions(options) {
398
503
  const parsed = piprConfigOptionsSchema.safeParse(options);
399
504
  if (!parsed.success) throw new Error(formatPiprConfigOptionsError(parsed.error));
@@ -420,33 +525,37 @@ function piprConfigLabel(pathSegments) {
420
525
  const path = pathSegments.join(".");
421
526
  return path ? `pipr.config ${path}` : "pipr.config";
422
527
  }
423
- function reviewRecipeReviewerOptions(options, name) {
424
- if (!options.model || !options.instructions) throw new Error("pipr.review requires model and instructions when reviewer is not provided");
425
- return {
426
- name,
528
+ function createReviewFindingsAgent(api, options) {
529
+ return api.agent({
530
+ name: `${options.id}-findings`,
427
531
  model: options.model,
428
532
  fallbacks: options.fallbacks,
429
- instructions: options.instructions,
430
- prompt: options.prompt,
431
- tools: options.tools,
432
- timeout: options.timeout
433
- };
533
+ instructions: options.instructions.findings,
534
+ tools: options.tools ?? api.tools.readOnly,
535
+ output: api.schemas.inlineFindings,
536
+ timeout: options.timeout,
537
+ prompt: () => api.prompt`Review this change for actionable inline findings.`
538
+ });
434
539
  }
435
- function createReviewer(api, options) {
540
+ function createReviewSummaryAgent(api, options) {
436
541
  return api.agent({
437
- name: options.name ?? "reviewer",
542
+ name: `${options.id}-summary`,
438
543
  model: options.model,
439
544
  fallbacks: options.fallbacks,
440
- instructions: options.instructions,
545
+ instructions: options.instructions.summary,
441
546
  tools: options.tools ?? api.tools.readOnly,
442
- output: api.schemas.review,
547
+ output: api.schemas.summary,
443
548
  timeout: options.timeout,
444
- prompt: options.prompt ?? (() => api.prompt`
445
- Review this change.
446
- `)
549
+ prompt: ({ inlineFindings, manifestSummary }) => api.prompt`
550
+ Summarize this change using the merged inline findings as evidence.
551
+
552
+ ${api.section("Scoped compressed manifest", api.json(manifestSummary, { maxCharacters: 6e4 }))}
553
+
554
+ ${api.section("Merged inline findings", api.json(inlineFindings, { maxCharacters: 6e4 }))}
555
+ `
447
556
  });
448
557
  }
449
- function createReviewRecipeTask(api, id, agent, options) {
558
+ function createReviewRecipeTask(api, id, findingsAgent, summaryAgent, options) {
450
559
  return api.task({
451
560
  name: id,
452
561
  check: options.check,
@@ -460,15 +569,27 @@ function createReviewRecipeTask(api, id, agent, options) {
460
569
  await context.comment({ main: "No changed files matched this review's path scope." });
461
570
  return;
462
571
  }
463
- const result = await context.pi.run(agent, {
572
+ const findings = await context.pi.run(findingsAgent, {
464
573
  manifest,
465
574
  change: context.change
466
575
  }, {
467
576
  timeout: options.timeout,
468
577
  paths: options.paths
469
578
  });
579
+ const result = {
580
+ summary: await context.pi.run(summaryAgent, {
581
+ manifestSummary: defaultReviewSummaryManifest(manifest),
582
+ change: context.change,
583
+ inlineFindings: findings.inlineFindings
584
+ }, {
585
+ timeout: options.timeout,
586
+ paths: options.paths
587
+ }),
588
+ inlineFindings: findings.inlineFindings
589
+ };
470
590
  const source = typeof options.comment === "function" ? await options.comment(result, {
471
591
  review: { id },
592
+ run: context.run,
472
593
  repository: context.repository,
473
594
  change: context.change,
474
595
  platform: context.platform
@@ -477,6 +598,35 @@ function createReviewRecipeTask(api, id, agent, options) {
477
598
  }
478
599
  });
479
600
  }
601
+ function defaultReviewSummaryManifest(manifest) {
602
+ const maxSerializedFileCharacters = 4e4;
603
+ const files = [];
604
+ let serializedFileCharacters = 0;
605
+ for (const file of manifest.files) {
606
+ const projected = {
607
+ path: file.path.slice(0, 1e3),
608
+ ...file.previousPath ? { previousPath: file.previousPath.slice(0, 1e3) } : {},
609
+ status: file.status,
610
+ ...file.language ? { language: file.language.slice(0, 100) } : {},
611
+ additions: file.additions,
612
+ deletions: file.deletions,
613
+ ...file.changedSymbols?.length ? { changedSymbols: file.changedSymbols.slice(0, 20).map((symbol) => symbol.slice(0, 200)) } : {},
614
+ ...file.excludedReason ? { excludedReason: file.excludedReason.slice(0, 500) } : {}
615
+ };
616
+ const projectedCharacters = JSON.stringify(projected).length;
617
+ if (serializedFileCharacters + projectedCharacters > maxSerializedFileCharacters) continue;
618
+ files.push(projected);
619
+ serializedFileCharacters += projectedCharacters;
620
+ }
621
+ return {
622
+ baseSha: manifest.baseSha,
623
+ headSha: manifest.headSha,
624
+ mergeBaseSha: manifest.mergeBaseSha,
625
+ fileCount: manifest.files.length,
626
+ omittedFileCount: manifest.files.length - files.length,
627
+ files
628
+ };
629
+ }
480
630
  function defaultReviewComment(result) {
481
631
  return {
482
632
  main: defaultReviewMarkdown(result),
@@ -558,23 +708,6 @@ function assertDiffManifestLimitConflicts(current, next) {
558
708
  for (const [key, value] of Object.entries(next.diffManifest)) if (value !== void 0 && current.diffManifest[key] !== void 0 && current.diffManifest[key] !== value) throw new Error(`pipr.config limits.diffManifest.${key} conflicts with existing value`);
559
709
  }
560
710
  }
561
- function createAgent(definition) {
562
- return {
563
- kind: "pipr.agent",
564
- name: definition.name,
565
- definition,
566
- extend(patch) {
567
- return createAgent({
568
- ...definition,
569
- ...patch,
570
- instructions: patch.instructions === void 0 ? definition.instructions : {
571
- kind: "pipr.prompt",
572
- value: `${renderPromptValue(definition.instructions)}\n\n${renderPromptValue(patch.instructions)}`.trim()
573
- }
574
- });
575
- }
576
- };
577
- }
578
711
  function assertUnique(values, label) {
579
712
  const seen = /* @__PURE__ */ new Set();
580
713
  for (const value of values) {
@@ -594,7 +727,7 @@ function assertNoDuplicateModelConfigs(models) {
594
727
  provider: model.provider,
595
728
  model: model.model,
596
729
  apiKeyEnv: model.apiKey?.name,
597
- options: model.options
730
+ thinking: model.thinking
598
731
  });
599
732
  const existingConfigId = effectiveConfigs.get(effectiveConfig);
600
733
  if (existingConfigId) throw new Error(`Duplicate model config for '${model.id}'. Reuse model '${existingConfigId}' instead.`);
@@ -629,6 +762,128 @@ function stableJsonValue(value) {
629
762
  return value;
630
763
  }
631
764
  //#endregion
632
- export { defaultReviewActions, defaultReviewEntrypoints, definePipr, definePlugin, jsonSchema, md, parseReviewFinding, parseReviewResult, parseReviewSummary, reviewFindingSchema, reviewResultSchema, reviewSchemaExample, reviewSummarySchema, schema, schemas, z };
765
+ //#region src/result.ts
766
+ const piprRunTriggers = [
767
+ "change-request",
768
+ "command",
769
+ "verifier",
770
+ "local"
771
+ ];
772
+ const text = z$1.string().min(1);
773
+ const count = z$1.number().int().nonnegative();
774
+ const header = { formatVersion: z$1.literal(2) };
775
+ const runSummarySchema = z$1.strictObject({
776
+ id: text.max(200),
777
+ trigger: z$1.enum(piprRunTriggers),
778
+ baseSha: text.max(200),
779
+ headSha: text.max(200),
780
+ tasks: z$1.array(text.max(200)).max(200),
781
+ durationMs: count,
782
+ models: z$1.array(text.max(200)).max(20),
783
+ agentRuns: count,
784
+ inputTokens: count,
785
+ outputTokens: count,
786
+ costUsd: z$1.number().nonnegative().finite(),
787
+ usageStatus: z$1.enum([
788
+ "complete",
789
+ "partial",
790
+ "unavailable"
791
+ ])
792
+ });
793
+ const inlineCountsSchema = z$1.strictObject({
794
+ posted: count,
795
+ skipped: count,
796
+ failed: count
797
+ });
798
+ const publicationCountsSchema = z$1.strictObject({
799
+ inlineComments: inlineCountsSchema,
800
+ inlinePublicationErrorCount: count,
801
+ inlineResolutionErrorCount: count
802
+ });
803
+ const reviewPublicationSchema = z$1.discriminatedUnion("state", [z$1.strictObject({ state: z$1.literal("disabled") }), z$1.strictObject({
804
+ state: z$1.literal("completed"),
805
+ mainComment: z$1.strictObject({ action: z$1.enum(["created", "updated"]) }),
806
+ ...publicationCountsSchema.shape
807
+ })]);
808
+ const schemas$1 = [
809
+ z$1.strictObject({
810
+ ...header,
811
+ kind: z$1.literal("review"),
812
+ run: runSummarySchema,
813
+ mainComment: z$1.string(),
814
+ inlineFindings: z$1.array(reviewFindingSchema),
815
+ droppedFindings: z$1.array(z$1.strictObject({
816
+ finding: reviewFindingSchema,
817
+ reason: text
818
+ })),
819
+ taskChecks: z$1.array(z$1.strictObject({
820
+ taskName: text,
821
+ conclusion: z$1.enum([
822
+ "success",
823
+ "failure",
824
+ "neutral"
825
+ ]),
826
+ summary: text.optional()
827
+ })),
828
+ repairAttempted: z$1.boolean(),
829
+ publication: reviewPublicationSchema
830
+ }),
831
+ z$1.strictObject({
832
+ ...header,
833
+ kind: z$1.literal("skipped"),
834
+ reason: text
835
+ }),
836
+ z$1.strictObject({
837
+ ...header,
838
+ kind: z$1.literal("ignored"),
839
+ reason: text
840
+ }),
841
+ z$1.strictObject({
842
+ ...header,
843
+ kind: z$1.literal("dry-run")
844
+ }),
845
+ z$1.strictObject({
846
+ ...header,
847
+ kind: z$1.literal("command-help"),
848
+ reason: text,
849
+ mainComment: z$1.string()
850
+ }),
851
+ z$1.strictObject({
852
+ ...header,
853
+ kind: z$1.literal("command-response"),
854
+ run: runSummarySchema,
855
+ mainComment: z$1.string(),
856
+ publication: z$1.strictObject({
857
+ state: z$1.literal("completed"),
858
+ action: z$1.enum(["created", "updated"])
859
+ })
860
+ }),
861
+ z$1.strictObject({
862
+ ...header,
863
+ kind: z$1.literal("verifier"),
864
+ run: runSummarySchema,
865
+ publication: z$1.strictObject({
866
+ state: z$1.literal("completed"),
867
+ inlineResolutionErrorCount: count
868
+ })
869
+ }),
870
+ z$1.strictObject({
871
+ ...header,
872
+ kind: z$1.literal("publication-error"),
873
+ message: text,
874
+ publication: publicationCountsSchema.optional()
875
+ }),
876
+ z$1.strictObject({
877
+ ...header,
878
+ kind: z$1.literal("error"),
879
+ message: text
880
+ })
881
+ ];
882
+ const piprResultSchema = z$1.discriminatedUnion("kind", schemas$1);
883
+ function parsePiprResult(value) {
884
+ return piprResultSchema.parse(value);
885
+ }
886
+ //#endregion
887
+ export { defaultReviewActions, defaultReviewEntrypoints, definePipr, definePlugin, jsonSchema, md, modelThinkingLevels, parsePiprResult, parseReviewFinding, parseReviewFindingsResult, parseReviewResult, parseReviewSummary, piprResultSchema, reviewFindingSchema, reviewFindingsResultSchema, reviewResultSchema, reviewSchemaExample, reviewSummarySchema, schema, schemas, z };
633
888
 
634
889
  //# sourceMappingURL=index.mjs.map