@intentic/sandbox-contract 1.246.1 → 1.248.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/batch-runs.d.ts +2 -0
- package/dist/batch-runs.d.ts.map +1 -1
- package/dist/batch-runs.js +1 -0
- package/dist/batch-runs.js.map +1 -1
- package/dist/contracts/agent.contract.d.ts +20 -0
- package/dist/contracts/agent.contract.d.ts.map +1 -1
- package/dist/contracts/personas.contract.d.ts +38 -4
- package/dist/contracts/personas.contract.d.ts.map +1 -1
- package/dist/contracts/personas.contract.js +10 -1
- package/dist/contracts/personas.contract.js.map +1 -1
- package/dist/contracts/runner.contract.d.ts +93 -93
- package/dist/contracts/settings.contract.d.ts +109 -12
- package/dist/contracts/settings.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.d.ts +22 -0
- package/dist/contracts/usage.contract.d.ts.map +1 -1
- package/dist/contracts/usage.contract.js +19 -0
- package/dist/contracts/usage.contract.js.map +1 -1
- package/dist/definition.d.ts +20 -24
- package/dist/definition.d.ts.map +1 -1
- package/dist/fast-tier.js +1 -1
- package/dist/fast-tier.js.map +1 -1
- package/dist/index.d.ts +191 -19
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -3
- package/dist/index.js.map +1 -1
- package/dist/model-pins.d.ts +15 -0
- package/dist/model-pins.d.ts.map +1 -0
- package/dist/model-pins.js +22 -0
- package/dist/model-pins.js.map +1 -0
- package/dist/model-roles.d.ts +172 -0
- package/dist/model-roles.d.ts.map +1 -0
- package/dist/model-roles.js +167 -0
- package/dist/model-roles.js.map +1 -0
- package/dist/schemas/agent.d.ts +22 -2
- package/dist/schemas/agent.d.ts.map +1 -1
- package/dist/schemas/agent.js +4 -2
- package/dist/schemas/agent.js.map +1 -1
- package/dist/schemas/automations.d.ts.map +1 -1
- package/dist/schemas/automations.js.map +1 -1
- package/dist/schemas/personas.d.ts +48 -4
- package/dist/schemas/personas.d.ts.map +1 -1
- package/dist/schemas/personas.js +28 -5
- package/dist/schemas/personas.js.map +1 -1
- package/dist/schemas/plan-limits.d.ts +20 -0
- package/dist/schemas/plan-limits.d.ts.map +1 -1
- package/dist/schemas/plan-limits.js +21 -0
- package/dist/schemas/plan-limits.js.map +1 -1
- package/dist/schemas/settings.d.ts +88 -6
- package/dist/schemas/settings.d.ts.map +1 -1
- package/dist/schemas/settings.js +19 -23
- package/dist/schemas/settings.js.map +1 -1
- package/dist/schemas/usage.d.ts +5 -0
- package/dist/schemas/usage.d.ts.map +1 -1
- package/dist/schemas/usage.js +5 -0
- package/dist/schemas/usage.js.map +1 -1
- package/dist/workspace-state.d.ts +0 -5
- package/dist/workspace-state.d.ts.map +1 -1
- package/dist/workspace-state.js +0 -1
- package/dist/workspace-state.js.map +1 -1
- package/package.json +4 -4
- package/src/agent-catalog.ts +1 -1
- package/src/batch-runs.test.ts +10 -5
- package/src/batch-runs.ts +10 -3
- package/src/chores/chores.ts +1 -1
- package/src/chores/verdict.test.ts +2 -2
- package/src/chores/verdict.ts +3 -3
- package/src/contracts/personas.contract.ts +17 -0
- package/src/contracts/usage.contract.ts +31 -0
- package/src/events.ts +1 -1
- package/src/fast-tier.test.ts +1 -1
- package/src/fast-tier.ts +5 -5
- package/src/index.ts +2 -3
- package/src/model-pins.test.ts +121 -0
- package/src/model-pins.ts +132 -0
- package/src/model-roles.test.ts +52 -0
- package/src/model-roles.ts +320 -0
- package/src/plan-pools.ts +1 -1
- package/src/prompt-complexity.test.ts +1 -1
- package/src/prompt-complexity.ts +2 -2
- package/src/provider-specs.test.ts +1 -1
- package/src/schemas/agent.ts +42 -17
- package/src/schemas/agents.ts +2 -2
- package/src/schemas/automations.ts +6 -2
- package/src/schemas/personas.ts +85 -18
- package/src/schemas/plan-limits.ts +50 -0
- package/src/schemas/settings.ts +92 -98
- package/src/schemas/usage.ts +59 -0
- package/src/workspace-state.test.ts +0 -1
- package/src/workspace-state.ts +0 -6
- package/dist/agent-run-model.d.ts +0 -4
- package/dist/agent-run-model.d.ts.map +0 -1
- package/dist/agent-run-model.js +0 -13
- package/dist/agent-run-model.js.map +0 -1
- package/dist/quick-model.d.ts +0 -15
- package/dist/quick-model.d.ts.map +0 -1
- package/dist/quick-model.js +0 -39
- package/dist/quick-model.js.map +0 -1
- package/dist/schemas/context.d.ts +0 -30
- package/dist/schemas/context.d.ts.map +0 -1
- package/dist/schemas/context.js +0 -34
- package/dist/schemas/context.js.map +0 -1
- package/src/agent-run-model.test.ts +0 -76
- package/src/agent-run-model.ts +0 -65
- package/src/quick-model.test.ts +0 -158
- package/src/quick-model.ts +0 -162
- package/src/schemas/context.ts +0 -87
package/src/schemas/settings.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// settings: per-sandbox agent settings (.intentic/config/settings.json)
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { CommandJudgeModeSchema } from "../safety-policy.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ModelRoleSchema } from "../model-roles.js";
|
|
5
|
+
import { AdmissionPolicySchema, AdmissionRuleSchema, ModelPinSchema } from "./agent.js";
|
|
5
6
|
// Which prompt the agent is, before this turn composes anything on top. Two built-in bases and an escape
|
|
6
7
|
// hatch: Intentic's own (the default), Claude Code's preset, or the owner's text. Declared out here rather
|
|
7
8
|
// than inline in the settings object because both sides of the wire branch on it, the daemon to build the
|
|
@@ -262,6 +263,8 @@ export const SkillRemoveSchema = z.object({
|
|
|
262
263
|
// workspaceMap , computes an AREA index of the project a run starts in and prepends it to the
|
|
263
264
|
// conversation's opening message, so the turn does not have to buy its own orientation
|
|
264
265
|
// with a directory listing. Generated from the filesystem every time, never stored.
|
|
266
|
+
// workspaceMapHoldout, conversation-level measurement control for workspaceMap (UsageTurn.mapArm), judged on
|
|
267
|
+
// the directory listings the opening turn ran rather than on its searches.
|
|
265
268
|
// sidecars , the background pass converging a markdown shadow of every binary workspace file
|
|
266
269
|
// (docx/pdf/images/audio → .intentic/local/cache/derived/) the moment it lands, via
|
|
267
270
|
// the baked fileq CLI, so reasoning-time reads are pre-derived. The CLI itself is
|
|
@@ -304,17 +307,21 @@ export const SandboxSettingsSchema = z.object({
|
|
|
304
307
|
"Keep the instructions identical between turns so the provider can cache them, moving anything that varies into the message instead. Cheaper, at the cost of some flexibility.",
|
|
305
308
|
),
|
|
306
309
|
skills: z.array(z.string()).default(["lsp", "fileq"]).describe("Which skills are switched on."),
|
|
307
|
-
/*
|
|
308
|
-
*
|
|
309
|
-
*
|
|
310
|
-
*
|
|
311
|
-
*
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
310
|
+
/* WHETHER A NEW CHAT IS ROUTED ONTO A PERSONA, and how far the answer goes without a press. The router is
|
|
311
|
+
* the `persona-router` helper role (model-roles.ts): it reads the first message and one line per card and
|
|
312
|
+
* names one card or none, once per chat, before the first turn (the sandbox's agent/persona-router.ts).
|
|
313
|
+
* off — never asked. A chat wears the persona the user picked, or none.
|
|
314
|
+
* suggest — asked, and the answer is a chip on the composer that the user presses to apply. The default:
|
|
315
|
+
* a persona takes accounts and repositories AWAY from a chat, and the first time that happens
|
|
316
|
+
* it should happen because somebody pressed it.
|
|
317
|
+
* auto — the answer is applied when the message is sent, unless the chip was dismissed first.
|
|
318
|
+
* Attended chats only, whatever this says: a wake nobody is watching names its persona on its own form,
|
|
319
|
+
* and routing one onto a card would GRANT it accounts the owner never named for it. */
|
|
320
|
+
personaRouting: z
|
|
321
|
+
.enum(["off", "suggest", "auto"])
|
|
322
|
+
.default("suggest")
|
|
316
323
|
.describe(
|
|
317
|
-
"
|
|
324
|
+
"Whether a new chat is matched to one of your personas from its first message. Suggest shows the match on the composer for you to press; auto applies it when you send unless you dismiss it first. Never applies to unwatched runs, which name their persona themselves.",
|
|
318
325
|
),
|
|
319
326
|
hashlineEdits: z
|
|
320
327
|
.boolean()
|
|
@@ -388,6 +395,21 @@ export const SandboxSettingsSchema = z.object({
|
|
|
388
395
|
.describe(
|
|
389
396
|
"Open every conversation with a map of the project it starts in: what is in it, what each part is for, and where the agent is standing. Worked out fresh each time rather than written down anywhere, because a written layout is wrong within a fortnight. Off by default, since it spends tokens on the first message of every conversation.",
|
|
390
397
|
),
|
|
398
|
+
/* Measurement control for the map, at CONVERSATION level for the plainest of reasons: the note is sent on
|
|
399
|
+
* the opening message, so every later turn of a mapped conversation has a map in its transcript and a
|
|
400
|
+
* per-turn flip would call eleven treated turns controls.
|
|
401
|
+
*
|
|
402
|
+
* Judged on `UsageTurn.openingListings` and read on each conversation's opening turn (usage/turn-experiments.ts),
|
|
403
|
+
* because that is the turn the note was sent to and averaging it across a long conversation divides the
|
|
404
|
+
* effect by the conversation's length. 0 ⇒ no measurement and every conversation receives the map. */
|
|
405
|
+
workspaceMapHoldout: z
|
|
406
|
+
.number()
|
|
407
|
+
.min(0)
|
|
408
|
+
.max(1)
|
|
409
|
+
.default(0)
|
|
410
|
+
.describe(
|
|
411
|
+
"What share of conversations to open without the map, so the two can be compared. Whole conversations rather than individual turns, because the map is sent once and stays in the conversation's history afterwards.",
|
|
412
|
+
),
|
|
391
413
|
/* THE MARKDOWN SHADOWS OF BINARY FILES, the eager half of fileq (_sandbox/fileq). The lazy half — the
|
|
392
414
|
* `fileq` CLI an agent runs mid-task — is always on PATH and gated only by its skill; this switch is
|
|
393
415
|
* about the BACKGROUND pass: the daemon watching /work and converging a sidecar under
|
|
@@ -441,26 +463,40 @@ export const SandboxSettingsSchema = z.object({
|
|
|
441
463
|
.max(1)
|
|
442
464
|
.default(0)
|
|
443
465
|
.describe("What share of commands to leave untrimmed, so the saving can be measured against a real comparison rather than estimated."),
|
|
444
|
-
/*
|
|
445
|
-
*
|
|
446
|
-
*
|
|
447
|
-
*
|
|
448
|
-
*
|
|
449
|
-
*
|
|
450
|
-
*
|
|
451
|
-
*
|
|
452
|
-
*
|
|
453
|
-
*
|
|
454
|
-
*
|
|
455
|
-
*
|
|
456
|
-
*
|
|
457
|
-
*
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
466
|
+
/* WHICH MODEL DOES WHICH JOB, one ordered list per ROLE (model-roles.ts declares them all).
|
|
467
|
+
*
|
|
468
|
+
* ONE KEY RATHER THAN SEVENTEEN, and the record is keyed by the role catalog rather than by free strings: a
|
|
469
|
+
* job that starts choosing a model tomorrow becomes configurable by adding a row to that table, and the
|
|
470
|
+
* settings page, the resolver and the daemon's lookup all follow without a schema change. Seventeen named
|
|
471
|
+
* fields here would be the same table written a fourth time, in the one place where getting it out of step
|
|
472
|
+
* spends somebody's money.
|
|
473
|
+
*
|
|
474
|
+
* IT REPLACED THREE BUNDLED KEYS — `quickModel`, `agentRunModels` and `commandJudgeModels` — and the reason
|
|
475
|
+
* is worth keeping: the first two were grouped by assumed INTENSITY, not by job. "Quick" covered commit
|
|
476
|
+
* messages, session titles and loop verdicts at once, so an owner who wanted better commit subjects could
|
|
477
|
+
* not ask for them without also moving every session title onto the same model; "agent runs" covered a
|
|
478
|
+
* production incident and a documentation sweep with one tier. An intensity is a guess about work its owner
|
|
479
|
+
* knows better, and neither the configuration nor the UI was actually saving anyone anything by making it.
|
|
480
|
+
*
|
|
481
|
+
* EACH LIST IS AN ORDERED LADDER of pins, tried top to bottom, because the interesting failure is a model
|
|
482
|
+
* that is connected and will not answer today: the account's allowance went on the chat, and one spent
|
|
483
|
+
* provider takes that job down for hours while the others sit idle.
|
|
484
|
+
*
|
|
485
|
+
* AN ABSENT OR EMPTY LIST IS THE JOB SWITCHED OFF, and nothing is derived to fill it. A one-shot helper
|
|
486
|
+
* used to fall to an "Auto ladder" worked out from whatever was connected, which meant a sandbox nobody
|
|
487
|
+
* had configured still spent an account on every commit subject, every session title and every safety
|
|
488
|
+
* verdict, on a ranking this repo invented and re-ranked whenever an account was added. Not set now means
|
|
489
|
+
* not set: no auto-selection and no recommendation. A one-shot with no list does not run; a whole session
|
|
490
|
+
* with no list opens on the model the owner picked for their own chat, which is a choice they made rather
|
|
491
|
+
* than one this schema guessed. */
|
|
492
|
+
// `partialRecord`, not `record`: an exhaustive one would make every role a required key, so a settings file
|
|
493
|
+
// that has never been touched would have to spell out seventeen empty arrays to be valid, and adding a role
|
|
494
|
+
// would invalidate every settings file in existence. An absent key IS the answer "this role has no list".
|
|
495
|
+
modelRoles: z
|
|
496
|
+
.partialRecord(ModelRoleSchema, z.array(ModelPinSchema).max(10))
|
|
497
|
+
.default({})
|
|
462
498
|
.describe(
|
|
463
|
-
"Which models do
|
|
499
|
+
"Which models do which job, one ordered list per job: commit messages, session titles, the safety judge, pipeline fixes, and every other place this sandbox picks a model for you. Tried in order, so one spent account does not take a job down. Nothing is chosen for you: a one-shot job with no list does not run, and a whole session with no list opens on whatever your own chat is set to.",
|
|
464
500
|
),
|
|
465
501
|
/* WHICH REPOS KEEP A CHANGELOG, the repos whose commits carry a `Release-Note:` trailer, written by the
|
|
466
502
|
* same quick model that drafts the subject (git/commit-message.ts) and harvested at release time.
|
|
@@ -482,40 +518,6 @@ export const SandboxSettingsSchema = z.object({
|
|
|
482
518
|
.describe(
|
|
483
519
|
"Which repositories keep a changelog, and so get a user-facing note written alongside each merge. A list rather than a switch, and empty by default, because the commit writer's standing rule is to copy the house style rather than impose one, and a repository that has never written such a note gives it nothing to copy.",
|
|
484
520
|
),
|
|
485
|
-
/* WHAT AN AGENT RUN OPENS ON, the tier above quickModel, and the answer for every turn a SURFACE starts
|
|
486
|
-
* rather than a person at a composer: Fix with agent on a pipeline or a deployment, a Maintenance chore, a
|
|
487
|
-
* Documentation or Acceptance run, the fix a failed pre-push check proposes. An ORDERED list of PINS, each
|
|
488
|
-
* naming a provider and model AND how that one is to be run (AgentRunPinSchema); EMPTY ⇒ whatever the chat
|
|
489
|
-
* composer would have started with, which is the honest floor because it is the model the user already
|
|
490
|
-
* chose to work with.
|
|
491
|
-
*
|
|
492
|
-
* EACH ENTRY CARRIES ITS OWN REASONING AND COST KNOBS, which is why these are objects rather than the
|
|
493
|
-
* `${provider}:${model}` keys the two lists around them still hold. The effort used to be one field beside
|
|
494
|
-
* the list, answering for every model in it, and the entries of this list are the least interchangeable
|
|
495
|
-
* things on the page: the head is the tier the owner wants the work done at and what follows it is the
|
|
496
|
-
* account that catches it when the first is spent. AgentRunPinSchema has the rest of the argument.
|
|
497
|
-
*
|
|
498
|
-
* A LIST, for the reason quickModel is one: the account at the head runs out, and every surface-started run
|
|
499
|
-
* in the sandbox then fails on a credential the user cannot see from the row they pressed. Written in order,
|
|
500
|
-
* the next one down catches it (turn-resume.ts walks it).
|
|
501
|
-
*
|
|
502
|
-
* PINNED, NOT DERIVED, the deliberate difference from quickModel one line above, and the reason these are
|
|
503
|
-
* two settings rather than one. A quick helper exists to stay OFF the frontier tier, so cheapest-connected
|
|
504
|
-
* is the right automatic answer and an empty list resolves to Auto. An agent run has to read a failing
|
|
505
|
-
* suite, or a container log, or a story, and repair the thing: the tier is a judgement about how much the
|
|
506
|
-
* job is worth, nothing here can make it, and a wrong guess is billed in whole sessions rather than in
|
|
507
|
-
* tokens. So an empty list here resolves to NOTHING and the composer's own pick answers instead.
|
|
508
|
-
*
|
|
509
|
-
* The daemon applies this to any turn flagged `unattended` that names no model of its own, one rule, so a
|
|
510
|
-
* surface added tomorrow inherits it by saying what it is instead of re-deriving where models come from. A
|
|
511
|
-
* surface MAY still name one (the shared run button's caret, Acceptance's per-run pick), and that wins. */
|
|
512
|
-
agentRunModels: z
|
|
513
|
-
.array(AgentRunPinSchema)
|
|
514
|
-
.max(10)
|
|
515
|
-
.default([])
|
|
516
|
-
.describe(
|
|
517
|
-
"Which models run the work a screen starts rather than a person: fixing a red pipeline, a maintenance chore, an acceptance run. Tried in order, so one spent account does not take every such run down, and each entry says how hard that model should think as well as which one it is. Empty falls back to whatever the chat would have used, which is the honest floor because it is the model you already chose to work with.",
|
|
518
|
-
),
|
|
519
521
|
/* AUTOMATIC TIER SELECTION: may the daemon run an easy-looking turn on a cheaper rung of the provider the
|
|
520
522
|
* user is already on, instead of on the model they picked?
|
|
521
523
|
*
|
|
@@ -558,9 +560,9 @@ export const SandboxSettingsSchema = z.object({
|
|
|
558
560
|
"How readily a turn counts as simple enough for the cheaper model. It moves only the cutoff: at every setting a turn still has to say something positively easy, so nothing here can downgrade a short vague request.",
|
|
559
561
|
),
|
|
560
562
|
/* WHICH CHEAP MODEL A DOWNGRADED TURN LANDS ON, an ordered list of `${provider}:${model}` keys
|
|
561
|
-
* (
|
|
563
|
+
* (modelPinKey), or EMPTY for Auto.
|
|
562
564
|
*
|
|
563
|
-
* Empty is the default and the interesting case, exactly as
|
|
565
|
+
* Empty is the default and the interesting case, exactly as a one-shot role's is: Auto is the cheapest row the
|
|
564
566
|
* turn's own provider publishes, read through the same cheap-end order (compareCheapestFirst), so the two
|
|
565
567
|
* features can never disagree about which rung is the cheap one, and connecting an account tomorrow
|
|
566
568
|
* improves the answer by itself.
|
|
@@ -724,35 +726,13 @@ export const SandboxSettingsSchema = z.object({
|
|
|
724
726
|
* entitled to say so, and before this they could not: the old rulebook could be set to allow everything, and
|
|
725
727
|
* the redesign quietly made itself the one part of the sandbox you could only opt further into.
|
|
726
728
|
*
|
|
727
|
-
*
|
|
728
|
-
*
|
|
729
|
-
* commit message
|
|
730
|
-
*
|
|
731
|
-
* should have been. */
|
|
729
|
+
* WHICH MODEL judges is not answered here: it is the `safety-judge` role in `modelRoles`, like every other
|
|
730
|
+
* job in this sandbox that picks one. It used to need its own key, on the argument that a verdict is worth a
|
|
731
|
+
* different model than a commit message — true, and the fact that it had to be argued for one job at a time
|
|
732
|
+
* is exactly what the role catalog replaced. */
|
|
732
733
|
commandJudge: CommandJudgeModeSchema.default("on").describe(
|
|
733
734
|
"Whether a model reads your safety policy before a flagged command runs. Off judges nothing and asks about nothing; Watch judges everything and records it without ever interrupting you, which is how you find out what your policy actually does before you let it stop anything; On lets the verdict decide. Wiping a disk or deleting under /history asks at every setting — that rule is typed rather than judged, and cannot be turned off.",
|
|
734
735
|
),
|
|
735
|
-
/* WHICH MODEL READS THE POLICY, an ordered list of `${provider}:${modelId}` keys (quickModelKey) walked top
|
|
736
|
-
* to bottom, or EMPTY for whatever the quick model would be.
|
|
737
|
-
*
|
|
738
|
-
* A LIST, for the reason every other model setting here is one: the head runs out and the whole feature goes
|
|
739
|
-
* with it. Falling back to the quick chain rather than to Auto is deliberate — it is what this did before the
|
|
740
|
-
* setting existed, so an owner who never opens the row keeps exactly the behaviour they had, and one who
|
|
741
|
-
* writes an entry is saying that command verdicts are worth a different model than commit messages.
|
|
742
|
-
*
|
|
743
|
-
* THE ARGUMENT FOR SETTING IT AT ALL, since the cheapest connected rung is the default: this prompt is the
|
|
744
|
-
* one quick job that is genuinely adversarial. Its input includes text the agent is about to run, which may
|
|
745
|
-
* have arrived from a stranger's web page, and a small model can be talked round by it (command-judge.ts is
|
|
746
|
-
* candid about that). It is also the job where being WRONG is expensive in both directions — a needless card
|
|
747
|
-
* teaches the owner to click through the next one. Neither is a reason for us to spend somebody's frontier
|
|
748
|
-
* allowance by default; both are reasons for them to be able to. */
|
|
749
|
-
commandJudgeModels: z
|
|
750
|
-
.array(z.string())
|
|
751
|
-
.max(10)
|
|
752
|
-
.default([])
|
|
753
|
-
.describe(
|
|
754
|
-
"Which models decide whether a flagged command should run, tried in order so one spent account does not take the gate down. Empty uses whatever the quick model is, which is what this did before the setting existed.",
|
|
755
|
-
),
|
|
756
736
|
/* HOW MUCH AN AGENT MAY DELEGATE, the three ceilings the Claude Code harness enforces on its own Agent
|
|
757
737
|
* tool, surfaced here because their defaults are tuned for a laptop and this is a container the owner sized.
|
|
758
738
|
*
|
|
@@ -836,10 +816,15 @@ export const SavingsArmSchema = z.object({ turns: z.number(), mean: z.number() }
|
|
|
836
816
|
* `metric` says what `mean` counts and what `deltaPct` is a delta in, and choosing it is most of the work.
|
|
837
817
|
* searchCalls , the search teaching: the searches a turn ran, which the teaching directly changes.
|
|
838
818
|
* openingSearches, the same, narrower: the searches before the turn first touched a file.
|
|
839
|
-
*
|
|
840
|
-
*
|
|
819
|
+
* openingListings , the project map: the directory listings a turn ran to work out where it was, which is
|
|
820
|
+
* what the map hands over and what its note tells the turn not to go and fetch.
|
|
821
|
+
* callsBeforeTarget, the map again, on value rather than compliance: how far the turn walked before
|
|
822
|
+
* touching a file it went on to edit.
|
|
823
|
+
* Neither mechanism may be judged on COST. Cost is a whole turn's work, both of these move one part of it, and
|
|
824
|
+
* the part sits inside the noise of the rest. The map's whole payload is about 200 tokens, so a cost reading
|
|
825
|
+
* would be measuring a quantity two orders of magnitude under its own error bar. */
|
|
841
826
|
export const TurnMetricReadingSchema = z.object({
|
|
842
|
-
metric: z.enum(["searchCalls", "openingSearches"]),
|
|
827
|
+
metric: z.enum(["searchCalls", "openingSearches", "openingListings", "callsBeforeTarget"]),
|
|
843
828
|
on: SavingsArmSchema,
|
|
844
829
|
off: SavingsArmSchema,
|
|
845
830
|
/* HOW MUCH LONGER, when the margin spans zero and the honest answer is "keep collecting": the additional
|
|
@@ -896,9 +881,14 @@ export const TurnExperimentSchema = z.object({
|
|
|
896
881
|
// counts toward the daemon's real threshold instead of a number the browser guessed. Shared by every
|
|
897
882
|
// reading: they are the same turns counted differently, so they clear it together.
|
|
898
883
|
minTurns: z.number(),
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
884
|
+
/* The randomized unit behind the arm counts. Turn mechanisms default to turns. Teaching loaded into a
|
|
885
|
+
* provider session randomizes and analyzes whole conversations, so repeated turns are not false replicas.
|
|
886
|
+
*
|
|
887
|
+
* "opening turns" is the third case and belongs to a treatment sent ONCE: the project map rides the first
|
|
888
|
+
* message and nothing after it, so the sample is one turn per conversation rather than an average over
|
|
889
|
+
* the conversation's turns. The distinction is not cosmetic. Averaging a first-turn treatment across a
|
|
890
|
+
* twelve-turn conversation divides its effect by twelve and reports the remainder as noise. */
|
|
891
|
+
sampleUnit: z.enum(["turns", "conversations", "opening turns"]).optional(),
|
|
902
892
|
// Content-addressed treatment version. Present where mixing rows from two instruction revisions would turn
|
|
903
893
|
// one experiment into two unnamed ones; the reader filters to this (latest) cohort.
|
|
904
894
|
cohort: z.string().optional(),
|
|
@@ -942,6 +932,10 @@ export type TierReport = z.infer<typeof TierReportSchema>;
|
|
|
942
932
|
export const SavingsReportSchema = z.object({
|
|
943
933
|
input: InputSavingsSchema,
|
|
944
934
|
search: TurnExperimentSchema.optional(),
|
|
935
|
+
/* The project map's arms, read on opening turns (see TurnExperimentSchema.sampleUnit). Absent under the
|
|
936
|
+
* same rule as `search`: the switch is off, or no holdout is set, and a section that is not there reads as
|
|
937
|
+
* "not measured", which is the truth, where zeros would read as "measured, worth nothing". */
|
|
938
|
+
map: TurnExperimentSchema.optional(),
|
|
945
939
|
// Automatic tier selection's readout, see TierReportSchema. Absent ⇒ nothing was judged in the window.
|
|
946
940
|
tier: TierReportSchema.optional(),
|
|
947
941
|
});
|
package/src/schemas/usage.ts
CHANGED
|
@@ -119,6 +119,65 @@ export const UsageTurnSchema = z.object({
|
|
|
119
119
|
*
|
|
120
120
|
* Absent ⇒ as for `searchCalls`. */
|
|
121
121
|
openingSearches: z.number().optional(),
|
|
122
|
+
/* THE LISTINGS THIS TURN RAN TO WORK OUT WHERE IT WAS, `ls`, `ls /work`, `tree intentic`, the LS tool
|
|
123
|
+
* aimed at the same places (isRootListing owns the rule). What the project map is judged on, and the
|
|
124
|
+
* reason it could not be judged before.
|
|
125
|
+
*
|
|
126
|
+
* `searchCalls` counts a directory listing and a ripgrep as one event, deliberately, so that a taxonomy
|
|
127
|
+
* cannot report whichever spelling of a search the model happened to reach for. That is right for the
|
|
128
|
+
* search teaching and blind to the map: measured over 468 mapped sessions of this workspace against 497
|
|
129
|
+
* unmapped ones, searches before the first file moved +7.6% with a margin of ±17.6pp, while the share of
|
|
130
|
+
* sessions opening with a directory listing fell from 46.3% to 32.1%. The map does not shorten the
|
|
131
|
+
* orientation burst, it changes what the burst is made of, and only this counts the difference.
|
|
132
|
+
*
|
|
133
|
+
* UP TO THE FIRST FILE, exactly like `openingSearches`, which took the corpus to settle. Counted over the
|
|
134
|
+
* whole turn instead, the same sessions give 66.4% against 73.3%, a gap of 6.9pp where the orientation
|
|
135
|
+
* window gives 14.2pp. The dilution is not noise: a turn already at work lists the directory it has
|
|
136
|
+
* narrowed to, and no map could have answered that. The shape of the listing cannot tell the two apart,
|
|
137
|
+
* because it is the same shape; only when it happened can.
|
|
138
|
+
*
|
|
139
|
+
* Absent ⇒ the turn predates this being measured, never a turn that listed nothing. */
|
|
140
|
+
openingListings: z.number().optional(),
|
|
141
|
+
/* TOOL CALLS BEFORE THE TURN FIRST TOUCHED A FILE IT WENT ON TO EDIT: how far it walked before reaching
|
|
142
|
+
* the thing it turned out to be looking for. The corpus study this map was designed from measured the
|
|
143
|
+
* same quantity by hand (the workspace's docs/agent-exploration-patterns.md §4: median 4, mean 8.2) and called it the one
|
|
144
|
+
* honest reading of whether orientation got better.
|
|
145
|
+
*
|
|
146
|
+
* IT CAN ONLY BE KNOWN AT THE END, which is why it is recorded here and computed nowhere else: whether a
|
|
147
|
+
* file was the target is a fact about the turn's edits, and the turn has to finish before that is
|
|
148
|
+
* decided. The route keeps the first call index per path and intersects it with the edit ledger.
|
|
149
|
+
*
|
|
150
|
+
* Absent on a turn that edited nothing, which is most short turns, and NOT zero: a turn with no target
|
|
151
|
+
* never reached one, and averaging that in as "reached it immediately" would report the turns that did
|
|
152
|
+
* no work as the best targeted. That absence costs the reading three quarters of the population, so it
|
|
153
|
+
* is a metric to accumulate for months rather than a gate to wait on. */
|
|
154
|
+
callsBeforeTarget: z.number().optional(),
|
|
155
|
+
/* WHICH ARM OF THE PROJECT MAP EXPERIMENT this conversation ran (settings.workspaceMapHoldout), and how
|
|
156
|
+
* many characters the note actually cost when it was sent.
|
|
157
|
+
*
|
|
158
|
+
* CONVERSATION-STABLE, and for a plainer reason than the search teaching's: the map is sent once, on the
|
|
159
|
+
* opening message, so every later turn of a mapped conversation is a turn whose transcript holds a map.
|
|
160
|
+
* A per-turn flip would label eleven treated turns as controls.
|
|
161
|
+
*
|
|
162
|
+
* `mapChars` rather than a token estimate, because characters are what the renderer's budget is in
|
|
163
|
+
* (workspace-map.ts caps the note at 2,800) and a tokenizer's answer would vary by model. Present only on
|
|
164
|
+
* the turn that actually sent one, so the ledger says what the feature costs instead of assuming it: the
|
|
165
|
+
* median note over this workspace's own corpus is 795 characters against a ceiling of 2,800.
|
|
166
|
+
*
|
|
167
|
+
* Absent ⇒ no measurement (the holdout is zero, or the row predates it); true/false ⇒ mapped/unmapped. */
|
|
168
|
+
mapArm: z.boolean().optional(),
|
|
169
|
+
mapChars: z.number().optional(),
|
|
170
|
+
/* WHICH TURN OF ITS CONVERSATION THIS WAS, counting from zero, so an opening turn can be recognised from
|
|
171
|
+
* one row instead of inferred from the rows around it.
|
|
172
|
+
*
|
|
173
|
+
* The inference it replaces is wrong at exactly one place and it is the place that matters: a reader
|
|
174
|
+
* windowed to the last seven days would take each conversation's earliest row IN THE WINDOW as its
|
|
175
|
+
* opening turn, so every conversation that started the week before would contribute a mid-conversation
|
|
176
|
+
* turn to a reading about first turns. The project map is sent on turn zero and nowhere else, so that
|
|
177
|
+
* misreading is not an edge case for it, it is the measurement.
|
|
178
|
+
*
|
|
179
|
+
* Absent ⇒ the row predates this, or the turn belonged to no conversation at all. */
|
|
180
|
+
turnIndex: z.number().optional(),
|
|
122
181
|
/* DID THIS TURN FINISH, OR DID IT STOP TALKING. The fields that tell the two apart, and the reason
|
|
123
182
|
* `outcome` alone could never.
|
|
124
183
|
*
|
|
@@ -380,7 +380,6 @@ describe(`VERSIONED_STATE_PATHS`, () => {
|
|
|
380
380
|
`${STATE_DIR}/config/capability-dismissals.json`,
|
|
381
381
|
// The context shelves: which repositories a conversation opened on one carries. A list of names, and
|
|
382
382
|
// the decision about what a session may see, which is what a review is for.
|
|
383
|
-
`${STATE_DIR}/config/context/`,
|
|
384
383
|
/* The two entries the AGENT authors on its own initiative, and the reason `versioned` is not read as
|
|
385
384
|
* config-only. Both are the sandbox acting outward: a draft publishes words under the owner's name,
|
|
386
385
|
* a workspace extension is code that runs in the app and can serve HTTP with the workspace under
|
package/src/workspace-state.ts
CHANGED
|
@@ -738,12 +738,6 @@ const STATE_FILES = [
|
|
|
738
738
|
* behaves, it holds no credential, and it belongs in a pull request, which is also what makes it
|
|
739
739
|
* searchable, since every versioned entry already is. */
|
|
740
740
|
{ path: ".intentic/config/personas/", invalidates: ["personas"], portability: "carry", versioned: true },
|
|
741
|
-
|
|
742
|
-
/* THE CONTEXT SHELVES, one JSON file per shelf (schemas/context.ts): which part of the workspace a
|
|
743
|
-
* conversation opened on it carries. `versioned` and `carry` on the persona card's own argument, a shelf is
|
|
744
|
-
* a list of item ids and holds no credential, and which repositories a session can see is exactly the kind
|
|
745
|
-
* of decision that belongs in a pull request. */
|
|
746
|
-
{ path: ".intentic/config/context/", invalidates: ["context"], portability: "carry", versioned: true },
|
|
747
741
|
] as const satisfies readonly WorkspaceStateFile[];
|
|
748
742
|
|
|
749
743
|
export const WORKSPACE_STATE_FILES: readonly WorkspaceStateFile[] = STATE_FILES;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { type QuickModelSource } from "./quick-model.js";
|
|
2
|
-
import type { AgentRunPin } from "./schemas/agent.js";
|
|
3
|
-
export declare const resolveAgentRunModels: (sources: readonly QuickModelSource[], pinned: readonly AgentRunPin[]) => readonly AgentRunPin[];
|
|
4
|
-
//# sourceMappingURL=agent-run-model.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-model.d.ts","sourceRoot":"","sources":["../src/agent-run-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACxE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AA2CtD,eAAO,MAAM,qBAAqB,YAAa,SAAS,gBAAgB,EAAE,UAAU,SAAS,WAAW,EAAE,KAAG,SAAS,WAAW,EAoBhI,CAAC"}
|
package/dist/agent-run-model.js
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { quickModelKey } from "./quick-model.js";
|
|
2
|
-
export const resolveAgentRunModels = (sources, pinned) => {
|
|
3
|
-
const ready = new Set(sources.filter((source) => source.ready).map((source) => source.provider));
|
|
4
|
-
const requested = pinned.filter((pin) => ready.has(pin.provider));
|
|
5
|
-
const chain = [];
|
|
6
|
-
for (const pin of requested) {
|
|
7
|
-
if (!chain.some((held) => quickModelKey(held) === quickModelKey(pin))) {
|
|
8
|
-
chain.push(pin);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
return chain;
|
|
12
|
-
};
|
|
13
|
-
//# sourceMappingURL=agent-run-model.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-model.js","sourceRoot":"","sources":["../src/agent-run-model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAyB,MAAM,kBAAkB,CAAC;AA4CxE,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,OAAoC,EAAE,MAA8B,EAA0B,EAAE;IAClI,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC;IAIjG,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC;IAQlE,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;YACpE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;IACL,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC,CAAC"}
|
package/dist/quick-model.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { AgentProvider } from "./schemas/agent.js";
|
|
2
|
-
export interface QuickModelSource {
|
|
3
|
-
readonly provider: AgentProvider;
|
|
4
|
-
readonly ready: boolean;
|
|
5
|
-
readonly models: readonly string[];
|
|
6
|
-
}
|
|
7
|
-
export interface QuickModelChoice {
|
|
8
|
-
readonly provider: AgentProvider;
|
|
9
|
-
readonly model: string;
|
|
10
|
-
}
|
|
11
|
-
export declare const quickModelKey: (choice: QuickModelChoice) => string;
|
|
12
|
-
export declare const parsePinned: (pinned: string) => QuickModelChoice | undefined;
|
|
13
|
-
export declare const pinnedModelLabel: (choice: QuickModelChoice) => string;
|
|
14
|
-
export declare const resolveQuickModels: (sources: readonly QuickModelSource[], pinned: readonly string[]) => readonly QuickModelChoice[];
|
|
15
|
-
//# sourceMappingURL=quick-model.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quick-model.d.ts","sourceRoot":"","sources":["../src/quick-model.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA+BxD,MAAM,WAAW,gBAAgB;IAM7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IAGjC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC;AAED,MAAM,WAAW,gBAAgB;IAC7B,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CAC1B;AAID,eAAO,MAAM,aAAa,WAAY,gBAAgB,KAAG,MAA8C,CAAC;AASxG,eAAO,MAAM,WAAW,WAAY,MAAM,KAAG,gBAAgB,GAAG,SAM/D,CAAC;AAOF,eAAO,MAAM,gBAAgB,WAAY,gBAAgB,KAAG,MACyC,CAAC;AAuEtG,eAAO,MAAM,kBAAkB,YAAa,SAAS,gBAAgB,EAAE,UAAU,SAAS,MAAM,EAAE,KAAG,SAAS,gBAAgB,EAa7H,CAAC"}
|
package/dist/quick-model.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { accessFor, modelsFor, PROVIDERS } from "./agent-catalog.js";
|
|
2
|
-
import { ACCESS_COST } from "./provider-specs.js";
|
|
3
|
-
import { compareCheapestFirst, familyOf, tierRankOf } from "./model-order.js";
|
|
4
|
-
export const quickModelKey = (choice) => `${choice.provider}:${choice.model}`;
|
|
5
|
-
export const parsePinned = (pinned) => {
|
|
6
|
-
const separator = pinned.indexOf(`:`);
|
|
7
|
-
if (separator <= 0 || separator === pinned.length - 1) {
|
|
8
|
-
return undefined;
|
|
9
|
-
}
|
|
10
|
-
return { provider: pinned.slice(0, separator), model: pinned.slice(separator + 1) };
|
|
11
|
-
};
|
|
12
|
-
export const pinnedModelLabel = (choice) => modelsFor(choice.provider).find((option) => option.value === choice.model)?.label ?? choice.model;
|
|
13
|
-
const cheapestOf = (source) => source.models.toSorted(compareCheapestFirst)[0];
|
|
14
|
-
const tierOf = (model) => tierRankOf(familyOf(model));
|
|
15
|
-
const providerOrder = (provider) => PROVIDERS.findIndex((entry) => entry.value === provider);
|
|
16
|
-
const METERED_COST = Math.max(...Object.values(ACCESS_COST)) + 1;
|
|
17
|
-
const costOf = (provider) => {
|
|
18
|
-
const access = accessFor(provider);
|
|
19
|
-
return access === undefined ? METERED_COST : ACCESS_COST[access.kind];
|
|
20
|
-
};
|
|
21
|
-
const autoLadder = (sources) => sources
|
|
22
|
-
.filter((source) => source.ready)
|
|
23
|
-
.flatMap((source) => {
|
|
24
|
-
const model = cheapestOf(source);
|
|
25
|
-
return model === undefined ? [] : [{ provider: source.provider, model }];
|
|
26
|
-
})
|
|
27
|
-
.toSorted((left, right) => tierOf(right.model) - tierOf(left.model) ||
|
|
28
|
-
costOf(left.provider) - costOf(right.provider) ||
|
|
29
|
-
providerOrder(left.provider) - providerOrder(right.provider));
|
|
30
|
-
export const resolveQuickModels = (sources, pinned) => {
|
|
31
|
-
const ready = new Set(sources.filter((source) => source.ready).map((source) => source.provider));
|
|
32
|
-
const requested = pinned.flatMap((key) => {
|
|
33
|
-
const choice = parsePinned(key);
|
|
34
|
-
return choice === undefined || !ready.has(choice.provider) ? [] : [choice];
|
|
35
|
-
});
|
|
36
|
-
const chain = [...new Map(requested.map((choice) => [quickModelKey(choice), choice])).values()];
|
|
37
|
-
return chain.length > 0 ? chain : autoLadder(sources);
|
|
38
|
-
};
|
|
39
|
-
//# sourceMappingURL=quick-model.js.map
|
package/dist/quick-model.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"quick-model.js","sourceRoot":"","sources":["../src/quick-model.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
export declare const CONTEXT_ITEM_KINDS: readonly ["repo"];
|
|
3
|
-
export type ContextItemKind = (typeof CONTEXT_ITEM_KINDS)[number];
|
|
4
|
-
export declare const ContextItemIdSchema: z.ZodString;
|
|
5
|
-
export type ContextItemId = z.infer<typeof ContextItemIdSchema>;
|
|
6
|
-
export declare const contextItem: (id: ContextItemId) => {
|
|
7
|
-
readonly kind: ContextItemKind;
|
|
8
|
-
readonly name: string;
|
|
9
|
-
};
|
|
10
|
-
export declare const ContextCapsSchema: z.ZodObject<{
|
|
11
|
-
repos: z.ZodOptional<z.ZodNumber>;
|
|
12
|
-
}, z.core.$strip>;
|
|
13
|
-
export type ContextCaps = z.infer<typeof ContextCapsSchema>;
|
|
14
|
-
export declare const ContextShelfSchema: z.ZodObject<{
|
|
15
|
-
id: z.ZodString;
|
|
16
|
-
label: z.ZodOptional<z.ZodString>;
|
|
17
|
-
pinned: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
18
|
-
allowed: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
19
|
-
denied: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
20
|
-
caps: z.ZodOptional<z.ZodObject<{
|
|
21
|
-
repos: z.ZodOptional<z.ZodNumber>;
|
|
22
|
-
}, z.core.$strip>>;
|
|
23
|
-
}, z.core.$strip>;
|
|
24
|
-
export type ContextShelf = z.infer<typeof ContextShelfSchema>;
|
|
25
|
-
export declare const ContextCompositionSchema: z.ZodObject<{
|
|
26
|
-
shelf: z.ZodOptional<z.ZodString>;
|
|
27
|
-
items: z.ZodArray<z.ZodString>;
|
|
28
|
-
}, z.core.$strip>;
|
|
29
|
-
export type ContextComposition = z.infer<typeof ContextCompositionSchema>;
|
|
30
|
-
//# sourceMappingURL=context.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/schemas/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAoBxB,eAAO,MAAM,kBAAkB,YAAI,MAAM,CAAU,CAAC;AACpD,MAAM,MAAM,eAAe,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAKlE,eAAO,MAAM,mBAAmB,aAK0I,CAAC;AAC3K,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAGhE,eAAO,MAAM,WAAW,OAAQ,aAAa,KAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAGtG,CAAC;AAMF,eAAO,MAAM,iBAAiB;;iBAE5B,CAAC;AACH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAa5D,eAAO,MAAM,kBAAkB;;;;;;;;;iBAW7B,CAAC;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAS9D,eAAO,MAAM,wBAAwB;;;iBAGnC,CAAC;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC,CAAC"}
|
package/dist/schemas/context.js
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { entryId } from "./internal.js";
|
|
3
|
-
export const CONTEXT_ITEM_KINDS = ["repo"];
|
|
4
|
-
const ITEM = /^(repo):[a-zA-Z0-9][a-zA-Z0-9._-]*(\/[a-zA-Z0-9][a-zA-Z0-9._-]*)*$/;
|
|
5
|
-
export const ContextItemIdSchema = z
|
|
6
|
-
.string()
|
|
7
|
-
.min(1)
|
|
8
|
-
.max(200)
|
|
9
|
-
.regex(ITEM)
|
|
10
|
-
.describe("One thing in the workspace a conversation can carry, as `<kind>:<name>`. Today the kind is `repo` and the name is a repository's workspace-relative path.");
|
|
11
|
-
export const contextItem = (id) => {
|
|
12
|
-
const at = id.indexOf(":");
|
|
13
|
-
return { kind: id.slice(0, at), name: id.slice(at + 1) };
|
|
14
|
-
};
|
|
15
|
-
export const ContextCapsSchema = z.object({
|
|
16
|
-
repos: z.number().int().min(0).optional().describe("How many repositories a composition may hold. Absent means as many as the shelf allows."),
|
|
17
|
-
});
|
|
18
|
-
export const ContextShelfSchema = z.object({
|
|
19
|
-
id: entryId.describe("The shelf's id, which is also its file name."),
|
|
20
|
-
label: z.string().max(60).optional().describe("What to call it on screen. Absent falls back to the id."),
|
|
21
|
-
pinned: z.array(ContextItemIdSchema).max(200).default([]).describe("Items every composition from this shelf carries."),
|
|
22
|
-
allowed: z
|
|
23
|
-
.array(ContextItemIdSchema)
|
|
24
|
-
.max(500)
|
|
25
|
-
.default([])
|
|
26
|
-
.describe("Items a composition may carry, in the order they are loaded and shed. The order is the priority; nothing else is."),
|
|
27
|
-
denied: z.array(ContextItemIdSchema).max(200).default([]).describe("Items no composition from this shelf carries, whatever else says so."),
|
|
28
|
-
caps: ContextCapsSchema.optional().describe("How many of each kind a composition may hold."),
|
|
29
|
-
});
|
|
30
|
-
export const ContextCompositionSchema = z.object({
|
|
31
|
-
shelf: entryId.optional().describe("Which shelf this pick was made from. Absent when the items were set without one."),
|
|
32
|
-
items: z.array(ContextItemIdSchema).max(500).describe("What the conversation carries, in shelf order. The root repository is always carried and never listed."),
|
|
33
|
-
});
|
|
34
|
-
//# sourceMappingURL=context.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/schemas/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AAmBxC,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,MAAM,CAAU,CAAC;AAKpD,MAAM,IAAI,GAAG,oEAAoE,CAAC;AAClF,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC;KAC/B,MAAM,EAAE;KACR,GAAG,CAAC,CAAC,CAAC;KACN,GAAG,CAAC,GAAG,CAAC;KACR,KAAK,CAAC,IAAI,CAAC;KACX,QAAQ,CAAC,2JAA2J,CAAC,CAAC;AAI3K,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,EAAiB,EAA6D,EAAE;IACxG,MAAM,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAoB,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC;AAChF,CAAC,CAAC;AAMF,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACtC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yFAAyF,CAAC;CAChJ,CAAC,CAAC;AAcH,MAAM,CAAC,MAAM,kBAAkB,GAAG,CAAC,CAAC,MAAM,CAAC;IACvC,EAAE,EAAE,OAAO,CAAC,QAAQ,CAAC,8CAA8C,CAAC;IACpE,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,yDAAyD,CAAC;IACxG,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,kDAAkD,CAAC;IACtH,OAAO,EAAE,CAAC;SACL,KAAK,CAAC,mBAAmB,CAAC;SAC1B,GAAG,CAAC,GAAG,CAAC;SACR,OAAO,CAAC,EAAE,CAAC;SACX,QAAQ,CAAC,mHAAmH,CAAC;IAClI,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,sEAAsE,CAAC;IAC1I,IAAI,EAAE,iBAAiB,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,+CAA+C,CAAC;CAC/F,CAAC,CAAC;AAUH,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7C,KAAK,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,kFAAkF,CAAC;IACtH,KAAK,EAAE,CAAC,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,wGAAwG,CAAC;CAClK,CAAC,CAAC"}
|