amd-gaia 0.14.1__py3-none-any.whl
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.
- amd_gaia-0.14.1.dist-info/METADATA +768 -0
- amd_gaia-0.14.1.dist-info/RECORD +800 -0
- amd_gaia-0.14.1.dist-info/WHEEL +5 -0
- amd_gaia-0.14.1.dist-info/entry_points.txt +5 -0
- amd_gaia-0.14.1.dist-info/licenses/LICENSE.md +21 -0
- amd_gaia-0.14.1.dist-info/top_level.txt +1 -0
- gaia/__init__.py +2 -0
- gaia/agents/__init__.py +19 -0
- gaia/agents/base/__init__.py +9 -0
- gaia/agents/base/agent.py +2072 -0
- gaia/agents/base/api_agent.py +120 -0
- gaia/agents/base/console.py +1457 -0
- gaia/agents/base/mcp_agent.py +86 -0
- gaia/agents/base/tools.py +83 -0
- gaia/agents/blender/agent.py +556 -0
- gaia/agents/blender/agent_simple.py +135 -0
- gaia/agents/blender/app.py +211 -0
- gaia/agents/blender/app_simple.py +41 -0
- gaia/agents/blender/core/__init__.py +16 -0
- gaia/agents/blender/core/materials.py +506 -0
- gaia/agents/blender/core/objects.py +316 -0
- gaia/agents/blender/core/rendering.py +225 -0
- gaia/agents/blender/core/scene.py +220 -0
- gaia/agents/blender/core/view.py +146 -0
- gaia/agents/chat/__init__.py +9 -0
- gaia/agents/chat/agent.py +975 -0
- gaia/agents/chat/app.py +1058 -0
- gaia/agents/chat/session.py +508 -0
- gaia/agents/chat/tools/__init__.py +15 -0
- gaia/agents/chat/tools/file_tools.py +96 -0
- gaia/agents/chat/tools/rag_tools.py +1729 -0
- gaia/agents/chat/tools/shell_tools.py +436 -0
- gaia/agents/code/__init__.py +7 -0
- gaia/agents/code/agent.py +547 -0
- gaia/agents/code/app.py +266 -0
- gaia/agents/code/models.py +135 -0
- gaia/agents/code/orchestration/__init__.py +24 -0
- gaia/agents/code/orchestration/checklist_executor.py +1739 -0
- gaia/agents/code/orchestration/checklist_generator.py +709 -0
- gaia/agents/code/orchestration/factories/__init__.py +9 -0
- gaia/agents/code/orchestration/factories/base.py +63 -0
- gaia/agents/code/orchestration/factories/nextjs_factory.py +118 -0
- gaia/agents/code/orchestration/factories/python_factory.py +106 -0
- gaia/agents/code/orchestration/orchestrator.py +610 -0
- gaia/agents/code/orchestration/project_analyzer.py +391 -0
- gaia/agents/code/orchestration/steps/__init__.py +67 -0
- gaia/agents/code/orchestration/steps/base.py +188 -0
- gaia/agents/code/orchestration/steps/error_handler.py +314 -0
- gaia/agents/code/orchestration/steps/nextjs.py +828 -0
- gaia/agents/code/orchestration/steps/python.py +307 -0
- gaia/agents/code/orchestration/template_catalog.py +463 -0
- gaia/agents/code/orchestration/workflows/__init__.py +14 -0
- gaia/agents/code/orchestration/workflows/base.py +80 -0
- gaia/agents/code/orchestration/workflows/nextjs.py +186 -0
- gaia/agents/code/orchestration/workflows/python.py +94 -0
- gaia/agents/code/prompts/__init__.py +11 -0
- gaia/agents/code/prompts/base_prompt.py +77 -0
- gaia/agents/code/prompts/code_patterns.py +1925 -0
- gaia/agents/code/prompts/nextjs_prompt.py +40 -0
- gaia/agents/code/prompts/python_prompt.py +109 -0
- gaia/agents/code/schema_inference.py +365 -0
- gaia/agents/code/system_prompt.py +41 -0
- gaia/agents/code/tools/__init__.py +42 -0
- gaia/agents/code/tools/cli_tools.py +1138 -0
- gaia/agents/code/tools/code_formatting.py +319 -0
- gaia/agents/code/tools/code_tools.py +769 -0
- gaia/agents/code/tools/error_fixing.py +1347 -0
- gaia/agents/code/tools/external_tools.py +180 -0
- gaia/agents/code/tools/file_io.py +845 -0
- gaia/agents/code/tools/prisma_tools.py +190 -0
- gaia/agents/code/tools/project_management.py +1016 -0
- gaia/agents/code/tools/testing.py +321 -0
- gaia/agents/code/tools/typescript_tools.py +122 -0
- gaia/agents/code/tools/validation_parsing.py +461 -0
- gaia/agents/code/tools/validation_tools.py +803 -0
- gaia/agents/code/tools/web_dev_tools.py +1744 -0
- gaia/agents/code/validators/__init__.py +16 -0
- gaia/agents/code/validators/antipattern_checker.py +241 -0
- gaia/agents/code/validators/ast_analyzer.py +197 -0
- gaia/agents/code/validators/requirements_validator.py +145 -0
- gaia/agents/code/validators/syntax_validator.py +171 -0
- gaia/agents/docker/__init__.py +7 -0
- gaia/agents/docker/agent.py +642 -0
- gaia/agents/jira/__init__.py +11 -0
- gaia/agents/jira/agent.py +894 -0
- gaia/agents/jira/jql_templates.py +299 -0
- gaia/agents/routing/__init__.py +7 -0
- gaia/agents/routing/agent.py +512 -0
- gaia/agents/routing/system_prompt.py +75 -0
- gaia/api/__init__.py +23 -0
- gaia/api/agent_registry.py +238 -0
- gaia/api/app.py +305 -0
- gaia/api/openai_server.py +575 -0
- gaia/api/schemas.py +186 -0
- gaia/api/sse_handler.py +370 -0
- gaia/apps/__init__.py +4 -0
- gaia/apps/llm/__init__.py +6 -0
- gaia/apps/llm/app.py +169 -0
- gaia/apps/summarize/app.py +633 -0
- gaia/apps/summarize/html_viewer.py +133 -0
- gaia/apps/summarize/pdf_formatter.py +284 -0
- gaia/audio/__init__.py +2 -0
- gaia/audio/audio_client.py +439 -0
- gaia/audio/audio_recorder.py +269 -0
- gaia/audio/kokoro_tts.py +599 -0
- gaia/audio/whisper_asr.py +432 -0
- gaia/chat/__init__.py +16 -0
- gaia/chat/app.py +430 -0
- gaia/chat/prompts.py +522 -0
- gaia/chat/sdk.py +1200 -0
- gaia/cli.py +5621 -0
- gaia/eval/batch_experiment.py +2332 -0
- gaia/eval/claude.py +542 -0
- gaia/eval/config.py +37 -0
- gaia/eval/email_generator.py +512 -0
- gaia/eval/eval.py +3179 -0
- gaia/eval/groundtruth.py +1130 -0
- gaia/eval/transcript_generator.py +582 -0
- gaia/eval/webapp/README.md +168 -0
- gaia/eval/webapp/node_modules/.bin/mime +16 -0
- gaia/eval/webapp/node_modules/.bin/mime.cmd +17 -0
- gaia/eval/webapp/node_modules/.bin/mime.ps1 +28 -0
- gaia/eval/webapp/node_modules/.package-lock.json +865 -0
- gaia/eval/webapp/node_modules/accepts/HISTORY.md +243 -0
- gaia/eval/webapp/node_modules/accepts/LICENSE +23 -0
- gaia/eval/webapp/node_modules/accepts/README.md +140 -0
- gaia/eval/webapp/node_modules/accepts/index.js +238 -0
- gaia/eval/webapp/node_modules/accepts/package.json +47 -0
- gaia/eval/webapp/node_modules/array-flatten/LICENSE +21 -0
- gaia/eval/webapp/node_modules/array-flatten/README.md +43 -0
- gaia/eval/webapp/node_modules/array-flatten/array-flatten.js +64 -0
- gaia/eval/webapp/node_modules/array-flatten/package.json +39 -0
- gaia/eval/webapp/node_modules/body-parser/HISTORY.md +672 -0
- gaia/eval/webapp/node_modules/body-parser/LICENSE +23 -0
- gaia/eval/webapp/node_modules/body-parser/README.md +476 -0
- gaia/eval/webapp/node_modules/body-parser/SECURITY.md +25 -0
- gaia/eval/webapp/node_modules/body-parser/index.js +156 -0
- gaia/eval/webapp/node_modules/body-parser/lib/read.js +205 -0
- gaia/eval/webapp/node_modules/body-parser/lib/types/json.js +247 -0
- gaia/eval/webapp/node_modules/body-parser/lib/types/raw.js +101 -0
- gaia/eval/webapp/node_modules/body-parser/lib/types/text.js +121 -0
- gaia/eval/webapp/node_modules/body-parser/lib/types/urlencoded.js +307 -0
- gaia/eval/webapp/node_modules/body-parser/package.json +56 -0
- gaia/eval/webapp/node_modules/bytes/History.md +97 -0
- gaia/eval/webapp/node_modules/bytes/LICENSE +23 -0
- gaia/eval/webapp/node_modules/bytes/Readme.md +152 -0
- gaia/eval/webapp/node_modules/bytes/index.js +170 -0
- gaia/eval/webapp/node_modules/bytes/package.json +42 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/.eslintrc +17 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/.nycrc +9 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/CHANGELOG.md +30 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/LICENSE +21 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/README.md +62 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/actualApply.d.ts +1 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/actualApply.js +10 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/applyBind.d.ts +19 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/applyBind.js +10 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionApply.d.ts +1 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionApply.js +4 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionCall.d.ts +1 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionCall.js +4 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/index.d.ts +64 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/index.js +15 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/package.json +85 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/reflectApply.d.ts +3 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/reflectApply.js +4 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/test/index.js +63 -0
- gaia/eval/webapp/node_modules/call-bind-apply-helpers/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/call-bound/.eslintrc +13 -0
- gaia/eval/webapp/node_modules/call-bound/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/call-bound/.nycrc +9 -0
- gaia/eval/webapp/node_modules/call-bound/CHANGELOG.md +42 -0
- gaia/eval/webapp/node_modules/call-bound/LICENSE +21 -0
- gaia/eval/webapp/node_modules/call-bound/README.md +53 -0
- gaia/eval/webapp/node_modules/call-bound/index.d.ts +94 -0
- gaia/eval/webapp/node_modules/call-bound/index.js +19 -0
- gaia/eval/webapp/node_modules/call-bound/package.json +99 -0
- gaia/eval/webapp/node_modules/call-bound/test/index.js +61 -0
- gaia/eval/webapp/node_modules/call-bound/tsconfig.json +10 -0
- gaia/eval/webapp/node_modules/content-disposition/HISTORY.md +60 -0
- gaia/eval/webapp/node_modules/content-disposition/LICENSE +22 -0
- gaia/eval/webapp/node_modules/content-disposition/README.md +142 -0
- gaia/eval/webapp/node_modules/content-disposition/index.js +458 -0
- gaia/eval/webapp/node_modules/content-disposition/package.json +44 -0
- gaia/eval/webapp/node_modules/content-type/HISTORY.md +29 -0
- gaia/eval/webapp/node_modules/content-type/LICENSE +22 -0
- gaia/eval/webapp/node_modules/content-type/README.md +94 -0
- gaia/eval/webapp/node_modules/content-type/index.js +225 -0
- gaia/eval/webapp/node_modules/content-type/package.json +42 -0
- gaia/eval/webapp/node_modules/cookie/LICENSE +24 -0
- gaia/eval/webapp/node_modules/cookie/README.md +317 -0
- gaia/eval/webapp/node_modules/cookie/SECURITY.md +25 -0
- gaia/eval/webapp/node_modules/cookie/index.js +334 -0
- gaia/eval/webapp/node_modules/cookie/package.json +44 -0
- gaia/eval/webapp/node_modules/cookie-signature/.npmignore +4 -0
- gaia/eval/webapp/node_modules/cookie-signature/History.md +38 -0
- gaia/eval/webapp/node_modules/cookie-signature/Readme.md +42 -0
- gaia/eval/webapp/node_modules/cookie-signature/index.js +51 -0
- gaia/eval/webapp/node_modules/cookie-signature/package.json +18 -0
- gaia/eval/webapp/node_modules/debug/.coveralls.yml +1 -0
- gaia/eval/webapp/node_modules/debug/.eslintrc +11 -0
- gaia/eval/webapp/node_modules/debug/.npmignore +9 -0
- gaia/eval/webapp/node_modules/debug/.travis.yml +14 -0
- gaia/eval/webapp/node_modules/debug/CHANGELOG.md +362 -0
- gaia/eval/webapp/node_modules/debug/LICENSE +19 -0
- gaia/eval/webapp/node_modules/debug/Makefile +50 -0
- gaia/eval/webapp/node_modules/debug/README.md +312 -0
- gaia/eval/webapp/node_modules/debug/component.json +19 -0
- gaia/eval/webapp/node_modules/debug/karma.conf.js +70 -0
- gaia/eval/webapp/node_modules/debug/node.js +1 -0
- gaia/eval/webapp/node_modules/debug/package.json +49 -0
- gaia/eval/webapp/node_modules/debug/src/browser.js +185 -0
- gaia/eval/webapp/node_modules/debug/src/debug.js +202 -0
- gaia/eval/webapp/node_modules/debug/src/index.js +10 -0
- gaia/eval/webapp/node_modules/debug/src/inspector-log.js +15 -0
- gaia/eval/webapp/node_modules/debug/src/node.js +248 -0
- gaia/eval/webapp/node_modules/depd/History.md +103 -0
- gaia/eval/webapp/node_modules/depd/LICENSE +22 -0
- gaia/eval/webapp/node_modules/depd/Readme.md +280 -0
- gaia/eval/webapp/node_modules/depd/index.js +538 -0
- gaia/eval/webapp/node_modules/depd/lib/browser/index.js +77 -0
- gaia/eval/webapp/node_modules/depd/package.json +45 -0
- gaia/eval/webapp/node_modules/destroy/LICENSE +23 -0
- gaia/eval/webapp/node_modules/destroy/README.md +63 -0
- gaia/eval/webapp/node_modules/destroy/index.js +209 -0
- gaia/eval/webapp/node_modules/destroy/package.json +48 -0
- gaia/eval/webapp/node_modules/dunder-proto/.eslintrc +5 -0
- gaia/eval/webapp/node_modules/dunder-proto/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/dunder-proto/.nycrc +13 -0
- gaia/eval/webapp/node_modules/dunder-proto/CHANGELOG.md +24 -0
- gaia/eval/webapp/node_modules/dunder-proto/LICENSE +21 -0
- gaia/eval/webapp/node_modules/dunder-proto/README.md +54 -0
- gaia/eval/webapp/node_modules/dunder-proto/get.d.ts +5 -0
- gaia/eval/webapp/node_modules/dunder-proto/get.js +30 -0
- gaia/eval/webapp/node_modules/dunder-proto/package.json +76 -0
- gaia/eval/webapp/node_modules/dunder-proto/set.d.ts +5 -0
- gaia/eval/webapp/node_modules/dunder-proto/set.js +35 -0
- gaia/eval/webapp/node_modules/dunder-proto/test/get.js +34 -0
- gaia/eval/webapp/node_modules/dunder-proto/test/index.js +4 -0
- gaia/eval/webapp/node_modules/dunder-proto/test/set.js +50 -0
- gaia/eval/webapp/node_modules/dunder-proto/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/ee-first/LICENSE +22 -0
- gaia/eval/webapp/node_modules/ee-first/README.md +80 -0
- gaia/eval/webapp/node_modules/ee-first/index.js +95 -0
- gaia/eval/webapp/node_modules/ee-first/package.json +29 -0
- gaia/eval/webapp/node_modules/encodeurl/LICENSE +22 -0
- gaia/eval/webapp/node_modules/encodeurl/README.md +109 -0
- gaia/eval/webapp/node_modules/encodeurl/index.js +60 -0
- gaia/eval/webapp/node_modules/encodeurl/package.json +40 -0
- gaia/eval/webapp/node_modules/es-define-property/.eslintrc +13 -0
- gaia/eval/webapp/node_modules/es-define-property/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/es-define-property/.nycrc +9 -0
- gaia/eval/webapp/node_modules/es-define-property/CHANGELOG.md +29 -0
- gaia/eval/webapp/node_modules/es-define-property/LICENSE +21 -0
- gaia/eval/webapp/node_modules/es-define-property/README.md +49 -0
- gaia/eval/webapp/node_modules/es-define-property/index.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-define-property/index.js +14 -0
- gaia/eval/webapp/node_modules/es-define-property/package.json +81 -0
- gaia/eval/webapp/node_modules/es-define-property/test/index.js +56 -0
- gaia/eval/webapp/node_modules/es-define-property/tsconfig.json +10 -0
- gaia/eval/webapp/node_modules/es-errors/.eslintrc +5 -0
- gaia/eval/webapp/node_modules/es-errors/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/es-errors/CHANGELOG.md +40 -0
- gaia/eval/webapp/node_modules/es-errors/LICENSE +21 -0
- gaia/eval/webapp/node_modules/es-errors/README.md +55 -0
- gaia/eval/webapp/node_modules/es-errors/eval.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/eval.js +4 -0
- gaia/eval/webapp/node_modules/es-errors/index.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/index.js +4 -0
- gaia/eval/webapp/node_modules/es-errors/package.json +80 -0
- gaia/eval/webapp/node_modules/es-errors/range.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/range.js +4 -0
- gaia/eval/webapp/node_modules/es-errors/ref.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/ref.js +4 -0
- gaia/eval/webapp/node_modules/es-errors/syntax.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/syntax.js +4 -0
- gaia/eval/webapp/node_modules/es-errors/test/index.js +19 -0
- gaia/eval/webapp/node_modules/es-errors/tsconfig.json +49 -0
- gaia/eval/webapp/node_modules/es-errors/type.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/type.js +4 -0
- gaia/eval/webapp/node_modules/es-errors/uri.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-errors/uri.js +4 -0
- gaia/eval/webapp/node_modules/es-object-atoms/.eslintrc +16 -0
- gaia/eval/webapp/node_modules/es-object-atoms/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/es-object-atoms/CHANGELOG.md +37 -0
- gaia/eval/webapp/node_modules/es-object-atoms/LICENSE +21 -0
- gaia/eval/webapp/node_modules/es-object-atoms/README.md +63 -0
- gaia/eval/webapp/node_modules/es-object-atoms/RequireObjectCoercible.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-object-atoms/RequireObjectCoercible.js +11 -0
- gaia/eval/webapp/node_modules/es-object-atoms/ToObject.d.ts +7 -0
- gaia/eval/webapp/node_modules/es-object-atoms/ToObject.js +10 -0
- gaia/eval/webapp/node_modules/es-object-atoms/index.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-object-atoms/index.js +4 -0
- gaia/eval/webapp/node_modules/es-object-atoms/isObject.d.ts +3 -0
- gaia/eval/webapp/node_modules/es-object-atoms/isObject.js +6 -0
- gaia/eval/webapp/node_modules/es-object-atoms/package.json +80 -0
- gaia/eval/webapp/node_modules/es-object-atoms/test/index.js +38 -0
- gaia/eval/webapp/node_modules/es-object-atoms/tsconfig.json +6 -0
- gaia/eval/webapp/node_modules/escape-html/LICENSE +24 -0
- gaia/eval/webapp/node_modules/escape-html/Readme.md +43 -0
- gaia/eval/webapp/node_modules/escape-html/index.js +78 -0
- gaia/eval/webapp/node_modules/escape-html/package.json +24 -0
- gaia/eval/webapp/node_modules/etag/HISTORY.md +83 -0
- gaia/eval/webapp/node_modules/etag/LICENSE +22 -0
- gaia/eval/webapp/node_modules/etag/README.md +159 -0
- gaia/eval/webapp/node_modules/etag/index.js +131 -0
- gaia/eval/webapp/node_modules/etag/package.json +47 -0
- gaia/eval/webapp/node_modules/express/History.md +3656 -0
- gaia/eval/webapp/node_modules/express/LICENSE +24 -0
- gaia/eval/webapp/node_modules/express/Readme.md +260 -0
- gaia/eval/webapp/node_modules/express/index.js +11 -0
- gaia/eval/webapp/node_modules/express/lib/application.js +661 -0
- gaia/eval/webapp/node_modules/express/lib/express.js +116 -0
- gaia/eval/webapp/node_modules/express/lib/middleware/init.js +43 -0
- gaia/eval/webapp/node_modules/express/lib/middleware/query.js +47 -0
- gaia/eval/webapp/node_modules/express/lib/request.js +525 -0
- gaia/eval/webapp/node_modules/express/lib/response.js +1179 -0
- gaia/eval/webapp/node_modules/express/lib/router/index.js +673 -0
- gaia/eval/webapp/node_modules/express/lib/router/layer.js +181 -0
- gaia/eval/webapp/node_modules/express/lib/router/route.js +230 -0
- gaia/eval/webapp/node_modules/express/lib/utils.js +303 -0
- gaia/eval/webapp/node_modules/express/lib/view.js +182 -0
- gaia/eval/webapp/node_modules/express/package.json +102 -0
- gaia/eval/webapp/node_modules/finalhandler/HISTORY.md +210 -0
- gaia/eval/webapp/node_modules/finalhandler/LICENSE +22 -0
- gaia/eval/webapp/node_modules/finalhandler/README.md +147 -0
- gaia/eval/webapp/node_modules/finalhandler/SECURITY.md +25 -0
- gaia/eval/webapp/node_modules/finalhandler/index.js +341 -0
- gaia/eval/webapp/node_modules/finalhandler/package.json +47 -0
- gaia/eval/webapp/node_modules/forwarded/HISTORY.md +21 -0
- gaia/eval/webapp/node_modules/forwarded/LICENSE +22 -0
- gaia/eval/webapp/node_modules/forwarded/README.md +57 -0
- gaia/eval/webapp/node_modules/forwarded/index.js +90 -0
- gaia/eval/webapp/node_modules/forwarded/package.json +45 -0
- gaia/eval/webapp/node_modules/fresh/HISTORY.md +70 -0
- gaia/eval/webapp/node_modules/fresh/LICENSE +23 -0
- gaia/eval/webapp/node_modules/fresh/README.md +119 -0
- gaia/eval/webapp/node_modules/fresh/index.js +137 -0
- gaia/eval/webapp/node_modules/fresh/package.json +46 -0
- gaia/eval/webapp/node_modules/fs/README.md +9 -0
- gaia/eval/webapp/node_modules/fs/package.json +20 -0
- gaia/eval/webapp/node_modules/function-bind/.eslintrc +21 -0
- gaia/eval/webapp/node_modules/function-bind/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/function-bind/.github/SECURITY.md +3 -0
- gaia/eval/webapp/node_modules/function-bind/.nycrc +13 -0
- gaia/eval/webapp/node_modules/function-bind/CHANGELOG.md +136 -0
- gaia/eval/webapp/node_modules/function-bind/LICENSE +20 -0
- gaia/eval/webapp/node_modules/function-bind/README.md +46 -0
- gaia/eval/webapp/node_modules/function-bind/implementation.js +84 -0
- gaia/eval/webapp/node_modules/function-bind/index.js +5 -0
- gaia/eval/webapp/node_modules/function-bind/package.json +87 -0
- gaia/eval/webapp/node_modules/function-bind/test/.eslintrc +9 -0
- gaia/eval/webapp/node_modules/function-bind/test/index.js +252 -0
- gaia/eval/webapp/node_modules/get-intrinsic/.eslintrc +42 -0
- gaia/eval/webapp/node_modules/get-intrinsic/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/get-intrinsic/.nycrc +9 -0
- gaia/eval/webapp/node_modules/get-intrinsic/CHANGELOG.md +186 -0
- gaia/eval/webapp/node_modules/get-intrinsic/LICENSE +21 -0
- gaia/eval/webapp/node_modules/get-intrinsic/README.md +71 -0
- gaia/eval/webapp/node_modules/get-intrinsic/index.js +378 -0
- gaia/eval/webapp/node_modules/get-intrinsic/package.json +97 -0
- gaia/eval/webapp/node_modules/get-intrinsic/test/GetIntrinsic.js +274 -0
- gaia/eval/webapp/node_modules/get-proto/.eslintrc +10 -0
- gaia/eval/webapp/node_modules/get-proto/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/get-proto/.nycrc +9 -0
- gaia/eval/webapp/node_modules/get-proto/CHANGELOG.md +21 -0
- gaia/eval/webapp/node_modules/get-proto/LICENSE +21 -0
- gaia/eval/webapp/node_modules/get-proto/Object.getPrototypeOf.d.ts +5 -0
- gaia/eval/webapp/node_modules/get-proto/Object.getPrototypeOf.js +6 -0
- gaia/eval/webapp/node_modules/get-proto/README.md +50 -0
- gaia/eval/webapp/node_modules/get-proto/Reflect.getPrototypeOf.d.ts +3 -0
- gaia/eval/webapp/node_modules/get-proto/Reflect.getPrototypeOf.js +4 -0
- gaia/eval/webapp/node_modules/get-proto/index.d.ts +5 -0
- gaia/eval/webapp/node_modules/get-proto/index.js +27 -0
- gaia/eval/webapp/node_modules/get-proto/package.json +81 -0
- gaia/eval/webapp/node_modules/get-proto/test/index.js +68 -0
- gaia/eval/webapp/node_modules/get-proto/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/gopd/.eslintrc +16 -0
- gaia/eval/webapp/node_modules/gopd/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/gopd/CHANGELOG.md +45 -0
- gaia/eval/webapp/node_modules/gopd/LICENSE +21 -0
- gaia/eval/webapp/node_modules/gopd/README.md +40 -0
- gaia/eval/webapp/node_modules/gopd/gOPD.d.ts +1 -0
- gaia/eval/webapp/node_modules/gopd/gOPD.js +4 -0
- gaia/eval/webapp/node_modules/gopd/index.d.ts +5 -0
- gaia/eval/webapp/node_modules/gopd/index.js +15 -0
- gaia/eval/webapp/node_modules/gopd/package.json +77 -0
- gaia/eval/webapp/node_modules/gopd/test/index.js +36 -0
- gaia/eval/webapp/node_modules/gopd/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/has-symbols/.eslintrc +11 -0
- gaia/eval/webapp/node_modules/has-symbols/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/has-symbols/.nycrc +9 -0
- gaia/eval/webapp/node_modules/has-symbols/CHANGELOG.md +91 -0
- gaia/eval/webapp/node_modules/has-symbols/LICENSE +21 -0
- gaia/eval/webapp/node_modules/has-symbols/README.md +46 -0
- gaia/eval/webapp/node_modules/has-symbols/index.d.ts +3 -0
- gaia/eval/webapp/node_modules/has-symbols/index.js +14 -0
- gaia/eval/webapp/node_modules/has-symbols/package.json +111 -0
- gaia/eval/webapp/node_modules/has-symbols/shams.d.ts +3 -0
- gaia/eval/webapp/node_modules/has-symbols/shams.js +45 -0
- gaia/eval/webapp/node_modules/has-symbols/test/index.js +22 -0
- gaia/eval/webapp/node_modules/has-symbols/test/shams/core-js.js +29 -0
- gaia/eval/webapp/node_modules/has-symbols/test/shams/get-own-property-symbols.js +29 -0
- gaia/eval/webapp/node_modules/has-symbols/test/tests.js +58 -0
- gaia/eval/webapp/node_modules/has-symbols/tsconfig.json +10 -0
- gaia/eval/webapp/node_modules/hasown/.eslintrc +5 -0
- gaia/eval/webapp/node_modules/hasown/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/hasown/.nycrc +13 -0
- gaia/eval/webapp/node_modules/hasown/CHANGELOG.md +40 -0
- gaia/eval/webapp/node_modules/hasown/LICENSE +21 -0
- gaia/eval/webapp/node_modules/hasown/README.md +40 -0
- gaia/eval/webapp/node_modules/hasown/index.d.ts +3 -0
- gaia/eval/webapp/node_modules/hasown/index.js +8 -0
- gaia/eval/webapp/node_modules/hasown/package.json +92 -0
- gaia/eval/webapp/node_modules/hasown/tsconfig.json +6 -0
- gaia/eval/webapp/node_modules/http-errors/HISTORY.md +180 -0
- gaia/eval/webapp/node_modules/http-errors/LICENSE +23 -0
- gaia/eval/webapp/node_modules/http-errors/README.md +169 -0
- gaia/eval/webapp/node_modules/http-errors/index.js +289 -0
- gaia/eval/webapp/node_modules/http-errors/package.json +50 -0
- gaia/eval/webapp/node_modules/iconv-lite/Changelog.md +162 -0
- gaia/eval/webapp/node_modules/iconv-lite/LICENSE +21 -0
- gaia/eval/webapp/node_modules/iconv-lite/README.md +156 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/dbcs-codec.js +555 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/dbcs-data.js +176 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/index.js +22 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/internal.js +188 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-codec.js +72 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-data-generated.js +451 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-data.js +174 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/big5-added.json +122 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp936.json +264 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp949.json +273 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp950.json +177 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/eucjp.json +182 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +1 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/gbk-added.json +55 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/shiftjis.json +125 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/utf16.js +177 -0
- gaia/eval/webapp/node_modules/iconv-lite/encodings/utf7.js +290 -0
- gaia/eval/webapp/node_modules/iconv-lite/lib/bom-handling.js +52 -0
- gaia/eval/webapp/node_modules/iconv-lite/lib/extend-node.js +217 -0
- gaia/eval/webapp/node_modules/iconv-lite/lib/index.d.ts +24 -0
- gaia/eval/webapp/node_modules/iconv-lite/lib/index.js +153 -0
- gaia/eval/webapp/node_modules/iconv-lite/lib/streams.js +121 -0
- gaia/eval/webapp/node_modules/iconv-lite/package.json +46 -0
- gaia/eval/webapp/node_modules/inherits/LICENSE +16 -0
- gaia/eval/webapp/node_modules/inherits/README.md +42 -0
- gaia/eval/webapp/node_modules/inherits/inherits.js +9 -0
- gaia/eval/webapp/node_modules/inherits/inherits_browser.js +27 -0
- gaia/eval/webapp/node_modules/inherits/package.json +29 -0
- gaia/eval/webapp/node_modules/ipaddr.js/LICENSE +19 -0
- gaia/eval/webapp/node_modules/ipaddr.js/README.md +233 -0
- gaia/eval/webapp/node_modules/ipaddr.js/ipaddr.min.js +1 -0
- gaia/eval/webapp/node_modules/ipaddr.js/lib/ipaddr.js +673 -0
- gaia/eval/webapp/node_modules/ipaddr.js/lib/ipaddr.js.d.ts +68 -0
- gaia/eval/webapp/node_modules/ipaddr.js/package.json +35 -0
- gaia/eval/webapp/node_modules/math-intrinsics/.eslintrc +16 -0
- gaia/eval/webapp/node_modules/math-intrinsics/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/math-intrinsics/CHANGELOG.md +24 -0
- gaia/eval/webapp/node_modules/math-intrinsics/LICENSE +21 -0
- gaia/eval/webapp/node_modules/math-intrinsics/README.md +50 -0
- gaia/eval/webapp/node_modules/math-intrinsics/abs.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/abs.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/constants/maxArrayLength.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/constants/maxArrayLength.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/constants/maxSafeInteger.js +5 -0
- gaia/eval/webapp/node_modules/math-intrinsics/constants/maxValue.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/constants/maxValue.js +5 -0
- gaia/eval/webapp/node_modules/math-intrinsics/floor.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/floor.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isFinite.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isFinite.js +12 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isInteger.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isInteger.js +16 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isNaN.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isNaN.js +6 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isNegativeZero.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/isNegativeZero.js +6 -0
- gaia/eval/webapp/node_modules/math-intrinsics/max.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/max.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/min.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/min.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/mod.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/mod.js +9 -0
- gaia/eval/webapp/node_modules/math-intrinsics/package.json +86 -0
- gaia/eval/webapp/node_modules/math-intrinsics/pow.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/pow.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/round.d.ts +1 -0
- gaia/eval/webapp/node_modules/math-intrinsics/round.js +4 -0
- gaia/eval/webapp/node_modules/math-intrinsics/sign.d.ts +3 -0
- gaia/eval/webapp/node_modules/math-intrinsics/sign.js +11 -0
- gaia/eval/webapp/node_modules/math-intrinsics/test/index.js +192 -0
- gaia/eval/webapp/node_modules/math-intrinsics/tsconfig.json +3 -0
- gaia/eval/webapp/node_modules/media-typer/HISTORY.md +22 -0
- gaia/eval/webapp/node_modules/media-typer/LICENSE +22 -0
- gaia/eval/webapp/node_modules/media-typer/README.md +81 -0
- gaia/eval/webapp/node_modules/media-typer/index.js +270 -0
- gaia/eval/webapp/node_modules/media-typer/package.json +26 -0
- gaia/eval/webapp/node_modules/merge-descriptors/HISTORY.md +21 -0
- gaia/eval/webapp/node_modules/merge-descriptors/LICENSE +23 -0
- gaia/eval/webapp/node_modules/merge-descriptors/README.md +49 -0
- gaia/eval/webapp/node_modules/merge-descriptors/index.js +60 -0
- gaia/eval/webapp/node_modules/merge-descriptors/package.json +39 -0
- gaia/eval/webapp/node_modules/methods/HISTORY.md +29 -0
- gaia/eval/webapp/node_modules/methods/LICENSE +24 -0
- gaia/eval/webapp/node_modules/methods/README.md +51 -0
- gaia/eval/webapp/node_modules/methods/index.js +69 -0
- gaia/eval/webapp/node_modules/methods/package.json +36 -0
- gaia/eval/webapp/node_modules/mime/.npmignore +0 -0
- gaia/eval/webapp/node_modules/mime/CHANGELOG.md +164 -0
- gaia/eval/webapp/node_modules/mime/LICENSE +21 -0
- gaia/eval/webapp/node_modules/mime/README.md +90 -0
- gaia/eval/webapp/node_modules/mime/cli.js +8 -0
- gaia/eval/webapp/node_modules/mime/mime.js +108 -0
- gaia/eval/webapp/node_modules/mime/package.json +44 -0
- gaia/eval/webapp/node_modules/mime/src/build.js +53 -0
- gaia/eval/webapp/node_modules/mime/src/test.js +60 -0
- gaia/eval/webapp/node_modules/mime/types.json +1 -0
- gaia/eval/webapp/node_modules/mime-db/HISTORY.md +507 -0
- gaia/eval/webapp/node_modules/mime-db/LICENSE +23 -0
- gaia/eval/webapp/node_modules/mime-db/README.md +100 -0
- gaia/eval/webapp/node_modules/mime-db/db.json +8519 -0
- gaia/eval/webapp/node_modules/mime-db/index.js +12 -0
- gaia/eval/webapp/node_modules/mime-db/package.json +60 -0
- gaia/eval/webapp/node_modules/mime-types/HISTORY.md +397 -0
- gaia/eval/webapp/node_modules/mime-types/LICENSE +23 -0
- gaia/eval/webapp/node_modules/mime-types/README.md +113 -0
- gaia/eval/webapp/node_modules/mime-types/index.js +188 -0
- gaia/eval/webapp/node_modules/mime-types/package.json +44 -0
- gaia/eval/webapp/node_modules/ms/index.js +152 -0
- gaia/eval/webapp/node_modules/ms/license.md +21 -0
- gaia/eval/webapp/node_modules/ms/package.json +37 -0
- gaia/eval/webapp/node_modules/ms/readme.md +51 -0
- gaia/eval/webapp/node_modules/negotiator/HISTORY.md +108 -0
- gaia/eval/webapp/node_modules/negotiator/LICENSE +24 -0
- gaia/eval/webapp/node_modules/negotiator/README.md +203 -0
- gaia/eval/webapp/node_modules/negotiator/index.js +82 -0
- gaia/eval/webapp/node_modules/negotiator/lib/charset.js +169 -0
- gaia/eval/webapp/node_modules/negotiator/lib/encoding.js +184 -0
- gaia/eval/webapp/node_modules/negotiator/lib/language.js +179 -0
- gaia/eval/webapp/node_modules/negotiator/lib/mediaType.js +294 -0
- gaia/eval/webapp/node_modules/negotiator/package.json +42 -0
- gaia/eval/webapp/node_modules/object-inspect/.eslintrc +53 -0
- gaia/eval/webapp/node_modules/object-inspect/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/object-inspect/.nycrc +13 -0
- gaia/eval/webapp/node_modules/object-inspect/CHANGELOG.md +424 -0
- gaia/eval/webapp/node_modules/object-inspect/LICENSE +21 -0
- gaia/eval/webapp/node_modules/object-inspect/example/all.js +23 -0
- gaia/eval/webapp/node_modules/object-inspect/example/circular.js +6 -0
- gaia/eval/webapp/node_modules/object-inspect/example/fn.js +5 -0
- gaia/eval/webapp/node_modules/object-inspect/example/inspect.js +10 -0
- gaia/eval/webapp/node_modules/object-inspect/index.js +544 -0
- gaia/eval/webapp/node_modules/object-inspect/package-support.json +20 -0
- gaia/eval/webapp/node_modules/object-inspect/package.json +105 -0
- gaia/eval/webapp/node_modules/object-inspect/readme.markdown +84 -0
- gaia/eval/webapp/node_modules/object-inspect/test/bigint.js +58 -0
- gaia/eval/webapp/node_modules/object-inspect/test/browser/dom.js +15 -0
- gaia/eval/webapp/node_modules/object-inspect/test/circular.js +16 -0
- gaia/eval/webapp/node_modules/object-inspect/test/deep.js +12 -0
- gaia/eval/webapp/node_modules/object-inspect/test/element.js +53 -0
- gaia/eval/webapp/node_modules/object-inspect/test/err.js +48 -0
- gaia/eval/webapp/node_modules/object-inspect/test/fakes.js +29 -0
- gaia/eval/webapp/node_modules/object-inspect/test/fn.js +76 -0
- gaia/eval/webapp/node_modules/object-inspect/test/global.js +17 -0
- gaia/eval/webapp/node_modules/object-inspect/test/has.js +15 -0
- gaia/eval/webapp/node_modules/object-inspect/test/holes.js +15 -0
- gaia/eval/webapp/node_modules/object-inspect/test/indent-option.js +271 -0
- gaia/eval/webapp/node_modules/object-inspect/test/inspect.js +139 -0
- gaia/eval/webapp/node_modules/object-inspect/test/lowbyte.js +12 -0
- gaia/eval/webapp/node_modules/object-inspect/test/number.js +58 -0
- gaia/eval/webapp/node_modules/object-inspect/test/quoteStyle.js +26 -0
- gaia/eval/webapp/node_modules/object-inspect/test/toStringTag.js +40 -0
- gaia/eval/webapp/node_modules/object-inspect/test/undef.js +12 -0
- gaia/eval/webapp/node_modules/object-inspect/test/values.js +261 -0
- gaia/eval/webapp/node_modules/object-inspect/test-core-js.js +26 -0
- gaia/eval/webapp/node_modules/object-inspect/util.inspect.js +1 -0
- gaia/eval/webapp/node_modules/on-finished/HISTORY.md +98 -0
- gaia/eval/webapp/node_modules/on-finished/LICENSE +23 -0
- gaia/eval/webapp/node_modules/on-finished/README.md +162 -0
- gaia/eval/webapp/node_modules/on-finished/index.js +234 -0
- gaia/eval/webapp/node_modules/on-finished/package.json +39 -0
- gaia/eval/webapp/node_modules/parseurl/HISTORY.md +58 -0
- gaia/eval/webapp/node_modules/parseurl/LICENSE +24 -0
- gaia/eval/webapp/node_modules/parseurl/README.md +133 -0
- gaia/eval/webapp/node_modules/parseurl/index.js +158 -0
- gaia/eval/webapp/node_modules/parseurl/package.json +40 -0
- gaia/eval/webapp/node_modules/path/.npmignore +1 -0
- gaia/eval/webapp/node_modules/path/LICENSE +18 -0
- gaia/eval/webapp/node_modules/path/README.md +15 -0
- gaia/eval/webapp/node_modules/path/package.json +24 -0
- gaia/eval/webapp/node_modules/path/path.js +628 -0
- gaia/eval/webapp/node_modules/path-to-regexp/LICENSE +21 -0
- gaia/eval/webapp/node_modules/path-to-regexp/Readme.md +35 -0
- gaia/eval/webapp/node_modules/path-to-regexp/index.js +156 -0
- gaia/eval/webapp/node_modules/path-to-regexp/package.json +30 -0
- gaia/eval/webapp/node_modules/process/.eslintrc +21 -0
- gaia/eval/webapp/node_modules/process/LICENSE +22 -0
- gaia/eval/webapp/node_modules/process/README.md +26 -0
- gaia/eval/webapp/node_modules/process/browser.js +184 -0
- gaia/eval/webapp/node_modules/process/index.js +2 -0
- gaia/eval/webapp/node_modules/process/package.json +27 -0
- gaia/eval/webapp/node_modules/process/test.js +199 -0
- gaia/eval/webapp/node_modules/proxy-addr/HISTORY.md +161 -0
- gaia/eval/webapp/node_modules/proxy-addr/LICENSE +22 -0
- gaia/eval/webapp/node_modules/proxy-addr/README.md +139 -0
- gaia/eval/webapp/node_modules/proxy-addr/index.js +327 -0
- gaia/eval/webapp/node_modules/proxy-addr/package.json +47 -0
- gaia/eval/webapp/node_modules/qs/.editorconfig +46 -0
- gaia/eval/webapp/node_modules/qs/.eslintrc +38 -0
- gaia/eval/webapp/node_modules/qs/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/qs/.nycrc +13 -0
- gaia/eval/webapp/node_modules/qs/CHANGELOG.md +600 -0
- gaia/eval/webapp/node_modules/qs/LICENSE.md +29 -0
- gaia/eval/webapp/node_modules/qs/README.md +709 -0
- gaia/eval/webapp/node_modules/qs/dist/qs.js +90 -0
- gaia/eval/webapp/node_modules/qs/lib/formats.js +23 -0
- gaia/eval/webapp/node_modules/qs/lib/index.js +11 -0
- gaia/eval/webapp/node_modules/qs/lib/parse.js +296 -0
- gaia/eval/webapp/node_modules/qs/lib/stringify.js +351 -0
- gaia/eval/webapp/node_modules/qs/lib/utils.js +265 -0
- gaia/eval/webapp/node_modules/qs/package.json +91 -0
- gaia/eval/webapp/node_modules/qs/test/empty-keys-cases.js +267 -0
- gaia/eval/webapp/node_modules/qs/test/parse.js +1170 -0
- gaia/eval/webapp/node_modules/qs/test/stringify.js +1298 -0
- gaia/eval/webapp/node_modules/qs/test/utils.js +136 -0
- gaia/eval/webapp/node_modules/range-parser/HISTORY.md +56 -0
- gaia/eval/webapp/node_modules/range-parser/LICENSE +23 -0
- gaia/eval/webapp/node_modules/range-parser/README.md +84 -0
- gaia/eval/webapp/node_modules/range-parser/index.js +162 -0
- gaia/eval/webapp/node_modules/range-parser/package.json +44 -0
- gaia/eval/webapp/node_modules/raw-body/HISTORY.md +308 -0
- gaia/eval/webapp/node_modules/raw-body/LICENSE +22 -0
- gaia/eval/webapp/node_modules/raw-body/README.md +223 -0
- gaia/eval/webapp/node_modules/raw-body/SECURITY.md +24 -0
- gaia/eval/webapp/node_modules/raw-body/index.d.ts +87 -0
- gaia/eval/webapp/node_modules/raw-body/index.js +336 -0
- gaia/eval/webapp/node_modules/raw-body/package.json +49 -0
- gaia/eval/webapp/node_modules/safe-buffer/LICENSE +21 -0
- gaia/eval/webapp/node_modules/safe-buffer/README.md +584 -0
- gaia/eval/webapp/node_modules/safe-buffer/index.d.ts +187 -0
- gaia/eval/webapp/node_modules/safe-buffer/index.js +65 -0
- gaia/eval/webapp/node_modules/safe-buffer/package.json +51 -0
- gaia/eval/webapp/node_modules/safer-buffer/LICENSE +21 -0
- gaia/eval/webapp/node_modules/safer-buffer/Porting-Buffer.md +268 -0
- gaia/eval/webapp/node_modules/safer-buffer/Readme.md +156 -0
- gaia/eval/webapp/node_modules/safer-buffer/dangerous.js +58 -0
- gaia/eval/webapp/node_modules/safer-buffer/package.json +34 -0
- gaia/eval/webapp/node_modules/safer-buffer/safer.js +77 -0
- gaia/eval/webapp/node_modules/safer-buffer/tests.js +406 -0
- gaia/eval/webapp/node_modules/send/HISTORY.md +526 -0
- gaia/eval/webapp/node_modules/send/LICENSE +23 -0
- gaia/eval/webapp/node_modules/send/README.md +327 -0
- gaia/eval/webapp/node_modules/send/SECURITY.md +24 -0
- gaia/eval/webapp/node_modules/send/index.js +1142 -0
- gaia/eval/webapp/node_modules/send/node_modules/encodeurl/HISTORY.md +14 -0
- gaia/eval/webapp/node_modules/send/node_modules/encodeurl/LICENSE +22 -0
- gaia/eval/webapp/node_modules/send/node_modules/encodeurl/README.md +128 -0
- gaia/eval/webapp/node_modules/send/node_modules/encodeurl/index.js +60 -0
- gaia/eval/webapp/node_modules/send/node_modules/encodeurl/package.json +40 -0
- gaia/eval/webapp/node_modules/send/node_modules/ms/index.js +162 -0
- gaia/eval/webapp/node_modules/send/node_modules/ms/license.md +21 -0
- gaia/eval/webapp/node_modules/send/node_modules/ms/package.json +38 -0
- gaia/eval/webapp/node_modules/send/node_modules/ms/readme.md +59 -0
- gaia/eval/webapp/node_modules/send/package.json +62 -0
- gaia/eval/webapp/node_modules/serve-static/HISTORY.md +487 -0
- gaia/eval/webapp/node_modules/serve-static/LICENSE +25 -0
- gaia/eval/webapp/node_modules/serve-static/README.md +257 -0
- gaia/eval/webapp/node_modules/serve-static/index.js +209 -0
- gaia/eval/webapp/node_modules/serve-static/package.json +42 -0
- gaia/eval/webapp/node_modules/setprototypeof/LICENSE +13 -0
- gaia/eval/webapp/node_modules/setprototypeof/README.md +31 -0
- gaia/eval/webapp/node_modules/setprototypeof/index.d.ts +2 -0
- gaia/eval/webapp/node_modules/setprototypeof/index.js +17 -0
- gaia/eval/webapp/node_modules/setprototypeof/package.json +38 -0
- gaia/eval/webapp/node_modules/setprototypeof/test/index.js +24 -0
- gaia/eval/webapp/node_modules/side-channel/.editorconfig +9 -0
- gaia/eval/webapp/node_modules/side-channel/.eslintrc +12 -0
- gaia/eval/webapp/node_modules/side-channel/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/side-channel/.nycrc +13 -0
- gaia/eval/webapp/node_modules/side-channel/CHANGELOG.md +110 -0
- gaia/eval/webapp/node_modules/side-channel/LICENSE +21 -0
- gaia/eval/webapp/node_modules/side-channel/README.md +61 -0
- gaia/eval/webapp/node_modules/side-channel/index.d.ts +14 -0
- gaia/eval/webapp/node_modules/side-channel/index.js +43 -0
- gaia/eval/webapp/node_modules/side-channel/package.json +85 -0
- gaia/eval/webapp/node_modules/side-channel/test/index.js +104 -0
- gaia/eval/webapp/node_modules/side-channel/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/side-channel-list/.editorconfig +9 -0
- gaia/eval/webapp/node_modules/side-channel-list/.eslintrc +11 -0
- gaia/eval/webapp/node_modules/side-channel-list/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/side-channel-list/.nycrc +13 -0
- gaia/eval/webapp/node_modules/side-channel-list/CHANGELOG.md +15 -0
- gaia/eval/webapp/node_modules/side-channel-list/LICENSE +21 -0
- gaia/eval/webapp/node_modules/side-channel-list/README.md +62 -0
- gaia/eval/webapp/node_modules/side-channel-list/index.d.ts +13 -0
- gaia/eval/webapp/node_modules/side-channel-list/index.js +113 -0
- gaia/eval/webapp/node_modules/side-channel-list/list.d.ts +14 -0
- gaia/eval/webapp/node_modules/side-channel-list/package.json +77 -0
- gaia/eval/webapp/node_modules/side-channel-list/test/index.js +104 -0
- gaia/eval/webapp/node_modules/side-channel-list/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/side-channel-map/.editorconfig +9 -0
- gaia/eval/webapp/node_modules/side-channel-map/.eslintrc +11 -0
- gaia/eval/webapp/node_modules/side-channel-map/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/side-channel-map/.nycrc +13 -0
- gaia/eval/webapp/node_modules/side-channel-map/CHANGELOG.md +22 -0
- gaia/eval/webapp/node_modules/side-channel-map/LICENSE +21 -0
- gaia/eval/webapp/node_modules/side-channel-map/README.md +62 -0
- gaia/eval/webapp/node_modules/side-channel-map/index.d.ts +15 -0
- gaia/eval/webapp/node_modules/side-channel-map/index.js +68 -0
- gaia/eval/webapp/node_modules/side-channel-map/package.json +80 -0
- gaia/eval/webapp/node_modules/side-channel-map/test/index.js +114 -0
- gaia/eval/webapp/node_modules/side-channel-map/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/.editorconfig +9 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/.eslintrc +12 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/.github/FUNDING.yml +12 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/.nycrc +13 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/CHANGELOG.md +28 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/LICENSE +21 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/README.md +62 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/index.d.ts +15 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/index.js +84 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/package.json +87 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/test/index.js +114 -0
- gaia/eval/webapp/node_modules/side-channel-weakmap/tsconfig.json +9 -0
- gaia/eval/webapp/node_modules/statuses/HISTORY.md +82 -0
- gaia/eval/webapp/node_modules/statuses/LICENSE +23 -0
- gaia/eval/webapp/node_modules/statuses/README.md +136 -0
- gaia/eval/webapp/node_modules/statuses/codes.json +65 -0
- gaia/eval/webapp/node_modules/statuses/index.js +146 -0
- gaia/eval/webapp/node_modules/statuses/package.json +49 -0
- gaia/eval/webapp/node_modules/toidentifier/HISTORY.md +9 -0
- gaia/eval/webapp/node_modules/toidentifier/LICENSE +21 -0
- gaia/eval/webapp/node_modules/toidentifier/README.md +61 -0
- gaia/eval/webapp/node_modules/toidentifier/index.js +32 -0
- gaia/eval/webapp/node_modules/toidentifier/package.json +38 -0
- gaia/eval/webapp/node_modules/type-is/HISTORY.md +259 -0
- gaia/eval/webapp/node_modules/type-is/LICENSE +23 -0
- gaia/eval/webapp/node_modules/type-is/README.md +170 -0
- gaia/eval/webapp/node_modules/type-is/index.js +266 -0
- gaia/eval/webapp/node_modules/type-is/package.json +45 -0
- gaia/eval/webapp/node_modules/unpipe/HISTORY.md +4 -0
- gaia/eval/webapp/node_modules/unpipe/LICENSE +22 -0
- gaia/eval/webapp/node_modules/unpipe/README.md +43 -0
- gaia/eval/webapp/node_modules/unpipe/index.js +69 -0
- gaia/eval/webapp/node_modules/unpipe/package.json +27 -0
- gaia/eval/webapp/node_modules/util/LICENSE +18 -0
- gaia/eval/webapp/node_modules/util/README.md +15 -0
- gaia/eval/webapp/node_modules/util/node_modules/inherits/LICENSE +16 -0
- gaia/eval/webapp/node_modules/util/node_modules/inherits/README.md +42 -0
- gaia/eval/webapp/node_modules/util/node_modules/inherits/inherits.js +7 -0
- gaia/eval/webapp/node_modules/util/node_modules/inherits/inherits_browser.js +23 -0
- gaia/eval/webapp/node_modules/util/node_modules/inherits/package.json +29 -0
- gaia/eval/webapp/node_modules/util/package.json +35 -0
- gaia/eval/webapp/node_modules/util/support/isBuffer.js +3 -0
- gaia/eval/webapp/node_modules/util/support/isBufferBrowser.js +6 -0
- gaia/eval/webapp/node_modules/util/util.js +586 -0
- gaia/eval/webapp/node_modules/utils-merge/.npmignore +9 -0
- gaia/eval/webapp/node_modules/utils-merge/LICENSE +20 -0
- gaia/eval/webapp/node_modules/utils-merge/README.md +34 -0
- gaia/eval/webapp/node_modules/utils-merge/index.js +23 -0
- gaia/eval/webapp/node_modules/utils-merge/package.json +40 -0
- gaia/eval/webapp/node_modules/vary/HISTORY.md +39 -0
- gaia/eval/webapp/node_modules/vary/LICENSE +22 -0
- gaia/eval/webapp/node_modules/vary/README.md +101 -0
- gaia/eval/webapp/node_modules/vary/index.js +149 -0
- gaia/eval/webapp/node_modules/vary/package.json +43 -0
- gaia/eval/webapp/package-lock.json +875 -0
- gaia/eval/webapp/package.json +21 -0
- gaia/eval/webapp/public/app.js +3403 -0
- gaia/eval/webapp/public/index.html +88 -0
- gaia/eval/webapp/public/styles.css +3661 -0
- gaia/eval/webapp/server.js +416 -0
- gaia/eval/webapp/test-setup.js +73 -0
- gaia/llm/__init__.py +2 -0
- gaia/llm/lemonade_client.py +3083 -0
- gaia/llm/lemonade_manager.py +269 -0
- gaia/llm/llm_client.py +729 -0
- gaia/llm/vlm_client.py +307 -0
- gaia/logger.py +189 -0
- gaia/mcp/agent_mcp_server.py +245 -0
- gaia/mcp/blender_mcp_client.py +138 -0
- gaia/mcp/blender_mcp_server.py +648 -0
- gaia/mcp/context7_cache.py +332 -0
- gaia/mcp/external_services.py +518 -0
- gaia/mcp/mcp_bridge.py +550 -0
- gaia/mcp/servers/__init__.py +6 -0
- gaia/mcp/servers/docker_mcp.py +83 -0
- gaia/rag/__init__.py +10 -0
- gaia/rag/app.py +293 -0
- gaia/rag/demo.py +304 -0
- gaia/rag/pdf_utils.py +235 -0
- gaia/rag/sdk.py +2194 -0
- gaia/security.py +163 -0
- gaia/talk/app.py +289 -0
- gaia/talk/sdk.py +538 -0
- gaia/util.py +46 -0
- gaia/version.py +100 -0
gaia/eval/groundtruth.py
ADDED
|
@@ -0,0 +1,1130 @@
|
|
|
1
|
+
# Copyright(C) 2024-2025 Advanced Micro Devices, Inc. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: MIT
|
|
3
|
+
|
|
4
|
+
import argparse
|
|
5
|
+
import json
|
|
6
|
+
import time
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from enum import Enum
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
from gaia.eval.claude import ClaudeClient
|
|
12
|
+
from gaia.eval.config import DEFAULT_CLAUDE_MODEL
|
|
13
|
+
from gaia.logger import get_logger
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class UseCase(Enum):
|
|
17
|
+
"""Supported use cases for ground truth generation."""
|
|
18
|
+
|
|
19
|
+
RAG = "rag"
|
|
20
|
+
SUMMARIZATION = "summarization"
|
|
21
|
+
QA = "qa"
|
|
22
|
+
EMAIL = "email"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class GroundTruthGenerator:
|
|
26
|
+
"""Generates ground truth data for various evaluation use cases using Claude."""
|
|
27
|
+
|
|
28
|
+
@staticmethod
|
|
29
|
+
def get_default_prompt(use_case=UseCase.RAG, num_samples=5):
|
|
30
|
+
"""Generate default prompt based on use case."""
|
|
31
|
+
if use_case == UseCase.RAG:
|
|
32
|
+
return f"""
|
|
33
|
+
Given this document, generate exactly {num_samples} short queries a user may ask about the document
|
|
34
|
+
and produce a set of ground truth answers to be used in validating a RAG system.
|
|
35
|
+
Include a summary of the document in the queries. Return a json formatted list of
|
|
36
|
+
query-response pairs formatted as follows:
|
|
37
|
+
{{
|
|
38
|
+
'source': 'path/to/document',
|
|
39
|
+
'summary': 'summarized document',
|
|
40
|
+
'qa_pairs': [
|
|
41
|
+
{{'query': 'query1', 'response': 'response1'}},
|
|
42
|
+
{{'query': 'query2', 'response': 'response2'}},
|
|
43
|
+
...
|
|
44
|
+
]
|
|
45
|
+
}}
|
|
46
|
+
|
|
47
|
+
Generate exactly {num_samples} qa_pairs - no more, no less.
|
|
48
|
+
|
|
49
|
+
IMPORTANT: Return ONLY the JSON object with no additional text, explanations, or formatting.
|
|
50
|
+
"""
|
|
51
|
+
elif use_case == UseCase.SUMMARIZATION:
|
|
52
|
+
return f"""
|
|
53
|
+
Given this transcript, generate comprehensive ground truth summaries and metadata for evaluation.
|
|
54
|
+
Analyze the content and provide different types of summaries with evaluation criteria.
|
|
55
|
+
Return a json formatted response as follows:
|
|
56
|
+
{{
|
|
57
|
+
'source': 'path/to/transcript',
|
|
58
|
+
'transcript_metadata': {{
|
|
59
|
+
'estimated_duration': 'estimated meeting duration',
|
|
60
|
+
'participant_count': 'estimated number of participants',
|
|
61
|
+
'meeting_type': 'type of meeting (e.g., standup, planning, review)'
|
|
62
|
+
}},
|
|
63
|
+
'summaries': {{
|
|
64
|
+
'executive_summary': 'high-level overview for executives',
|
|
65
|
+
'detailed_summary': 'comprehensive summary with key details',
|
|
66
|
+
'action_items': ['list', 'of', 'action', 'items'],
|
|
67
|
+
'key_decisions': ['list', 'of', 'key', 'decisions'],
|
|
68
|
+
'participants': ['list', 'of', 'identified', 'participants'],
|
|
69
|
+
'topics_discussed': ['list', 'of', 'main', 'topics']
|
|
70
|
+
}},
|
|
71
|
+
'evaluation_criteria': {{
|
|
72
|
+
'summary_completeness': 'how complete should a good summary be',
|
|
73
|
+
'summary_accuracy': 'what constitutes accurate information extraction for summaries',
|
|
74
|
+
'relevance': 'what information is most relevant to include',
|
|
75
|
+
'structure': 'how should the summary be structured'
|
|
76
|
+
}}
|
|
77
|
+
}}
|
|
78
|
+
|
|
79
|
+
Focus on generating comprehensive summaries and metadata for transcript summarization evaluation.
|
|
80
|
+
|
|
81
|
+
IMPORTANT: Return ONLY the JSON object with no additional text, explanations, or formatting.
|
|
82
|
+
"""
|
|
83
|
+
elif use_case == UseCase.QA:
|
|
84
|
+
return f"""
|
|
85
|
+
Given this transcript, generate exactly {num_samples} relevant questions with accurate answers for evaluation.
|
|
86
|
+
Focus on questions that would commonly be asked about this type of meeting or conversation.
|
|
87
|
+
Return a json formatted response as follows:
|
|
88
|
+
{{
|
|
89
|
+
'source': 'path/to/transcript',
|
|
90
|
+
'transcript_metadata': {{
|
|
91
|
+
'estimated_duration': 'estimated meeting duration',
|
|
92
|
+
'participant_count': 'estimated number of participants',
|
|
93
|
+
'meeting_type': 'type of meeting (e.g., standup, planning, review)'
|
|
94
|
+
}},
|
|
95
|
+
'qa_pairs': [
|
|
96
|
+
{{'query': 'What were the main topics discussed in this meeting?', 'response': 'detailed answer based on transcript content'}},
|
|
97
|
+
{{'query': 'What action items were assigned and to whom?', 'response': 'specific action items and assignees'}},
|
|
98
|
+
{{'query': 'What decisions were made during this meeting?', 'response': 'key decisions and rationale'}},
|
|
99
|
+
{{'query': 'Who participated in this meeting and what were their roles?', 'response': 'participant list and contributions'}},
|
|
100
|
+
{{'query': 'What are the next steps or follow-up items?', 'response': 'future actions and timelines'}}
|
|
101
|
+
],
|
|
102
|
+
'evaluation_criteria': {{
|
|
103
|
+
'qa_accuracy': 'what constitutes accurate answers to questions about the transcript',
|
|
104
|
+
'relevance': 'what information is most relevant to include in answers',
|
|
105
|
+
'completeness': 'how complete should answers be for different question types'
|
|
106
|
+
}}
|
|
107
|
+
}}
|
|
108
|
+
|
|
109
|
+
Generate exactly {num_samples} qa_pairs - no more, no less. Focus on questions that would be commonly asked about this type of meeting transcript.
|
|
110
|
+
|
|
111
|
+
IMPORTANT: Return ONLY the JSON object with no additional text, explanations, or formatting.
|
|
112
|
+
"""
|
|
113
|
+
elif use_case == UseCase.EMAIL:
|
|
114
|
+
return f"""
|
|
115
|
+
Given this business email, generate comprehensive ground truth summaries and analysis for evaluation.
|
|
116
|
+
Analyze the email content and provide structured summaries with evaluation criteria.
|
|
117
|
+
Return a json formatted response as follows:
|
|
118
|
+
{{
|
|
119
|
+
'source': 'path/to/email',
|
|
120
|
+
'email_metadata': {{
|
|
121
|
+
'email_type': 'type of email (e.g., project_update, customer_support, sales_outreach)',
|
|
122
|
+
'sender_role': 'estimated role of sender',
|
|
123
|
+
'recipient_type': 'type of recipients',
|
|
124
|
+
'urgency_level': 'low/medium/high priority assessment'
|
|
125
|
+
}},
|
|
126
|
+
'summaries': {{
|
|
127
|
+
'executive_summary': 'high-level overview of email purpose and content',
|
|
128
|
+
'detailed_summary': 'comprehensive summary with key details and context',
|
|
129
|
+
'key_points': ['list', 'of', 'main', 'points'],
|
|
130
|
+
'action_items': ['list', 'of', 'action', 'items', 'or', 'requests'],
|
|
131
|
+
'decisions_mentioned': ['list', 'of', 'decisions', 'or', 'announcements'],
|
|
132
|
+
'follow_up_required': 'whether follow-up is needed and what type'
|
|
133
|
+
}},
|
|
134
|
+
'qa_pairs': [
|
|
135
|
+
{{'query': 'What is the main purpose of this email?', 'response': 'detailed answer based on email content'}},
|
|
136
|
+
{{'query': 'What action items or requests are mentioned?', 'response': 'specific actions requested'}},
|
|
137
|
+
{{'query': 'What key information or updates are shared?', 'response': 'main information conveyed'}},
|
|
138
|
+
{{'query': 'Who is the intended audience and what is expected of them?', 'response': 'recipient expectations and required responses'}},
|
|
139
|
+
{{'query': 'What is the timeline or urgency level?', 'response': 'timing and priority information'}}
|
|
140
|
+
],
|
|
141
|
+
'evaluation_criteria': {{
|
|
142
|
+
'summary_completeness': 'how complete should a good email summary be',
|
|
143
|
+
'summary_accuracy': 'what constitutes accurate information extraction for emails',
|
|
144
|
+
'relevance': 'what information is most relevant to include',
|
|
145
|
+
'context_understanding': 'how well should the business context be captured',
|
|
146
|
+
'action_identification': 'how effectively should action items be identified'
|
|
147
|
+
}}
|
|
148
|
+
}}
|
|
149
|
+
|
|
150
|
+
Focus on generating comprehensive summaries and analysis for business email evaluation. Always include exactly 5 qa_pairs.
|
|
151
|
+
|
|
152
|
+
IMPORTANT: Return ONLY the JSON object with no additional text, explanations, or formatting.
|
|
153
|
+
"""
|
|
154
|
+
else:
|
|
155
|
+
raise ValueError(f"Unsupported use case: {use_case}")
|
|
156
|
+
|
|
157
|
+
def __init__(self, model=None, max_tokens=4096):
|
|
158
|
+
self.log = get_logger(__name__)
|
|
159
|
+
if model is None:
|
|
160
|
+
model = DEFAULT_CLAUDE_MODEL
|
|
161
|
+
self.claude = ClaudeClient(model=model, max_tokens=max_tokens)
|
|
162
|
+
|
|
163
|
+
def generate(
|
|
164
|
+
self,
|
|
165
|
+
file_path,
|
|
166
|
+
use_case=UseCase.RAG,
|
|
167
|
+
prompt=None,
|
|
168
|
+
save_text=True,
|
|
169
|
+
output_dir=None,
|
|
170
|
+
num_samples=5,
|
|
171
|
+
save_file=True,
|
|
172
|
+
):
|
|
173
|
+
"""
|
|
174
|
+
Generate ground truth data for a given document based on use case.
|
|
175
|
+
|
|
176
|
+
Args:
|
|
177
|
+
file_path (str): Path to the input document
|
|
178
|
+
use_case (UseCase): The evaluation use case (RAG or transcript summarization)
|
|
179
|
+
prompt (str, optional): Custom prompt for Claude. If None, uses default prompt for use case
|
|
180
|
+
save_text (bool): Whether to save extracted text for HTML files
|
|
181
|
+
output_dir (str, optional): Directory to save output files. If None, uses same directory as input
|
|
182
|
+
num_samples (int): Number of Q&A pairs to generate (for RAG use case only, default: 5)
|
|
183
|
+
|
|
184
|
+
Returns:
|
|
185
|
+
dict: Generated ground truth data with metadata
|
|
186
|
+
"""
|
|
187
|
+
self.log.info(
|
|
188
|
+
f"Generating ground truth data for: {file_path} (use case: {use_case.value})"
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
file_path = Path(file_path)
|
|
192
|
+
if not file_path.exists():
|
|
193
|
+
raise FileNotFoundError(f"Input file not found: {file_path}")
|
|
194
|
+
|
|
195
|
+
# Use appropriate prompt based on use case
|
|
196
|
+
if prompt is None:
|
|
197
|
+
prompt = self.get_default_prompt(use_case, num_samples)
|
|
198
|
+
|
|
199
|
+
try:
|
|
200
|
+
# Generate analysis using Claude with usage tracking
|
|
201
|
+
response = self.claude.analyze_file_with_usage(
|
|
202
|
+
str(file_path), prompt, save_text=save_text
|
|
203
|
+
)
|
|
204
|
+
analysis = response["content"]
|
|
205
|
+
usage = response["usage"]
|
|
206
|
+
cost = response["cost"]
|
|
207
|
+
|
|
208
|
+
# Debug: Log the raw analysis response
|
|
209
|
+
self.log.debug(
|
|
210
|
+
f"Raw Claude response length: {len(analysis) if analysis else 0}"
|
|
211
|
+
)
|
|
212
|
+
self.log.debug(
|
|
213
|
+
f"Raw Claude response preview: {analysis[:500] if analysis else 'None'}"
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
# Check if analysis is valid
|
|
217
|
+
if not analysis or not analysis.strip():
|
|
218
|
+
raise ValueError(
|
|
219
|
+
"Claude returned an empty response. This may be due to token limits or API issues."
|
|
220
|
+
)
|
|
221
|
+
|
|
222
|
+
# Try to parse the JSON response
|
|
223
|
+
try:
|
|
224
|
+
parsed_analysis = json.loads(analysis)
|
|
225
|
+
except json.JSONDecodeError as je:
|
|
226
|
+
# Try to extract JSON from the response if it's wrapped in text
|
|
227
|
+
self.log.debug(
|
|
228
|
+
"Initial JSON parsing failed, attempting to extract JSON from response"
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# Look for JSON content within the response
|
|
232
|
+
start_idx = analysis.find("{")
|
|
233
|
+
end_idx = analysis.rfind("}") + 1
|
|
234
|
+
|
|
235
|
+
if start_idx >= 0 and end_idx > start_idx:
|
|
236
|
+
json_content = analysis[start_idx:end_idx]
|
|
237
|
+
try:
|
|
238
|
+
parsed_analysis = json.loads(json_content)
|
|
239
|
+
self.log.info("Successfully extracted JSON from response")
|
|
240
|
+
except json.JSONDecodeError:
|
|
241
|
+
self.log.error(
|
|
242
|
+
f"Failed to parse extracted JSON. Response content: {analysis}"
|
|
243
|
+
)
|
|
244
|
+
raise ValueError(
|
|
245
|
+
f"Claude response is not valid JSON: {str(je)}"
|
|
246
|
+
)
|
|
247
|
+
else:
|
|
248
|
+
self.log.error(f"No JSON content found in response: {analysis}")
|
|
249
|
+
raise ValueError(
|
|
250
|
+
f"No valid JSON found in Claude response: {str(je)}"
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
# Prepare output data with metadata including usage and cost
|
|
254
|
+
output_data = {
|
|
255
|
+
"metadata": {
|
|
256
|
+
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
257
|
+
"model": self.claude.model,
|
|
258
|
+
"source_file": str(file_path),
|
|
259
|
+
"use_case": use_case.value,
|
|
260
|
+
"prompt": prompt,
|
|
261
|
+
"num_samples_requested": (
|
|
262
|
+
num_samples if use_case == UseCase.RAG else None
|
|
263
|
+
),
|
|
264
|
+
"usage": usage,
|
|
265
|
+
"cost": cost,
|
|
266
|
+
},
|
|
267
|
+
"analysis": parsed_analysis,
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
# Save to file if save_file is True
|
|
271
|
+
if save_file:
|
|
272
|
+
# Default output directory to ./groundtruth if not specified
|
|
273
|
+
if output_dir is None:
|
|
274
|
+
output_dir = "./groundtruth"
|
|
275
|
+
|
|
276
|
+
output_dir = Path(output_dir)
|
|
277
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
278
|
+
|
|
279
|
+
# If file_path is relative and has parent directories, preserve them
|
|
280
|
+
if file_path.is_relative_to(Path.cwd()) and file_path.parent != Path(
|
|
281
|
+
"."
|
|
282
|
+
):
|
|
283
|
+
# Try to preserve relative directory structure
|
|
284
|
+
try:
|
|
285
|
+
relative_path = file_path.relative_to(Path.cwd())
|
|
286
|
+
relative_dir = relative_path.parent
|
|
287
|
+
output_subdir = output_dir / relative_dir
|
|
288
|
+
output_subdir.mkdir(parents=True, exist_ok=True)
|
|
289
|
+
output_path = (
|
|
290
|
+
output_subdir
|
|
291
|
+
/ f"{file_path.stem}.{use_case.value}.groundtruth.json"
|
|
292
|
+
)
|
|
293
|
+
except ValueError:
|
|
294
|
+
# Fall back to flat structure if relative path calculation fails
|
|
295
|
+
output_path = (
|
|
296
|
+
output_dir
|
|
297
|
+
/ f"{file_path.stem}.{use_case.value}.groundtruth.json"
|
|
298
|
+
)
|
|
299
|
+
else:
|
|
300
|
+
output_path = (
|
|
301
|
+
output_dir
|
|
302
|
+
/ f"{file_path.stem}.{use_case.value}.groundtruth.json"
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
|
306
|
+
json.dump(output_data, f, indent=2)
|
|
307
|
+
self.log.info(f"Ground truth data saved to: {output_path}")
|
|
308
|
+
|
|
309
|
+
return output_data
|
|
310
|
+
|
|
311
|
+
except Exception as e:
|
|
312
|
+
self.log.error(f"Error generating ground truth data: {e}")
|
|
313
|
+
raise
|
|
314
|
+
|
|
315
|
+
def generate_batch(
|
|
316
|
+
self, input_dir, file_pattern="*", use_case=UseCase.RAG, force=False, **kwargs
|
|
317
|
+
):
|
|
318
|
+
"""
|
|
319
|
+
Generate ground truth data for multiple documents in a directory.
|
|
320
|
+
All results are automatically consolidated into a single JSON file.
|
|
321
|
+
Supports resuming from interrupted runs by skipping files that already have ground truth.
|
|
322
|
+
|
|
323
|
+
Args:
|
|
324
|
+
input_dir (str): Directory containing input documents
|
|
325
|
+
file_pattern (str): Glob pattern to match input files
|
|
326
|
+
use_case (UseCase): The evaluation use case
|
|
327
|
+
force (bool): If True, regenerate all ground truth files even if they exist (default: False)
|
|
328
|
+
**kwargs: Additional arguments passed to generate()
|
|
329
|
+
|
|
330
|
+
Returns:
|
|
331
|
+
dict: Consolidated ground truth data for all documents
|
|
332
|
+
"""
|
|
333
|
+
input_dir = Path(input_dir)
|
|
334
|
+
if not input_dir.is_dir():
|
|
335
|
+
raise NotADirectoryError(f"Input directory not found: {input_dir}")
|
|
336
|
+
|
|
337
|
+
# Get output directory from kwargs, with fallback
|
|
338
|
+
output_dir = kwargs.get("output_dir", "./output/groundtruth")
|
|
339
|
+
output_dir = Path(output_dir)
|
|
340
|
+
output_dir.mkdir(parents=True, exist_ok=True)
|
|
341
|
+
|
|
342
|
+
# Remove output_dir and force from kwargs to avoid individual file saves in the generate method
|
|
343
|
+
generate_kwargs = {
|
|
344
|
+
k: v for k, v in kwargs.items() if k not in ["output_dir", "force"]
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
results = []
|
|
348
|
+
individual_files = []
|
|
349
|
+
|
|
350
|
+
# Collect all matching files recursively
|
|
351
|
+
matching_files = list(input_dir.rglob(file_pattern))
|
|
352
|
+
self.log.info(
|
|
353
|
+
f"Found {len(matching_files)} files matching pattern '{file_pattern}' in {input_dir}"
|
|
354
|
+
)
|
|
355
|
+
|
|
356
|
+
if not matching_files:
|
|
357
|
+
self.log.warning(
|
|
358
|
+
f"No files found matching pattern '{file_pattern}' in {input_dir}"
|
|
359
|
+
)
|
|
360
|
+
# List directory contents for debugging
|
|
361
|
+
try:
|
|
362
|
+
all_files = list(input_dir.rglob("*"))
|
|
363
|
+
self.log.info(
|
|
364
|
+
f"All files in directory: {[str(f) for f in all_files[:10]]}"
|
|
365
|
+
) # Show first 10
|
|
366
|
+
except Exception as e:
|
|
367
|
+
self.log.error(f"Error listing directory contents: {e}")
|
|
368
|
+
|
|
369
|
+
for match in matching_files:
|
|
370
|
+
self.log.info(f" Found: {match}")
|
|
371
|
+
|
|
372
|
+
# Filter out metadata files
|
|
373
|
+
filtered_files = []
|
|
374
|
+
for f in matching_files:
|
|
375
|
+
# Skip directories (rglob returns both files and directories)
|
|
376
|
+
if f.is_dir():
|
|
377
|
+
self.log.info(f"Skipping directory: {f.name}")
|
|
378
|
+
continue
|
|
379
|
+
# Skip metadata files
|
|
380
|
+
if f.name in [
|
|
381
|
+
"transcript_metadata.json",
|
|
382
|
+
"metadata.json",
|
|
383
|
+
"experiment_metadata.json",
|
|
384
|
+
]:
|
|
385
|
+
self.log.info(f"Skipping metadata file: {f.name}")
|
|
386
|
+
continue
|
|
387
|
+
# Skip any file with 'metadata' in the name and .json extension
|
|
388
|
+
if "metadata" in f.name.lower() and f.suffix == ".json":
|
|
389
|
+
self.log.info(f"Skipping metadata file: {f.name}")
|
|
390
|
+
continue
|
|
391
|
+
filtered_files.append(f)
|
|
392
|
+
|
|
393
|
+
if not filtered_files:
|
|
394
|
+
self.log.warning(
|
|
395
|
+
f"No valid files to process after filtering out metadata files"
|
|
396
|
+
)
|
|
397
|
+
return None
|
|
398
|
+
|
|
399
|
+
self.log.info(
|
|
400
|
+
f"Processing {len(filtered_files)} files (excluded {len(matching_files) - len(filtered_files)} metadata files)"
|
|
401
|
+
)
|
|
402
|
+
|
|
403
|
+
# Create progress tracking directory
|
|
404
|
+
progress_dir = output_dir / f"groundtruth_{use_case.value}_progress"
|
|
405
|
+
progress_dir.mkdir(parents=True, exist_ok=True)
|
|
406
|
+
|
|
407
|
+
# Track statistics
|
|
408
|
+
skipped_count = 0
|
|
409
|
+
processed_count = 0
|
|
410
|
+
error_count = 0
|
|
411
|
+
|
|
412
|
+
# Track costs for this run (only newly generated files)
|
|
413
|
+
run_usage = {"input_tokens": 0, "output_tokens": 0, "total_tokens": 0}
|
|
414
|
+
run_cost = {"input_cost": 0.0, "output_cost": 0.0, "total_cost": 0.0}
|
|
415
|
+
|
|
416
|
+
for i, file_path in enumerate(filtered_files):
|
|
417
|
+
# Calculate the expected output path for this file
|
|
418
|
+
relative_path = file_path.relative_to(input_dir)
|
|
419
|
+
relative_dir = relative_path.parent
|
|
420
|
+
output_subdir = output_dir / relative_dir
|
|
421
|
+
individual_file_path = (
|
|
422
|
+
output_subdir / f"{file_path.stem}.{use_case.value}.groundtruth.json"
|
|
423
|
+
)
|
|
424
|
+
|
|
425
|
+
# Check if ground truth already exists and skip if not forced
|
|
426
|
+
if not force and individual_file_path.exists():
|
|
427
|
+
self.log.info(
|
|
428
|
+
f"Skipping file {i+1}/{len(filtered_files)} (already exists): {file_path}"
|
|
429
|
+
)
|
|
430
|
+
self.log.debug(f" Existing ground truth: {individual_file_path}")
|
|
431
|
+
skipped_count += 1
|
|
432
|
+
|
|
433
|
+
# Load existing result for consolidation
|
|
434
|
+
try:
|
|
435
|
+
with open(individual_file_path, "r", encoding="utf-8") as f:
|
|
436
|
+
existing_result = json.load(f)
|
|
437
|
+
results.append(existing_result)
|
|
438
|
+
individual_files.append(individual_file_path)
|
|
439
|
+
# Successfully loaded existing file, skip to next iteration
|
|
440
|
+
continue
|
|
441
|
+
except Exception as e:
|
|
442
|
+
self.log.error(
|
|
443
|
+
f"Error loading existing ground truth {individual_file_path}: {e}"
|
|
444
|
+
)
|
|
445
|
+
self.log.warning(
|
|
446
|
+
f"Will regenerate ground truth for {file_path} due to load error"
|
|
447
|
+
)
|
|
448
|
+
# Decrement skip count since we're actually processing this file
|
|
449
|
+
skipped_count -= 1
|
|
450
|
+
# Fall through to regeneration below
|
|
451
|
+
|
|
452
|
+
self.log.info(f"Processing file {i+1}/{len(filtered_files)}: {file_path}")
|
|
453
|
+
file_start_time = time.time()
|
|
454
|
+
|
|
455
|
+
try:
|
|
456
|
+
# Generate without saving individual files by passing save_file=False
|
|
457
|
+
result = self.generate(
|
|
458
|
+
file_path, use_case=use_case, save_file=False, **generate_kwargs
|
|
459
|
+
)
|
|
460
|
+
results.append(result)
|
|
461
|
+
processed_count += 1
|
|
462
|
+
|
|
463
|
+
# Accumulate costs for this run
|
|
464
|
+
usage = result.get("metadata", {}).get("usage", {})
|
|
465
|
+
cost = result.get("metadata", {}).get("cost", {})
|
|
466
|
+
run_usage["input_tokens"] += usage.get("input_tokens", 0)
|
|
467
|
+
run_usage["output_tokens"] += usage.get("output_tokens", 0)
|
|
468
|
+
run_usage["total_tokens"] += usage.get("total_tokens", 0)
|
|
469
|
+
run_cost["input_cost"] += cost.get("input_cost", 0.0)
|
|
470
|
+
run_cost["output_cost"] += cost.get("output_cost", 0.0)
|
|
471
|
+
run_cost["total_cost"] += cost.get("total_cost", 0.0)
|
|
472
|
+
|
|
473
|
+
# Create output directory structure
|
|
474
|
+
output_subdir.mkdir(parents=True, exist_ok=True)
|
|
475
|
+
|
|
476
|
+
# Save individual file (this provides immediate incremental progress)
|
|
477
|
+
with open(individual_file_path, "w", encoding="utf-8") as f:
|
|
478
|
+
json.dump(result, f, indent=2)
|
|
479
|
+
individual_files.append(individual_file_path)
|
|
480
|
+
|
|
481
|
+
# Write progress tracking information
|
|
482
|
+
file_time = time.time() - file_start_time
|
|
483
|
+
progress_file = progress_dir / f"file_{i+1:04d}_progress.json"
|
|
484
|
+
progress_data = {
|
|
485
|
+
"file_index": i,
|
|
486
|
+
"file_path": str(file_path),
|
|
487
|
+
"individual_output_path": str(individual_file_path),
|
|
488
|
+
"processing_time_seconds": round(file_time, 3),
|
|
489
|
+
"usage": result.get("metadata", {}).get("usage", {}),
|
|
490
|
+
"cost": result.get("metadata", {}).get("cost", {}),
|
|
491
|
+
"timestamp": datetime.now().isoformat(),
|
|
492
|
+
"status": "completed",
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
with open(progress_file, "w", encoding="utf-8") as f:
|
|
496
|
+
json.dump(progress_data, f, indent=2)
|
|
497
|
+
|
|
498
|
+
# Update overall progress
|
|
499
|
+
overall_progress_file = progress_dir / "overall_progress.json"
|
|
500
|
+
overall_progress_data = {
|
|
501
|
+
"total_files": len(filtered_files),
|
|
502
|
+
"completed_files": i + 1,
|
|
503
|
+
"progress_percent": round((i + 1) / len(filtered_files) * 100, 1),
|
|
504
|
+
"use_case": use_case.value,
|
|
505
|
+
"last_updated": datetime.now().isoformat(),
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
with open(overall_progress_file, "w", encoding="utf-8") as f:
|
|
509
|
+
json.dump(overall_progress_data, f, indent=2)
|
|
510
|
+
|
|
511
|
+
self.log.info(
|
|
512
|
+
f"Ground truth progress: {i+1}/{len(filtered_files)} files completed ({overall_progress_data['progress_percent']}%)"
|
|
513
|
+
)
|
|
514
|
+
|
|
515
|
+
except Exception as e:
|
|
516
|
+
self.log.error(f"Error processing {file_path}: {e}")
|
|
517
|
+
error_count += 1
|
|
518
|
+
|
|
519
|
+
# Write error progress information
|
|
520
|
+
progress_file = progress_dir / f"file_{i+1:04d}_progress.json"
|
|
521
|
+
progress_data = {
|
|
522
|
+
"file_index": i,
|
|
523
|
+
"file_path": str(file_path),
|
|
524
|
+
"error": str(e),
|
|
525
|
+
"timestamp": datetime.now().isoformat(),
|
|
526
|
+
"status": "error",
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
with open(progress_file, "w", encoding="utf-8") as f:
|
|
530
|
+
json.dump(progress_data, f, indent=2)
|
|
531
|
+
|
|
532
|
+
continue
|
|
533
|
+
|
|
534
|
+
# Log summary statistics
|
|
535
|
+
self.log.info("=" * 60)
|
|
536
|
+
self.log.info("Ground Truth Generation Summary:")
|
|
537
|
+
self.log.info(f" Total files found: {len(filtered_files)}")
|
|
538
|
+
self.log.info(f" Processed (new): {processed_count}")
|
|
539
|
+
self.log.info(f" Skipped (existing): {skipped_count}")
|
|
540
|
+
self.log.info(f" Errors: {error_count}")
|
|
541
|
+
self.log.info(f" Total results available: {len(results)}")
|
|
542
|
+
if processed_count > 0:
|
|
543
|
+
self.log.info(
|
|
544
|
+
f" This run cost: ${run_cost['total_cost']:.4f} "
|
|
545
|
+
f"({run_usage['total_tokens']:,} tokens)"
|
|
546
|
+
)
|
|
547
|
+
self.log.info("=" * 60)
|
|
548
|
+
|
|
549
|
+
if not results:
|
|
550
|
+
self.log.warning("No files were processed successfully")
|
|
551
|
+
return None
|
|
552
|
+
|
|
553
|
+
# Consolidate all results into a single file
|
|
554
|
+
try:
|
|
555
|
+
self.log.info(
|
|
556
|
+
f"Consolidating {len(results)} ground truth files into single JSON"
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
# Use the consolidate method to create the final consolidated file
|
|
560
|
+
consolidated_file_pattern = f"*.{use_case.value}.groundtruth.json"
|
|
561
|
+
consolidated_output_path = (
|
|
562
|
+
output_dir / f"consolidated_{use_case.value}_groundtruth.json"
|
|
563
|
+
)
|
|
564
|
+
|
|
565
|
+
consolidated_data = self.consolidate_groundtruth(
|
|
566
|
+
input_dir=output_dir,
|
|
567
|
+
output_path=consolidated_output_path,
|
|
568
|
+
file_pattern=consolidated_file_pattern,
|
|
569
|
+
)
|
|
570
|
+
|
|
571
|
+
# Keep individual files - don't clean them up
|
|
572
|
+
self.log.info(f"Individual ground truth files saved in: {output_dir}")
|
|
573
|
+
self.log.info(
|
|
574
|
+
f"Consolidated ground truth file saved as: {consolidated_output_path}"
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
self.log.info(
|
|
578
|
+
f"Consolidated ground truth data saved to: {consolidated_output_path}"
|
|
579
|
+
)
|
|
580
|
+
self.log.info(f"Total files processed: {len(results)}")
|
|
581
|
+
|
|
582
|
+
# Add this run's statistics to consolidated metadata
|
|
583
|
+
consolidated_data["metadata"]["run_stats"] = {
|
|
584
|
+
"processed_count": processed_count,
|
|
585
|
+
"skipped_count": skipped_count,
|
|
586
|
+
"error_count": error_count,
|
|
587
|
+
"run_usage": run_usage,
|
|
588
|
+
"run_cost": run_cost,
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
# Return the consolidated data instead of individual results
|
|
592
|
+
return consolidated_data
|
|
593
|
+
|
|
594
|
+
except Exception as e:
|
|
595
|
+
self.log.error(f"Error during consolidation: {e}")
|
|
596
|
+
# If consolidation fails, return individual results
|
|
597
|
+
self.log.warning("Falling back to individual results")
|
|
598
|
+
return results
|
|
599
|
+
finally:
|
|
600
|
+
# Clean up progress directory after successful completion
|
|
601
|
+
try:
|
|
602
|
+
import shutil
|
|
603
|
+
|
|
604
|
+
if progress_dir.exists():
|
|
605
|
+
shutil.rmtree(progress_dir)
|
|
606
|
+
self.log.info(
|
|
607
|
+
f"Cleaned up progress tracking files from: {progress_dir}"
|
|
608
|
+
)
|
|
609
|
+
except Exception as e:
|
|
610
|
+
self.log.warning(
|
|
611
|
+
f"Failed to clean up progress directory {progress_dir}: {e}"
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
def consolidate_groundtruth(
|
|
615
|
+
self,
|
|
616
|
+
input_dir,
|
|
617
|
+
output_path=None,
|
|
618
|
+
file_pattern="*.summarization.groundtruth.json",
|
|
619
|
+
):
|
|
620
|
+
"""
|
|
621
|
+
Consolidate multiple ground truth files into a single JSON file for easier evaluation.
|
|
622
|
+
|
|
623
|
+
Args:
|
|
624
|
+
input_dir (str): Directory containing ground truth files
|
|
625
|
+
output_path (str, optional): Path for consolidated output file. If None, creates in input_dir
|
|
626
|
+
file_pattern (str): Glob pattern to match ground truth files
|
|
627
|
+
|
|
628
|
+
Returns:
|
|
629
|
+
dict: Consolidated ground truth data
|
|
630
|
+
"""
|
|
631
|
+
input_dir = Path(input_dir)
|
|
632
|
+
if not input_dir.is_dir():
|
|
633
|
+
raise NotADirectoryError(f"Input directory not found: {input_dir}")
|
|
634
|
+
|
|
635
|
+
# Find all matching ground truth files
|
|
636
|
+
gt_files = list(input_dir.rglob(file_pattern))
|
|
637
|
+
if not gt_files:
|
|
638
|
+
raise FileNotFoundError(
|
|
639
|
+
f"No ground truth files found matching pattern: {file_pattern}"
|
|
640
|
+
)
|
|
641
|
+
|
|
642
|
+
self.log.info(f"Consolidating {len(gt_files)} ground truth files")
|
|
643
|
+
|
|
644
|
+
consolidated_data = {
|
|
645
|
+
"metadata": {
|
|
646
|
+
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
|
|
647
|
+
"consolidated_from": len(gt_files),
|
|
648
|
+
"source_files": [],
|
|
649
|
+
"total_usage": {
|
|
650
|
+
"input_tokens": 0,
|
|
651
|
+
"output_tokens": 0,
|
|
652
|
+
"total_tokens": 0,
|
|
653
|
+
},
|
|
654
|
+
"total_cost": {
|
|
655
|
+
"input_cost": 0.0,
|
|
656
|
+
"output_cost": 0.0,
|
|
657
|
+
"total_cost": 0.0,
|
|
658
|
+
},
|
|
659
|
+
},
|
|
660
|
+
"analysis": {
|
|
661
|
+
"summaries": {},
|
|
662
|
+
"transcript_metadata": {},
|
|
663
|
+
"qa_pairs": {},
|
|
664
|
+
"evaluation_criteria": {},
|
|
665
|
+
},
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
# Process each ground truth file
|
|
669
|
+
for gt_file in gt_files:
|
|
670
|
+
try:
|
|
671
|
+
with open(gt_file, "r", encoding="utf-8") as f:
|
|
672
|
+
gt_data = json.load(f)
|
|
673
|
+
|
|
674
|
+
# Extract transcript identifier from filename (handle all use cases)
|
|
675
|
+
transcript_id = gt_file.stem
|
|
676
|
+
for use_case in UseCase:
|
|
677
|
+
transcript_id = transcript_id.replace(
|
|
678
|
+
f".{use_case.value}.groundtruth", ""
|
|
679
|
+
)
|
|
680
|
+
|
|
681
|
+
# Store source file info
|
|
682
|
+
consolidated_data["metadata"]["source_files"].append(
|
|
683
|
+
{
|
|
684
|
+
"transcript_id": transcript_id,
|
|
685
|
+
"file_path": str(gt_file),
|
|
686
|
+
"source_file": gt_data["metadata"].get("source_file", ""),
|
|
687
|
+
"timestamp": gt_data["metadata"].get("timestamp", ""),
|
|
688
|
+
}
|
|
689
|
+
)
|
|
690
|
+
|
|
691
|
+
# Aggregate usage and cost data
|
|
692
|
+
usage = gt_data["metadata"].get("usage", {})
|
|
693
|
+
cost = gt_data["metadata"].get("cost", {})
|
|
694
|
+
|
|
695
|
+
consolidated_data["metadata"]["total_usage"][
|
|
696
|
+
"input_tokens"
|
|
697
|
+
] += usage.get("input_tokens", 0)
|
|
698
|
+
consolidated_data["metadata"]["total_usage"][
|
|
699
|
+
"output_tokens"
|
|
700
|
+
] += usage.get("output_tokens", 0)
|
|
701
|
+
consolidated_data["metadata"]["total_usage"][
|
|
702
|
+
"total_tokens"
|
|
703
|
+
] += usage.get("total_tokens", 0)
|
|
704
|
+
|
|
705
|
+
consolidated_data["metadata"]["total_cost"]["input_cost"] += cost.get(
|
|
706
|
+
"input_cost", 0.0
|
|
707
|
+
)
|
|
708
|
+
consolidated_data["metadata"]["total_cost"]["output_cost"] += cost.get(
|
|
709
|
+
"output_cost", 0.0
|
|
710
|
+
)
|
|
711
|
+
consolidated_data["metadata"]["total_cost"]["total_cost"] += cost.get(
|
|
712
|
+
"total_cost", 0.0
|
|
713
|
+
)
|
|
714
|
+
|
|
715
|
+
# Store analysis data with transcript ID as key
|
|
716
|
+
analysis = gt_data.get("analysis", {})
|
|
717
|
+
consolidated_data["analysis"]["summaries"][transcript_id] = (
|
|
718
|
+
analysis.get("summaries", {})
|
|
719
|
+
)
|
|
720
|
+
consolidated_data["analysis"]["transcript_metadata"][transcript_id] = (
|
|
721
|
+
analysis.get("transcript_metadata", {})
|
|
722
|
+
)
|
|
723
|
+
|
|
724
|
+
# Store qa_pairs if present (for QA use case)
|
|
725
|
+
if "qa_pairs" in analysis:
|
|
726
|
+
consolidated_data["analysis"]["qa_pairs"][transcript_id] = (
|
|
727
|
+
analysis.get("qa_pairs", [])
|
|
728
|
+
)
|
|
729
|
+
|
|
730
|
+
# Store evaluation criteria (should be similar across transcripts, but keep first one)
|
|
731
|
+
if not consolidated_data["analysis"]["evaluation_criteria"]:
|
|
732
|
+
consolidated_data["analysis"]["evaluation_criteria"] = analysis.get(
|
|
733
|
+
"evaluation_criteria", {}
|
|
734
|
+
)
|
|
735
|
+
|
|
736
|
+
self.log.debug(f"Processed ground truth file: {gt_file}")
|
|
737
|
+
|
|
738
|
+
except Exception as e:
|
|
739
|
+
self.log.error(f"Error processing {gt_file}: {e}")
|
|
740
|
+
continue
|
|
741
|
+
|
|
742
|
+
# Set output path if not provided
|
|
743
|
+
if output_path is None:
|
|
744
|
+
output_path = input_dir / "consolidated_groundtruth.json"
|
|
745
|
+
else:
|
|
746
|
+
output_path = Path(output_path)
|
|
747
|
+
|
|
748
|
+
# Save consolidated data
|
|
749
|
+
with open(output_path, "w", encoding="utf-8") as f:
|
|
750
|
+
json.dump(consolidated_data, f, indent=2, ensure_ascii=False)
|
|
751
|
+
|
|
752
|
+
self.log.info(f"Consolidated ground truth saved to: {output_path}")
|
|
753
|
+
self.log.info(f"Total files: {len(gt_files)}")
|
|
754
|
+
self.log.info(
|
|
755
|
+
f"Total cost: ${consolidated_data['metadata']['total_cost']['total_cost']:.4f}"
|
|
756
|
+
)
|
|
757
|
+
|
|
758
|
+
return consolidated_data
|
|
759
|
+
|
|
760
|
+
|
|
761
|
+
def main():
|
|
762
|
+
"""Command line interface for ground truth generation."""
|
|
763
|
+
parser = argparse.ArgumentParser(
|
|
764
|
+
description="Generate ground truth data for various evaluation use cases",
|
|
765
|
+
formatter_class=argparse.RawDescriptionHelpFormatter,
|
|
766
|
+
epilog="""
|
|
767
|
+
Examples:
|
|
768
|
+
# Process a single file for RAG evaluation (default)
|
|
769
|
+
python -m gaia.eval.groundtruth -f ./data/html/blender/introduction.html
|
|
770
|
+
|
|
771
|
+
# Process a transcript for summary generation
|
|
772
|
+
python -m gaia.eval.groundtruth -f ./data/transcripts/meeting.txt --use-case summarization
|
|
773
|
+
|
|
774
|
+
# Process a transcript for Q&A generation
|
|
775
|
+
python -m gaia.eval.groundtruth -f ./data/transcripts/meeting.txt --use-case qa
|
|
776
|
+
|
|
777
|
+
# Process all HTML files in a directory for RAG (creates consolidated file)
|
|
778
|
+
python -m gaia.eval.groundtruth -d ./data/html/blender
|
|
779
|
+
|
|
780
|
+
# Process transcript files for summarization (creates consolidated file)
|
|
781
|
+
python -m gaia.eval.groundtruth -d ./data/transcripts -p "*.txt" --use-case summarization
|
|
782
|
+
|
|
783
|
+
# Process transcript files for Q&A generation (creates consolidated file)
|
|
784
|
+
python -m gaia.eval.groundtruth -d ./data/transcripts -p "*.txt" --use-case qa
|
|
785
|
+
|
|
786
|
+
# Process with custom output directory
|
|
787
|
+
python -m gaia.eval.groundtruth -f ./data/html/intro.html -o ./output/gt
|
|
788
|
+
|
|
789
|
+
# Use custom Claude model
|
|
790
|
+
python -m gaia.eval.groundtruth -f ./data/doc.html -m claude-3-opus-20240229
|
|
791
|
+
|
|
792
|
+
# Generate 10 Q&A pairs per document (RAG only)
|
|
793
|
+
python -m gaia.eval.groundtruth -d ./data/html/blender --num-samples 10
|
|
794
|
+
|
|
795
|
+
# Consolidate multiple ground truth files into one
|
|
796
|
+
python -m gaia.eval.groundtruth -d ./output/groundtruth --consolidate
|
|
797
|
+
|
|
798
|
+
# Resume generation (skip files that already have ground truth)
|
|
799
|
+
python -m gaia.eval.groundtruth -d ./data/transcripts -p "*.txt" --use-case summarization
|
|
800
|
+
|
|
801
|
+
# Force regeneration of all files (even if ground truth exists)
|
|
802
|
+
python -m gaia.eval.groundtruth -d ./data/transcripts -p "*.txt" --use-case summarization --force
|
|
803
|
+
""",
|
|
804
|
+
)
|
|
805
|
+
|
|
806
|
+
# Input source (mutually exclusive)
|
|
807
|
+
input_group = parser.add_mutually_exclusive_group(required=True)
|
|
808
|
+
input_group.add_argument(
|
|
809
|
+
"-f", "--file", type=str, help="Path to a single document file to process"
|
|
810
|
+
)
|
|
811
|
+
input_group.add_argument(
|
|
812
|
+
"-d", "--directory", type=str, help="Directory containing documents to process"
|
|
813
|
+
)
|
|
814
|
+
|
|
815
|
+
# Optional arguments
|
|
816
|
+
parser.add_argument(
|
|
817
|
+
"-o",
|
|
818
|
+
"--output-dir",
|
|
819
|
+
type=str,
|
|
820
|
+
default="./output/groundtruth",
|
|
821
|
+
help="Output directory for generated ground truth files (default: ./output/groundtruth)",
|
|
822
|
+
)
|
|
823
|
+
parser.add_argument(
|
|
824
|
+
"-p",
|
|
825
|
+
"--pattern",
|
|
826
|
+
type=str,
|
|
827
|
+
default="*.html",
|
|
828
|
+
help="File pattern to match when processing directory (default: *.html)",
|
|
829
|
+
)
|
|
830
|
+
parser.add_argument(
|
|
831
|
+
"-u",
|
|
832
|
+
"--use-case",
|
|
833
|
+
type=str,
|
|
834
|
+
choices=[uc.value for uc in UseCase],
|
|
835
|
+
default=UseCase.RAG.value,
|
|
836
|
+
help=f"Use case for ground truth generation (default: {UseCase.RAG.value})",
|
|
837
|
+
)
|
|
838
|
+
parser.add_argument(
|
|
839
|
+
"-m",
|
|
840
|
+
"--model",
|
|
841
|
+
type=str,
|
|
842
|
+
default=None,
|
|
843
|
+
help=f"Claude model to use (default: {DEFAULT_CLAUDE_MODEL})",
|
|
844
|
+
)
|
|
845
|
+
parser.add_argument(
|
|
846
|
+
"--max-tokens",
|
|
847
|
+
type=int,
|
|
848
|
+
default=4096,
|
|
849
|
+
help="Maximum tokens for Claude responses (default: 4096)",
|
|
850
|
+
)
|
|
851
|
+
parser.add_argument(
|
|
852
|
+
"--no-save-text",
|
|
853
|
+
action="store_true",
|
|
854
|
+
help="Don't save extracted text for HTML files",
|
|
855
|
+
)
|
|
856
|
+
parser.add_argument(
|
|
857
|
+
"--custom-prompt",
|
|
858
|
+
type=str,
|
|
859
|
+
help="Path to a file containing a custom prompt for Claude",
|
|
860
|
+
)
|
|
861
|
+
parser.add_argument(
|
|
862
|
+
"--num-samples",
|
|
863
|
+
type=int,
|
|
864
|
+
default=5,
|
|
865
|
+
help="Number of Q&A pairs to generate per document (RAG use case only, default: 5)",
|
|
866
|
+
)
|
|
867
|
+
parser.add_argument(
|
|
868
|
+
"--consolidate",
|
|
869
|
+
action="store_true",
|
|
870
|
+
help="Consolidate multiple ground truth files into a single file",
|
|
871
|
+
)
|
|
872
|
+
parser.add_argument(
|
|
873
|
+
"--force",
|
|
874
|
+
action="store_true",
|
|
875
|
+
help="Force regeneration of all ground truth files, even if they already exist",
|
|
876
|
+
)
|
|
877
|
+
|
|
878
|
+
args = parser.parse_args()
|
|
879
|
+
|
|
880
|
+
# Convert use case string to enum
|
|
881
|
+
use_case = UseCase(args.use_case)
|
|
882
|
+
|
|
883
|
+
# Initialize generator
|
|
884
|
+
try:
|
|
885
|
+
generator = GroundTruthGenerator(model=args.model, max_tokens=args.max_tokens)
|
|
886
|
+
except Exception as e:
|
|
887
|
+
print(f"Error initializing generator: {e}")
|
|
888
|
+
return 1
|
|
889
|
+
|
|
890
|
+
# Load custom prompt if provided
|
|
891
|
+
custom_prompt = None
|
|
892
|
+
if args.custom_prompt:
|
|
893
|
+
try:
|
|
894
|
+
with open(args.custom_prompt, "r", encoding="utf-8") as f:
|
|
895
|
+
custom_prompt = f.read().strip()
|
|
896
|
+
print(f"Using custom prompt from: {args.custom_prompt}")
|
|
897
|
+
except Exception as e:
|
|
898
|
+
print(f"Error loading custom prompt: {e}")
|
|
899
|
+
return 1
|
|
900
|
+
|
|
901
|
+
save_text = not args.no_save_text
|
|
902
|
+
|
|
903
|
+
try:
|
|
904
|
+
if args.consolidate:
|
|
905
|
+
# Consolidate mode - directory is required
|
|
906
|
+
if not args.directory:
|
|
907
|
+
print("Error: --consolidate requires --directory (-d) to be specified")
|
|
908
|
+
return 1
|
|
909
|
+
|
|
910
|
+
# Use the specified use case for the consolidation pattern
|
|
911
|
+
consolidate_pattern = f"*.{use_case.value}.groundtruth.json"
|
|
912
|
+
print(f"Consolidating ground truth files from: {args.directory}")
|
|
913
|
+
print(f"Pattern: {consolidate_pattern}")
|
|
914
|
+
result = generator.consolidate_groundtruth(
|
|
915
|
+
input_dir=args.directory,
|
|
916
|
+
output_path=Path(args.output_dir)
|
|
917
|
+
/ f"consolidated_{use_case.value}_groundtruth.json",
|
|
918
|
+
file_pattern=consolidate_pattern,
|
|
919
|
+
)
|
|
920
|
+
print(
|
|
921
|
+
f"✅ Successfully consolidated {result['metadata']['consolidated_from']} files"
|
|
922
|
+
)
|
|
923
|
+
print(
|
|
924
|
+
f" Output: {Path(args.output_dir) / f'consolidated_{use_case.value}_groundtruth.json'}"
|
|
925
|
+
)
|
|
926
|
+
print(
|
|
927
|
+
f" Total cost: ${result['metadata']['total_cost']['total_cost']:.4f}"
|
|
928
|
+
)
|
|
929
|
+
print(
|
|
930
|
+
f" Total tokens: {result['metadata']['total_usage']['total_tokens']:,}"
|
|
931
|
+
)
|
|
932
|
+
|
|
933
|
+
elif args.file:
|
|
934
|
+
# Process single file
|
|
935
|
+
print(f"Processing single file: {args.file} (use case: {use_case.value})")
|
|
936
|
+
result = generator.generate(
|
|
937
|
+
file_path=args.file,
|
|
938
|
+
use_case=use_case,
|
|
939
|
+
prompt=custom_prompt,
|
|
940
|
+
save_text=save_text,
|
|
941
|
+
output_dir=args.output_dir,
|
|
942
|
+
num_samples=args.num_samples,
|
|
943
|
+
)
|
|
944
|
+
print(f"✅ Successfully generated ground truth data")
|
|
945
|
+
print(f" Output: {args.output_dir}")
|
|
946
|
+
usage = result["metadata"]["usage"]
|
|
947
|
+
cost = result["metadata"]["cost"]
|
|
948
|
+
print(
|
|
949
|
+
f" Token usage: {usage['input_tokens']:,} input + {usage['output_tokens']:,} output = {usage['total_tokens']:,} total"
|
|
950
|
+
)
|
|
951
|
+
print(
|
|
952
|
+
f" Cost: ${cost['input_cost']:.4f} input + ${cost['output_cost']:.4f} output = ${cost['total_cost']:.4f} total"
|
|
953
|
+
)
|
|
954
|
+
|
|
955
|
+
# Different output based on use case
|
|
956
|
+
if use_case == UseCase.RAG:
|
|
957
|
+
qa_pairs_count = len(result["analysis"]["qa_pairs"])
|
|
958
|
+
print(
|
|
959
|
+
f" Q&A pairs: {qa_pairs_count} (${cost['total_cost']/qa_pairs_count:.4f} per pair)"
|
|
960
|
+
)
|
|
961
|
+
elif use_case == UseCase.SUMMARIZATION:
|
|
962
|
+
print(
|
|
963
|
+
f" Summary types generated: {len(result['analysis']['summaries'])} different formats"
|
|
964
|
+
)
|
|
965
|
+
print(
|
|
966
|
+
f" Evaluation criteria: {len(result['analysis']['evaluation_criteria'])} categories"
|
|
967
|
+
)
|
|
968
|
+
elif use_case == UseCase.QA:
|
|
969
|
+
print(f" Q&A pairs: {len(result['analysis']['qa_pairs'])}")
|
|
970
|
+
print(
|
|
971
|
+
f" Evaluation criteria: {len(result['analysis']['evaluation_criteria'])} categories"
|
|
972
|
+
)
|
|
973
|
+
|
|
974
|
+
elif args.directory:
|
|
975
|
+
# Process directory
|
|
976
|
+
print(
|
|
977
|
+
f"Processing directory: {args.directory} (use case: {use_case.value})"
|
|
978
|
+
)
|
|
979
|
+
print(f"File pattern: {args.pattern}")
|
|
980
|
+
if args.force:
|
|
981
|
+
print("Force mode: Regenerating all ground truth files")
|
|
982
|
+
else:
|
|
983
|
+
print(
|
|
984
|
+
"Resume mode: Skipping files with existing ground truth (use --force to regenerate all)"
|
|
985
|
+
)
|
|
986
|
+
results = generator.generate_batch(
|
|
987
|
+
input_dir=args.directory,
|
|
988
|
+
file_pattern=args.pattern,
|
|
989
|
+
use_case=use_case,
|
|
990
|
+
force=args.force,
|
|
991
|
+
prompt=custom_prompt,
|
|
992
|
+
save_text=save_text,
|
|
993
|
+
output_dir=args.output_dir,
|
|
994
|
+
num_samples=args.num_samples,
|
|
995
|
+
)
|
|
996
|
+
|
|
997
|
+
if results:
|
|
998
|
+
# Handle consolidated dict vs list of results
|
|
999
|
+
if isinstance(results, dict):
|
|
1000
|
+
# Consolidated results from generate_batch
|
|
1001
|
+
# Cumulative totals (all files including existing ones)
|
|
1002
|
+
cumulative_usage = results["metadata"]["total_usage"]
|
|
1003
|
+
cumulative_cost = results["metadata"]["total_cost"]
|
|
1004
|
+
num_files = results["metadata"]["consolidated_from"]
|
|
1005
|
+
print(f"✅ Successfully processed batch")
|
|
1006
|
+
print(f" Output: {args.output_dir}")
|
|
1007
|
+
print(
|
|
1008
|
+
f" Total files: {num_files} ({results['metadata'].get('source_files', []).__len__()} in consolidated output)"
|
|
1009
|
+
)
|
|
1010
|
+
else:
|
|
1011
|
+
# Fallback: list of individual results
|
|
1012
|
+
total_usage = {
|
|
1013
|
+
"input_tokens": sum(
|
|
1014
|
+
r["metadata"]["usage"]["input_tokens"] for r in results
|
|
1015
|
+
),
|
|
1016
|
+
"output_tokens": sum(
|
|
1017
|
+
r["metadata"]["usage"]["output_tokens"] for r in results
|
|
1018
|
+
),
|
|
1019
|
+
"total_tokens": sum(
|
|
1020
|
+
r["metadata"]["usage"]["total_tokens"] for r in results
|
|
1021
|
+
),
|
|
1022
|
+
}
|
|
1023
|
+
total_cost = {
|
|
1024
|
+
"input_cost": sum(
|
|
1025
|
+
r["metadata"]["cost"]["input_cost"] for r in results
|
|
1026
|
+
),
|
|
1027
|
+
"output_cost": sum(
|
|
1028
|
+
r["metadata"]["cost"]["output_cost"] for r in results
|
|
1029
|
+
),
|
|
1030
|
+
"total_cost": sum(
|
|
1031
|
+
r["metadata"]["cost"]["total_cost"] for r in results
|
|
1032
|
+
),
|
|
1033
|
+
}
|
|
1034
|
+
num_files = len(results)
|
|
1035
|
+
print(f"✅ Successfully processed {num_files} files")
|
|
1036
|
+
print(f" Output: {args.output_dir}")
|
|
1037
|
+
|
|
1038
|
+
# Print this run's cost (if available)
|
|
1039
|
+
if isinstance(results, dict) and "run_stats" in results.get(
|
|
1040
|
+
"metadata", {}
|
|
1041
|
+
):
|
|
1042
|
+
run_stats = results["metadata"]["run_stats"]
|
|
1043
|
+
run_cost_data = run_stats["run_cost"]
|
|
1044
|
+
run_usage_data = run_stats["run_usage"]
|
|
1045
|
+
processed = run_stats["processed_count"]
|
|
1046
|
+
|
|
1047
|
+
if processed > 0:
|
|
1048
|
+
print(
|
|
1049
|
+
f"\n This run (generated {processed} new file{'s' if processed != 1 else ''}):"
|
|
1050
|
+
)
|
|
1051
|
+
print(
|
|
1052
|
+
f" Cost: ${run_cost_data['total_cost']:.4f} "
|
|
1053
|
+
f"({run_usage_data['total_tokens']:,} tokens)"
|
|
1054
|
+
)
|
|
1055
|
+
|
|
1056
|
+
# Print cumulative totals for dict, or totals for list
|
|
1057
|
+
label = "Cumulative total" if isinstance(results, dict) else "Total"
|
|
1058
|
+
usage_data = (
|
|
1059
|
+
cumulative_usage if isinstance(results, dict) else total_usage
|
|
1060
|
+
)
|
|
1061
|
+
cost_data = cumulative_cost if isinstance(results, dict) else total_cost
|
|
1062
|
+
|
|
1063
|
+
print(f"\n {label} (all files):")
|
|
1064
|
+
print(
|
|
1065
|
+
f" Token usage: {usage_data['input_tokens']:,} input + "
|
|
1066
|
+
f"{usage_data['output_tokens']:,} output = {usage_data['total_tokens']:,} total"
|
|
1067
|
+
)
|
|
1068
|
+
print(
|
|
1069
|
+
f" Cost: ${cost_data['input_cost']:.4f} input + "
|
|
1070
|
+
f"${cost_data['output_cost']:.4f} output = ${cost_data['total_cost']:.4f} total"
|
|
1071
|
+
)
|
|
1072
|
+
if num_files > 0:
|
|
1073
|
+
print(
|
|
1074
|
+
f" Average per file: ${cost_data['total_cost']/num_files:.4f}"
|
|
1075
|
+
)
|
|
1076
|
+
|
|
1077
|
+
# Different summary stats based on use case
|
|
1078
|
+
if isinstance(results, dict):
|
|
1079
|
+
# Consolidated results
|
|
1080
|
+
if use_case == UseCase.RAG:
|
|
1081
|
+
# Count total Q&A pairs across all files
|
|
1082
|
+
total_pairs = sum(
|
|
1083
|
+
len(qa_pairs)
|
|
1084
|
+
for qa_pairs in results["analysis"]
|
|
1085
|
+
.get("qa_pairs", {})
|
|
1086
|
+
.values()
|
|
1087
|
+
)
|
|
1088
|
+
print(f" Total Q&A pairs: {total_pairs}")
|
|
1089
|
+
if total_pairs > 0:
|
|
1090
|
+
print(
|
|
1091
|
+
f" Average cost per Q&A pair: ${cumulative_cost['total_cost']/total_pairs:.4f}"
|
|
1092
|
+
)
|
|
1093
|
+
elif use_case == UseCase.SUMMARIZATION:
|
|
1094
|
+
num_summaries = len(results["analysis"].get("summaries", {}))
|
|
1095
|
+
print(
|
|
1096
|
+
f" Generated {num_summaries} comprehensive transcript summaries"
|
|
1097
|
+
)
|
|
1098
|
+
elif use_case == UseCase.QA:
|
|
1099
|
+
num_qa = len(results["analysis"].get("qa_pairs", {}))
|
|
1100
|
+
print(f" Generated Q&A for {num_qa} transcripts")
|
|
1101
|
+
else:
|
|
1102
|
+
# List results
|
|
1103
|
+
if use_case == UseCase.RAG:
|
|
1104
|
+
total_pairs = sum(
|
|
1105
|
+
len(r["analysis"]["qa_pairs"]) for r in results
|
|
1106
|
+
)
|
|
1107
|
+
print(f" Total Q&A pairs: {total_pairs}")
|
|
1108
|
+
if total_pairs > 0:
|
|
1109
|
+
print(
|
|
1110
|
+
f" Average cost per Q&A pair: ${total_cost['total_cost']/total_pairs:.4f}"
|
|
1111
|
+
)
|
|
1112
|
+
elif use_case == UseCase.SUMMARIZATION:
|
|
1113
|
+
print(
|
|
1114
|
+
f" Generated {len(results)} comprehensive transcript summaries"
|
|
1115
|
+
)
|
|
1116
|
+
elif use_case == UseCase.QA:
|
|
1117
|
+
print(f" Generated {len(results)} Q&A pairs")
|
|
1118
|
+
else:
|
|
1119
|
+
print("No files were processed successfully")
|
|
1120
|
+
return 1
|
|
1121
|
+
|
|
1122
|
+
except Exception as e:
|
|
1123
|
+
print(f"Error during processing: {e}")
|
|
1124
|
+
return 1
|
|
1125
|
+
|
|
1126
|
+
return 0
|
|
1127
|
+
|
|
1128
|
+
|
|
1129
|
+
if __name__ == "__main__":
|
|
1130
|
+
exit(main())
|