@xenosystem/agent-interface-core 0.1.3
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/LICENSE +67 -0
- package/dist/agentDiscovery.d.ts +97 -0
- package/dist/agentDiscovery.d.ts.map +1 -0
- package/dist/agentDiscovery.js +93 -0
- package/dist/agentDiscovery.js.map +1 -0
- package/dist/capabilityRouting.d.ts +72 -0
- package/dist/capabilityRouting.d.ts.map +1 -0
- package/dist/capabilityRouting.js +124 -0
- package/dist/capabilityRouting.js.map +1 -0
- package/dist/capabilityTier.d.ts +105 -0
- package/dist/capabilityTier.d.ts.map +1 -0
- package/dist/capabilityTier.js +120 -0
- package/dist/capabilityTier.js.map +1 -0
- package/dist/combinationVerification.d.ts +101 -0
- package/dist/combinationVerification.d.ts.map +1 -0
- package/dist/combinationVerification.js +115 -0
- package/dist/combinationVerification.js.map +1 -0
- package/dist/context/agentAttachedContextPrompt.d.ts +13 -0
- package/dist/context/agentAttachedContextPrompt.d.ts.map +1 -0
- package/dist/context/agentAttachedContextPrompt.js +50 -0
- package/dist/context/agentAttachedContextPrompt.js.map +1 -0
- package/dist/context/agentModelContext.d.ts +77 -0
- package/dist/context/agentModelContext.d.ts.map +1 -0
- package/dist/context/agentModelContext.js +297 -0
- package/dist/context/agentModelContext.js.map +1 -0
- package/dist/fanOutPlanner.d.ts +65 -0
- package/dist/fanOutPlanner.d.ts.map +1 -0
- package/dist/fanOutPlanner.js +78 -0
- package/dist/fanOutPlanner.js.map +1 -0
- package/dist/fleetBoardProjection.d.ts +143 -0
- package/dist/fleetBoardProjection.d.ts.map +1 -0
- package/dist/fleetBoardProjection.js +156 -0
- package/dist/fleetBoardProjection.js.map +1 -0
- package/dist/fleetProjection.d.ts +63 -0
- package/dist/fleetProjection.d.ts.map +1 -0
- package/dist/fleetProjection.js +86 -0
- package/dist/fleetProjection.js.map +1 -0
- package/dist/hostBackedCapabilities.d.ts +50 -0
- package/dist/hostBackedCapabilities.d.ts.map +1 -0
- package/dist/hostBackedCapabilities.js +66 -0
- package/dist/hostBackedCapabilities.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +134 -0
- package/dist/index.js.map +1 -0
- package/dist/intakeBoardProjection.d.ts +75 -0
- package/dist/intakeBoardProjection.d.ts.map +1 -0
- package/dist/intakeBoardProjection.js +90 -0
- package/dist/intakeBoardProjection.js.map +1 -0
- package/dist/intakeClaim.d.ts +156 -0
- package/dist/intakeClaim.d.ts.map +1 -0
- package/dist/intakeClaim.js +190 -0
- package/dist/intakeClaim.js.map +1 -0
- package/dist/knowledgeBoardProjection.d.ts +57 -0
- package/dist/knowledgeBoardProjection.d.ts.map +1 -0
- package/dist/knowledgeBoardProjection.js +74 -0
- package/dist/knowledgeBoardProjection.js.map +1 -0
- package/dist/landingOverlap.d.ts +127 -0
- package/dist/landingOverlap.d.ts.map +1 -0
- package/dist/landingOverlap.js +107 -0
- package/dist/landingOverlap.js.map +1 -0
- package/dist/landingQueue.d.ts +152 -0
- package/dist/landingQueue.d.ts.map +1 -0
- package/dist/landingQueue.js +258 -0
- package/dist/landingQueue.js.map +1 -0
- package/dist/markdown/markdownWindowsPaths.d.ts +20 -0
- package/dist/markdown/markdownWindowsPaths.d.ts.map +1 -0
- package/dist/markdown/markdownWindowsPaths.js +208 -0
- package/dist/markdown/markdownWindowsPaths.js.map +1 -0
- package/dist/reviewProjection.d.ts +118 -0
- package/dist/reviewProjection.d.ts.map +1 -0
- package/dist/reviewProjection.js +133 -0
- package/dist/reviewProjection.js.map +1 -0
- package/dist/runDiff.d.ts +86 -0
- package/dist/runDiff.d.ts.map +1 -0
- package/dist/runDiff.js +103 -0
- package/dist/runDiff.js.map +1 -0
- package/dist/runtime/agentReasoningEffort.d.ts +22 -0
- package/dist/runtime/agentReasoningEffort.d.ts.map +1 -0
- package/dist/runtime/agentReasoningEffort.js +76 -0
- package/dist/runtime/agentReasoningEffort.js.map +1 -0
- package/dist/runtime/agentRuntimeProvider.d.ts +12 -0
- package/dist/runtime/agentRuntimeProvider.d.ts.map +1 -0
- package/dist/runtime/agentRuntimeProvider.js +294 -0
- package/dist/runtime/agentRuntimeProvider.js.map +1 -0
- package/dist/runtime/agentRuntimeProviderTypes.d.ts +100 -0
- package/dist/runtime/agentRuntimeProviderTypes.d.ts.map +1 -0
- package/dist/runtime/agentRuntimeProviderTypes.js +2 -0
- package/dist/runtime/agentRuntimeProviderTypes.js.map +1 -0
- package/dist/runtime/conversationRuntime.d.ts +53 -0
- package/dist/runtime/conversationRuntime.d.ts.map +1 -0
- package/dist/runtime/conversationRuntime.js +207 -0
- package/dist/runtime/conversationRuntime.js.map +1 -0
- package/dist/runtime/legacyAgentRuntimeEvents.d.ts +65 -0
- package/dist/runtime/legacyAgentRuntimeEvents.d.ts.map +1 -0
- package/dist/runtime/legacyAgentRuntimeEvents.js +104 -0
- package/dist/runtime/legacyAgentRuntimeEvents.js.map +1 -0
- package/dist/runtimeProjection.d.ts +19 -0
- package/dist/runtimeProjection.d.ts.map +1 -0
- package/dist/runtimeProjection.js +133 -0
- package/dist/runtimeProjection.js.map +1 -0
- package/dist/sessionBoardProjection.d.ts +84 -0
- package/dist/sessionBoardProjection.d.ts.map +1 -0
- package/dist/sessionBoardProjection.js +103 -0
- package/dist/sessionBoardProjection.js.map +1 -0
- package/dist/sessionMode.d.ts +115 -0
- package/dist/sessionMode.d.ts.map +1 -0
- package/dist/sessionMode.js +98 -0
- package/dist/sessionMode.js.map +1 -0
- package/dist/workspace/workspaceSelectionContinuation.d.ts +8 -0
- package/dist/workspace/workspaceSelectionContinuation.d.ts.map +1 -0
- package/dist/workspace/workspaceSelectionContinuation.js +18 -0
- package/dist/workspace/workspaceSelectionContinuation.js.map +1 -0
- package/dist/workspaceKnowledge.d.ts +90 -0
- package/dist/workspaceKnowledge.d.ts.map +1 -0
- package/dist/workspaceKnowledge.js +103 -0
- package/dist/workspaceKnowledge.js.map +1 -0
- package/dist/writeLease.d.ts +92 -0
- package/dist/writeLease.d.ts.map +1 -0
- package/dist/writeLease.js +108 -0
- package/dist/writeLease.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a fleet surface may SHOW — ADE §9 step 6, the presentation half.
|
|
3
|
+
*
|
|
4
|
+
* `fleet.view` answers what the host knows. This decides what a person is told,
|
|
5
|
+
* and in what order. Pure, in `core`, for the same reason `reviewProjection`
|
|
6
|
+
* is: every rule here is about honesty rather than layout, and an honesty rule
|
|
7
|
+
* written in JSX is enforced by whoever writes the next component.
|
|
8
|
+
*
|
|
9
|
+
* ## 🔴 The board is ordered by what needs a human, not by name
|
|
10
|
+
*
|
|
11
|
+
* A fleet view exists to answer one question — *where do I need to look?* Sorted
|
|
12
|
+
* alphabetically it answers a different, useless one. So rows are ranked by
|
|
13
|
+
* attention: a run blocked on a live collision first, then one whose changes
|
|
14
|
+
* another run also touched, then one whose diff has a hole, then whatever is
|
|
15
|
+
* merely working.
|
|
16
|
+
*
|
|
17
|
+
* Ties break on run id so the order is STABLE. A board that reshuffles between
|
|
18
|
+
* polls is unusable for the thing a board is for — noticing what changed.
|
|
19
|
+
*
|
|
20
|
+
* ## Unobserved is its own status
|
|
21
|
+
*
|
|
22
|
+
* `diffComplete` is absent when nobody watched a run, and that is a third state
|
|
23
|
+
* beside complete and incomplete. Folding it into either lies in a different
|
|
24
|
+
* direction each way: "complete" claims a diff nobody collected, "incomplete"
|
|
25
|
+
* sends someone to fix an observation problem that does not exist.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Why a run is at the top of the board, or that it is not.
|
|
29
|
+
*
|
|
30
|
+
* Ordered by urgency, and the numbers are deliberate: the projection sorts on
|
|
31
|
+
* them, so adding a status between two others is a one-line change rather than
|
|
32
|
+
* a re-reading of a comparator.
|
|
33
|
+
*/
|
|
34
|
+
export const FLEET_ATTENTION = {
|
|
35
|
+
/**
|
|
36
|
+
* 🔴 ABOVE `blocked`, deliberately.
|
|
37
|
+
*
|
|
38
|
+
* Both are stopped, but only one of them the reader can clear. A path
|
|
39
|
+
* collision waits on another RUN finishing; a permission prompt waits on the
|
|
40
|
+
* person looking at this board, and every second it sits below something they
|
|
41
|
+
* cannot act on is a second of nothing happening for no reason.
|
|
42
|
+
*/
|
|
43
|
+
'awaiting-approval': 0,
|
|
44
|
+
blocked: 1,
|
|
45
|
+
contested: 2,
|
|
46
|
+
incomplete: 3,
|
|
47
|
+
working: 4,
|
|
48
|
+
unobserved: 5,
|
|
49
|
+
idle: 6,
|
|
50
|
+
};
|
|
51
|
+
export function projectFleetBoard(input) {
|
|
52
|
+
const blockedRuns = new Set();
|
|
53
|
+
for (const collision of input.collisions) {
|
|
54
|
+
// The run that WANTED the scope is the blocked one. The holder is working
|
|
55
|
+
// normally and has no idea it is in anyone's way.
|
|
56
|
+
if (collision.stillHeld)
|
|
57
|
+
blockedRuns.add(collision.wantedByRunId);
|
|
58
|
+
}
|
|
59
|
+
const rows = input.runs.map((run) => {
|
|
60
|
+
const attention = attentionFor(run, blockedRuns.has(run.runId));
|
|
61
|
+
return {
|
|
62
|
+
runId: run.runId,
|
|
63
|
+
attention,
|
|
64
|
+
...(run.heldMessages === undefined ? {} : { heldMessages: run.heldMessages }),
|
|
65
|
+
...(run.inboundPolicy === undefined ? {} : { inboundPolicy: run.inboundPolicy }),
|
|
66
|
+
...(run.isolation === undefined ? {} : { isolation: run.isolation }),
|
|
67
|
+
...(run.isolationMechanism === undefined ? {} : { isolationMechanism: run.isolationMechanism }),
|
|
68
|
+
working: run.working,
|
|
69
|
+
claims: run.claims,
|
|
70
|
+
contestedPaths: run.contestedPaths,
|
|
71
|
+
// Carried through rather than derived: the host owns provenance, and a
|
|
72
|
+
// projection that inferred an origin would be inventing one.
|
|
73
|
+
...(run.intakeItemId ? { intakeItemId: run.intakeItemId } : {}),
|
|
74
|
+
...(run.changes ? { changes: run.changes } : {}),
|
|
75
|
+
headline: headlineFor(run, attention),
|
|
76
|
+
// Only a diff explicitly reported complete may be trusted. Absent means
|
|
77
|
+
// unobserved, which is not a diff at all.
|
|
78
|
+
diffTrustworthy: run.diffComplete === true,
|
|
79
|
+
};
|
|
80
|
+
});
|
|
81
|
+
rows.sort((left, right) => FLEET_ATTENTION[left.attention] === FLEET_ATTENTION[right.attention]
|
|
82
|
+
? left.runId.localeCompare(right.runId)
|
|
83
|
+
: FLEET_ATTENTION[left.attention] - FLEET_ATTENTION[right.attention]);
|
|
84
|
+
const liveCollisions = input.collisions.filter((collision) => collision.stillHeld);
|
|
85
|
+
const resolvedCollisions = input.collisions.filter((collision) => !collision.stillHeld);
|
|
86
|
+
const trustworthy = input.coordinationComplete && input.observationComplete;
|
|
87
|
+
return {
|
|
88
|
+
rows,
|
|
89
|
+
liveCollisions,
|
|
90
|
+
resolvedCollisions,
|
|
91
|
+
...(trustworthy ? {} : { notice: noticeFor(input) }),
|
|
92
|
+
trustworthy,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
function attentionFor(run, blocked) {
|
|
96
|
+
// FIRST, above every other reason a run is stopped: this is the only one the
|
|
97
|
+
// reader can clear themselves, and `working` would otherwise swallow it — a
|
|
98
|
+
// turn blocked on a human is still in flight.
|
|
99
|
+
if (run.awaitingApproval === true)
|
|
100
|
+
return 'awaiting-approval';
|
|
101
|
+
if (blocked)
|
|
102
|
+
return 'blocked';
|
|
103
|
+
if (run.contestedPaths.length > 0)
|
|
104
|
+
return 'contested';
|
|
105
|
+
if (run.diffComplete === false)
|
|
106
|
+
return 'incomplete';
|
|
107
|
+
if (run.working)
|
|
108
|
+
return 'working';
|
|
109
|
+
// Checked AFTER `working`: a run that is executing right now is worth showing
|
|
110
|
+
// as working even though nothing is watching its filesystem. Ordering these
|
|
111
|
+
// the other way would bury every live run under a bookkeeping status.
|
|
112
|
+
if (run.diffComplete === undefined)
|
|
113
|
+
return 'unobserved';
|
|
114
|
+
return 'idle';
|
|
115
|
+
}
|
|
116
|
+
function headlineFor(run, attention) {
|
|
117
|
+
switch (attention) {
|
|
118
|
+
case 'awaiting-approval':
|
|
119
|
+
// Second person, because the reader is the one being waited on.
|
|
120
|
+
return 'Waiting for your approval.';
|
|
121
|
+
case 'blocked':
|
|
122
|
+
return 'Waiting on a path another run holds.';
|
|
123
|
+
case 'contested':
|
|
124
|
+
return run.contestedPaths.length === 1
|
|
125
|
+
? `Also changed by another run: ${run.contestedPaths[0]}`
|
|
126
|
+
: `${run.contestedPaths.length} paths are also changed by another run.`;
|
|
127
|
+
case 'incomplete':
|
|
128
|
+
return 'Some of this run\'s changes were missed. Do not treat its diff as the whole story.';
|
|
129
|
+
case 'working':
|
|
130
|
+
return 'Working.';
|
|
131
|
+
case 'unobserved':
|
|
132
|
+
return 'Not observed, so there is no diff for this run.';
|
|
133
|
+
case 'idle':
|
|
134
|
+
return summariseChanges(run.changes);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function summariseChanges(changes) {
|
|
138
|
+
if (!changes)
|
|
139
|
+
return 'Idle.';
|
|
140
|
+
const total = changes.added + changes.modified + changes.deleted;
|
|
141
|
+
if (total === 0)
|
|
142
|
+
return 'Changed nothing.';
|
|
143
|
+
return `${changes.added} added, ${changes.modified} modified, ${changes.deleted} deleted.`;
|
|
144
|
+
}
|
|
145
|
+
function noticeFor(input) {
|
|
146
|
+
// The first problem, not all of them: a board is scanned, and a paragraph of
|
|
147
|
+
// caveats is skipped. The rest stay available on the runs themselves.
|
|
148
|
+
const first = input.problems[0];
|
|
149
|
+
if (!input.observationComplete) {
|
|
150
|
+
return first
|
|
151
|
+
? `Some runs have gaps in what was observed: ${first}`
|
|
152
|
+
: 'Some runs have gaps in what was observed. Their diffs are not the whole story.';
|
|
153
|
+
}
|
|
154
|
+
return first ?? 'This board may not show everything.';
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=fleetBoardProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleetBoardProjection.js","sourceRoot":"","sources":["../src/fleetBoardProjection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import type { AgentRuntimeEventEnvelope } from '@xenosystem/agent-interface-contract';
|
|
2
|
+
/**
|
|
3
|
+
* The fleet view — what is claimed, by whom, and where two runs collided.
|
|
4
|
+
*
|
|
5
|
+
* @unwired-by-design ADE §9 step 6 — the LIVE fleet view (`fleet.view`) shipped
|
|
6
|
+
* without this, and deliberately. It reads claims from the registry and records
|
|
7
|
+
* collisions from the coordination sink, because those are the only places the
|
|
8
|
+
* facts exist right now: `publishPersistedRuntimeEvent` does not add persisted
|
|
9
|
+
* events to the host's in-memory map, so a projection over that map reported
|
|
10
|
+
* nothing in any composition with a repository — which is every real one. This
|
|
11
|
+
* projection remains correct for the case it was written for and that has no
|
|
12
|
+
* consumer yet: reconstructing a fleet AFTER the fact from a durable timeline,
|
|
13
|
+
* where no service is holding anything. It needs a timeline reader, not a
|
|
14
|
+
* surface.
|
|
15
|
+
*
|
|
16
|
+
* `XENO_AGENT_COORDINATION_SPEC.md` §5: a claim is "advisory to the agent and
|
|
17
|
+
* **authoritative to the human**", and "the fleet view shows what is claimed by
|
|
18
|
+
* whom, which is the fastest way to see a collision before it becomes a merge."
|
|
19
|
+
*
|
|
20
|
+
* ## Why a projection over events rather than a read of live state
|
|
21
|
+
*
|
|
22
|
+
* `CoordinationService` already knows the current claim map, so exposing that
|
|
23
|
+
* would be simpler — and would only ever answer for *now*. Deriving the view
|
|
24
|
+
* from the runtime timeline instead means the same function serves a live fleet
|
|
25
|
+
* dashboard and a reviewer opening yesterday's run, which is the case §9 cares
|
|
26
|
+
* about: reconstructing why a diff looks the way it does, after the fact, when
|
|
27
|
+
* no service is holding anything.
|
|
28
|
+
*
|
|
29
|
+
* Pure and provider-neutral, matching `projectAgentToolCalls` in this package.
|
|
30
|
+
*
|
|
31
|
+
* ## Collisions are kept after they resolve
|
|
32
|
+
*
|
|
33
|
+
* A refusal is evidence two runs wanted the same work. Dropping it once the
|
|
34
|
+
* holder releases would erase exactly the record a reviewer needs when the merge
|
|
35
|
+
* turns out wrong — "nobody collided" and "a collision happened and was handled"
|
|
36
|
+
* are different histories. Each collision carries `stillHeld` so a live view can
|
|
37
|
+
* show what is urgent without the projection having to forget what happened.
|
|
38
|
+
*/
|
|
39
|
+
export interface FleetClaim {
|
|
40
|
+
scope: string;
|
|
41
|
+
runId: string;
|
|
42
|
+
claimId: string;
|
|
43
|
+
/** ISO timestamp of the acquiring event. */
|
|
44
|
+
acquiredAt: string;
|
|
45
|
+
}
|
|
46
|
+
export interface FleetCollision {
|
|
47
|
+
scope: string;
|
|
48
|
+
wantedByRunId: string;
|
|
49
|
+
heldByRunId: string;
|
|
50
|
+
at: string;
|
|
51
|
+
/** True while the holder still holds an overlapping claim. */
|
|
52
|
+
stillHeld: boolean;
|
|
53
|
+
}
|
|
54
|
+
export interface FleetView {
|
|
55
|
+
/** Live claims, newest first. */
|
|
56
|
+
claims: FleetClaim[];
|
|
57
|
+
/** Every recorded collision, newest first. */
|
|
58
|
+
collisions: FleetCollision[];
|
|
59
|
+
/** Runs that appear anywhere in the coordination record. */
|
|
60
|
+
runIds: string[];
|
|
61
|
+
}
|
|
62
|
+
export declare function projectFleetView(runtimeEvents: readonly AgentRuntimeEventEnvelope[]): FleetView;
|
|
63
|
+
//# sourceMappingURL=fleetProjection.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleetProjection.d.ts","sourceRoot":"","sources":["../src/fleetProjection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,sCAAsC,CAAA;AAErF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,CAAA;IACrB,WAAW,EAAE,MAAM,CAAA;IACnB,EAAE,EAAE,MAAM,CAAA;IACV,8DAA8D;IAC9D,SAAS,EAAE,OAAO,CAAA;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,iCAAiC;IACjC,MAAM,EAAE,UAAU,EAAE,CAAA;IACpB,8CAA8C;IAC9C,UAAU,EAAE,cAAc,EAAE,CAAA;IAC5B,4DAA4D;IAC5D,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAoBD,wBAAgB,gBAAgB,CAC9B,aAAa,EAAE,SAAS,yBAAyB,EAAE,GAClD,SAAS,CAwEX"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
function text(value) {
|
|
2
|
+
return typeof value === 'string' && value.trim().length > 0 ? value : undefined;
|
|
3
|
+
}
|
|
4
|
+
/**
|
|
5
|
+
* Same containment rule as the claim registry: `src/` covers `src/app.ts`.
|
|
6
|
+
*
|
|
7
|
+
* Compared SEGMENT-wise so `src` cannot swallow `srcgen`. Duplicated here rather
|
|
8
|
+
* than imported because this package is provider-neutral and must not depend on
|
|
9
|
+
* the host — and the rule is four lines. ⚠️ If it changes in one place it must
|
|
10
|
+
* change in both; `fleetProjection.test.ts` pins the boundary case so a drift
|
|
11
|
+
* fails rather than silently reporting the wrong collisions.
|
|
12
|
+
*/
|
|
13
|
+
function overlaps(a, b) {
|
|
14
|
+
if (a === b)
|
|
15
|
+
return true;
|
|
16
|
+
return b.startsWith(`${a}/`) || a.startsWith(`${b}/`);
|
|
17
|
+
}
|
|
18
|
+
export function projectFleetView(runtimeEvents) {
|
|
19
|
+
const claims = new Map();
|
|
20
|
+
const collisions = [];
|
|
21
|
+
const runIds = new Set();
|
|
22
|
+
const seen = new Set();
|
|
23
|
+
const ordered = [...runtimeEvents].sort((left, right) => left.sequence === right.sequence
|
|
24
|
+
? left.timestamp.localeCompare(right.timestamp)
|
|
25
|
+
: left.sequence - right.sequence);
|
|
26
|
+
for (const envelope of ordered) {
|
|
27
|
+
// Runtime events are at-least-once in some transports; a replayed acquire
|
|
28
|
+
// would otherwise show one claim twice and a replayed release could drop a
|
|
29
|
+
// claim that is still held.
|
|
30
|
+
if (seen.has(envelope.id))
|
|
31
|
+
continue;
|
|
32
|
+
seen.add(envelope.id);
|
|
33
|
+
const payload = envelope.event;
|
|
34
|
+
const runId = text(payload.runId);
|
|
35
|
+
switch (envelope.type) {
|
|
36
|
+
case 'coordination.claim.acquired': {
|
|
37
|
+
const scope = text(payload.scope);
|
|
38
|
+
const claimId = text(payload.claimId);
|
|
39
|
+
if (!scope || !claimId || !runId)
|
|
40
|
+
continue;
|
|
41
|
+
runIds.add(runId);
|
|
42
|
+
claims.set(claimId, { scope, runId, claimId, acquiredAt: envelope.timestamp });
|
|
43
|
+
break;
|
|
44
|
+
}
|
|
45
|
+
case 'coordination.claim.refused': {
|
|
46
|
+
const scope = text(payload.scope);
|
|
47
|
+
const heldByRunId = text(payload.heldByRunId);
|
|
48
|
+
if (!scope || !heldByRunId || !runId)
|
|
49
|
+
continue;
|
|
50
|
+
runIds.add(runId);
|
|
51
|
+
runIds.add(heldByRunId);
|
|
52
|
+
collisions.push({
|
|
53
|
+
scope,
|
|
54
|
+
wantedByRunId: runId,
|
|
55
|
+
heldByRunId,
|
|
56
|
+
at: envelope.timestamp,
|
|
57
|
+
// Recomputed at the end: a release later in the stream must clear it.
|
|
58
|
+
stillHeld: true,
|
|
59
|
+
});
|
|
60
|
+
break;
|
|
61
|
+
}
|
|
62
|
+
case 'coordination.claim.released': {
|
|
63
|
+
if (!runId)
|
|
64
|
+
continue;
|
|
65
|
+
runIds.add(runId);
|
|
66
|
+
for (const [claimId, claim] of claims) {
|
|
67
|
+
if (claim.runId === runId)
|
|
68
|
+
claims.delete(claimId);
|
|
69
|
+
}
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
default:
|
|
73
|
+
break;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
const live = [...claims.values()];
|
|
77
|
+
for (const collision of collisions) {
|
|
78
|
+
collision.stillHeld = live.some((claim) => claim.runId === collision.heldByRunId && overlaps(claim.scope, collision.scope));
|
|
79
|
+
}
|
|
80
|
+
return {
|
|
81
|
+
claims: live.sort((left, right) => right.acquiredAt.localeCompare(left.acquiredAt)),
|
|
82
|
+
collisions: collisions.sort((left, right) => right.at.localeCompare(left.at)),
|
|
83
|
+
runIds: [...runIds].sort(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=fleetProjection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fleetProjection.js","sourceRoot":"","sources":["../src/fleetProjection.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A provider may not advertise a capability the HOST does not have — §7.1.
|
|
3
|
+
*
|
|
4
|
+
* Most entries in `AGENT_HARNESS_CAPABILITIES` are facts about a provider: this
|
|
5
|
+
* agent can read files, that one streams. A few are not. Coordination between
|
|
6
|
+
* runs is a property of the HOST — whether a `CoordinationService` is mounted —
|
|
7
|
+
* and no provider can make it true by declaring it.
|
|
8
|
+
*
|
|
9
|
+
* 🔴 Today no adapter declares them, so nothing is currently wrong. This exists
|
|
10
|
+
* for the commit that changes that. When coordination tools land, someone will
|
|
11
|
+
* flip these to `available` in an adapter matrix, and the host they run on may
|
|
12
|
+
* still have no coordination service. The surface would then offer a claim map
|
|
13
|
+
* for a host that cannot answer, which is precisely the capability-honesty
|
|
14
|
+
* failure the matrix was introduced to prevent.
|
|
15
|
+
*
|
|
16
|
+
* ## Downgrade, not refuse
|
|
17
|
+
*
|
|
18
|
+
* A provider that over-claims is still useful for everything else it does, so
|
|
19
|
+
* refusing to register it would trade a small dishonesty for a total loss of the
|
|
20
|
+
* lane. The claim is lowered to `unsupported` with a reason naming the host as
|
|
21
|
+
* the source — `source: 'host'` is the honest attribution, because the provider
|
|
22
|
+
* did not decide this and a reader chasing the reason should look at the host.
|
|
23
|
+
*/
|
|
24
|
+
import type { AgentCapabilityMatrix } from '@xenosystem/agent-interface-contract';
|
|
25
|
+
/**
|
|
26
|
+
* Capabilities whose truth is owned by the host, not the provider.
|
|
27
|
+
*
|
|
28
|
+
* Deliberately narrow. A capability belongs here only when NO provider
|
|
29
|
+
* implementation could make it true on a host that lacks the backing — which is
|
|
30
|
+
* why `background-runs` is absent: it names background processes the engineering
|
|
31
|
+
* workbench runs, not the detached host, and a provider genuinely differs there.
|
|
32
|
+
*/
|
|
33
|
+
export declare const HOST_BACKED_CAPABILITIES: {
|
|
34
|
+
readonly 'coordination.messages': "coordination";
|
|
35
|
+
readonly 'coordination.claims': "coordination";
|
|
36
|
+
readonly 'coordination.query': "coordination";
|
|
37
|
+
};
|
|
38
|
+
export interface HostCapabilityBacking {
|
|
39
|
+
/** True when a coordination service is mounted on this host. */
|
|
40
|
+
coordination: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Lowers any host-backed capability the host cannot support.
|
|
44
|
+
*
|
|
45
|
+
* Returns the SAME matrix object when nothing changed, so a caller can tell a
|
|
46
|
+
* downgrade happened without comparing every entry — and so registering an
|
|
47
|
+
* honest provider costs nothing.
|
|
48
|
+
*/
|
|
49
|
+
export declare function withHostBackedCapabilities(matrix: AgentCapabilityMatrix, backing: HostCapabilityBacking): AgentCapabilityMatrix;
|
|
50
|
+
//# sourceMappingURL=hostBackedCapabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostBackedCapabilities.d.ts","sourceRoot":"","sources":["../src/hostBackedCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EACV,qBAAqB,EAEtB,MAAM,sCAAsC,CAAA;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,wBAAwB;;;;CAI+B,CAAA;AAEpE,MAAM,WAAW,qBAAqB;IACpC,gEAAgE;IAChE,YAAY,EAAE,OAAO,CAAA;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,qBAAqB,EAC7B,OAAO,EAAE,qBAAqB,GAC7B,qBAAqB,CAsBvB"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A provider may not advertise a capability the HOST does not have — §7.1.
|
|
3
|
+
*
|
|
4
|
+
* Most entries in `AGENT_HARNESS_CAPABILITIES` are facts about a provider: this
|
|
5
|
+
* agent can read files, that one streams. A few are not. Coordination between
|
|
6
|
+
* runs is a property of the HOST — whether a `CoordinationService` is mounted —
|
|
7
|
+
* and no provider can make it true by declaring it.
|
|
8
|
+
*
|
|
9
|
+
* 🔴 Today no adapter declares them, so nothing is currently wrong. This exists
|
|
10
|
+
* for the commit that changes that. When coordination tools land, someone will
|
|
11
|
+
* flip these to `available` in an adapter matrix, and the host they run on may
|
|
12
|
+
* still have no coordination service. The surface would then offer a claim map
|
|
13
|
+
* for a host that cannot answer, which is precisely the capability-honesty
|
|
14
|
+
* failure the matrix was introduced to prevent.
|
|
15
|
+
*
|
|
16
|
+
* ## Downgrade, not refuse
|
|
17
|
+
*
|
|
18
|
+
* A provider that over-claims is still useful for everything else it does, so
|
|
19
|
+
* refusing to register it would trade a small dishonesty for a total loss of the
|
|
20
|
+
* lane. The claim is lowered to `unsupported` with a reason naming the host as
|
|
21
|
+
* the source — `source: 'host'` is the honest attribution, because the provider
|
|
22
|
+
* did not decide this and a reader chasing the reason should look at the host.
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Capabilities whose truth is owned by the host, not the provider.
|
|
26
|
+
*
|
|
27
|
+
* Deliberately narrow. A capability belongs here only when NO provider
|
|
28
|
+
* implementation could make it true on a host that lacks the backing — which is
|
|
29
|
+
* why `background-runs` is absent: it names background processes the engineering
|
|
30
|
+
* workbench runs, not the detached host, and a provider genuinely differs there.
|
|
31
|
+
*/
|
|
32
|
+
export const HOST_BACKED_CAPABILITIES = {
|
|
33
|
+
'coordination.messages': 'coordination',
|
|
34
|
+
'coordination.claims': 'coordination',
|
|
35
|
+
'coordination.query': 'coordination',
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* Lowers any host-backed capability the host cannot support.
|
|
39
|
+
*
|
|
40
|
+
* Returns the SAME matrix object when nothing changed, so a caller can tell a
|
|
41
|
+
* downgrade happened without comparing every entry — and so registering an
|
|
42
|
+
* honest provider costs nothing.
|
|
43
|
+
*/
|
|
44
|
+
export function withHostBackedCapabilities(matrix, backing) {
|
|
45
|
+
let changed = false;
|
|
46
|
+
const next = { ...matrix };
|
|
47
|
+
for (const [capability, backedBy] of Object.entries(HOST_BACKED_CAPABILITIES)) {
|
|
48
|
+
const declared = matrix[capability];
|
|
49
|
+
// Only a POSITIVE claim is a lie worth correcting. `degraded`, `blocked` and
|
|
50
|
+
// `unsupported` already tell a surface not to rely on it.
|
|
51
|
+
if (!declared || declared.status !== 'available')
|
|
52
|
+
continue;
|
|
53
|
+
if (backing[backedBy])
|
|
54
|
+
continue;
|
|
55
|
+
changed = true;
|
|
56
|
+
next[capability] = {
|
|
57
|
+
status: 'unsupported',
|
|
58
|
+
// The HOST decided this, not the provider. A reader chasing the reason
|
|
59
|
+
// must be sent to the right place.
|
|
60
|
+
source: 'host',
|
|
61
|
+
reason: `This host has no ${backedBy} service mounted, so ${capability} cannot work here.`,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return changed ? next : matrix;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=hostBackedCapabilities.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hostBackedCapabilities.js","sourceRoot":"","sources":["../src/hostBackedCapabilities.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAOH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,wBAAwB,GAAG;IACtC,uBAAuB,EAAE,cAAc;IACvC,qBAAqB,EAAE,cAAc;IACrC,oBAAoB,EAAE,cAAc;CAC8B,CAAA;AAOpE;;;;;;GAMG;AACH,MAAM,UAAU,0BAA0B,CACxC,MAA6B,EAC7B,OAA8B;IAE9B,IAAI,OAAO,GAAG,KAAK,CAAA;IACnB,MAAM,IAAI,GAA0B,EAAE,GAAG,MAAM,EAAE,CAAA;IAEjD,KAAK,MAAM,CAAC,UAAU,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,wBAAwB,CAAC,EAAE,CAAC;QAC9E,MAAM,QAAQ,GAAG,MAAM,CAAC,UAAoC,CAAC,CAAA;QAC7D,6EAA6E;QAC7E,0DAA0D;QAC1D,IAAI,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,KAAK,WAAW;YAAE,SAAQ;QAC1D,IAAI,OAAO,CAAC,QAAuC,CAAC;YAAE,SAAQ;QAE9D,OAAO,GAAG,IAAI,CAAA;QACd,IAAI,CAAC,UAAoC,CAAC,GAAG;YAC3C,MAAM,EAAE,aAAa;YACrB,uEAAuE;YACvE,mCAAmC;YACnC,MAAM,EAAE,MAAM;YACd,MAAM,EAAE,oBAAoB,QAAQ,wBAAwB,UAAU,oBAAoB;SAC3F,CAAA;IACH,CAAC;IAED,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAA;AAChC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { type AgentCapabilityDescriptor, type AgentCapabilityMatrix, type AgentHarnessCapability, type AgentRuntimeProviderDescriptor, type AgentRuntimeSelection } from '@xenosystem/agent-interface-contract';
|
|
2
|
+
export * from './runtimeProjection.js';
|
|
3
|
+
export * from './fleetProjection.js';
|
|
4
|
+
export * from './fleetBoardProjection.js';
|
|
5
|
+
export * from './sessionBoardProjection.js';
|
|
6
|
+
export * from './intakeClaim.js';
|
|
7
|
+
export * from './intakeBoardProjection.js';
|
|
8
|
+
export * from './workspaceKnowledge.js';
|
|
9
|
+
export * from './knowledgeBoardProjection.js';
|
|
10
|
+
export * from './hostBackedCapabilities.js';
|
|
11
|
+
export * from './sessionMode.js';
|
|
12
|
+
export * from './writeLease.js';
|
|
13
|
+
export * from './landingOverlap.js';
|
|
14
|
+
export * from './landingQueue.js';
|
|
15
|
+
export * from './reviewProjection.js';
|
|
16
|
+
export * from './combinationVerification.js';
|
|
17
|
+
export * from './capabilityTier.js';
|
|
18
|
+
export * from './runDiff.js';
|
|
19
|
+
export * from './context/agentAttachedContextPrompt.js';
|
|
20
|
+
export * from './context/agentModelContext.js';
|
|
21
|
+
export * from './markdown/markdownWindowsPaths.js';
|
|
22
|
+
export * from './runtime/agentReasoningEffort.js';
|
|
23
|
+
export * from './runtime/agentRuntimeProvider.js';
|
|
24
|
+
export * from './runtime/agentRuntimeProviderTypes.js';
|
|
25
|
+
export * from './runtime/conversationRuntime.js';
|
|
26
|
+
export * from './runtime/legacyAgentRuntimeEvents.js';
|
|
27
|
+
export * from './workspace/workspaceSelectionContinuation.js';
|
|
28
|
+
export declare const DEVELOPMENT_REQUIRED_CAPABILITIES: readonly ["development.execution", "turn.streaming", "tools.file.read", "tools.file.write", "tools.terminal"];
|
|
29
|
+
export declare function createCapabilityMatrix(overrides?: AgentCapabilityMatrix, fallback?: AgentCapabilityDescriptor): Record<AgentHarnessCapability, AgentCapabilityDescriptor>;
|
|
30
|
+
export declare function capabilityStatus(matrix: AgentCapabilityMatrix, capability: AgentHarnessCapability): AgentCapabilityDescriptor;
|
|
31
|
+
export declare function isCapabilityUsable(descriptor: AgentCapabilityDescriptor): boolean;
|
|
32
|
+
export declare function isDevelopmentProviderReady(provider: AgentRuntimeProviderDescriptor): boolean;
|
|
33
|
+
export declare function missingDevelopmentCapabilities(provider: AgentRuntimeProviderDescriptor): AgentHarnessCapability[];
|
|
34
|
+
export declare function selectAvailableProviders(providers: readonly AgentRuntimeProviderDescriptor[], includeUnavailable?: boolean): AgentRuntimeProviderDescriptor[];
|
|
35
|
+
export declare function cloneProvider(provider: AgentRuntimeProviderDescriptor): AgentRuntimeProviderDescriptor;
|
|
36
|
+
export type AgentRuntimeSelectionFailureCode = 'provider_not_found' | 'provider_unavailable' | 'model_not_found' | 'model_unavailable' | 'model_required' | 'reasoning_option_not_found';
|
|
37
|
+
export type AgentRuntimeSelectionResult = {
|
|
38
|
+
ok: true;
|
|
39
|
+
selection: Readonly<AgentRuntimeSelection>;
|
|
40
|
+
} | {
|
|
41
|
+
ok: false;
|
|
42
|
+
code: AgentRuntimeSelectionFailureCode;
|
|
43
|
+
safeReason: string;
|
|
44
|
+
};
|
|
45
|
+
export interface ResolveAgentRuntimeSelectionInput {
|
|
46
|
+
providerId: string;
|
|
47
|
+
modelId?: string;
|
|
48
|
+
reasoningOptionId?: string;
|
|
49
|
+
}
|
|
50
|
+
export declare function resolveAgentRuntimeSelection(providers: readonly AgentRuntimeProviderDescriptor[], input: ResolveAgentRuntimeSelectionInput): AgentRuntimeSelectionResult;
|
|
51
|
+
export * from './capabilityRouting.js';
|
|
52
|
+
export * from './fanOutPlanner.js';
|
|
53
|
+
export * from './agentDiscovery.js';
|
|
54
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC9B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,8BAA8B,EACnC,KAAK,qBAAqB,EAC3B,MAAM,sCAAsC,CAAA;AAE7C,cAAc,wBAAwB,CAAA;AACtC,cAAc,sBAAsB,CAAA;AACpC,cAAc,2BAA2B,CAAA;AACzC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kBAAkB,CAAA;AAChC,cAAc,4BAA4B,CAAA;AAC1C,cAAc,yBAAyB,CAAA;AACvC,cAAc,+BAA+B,CAAA;AAC7C,cAAc,6BAA6B,CAAA;AAC3C,cAAc,kBAAkB,CAAA;AAChC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,qBAAqB,CAAA;AACnC,cAAc,mBAAmB,CAAA;AACjC,cAAc,uBAAuB,CAAA;AACrC,cAAc,8BAA8B,CAAA;AAC5C,cAAc,qBAAqB,CAAA;AACnC,cAAc,cAAc,CAAA;AAC5B,cAAc,yCAAyC,CAAA;AACvD,cAAc,gCAAgC,CAAA;AAC9C,cAAc,oCAAoC,CAAA;AAClD,cAAc,mCAAmC,CAAA;AACjD,cAAc,mCAAmC,CAAA;AACjD,cAAc,wCAAwC,CAAA;AACtD,cAAc,kCAAkC,CAAA;AAChD,cAAc,uCAAuC,CAAA;AACrD,cAAc,+CAA+C,CAAA;AAE7D,eAAO,MAAM,iCAAiC,+GAMQ,CAAA;AAEtD,wBAAgB,sBAAsB,CACpC,SAAS,GAAE,qBAA0B,EACrC,QAAQ,GAAE,yBAAyE,GAClF,MAAM,CAAC,sBAAsB,EAAE,yBAAyB,CAAC,CAM3D;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,qBAAqB,EAC7B,UAAU,EAAE,sBAAsB,GACjC,yBAAyB,CAE3B;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,yBAAyB,GAAG,OAAO,CAEjF;AAED,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,8BAA8B,GAAG,OAAO,CAK5F;AAED,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,8BAA8B,GACvC,sBAAsB,EAAE,CAI1B;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS,8BAA8B,EAAE,EACpD,kBAAkB,UAAQ,GACzB,8BAA8B,EAAE,CAKlC;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,8BAA8B,GAAG,8BAA8B,CAatG;AAED,MAAM,MAAM,gCAAgC,GACxC,oBAAoB,GACpB,sBAAsB,GACtB,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,4BAA4B,CAAA;AAEhC,MAAM,MAAM,2BAA2B,GACnC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,SAAS,EAAE,QAAQ,CAAC,qBAAqB,CAAC,CAAA;CAAE,GACxD;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,gCAAgC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,CAAA;AAE7E,MAAM,WAAW,iCAAiC;IAChD,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAC3B;AAED,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,SAAS,8BAA8B,EAAE,EACpD,KAAK,EAAE,iCAAiC,GACvC,2BAA2B,CAyD7B;AAKD,cAAc,wBAAwB,CAAA;AACtC,cAAc,oBAAoB,CAAA;AAClC,cAAc,qBAAqB,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { AGENT_HARNESS_CAPABILITIES, } from '@xenosystem/agent-interface-contract';
|
|
2
|
+
export * from './runtimeProjection.js';
|
|
3
|
+
export * from './fleetProjection.js';
|
|
4
|
+
export * from './fleetBoardProjection.js';
|
|
5
|
+
export * from './sessionBoardProjection.js';
|
|
6
|
+
export * from './intakeClaim.js';
|
|
7
|
+
export * from './intakeBoardProjection.js';
|
|
8
|
+
export * from './workspaceKnowledge.js';
|
|
9
|
+
export * from './knowledgeBoardProjection.js';
|
|
10
|
+
export * from './hostBackedCapabilities.js';
|
|
11
|
+
export * from './sessionMode.js';
|
|
12
|
+
export * from './writeLease.js';
|
|
13
|
+
export * from './landingOverlap.js';
|
|
14
|
+
export * from './landingQueue.js';
|
|
15
|
+
export * from './reviewProjection.js';
|
|
16
|
+
export * from './combinationVerification.js';
|
|
17
|
+
export * from './capabilityTier.js';
|
|
18
|
+
export * from './runDiff.js';
|
|
19
|
+
export * from './context/agentAttachedContextPrompt.js';
|
|
20
|
+
export * from './context/agentModelContext.js';
|
|
21
|
+
export * from './markdown/markdownWindowsPaths.js';
|
|
22
|
+
export * from './runtime/agentReasoningEffort.js';
|
|
23
|
+
export * from './runtime/agentRuntimeProvider.js';
|
|
24
|
+
export * from './runtime/agentRuntimeProviderTypes.js';
|
|
25
|
+
export * from './runtime/conversationRuntime.js';
|
|
26
|
+
export * from './runtime/legacyAgentRuntimeEvents.js';
|
|
27
|
+
export * from './workspace/workspaceSelectionContinuation.js';
|
|
28
|
+
export const DEVELOPMENT_REQUIRED_CAPABILITIES = [
|
|
29
|
+
'development.execution',
|
|
30
|
+
'turn.streaming',
|
|
31
|
+
'tools.file.read',
|
|
32
|
+
'tools.file.write',
|
|
33
|
+
'tools.terminal',
|
|
34
|
+
];
|
|
35
|
+
export function createCapabilityMatrix(overrides = {}, fallback = { status: 'unsupported', source: 'provider' }) {
|
|
36
|
+
const entries = AGENT_HARNESS_CAPABILITIES.map((capability) => [
|
|
37
|
+
capability,
|
|
38
|
+
overrides[capability] ?? fallback,
|
|
39
|
+
]);
|
|
40
|
+
return Object.fromEntries(entries);
|
|
41
|
+
}
|
|
42
|
+
export function capabilityStatus(matrix, capability) {
|
|
43
|
+
return matrix[capability] ?? { status: 'unsupported', source: 'provider' };
|
|
44
|
+
}
|
|
45
|
+
export function isCapabilityUsable(descriptor) {
|
|
46
|
+
return descriptor.status === 'available' || descriptor.status === 'degraded';
|
|
47
|
+
}
|
|
48
|
+
export function isDevelopmentProviderReady(provider) {
|
|
49
|
+
if (provider.availability !== 'available' && provider.availability !== 'degraded')
|
|
50
|
+
return false;
|
|
51
|
+
return DEVELOPMENT_REQUIRED_CAPABILITIES.every((capability) => (isCapabilityUsable(capabilityStatus(provider.capabilities, capability))));
|
|
52
|
+
}
|
|
53
|
+
export function missingDevelopmentCapabilities(provider) {
|
|
54
|
+
return DEVELOPMENT_REQUIRED_CAPABILITIES.filter((capability) => (!isCapabilityUsable(capabilityStatus(provider.capabilities, capability))));
|
|
55
|
+
}
|
|
56
|
+
export function selectAvailableProviders(providers, includeUnavailable = false) {
|
|
57
|
+
return providers
|
|
58
|
+
.filter((provider) => includeUnavailable || provider.availability !== 'unavailable')
|
|
59
|
+
.map(cloneProvider)
|
|
60
|
+
.sort((a, b) => a.displayName.localeCompare(b.displayName) || a.id.localeCompare(b.id));
|
|
61
|
+
}
|
|
62
|
+
export function cloneProvider(provider) {
|
|
63
|
+
return {
|
|
64
|
+
...provider,
|
|
65
|
+
capabilities: Object.fromEntries(Object.entries(provider.capabilities).map(([key, value]) => [key, value ? { ...value } : value])),
|
|
66
|
+
models: provider.models.map((model) => ({
|
|
67
|
+
...model,
|
|
68
|
+
...(model.reasoningOptions
|
|
69
|
+
? { reasoningOptions: model.reasoningOptions.map((option) => ({ ...option })) }
|
|
70
|
+
: {}),
|
|
71
|
+
})),
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function resolveAgentRuntimeSelection(providers, input) {
|
|
75
|
+
const provider = providers.find((candidate) => candidate.id === input.providerId);
|
|
76
|
+
if (!provider) {
|
|
77
|
+
return { ok: false, code: 'provider_not_found', safeReason: 'The selected runtime provider is no longer in the catalog.' };
|
|
78
|
+
}
|
|
79
|
+
if (provider.availability !== 'available' && provider.availability !== 'degraded') {
|
|
80
|
+
return {
|
|
81
|
+
ok: false,
|
|
82
|
+
code: 'provider_unavailable',
|
|
83
|
+
safeReason: provider.safeUnavailableReason || 'The selected runtime provider is unavailable.',
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const requestedModelId = input.modelId || provider.defaultModelId;
|
|
87
|
+
const fallbackModel = provider.models.find((model) => model.isDefault && isModelUsable(model))
|
|
88
|
+
|| provider.models.find(isModelUsable);
|
|
89
|
+
const model = requestedModelId
|
|
90
|
+
? provider.models.find((candidate) => candidate.id === requestedModelId)
|
|
91
|
+
: fallbackModel;
|
|
92
|
+
if (requestedModelId && !model) {
|
|
93
|
+
return { ok: false, code: 'model_not_found', safeReason: 'The selected model is no longer advertised by this provider.' };
|
|
94
|
+
}
|
|
95
|
+
if (model && !isModelUsable(model)) {
|
|
96
|
+
return {
|
|
97
|
+
ok: false,
|
|
98
|
+
code: 'model_unavailable',
|
|
99
|
+
safeReason: model.safeUnavailableReason || 'The selected model is unavailable.',
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (!model && provider.allowsProviderDefaultModel !== true) {
|
|
103
|
+
return { ok: false, code: 'model_required', safeReason: 'This provider requires an available model selection.' };
|
|
104
|
+
}
|
|
105
|
+
const reasoningOptionId = input.reasoningOptionId
|
|
106
|
+
|| model?.reasoningOptions?.find((option) => option.isDefault)?.id;
|
|
107
|
+
const reasoningOption = reasoningOptionId
|
|
108
|
+
? model?.reasoningOptions?.find((option) => option.id === reasoningOptionId)
|
|
109
|
+
: undefined;
|
|
110
|
+
if (reasoningOptionId && !reasoningOption) {
|
|
111
|
+
return {
|
|
112
|
+
ok: false,
|
|
113
|
+
code: 'reasoning_option_not_found',
|
|
114
|
+
safeReason: 'The selected reasoning option is not advertised by this model.',
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
ok: true,
|
|
119
|
+
selection: Object.freeze({
|
|
120
|
+
providerId: provider.id,
|
|
121
|
+
catalogRevision: provider.catalogRevision,
|
|
122
|
+
...(model ? { modelId: model.id } : {}),
|
|
123
|
+
...(reasoningOptionId ? { reasoningOptionId } : {}),
|
|
124
|
+
...(model ? { runtimeModelId: reasoningOption?.runtimeModelId || model.id } : {}),
|
|
125
|
+
}),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
function isModelUsable(model) {
|
|
129
|
+
return model.availability === 'available' || model.availability === 'degraded';
|
|
130
|
+
}
|
|
131
|
+
export * from './capabilityRouting.js';
|
|
132
|
+
export * from './fanOutPlanner.js';
|
|
133
|
+
export * from './agentDiscovery.js';
|
|
134
|
+
//# sourceMappingURL=index.js.map
|