@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
|
@@ -1,1371 +0,0 @@
|
|
|
1
|
-
import b4a from 'b4a';
|
|
2
|
-
import { attachOutputs, stageInputs } from './attachments.js';
|
|
3
|
-
import { checkFileName, checkOutputName, MAX_INPUTS, MAX_OUTPUTS } from './output-policy.js';
|
|
4
|
-
import { runPython } from './pyodide.js';
|
|
5
|
-
import { isTranscoder, TRANSCODE_ERROR, VIDEO_TOOLS_ERROR, videoTool } from '../../video-tools.js';
|
|
6
|
-
import { moduleDistribution } from './distributions.js';
|
|
7
|
-
import { namedHosts } from './named-hosts.js';
|
|
8
|
-
import { normalizeDistribution, planVendoredInstall, vendoredSpec } from './wheels.js';
|
|
9
|
-
export function isPythonLanguage(language) {
|
|
10
|
-
return typeof language === 'string' && language.trim().toLowerCase() === 'python';
|
|
11
|
-
}
|
|
12
|
-
export function runsThroughPyodide(language, disablePyodide) {
|
|
13
|
-
return !disablePyodide && isPythonLanguage(language);
|
|
14
|
-
}
|
|
15
|
-
const SHELL_WRAPPER = /^(python3?|py|pip3?)(\s*$|\s+(-[A-Za-z]|['"]|[\w./]))/;
|
|
16
|
-
const INTERPS = ['python3', 'python', 'py'];
|
|
17
|
-
const PIPS = ['pip3', 'pip'];
|
|
18
|
-
function isAsciiWs(c) {
|
|
19
|
-
return c === ' ' || c === '\t' || c === '\n' || c === '\r' || c === '\f';
|
|
20
|
-
}
|
|
21
|
-
function skipWs(s, i) {
|
|
22
|
-
while (i < s.length && isAsciiWs(s.charAt(i))) {
|
|
23
|
-
i++;
|
|
24
|
-
}
|
|
25
|
-
return i;
|
|
26
|
-
}
|
|
27
|
-
function leadingToken(s, tokens) {
|
|
28
|
-
for (const t of tokens) {
|
|
29
|
-
if (!s.startsWith(t))
|
|
30
|
-
continue;
|
|
31
|
-
const next = s[t.length];
|
|
32
|
-
if (next !== undefined && /[A-Za-z0-9_]/.test(next)) {
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
return t;
|
|
36
|
-
}
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
function unquote(payload) {
|
|
40
|
-
const quote = payload[0];
|
|
41
|
-
if (quote !== '"' && quote !== "'") {
|
|
42
|
-
return payload;
|
|
43
|
-
}
|
|
44
|
-
const body = payload.endsWith(quote) ? payload.slice(1, -1) : payload.slice(1);
|
|
45
|
-
return quote === '"' ? body.replace(/\\"/g, '"') : body;
|
|
46
|
-
}
|
|
47
|
-
function unwrapHeredoc(s) {
|
|
48
|
-
const interp = leadingToken(s, INTERPS);
|
|
49
|
-
if (!interp) {
|
|
50
|
-
return null;
|
|
51
|
-
}
|
|
52
|
-
let i = skipWs(s, interp.length);
|
|
53
|
-
if (!s.startsWith('<<', i)) {
|
|
54
|
-
return null;
|
|
55
|
-
}
|
|
56
|
-
i += 2;
|
|
57
|
-
if (s[i] === '-') {
|
|
58
|
-
i++;
|
|
59
|
-
}
|
|
60
|
-
i = skipWs(s, i);
|
|
61
|
-
const open = s.charAt(i);
|
|
62
|
-
const quote = open === '"' || open === "'" ? open : null;
|
|
63
|
-
if (quote) {
|
|
64
|
-
i++;
|
|
65
|
-
}
|
|
66
|
-
const tagStart = i;
|
|
67
|
-
while (i < s.length && /[A-Za-z0-9_]/.test(s.charAt(i))) {
|
|
68
|
-
i++;
|
|
69
|
-
}
|
|
70
|
-
if (i === tagStart) {
|
|
71
|
-
return null;
|
|
72
|
-
}
|
|
73
|
-
const tag = s.slice(tagStart, i);
|
|
74
|
-
if (quote) {
|
|
75
|
-
if (s[i] !== quote) {
|
|
76
|
-
return null;
|
|
77
|
-
}
|
|
78
|
-
i++;
|
|
79
|
-
}
|
|
80
|
-
while (i < s.length && (s[i] === ' ' || s[i] === '\t')) {
|
|
81
|
-
i++;
|
|
82
|
-
}
|
|
83
|
-
if (s[i] !== '\n') {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
i++;
|
|
87
|
-
const body = s.slice(i);
|
|
88
|
-
for (let j = 0; j < body.length; j++) {
|
|
89
|
-
if (body[j] !== '\n')
|
|
90
|
-
continue;
|
|
91
|
-
let k = j + 1;
|
|
92
|
-
const closeInterp = leadingToken(body.slice(k), INTERPS);
|
|
93
|
-
if (closeInterp) {
|
|
94
|
-
k += closeInterp.length;
|
|
95
|
-
}
|
|
96
|
-
k = skipWs(body, k);
|
|
97
|
-
if (!body.startsWith(tag, k)) {
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
k += tag.length;
|
|
101
|
-
k = skipWs(body, k);
|
|
102
|
-
if (k === body.length) {
|
|
103
|
-
return body.slice(0, j).trim();
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
return body.trim();
|
|
107
|
-
}
|
|
108
|
-
function unwrapDashC(s) {
|
|
109
|
-
const interp = leadingToken(s, INTERPS);
|
|
110
|
-
if (!interp) {
|
|
111
|
-
return null;
|
|
112
|
-
}
|
|
113
|
-
let i = skipWs(s, interp.length);
|
|
114
|
-
if (!s.startsWith('-c', i)) {
|
|
115
|
-
return null;
|
|
116
|
-
}
|
|
117
|
-
i += 2;
|
|
118
|
-
if (i >= s.length || !isAsciiWs(s.charAt(i))) {
|
|
119
|
-
return null;
|
|
120
|
-
}
|
|
121
|
-
i = skipWs(s, i);
|
|
122
|
-
if (i >= s.length) {
|
|
123
|
-
return null;
|
|
124
|
-
}
|
|
125
|
-
const source = unquote(s.slice(i).trim()).trim();
|
|
126
|
-
return source || null;
|
|
127
|
-
}
|
|
128
|
-
function unwrapBareInterpreter(s) {
|
|
129
|
-
const interp = leadingToken(s, INTERPS);
|
|
130
|
-
if (!interp) {
|
|
131
|
-
return null;
|
|
132
|
-
}
|
|
133
|
-
let i = interp.length;
|
|
134
|
-
while (i < s.length && (s[i] === ' ' || s[i] === '\t')) {
|
|
135
|
-
i++;
|
|
136
|
-
}
|
|
137
|
-
if (s[i] !== '\n') {
|
|
138
|
-
return null;
|
|
139
|
-
}
|
|
140
|
-
const body = s.slice(i + 1).trim();
|
|
141
|
-
return body || null;
|
|
142
|
-
}
|
|
143
|
-
export function unwrapPythonSource(command) {
|
|
144
|
-
const trimmed = withoutProgramDir(command).trim();
|
|
145
|
-
const heredoc = unwrapHeredoc(trimmed);
|
|
146
|
-
if (heredoc !== null) {
|
|
147
|
-
return heredoc;
|
|
148
|
-
}
|
|
149
|
-
const dashC = unwrapDashC(trimmed);
|
|
150
|
-
if (dashC !== null) {
|
|
151
|
-
return dashC;
|
|
152
|
-
}
|
|
153
|
-
return unwrapBareInterpreter(trimmed);
|
|
154
|
-
}
|
|
155
|
-
export function withoutProgramDir(command) {
|
|
156
|
-
return command.trimStart().replace(/^[^\s'"]*[/\\](?=[^\s/\\]+(\s|$))/, '');
|
|
157
|
-
}
|
|
158
|
-
function pipInstallRest(command) {
|
|
159
|
-
const s = withoutProgramDir(command).trim();
|
|
160
|
-
let i = 0;
|
|
161
|
-
const pip = leadingToken(s, PIPS);
|
|
162
|
-
if (pip) {
|
|
163
|
-
i = pip.length;
|
|
164
|
-
}
|
|
165
|
-
else {
|
|
166
|
-
const interp = leadingToken(s, INTERPS);
|
|
167
|
-
if (!interp) {
|
|
168
|
-
return null;
|
|
169
|
-
}
|
|
170
|
-
i = skipWs(s, interp.length);
|
|
171
|
-
if (!s.startsWith('-m', i)) {
|
|
172
|
-
return null;
|
|
173
|
-
}
|
|
174
|
-
i += 2;
|
|
175
|
-
if (i >= s.length || !isAsciiWs(s.charAt(i))) {
|
|
176
|
-
return null;
|
|
177
|
-
}
|
|
178
|
-
i = skipWs(s, i);
|
|
179
|
-
if (!s.startsWith('pip', i)) {
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
const after = s[i + 3];
|
|
183
|
-
if (after !== undefined && /[A-Za-z0-9_]/.test(after)) {
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
i += 3;
|
|
187
|
-
}
|
|
188
|
-
if (i >= s.length || !isAsciiWs(s.charAt(i))) {
|
|
189
|
-
return null;
|
|
190
|
-
}
|
|
191
|
-
i = skipWs(s, i);
|
|
192
|
-
if (!s.startsWith('install', i)) {
|
|
193
|
-
return null;
|
|
194
|
-
}
|
|
195
|
-
i += 'install'.length;
|
|
196
|
-
if (i >= s.length || !isAsciiWs(s.charAt(i))) {
|
|
197
|
-
return null;
|
|
198
|
-
}
|
|
199
|
-
i = skipWs(s, i);
|
|
200
|
-
if (i >= s.length) {
|
|
201
|
-
return null;
|
|
202
|
-
}
|
|
203
|
-
return s.slice(i);
|
|
204
|
-
}
|
|
205
|
-
const REQUIREMENT = /^[A-Za-z0-9][A-Za-z0-9._-]*(\[[A-Za-z0-9,._-]+\])?([=<>!~]=?[^\s]+)?$/;
|
|
206
|
-
export function pipInstallTargets(command) {
|
|
207
|
-
const rest = pipInstallRest(command);
|
|
208
|
-
if (!rest) {
|
|
209
|
-
return null;
|
|
210
|
-
}
|
|
211
|
-
const targets = [];
|
|
212
|
-
for (const raw of rest.split(/\s+/)) {
|
|
213
|
-
if (/[|;&<>()`$]/.test(raw))
|
|
214
|
-
break;
|
|
215
|
-
const token = raw.replace(/^['"]|['"]$/g, '');
|
|
216
|
-
if (/^(-r|--requirement|-e|--editable|-c|--constraint|-f|--find-links)$/.test(token)) {
|
|
217
|
-
return null;
|
|
218
|
-
}
|
|
219
|
-
if (!token || token.startsWith('-')) {
|
|
220
|
-
continue;
|
|
221
|
-
}
|
|
222
|
-
if (!REQUIREMENT.test(token)) {
|
|
223
|
-
return null;
|
|
224
|
-
}
|
|
225
|
-
if (/^pip3?$/i.test(token.split(/[=<>!~[]/)[0] ?? '')) {
|
|
226
|
-
continue;
|
|
227
|
-
}
|
|
228
|
-
targets.push(token);
|
|
229
|
-
}
|
|
230
|
-
return targets.length > 0 ? targets : null;
|
|
231
|
-
}
|
|
232
|
-
const SANDBOX_NO_INSTALL = 'and sandbox mode installs only the packages bundled with this app, which do not include it. Use only what is already installed, or tell the user it is unavailable while sandbox mode is on.';
|
|
233
|
-
const specName = (spec) => normalizeDistribution(spec.split(/[=<>!~[]/)[0] ?? '');
|
|
234
|
-
export function pinned(spec) {
|
|
235
|
-
return /[=<>!~]/.test(spec) ? spec : (vendoredSpec(spec) ?? spec);
|
|
236
|
-
}
|
|
237
|
-
export function pipMessage(targets, { sandbox = false } = {}) {
|
|
238
|
-
const specs = targets?.map(pinned) ?? null;
|
|
239
|
-
if (sandbox && !(specs?.length && planVendoredInstall(specs))) {
|
|
240
|
-
return `pip is not available, ${SANDBOX_NO_INSTALL}`;
|
|
241
|
-
}
|
|
242
|
-
const declare = specs ? `packages: ${JSON.stringify(specs)}` : 'the PyPI names in packages';
|
|
243
|
-
return `pip is not available. Call exec with language "python", ${declare} and the Python source in command. Installing and running are the same one call.`;
|
|
244
|
-
}
|
|
245
|
-
export function sandboxInstallError(command, declared) {
|
|
246
|
-
const install = pipInstallTargets(command)?.map(pinned) ?? null;
|
|
247
|
-
const packages = [...new Set([...(declared ?? []), ...(install ?? [])])];
|
|
248
|
-
if (packages.length === 0 || planVendoredInstall(packages)) {
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
return install
|
|
252
|
-
? pipMessage(install, { sandbox: true })
|
|
253
|
-
: 'sandbox mode: installing packages reaches the network';
|
|
254
|
-
}
|
|
255
|
-
const PIP_CALL = /\b(?:subprocess\.\w+|os\.(?:system|popen)|Popen|check_(?:output|call))\s*\(/;
|
|
256
|
-
const STRING_LITERAL = /"([^"\n]*)"|'([^'\n]*)'/g;
|
|
257
|
-
function pipLineTargets(line) {
|
|
258
|
-
const words = [...line.matchAll(STRING_LITERAL)].map((match) => match[1] ?? match[2] ?? '');
|
|
259
|
-
const whole = words.find((word) => /\bpip3?\b[^]*\binstall\b/.test(word));
|
|
260
|
-
if (whole !== undefined) {
|
|
261
|
-
return pipInstallTargets(whole.trim());
|
|
262
|
-
}
|
|
263
|
-
const at = words.findIndex((word) => /^pip3?$/.test(word));
|
|
264
|
-
if (at === -1) {
|
|
265
|
-
return undefined;
|
|
266
|
-
}
|
|
267
|
-
return pipInstallTargets(words.slice(at).join(' '));
|
|
268
|
-
}
|
|
269
|
-
export function pipFromSourceHint(stderr, source, { packages, sandbox = false } = {}) {
|
|
270
|
-
if (!/emscripten does not support processes/.test(stderr))
|
|
271
|
-
return null;
|
|
272
|
-
for (const line of source.split('\n')) {
|
|
273
|
-
if (!PIP_CALL.test(line))
|
|
274
|
-
continue;
|
|
275
|
-
const targets = pipLineTargets(line);
|
|
276
|
-
if (targets === undefined) {
|
|
277
|
-
continue;
|
|
278
|
-
}
|
|
279
|
-
const declared = packages ?? [];
|
|
280
|
-
const has = new Set(declared.map(specName));
|
|
281
|
-
const missing = (targets ?? []).filter((t) => !has.has(specName(t))).map(pinned);
|
|
282
|
-
if (sandbox && (targets === null || !planVendoredInstall([...declared, ...missing]))) {
|
|
283
|
-
return `pip cannot run here: this Python cannot start processes, so that line failed, ${SANDBOX_NO_INSTALL} Delete the pip line.`;
|
|
284
|
-
}
|
|
285
|
-
if (targets === null) {
|
|
286
|
-
return 'pip cannot run here: this Python cannot start processes, so that line failed. Delete it and declare the PyPI names in packages on this same call.';
|
|
287
|
-
}
|
|
288
|
-
if (missing.length) {
|
|
289
|
-
return `pip cannot run here: this Python cannot start processes, so that line failed. Delete it and send the same source with packages: ${JSON.stringify([...declared, ...missing])} on this one call. Installing and running are the same call.`;
|
|
290
|
-
}
|
|
291
|
-
if (declared.length) {
|
|
292
|
-
return `pip cannot run here: this Python cannot start processes, so that line failed. packages: ${JSON.stringify(declared)} already installs before your code runs, so delete the pip line and send the rest.`;
|
|
293
|
-
}
|
|
294
|
-
return 'pip cannot run here: this Python cannot start processes, so that line failed. Delete it and declare the PyPI names in packages on this same call.';
|
|
295
|
-
}
|
|
296
|
-
return null;
|
|
297
|
-
}
|
|
298
|
-
export function stringLiteralProgramHint(source) {
|
|
299
|
-
const first = source.trimStart()[0];
|
|
300
|
-
if (first !== '"' && first !== "'") {
|
|
301
|
-
return null;
|
|
302
|
-
}
|
|
303
|
-
if (!source.trimEnd().endsWith(first)) {
|
|
304
|
-
return null;
|
|
305
|
-
}
|
|
306
|
-
if (!/\bimport\b/.test(source)) {
|
|
307
|
-
return null;
|
|
308
|
-
}
|
|
309
|
-
return ('command is wrapped in a string literal, so Python evaluates it as text and runs ' +
|
|
310
|
-
'nothing: remove the wrapping quotes (and any escaped \\" quotes) so the first line ' +
|
|
311
|
-
'of command is the first line of the program, e.g. from fpdf import FPDF.');
|
|
312
|
-
}
|
|
313
|
-
const COLLAPSED_COMPOUND = /;\s*(?:async\s+)?(?:for|if|while|with|def|class|try|match)\b/;
|
|
314
|
-
export function checkCollapsedCompound(source) {
|
|
315
|
-
if (source.includes('\n'))
|
|
316
|
-
return null;
|
|
317
|
-
if (!COLLAPSED_COMPOUND.test(source))
|
|
318
|
-
return null;
|
|
319
|
-
return ('command must keep real newlines: a compound statement (for/if/while/with/def/…) ' +
|
|
320
|
-
'cannot follow a semicolon. Pass multi-line Python source with newline characters, ' +
|
|
321
|
-
'not a single-line semicolon chain.');
|
|
322
|
-
}
|
|
323
|
-
const MANGLED_PPTX = [
|
|
324
|
-
['textframe', 'text_frame'],
|
|
325
|
-
['addslide', 'add_slide'],
|
|
326
|
-
['slidelayouts', 'slide_layouts'],
|
|
327
|
-
['slidewidth', 'slide_width'],
|
|
328
|
-
['slideheight', 'slide_height'],
|
|
329
|
-
['wordwrap', 'word_wrap'],
|
|
330
|
-
['addparagraph', 'add_paragraph'],
|
|
331
|
-
['addtextbox', 'add_textbox'],
|
|
332
|
-
['addpicture', 'add_picture'],
|
|
333
|
-
['ppalign', 'PP_ALIGN']
|
|
334
|
-
];
|
|
335
|
-
export function mangledPptxApiHint(source) {
|
|
336
|
-
if (!/\bpptx\b|Presentation\s*\(/.test(source))
|
|
337
|
-
return null;
|
|
338
|
-
const found = [];
|
|
339
|
-
for (const [bad, good] of MANGLED_PPTX) {
|
|
340
|
-
if (new RegExp(`\\b${bad}\\b`, 'i').test(source) && !source.includes(good)) {
|
|
341
|
-
found.push(`${bad} → ${good}`);
|
|
342
|
-
}
|
|
343
|
-
}
|
|
344
|
-
if (found.length === 0) {
|
|
345
|
-
return null;
|
|
346
|
-
}
|
|
347
|
-
return (`python-pptx names keep their underscores — found stripped forms (${found.join(', ')}). ` +
|
|
348
|
-
'Restore them (text_frame not textframe, add_slide not addslide) and keep the skill ' +
|
|
349
|
-
'sample multi-line with real newlines.');
|
|
350
|
-
}
|
|
351
|
-
export function wrongRgbColorHint(source) {
|
|
352
|
-
if (!/\bpptx\b|Presentation\s*\(/.test(source))
|
|
353
|
-
return null;
|
|
354
|
-
if (/\bRGBColor\b/.test(source))
|
|
355
|
-
return null;
|
|
356
|
-
const code = source.replace(/#[^\n]*/g, '').replace(/'[^'\n]*'|"[^"\n]*"/g, '');
|
|
357
|
-
if (!/\bRgbColor\b|\brgbColor\b|\brgbcolor\b|\bRGB_Color\b|\brgb_color\b/.test(code)) {
|
|
358
|
-
return null;
|
|
359
|
-
}
|
|
360
|
-
return ('python-pptx color type is RGBColor (RGB in all caps): ' +
|
|
361
|
-
'from pptx.dml.color import RGBColor — not RgbColor / rgbColor. ' +
|
|
362
|
-
'Do not catch that ImportError and continue; fix the name and rerun.');
|
|
363
|
-
}
|
|
364
|
-
const FPDF_SIZE_KEYWORD = /\b(cell|multi_cell)\s*\([^)]*\b(width|height)\s*=/;
|
|
365
|
-
export function fpdfSizeKeywordHint(source) {
|
|
366
|
-
if (!/\bfpdf\b|\bFPDF\b/.test(source))
|
|
367
|
-
return null;
|
|
368
|
-
const match = FPDF_SIZE_KEYWORD.exec(source);
|
|
369
|
-
if (!match) {
|
|
370
|
-
return null;
|
|
371
|
-
}
|
|
372
|
-
return (`fpdf2 ${match[1]}() has no "${match[2]}" keyword — the size parameters are the positional ` +
|
|
373
|
-
'w and h: write every line (headings and body) with pdf.multi_cell(0, 6, text, ' +
|
|
374
|
-
'new_x="LMARGIN", new_y="NEXT"). Rename the arguments and keep new_x/new_y; ' +
|
|
375
|
-
'deleting keywords to silence the error prints later lines on top of each other.');
|
|
376
|
-
}
|
|
377
|
-
export function fpdfKeywordErrorHint(stderr) {
|
|
378
|
-
const match = /TypeError: FPDF\.(\w+)\(\) got an unexpected keyword argument '(\w+)'/.exec(stderr);
|
|
379
|
-
if (!match) {
|
|
380
|
-
return null;
|
|
381
|
-
}
|
|
382
|
-
const sized = match[2] === 'width' || match[2] === 'height';
|
|
383
|
-
const fix = sized
|
|
384
|
-
? 'the size parameters are the positional w and h'
|
|
385
|
-
: 'copy the exact call shape from the pdf skill sample';
|
|
386
|
-
return (`fpdf2 ${match[1]}() has no "${match[2]}" keyword — ${fix}: ` +
|
|
387
|
-
'write every line (headings and body) with pdf.multi_cell(0, 6, text, ' +
|
|
388
|
-
'new_x="LMARGIN", new_y="NEXT"). Rename the arguments and keep new_x/new_y; ' +
|
|
389
|
-
'deleting keywords to silence the error prints later lines on top of each other.');
|
|
390
|
-
}
|
|
391
|
-
const LATIN1_SUBSTITUTES = [
|
|
392
|
-
[/[\u2010-\u2015\u2212]/gu, '-'],
|
|
393
|
-
[/[\u2022\u25e6\u25aa\u25cf]/gu, '-'],
|
|
394
|
-
[/\u2026/gu, '...'],
|
|
395
|
-
[/\u2192/gu, '->'],
|
|
396
|
-
[/\u2190/gu, '<-'],
|
|
397
|
-
[/\u2248/gu, '~'],
|
|
398
|
-
[/\u2264/gu, '<='],
|
|
399
|
-
[/\u2265/gu, '>='],
|
|
400
|
-
[/\u2122/gu, '(TM)'],
|
|
401
|
-
[/\u20ac/gu, 'EUR'],
|
|
402
|
-
[/[\u2000-\u200a]/gu, ' '],
|
|
403
|
-
[/[\u200b-\u200d\ufeff]/gu, '']
|
|
404
|
-
];
|
|
405
|
-
export function normalizeFpdfSource(source) {
|
|
406
|
-
if (!/\bfpdf\b|\bFPDF\b/.test(source))
|
|
407
|
-
return source;
|
|
408
|
-
let out = source;
|
|
409
|
-
for (const [from, to] of LATIN1_SUBSTITUTES) {
|
|
410
|
-
out = out.replace(from, to);
|
|
411
|
-
}
|
|
412
|
-
return out;
|
|
413
|
-
}
|
|
414
|
-
const CURLY_QUOTE = /[\u2018\u2019\u201a\u2032\u201c\u201d\u201e\u2033]/u;
|
|
415
|
-
const TEXT_WITHOUT_COORDS = /\.text\s*\(\s*['"]/;
|
|
416
|
-
const TEXT_IS_STAMP_ONLY = 'fpdf2 text(x, y, string) paints at a fixed point with no wrapping \u2014 it is only for the ' +
|
|
417
|
-
'watermark stamp. Write document text (headings, paragraphs, bullets) with ' +
|
|
418
|
-
'pdf.multi_cell(0, 6, text, new_x="LMARGIN", new_y="NEXT").';
|
|
419
|
-
export function fpdfTextCallHint(source) {
|
|
420
|
-
if (!/\bfpdf\b|\bFPDF\b/.test(source))
|
|
421
|
-
return null;
|
|
422
|
-
if (!TEXT_WITHOUT_COORDS.test(source))
|
|
423
|
-
return null;
|
|
424
|
-
return TEXT_IS_STAMP_ONLY;
|
|
425
|
-
}
|
|
426
|
-
export function fpdfTextErrorHint(stderr) {
|
|
427
|
-
if (!/TypeError: FPDF\.text\(\)/.test(stderr))
|
|
428
|
-
return null;
|
|
429
|
-
return TEXT_IS_STAMP_ONLY;
|
|
430
|
-
}
|
|
431
|
-
export function fpdfNonLatin1Hint(source) {
|
|
432
|
-
if (!/\bfpdf\b|\bFPDF\b/.test(source))
|
|
433
|
-
return null;
|
|
434
|
-
if (source.includes('.replace('))
|
|
435
|
-
return null;
|
|
436
|
-
const bad = /[^\u0000-\u00ff]/u.exec(normalizeFpdfSource(source))?.[0];
|
|
437
|
-
if (!bad) {
|
|
438
|
-
return null;
|
|
439
|
-
}
|
|
440
|
-
if (CURLY_QUOTE.test(bad)) {
|
|
441
|
-
return (`fpdf2 core fonts are latin-1 only and the curly quote ${bad} is outside it — rewrite ` +
|
|
442
|
-
'the strings with straight quotes \' and " and rerun.');
|
|
443
|
-
}
|
|
444
|
-
return (`fpdf2 core fonts are latin-1 only and "${bad}" cannot be rendered — there are no Unicode ` +
|
|
445
|
-
'fonts in this runtime. Drop it or use a latin transliteration, and tell the user CJK and ' +
|
|
446
|
-
'emoji cannot appear in the PDF.');
|
|
447
|
-
}
|
|
448
|
-
export function fpdfUnicodeErrorHint(stderr) {
|
|
449
|
-
const encoding = /FPDFUnicodeEncodingException/.test(stderr) ||
|
|
450
|
-
(/UnicodeEncodeError: 'latin-1' codec/.test(stderr) && /fpdf/.test(stderr));
|
|
451
|
-
if (!encoding) {
|
|
452
|
-
return null;
|
|
453
|
-
}
|
|
454
|
-
return ('a character outside latin-1 reached an fpdf2 core font: replace it with ASCII ' +
|
|
455
|
-
'(bullets "- ", straight quotes, plain hyphens). CJK and emoji cannot be rendered — ' +
|
|
456
|
-
'tell the user instead of retrying with the same string.');
|
|
457
|
-
}
|
|
458
|
-
export function fpdfHorizontalSpaceHint(stderr) {
|
|
459
|
-
if (!/FPDFException: Not enough horizontal space/.test(stderr))
|
|
460
|
-
return null;
|
|
461
|
-
return ('an earlier cell/multi_cell left the cursor at the right margin: add ' +
|
|
462
|
-
'new_x="LMARGIN", new_y="NEXT" to every cell and multi_cell call so each ' +
|
|
463
|
-
'one starts on its own line.');
|
|
464
|
-
}
|
|
465
|
-
export function rgbColorImportHint(stderr) {
|
|
466
|
-
const name = /cannot import name '([^']+)' from 'pptx\.dml\.color'/.exec(stderr)?.[1];
|
|
467
|
-
if (!name || name === 'RGBColor') {
|
|
468
|
-
return null;
|
|
469
|
-
}
|
|
470
|
-
if (!/^rgb_?color$/i.test(name)) {
|
|
471
|
-
return null;
|
|
472
|
-
}
|
|
473
|
-
return (`pptx.dml.color exports RGBColor (all-caps RGB), not ${name}: ` +
|
|
474
|
-
'from pptx.dml.color import RGBColor');
|
|
475
|
-
}
|
|
476
|
-
export function checkPythonSource(command) {
|
|
477
|
-
const source = unwrapPythonSource(command) ?? command;
|
|
478
|
-
const literal = stringLiteralProgramHint(source);
|
|
479
|
-
if (literal) {
|
|
480
|
-
return literal;
|
|
481
|
-
}
|
|
482
|
-
const collapsed = checkCollapsedCompound(source);
|
|
483
|
-
if (collapsed) {
|
|
484
|
-
return collapsed;
|
|
485
|
-
}
|
|
486
|
-
const mangled = mangledPptxApiHint(source);
|
|
487
|
-
if (mangled) {
|
|
488
|
-
return mangled;
|
|
489
|
-
}
|
|
490
|
-
const rgb = wrongRgbColorHint(source);
|
|
491
|
-
if (rgb) {
|
|
492
|
-
return rgb;
|
|
493
|
-
}
|
|
494
|
-
const fpdfKeyword = fpdfSizeKeywordHint(source);
|
|
495
|
-
if (fpdfKeyword) {
|
|
496
|
-
return fpdfKeyword;
|
|
497
|
-
}
|
|
498
|
-
const fpdfLatin1 = fpdfNonLatin1Hint(source);
|
|
499
|
-
if (fpdfLatin1) {
|
|
500
|
-
return fpdfLatin1;
|
|
501
|
-
}
|
|
502
|
-
const fpdfText = fpdfTextCallHint(source);
|
|
503
|
-
if (fpdfText) {
|
|
504
|
-
return fpdfText;
|
|
505
|
-
}
|
|
506
|
-
const first = command.trimStart().split('\n')[0] ?? '';
|
|
507
|
-
if (!SHELL_WRAPPER.test(first)) {
|
|
508
|
-
return null;
|
|
509
|
-
}
|
|
510
|
-
if (pipInstallTargets(command)) {
|
|
511
|
-
return null;
|
|
512
|
-
}
|
|
513
|
-
if (/^pip3?\b/.test(first) || /^(python3?|py)\s+-m\s+pip\b/.test(first)) {
|
|
514
|
-
return 'language "python" does not run shell commands: install packages via the packages argument (e.g. packages: ["python-pptx==1.0.2"]), not pip';
|
|
515
|
-
}
|
|
516
|
-
if (unwrapPythonSource(command)) {
|
|
517
|
-
return null;
|
|
518
|
-
}
|
|
519
|
-
return 'language "python" runs command as Python source: its first line is the first line of the program, so command must start with the code itself. There is no shell, no interpreter, and no script file to name.';
|
|
520
|
-
}
|
|
521
|
-
export function syntaxErrorHint(stderr, source) {
|
|
522
|
-
if (!/SyntaxError/.test(stderr))
|
|
523
|
-
return null;
|
|
524
|
-
return (checkCollapsedCompound(source) ??
|
|
525
|
-
mangledPptxApiHint(source) ??
|
|
526
|
-
'SyntaxError means the Python source is invalid as written — keep real newlines for for/if/with/def bodies; do not collapse a multi-line program into one semicolon-separated line.');
|
|
527
|
-
}
|
|
528
|
-
export function checkPptxBuildSource(source, outputs, packages) {
|
|
529
|
-
if (!outputs?.some((name) => name.toLowerCase().endsWith('.pptx'))) {
|
|
530
|
-
return null;
|
|
531
|
-
}
|
|
532
|
-
const pkgPptx = (packages ?? []).some((p) => {
|
|
533
|
-
const name = (p.split(/[=<>!~[]/)[0] ?? '').trim().toLowerCase();
|
|
534
|
-
return name === 'python-pptx' || name === 'pptx';
|
|
535
|
-
});
|
|
536
|
-
const srcPptx = /\bpptx\b|\bPresentation\s*\(/.test(source);
|
|
537
|
-
if (!pkgPptx && !srcPptx) {
|
|
538
|
-
return null;
|
|
539
|
-
}
|
|
540
|
-
const builds = /\bPresentation\s*\(/.test(source) && /\.save\s*\(/.test(source);
|
|
541
|
-
if (builds) {
|
|
542
|
-
return null;
|
|
543
|
-
}
|
|
544
|
-
return ('outputs declare a .pptx but command does not build one: pass multi-line python-pptx ' +
|
|
545
|
-
'source that constructs Presentation(...) and calls save("deck.pptx") matching an ' +
|
|
546
|
-
'outputs entry. Do not use python -c, os.listdir, pip, or a different package pin — ' +
|
|
547
|
-
'language="python" already runs bare source, and packages must stay ["python-pptx==1.0.2"].');
|
|
548
|
-
}
|
|
549
|
-
export function tripleQuoteAt(source, index) {
|
|
550
|
-
if (source.startsWith('"""', index))
|
|
551
|
-
return '"""';
|
|
552
|
-
return source.startsWith("'''", index) ? "'''" : null;
|
|
553
|
-
}
|
|
554
|
-
export function isEscaped(source, index) {
|
|
555
|
-
let slashes = 0;
|
|
556
|
-
while (index - slashes > 0 && source[index - slashes - 1] === '\\') {
|
|
557
|
-
slashes++;
|
|
558
|
-
}
|
|
559
|
-
return slashes % 2 === 1;
|
|
560
|
-
}
|
|
561
|
-
function splitCallArgs(source, open) {
|
|
562
|
-
const args = [];
|
|
563
|
-
let arg = '';
|
|
564
|
-
let depth = 0;
|
|
565
|
-
let quote = null;
|
|
566
|
-
for (let i = open; i < source.length; i++) {
|
|
567
|
-
const ch = source.charAt(i);
|
|
568
|
-
if (quote) {
|
|
569
|
-
arg += ch;
|
|
570
|
-
if (ch === quote && !isEscaped(source, i)) {
|
|
571
|
-
quote = null;
|
|
572
|
-
}
|
|
573
|
-
continue;
|
|
574
|
-
}
|
|
575
|
-
if (ch === '"' || ch === "'") {
|
|
576
|
-
quote = ch;
|
|
577
|
-
arg += ch;
|
|
578
|
-
continue;
|
|
579
|
-
}
|
|
580
|
-
if (ch === '(' || ch === '[' || ch === '{') {
|
|
581
|
-
depth++;
|
|
582
|
-
if (depth > 1) {
|
|
583
|
-
arg += ch;
|
|
584
|
-
}
|
|
585
|
-
continue;
|
|
586
|
-
}
|
|
587
|
-
if (ch === ')' || ch === ']' || ch === '}') {
|
|
588
|
-
depth--;
|
|
589
|
-
if (depth === 0) {
|
|
590
|
-
args.push(arg);
|
|
591
|
-
return args.map((a) => a.trim());
|
|
592
|
-
}
|
|
593
|
-
arg += ch;
|
|
594
|
-
continue;
|
|
595
|
-
}
|
|
596
|
-
if (ch === ',' && depth === 1) {
|
|
597
|
-
args.push(arg);
|
|
598
|
-
arg = '';
|
|
599
|
-
continue;
|
|
600
|
-
}
|
|
601
|
-
arg += ch;
|
|
602
|
-
}
|
|
603
|
-
return null;
|
|
604
|
-
}
|
|
605
|
-
const MIN_MEANT_EMU = 12700;
|
|
606
|
-
function bareEmuMistake(arg) {
|
|
607
|
-
if (!/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)$/.test(arg))
|
|
608
|
-
return false;
|
|
609
|
-
const value = Math.abs(Number(arg));
|
|
610
|
-
return value !== 0 && value < MIN_MEANT_EMU;
|
|
611
|
-
}
|
|
612
|
-
function stripCommentsAndStrings(source) {
|
|
613
|
-
let out = '';
|
|
614
|
-
let i = 0;
|
|
615
|
-
while (i < source.length) {
|
|
616
|
-
const ch = source.charAt(i);
|
|
617
|
-
const triple = tripleQuoteAt(source, i);
|
|
618
|
-
const quote = triple ?? (ch === '"' || ch === "'" ? ch : null);
|
|
619
|
-
if (quote) {
|
|
620
|
-
i += quote.length;
|
|
621
|
-
while (i < source.length && !(source.startsWith(quote, i) && !isEscaped(source, i))) {
|
|
622
|
-
i++;
|
|
623
|
-
}
|
|
624
|
-
out += '""';
|
|
625
|
-
i += quote.length;
|
|
626
|
-
continue;
|
|
627
|
-
}
|
|
628
|
-
if (ch === '#') {
|
|
629
|
-
while (i < source.length && source[i] !== '\n') {
|
|
630
|
-
i++;
|
|
631
|
-
}
|
|
632
|
-
continue;
|
|
633
|
-
}
|
|
634
|
-
out += ch;
|
|
635
|
-
i++;
|
|
636
|
-
}
|
|
637
|
-
return out;
|
|
638
|
-
}
|
|
639
|
-
const LENGTH_LIBRARY = {
|
|
640
|
-
pptx: {
|
|
641
|
-
module: 'pptx.util',
|
|
642
|
-
effect: 'the shape collapses to an invisible box in the top-left corner and the deck is delivered broken',
|
|
643
|
-
example: 'add_textbox(Inches(1), Inches(1), Inches(8), Inches(1.5))'
|
|
644
|
-
},
|
|
645
|
-
docx: {
|
|
646
|
-
module: 'docx.shared',
|
|
647
|
-
effect: 'the image collapses to nothing and the document is delivered broken',
|
|
648
|
-
example: 'add_picture("chart.png", width=Inches(5.5))'
|
|
649
|
-
}
|
|
650
|
-
};
|
|
651
|
-
function lengthLibrary(source, packages) {
|
|
652
|
-
const names = (packages ?? []).map((p) => (p.split(/[=<>!~[]/)[0] ?? '').trim().toLowerCase());
|
|
653
|
-
if (names.includes('python-pptx') || names.includes('pptx')) {
|
|
654
|
-
return 'pptx';
|
|
655
|
-
}
|
|
656
|
-
if (names.includes('python-docx') || names.includes('docx')) {
|
|
657
|
-
return 'docx';
|
|
658
|
-
}
|
|
659
|
-
if (/\bpptx\b|\bPresentation\s*\(/.test(source)) {
|
|
660
|
-
return 'pptx';
|
|
661
|
-
}
|
|
662
|
-
if (/\bdocx\b|\bDocument\s*\(/.test(source)) {
|
|
663
|
-
return 'docx';
|
|
664
|
-
}
|
|
665
|
-
return null;
|
|
666
|
-
}
|
|
667
|
-
const LENGTH_KEYWORDS = ['left', 'top', 'width', 'height'];
|
|
668
|
-
const FIRST_LENGTH_ARG = { add_textbox: 0, add_picture: 1 };
|
|
669
|
-
function callLibrary(method, before, fallback) {
|
|
670
|
-
if (method === 'add_textbox')
|
|
671
|
-
return 'pptx';
|
|
672
|
-
if (/\bshapes\s*\.\s*$/.test(before))
|
|
673
|
-
return 'pptx';
|
|
674
|
-
if (/\b(?:doc|document|run|paragraph|cell)\s*\.\s*$/.test(before)) {
|
|
675
|
-
return 'docx';
|
|
676
|
-
}
|
|
677
|
-
return fallback;
|
|
678
|
-
}
|
|
679
|
-
export function checkBareLengthArgs(source, packages) {
|
|
680
|
-
const clean = stripCommentsAndStrings(source);
|
|
681
|
-
const library = lengthLibrary(clean, packages);
|
|
682
|
-
if (!library) {
|
|
683
|
-
return null;
|
|
684
|
-
}
|
|
685
|
-
for (const method of ['add_textbox', 'add_picture']) {
|
|
686
|
-
const calls = new RegExp(`\\b${method}\\s*\\(`, 'g');
|
|
687
|
-
let call;
|
|
688
|
-
while ((call = calls.exec(clean)) !== null) {
|
|
689
|
-
const args = splitCallArgs(clean, calls.lastIndex - 1);
|
|
690
|
-
if (!args) {
|
|
691
|
-
continue;
|
|
692
|
-
}
|
|
693
|
-
const offender = args.find((arg, index) => {
|
|
694
|
-
const eq = arg.indexOf('=');
|
|
695
|
-
const name = eq === -1 ? '' : arg.slice(0, eq).trim();
|
|
696
|
-
if (eq !== -1 && /^[A-Za-z_]\w*$/.test(name)) {
|
|
697
|
-
return LENGTH_KEYWORDS.includes(name) && bareEmuMistake(arg.slice(eq + 1).trim());
|
|
698
|
-
}
|
|
699
|
-
return index >= FIRST_LENGTH_ARG[method] && bareEmuMistake(arg);
|
|
700
|
-
});
|
|
701
|
-
if (offender !== undefined) {
|
|
702
|
-
const before = clean.slice(Math.max(0, call.index - 40), call.index);
|
|
703
|
-
return bareLengthError(`${method}(...)`, offender, callLibrary(method, before, library));
|
|
704
|
-
}
|
|
705
|
-
}
|
|
706
|
-
}
|
|
707
|
-
if (library === 'pptx') {
|
|
708
|
-
const assignments = /\bslide_(?:width|height)\s*=\s*([^\n]+)/g;
|
|
709
|
-
let assigned;
|
|
710
|
-
while ((assigned = assignments.exec(clean)) !== null) {
|
|
711
|
-
const value = (assigned[1] ?? '').trim();
|
|
712
|
-
if (bareEmuMistake(value)) {
|
|
713
|
-
return bareLengthError('slide_width / slide_height', value, library);
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
}
|
|
717
|
-
return null;
|
|
718
|
-
}
|
|
719
|
-
function bareLengthError(where, value, library) {
|
|
720
|
-
const fix = LENGTH_LIBRARY[library];
|
|
721
|
-
return (`${where} was given the bare number ${value} where a typed length is required: ` +
|
|
722
|
-
`python-${library} reads a bare number as EMU (914400 to the inch), so ${fix.effect}. ` +
|
|
723
|
-
'Nothing raises, so this never reaches you as an error. Wrap every position and size ' +
|
|
724
|
-
`with Inches(...), Pt(...) or Emu(...) from ${fix.module}, e.g. ${fix.example}. ` +
|
|
725
|
-
'Do not rescale the raw numbers.');
|
|
726
|
-
}
|
|
727
|
-
export function checkPdfBuildSource(source, outputs, packages) {
|
|
728
|
-
if (!outputs?.some((name) => name.toLowerCase().endsWith('.pdf')))
|
|
729
|
-
return null;
|
|
730
|
-
const pkgPdf = (packages ?? []).some((p) => {
|
|
731
|
-
const name = (p.split(/[=<>!~[]/)[0] ?? '').trim().toLowerCase();
|
|
732
|
-
return name === 'fpdf2' || name === 'pypdf';
|
|
733
|
-
});
|
|
734
|
-
const srcPdf = /\b(fpdf|FPDF|pypdf|PdfWriter|PdfReader)\b/.test(source);
|
|
735
|
-
if (!pkgPdf && !srcPdf) {
|
|
736
|
-
return null;
|
|
737
|
-
}
|
|
738
|
-
const builds = /\.output\s*\(|\.write\s*\(/.test(source);
|
|
739
|
-
if (builds) {
|
|
740
|
-
return null;
|
|
741
|
-
}
|
|
742
|
-
return ('outputs declare a .pdf but command never writes one: pass multi-line Python that ' +
|
|
743
|
-
'builds the document and saves it under the declared name — fpdf2 ends with ' +
|
|
744
|
-
'pdf.output("name.pdf"), pypdf with writer.write("name.pdf"). Do not send diagnostics ' +
|
|
745
|
-
'like os.listdir or print-only scripts while outputs still lists the file.');
|
|
746
|
-
}
|
|
747
|
-
export function stripCommentsAndDocstrings(source) {
|
|
748
|
-
let out = '';
|
|
749
|
-
let i = 0;
|
|
750
|
-
while (i < source.length) {
|
|
751
|
-
const ch = source.charAt(i);
|
|
752
|
-
const triple = tripleQuoteAt(source, i);
|
|
753
|
-
if (triple) {
|
|
754
|
-
i += triple.length;
|
|
755
|
-
while (i < source.length && !(source.startsWith(triple, i) && !isEscaped(source, i))) {
|
|
756
|
-
i++;
|
|
757
|
-
}
|
|
758
|
-
out += '""';
|
|
759
|
-
i += triple.length;
|
|
760
|
-
continue;
|
|
761
|
-
}
|
|
762
|
-
if (ch === '"' || ch === "'") {
|
|
763
|
-
const start = i;
|
|
764
|
-
i++;
|
|
765
|
-
while (i < source.length && !(source[i] === ch && !isEscaped(source, i))) {
|
|
766
|
-
i++;
|
|
767
|
-
}
|
|
768
|
-
i++;
|
|
769
|
-
out += source.slice(start, Math.min(i, source.length));
|
|
770
|
-
continue;
|
|
771
|
-
}
|
|
772
|
-
if (ch === '#') {
|
|
773
|
-
while (i < source.length && source[i] !== '\n') {
|
|
774
|
-
i++;
|
|
775
|
-
}
|
|
776
|
-
continue;
|
|
777
|
-
}
|
|
778
|
-
out += ch;
|
|
779
|
-
i++;
|
|
780
|
-
}
|
|
781
|
-
return out;
|
|
782
|
-
}
|
|
783
|
-
export const PDF_READ = /(?:PdfReader|append)\s*\(\s*['"]([\w.-]+\.pdf)['"]|clone_from\s*=\s*['"]([\w.-]+\.pdf)['"]|open\s*\(\s*['"]([\w.-]+\.pdf)['"]\s*(?:,\s*(?:mode\s*=\s*)?['"](?<mode>[rwaxb+]+)['"])?/g;
|
|
784
|
-
export const OFFICE_READ = /(?:load_workbook|Document|Presentation)\s*\(\s*['"]([\w.-]+\.(?:xlsx|xlsm|docx|pptx))['"]/g;
|
|
785
|
-
export function checkUnstagedRead(source, inputs) {
|
|
786
|
-
const staged = new Set((inputs ?? []).map((i) => i.path));
|
|
787
|
-
const clean = stripCommentsAndDocstrings(source);
|
|
788
|
-
for (const pattern of [PDF_READ, OFFICE_READ]) {
|
|
789
|
-
const reads = new RegExp(pattern.source, 'g');
|
|
790
|
-
let match;
|
|
791
|
-
while ((match = reads.exec(clean)) !== null) {
|
|
792
|
-
const name = match.slice(1).find((group) => group !== undefined) ?? '';
|
|
793
|
-
const mode = match.groups?.mode;
|
|
794
|
-
if (mode !== undefined && /[wax]/.test(mode)) {
|
|
795
|
-
continue;
|
|
796
|
-
}
|
|
797
|
-
if (staged.has(name)) {
|
|
798
|
-
continue;
|
|
799
|
-
}
|
|
800
|
-
const before = clean.slice(0, match.index);
|
|
801
|
-
if (before.includes(`"${name}"`) || before.includes(`'${name}'`)) {
|
|
802
|
-
continue;
|
|
803
|
-
}
|
|
804
|
-
return (`${name} does not exist in the working directory — it starts empty on every run, so ` +
|
|
805
|
-
'files from earlier calls are gone. Stage the attachment via inputs: ' +
|
|
806
|
-
`[{ "attachmentId": "<id from the tool result that produced it, or from the ` +
|
|
807
|
-
`[Attached file …] line if the user uploaded it>", "path": "${name}" }] ` +
|
|
808
|
-
'and open it by that bare name; if no id for it appears anywhere in the chat, ' +
|
|
809
|
-
'ask the user to attach the file.');
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
return null;
|
|
813
|
-
}
|
|
814
|
-
const ATTACHMENT_ID = /^[0-9a-f]{32}$/i;
|
|
815
|
-
export function missingFileHint(stderr) {
|
|
816
|
-
const name = /FileNotFoundError: \[Errno \d+\] No such file or directory: '([^']+)'/.exec(stderr)?.[1];
|
|
817
|
-
if (!name) {
|
|
818
|
-
return null;
|
|
819
|
-
}
|
|
820
|
-
if (ATTACHMENT_ID.test(name)) {
|
|
821
|
-
return (`"${name}" is an attachment id, not a file name, and nothing is on disk under it. ` +
|
|
822
|
-
'An id belongs in `attachmentId`; `path` is a bare file name you choose, and the code ' +
|
|
823
|
-
`opens that name. Stage it as inputs [{ "attachmentId": "${name}", "path": "photo.png" }] ` +
|
|
824
|
-
'and open "photo.png".');
|
|
825
|
-
}
|
|
826
|
-
return (`the working directory starts empty on every call — ${name} from an earlier run is gone. ` +
|
|
827
|
-
`Stage the chat attachment via inputs [{ "attachmentId": "<id from the tool result that ` +
|
|
828
|
-
`produced it, or from the [Attached file …] line if the user uploaded it>", ` +
|
|
829
|
-
`"path": "${name}" }] and open it by that bare name; if no id for it appears anywhere ` +
|
|
830
|
-
'in the chat, ask the user to attach the file.');
|
|
831
|
-
}
|
|
832
|
-
export function parsePackages(value) {
|
|
833
|
-
if (value === undefined || value === null)
|
|
834
|
-
return undefined;
|
|
835
|
-
if (!Array.isArray(value) || value.some((p) => typeof p !== 'string' || !p.trim())) {
|
|
836
|
-
return { error: 'packages must be an array of non-empty strings' };
|
|
837
|
-
}
|
|
838
|
-
const trimmed = value.map((p) => p.trim());
|
|
839
|
-
if (trimmed.some((p) => p.includes(':'))) {
|
|
840
|
-
return { error: 'packages must be PyPI names, not URLs' };
|
|
841
|
-
}
|
|
842
|
-
return trimmed;
|
|
843
|
-
}
|
|
844
|
-
function inputEntry(value) {
|
|
845
|
-
if (typeof value !== 'object' || value === null)
|
|
846
|
-
return null;
|
|
847
|
-
return {
|
|
848
|
-
attachmentId: 'attachmentId' in value ? value.attachmentId : undefined,
|
|
849
|
-
path: 'path' in value ? value.path : undefined
|
|
850
|
-
};
|
|
851
|
-
}
|
|
852
|
-
export function parseInputs(value) {
|
|
853
|
-
if (value === undefined || value === null)
|
|
854
|
-
return undefined;
|
|
855
|
-
if (!Array.isArray(value)) {
|
|
856
|
-
return { error: 'inputs must be an array' };
|
|
857
|
-
}
|
|
858
|
-
if (value.length > MAX_INPUTS) {
|
|
859
|
-
return { error: `inputs must declare at most ${MAX_INPUTS} files` };
|
|
860
|
-
}
|
|
861
|
-
const parsed = [];
|
|
862
|
-
const paths = new Set();
|
|
863
|
-
for (const raw of value) {
|
|
864
|
-
const entry = inputEntry(raw);
|
|
865
|
-
if (!entry) {
|
|
866
|
-
return { error: 'each input must be an { attachmentId, path } object' };
|
|
867
|
-
}
|
|
868
|
-
const attachmentId = attachmentIdOf(entry.attachmentId);
|
|
869
|
-
if (attachmentId === '') {
|
|
870
|
-
return { error: 'attachmentId must be a non-empty string, or omitted for a user upload' };
|
|
871
|
-
}
|
|
872
|
-
const path = typeof entry.path === 'string' ? entry.path.trim() : '';
|
|
873
|
-
const nameError = checkFileName(path);
|
|
874
|
-
if (nameError) {
|
|
875
|
-
return { error: `input path: ${nameError}` };
|
|
876
|
-
}
|
|
877
|
-
if (paths.has(path)) {
|
|
878
|
-
return { error: 'input paths must be unique' };
|
|
879
|
-
}
|
|
880
|
-
paths.add(path);
|
|
881
|
-
parsed.push({ attachmentId, path });
|
|
882
|
-
}
|
|
883
|
-
return parsed;
|
|
884
|
-
}
|
|
885
|
-
export function parseOutputs(value) {
|
|
886
|
-
if (value === undefined || value === null)
|
|
887
|
-
return undefined;
|
|
888
|
-
if (!Array.isArray(value) || value.some((o) => typeof o !== 'string')) {
|
|
889
|
-
return { error: 'outputs must be an array of file names' };
|
|
890
|
-
}
|
|
891
|
-
if (value.length > MAX_OUTPUTS) {
|
|
892
|
-
return { error: `outputs must declare at most ${MAX_OUTPUTS} files` };
|
|
893
|
-
}
|
|
894
|
-
const trimmed = [...new Set(value.map((o) => o.trim()))];
|
|
895
|
-
for (const name of trimmed) {
|
|
896
|
-
const nameError = checkOutputName(name);
|
|
897
|
-
if (nameError) {
|
|
898
|
-
return { error: `output name: ${nameError}` };
|
|
899
|
-
}
|
|
900
|
-
}
|
|
901
|
-
return trimmed;
|
|
902
|
-
}
|
|
903
|
-
export function parseWorkdir(value) {
|
|
904
|
-
if (value === undefined || value === null)
|
|
905
|
-
return undefined;
|
|
906
|
-
if (typeof value !== 'string') {
|
|
907
|
-
return { error: 'workdir must be a string' };
|
|
908
|
-
}
|
|
909
|
-
const trimmed = value.trim();
|
|
910
|
-
if (!trimmed) {
|
|
911
|
-
return undefined;
|
|
912
|
-
}
|
|
913
|
-
const nameError = checkFileName(trimmed);
|
|
914
|
-
if (nameError) {
|
|
915
|
-
return { error: `workdir: ${nameError}` };
|
|
916
|
-
}
|
|
917
|
-
return trimmed;
|
|
918
|
-
}
|
|
919
|
-
function prepare(args, cwd) {
|
|
920
|
-
const packages = parsePackages(args.packages);
|
|
921
|
-
if (packages && 'error' in packages) {
|
|
922
|
-
return packages;
|
|
923
|
-
}
|
|
924
|
-
const inputs = parseInputs(args.inputs);
|
|
925
|
-
if (inputs && 'error' in inputs) {
|
|
926
|
-
return inputs;
|
|
927
|
-
}
|
|
928
|
-
const outputs = parseOutputs(args.outputs);
|
|
929
|
-
if (outputs && 'error' in outputs) {
|
|
930
|
-
return outputs;
|
|
931
|
-
}
|
|
932
|
-
const workdir = parseWorkdir(cwd);
|
|
933
|
-
if (workdir && typeof workdir === 'object') {
|
|
934
|
-
return workdir;
|
|
935
|
-
}
|
|
936
|
-
return { packages, inputs, outputs, workdir };
|
|
937
|
-
}
|
|
938
|
-
export function missingModuleHint(stderr, { packages, sandbox = false, network = false } = {}) {
|
|
939
|
-
const module = /ModuleNotFoundError: No module named '([^']+)'/.exec(stderr)?.[1];
|
|
940
|
-
if (!module) {
|
|
941
|
-
return null;
|
|
942
|
-
}
|
|
943
|
-
const root = module.split('.')[0] ?? '';
|
|
944
|
-
const tool = videoTool(root);
|
|
945
|
-
if (tool && (!network || isTranscoder(tool))) {
|
|
946
|
-
return network ? TRANSCODE_ERROR : VIDEO_TOOLS_ERROR;
|
|
947
|
-
}
|
|
948
|
-
if (module !== root) {
|
|
949
|
-
const then = sandbox
|
|
950
|
-
? 'If the path is right it ships as its own distribution under a shared namespace, which sandbox mode cannot install: tell the user.'
|
|
951
|
-
: 'If the path is right it ships as its own distribution under a shared namespace, as google.* does: declare that distribution in packages.';
|
|
952
|
-
return `"${module}" failed to import although "${root}" loaded. Check the import path first. ${then}`;
|
|
953
|
-
}
|
|
954
|
-
const distribution = moduleDistribution(root);
|
|
955
|
-
const provider = distribution ?? root;
|
|
956
|
-
const vendored = vendoredSpec(provider);
|
|
957
|
-
if (sandbox && !vendored) {
|
|
958
|
-
return `module "${root}" is not installed, ${SANDBOX_NO_INSTALL}`;
|
|
959
|
-
}
|
|
960
|
-
const spec = vendored ?? provider;
|
|
961
|
-
const renamed = distribution !== null && distribution.toLowerCase() !== root.toLowerCase();
|
|
962
|
-
const declared = (packages ?? []).map(specName);
|
|
963
|
-
if (declared.includes(root.toLowerCase()) && renamed) {
|
|
964
|
-
return `"${root}" was declared in packages but does not provide that module; the distribution that does is "${spec}": put that in packages instead. There is no pip.`;
|
|
965
|
-
}
|
|
966
|
-
if (declared.includes(root.toLowerCase()) || declared.includes(provider.toLowerCase())) {
|
|
967
|
-
return `"${provider}" is already declared in packages and still does not provide "${root}", so declaring it again cannot help. Import the module name the library really exports, or tell the user it is unavailable on this device.`;
|
|
968
|
-
}
|
|
969
|
-
return `module "${root}" is not installed: add "${spec}" to packages (packages: ["${spec}"]) and run the same source again. There is no pip.`;
|
|
970
|
-
}
|
|
971
|
-
export function nonePlaceholderHint(stderr) {
|
|
972
|
-
if (!/AttributeError: 'NoneType' object has no attribute '(text|text_frame)'/.test(stderr)) {
|
|
973
|
-
return null;
|
|
974
|
-
}
|
|
975
|
-
return 'a placeholder the layout does not have reads as None: the blank layout has no title and no body, so shapes.title is None there. Use a layout that owns the placeholder (title+content is commonly index 1), or keep the blank layout and add every text box explicitly with shapes.add_textbox(left, top, width, height).';
|
|
976
|
-
}
|
|
977
|
-
export function slideShapesHint(stderr) {
|
|
978
|
-
const attribute = /AttributeError: 'Slide' object has no attribute '(add_picture|add_textbox|addpicture|addtextbox)'/.exec(stderr)?.[1];
|
|
979
|
-
if (!attribute) {
|
|
980
|
-
return null;
|
|
981
|
-
}
|
|
982
|
-
const method = attribute.startsWith('addp') ? 'add_picture' : 'add_textbox';
|
|
983
|
-
return `a Slide has no add_* methods of its own — they live on its shapes collection: slide.shapes.${method}(...), not slide.${method}(...).`;
|
|
984
|
-
}
|
|
985
|
-
export function shapeFontHint(stderr) {
|
|
986
|
-
const attribute = /AttributeError: '\w*(?:Placeholder|Shape|Slide)\w*' object has no attribute '(font|alignment|text_align|word_wrap|paragraphs|add_paragraph)'/.exec(stderr)?.[1];
|
|
987
|
-
if (!attribute) {
|
|
988
|
-
return null;
|
|
989
|
-
}
|
|
990
|
-
return `"${attribute}" belongs to the text frame or a paragraph inside it, not to the shape: go through shape.text_frame first (shape.text_frame.word_wrap, shape.text_frame.paragraphs[0].font.size, shape.text_frame.paragraphs[0].alignment). shape.text is the one shortcut that reads through to the frame.`;
|
|
991
|
-
}
|
|
992
|
-
export function shapesBackgroundHint(stderr) {
|
|
993
|
-
if (!/AttributeError: '\w*(?:Shapes|Shape|Placeholder)\w*' object has no attribute 'background'/.test(stderr)) {
|
|
994
|
-
return null;
|
|
995
|
-
}
|
|
996
|
-
return "'background' lives on the slide, not on its shapes: fill = slide.background.fill; fill.solid(); fill.fore_color.rgb = RGBColor(...). A shape is tinted through its own shape.fill the same way.";
|
|
997
|
-
}
|
|
998
|
-
export function paragraphFillHint(stderr) {
|
|
999
|
-
if (!/AttributeError: '(?:_Paragraph|_Run|TextFrame)' object has no attribute 'fill'/.test(stderr)) {
|
|
1000
|
-
return null;
|
|
1001
|
-
}
|
|
1002
|
-
return "text has no 'fill': color it through the font — paragraph.font.color.rgb = RGBColor(...). A fill belongs to a shape (shape.fill) or to slide.background.fill, never to a paragraph or text frame.";
|
|
1003
|
-
}
|
|
1004
|
-
export function readOnlyPropertyHint(stderr) {
|
|
1005
|
-
if (!/AttributeError: can't set attribute/.test(stderr))
|
|
1006
|
-
return null;
|
|
1007
|
-
if (!/pptx[/\\]util\.py/.test(stderr))
|
|
1008
|
-
return null;
|
|
1009
|
-
return 'a python-pptx container is read-only: font, text_frame, paragraphs, runs and shapes cannot be assigned, only reached through. Set the leaf property instead — paragraph.font.size = Pt(20) and paragraph.font.bold = True, not paragraph.font = …; and write text with text_frame.text or paragraph.text, never text_frame = …';
|
|
1010
|
-
}
|
|
1011
|
-
export function paragraphIndexHint(stderr, outputs) {
|
|
1012
|
-
if (!/IndexError: tuple index out of range/.test(stderr))
|
|
1013
|
-
return null;
|
|
1014
|
-
if (!outputs.some((name) => name.toLowerCase().endsWith('.pptx')))
|
|
1015
|
-
return null;
|
|
1016
|
-
return 'a new text frame holds exactly one paragraph, so text_frame.paragraphs[1] does not exist yet: write the first through paragraphs[0] (or text_frame.text) and create each one after it with text_frame.add_paragraph(), which returns the new paragraph. A paragraph has .text, .font and .alignment — it has no .paragraphs and no .add_paragraph of its own.';
|
|
1017
|
-
}
|
|
1018
|
-
export function shellNameHint(stderr) {
|
|
1019
|
-
const name = /NameError: name '(python3?|py|pip3?)' is not defined/.exec(stderr)?.[1];
|
|
1020
|
-
if (!name) {
|
|
1021
|
-
return null;
|
|
1022
|
-
}
|
|
1023
|
-
return `"${name}" is not defined because command already runs as Python source — remove the ${name} invocation and pass only the Python code itself`;
|
|
1024
|
-
}
|
|
1025
|
-
export function noProcessHint(stderr, sandbox = false) {
|
|
1026
|
-
if (!/emscripten does not support processes/.test(stderr))
|
|
1027
|
-
return null;
|
|
1028
|
-
const packages = sandbox
|
|
1029
|
-
? ' In sandbox mode only the packages bundled with this app install;'
|
|
1030
|
-
: ' Declare PyPI packages in packages;';
|
|
1031
|
-
return `Python here cannot start processes: there is no shell and no pip from the source.${packages} run a shell command as its own exec call without language.`;
|
|
1032
|
-
}
|
|
1033
|
-
const FETCH_TOOLS = ['http_request', 'web_fetch'];
|
|
1034
|
-
export function noNetworkHint(stderr, tools, network = false) {
|
|
1035
|
-
if (network)
|
|
1036
|
-
return null;
|
|
1037
|
-
if (!/Host is unreachable|Network is unreachable|socket\.gaierror|URLError|Temporary failure in name resolution|NewConnectionError|XMLHttpRequest is not defined/.test(stderr)) {
|
|
1038
|
-
return null;
|
|
1039
|
-
}
|
|
1040
|
-
const failed = 'Python here cannot open network connections (requests, urllib and sockets fail), and retrying will not change that.';
|
|
1041
|
-
const fetchers = FETCH_TOOLS.filter((name) => !tools || tools.includes(name));
|
|
1042
|
-
return fetchers.length
|
|
1043
|
-
? `${failed} Fetch the URL with the ${fetchers.join(' or ')} tool and pass the data into the source.`
|
|
1044
|
-
: `${failed} No tool that fetches a URL is available to you, so tell the user.`;
|
|
1045
|
-
}
|
|
1046
|
-
export function nativeWheelHint(stderr) {
|
|
1047
|
-
const name = /Can't find a pure Python 3 wheel for '([^']+)'/.exec(stderr)?.[1];
|
|
1048
|
-
if (!name) {
|
|
1049
|
-
return null;
|
|
1050
|
-
}
|
|
1051
|
-
return `"${name}" is built from compiled code, and this device installs only pure-Python packages plus the set already built into its Python. Nothing about this call can install it: use a pure-Python library instead, or tell the user it is not available here.`;
|
|
1052
|
-
}
|
|
1053
|
-
export function packageFetchFailedHint(stderr) {
|
|
1054
|
-
const name = /Can't fetch metadata for '([^']+)'/.exec(stderr)?.[1];
|
|
1055
|
-
if (!name) {
|
|
1056
|
-
return null;
|
|
1057
|
-
}
|
|
1058
|
-
return `"${name}" could not be fetched: either it is not a PyPI distribution name or this device has no network. Where a skill documents an exact spec for that library, send that spec verbatim; otherwise the package cannot be installed here — tell the user and stop. Do not try other names.`;
|
|
1059
|
-
}
|
|
1060
|
-
function fail(stderr) {
|
|
1061
|
-
return { stdout: '', stderr, exitCode: 1 };
|
|
1062
|
-
}
|
|
1063
|
-
export const IMAGE_INPUT = /\.(png|jpe?g|gif|webp|bmp|heic|heif|avif|tiff?)$/i;
|
|
1064
|
-
const PPT_MEDIA = b4a.from('ppt/media/');
|
|
1065
|
-
const deckAttachedThisTurn = new WeakMap();
|
|
1066
|
-
export function pptxHasEmbeddedMedia(bytes) {
|
|
1067
|
-
outer: for (let i = 0; i <= bytes.length - PPT_MEDIA.length; i++) {
|
|
1068
|
-
for (let j = 0; j < PPT_MEDIA.length; j++) {
|
|
1069
|
-
if (bytes[i + j] !== PPT_MEDIA[j])
|
|
1070
|
-
continue outer;
|
|
1071
|
-
}
|
|
1072
|
-
return true;
|
|
1073
|
-
}
|
|
1074
|
-
return false;
|
|
1075
|
-
}
|
|
1076
|
-
export function softFailedDeckHint(stdout, exitCode, source) {
|
|
1077
|
-
if (exitCode !== 0)
|
|
1078
|
-
return null;
|
|
1079
|
-
if (!/\bPresentation\s*\(/.test(source))
|
|
1080
|
-
return null;
|
|
1081
|
-
if (!/Image loading error|expected if file not found|cannot import name ['"]RgbColor['"]/i.test(stdout)) {
|
|
1082
|
-
return null;
|
|
1083
|
-
}
|
|
1084
|
-
return ('the deck soft-failed (caught an image/import error and continued): remove try/except ' +
|
|
1085
|
-
'around imports and add_picture, fix the error, and rerun once — a partial deck must not be saved');
|
|
1086
|
-
}
|
|
1087
|
-
export function stagedImagesMissingFromDeck(result, { inputs, outputs, source }) {
|
|
1088
|
-
if (result.exitCode !== 0)
|
|
1089
|
-
return null;
|
|
1090
|
-
if (!/\bPresentation\s*\(/.test(source))
|
|
1091
|
-
return null;
|
|
1092
|
-
const images = (inputs ?? []).filter((i) => IMAGE_INPUT.test(i.path));
|
|
1093
|
-
const [first] = images;
|
|
1094
|
-
if (!first) {
|
|
1095
|
-
return null;
|
|
1096
|
-
}
|
|
1097
|
-
for (const name of outputs ?? []) {
|
|
1098
|
-
if (!name.toLowerCase().endsWith('.pptx'))
|
|
1099
|
-
continue;
|
|
1100
|
-
const bytes = result.files?.get(name);
|
|
1101
|
-
if (!bytes) {
|
|
1102
|
-
continue;
|
|
1103
|
-
}
|
|
1104
|
-
if (!pptxHasEmbeddedMedia(bytes)) {
|
|
1105
|
-
return (`staged image(s) ${images.map((i) => i.path).join(', ')} were not embedded: ` +
|
|
1106
|
-
`call slide.shapes.add_picture("${first.path}", …) without try/except, then save`);
|
|
1107
|
-
}
|
|
1108
|
-
}
|
|
1109
|
-
return null;
|
|
1110
|
-
}
|
|
1111
|
-
export function checkStagedImagesUsed(source, inputs, outputs) {
|
|
1112
|
-
if (!inputs?.length)
|
|
1113
|
-
return null;
|
|
1114
|
-
if (!outputs?.some((n) => n.toLowerCase().endsWith('.pptx')))
|
|
1115
|
-
return null;
|
|
1116
|
-
if (!/\bPresentation\s*\(/.test(source)) {
|
|
1117
|
-
return null;
|
|
1118
|
-
}
|
|
1119
|
-
const images = inputs.filter((i) => IMAGE_INPUT.test(i.path));
|
|
1120
|
-
if (!images.length) {
|
|
1121
|
-
return null;
|
|
1122
|
-
}
|
|
1123
|
-
if (!/\.add_picture\s*\(/.test(source)) {
|
|
1124
|
-
return ('inputs stage image(s) but command never calls slide.shapes.add_picture(...): ' +
|
|
1125
|
-
'embed each staged path or drop it from inputs');
|
|
1126
|
-
}
|
|
1127
|
-
const missing = images.filter((i) => !source.includes(`"${i.path}"`) && !source.includes(`'${i.path}'`));
|
|
1128
|
-
if (missing.length) {
|
|
1129
|
-
return (`inputs stage ${missing.map((m) => m.path).join(', ')} but command never opens those files — ` +
|
|
1130
|
-
`pass the bare path to slide.shapes.add_picture("…")`);
|
|
1131
|
-
}
|
|
1132
|
-
if (/\btry\s*:(?:(?!\bexcept\b|\bfinally\b)[\s\S]){0,1200}?\badd_picture\b/.test(source)) {
|
|
1133
|
-
return 'do not wrap add_picture in try/except: if the image fails the run must fail so you can fix it';
|
|
1134
|
-
}
|
|
1135
|
-
return null;
|
|
1136
|
-
}
|
|
1137
|
-
export function checkTurnImagesStaged(source, { inputs, outputs, turnImages }) {
|
|
1138
|
-
if (!turnImages?.length)
|
|
1139
|
-
return null;
|
|
1140
|
-
if (!outputs?.some((n) => n.toLowerCase().endsWith('.pptx')))
|
|
1141
|
-
return null;
|
|
1142
|
-
if (!/\bPresentation\s*\(/.test(source)) {
|
|
1143
|
-
return null;
|
|
1144
|
-
}
|
|
1145
|
-
if ((inputs ?? []).some((i) => i.attachmentId === undefined)) {
|
|
1146
|
-
return null;
|
|
1147
|
-
}
|
|
1148
|
-
return (`the user's message has ${turnImages.length} uploaded image(s) but inputs stage none of them — ` +
|
|
1149
|
-
'add one id-less { "path": "…" } entry per image and embed each with slide.shapes.add_picture(...)');
|
|
1150
|
-
}
|
|
1151
|
-
export function deckDeliveredStop(attachments, exitCode, source) {
|
|
1152
|
-
if (exitCode !== 0 || !attachments?.length)
|
|
1153
|
-
return null;
|
|
1154
|
-
if (source !== undefined && !/\bpptx\b|\bPresentation\s*\(/.test(source)) {
|
|
1155
|
-
return null;
|
|
1156
|
-
}
|
|
1157
|
-
const decks = attachments.filter((a) => a.fileName.toLowerCase().endsWith('.pptx'));
|
|
1158
|
-
if (decks.length === 0) {
|
|
1159
|
-
return null;
|
|
1160
|
-
}
|
|
1161
|
-
const names = decks.map((a) => a.fileName).join(', ');
|
|
1162
|
-
const verb = decks.length === 1 ? 'is' : 'are';
|
|
1163
|
-
return (`${names} ${verb} attached to the chat. STOP: do not call exec again for this deck. ` +
|
|
1164
|
-
'A second exec that rebuilds the same .pptx will be rejected. ' +
|
|
1165
|
-
'Reply to the user with one line naming the file and slide count from stdout — nothing else.');
|
|
1166
|
-
}
|
|
1167
|
-
async function stage(inputs, fetchAttachment, opts = {}) {
|
|
1168
|
-
if (!inputs?.length)
|
|
1169
|
-
return undefined;
|
|
1170
|
-
if (!fetchAttachment) {
|
|
1171
|
-
return { error: 'this device cannot read chat attachments' };
|
|
1172
|
-
}
|
|
1173
|
-
return stageInputs(fetchAttachment, inputs, opts);
|
|
1174
|
-
}
|
|
1175
|
-
async function collect(result, { declared, attach, runBudget, source }) {
|
|
1176
|
-
const base = {
|
|
1177
|
-
stdout: result.stdout,
|
|
1178
|
-
stderr: result.stderr,
|
|
1179
|
-
exitCode: result.exitCode
|
|
1180
|
-
};
|
|
1181
|
-
if (!declared?.length || !attach) {
|
|
1182
|
-
return base;
|
|
1183
|
-
}
|
|
1184
|
-
const pptxBuild = source !== undefined && /\bpptx\b|\bPresentation\s*\(/.test(source);
|
|
1185
|
-
const pptxNames = declared.filter((n) => n.toLowerCase().endsWith('.pptx') && result.files?.has(n));
|
|
1186
|
-
const wouldAttachPptx = result.exitCode === 0 && pptxBuild && pptxNames.length > 0;
|
|
1187
|
-
if (wouldAttachPptx) {
|
|
1188
|
-
const attached = deckAttachedThisTurn.get(attach);
|
|
1189
|
-
if (attached) {
|
|
1190
|
-
const collision = pptxNames.find((n) => attached.has(n.toLowerCase()));
|
|
1191
|
-
if (collision) {
|
|
1192
|
-
return fail(`"${collision}" was already attached this turn — do not rebuild it; reply to the user with the file name and slide count`);
|
|
1193
|
-
}
|
|
1194
|
-
}
|
|
1195
|
-
}
|
|
1196
|
-
const { attachments, missingOutputs, rejectedOutputs } = await attachOutputs(attach, (result.exitCode === 0 && result.files) || new Map(), { declared, runBudget });
|
|
1197
|
-
const rejected = [...(result.rejected ?? []), ...rejectedOutputs];
|
|
1198
|
-
const stop = deckDeliveredStop(attachments, result.exitCode, source);
|
|
1199
|
-
if (stop && result.exitCode === 0) {
|
|
1200
|
-
let attached = deckAttachedThisTurn.get(attach);
|
|
1201
|
-
if (!attached) {
|
|
1202
|
-
attached = new Set();
|
|
1203
|
-
deckAttachedThisTurn.set(attach, attached);
|
|
1204
|
-
}
|
|
1205
|
-
for (const n of pptxNames) {
|
|
1206
|
-
attached.add(n.toLowerCase());
|
|
1207
|
-
}
|
|
1208
|
-
}
|
|
1209
|
-
const stdout = stop && result.exitCode === 0
|
|
1210
|
-
? `${base.stdout}${base.stdout && !base.stdout.endsWith('\n') ? '\n' : ''}${stop}`
|
|
1211
|
-
: base.stdout;
|
|
1212
|
-
return {
|
|
1213
|
-
...base,
|
|
1214
|
-
stdout,
|
|
1215
|
-
attachments: attachments.length > 0 ? attachments : undefined,
|
|
1216
|
-
missingOutputs: missingOutputs.length > 0 ? missingOutputs : undefined,
|
|
1217
|
-
rejectedOutputs: rejected.length > 0 ? rejected : undefined
|
|
1218
|
-
};
|
|
1219
|
-
}
|
|
1220
|
-
export function createPythonAdapter(disabled, loadPyodide, network = false) {
|
|
1221
|
-
return {
|
|
1222
|
-
resolve(args, ctx) {
|
|
1223
|
-
if (!runsThroughPyodide(args.language, disabled))
|
|
1224
|
-
return null;
|
|
1225
|
-
const command = String(args.command ?? '').trim();
|
|
1226
|
-
const attach = ctx?.attach;
|
|
1227
|
-
const fetchAttachment = ctx?.fetchAttachment;
|
|
1228
|
-
const turnImages = ctx?.turnImages;
|
|
1229
|
-
const runBudget = ctx?.runBudget;
|
|
1230
|
-
const sandbox = ctx?.sandboxMode === true;
|
|
1231
|
-
const toolNames = ctx?.toolNames;
|
|
1232
|
-
const approved = ctx?.approval === 'allowed' || ctx?.approval === 'skip-all';
|
|
1233
|
-
const reach = network && !sandbox && approved;
|
|
1234
|
-
const gated = reach && ctx?.approval === 'allowed';
|
|
1235
|
-
const confirmConnect = ctx?.confirmConnect;
|
|
1236
|
-
return {
|
|
1237
|
-
async run(options) {
|
|
1238
|
-
if (!command) {
|
|
1239
|
-
return fail('command is required');
|
|
1240
|
-
}
|
|
1241
|
-
const sourceError = checkPythonSource(command);
|
|
1242
|
-
if (sourceError) {
|
|
1243
|
-
return fail(sourceError);
|
|
1244
|
-
}
|
|
1245
|
-
const source = normalizeFpdfSource(unwrapPythonSource(command) ?? command);
|
|
1246
|
-
const prepared = prepare(args, options.cwd);
|
|
1247
|
-
if ('error' in prepared) {
|
|
1248
|
-
return fail(prepared.error);
|
|
1249
|
-
}
|
|
1250
|
-
const pptxError = checkPptxBuildSource(source, prepared.outputs, prepared.packages);
|
|
1251
|
-
if (pptxError) {
|
|
1252
|
-
return fail(pptxError);
|
|
1253
|
-
}
|
|
1254
|
-
const pdfError = checkPdfBuildSource(source, prepared.outputs, prepared.packages);
|
|
1255
|
-
if (pdfError) {
|
|
1256
|
-
return fail(pdfError);
|
|
1257
|
-
}
|
|
1258
|
-
const bareLength = checkBareLengthArgs(source, prepared.packages);
|
|
1259
|
-
if (bareLength) {
|
|
1260
|
-
return fail(bareLength);
|
|
1261
|
-
}
|
|
1262
|
-
const unstagedRead = checkUnstagedRead(source, prepared.inputs);
|
|
1263
|
-
if (unstagedRead) {
|
|
1264
|
-
return fail(unstagedRead);
|
|
1265
|
-
}
|
|
1266
|
-
const stagedUse = checkStagedImagesUsed(source, prepared.inputs, prepared.outputs);
|
|
1267
|
-
if (stagedUse) {
|
|
1268
|
-
return fail(stagedUse);
|
|
1269
|
-
}
|
|
1270
|
-
const turnStage = checkTurnImagesStaged(source, {
|
|
1271
|
-
inputs: prepared.inputs,
|
|
1272
|
-
outputs: prepared.outputs,
|
|
1273
|
-
turnImages
|
|
1274
|
-
});
|
|
1275
|
-
if (turnStage) {
|
|
1276
|
-
return fail(turnStage);
|
|
1277
|
-
}
|
|
1278
|
-
if (prepared.outputs?.length && !attach) {
|
|
1279
|
-
return fail('this device cannot persist produced files');
|
|
1280
|
-
}
|
|
1281
|
-
const staged = await stage(prepared.inputs, fetchAttachment, {
|
|
1282
|
-
turnImages,
|
|
1283
|
-
signal: options.signal
|
|
1284
|
-
});
|
|
1285
|
-
if (staged && 'error' in staged) {
|
|
1286
|
-
return fail(staged.error);
|
|
1287
|
-
}
|
|
1288
|
-
const install = pipInstallTargets(command)?.map(pinned) ?? null;
|
|
1289
|
-
const packages = install
|
|
1290
|
-
? [...new Set([...(prepared.packages ?? []), ...install])]
|
|
1291
|
-
: prepared.packages;
|
|
1292
|
-
const refusal = sandbox ? sandboxInstallError(command, prepared.packages) : null;
|
|
1293
|
-
if (refusal) {
|
|
1294
|
-
return fail(refusal);
|
|
1295
|
-
}
|
|
1296
|
-
const result = await runPython(install ? 'pass' : source, {
|
|
1297
|
-
timeoutMs: options.timeoutMs,
|
|
1298
|
-
maxOutputChars: options.maxOutputChars,
|
|
1299
|
-
signal: options.signal,
|
|
1300
|
-
packages,
|
|
1301
|
-
inputs: staged?.files,
|
|
1302
|
-
outputs: prepared.outputs,
|
|
1303
|
-
workdir: prepared.workdir,
|
|
1304
|
-
loadPyodide,
|
|
1305
|
-
network: reach,
|
|
1306
|
-
hosts: gated ? namedHosts(source) : undefined,
|
|
1307
|
-
askConnect: gated ? confirmConnect : undefined
|
|
1308
|
-
});
|
|
1309
|
-
const soft = softFailedDeckHint(result.stdout, result.exitCode, source);
|
|
1310
|
-
if (soft) {
|
|
1311
|
-
return fail(soft);
|
|
1312
|
-
}
|
|
1313
|
-
const missingPic = stagedImagesMissingFromDeck(result, {
|
|
1314
|
-
inputs: prepared.inputs,
|
|
1315
|
-
outputs: prepared.outputs,
|
|
1316
|
-
source
|
|
1317
|
-
});
|
|
1318
|
-
if (missingPic) {
|
|
1319
|
-
return fail(missingPic);
|
|
1320
|
-
}
|
|
1321
|
-
const hint = packageFetchFailedHint(result.stderr) ??
|
|
1322
|
-
nativeWheelHint(result.stderr) ??
|
|
1323
|
-
missingModuleHint(result.stderr, { packages, sandbox, network: reach }) ??
|
|
1324
|
-
pipFromSourceHint(result.stderr, source, { packages, sandbox }) ??
|
|
1325
|
-
noProcessHint(result.stderr, sandbox) ??
|
|
1326
|
-
noNetworkHint(result.stderr, toolNames, reach) ??
|
|
1327
|
-
missingFileHint(result.stderr) ??
|
|
1328
|
-
rgbColorImportHint(result.stderr) ??
|
|
1329
|
-
nonePlaceholderHint(result.stderr) ??
|
|
1330
|
-
slideShapesHint(result.stderr) ??
|
|
1331
|
-
shapeFontHint(result.stderr) ??
|
|
1332
|
-
shapesBackgroundHint(result.stderr) ??
|
|
1333
|
-
paragraphFillHint(result.stderr) ??
|
|
1334
|
-
readOnlyPropertyHint(result.stderr) ??
|
|
1335
|
-
paragraphIndexHint(result.stderr, prepared.outputs ?? []) ??
|
|
1336
|
-
fpdfTextErrorHint(result.stderr) ??
|
|
1337
|
-
fpdfKeywordErrorHint(result.stderr) ??
|
|
1338
|
-
fpdfHorizontalSpaceHint(result.stderr) ??
|
|
1339
|
-
fpdfUnicodeErrorHint(result.stderr) ??
|
|
1340
|
-
shellNameHint(result.stderr) ??
|
|
1341
|
-
syntaxErrorHint(result.stderr, source) ??
|
|
1342
|
-
mangledPptxApiHint(source);
|
|
1343
|
-
const hinted = hint ? { ...result, stderr: `${result.stderr}\n${hint}` } : result;
|
|
1344
|
-
const installed = install && result.exitCode === 0
|
|
1345
|
-
? {
|
|
1346
|
-
...hinted,
|
|
1347
|
-
stdout: `installed: ${packages?.join(', ')}\nnothing was run — call exec again with language "python", packages: ${JSON.stringify(packages ?? [])} and the Python source in command\n${hinted.stdout}`
|
|
1348
|
-
}
|
|
1349
|
-
: hinted;
|
|
1350
|
-
const undelivered = result.undeclared?.length
|
|
1351
|
-
? {
|
|
1352
|
-
...installed,
|
|
1353
|
-
stderr: `${installed.stderr}${installed.stderr ? '\n' : ''}${result.undeclared.join(', ')} ${result.undeclared.length === 1 ? 'was' : 'were'} written but not declared in outputs, so ${result.undeclared.length === 1 ? 'it was' : 'they were'} discarded and nothing reached the user. There is no shell to inspect it with and nothing to look for on disk: declare it in outputs and run the same code again.`
|
|
1354
|
-
}
|
|
1355
|
-
: installed;
|
|
1356
|
-
return collect(undelivered, {
|
|
1357
|
-
declared: prepared.outputs,
|
|
1358
|
-
attach,
|
|
1359
|
-
runBudget,
|
|
1360
|
-
source
|
|
1361
|
-
});
|
|
1362
|
-
}
|
|
1363
|
-
};
|
|
1364
|
-
}
|
|
1365
|
-
};
|
|
1366
|
-
}
|
|
1367
|
-
function attachmentIdOf(value) {
|
|
1368
|
-
if (value === undefined)
|
|
1369
|
-
return undefined;
|
|
1370
|
-
return typeof value === 'string' ? value.trim() : '';
|
|
1371
|
-
}
|