bitfab-cli 0.2.508 → 0.2.510

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.
Files changed (2) hide show
  1. package/dist/index.js +9 -8
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -28956,6 +28956,7 @@ var spanFieldSchema = external_exports.enum([
28956
28956
  ]);
28957
28957
  var GET_TRACE_ASSERTIONS_MAX_IDS = 100;
28958
28958
  var MAX_ASSERTIONS_PER_REQUEST = 50;
28959
+ var MAX_CODE_DRAFTS_PER_SAVE = 10;
28959
28960
  var MAX_ASSIGNEE_EMAIL_LENGTH = 320;
28960
28961
  var GET_GRADER_VERDICTS_MAX_IDS = 100;
28961
28962
  var DEFAULT_GRADER_VERDICT_LIMIT = 50;
@@ -29199,7 +29200,7 @@ var assertionTargetShape = external_exports.discriminatedUnion("kind", [
29199
29200
  ]).optional().describe('Which call to check when the trace runs that span more than once, e.g. a retry loop. "first", "last" (the default), or a 0-based index. Leave it off unless the repetition matters.')
29200
29201
  }).describe("Check one span by name rather than the whole trace, e.g. that a particular tool call was made with the right arguments.")
29201
29202
  ]).describe('SCOPE: what part of the trace under evaluation this assertion is checked against. OMIT IT for the whole trace, which is the common case and the right default when unsure. On an edit, omitting it keeps the current scope, and passing null returns the assertion to the whole trace. Pass { "kind": "output" } to check only the final output, or { "kind": "span", "name": "..." } to check one span. Scoping narrows what a judge looks at, so a wrong scope hides real failures. A target naming something the evaluated trace does not contain makes the check ERRORED, never passed, because a check that could not run must never look like a check that succeeded.');
29202
- var assertionKindShape = external_exports.enum(["judge", "code", "hybrid"]).describe('KIND: who decides this assertion on a replay. "judge" (the default): the LLM judge reads the run. "code": the code below decides every replay by itself, and never returns "defer". "hybrid": the code decides what a program can read and returns "defer" to hand the rest to the LLM judge. Send "code" or "hybrid" together with code. On an edit, omit it to keep the current kind, and pass "judge" to remove the code.');
29203
+ var assertionKindShape = external_exports.enum(["judge", "code", "hybrid"]).describe(`KIND: who decides this assertion on a replay. "judge" (the default): the LLM judge reads the run. "code": the code below decides every replay by itself, and never returns "defer". "hybrid": the code decides what a program can read and returns "defer" to hand the rest to the LLM judge. Send "code" or "hybrid" with code to write the code yourself. To have Bitfab write it, send "code" or "hybrid" with no code, on a new assertion or one that has no code yet: before this call returns, Bitfab checks the wording against the writing rules (unless guidedRewrite is false), writes code of the kind you asked for, and runs it on this trace. The response says whether it wrote working code; when it could not, the assertion is saved without code and the LLM judge decides it. At most ${MAX_CODE_DRAFTS_PER_SAVE} assertions per call can ask Bitfab for code. On an edit, omit it to keep the current kind, and pass "judge" to remove the code.`);
29203
29204
  var assertionCodeShape = external_exports.object({
29204
29205
  source: external_exports.string().trim().min(1).max(2e4).describe('Body of an async TypeScript function (plain JavaScript also works) called with `spans` (every span of the run in start order, each { name, index, hasData } without its data), `input`, and `output` (the run\'s root input and output). Read span data with `await named("span name")`, which returns the spans with that name with { name, index, input, output, metadata }, or `await span.data()`. Count or order spans from `spans` without loading data. It returns "pass", "fail", or "defer", or { result, reason } with a short reason. Only a hybrid assertion returns "defer": when the part the code can read holds and the rest needs reading what text means, so the LLM judge decides it. Copy ids, recipients, and times from the trace as literals, never match the wording of prose, and guard every read so it never throws on a missing field. It runs in a sandbox with no network, files, or timers, gets one second of compute, and may load the data of at most 50 spans within ten seconds.'),
29205
29206
  spanNames: external_exports.array(external_exports.string().min(1)).max(50).describe("Every span name the code expects a correct run to produce. Leave out names it only checks did not run. When one of these is missing from a replay and from the other replays sampled for the same function, the code is reported as broken rather than failing the replay.")
@@ -29274,7 +29275,7 @@ var generateTraceAssertions = {
29274
29275
  var saveTraceAssertions = {
29275
29276
  name: "save_trace_assertions",
29276
29277
  title: "Save Trace Assertions",
29277
- description: `Record what SHOULD happen when this trace is replayed. Bitfab stores two kinds of record on a trace. A VERDICT says how a run that already happened turned out, and that is save_agent_verdicts / save_human_verdicts. An ASSERTION, which is what this tool writes, says what a correct run looks like for THIS specific input, carries no pass/fail of its own, and is checked against a later replay once a reviewer approves it. A trace holds any number of assertions, and each verdict is recorded on one of them. Call it when the user describes the right answer for a particular case, for example "this booking should have picked the 6am flight, not the 9am". This is not a verdict on a run that already happened, which is save_agent_verdicts, and it is not a check that applies to every trace of a function, which is save_grader. Pass \`assertion\` plus optional \`passCriteria\` / \`failCriteria\`, the same trio save_grader takes, so an assertion that proves out across many traces can later be promoted into a grader with no rewriting. \`humanNote\` stores people-only context on the assertion; preserve and return it, but never use it to judge whether a replay passed. \`assigneeEmail\` names the member who should review it, which routes the assertion to that person without deciding anything, so it never changes the approval state. Pass an entry's \`id\` to edit an existing assertion, or omit it to add a new one, so two callers adding different assertions to one trace never overwrite each other. What this tool writes is saved awaiting review, so nothing checks it yet; a reviewer approves it, in Bitfab or with \`approvalState\` on a later call here, and from then on every replay of the trace is judged against it. \`approvalState\` decides an assertion that already exists, so deciding one is \`{ id, approvalState }\` with nothing else: an omitted \`assertion\` keeps the current wording. It is refused on a new assertion, so the call that invents a claim is never the call that puts it into force. One decision covers the assertion and the category it is filed under, so set \`category_id\` and \`approvalState\` in the same entry when you are deciding both; recategorizing on a later call without deciding returns it to not reviewed, since the approval covered the old category. What it gates is whether replays check the assertion at all, so decide from the assertion and the spans it cites rather than from memory of having written it. Rewording an assertion, or changing its criteria, target, or category, returns it to not reviewed unless the same call says otherwise. Call get_trace_assertions first to find the assertion to edit and to avoid creating a duplicate, and read them back before judging a replay, where it lists the approved ones by default. Pass it \`approvalStates: ["pending"]\` to read back drafts awaiting review, including the ones you just wrote. Each assertion with new text is checked against the writing rules and rewritten when it breaks one, unless \`guidedRewrite\` is false, so read the response for what was saved and for any claim to save separately. Up to ${MAX_ASSERTIONS_PER_REQUEST} per call.`,
29278
+ description: `Record what SHOULD happen when this trace is replayed. Bitfab stores two kinds of record on a trace. A VERDICT says how a run that already happened turned out, and that is save_agent_verdicts / save_human_verdicts. An ASSERTION, which is what this tool writes, says what a correct run looks like for THIS specific input, carries no pass/fail of its own, and is checked against a later replay once a reviewer approves it. A trace holds any number of assertions, and each verdict is recorded on one of them. Call it when the user describes the right answer for a particular case, for example "this booking should have picked the 6am flight, not the 9am". This is not a verdict on a run that already happened, which is save_agent_verdicts, and it is not a check that applies to every trace of a function, which is save_grader. Pass \`assertion\` plus optional \`passCriteria\` / \`failCriteria\`, the same trio save_grader takes, so an assertion that proves out across many traces can later be promoted into a grader with no rewriting. \`humanNote\` stores people-only context on the assertion; preserve and return it, but never use it to judge whether a replay passed. \`assigneeEmail\` names the member who should review it, which routes the assertion to that person without deciding anything, so it never changes the approval state. Pass an entry's \`id\` to edit an existing assertion, or omit it to add a new one, so two callers adding different assertions to one trace never overwrite each other. What this tool writes is saved awaiting review, so nothing checks it yet; a reviewer approves it, in Bitfab or with \`approvalState\` on a later call here, and from then on every replay of the trace is judged against it. \`approvalState\` decides an assertion that already exists, so deciding one is \`{ id, approvalState }\` with nothing else: an omitted \`assertion\` keeps the current wording. It is refused on a new assertion, so the call that invents a claim is never the call that puts it into force. One decision covers the assertion and the category it is filed under, so set \`category_id\` and \`approvalState\` in the same entry when you are deciding both; recategorizing on a later call without deciding returns it to not reviewed, since the approval covered the old category. What it gates is whether replays check the assertion at all, so decide from the assertion and the spans it cites rather than from memory of having written it. Rewording an assertion, or changing its criteria, target, or category, returns it to not reviewed unless the same call says otherwise. Call get_trace_assertions first to find the assertion to edit and to avoid creating a duplicate, and read them back before judging a replay, where it lists the approved ones by default. Pass it \`approvalStates: ["pending"]\` to read back drafts awaiting review, including the ones you just wrote. Each assertion with new text is checked against the writing rules and rewritten when it breaks one, unless \`guidedRewrite\` is false, so read the response for what was saved and for any claim to save separately. To make an assertion a code assertion without writing the code, send \`kind\` "code" or "hybrid" with no \`code\`: Bitfab rewrites the wording and writes and runs the code before this call returns, keeping the kind you asked for, and says in the response when it could not write working code. Up to ${MAX_ASSERTIONS_PER_REQUEST} per call.`,
29278
29279
  inputSchema: {
29279
29280
  traceId: external_exports.uuid().describe("The ORIGINAL trace to attach assertions to. A replay trace id is refused, and the error names the original to retry with, because a replay reads its original's assertions automatically."),
29280
29281
  assertions: external_exports.preprocess(parseJsonString, external_exports.array(external_exports.object({
@@ -29623,10 +29624,10 @@ var scenarioTargetSchema = {
29623
29624
  var listScenarios = {
29624
29625
  name: "list_scenarios",
29625
29626
  title: "List Scenarios",
29626
- description: `List scenarios, newest first, with each one's id, name, trace function, and review status: needs updating (a person flagged the scenario itself as wrong or incomplete, for example missing history or records), updated (the flag was resolved and waits for the person to check the fix), needs label, drafting (assertions are being drafted from the label), drafting failed, no assertions (the draft found nothing checkable), needs review (drafted assertions wait for approval), or done. A scenario that needs updating is printed with its note. Pass queue "needs_updating" to find the scenarios people flagged for fixing, then read each with get_scenario and fix it with save_scenario, sending needsUpdatingResolution to say what you changed. That puts it back in the person's inbox, under needs review, to check. Returns a cursor when more remain.`,
29627
+ description: `List scenarios, newest first, with each one's id, name, trace function, and review status: needs updating (a person flagged the scenario itself as wrong or incomplete, for example missing history or records), updated (the flag was resolved and waits for the person to check the fix), needs label, drafting (assertions are being drafted from the label), drafting failed, no assertions (the draft found nothing checkable), needs review (drafted assertions wait for approval), done, or waiting on data (the organization has a scenario callback and it has not filled the scenario's data yet, so the scenario stays out of the inbox until the data arrives or a person labels it anyway). A scenario that needs updating is printed with its note. Pass queue "needs_updating" to find the scenarios people flagged for fixing, then read each with get_scenario and fix it with save_scenario, sending needsUpdatingResolution to say what you changed. That puts it back in the person's inbox, under needs review, to check. Returns a cursor when more remain.`,
29627
29628
  inputSchema: {
29628
29629
  traceFunctionKey: external_exports.string().min(1).optional().describe("Key of the trace function whose scenarios to list. Leave it out to list every trace function's."),
29629
- queue: external_exports.enum(["inbox", "needs_label", "needs_review", "needs_updating", "done"]).optional().describe("inbox: waiting on a person, everything in needs_label and needs_review. needs_label: needs a label, or its draft failed and the label needs sending again. needs_review: drafting, drafted assertions waiting for approval, a draft that found nothing to check, or a resolved update waiting to be checked. needs_updating: a person flagged the scenario itself with a note. done: every assertion reviewed, or accepted with none. Leave it out to list all."),
29630
+ queue: external_exports.enum(["inbox", "needs_label", "needs_review", "needs_updating", "done"]).optional().describe("inbox: waiting on a person, everything in needs_label and needs_review. needs_label: needs a label, or its draft failed and the label needs sending again. needs_review: drafting, drafted assertions waiting for approval, a draft that found nothing to check, or a resolved update waiting to be checked. needs_updating: a person flagged the scenario itself with a note. done: every assertion reviewed, or accepted with none. Scenarios waiting on data are in no queue. Leave it out to list all."),
29630
29631
  cursor: external_exports.string().min(1).optional().describe("The cursor a previous call returned, to read the next page."),
29631
29632
  limit: external_exports.number().int().min(1).max(100).optional().describe("How many scenarios to return, up to 100. Defaults to 25.")
29632
29633
  }
@@ -31134,10 +31135,10 @@ var semver2 = __toESM(require_semver2(), 1);
31134
31135
 
31135
31136
  // ../bitfab-plugin-lib/dist/bakedSdkVersions.js
31136
31137
  var BAKED_SDK_VERSIONS = {
31137
- typescript: "0.74.4",
31138
- python: "0.74.3",
31139
- ruby: "0.74.0",
31140
- go: "0.74.0"
31138
+ typescript: "0.74.5",
31139
+ python: "0.74.4",
31140
+ ruby: "0.74.1",
31141
+ go: "0.74.1"
31141
31142
  };
31142
31143
 
31143
31144
  // ../bitfab-plugin-lib/dist/installedSdk.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bitfab-cli",
3
- "version": "0.2.508",
3
+ "version": "0.2.510",
4
4
  "description": "Install and configure the Bitfab plugin in Claude Code, Codex, or Cursor, or the Bitfab skill pack in Amp (Alpha).",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",