@qvac/harness 0.8.5 → 0.8.7

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 (88) hide show
  1. package/CHANGELOG.md +1278 -472
  2. package/README.md +49 -0
  3. package/dist-lib/index.d.ts +42 -2
  4. package/dist-lib/index.js +447 -58
  5. package/dist-lib/lib/audio-transcode-bare.d.ts +1 -1
  6. package/dist-lib/lib/audio-transcode-bare.js +22 -25
  7. package/dist-lib/lib/audio-transcode-node.d.ts +1 -1
  8. package/dist-lib/lib/audio-transcode-node.js +1 -3
  9. package/dist-lib/lib/capabilities/audio-resample.d.ts +1 -1
  10. package/dist-lib/lib/capabilities/audio-resample.js +7 -8
  11. package/dist-lib/lib/capabilities/completion.d.ts +6 -3
  12. package/dist-lib/lib/capabilities/completion.js +96 -49
  13. package/dist-lib/lib/capabilities/download.d.ts +3 -1
  14. package/dist-lib/lib/capabilities/download.js +1 -1
  15. package/dist-lib/lib/capabilities/preview-model-source.d.ts +1 -0
  16. package/dist-lib/lib/capabilities/preview-model-source.js +1 -0
  17. package/dist-lib/lib/capabilities/tool-selection.d.ts +1 -3
  18. package/dist-lib/lib/capabilities/tool-selection.js +2 -4
  19. package/dist-lib/lib/capabilities/tool-turns.d.ts +0 -1
  20. package/dist-lib/lib/capabilities/tool-turns.js +0 -6
  21. package/dist-lib/lib/capabilities/usage-breakdown.js +4 -1
  22. package/dist-lib/lib/capabilities/voice.d.ts +5 -1
  23. package/dist-lib/lib/capabilities/voice.js +94 -26
  24. package/dist-lib/lib/connect.d.ts +4 -1
  25. package/dist-lib/lib/connect.js +16 -1
  26. package/dist-lib/lib/contract-types.d.ts +12 -0
  27. package/dist-lib/lib/helpers/tool-call-markup.d.ts +1 -0
  28. package/dist-lib/lib/helpers/tool-call-markup.js +3 -0
  29. package/dist-lib/lib/models/context-choice.d.ts +15 -0
  30. package/dist-lib/lib/models/context-choice.js +55 -0
  31. package/dist-lib/lib/models/download-gate.d.ts +20 -0
  32. package/dist-lib/lib/models/download-gate.js +73 -0
  33. package/dist-lib/lib/models/memory-cap.d.ts +13 -0
  34. package/dist-lib/lib/models/memory-cap.js +21 -0
  35. package/dist-lib/lib/models/model-catalog-constants.d.ts +3 -1
  36. package/dist-lib/lib/models/model-catalog-constants.js +9 -1
  37. package/dist-lib/lib/models/model-catalog.d.ts +6 -2
  38. package/dist-lib/lib/models/model-catalog.js +35 -3
  39. package/dist-lib/lib/models/model-handle.d.ts +8 -1
  40. package/dist-lib/lib/models/model-handle.js +20 -2
  41. package/dist-lib/lib/models/model-list.d.ts +8 -1
  42. package/dist-lib/lib/models/model-list.js +23 -0
  43. package/dist-lib/lib/models/model-pool.d.ts +35 -5
  44. package/dist-lib/lib/models/model-pool.js +97 -32
  45. package/dist-lib/lib/models/sdk-faults.d.ts +1 -0
  46. package/dist-lib/lib/models/sdk-faults.js +6 -0
  47. package/dist-lib/lib/office/engine/pptx/picture-area.d.ts +23 -0
  48. package/dist-lib/lib/office/engine/pptx/picture-area.js +84 -0
  49. package/dist-lib/lib/office/engine/pptx/presentation.d.ts +2 -0
  50. package/dist-lib/lib/office/engine/pptx/presentation.js +55 -17
  51. package/dist-lib/lib/office/engine/pptx/types.d.ts +1 -0
  52. package/dist-lib/lib/office/engine/xlsx/workbook.d.ts +1 -0
  53. package/dist-lib/lib/office/engine/xlsx/workbook.js +34 -3
  54. package/dist-lib/lib/serve.js +23 -3
  55. package/dist-lib/lib/spawn.js +4 -10
  56. package/dist-lib/lib/tools/exec.d.ts +4 -1
  57. package/dist-lib/lib/tools/exec.js +55 -11
  58. package/dist-lib/lib/tools/generate-image.d.ts +4 -2
  59. package/dist-lib/lib/tools/generate-image.js +5 -2
  60. package/dist-lib/lib/tools/generate-music.d.ts +4 -2
  61. package/dist-lib/lib/tools/generate-music.js +5 -2
  62. package/dist-lib/lib/tools/office/ops.js +1 -1
  63. package/dist-lib/lib/tools/office.js +29 -6
  64. package/dist-lib/lib/tools/skills/catalog.d.ts +1 -0
  65. package/dist-lib/lib/tools/skills/catalog.js +2 -0
  66. package/dist-lib/lib/tools/skills/cli-schema-check.d.ts +1 -0
  67. package/dist-lib/lib/tools/skills/cli-schema-check.js +3 -0
  68. package/dist-lib/lib/tools/skills/cli-schema-load.js +10 -0
  69. package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +2 -0
  70. package/dist-lib/lib/tools/skills/cli-schema.js +6 -3
  71. package/dist-lib/lib/tools/skills/frontmatter-parser.d.ts +1 -0
  72. package/dist-lib/lib/tools/skills/manifest-parse.d.ts +1 -0
  73. package/dist-lib/lib/tools/skills/manifest-parse.js +12 -0
  74. package/dist-lib/lib/tools/skills/mention.d.ts +0 -1
  75. package/dist-lib/lib/tools/skills/mention.js +0 -3
  76. package/dist-lib/lib/tools/translate.d.ts +3 -1
  77. package/dist-lib/lib/tools/translate.js +6 -1
  78. package/dist-lib/schema/harness.js +43 -4
  79. package/dist-lib/spec/bind.js +9 -0
  80. package/dist-lib/spec/calls.js +3 -0
  81. package/dist-lib/spec/hrpc/hrpc.json +39 -0
  82. package/dist-lib/spec/hrpc/index.js +39 -3
  83. package/dist-lib/spec/hrpc/messages.js +101 -13
  84. package/dist-lib/spec/hyperschema/index.js +101 -13
  85. package/dist-lib/spec/hyperschema/schema.json +62 -1
  86. package/dist-lib/spec/hyperschema/types.d.ts +20 -2
  87. package/package.json +8 -10
  88. package/worker/harness-sidecar.mjs +2 -1
package/README.md CHANGED
@@ -268,6 +268,55 @@ unloaded, and the next call loads what it needs again. The clock covers the
268
268
  whole device: any call resets it, whichever model it uses. `0`, the default, is
269
269
  Never.
270
270
 
271
+ ## Keeping several models in memory
272
+
273
+ ```js
274
+ await harness.setModelMemoryCap(85)
275
+ ```
276
+
277
+ Loaded models may fill that percent of the device's `memoryBudget`, so two chat
278
+ models that fit stay loaded and a chat switching between them loads neither
279
+ again. A model is unloaded only when the next load would not fit, one at a time:
280
+ idle image and music models first, then embedding, speech and transcription
281
+ models, then chat models a request loaded, then chat models loaded by hand, the
282
+ least recently used first within each. A model a request holds stays, and a
283
+ load past the cap goes ahead once nothing else can give way, so a model larger
284
+ than the cap loads alone. A manual `loadModel`, of any kind, still never unloads
285
+ another model: beside what is loaded it must fit the cap, or it is refused with
286
+ `reason: 'memory'`. Lowering the cap unloads idle models past it at once. Loads
287
+ under way count by their estimate, so two at once never count on the same room.
288
+
289
+ Each load is sized by the SDK's `assessModelFit` for exactly the load it runs,
290
+ falling back to the download size, and `list()` rows of loaded models carry that
291
+ estimate as `memoryBytes`. `memoryUsage()` answers what every loaded model holds,
292
+ whichever list rows a host reads. `0`, and any cap on a mobile device, keeps one chat
293
+ model a request loaded, as without a cap; a host that never calls it keeps that
294
+ behaviour and sizes nothing.
295
+
296
+ ## Holding model downloads
297
+
298
+ ```js
299
+ await harness.setDownloadsAllowed({ allowed: false })
300
+ ```
301
+
302
+ With downloads not allowed, a load whose model is not on the device does not
303
+ download it. This covers every load the harness makes: chat, embedding, speech,
304
+ transcription, image, music and translation. The load emits one `model` event
305
+ with `status: 'held'`, the model's download name and its `addon`, then waits.
306
+ Each `download()` that completes re-checks every waiting load, and a load goes
307
+ ahead once its model is on the device, or once
308
+ `setDownloadsAllowed({ allowed: true })` arrives, with no retry from the caller.
309
+ Aborting the caller's signal ends the wait with `AbortedError`, and a suspend or
310
+ close ends every wait. A wait that ends without loading reports `error` with
311
+ `message: 'aborted'`. A released wait reports nothing of its own: the `loading`
312
+ and `ready` after it name the model the way the pool does, which for embedding,
313
+ speech and transcription is not the row name. So a host clears `held` when its
314
+ `download()` of the row completes, when it allows downloads again, or on that
315
+ `error`. A model already on the device loads with no wait. The
316
+ check is the one `list({ cachedOnly: true })` makes, so a model counts as on the
317
+ device only when its companions and projection are too. `download()` itself is
318
+ never held. Downloads are allowed by default.
319
+
271
320
  ## Office extraction
272
321
 
273
322
  Hosts can supply the bundled Python extractor to their document pipeline:
@@ -10,7 +10,7 @@ import { type EmbedContext } from './lib/capabilities/embed.ts';
10
10
  import { type KvCacheDeletionResult } from './lib/capabilities/kv-cache.ts';
11
11
  import type { LlmGenerationParams } from './lib/models/llm-presets.ts';
12
12
  import { type SpeakContext, type SpeakResult, type SpeakStreamContext, type TranscribeContext } from './lib/capabilities/voice.ts';
13
- import type { CapabilityInfo, CredentialEntry, HarnessDiagnostics, InfraModel, LoadModelResult, SkillsOptions, SkillWriteResult, UnloadModelContext, UnloadModelResult } from './lib/contract-types.ts';
13
+ import type { CapabilityInfo, CredentialEntry, HarnessDiagnostics, InfraModel, LoadModelResult, MemoryUsage, SkillsOptions, SkillWriteResult, UnloadModelContext, UnloadModelResult } from './lib/contract-types.ts';
14
14
  import { type CustomModelEntry } from './lib/models/model-catalog.ts';
15
15
  import { type ListModelsOptions, type ModelInfo } from './lib/models/model-list.ts';
16
16
  import { type DeleteModelSummary } from './lib/models/model-delete.ts';
@@ -54,7 +54,7 @@ export { isAvailableState, SKILL_STATE, type SkillState } from './lib/tools/skil
54
54
  export { connectHarness, HARNESS_DIED, RemoteHarness } from './lib/connect.ts';
55
55
  export type { KvCacheDeletionResult } from './lib/capabilities/kv-cache.ts';
56
56
  export type { AgentKnobs, ApprovalCall, ChatMessage, CredentialEntry, DownloadContext, HarnessContract, HarnessDiagnostics, HarnessEvent, HarnessInfo, HarnessStatus, InfraModel, ModelState, SkillsOptions, SkillWriteResult } from './lib/contract-types.ts';
57
- import type { HarnessInfo } from './lib/contract-types.ts';
57
+ import type { DownloadsAllowedOptions, HarnessInfo } from './lib/contract-types.ts';
58
58
  export { serveHarness } from './lib/serve.ts';
59
59
  export { hlog, setHarnessLog, setHarnessLogSink } from './lib/log.ts';
60
60
  export { harnessHooks } from './lib/hooks/registry.ts';
@@ -99,7 +99,9 @@ export interface CompletionContext {
99
99
  model: string;
100
100
  agent?: Agent;
101
101
  messages: Message[];
102
+ typedText?: string;
102
103
  cacheKey?: string;
104
+ session?: string;
103
105
  thinkingDefault?: string;
104
106
  toolConfigs?: Record<string, Record<string, unknown>>;
105
107
  generationParams?: LlmGenerationParams;
@@ -142,6 +144,8 @@ export declare class Harness extends ReadyResource {
142
144
  private readonly _pinned;
143
145
  private readonly _replying;
144
146
  private readonly _modelStatus;
147
+ private readonly _downloads;
148
+ private readonly _hold;
145
149
  private _models;
146
150
  private _embedModels;
147
151
  private readonly _retiredEmbedModels;
@@ -184,6 +188,12 @@ export declare class Harness extends ReadyResource {
184
188
  private _capabilityInflight;
185
189
  private readonly _modelFaults;
186
190
  private readonly _idle;
191
+ private _sizeLoads;
192
+ private _capBytes;
193
+ private readonly _reserved;
194
+ private readonly _contexts;
195
+ private readonly _admission;
196
+ private readonly _byHand;
187
197
  constructor({ tools, sdkLoader, skillsDir, modelsDir, projectionModel, imageModel, imageClamps, musicModel, musicClamps, llmDevice, llmGpuLayers, contextSize, kvCacheK, kvCacheV, embedDevice, embedGpuLayers, embedBatchSize, transcriptionDevice, completionModelCap, credentialStore, platform, gpuStats }?: HarnessOptions);
188
198
  _open(): Promise<void>;
189
199
  get suspended(): boolean;
@@ -213,6 +223,10 @@ export declare class Harness extends ReadyResource {
213
223
  private _projectionFor;
214
224
  setCustomModels(entries: ReadonlyArray<CustomModelEntry>): void;
215
225
  setModelIdleTimeout(ms: number): void;
226
+ setModelMemoryCap(percent: number): Promise<void>;
227
+ memoryUsage(): Promise<MemoryUsage>;
228
+ setDownloadsAllowed({ allowed }: DownloadsAllowedOptions): void;
229
+ private _isModelCached;
216
230
  previewModelSource(context: PreviewModelSourceContext): Promise<ModelSourcePreview>;
217
231
  private _assessFit;
218
232
  describe(): Promise<HarnessInfo>;
@@ -234,6 +248,7 @@ export declare class Harness extends ReadyResource {
234
248
  private _notifyModel;
235
249
  private _collectRetiredEmbedPool;
236
250
  private _releaseEmbedResource;
251
+ private _collectRetiredEmbedPoolAfter;
237
252
  private _releaseEmbedResourceAfter;
238
253
  private _destroyEmbedPools;
239
254
  private _enqueueEmbedControl;
@@ -275,6 +290,31 @@ export declare class Harness extends ReadyResource {
275
290
  private _loadAndRelease;
276
291
  private _unloadIdleGenerators;
277
292
  private _fits;
293
+ private _curatedFit;
294
+ private _admitByHand;
295
+ private _replacedBy;
296
+ private _replacedEntries;
297
+ private _alone;
298
+ private _sizeByHand;
299
+ private _loadByHand;
300
+ private _admit;
301
+ private _makeRoomForGenerator;
302
+ private _yieldGenerators;
303
+ private _beforeLoad;
304
+ private _reserveByHand;
305
+ private _reserve;
306
+ private _sizeLoad;
307
+ private _chooseContext;
308
+ private _capRoom;
309
+ private _contextProfile;
310
+ private _trainedContext;
311
+ private _ctxSizeOf;
312
+ private _makeRoom;
313
+ private _capVictims;
314
+ private _victimRank;
315
+ private _usedBytes;
316
+ private _settledBytes;
317
+ private _memoryByModel;
278
318
  private _yieldPins;
279
319
  private _residency;
280
320
  private _completionLoadOptions;