@empiricalrun/test-gen 0.77.0 → 0.78.1
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 +25 -0
- package/dist/actions/index.d.ts +0 -1
- package/dist/actions/index.d.ts.map +1 -1
- package/dist/actions/index.js +0 -10
- package/dist/agent/base/index.d.ts +28 -19
- package/dist/agent/base/index.d.ts.map +1 -1
- package/dist/agent/base/index.js +30 -17
- package/dist/agent/browsing/run.d.ts +1 -1
- package/dist/agent/browsing/run.d.ts.map +1 -1
- package/dist/agent/chat/agent-loop.d.ts +5 -5
- package/dist/agent/chat/agent-loop.d.ts.map +1 -1
- package/dist/agent/chat/exports.d.ts +3 -3
- package/dist/agent/chat/exports.d.ts.map +1 -1
- package/dist/agent/chat/exports.js +5 -11
- package/dist/agent/chat/index.d.ts +4 -3
- package/dist/agent/chat/index.d.ts.map +1 -1
- package/dist/agent/chat/index.js +10 -5
- package/dist/agent/chat/models.d.ts +1 -1
- package/dist/agent/chat/models.d.ts.map +1 -1
- package/dist/agent/chat/models.js +3 -3
- package/dist/agent/chat/prompt/pw-utils-docs.d.ts +1 -1
- package/dist/agent/chat/prompt/pw-utils-docs.d.ts.map +1 -1
- package/dist/agent/chat/prompt/pw-utils-docs.js +42 -0
- package/dist/agent/chat/prompt/repo.d.ts +2 -2
- package/dist/agent/chat/prompt/repo.d.ts.map +1 -1
- package/dist/agent/chat/prompt/repo.js +2 -2
- package/dist/agent/chat/state.d.ts +13 -25
- package/dist/agent/chat/state.d.ts.map +1 -1
- package/dist/agent/chat/state.js +10 -60
- package/dist/agent/chat/utils.d.ts +5 -5
- package/dist/agent/chat/utils.d.ts.map +1 -1
- package/dist/agent/cli.d.ts +2 -2
- package/dist/agent/cli.d.ts.map +1 -1
- package/dist/agent/cli.js +17 -31
- package/dist/agent/code-review/index.d.ts +5 -4
- package/dist/agent/code-review/index.d.ts.map +1 -1
- package/dist/agent/code-review/index.js +13 -4
- package/dist/agent/code-review/types.d.ts +2 -35
- package/dist/agent/code-review/types.d.ts.map +1 -1
- package/dist/agent/code-review/types.js +4 -11
- package/dist/agent/cua/index.d.ts +1 -1
- package/dist/agent/cua/index.d.ts.map +1 -1
- package/dist/agent/cua/index.js +13 -5
- package/dist/agent/cua/pw-codegen/pw-pause/for-recorder.d.ts.map +1 -1
- package/dist/agent/cua/pw-codegen/pw-pause/for-recorder.js +0 -3
- package/dist/agent/cua/pw-codegen/pw-pause/index.js +1 -1
- package/dist/agent/index.d.ts +1 -5
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +1 -11
- package/dist/agent/master/element-annotation.d.ts +1 -1
- package/dist/agent/master/element-annotation.d.ts.map +1 -1
- package/dist/agent/master/next-action.d.ts +1 -1
- package/dist/agent/master/next-action.d.ts.map +1 -1
- package/dist/agent/master/next-action.js +1 -6
- package/dist/agent/master/run.d.ts +3 -2
- package/dist/agent/master/run.d.ts.map +1 -1
- package/dist/agent/master/run.js +0 -26
- package/dist/agent/triage/index.d.ts +4 -3
- package/dist/agent/triage/index.d.ts.map +1 -1
- package/dist/agent/triage/index.js +35 -29
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.d.ts.map +1 -1
- package/dist/artifacts/utils.d.ts +1 -1
- package/dist/artifacts/utils.d.ts.map +1 -1
- package/dist/bin/environments.d.ts +1 -1
- package/dist/bin/environments.d.ts.map +1 -1
- package/dist/bin/index.js +2 -57
- package/dist/bin/setup.d.ts +1 -1
- package/dist/bin/setup.d.ts.map +1 -1
- package/dist/bin/utils/fs/index.d.ts +1 -1
- package/dist/bin/utils/fs/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.d.ts +2 -2
- package/dist/bin/utils/platform/web/index.d.ts.map +1 -1
- package/dist/bin/utils/platform/web/index.js +1 -1
- package/dist/bin/utils/scenarios/index.d.ts +1 -1
- package/dist/bin/utils/scenarios/index.d.ts.map +1 -1
- package/dist/constants/index.d.ts +0 -4
- package/dist/constants/index.d.ts.map +1 -1
- package/dist/constants/index.js +0 -6
- package/dist/dashboard/client.d.ts +1 -1
- package/dist/dashboard/client.d.ts.map +1 -1
- package/dist/dashboard/index.d.ts +1 -0
- package/dist/dashboard/index.d.ts.map +1 -1
- package/dist/dashboard/index.js +4 -1
- package/dist/dashboard/tool-response.d.ts +5 -0
- package/dist/dashboard/tool-response.d.ts.map +1 -0
- package/dist/dashboard/tool-response.js +88 -0
- package/dist/dashboard/totp.js +1 -1
- package/dist/file/server.d.ts +1 -1
- package/dist/file/server.d.ts.map +1 -1
- package/dist/file/server.js +2 -1
- package/dist/file-info/adapters/file-system/index.d.ts +1 -1
- package/dist/file-info/adapters/file-system/index.d.ts.map +1 -1
- package/dist/file-info/adapters/file-system/reader.d.ts +1 -1
- package/dist/file-info/adapters/file-system/reader.d.ts.map +1 -1
- package/dist/file-info/adapters/github/index.d.ts +2 -1
- package/dist/file-info/adapters/github/index.d.ts.map +1 -1
- package/dist/file-info/adapters/github/reader.d.ts +2 -1
- package/dist/file-info/adapters/github/reader.d.ts.map +1 -1
- package/dist/recorder/index.d.ts.map +1 -1
- package/dist/recorder/index.js +2 -1
- package/dist/recorder/upload.d.ts +1 -1
- package/dist/recorder/upload.d.ts.map +1 -1
- package/dist/tools/analyse-video/index.d.ts +1 -1
- package/dist/tools/analyse-video/index.d.ts.map +1 -1
- package/dist/tools/analyse-video/index.js +28 -15
- package/dist/tools/create-pull-request/index.d.ts +1 -1
- package/dist/tools/create-pull-request/index.d.ts.map +1 -1
- package/dist/tools/create-pull-request/utils.d.ts +2 -1
- package/dist/tools/create-pull-request/utils.d.ts.map +1 -1
- package/dist/tools/definitions/analyse-video.d.ts +9 -19
- package/dist/tools/definitions/analyse-video.d.ts.map +1 -1
- package/dist/tools/definitions/analyse-video.js +13 -26
- package/dist/tools/definitions/delete-file.d.ts +9 -1
- package/dist/tools/definitions/delete-file.d.ts.map +1 -1
- package/dist/tools/definitions/delete-file.js +3 -3
- package/dist/tools/definitions/download-build.d.ts +1 -1
- package/dist/tools/definitions/download-build.d.ts.map +1 -1
- package/dist/tools/definitions/grep.d.ts +1 -1
- package/dist/tools/definitions/grep.d.ts.map +1 -1
- package/dist/tools/definitions/list-tests-and-projects.d.ts +1 -1
- package/dist/tools/definitions/list-tests-and-projects.d.ts.map +1 -1
- package/dist/tools/definitions/list-tests-and-projects.js +1 -1
- package/dist/tools/definitions/merge-conflicts.d.ts +1 -1
- package/dist/tools/definitions/merge-conflicts.d.ts.map +1 -1
- package/dist/tools/definitions/merge-conflicts.js +2 -2
- package/dist/tools/definitions/rename-file.d.ts +1 -1
- package/dist/tools/definitions/rename-file.d.ts.map +1 -1
- package/dist/tools/definitions/review-pull-request.d.ts +1 -1
- package/dist/tools/definitions/review-pull-request.d.ts.map +1 -1
- package/dist/tools/definitions/review-pull-request.js +1 -1
- package/dist/tools/definitions/run-test.d.ts +1 -1
- package/dist/tools/definitions/run-test.d.ts.map +1 -1
- package/dist/tools/definitions/str_replace_editor.d.ts +1 -1
- package/dist/tools/definitions/str_replace_editor.d.ts.map +1 -1
- package/dist/tools/definitions/test-gen-browser.d.ts +1 -1
- package/dist/tools/definitions/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/definitions/upgrade-packages.d.ts +1 -1
- package/dist/tools/definitions/upgrade-packages.d.ts.map +1 -1
- package/dist/tools/definitions/utils.js +1 -1
- package/dist/tools/delete-file/index.d.ts +1 -1
- package/dist/tools/delete-file/index.d.ts.map +1 -1
- package/dist/tools/delete-file/index.js +6 -2
- package/dist/tools/diagnosis-fetcher.d.ts +1 -1
- package/dist/tools/diagnosis-fetcher.d.ts.map +1 -1
- package/dist/tools/diagnosis-fetcher.js +92 -47
- package/dist/tools/download-build/index.d.ts +1 -1
- package/dist/tools/download-build/index.d.ts.map +1 -1
- package/dist/tools/executor/base.d.ts +4 -3
- package/dist/tools/executor/base.d.ts.map +1 -1
- package/dist/tools/executor/base.js +16 -2
- package/dist/tools/executor/index.d.ts +3 -0
- package/dist/tools/executor/index.d.ts.map +1 -1
- package/dist/tools/executor/index.js +10 -10
- package/dist/tools/executor/utils/checkpoint.d.ts.map +1 -1
- package/dist/tools/executor/utils/checkpoint.js +0 -4
- package/dist/tools/executor/utils/git.d.ts +7 -1
- package/dist/tools/executor/utils/git.d.ts.map +1 -1
- package/dist/tools/executor/utils/git.js +10 -3
- package/dist/tools/executor/utils/index.d.ts +4 -3
- package/dist/tools/executor/utils/index.d.ts.map +1 -1
- package/dist/tools/executor/utils/index.js +2 -1
- package/dist/tools/executor/utils/pr-description.d.ts +1 -1
- package/dist/tools/executor/utils/pr-description.d.ts.map +1 -1
- package/dist/tools/fetch-file/index.d.ts +1 -1
- package/dist/tools/fetch-file/index.d.ts.map +1 -1
- package/dist/tools/fetch-file/index.js +53 -13
- package/dist/tools/fetch-file/utils.d.ts +3 -0
- package/dist/tools/fetch-file/utils.d.ts.map +1 -0
- package/dist/tools/fetch-file/utils.js +136 -0
- package/dist/tools/fetch-session-diff/index.d.ts +1 -1
- package/dist/tools/fetch-session-diff/index.d.ts.map +1 -1
- package/dist/tools/fetch-session-diff/index.js +26 -2
- package/dist/tools/file-operations/create.d.ts +1 -1
- package/dist/tools/file-operations/create.d.ts.map +1 -1
- package/dist/tools/file-operations/index.d.ts +2 -1
- package/dist/tools/file-operations/index.d.ts.map +1 -1
- package/dist/tools/file-operations/insert.d.ts +1 -1
- package/dist/tools/file-operations/insert.d.ts.map +1 -1
- package/dist/tools/file-operations/replace.d.ts +1 -1
- package/dist/tools/file-operations/replace.d.ts.map +1 -1
- package/dist/tools/file-operations/replace.js +20 -22
- package/dist/tools/file-operations/shared/helpers.d.ts +3 -5
- package/dist/tools/file-operations/shared/helpers.d.ts.map +1 -1
- package/dist/tools/file-operations/shared/helpers.js +1 -5
- package/dist/tools/file-operations/view/index.d.ts +2 -1
- package/dist/tools/file-operations/view/index.d.ts.map +1 -1
- package/dist/tools/grep/index.d.ts +1 -1
- package/dist/tools/grep/index.d.ts.map +1 -1
- package/dist/tools/grep/index.js +15 -12
- package/dist/tools/index.d.ts +3 -24
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +13 -42
- package/dist/tools/issues-v1/create-issue.d.ts +3 -0
- package/dist/tools/issues-v1/create-issue.d.ts.map +1 -0
- package/dist/tools/{issues → issues-v1}/create-issue.js +5 -9
- package/dist/tools/issues-v1/index.d.ts.map +1 -0
- package/dist/tools/issues-v1/list-issues.d.ts +3 -0
- package/dist/tools/issues-v1/list-issues.d.ts.map +1 -0
- package/dist/tools/issues-v1/update-issue.d.ts +3 -0
- package/dist/tools/issues-v1/update-issue.d.ts.map +1 -0
- package/dist/tools/{issues → issues-v1}/update-issue.js +1 -9
- package/dist/tools/{issues → issues-v1}/utils.d.ts +2 -1
- package/dist/tools/issues-v1/utils.d.ts.map +1 -0
- package/dist/tools/issues-v2/create-issue.d.ts +3 -0
- package/dist/tools/issues-v2/create-issue.d.ts.map +1 -0
- package/dist/tools/issues-v2/create-issue.js +86 -0
- package/dist/tools/issues-v2/update-issue.d.ts +3 -0
- package/dist/tools/issues-v2/update-issue.d.ts.map +1 -0
- package/dist/tools/issues-v2/update-issue.js +87 -0
- package/dist/tools/list-environments.d.ts +1 -1
- package/dist/tools/list-environments.d.ts.map +1 -1
- package/dist/tools/list-tests-and-projects/index.d.ts +1 -1
- package/dist/tools/list-tests-and-projects/index.d.ts.map +1 -1
- package/dist/tools/list-tests-and-projects/index.js +14 -4
- package/dist/tools/merge-conflicts/index.d.ts +1 -1
- package/dist/tools/merge-conflicts/index.d.ts.map +1 -1
- package/dist/tools/merge-conflicts/index.js +23 -10
- package/dist/tools/rename-file/index.d.ts +1 -1
- package/dist/tools/rename-file/index.d.ts.map +1 -1
- package/dist/tools/rename-file/index.js +0 -1
- package/dist/tools/review-pull-request/index.d.ts +1 -1
- package/dist/tools/review-pull-request/index.d.ts.map +1 -1
- package/dist/tools/review-pull-request/index.js +9 -15
- package/dist/tools/run-test.d.ts +1 -1
- package/dist/tools/run-test.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.d.ts +1 -1
- package/dist/tools/test-gen-browser.d.ts.map +1 -1
- package/dist/tools/test-gen-browser.js +55 -19
- package/dist/tools/test-run-fetcher/index.d.ts +2 -2
- package/dist/tools/test-run-fetcher/index.d.ts.map +1 -1
- package/dist/tools/test-run-fetcher/index.js +67 -66
- package/dist/tools/trace-dot-zip/index.d.ts +1 -1
- package/dist/tools/trace-dot-zip/index.d.ts.map +1 -1
- package/dist/tools/trace-dot-zip/utils/network-trace.d.ts.map +1 -1
- package/dist/tools/trace-dot-zip/utils/network-trace.js +5 -10
- package/dist/tools/triage-summary/index.d.ts +1 -1
- package/dist/tools/triage-summary/index.d.ts.map +1 -1
- package/dist/tools/triage-summary/index.js +5 -2
- package/dist/tools/triage-summary/utils.d.ts +1 -1
- package/dist/tools/triage-summary/utils.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/index.d.ts +1 -1
- package/dist/tools/upgrade-packages/index.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/index.js +18 -8
- package/dist/tools/upgrade-packages/utils.d.ts +10 -5
- package/dist/tools/upgrade-packages/utils.d.ts.map +1 -1
- package/dist/tools/upgrade-packages/utils.js +57 -16
- package/dist/tools/utils/queue.d.ts +1 -1
- package/dist/tools/utils/queue.d.ts.map +1 -1
- package/dist/tools/utils/validate-schema.d.ts +3 -0
- package/dist/tools/utils/validate-schema.d.ts.map +1 -0
- package/dist/tools/utils/validate-schema.js +22 -0
- package/dist/trace-utils/index.d.ts +1 -1
- package/dist/trace-utils/index.d.ts.map +1 -1
- package/dist/trace-utils/index.js +1 -1
- package/dist/utils/SQSClient.d.ts +1 -1
- package/dist/utils/SQSClient.d.ts.map +1 -1
- package/dist/utils/dedup/dedup-image.d.ts +22 -0
- package/dist/utils/dedup/dedup-image.d.ts.map +1 -0
- package/dist/utils/dedup/dedup-image.js +26 -0
- package/dist/utils/dedup/find-threshold.d.ts +2 -0
- package/dist/utils/dedup/find-threshold.d.ts.map +1 -0
- package/dist/utils/{find-threshold.js → dedup/find-threshold.js} +2 -15
- package/dist/utils/model.d.ts +1 -1
- package/dist/utils/model.d.ts.map +1 -1
- package/dist/utils/model.js +4 -3
- package/dist/utils/playwright-report-parser.d.ts +1 -1
- package/dist/utils/playwright-report-parser.d.ts.map +1 -1
- package/dist/utils/playwright-test-id.d.ts +8 -0
- package/dist/utils/playwright-test-id.d.ts.map +1 -0
- package/dist/utils/playwright-test-id.js +21 -0
- package/dist/utils/repo-tree.d.ts +1 -1
- package/dist/utils/repo-tree.d.ts.map +1 -1
- package/dist/utils/slug.d.ts.map +1 -1
- package/dist/utils/slug.js +15 -4
- package/dist/utils/url-validation.d.ts +2 -0
- package/dist/utils/url-validation.d.ts.map +1 -0
- package/dist/utils/url-validation.js +16 -0
- package/dist/video-core/index.d.ts +14 -36
- package/dist/video-core/index.d.ts.map +1 -1
- package/dist/video-core/index.js +118 -181
- package/dist/video-core/model-limits.d.ts +2 -2
- package/dist/video-core/model-limits.d.ts.map +1 -1
- package/dist/video-core/model-limits.js +16 -20
- package/dist/video-core/storage-manager.d.ts +2 -1
- package/dist/video-core/storage-manager.d.ts.map +1 -1
- package/dist/video-core/storage-manager.js +13 -6
- package/dist/video-core/types.d.ts +1 -1
- package/dist/video-core/types.d.ts.map +1 -1
- package/dist/video-core/utils.d.ts +5 -17
- package/dist/video-core/utils.d.ts.map +1 -1
- package/dist/video-core/utils.js +39 -149
- package/package.json +10 -5
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/actions/skill.d.ts +0 -21
- package/dist/actions/skill.d.ts.map +0 -1
- package/dist/actions/skill.js +0 -127
- package/dist/agent/chat/filesystem-cache.d.ts +0 -12
- package/dist/agent/chat/filesystem-cache.d.ts.map +0 -1
- package/dist/agent/chat/filesystem-cache.js +0 -101
- package/dist/agent/codegen/create-test-block.d.ts +0 -8
- package/dist/agent/codegen/create-test-block.d.ts.map +0 -1
- package/dist/agent/codegen/create-test-block.js +0 -47
- package/dist/agent/codegen/fix-ts-errors.d.ts +0 -12
- package/dist/agent/codegen/fix-ts-errors.d.ts.map +0 -1
- package/dist/agent/codegen/fix-ts-errors.js +0 -78
- package/dist/agent/codegen/lexical-scoped-vars.d.ts +0 -9
- package/dist/agent/codegen/lexical-scoped-vars.d.ts.map +0 -1
- package/dist/agent/codegen/lexical-scoped-vars.js +0 -55
- package/dist/agent/codegen/skills-retriever.d.ts +0 -26
- package/dist/agent/codegen/skills-retriever.d.ts.map +0 -1
- package/dist/agent/codegen/skills-retriever.js +0 -93
- package/dist/agent/codegen/test-update-feedback.d.ts +0 -12
- package/dist/agent/codegen/test-update-feedback.d.ts.map +0 -1
- package/dist/agent/codegen/test-update-feedback.js +0 -49
- package/dist/agent/codegen/types.d.ts +0 -25
- package/dist/agent/codegen/types.d.ts.map +0 -1
- package/dist/agent/codegen/types.js +0 -8
- package/dist/agent/codegen/update-flow.d.ts +0 -36
- package/dist/agent/codegen/update-flow.d.ts.map +0 -1
- package/dist/agent/codegen/update-flow.js +0 -259
- package/dist/agent/codegen/use-skill.d.ts +0 -11
- package/dist/agent/codegen/use-skill.d.ts.map +0 -1
- package/dist/agent/codegen/use-skill.js +0 -53
- package/dist/agent/codegen/utils.d.ts +0 -110
- package/dist/agent/codegen/utils.d.ts.map +0 -1
- package/dist/agent/codegen/utils.js +0 -376
- package/dist/agent/master/browser-tests/skills.spec.d.ts +0 -2
- package/dist/agent/master/browser-tests/skills.spec.d.ts.map +0 -1
- package/dist/agent/master/browser-tests/skills.spec.js +0 -112
- package/dist/agent/master/execute-skill-action.d.ts +0 -11
- package/dist/agent/master/execute-skill-action.d.ts.map +0 -1
- package/dist/agent/master/execute-skill-action.js +0 -23
- package/dist/agent/video-analysis/executor/index.d.ts +0 -5
- package/dist/agent/video-analysis/executor/index.d.ts.map +0 -1
- package/dist/agent/video-analysis/executor/index.js +0 -10
- package/dist/agent/video-analysis/index.d.ts +0 -7
- package/dist/agent/video-analysis/index.d.ts.map +0 -1
- package/dist/agent/video-analysis/index.js +0 -60
- package/dist/evals/append-create-test-agent.evals.d.ts +0 -4
- package/dist/evals/append-create-test-agent.evals.d.ts.map +0 -1
- package/dist/evals/append-create-test-agent.evals.js +0 -117
- package/dist/evals/fetch-pom-skills-agent.evals.d.ts +0 -4
- package/dist/evals/fetch-pom-skills-agent.evals.d.ts.map +0 -1
- package/dist/evals/fetch-pom-skills-agent.evals.js +0 -36
- package/dist/evals/master-agent.evals.d.ts +0 -4
- package/dist/evals/master-agent.evals.d.ts.map +0 -1
- package/dist/evals/master-agent.evals.js +0 -35
- package/dist/evals/type.d.ts +0 -12
- package/dist/evals/type.d.ts.map +0 -1
- package/dist/evals/type.js +0 -2
- package/dist/evals/update-scenario-agent.evals.d.ts +0 -4
- package/dist/evals/update-scenario-agent.evals.d.ts.map +0 -1
- package/dist/evals/update-scenario-agent.evals.js +0 -47
- package/dist/tools/fetch-last-successful-test-run/index.d.ts +0 -3
- package/dist/tools/fetch-last-successful-test-run/index.d.ts.map +0 -1
- package/dist/tools/fetch-last-successful-test-run/index.js +0 -60
- package/dist/tools/issues/create-issue.d.ts +0 -3
- package/dist/tools/issues/create-issue.d.ts.map +0 -1
- package/dist/tools/issues/index.d.ts.map +0 -1
- package/dist/tools/issues/list-issues.d.ts +0 -3
- package/dist/tools/issues/list-issues.d.ts.map +0 -1
- package/dist/tools/issues/metadata-schema.d.ts +0 -24
- package/dist/tools/issues/metadata-schema.d.ts.map +0 -1
- package/dist/tools/issues/metadata-schema.js +0 -22
- package/dist/tools/issues/update-issue.d.ts +0 -3
- package/dist/tools/issues/update-issue.d.ts.map +0 -1
- package/dist/tools/issues/utils.d.ts.map +0 -1
- package/dist/tools/utils/urls.d.ts +0 -5
- package/dist/tools/utils/urls.d.ts.map +0 -1
- package/dist/tools/utils/urls.js +0 -19
- package/dist/tools/view-failed-test-run-report/index.d.ts +0 -12
- package/dist/tools/view-failed-test-run-report/index.d.ts.map +0 -1
- package/dist/tools/view-failed-test-run-report/index.js +0 -151
- package/dist/utils/artifact-paths.d.ts +0 -20
- package/dist/utils/artifact-paths.d.ts.map +0 -1
- package/dist/utils/artifact-paths.js +0 -16
- package/dist/utils/dedup-image-fs.d.ts +0 -13
- package/dist/utils/dedup-image-fs.d.ts.map +0 -1
- package/dist/utils/dedup-image-fs.js +0 -84
- package/dist/utils/dedup-image.d.ts +0 -12
- package/dist/utils/dedup-image.d.ts.map +0 -1
- package/dist/utils/dedup-image.js +0 -25
- package/dist/utils/ffmpeg/index.d.ts +0 -26
- package/dist/utils/ffmpeg/index.d.ts.map +0 -1
- package/dist/utils/ffmpeg/index.js +0 -415
- package/dist/utils/find-threshold.d.ts +0 -8
- package/dist/utils/find-threshold.d.ts.map +0 -1
- package/dist/video-core/agent-orchestrator.d.ts +0 -14
- package/dist/video-core/agent-orchestrator.d.ts.map +0 -1
- package/dist/video-core/agent-orchestrator.js +0 -78
- package/dist/video-core/analysis-server.d.ts +0 -24
- package/dist/video-core/analysis-server.d.ts.map +0 -1
- package/dist/video-core/analysis-server.js +0 -398
- package/dist/video-core/analysis-viewer.html +0 -1374
- package/dist/video-core/xml-parser.d.ts +0 -3
- package/dist/video-core/xml-parser.d.ts.map +0 -1
- package/dist/video-core/xml-parser.js +0 -27
- /package/dist/tools/{issues → issues-v1}/index.d.ts +0 -0
- /package/dist/tools/{issues → issues-v1}/index.js +0 -0
- /package/dist/tools/{issues → issues-v1}/list-issues.js +0 -0
- /package/dist/tools/{issues → issues-v1}/utils.js +0 -0
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* root/ (= baseArtifactDir)
|
|
3
|
-
* - video_<videoUrlHash>.webm (= videoFile)
|
|
4
|
-
* - chunk_1.mp4
|
|
5
|
-
* - consolidated_frames/ (= consolidatedFramesDir)
|
|
6
|
-
* - frame_0001.png
|
|
7
|
-
* - frame_0002.png
|
|
8
|
-
* - ...
|
|
9
|
-
* - unique_frames/ (= uniqueFramesDir)
|
|
10
|
-
* - frame_0002.png
|
|
11
|
-
* - ...
|
|
12
|
-
*/
|
|
13
|
-
export interface VideoArtifactPaths {
|
|
14
|
-
baseArtifactDir: string;
|
|
15
|
-
videoFile: string;
|
|
16
|
-
consolidatedFramesDir: string;
|
|
17
|
-
uniqueFramesDir: string;
|
|
18
|
-
}
|
|
19
|
-
export declare function resolveVideoArtifactPaths(artifactsPath: string, videoUrlHash: string): VideoArtifactPaths;
|
|
20
|
-
//# sourceMappingURL=artifact-paths.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"artifact-paths.d.ts","sourceRoot":"","sources":["../../src/utils/artifact-paths.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,kBAAkB;IAEjC,eAAe,EAAE,MAAM,CAAC;IAExB,SAAS,EAAE,MAAM,CAAC;IAElB,qBAAqB,EAAE,MAAM,CAAC;IAE9B,eAAe,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,yBAAyB,CACvC,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,MAAM,GACnB,kBAAkB,CAQpB"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.resolveVideoArtifactPaths = resolveVideoArtifactPaths;
|
|
7
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
8
|
-
function resolveVideoArtifactPaths(artifactsPath, videoUrlHash) {
|
|
9
|
-
const baseArtifactDir = artifactsPath;
|
|
10
|
-
return {
|
|
11
|
-
baseArtifactDir,
|
|
12
|
-
videoFile: node_path_1.default.join(baseArtifactDir, `video_${videoUrlHash}.webm`),
|
|
13
|
-
consolidatedFramesDir: node_path_1.default.join(baseArtifactDir, "consolidated_frames"),
|
|
14
|
-
uniqueFramesDir: node_path_1.default.join(baseArtifactDir, "unique_frames"),
|
|
15
|
-
};
|
|
16
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
export declare function deduplicateImageFiles({ imagePaths, batchSize, threshold, logPrefix, }: {
|
|
2
|
-
imagePaths: string[];
|
|
3
|
-
batchSize: number;
|
|
4
|
-
threshold: number;
|
|
5
|
-
logPrefix?: string;
|
|
6
|
-
}): Promise<{
|
|
7
|
-
metadata: {
|
|
8
|
-
index: number;
|
|
9
|
-
path: string;
|
|
10
|
-
};
|
|
11
|
-
image: string;
|
|
12
|
-
}[]>;
|
|
13
|
-
//# sourceMappingURL=dedup-image-fs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dedup-image-fs.d.ts","sourceRoot":"","sources":["../../src/utils/dedup-image-fs.ts"],"names":[],"mappings":"AAKA,wBAAsB,qBAAqB,CAAC,EAC1C,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAA4B,GAC7B,EAAE;IACD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CA2G1E"}
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.deduplicateImageFiles = deduplicateImageFiles;
|
|
7
|
-
const fs_1 = require("fs");
|
|
8
|
-
const path_1 = __importDefault(require("path"));
|
|
9
|
-
const dedup_image_1 = require("./dedup-image");
|
|
10
|
-
async function deduplicateImageFiles({ imagePaths, batchSize, threshold, logPrefix = "dedup-image-fs", }) {
|
|
11
|
-
const uniqueImages = [];
|
|
12
|
-
console.log(`[${logPrefix}] Processing ${imagePaths.length} images in batches of ${batchSize}`);
|
|
13
|
-
for (let i = 0; i < imagePaths.length; i += batchSize) {
|
|
14
|
-
const batch = imagePaths.slice(i, i + batchSize);
|
|
15
|
-
console.log(`[${logPrefix}] Processing batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(imagePaths.length / batchSize)}`);
|
|
16
|
-
const batchBase64Images = [];
|
|
17
|
-
for (let j = 0; j < batch.length; j++) {
|
|
18
|
-
const imagePath = batch[j];
|
|
19
|
-
if (!imagePath) {
|
|
20
|
-
console.error(`[${logPrefix}] Error: imagePath is undefined for batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(imagePaths.length / batchSize)}`);
|
|
21
|
-
continue;
|
|
22
|
-
}
|
|
23
|
-
try {
|
|
24
|
-
const buffer = await fs_1.promises.readFile(imagePath);
|
|
25
|
-
const base64 = buffer.toString("base64");
|
|
26
|
-
// Extract actual frame number from filename instead of using serial index
|
|
27
|
-
const filename = path_1.default.basename(imagePath);
|
|
28
|
-
const frameNumberMatch = filename.match(/frame_(\d+)\.png$/);
|
|
29
|
-
const frameIndex = frameNumberMatch
|
|
30
|
-
? parseInt(frameNumberMatch[1], 10)
|
|
31
|
-
: i + j; // Fallback to serial index if no match
|
|
32
|
-
batchBase64Images.push({
|
|
33
|
-
metadata: {
|
|
34
|
-
index: frameIndex,
|
|
35
|
-
path: imagePath,
|
|
36
|
-
},
|
|
37
|
-
image: base64,
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
catch (error) {
|
|
41
|
-
console.error(`[${logPrefix}] Error reading image ${imagePath}:`, error);
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
// If this is the first batch, just deduplicate within the batch
|
|
46
|
-
if (uniqueImages.length === 0) {
|
|
47
|
-
const batchUniqueImages = await (0, dedup_image_1.deduplicateImages)({
|
|
48
|
-
base64Images: batchBase64Images,
|
|
49
|
-
threshold,
|
|
50
|
-
logPrefix: `${logPrefix}-batch-${Math.floor(i / batchSize) + 1}`,
|
|
51
|
-
});
|
|
52
|
-
uniqueImages.push(...batchUniqueImages);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
// For subsequent batches, compare against the last unique image and then deduplicate within batch
|
|
56
|
-
const lastUniqueImage = uniqueImages[uniqueImages.length - 1];
|
|
57
|
-
if (!lastUniqueImage) {
|
|
58
|
-
console.error(`[${logPrefix}] Error: lastUniqueImage is undefined for batch ${Math.floor(i / batchSize) + 1}/${Math.ceil(imagePaths.length / batchSize)}`);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
const batchWithPrevious = [lastUniqueImage, ...batchBase64Images];
|
|
62
|
-
const batchUniqueImages = await (0, dedup_image_1.deduplicateImages)({
|
|
63
|
-
base64Images: batchWithPrevious,
|
|
64
|
-
threshold,
|
|
65
|
-
logPrefix: `${logPrefix}-batch-${Math.floor(i / batchSize) + 1}`,
|
|
66
|
-
});
|
|
67
|
-
// Remove the first image if it's the same as the last unique image (it was a duplicate)
|
|
68
|
-
// and add the rest to unique images
|
|
69
|
-
if (batchUniqueImages.length > 0) {
|
|
70
|
-
// Skip the first image if it has the same path as the last unique image
|
|
71
|
-
const startIndex = batchUniqueImages[0]?.metadata.path === lastUniqueImage.metadata.path
|
|
72
|
-
? 1
|
|
73
|
-
: 0;
|
|
74
|
-
uniqueImages.push(...batchUniqueImages.slice(startIndex));
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// Force garbage collection after each batch
|
|
78
|
-
if (global.gc) {
|
|
79
|
-
global.gc();
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
console.log(`[${logPrefix}] Filtered to ${uniqueImages.length} unique images from ${imagePaths.length} total images`);
|
|
83
|
-
return uniqueImages;
|
|
84
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export declare function deduplicateImages({ base64Images, threshold, logPrefix, }: {
|
|
2
|
-
base64Images: {
|
|
3
|
-
metadata: any;
|
|
4
|
-
image: string;
|
|
5
|
-
}[];
|
|
6
|
-
threshold: number;
|
|
7
|
-
logPrefix?: string;
|
|
8
|
-
}): Promise<{
|
|
9
|
-
metadata: any;
|
|
10
|
-
image: string;
|
|
11
|
-
}[]>;
|
|
12
|
-
//# sourceMappingURL=dedup-image.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dedup-image.d.ts","sourceRoot":"","sources":["../../src/utils/dedup-image.ts"],"names":[],"mappings":"AAEA,wBAAsB,iBAAiB,CAAC,EACtC,YAAY,EACZ,SAAS,EACT,SAAyB,GAC1B,EAAE;IACD,YAAY,EAAE;QAAE,QAAQ,EAAE,GAAG,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC;IAAE,QAAQ,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAE,CAAC,CA0B9C"}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.deduplicateImages = deduplicateImages;
|
|
4
|
-
const find_threshold_1 = require("./find-threshold");
|
|
5
|
-
async function deduplicateImages({ base64Images, threshold, logPrefix = "dedup-image", }) {
|
|
6
|
-
const uniqueImages = [];
|
|
7
|
-
let previousImageBuffer = null;
|
|
8
|
-
for (const imgData of base64Images) {
|
|
9
|
-
try {
|
|
10
|
-
const currentBuffer = Buffer.from(imgData.image, "base64");
|
|
11
|
-
let isDuplicate = false;
|
|
12
|
-
if (previousImageBuffer) {
|
|
13
|
-
isDuplicate = await (0, find_threshold_1.areImagesDuplicate)(currentBuffer, previousImageBuffer, threshold);
|
|
14
|
-
}
|
|
15
|
-
if (!isDuplicate) {
|
|
16
|
-
uniqueImages.push(imgData);
|
|
17
|
-
previousImageBuffer = currentBuffer;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
console.error(`[${logPrefix}] Error processing image:`, error);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return uniqueImages;
|
|
25
|
-
}
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { UniqueFrameInfos } from "@empiricalrun/shared-types";
|
|
2
|
-
export declare class LocalFFmpegClient {
|
|
3
|
-
private static readonly MAX_VIDEO_DURATION_SECONDS;
|
|
4
|
-
private static readonly CHUNK_DURATION_SECONDS;
|
|
5
|
-
constructor();
|
|
6
|
-
private checkFFmpegAvailability;
|
|
7
|
-
private getVideoDuration;
|
|
8
|
-
private validateVideoChunk;
|
|
9
|
-
private ensureEmptyDir;
|
|
10
|
-
private runFFmpegCommand;
|
|
11
|
-
private createVideoChunks;
|
|
12
|
-
private extractFramesWithFPS;
|
|
13
|
-
private processVideoChunks;
|
|
14
|
-
storeUniqueFrames(uniqueFrameInfos: UniqueFrameInfos[], workingDir: string): Promise<string>;
|
|
15
|
-
extractVideoFrames(videoUrl: string, videoUrlHash: string, absoluteWorkingDir: string, options?: {
|
|
16
|
-
fps?: number;
|
|
17
|
-
threshold?: number;
|
|
18
|
-
startTime?: number;
|
|
19
|
-
duration?: number;
|
|
20
|
-
}): Promise<{
|
|
21
|
-
totalFramesCount: number;
|
|
22
|
-
uniqueFrameInfos: UniqueFrameInfos[];
|
|
23
|
-
videoDurationSeconds: number;
|
|
24
|
-
}>;
|
|
25
|
-
}
|
|
26
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/ffmpeg/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAa9D,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,0BAA0B,CAAW;IAC7D,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAU;;IAMxD,OAAO,CAAC,uBAAuB;YAWjB,gBAAgB;YAiBhB,kBAAkB;YAgClB,cAAc;YASd,gBAAgB;YAoBhB,iBAAiB;YAsEjB,oBAAoB;YAkEpB,kBAAkB;IA8G1B,iBAAiB,CACrB,gBAAgB,EAAE,gBAAgB,EAAE,EACpC,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC;IAgFZ,kBAAkB,CACtB,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,MAAM,EACpB,kBAAkB,EAAE,MAAM,EAC1B,OAAO,CAAC,EAAE;QACR,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,GACA,OAAO,CAAC;QACT,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,gBAAgB,EAAE,CAAC;QACrC,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;CA0IH"}
|
|
@@ -1,415 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.LocalFFmpegClient = void 0;
|
|
7
|
-
const node_crypto_1 = __importDefault(require("node:crypto"));
|
|
8
|
-
const child_process_1 = require("child_process");
|
|
9
|
-
const fs_1 = require("fs");
|
|
10
|
-
const path_1 = __importDefault(require("path"));
|
|
11
|
-
const util_1 = require("util");
|
|
12
|
-
const constants_1 = require("../../constants");
|
|
13
|
-
const utils_1 = require("../../video-core/utils");
|
|
14
|
-
const dedup_image_fs_1 = require("../dedup-image-fs");
|
|
15
|
-
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
16
|
-
const FRAME_DIMENSION = "1280:720";
|
|
17
|
-
class LocalFFmpegClient {
|
|
18
|
-
static MAX_VIDEO_DURATION_SECONDS = 15 * 60; // 15 minutes
|
|
19
|
-
static CHUNK_DURATION_SECONDS = 2 * 60; // 2 minutes
|
|
20
|
-
constructor() {
|
|
21
|
-
this.checkFFmpegAvailability();
|
|
22
|
-
}
|
|
23
|
-
checkFFmpegAvailability() {
|
|
24
|
-
try {
|
|
25
|
-
(0, child_process_1.execSync)("ffmpeg -version", { stdio: "ignore" });
|
|
26
|
-
(0, child_process_1.execSync)("ffprobe -version", { stdio: "ignore" });
|
|
27
|
-
}
|
|
28
|
-
catch (error) {
|
|
29
|
-
throw new Error(`ffmpeg and ffprobe are required for video processing: ${error}`);
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
async getVideoDuration(videoPath) {
|
|
33
|
-
const command = `ffprobe -v quiet -show_entries format=duration -of csv=p=0 "${videoPath}"`;
|
|
34
|
-
try {
|
|
35
|
-
const { stdout } = await execAsync(command);
|
|
36
|
-
const duration = parseFloat(stdout.trim());
|
|
37
|
-
if (isNaN(duration)) {
|
|
38
|
-
throw new Error("Could not determine video duration");
|
|
39
|
-
}
|
|
40
|
-
return duration;
|
|
41
|
-
}
|
|
42
|
-
catch (error) {
|
|
43
|
-
throw new Error(`Failed to get video duration: ${error}`);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
async validateVideoChunk(chunkPath) {
|
|
47
|
-
const command = `ffprobe -v error -show_entries format=duration -of csv=p=0 "${chunkPath}"`;
|
|
48
|
-
try {
|
|
49
|
-
const { stdout, stderr } = await execAsync(command);
|
|
50
|
-
if (stderr && stderr.toLowerCase().includes("error")) {
|
|
51
|
-
console.warn(`Chunk validation found errors: ${stderr}`);
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
|
-
const duration = parseFloat(stdout.trim());
|
|
55
|
-
if (isNaN(duration) || duration <= 0) {
|
|
56
|
-
console.warn(`Chunk has invalid duration: ${duration}`);
|
|
57
|
-
return false;
|
|
58
|
-
}
|
|
59
|
-
// Check file size as additional validation
|
|
60
|
-
const stats = await fs_1.promises.stat(chunkPath);
|
|
61
|
-
if (stats.size < 1024) {
|
|
62
|
-
// Less than 1KB is suspicious for a video chunk
|
|
63
|
-
console.warn(`Chunk file size too small: ${stats.size} bytes`);
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
catch (error) {
|
|
69
|
-
console.warn(`Chunk validation failed: ${error}`);
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
async ensureEmptyDir(dir) {
|
|
74
|
-
try {
|
|
75
|
-
await fs_1.promises.rm(dir, { recursive: true, force: true });
|
|
76
|
-
}
|
|
77
|
-
catch {
|
|
78
|
-
// ignore
|
|
79
|
-
}
|
|
80
|
-
await fs_1.promises.mkdir(dir, { recursive: true });
|
|
81
|
-
}
|
|
82
|
-
async runFFmpegCommand({ inputPath, args, outputPath, }) {
|
|
83
|
-
const quotedInput = `"${inputPath}"`;
|
|
84
|
-
const output = outputPath ? ` "${outputPath}"` : "";
|
|
85
|
-
const cmd = `ffmpeg -y -nostdin -i ${quotedInput} ${args.join(" ")}${output}`;
|
|
86
|
-
try {
|
|
87
|
-
await execAsync(cmd);
|
|
88
|
-
}
|
|
89
|
-
catch (error) {
|
|
90
|
-
throw new Error(`ffmpeg command failed: ${cmd} => ${String(error)}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
async createVideoChunks(videoPath, outputDir, duration, startTime = 0) {
|
|
94
|
-
const chunkPaths = [];
|
|
95
|
-
const chunkCount = Math.ceil(duration / LocalFFmpegClient.CHUNK_DURATION_SECONDS);
|
|
96
|
-
console.log(`Creating ${chunkCount} chunks of ${LocalFFmpegClient.CHUNK_DURATION_SECONDS} seconds each`);
|
|
97
|
-
for (let i = 0; i < chunkCount; i++) {
|
|
98
|
-
const chunkOffsetTime = i * LocalFFmpegClient.CHUNK_DURATION_SECONDS;
|
|
99
|
-
const absoluteStartTime = startTime + chunkOffsetTime;
|
|
100
|
-
const chunkPath = path_1.default.join(outputDir, `chunk_${i.toString().padStart(3, "0")}.mp4`);
|
|
101
|
-
const remainingDuration = duration - chunkOffsetTime;
|
|
102
|
-
const chunkDuration = Math.min(LocalFFmpegClient.CHUNK_DURATION_SECONDS, remainingDuration);
|
|
103
|
-
try {
|
|
104
|
-
await fs_1.promises.rm(chunkPath, { force: true });
|
|
105
|
-
await this.runFFmpegCommand({
|
|
106
|
-
inputPath: videoPath,
|
|
107
|
-
args: [
|
|
108
|
-
"-ss",
|
|
109
|
-
String(absoluteStartTime),
|
|
110
|
-
"-t",
|
|
111
|
-
String(chunkDuration),
|
|
112
|
-
"-c:v",
|
|
113
|
-
"libx264",
|
|
114
|
-
"-c:a",
|
|
115
|
-
"aac",
|
|
116
|
-
"-preset",
|
|
117
|
-
"ultrafast",
|
|
118
|
-
"-crf",
|
|
119
|
-
"28",
|
|
120
|
-
],
|
|
121
|
-
outputPath: chunkPath,
|
|
122
|
-
});
|
|
123
|
-
// Validate the created chunk
|
|
124
|
-
const isValid = await this.validateVideoChunk(chunkPath);
|
|
125
|
-
if (isValid) {
|
|
126
|
-
chunkPaths.push(chunkPath);
|
|
127
|
-
}
|
|
128
|
-
else {
|
|
129
|
-
console.warn(`Chunk ${i} appears corrupted, skipping...`);
|
|
130
|
-
try {
|
|
131
|
-
await fs_1.promises.unlink(chunkPath);
|
|
132
|
-
}
|
|
133
|
-
catch (unlinkError) {
|
|
134
|
-
console.warn(`Failed to remove corrupted chunk: ${unlinkError}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
catch (error) {
|
|
139
|
-
throw new Error(`Failed to create chunk ${i}: ${error}`);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
return chunkPaths;
|
|
143
|
-
}
|
|
144
|
-
async extractFramesWithFPS({ videoPath, outputDir, fps, globalStartTime, duration, }) {
|
|
145
|
-
// Create directory but don't clear it - multiple calls may be appending
|
|
146
|
-
await fs_1.promises.mkdir(outputDir, { recursive: true });
|
|
147
|
-
console.log(`Extracting frames at ${fps} fps using single ffmpeg command (${duration ? duration + "s duration" : "full length"}) starting at global time ${globalStartTime}s`);
|
|
148
|
-
const outputPattern = path_1.default.join(outputDir, "frame_%06d.png");
|
|
149
|
-
const args = [];
|
|
150
|
-
if (duration) {
|
|
151
|
-
args.push("-t", duration.toString());
|
|
152
|
-
}
|
|
153
|
-
const vf = `fps=${fps},scale=${FRAME_DIMENSION}:force_original_aspect_ratio=decrease,pad=${FRAME_DIMENSION}:(ow-iw)/2:(oh-ih)/2`;
|
|
154
|
-
args.push("-vf", `"${vf}"`, "-q:v", "2", "-y");
|
|
155
|
-
try {
|
|
156
|
-
await this.runFFmpegCommand({
|
|
157
|
-
inputPath: videoPath,
|
|
158
|
-
args: args,
|
|
159
|
-
outputPath: outputPattern,
|
|
160
|
-
});
|
|
161
|
-
const files = await fs_1.promises.readdir(outputDir);
|
|
162
|
-
const frameFiles = files
|
|
163
|
-
.filter((f) => f.startsWith("frame_") && f.endsWith(".png"))
|
|
164
|
-
.sort();
|
|
165
|
-
const renamedFiles = [];
|
|
166
|
-
for (let i = 0; i < frameFiles.length; i++) {
|
|
167
|
-
const originalPath = path_1.default.join(outputDir, frameFiles[i]);
|
|
168
|
-
const globalFrameNumber = Math.floor(globalStartTime * fps) + i;
|
|
169
|
-
const newFileName = `chunk0_frame_${globalFrameNumber.toString().padStart(6, "0")}.png`;
|
|
170
|
-
const newPath = path_1.default.join(outputDir, newFileName);
|
|
171
|
-
await fs_1.promises.rename(originalPath, newPath);
|
|
172
|
-
renamedFiles.push(newPath);
|
|
173
|
-
}
|
|
174
|
-
console.log(`Successfully extracted ${renamedFiles.length} frames using single ffmpeg command with global frame numbering starting from ${Math.floor(globalStartTime * fps)}`);
|
|
175
|
-
return renamedFiles;
|
|
176
|
-
}
|
|
177
|
-
catch (error) {
|
|
178
|
-
console.warn(`Failed to extract frames with fps filter:`, error);
|
|
179
|
-
return [];
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
async processVideoChunks(chunkPaths, workingDir, fps, effectiveDuration, globalStartTime = 0) {
|
|
183
|
-
const allFramePaths = [];
|
|
184
|
-
const consolidatedFramesDir = path_1.default.join(workingDir, "consolidated_frames");
|
|
185
|
-
// Check if consolidated_frames directory exists and has frames - if so, append mode
|
|
186
|
-
const dirExists = await fs_1.promises
|
|
187
|
-
.access(consolidatedFramesDir)
|
|
188
|
-
.then(() => true)
|
|
189
|
-
.catch(() => false);
|
|
190
|
-
let hasExistingFrames = false;
|
|
191
|
-
if (dirExists) {
|
|
192
|
-
try {
|
|
193
|
-
const existingFiles = await fs_1.promises.readdir(consolidatedFramesDir);
|
|
194
|
-
hasExistingFrames = existingFiles.some((file) => file.endsWith(".png"));
|
|
195
|
-
}
|
|
196
|
-
catch {
|
|
197
|
-
hasExistingFrames = false;
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
if (hasExistingFrames) {
|
|
201
|
-
// Append mode: directory has frames, don't clear it
|
|
202
|
-
console.log(`Appending to existing consolidated_frames directory`);
|
|
203
|
-
}
|
|
204
|
-
else {
|
|
205
|
-
// Fresh mode: clear and recreate directory
|
|
206
|
-
await this.ensureEmptyDir(consolidatedFramesDir);
|
|
207
|
-
console.log(`Creating fresh consolidated_frames directory`);
|
|
208
|
-
}
|
|
209
|
-
for (let i = 0; i < chunkPaths.length; i++) {
|
|
210
|
-
const chunkPath = chunkPaths[i];
|
|
211
|
-
const chunkFramesDir = path_1.default.join(workingDir, `chunk_${i}_frames`);
|
|
212
|
-
console.log(`Processing chunk ${i + 1}/${chunkPaths.length} with precise frame extraction`);
|
|
213
|
-
if (chunkPath === undefined) {
|
|
214
|
-
throw new Error(`Chunk path is undefined for chunk ${i + 1}`);
|
|
215
|
-
}
|
|
216
|
-
try {
|
|
217
|
-
const chunkStartTime = i * LocalFFmpegClient.CHUNK_DURATION_SECONDS;
|
|
218
|
-
const chunkDuration = Math.min(LocalFFmpegClient.CHUNK_DURATION_SECONDS, effectiveDuration - chunkStartTime);
|
|
219
|
-
const actualGlobalStartTime = globalStartTime + chunkStartTime;
|
|
220
|
-
const chunkFramePaths = await this.extractFramesWithFPS({
|
|
221
|
-
videoPath: chunkPath,
|
|
222
|
-
outputDir: chunkFramesDir,
|
|
223
|
-
fps,
|
|
224
|
-
globalStartTime: actualGlobalStartTime,
|
|
225
|
-
duration: chunkDuration,
|
|
226
|
-
});
|
|
227
|
-
for (const framePath of chunkFramePaths) {
|
|
228
|
-
const basename = path_1.default.basename(framePath);
|
|
229
|
-
const frameNumberMatch = basename.match(/frame_(\d+)\.png$/);
|
|
230
|
-
const localFrameNumber = frameNumberMatch && frameNumberMatch[1]
|
|
231
|
-
? parseInt(frameNumberMatch[1], 10)
|
|
232
|
-
: 0;
|
|
233
|
-
const globalFrameNumber = Math.floor(chunkStartTime * fps) + localFrameNumber;
|
|
234
|
-
const newFramePath = path_1.default.join(consolidatedFramesDir, `frame_${globalFrameNumber.toString().padStart(6, "0")}.png`);
|
|
235
|
-
// In append mode, check if frame already exists
|
|
236
|
-
if (hasExistingFrames) {
|
|
237
|
-
const frameExists = await fs_1.promises
|
|
238
|
-
.access(newFramePath)
|
|
239
|
-
.then(() => true)
|
|
240
|
-
.catch(() => false);
|
|
241
|
-
if (frameExists) {
|
|
242
|
-
console.log(`Frame ${newFramePath} already exists, skipping`);
|
|
243
|
-
allFramePaths.push(newFramePath);
|
|
244
|
-
continue;
|
|
245
|
-
}
|
|
246
|
-
}
|
|
247
|
-
await fs_1.promises.rename(framePath, newFramePath);
|
|
248
|
-
allFramePaths.push(newFramePath);
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
catch (error) {
|
|
252
|
-
console.warn(`Failed to process chunk ${i + 1}: ${error}. Skipping this chunk.`);
|
|
253
|
-
// Continue with other chunks instead of failing completely
|
|
254
|
-
}
|
|
255
|
-
if (global.gc) {
|
|
256
|
-
global.gc();
|
|
257
|
-
}
|
|
258
|
-
}
|
|
259
|
-
return allFramePaths;
|
|
260
|
-
}
|
|
261
|
-
async storeUniqueFrames(uniqueFrameInfos, workingDir) {
|
|
262
|
-
const uniqueFramesDir = path_1.default.join(workingDir, "unique_frames");
|
|
263
|
-
// Check if directory exists and has frames - if so, append mode
|
|
264
|
-
const dirExists = await fs_1.promises
|
|
265
|
-
.access(uniqueFramesDir)
|
|
266
|
-
.then(() => true)
|
|
267
|
-
.catch(() => false);
|
|
268
|
-
let hasExistingFrames = false;
|
|
269
|
-
if (dirExists) {
|
|
270
|
-
try {
|
|
271
|
-
const existingFiles = await fs_1.promises.readdir(uniqueFramesDir);
|
|
272
|
-
hasExistingFrames = existingFiles.some((file) => file.endsWith(".png"));
|
|
273
|
-
}
|
|
274
|
-
catch {
|
|
275
|
-
hasExistingFrames = false;
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
if (hasExistingFrames) {
|
|
279
|
-
// Append mode: directory has frames, don't clear it
|
|
280
|
-
console.log(`Appending ${uniqueFrameInfos.length} frames to existing ${uniqueFramesDir}`);
|
|
281
|
-
}
|
|
282
|
-
else {
|
|
283
|
-
// Fresh mode: clear and recreate directory
|
|
284
|
-
await this.ensureEmptyDir(uniqueFramesDir);
|
|
285
|
-
console.log(`Creating fresh ${uniqueFramesDir} with ${uniqueFrameInfos.length} frames`);
|
|
286
|
-
}
|
|
287
|
-
console.log(`Storing ${uniqueFrameInfos.length} unique frames in ${uniqueFramesDir}`);
|
|
288
|
-
for (let i = 0; i < uniqueFrameInfos.length; i++) {
|
|
289
|
-
const frame = uniqueFrameInfos[i];
|
|
290
|
-
if (!frame)
|
|
291
|
-
continue;
|
|
292
|
-
const originalPath = frame.path;
|
|
293
|
-
const originalBasename = path_1.default.basename(originalPath);
|
|
294
|
-
const frameNumberMatch = originalBasename.match(/frame_(\d+)\.png$/);
|
|
295
|
-
const frameNumber = frameNumberMatch
|
|
296
|
-
? frameNumberMatch[1]
|
|
297
|
-
: i.toString().padStart(6, "0");
|
|
298
|
-
const uniqueFramePath = path_1.default.join(uniqueFramesDir, `frame_${frameNumber}.png`);
|
|
299
|
-
try {
|
|
300
|
-
// In append mode, check if frame already exists to avoid overwriting
|
|
301
|
-
if (hasExistingFrames) {
|
|
302
|
-
const frameExists = await fs_1.promises
|
|
303
|
-
.access(uniqueFramePath)
|
|
304
|
-
.then(() => true)
|
|
305
|
-
.catch(() => false);
|
|
306
|
-
if (frameExists) {
|
|
307
|
-
console.log(`Frame ${uniqueFramePath} already exists, skipping`);
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
await fs_1.promises.copyFile(originalPath, uniqueFramePath);
|
|
312
|
-
}
|
|
313
|
-
catch (error) {
|
|
314
|
-
console.warn(`Failed to copy frame ${originalPath} to ${uniqueFramePath}:`, error);
|
|
315
|
-
}
|
|
316
|
-
}
|
|
317
|
-
console.log(`Stored ${uniqueFrameInfos.length} unique frames in: ${uniqueFramesDir}`);
|
|
318
|
-
return uniqueFramesDir;
|
|
319
|
-
}
|
|
320
|
-
async extractVideoFrames(videoUrl, videoUrlHash, absoluteWorkingDir, options) {
|
|
321
|
-
console.log("🚀 ~ LocalFFmpegClient ~ using absolute workingDir:", absoluteWorkingDir);
|
|
322
|
-
const workingDir = absoluteWorkingDir;
|
|
323
|
-
const urlHash = node_crypto_1.default
|
|
324
|
-
.createHash("sha256")
|
|
325
|
-
.update(videoUrl)
|
|
326
|
-
.digest("hex")
|
|
327
|
-
.substring(0, 16);
|
|
328
|
-
const videoPath = path_1.default.join(workingDir, `video_${urlHash}.webm`);
|
|
329
|
-
const fps = options?.fps ?? 30;
|
|
330
|
-
const threshold = options?.threshold ?? 0.001;
|
|
331
|
-
const startTime = options?.startTime;
|
|
332
|
-
const duration = options?.duration;
|
|
333
|
-
try {
|
|
334
|
-
await fs_1.promises.mkdir(workingDir, { recursive: true });
|
|
335
|
-
await (0, utils_1.downloadVideo)(videoUrl, videoPath);
|
|
336
|
-
const videoDuration = await this.getVideoDuration(videoPath);
|
|
337
|
-
console.log(`Video duration: ${Math.round(videoDuration)} seconds`);
|
|
338
|
-
if (videoDuration > LocalFFmpegClient.MAX_VIDEO_DURATION_SECONDS) {
|
|
339
|
-
throw new Error(`Video duration (${Math.round(videoDuration)}s) exceeds maximum allowed duration (${LocalFFmpegClient.MAX_VIDEO_DURATION_SECONDS}s)`);
|
|
340
|
-
}
|
|
341
|
-
// Validate and adjust time parameters
|
|
342
|
-
let effectiveStartTime = 0;
|
|
343
|
-
let effectiveDuration = videoDuration;
|
|
344
|
-
if (startTime !== undefined) {
|
|
345
|
-
if (startTime < 0) {
|
|
346
|
-
throw new Error(`Start time cannot be negative: ${startTime}`);
|
|
347
|
-
}
|
|
348
|
-
if (startTime >= videoDuration) {
|
|
349
|
-
throw new Error(`Start time (${startTime}s) exceeds video duration (${Math.round(videoDuration)}s)`);
|
|
350
|
-
}
|
|
351
|
-
effectiveStartTime = startTime;
|
|
352
|
-
effectiveDuration = videoDuration - startTime;
|
|
353
|
-
}
|
|
354
|
-
if (duration !== undefined) {
|
|
355
|
-
if (duration <= 0) {
|
|
356
|
-
throw new Error(`Duration must be positive: ${duration}`);
|
|
357
|
-
}
|
|
358
|
-
const maxAllowedDuration = videoDuration - effectiveStartTime;
|
|
359
|
-
if (duration > maxAllowedDuration) {
|
|
360
|
-
console.warn(`Requested duration (${duration}s) exceeds available time (${maxAllowedDuration}s), truncating to fit`);
|
|
361
|
-
effectiveDuration = maxAllowedDuration;
|
|
362
|
-
}
|
|
363
|
-
else {
|
|
364
|
-
effectiveDuration = duration;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
console.log(`Effective extraction range: ${effectiveStartTime}s to ${effectiveStartTime + effectiveDuration}s`);
|
|
368
|
-
const chunkPaths = await this.createVideoChunks(videoPath, workingDir, effectiveDuration, effectiveStartTime);
|
|
369
|
-
const allFramePaths = await this.processVideoChunks(chunkPaths, workingDir, fps, effectiveDuration, // Pass duration for precise calculations
|
|
370
|
-
effectiveStartTime);
|
|
371
|
-
const allFramesCount = allFramePaths.length;
|
|
372
|
-
const uniqueImages = await (0, dedup_image_fs_1.deduplicateImageFiles)({
|
|
373
|
-
imagePaths: allFramePaths,
|
|
374
|
-
batchSize: 50,
|
|
375
|
-
threshold,
|
|
376
|
-
logPrefix: "ffmpeg-chunk-frame-dedup",
|
|
377
|
-
});
|
|
378
|
-
console.log(`Filtered to ${uniqueImages.length} unique frames from ${allFramesCount} total frames across ${chunkPaths.length} chunks`);
|
|
379
|
-
if (uniqueImages.length === 0) {
|
|
380
|
-
if (chunkPaths.length === 0) {
|
|
381
|
-
throw new Error("No valid video chunks were created. The video may be corrupted or in an unsupported format.");
|
|
382
|
-
}
|
|
383
|
-
throw new Error("No frames were extracted from the video");
|
|
384
|
-
}
|
|
385
|
-
const uniqueFrameInfos = uniqueImages.map((f) => {
|
|
386
|
-
const normalizedIndex = f.metadata.index
|
|
387
|
-
.toString()
|
|
388
|
-
.padStart(constants_1.VIDEO_ANALYSIS.FRAME_INDEX_PADDING, "0");
|
|
389
|
-
const timeInSeconds = f.metadata.index / fps;
|
|
390
|
-
const minutes = Math.floor(timeInSeconds / 60);
|
|
391
|
-
const seconds = Math.floor(timeInSeconds % 60);
|
|
392
|
-
const timestamp = `${minutes}m${seconds.toString().padStart(2, "0")}s`;
|
|
393
|
-
const fileName = `frame_${normalizedIndex}.png`;
|
|
394
|
-
return {
|
|
395
|
-
index: f.metadata.index,
|
|
396
|
-
path: f.metadata.path,
|
|
397
|
-
fileName: fileName,
|
|
398
|
-
base64: f.image,
|
|
399
|
-
url: `${(0, utils_1.getR2BaseUrlByHash)(videoUrlHash)}${fileName}`,
|
|
400
|
-
timestamp: timestamp,
|
|
401
|
-
};
|
|
402
|
-
});
|
|
403
|
-
await this.storeUniqueFrames(uniqueFrameInfos, workingDir);
|
|
404
|
-
return {
|
|
405
|
-
totalFramesCount: allFramesCount,
|
|
406
|
-
uniqueFrameInfos,
|
|
407
|
-
videoDurationSeconds: videoDuration,
|
|
408
|
-
};
|
|
409
|
-
}
|
|
410
|
-
catch (error) {
|
|
411
|
-
throw new Error(`Frame extraction failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
}
|
|
415
|
-
exports.LocalFFmpegClient = LocalFFmpegClient;
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export declare function compareImageBuffers(buffer1: Buffer, buffer2: Buffer, pixelmatchThreshold: number): Promise<{
|
|
2
|
-
diffPixels: number;
|
|
3
|
-
totalPixels: number;
|
|
4
|
-
diffFraction: number;
|
|
5
|
-
}>;
|
|
6
|
-
export declare function findSimilarityPercentage(base64Image1: string, base64Image2: string): Promise<number>;
|
|
7
|
-
export declare function areImagesDuplicate(buffer1: Buffer, buffer2: Buffer, threshold: number): Promise<boolean>;
|
|
8
|
-
//# sourceMappingURL=find-threshold.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"find-threshold.d.ts","sourceRoot":"","sources":["../../src/utils/find-threshold.ts"],"names":[],"mappings":"AAKA,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,mBAAmB,EAAE,MAAM,GAC1B,OAAO,CAAC;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CAAC,CA6B5E;AAED,wBAAsB,wBAAwB,CAC5C,YAAY,EAAE,MAAM,EACpB,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,OAAO,CAAC,CAYlB"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { Attachment, CanonicalMessage, ChatState, SupportedChatModels } from "@empiricalrun/shared-types";
|
|
2
|
-
import { ProcessedAnalysis } from "./types";
|
|
3
|
-
export declare function extractTextPartFromLastMessage(messages: CanonicalMessage[]): string | null;
|
|
4
|
-
export declare function getChatStateWithFrameIdAttachmentParts(attachments: Attachment[], selectedModel: SupportedChatModels): ChatState;
|
|
5
|
-
export declare function orchestrateVideoAnalysis({ selectedModel, featureFlags, workingDirectory, frameBatch, }: {
|
|
6
|
-
selectedModel: SupportedChatModels;
|
|
7
|
-
featureFlags: string[];
|
|
8
|
-
workingDirectory: string;
|
|
9
|
-
frameBatch: Attachment[];
|
|
10
|
-
}): Promise<{
|
|
11
|
-
analysis: string;
|
|
12
|
-
allMessages: CanonicalMessage[];
|
|
13
|
-
} & ProcessedAnalysis>;
|
|
14
|
-
//# sourceMappingURL=agent-orchestrator.d.ts.map
|