@axiom-lattice/core 3.0.6 → 3.1.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.mjs CHANGED
@@ -2646,6 +2646,7 @@ var InMemoryTaskStore = class {
2646
2646
  projectId: params.projectId,
2647
2647
  dueDate: params.dueDate,
2648
2648
  metadata: params.metadata,
2649
+ files: params.files,
2649
2650
  parentId: params.parentId,
2650
2651
  sourceId: params.sourceId,
2651
2652
  context: params.context,
@@ -2703,6 +2704,7 @@ var InMemoryTaskStore = class {
2703
2704
  const updated = {
2704
2705
  ...existing,
2705
2706
  ...updates,
2707
+ files: updates.files !== void 0 ? updates.files : existing.files,
2706
2708
  updatedAt: /* @__PURE__ */ new Date()
2707
2709
  };
2708
2710
  tenantTasks.set(id, updated);
@@ -14207,6 +14209,11 @@ var manageTaskSchema = z41.object({
14207
14209
  dependencies: z41.array(z41.string()).optional().describe("List of task IDs that must be completed before this task can start"),
14208
14210
  result: z41.string().optional().describe("Result summary when task is completed"),
14209
14211
  failureReason: z41.string().optional().describe("Reason for failure (use when status='failed')"),
14212
+ files: z41.array(z41.object({
14213
+ uri: z41.string().describe("Uniquely locates the resource: http(s):// URL, /s/:token share, or sandbox path"),
14214
+ name: z41.string().optional().describe("Display name"),
14215
+ addedBy: z41.enum(["user", "agent"]).optional().describe("Who attached the file")
14216
+ })).optional().describe("File references attached to this task"),
14210
14217
  summary: z41.string().optional().describe("Brief summary of the operation")
14211
14218
  });
14212
14219
  function buildReviewMarkdown(task) {
@@ -14265,7 +14272,8 @@ function createTaskMiddleware() {
14265
14272
  requireReview: input.requireReview,
14266
14273
  dependencies: input.dependencies,
14267
14274
  workspaceId,
14268
- projectId
14275
+ projectId,
14276
+ files: input.files
14269
14277
  });
14270
14278
  return JSON.stringify({ success: true, data: task });
14271
14279
  }
@@ -14344,7 +14352,8 @@ function createTaskMiddleware() {
14344
14352
  "result",
14345
14353
  "failureReason",
14346
14354
  "requireReview",
14347
- "dependencies"
14355
+ "dependencies",
14356
+ "files"
14348
14357
  ];
14349
14358
  for (const field of settableFields) {
14350
14359
  if (input[field] !== void 0) {
@@ -18182,11 +18191,11 @@ ${BASE_PROMPT}` : BASE_PROMPT;
18182
18191
  defaultInterruptOn: interruptOn,
18183
18192
  subagents,
18184
18193
  generalPurposeAgent: true
18185
- }),
18186
- // Enables Anthropic prompt caching for improved performance and reduced costs
18187
- anthropicPromptCachingMiddleware({
18188
- unsupportedModelBehavior: "ignore"
18189
18194
  })
18195
+ // Enables Anthropic prompt caching for improved performance and reduced costs
18196
+ // anthropicPromptCachingMiddleware({
18197
+ // unsupportedModelBehavior: "ignore",
18198
+ // })
18190
18199
  ];
18191
18200
  if (interruptOn) {
18192
18201
  middleware.push(humanInTheLoopMiddleware2({ interruptOn }));
@@ -21864,6 +21873,27 @@ registerToolLattice(
21864
21873
  }
21865
21874
  }
21866
21875
  );
21876
+ registerToolLattice(
21877
+ "list_models",
21878
+ {
21879
+ name: "list_models",
21880
+ description: "List all registered models. Returns each model's key (use this string as modelKey when creating eval projects via manage_eval create_project, or as an agent's modelKey in create_agent/update_agent) and its display name.",
21881
+ schema: z49.object({})
21882
+ },
21883
+ async (_input) => {
21884
+ try {
21885
+ const lattices = modelLatticeManager.getAllLattices();
21886
+ return JSON.stringify({
21887
+ models: lattices.map((l) => ({
21888
+ key: l.key,
21889
+ name: l.client.name ?? l.key
21890
+ }))
21891
+ });
21892
+ } catch (error) {
21893
+ return JSON.stringify({ error: `Failed to list models: ${error.message}` });
21894
+ }
21895
+ }
21896
+ );
21867
21897
  registerToolLattice(
21868
21898
  "invoke_agent",
21869
21899
  {
@@ -21995,6 +22025,22 @@ The skills document WHY and HOW; these gates are the unskippable
21995
22025
  minimum. If you cannot satisfy a gate (e.g. user says skip), record it
21996
22026
  and proceed only on the user's explicit instruction.
21997
22027
 
22028
+ LEARNING ROUND KICKOFF \u2014 a message that names an existing target agent
22029
+ id AND an existing tracking task id (a "learning round"). This protocol
22030
+ OVERRIDES the defaults above:
22031
+ - The target agent ALREADY EXISTS (an empty placeholder). Build and
22032
+ refine it via update_agent on that exact id. NEVER call create_agent \u2014
22033
+ a new agent would disconnect the round's tracking.
22034
+ - The parent task ALREADY EXISTS \u2014 your create-a-task-first duty is
22035
+ satisfied by it. Create subtasks with manage_task under its id
22036
+ (parentId); NEVER create a new parent task for the round.
22037
+ - The round is pre-approved \u2014 skip the DESIGN\u2192CONFIRM gates: show the
22038
+ design in your reply, then build directly.
22039
+ - Every update_agent call must be mirrored by a manage_task work item
22040
+ whose summary names the changed keys (e.g. "update_agent: prompt,
22041
+ modelKey") \u2014 the round feed highlights these so the user can see what
22042
+ changed between iterations.
22043
+
21998
22044
  Your sub-skills (accessible via the MOC or direct loading):
21999
22045
  - [[learn-capability]] \u2014 Learn from any source material \u2192 skills + agents
22000
22046
  - [[agent-build]] \u2014 Design and build single agents (REACT/DEEP_AGENT)
@@ -22109,6 +22155,7 @@ var agentArchitectConfig = {
22109
22155
  tools: [
22110
22156
  "list_agents",
22111
22157
  "list_tools",
22158
+ "list_models",
22112
22159
  "list_middleware_types",
22113
22160
  "list_connections",
22114
22161
  "get_agent",
@@ -26109,7 +26156,7 @@ File content: ${files[key4]}`
26109
26156
  {
26110
26157
  dimension: "correctness",
26111
26158
  weight: 100,
26112
- description: "\u6574\u4F53\u6B63\u786E\u6027\uFF0C\u662F\u5426\u7B26\u5408\u9884\u671F\u8F93\u51FA\u63CF\u8FF0\u3002"
26159
+ description: "Overall correctness \u2014 whether the result matches the expected output description."
26113
26160
  }
26114
26161
  ];
26115
26162
  const evalRubrics = evalCase.eval.eval_rubrics && evalCase.eval.eval_rubrics.length > 0 ? evalCase.eval.eval_rubrics : defaultRubrics;
@@ -26123,53 +26170,53 @@ File content: ${files[key4]}`
26123
26170
  ${evalRubrics.map(
26124
26171
  (r) => `- **${r.dimension}**\uFF08\u6743\u91CD\uFF1A${r.weight}\uFF09\uFF1A${r.description}`
26125
26172
  ).join("\n")}`;
26126
- const testPrompt = `# \u89D2\u8272
26127
- \u4F60\u662F\u4E00\u540D\u8D44\u6DF1\u7684 AI Agent \u8BC4\u4F30\u4E13\u5BB6\uFF0C\u8D1F\u8D23\u6839\u636E\u9884\u8BBE\u7684\u6307\u6807\uFF08Rubrics\uFF09\u5BF9 Agent \u7684\u6267\u884C\u8FC7\u7A0B\u4E0E\u7ED3\u679C\u8FDB\u884C"\u9ED1\u76D2\u6D4B\u8BD5"\u5224\u5B9A\u3002
26173
+ const testPrompt = `# Role
26174
+ You are a senior AI Agent evaluation expert. Your job is to perform a "black-box test" judgment of the agent's execution process and results against the preset evaluation rubrics.
26128
26175
 
26129
- # \u8F93\u5165\u4FE1\u606F
26130
- \u6D4B\u8BD5\u6846\u67B6\u5C06\u4E3A\u4F60\u63D0\u4F9B\u4EE5\u4E0B\u4E94\u4E2A\u6838\u5FC3\u4E0A\u4E0B\u6587\uFF1A
26176
+ # Input Information
26177
+ The test framework provides you with the following five core contexts:
26131
26178
 
26132
- 1. **\u7528\u6237\u610F\u56FE\uFF08User Intent\uFF09**\uFF1A${evalCase.input.message}
26179
+ 1. **User Intent**: ${evalCase.input.message}
26133
26180
 
26134
- 2. **\u8F93\u5165\u6587\u4EF6\uFF08Input Files\uFF09**\uFF1A${testCaseFilesContent || "\u65E0"}
26181
+ 2. **Input Files**: ${testCaseFilesContent || "None"}
26135
26182
 
26136
- 3. **\u6267\u884C\u8FC7\u7A0B\uFF08Execution Trajectory\uFF0CAgent \u5168\u7A0B\u7684\u6D88\u606F/\u5DE5\u5177\u8C03\u7528\u8BB0\u5F55\uFF09**\uFF1A
26183
+ 3. **Execution Trajectory** (the agent's full message/tool-call record):
26137
26184
  ${trajectory}
26138
26185
 
26139
- 4. **\u6700\u7EC8\u8F93\u51FA\uFF08Final Output\uFF0CAgent \u7684\u6700\u540E\u4E00\u6761\u56DE\u590D\uFF09**\uFF1A
26186
+ 4. **Final Output** (the agent's last reply):
26140
26187
  ${finalOutput}
26141
26188
 
26142
- 5. **\u671F\u671B\u8F93\u51FA\u63CF\u8FF0\uFF08Expected Output Description\uFF09**\uFF1A${evalCase.eval.content_assertion}
26189
+ 5. **Expected Output Description**: ${evalCase.eval.content_assertion}
26143
26190
  ${rubricsSection}
26144
26191
 
26145
- # \u4EFB\u52A1
26146
- \u4F60\u5FC5\u987B\u4E25\u683C\u5BF9\u7167"\u8BC4\u4F30\u6307\u6807\uFF08Evaluation Rubrics\uFF09"\u4E2D\u7684\u6BCF\u4E00\u9879\u6307\u6807\uFF0C\u7ED3\u5408"\u6267\u884C\u8FC7\u7A0B"\u4E0E"\u6700\u7EC8\u8F93\u51FA"\uFF0C\u5206\u6790 Agent \u662F\u5426\u8FBE\u6807\u3002\u8BC4\u4F30\u65F6\u65E2\u8981\u68C0\u67E5\u6700\u7EC8\u7ED3\u679C\uFF0C\u4E5F\u8981\u68C0\u67E5\u8FC7\u7A0B\u4E2D\u662F\u5426\u6B63\u786E\u5B8C\u6210\u4E86\u5FC5\u8981\u7684\u6B65\u9AA4\uFF08\u5982\u5DE5\u5177\u8C03\u7528\u3001\u4FE1\u606F\u68C0\u7D22\u7B49\uFF09\u3002
26192
+ # Task
26193
+ You must strictly evaluate the agent against every rubric in the "Evaluation Rubrics" section, using both the "Execution Trajectory" and the "Final Output". Evaluate the final result AND whether the process correctly performed the required intermediate steps (tool calls, information retrieval, etc.).
26147
26194
 
26148
- # \u89C4\u5219
26149
- 1. **\u5BA2\u89C2\u6027**\uFF1A\u4EC5\u6839\u636E\u63D0\u4F9B\u7684\u4E0A\u4E0B\u6587\u5224\u5B9A\u3002\u5982\u679C\u6807\u51C6\u8981\u6C42"\u5305\u542B\u6570\u5B57"\uFF0C\u4F46\u8F93\u51FA\u53EA\u6709\u6587\u5B57\uFF0C\u5373\u4F7F\u8BED\u6C14\u518D\u597D\u4E5F\u5FC5\u987B\u6263\u5206\u3002
26150
- 2. **\u7ED3\u679C\u6821\u9A8C**\uFF1A\u5982\u679C"\u6700\u7EC8\u8F93\u51FA"\u4E2D\u7F3A\u5931\u9884\u671F\u7684\u5185\u5BB9\uFF0C\u6216\u5185\u5BB9\u4E0D\u7B26\u5408"\u8BC4\u4F30\u6307\u6807"\u4E2D\u7684\u6807\u51C6\uFF0C\u5BF9\u5E94\u7684\u6307\u6807\u5E94\u5224\u5B9A\u4E3A\u5931\u8D25\u3002
26151
- 3. **\u8FC7\u7A0B\u6821\u9A8C**\uFF1A\u5982\u679C"\u6267\u884C\u8FC7\u7A0B"\u663E\u793A Agent \u672A\u6267\u884C\u5FC5\u8981\u7684\u4E2D\u95F4\u6B65\u9AA4\uFF08\u5982\u5E94\u8C03\u7528\u5DE5\u5177\u800C\u672A\u8C03\u7528\uFF09\uFF0C\u5373\u4F7F\u6700\u7EC8\u8F93\u51FA\u770B\u4F3C\u5408\u7406\uFF0C\u4E5F\u5E94\u5728\u5BF9\u5E94\u6307\u6807\u4E0A\u6263\u5206\u3002
26152
- 4. **\u8BC1\u636E\u5BFC\u5411**\uFF1A\u5728\u7ED9\u51FA\u539F\u56E0\uFF08reason\uFF09\u65F6\uFF0C\u5FC5\u987B\u5F15\u7528\u6267\u884C\u8FC7\u7A0B\u6216\u6700\u7EC8\u8F93\u51FA\u4E2D\u7684\u5177\u4F53\u5185\u5BB9\u3002
26153
- 5. **\u52A0\u6743\u8BA1\u7B97**\uFF1A\u6700\u7EC8\u5206\u6570\u4E3A\u5404\u9879\u6307\u6807\u5F97\u5206\u4E0E\u5176\u6743\u91CD\u7684\u4E58\u79EF\u4E4B\u548C\uFF080-100\u5206\u5236\uFF09\u3002
26154
- 6. **HITL \u4E2D\u65AD\u5224\u5B9A**\uFF1A\u5982\u679C\u6267\u884C\u8FC7\u7A0B\u4E2D\u51FA\u73B0\u300CHITL \u6682\u505C\uFF1AAgent \u8BF7\u6C42\u4EBA\u5DE5\u8F93\u5165\u300D\u6761\u76EE\uFF0C\u8BF4\u660E Agent \u5728\u7B49\u5F85\u4EBA\u5DE5\u786E\u8BA4\u3002\u8BF7\u628A\u5B83\u5F53\u4F5C\u88AB\u6D4B\u4E1A\u52A1\u884C\u4E3A\u6765\u8BC4\u5224\uFF1A\u82E5\u671F\u671B\u8F93\u51FA\u8981\u6C42\u81EA\u4E3B\u5B8C\u6210\uFF08\u5982"\u65E0\u9700\u786E\u8BA4\u81EA\u52A8\u6267\u884C"\uFF09\uFF0C\u8BF7\u6C42\u4EBA\u5DE5\u8F93\u5165\u5E94\u5224\u5931\u8D25\uFF1B\u82E5\u671F\u671B\u8F93\u51FA\u8981\u6C42\u5148\u83B7\u5F97\u786E\u8BA4\u6216\u6279\u51C6\uFF08\u5982"\u6267\u884C\u524D\u5FC5\u987B\u8BF7\u6C42\u6279\u51C6"\uFF09\uFF0C\u8BF7\u6C42\u4EBA\u5DE5\u8F93\u5165\u662F\u6B63\u786E\u884C\u4E3A\uFF0C\u5E94\u7ED3\u5408\u5176\u65F6\u673A\u4E0E\u5185\u5BB9\u5224\u5B9A\u4E3A\u901A\u8FC7\u6216\u6309\u6307\u6807\u7ED9\u5206\u3002
26155
- 7. **HITL \u81EA\u52A8\u54CD\u5E94\u5224\u5B9A**\uFF1A\u5982\u679C\u300CHITL \u6682\u505C\u300D\u6761\u76EE\u4E4B\u540E\u51FA\u73B0\u300C\u5DF2\u81EA\u52A8\u54CD\u5E94\uFF08\u6D4B\u8BD5\u7B56\u7565 auto-approve/auto-reject/canned-response\uFF09\u300D\u6761\u76EE\uFF0C\u8BF4\u660E\u6D4B\u8BD5\u6846\u67B6\u6CE8\u5165\u4E86\u4EBA\u5DE5\u56DE\u590D\u3001\u6D41\u7A0B\u5DF2\u7EE7\u7EED\u2014\u2014\u8BF7\u6309**\u5B8C\u6574\u6D41\u7A0B**\u8BC4\u5224\u6682\u505C\u4E4B\u540E\u7684\u884C\u4E3A\uFF08\u5982\u6279\u51C6\u540E\u662F\u5426\u6B63\u786E\u6267\u884C\u4E86\u64CD\u4F5C\uFF09\uFF0C\u5E76\u6838\u5BF9\u81EA\u52A8\u54CD\u5E94\u5185\u5BB9\u662F\u5426\u7B26\u5408\u4EBA\u5DE5\u56DE\u590D\u7684\u5408\u7406\u9884\u671F\u3002
26195
+ # Rules
26196
+ 1. **Objectivity**: Judge solely from the provided context. If the standard requires "contains a number" but the output has only text, points must be deducted even if the tone is good.
26197
+ 2. **Result verification**: If the "Final Output" is missing expected content, or does not meet the criteria in the "Evaluation Rubrics", the corresponding rubric must be marked as failed.
26198
+ 3. **Process verification**: If the "Execution Trajectory" shows the agent did not perform a necessary intermediate step (e.g., should have called a tool but did not), deduct points on the corresponding rubric even if the final output looks plausible.
26199
+ 4. **Evidence-based**: When giving a reason, you must quote specific content from the execution trajectory or final output.
26200
+ 5. **Weighted scoring**: The final score is the weighted sum of the rubric scores (on a 0-100 scale).
26201
+ 6. **HITL interrupt judgment**: If the trajectory contains a "HITL pause: agent requested human input" entry, the agent is waiting for human confirmation. Treat this as the business behavior under test: if the expected output requires autonomous completion (e.g., "execute automatically without confirmation"), requesting human input should be judged a failure; if the expected output requires confirmation or approval first (e.g., "must request approval before executing"), requesting human input is correct behavior \u2014 judge its timing and content, passing or scoring according to the rubrics.
26202
+ 7. **HITL auto-response judgment**: If a "HITL pause" entry is followed by an "auto-responded (test policy auto-approve/auto-reject/canned-response)" entry, the test framework injected a human reply and the flow continued \u2014 evaluate the behavior AFTER the pause as the complete flow (e.g., whether the operation was correctly executed after approval), and check whether the auto-response content matches a reasonable human reply.
26156
26203
 
26157
- # \u8F93\u51FA\u683C\u5F0F\uFF08\u4EC5JSON\uFF09
26158
- \u4F60\u5FC5\u987B\u4EC5\u4EE5 JSON \u683C\u5F0F\u56DE\u590D\uFF0C\u7ED3\u6784\u5982\u4E0B\uFF1A
26204
+ # Output Format (JSON only)
26205
+ You MUST reply with JSON only, using this structure:
26159
26206
  {
26160
26207
  "pass": true | false,
26161
26208
  "final_score": number,
26162
26209
  "dimension_results": [
26163
26210
  {
26164
- "name": "\u6307\u6807\u540D\u79F0",
26211
+ "name": "rubric name",
26165
26212
  "score": number,
26166
- "reason": "\u5177\u4F53\u7684\u6263\u5206\u6216\u7ED9\u5206\u7406\u7531\uFF0C\u9700\u5F15\u7528\u8BC1\u636E"
26213
+ "reason": "specific reason for deduction or credit, citing evidence"
26167
26214
  }
26168
26215
  ],
26169
- "summary": "\u5BF9 Agent \u8868\u73B0\u7684\u6574\u4F53\u8BC4\u4EF7"
26216
+ "summary": "overall evaluation of the agent's performance"
26170
26217
  }
26171
26218
 
26172
- \u6CE8\u610F\uFF1A\u5982\u679C final_score >= 80 \u4E14\u6CA1\u6709\u81F4\u547D\u6027\u9519\u8BEF\uFF0Cpass \u5E94\u4E3A true\uFF1B\u5426\u5219\u4E3A false\u3002`;
26219
+ Note: if final_score >= 80 and there are no fatal errors, pass should be true; otherwise false.`;
26173
26220
  this.lastTestPrompt = testPrompt;
26174
26221
  const judgeThreadId = v44();
26175
26222
  this.lastJudgeThreadId = judgeThreadId;
@@ -26552,6 +26599,32 @@ var LatticeEvalSuite = class {
26552
26599
  import { AgentType as AgentType6 } from "@axiom-lattice/protocols";
26553
26600
  import { HumanMessage as HumanMessage5 } from "@langchain/core/messages";
26554
26601
  import { v4 as uuidv46 } from "uuid";
26602
+ var DEFAULT_CALIBRATION_PROBES = [
26603
+ {
26604
+ id: "catch-up-correct",
26605
+ task: "A train leaves Station A at 10:00 AM traveling at 60 mph. A second train leaves Station A at 10:30 AM traveling at 90 mph on the same route. The final answer must be the time (HH:MM) at which the second train catches up to the first.",
26606
+ finalOutput: "11:30",
26607
+ expectedPass: true
26608
+ },
26609
+ {
26610
+ id: "catch-up-wrong",
26611
+ task: "A train leaves Station A at 10:00 AM traveling at 60 mph. A second train leaves Station A at 10:30 AM traveling at 90 mph on the same route. The final answer must be the time (HH:MM) at which the second train catches up to the first.",
26612
+ finalOutput: "12:30",
26613
+ expectedPass: false
26614
+ },
26615
+ {
26616
+ id: "discount-tax-correct",
26617
+ task: "A store offers a 20% discount on an item priced at $150, then adds 8% sales tax to the discounted price. The final answer must be the total price in dollars.",
26618
+ finalOutput: "129.6",
26619
+ expectedPass: true
26620
+ },
26621
+ {
26622
+ id: "discount-tax-wrong",
26623
+ task: "A store offers a 20% discount on an item priced at $150, then adds 8% sales tax to the discounted price. The final answer must be the total price in dollars.",
26624
+ finalOutput: "162",
26625
+ expectedPass: false
26626
+ }
26627
+ ];
26555
26628
  var LatticeEvalProject = class {
26556
26629
  constructor(project, onCaseComplete) {
26557
26630
  this.suites = /* @__PURE__ */ new Map();
@@ -26659,21 +26732,22 @@ var LatticeEvalProject = class {
26659
26732
  }
26660
26733
  /**
26661
26734
  * Verify the judge agent can produce parseable, correct verdicts
26662
- * before committing to a full run. Uses two known-answer cases
26663
- * (one expected PASS, one expected FAIL) to catch broken judges.
26735
+ * before committing to a full run. Uses known-answer probes (default
26736
+ * multi-step reasoning set, overridable per project via
26737
+ * judge_agent_config.calibration_cases) to catch broken judges.
26738
+ * Checks both the pass verdict and the final_score direction.
26664
26739
  */
26665
26740
  async calibrateJudge() {
26666
26741
  const tenantId2 = this.project.lattice_server_config.tenant_id || "default";
26667
26742
  const judgeAgent = await getAgentClient(tenantId2, this.judgeAgentKey);
26668
- const cases = [
26669
- { output: "7", expected: "7", expectedPass: true },
26670
- { output: "7", expected: "999", expectedPass: false }
26671
- ];
26672
- for (const c of cases) {
26673
- const prompt = `\u4F60\u662F\u8BC4\u4F30\u4E13\u5BB6\u3002\u5224\u5B9A\u6700\u7EC8\u8F93\u51FA\u662F\u5426\u7B26\u5408\u671F\u671B\u3002
26674
- \u6700\u7EC8\u8F93\u51FA\uFF1A${c.output}
26675
- \u671F\u671B\u8F93\u51FA\uFF1A${c.expected}
26676
- \u4EC5\u8F93\u51FA JSON\uFF1A{"pass": true|false, "final_score": 0-100, "summary": "\u7406\u7531"}`;
26743
+ const probes = this.project.judge_agent_config.calibration_cases && this.project.judge_agent_config.calibration_cases.length > 0 ? this.project.judge_agent_config.calibration_cases : DEFAULT_CALIBRATION_PROBES;
26744
+ for (const probe of probes) {
26745
+ const trajectorySection = probe.trajectory ? `
26746
+ Trajectory: ${probe.trajectory}` : "";
26747
+ const prompt = `You are an evaluation expert. Judge whether the final output meets the expected output description.
26748
+ Expected output description: ${probe.task}
26749
+ Final output: ${probe.finalOutput}${trajectorySection}
26750
+ Respond with JSON only: {"pass": true|false, "final_score": 0-100, "summary": "reason"}`;
26677
26751
  let raw = "";
26678
26752
  let invokeError = null;
26679
26753
  for (let attempt = 0; attempt < 2; attempt++) {
@@ -26698,13 +26772,24 @@ var LatticeEvalProject = class {
26698
26772
  return { ok: false, reason: `Calibration output unparseable: ${parsed.error}`, bypassed: true };
26699
26773
  }
26700
26774
  const actualPass = parsed.pass !== void 0 ? parsed.pass : (parsed.final_score ?? 0) >= 80;
26701
- if (actualPass !== c.expectedPass) {
26775
+ if (actualPass !== probe.expectedPass) {
26702
26776
  return {
26703
26777
  ok: false,
26704
- reason: `Calibration mismatch: output="${c.output}" expected="${c.expected}" \u2014 judge said ${actualPass ? "PASS" : "FAIL"}, expected ${c.expectedPass ? "PASS" : "FAIL"}`,
26778
+ reason: `Calibration mismatch (probe=${probe.id}): expected ${probe.expectedPass ? "PASS" : "FAIL"}, judge said ${actualPass ? "PASS" : "FAIL"}`,
26705
26779
  bypassed: true
26706
26780
  };
26707
26781
  }
26782
+ if (parsed.final_score !== void 0) {
26783
+ const minScore = probe.expectedScoreMin ?? 80;
26784
+ const scoreOk = probe.expectedPass ? parsed.final_score >= minScore : parsed.final_score < minScore;
26785
+ if (!scoreOk) {
26786
+ return {
26787
+ ok: false,
26788
+ reason: `Calibration score mismatch (probe=${probe.id}): expected ${probe.expectedPass ? "final_score >= " + minScore : "final_score < " + minScore}, judge gave ${parsed.final_score}`,
26789
+ bypassed: true
26790
+ };
26791
+ }
26792
+ }
26708
26793
  }
26709
26794
  return { ok: true };
26710
26795
  }
@@ -28949,6 +29034,7 @@ function createManageEvalTool() {
28949
29034
  description: z66.string().optional(),
28950
29035
  judgeModelKey: z66.string().optional(),
28951
29036
  concurrency: z66.number().optional(),
29037
+ targetAgentId: z66.string().optional().describe("Optional for create_project \u2014 the agent this eval project verifies. Recorded in targetServerConfig so the agent's detail page can find its eval data without relying on project naming."),
28952
29038
  suiteId: z66.string().optional(),
28953
29039
  caseId: z66.string().optional(),
28954
29040
  inputMessage: z66.string().optional(),
@@ -28980,7 +29066,11 @@ function createManageEvalTool() {
28980
29066
  judgeModelConfig: { modelKey: input.judgeModelKey },
28981
29067
  targetServerConfig: {
28982
29068
  workspace_id: ctx.workspaceId,
28983
- project_id: ctx.projectId
29069
+ project_id: ctx.projectId,
29070
+ // The project↔agent association lives here (not in the project
29071
+ // name): an eval project is agent-agnostic by design, this
29072
+ // pointer is merely the agent's designated verifier.
29073
+ ...input.targetAgentId ? { targetAgentId: input.targetAgentId } : {}
28984
29074
  },
28985
29075
  concurrency: input.concurrency ?? 3
28986
29076
  });
@@ -29047,7 +29137,7 @@ function createManageEvalTool() {
29047
29137
  name: "manage_eval",
29048
29138
  description: `Create, update, delete evaluation projects, suites, and test cases.
29049
29139
 
29050
- Project: create_project(name, description?, judgeModelKey?, concurrency?) | update_project | delete_project
29140
+ Project: create_project(name, description?, judgeModelKey?, concurrency?, targetAgentId?) | update_project | delete_project
29051
29141
  judgeModelKey defaults to first available model. concurrency defaults to 3.
29052
29142
  delete_project rejected if active runs exist.
29053
29143
  **When creating a project from within a workspace, the workspace/project context is
@@ -29071,6 +29161,7 @@ function createRunEvalTool() {
29071
29161
  suiteIds: z66.array(z66.string()).optional().describe("Optional for start \u2014 only run these suites (e.g. dev set only). Omit to run all."),
29072
29162
  caseIds: z66.array(z66.string()).optional().describe("Optional for start \u2014 only run these cases across the selected suites. Omit to run all cases in those suites."),
29073
29163
  runId: z66.string().optional().describe("Required for status, resume, abort"),
29164
+ taskId: z66.string().optional().describe("Optional for start \u2014 training task ID this run belongs to (round association)"),
29074
29165
  sleepMs: z66.number().int().min(0).max(12e4).optional().describe("Optional for status \u2014 sleep this many ms BEFORE checking the run, to pace polling (e.g. 15000 \u2192 30000 \u2192 60000 \u2192 120000). Omit to check immediately."),
29075
29166
  wait: z66.boolean().optional().describe("Optional for start \u2014 defaults to true: block synchronously (up to ~150s) and return final results in one call. Set false to return the runId immediately and poll.")
29076
29167
  });
@@ -29088,7 +29179,7 @@ function createRunEvalTool() {
29088
29179
  switch (input.action) {
29089
29180
  case "start": {
29090
29181
  const ctx = workspaceContext(exeConfig);
29091
- const runId = await svc.startRun(tid, input.projectId, input.suiteIds, input.caseIds, ctx);
29182
+ const runId = await svc.startRun(tid, input.projectId, input.suiteIds, input.caseIds, ctx, input.taskId);
29092
29183
  if (input.wait === false) {
29093
29184
  data = sanitize({ runId, message: "Run started. Poll with run_eval status (backoff: 15s\u219230s\u219260s\u2192max 120s)." });
29094
29185
  break;
@@ -31096,6 +31187,7 @@ export {
31096
31187
  ConsoleLoggerClient,
31097
31188
  CustomMetricsClient,
31098
31189
  CustomMiddlewareRegistry,
31190
+ DEFAULT_CALIBRATION_PROBES,
31099
31191
  DaytonaInstance,
31100
31192
  DaytonaProvider,
31101
31193
  DefaultScheduleClient,