@telora/daemon 0.18.58 → 0.18.67

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 (89) hide show
  1. package/build-info.json +4 -3
  2. package/dist/cli/connect.d.ts +15 -11
  3. package/dist/cli/connect.d.ts.map +1 -1
  4. package/dist/cli/connect.js +20 -24
  5. package/dist/cli/connect.js.map +1 -1
  6. package/dist/completion/review-exit-phase.d.ts.map +1 -1
  7. package/dist/completion/review-exit-phase.js +37 -10
  8. package/dist/completion/review-exit-phase.js.map +1 -1
  9. package/dist/config.d.ts +16 -3
  10. package/dist/config.d.ts.map +1 -1
  11. package/dist/config.js +69 -13
  12. package/dist/config.js.map +1 -1
  13. package/dist/delivery-reconciler.d.ts +21 -1
  14. package/dist/delivery-reconciler.d.ts.map +1 -1
  15. package/dist/delivery-reconciler.js +21 -3
  16. package/dist/delivery-reconciler.js.map +1 -1
  17. package/dist/discovery-poll.d.ts.map +1 -1
  18. package/dist/discovery-poll.js +14 -2
  19. package/dist/discovery-poll.js.map +1 -1
  20. package/dist/focus-executor.d.ts +32 -3
  21. package/dist/focus-executor.d.ts.map +1 -1
  22. package/dist/focus-executor.js +89 -2
  23. package/dist/focus-executor.js.map +1 -1
  24. package/dist/focus-lifecycle.js +1 -1
  25. package/dist/focus-lifecycle.js.map +1 -1
  26. package/dist/focus-provisioning.js +1 -1
  27. package/dist/focus-provisioning.js.map +1 -1
  28. package/dist/git-fetch.d.ts +123 -0
  29. package/dist/git-fetch.d.ts.map +1 -0
  30. package/dist/git-fetch.js +164 -0
  31. package/dist/git-fetch.js.map +1 -0
  32. package/dist/git-state-detector.d.ts.map +1 -1
  33. package/dist/git-state-detector.js +63 -26
  34. package/dist/git-state-detector.js.map +1 -1
  35. package/dist/host-control/capability.d.ts +31 -0
  36. package/dist/host-control/capability.d.ts.map +1 -0
  37. package/dist/host-control/capability.js +50 -0
  38. package/dist/host-control/capability.js.map +1 -0
  39. package/dist/host-control/catalog.d.ts +48 -0
  40. package/dist/host-control/catalog.d.ts.map +1 -0
  41. package/dist/host-control/catalog.js +149 -0
  42. package/dist/host-control/catalog.js.map +1 -0
  43. package/dist/host-control/client.d.ts +76 -0
  44. package/dist/host-control/client.d.ts.map +1 -0
  45. package/dist/host-control/client.js +203 -0
  46. package/dist/host-control/client.js.map +1 -0
  47. package/dist/host-control/index.d.ts +18 -0
  48. package/dist/host-control/index.d.ts.map +1 -0
  49. package/dist/host-control/index.js +14 -0
  50. package/dist/host-control/index.js.map +1 -0
  51. package/dist/host-control/load.d.ts +136 -0
  52. package/dist/host-control/load.d.ts.map +1 -0
  53. package/dist/host-control/load.js +241 -0
  54. package/dist/host-control/load.js.map +1 -0
  55. package/dist/host-control/sizing.d.ts +207 -0
  56. package/dist/host-control/sizing.d.ts.map +1 -0
  57. package/dist/host-control/sizing.js +464 -0
  58. package/dist/host-control/sizing.js.map +1 -0
  59. package/dist/host-control/types.d.ts +174 -0
  60. package/dist/host-control/types.d.ts.map +1 -0
  61. package/dist/host-control/types.js +16 -0
  62. package/dist/host-control/types.js.map +1 -0
  63. package/dist/prd-controller.d.ts +10 -12
  64. package/dist/prd-controller.d.ts.map +1 -1
  65. package/dist/prd-controller.js +24 -54
  66. package/dist/prd-controller.js.map +1 -1
  67. package/dist/prompt-sections/persona-sections.d.ts +19 -0
  68. package/dist/prompt-sections/persona-sections.d.ts.map +1 -1
  69. package/dist/prompt-sections/persona-sections.js +55 -0
  70. package/dist/prompt-sections/persona-sections.js.map +1 -1
  71. package/dist/review-defect-detector.d.ts +33 -0
  72. package/dist/review-defect-detector.d.ts.map +1 -1
  73. package/dist/review-defect-detector.js +53 -0
  74. package/dist/review-defect-detector.js.map +1 -1
  75. package/dist/team-prompt-base.d.ts +1 -1
  76. package/dist/team-prompt-base.d.ts.map +1 -1
  77. package/dist/team-prompt-base.js +1 -1
  78. package/dist/team-prompt-base.js.map +1 -1
  79. package/dist/unified-init.d.ts.map +1 -1
  80. package/dist/unified-init.js +0 -2
  81. package/dist/unified-init.js.map +1 -1
  82. package/dist/unified-shell.d.ts.map +1 -1
  83. package/dist/unified-shell.js +0 -2
  84. package/dist/unified-shell.js.map +1 -1
  85. package/dist/worktree.d.ts +5 -2
  86. package/dist/worktree.d.ts.map +1 -1
  87. package/dist/worktree.js +6 -5
  88. package/dist/worktree.js.map +1 -1
  89. package/package.json +3 -3
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Typed JSON HTTP helpers for the host-control plane (Local model host control, D1).
3
+ *
4
+ * These mirror the security posture of `discovery-poll.ts` exactly: the host
5
+ * control surface is an operator-supplied LAN endpoint, so every request must
6
+ * (1) pass the SSRF guard before any network call (TEL-5), (2) time-box with an
7
+ * AbortController so an unreachable host fails fast (TEL-6), (3) cap the body
8
+ * read so a malicious/oversized response can't OOM the daemon (TEL-6), and
9
+ * (4) surface only address-free error categories -- the raw URL/system detail is
10
+ * logged daemon-side, never returned to a caller that may write it to an
11
+ * org-readable column (TEL-5, probe-oracle defense).
12
+ *
13
+ * `hostGet`/`hostPost` are deliberately generic over the decoded shape; the
14
+ * caller validates the `unknown` payload with a defensive normalizer (the
15
+ * control-surface JSON shape is host-specific and reconciled per the runbook).
16
+ */
17
+ /**
18
+ * Time-box a single host-control fetch. Mirrors `DISCOVERY_FETCH_TIMEOUT_MS`
19
+ * (5000ms) so the control probe fails fast on an unreachable host exactly like
20
+ * the `/v1/models` probe it rides alongside. Re-exported so callers and tests
21
+ * reference one source of truth.
22
+ */
23
+ export declare const HOST_CONTROL_FETCH_TIMEOUT_MS = 5000;
24
+ /**
25
+ * Hard ceiling on a host-control response body. A model catalog is small (~25
26
+ * entries observed live); this cap defends against an endpoint streaming an
27
+ * unbounded body to OOM the daemon (TEL-6). Mirrors discovery-poll's
28
+ * `MAX_DISCOVERY_BYTES` (1MB) -- declared as its own literal rather than
29
+ * re-exported to avoid an init-order coupling with the cyclic discovery-poll
30
+ * import (this module is imported by discovery-poll, which it also imports from).
31
+ */
32
+ export declare const HOST_CONTROL_MAX_BYTES = 1000000;
33
+ /**
34
+ * Address-free error categories for the host-control client. The control plane
35
+ * is fail-safe -- callers turn any of these into "not controllable, fall back to
36
+ * the floor" rather than propagating detail -- but they are kept distinct (and
37
+ * address-free) so daemon-side logs can categorize without leaking the endpoint.
38
+ */
39
+ export declare const HOST_CONTROL_ERROR_REJECTED_URL = "Rejected non-http(s) host URL";
40
+ export declare const HOST_CONTROL_ERROR_STATUS = "Host returned an error status";
41
+ export declare const HOST_CONTROL_ERROR_UNREACHABLE = "Host unreachable or timed out";
42
+ export declare const HOST_CONTROL_ERROR_INVALID = "Host response was not valid";
43
+ /**
44
+ * A host-control client error carrying a sanitized, address-free `dbMessage`
45
+ * alongside the rich `message` (URL/system detail) that is safe only for the
46
+ * daemon log. Same precedent as `discovery-poll`'s `DiscoveryError`.
47
+ */
48
+ export declare class HostControlError extends Error {
49
+ /** Address-free category string safe to surface anywhere (TEL-5). */
50
+ readonly dbMessage: string;
51
+ constructor(message: string,
52
+ /** Address-free category string safe to surface anywhere (TEL-5). */
53
+ dbMessage: string);
54
+ }
55
+ /** Options common to host-control requests. */
56
+ export interface HostRequestOptions {
57
+ /** Bearer key VALUE for an authenticated host (resolved from the Telora secret). */
58
+ apiKey?: string | null;
59
+ /** Per-request timeout override; defaults to `HOST_CONTROL_FETCH_TIMEOUT_MS`. */
60
+ timeoutMs?: number;
61
+ }
62
+ /** Typed JSON GET against a host-control URL. See `hostRequest` for the posture. */
63
+ export declare function hostGet<T>(url: string, opts?: HostRequestOptions): Promise<T>;
64
+ /** Typed JSON POST against a host-control URL. The body is JSON-encoded. */
65
+ export declare function hostPost<T>(url: string, body: unknown, opts?: HostRequestOptions): Promise<T>;
66
+ /**
67
+ * Derive the host ROOT from a stored `baseUrl`. The registry stores the
68
+ * OpenAI-compatible base (e.g. `http://host:8888/v1`), but the control surface
69
+ * lives under `/api` at the host root, NOT under `/v1`. Strip a single trailing
70
+ * `/v1` segment and any trailing slashes so callers can append `/api/...`. A
71
+ * `baseUrl` that is already a bare root passes through unchanged.
72
+ *
73
+ * Pure + exported for unit testing.
74
+ */
75
+ export declare function hostRootFromBaseUrl(baseUrl: string): string;
76
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/host-control/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAElD;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB,UAAY,CAAC;AAEhD;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,kCAAkC,CAAC;AAC/E,eAAO,MAAM,yBAAyB,kCAAkC,CAAC;AACzE,eAAO,MAAM,8BAA8B,kCAAkC,CAAC;AAC9E,eAAO,MAAM,0BAA0B,gCAAgC,CAAC;AAExE;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,KAAK;IAGvC,qEAAqE;IACrE,QAAQ,CAAC,SAAS,EAAE,MAAM;gBAF1B,OAAO,EAAE,MAAM;IACf,qEAAqE;IAC5D,SAAS,EAAE,MAAM;CAK7B;AAED,+CAA+C;AAC/C,MAAM,WAAW,kBAAkB;IACjC,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,iFAAiF;IACjF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA0ID,oFAAoF;AACpF,wBAAsB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,kBAAuB,GAAG,OAAO,CAAC,CAAC,CAAC,CAEvF;AAED,4EAA4E;AAC5E,wBAAsB,QAAQ,CAAC,CAAC,EAC9B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,OAAO,EACb,IAAI,GAAE,kBAAuB,GAC5B,OAAO,CAAC,CAAC,CAAC,CAMZ;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAO3D"}
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Typed JSON HTTP helpers for the host-control plane (Local model host control, D1).
3
+ *
4
+ * These mirror the security posture of `discovery-poll.ts` exactly: the host
5
+ * control surface is an operator-supplied LAN endpoint, so every request must
6
+ * (1) pass the SSRF guard before any network call (TEL-5), (2) time-box with an
7
+ * AbortController so an unreachable host fails fast (TEL-6), (3) cap the body
8
+ * read so a malicious/oversized response can't OOM the daemon (TEL-6), and
9
+ * (4) surface only address-free error categories -- the raw URL/system detail is
10
+ * logged daemon-side, never returned to a caller that may write it to an
11
+ * org-readable column (TEL-5, probe-oracle defense).
12
+ *
13
+ * `hostGet`/`hostPost` are deliberately generic over the decoded shape; the
14
+ * caller validates the `unknown` payload with a defensive normalizer (the
15
+ * control-surface JSON shape is host-specific and reconciled per the runbook).
16
+ */
17
+ import { isAllowedDiscoveryUrl } from '../discovery-poll.js';
18
+ /**
19
+ * Time-box a single host-control fetch. Mirrors `DISCOVERY_FETCH_TIMEOUT_MS`
20
+ * (5000ms) so the control probe fails fast on an unreachable host exactly like
21
+ * the `/v1/models` probe it rides alongside. Re-exported so callers and tests
22
+ * reference one source of truth.
23
+ */
24
+ export const HOST_CONTROL_FETCH_TIMEOUT_MS = 5000;
25
+ /**
26
+ * Hard ceiling on a host-control response body. A model catalog is small (~25
27
+ * entries observed live); this cap defends against an endpoint streaming an
28
+ * unbounded body to OOM the daemon (TEL-6). Mirrors discovery-poll's
29
+ * `MAX_DISCOVERY_BYTES` (1MB) -- declared as its own literal rather than
30
+ * re-exported to avoid an init-order coupling with the cyclic discovery-poll
31
+ * import (this module is imported by discovery-poll, which it also imports from).
32
+ */
33
+ export const HOST_CONTROL_MAX_BYTES = 1_000_000;
34
+ /**
35
+ * Address-free error categories for the host-control client. The control plane
36
+ * is fail-safe -- callers turn any of these into "not controllable, fall back to
37
+ * the floor" rather than propagating detail -- but they are kept distinct (and
38
+ * address-free) so daemon-side logs can categorize without leaking the endpoint.
39
+ */
40
+ export const HOST_CONTROL_ERROR_REJECTED_URL = 'Rejected non-http(s) host URL';
41
+ export const HOST_CONTROL_ERROR_STATUS = 'Host returned an error status';
42
+ export const HOST_CONTROL_ERROR_UNREACHABLE = 'Host unreachable or timed out';
43
+ export const HOST_CONTROL_ERROR_INVALID = 'Host response was not valid';
44
+ /**
45
+ * A host-control client error carrying a sanitized, address-free `dbMessage`
46
+ * alongside the rich `message` (URL/system detail) that is safe only for the
47
+ * daemon log. Same precedent as `discovery-poll`'s `DiscoveryError`.
48
+ */
49
+ export class HostControlError extends Error {
50
+ dbMessage;
51
+ constructor(message,
52
+ /** Address-free category string safe to surface anywhere (TEL-5). */
53
+ dbMessage) {
54
+ super(message);
55
+ this.dbMessage = dbMessage;
56
+ this.name = 'HostControlError';
57
+ }
58
+ }
59
+ /**
60
+ * Build request headers for a host-control call. When a bearer key VALUE is
61
+ * provided an `Authorization: Bearer <value>` header is added; a blank/absent
62
+ * value yields no auth header (unauthenticated probe). The value is never
63
+ * logged or persisted by this module. Mirrors `buildDiscoveryHeaders`.
64
+ */
65
+ function buildHostHeaders(apiKey, extra) {
66
+ const headers = { accept: 'application/json', ...extra };
67
+ const value = typeof apiKey === 'string' ? apiKey.trim() : '';
68
+ if (value)
69
+ headers.Authorization = `Bearer ${value}`;
70
+ return headers;
71
+ }
72
+ /**
73
+ * Read a fetch response body with a hard byte ceiling, aborting once the cap is
74
+ * exceeded so a lying Content-Length (or a chunked body with none) can't OOM the
75
+ * daemon (TEL-6). Returns the decoded text. Throws a `HostControlError` past the
76
+ * ceiling. Mirrors `discovery-poll`'s `readBodyCapped`.
77
+ */
78
+ async function readBodyCapped(res) {
79
+ const body = res.body;
80
+ if (!body) {
81
+ // No stream available -- fall back to arrayBuffer but still cap by byteLength.
82
+ const buf = await res.arrayBuffer();
83
+ if (buf.byteLength > HOST_CONTROL_MAX_BYTES) {
84
+ throw new HostControlError('Response body exceeded byte ceiling', HOST_CONTROL_ERROR_INVALID);
85
+ }
86
+ return new TextDecoder().decode(buf);
87
+ }
88
+ const reader = body.getReader();
89
+ const chunks = [];
90
+ let total = 0;
91
+ try {
92
+ for (;;) {
93
+ const { done, value } = await reader.read();
94
+ if (done)
95
+ break;
96
+ if (value) {
97
+ total += value.byteLength;
98
+ if (total > HOST_CONTROL_MAX_BYTES) {
99
+ throw new HostControlError('Response body exceeded byte ceiling', HOST_CONTROL_ERROR_INVALID);
100
+ }
101
+ chunks.push(value);
102
+ }
103
+ }
104
+ }
105
+ finally {
106
+ // Stop the underlying transfer; ignore cancel errors.
107
+ await reader.cancel().catch(() => { });
108
+ }
109
+ const merged = new Uint8Array(total);
110
+ let offset = 0;
111
+ for (const c of chunks) {
112
+ merged.set(c, offset);
113
+ offset += c.byteLength;
114
+ }
115
+ return new TextDecoder().decode(merged);
116
+ }
117
+ /**
118
+ * Map a non-2xx status to an address-free category. 401/403 surface as a status
119
+ * error here (the host-control plane is optional, so an auth wall just means we
120
+ * fall back to the floor) -- unlike discovery, we don't disclose an auth-specific
121
+ * message, because a control-surface 401 is not independently actionable.
122
+ */
123
+ function statusDbMessage(_status) {
124
+ return HOST_CONTROL_ERROR_STATUS;
125
+ }
126
+ /**
127
+ * Issue a host-control request and decode the JSON body, enforcing the full
128
+ * security posture (SSRF guard, timeout, byte cap, address-free errors). Shared
129
+ * core of `hostGet`/`hostPost`. Throws a `HostControlError` on any failure.
130
+ */
131
+ async function hostRequest(url, init, opts) {
132
+ // TEL-5: validate the operator-supplied URL before any network call -- reject
133
+ // anything that isn't a parseable http/https URL (no file:, ftp:, etc).
134
+ if (!isAllowedDiscoveryUrl(url)) {
135
+ throw new HostControlError(`Rejected non-http(s) host-control URL: ${url}`, HOST_CONTROL_ERROR_REJECTED_URL);
136
+ }
137
+ const timeoutMs = opts.timeoutMs ?? HOST_CONTROL_FETCH_TIMEOUT_MS;
138
+ const controller = new AbortController();
139
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
140
+ try {
141
+ const extra = init.method === 'POST' && init.contentType ? { 'content-type': init.contentType } : undefined;
142
+ const res = await fetch(url, {
143
+ method: init.method,
144
+ signal: controller.signal,
145
+ headers: buildHostHeaders(opts.apiKey, extra),
146
+ ...(init.body !== undefined ? { body: init.body } : {}),
147
+ });
148
+ if (!res.ok) {
149
+ throw new HostControlError(`Host returned HTTP ${res.status}`, statusDbMessage(res.status));
150
+ }
151
+ // TEL-6: reject a too-large declared body up front, then defensively cap the
152
+ // actual stream in case the header lied / is absent.
153
+ const declared = Number(res.headers.get('content-length'));
154
+ if (Number.isFinite(declared) && declared > HOST_CONTROL_MAX_BYTES) {
155
+ throw new HostControlError(`Declared Content-Length ${declared} exceeds cap`, HOST_CONTROL_ERROR_INVALID);
156
+ }
157
+ const text = await readBodyCapped(res);
158
+ try {
159
+ return JSON.parse(text);
160
+ }
161
+ catch {
162
+ throw new HostControlError('Response body was not valid JSON', HOST_CONTROL_ERROR_INVALID);
163
+ }
164
+ }
165
+ catch (err) {
166
+ if (err instanceof HostControlError)
167
+ throw err;
168
+ if (err.name === 'AbortError') {
169
+ throw new HostControlError(`Timed out after ${timeoutMs}ms reaching ${url}`, HOST_CONTROL_ERROR_UNREACHABLE);
170
+ }
171
+ // Network-level failure (DNS, connection refused, TLS): generic to callers.
172
+ throw new HostControlError(err.message || `Failed to reach ${url}`, HOST_CONTROL_ERROR_UNREACHABLE);
173
+ }
174
+ finally {
175
+ clearTimeout(timer);
176
+ }
177
+ }
178
+ /** Typed JSON GET against a host-control URL. See `hostRequest` for the posture. */
179
+ export async function hostGet(url, opts = {}) {
180
+ return hostRequest(url, { method: 'GET' }, opts);
181
+ }
182
+ /** Typed JSON POST against a host-control URL. The body is JSON-encoded. */
183
+ export async function hostPost(url, body, opts = {}) {
184
+ return hostRequest(url, { method: 'POST', body: JSON.stringify(body ?? {}), contentType: 'application/json' }, opts);
185
+ }
186
+ /**
187
+ * Derive the host ROOT from a stored `baseUrl`. The registry stores the
188
+ * OpenAI-compatible base (e.g. `http://host:8888/v1`), but the control surface
189
+ * lives under `/api` at the host root, NOT under `/v1`. Strip a single trailing
190
+ * `/v1` segment and any trailing slashes so callers can append `/api/...`. A
191
+ * `baseUrl` that is already a bare root passes through unchanged.
192
+ *
193
+ * Pure + exported for unit testing.
194
+ */
195
+ export function hostRootFromBaseUrl(baseUrl) {
196
+ // Trim trailing slashes first so a trailing-slash `/v1/` still matches.
197
+ const trimmed = baseUrl.replace(/\/+$/, '');
198
+ // Strip exactly one trailing `/v1` segment (case-sensitive, the API convention).
199
+ const root = trimmed.replace(/\/v1$/, '');
200
+ // A `/v1` with its own trailing slash (`/v1/`) leaves a dangling slash; clean it.
201
+ return root.replace(/\/+$/, '');
202
+ }
203
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/host-control/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Host-control plane barrel (Local model host control, D1).
3
+ *
4
+ * The spine for detecting and reading a controllable model host ABOVE the
5
+ * OpenAI-compatible `/v1/models` floor. Delivery 1 ships the client, capability
6
+ * detection, and catalog read; later deliveries add `load.ts` (id -> model_path
7
+ * load/unload) and `sizing.ts` -- export those from here when they land.
8
+ */
9
+ export type { HostCapability, LoadableCatalog, LoadableModel, HostStatus, LoadModelParams, SwapAction, SwapDecision, HostHardware, KvCacheEstimate, KvCacheEstimateParams, SafeMaxSeqInput, SafeMaxSeqResult, } from './types.js';
10
+ export { hostGet, hostPost, hostRootFromBaseUrl, HostControlError, HOST_CONTROL_FETCH_TIMEOUT_MS, HOST_CONTROL_MAX_BYTES, HOST_CONTROL_ERROR_REJECTED_URL, HOST_CONTROL_ERROR_STATUS, HOST_CONTROL_ERROR_UNREACHABLE, HOST_CONTROL_ERROR_INVALID, } from './client.js';
11
+ export type { HostRequestOptions } from './client.js';
12
+ export { detectHostCapability, isControllableCatalogPayload } from './capability.js';
13
+ export { readLoadableCatalog, normalizeLocalCatalog, HOST_CONTROL_CATALOG_PATH, } from './catalog.js';
14
+ export { loadModel, unloadModel, getStatus, resolveModelPath, decideSwap, ensureLoaded, normalizeStatus, DEFAULT_MAX_SEQ_LENGTH, HOST_CONTROL_LOAD_PATH, HOST_CONTROL_UNLOAD_PATH, HOST_CONTROL_STATUS_PATH, HOST_CONTROL_LOAD_READY_TIMEOUT_MS, HOST_CONTROL_LOAD_POLL_INTERVAL_MS, HOST_CONTROL_ERROR_LOAD_TIMEOUT, } from './load.js';
15
+ export type { EnsureLoadedOptions } from './load.js';
16
+ export { getHardware, getKvCacheEstimate, normalizeHardware, normalizeKvCacheEstimate, computeSafeMaxSeqLength, resolveSafeLoadOptions, CODEX_TURN1_FLOOR, VRAM_SAFETY_MARGIN_MB, KV_CACHE_MB_PER_TOKEN, KV_QUANT_FOOTPRINT_FACTOR, KV_QUANT_CACHE_TYPE, MAX_SEQ_LENGTH_CEILING, HOST_CONTROL_HARDWARE_PATH, HOST_CONTROL_KV_CACHE_PATH, } from './sizing.js';
17
+ export type { SafeLoadSizingHints } from './sizing.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/host-control/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,YAAY,EACV,cAAc,EACd,eAAe,EACf,aAAa,EACb,UAAU,EACV,eAAe,EACf,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,qBAAqB,EACrB,eAAe,EACf,gBAAgB,GACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,OAAO,EACP,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,EAChB,6BAA6B,EAC7B,sBAAsB,EACtB,+BAA+B,EAC/B,yBAAyB,EACzB,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAErF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,kCAAkC,EAClC,kCAAkC,EAClC,+BAA+B,GAChC,MAAM,WAAW,CAAC;AACnB,YAAY,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAErD,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AACrB,YAAY,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Host-control plane barrel (Local model host control, D1).
3
+ *
4
+ * The spine for detecting and reading a controllable model host ABOVE the
5
+ * OpenAI-compatible `/v1/models` floor. Delivery 1 ships the client, capability
6
+ * detection, and catalog read; later deliveries add `load.ts` (id -> model_path
7
+ * load/unload) and `sizing.ts` -- export those from here when they land.
8
+ */
9
+ export { hostGet, hostPost, hostRootFromBaseUrl, HostControlError, HOST_CONTROL_FETCH_TIMEOUT_MS, HOST_CONTROL_MAX_BYTES, HOST_CONTROL_ERROR_REJECTED_URL, HOST_CONTROL_ERROR_STATUS, HOST_CONTROL_ERROR_UNREACHABLE, HOST_CONTROL_ERROR_INVALID, } from './client.js';
10
+ export { detectHostCapability, isControllableCatalogPayload } from './capability.js';
11
+ export { readLoadableCatalog, normalizeLocalCatalog, HOST_CONTROL_CATALOG_PATH, } from './catalog.js';
12
+ export { loadModel, unloadModel, getStatus, resolveModelPath, decideSwap, ensureLoaded, normalizeStatus, DEFAULT_MAX_SEQ_LENGTH, HOST_CONTROL_LOAD_PATH, HOST_CONTROL_UNLOAD_PATH, HOST_CONTROL_STATUS_PATH, HOST_CONTROL_LOAD_READY_TIMEOUT_MS, HOST_CONTROL_LOAD_POLL_INTERVAL_MS, HOST_CONTROL_ERROR_LOAD_TIMEOUT, } from './load.js';
13
+ export { getHardware, getKvCacheEstimate, normalizeHardware, normalizeKvCacheEstimate, computeSafeMaxSeqLength, resolveSafeLoadOptions, CODEX_TURN1_FLOOR, VRAM_SAFETY_MARGIN_MB, KV_CACHE_MB_PER_TOKEN, KV_QUANT_FOOTPRINT_FACTOR, KV_QUANT_CACHE_TYPE, MAX_SEQ_LENGTH_CEILING, HOST_CONTROL_HARDWARE_PATH, HOST_CONTROL_KV_CACHE_PATH, } from './sizing.js';
14
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/host-control/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAiBH,OAAO,EACL,OAAO,EACP,QAAQ,EACR,mBAAmB,EACnB,gBAAgB,EAChB,6BAA6B,EAC7B,sBAAsB,EACtB,+BAA+B,EAC/B,yBAAyB,EACzB,8BAA8B,EAC9B,0BAA0B,GAC3B,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,oBAAoB,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAErF,OAAO,EACL,mBAAmB,EACnB,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,SAAS,EACT,WAAW,EACX,SAAS,EACT,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,kCAAkC,EAClC,kCAAkC,EAClC,+BAA+B,GAChC,MAAM,WAAW,CAAC;AAGnB,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,mBAAmB,EACnB,sBAAsB,EACtB,0BAA0B,EAC1B,0BAA0B,GAC3B,MAAM,aAAa,CAAC"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Load / unload orchestration for the host-control plane (Local model host
3
+ * control, D2).
4
+ *
5
+ * Per-pass model selection (D1) records which local model a coding vs review
6
+ * pass wants, but the daemon had no LOAD path -- so the selection could not
7
+ * drive an actual model switch. This module closes that gap: it loads / unloads
8
+ * the chosen per-pass model around each pass as a SEQUENTIAL swap on a single
9
+ * GPU (one model resident at a time -- loading evicts the prior), so a distinct
10
+ * coding-vs-review model can run end-to-end with NO manual swap in the studio.
11
+ *
12
+ * The control endpoints live under `/v1` (reachable from the stored baseUrl
13
+ * directly, which already ends in `/v1`): `POST /v1/load`, `POST /v1/unload`,
14
+ * `GET /v1/status`. Live JSON shapes are host-specific; `/v1/status` in
15
+ * particular is NOT pinned, so `normalizeStatus` is DEFENSIVE (tolerant of
16
+ * reasonable field names) and must be reconciled per the runbook.
17
+ *
18
+ * The maxSeqLength a load uses is an INJECTED input (an option, never hardcoded
19
+ * inside `ensureLoaded`) so Delivery 3 can replace the fixed `DEFAULT_MAX_SEQ_LENGTH`
20
+ * floor with a computed safe value without re-architecting this module.
21
+ */
22
+ import type { HostStatus, LoadModelParams, SwapDecision } from './types.js';
23
+ /**
24
+ * The control surface lives under `/v1` -- the SAME segment the stored baseUrl
25
+ * already ends in. We append these to the baseUrl directly (NOT the host root):
26
+ * a baseUrl of `http://host:8888/v1` yields `http://host:8888/v1/load`. A
27
+ * baseUrl without a trailing `/v1` still composes a sane path.
28
+ */
29
+ export declare const HOST_CONTROL_LOAD_PATH = "/load";
30
+ export declare const HOST_CONTROL_UNLOAD_PATH = "/unload";
31
+ export declare const HOST_CONTROL_STATUS_PATH = "/status";
32
+ /**
33
+ * Default max sequence length for a load. Sized at the live-proven 16384, which
34
+ * clears codex's ~8k turn-1 context floor with headroom. NOTE: Delivery 3 will
35
+ * REPLACE this fixed value with a computed safe value derived from the model +
36
+ * available VRAM; `loadModel`/`ensureLoaded` take maxSeqLength as an INJECTED
37
+ * input so D3 can pass a computed value without touching this module's shape.
38
+ */
39
+ export declare const DEFAULT_MAX_SEQ_LENGTH = 16384;
40
+ /**
41
+ * How long `ensureLoaded` will poll `/v1/status` for the target to become ready
42
+ * after issuing a load before giving up with a typed timeout. A cold load on a
43
+ * 12GB GPU has real latency; this is the bounded ceiling, not the expected wait.
44
+ */
45
+ export declare const HOST_CONTROL_LOAD_READY_TIMEOUT_MS = 180000;
46
+ /** Interval between `/v1/status` readiness polls while waiting for a load. */
47
+ export declare const HOST_CONTROL_LOAD_POLL_INTERVAL_MS = 2000;
48
+ /** Address-free category for a load that never reached ready within the budget. */
49
+ export declare const HOST_CONTROL_ERROR_LOAD_TIMEOUT = "Host load did not reach ready in time";
50
+ /**
51
+ * Normalize a `/v1/status` payload into a typed `HostStatus`. DEFENSIVE: the
52
+ * live shape is NOT pinned, so we tolerate the loaded-model id under any of
53
+ * `model`/`id`/`loaded_model`/... and readiness under `status`/`state`/`ready`
54
+ * (string token OR boolean). A payload that proves nothing loaded yields
55
+ * `{ loadedModelId: null, ready: false }`. Pure + exported for unit testing.
56
+ *
57
+ * Runbook flag: confirm the live `/v1/status` field names + readiness vocabulary
58
+ * and tighten `STATUS_*_KEYS` / `READY_TOKENS` once observed.
59
+ */
60
+ export declare function normalizeStatus(payload: unknown): HostStatus;
61
+ /**
62
+ * Issue a model load (`POST /v1/load`). Maps camelCase app params to the host's
63
+ * snake_case wire field names (`model_path`, `max_seq_length`, `cache_type_kv`,
64
+ * `gpu_ids`) at THIS boundary only. `maxSeqLength` is a required INJECTED input
65
+ * so D3 can pass a computed value. Throws `HostControlError` on any failure.
66
+ */
67
+ export declare function loadModel(baseUrl: string, params: LoadModelParams, apiKey?: string | null): Promise<void>;
68
+ /** Issue an unload (`POST /v1/unload`) -- evicts whatever is currently resident. */
69
+ export declare function unloadModel(baseUrl: string, apiKey?: string | null): Promise<void>;
70
+ /** Read current host status (`GET /v1/status`), normalized to a typed shape. */
71
+ export declare function getStatus(baseUrl: string, apiKey?: string | null): Promise<HostStatus>;
72
+ /**
73
+ * Resolve a chosen local_models `model` id to the host's `model_path` by reading
74
+ * the loadable catalog (D1) and matching by id. Returns null when the host is
75
+ * not controllable, the id is not in the catalog, or the matching entry carries
76
+ * no modelPath (a floor entry). The caller treats null as "cannot load" and
77
+ * skips the swap.
78
+ */
79
+ export declare function resolveModelPath(baseUrl: string, modelId: string, apiKey?: string | null): Promise<string | null>;
80
+ /**
81
+ * PURE swap decision over the current vs target resident model. Extracted from
82
+ * `ensureLoaded` so the core single-GPU swap logic is unit-testable with NO HTTP:
83
+ *
84
+ * - target already resident + ready -> 'noop'
85
+ * - a DIFFERENT model resident -> 'evict_then_load' (single GPU -- evict first)
86
+ * - nothing resident -> 'load'
87
+ *
88
+ * `current.modelId` is the currently-loaded id (null = nothing resident);
89
+ * `current.ready` gates the noop (a resident-but-not-ready target still needs a
90
+ * poll, but no reload -- treated as 'load' here so `ensureLoaded` re-issues +
91
+ * polls; the host treats a load of the resident model as a fast no-op/confirm).
92
+ */
93
+ export declare function decideSwap(input: {
94
+ current: {
95
+ modelId: string | null;
96
+ ready: boolean;
97
+ };
98
+ target: string;
99
+ }): SwapDecision;
100
+ /** Options for `ensureLoaded`. `maxSeqLength` is injected (D3 computes it). */
101
+ export interface EnsureLoadedOptions {
102
+ /** Context window to load with. Defaults to `DEFAULT_MAX_SEQ_LENGTH`. */
103
+ maxSeqLength?: number;
104
+ /** Optional KV cache dtype passed through to the load. */
105
+ cacheTypeKv?: string;
106
+ /** Optional GPU id selection passed through to the load. */
107
+ gpuIds?: number[];
108
+ /** Override the ready-poll budget (ms). Defaults to the module constant. */
109
+ readyTimeoutMs?: number;
110
+ /** Override the ready-poll interval (ms). Defaults to the module constant. */
111
+ pollIntervalMs?: number;
112
+ /**
113
+ * Injectable sleep, so the timeout/poll path is fast + deterministic in tests.
114
+ * Defaults to a real `setTimeout` wait.
115
+ */
116
+ sleep?: (ms: number) => Promise<void>;
117
+ /** Injectable clock for the bounded-poll deadline (defaults to `Date.now`). */
118
+ now?: () => number;
119
+ }
120
+ /**
121
+ * Orchestrate the SEQUENTIAL single-GPU swap so the target model is resident +
122
+ * ready before the caller spawns against it:
123
+ *
124
+ * 1. read status; if the target is already resident + ready -> no-op return.
125
+ * 2. else: if a DIFFERENT model is resident, unload it first (single GPU --
126
+ * one resident at a time). Resolve the target id -> model_path, then load
127
+ * with the injected maxSeqLength.
128
+ * 3. poll `/v1/status` until the target is ready, or throw a typed timeout
129
+ * (`HOST_CONTROL_ERROR_LOAD_TIMEOUT`) once the bounded budget elapses.
130
+ *
131
+ * Throws `HostControlError` on an unresolvable path, a load/unload failure, or
132
+ * the ready timeout. The caller (focus-executor) turns any throw into "skip the
133
+ * spawn this tick" -- it must NOT spawn against a not-yet-loaded model.
134
+ */
135
+ export declare function ensureLoaded(baseUrl: string, modelId: string, opts?: EnsureLoadedOptions, apiKey?: string | null): Promise<void>;
136
+ //# sourceMappingURL=load.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"load.d.ts","sourceRoot":"","sources":["../../src/host-control/load.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAc,YAAY,EAAE,MAAM,YAAY,CAAC;AAExF;;;;;GAKG;AACH,eAAO,MAAM,sBAAsB,UAAU,CAAC;AAC9C,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAClD,eAAO,MAAM,wBAAwB,YAAY,CAAC;AAElD;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB,QAAQ,CAAC;AAE5C;;;;GAIG;AACH,eAAO,MAAM,kCAAkC,SAAU,CAAC;AAE1D,8EAA8E;AAC9E,eAAO,MAAM,kCAAkC,OAAQ,CAAC;AAExD,mFAAmF;AACnF,eAAO,MAAM,+BAA+B,0CAA0C,CAAC;AAoCvF;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,UAAU,CA4B5D;AAED;;;;;GAKG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,IAAI,CAAC,CAQf;AAED,oFAAoF;AACpF,wBAAsB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAExF;AAED,gFAAgF;AAChF,wBAAsB,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,CAAC,CAG5F;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAIxB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE;IAChC,OAAO,EAAE;QAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;IACpD,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,YAAY,CAWf;AAED,+EAA+E;AAC/E,MAAM,WAAW,mBAAmB;IAClC,yEAAyE;IACzE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,4EAA4E;IAC5E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,+EAA+E;IAC/E,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAMD;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,IAAI,GAAE,mBAAwB,EAC9B,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GACrB,OAAO,CAAC,IAAI,CAAC,CAqDf"}