@qvac/harness 1.0.0-rc.1 → 1.0.0-rc.2
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/CHANGELOG.md +1168 -1
- package/NOTICE.md +16 -0
- package/README.md +278 -471
- package/dist-lib/index.d.ts +101 -169
- package/dist-lib/index.js +423 -1506
- package/dist-lib/lib/addon-seal.bare.d.ts +1 -0
- package/dist-lib/lib/addon-seal.bare.js +3 -0
- package/dist-lib/lib/addon-seal.node.d.ts +1 -0
- package/dist-lib/lib/addon-seal.node.js +1 -0
- package/dist-lib/lib/agent/delegate.d.ts +83 -0
- package/dist-lib/lib/agent/delegate.js +261 -0
- package/dist-lib/lib/agent/follow.d.ts +32 -0
- package/dist-lib/lib/agent/follow.js +162 -0
- package/dist-lib/lib/agent/index.d.ts +37 -0
- package/dist-lib/lib/agent/index.js +42 -0
- package/dist-lib/lib/agent/plan.d.ts +6 -0
- package/dist-lib/lib/agent/plan.js +74 -0
- package/dist-lib/lib/agent/resolve.d.ts +3 -0
- package/dist-lib/lib/agent/resolve.js +78 -0
- package/dist-lib/lib/{capabilities → agent}/tool-names.d.ts +0 -1
- package/dist-lib/lib/{capabilities → agent}/tool-names.js +0 -1
- package/dist-lib/lib/{capabilities → agent}/tool-selection.d.ts +3 -6
- package/dist-lib/lib/{capabilities → agent}/tool-selection.js +9 -1
- package/dist-lib/lib/agent/tools.d.ts +14 -0
- package/dist-lib/lib/agent/tools.js +16 -0
- package/dist-lib/lib/agent/transfer.d.ts +7 -0
- package/dist-lib/lib/agent/transfer.js +26 -0
- package/dist-lib/lib/capabilities/agent-ports.d.ts +3 -0
- package/dist-lib/lib/capabilities/agent-ports.js +9 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/answering.d.ts +1 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/answering.js +25 -9
- package/dist-lib/lib/capabilities/completion-engine/actors/batching.d.ts +3 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/batching.js +90 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/direct-search.d.ts +2 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/direct-search.js +14 -5
- package/dist-lib/lib/capabilities/completion-engine/actors/execute.d.ts +5 -3
- package/dist-lib/lib/capabilities/completion-engine/actors/execute.js +8 -3
- package/dist-lib/lib/capabilities/completion-engine/actors/executing.d.ts +29 -2
- package/dist-lib/lib/capabilities/completion-engine/actors/executing.js +100 -40
- package/dist-lib/lib/capabilities/completion-engine/actors/execution-plan.d.ts +11 -10
- package/dist-lib/lib/capabilities/completion-engine/actors/execution-plan.js +28 -21
- package/dist-lib/lib/capabilities/completion-engine/actors/finishing.js +2 -2
- package/dist-lib/lib/capabilities/completion-engine/actors/inspect-prepare.d.ts +4 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/inspect-prepare.js +67 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/inspecting.d.ts +10 -3
- package/dist-lib/lib/capabilities/completion-engine/actors/inspecting.js +14 -11
- package/dist-lib/lib/capabilities/completion-engine/actors/loading-skill.d.ts +7 -3
- package/dist-lib/lib/capabilities/completion-engine/actors/loading-skill.js +30 -31
- package/dist-lib/lib/capabilities/completion-engine/actors/preparing.d.ts +3 -2
- package/dist-lib/lib/capabilities/completion-engine/actors/preparing.js +86 -102
- package/dist-lib/lib/capabilities/completion-engine/actors/rejecting.d.ts +1 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/rejecting.js +24 -7
- package/dist-lib/lib/capabilities/completion-engine/actors/rejection.d.ts +4 -2
- package/dist-lib/lib/capabilities/completion-engine/actors/rejection.js +8 -8
- package/dist-lib/lib/capabilities/completion-engine/actors/resolving.d.ts +1 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/resolving.js +73 -15
- package/dist-lib/lib/capabilities/completion-engine/actors/retrieving.d.ts +10 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/retrieving.js +56 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/run-prepare.d.ts +4 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/run-prepare.js +74 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/skill-step.d.ts +2 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/skill-step.js +76 -0
- package/dist-lib/lib/capabilities/completion-engine/actors/stream.d.ts +2 -2
- package/dist-lib/lib/capabilities/completion-engine/actors/stream.js +2 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/streaming.d.ts +1 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/streaming.js +84 -26
- package/dist-lib/lib/capabilities/completion-engine/actors/wrap-up.d.ts +1 -1
- package/dist-lib/lib/capabilities/completion-engine/actors/wrap-up.js +16 -6
- package/dist-lib/lib/capabilities/completion-engine/actors.d.ts +11 -0
- package/dist-lib/lib/capabilities/completion-engine/actors.js +216 -0
- package/dist-lib/lib/capabilities/completion-engine/driver.d.ts +12 -5
- package/dist-lib/lib/capabilities/completion-engine/driver.js +118 -33
- package/dist-lib/lib/capabilities/completion-engine/durable.d.ts +2 -1
- package/dist-lib/lib/capabilities/completion-engine/durable.js +6 -4
- package/dist-lib/lib/capabilities/completion-engine/engine.d.ts +65 -0
- package/dist-lib/lib/{machine → capabilities/completion-engine}/engine.js +67 -130
- package/dist-lib/lib/capabilities/completion-engine/index.d.ts +30 -0
- package/dist-lib/lib/capabilities/completion-engine/index.js +44 -0
- package/dist-lib/lib/capabilities/completion-engine/loop.d.ts +58 -0
- package/dist-lib/lib/capabilities/completion-engine/loop.js +62 -0
- package/dist-lib/lib/capabilities/completion-engine/metrics.d.ts +4 -0
- package/dist-lib/lib/capabilities/completion-engine/metrics.js +46 -0
- package/dist-lib/lib/capabilities/completion-engine/operations.d.ts +5 -2
- package/dist-lib/lib/capabilities/completion-engine/operations.js +84 -15
- package/dist-lib/lib/capabilities/completion-engine/ports.d.ts +25 -2
- package/dist-lib/lib/capabilities/completion-engine/ports.js +25 -16
- package/dist-lib/lib/capabilities/completion-engine/prepare-step.d.ts +26 -0
- package/dist-lib/lib/{machine → capabilities/completion-engine}/replay-output.d.ts +1 -1
- package/dist-lib/lib/{machine → capabilities/completion-engine}/replay-output.js +1 -1
- package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/round.d.ts +24 -4
- package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/round.js +242 -27
- package/dist-lib/lib/capabilities/completion-engine/session.d.ts +19 -12
- package/dist-lib/lib/capabilities/completion-engine/session.js +12 -6
- package/dist-lib/lib/capabilities/completion-engine/splice.d.ts +2 -0
- package/dist-lib/lib/capabilities/completion-engine/splice.js +7 -0
- package/dist-lib/lib/capabilities/completion-engine/stages.d.ts +23 -0
- package/dist-lib/lib/capabilities/completion-engine/tool-caller.d.ts +10 -0
- package/dist-lib/lib/capabilities/completion-engine/tool-caller.js +151 -0
- package/dist-lib/lib/capabilities/completion-engine/tool-execution.d.ts +77 -0
- package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/tool-execution.js +74 -25
- package/dist-lib/lib/capabilities/{completion-loop → completion-engine}/turns.d.ts +8 -4
- package/dist-lib/lib/capabilities/completion-engine/turns.js +225 -0
- package/dist-lib/lib/capabilities/enhance.d.ts +1 -1
- package/dist-lib/lib/capabilities/enhance.js +3 -2
- package/dist-lib/lib/capabilities/invoke.d.ts +1 -1
- package/dist-lib/lib/capabilities/preview-model-source.d.ts +1 -10
- package/dist-lib/lib/capabilities/preview-model-source.js +3 -1
- package/dist-lib/lib/capabilities/sdk-tool.d.ts +10 -0
- package/dist-lib/lib/capabilities/sdk-tool.js +130 -0
- package/dist-lib/lib/capabilities/skill-entry.d.ts +8 -0
- package/dist-lib/lib/capabilities/skill-entry.js +14 -0
- package/dist-lib/lib/capabilities/tool-plan.d.ts +6 -5
- package/dist-lib/lib/capabilities/tool-plan.js +16 -10
- package/dist-lib/lib/capabilities/tool-turns.d.ts +29 -4
- package/dist-lib/lib/capabilities/tool-turns.js +120 -10
- package/dist-lib/lib/capabilities/usage-breakdown.d.ts +1 -1
- package/dist-lib/lib/capabilities/usage-breakdown.js +4 -1
- package/dist-lib/lib/connect.d.ts +6 -0
- package/dist-lib/lib/connect.js +153 -65
- package/dist-lib/lib/context-window.d.ts +4 -2
- package/dist-lib/lib/context-window.js +27 -16
- package/dist-lib/lib/contract/agent.d.ts +65 -0
- package/dist-lib/lib/{capabilities/types.d.ts → contract/completion.d.ts} +140 -26
- package/dist-lib/lib/contract/exec.d.ts +134 -0
- package/dist-lib/lib/{hooks/types.d.ts → contract/hooks.d.ts} +62 -10
- package/dist-lib/lib/contract/index.d.ts +5 -0
- package/dist-lib/lib/contract/knowledge.d.ts +60 -0
- package/dist-lib/lib/contract/knowledge.js +1 -0
- package/dist-lib/lib/contract/models.d.ts +56 -0
- package/dist-lib/lib/contract/models.js +1 -0
- package/dist-lib/lib/contract/run.d.ts +142 -0
- package/dist-lib/lib/contract/run.js +1 -0
- package/dist-lib/lib/contract/sandbox.d.ts +29 -0
- package/dist-lib/lib/contract/sandbox.js +1 -0
- package/dist-lib/lib/contract/skill-readiness.d.ts +14 -0
- package/dist-lib/lib/contract/skill-readiness.js +1 -0
- package/dist-lib/lib/{capabilities/voice.d.ts → contract/speech.d.ts} +11 -16
- package/dist-lib/lib/contract/speech.js +1 -0
- package/dist-lib/lib/contract-types.d.ts +43 -16
- package/dist-lib/lib/docx/index.d.ts +0 -1
- package/dist-lib/lib/docx/index.js +15 -24
- package/dist-lib/lib/embeddings/index.d.ts +63 -0
- package/dist-lib/lib/embeddings/index.js +267 -0
- package/dist-lib/lib/fold/index.d.ts +50 -0
- package/dist-lib/lib/fold/index.js +123 -0
- package/dist-lib/lib/{tools/exec/adapters/python/guarded-fetch.d.ts → guarded-fetch.d.ts} +5 -12
- package/dist-lib/lib/{tools/exec/adapters/python/guarded-fetch.js → guarded-fetch.js} +12 -34
- package/dist-lib/lib/helpers/completion-params.d.ts +3 -0
- package/dist-lib/lib/helpers/completion-params.js +12 -0
- package/dist-lib/lib/helpers/copy.d.ts +1 -0
- package/dist-lib/lib/helpers/copy.js +5 -0
- package/dist-lib/lib/helpers/drain.d.ts +5 -0
- package/dist-lib/lib/helpers/drain.js +19 -0
- package/dist-lib/lib/{machine/errors.d.ts → helpers/engine-error.d.ts} +6 -9
- package/dist-lib/lib/{machine/errors.js → helpers/engine-error.js} +9 -25
- package/dist-lib/lib/helpers/failure-result.d.ts +21 -0
- package/dist-lib/lib/helpers/failure-result.js +39 -0
- package/dist-lib/lib/helpers/head-tail.d.ts +7 -0
- package/dist-lib/lib/helpers/head-tail.js +19 -0
- package/dist-lib/lib/helpers/image-settings.d.ts +2 -0
- package/dist-lib/lib/helpers/image-settings.js +19 -0
- package/dist-lib/lib/helpers/mcp-methods.d.ts +2 -0
- package/dist-lib/lib/helpers/mcp-methods.js +14 -0
- package/dist-lib/lib/helpers/race-abort.d.ts +1 -1
- package/dist-lib/lib/helpers/race-abort.js +1 -1
- package/dist-lib/lib/helpers/repeated-reply.d.ts +2 -0
- package/dist-lib/lib/helpers/repeated-reply.js +63 -0
- package/dist-lib/lib/helpers/run-outcome.d.ts +5 -4
- package/dist-lib/lib/helpers/run-outcome.js +11 -9
- package/dist-lib/lib/{machine → helpers}/stable-stringify.js +1 -1
- package/dist-lib/lib/helpers/tool-call-markup.d.ts +1 -0
- package/dist-lib/lib/helpers/tool-call-markup.js +9 -5
- package/dist-lib/lib/helpers/tool-label.d.ts +2 -2
- package/dist-lib/lib/helpers/tool-label.js +3 -3
- package/dist-lib/lib/hooks/built-in/arg-repair.d.ts +1 -1
- package/dist-lib/lib/hooks/built-in/arg-repair.js +109 -19
- package/dist-lib/lib/hooks/built-in/egress.d.ts +1 -1
- package/dist-lib/lib/hooks/built-in/egress.js +13 -21
- package/dist-lib/lib/hooks/built-in/sandbox.d.ts +1 -1
- package/dist-lib/lib/hooks/built-in/skill-catalog.d.ts +1 -1
- package/dist-lib/lib/hooks/index.d.ts +48 -0
- package/dist-lib/lib/hooks/index.js +130 -0
- package/dist-lib/lib/hooks/run.d.ts +9 -6
- package/dist-lib/lib/hooks/run.js +113 -48
- package/dist-lib/lib/{completion-lifecycle.d.ts → lifecycle/completion-run.d.ts} +1 -1
- package/dist-lib/lib/{completion-lifecycle.js → lifecycle/completion-run.js} +1 -1
- package/dist-lib/lib/lifecycle/index.d.ts +83 -0
- package/dist-lib/lib/lifecycle/index.js +335 -0
- package/dist-lib/lib/{harness-lifecycle.js → lifecycle/machine.js} +2 -2
- package/dist-lib/lib/machine/completion/actions/completion.d.ts +11 -2
- package/dist-lib/lib/machine/completion/actions/completion.js +98 -14
- package/dist-lib/lib/machine/completion/actions/prepare.d.ts +9 -0
- package/dist-lib/lib/machine/completion/actions/prepare.js +30 -0
- package/dist-lib/lib/machine/completion/actions/tools.d.ts +10 -1
- package/dist-lib/lib/machine/completion/actions/tools.js +79 -7
- package/dist-lib/lib/machine/completion/context.d.ts +7 -2
- package/dist-lib/lib/machine/completion/context.js +29 -5
- package/dist-lib/lib/machine/completion/guards/retry.d.ts +1 -0
- package/dist-lib/lib/machine/completion/guards/retry.js +6 -3
- package/dist-lib/lib/machine/completion/implementations.d.ts +38 -12
- package/dist-lib/lib/machine/completion/implementations.js +81 -31
- package/dist-lib/lib/machine/completion/machine.d.ts +140 -63
- package/dist-lib/lib/machine/completion/machine.js +194 -58
- package/dist-lib/lib/machine/completion/ports.d.ts +7 -55
- package/dist-lib/lib/machine/completion/ports.js +1 -224
- package/dist-lib/lib/machine/completion/rules.d.ts +20 -19
- package/dist-lib/lib/machine/completion/rules.js +73 -52
- package/dist-lib/lib/machine/completion/types.d.ts +110 -187
- package/dist-lib/lib/machine/completion/version.d.ts +1 -0
- package/dist-lib/lib/machine/completion/version.js +1 -0
- package/dist-lib/lib/machine/definition.d.ts +23 -0
- package/dist-lib/lib/machine/definition.js +76 -0
- package/dist-lib/lib/machine/index.d.ts +463 -20
- package/dist-lib/lib/machine/index.js +15 -11
- package/dist-lib/lib/models/llm-presets.d.ts +1 -0
- package/dist-lib/lib/models/model-catalog-constants.d.ts +3 -1
- package/dist-lib/lib/models/model-catalog-constants.js +9 -1
- package/dist-lib/lib/models/model-catalog.d.ts +31 -4
- package/dist-lib/lib/models/model-catalog.js +89 -8
- package/dist-lib/lib/models/model-fit.d.ts +55 -0
- package/dist-lib/lib/models/model-fit.js +102 -0
- package/dist-lib/lib/models/model-handle.d.ts +4 -0
- package/dist-lib/lib/models/model-handle.js +8 -1
- package/dist-lib/lib/models/model-list.d.ts +4 -0
- package/dist-lib/lib/models/model-pool.d.ts +35 -10
- package/dist-lib/lib/models/model-pool.js +63 -14
- package/dist-lib/lib/models/music-catalog.d.ts +1 -1
- package/dist-lib/lib/models/music-catalog.js +8 -1
- package/dist-lib/lib/models/sdk-faults.d.ts +2 -0
- package/dist-lib/lib/models/sdk-faults.js +18 -0
- package/dist-lib/lib/models/tts-model-default.js +3 -3
- package/dist-lib/lib/office/engine/codes.d.ts +62 -0
- package/dist-lib/lib/office/engine/codes.js +61 -0
- package/dist-lib/lib/office/engine/docx/document.d.ts +216 -0
- package/dist-lib/lib/office/engine/docx/document.js +1152 -0
- package/dist-lib/lib/office/engine/docx/index.d.ts +7 -0
- package/dist-lib/lib/office/engine/docx/index.js +8 -0
- package/dist-lib/lib/office/engine/docx/styles.d.ts +31 -0
- package/dist-lib/lib/office/engine/docx/styles.js +173 -0
- package/dist-lib/lib/office/engine/docx/template.d.ts +18 -0
- package/dist-lib/lib/office/engine/docx/template.js +133 -0
- package/dist-lib/lib/office/engine/docx/text.d.ts +55 -0
- package/dist-lib/lib/office/engine/docx/text.js +538 -0
- package/dist-lib/lib/office/engine/drawingml/chart.d.ts +63 -0
- package/dist-lib/lib/office/engine/drawingml/chart.js +539 -0
- package/dist-lib/lib/office/engine/drawingml/text.d.ts +35 -0
- package/dist-lib/lib/office/engine/drawingml/text.js +352 -0
- package/dist-lib/lib/office/engine/errors.d.ts +6 -0
- package/dist-lib/lib/office/engine/errors.js +12 -0
- package/dist-lib/lib/office/engine/image.d.ts +8 -0
- package/dist-lib/lib/office/engine/image.js +48 -0
- package/dist-lib/lib/office/engine/index.d.ts +12 -0
- package/dist-lib/lib/office/engine/index.js +7 -0
- package/dist-lib/lib/office/engine/opc/content-types.d.ts +17 -0
- package/dist-lib/lib/office/engine/opc/content-types.js +74 -0
- package/dist-lib/lib/office/engine/opc/media.d.ts +13 -0
- package/dist-lib/lib/office/engine/opc/media.js +11 -0
- package/dist-lib/lib/office/engine/opc/package.d.ts +51 -0
- package/dist-lib/lib/office/engine/opc/package.js +324 -0
- package/dist-lib/lib/office/engine/opc/paths.d.ts +7 -0
- package/dist-lib/lib/office/engine/opc/paths.js +46 -0
- package/dist-lib/lib/office/engine/opc/properties.d.ts +7 -0
- package/dist-lib/lib/office/engine/opc/properties.js +75 -0
- package/dist-lib/lib/office/engine/opc/relationships.d.ts +23 -0
- package/dist-lib/lib/office/engine/opc/relationships.js +65 -0
- package/dist-lib/lib/office/engine/opc/zip.d.ts +15 -0
- package/dist-lib/lib/office/engine/opc/zip.js +264 -0
- package/dist-lib/lib/office/engine/pptx/fit.d.ts +12 -0
- package/dist-lib/lib/office/engine/pptx/fit.js +37 -0
- package/dist-lib/lib/office/engine/pptx/index.d.ts +8 -0
- package/dist-lib/lib/office/engine/pptx/index.js +8 -0
- package/dist-lib/lib/office/engine/pptx/inherit.d.ts +29 -0
- package/dist-lib/lib/office/engine/pptx/inherit.js +155 -0
- package/dist-lib/lib/office/engine/pptx/notes.d.ts +5 -0
- package/dist-lib/lib/office/engine/pptx/notes.js +85 -0
- package/dist-lib/lib/office/engine/pptx/presentation.d.ts +54 -0
- package/dist-lib/lib/office/engine/pptx/presentation.js +749 -0
- package/dist-lib/lib/office/engine/pptx/read.d.ts +9 -0
- package/dist-lib/lib/office/engine/pptx/read.js +66 -0
- package/dist-lib/lib/office/engine/pptx/shapes.d.ts +52 -0
- package/dist-lib/lib/office/engine/pptx/shapes.js +276 -0
- package/dist-lib/lib/office/engine/pptx/slides.d.ts +27 -0
- package/dist-lib/lib/office/engine/pptx/slides.js +123 -0
- package/dist-lib/lib/office/engine/pptx/template.d.ts +20 -0
- package/dist-lib/lib/office/engine/pptx/template.js +391 -0
- package/dist-lib/lib/office/engine/pptx/types.d.ts +120 -0
- package/dist-lib/lib/office/engine/pptx/types.js +1 -0
- package/dist-lib/lib/office/engine/units.d.ts +3 -0
- package/dist-lib/lib/office/engine/units.js +12 -0
- package/dist-lib/lib/office/engine/utf8.d.ts +2 -0
- package/dist-lib/lib/office/engine/utf8.js +103 -0
- package/dist-lib/lib/office/engine/xlsx/formula.d.ts +49 -0
- package/dist-lib/lib/office/engine/xlsx/formula.js +381 -0
- package/dist-lib/lib/office/engine/xlsx/index.d.ts +8 -0
- package/dist-lib/lib/office/engine/xlsx/index.js +8 -0
- package/dist-lib/lib/office/engine/xlsx/refs.d.ts +22 -0
- package/dist-lib/lib/office/engine/xlsx/refs.js +82 -0
- package/dist-lib/lib/office/engine/xlsx/reshape.d.ts +21 -0
- package/dist-lib/lib/office/engine/xlsx/reshape.js +424 -0
- package/dist-lib/lib/office/engine/xlsx/sheet.d.ts +108 -0
- package/dist-lib/lib/office/engine/xlsx/sheet.js +662 -0
- package/dist-lib/lib/office/engine/xlsx/strings.d.ts +15 -0
- package/dist-lib/lib/office/engine/xlsx/strings.js +93 -0
- package/dist-lib/lib/office/engine/xlsx/styles.d.ts +38 -0
- package/dist-lib/lib/office/engine/xlsx/styles.js +369 -0
- package/dist-lib/lib/office/engine/xlsx/template.d.ts +7 -0
- package/dist-lib/lib/office/engine/xlsx/template.js +54 -0
- package/dist-lib/lib/office/engine/xlsx/workbook.d.ts +161 -0
- package/dist-lib/lib/office/engine/xlsx/workbook.js +850 -0
- package/dist-lib/lib/office/engine/xlsx/write.d.ts +2 -0
- package/dist-lib/lib/office/engine/xlsx/write.js +42 -0
- package/dist-lib/lib/office/engine/xml.d.ts +45 -0
- package/dist-lib/lib/office/engine/xml.js +258 -0
- package/dist-lib/lib/office/extract.d.ts +9 -0
- package/dist-lib/lib/office/extract.js +19 -0
- package/dist-lib/lib/office/index.d.ts +1 -1
- package/dist-lib/lib/office/index.js +74 -19
- package/dist-lib/lib/plugins/addons.d.ts +2 -0
- package/dist-lib/lib/plugins/addons.js +12 -0
- package/dist-lib/lib/plugins/context.d.ts +16 -0
- package/dist-lib/lib/plugins/context.js +48 -0
- package/dist-lib/lib/plugins/index.d.ts +3 -0
- package/dist-lib/lib/plugins/index.js +1 -0
- package/dist-lib/lib/plugins/registry.d.ts +116 -0
- package/dist-lib/lib/plugins/registry.js +505 -0
- package/dist-lib/lib/plugins/runtime.d.ts +27 -0
- package/dist-lib/lib/plugins/runtime.js +143 -0
- package/dist-lib/lib/plugins/scope.d.ts +17 -0
- package/dist-lib/lib/plugins/scope.js +55 -0
- package/dist-lib/lib/prompt.d.ts +2 -5
- package/dist-lib/lib/prompt.js +9 -0
- package/dist-lib/lib/residency/completion-runtime.d.ts +52 -0
- package/dist-lib/lib/{capabilities → residency}/completion-runtime.js +22 -15
- package/dist-lib/lib/residency/index.d.ts +148 -0
- package/dist-lib/lib/residency/index.js +539 -0
- package/dist-lib/lib/run-log/boundary.d.ts +17 -0
- package/dist-lib/lib/run-log/boundary.js +58 -0
- package/dist-lib/lib/run-log/history-codec.d.ts +7 -6
- package/dist-lib/lib/run-log/history-codec.js +175 -46
- package/dist-lib/lib/run-log/index.d.ts +46 -0
- package/dist-lib/lib/run-log/index.js +40 -0
- package/dist-lib/lib/run-log/inspect.d.ts +53 -0
- package/dist-lib/lib/{run-log-inspect.js → run-log/inspect.js} +196 -139
- package/dist-lib/lib/run-log/live.d.ts +37 -0
- package/dist-lib/lib/run-log/live.js +195 -0
- package/dist-lib/lib/run-log/persisted-actor.d.ts +1 -6
- package/dist-lib/lib/run-log/persisted-actor.js +4 -3
- package/dist-lib/lib/run-log/protocol-types.d.ts +37 -14
- package/dist-lib/lib/run-log/protocol.d.ts +1 -2
- package/dist-lib/lib/run-log/protocol.js +45 -40
- package/dist-lib/lib/{run-log-redact.d.ts → run-log/redact.d.ts} +3 -2
- package/dist-lib/lib/{run-log-redact.js → run-log/redact.js} +101 -16
- package/dist-lib/lib/run-log/replay.d.ts +3 -2
- package/dist-lib/lib/run-log/replay.js +7 -6
- package/dist-lib/lib/run-log/request-codec.d.ts +17 -0
- package/dist-lib/lib/run-log/request-codec.js +87 -0
- package/dist-lib/lib/run-log/run-journal.d.ts +14 -8
- package/dist-lib/lib/run-log/run-journal.js +100 -75
- package/dist-lib/lib/sdk-loader.d.ts +2 -7
- package/dist-lib/lib/sdk-loader.js +8 -15
- package/dist-lib/lib/sdk-storage.js +3 -1
- package/dist-lib/lib/serve.js +139 -38
- package/dist-lib/lib/skills-host/index.d.ts +59 -0
- package/dist-lib/lib/skills-host/index.js +268 -0
- package/dist-lib/lib/spawn.d.ts +37 -3
- package/dist-lib/lib/spawn.js +7 -3
- package/dist-lib/lib/spill.d.ts +11 -0
- package/dist-lib/lib/spill.js +82 -0
- package/dist-lib/lib/tools/{exec/adapters/python → attachments}/output-policy.d.ts +2 -3
- package/dist-lib/lib/tools/{exec/adapters/python/attachments.d.ts → attachments/staging.d.ts} +2 -2
- package/dist-lib/lib/tools/{exec/adapters/python/attachments.js → attachments/staging.js} +3 -3
- package/dist-lib/lib/tools/catalog.d.ts +1 -1
- package/dist-lib/lib/tools/catalog.js +1 -1
- package/dist-lib/lib/tools/create-documents.d.ts +1 -1
- package/dist-lib/lib/tools/edit-documents.d.ts +1 -1
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +5 -7
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +3 -2
- package/dist-lib/lib/tools/exec/bare-runtime.js +2 -4
- package/dist-lib/lib/tools/exec/python-source.d.ts +6 -0
- package/dist-lib/lib/tools/exec/python-source.js +243 -0
- package/dist-lib/lib/tools/exec/runner.d.ts +24 -45
- package/dist-lib/lib/tools/exec/runner.js +68 -34
- package/dist-lib/lib/tools/exec/scope.d.ts +2 -0
- package/dist-lib/lib/tools/exec/scope.js +33 -2
- package/dist-lib/lib/tools/exec/shell-guidance.d.ts +11 -9
- package/dist-lib/lib/tools/exec/shell-guidance.js +28 -57
- package/dist-lib/lib/tools/exec/video-tools.d.ts +0 -1
- package/dist-lib/lib/tools/exec/video-tools.js +0 -5
- package/dist-lib/lib/tools/exec.d.ts +7 -14
- package/dist-lib/lib/tools/exec.js +181 -457
- package/dist-lib/lib/tools/file-glob.d.ts +1 -1
- package/dist-lib/lib/tools/file-glob.js +1 -0
- package/dist-lib/lib/tools/fs/scope.d.ts +1 -0
- package/dist-lib/lib/tools/fs/scope.js +8 -3
- package/dist-lib/lib/tools/grep.d.ts +1 -1
- package/dist-lib/lib/tools/grep.js +1 -0
- package/dist-lib/lib/tools/http-request.d.ts +1 -1
- package/dist-lib/lib/tools/http-request.js +1 -0
- package/dist-lib/lib/tools/index.d.ts +21 -0
- package/dist-lib/lib/tools/index.js +46 -0
- package/dist-lib/lib/tools/office/ops.d.ts +13 -0
- package/dist-lib/lib/tools/office/ops.js +100 -0
- package/dist-lib/lib/tools/office.d.ts +12 -0
- package/dist-lib/lib/tools/office.js +486 -0
- package/dist-lib/lib/tools/operations/compile.d.ts +3 -3
- package/dist-lib/lib/tools/operations/compile.js +2 -1
- package/dist-lib/lib/tools/operations/decoders.js +1 -1
- package/dist-lib/lib/tools/operations/manifest.d.ts +1 -1
- package/dist-lib/lib/tools/outbound-guard.d.ts +3 -1
- package/dist-lib/lib/tools/outbound-guard.js +4 -0
- package/dist-lib/lib/tools/pdf/build.d.ts +43 -0
- package/dist-lib/lib/tools/pdf/build.js +150 -0
- package/dist-lib/lib/tools/pdf/images.d.ts +7 -0
- package/dist-lib/lib/tools/pdf/images.js +82 -0
- package/dist-lib/lib/tools/pdf/request.d.ts +63 -0
- package/dist-lib/lib/tools/pdf/request.js +335 -0
- package/dist-lib/lib/tools/pdf.d.ts +6 -0
- package/dist-lib/lib/tools/pdf.js +303 -0
- package/dist-lib/lib/tools/read-files.d.ts +1 -1
- package/dist-lib/lib/tools/read-files.js +5 -1
- package/dist-lib/lib/tools/skill.d.ts +2 -4
- package/dist-lib/lib/tools/skill.js +20 -22
- package/dist-lib/lib/tools/skills/auth-resolver.d.ts +1 -1
- package/dist-lib/lib/tools/skills/catalog.d.ts +9 -2
- package/dist-lib/lib/tools/skills/catalog.js +7 -7
- package/dist-lib/lib/tools/skills/cli-schema.js +1 -1
- package/dist-lib/lib/tools/skills/frontmatter-parser.d.ts +1 -0
- package/dist-lib/lib/tools/skills/frontmatter-parser.js +1 -0
- package/dist-lib/lib/tools/skills/mention.d.ts +1 -2
- package/dist-lib/lib/tools/skills/mention.js +0 -3
- package/dist-lib/lib/tools/skills/scope-key.d.ts +2 -1
- package/dist-lib/lib/tools/skills/scope-key.js +2 -3
- package/dist-lib/lib/tools/skills/skill-state.d.ts +2 -2
- package/dist-lib/lib/tools/skills/skill-state.js +11 -28
- package/dist-lib/lib/tools/toolsets.d.ts +3 -7
- package/dist-lib/lib/tools/toolsets.js +5 -9
- package/dist-lib/lib/tools/web-fetch.d.ts +1 -1
- package/dist-lib/lib/tools/web-fetch.js +42 -6
- package/dist-lib/lib/web-fetch/embedded-state.js +1 -1
- package/dist-lib/lib/web-fetch/extract.js +1 -1
- package/dist-lib/lib/web-fetch/images.js +1 -1
- package/dist-lib/lib/web-fetch/video.js +1 -1
- package/dist-lib/lib/wire.d.ts +8 -0
- package/dist-lib/lib/wire.js +112 -2
- package/dist-lib/plugins/code-mode/index.d.ts +16 -0
- package/dist-lib/plugins/code-mode/index.js +43 -0
- package/dist-lib/plugins/coding/index.d.ts +15 -0
- package/dist-lib/plugins/coding/index.js +42 -0
- package/dist-lib/plugins/coding/jobs.d.ts +24 -0
- package/dist-lib/plugins/coding/jobs.js +144 -0
- package/dist-lib/plugins/coding/session.d.ts +51 -0
- package/dist-lib/plugins/coding/session.js +263 -0
- package/dist-lib/plugins/coding/write-file.d.ts +3 -0
- package/dist-lib/plugins/coding/write-file.js +52 -0
- package/dist-lib/plugins/command-hooks/index.d.ts +88 -0
- package/dist-lib/plugins/command-hooks/index.js +338 -0
- package/dist-lib/plugins/external-agents/acp.d.ts +27 -0
- package/dist-lib/plugins/external-agents/acp.js +264 -0
- package/dist-lib/plugins/external-agents/cli.d.ts +3 -0
- package/dist-lib/plugins/external-agents/cli.js +199 -0
- package/dist-lib/plugins/external-agents/index.d.ts +25 -0
- package/dist-lib/plugins/external-agents/index.js +54 -0
- package/dist-lib/plugins/external-agents/process.d.ts +19 -0
- package/dist-lib/plugins/external-agents/process.js +92 -0
- package/dist-lib/plugins/external-agents/targets.d.ts +32 -0
- package/dist-lib/plugins/external-agents/targets.js +66 -0
- package/dist-lib/{lib/tools → plugins/image}/edit-image.d.ts +3 -2
- package/dist-lib/{lib/tools → plugins/image}/edit-image.js +7 -2
- package/dist-lib/{lib/tools → plugins/image}/generate-image.d.ts +6 -12
- package/dist-lib/{lib/tools → plugins/image}/generate-image.js +6 -7
- package/dist-lib/plugins/image/index.d.ts +25 -0
- package/dist-lib/plugins/image/index.js +76 -0
- package/dist-lib/plugins/knowledge/index.d.ts +21 -0
- package/dist-lib/plugins/knowledge/index.js +47 -0
- package/dist-lib/plugins/knowledge/search-tool.d.ts +4 -0
- package/dist-lib/plugins/knowledge/search-tool.js +38 -0
- package/dist-lib/plugins/knowledge/store.d.ts +42 -0
- package/dist-lib/plugins/knowledge/store.js +332 -0
- package/dist-lib/plugins/lsp/index.d.ts +32 -0
- package/dist-lib/plugins/lsp/index.js +77 -0
- package/dist-lib/plugins/lsp/pool.d.ts +24 -0
- package/dist-lib/plugins/lsp/pool.js +73 -0
- package/dist-lib/plugins/lsp/rpc.d.ts +37 -0
- package/dist-lib/plugins/lsp/rpc.js +145 -0
- package/dist-lib/plugins/lsp/server.d.ts +55 -0
- package/dist-lib/plugins/lsp/server.js +192 -0
- package/dist-lib/plugins/lsp/tool.d.ts +12 -0
- package/dist-lib/plugins/lsp/tool.js +366 -0
- package/dist-lib/plugins/mcp/call.d.ts +17 -0
- package/dist-lib/{lib/tools/mcp-call.js → plugins/mcp/call.js} +92 -84
- package/dist-lib/plugins/mcp/index.d.ts +21 -0
- package/dist-lib/plugins/mcp/index.js +85 -0
- package/dist-lib/{lib/tools → plugins}/mcp/protocol.d.ts +9 -16
- package/dist-lib/{lib/tools → plugins}/mcp/protocol.js +3 -16
- package/dist-lib/plugins/mcp/server.d.ts +23 -0
- package/dist-lib/plugins/mcp/server.js +108 -0
- package/dist-lib/{lib/tools → plugins/music}/generate-music.d.ts +6 -15
- package/dist-lib/{lib/tools → plugins/music}/generate-music.js +7 -8
- package/dist-lib/plugins/music/index.d.ts +24 -0
- package/dist-lib/plugins/music/index.js +48 -0
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli-process.d.ts +2 -2
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli-process.js +2 -2
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli.d.ts +1 -1
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/cli.js +7 -7
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/command.js +1 -1
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/guidance.d.ts +0 -1
- package/dist-lib/{lib/tools/exec → plugins}/obsidian/guidance.js +0 -7
- package/dist-lib/plugins/obsidian/index.d.ts +26 -0
- package/dist-lib/plugins/obsidian/index.js +138 -0
- package/dist-lib/{lib/tools/skills/obsidian-readiness.d.ts → plugins/obsidian/readiness.d.ts} +1 -0
- package/dist-lib/{lib/tools/skills/obsidian-readiness.js → plugins/obsidian/readiness.js} +7 -0
- package/dist-lib/plugins/python/guarded-fetch.d.ts +13 -0
- package/dist-lib/plugins/python/guarded-fetch.js +32 -0
- package/dist-lib/plugins/python/index.d.ts +18 -0
- package/dist-lib/plugins/python/index.js +19 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/interrupt-timer.js +2 -2
- package/dist-lib/plugins/python/language.d.ts +8 -0
- package/dist-lib/plugins/python/language.js +377 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/loader.d.ts +1 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/loader.js +8 -1
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/memfs.js +3 -3
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/module-distributions.js +0 -3
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/pyodide.js +4 -4
- package/dist-lib/plugins/python/python-adapter.d.ts +41 -0
- package/dist-lib/plugins/python/python-adapter.js +515 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/run-session.d.ts +1 -2
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/run-session.js +10 -99
- package/dist-lib/plugins/python/shell-redirect.d.ts +8 -0
- package/dist-lib/plugins/python/shell-redirect.js +25 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/wheels.js +4 -3
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/active.js +1 -1
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/client.d.ts +1 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/client.js +6 -3
- package/dist-lib/plugins/python/worker/entry.d.ts +1 -0
- package/dist-lib/plugins/python/worker/entry.js +9 -0
- package/dist-lib/plugins/python/worker/interrupt-deadline.d.ts +1 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/interrupt-deadline.js +1 -1
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/serve.js +2 -2
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/spawn.d.ts +1 -0
- package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/spawn.js +7 -0
- package/dist-lib/plugins/quickjs/index.d.ts +20 -0
- package/dist-lib/plugins/quickjs/index.js +25 -0
- package/dist-lib/plugins/quickjs/language.d.ts +3 -0
- package/dist-lib/plugins/quickjs/language.js +59 -0
- package/dist-lib/plugins/quickjs/runtime.d.ts +38 -0
- package/dist-lib/plugins/quickjs/runtime.js +421 -0
- package/dist-lib/plugins/quickjs/text-decoder.d.ts +1 -0
- package/dist-lib/plugins/quickjs/text-decoder.js +15 -0
- package/dist-lib/plugins/run-report/brand.d.ts +1 -0
- package/dist-lib/plugins/run-report/brand.js +1 -0
- package/dist-lib/plugins/run-report/flow-view.d.ts +6 -0
- package/dist-lib/plugins/run-report/flow-view.js +53 -0
- package/dist-lib/plugins/run-report/flow.d.ts +33 -0
- package/dist-lib/plugins/run-report/flow.js +201 -0
- package/dist-lib/plugins/run-report/index.d.ts +17 -0
- package/dist-lib/plugins/run-report/index.js +27 -0
- package/dist-lib/plugins/run-report/layout.d.ts +39 -0
- package/dist-lib/plugins/run-report/layout.js +175 -0
- package/dist-lib/plugins/run-report/meaning.d.ts +6 -0
- package/dist-lib/plugins/run-report/meaning.js +43 -0
- package/dist-lib/plugins/run-report/model.d.ts +86 -0
- package/dist-lib/plugins/run-report/model.js +387 -0
- package/dist-lib/plugins/run-report/page.d.ts +13 -0
- package/dist-lib/plugins/run-report/page.js +234 -0
- package/dist-lib/plugins/run-report/script.d.ts +1 -0
- package/dist-lib/plugins/run-report/script.js +661 -0
- package/dist-lib/plugins/run-report/story.d.ts +48 -0
- package/dist-lib/plugins/run-report/story.js +188 -0
- package/dist-lib/plugins/run-report/style.d.ts +1 -0
- package/dist-lib/plugins/run-report/style.js +410 -0
- package/dist-lib/plugins/run-report/why.d.ts +28 -0
- package/dist-lib/plugins/run-report/why.js +170 -0
- package/dist-lib/plugins/sandbox-macos/index.d.ts +48 -0
- package/dist-lib/plugins/sandbox-macos/index.js +175 -0
- package/dist-lib/plugins/sandbox-vm/index.d.ts +24 -0
- package/dist-lib/plugins/sandbox-vm/index.js +27 -0
- package/dist-lib/plugins/sandbox-vm/vm-shell.d.ts +46 -0
- package/dist-lib/plugins/sandbox-vm/vm-shell.js +106 -0
- package/dist-lib/{lib → plugins/speech}/audio-transcode-bare.js +2 -2
- package/dist-lib/plugins/speech/index.d.ts +17 -0
- package/dist-lib/plugins/speech/index.js +24 -0
- package/dist-lib/plugins/speech/speech-engine.d.ts +23 -0
- package/dist-lib/plugins/speech/speech-engine.js +55 -0
- package/dist-lib/plugins/speech/speech-runtime.d.ts +22 -0
- package/dist-lib/plugins/speech/speech-runtime.js +212 -0
- package/dist-lib/{lib/capabilities → plugins/speech}/speech-text.d.ts +1 -0
- package/dist-lib/{lib/capabilities → plugins/speech}/speech-text.js +10 -3
- package/dist-lib/plugins/speech/voice-lane.d.ts +2 -0
- package/dist-lib/plugins/speech/voice-lane.js +9 -0
- package/dist-lib/plugins/speech/voice.d.ts +17 -0
- package/dist-lib/{lib/capabilities → plugins/speech}/voice.js +27 -25
- package/dist-lib/plugins/translation/index.d.ts +22 -0
- package/dist-lib/plugins/translation/index.js +63 -0
- package/dist-lib/{lib/models → plugins/translation}/nmt-catalog.d.ts +0 -1
- package/dist-lib/{lib/models → plugins/translation}/nmt-catalog.js +0 -3
- package/dist-lib/{lib/tools → plugins/translation}/translate.d.ts +14 -6
- package/dist-lib/{lib/tools → plugins/translation}/translate.js +14 -8
- package/dist-lib/plugins/walkie-talkie/crew.d.ts +27 -0
- package/dist-lib/plugins/walkie-talkie/crew.js +103 -0
- package/dist-lib/plugins/walkie-talkie/index.d.ts +127 -0
- package/dist-lib/plugins/walkie-talkie/index.js +340 -0
- package/dist-lib/plugins/walkie-talkie/wire.d.ts +67 -0
- package/dist-lib/plugins/walkie-talkie/wire.js +136 -0
- package/dist-lib/plugins/weather/geocode.d.ts +25 -0
- package/dist-lib/plugins/weather/geocode.js +101 -0
- package/dist-lib/plugins/weather/index.d.ts +15 -0
- package/dist-lib/plugins/weather/index.js +17 -0
- package/dist-lib/plugins/weather/lookup.d.ts +6 -0
- package/dist-lib/plugins/weather/lookup.js +169 -0
- package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/place.js +5 -1
- package/dist-lib/plugins/web-search/engine-registry.d.ts +44 -0
- package/dist-lib/plugins/web-search/engine-registry.js +17 -0
- package/dist-lib/{lib → plugins}/web-search/engines/aol.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/aol.js +5 -3
- package/dist-lib/{lib → plugins}/web-search/engines/bing.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/bing.js +9 -4
- package/dist-lib/{lib → plugins}/web-search/engines/brave.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/brave.js +5 -3
- package/dist-lib/{lib → plugins}/web-search/engines/duckduckgo.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/duckduckgo.js +5 -2
- package/dist-lib/{lib → plugins}/web-search/engines/google.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/google.js +6 -4
- package/dist-lib/{lib → plugins}/web-search/engines/wikipedia.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/wikipedia.js +5 -3
- package/dist-lib/{lib → plugins}/web-search/engines/yahoo.d.ts +1 -0
- package/dist-lib/{lib → plugins}/web-search/engines/yahoo.js +5 -3
- package/dist-lib/{lib → plugins}/web-search/fetch-html.js +1 -1
- package/dist-lib/plugins/web-search/index.d.ts +18 -0
- package/dist-lib/plugins/web-search/index.js +33 -0
- package/dist-lib/{lib → plugins}/web-search/orchestrator.d.ts +3 -1
- package/dist-lib/{lib → plugins}/web-search/orchestrator.js +5 -5
- package/dist-lib/plugins/web-search/tool.d.ts +3 -0
- package/dist-lib/{lib/tools/web-search.js → plugins/web-search/tool.js} +18 -14
- package/dist-lib/plugins/web-search/types.js +1 -0
- package/dist-lib/schema/generate.js +5 -2
- package/dist-lib/schema/harness.js +158 -7
- package/dist-lib/spec/bind.js +20 -4
- package/dist-lib/spec/calls.js +4 -0
- package/dist-lib/spec/hrpc/hrpc.json +52 -0
- package/dist-lib/spec/hrpc/index.js +51 -3
- package/dist-lib/spec/hrpc/messages.js +595 -17
- package/dist-lib/spec/hyperschema/index.js +595 -17
- package/dist-lib/spec/hyperschema/schema.json +464 -1
- package/dist-lib/spec/hyperschema/types.d.ts +113 -2
- package/package.json +261 -484
- package/patches/{@qvac%2Finference@0.20.0.patch → @qvac%2Finference@0.21.0.patch} +8 -8
- package/scripts/addon-externals.cjs +386 -0
- package/scripts/addon-externals.d.ts +30 -0
- package/wheels/manifest.json +1 -160
- package/worker/harness-sidecar.mjs +80 -59
- package/dist-lib/lib/capabilities/completion-engine/actors/inspect-preload.d.ts +0 -3
- package/dist-lib/lib/capabilities/completion-engine/actors/inspect-preload.js +0 -75
- package/dist-lib/lib/capabilities/completion-engine/actors/preload-failure.d.ts +0 -9
- package/dist-lib/lib/capabilities/completion-engine/actors/preload-failure.js +0 -11
- package/dist-lib/lib/capabilities/completion-engine/actors/preloading.d.ts +0 -3
- package/dist-lib/lib/capabilities/completion-engine/actors/preloading.js +0 -114
- package/dist-lib/lib/capabilities/completion-loop/index.d.ts +0 -80
- package/dist-lib/lib/capabilities/completion-loop/index.js +0 -158
- package/dist-lib/lib/capabilities/completion-loop/metrics.d.ts +0 -5
- package/dist-lib/lib/capabilities/completion-loop/metrics.js +0 -29
- package/dist-lib/lib/capabilities/completion-loop/tool-execution.d.ts +0 -60
- package/dist-lib/lib/capabilities/completion-loop/turns.js +0 -112
- package/dist-lib/lib/capabilities/completion-runtime.d.ts +0 -46
- package/dist-lib/lib/capabilities/completion.d.ts +0 -18
- package/dist-lib/lib/capabilities/completion.js +0 -22
- package/dist-lib/lib/helpers/recovery-required.d.ts +0 -1
- package/dist-lib/lib/helpers/recovery-required.js +0 -1
- package/dist-lib/lib/hooks/built-in/index.d.ts +0 -4
- package/dist-lib/lib/hooks/built-in/index.js +0 -4
- package/dist-lib/lib/hooks/pipeline.d.ts +0 -24
- package/dist-lib/lib/hooks/pipeline.js +0 -74
- package/dist-lib/lib/hooks/registry.d.ts +0 -2
- package/dist-lib/lib/hooks/registry.js +0 -7
- package/dist-lib/lib/machine/completion/actions/skills.d.ts +0 -9
- package/dist-lib/lib/machine/completion/actions/skills.js +0 -83
- package/dist-lib/lib/machine/engine.d.ts +0 -93
- package/dist-lib/lib/machine/guards.d.ts +0 -2
- package/dist-lib/lib/machine/guards.js +0 -6
- package/dist-lib/lib/office/pptx.d.ts +0 -1
- package/dist-lib/lib/office/pptx.js +0 -26
- package/dist-lib/lib/office/python.d.ts +0 -8
- package/dist-lib/lib/office/python.js +0 -32
- package/dist-lib/lib/office/xlsx.d.ts +0 -1
- package/dist-lib/lib/office/xlsx.js +0 -26
- package/dist-lib/lib/run-log-inspect.d.ts +0 -25
- package/dist-lib/lib/run-log-protocol.d.ts +0 -2
- package/dist-lib/lib/run-log-protocol.js +0 -1
- package/dist-lib/lib/tool-call-display.d.ts +0 -1
- package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +0 -31
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +0 -7
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +0 -318
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +0 -89
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +0 -1371
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +0 -3
- package/dist-lib/lib/tools/exec/obsidian/route.d.ts +0 -17
- package/dist-lib/lib/tools/exec/obsidian/route.js +0 -91
- package/dist-lib/lib/tools/mcp-call.d.ts +0 -14
- package/dist-lib/lib/tools/rag-search.d.ts +0 -2
- package/dist-lib/lib/tools/rag-search.js +0 -105
- package/dist-lib/lib/tools/weather-lookup.d.ts +0 -8
- package/dist-lib/lib/tools/weather-lookup.js +0 -122
- package/dist-lib/lib/tools/web-search.d.ts +0 -6
- package/dist-lib/lib/web-search/engine-registry.d.ts +0 -7
- package/dist-lib/lib/web-search/engine-registry.js +0 -17
- package/wheels/cffi-2.0.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/cryptography-47.0.0-cp314-abi3-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/defusedxml-0.7.1-py2.py3-none-any.whl +0 -0
- package/wheels/et_xmlfile-2.0.0-py3-none-any.whl +0 -0
- package/wheels/fonttools-4.62.1-py3-none-any.whl +0 -0
- package/wheels/fpdf2-2.8.8-py3-none-any.whl +0 -0
- package/wheels/lxml-6.0.2-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/openpyxl-3.1.5-py2.py3-none-any.whl +0 -0
- package/wheels/pillow-12.2.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl +0 -0
- package/wheels/pycparser-3.0-py3-none-any.whl +0 -0
- package/wheels/pypdf-6.15.0-py3-none-any.whl +0 -0
- package/wheels/python_docx-1.2.0-py3-none-any.whl +0 -0
- package/wheels/python_pptx-1.0.2-py3-none-any.whl +0 -0
- package/wheels/six-1.17.0-py2.py3-none-any.whl +0 -0
- package/wheels/typing_extensions-4.15.0-py3-none-any.whl +0 -0
- package/wheels/xlsxwriter-3.2.9-py3-none-any.whl +0 -0
- /package/dist-lib/lib/{tools/skills → agent}/tool-grants.d.ts +0 -0
- /package/dist-lib/lib/{tools/skills → agent}/tool-grants.js +0 -0
- /package/dist-lib/lib/capabilities/{types.js → completion-engine/prepare-step.js} +0 -0
- /package/dist-lib/lib/{hooks/types.js → capabilities/completion-engine/stages.js} +0 -0
- /package/dist-lib/lib/{tool-call-display.js → contract/agent.js} +0 -0
- /package/dist-lib/lib/{tools/exec/adapters/adapter.js → contract/completion.js} +0 -0
- /package/dist-lib/lib/{tools/exec/adapters/python/worker/entry.d.ts → contract/exec.js} +0 -0
- /package/dist-lib/lib/{tools/exec/adapters/python/worker/interrupt-deadline.d.ts → contract/hooks.js} +0 -0
- /package/dist-lib/lib/{web-search/types.js → contract/index.js} +0 -0
- /package/dist-lib/lib/{capabilities/completion-engine → helpers}/abort-polyfill.d.ts +0 -0
- /package/dist-lib/lib/{capabilities/completion-engine → helpers}/abort-polyfill.js +0 -0
- /package/dist-lib/lib/{web-search → helpers}/html-helpers.d.ts +0 -0
- /package/dist-lib/lib/{web-search → helpers}/html-helpers.js +0 -0
- /package/dist-lib/lib/{tools → helpers}/model-args.d.ts +0 -0
- /package/dist-lib/lib/{tools → helpers}/model-args.js +0 -0
- /package/dist-lib/lib/{machine → helpers}/stable-stringify.d.ts +0 -0
- /package/dist-lib/lib/{web-search → helpers}/user-agents.d.ts +0 -0
- /package/dist-lib/lib/{web-search → helpers}/user-agents.js +0 -0
- /package/dist-lib/lib/{harness-lifecycle.d.ts → lifecycle/machine.d.ts} +0 -0
- /package/dist-lib/lib/tools/{exec/adapters/python → attachments}/output-policy.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/command.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/note-name.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/note-name.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/output.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/output.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/safe-path.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/safe-path.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-create.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-create.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-fs.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-fs.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-paths.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-paths.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-read.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-read.js +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-write.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec → plugins}/obsidian/vault-write.js +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/deadline-state.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/deadline-state.js +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/distributions.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/distributions.js +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/interrupt-timer.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/memfs.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/module-distributions.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/named-hosts.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/named-hosts.js +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/net-shim.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/net-shim.js +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/pyodide.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/wheels.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/active.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/protocol.d.ts +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/protocol.js +0 -0
- /package/dist-lib/{lib/tools/exec/adapters → plugins}/python/worker/serve.d.ts +0 -0
- /package/dist-lib/{lib/capabilities → plugins/speech}/audio-resample.d.ts +0 -0
- /package/dist-lib/{lib/capabilities → plugins/speech}/audio-resample.js +0 -0
- /package/dist-lib/{lib → plugins/speech}/audio-transcode-bare.d.ts +0 -0
- /package/dist-lib/{lib → plugins/speech}/audio-transcode-node.d.ts +0 -0
- /package/dist-lib/{lib → plugins/speech}/audio-transcode-node.js +0 -0
- /package/dist-lib/{lib/capabilities → plugins/speech}/speech-lexicon.d.ts +0 -0
- /package/dist-lib/{lib/capabilities → plugins/speech}/speech-lexicon.js +0 -0
- /package/dist-lib/{lib → plugins/speech}/wav-encode.d.ts +0 -0
- /package/dist-lib/{lib → plugins/speech}/wav-encode.js +0 -0
- /package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/place.d.ts +0 -0
- /package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/report.d.ts +0 -0
- /package/dist-lib/{lib/tools/weather-lookup → plugins/weather}/report.js +0 -0
- /package/dist-lib/{lib → plugins}/web-search/fetch-html.d.ts +0 -0
- /package/dist-lib/{lib → plugins}/web-search/format-results.d.ts +0 -0
- /package/dist-lib/{lib → plugins}/web-search/format-results.js +0 -0
- /package/dist-lib/{lib → plugins}/web-search/merge-results.d.ts +0 -0
- /package/dist-lib/{lib → plugins}/web-search/merge-results.js +0 -0
- /package/dist-lib/{lib → plugins}/web-search/types.d.ts +0 -0
- /package/dist-lib/{lib → plugins}/web-search/url-helpers.d.ts +0 -0
- /package/dist-lib/{lib → plugins}/web-search/url-helpers.js +0 -0
- /package/dist-lib/{lib → plugins}/web-search/url-normalize.d.ts +0 -0
- /package/dist-lib/{lib → plugins}/web-search/url-normalize.js +0 -0
package/dist-lib/index.js
CHANGED
|
@@ -4,69 +4,49 @@ import process from 'process';
|
|
|
4
4
|
import ReadyResource from 'ready-resource';
|
|
5
5
|
import { probeGpuStats } from './lib/hardware/gpu-probe.js';
|
|
6
6
|
import { probeCapabilityProfile } from './lib/hardware/capability-probe.js';
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import { completion, imageSettingsFrom } from './lib/capabilities/completion.js';
|
|
7
|
+
import { Lifecycle } from './lib/lifecycle/index.js';
|
|
8
|
+
import { didDrainTimeOut, raceDrain } from './lib/helpers/drain.js';
|
|
9
|
+
import { CompletionEngine } from './lib/capabilities/completion-engine/index.js';
|
|
10
|
+
import { imageSettingsFrom } from './lib/helpers/image-settings.js';
|
|
12
11
|
import { detectLanguage } from './lib/capabilities/detect-language.js';
|
|
13
12
|
import { invoke } from './lib/capabilities/invoke.js';
|
|
14
13
|
import { previewModelSource } from './lib/capabilities/preview-model-source.js';
|
|
15
14
|
import { expandImagePrompt } from './lib/capabilities/enhance.js';
|
|
16
|
-
import { cleanAnswer } from './lib/helpers/clean-answer.js';
|
|
17
|
-
import { isTranslationModel } from './lib/models/nmt-catalog.js';
|
|
18
|
-
import { createTranslateTool, createTranslationRuntime } from './lib/tools/translate.js';
|
|
19
15
|
import { download } from './lib/capabilities/download.js';
|
|
20
|
-
import {
|
|
16
|
+
import { Embeddings } from './lib/embeddings/index.js';
|
|
21
17
|
import { deleteAllKvCaches, deleteKvCacheKey } from './lib/capabilities/kv-cache.js';
|
|
22
|
-
import { pcmForTranscription } from './lib/capabilities/audio-resample.js';
|
|
23
|
-
import { buildWavBuffer } from './lib/wav-encode.js';
|
|
24
|
-
import { createVoiceLane, packSamples, speakOnce, speakStreamOnce, transcribeOnce, transcribeStreaming, SUPERTONIC_SAMPLE_RATE } from './lib/capabilities/voice.js';
|
|
25
18
|
import { pushQueue } from './lib/queue.js';
|
|
26
|
-
import { AbortedError
|
|
27
|
-
import { audioGenDownloadMetadata, customProjectionMap, defaultProjectionMap,
|
|
28
|
-
import {
|
|
19
|
+
import { AbortedError } from './lib/helpers/race-abort.js';
|
|
20
|
+
import { audioGenDownloadMetadata, categoryDownloadMetadata, customProjectionMap, defaultProjectionMap, defaultVoiceModel, diffusionDownloadMetadata, infraModelsFor, modelNameToCapabilityProfile, residentSrc, setCustomModels } from './lib/models/model-catalog.js';
|
|
21
|
+
import { customModelRows, mergeCustomRows, listModels } from './lib/models/model-list.js';
|
|
29
22
|
import { deleteModelFiles, summarizeDelete } from './lib/models/model-delete.js';
|
|
30
|
-
import {
|
|
31
|
-
import { defaultContextSize } from './lib/models/context.js';
|
|
32
|
-
import { resolveMainGpu } from './lib/models/gpu-selection.js';
|
|
33
|
-
import { createIdleReaper } from './lib/models/idle-unload.js';
|
|
23
|
+
import { createLoadTracker, createVoicePool, evictIdle, evictIdleWhere, isResident, leaseResidentModel, loadedModels, releaseModel, progressState } from './lib/models/model-pool.js';
|
|
34
24
|
import { openclCacheDir } from './lib/models/opencl-cache.js';
|
|
35
|
-
import {
|
|
36
|
-
import { createGpuFaultState, isSdkGpuDeviceLostError, isSdkModelWedgedError } from './lib/models/sdk-faults.js';
|
|
25
|
+
import { isSdkModelWedgedError } from './lib/models/sdk-faults.js';
|
|
37
26
|
import { createSdkLoader } from './lib/sdk-loader.js';
|
|
38
|
-
import { installAbortControllerPolyfill } from './lib/
|
|
39
|
-
import {
|
|
40
|
-
import { createEditImageTool } from './lib/tools/edit-image.js';
|
|
27
|
+
import { installAbortControllerPolyfill } from './lib/helpers/abort-polyfill.js';
|
|
28
|
+
import { Residency } from './lib/residency/index.js';
|
|
41
29
|
import { toolCatalog } from './lib/tools/catalog.js';
|
|
42
|
-
import {
|
|
43
|
-
import { createGenerateMusicTool, createMusicRuntime } from './lib/tools/generate-music.js';
|
|
44
|
-
import { availableSkills, detectPlatform, loadSkillCatalog, resolveSkillStatuses, skillSupportsPlatform, versionProbeSkills } from './lib/tools/skills/catalog.js';
|
|
45
|
-
import { ensureBundledSkillsDir } from './lib/tools/skills/bundled-dir.js';
|
|
46
|
-
import { ensureSkillsOverlayDir } from './lib/tools/skills/overlay-dir.js';
|
|
47
|
-
import { copyBaseForEdit, deleteOverlaySkill, listManagedSkills, readSkillFile, writeSkillFile } from './lib/tools/skills/overlay-crud.js';
|
|
48
|
-
import { watchSkillsOverlay } from './lib/tools/skills/overlay-watch.js';
|
|
30
|
+
import { SkillsHost } from './lib/skills-host/index.js';
|
|
49
31
|
import { errorMessage, isRecord } from './lib/guards.js';
|
|
50
32
|
import { redactedRecoveryFields } from './lib/wire.js';
|
|
51
33
|
import { hlog } from './lib/log.js';
|
|
52
34
|
import { installResolutionDetector, resolutionDetail } from './lib/resolution-detector.js';
|
|
53
|
-
import { probeBinVersions } from './lib/tools/skills/bin-check.js';
|
|
54
35
|
import { bareRuntime } from './lib/tools/exec/bare-runtime.js';
|
|
55
36
|
import { runCommand } from './lib/tools/exec/runner.js';
|
|
56
37
|
import { createLocalRoots } from './lib/tools/fs/local.js';
|
|
57
38
|
import { createRemoteRoots } from './lib/tools/fs/remote.js';
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
export
|
|
39
|
+
export { CompletionEngine } from './lib/capabilities/completion-engine/index.js';
|
|
40
|
+
export const CONTEXT_OVERFLOW_MESSAGE = CompletionEngine.CONTEXT_OVERFLOW_MESSAGE;
|
|
41
|
+
export { imageSettingsFrom } from './lib/helpers/image-settings.js';
|
|
42
|
+
export { skillInContext, unreadySkillState } from './lib/capabilities/skill-entry.js';
|
|
43
|
+
export { toSdkTool } from './lib/capabilities/sdk-tool.js';
|
|
62
44
|
export { attachmentTurn, loadedSkillsFrom, skillLoadedTurn } from './lib/capabilities/tool-turns.js';
|
|
63
45
|
export { CAPABILITIES, isCapability } from './lib/capabilities/invoke.js';
|
|
64
|
-
export { EURONANO_LANGUAGES, NMT_FROM_ENGLISH, NMT_TO_ENGLISH, SLM_LANGUAGE_CODES, SLM_LANGUAGE_NAMES, translationPlanFor } from './lib/models/nmt-catalog.js';
|
|
65
46
|
export * from './lib/capabilities/download.js';
|
|
66
47
|
export * from './lib/models/model-catalog.js';
|
|
67
48
|
export * from './lib/models/model-list.js';
|
|
68
49
|
export { harnessChild, spawnHarness } from './lib/spawn.js';
|
|
69
|
-
export { settingsDimension, settingsSteps } from './lib/tools/generate-image.js';
|
|
70
50
|
export * from './lib/tools/skills/catalog.js';
|
|
71
51
|
export { requiredSettings, settingEnvName } from './lib/tools/skills/skill-settings.js';
|
|
72
52
|
export { TOOLSETS, toolsetEnabled } from './lib/tools/toolsets.js';
|
|
@@ -76,455 +56,337 @@ export { isAvailableState, SKILL_STATE } from './lib/tools/skills/skill-state.js
|
|
|
76
56
|
export { connectHarness, HARNESS_DIED, RemoteHarness } from './lib/connect.js';
|
|
77
57
|
export { serveHarness } from './lib/serve.js';
|
|
78
58
|
export { hlog, setHarnessLog, setHarnessLogSink } from './lib/log.js';
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
59
|
+
import { HookPipeline } from './lib/hooks/index.js';
|
|
60
|
+
import { Agent } from './lib/agent/index.js';
|
|
61
|
+
export { HookPipeline };
|
|
62
|
+
import { createGuardedFetch } from './lib/guarded-fetch.js';
|
|
63
|
+
import { PluginRegistry } from './lib/plugins/index.js';
|
|
64
|
+
import { createExecTool } from './lib/tools/exec.js';
|
|
65
|
+
import { deniedRootsFor } from './lib/tools/fs/scope.js';
|
|
66
|
+
export const PLUGIN_API_VERSION = PluginRegistry.API_VERSION;
|
|
82
67
|
const SUSPEND_SETTLE_MS = 500;
|
|
83
|
-
const
|
|
84
|
-
const
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const UNLOAD_LEASE_WAIT_MS = 10_000;
|
|
91
|
-
const DEFAULT_COMPLETION_MODEL_CAP = 1;
|
|
92
|
-
const WEDGED_EVICT_LEASED_MS = 120_000;
|
|
93
|
-
const TTS_MODEL_CONFIG = {
|
|
94
|
-
ttsEngine: 'supertonic',
|
|
95
|
-
language: 'en',
|
|
96
|
-
ttsSpeed: 1.175,
|
|
97
|
-
ttsNumInferenceSteps: 5
|
|
98
|
-
};
|
|
68
|
+
const SPEECH_PLUGIN_MISSING = 'speech needs the speech plugin';
|
|
69
|
+
const KNOWLEDGE_PLUGIN_MISSING = 'knowledge needs the knowledge plugin';
|
|
70
|
+
function execOptions(exec) {
|
|
71
|
+
if (!exec)
|
|
72
|
+
return null;
|
|
73
|
+
return exec === true ? {} : exec;
|
|
74
|
+
}
|
|
99
75
|
export class Harness extends ReadyResource {
|
|
76
|
+
_hostTools;
|
|
100
77
|
_tools;
|
|
78
|
+
_capabilities = [];
|
|
101
79
|
_sdk;
|
|
102
80
|
_loads = createLoadTracker();
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
_retiredEmbedModels;
|
|
109
|
-
_faultedEmbedKeys = new WeakMap();
|
|
110
|
-
_embedLane = createEmbedLane();
|
|
111
|
-
_embedFaults;
|
|
112
|
-
_embedGpuLayers;
|
|
113
|
-
_embedBatchSize;
|
|
114
|
-
_embedControl;
|
|
115
|
-
_ttsModels;
|
|
116
|
-
_transcriptionModels;
|
|
117
|
-
_voiceLane = createVoiceLane();
|
|
118
|
-
_lifecycle = createHarnessLifecycle({
|
|
119
|
-
suspend: () => this._suspendRuntimes(),
|
|
120
|
-
resume: () => this._resumeRuntimes()
|
|
121
|
-
});
|
|
122
|
-
_detachedRuns = new Set();
|
|
123
|
-
_effectDrainWaiters = new Set();
|
|
124
|
-
_activeWork = 0;
|
|
125
|
-
_workDrainWaiters = new Set();
|
|
126
|
-
_runtimeDraining = false;
|
|
127
|
-
_runtimeUnloadFailed = false;
|
|
128
|
-
_poolUnloadFailed = false;
|
|
129
|
-
_poolCleanupFailed = false;
|
|
130
|
-
_failedModelUnloads = new Set();
|
|
131
|
-
_sdkClosed = false;
|
|
132
|
-
_runtimesReleased = false;
|
|
81
|
+
_residency;
|
|
82
|
+
_embeddings;
|
|
83
|
+
_voicePools = new Map();
|
|
84
|
+
_skills;
|
|
85
|
+
_lifecycle;
|
|
133
86
|
_closeRetryNeeded = false;
|
|
134
|
-
_closeRequested = false;
|
|
135
|
-
_skillsDir;
|
|
136
87
|
_modelsDir;
|
|
137
|
-
|
|
138
|
-
|
|
88
|
+
_skillsDir;
|
|
89
|
+
_exec;
|
|
90
|
+
_deniedRoots;
|
|
139
91
|
_projectionModel;
|
|
140
92
|
_customProjection = {};
|
|
141
|
-
_llmDevice;
|
|
142
|
-
_llmGpuLayers;
|
|
143
|
-
_contextSize;
|
|
144
|
-
_kvCacheK;
|
|
145
|
-
_kvCacheV;
|
|
146
|
-
_transcriptionDevice;
|
|
147
93
|
_gpuStats;
|
|
148
|
-
_completionModelCap;
|
|
149
|
-
_allSkills;
|
|
150
|
-
_credentialStore;
|
|
151
|
-
_credentials = new Map();
|
|
152
|
-
_settings = new Map();
|
|
153
|
-
_platform;
|
|
154
|
-
_diffusionSdk;
|
|
155
|
-
_imageRuntime;
|
|
156
|
-
_musicSdk;
|
|
157
|
-
_translationSdk;
|
|
158
|
-
_musicRuntime;
|
|
159
|
-
_completionRuns;
|
|
160
|
-
_translationRuntime;
|
|
161
|
-
_capabilityTools;
|
|
162
94
|
_capability = null;
|
|
163
95
|
_capabilityInflight = null;
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
96
|
+
_hostHooks;
|
|
97
|
+
_hooks;
|
|
98
|
+
_plugins;
|
|
99
|
+
_pluginMode;
|
|
100
|
+
_pluginsStarted = null;
|
|
101
|
+
constructor({ tools = [], sdkLoader, skillsDir, modelsDir, sdkHome, exec, projectionModel, llmDevice, llmGpuLayers, contextSize, kvCacheK, kvCacheV, llmLoad, slots, embedDevice, embedGpuLayers, embedBatchSize, transcriptionDevice, completionModelCap, credentialStore, platform, gpuStats, hooks, plugins = [], pluginMode = 'frozen' } = {}) {
|
|
167
102
|
super();
|
|
103
|
+
this._exec = execOptions(exec);
|
|
104
|
+
if (this._exec && tools.some((tool) => tool.name === PluginRegistry.EXEC_TOOL)) {
|
|
105
|
+
throw new Error(`tools has '${PluginRegistry.EXEC_TOOL}', which the harness builds when exec is set`);
|
|
106
|
+
}
|
|
107
|
+
this._deniedRoots = sdkHome === undefined ? undefined : deniedRootsFor(sdkHome);
|
|
108
|
+
this._plugins = new PluginRegistry(plugins, {
|
|
109
|
+
services: { models: this._modelHost(transcriptionDevice), embed: this._embedHost() },
|
|
110
|
+
exec: this._exec !== null,
|
|
111
|
+
deniedRoots: this._deniedRoots ?? []
|
|
112
|
+
});
|
|
113
|
+
this._pluginMode = pluginMode;
|
|
168
114
|
installAbortControllerPolyfill();
|
|
115
|
+
this._hostHooks = Object.freeze([...(hooks ?? HookPipeline.defaults())]);
|
|
116
|
+
this._hooks = this._hostHooks;
|
|
169
117
|
this._sdk = sdkLoader ?? createSdkLoader();
|
|
170
|
-
this.
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
118
|
+
this._lifecycle = new Lifecycle({
|
|
119
|
+
resource: this,
|
|
120
|
+
sdk: { peek: () => this._sdk.peek() },
|
|
121
|
+
loads: this._loads,
|
|
122
|
+
releases: {
|
|
123
|
+
pools: () => [
|
|
124
|
+
this._residency.destroy(),
|
|
125
|
+
this._embeddings.destroy(),
|
|
126
|
+
...[...this._voicePools.values()].map((entry) => entry.pool.destroy())
|
|
127
|
+
],
|
|
128
|
+
runtimes: () => [],
|
|
129
|
+
plugins: () => this._plugins.unload()
|
|
130
|
+
},
|
|
131
|
+
models: () => loadedModels(this._residency.pool).map((entry) => entry.model),
|
|
132
|
+
recreate: () => {
|
|
133
|
+
this._residency.recreate();
|
|
134
|
+
this._embeddings.recreate();
|
|
135
|
+
for (const entry of this._voicePools.values()) {
|
|
136
|
+
entry.pool = this._createVoicePool(entry.spec);
|
|
137
|
+
}
|
|
138
|
+
},
|
|
139
|
+
statusChanged: () => this._residency.invalidateStatus(),
|
|
140
|
+
teardown: async () => {
|
|
141
|
+
this._skills.close();
|
|
142
|
+
await this._teardownPlugins();
|
|
143
|
+
}
|
|
182
144
|
});
|
|
183
|
-
this.
|
|
184
|
-
this.
|
|
185
|
-
this.
|
|
186
|
-
this.
|
|
187
|
-
this.
|
|
188
|
-
|
|
189
|
-
|
|
145
|
+
this._gpuStats = gpuStats;
|
|
146
|
+
this._hostTools = tools;
|
|
147
|
+
this._tools = tools;
|
|
148
|
+
this._projectionModel = projectionModel ?? defaultProjectionMap();
|
|
149
|
+
this._modelsDir = modelsDir;
|
|
150
|
+
this._skillsDir = skillsDir;
|
|
151
|
+
this._skills = new SkillsHost({
|
|
152
|
+
skillsDir,
|
|
153
|
+
platform,
|
|
154
|
+
credentialStore,
|
|
155
|
+
tools: () => this._tools,
|
|
156
|
+
startPlugins: () => this._startPlugins()
|
|
190
157
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return;
|
|
213
|
-
}
|
|
214
|
-
imageTransfers.delete(model);
|
|
215
|
-
invalidateModelStatusCache(this._modelStatus);
|
|
216
|
-
this.emit('model', { ...transfer, status: 'downloaded' });
|
|
217
|
-
},
|
|
218
|
-
onBeforeLoad: async (signal) => {
|
|
219
|
-
if (this._models.destroyed)
|
|
220
|
-
return;
|
|
221
|
-
const evicted = await awaitModelCapacity(this._models, {
|
|
222
|
-
cap: 1,
|
|
223
|
-
deadlineMs: DIFFUSION_EVICT_WAIT_MS,
|
|
224
|
-
signal
|
|
225
|
-
});
|
|
226
|
-
if (signal?.aborted) {
|
|
227
|
-
throw new AbortedError();
|
|
228
|
-
}
|
|
229
|
-
if (!evicted) {
|
|
230
|
-
throw new Error('the chat model is busy; try the image again once the current reply finishes');
|
|
231
|
-
}
|
|
158
|
+
this._residency = new Residency({
|
|
159
|
+
llmDevice,
|
|
160
|
+
llmGpuLayers,
|
|
161
|
+
contextSize,
|
|
162
|
+
kvCacheK,
|
|
163
|
+
kvCacheV,
|
|
164
|
+
llmLoad,
|
|
165
|
+
slots,
|
|
166
|
+
completionModelCap,
|
|
167
|
+
sdk: { load: () => this._sdk.load() },
|
|
168
|
+
loads: this._loads,
|
|
169
|
+
gate: this._lifecycle,
|
|
170
|
+
emit: (state) => this.emit('model', state),
|
|
171
|
+
projectionFor: (model) => this._projectionFor(model),
|
|
172
|
+
pools: () => [
|
|
173
|
+
...this._embeddings.pools(),
|
|
174
|
+
...[...this._voicePools.values()].map((entry) => entry.pool)
|
|
175
|
+
],
|
|
176
|
+
poolFor: (addon, model) => {
|
|
177
|
+
if (addon === 'embeddings') {
|
|
178
|
+
return this._embeddings.target(model);
|
|
232
179
|
}
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this._musicRuntime = music
|
|
237
|
-
? createMusicRuntime({
|
|
238
|
-
...music,
|
|
239
|
-
loads: this._loads,
|
|
240
|
-
loadSdk: () => this._loadMusicSdk(),
|
|
241
|
-
onProgress: (model, progress) => {
|
|
242
|
-
const state = progressState(model, progress);
|
|
243
|
-
this.emit('model', state);
|
|
244
|
-
},
|
|
245
|
-
onBeforeLoad: async (signal) => {
|
|
246
|
-
if (this._models.destroyed)
|
|
247
|
-
return;
|
|
248
|
-
const evicted = await awaitModelCapacity(this._models, {
|
|
249
|
-
cap: 1,
|
|
250
|
-
deadlineMs: MUSIC_EVICT_WAIT_MS,
|
|
251
|
-
signal
|
|
252
|
-
});
|
|
253
|
-
if (signal?.aborted) {
|
|
254
|
-
throw new AbortedError();
|
|
255
|
-
}
|
|
256
|
-
if (!evicted) {
|
|
257
|
-
throw new Error('the chat model is busy; try the music again once the current reply finishes');
|
|
258
|
-
}
|
|
180
|
+
const entry = this._voicePools.get(addon);
|
|
181
|
+
if (!entry) {
|
|
182
|
+
throw new Error(SPEECH_PLUGIN_MISSING);
|
|
259
183
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
184
|
+
const key = residentSrc(model, addon);
|
|
185
|
+
return {
|
|
186
|
+
pool: entry.pool,
|
|
187
|
+
key,
|
|
188
|
+
needsRoom: entry.spec.needsRoom?.(key) ?? false,
|
|
189
|
+
open: () => entry.pool.open(key, key)
|
|
190
|
+
};
|
|
191
|
+
},
|
|
192
|
+
embedRoom: (model, target) => this._embeddings.makeRoom(model, target),
|
|
193
|
+
evictIdle: () => [
|
|
194
|
+
...this._embeddings.evictIdle(),
|
|
195
|
+
...[...this._voicePools.values()].map((entry) => evictIdle(entry.pool))
|
|
196
|
+
],
|
|
197
|
+
unloadIdlePlugins: () => this._plugins.unloadIdle(),
|
|
198
|
+
tools: () => this._tools,
|
|
199
|
+
skills: (agentId, model) => this._skills.completionSkills(agentId, model)
|
|
266
200
|
});
|
|
267
|
-
this.
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
createEditImageTool(this._imageRuntime, {}, imageClamps)
|
|
278
|
-
]
|
|
279
|
-
: []),
|
|
280
|
-
...(this._musicRuntime ? [createGenerateMusicTool(this._musicRuntime, musicClamps)] : [])
|
|
281
|
-
];
|
|
282
|
-
this._projectionModel = projectionModel ?? defaultProjectionMap();
|
|
283
|
-
this._skillsDir = skillsDir;
|
|
284
|
-
this._modelsDir = modelsDir;
|
|
285
|
-
this._supportedSkills = [];
|
|
286
|
-
this._allSkills = [];
|
|
287
|
-
this._credentialStore = credentialStore;
|
|
288
|
-
this._platform = platform;
|
|
289
|
-
this._diffusionSdk = null;
|
|
290
|
-
this._musicSdk = null;
|
|
291
|
-
this._completionRuns = new Set();
|
|
292
|
-
this._translationSdk = null;
|
|
293
|
-
this._models = this._createPool();
|
|
294
|
-
this._embedModels = this._createEmbedPool();
|
|
295
|
-
this._ttsModels = this._createTtsPool();
|
|
296
|
-
this._transcriptionModels = this._createTranscriptionPool();
|
|
297
|
-
this._idle = createIdleReaper({
|
|
298
|
-
sweep: () => this._unloadIdleModels(),
|
|
299
|
-
waitMs: WEDGED_EVICT_WAIT_MS,
|
|
300
|
-
onError: (err) => hlog('idle unload failed', { err: errorMessage(err) })
|
|
201
|
+
this._embeddings = new Embeddings({
|
|
202
|
+
device: embedDevice,
|
|
203
|
+
gpuLayers: embedGpuLayers,
|
|
204
|
+
batchSize: embedBatchSize,
|
|
205
|
+
sdk: { loadEmbed: () => this._sdk.loadEmbed() },
|
|
206
|
+
loads: this._loads,
|
|
207
|
+
gate: this._lifecycle,
|
|
208
|
+
notify: (state) => this._residency.notify(state),
|
|
209
|
+
settleFit: (query) => this._residency.fit.settle(query),
|
|
210
|
+
evictIdleChat: () => this._residency.evictIdleChat()
|
|
301
211
|
});
|
|
302
212
|
}
|
|
303
213
|
async _open() {
|
|
304
214
|
try {
|
|
305
215
|
installResolutionDetector(import.meta);
|
|
306
|
-
await this.
|
|
307
|
-
await this.
|
|
308
|
-
|
|
216
|
+
await this._startPlugins();
|
|
217
|
+
await this._loadAddons();
|
|
218
|
+
await this._skills.open();
|
|
219
|
+
hlog('open', { skills: this._skills.names.length, tools: this._tools.length });
|
|
309
220
|
}
|
|
310
221
|
catch (error) {
|
|
222
|
+
await this._teardownPlugins();
|
|
311
223
|
throw error;
|
|
312
224
|
}
|
|
313
225
|
}
|
|
226
|
+
_startPlugins() {
|
|
227
|
+
this._pluginsStarted ??= this._runPluginStart();
|
|
228
|
+
return this._pluginsStarted;
|
|
229
|
+
}
|
|
230
|
+
async _runPluginStart() {
|
|
231
|
+
const reserved = this._hostTools.map((tool) => tool.name);
|
|
232
|
+
if (this._exec) {
|
|
233
|
+
reserved.push(PluginRegistry.EXEC_TOOL);
|
|
234
|
+
}
|
|
235
|
+
const started = await this._plugins.start([...reserved, Agent.TRANSFER_TOOL_NAME, Agent.DELEGATE_TOOL_NAME], {
|
|
236
|
+
fetch: (signal, mayConnect) => createGuardedFetch({ signal, mayConnect }),
|
|
237
|
+
publish: (swapped) => this._publishPlugins(swapped)
|
|
238
|
+
});
|
|
239
|
+
this._publishPlugins(started);
|
|
240
|
+
}
|
|
241
|
+
_publishPlugins({ tools, capabilities, hooks, skills, exec }) {
|
|
242
|
+
const pre = hooks.filter((hook) => hook.phase === 'preToolCall');
|
|
243
|
+
const rest = hooks.filter((hook) => hook.phase !== 'preToolCall');
|
|
244
|
+
this._tools = Object.freeze([...this._hostTools, ...this._execTools(exec), ...tools]);
|
|
245
|
+
this._capabilities = Object.freeze(capabilities);
|
|
246
|
+
this._hooks = Object.freeze([...pre, ...this._hostHooks, ...rest]);
|
|
247
|
+
this._skills.publish(skills);
|
|
248
|
+
}
|
|
249
|
+
_execTools(exec) {
|
|
250
|
+
if (!this._exec) {
|
|
251
|
+
return [];
|
|
252
|
+
}
|
|
253
|
+
return [
|
|
254
|
+
createExecTool({
|
|
255
|
+
...this._exec,
|
|
256
|
+
...exec,
|
|
257
|
+
deniedRoots: this._deniedRoots,
|
|
258
|
+
skillsDir: this._skillsDir,
|
|
259
|
+
skillSettings: (skill, agentId) => this._skills.skillSettings(skill, agentId)
|
|
260
|
+
})
|
|
261
|
+
];
|
|
262
|
+
}
|
|
263
|
+
async addPlugin(plugin) {
|
|
264
|
+
await this._dynamicPlugins();
|
|
265
|
+
await this._plugins.add(plugin);
|
|
266
|
+
}
|
|
267
|
+
async removePlugin(name) {
|
|
268
|
+
await this._dynamicPlugins();
|
|
269
|
+
await this._plugins.remove(name);
|
|
270
|
+
}
|
|
271
|
+
async reloadPlugin(name, plugin) {
|
|
272
|
+
await this._dynamicPlugins();
|
|
273
|
+
await this._plugins.reload(name, plugin);
|
|
274
|
+
}
|
|
275
|
+
async _dynamicPlugins() {
|
|
276
|
+
if (this._pluginMode !== 'dynamic') {
|
|
277
|
+
throw new Error("plugins are frozen: construct the harness with pluginMode 'dynamic'");
|
|
278
|
+
}
|
|
279
|
+
if (!this.opened)
|
|
280
|
+
await this.ready();
|
|
281
|
+
this._lifecycle.assertNotClosing();
|
|
282
|
+
}
|
|
283
|
+
_modelHost(transcriptionDevice) {
|
|
284
|
+
return {
|
|
285
|
+
transcriptionDevice,
|
|
286
|
+
sdk: () => this._sdk.load(),
|
|
287
|
+
track: (load, sdk) => this._loads.track(load, sdk),
|
|
288
|
+
makeRoom: (signal, busyMessage) => this._residency.makeRoomForPlugin(signal, busyMessage),
|
|
289
|
+
completionModel: (model, signal) => this._residency.borrow(model, signal),
|
|
290
|
+
emit: (state) => this.emit('model', state),
|
|
291
|
+
progressState,
|
|
292
|
+
statusChanged: () => this._residency.statusChanged(),
|
|
293
|
+
registerPool: (spec) => this._registerPool(spec),
|
|
294
|
+
enterWork: () => {
|
|
295
|
+
if (this._lifecycle.suspended) {
|
|
296
|
+
throw new Error('harness is suspended');
|
|
297
|
+
}
|
|
298
|
+
return this._lifecycle.enterWork();
|
|
299
|
+
}
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
_registerPool(spec) {
|
|
303
|
+
const entry = { spec, pool: this._createVoicePool(spec) };
|
|
304
|
+
this._voicePools.set(spec.addon, entry);
|
|
305
|
+
return {
|
|
306
|
+
open: (model) => {
|
|
307
|
+
const pool = entry.pool;
|
|
308
|
+
const handle = pool.open(model, model);
|
|
309
|
+
return {
|
|
310
|
+
load: async () => {
|
|
311
|
+
const { modelId } = await handle.load();
|
|
312
|
+
this._lifecycle.assertNotClosing();
|
|
313
|
+
return { modelId };
|
|
314
|
+
},
|
|
315
|
+
peek: () => handle.peek(),
|
|
316
|
+
release: () => releaseModel(pool, model)
|
|
317
|
+
};
|
|
318
|
+
},
|
|
319
|
+
resident: (model) => isResident(entry.pool, model),
|
|
320
|
+
evictIdle: (wanted) => evictIdleWhere(entry.pool, wanted)
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
_createVoicePool({ sdk, label, openclCache, ...spec }) {
|
|
324
|
+
return createVoicePool(() => sdk(), (state) => this._residency.notify(label ? { ...state, model: label } : state), {
|
|
325
|
+
...spec,
|
|
326
|
+
openclCacheDir: openclCache ? openclCacheDir : undefined,
|
|
327
|
+
loads: this._loads,
|
|
328
|
+
onUnloadFailure: (modelId, error) => this._lifecycle.recordModelUnloadFailure(modelId, error)
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
_embedHost() {
|
|
332
|
+
return {
|
|
333
|
+
embed: (request) => this.embed(request),
|
|
334
|
+
sdk: () => this._sdk.loadEmbed()
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
async _loadAddons() {
|
|
338
|
+
await Promise.all([
|
|
339
|
+
PluginRegistry.loadAddons('the harness', this._sdk.addons),
|
|
340
|
+
...this._tools.map((tool) => PluginRegistry.loadAddons(`tool '${tool.name}'`, tool.addons))
|
|
341
|
+
]);
|
|
342
|
+
}
|
|
343
|
+
_teardownPlugins() {
|
|
344
|
+
return this._plugins.teardown((plugin, error) => hlog('plugin teardown failed', { plugin, err: errorMessage(error) }));
|
|
345
|
+
}
|
|
314
346
|
get suspended() {
|
|
315
347
|
return this._lifecycle.suspended;
|
|
316
348
|
}
|
|
317
349
|
get skillNames() {
|
|
318
|
-
return this.
|
|
350
|
+
return this._skills.names;
|
|
319
351
|
}
|
|
320
352
|
setCredentials(entries) {
|
|
321
|
-
|
|
322
|
-
const next = new Map();
|
|
323
|
-
for (const { key, token, expiresAt, agentId, skill } of entries) {
|
|
324
|
-
if (!token)
|
|
325
|
-
continue;
|
|
326
|
-
const storeKey = scopeKey({ agentId, skill, key });
|
|
327
|
-
const record = typeof expiresAt === 'number' && expiresAt > 0 ? { token, expiresAt } : { token };
|
|
328
|
-
const current = previous.get(storeKey);
|
|
329
|
-
if (!current || current.token !== record.token || current.expiresAt !== record.expiresAt) {
|
|
330
|
-
resetCredentialHealthAfterSnapshot(key, agentId, skill);
|
|
331
|
-
}
|
|
332
|
-
next.set(storeKey, record);
|
|
333
|
-
}
|
|
334
|
-
this._credentials = next;
|
|
353
|
+
this._skills.setCredentials(entries);
|
|
335
354
|
}
|
|
336
355
|
setSkillSettings(entries) {
|
|
337
|
-
|
|
338
|
-
for (const { skill, key, value, agentId } of entries) {
|
|
339
|
-
if (!skill || !key || typeof value !== 'string')
|
|
340
|
-
continue;
|
|
341
|
-
const scope = settingsScopeKey(skill, agentId);
|
|
342
|
-
const bucket = next.get(scope) ?? {};
|
|
343
|
-
bucket[key] = value;
|
|
344
|
-
next.set(scope, bucket);
|
|
345
|
-
}
|
|
346
|
-
this._settings = next;
|
|
356
|
+
this._skills.setSkillSettings(entries);
|
|
347
357
|
}
|
|
348
358
|
skillSettings(skill, agentId) {
|
|
349
|
-
return
|
|
350
|
-
...this._settings.get(settingsScopeKey(skill, null)),
|
|
351
|
-
...(agentId ? this._settings.get(settingsScopeKey(skill, agentId)) : undefined)
|
|
352
|
-
};
|
|
359
|
+
return this._skills.skillSettings(skill, agentId);
|
|
353
360
|
}
|
|
354
|
-
|
|
355
|
-
return this.
|
|
361
|
+
listManagedSkills() {
|
|
362
|
+
return this._skills.listManagedSkills();
|
|
356
363
|
}
|
|
357
|
-
|
|
358
|
-
return
|
|
364
|
+
readSkillFile(name) {
|
|
365
|
+
return this._skills.readSkillFile(name);
|
|
359
366
|
}
|
|
360
|
-
|
|
361
|
-
return
|
|
367
|
+
writeSkillFile(name, content) {
|
|
368
|
+
return this._skills.writeSkillFile(name, content);
|
|
362
369
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
if (!overlay) {
|
|
366
|
-
throw new Error('no writable skills overlay is configured');
|
|
367
|
-
}
|
|
368
|
-
await writeSkillFile(overlay, name, content);
|
|
369
|
-
await this._reloadSkills();
|
|
370
|
-
return { ok: true };
|
|
371
|
-
}
|
|
372
|
-
async copyBaseForEdit(name) {
|
|
373
|
-
const overlay = await ensureSkillsOverlayDir();
|
|
374
|
-
if (!overlay) {
|
|
375
|
-
throw new Error('no writable skills overlay is configured');
|
|
376
|
-
}
|
|
377
|
-
const result = await copyBaseForEdit(await this._baseSkillsDir(), overlay, name);
|
|
378
|
-
if (result.copied) {
|
|
379
|
-
await this._reloadSkills();
|
|
380
|
-
}
|
|
381
|
-
return result;
|
|
370
|
+
copyBaseForEdit(name) {
|
|
371
|
+
return this._skills.copyBaseForEdit(name);
|
|
382
372
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
if (!overlay) {
|
|
386
|
-
throw new Error('no writable skills overlay is configured');
|
|
387
|
-
}
|
|
388
|
-
const result = await deleteOverlaySkill(overlay, name);
|
|
389
|
-
if (result.removed) {
|
|
390
|
-
await this._reloadSkills();
|
|
391
|
-
}
|
|
392
|
-
return result;
|
|
373
|
+
deleteOverlaySkill(name) {
|
|
374
|
+
return this._skills.deleteOverlaySkill(name);
|
|
393
375
|
}
|
|
394
376
|
resolveCredential(key, ctx) {
|
|
395
|
-
|
|
396
|
-
return this._credentialStore(key, ctx);
|
|
397
|
-
}
|
|
398
|
-
const agentId = ctx?.agentId ?? null;
|
|
399
|
-
const deviceShared = isDeviceSharedCredentialKey(key);
|
|
400
|
-
for (const skill of ctx?.skills ?? []) {
|
|
401
|
-
const owned = this._credentials.get(scopeKey({ agentId, skill, key })) ??
|
|
402
|
-
(agentId && deviceShared ? this._credentials.get(scopeKey({ skill, key })) : undefined);
|
|
403
|
-
if (owned) {
|
|
404
|
-
return owned;
|
|
405
|
-
}
|
|
406
|
-
}
|
|
407
|
-
if (agentId) {
|
|
408
|
-
const scoped = this._credentials.get(scopeKey({ agentId, key }));
|
|
409
|
-
if (scoped) {
|
|
410
|
-
return scoped;
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
if (!agentId || deviceShared) {
|
|
414
|
-
return this._credentials.get(scopeKey({ key })) ?? null;
|
|
415
|
-
}
|
|
416
|
-
return null;
|
|
417
|
-
}
|
|
418
|
-
async _completionSkills(agentId, model) {
|
|
419
|
-
const statuses = new Map((await this.skills(agentId, model, { skipCredentialProbe: true, skipBinProbe: true })).map((entry) => [entry.name, entry.status]));
|
|
420
|
-
return availableSkills(this._supportedSkills, new Set(this._tools.map((tool) => tool.name)), modelNameToCapabilityProfile(model)).map((entry) => ({
|
|
421
|
-
...entry,
|
|
422
|
-
status: statuses.get(entry.name)
|
|
423
|
-
}));
|
|
377
|
+
return this._skills.resolveCredential(key, ctx);
|
|
424
378
|
}
|
|
425
379
|
async skills(agentId, modelName, options) {
|
|
426
380
|
if (!this.opened)
|
|
427
381
|
await this.ready();
|
|
428
|
-
this.
|
|
429
|
-
|
|
430
|
-
const refresh = options?.refresh === true;
|
|
431
|
-
return resolveSkillStatuses(this._allSkills, {
|
|
432
|
-
installedTools: new Set(this._tools.map((tool) => tool.name)),
|
|
433
|
-
credentialStore: (key, ctx) => this.resolveCredential(key, ctx),
|
|
434
|
-
settingsStore: (skill, agentId) => this.skillSettings(skill, agentId),
|
|
435
|
-
platform,
|
|
436
|
-
agentId,
|
|
437
|
-
binVersions: options?.skipBinProbe === true
|
|
438
|
-
? (this._binVersionCache?.bySkill ?? new Map())
|
|
439
|
-
: await this._probeBinVersions(platform, refresh),
|
|
440
|
-
refresh,
|
|
441
|
-
skipCredentialProbe: options?.skipCredentialProbe === true,
|
|
442
|
-
activeProfile: modelName ? modelNameToCapabilityProfile(modelName) : undefined
|
|
443
|
-
});
|
|
444
|
-
}
|
|
445
|
-
async _reloadSkills() {
|
|
446
|
-
const skillsDir = this._skillsDir ?? (await ensureBundledSkillsDir());
|
|
447
|
-
this._allSkills = await loadSkillCatalog(skillsDir, { platform: null });
|
|
448
|
-
const platform = this._platform ?? detectPlatform();
|
|
449
|
-
const supported = this._allSkills.filter((skill) => skillSupportsPlatform(skill, platform));
|
|
450
|
-
this._supportedSkills = availableSkills(supported, new Set(this._tools.map((t) => t.name)));
|
|
451
|
-
}
|
|
452
|
-
async _startOverlayWatch() {
|
|
453
|
-
if (this._overlayWatcher)
|
|
454
|
-
return;
|
|
455
|
-
try {
|
|
456
|
-
const overlay = await ensureSkillsOverlayDir();
|
|
457
|
-
if (!overlay) {
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
this._overlayWatcher = watchSkillsOverlay(overlay, () => {
|
|
461
|
-
this._reloadSkills().catch((err) => hlog('overlay reload failed', { err: errorMessage(err) }));
|
|
462
|
-
});
|
|
463
|
-
}
|
|
464
|
-
catch (err) {
|
|
465
|
-
hlog('overlay watch unavailable', { err: errorMessage(err) });
|
|
466
|
-
}
|
|
382
|
+
this._lifecycle.assertNotClosing();
|
|
383
|
+
return this._skills.statuses(agentId, modelName, options);
|
|
467
384
|
}
|
|
468
385
|
async tools() {
|
|
386
|
+
if (!this.opened)
|
|
387
|
+
await this.ready();
|
|
469
388
|
return toolCatalog(this._tools);
|
|
470
389
|
}
|
|
471
|
-
_binVersionCache = null;
|
|
472
|
-
_binVersionInflight = null;
|
|
473
|
-
async _probeBinVersions(platform, refresh = false) {
|
|
474
|
-
const now = Date.now();
|
|
475
|
-
if (!refresh && this._binVersionCache && this._binVersionCache.expiresAt > now) {
|
|
476
|
-
return this._binVersionCache.bySkill;
|
|
477
|
-
}
|
|
478
|
-
if (this._binVersionInflight) {
|
|
479
|
-
return this._binVersionInflight;
|
|
480
|
-
}
|
|
481
|
-
this._binVersionInflight = this._runBinVersionProbes(platform)
|
|
482
|
-
.then((bySkill) => {
|
|
483
|
-
this._binVersionCache = {
|
|
484
|
-
expiresAt: Date.now() + BIN_VERSION_PROBE_TTL_MS,
|
|
485
|
-
bySkill
|
|
486
|
-
};
|
|
487
|
-
return bySkill;
|
|
488
|
-
})
|
|
489
|
-
.finally(() => {
|
|
490
|
-
this._binVersionInflight = null;
|
|
491
|
-
});
|
|
492
|
-
return this._binVersionInflight;
|
|
493
|
-
}
|
|
494
|
-
async _runBinVersionProbes(platform) {
|
|
495
|
-
if (process.env.QVAC_NO_SKILL_BIN_PROBE) {
|
|
496
|
-
return new Map();
|
|
497
|
-
}
|
|
498
|
-
const installed = new Set(this._tools.map((tool) => tool.name));
|
|
499
|
-
const candidates = versionProbeSkills(this._allSkills, installed, platform);
|
|
500
|
-
if (candidates.length === 0) {
|
|
501
|
-
return new Map();
|
|
502
|
-
}
|
|
503
|
-
let runtime;
|
|
504
|
-
try {
|
|
505
|
-
runtime = await bareRuntime();
|
|
506
|
-
}
|
|
507
|
-
catch {
|
|
508
|
-
return new Map();
|
|
509
|
-
}
|
|
510
|
-
const run = async (command) => {
|
|
511
|
-
try {
|
|
512
|
-
const result = await runCommand(command, { ...runtime, timeoutMs: 5_000 });
|
|
513
|
-
return result.exitCode === 0 ? result.stdout : null;
|
|
514
|
-
}
|
|
515
|
-
catch {
|
|
516
|
-
return null;
|
|
517
|
-
}
|
|
518
|
-
};
|
|
519
|
-
const bySkill = new Map();
|
|
520
|
-
for (const skill of candidates) {
|
|
521
|
-
const states = await probeBinVersions(skill.requires, { platform, run });
|
|
522
|
-
if (states.size > 0) {
|
|
523
|
-
bySkill.set(skill.name, states);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
return bySkill;
|
|
527
|
-
}
|
|
528
390
|
get toolNames() {
|
|
529
391
|
return this._tools.map((tool) => tool.name);
|
|
530
392
|
}
|
|
@@ -554,550 +416,65 @@ export class Harness extends ReadyResource {
|
|
|
554
416
|
this._customProjection = customProjectionMap();
|
|
555
417
|
}
|
|
556
418
|
setModelIdleTimeout(ms) {
|
|
557
|
-
this.
|
|
419
|
+
this._residency.setIdleTimeout(ms);
|
|
558
420
|
}
|
|
559
421
|
previewModelSource(context) {
|
|
560
|
-
return previewModelSource(context, { assessFit: (query) => this.
|
|
561
|
-
}
|
|
562
|
-
async _assessFit({ sha256Checksum, name, contextTokens }) {
|
|
563
|
-
const sdk = await this._sdk.load();
|
|
564
|
-
const result = await sdk.assessModelFit({
|
|
565
|
-
models: [{ model: { sha256Checksum, name }, workload: { kind: 'llm', contextTokens } }]
|
|
566
|
-
});
|
|
567
|
-
const model = result.models[0];
|
|
568
|
-
return {
|
|
569
|
-
fit: model?.verdict ?? result.verdict,
|
|
570
|
-
fitReasons: [...(model?.reasons ?? result.reasons)]
|
|
571
|
-
};
|
|
422
|
+
return previewModelSource(context, { assessFit: (query) => this._residency.fit.assess(query) });
|
|
572
423
|
}
|
|
573
424
|
async describe() {
|
|
574
425
|
if (!this.opened)
|
|
575
426
|
await this.ready();
|
|
576
427
|
return {
|
|
577
428
|
toolNames: this.toolNames,
|
|
578
|
-
skills: this.
|
|
429
|
+
skills: this._skills.names,
|
|
579
430
|
supportsImages: this.supportsImages,
|
|
580
431
|
supportsKvCacheDeletion: true
|
|
581
432
|
};
|
|
582
433
|
}
|
|
583
434
|
diagnostics() {
|
|
584
435
|
return {
|
|
585
|
-
models: this.opened ? this.
|
|
436
|
+
models: this.opened ? this._residency.loaded() : [],
|
|
586
437
|
suspended: this.suspended,
|
|
587
438
|
sdkLoaded: this._sdk.peek() !== null,
|
|
588
439
|
toolNames: this.toolNames,
|
|
589
|
-
skills: this.
|
|
590
|
-
device: this.
|
|
591
|
-
};
|
|
592
|
-
}
|
|
593
|
-
_loadedModels() {
|
|
594
|
-
return this._pools().flatMap((pool) => loadedModels(pool));
|
|
595
|
-
}
|
|
596
|
-
_loadingModels() {
|
|
597
|
-
return new Set(this._pools().flatMap((pool) => loadingModels(pool)));
|
|
598
|
-
}
|
|
599
|
-
_settledModels() {
|
|
600
|
-
return new Set(this._pools().flatMap((pool) => settledModels(pool)));
|
|
601
|
-
}
|
|
602
|
-
_pools() {
|
|
603
|
-
return [
|
|
604
|
-
this._models,
|
|
605
|
-
this._embedModels,
|
|
606
|
-
...this._retiredEmbedModels,
|
|
607
|
-
this._ttsModels,
|
|
608
|
-
this._transcriptionModels
|
|
609
|
-
];
|
|
610
|
-
}
|
|
611
|
-
_loadPluginSdk(current, store, importPlugin) {
|
|
612
|
-
let pending = current();
|
|
613
|
-
if (!pending) {
|
|
614
|
-
pending = (async () => {
|
|
615
|
-
const sdk = await this._sdk.load();
|
|
616
|
-
const [plugin, { registerPlugin }] = await Promise.all([
|
|
617
|
-
importPlugin(),
|
|
618
|
-
import('@qvac/sdk/plugins')
|
|
619
|
-
]);
|
|
620
|
-
try {
|
|
621
|
-
registerPlugin(plugin);
|
|
622
|
-
}
|
|
623
|
-
catch { }
|
|
624
|
-
return sdk;
|
|
625
|
-
})().catch((err) => {
|
|
626
|
-
store(null);
|
|
627
|
-
throw err;
|
|
628
|
-
});
|
|
629
|
-
store(pending);
|
|
630
|
-
}
|
|
631
|
-
return pending;
|
|
632
|
-
}
|
|
633
|
-
_loadDiffusionSdk() {
|
|
634
|
-
return this._loadPluginSdk(() => this._diffusionSdk, (sdk) => {
|
|
635
|
-
this._diffusionSdk = sdk;
|
|
636
|
-
}, () => import('@qvac/sdk/sdcpp-generation/plugin').then((m) => m.diffusionPlugin));
|
|
637
|
-
}
|
|
638
|
-
async _slmTranslate(model, { text, from, to }, signal) {
|
|
639
|
-
const loadOpts = resolveLoadOptions({}, this._deviceConfig());
|
|
640
|
-
const key = modelKey(model, loadOpts);
|
|
641
|
-
const pool = this._models;
|
|
642
|
-
if (!isResident(pool, key)) {
|
|
643
|
-
await this._makeRoomForCompletion(model, { ctxSize: loadOpts.ctxSize, signal });
|
|
644
|
-
}
|
|
645
|
-
try {
|
|
646
|
-
const { modelId } = await raceAbort(pool.open(key, model, loadOpts).load(), signal);
|
|
647
|
-
const sdk = await this._sdk.load();
|
|
648
|
-
const answer = await raceAbort(sdk.translate({ modelId, text, from, to, stream: false, modelType: 'llm' }).text, signal);
|
|
649
|
-
return cleanAnswer(answer, text);
|
|
650
|
-
}
|
|
651
|
-
finally {
|
|
652
|
-
releaseModel(pool, key);
|
|
653
|
-
}
|
|
654
|
-
}
|
|
655
|
-
_loadTranslationSdk() {
|
|
656
|
-
return this._loadPluginSdk(() => this._translationSdk, (sdk) => {
|
|
657
|
-
this._translationSdk = sdk;
|
|
658
|
-
}, () => import('@qvac/sdk/nmtcpp-translation/plugin').then((m) => m.nmtPlugin));
|
|
659
|
-
}
|
|
660
|
-
_loadMusicSdk() {
|
|
661
|
-
return this._loadPluginSdk(() => this._musicSdk, (sdk) => {
|
|
662
|
-
this._musicSdk = sdk;
|
|
663
|
-
}, () => import('@qvac/sdk/audiogen-ggml/plugin').then((m) => m.audioGenPlugin));
|
|
664
|
-
}
|
|
665
|
-
_deviceConfig() {
|
|
666
|
-
return {
|
|
667
|
-
device: this._llmDevice,
|
|
668
|
-
gpuLayers: this._llmGpuLayers,
|
|
669
|
-
contextSize: this._contextSize,
|
|
670
|
-
kvCacheK: this._kvCacheK,
|
|
671
|
-
kvCacheV: this._kvCacheV,
|
|
672
|
-
mainGpu: resolveMainGpu,
|
|
673
|
-
openclCacheDir
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
_createPool() {
|
|
677
|
-
const loadSdk = () => this._loadModelLifecycleSdk();
|
|
678
|
-
return createModelPool(loadSdk, (state) => this._notifyModel(state), {
|
|
679
|
-
deviceConfig: this._deviceConfig(),
|
|
680
|
-
loads: this._loads,
|
|
681
|
-
onUnloadFailure: (modelId, error) => this._recordModelUnloadFailure(modelId, error)
|
|
682
|
-
});
|
|
683
|
-
}
|
|
684
|
-
_loadModelLifecycleSdk() {
|
|
685
|
-
return this._sdk.load();
|
|
686
|
-
}
|
|
687
|
-
_createEmbedPool() {
|
|
688
|
-
const loadSdk = () => this._sdk.loadEmbed();
|
|
689
|
-
return createEmbedPool(loadSdk, (state) => this._notifyModel(state), {
|
|
690
|
-
faults: this._embedFaults,
|
|
691
|
-
batchSize: this._embedBatchSize,
|
|
692
|
-
openclCacheDir,
|
|
693
|
-
loads: this._loads,
|
|
694
|
-
onUnloadFailure: (modelId, error) => this._recordModelUnloadFailure(modelId, error)
|
|
695
|
-
});
|
|
696
|
-
}
|
|
697
|
-
_createTtsPool() {
|
|
698
|
-
const loadSdk = () => this._sdk.loadVoice();
|
|
699
|
-
return createVoicePool(loadSdk, (state) => this._notifyModel(state), {
|
|
700
|
-
modelType: 'tts-ggml',
|
|
701
|
-
addon: 'tts',
|
|
702
|
-
modelConfig: TTS_MODEL_CONFIG,
|
|
703
|
-
loads: this._loads,
|
|
704
|
-
onUnloadFailure: (modelId, error) => this._recordModelUnloadFailure(modelId, error)
|
|
705
|
-
});
|
|
706
|
-
}
|
|
707
|
-
_createTranscriptionPool() {
|
|
708
|
-
const loadSdk = () => this._sdk.loadVoice();
|
|
709
|
-
return createVoicePool(loadSdk, (state) => this._notifyModel({ ...state, model: TRANSCRIPTION_MODEL_LABEL }), {
|
|
710
|
-
modelType: 'parakeet-transcription',
|
|
711
|
-
addon: 'parakeet',
|
|
712
|
-
modelConfig: { useGPU: this._transcriptionDevice !== 'cpu' },
|
|
713
|
-
openclCacheDir,
|
|
714
|
-
loads: this._loads,
|
|
715
|
-
onUnloadFailure: (modelId, error) => this._recordModelUnloadFailure(modelId, error)
|
|
716
|
-
});
|
|
717
|
-
}
|
|
718
|
-
_recordModelUnloadFailure(modelId, error) {
|
|
719
|
-
this._failedModelUnloads.add(modelId);
|
|
720
|
-
this._poolUnloadFailed = true;
|
|
721
|
-
this._runtimeUnloadFailed = true;
|
|
722
|
-
hlog('model unload failed', { modelId, err: errorMessage(error) });
|
|
723
|
-
}
|
|
724
|
-
_notifyModel(state) {
|
|
725
|
-
if (state.status === 'ready' || state.status === 'unloaded' || state.status === 'error') {
|
|
726
|
-
invalidateModelStatusCache(this._modelStatus);
|
|
727
|
-
}
|
|
728
|
-
if (state.status === 'unloaded') {
|
|
729
|
-
for (const key of this._pinned) {
|
|
730
|
-
if (!isResident(this._models, key)) {
|
|
731
|
-
this._pinned.delete(key);
|
|
732
|
-
}
|
|
733
|
-
}
|
|
734
|
-
}
|
|
735
|
-
this.emit('model', {
|
|
736
|
-
...state,
|
|
737
|
-
catalogChanged: state.catalogChanged === true,
|
|
738
|
-
loaded: this._loadedModels()
|
|
739
|
-
});
|
|
740
|
-
}
|
|
741
|
-
async _collectRetiredEmbedPool(pool) {
|
|
742
|
-
if (!this._retiredEmbedModels.has(pool) || pool.idle !== pool.size)
|
|
743
|
-
return;
|
|
744
|
-
try {
|
|
745
|
-
await pool.destroy();
|
|
746
|
-
}
|
|
747
|
-
catch (error) {
|
|
748
|
-
if (!(error instanceof ModelUnloadError)) {
|
|
749
|
-
this._poolCleanupFailed = true;
|
|
750
|
-
this._poolUnloadFailed = true;
|
|
751
|
-
this._runtimeUnloadFailed = true;
|
|
752
|
-
}
|
|
753
|
-
throw error;
|
|
754
|
-
}
|
|
755
|
-
this._retiredEmbedModels.delete(pool);
|
|
756
|
-
}
|
|
757
|
-
async _releaseEmbedResource(pool, key) {
|
|
758
|
-
releaseModel(pool, key);
|
|
759
|
-
const faulted = this._faultedEmbedKeys.get(pool);
|
|
760
|
-
if (faulted?.has(key)) {
|
|
761
|
-
await evictIdle(pool);
|
|
762
|
-
if (!isResident(pool, key)) {
|
|
763
|
-
faulted.delete(key);
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
await this._collectRetiredEmbedPool(pool);
|
|
767
|
-
}
|
|
768
|
-
async _releaseEmbedResourceBeforeWork(releasing, releaseWork) {
|
|
769
|
-
try {
|
|
770
|
-
await releasing;
|
|
771
|
-
}
|
|
772
|
-
finally {
|
|
773
|
-
releaseWork();
|
|
774
|
-
}
|
|
775
|
-
}
|
|
776
|
-
_markEmbedFault({ pool, key, faults, generation }) {
|
|
777
|
-
faults.recordFault(generation);
|
|
778
|
-
let faulted = this._faultedEmbedKeys.get(pool);
|
|
779
|
-
if (!faulted) {
|
|
780
|
-
faulted = new Set();
|
|
781
|
-
this._faultedEmbedKeys.set(pool, faulted);
|
|
782
|
-
}
|
|
783
|
-
faulted.add(key);
|
|
784
|
-
}
|
|
785
|
-
_releaseEmbedResourceAfter(settled, fault) {
|
|
786
|
-
return settled
|
|
787
|
-
.then(() => this._releaseEmbedResource(fault.pool, fault.key), (error) => {
|
|
788
|
-
if (isSdkGpuDeviceLostError(error)) {
|
|
789
|
-
this._markEmbedFault(fault);
|
|
790
|
-
}
|
|
791
|
-
return this._releaseEmbedResource(fault.pool, fault.key);
|
|
792
|
-
})
|
|
793
|
-
.catch(noop);
|
|
794
|
-
}
|
|
795
|
-
async _destroyEmbedPools() {
|
|
796
|
-
const pools = [this._embedModels, ...this._retiredEmbedModels].filter((pool) => Boolean(pool));
|
|
797
|
-
const outcomes = await Promise.allSettled(pools.map(async (pool) => {
|
|
798
|
-
await pool.destroy();
|
|
799
|
-
this._retiredEmbedModels.delete(pool);
|
|
800
|
-
}));
|
|
801
|
-
const generic = outcomes.find((outcome) => outcome.status === 'rejected' && !(outcome.reason instanceof ModelUnloadError));
|
|
802
|
-
if (generic?.status === 'rejected') {
|
|
803
|
-
throw generic.reason;
|
|
804
|
-
}
|
|
805
|
-
const failed = outcomes.find((outcome) => outcome.status === 'rejected');
|
|
806
|
-
if (failed?.status === 'rejected') {
|
|
807
|
-
throw failed.reason;
|
|
808
|
-
}
|
|
809
|
-
}
|
|
810
|
-
_enqueueEmbedControl(run) {
|
|
811
|
-
const next = this._embedControl.then(run, run);
|
|
812
|
-
this._embedControl = next.catch(noop);
|
|
813
|
-
return next;
|
|
814
|
-
}
|
|
815
|
-
async _runLifecycle(type, { open = true } = {}) {
|
|
816
|
-
if (!this.opened) {
|
|
817
|
-
if (open) {
|
|
818
|
-
await this.ready();
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
|
-
if (this._closeRequested || this.closing) {
|
|
822
|
-
return;
|
|
823
|
-
}
|
|
824
|
-
await this._lifecycle.send(type);
|
|
825
|
-
}
|
|
826
|
-
_abortCompletions() {
|
|
827
|
-
for (const run of this._completionRuns) {
|
|
828
|
-
run.abort();
|
|
829
|
-
}
|
|
830
|
-
}
|
|
831
|
-
_assertNotClosing() {
|
|
832
|
-
if (this._closeRequested || this.closing || this.closed) {
|
|
833
|
-
throw new Error('harness is closing');
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
_enterWork() {
|
|
837
|
-
this._assertNotClosing();
|
|
838
|
-
if (this._runtimeDraining) {
|
|
839
|
-
throw new Error('harness is suspended');
|
|
840
|
-
}
|
|
841
|
-
if (this._runtimeUnloadFailed) {
|
|
842
|
-
throw new Error('Runtime unload failed; close the harness before loading models again');
|
|
843
|
-
}
|
|
844
|
-
this._activeWork++;
|
|
845
|
-
let released = false;
|
|
846
|
-
return () => {
|
|
847
|
-
if (released)
|
|
848
|
-
return;
|
|
849
|
-
released = true;
|
|
850
|
-
if (--this._activeWork !== 0) {
|
|
851
|
-
return;
|
|
852
|
-
}
|
|
853
|
-
for (const resolve of this._workDrainWaiters) {
|
|
854
|
-
resolve();
|
|
855
|
-
}
|
|
856
|
-
this._workDrainWaiters.clear();
|
|
440
|
+
skills: this._skills.names,
|
|
441
|
+
device: this._residency.deviceConfig().device
|
|
857
442
|
};
|
|
858
443
|
}
|
|
859
|
-
_waitForWorkDrain() {
|
|
860
|
-
if (!this._activeWork) {
|
|
861
|
-
return Promise.resolve();
|
|
862
|
-
}
|
|
863
|
-
return new Promise((resolve) => this._workDrainWaiters.add(resolve));
|
|
864
|
-
}
|
|
865
|
-
_effectsSettled() {
|
|
866
|
-
return !this._detachedRuns.size && ![...this._completionRuns].some((run) => run.started);
|
|
867
|
-
}
|
|
868
|
-
_notifyEffectDrain() {
|
|
869
|
-
if (!this._effectsSettled())
|
|
870
|
-
return;
|
|
871
|
-
for (const resolve of this._effectDrainWaiters) {
|
|
872
|
-
resolve();
|
|
873
|
-
}
|
|
874
|
-
this._effectDrainWaiters.clear();
|
|
875
|
-
}
|
|
876
|
-
_waitForEffectDrain() {
|
|
877
|
-
if (this._effectsSettled()) {
|
|
878
|
-
return Promise.resolve();
|
|
879
|
-
}
|
|
880
|
-
return new Promise((resolve) => this._effectDrainWaiters.add(resolve));
|
|
881
|
-
}
|
|
882
|
-
_trackDetachedRun(pending, runId) {
|
|
883
|
-
const tracked = pending.catch((error) => {
|
|
884
|
-
hlog('detached completion effect failed', { runId, err: errorMessage(error) });
|
|
885
|
-
});
|
|
886
|
-
this._detachedRuns.add(tracked);
|
|
887
|
-
void tracked
|
|
888
|
-
.finally(() => {
|
|
889
|
-
this._detachedRuns.delete(tracked);
|
|
890
|
-
this._notifyEffectDrain();
|
|
891
|
-
})
|
|
892
|
-
.catch(noop);
|
|
893
|
-
}
|
|
894
|
-
async _closeCompletions(runs = this._completionRuns) {
|
|
895
|
-
const closed = await Promise.allSettled([...runs].map((run) => run.close()));
|
|
896
|
-
for (const outcome of closed) {
|
|
897
|
-
if (outcome.status === 'rejected') {
|
|
898
|
-
hlog('completion close failed', {
|
|
899
|
-
err: errorMessage(outcome.reason)
|
|
900
|
-
});
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
}
|
|
904
444
|
getEmbeddingDevice() {
|
|
905
|
-
return this.
|
|
445
|
+
return this._embeddings.device;
|
|
906
446
|
}
|
|
907
447
|
setEmbeddingDevice(device) {
|
|
908
|
-
|
|
909
|
-
return this._enqueueEmbedControl(() => this._setEmbeddingDevice(device));
|
|
910
|
-
}
|
|
911
|
-
async _setEmbeddingDevice(device) {
|
|
912
|
-
if (!this.opened)
|
|
913
|
-
await this.ready();
|
|
914
|
-
if (this.suspended) {
|
|
915
|
-
this._assertNotClosing();
|
|
916
|
-
if (this._embedFaults.device === device) {
|
|
917
|
-
return;
|
|
918
|
-
}
|
|
919
|
-
this._embedFaults = createGpuFaultState({ device, gpuLayers: this._embedGpuLayers });
|
|
920
|
-
return;
|
|
921
|
-
}
|
|
922
|
-
const releaseWork = this._enterWork();
|
|
923
|
-
try {
|
|
924
|
-
if (this._embedFaults.device === device) {
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
927
|
-
this._embedFaults = createGpuFaultState({ device, gpuLayers: this._embedGpuLayers });
|
|
928
|
-
if (this.suspended) {
|
|
929
|
-
return;
|
|
930
|
-
}
|
|
931
|
-
const retired = this._embedModels;
|
|
932
|
-
this._retiredEmbedModels.add(retired);
|
|
933
|
-
this._embedModels = this._createEmbedPool();
|
|
934
|
-
await this._collectRetiredEmbedPool(retired);
|
|
935
|
-
}
|
|
936
|
-
finally {
|
|
937
|
-
releaseWork();
|
|
938
|
-
}
|
|
448
|
+
return this._embeddings.setDevice(device);
|
|
939
449
|
}
|
|
940
450
|
async presuspend() {
|
|
941
|
-
await this.
|
|
451
|
+
await this._lifecycle.send('PRESUSPEND', { open: false });
|
|
942
452
|
}
|
|
943
453
|
async suspend() {
|
|
944
|
-
const result = await raceDrain(this.
|
|
454
|
+
const result = await raceDrain(this._lifecycle.send('SUSPEND'), SUSPEND_SETTLE_MS);
|
|
945
455
|
if (didDrainTimeOut(result)) {
|
|
946
456
|
throw new Error('Harness suspend is still waiting for active work to settle');
|
|
947
457
|
}
|
|
948
458
|
}
|
|
949
|
-
async _suspendRuntimes() {
|
|
950
|
-
this._runtimeDraining = true;
|
|
951
|
-
hlog('suspending', { models: loadedModels(this._models).map((entry) => entry.model) });
|
|
952
|
-
this._abortCompletions();
|
|
953
|
-
this._loads.drain();
|
|
954
|
-
await this._closeCompletions([...this._completionRuns].filter((run) => run.started));
|
|
955
|
-
await this._waitForEffectDrain();
|
|
956
|
-
const pending = this._sdk.peek();
|
|
957
|
-
if (pending) {
|
|
958
|
-
const sdk = await pending.catch(noop);
|
|
959
|
-
if (sdk) {
|
|
960
|
-
this._loads.drain(sdk);
|
|
961
|
-
}
|
|
962
|
-
}
|
|
963
|
-
await this._waitForWorkDrain();
|
|
964
|
-
if (!(await this._releaseRuntimes())) {
|
|
965
|
-
throw new Error('Runtime unload failed; close the harness before loading models again');
|
|
966
|
-
}
|
|
967
|
-
invalidateModelStatusCache(this._modelStatus);
|
|
968
|
-
await this._sdkLifecycle('suspend');
|
|
969
|
-
hlog('suspended');
|
|
970
|
-
}
|
|
971
|
-
async _sdkLifecycle(op) {
|
|
972
|
-
const sdk = await this._sdk.peek()?.catch(noop);
|
|
973
|
-
if (!sdk) {
|
|
974
|
-
return;
|
|
975
|
-
}
|
|
976
|
-
try {
|
|
977
|
-
await sdk[op]();
|
|
978
|
-
}
|
|
979
|
-
catch (err) {
|
|
980
|
-
hlog(`sdk ${op} failed`, { err: errorMessage(err) });
|
|
981
|
-
if (op === 'suspend') {
|
|
982
|
-
throw err;
|
|
983
|
-
}
|
|
984
|
-
await sdk.resume().catch((retryErr) => {
|
|
985
|
-
hlog('sdk resume retry failed', {
|
|
986
|
-
err: errorMessage(retryErr)
|
|
987
|
-
});
|
|
988
|
-
throw retryErr;
|
|
989
|
-
});
|
|
990
|
-
}
|
|
991
|
-
}
|
|
992
|
-
async _releaseRuntimes() {
|
|
993
|
-
const released = await Promise.allSettled([
|
|
994
|
-
this._models?.destroy(),
|
|
995
|
-
this._destroyEmbedPools(),
|
|
996
|
-
this._ttsModels?.destroy(),
|
|
997
|
-
this._transcriptionModels?.destroy(),
|
|
998
|
-
this._imageRuntime?.unload(),
|
|
999
|
-
this._musicRuntime?.unload(),
|
|
1000
|
-
this._translationRuntime.unload()
|
|
1001
|
-
]);
|
|
1002
|
-
for (const [index, outcome] of released.entries()) {
|
|
1003
|
-
if (outcome.status !== 'rejected')
|
|
1004
|
-
continue;
|
|
1005
|
-
if (index < 4 && !(outcome.reason instanceof ModelUnloadError)) {
|
|
1006
|
-
this._poolCleanupFailed = true;
|
|
1007
|
-
}
|
|
1008
|
-
const err = outcome.reason;
|
|
1009
|
-
hlog('unload failed', { err: errorMessage(err) });
|
|
1010
|
-
}
|
|
1011
|
-
const sdk = await this._sdk.peek()?.catch(noop);
|
|
1012
|
-
if (sdk) {
|
|
1013
|
-
for (const modelId of this._failedModelUnloads) {
|
|
1014
|
-
try {
|
|
1015
|
-
await sdk.unloadModel({ modelId });
|
|
1016
|
-
this._failedModelUnloads.delete(modelId);
|
|
1017
|
-
invalidateModelStatusCache(this._modelStatus);
|
|
1018
|
-
}
|
|
1019
|
-
catch (error) {
|
|
1020
|
-
hlog('model unload retry failed', {
|
|
1021
|
-
modelId,
|
|
1022
|
-
err: errorMessage(error)
|
|
1023
|
-
});
|
|
1024
|
-
}
|
|
1025
|
-
}
|
|
1026
|
-
}
|
|
1027
|
-
this._poolUnloadFailed = this._poolCleanupFailed || this._failedModelUnloads.size > 0;
|
|
1028
|
-
this._runtimeUnloadFailed =
|
|
1029
|
-
this._poolUnloadFailed || released.slice(4).some((outcome) => outcome.status === 'rejected');
|
|
1030
|
-
return !this._runtimeUnloadFailed;
|
|
1031
|
-
}
|
|
1032
|
-
async _unloadIdleModels() {
|
|
1033
|
-
if (!this.opened || this.closing || this.suspended || this._runtimeDraining) {
|
|
1034
|
-
return;
|
|
1035
|
-
}
|
|
1036
|
-
hlog('idle unload', { models: this._loadedModels().map((entry) => entry.model) });
|
|
1037
|
-
const released = await Promise.allSettled([
|
|
1038
|
-
evictIdle(this._models),
|
|
1039
|
-
evictIdle(this._embedModels),
|
|
1040
|
-
...[...this._retiredEmbedModels].map((pool) => this._collectRetiredEmbedPool(pool)),
|
|
1041
|
-
evictIdle(this._ttsModels),
|
|
1042
|
-
evictIdle(this._transcriptionModels),
|
|
1043
|
-
this._imageRuntime?.unloadIdle(),
|
|
1044
|
-
this._musicRuntime?.unloadIdle(),
|
|
1045
|
-
this._translationRuntime.unload()
|
|
1046
|
-
]);
|
|
1047
|
-
for (const outcome of released) {
|
|
1048
|
-
if (outcome.status !== 'rejected')
|
|
1049
|
-
continue;
|
|
1050
|
-
hlog('idle unload failed', { err: errorMessage(outcome.reason) });
|
|
1051
|
-
}
|
|
1052
|
-
invalidateModelStatusCache(this._modelStatus);
|
|
1053
|
-
}
|
|
1054
459
|
async resume() {
|
|
1055
|
-
await this.
|
|
1056
|
-
}
|
|
1057
|
-
async _resumeRuntimes() {
|
|
1058
|
-
this._assertNotClosing();
|
|
1059
|
-
if (this._runtimeUnloadFailed) {
|
|
1060
|
-
throw new Error('Runtime unload failed; close the harness before loading models again');
|
|
1061
|
-
}
|
|
1062
|
-
hlog('resuming', { pools: 'recreated' });
|
|
1063
|
-
this._loads.undrain();
|
|
1064
|
-
this._models = this._createPool();
|
|
1065
|
-
this._embedModels = this._createEmbedPool();
|
|
1066
|
-
this._ttsModels = this._createTtsPool();
|
|
1067
|
-
this._transcriptionModels = this._createTranscriptionPool();
|
|
1068
|
-
try {
|
|
1069
|
-
await this._sdkLifecycle('resume');
|
|
1070
|
-
this._runtimeDraining = false;
|
|
1071
|
-
}
|
|
1072
|
-
catch (error) {
|
|
1073
|
-
const sdk = await this._sdk.peek()?.catch(noop);
|
|
1074
|
-
if (sdk) {
|
|
1075
|
-
this._loads.drain(sdk);
|
|
1076
|
-
}
|
|
1077
|
-
await this._releaseRuntimes();
|
|
1078
|
-
throw error;
|
|
1079
|
-
}
|
|
460
|
+
await this._lifecycle.send('RESUME');
|
|
1080
461
|
}
|
|
1081
462
|
async wakeup() {
|
|
1082
|
-
await this.
|
|
463
|
+
await this._lifecycle.send('WAKEUP');
|
|
1083
464
|
}
|
|
1084
465
|
ready() {
|
|
1085
|
-
if (this.
|
|
466
|
+
if (this._lifecycle.closeRequested || this.closing || this.closed) {
|
|
1086
467
|
return Promise.reject(new Error('harness is closing'));
|
|
1087
468
|
}
|
|
1088
469
|
return super.ready();
|
|
1089
470
|
}
|
|
1090
471
|
async _close() {
|
|
1091
472
|
hlog('closing');
|
|
1092
|
-
this.
|
|
1093
|
-
this._lifecycle.
|
|
1094
|
-
this._abortCompletions();
|
|
1095
|
-
this._loads.drain();
|
|
1096
|
-
await this._lifecycle.settled();
|
|
1097
|
-
await this._finishClose();
|
|
473
|
+
this._residency.closeIdle();
|
|
474
|
+
await this._lifecycle.close();
|
|
1098
475
|
}
|
|
1099
476
|
close() {
|
|
1100
|
-
this.
|
|
477
|
+
this._lifecycle.requestClose();
|
|
1101
478
|
if (this._closeRetryNeeded) {
|
|
1102
479
|
this.closing = null;
|
|
1103
480
|
this._closeRetryNeeded = false;
|
|
@@ -1120,80 +497,33 @@ export class Harness extends ReadyResource {
|
|
|
1120
497
|
if (this.closing)
|
|
1121
498
|
return this.closing;
|
|
1122
499
|
const opening = this.opening;
|
|
500
|
+
const pluginsClosing = this._teardownPlugins();
|
|
1123
501
|
const pending = (async () => {
|
|
1124
502
|
await opening?.catch(noop);
|
|
1125
|
-
|
|
503
|
+
await pluginsClosing;
|
|
504
|
+
this._lifecycle.abortCompletions();
|
|
1126
505
|
this._loads.drain();
|
|
1127
|
-
await this.
|
|
506
|
+
await this._lifecycle.finishClose();
|
|
1128
507
|
this.closed = true;
|
|
1129
508
|
this.emit('close');
|
|
1130
509
|
})();
|
|
1131
510
|
this.closing = pending;
|
|
1132
511
|
return pending;
|
|
1133
512
|
}
|
|
1134
|
-
async _finishClose() {
|
|
1135
|
-
let completed = false;
|
|
1136
|
-
try {
|
|
1137
|
-
const pending = this._sdk.peek();
|
|
1138
|
-
if (pending) {
|
|
1139
|
-
const sdk = await pending.catch(noop);
|
|
1140
|
-
if (sdk) {
|
|
1141
|
-
this._loads.drain(sdk);
|
|
1142
|
-
}
|
|
1143
|
-
}
|
|
1144
|
-
await this._closeCompletions();
|
|
1145
|
-
await this._waitForEffectDrain();
|
|
1146
|
-
await this._waitForWorkDrain();
|
|
1147
|
-
this._overlayWatcher?.stop();
|
|
1148
|
-
this._overlayWatcher = null;
|
|
1149
|
-
if (!this._runtimesReleased) {
|
|
1150
|
-
let [released] = await Promise.all([this._releaseRuntimes(), closePythonWorker()]);
|
|
1151
|
-
if (!released && !this._poolUnloadFailed) {
|
|
1152
|
-
released = await this._releaseRuntimes();
|
|
1153
|
-
}
|
|
1154
|
-
this._runtimesReleased = released;
|
|
1155
|
-
}
|
|
1156
|
-
let sdkCloseFailed = false;
|
|
1157
|
-
let sdkCloseError;
|
|
1158
|
-
const sdk = !this._sdkClosed && !this._runtimeUnloadFailed ? await this._sdk.peek()?.catch(noop) : null;
|
|
1159
|
-
if (sdk) {
|
|
1160
|
-
try {
|
|
1161
|
-
await sdk.close();
|
|
1162
|
-
this._sdkClosed = true;
|
|
1163
|
-
}
|
|
1164
|
-
catch (error) {
|
|
1165
|
-
sdkCloseFailed = true;
|
|
1166
|
-
sdkCloseError = error;
|
|
1167
|
-
hlog('sdk close failed', { err: errorMessage(error) });
|
|
1168
|
-
}
|
|
1169
|
-
}
|
|
1170
|
-
if (sdkCloseFailed) {
|
|
1171
|
-
throw sdkCloseError;
|
|
1172
|
-
}
|
|
1173
|
-
if (this._runtimeUnloadFailed) {
|
|
1174
|
-
throw new Error('Runtime unload failed; model cleanup could not be confirmed');
|
|
1175
|
-
}
|
|
1176
|
-
completed = true;
|
|
1177
|
-
}
|
|
1178
|
-
finally {
|
|
1179
|
-
if (completed) {
|
|
1180
|
-
this._lifecycle.stop();
|
|
1181
|
-
}
|
|
1182
|
-
}
|
|
1183
|
-
}
|
|
1184
513
|
download(args) {
|
|
1185
|
-
this.
|
|
514
|
+
this._lifecycle.assertNotClosing();
|
|
1186
515
|
let releaseWork = null;
|
|
1187
516
|
const projection = (args.addon ?? 'llm') === 'llm' ? this._projectionFor(args.model) : undefined;
|
|
1188
517
|
const multiFile = diffusionDownloadMetadata(args.model, args.addon) ??
|
|
1189
|
-
audioGenDownloadMetadata(args.model, args.addon)
|
|
518
|
+
audioGenDownloadMetadata(args.model, args.addon) ??
|
|
519
|
+
categoryDownloadMetadata(args.model, args.addon);
|
|
1190
520
|
return download(async () => {
|
|
1191
521
|
if (!this.opened)
|
|
1192
522
|
await this.ready();
|
|
1193
|
-
releaseWork = this.
|
|
523
|
+
releaseWork = this._lifecycle.enterWork();
|
|
1194
524
|
try {
|
|
1195
525
|
const sdk = await this._sdk.load();
|
|
1196
|
-
this.
|
|
526
|
+
this._lifecycle.assertNotClosing();
|
|
1197
527
|
return sdk;
|
|
1198
528
|
}
|
|
1199
529
|
catch (error) {
|
|
@@ -1206,264 +536,100 @@ export class Harness extends ReadyResource {
|
|
|
1206
536
|
projection,
|
|
1207
537
|
companions: multiFile?.companions,
|
|
1208
538
|
assetSizes: multiFile?.assetSizes
|
|
1209
|
-
}, () =>
|
|
539
|
+
}, () => this._residency.invalidateStatus(), () => {
|
|
1210
540
|
releaseWork?.();
|
|
1211
541
|
releaseWork = null;
|
|
1212
542
|
});
|
|
1213
543
|
}
|
|
1214
544
|
embed(context) {
|
|
1215
|
-
return this.
|
|
545
|
+
return this._residency.busy(() => this._embeddings.embed(context));
|
|
1216
546
|
}
|
|
1217
|
-
async
|
|
547
|
+
async _speechService() {
|
|
1218
548
|
if (!this.opened)
|
|
1219
549
|
await this.ready();
|
|
1220
|
-
this.
|
|
1221
|
-
|
|
1222
|
-
throw new Error('harness is suspended');
|
|
1223
|
-
}
|
|
1224
|
-
if (texts.length === 0) {
|
|
1225
|
-
return [];
|
|
1226
|
-
}
|
|
1227
|
-
const pool = this._embedModels;
|
|
1228
|
-
const faults = this._embedFaults;
|
|
1229
|
-
const generation = faults.generation;
|
|
1230
|
-
const key = faults.key(residentSrc(model, 'embeddings'));
|
|
1231
|
-
const releaseWork = this._enterWork();
|
|
1232
|
-
let handle;
|
|
1233
|
-
try {
|
|
1234
|
-
handle = pool.open(key, model);
|
|
1235
|
-
}
|
|
1236
|
-
catch (error) {
|
|
1237
|
-
releaseWork();
|
|
1238
|
-
throw error;
|
|
1239
|
-
}
|
|
1240
|
-
let loaded = null;
|
|
1241
|
-
let job = null;
|
|
1242
|
-
let releaseAfter = null;
|
|
1243
|
-
let drainWorkAfter = null;
|
|
1244
|
-
try {
|
|
1245
|
-
loaded = await raceAbort(handle.load(), signal);
|
|
1246
|
-
const sdk = await this._sdk.loadEmbed();
|
|
1247
|
-
this._assertNotClosing();
|
|
1248
|
-
job = this._embedLane(sdk, { modelId: loaded.modelId, texts });
|
|
1249
|
-
const vectors = await raceAbort(job, signal);
|
|
1250
|
-
faults.reset();
|
|
1251
|
-
return vectors;
|
|
1252
|
-
}
|
|
1253
|
-
catch (err) {
|
|
1254
|
-
if (err instanceof AbortedError) {
|
|
1255
|
-
if (job || this._retiredEmbedModels.has(pool)) {
|
|
1256
|
-
releaseAfter = job ?? handle.peek();
|
|
1257
|
-
}
|
|
1258
|
-
else {
|
|
1259
|
-
drainWorkAfter = handle.peek();
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
if (isSdkGpuDeviceLostError(err)) {
|
|
1263
|
-
this._markEmbedFault({ pool, key, faults, generation });
|
|
1264
|
-
}
|
|
1265
|
-
throw err;
|
|
1266
|
-
}
|
|
1267
|
-
finally {
|
|
1268
|
-
if (releaseAfter) {
|
|
1269
|
-
void this._releaseEmbedResourceAfter(releaseAfter, {
|
|
1270
|
-
pool,
|
|
1271
|
-
key,
|
|
1272
|
-
faults,
|
|
1273
|
-
generation
|
|
1274
|
-
}).finally(releaseWork);
|
|
1275
|
-
}
|
|
1276
|
-
else {
|
|
1277
|
-
const releasing = this._releaseEmbedResource(pool, key);
|
|
1278
|
-
if (drainWorkAfter) {
|
|
1279
|
-
void Promise.allSettled([releasing, drainWorkAfter]).then(releaseWork);
|
|
1280
|
-
}
|
|
1281
|
-
else {
|
|
1282
|
-
await this._releaseEmbedResourceBeforeWork(releasing, releaseWork);
|
|
1283
|
-
}
|
|
1284
|
-
}
|
|
550
|
+
if (!this._plugins.ctx.speech) {
|
|
551
|
+
throw new Error(SPEECH_PLUGIN_MISSING);
|
|
1285
552
|
}
|
|
553
|
+
return this._plugins.ctx.speech;
|
|
1286
554
|
}
|
|
1287
|
-
async
|
|
1288
|
-
if (category !== 'tts') {
|
|
1289
|
-
return defaultVoiceModel(category);
|
|
1290
|
-
}
|
|
1291
|
-
try {
|
|
1292
|
-
const { capabilityProfile } = await this.capability();
|
|
1293
|
-
return defaultTtsFor(capabilityProfile).asset.src;
|
|
1294
|
-
}
|
|
1295
|
-
catch {
|
|
1296
|
-
return defaultVoiceModel('tts');
|
|
1297
|
-
}
|
|
1298
|
-
}
|
|
1299
|
-
async _voiceJob(pool, { category, model, signal }, run) {
|
|
555
|
+
async _knowledgeService() {
|
|
1300
556
|
if (!this.opened)
|
|
1301
557
|
await this.ready();
|
|
1302
|
-
if (this.
|
|
1303
|
-
throw new Error(
|
|
1304
|
-
const addon = category === 'tts' ? 'tts' : 'parakeet';
|
|
1305
|
-
const name = residentSrc(model || (await this._defaultVoiceSrc(category)), addon);
|
|
1306
|
-
this._assertNotClosing();
|
|
1307
|
-
const releaseWork = this._enterWork();
|
|
1308
|
-
let handle;
|
|
1309
|
-
try {
|
|
1310
|
-
handle = pool.open(name, name);
|
|
1311
|
-
}
|
|
1312
|
-
catch (error) {
|
|
1313
|
-
releaseWork();
|
|
1314
|
-
throw error;
|
|
1315
|
-
}
|
|
1316
|
-
let job = null;
|
|
1317
|
-
let releaseAfter = null;
|
|
1318
|
-
let sdk = null;
|
|
1319
|
-
let modelId = null;
|
|
1320
|
-
try {
|
|
1321
|
-
modelId = (await raceAbort(handle.load(), signal)).modelId;
|
|
1322
|
-
sdk = (await this._sdk.loadVoice());
|
|
1323
|
-
this._assertNotClosing();
|
|
1324
|
-
const boundSdk = sdk;
|
|
1325
|
-
const boundId = modelId;
|
|
1326
|
-
job = this._voiceLane(() => run(boundSdk, boundId));
|
|
1327
|
-
return await raceAbort(job, signal);
|
|
1328
|
-
}
|
|
1329
|
-
catch (err) {
|
|
1330
|
-
if (err instanceof AbortedError) {
|
|
1331
|
-
if (sdk && modelId) {
|
|
1332
|
-
void sdk.cancel({ modelId, operation: 'inference' }).catch(noop);
|
|
1333
|
-
}
|
|
1334
|
-
releaseAfter = job ?? handle.peek();
|
|
1335
|
-
}
|
|
1336
|
-
throw err;
|
|
1337
|
-
}
|
|
1338
|
-
finally {
|
|
1339
|
-
const release = () => {
|
|
1340
|
-
releaseModel(pool, name);
|
|
1341
|
-
};
|
|
1342
|
-
if (releaseAfter) {
|
|
1343
|
-
void releaseAfter.then(release, release).finally(releaseWork).catch(noop);
|
|
1344
|
-
}
|
|
1345
|
-
else {
|
|
1346
|
-
try {
|
|
1347
|
-
release();
|
|
1348
|
-
}
|
|
1349
|
-
finally {
|
|
1350
|
-
releaseWork();
|
|
1351
|
-
}
|
|
1352
|
-
}
|
|
558
|
+
if (!this._plugins.ctx.knowledge) {
|
|
559
|
+
throw new Error(KNOWLEDGE_PLUGIN_MISSING);
|
|
1353
560
|
}
|
|
561
|
+
return this._plugins.ctx.knowledge;
|
|
562
|
+
}
|
|
563
|
+
async knowledgeUpsert(artifact) {
|
|
564
|
+
return (await this._knowledgeService()).upsert(artifact);
|
|
565
|
+
}
|
|
566
|
+
async knowledgeRemove(artifactId) {
|
|
567
|
+
return (await this._knowledgeService()).remove(artifactId);
|
|
568
|
+
}
|
|
569
|
+
async knowledgeSearch(query) {
|
|
570
|
+
return (await this._knowledgeService()).search(query);
|
|
571
|
+
}
|
|
572
|
+
async knowledgeStatus() {
|
|
573
|
+
return (await this._knowledgeService()).status();
|
|
1354
574
|
}
|
|
1355
575
|
transcribe(context) {
|
|
1356
|
-
return this.
|
|
576
|
+
return this._residency.busy(() => this._transcribe(context));
|
|
1357
577
|
}
|
|
1358
578
|
async _transcribe({ model, audio, signal }) {
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
if (pcm && pcm.length >= TRANSCRIBE_STREAM_MIN_BYTES) {
|
|
1365
|
-
return transcribeStreaming(sdk, pcm, { modelId: id, signal });
|
|
1366
|
-
}
|
|
1367
|
-
return transcribeOnce(sdk, id, pcm ? buildWavBuffer(pcm) : audio);
|
|
579
|
+
const speech = await this._speechService();
|
|
580
|
+
return speech.transcribe({
|
|
581
|
+
model: model || defaultVoiceModel('transcription'),
|
|
582
|
+
audio,
|
|
583
|
+
signal
|
|
1368
584
|
});
|
|
1369
585
|
}
|
|
1370
586
|
detectLanguage(context) {
|
|
1371
587
|
return detectLanguage(context);
|
|
1372
588
|
}
|
|
1373
589
|
speak(context) {
|
|
1374
|
-
return this.
|
|
590
|
+
return this._residency.busy(() => this._speak(context));
|
|
1375
591
|
}
|
|
1376
592
|
async _speak({ model, text, signal }) {
|
|
1377
|
-
const
|
|
1378
|
-
return {
|
|
593
|
+
const speech = await this._speechService();
|
|
594
|
+
return speech.speak({ model: model || (await this._defaultTts(speech)), text, signal });
|
|
1379
595
|
}
|
|
1380
596
|
speakStream(context) {
|
|
1381
|
-
return this.
|
|
597
|
+
return this._residency.busyStream(() => this._speakStream(context));
|
|
1382
598
|
}
|
|
1383
599
|
async *_speakStream({ model, text, signal }) {
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
const
|
|
1389
|
-
|
|
1390
|
-
const pool = this._ttsModels;
|
|
1391
|
-
const chunks = pushQueue();
|
|
1392
|
-
const releaseWork = this._enterWork();
|
|
1393
|
-
let handle;
|
|
1394
|
-
try {
|
|
1395
|
-
handle = pool.open(name, name);
|
|
1396
|
-
}
|
|
1397
|
-
catch (error) {
|
|
1398
|
-
releaseWork();
|
|
1399
|
-
throw error;
|
|
1400
|
-
}
|
|
1401
|
-
let sdk = null;
|
|
1402
|
-
let modelId = null;
|
|
1403
|
-
const cancel = () => {
|
|
1404
|
-
if (sdk && modelId) {
|
|
1405
|
-
void sdk.cancel({ modelId, operation: 'inference' }).catch(noop);
|
|
1406
|
-
}
|
|
1407
|
-
};
|
|
1408
|
-
signal?.addEventListener('abort', cancel, { once: true });
|
|
1409
|
-
const job = this._voiceLane(async () => {
|
|
1410
|
-
try {
|
|
1411
|
-
modelId = (await handle.load()).modelId;
|
|
1412
|
-
sdk = (await this._sdk.loadVoice());
|
|
1413
|
-
this._assertNotClosing();
|
|
1414
|
-
if (signal?.aborted) {
|
|
1415
|
-
return;
|
|
1416
|
-
}
|
|
1417
|
-
for await (const chunk of speakStreamOnce(sdk, modelId, text)) {
|
|
1418
|
-
chunks.push(chunk);
|
|
1419
|
-
}
|
|
1420
|
-
}
|
|
1421
|
-
finally {
|
|
1422
|
-
chunks.end();
|
|
1423
|
-
}
|
|
1424
|
-
});
|
|
1425
|
-
let settled = false;
|
|
1426
|
-
try {
|
|
1427
|
-
yield* chunks;
|
|
1428
|
-
await job;
|
|
1429
|
-
settled = true;
|
|
1430
|
-
}
|
|
1431
|
-
finally {
|
|
1432
|
-
signal?.removeEventListener('abort', cancel);
|
|
1433
|
-
if (!settled) {
|
|
1434
|
-
cancel();
|
|
1435
|
-
}
|
|
1436
|
-
void job
|
|
1437
|
-
.catch(noop)
|
|
1438
|
-
.finally(() => {
|
|
1439
|
-
try {
|
|
1440
|
-
releaseModel(pool, name);
|
|
1441
|
-
}
|
|
1442
|
-
finally {
|
|
1443
|
-
releaseWork();
|
|
1444
|
-
}
|
|
1445
|
-
})
|
|
1446
|
-
.catch(noop);
|
|
1447
|
-
}
|
|
600
|
+
const speech = await this._speechService();
|
|
601
|
+
yield* speech.speakStream({ model: model || (await this._defaultTts(speech)), text, signal });
|
|
602
|
+
}
|
|
603
|
+
async _defaultTts(speech) {
|
|
604
|
+
const profile = await this.capability().then((capability) => capability.capabilityProfile, () => null);
|
|
605
|
+
return speech.defaultModel(profile);
|
|
1448
606
|
}
|
|
1449
607
|
async list(options = {}) {
|
|
1450
608
|
if (!this.opened)
|
|
1451
609
|
await this.ready();
|
|
1452
|
-
const releaseWork = this.
|
|
610
|
+
const releaseWork = this._lifecycle.enterWork();
|
|
1453
611
|
try {
|
|
1454
612
|
const sdk = await this._sdk.load();
|
|
1455
|
-
this.
|
|
613
|
+
this._lifecycle.assertNotClosing();
|
|
1456
614
|
const rows = await listModels(sdk, options, {
|
|
1457
|
-
cache: this.
|
|
615
|
+
cache: this._residency.status,
|
|
1458
616
|
projectionFor: (name) => this._projectionFor(name)
|
|
1459
617
|
});
|
|
1460
|
-
const loaded = this.
|
|
1461
|
-
const loading = this.
|
|
618
|
+
const loaded = this._residency.settled();
|
|
619
|
+
const loading = this._residency.loading();
|
|
1462
620
|
const custom = await customModelRows(options, { modelsDir: this._modelsDir, loaded });
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
621
|
+
const merged = mergeCustomRows(rows, custom);
|
|
622
|
+
const fits = await this._residency.rowFits(merged);
|
|
623
|
+
return merged.map((row) => {
|
|
624
|
+
const fit = row.isLoaded || loaded.has(row.name) ? undefined : fits.get(row.registryPath);
|
|
625
|
+
return {
|
|
626
|
+
...row,
|
|
627
|
+
isLoading: loading.has(row.name),
|
|
628
|
+
fit: fit?.verdict,
|
|
629
|
+
fitBasis: fit?.basis,
|
|
630
|
+
fitEvidence: fit?.evidence
|
|
631
|
+
};
|
|
632
|
+
});
|
|
1467
633
|
}
|
|
1468
634
|
finally {
|
|
1469
635
|
releaseWork();
|
|
@@ -1472,12 +638,12 @@ export class Harness extends ReadyResource {
|
|
|
1472
638
|
async deleteModel(name) {
|
|
1473
639
|
if (!this.opened)
|
|
1474
640
|
await this.ready();
|
|
1475
|
-
const releaseWork = this.
|
|
641
|
+
const releaseWork = this._lifecycle.enterWork();
|
|
1476
642
|
try {
|
|
1477
643
|
const sdk = await this._sdk.load();
|
|
1478
|
-
this.
|
|
644
|
+
this._lifecycle.assertNotClosing();
|
|
1479
645
|
const result = await deleteModelFiles(sdk, name, { modelsDir: this._modelsDir });
|
|
1480
|
-
|
|
646
|
+
this._residency.invalidateStatus();
|
|
1481
647
|
return summarizeDelete(result);
|
|
1482
648
|
}
|
|
1483
649
|
finally {
|
|
@@ -1487,10 +653,10 @@ export class Harness extends ReadyResource {
|
|
|
1487
653
|
async clearKvCache() {
|
|
1488
654
|
if (!this.opened)
|
|
1489
655
|
await this.ready();
|
|
1490
|
-
const releaseWork = this.
|
|
656
|
+
const releaseWork = this._lifecycle.enterWork();
|
|
1491
657
|
try {
|
|
1492
658
|
return await deleteAllKvCaches(() => {
|
|
1493
|
-
this.
|
|
659
|
+
this._lifecycle.assertNotClosing();
|
|
1494
660
|
return this._sdk.load();
|
|
1495
661
|
});
|
|
1496
662
|
}
|
|
@@ -1501,10 +667,10 @@ export class Harness extends ReadyResource {
|
|
|
1501
667
|
async deleteKvCache(kvCacheKey) {
|
|
1502
668
|
if (!this.opened)
|
|
1503
669
|
await this.ready();
|
|
1504
|
-
const releaseWork = this.
|
|
670
|
+
const releaseWork = this._lifecycle.enterWork();
|
|
1505
671
|
try {
|
|
1506
672
|
return await deleteKvCacheKey(() => {
|
|
1507
|
-
this.
|
|
673
|
+
this._lifecycle.assertNotClosing();
|
|
1508
674
|
return this._sdk.load();
|
|
1509
675
|
}, kvCacheKey);
|
|
1510
676
|
}
|
|
@@ -1518,7 +684,7 @@ export class Harness extends ReadyResource {
|
|
|
1518
684
|
async capability() {
|
|
1519
685
|
if (!this.opened)
|
|
1520
686
|
await this.ready();
|
|
1521
|
-
this.
|
|
687
|
+
this._lifecycle.assertNotClosing();
|
|
1522
688
|
if (this._capability) {
|
|
1523
689
|
return this._capability;
|
|
1524
690
|
}
|
|
@@ -1560,211 +726,25 @@ export class Harness extends ReadyResource {
|
|
|
1560
726
|
return this._capabilityInflight;
|
|
1561
727
|
}
|
|
1562
728
|
warmModel(context) {
|
|
1563
|
-
return this.
|
|
1564
|
-
}
|
|
1565
|
-
async _warmModel({ model, agent, signal }) {
|
|
1566
|
-
if (!this.opened)
|
|
1567
|
-
await this.ready();
|
|
1568
|
-
this._assertNotClosing();
|
|
1569
|
-
if (this.suspended) {
|
|
1570
|
-
return;
|
|
1571
|
-
}
|
|
1572
|
-
const target = this._residency(model, agent);
|
|
1573
|
-
hlog('warm model', { model, resident: isResident(target.pool, target.key) });
|
|
1574
|
-
await this._loadAndRelease(target, signal, async () => {
|
|
1575
|
-
if (target.pool !== this._models || isResident(target.pool, target.key)) {
|
|
1576
|
-
return true;
|
|
1577
|
-
}
|
|
1578
|
-
const roomed = await this._makeRoomForCompletion(model, {
|
|
1579
|
-
ctxSize: target.ctxSize,
|
|
1580
|
-
signal,
|
|
1581
|
-
deadlineMs: WARM_ROOM_WAIT_MS
|
|
1582
|
-
});
|
|
1583
|
-
if (roomed) {
|
|
1584
|
-
await this._unloadIdleGenerators();
|
|
1585
|
-
}
|
|
1586
|
-
return roomed;
|
|
1587
|
-
});
|
|
729
|
+
return this._residency.busy(() => this._residency.warm(context));
|
|
1588
730
|
}
|
|
1589
731
|
loadModel(context) {
|
|
1590
|
-
return this.
|
|
1591
|
-
}
|
|
1592
|
-
async _loadModel({ model, agent, signal }) {
|
|
1593
|
-
if (!this.opened)
|
|
1594
|
-
await this.ready();
|
|
1595
|
-
if (this.suspended) {
|
|
1596
|
-
throw new Error('harness is suspended');
|
|
1597
|
-
}
|
|
1598
|
-
const target = this._residency(model, agent);
|
|
1599
|
-
const resident = isResident(target.pool, target.key);
|
|
1600
|
-
hlog('load model', { model, resident });
|
|
1601
|
-
if (target.pool !== this._models) {
|
|
1602
|
-
await this._loadAndRelease(target, signal);
|
|
1603
|
-
return { loaded: true };
|
|
1604
|
-
}
|
|
1605
|
-
if (!resident) {
|
|
1606
|
-
if (!(await this._fits(model, target.ctxSize))) {
|
|
1607
|
-
return { loaded: false, reason: 'memory' };
|
|
1608
|
-
}
|
|
1609
|
-
await evictIdleWhere(this._models, (key) => modelOf(key) === model && !this._replying.includes(key));
|
|
1610
|
-
await this._unloadIdleGenerators();
|
|
1611
|
-
}
|
|
1612
|
-
this._pinned.add(target.key);
|
|
1613
|
-
try {
|
|
1614
|
-
await this._loadAndRelease(target, signal);
|
|
1615
|
-
}
|
|
1616
|
-
catch (err) {
|
|
1617
|
-
this._pinned.delete(target.key);
|
|
1618
|
-
throw err;
|
|
1619
|
-
}
|
|
1620
|
-
return { loaded: true };
|
|
732
|
+
return this._residency.busy(() => this._residency.load(context));
|
|
1621
733
|
}
|
|
1622
734
|
unloadModel(context) {
|
|
1623
|
-
return this.
|
|
1624
|
-
}
|
|
1625
|
-
async _unloadModel({ model }) {
|
|
1626
|
-
if (!this.opened)
|
|
1627
|
-
await this.ready();
|
|
1628
|
-
const target = this._residency(model);
|
|
1629
|
-
const name = modelOf(target.key);
|
|
1630
|
-
const unloaded = await evictModel(target.pool, name, { deadlineMs: UNLOAD_LEASE_WAIT_MS });
|
|
1631
|
-
hlog('unload model', { model, unloaded });
|
|
1632
|
-
if (unloaded) {
|
|
1633
|
-
for (const key of this._pinned) {
|
|
1634
|
-
if (modelOf(key) === name) {
|
|
1635
|
-
this._pinned.delete(key);
|
|
1636
|
-
}
|
|
1637
|
-
}
|
|
1638
|
-
}
|
|
1639
|
-
return { unloaded };
|
|
1640
|
-
}
|
|
1641
|
-
async _loadAndRelease({ pool, key, open }, signal, prepare = async () => true) {
|
|
1642
|
-
const lease = await this._acquireModelLease({ pool, key, open, signal, prepare });
|
|
1643
|
-
lease?.release();
|
|
1644
|
-
}
|
|
1645
|
-
async _unloadIdleGenerators() {
|
|
1646
|
-
await this._imageRuntime?.unloadIdle().catch(noop);
|
|
1647
|
-
await this._musicRuntime?.unloadIdle().catch(noop);
|
|
1648
|
-
}
|
|
1649
|
-
async _fits(model, ctxSize) {
|
|
1650
|
-
const asset = curatedModelAsset(model, 'llm');
|
|
1651
|
-
if (!asset) {
|
|
1652
|
-
return true;
|
|
1653
|
-
}
|
|
1654
|
-
const assessed = await this._assessFit({
|
|
1655
|
-
sha256Checksum: asset.sha256Checksum,
|
|
1656
|
-
name: asset.name,
|
|
1657
|
-
contextTokens: ctxSize || defaultContextSize(asset)
|
|
1658
|
-
}).catch((err) => {
|
|
1659
|
-
hlog('fit estimate failed', { model, err: errorMessage(err) });
|
|
1660
|
-
return null;
|
|
1661
|
-
});
|
|
1662
|
-
return assessed?.fit !== 'likely-too-large';
|
|
1663
|
-
}
|
|
1664
|
-
async _yieldPins(model, ctxSize) {
|
|
1665
|
-
for (const key of this._pinned) {
|
|
1666
|
-
if (leaseCount(this._models, key) > 0 || this._replying.includes(key)) {
|
|
1667
|
-
continue;
|
|
1668
|
-
}
|
|
1669
|
-
if (await this._fits(model, ctxSize))
|
|
1670
|
-
return;
|
|
1671
|
-
this._pinned.delete(key);
|
|
1672
|
-
await evictModelWithin(this._models, key, { deadlineMs: WEDGED_EVICT_WAIT_MS });
|
|
1673
|
-
}
|
|
1674
|
-
}
|
|
1675
|
-
_residency(model, agent) {
|
|
1676
|
-
const addon = modelAddonOf(model);
|
|
1677
|
-
if (addon === 'llm') {
|
|
1678
|
-
const loadOpts = this._completionLoadOptions(model, agent);
|
|
1679
|
-
const key = modelKey(model, loadOpts);
|
|
1680
|
-
return {
|
|
1681
|
-
pool: this._models,
|
|
1682
|
-
key,
|
|
1683
|
-
ctxSize: loadOpts.ctxSize,
|
|
1684
|
-
open: () => this._models.open(key, model, loadOpts)
|
|
1685
|
-
};
|
|
1686
|
-
}
|
|
1687
|
-
if (addon === 'embeddings') {
|
|
1688
|
-
const key = this._embedFaults.key(residentSrc(model, addon));
|
|
1689
|
-
return { pool: this._embedModels, key, open: () => this._embedModels.open(key, model) };
|
|
1690
|
-
}
|
|
1691
|
-
if (addon === 'tts' || addon === 'parakeet') {
|
|
1692
|
-
const pool = addon === 'tts' ? this._ttsModels : this._transcriptionModels;
|
|
1693
|
-
const key = residentSrc(model, addon);
|
|
1694
|
-
return { pool, key, open: () => pool.open(key, key) };
|
|
1695
|
-
}
|
|
1696
|
-
throw new Error(`${model} loads for each generation and is not kept in memory`);
|
|
1697
|
-
}
|
|
1698
|
-
_completionLoadOptions(model, agent) {
|
|
1699
|
-
return resolveLoadOptions({
|
|
1700
|
-
ctxSize: agent?.ctxSize ?? undefined,
|
|
1701
|
-
kvCacheK: agent?.kvCacheK ?? undefined,
|
|
1702
|
-
kvCacheV: agent?.kvCacheV ?? undefined,
|
|
1703
|
-
projectionModel: this._projectionFor(model)
|
|
1704
|
-
}, this._deviceConfig());
|
|
1705
|
-
}
|
|
1706
|
-
async _acquireModelLease({ pool, key, open, signal, prepare }) {
|
|
1707
|
-
const releaseWork = this._enterWork();
|
|
1708
|
-
let pendingLoad = null;
|
|
1709
|
-
let opened = false;
|
|
1710
|
-
let released = false;
|
|
1711
|
-
const release = () => {
|
|
1712
|
-
if (released) {
|
|
1713
|
-
return;
|
|
1714
|
-
}
|
|
1715
|
-
released = true;
|
|
1716
|
-
try {
|
|
1717
|
-
if (opened) {
|
|
1718
|
-
releaseModel(pool, key);
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
|
-
finally {
|
|
1722
|
-
releaseWork();
|
|
1723
|
-
}
|
|
1724
|
-
};
|
|
1725
|
-
try {
|
|
1726
|
-
if (!(await prepare())) {
|
|
1727
|
-
release();
|
|
1728
|
-
return null;
|
|
1729
|
-
}
|
|
1730
|
-
if (signal?.aborted) {
|
|
1731
|
-
throw new AbortedError();
|
|
1732
|
-
}
|
|
1733
|
-
if (this.suspended || this._runtimeDraining) {
|
|
1734
|
-
throw new Error('harness is suspended');
|
|
1735
|
-
}
|
|
1736
|
-
this._assertNotClosing();
|
|
1737
|
-
if (this._runtimeUnloadFailed) {
|
|
1738
|
-
throw new Error('Runtime unload failed; close the harness before loading models again');
|
|
1739
|
-
}
|
|
1740
|
-
const handle = open();
|
|
1741
|
-
opened = true;
|
|
1742
|
-
const loading = handle.load();
|
|
1743
|
-
pendingLoad = loading;
|
|
1744
|
-
const loaded = await raceAbort(loading, signal);
|
|
1745
|
-
return { modelId: loaded.modelId, release };
|
|
1746
|
-
}
|
|
1747
|
-
catch (error) {
|
|
1748
|
-
if (pendingLoad) {
|
|
1749
|
-
void pendingLoad.then(release, release).catch(noop);
|
|
1750
|
-
}
|
|
1751
|
-
else {
|
|
1752
|
-
release();
|
|
1753
|
-
}
|
|
1754
|
-
throw error;
|
|
1755
|
-
}
|
|
735
|
+
return this._residency.busy(() => this._residency.unload(context));
|
|
1756
736
|
}
|
|
1757
737
|
invoke(context) {
|
|
1758
|
-
return this.
|
|
738
|
+
return this._residency.busyStream(() => this._invoke(context));
|
|
1759
739
|
}
|
|
1760
740
|
async *_invoke({ capability, args, enhance, agent, attach, fetchAttachment, progress, signal }) {
|
|
1761
741
|
if (!this.opened)
|
|
1762
742
|
await this.ready();
|
|
1763
743
|
if (this.suspended) {
|
|
1764
|
-
this.
|
|
744
|
+
this._lifecycle.assertNotClosing();
|
|
1765
745
|
return yield { type: 'aborted' };
|
|
1766
746
|
}
|
|
1767
|
-
const releaseWork = this.
|
|
747
|
+
const releaseWork = this._lifecycle.enterWork();
|
|
1768
748
|
hlog('invoke start', { capability, enhance });
|
|
1769
749
|
try {
|
|
1770
750
|
yield* invoke({
|
|
@@ -1772,7 +752,7 @@ export class Harness extends ReadyResource {
|
|
|
1772
752
|
args,
|
|
1773
753
|
enhance,
|
|
1774
754
|
enhancer: this._residentEnhancer(),
|
|
1775
|
-
tools: [...this._tools, ...this.
|
|
755
|
+
tools: [...this._tools, ...this._capabilities],
|
|
1776
756
|
ctx: {
|
|
1777
757
|
image: imageSettingsFrom(agent),
|
|
1778
758
|
attach,
|
|
@@ -1788,56 +768,65 @@ export class Harness extends ReadyResource {
|
|
|
1788
768
|
}
|
|
1789
769
|
}
|
|
1790
770
|
completion(context) {
|
|
1791
|
-
|
|
1792
|
-
|
|
771
|
+
if (!context.agents) {
|
|
772
|
+
return this._completion(context);
|
|
773
|
+
}
|
|
774
|
+
if (context.boot || context.onStep) {
|
|
775
|
+
throw new TypeError('A run that follows handoffs cannot take boot or onStep; run it over the wire with a HostRunLog');
|
|
776
|
+
}
|
|
777
|
+
return Agent.follow({ completion: (hop) => this._completion(hop) }, { ...context, goal: undefined });
|
|
778
|
+
}
|
|
779
|
+
_completion(context) {
|
|
780
|
+
this._lifecycle.assertNotClosing();
|
|
781
|
+
if (this._lifecycle.draining) {
|
|
1793
782
|
throw new Error('harness is suspended');
|
|
1794
783
|
}
|
|
1795
|
-
if (this.
|
|
784
|
+
if (this._lifecycle.unloadFailed) {
|
|
1796
785
|
throw new Error('Runtime unload failed; close the harness before loading models again');
|
|
1797
786
|
}
|
|
1798
|
-
|
|
1799
|
-
this._completionRuns.delete(run);
|
|
1800
|
-
this._notifyEffectDrain();
|
|
1801
|
-
});
|
|
1802
|
-
const { iterator, run } = tracked;
|
|
1803
|
-
this._completionRuns.add(run);
|
|
1804
|
-
return iterator;
|
|
787
|
+
return this._lifecycle.trackCompletion((signal) => this._residency.busyStream(() => this._runCompletion({ ...context, signal })), context.signal);
|
|
1805
788
|
}
|
|
1806
789
|
async *_runCompletion(request) {
|
|
1807
790
|
if (!this.opened)
|
|
1808
791
|
await this.ready();
|
|
1809
|
-
this.
|
|
1810
|
-
if (this.suspended || this.
|
|
792
|
+
this._lifecycle.assertNotClosing();
|
|
793
|
+
if (this.suspended || this._lifecycle.draining) {
|
|
1811
794
|
yield { type: 'aborted' };
|
|
1812
795
|
return;
|
|
1813
796
|
}
|
|
1814
797
|
const { boot, onStep, hostAppendTimeoutMs, requestDigestKey, ...provided } = request;
|
|
1815
798
|
let modelId = request.model ?? '';
|
|
1816
799
|
let key = null;
|
|
800
|
+
const releasePlugins = await this._plugins.hold(request.parentRunId !== undefined);
|
|
801
|
+
const detached = [];
|
|
1817
802
|
try {
|
|
1818
803
|
const runtime = async (run) => {
|
|
1819
804
|
modelId = run.model ?? run.modelId;
|
|
1820
805
|
const runContext = { ...run, model: run.model ?? run.modelId };
|
|
1821
|
-
const lease = await this.
|
|
806
|
+
const lease = await this._residency.completionRuntime(runContext);
|
|
1822
807
|
if (!key) {
|
|
1823
|
-
this.
|
|
808
|
+
this._residency.reply(lease.key);
|
|
1824
809
|
}
|
|
1825
810
|
key = lease.key;
|
|
1826
|
-
return lease;
|
|
811
|
+
return { ...lease, services: this._plugins.ctx };
|
|
1827
812
|
};
|
|
1828
813
|
const args = { ...provided, lockOwner: this };
|
|
1829
|
-
for await (const event of
|
|
814
|
+
for await (const event of CompletionEngine.run(runtime, args, {
|
|
815
|
+
hooks: this._hooks,
|
|
1830
816
|
boot,
|
|
1831
817
|
onStep,
|
|
1832
818
|
hostAppendTimeoutMs,
|
|
1833
819
|
requestDigestKey,
|
|
1834
820
|
resumeRequest: provided,
|
|
1835
|
-
onDetached: (pending, runId) =>
|
|
821
|
+
onDetached: (pending, runId) => {
|
|
822
|
+
detached.push(pending);
|
|
823
|
+
this._lifecycle.trackDetachedRun(pending, runId);
|
|
824
|
+
}
|
|
1836
825
|
})) {
|
|
1837
826
|
yield event;
|
|
1838
827
|
}
|
|
1839
828
|
if (key) {
|
|
1840
|
-
this.
|
|
829
|
+
this._residency.clearFaults(modelId);
|
|
1841
830
|
}
|
|
1842
831
|
}
|
|
1843
832
|
catch (error) {
|
|
@@ -1846,15 +835,15 @@ export class Harness extends ReadyResource {
|
|
|
1846
835
|
finally {
|
|
1847
836
|
if (key) {
|
|
1848
837
|
hlog('completion end', { model: modelId });
|
|
1849
|
-
this.
|
|
1850
|
-
void this.
|
|
1851
|
-
void this._musicRuntime?.unloadIdle().catch(noop);
|
|
838
|
+
this._residency.replied(key);
|
|
839
|
+
void this._plugins.unloadIdle();
|
|
1852
840
|
}
|
|
841
|
+
void Promise.allSettled(detached).then(releasePlugins);
|
|
1853
842
|
}
|
|
1854
843
|
}
|
|
1855
844
|
async *_completionFailed(err, model, key) {
|
|
1856
|
-
if (err instanceof AbortedError || this.suspended || this.
|
|
1857
|
-
hlog('completion aborted', { model, suspended: this.suspended || this.
|
|
845
|
+
if (err instanceof AbortedError || this.suspended || this._lifecycle.draining) {
|
|
846
|
+
hlog('completion aborted', { model, suspended: this.suspended || this._lifecycle.draining });
|
|
1858
847
|
yield { type: 'aborted' };
|
|
1859
848
|
return;
|
|
1860
849
|
}
|
|
@@ -1862,7 +851,7 @@ export class Harness extends ReadyResource {
|
|
|
1862
851
|
const name = err instanceof Error ? err.name : undefined;
|
|
1863
852
|
hlog('completion failed', { model, ...resolutionDetail(err), err: message });
|
|
1864
853
|
if (key && isSdkModelWedgedError(err)) {
|
|
1865
|
-
const wedged = await this.
|
|
854
|
+
const wedged = await this._residency.evictWedged(model, key);
|
|
1866
855
|
yield completionErrorEvent(wedged.message, name, err);
|
|
1867
856
|
if (wedged.fatal) {
|
|
1868
857
|
process.exit(1);
|
|
@@ -1872,18 +861,9 @@ export class Harness extends ReadyResource {
|
|
|
1872
861
|
yield completionErrorEvent(message, name, err);
|
|
1873
862
|
}
|
|
1874
863
|
}
|
|
1875
|
-
async _completionRuntime(request) {
|
|
1876
|
-
const releaseWork = this._enterWork();
|
|
1877
|
-
try {
|
|
1878
|
-
return await prepareCompletionRuntime(this, request);
|
|
1879
|
-
}
|
|
1880
|
-
finally {
|
|
1881
|
-
releaseWork();
|
|
1882
|
-
}
|
|
1883
|
-
}
|
|
1884
864
|
_residentEnhancer() {
|
|
1885
865
|
return async (prompt, signal) => {
|
|
1886
|
-
const lease = await leaseResidentModel(this.
|
|
866
|
+
const lease = await leaseResidentModel(this._residency.pool, (model) => !this._residency.borrowed(model));
|
|
1887
867
|
if (!lease) {
|
|
1888
868
|
return null;
|
|
1889
869
|
}
|
|
@@ -1904,69 +884,6 @@ export class Harness extends ReadyResource {
|
|
|
1904
884
|
}
|
|
1905
885
|
};
|
|
1906
886
|
}
|
|
1907
|
-
async _makeRoomForCompletion(model, { ctxSize, signal, deadlineMs = MODEL_ROOM_WAIT_MS } = {}) {
|
|
1908
|
-
const roomed = await awaitModelCapacity(this._models, {
|
|
1909
|
-
cap: this._completionModelCap,
|
|
1910
|
-
deadlineMs,
|
|
1911
|
-
signal,
|
|
1912
|
-
evictable: (key) => !this._pinned.has(key) || modelOf(key) === model
|
|
1913
|
-
});
|
|
1914
|
-
if (!roomed) {
|
|
1915
|
-
hlog('model room wait gave up', {
|
|
1916
|
-
cap: this._completionModelCap,
|
|
1917
|
-
loaded: loadedModels(this._models).length
|
|
1918
|
-
});
|
|
1919
|
-
}
|
|
1920
|
-
await this._yieldPins(model, ctxSize);
|
|
1921
|
-
return roomed;
|
|
1922
|
-
}
|
|
1923
|
-
async _evictWedgedModel(model, key) {
|
|
1924
|
-
const faults = (this._modelFaults.get(model) ?? 0) + 1;
|
|
1925
|
-
this._modelFaults.set(model, faults);
|
|
1926
|
-
const leased = leaseCount(this._models, key) > 0;
|
|
1927
|
-
const evicted = leased
|
|
1928
|
-
? false
|
|
1929
|
-
: await evictModelWithin(this._models, key, { deadlineMs: WEDGED_EVICT_WAIT_MS });
|
|
1930
|
-
hlog('wedged model evicted', { model, faults, evicted, leased });
|
|
1931
|
-
if (leased) {
|
|
1932
|
-
this._evictAfterLeases(model, key);
|
|
1933
|
-
}
|
|
1934
|
-
if (!evicted && !leased) {
|
|
1935
|
-
return {
|
|
1936
|
-
message: `${model} is stuck in device memory — restarting the model runtime`,
|
|
1937
|
-
fatal: true
|
|
1938
|
-
};
|
|
1939
|
-
}
|
|
1940
|
-
return {
|
|
1941
|
-
message: faults > 1
|
|
1942
|
-
? `${model} keeps failing during inference on this device — it may need more memory than is available`
|
|
1943
|
-
: `${model} failed during inference and was unloaded — try again`,
|
|
1944
|
-
fatal: false
|
|
1945
|
-
};
|
|
1946
|
-
}
|
|
1947
|
-
_evictAfterLeases(model, key) {
|
|
1948
|
-
void evictModelWithin(this._models, key, { deadlineMs: WEDGED_EVICT_LEASED_MS })
|
|
1949
|
-
.then((evicted) => hlog('wedged model evicted after leases', { model, evicted }))
|
|
1950
|
-
.catch(noop);
|
|
1951
|
-
}
|
|
1952
|
-
async _busy(run) {
|
|
1953
|
-
await this._idle.enter();
|
|
1954
|
-
try {
|
|
1955
|
-
return await run();
|
|
1956
|
-
}
|
|
1957
|
-
finally {
|
|
1958
|
-
this._idle.exit();
|
|
1959
|
-
}
|
|
1960
|
-
}
|
|
1961
|
-
async *_busyStream(run) {
|
|
1962
|
-
await this._idle.enter();
|
|
1963
|
-
try {
|
|
1964
|
-
yield* run();
|
|
1965
|
-
}
|
|
1966
|
-
finally {
|
|
1967
|
-
this._idle.exit();
|
|
1968
|
-
}
|
|
1969
|
-
}
|
|
1970
887
|
}
|
|
1971
888
|
function completionErrorEvent(message, name, error) {
|
|
1972
889
|
const event = { type: 'error', message, ...completionErrorDetails(error) };
|