@qvac/harness 0.1.0 → 0.1.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/dist/harness.bundle +13 -64
- package/dist/prebuilds-manifest.json +0 -8
- package/dist-lib/index.d.ts +240 -0
- package/dist-lib/index.js +1063 -0
- package/dist-lib/lib/audio-transcode-bare.d.ts +2 -0
- package/dist-lib/lib/audio-transcode-bare.js +145 -0
- package/dist-lib/lib/audio-transcode-node.d.ts +2 -0
- package/dist-lib/lib/audio-transcode-node.js +6 -0
- package/dist-lib/lib/capabilities/audio-resample.d.ts +14 -0
- package/dist-lib/lib/capabilities/audio-resample.js +72 -0
- package/dist-lib/lib/capabilities/completion.d.ts +288 -0
- package/dist-lib/lib/capabilities/completion.js +1077 -0
- package/dist-lib/lib/capabilities/download.d.ts +46 -0
- package/dist-lib/lib/capabilities/download.js +124 -0
- package/dist-lib/lib/capabilities/embed.d.ts +20 -0
- package/dist-lib/lib/capabilities/embed.js +13 -0
- package/dist-lib/lib/capabilities/kv-cache.d.ts +13 -0
- package/dist-lib/lib/capabilities/kv-cache.js +21 -0
- package/dist-lib/lib/capabilities/prompt-prefix.d.ts +6 -0
- package/dist-lib/lib/capabilities/prompt-prefix.js +10 -0
- package/dist-lib/lib/capabilities/speech-lexicon.d.ts +5 -0
- package/dist-lib/lib/capabilities/speech-lexicon.js +32 -0
- package/dist-lib/lib/capabilities/speech-text.d.ts +6 -0
- package/dist-lib/lib/capabilities/speech-text.js +79 -0
- package/dist-lib/lib/capabilities/tool-names.d.ts +3 -0
- package/dist-lib/lib/capabilities/tool-names.js +3 -0
- package/dist-lib/lib/capabilities/tool-selection.d.ts +43 -0
- package/dist-lib/lib/capabilities/tool-selection.js +60 -0
- package/dist-lib/lib/capabilities/tool-turns.d.ts +9 -0
- package/dist-lib/lib/capabilities/tool-turns.js +101 -0
- package/dist-lib/lib/capabilities/usage-breakdown.d.ts +27 -0
- package/dist-lib/lib/capabilities/usage-breakdown.js +44 -0
- package/dist-lib/lib/capabilities/vision-history.d.ts +3 -0
- package/dist-lib/lib/capabilities/vision-history.js +21 -0
- package/dist-lib/lib/capabilities/voice.d.ts +78 -0
- package/dist-lib/lib/capabilities/voice.js +189 -0
- package/dist-lib/lib/connect.d.ts +76 -0
- package/dist-lib/lib/connect.js +789 -0
- package/dist-lib/lib/context-window.d.ts +7 -0
- package/dist-lib/lib/context-window.js +90 -0
- package/dist-lib/lib/contract-types.d.ts +210 -0
- package/dist-lib/lib/contract-types.js +1 -0
- package/dist-lib/lib/diagram-repair.d.ts +21 -0
- package/dist-lib/lib/diagram-repair.js +58 -0
- package/dist-lib/lib/dns-lookup.d.ts +1 -0
- package/dist-lib/lib/dns-lookup.js +13 -0
- package/dist-lib/lib/error-fields.d.ts +2 -0
- package/dist-lib/lib/error-fields.js +8 -0
- package/dist-lib/lib/fetch-node.d.ts +1 -0
- package/dist-lib/lib/fetch-node.js +1 -0
- package/dist-lib/lib/hardware/capability-probe.d.ts +9 -0
- package/dist-lib/lib/hardware/capability-probe.js +99 -0
- package/dist-lib/lib/hardware/gpu-classify.d.ts +2 -0
- package/dist-lib/lib/hardware/gpu-classify.js +32 -0
- package/dist-lib/lib/hardware/gpu-probe-addon.d.ts +2 -0
- package/dist-lib/lib/hardware/gpu-probe-addon.js +42 -0
- package/dist-lib/lib/hardware/gpu-stats.bare.d.ts +1 -0
- package/dist-lib/lib/hardware/gpu-stats.bare.js +24 -0
- package/dist-lib/lib/hardware/gpu-stats.stub.d.ts +1 -0
- package/dist-lib/lib/hardware/gpu-stats.stub.js +3 -0
- package/dist-lib/lib/hardware/memory-budget.d.ts +8 -0
- package/dist-lib/lib/hardware/memory-budget.js +1 -0
- package/dist-lib/lib/hardware/parsers.d.ts +7 -0
- package/dist-lib/lib/hardware/parsers.js +41 -0
- package/dist-lib/lib/headers-bare.d.ts +1 -0
- package/dist-lib/lib/headers-bare.js +1 -0
- package/dist-lib/lib/headers-node.d.ts +4 -0
- package/dist-lib/lib/headers-node.js +1 -0
- package/dist-lib/lib/helpers/buffer-burst.d.ts +1 -0
- package/dist-lib/lib/helpers/buffer-burst.js +20 -0
- package/dist-lib/lib/helpers/control-tokens.d.ts +7 -0
- package/dist-lib/lib/helpers/control-tokens.js +32 -0
- package/dist-lib/lib/helpers/join-guard.d.ts +6 -0
- package/dist-lib/lib/helpers/join-guard.js +46 -0
- package/dist-lib/lib/helpers/markup-stream-filter.d.ts +5 -0
- package/dist-lib/lib/helpers/markup-stream-filter.js +75 -0
- package/dist-lib/lib/helpers/race-abort.d.ts +5 -0
- package/dist-lib/lib/helpers/race-abort.js +18 -0
- package/dist-lib/lib/helpers/retry-memo.d.ts +5 -0
- package/dist-lib/lib/helpers/retry-memo.js +12 -0
- package/dist-lib/lib/helpers/run-outcome.d.ts +33 -0
- package/dist-lib/lib/helpers/run-outcome.js +204 -0
- package/dist-lib/lib/helpers/spawn-path.d.ts +5 -0
- package/dist-lib/lib/helpers/spawn-path.js +57 -0
- package/dist-lib/lib/helpers/text-coalescer.d.ts +15 -0
- package/dist-lib/lib/helpers/text-coalescer.js +34 -0
- package/dist-lib/lib/helpers/thinking.d.ts +8 -0
- package/dist-lib/lib/helpers/thinking.js +95 -0
- package/dist-lib/lib/helpers/tool-call-markup.d.ts +20 -0
- package/dist-lib/lib/helpers/tool-call-markup.js +201 -0
- package/dist-lib/lib/helpers/tool-intent.d.ts +7 -0
- package/dist-lib/lib/helpers/tool-intent.js +21 -0
- package/dist-lib/lib/helpers/tool-label.d.ts +8 -0
- package/dist-lib/lib/helpers/tool-label.js +131 -0
- package/dist-lib/lib/hooks/built-in/arg-repair.d.ts +5 -0
- package/dist-lib/lib/hooks/built-in/arg-repair.js +88 -0
- package/dist-lib/lib/hooks/built-in/egress.d.ts +5 -0
- package/dist-lib/lib/hooks/built-in/egress.js +29 -0
- package/dist-lib/lib/hooks/built-in/index.d.ts +3 -0
- package/dist-lib/lib/hooks/built-in/index.js +3 -0
- package/dist-lib/lib/hooks/built-in/skill-catalog.d.ts +10 -0
- package/dist-lib/lib/hooks/built-in/skill-catalog.js +17 -0
- package/dist-lib/lib/hooks/pipeline.d.ts +20 -0
- package/dist-lib/lib/hooks/pipeline.js +49 -0
- package/dist-lib/lib/hooks/registry.d.ts +2 -0
- package/dist-lib/lib/hooks/registry.js +6 -0
- package/dist-lib/lib/hooks/run.d.ts +5 -0
- package/dist-lib/lib/hooks/run.js +83 -0
- package/dist-lib/lib/hooks/types.d.ts +57 -0
- package/dist-lib/lib/hooks/types.js +1 -0
- package/dist-lib/lib/log.d.ts +5 -0
- package/dist-lib/lib/log.js +37 -0
- package/dist-lib/lib/model-download-progress.d.ts +22 -0
- package/dist-lib/lib/model-download-progress.js +95 -0
- package/dist-lib/lib/models/context.d.ts +5 -0
- package/dist-lib/lib/models/context.js +12 -0
- package/dist-lib/lib/models/embed-config.d.ts +14 -0
- package/dist-lib/lib/models/embed-config.js +31 -0
- package/dist-lib/lib/models/gpu-selection.d.ts +3 -0
- package/dist-lib/lib/models/gpu-selection.js +26 -0
- package/dist-lib/lib/models/kv-cache.d.ts +4 -0
- package/dist-lib/lib/models/kv-cache.js +6 -0
- package/dist-lib/lib/models/llm-presets.d.ts +10 -0
- package/dist-lib/lib/models/llm-presets.js +58 -0
- package/dist-lib/lib/models/model-catalog-constants.d.ts +29 -0
- package/dist-lib/lib/models/model-catalog-constants.js +103 -0
- package/dist-lib/lib/models/model-catalog.d.ts +125 -0
- package/dist-lib/lib/models/model-catalog.js +371 -0
- package/dist-lib/lib/models/model-delete.d.ts +18 -0
- package/dist-lib/lib/models/model-delete.js +47 -0
- package/dist-lib/lib/models/model-handle.d.ts +18 -0
- package/dist-lib/lib/models/model-handle.js +33 -0
- package/dist-lib/lib/models/model-list.d.ts +42 -0
- package/dist-lib/lib/models/model-list.js +123 -0
- package/dist-lib/lib/models/model-pool.d.ts +116 -0
- package/dist-lib/lib/models/model-pool.js +356 -0
- package/dist-lib/lib/models/model-source.d.ts +6 -0
- package/dist-lib/lib/models/model-source.js +21 -0
- package/dist-lib/lib/models/music-catalog.d.ts +12 -0
- package/dist-lib/lib/models/music-catalog.js +26 -0
- package/dist-lib/lib/models/opencl-cache.d.ts +5 -0
- package/dist-lib/lib/models/opencl-cache.js +50 -0
- package/dist-lib/lib/models/sdk-faults.d.ts +21 -0
- package/dist-lib/lib/models/sdk-faults.js +66 -0
- package/dist-lib/lib/models/tool-dialect.d.ts +2 -0
- package/dist-lib/lib/models/tool-dialect.js +19 -0
- package/dist-lib/lib/models/tts-model-default.d.ts +3 -0
- package/dist-lib/lib/models/tts-model-default.js +13 -0
- package/dist-lib/lib/no-redirect-fetch-bare.d.ts +15 -0
- package/dist-lib/lib/no-redirect-fetch-bare.js +59 -0
- package/dist-lib/lib/no-redirect-fetch-impl.d.ts +39 -0
- package/dist-lib/lib/no-redirect-fetch-impl.js +80 -0
- package/dist-lib/lib/no-redirect-fetch-node.d.ts +4 -0
- package/dist-lib/lib/no-redirect-fetch-node.js +52 -0
- package/dist-lib/lib/prompt.d.ts +22 -0
- package/dist-lib/lib/prompt.js +77 -0
- package/dist-lib/lib/queue.d.ts +9 -0
- package/dist-lib/lib/queue.js +48 -0
- package/dist-lib/lib/resolution-detector.d.ts +5 -0
- package/dist-lib/lib/resolution-detector.js +100 -0
- package/dist-lib/lib/rpc-session.d.ts +8 -0
- package/dist-lib/lib/rpc-session.js +20 -0
- package/dist-lib/lib/sdk-config-loader.bare.d.ts +1 -0
- package/dist-lib/lib/sdk-config-loader.bare.js +9 -0
- package/dist-lib/lib/sdk-config-loader.node.d.ts +1 -0
- package/dist-lib/lib/sdk-config-loader.node.js +1 -0
- package/dist-lib/lib/sdk-loader.d.ts +30 -0
- package/dist-lib/lib/sdk-loader.js +53 -0
- package/dist-lib/lib/sdk-storage.d.ts +8 -0
- package/dist-lib/lib/sdk-storage.js +24 -0
- package/dist-lib/lib/serve.d.ts +3 -0
- package/dist-lib/lib/serve.js +612 -0
- package/dist-lib/lib/spawn.d.ts +62 -0
- package/dist-lib/lib/spawn.js +71 -0
- package/dist-lib/lib/staging.d.ts +4 -0
- package/dist-lib/lib/staging.js +28 -0
- package/dist-lib/lib/storage.d.ts +18 -0
- package/dist-lib/lib/storage.js +26 -0
- package/dist-lib/lib/tmp-path.d.ts +7 -0
- package/dist-lib/lib/tmp-path.js +17 -0
- package/dist-lib/lib/tool-call-display.d.ts +21 -0
- package/dist-lib/lib/tool-call-display.js +1 -0
- package/dist-lib/lib/tools/catalog.d.ts +13 -0
- package/dist-lib/lib/tools/catalog.js +13 -0
- package/dist-lib/lib/tools/create-documents.d.ts +3 -0
- package/dist-lib/lib/tools/create-documents.js +87 -0
- package/dist-lib/lib/tools/edit-documents.d.ts +3 -0
- package/dist-lib/lib/tools/edit-documents.js +122 -0
- package/dist-lib/lib/tools/edit-image.d.ts +25 -0
- package/dist-lib/lib/tools/edit-image.js +271 -0
- package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +27 -0
- package/dist-lib/lib/tools/exec/adapters/adapter.js +1 -0
- package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +26 -0
- package/dist-lib/lib/tools/exec/adapters/python/attachments.js +160 -0
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +7 -0
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +290 -0
- package/dist-lib/lib/tools/exec/adapters/python/loader.d.ts +11 -0
- package/dist-lib/lib/tools/exec/adapters/python/loader.js +94 -0
- package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +47 -0
- package/dist-lib/lib/tools/exec/adapters/python/memfs.js +85 -0
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +13 -0
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +129 -0
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +19 -0
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +107 -0
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +75 -0
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +1094 -0
- package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +75 -0
- package/dist-lib/lib/tools/exec/adapters/python/run-session.js +273 -0
- package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +38 -0
- package/dist-lib/lib/tools/exec/adapters/python/wheels.js +102 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +7 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +188 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.d.ts +1 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +105 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +38 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +41 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.d.ts +2 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.js +30 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +13 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +45 -0
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +12 -0
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +20 -0
- package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +8 -0
- package/dist-lib/lib/tools/exec/obsidian/cli-process.js +74 -0
- package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +18 -0
- package/dist-lib/lib/tools/exec/obsidian/cli.js +153 -0
- package/dist-lib/lib/tools/exec/obsidian/command.d.ts +5 -0
- package/dist-lib/lib/tools/exec/obsidian/command.js +18 -0
- package/dist-lib/lib/tools/exec/obsidian/guidance.d.ts +5 -0
- package/dist-lib/lib/tools/exec/obsidian/guidance.js +18 -0
- package/dist-lib/lib/tools/exec/obsidian/note-name.d.ts +1 -0
- package/dist-lib/lib/tools/exec/obsidian/note-name.js +6 -0
- package/dist-lib/lib/tools/exec/obsidian/output.d.ts +1 -0
- package/dist-lib/lib/tools/exec/obsidian/output.js +31 -0
- package/dist-lib/lib/tools/exec/obsidian/route.d.ts +19 -0
- package/dist-lib/lib/tools/exec/obsidian/route.js +85 -0
- package/dist-lib/lib/tools/exec/obsidian/safe-path.d.ts +3 -0
- package/dist-lib/lib/tools/exec/obsidian/safe-path.js +56 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-create.d.ts +1 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-create.js +40 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-fs.d.ts +3 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-fs.js +57 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +20 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +171 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-read.d.ts +11 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-read.js +119 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-write.d.ts +7 -0
- package/dist-lib/lib/tools/exec/obsidian/vault-write.js +134 -0
- package/dist-lib/lib/tools/exec/runner.d.ts +62 -0
- package/dist-lib/lib/tools/exec/runner.js +87 -0
- package/dist-lib/lib/tools/exec/scope.d.ts +3 -0
- package/dist-lib/lib/tools/exec/scope.js +97 -0
- package/dist-lib/lib/tools/exec/shell-argv.d.ts +2 -0
- package/dist-lib/lib/tools/exec/shell-argv.js +48 -0
- package/dist-lib/lib/tools/exec.d.ts +29 -0
- package/dist-lib/lib/tools/exec.js +459 -0
- package/dist-lib/lib/tools/file-glob.d.ts +15 -0
- package/dist-lib/lib/tools/file-glob.js +112 -0
- package/dist-lib/lib/tools/fs/drive.d.ts +26 -0
- package/dist-lib/lib/tools/fs/drive.js +1 -0
- package/dist-lib/lib/tools/fs/glob.d.ts +1 -0
- package/dist-lib/lib/tools/fs/glob.js +34 -0
- package/dist-lib/lib/tools/fs/local.d.ts +2 -0
- package/dist-lib/lib/tools/fs/local.js +29 -0
- package/dist-lib/lib/tools/fs/read.d.ts +2 -0
- package/dist-lib/lib/tools/fs/read.js +17 -0
- package/dist-lib/lib/tools/fs/remote-protocol.d.ts +40 -0
- package/dist-lib/lib/tools/fs/remote-protocol.js +1 -0
- package/dist-lib/lib/tools/fs/remote.d.ts +17 -0
- package/dist-lib/lib/tools/fs/remote.js +131 -0
- package/dist-lib/lib/tools/fs/scope.d.ts +37 -0
- package/dist-lib/lib/tools/fs/scope.js +130 -0
- package/dist-lib/lib/tools/fs/walk.d.ts +15 -0
- package/dist-lib/lib/tools/fs/walk.js +38 -0
- package/dist-lib/lib/tools/fs/write.d.ts +4 -0
- package/dist-lib/lib/tools/fs/write.js +5 -0
- package/dist-lib/lib/tools/generate-image.d.ts +111 -0
- package/dist-lib/lib/tools/generate-image.js +369 -0
- package/dist-lib/lib/tools/generate-music.d.ts +124 -0
- package/dist-lib/lib/tools/generate-music.js +522 -0
- package/dist-lib/lib/tools/grep.d.ts +5 -0
- package/dist-lib/lib/tools/grep.js +158 -0
- package/dist-lib/lib/tools/http-methods.d.ts +1 -0
- package/dist-lib/lib/tools/http-methods.js +1 -0
- package/dist-lib/lib/tools/http-request/encode-fields.d.ts +2 -0
- package/dist-lib/lib/tools/http-request/encode-fields.js +69 -0
- package/dist-lib/lib/tools/http-request/truncate-response.d.ts +1 -0
- package/dist-lib/lib/tools/http-request/truncate-response.js +83 -0
- package/dist-lib/lib/tools/http-request/utils.d.ts +27 -0
- package/dist-lib/lib/tools/http-request/utils.js +84 -0
- package/dist-lib/lib/tools/http-request.d.ts +20 -0
- package/dist-lib/lib/tools/http-request.js +177 -0
- package/dist-lib/lib/tools/mcp/utils.d.ts +47 -0
- package/dist-lib/lib/tools/mcp/utils.js +172 -0
- package/dist-lib/lib/tools/mcp-call.d.ts +14 -0
- package/dist-lib/lib/tools/mcp-call.js +155 -0
- package/dist-lib/lib/tools/model-args.d.ts +1 -0
- package/dist-lib/lib/tools/model-args.js +4 -0
- package/dist-lib/lib/tools/operations/builders.d.ts +17 -0
- package/dist-lib/lib/tools/operations/builders.js +179 -0
- package/dist-lib/lib/tools/operations/compile.d.ts +7 -0
- package/dist-lib/lib/tools/operations/compile.js +92 -0
- package/dist-lib/lib/tools/operations/gmail-message.d.ts +15 -0
- package/dist-lib/lib/tools/operations/gmail-message.js +62 -0
- package/dist-lib/lib/tools/operations/manifest.d.ts +60 -0
- package/dist-lib/lib/tools/operations/manifest.js +50 -0
- package/dist-lib/lib/tools/outbound-guard.d.ts +10 -0
- package/dist-lib/lib/tools/outbound-guard.js +127 -0
- package/dist-lib/lib/tools/private-ip.d.ts +4 -0
- package/dist-lib/lib/tools/private-ip.js +126 -0
- package/dist-lib/lib/tools/rag-search.d.ts +2 -0
- package/dist-lib/lib/tools/rag-search.js +98 -0
- package/dist-lib/lib/tools/read-files.d.ts +5 -0
- package/dist-lib/lib/tools/read-files.js +153 -0
- package/dist-lib/lib/tools/skill.d.ts +10 -0
- package/dist-lib/lib/tools/skill.js +123 -0
- package/dist-lib/lib/tools/skills/auth-resolver.d.ts +43 -0
- package/dist-lib/lib/tools/skills/auth-resolver.js +121 -0
- package/dist-lib/lib/tools/skills/bin-check.d.ts +9 -0
- package/dist-lib/lib/tools/skills/bin-check.js +56 -0
- package/dist-lib/lib/tools/skills/bundled-dir.d.ts +2 -0
- package/dist-lib/lib/tools/skills/bundled-dir.js +117 -0
- package/dist-lib/lib/tools/skills/bundled-hash.d.ts +4 -0
- package/dist-lib/lib/tools/skills/bundled-hash.js +12 -0
- package/dist-lib/lib/tools/skills/catalog.d.ts +60 -0
- package/dist-lib/lib/tools/skills/catalog.js +203 -0
- package/dist-lib/lib/tools/skills/cli-argv.d.ts +9 -0
- package/dist-lib/lib/tools/skills/cli-argv.js +147 -0
- package/dist-lib/lib/tools/skills/cli-schema-check.d.ts +3 -0
- package/dist-lib/lib/tools/skills/cli-schema-check.js +62 -0
- package/dist-lib/lib/tools/skills/cli-schema-load.d.ts +4 -0
- package/dist-lib/lib/tools/skills/cli-schema-load.js +90 -0
- package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +30 -0
- package/dist-lib/lib/tools/skills/cli-schema-types.js +1 -0
- package/dist-lib/lib/tools/skills/cli-schema.d.ts +7 -0
- package/dist-lib/lib/tools/skills/cli-schema.js +35 -0
- package/dist-lib/lib/tools/skills/credential-check.d.ts +20 -0
- package/dist-lib/lib/tools/skills/credential-check.js +94 -0
- package/dist-lib/lib/tools/skills/credential-grants.d.ts +9 -0
- package/dist-lib/lib/tools/skills/credential-grants.js +25 -0
- package/dist-lib/lib/tools/skills/credential-health.d.ts +8 -0
- package/dist-lib/lib/tools/skills/credential-health.js +51 -0
- package/dist-lib/lib/tools/skills/credential-slots.d.ts +7 -0
- package/dist-lib/lib/tools/skills/credential-slots.js +8 -0
- package/dist-lib/lib/tools/skills/frontmatter-parser.d.ts +23 -0
- package/dist-lib/lib/tools/skills/frontmatter-parser.js +68 -0
- package/dist-lib/lib/tools/skills/index.d.ts +5 -0
- package/dist-lib/lib/tools/skills/index.js +5 -0
- package/dist-lib/lib/tools/skills/manifest-parse.d.ts +12 -0
- package/dist-lib/lib/tools/skills/manifest-parse.js +199 -0
- package/dist-lib/lib/tools/skills/manifest.d.ts +47 -0
- package/dist-lib/lib/tools/skills/manifest.js +1 -0
- package/dist-lib/lib/tools/skills/mention-name.d.ts +1 -0
- package/dist-lib/lib/tools/skills/mention-name.js +4 -0
- package/dist-lib/lib/tools/skills/mention.d.ts +6 -0
- package/dist-lib/lib/tools/skills/mention.js +42 -0
- package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +16 -0
- package/dist-lib/lib/tools/skills/obsidian-readiness.js +95 -0
- package/dist-lib/lib/tools/skills/overlay-crud.d.ts +18 -0
- package/dist-lib/lib/tools/skills/overlay-crud.js +98 -0
- package/dist-lib/lib/tools/skills/overlay-dir.d.ts +2 -0
- package/dist-lib/lib/tools/skills/overlay-dir.js +22 -0
- package/dist-lib/lib/tools/skills/overlay-watch.d.ts +13 -0
- package/dist-lib/lib/tools/skills/overlay-watch.js +44 -0
- package/dist-lib/lib/tools/skills/scope-key.d.ts +7 -0
- package/dist-lib/lib/tools/skills/scope-key.js +7 -0
- package/dist-lib/lib/tools/skills/setup-routes.d.ts +4 -0
- package/dist-lib/lib/tools/skills/setup-routes.js +14 -0
- package/dist-lib/lib/tools/skills/skill-settings.d.ts +16 -0
- package/dist-lib/lib/tools/skills/skill-settings.js +33 -0
- package/dist-lib/lib/tools/skills/skill-state-constants.d.ts +12 -0
- package/dist-lib/lib/tools/skills/skill-state-constants.js +14 -0
- package/dist-lib/lib/tools/skills/skill-state.d.ts +40 -0
- package/dist-lib/lib/tools/skills/skill-state.js +117 -0
- package/dist-lib/lib/tools/skills/tool-grants.d.ts +5 -0
- package/dist-lib/lib/tools/skills/tool-grants.js +14 -0
- package/dist-lib/lib/tools/toolsets.d.ts +8 -0
- package/dist-lib/lib/tools/toolsets.js +20 -0
- package/dist-lib/lib/tools/url-guard.d.ts +8 -0
- package/dist-lib/lib/tools/url-guard.js +40 -0
- package/dist-lib/lib/tools/web-fetch.d.ts +8 -0
- package/dist-lib/lib/tools/web-fetch.js +302 -0
- package/dist-lib/lib/tools/web-search.d.ts +6 -0
- package/dist-lib/lib/tools/web-search.js +55 -0
- package/dist-lib/lib/transport.d.ts +12 -0
- package/dist-lib/lib/transport.js +59 -0
- package/dist-lib/lib/user-agent.d.ts +1 -0
- package/dist-lib/lib/user-agent.js +1 -0
- package/dist-lib/lib/validating-lookup.d.ts +17 -0
- package/dist-lib/lib/validating-lookup.js +25 -0
- package/dist-lib/lib/wav-encode.d.ts +5 -0
- package/dist-lib/lib/wav-encode.js +24 -0
- package/dist-lib/lib/web-fetch/embedded-state.d.ts +1 -0
- package/dist-lib/lib/web-fetch/embedded-state.js +131 -0
- package/dist-lib/lib/web-fetch/extract.d.ts +6 -0
- package/dist-lib/lib/web-fetch/extract.js +65 -0
- package/dist-lib/lib/web-fetch/images.d.ts +3 -0
- package/dist-lib/lib/web-fetch/images.js +43 -0
- package/dist-lib/lib/web-fetch/video.d.ts +5 -0
- package/dist-lib/lib/web-fetch/video.js +42 -0
- package/dist-lib/lib/web-search/engine-registry.d.ts +7 -0
- package/dist-lib/lib/web-search/engine-registry.js +17 -0
- package/dist-lib/lib/web-search/engines/aol.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/aol.js +81 -0
- package/dist-lib/lib/web-search/engines/bing.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/bing.js +111 -0
- package/dist-lib/lib/web-search/engines/brave.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/brave.js +59 -0
- package/dist-lib/lib/web-search/engines/duckduckgo.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/duckduckgo.js +112 -0
- package/dist-lib/lib/web-search/engines/google.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/google.js +92 -0
- package/dist-lib/lib/web-search/engines/wikipedia.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/wikipedia.js +37 -0
- package/dist-lib/lib/web-search/engines/yahoo.d.ts +3 -0
- package/dist-lib/lib/web-search/engines/yahoo.js +81 -0
- package/dist-lib/lib/web-search/fetch-html.d.ts +25 -0
- package/dist-lib/lib/web-search/fetch-html.js +97 -0
- package/dist-lib/lib/web-search/format-results.d.ts +3 -0
- package/dist-lib/lib/web-search/format-results.js +14 -0
- package/dist-lib/lib/web-search/html-helpers.d.ts +3 -0
- package/dist-lib/lib/web-search/html-helpers.js +24 -0
- package/dist-lib/lib/web-search/merge-results.d.ts +2 -0
- package/dist-lib/lib/web-search/merge-results.js +53 -0
- package/dist-lib/lib/web-search/orchestrator.d.ts +14 -0
- package/dist-lib/lib/web-search/orchestrator.js +50 -0
- package/dist-lib/lib/web-search/types.d.ts +34 -0
- package/dist-lib/lib/web-search/types.js +1 -0
- package/dist-lib/lib/web-search/url-helpers.d.ts +1 -0
- package/dist-lib/lib/web-search/url-helpers.js +11 -0
- package/dist-lib/lib/web-search/url-normalize.d.ts +1 -0
- package/dist-lib/lib/web-search/url-normalize.js +25 -0
- package/dist-lib/lib/web-search/user-agents.d.ts +3 -0
- package/dist-lib/lib/web-search/user-agents.js +3 -0
- package/dist-lib/lib/wire.d.ts +50 -0
- package/dist-lib/lib/wire.js +145 -0
- package/dist-lib/schema/baseline.d.ts +8 -0
- package/dist-lib/schema/baseline.js +35 -0
- package/dist-lib/schema/build.d.ts +1 -0
- package/dist-lib/schema/build.js +39 -0
- package/dist-lib/schema/generate.d.ts +20 -0
- package/dist-lib/schema/generate.js +149 -0
- package/dist-lib/schema/harness.d.ts +2 -0
- package/dist-lib/schema/harness.js +745 -0
- package/dist-lib/schema/release-tags.d.ts +5 -0
- package/dist-lib/schema/release-tags.js +58 -0
- package/dist-lib/spec/bind.d.ts +2 -0
- package/dist-lib/spec/bind.js +124 -0
- package/dist-lib/spec/calls.d.ts +3 -0
- package/dist-lib/spec/calls.js +41 -0
- package/dist-lib/spec/hrpc/hrpc.json +356 -0
- package/dist-lib/spec/hrpc/index.d.ts +3 -0
- package/dist-lib/spec/hrpc/index.js +463 -0
- package/dist-lib/spec/hrpc/messages.d.ts +4 -0
- package/dist-lib/spec/hrpc/messages.js +3102 -0
- package/dist-lib/spec/hyperschema/index.js +3102 -0
- package/dist-lib/spec/hyperschema/schema.json +2290 -0
- package/dist-lib/spec/hyperschema/types.d.ts +554 -0
- package/dist-lib/spec/index.d.ts +8 -0
- package/dist-lib/spec/index.js +1 -0
- package/package.json +239 -64
- package/.gitattributes +0 -1
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { AbortedError } from "../helpers/race-abort.js";
|
|
4
|
+
import { BUSY_ERROR, DIM_STEP, effectiveSteps, generationPercentTick, IMAGE_LOAD_STALL_ERROR, normalizeClamps, parseCommonArgs, runDiffusion } from "./generate-image.js";
|
|
5
|
+
const DEFAULT_STRENGTH = 0.7;
|
|
6
|
+
const FLUX2_GUIDANCE = 3.5;
|
|
7
|
+
const FLUX2_CFG_SCALE = 1;
|
|
8
|
+
const MULTI_SOURCE_UNSUPPORTED = 'this image model edits one image at a time — fusing multiple sources needs an in-context editing model (FLUX.2 today)';
|
|
9
|
+
const IMAGE_REF_TOKEN_PATTERN = /@image\d+/i;
|
|
10
|
+
async function turnSources(turnImages) {
|
|
11
|
+
const sources = [];
|
|
12
|
+
for (const image of turnImages) {
|
|
13
|
+
const bytes = await fs.promises.readFile(image.path).catch(toNull);
|
|
14
|
+
if (!bytes)
|
|
15
|
+
return { error: `could not read attached image ${path.basename(image.path)}` };
|
|
16
|
+
sources.push({ bytes, fileName: path.basename(image.path) });
|
|
17
|
+
}
|
|
18
|
+
return sources;
|
|
19
|
+
}
|
|
20
|
+
async function resolveSources(fetchAttachment, ids, turnImages, signal) {
|
|
21
|
+
if (!ids.length) {
|
|
22
|
+
if (turnImages.length) {
|
|
23
|
+
const sources = await turnSources(turnImages);
|
|
24
|
+
return 'error' in sources ? sources : { sources };
|
|
25
|
+
}
|
|
26
|
+
const latest = await fetchAttachment({ signal });
|
|
27
|
+
if (!latest || !('bytes' in latest) || !latest.bytes) {
|
|
28
|
+
return { error: 'no image in this chat to edit' };
|
|
29
|
+
}
|
|
30
|
+
return { sources: [latest] };
|
|
31
|
+
}
|
|
32
|
+
const sources = [];
|
|
33
|
+
const missing = [];
|
|
34
|
+
for (const id of ids) {
|
|
35
|
+
const found = await fetchAttachment({ attachmentId: id, signal });
|
|
36
|
+
if (found && 'bytes' in found && found.bytes)
|
|
37
|
+
sources.push(found);
|
|
38
|
+
else
|
|
39
|
+
missing.push(id);
|
|
40
|
+
}
|
|
41
|
+
if (!missing.length)
|
|
42
|
+
return { sources };
|
|
43
|
+
if (sources.length) {
|
|
44
|
+
return {
|
|
45
|
+
sources,
|
|
46
|
+
note: `ignored unknown attachment id(s) ${missing.join(', ')} — edited the found source(s) only`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (turnImages.length) {
|
|
50
|
+
const fallback = await turnSources(turnImages);
|
|
51
|
+
if ('error' in fallback)
|
|
52
|
+
return fallback;
|
|
53
|
+
return {
|
|
54
|
+
sources: fallback,
|
|
55
|
+
note: `ignored unknown attachment id(s) ${missing.join(', ')} — edited the image(s) from the user's latest message`
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
return {
|
|
59
|
+
error: `attachment ${missing.join(', ')} not found in this chat — ids come only from earlier ` +
|
|
60
|
+
"tool results. Call again WITHOUT ids to edit the image(s) from the user's latest message"
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
async function defaultLoadMedia() {
|
|
64
|
+
try {
|
|
65
|
+
return (await import('bare-media'));
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
async function defaultResample(rgba, width, height) {
|
|
72
|
+
const { resize } = await import('bare-image-resample');
|
|
73
|
+
return resize(rgba, width, height);
|
|
74
|
+
}
|
|
75
|
+
export function createEditImageTool(runtime, { loadMedia = defaultLoadMedia, resample = defaultResample } = {}, clamps) {
|
|
76
|
+
const cap = normalizeClamps(clamps);
|
|
77
|
+
const stepsCap = clamps?.maxSteps ? cap.maxSteps : undefined;
|
|
78
|
+
const snap = (n) => Math.min(cap.maxDim, Math.max(DIM_STEP, Math.round(n / DIM_STEP) * DIM_STEP));
|
|
79
|
+
return {
|
|
80
|
+
name: 'edit_image',
|
|
81
|
+
toolset: null,
|
|
82
|
+
skillGated: true,
|
|
83
|
+
description: 'Edit or restyle an existing image from this chat using the local diffusion model ' +
|
|
84
|
+
'(image-to-image). To edit what the user just attached, call with the prompt ONLY — the ' +
|
|
85
|
+
"image(s) from the user's latest message (or the chat's most recent image) are the " +
|
|
86
|
+
'sources automatically. Never invent attachment ids; `attachment_ids` accepts only ids ' +
|
|
87
|
+
'returned by earlier tool results. Multiple sources fuse into one output (e.g. an object ' +
|
|
88
|
+
'from one image placed into another) — only image models with in-context editing support ' +
|
|
89
|
+
'this (FLUX.2 today); other models edit exactly one image. When fusing, reference the sources in the prompt as ' +
|
|
90
|
+
'@image1, @image2, ... in source order (e.g. "put @image1\'s hat on the man in @image2") ' +
|
|
91
|
+
'— without @imageN tokens the model collapses toward single-reference behavior. ' +
|
|
92
|
+
'`strength` 0..1 controls how far to move from the source: low keeps it, ' +
|
|
93
|
+
'high follows the prompt (default 0.7); in-context editing models ignore it. ' +
|
|
94
|
+
`Output keeps the source aspect ratio, fitted to the 64px grid (max ${cap.maxDim} per side on this device). ` +
|
|
95
|
+
'The edited image is saved as a chat attachment and shown to the user automatically; ' +
|
|
96
|
+
'the attachment id is returned to you.',
|
|
97
|
+
parameters: {
|
|
98
|
+
type: 'object',
|
|
99
|
+
properties: {
|
|
100
|
+
prompt: { type: 'string', description: 'How the image should change' },
|
|
101
|
+
attachment_id: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
description: 'Chat attachment to edit; omitted = the latest image in the chat'
|
|
104
|
+
},
|
|
105
|
+
attachment_ids: {
|
|
106
|
+
type: 'array',
|
|
107
|
+
items: { type: 'string' },
|
|
108
|
+
description: 'Source attachments to fuse (in-context editing models only); the first sets the output ' +
|
|
109
|
+
'size. Only ids ' +
|
|
110
|
+
"from earlier tool results — OMIT entirely for the user's attached images"
|
|
111
|
+
},
|
|
112
|
+
strength: {
|
|
113
|
+
type: 'number',
|
|
114
|
+
description: '0..1, how far to move from the source (default 0.7); in-context models ignore it'
|
|
115
|
+
},
|
|
116
|
+
steps: {
|
|
117
|
+
type: 'number',
|
|
118
|
+
description: `Diffusion steps (model default when omitted, max ${cap.maxSteps})`
|
|
119
|
+
},
|
|
120
|
+
seed: { type: 'number', description: 'Reproducibility seed; -1 or omitted = random' },
|
|
121
|
+
negative_prompt: { type: 'string', description: 'What the result should NOT contain' }
|
|
122
|
+
},
|
|
123
|
+
required: ['prompt']
|
|
124
|
+
},
|
|
125
|
+
effect: () => 'write',
|
|
126
|
+
resource: (args) => ({
|
|
127
|
+
kind: 'image-edit',
|
|
128
|
+
label: String(args.prompt ?? '').slice(0, 80)
|
|
129
|
+
}),
|
|
130
|
+
execute: async (args, ctx) => {
|
|
131
|
+
const common = parseCommonArgs(args, cap.maxSteps);
|
|
132
|
+
if ('error' in common)
|
|
133
|
+
return common;
|
|
134
|
+
let strength = DEFAULT_STRENGTH;
|
|
135
|
+
if (args.strength !== undefined && args.strength !== null) {
|
|
136
|
+
strength = Number(args.strength);
|
|
137
|
+
if (!Number.isFinite(strength) || strength < 0 || strength > 1) {
|
|
138
|
+
return { error: 'strength must be a number between 0 and 1' };
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
const attachmentId = typeof args.attachment_id === 'string' && args.attachment_id
|
|
142
|
+
? args.attachment_id
|
|
143
|
+
: undefined;
|
|
144
|
+
const attachmentIds = [];
|
|
145
|
+
if (Array.isArray(args.attachment_ids)) {
|
|
146
|
+
for (const id of args.attachment_ids) {
|
|
147
|
+
if (typeof id === 'string' && id)
|
|
148
|
+
attachmentIds.push(id);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
if (attachmentId && attachmentIds.length) {
|
|
152
|
+
return { error: 'pass attachment_id or attachment_ids, not both' };
|
|
153
|
+
}
|
|
154
|
+
if (attachmentId)
|
|
155
|
+
attachmentIds.push(attachmentId);
|
|
156
|
+
if (!ctx?.attach || !ctx.fetchAttachment) {
|
|
157
|
+
return { error: 'this device cannot edit chat images' };
|
|
158
|
+
}
|
|
159
|
+
const inContext = runtime.predictionFor(ctx.image?.modelChoice) === 'flux2_flow';
|
|
160
|
+
const turnImages = ctx.turnImages ?? [];
|
|
161
|
+
if (!attachmentIds.length && turnImages.length > 1 && !inContext) {
|
|
162
|
+
return { error: MULTI_SOURCE_UNSUPPORTED };
|
|
163
|
+
}
|
|
164
|
+
const resolved = await resolveSources(ctx.fetchAttachment, attachmentIds, turnImages, ctx.signal);
|
|
165
|
+
if (ctx.signal?.aborted)
|
|
166
|
+
return { error: 'image generation canceled' };
|
|
167
|
+
if ('error' in resolved)
|
|
168
|
+
return resolved;
|
|
169
|
+
const { sources, note } = resolved;
|
|
170
|
+
if (sources.length > 1 && !inContext)
|
|
171
|
+
return { error: MULTI_SOURCE_UNSUPPORTED };
|
|
172
|
+
if (!runtime.acquire())
|
|
173
|
+
return { error: BUSY_ERROR };
|
|
174
|
+
const report = ctx.progress;
|
|
175
|
+
const onTick = report && generationPercentTick((percentage) => report({ percentage }), sources.length);
|
|
176
|
+
try {
|
|
177
|
+
const media = await loadMedia();
|
|
178
|
+
if (!media) {
|
|
179
|
+
return {
|
|
180
|
+
error: 'image editing needs the native media codecs, unavailable on this device'
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
const inits = [];
|
|
184
|
+
let width = 0;
|
|
185
|
+
let height = 0;
|
|
186
|
+
for (const source of sources) {
|
|
187
|
+
let decoded;
|
|
188
|
+
try {
|
|
189
|
+
decoded = await media.image.decode(Buffer.from(source.bytes), { maxFrames: 1 });
|
|
190
|
+
}
|
|
191
|
+
catch {
|
|
192
|
+
return { error: `could not decode ${source.fileName} as an image` };
|
|
193
|
+
}
|
|
194
|
+
const frame = decoded.frames?.length ? decoded.frames[0] : decoded;
|
|
195
|
+
const scale = Math.min(1, cap.maxDim / Math.max(frame.width, frame.height));
|
|
196
|
+
const fitWidth = snap(frame.width * scale);
|
|
197
|
+
const fitHeight = snap(frame.height * scale);
|
|
198
|
+
const fitted = frame.width === fitWidth && frame.height === fitHeight
|
|
199
|
+
? frame
|
|
200
|
+
: await resample(frame, fitWidth, fitHeight);
|
|
201
|
+
inits.push(Buffer.from(await media.image.encode(fitted, { mimetype: 'image/png' })));
|
|
202
|
+
if (!width) {
|
|
203
|
+
width = fitWidth;
|
|
204
|
+
height = fitHeight;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const sdk = await runtime.loadSdk();
|
|
208
|
+
const { modelId } = await runtime.ensureLoaded(sdk, ctx.signal, ctx.image?.modelChoice);
|
|
209
|
+
const fusion = inits.length > 1;
|
|
210
|
+
const image = await runDiffusion(sdk, modelId, {
|
|
211
|
+
prompt: common.prompt,
|
|
212
|
+
width,
|
|
213
|
+
height,
|
|
214
|
+
steps: effectiveSteps(common.steps, ctx.image?.steps, stepsCap),
|
|
215
|
+
seed: common.seed,
|
|
216
|
+
negative_prompt: common.negativePrompt,
|
|
217
|
+
...(inContext
|
|
218
|
+
? {
|
|
219
|
+
init_images: inits,
|
|
220
|
+
auto_resize_ref_image: true,
|
|
221
|
+
guidance: FLUX2_GUIDANCE,
|
|
222
|
+
cfg_scale: FLUX2_CFG_SCALE
|
|
223
|
+
}
|
|
224
|
+
: { init_image: inits[0], strength })
|
|
225
|
+
}, ctx.signal, onTick);
|
|
226
|
+
if (!(image instanceof Uint8Array))
|
|
227
|
+
return image;
|
|
228
|
+
const record = await ctx.attach({
|
|
229
|
+
fileName: `edited-${Date.now()}.png`,
|
|
230
|
+
mimeType: 'image/png',
|
|
231
|
+
bytes: image,
|
|
232
|
+
raw: true
|
|
233
|
+
});
|
|
234
|
+
const notes = note ? [note] : [];
|
|
235
|
+
if (fusion) {
|
|
236
|
+
notes.push(IMAGE_REF_TOKEN_PATTERN.test(common.prompt)
|
|
237
|
+
? `multi-reference fusion of ${sources.length} images`
|
|
238
|
+
: `multi-reference fusion of ${sources.length} images; the prompt did not ` +
|
|
239
|
+
'reference @image1/@image2 — the model may have favored the first reference. ' +
|
|
240
|
+
'Next time write the prompt with explicit @imageN tokens in source order');
|
|
241
|
+
}
|
|
242
|
+
return {
|
|
243
|
+
attachmentId: record.id,
|
|
244
|
+
...(sources.length === 1 && sources[0].id
|
|
245
|
+
? { sourceAttachmentId: sources[0].id }
|
|
246
|
+
: { sourceFileNames: sources.map((source) => source.fileName) }),
|
|
247
|
+
...(notes.length ? { note: notes.join('; ') } : {}),
|
|
248
|
+
fileName: record.fileName,
|
|
249
|
+
byteLength: record.byteLength,
|
|
250
|
+
width,
|
|
251
|
+
height
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
if (err instanceof AbortedError)
|
|
256
|
+
return { error: 'image generation canceled' };
|
|
257
|
+
if (err instanceof Error && err.message === IMAGE_LOAD_STALL_ERROR) {
|
|
258
|
+
return { error: IMAGE_LOAD_STALL_ERROR };
|
|
259
|
+
}
|
|
260
|
+
throw err;
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
runtime.release();
|
|
264
|
+
report?.(null);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function toNull() {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
|
|
2
|
+
import type { AttachFn, FetchAttachmentFn, RunBudget } from '../../../capabilities/completion.ts';
|
|
3
|
+
import type { ExecResult } from '../runner.ts';
|
|
4
|
+
export type ExecutionOptions = {
|
|
5
|
+
readonly cwd?: string;
|
|
6
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
7
|
+
readonly timeoutMs?: number;
|
|
8
|
+
readonly maxOutputChars?: number;
|
|
9
|
+
readonly signal?: BareAbortSignal;
|
|
10
|
+
};
|
|
11
|
+
export type ExecutionContext = {
|
|
12
|
+
readonly attach?: AttachFn;
|
|
13
|
+
readonly fetchAttachment?: FetchAttachmentFn;
|
|
14
|
+
readonly turnImages?: readonly {
|
|
15
|
+
path: string;
|
|
16
|
+
}[];
|
|
17
|
+
readonly runBudget?: RunBudget;
|
|
18
|
+
};
|
|
19
|
+
export type ExecutionPlan = {
|
|
20
|
+
run(options: ExecutionOptions): Promise<ExecResult> | ExecResult;
|
|
21
|
+
};
|
|
22
|
+
export type ExecutionAdapter = {
|
|
23
|
+
resolve(args: Record<string, unknown>, ctx?: ExecutionContext): ExecutionPlan | null;
|
|
24
|
+
};
|
|
25
|
+
export type FallbackExecutionAdapter = {
|
|
26
|
+
resolve(args: Record<string, unknown>, ctx?: ExecutionContext): ExecutionPlan;
|
|
27
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { AbortSignal as BareAbortSignal } from 'bare-abort-controller';
|
|
2
|
+
import type { AttachFn, FetchAttachmentFn, RunBudget } from '../../../../capabilities/completion.ts';
|
|
3
|
+
import type { ExecAttachment, RejectedOutput } from '../../runner.ts';
|
|
4
|
+
export type ExecInput = {
|
|
5
|
+
readonly attachmentId?: string;
|
|
6
|
+
readonly path: string;
|
|
7
|
+
};
|
|
8
|
+
export type StagedInput = {
|
|
9
|
+
readonly path: string;
|
|
10
|
+
readonly bytes: Uint8Array;
|
|
11
|
+
};
|
|
12
|
+
export declare function stageInputs(fetchAttachment: FetchAttachmentFn, inputs: readonly ExecInput[], opts?: {
|
|
13
|
+
turnImages?: readonly {
|
|
14
|
+
path: string;
|
|
15
|
+
}[];
|
|
16
|
+
signal?: BareAbortSignal;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
files: readonly StagedInput[];
|
|
19
|
+
} | {
|
|
20
|
+
error: string;
|
|
21
|
+
}>;
|
|
22
|
+
export declare function attachOutputs(attach: AttachFn, files: ReadonlyMap<string, Uint8Array>, declared: readonly string[], runBudget?: RunBudget): Promise<{
|
|
23
|
+
attachments: readonly ExecAttachment[];
|
|
24
|
+
missingOutputs: readonly string[];
|
|
25
|
+
rejectedOutputs: readonly RejectedOutput[];
|
|
26
|
+
}>;
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { hlog } from "../../../../log.js";
|
|
4
|
+
import { checkOutputBytes, MAX_INPUT_TOTAL_BYTES, RUN_OUTPUT_BUDGET_BYTES } from "./output-policy.js";
|
|
5
|
+
const STAGE_TIMEOUT_MS = 60_000;
|
|
6
|
+
const STAGE_TIMEOUT_MESSAGE = `staging attachments timed out after ${STAGE_TIMEOUT_MS}ms`;
|
|
7
|
+
const OVER_BUDGET_ERROR = 'inputs exceed maximum total size';
|
|
8
|
+
const NO_UPLOAD_ERROR = 'no uploaded image in this chat — attach an image or pass an attachmentId';
|
|
9
|
+
const DOCUMENT_INPUT = /\.(pdf|docx?|xlsx?|xlsm|pptx?|csv|tsv|txt|md|markdown|rtf|odt|ods|odp|epub|jsonl?|xhtml|html?|xml|ya?ml|log|zip)$/i;
|
|
10
|
+
const NO_DOCUMENT_ERROR = 'an id-less input stages an uploaded image, and this path names a document — pass its ' +
|
|
11
|
+
'attachmentId, which the [Attached file "…"] line on the user\'s message carries';
|
|
12
|
+
function bounded(work, ms, message) {
|
|
13
|
+
let timer;
|
|
14
|
+
const bound = new Promise((_, reject) => {
|
|
15
|
+
timer = setTimeout(() => reject(new Error(message)), ms);
|
|
16
|
+
});
|
|
17
|
+
return Promise.race([work, bound]).finally(() => {
|
|
18
|
+
if (timer)
|
|
19
|
+
clearTimeout(timer);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
function hasBytes(record) {
|
|
23
|
+
return 'bytes' in record && record.bytes !== null;
|
|
24
|
+
}
|
|
25
|
+
function byteLengthOf(record) {
|
|
26
|
+
return hasBytes(record) ? record.bytes.byteLength : record.byteLength;
|
|
27
|
+
}
|
|
28
|
+
async function uploadedBytes(fetchAttachment, turnImages, index, signal) {
|
|
29
|
+
const image = turnImages[index];
|
|
30
|
+
if (image) {
|
|
31
|
+
const bytes = await fs.promises.readFile(image.path).catch(toNull);
|
|
32
|
+
if (!bytes)
|
|
33
|
+
return { error: `could not read attached image ${path.basename(image.path)}` };
|
|
34
|
+
return bytes;
|
|
35
|
+
}
|
|
36
|
+
if (turnImages.length) {
|
|
37
|
+
return {
|
|
38
|
+
error: `the user's latest message has only ${turnImages.length} image(s) — one id-less input per uploaded image`
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
if (index > 0)
|
|
42
|
+
return { error: NO_UPLOAD_ERROR };
|
|
43
|
+
const latest = await fetchAttachment({ signal });
|
|
44
|
+
if (!latest || !hasBytes(latest))
|
|
45
|
+
return { error: NO_UPLOAD_ERROR };
|
|
46
|
+
return latest.bytes;
|
|
47
|
+
}
|
|
48
|
+
export async function stageInputs(fetchAttachment, inputs, opts = {}) {
|
|
49
|
+
const { turnImages = [], signal } = opts;
|
|
50
|
+
const files = inputs.map(() => null);
|
|
51
|
+
const pending = [];
|
|
52
|
+
const deadline = Date.now() + STAGE_TIMEOUT_MS;
|
|
53
|
+
let total = 0;
|
|
54
|
+
let uploads = 0;
|
|
55
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
56
|
+
const input = inputs[i];
|
|
57
|
+
const id = input.attachmentId;
|
|
58
|
+
try {
|
|
59
|
+
if (id === undefined) {
|
|
60
|
+
if (DOCUMENT_INPUT.test(input.path))
|
|
61
|
+
return { error: NO_DOCUMENT_ERROR };
|
|
62
|
+
const bytes = await bounded(uploadedBytes(fetchAttachment, turnImages, uploads++, signal), deadline - Date.now(), STAGE_TIMEOUT_MESSAGE);
|
|
63
|
+
if ('error' in bytes)
|
|
64
|
+
return bytes;
|
|
65
|
+
total += bytes.byteLength;
|
|
66
|
+
if (total > MAX_INPUT_TOTAL_BYTES) {
|
|
67
|
+
hlog('python: input attachments over budget; skipping blob download', {
|
|
68
|
+
total,
|
|
69
|
+
cap: MAX_INPUT_TOTAL_BYTES,
|
|
70
|
+
count: inputs.length
|
|
71
|
+
});
|
|
72
|
+
return { error: OVER_BUDGET_ERROR };
|
|
73
|
+
}
|
|
74
|
+
files[i] = { path: input.path, bytes };
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
const head = await bounded(fetchAttachment({ attachmentId: id, meta: true, signal }), deadline - Date.now(), STAGE_TIMEOUT_MESSAGE);
|
|
78
|
+
if (!head)
|
|
79
|
+
return { error: `attachment ${id} not found in this chat` };
|
|
80
|
+
total += byteLengthOf(head);
|
|
81
|
+
if (total > MAX_INPUT_TOTAL_BYTES) {
|
|
82
|
+
hlog('python: input attachments over budget; skipping blob download', {
|
|
83
|
+
total,
|
|
84
|
+
cap: MAX_INPUT_TOTAL_BYTES,
|
|
85
|
+
count: inputs.length
|
|
86
|
+
});
|
|
87
|
+
return { error: OVER_BUDGET_ERROR };
|
|
88
|
+
}
|
|
89
|
+
if (hasBytes(head))
|
|
90
|
+
files[i] = { path: input.path, bytes: head.bytes };
|
|
91
|
+
else
|
|
92
|
+
pending.push(i);
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const i of pending) {
|
|
99
|
+
const input = inputs[i];
|
|
100
|
+
const id = input.attachmentId;
|
|
101
|
+
try {
|
|
102
|
+
const fetched = await bounded(fetchAttachment({ attachmentId: id, signal }), deadline - Date.now(), STAGE_TIMEOUT_MESSAGE);
|
|
103
|
+
if (!fetched || !hasBytes(fetched)) {
|
|
104
|
+
return { error: `attachment ${id} not found in this chat` };
|
|
105
|
+
}
|
|
106
|
+
files[i] = { path: input.path, bytes: fetched.bytes };
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
return { error: error instanceof Error ? error.message : String(error) };
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
return { files: files };
|
|
113
|
+
}
|
|
114
|
+
export async function attachOutputs(attach, files, declared, runBudget) {
|
|
115
|
+
const attachments = [];
|
|
116
|
+
const missingOutputs = [];
|
|
117
|
+
const rejectedOutputs = [];
|
|
118
|
+
let total = 0;
|
|
119
|
+
for (const name of declared) {
|
|
120
|
+
const bytes = files.get(name);
|
|
121
|
+
if (!bytes) {
|
|
122
|
+
missingOutputs.push(name);
|
|
123
|
+
continue;
|
|
124
|
+
}
|
|
125
|
+
const verdict = checkOutputBytes(name, bytes, total);
|
|
126
|
+
if ('error' in verdict) {
|
|
127
|
+
rejectedOutputs.push({ name, reason: verdict.error });
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
if (runBudget && runBudget.outputBytesUsed + bytes.length > RUN_OUTPUT_BUDGET_BYTES) {
|
|
131
|
+
rejectedOutputs.push({ name, reason: 'run output budget exceeded' });
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
let record;
|
|
135
|
+
try {
|
|
136
|
+
record = await attach({
|
|
137
|
+
fileName: name,
|
|
138
|
+
mimeType: verdict.mimeType,
|
|
139
|
+
bytes,
|
|
140
|
+
raw: true
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
catch {
|
|
144
|
+
rejectedOutputs.push({ name, reason: 'the host declined to persist this file' });
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
total += bytes.byteLength;
|
|
148
|
+
if (runBudget)
|
|
149
|
+
runBudget.outputBytesUsed += bytes.byteLength;
|
|
150
|
+
attachments.push({
|
|
151
|
+
attachmentId: record.id,
|
|
152
|
+
fileName: record.fileName,
|
|
153
|
+
byteLength: record.byteLength
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
return { attachments, missingOutputs, rejectedOutputs };
|
|
157
|
+
}
|
|
158
|
+
function toNull() {
|
|
159
|
+
return null;
|
|
160
|
+
}
|