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.
Files changed (800) hide show
  1. amd_gaia-0.14.1.dist-info/METADATA +768 -0
  2. amd_gaia-0.14.1.dist-info/RECORD +800 -0
  3. amd_gaia-0.14.1.dist-info/WHEEL +5 -0
  4. amd_gaia-0.14.1.dist-info/entry_points.txt +5 -0
  5. amd_gaia-0.14.1.dist-info/licenses/LICENSE.md +21 -0
  6. amd_gaia-0.14.1.dist-info/top_level.txt +1 -0
  7. gaia/__init__.py +2 -0
  8. gaia/agents/__init__.py +19 -0
  9. gaia/agents/base/__init__.py +9 -0
  10. gaia/agents/base/agent.py +2072 -0
  11. gaia/agents/base/api_agent.py +120 -0
  12. gaia/agents/base/console.py +1457 -0
  13. gaia/agents/base/mcp_agent.py +86 -0
  14. gaia/agents/base/tools.py +83 -0
  15. gaia/agents/blender/agent.py +556 -0
  16. gaia/agents/blender/agent_simple.py +135 -0
  17. gaia/agents/blender/app.py +211 -0
  18. gaia/agents/blender/app_simple.py +41 -0
  19. gaia/agents/blender/core/__init__.py +16 -0
  20. gaia/agents/blender/core/materials.py +506 -0
  21. gaia/agents/blender/core/objects.py +316 -0
  22. gaia/agents/blender/core/rendering.py +225 -0
  23. gaia/agents/blender/core/scene.py +220 -0
  24. gaia/agents/blender/core/view.py +146 -0
  25. gaia/agents/chat/__init__.py +9 -0
  26. gaia/agents/chat/agent.py +975 -0
  27. gaia/agents/chat/app.py +1058 -0
  28. gaia/agents/chat/session.py +508 -0
  29. gaia/agents/chat/tools/__init__.py +15 -0
  30. gaia/agents/chat/tools/file_tools.py +96 -0
  31. gaia/agents/chat/tools/rag_tools.py +1729 -0
  32. gaia/agents/chat/tools/shell_tools.py +436 -0
  33. gaia/agents/code/__init__.py +7 -0
  34. gaia/agents/code/agent.py +547 -0
  35. gaia/agents/code/app.py +266 -0
  36. gaia/agents/code/models.py +135 -0
  37. gaia/agents/code/orchestration/__init__.py +24 -0
  38. gaia/agents/code/orchestration/checklist_executor.py +1739 -0
  39. gaia/agents/code/orchestration/checklist_generator.py +709 -0
  40. gaia/agents/code/orchestration/factories/__init__.py +9 -0
  41. gaia/agents/code/orchestration/factories/base.py +63 -0
  42. gaia/agents/code/orchestration/factories/nextjs_factory.py +118 -0
  43. gaia/agents/code/orchestration/factories/python_factory.py +106 -0
  44. gaia/agents/code/orchestration/orchestrator.py +610 -0
  45. gaia/agents/code/orchestration/project_analyzer.py +391 -0
  46. gaia/agents/code/orchestration/steps/__init__.py +67 -0
  47. gaia/agents/code/orchestration/steps/base.py +188 -0
  48. gaia/agents/code/orchestration/steps/error_handler.py +314 -0
  49. gaia/agents/code/orchestration/steps/nextjs.py +828 -0
  50. gaia/agents/code/orchestration/steps/python.py +307 -0
  51. gaia/agents/code/orchestration/template_catalog.py +463 -0
  52. gaia/agents/code/orchestration/workflows/__init__.py +14 -0
  53. gaia/agents/code/orchestration/workflows/base.py +80 -0
  54. gaia/agents/code/orchestration/workflows/nextjs.py +186 -0
  55. gaia/agents/code/orchestration/workflows/python.py +94 -0
  56. gaia/agents/code/prompts/__init__.py +11 -0
  57. gaia/agents/code/prompts/base_prompt.py +77 -0
  58. gaia/agents/code/prompts/code_patterns.py +1925 -0
  59. gaia/agents/code/prompts/nextjs_prompt.py +40 -0
  60. gaia/agents/code/prompts/python_prompt.py +109 -0
  61. gaia/agents/code/schema_inference.py +365 -0
  62. gaia/agents/code/system_prompt.py +41 -0
  63. gaia/agents/code/tools/__init__.py +42 -0
  64. gaia/agents/code/tools/cli_tools.py +1138 -0
  65. gaia/agents/code/tools/code_formatting.py +319 -0
  66. gaia/agents/code/tools/code_tools.py +769 -0
  67. gaia/agents/code/tools/error_fixing.py +1347 -0
  68. gaia/agents/code/tools/external_tools.py +180 -0
  69. gaia/agents/code/tools/file_io.py +845 -0
  70. gaia/agents/code/tools/prisma_tools.py +190 -0
  71. gaia/agents/code/tools/project_management.py +1016 -0
  72. gaia/agents/code/tools/testing.py +321 -0
  73. gaia/agents/code/tools/typescript_tools.py +122 -0
  74. gaia/agents/code/tools/validation_parsing.py +461 -0
  75. gaia/agents/code/tools/validation_tools.py +803 -0
  76. gaia/agents/code/tools/web_dev_tools.py +1744 -0
  77. gaia/agents/code/validators/__init__.py +16 -0
  78. gaia/agents/code/validators/antipattern_checker.py +241 -0
  79. gaia/agents/code/validators/ast_analyzer.py +197 -0
  80. gaia/agents/code/validators/requirements_validator.py +145 -0
  81. gaia/agents/code/validators/syntax_validator.py +171 -0
  82. gaia/agents/docker/__init__.py +7 -0
  83. gaia/agents/docker/agent.py +642 -0
  84. gaia/agents/jira/__init__.py +11 -0
  85. gaia/agents/jira/agent.py +894 -0
  86. gaia/agents/jira/jql_templates.py +299 -0
  87. gaia/agents/routing/__init__.py +7 -0
  88. gaia/agents/routing/agent.py +512 -0
  89. gaia/agents/routing/system_prompt.py +75 -0
  90. gaia/api/__init__.py +23 -0
  91. gaia/api/agent_registry.py +238 -0
  92. gaia/api/app.py +305 -0
  93. gaia/api/openai_server.py +575 -0
  94. gaia/api/schemas.py +186 -0
  95. gaia/api/sse_handler.py +370 -0
  96. gaia/apps/__init__.py +4 -0
  97. gaia/apps/llm/__init__.py +6 -0
  98. gaia/apps/llm/app.py +169 -0
  99. gaia/apps/summarize/app.py +633 -0
  100. gaia/apps/summarize/html_viewer.py +133 -0
  101. gaia/apps/summarize/pdf_formatter.py +284 -0
  102. gaia/audio/__init__.py +2 -0
  103. gaia/audio/audio_client.py +439 -0
  104. gaia/audio/audio_recorder.py +269 -0
  105. gaia/audio/kokoro_tts.py +599 -0
  106. gaia/audio/whisper_asr.py +432 -0
  107. gaia/chat/__init__.py +16 -0
  108. gaia/chat/app.py +430 -0
  109. gaia/chat/prompts.py +522 -0
  110. gaia/chat/sdk.py +1200 -0
  111. gaia/cli.py +5621 -0
  112. gaia/eval/batch_experiment.py +2332 -0
  113. gaia/eval/claude.py +542 -0
  114. gaia/eval/config.py +37 -0
  115. gaia/eval/email_generator.py +512 -0
  116. gaia/eval/eval.py +3179 -0
  117. gaia/eval/groundtruth.py +1130 -0
  118. gaia/eval/transcript_generator.py +582 -0
  119. gaia/eval/webapp/README.md +168 -0
  120. gaia/eval/webapp/node_modules/.bin/mime +16 -0
  121. gaia/eval/webapp/node_modules/.bin/mime.cmd +17 -0
  122. gaia/eval/webapp/node_modules/.bin/mime.ps1 +28 -0
  123. gaia/eval/webapp/node_modules/.package-lock.json +865 -0
  124. gaia/eval/webapp/node_modules/accepts/HISTORY.md +243 -0
  125. gaia/eval/webapp/node_modules/accepts/LICENSE +23 -0
  126. gaia/eval/webapp/node_modules/accepts/README.md +140 -0
  127. gaia/eval/webapp/node_modules/accepts/index.js +238 -0
  128. gaia/eval/webapp/node_modules/accepts/package.json +47 -0
  129. gaia/eval/webapp/node_modules/array-flatten/LICENSE +21 -0
  130. gaia/eval/webapp/node_modules/array-flatten/README.md +43 -0
  131. gaia/eval/webapp/node_modules/array-flatten/array-flatten.js +64 -0
  132. gaia/eval/webapp/node_modules/array-flatten/package.json +39 -0
  133. gaia/eval/webapp/node_modules/body-parser/HISTORY.md +672 -0
  134. gaia/eval/webapp/node_modules/body-parser/LICENSE +23 -0
  135. gaia/eval/webapp/node_modules/body-parser/README.md +476 -0
  136. gaia/eval/webapp/node_modules/body-parser/SECURITY.md +25 -0
  137. gaia/eval/webapp/node_modules/body-parser/index.js +156 -0
  138. gaia/eval/webapp/node_modules/body-parser/lib/read.js +205 -0
  139. gaia/eval/webapp/node_modules/body-parser/lib/types/json.js +247 -0
  140. gaia/eval/webapp/node_modules/body-parser/lib/types/raw.js +101 -0
  141. gaia/eval/webapp/node_modules/body-parser/lib/types/text.js +121 -0
  142. gaia/eval/webapp/node_modules/body-parser/lib/types/urlencoded.js +307 -0
  143. gaia/eval/webapp/node_modules/body-parser/package.json +56 -0
  144. gaia/eval/webapp/node_modules/bytes/History.md +97 -0
  145. gaia/eval/webapp/node_modules/bytes/LICENSE +23 -0
  146. gaia/eval/webapp/node_modules/bytes/Readme.md +152 -0
  147. gaia/eval/webapp/node_modules/bytes/index.js +170 -0
  148. gaia/eval/webapp/node_modules/bytes/package.json +42 -0
  149. gaia/eval/webapp/node_modules/call-bind-apply-helpers/.eslintrc +17 -0
  150. gaia/eval/webapp/node_modules/call-bind-apply-helpers/.github/FUNDING.yml +12 -0
  151. gaia/eval/webapp/node_modules/call-bind-apply-helpers/.nycrc +9 -0
  152. gaia/eval/webapp/node_modules/call-bind-apply-helpers/CHANGELOG.md +30 -0
  153. gaia/eval/webapp/node_modules/call-bind-apply-helpers/LICENSE +21 -0
  154. gaia/eval/webapp/node_modules/call-bind-apply-helpers/README.md +62 -0
  155. gaia/eval/webapp/node_modules/call-bind-apply-helpers/actualApply.d.ts +1 -0
  156. gaia/eval/webapp/node_modules/call-bind-apply-helpers/actualApply.js +10 -0
  157. gaia/eval/webapp/node_modules/call-bind-apply-helpers/applyBind.d.ts +19 -0
  158. gaia/eval/webapp/node_modules/call-bind-apply-helpers/applyBind.js +10 -0
  159. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionApply.d.ts +1 -0
  160. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionApply.js +4 -0
  161. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionCall.d.ts +1 -0
  162. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionCall.js +4 -0
  163. gaia/eval/webapp/node_modules/call-bind-apply-helpers/index.d.ts +64 -0
  164. gaia/eval/webapp/node_modules/call-bind-apply-helpers/index.js +15 -0
  165. gaia/eval/webapp/node_modules/call-bind-apply-helpers/package.json +85 -0
  166. gaia/eval/webapp/node_modules/call-bind-apply-helpers/reflectApply.d.ts +3 -0
  167. gaia/eval/webapp/node_modules/call-bind-apply-helpers/reflectApply.js +4 -0
  168. gaia/eval/webapp/node_modules/call-bind-apply-helpers/test/index.js +63 -0
  169. gaia/eval/webapp/node_modules/call-bind-apply-helpers/tsconfig.json +9 -0
  170. gaia/eval/webapp/node_modules/call-bound/.eslintrc +13 -0
  171. gaia/eval/webapp/node_modules/call-bound/.github/FUNDING.yml +12 -0
  172. gaia/eval/webapp/node_modules/call-bound/.nycrc +9 -0
  173. gaia/eval/webapp/node_modules/call-bound/CHANGELOG.md +42 -0
  174. gaia/eval/webapp/node_modules/call-bound/LICENSE +21 -0
  175. gaia/eval/webapp/node_modules/call-bound/README.md +53 -0
  176. gaia/eval/webapp/node_modules/call-bound/index.d.ts +94 -0
  177. gaia/eval/webapp/node_modules/call-bound/index.js +19 -0
  178. gaia/eval/webapp/node_modules/call-bound/package.json +99 -0
  179. gaia/eval/webapp/node_modules/call-bound/test/index.js +61 -0
  180. gaia/eval/webapp/node_modules/call-bound/tsconfig.json +10 -0
  181. gaia/eval/webapp/node_modules/content-disposition/HISTORY.md +60 -0
  182. gaia/eval/webapp/node_modules/content-disposition/LICENSE +22 -0
  183. gaia/eval/webapp/node_modules/content-disposition/README.md +142 -0
  184. gaia/eval/webapp/node_modules/content-disposition/index.js +458 -0
  185. gaia/eval/webapp/node_modules/content-disposition/package.json +44 -0
  186. gaia/eval/webapp/node_modules/content-type/HISTORY.md +29 -0
  187. gaia/eval/webapp/node_modules/content-type/LICENSE +22 -0
  188. gaia/eval/webapp/node_modules/content-type/README.md +94 -0
  189. gaia/eval/webapp/node_modules/content-type/index.js +225 -0
  190. gaia/eval/webapp/node_modules/content-type/package.json +42 -0
  191. gaia/eval/webapp/node_modules/cookie/LICENSE +24 -0
  192. gaia/eval/webapp/node_modules/cookie/README.md +317 -0
  193. gaia/eval/webapp/node_modules/cookie/SECURITY.md +25 -0
  194. gaia/eval/webapp/node_modules/cookie/index.js +334 -0
  195. gaia/eval/webapp/node_modules/cookie/package.json +44 -0
  196. gaia/eval/webapp/node_modules/cookie-signature/.npmignore +4 -0
  197. gaia/eval/webapp/node_modules/cookie-signature/History.md +38 -0
  198. gaia/eval/webapp/node_modules/cookie-signature/Readme.md +42 -0
  199. gaia/eval/webapp/node_modules/cookie-signature/index.js +51 -0
  200. gaia/eval/webapp/node_modules/cookie-signature/package.json +18 -0
  201. gaia/eval/webapp/node_modules/debug/.coveralls.yml +1 -0
  202. gaia/eval/webapp/node_modules/debug/.eslintrc +11 -0
  203. gaia/eval/webapp/node_modules/debug/.npmignore +9 -0
  204. gaia/eval/webapp/node_modules/debug/.travis.yml +14 -0
  205. gaia/eval/webapp/node_modules/debug/CHANGELOG.md +362 -0
  206. gaia/eval/webapp/node_modules/debug/LICENSE +19 -0
  207. gaia/eval/webapp/node_modules/debug/Makefile +50 -0
  208. gaia/eval/webapp/node_modules/debug/README.md +312 -0
  209. gaia/eval/webapp/node_modules/debug/component.json +19 -0
  210. gaia/eval/webapp/node_modules/debug/karma.conf.js +70 -0
  211. gaia/eval/webapp/node_modules/debug/node.js +1 -0
  212. gaia/eval/webapp/node_modules/debug/package.json +49 -0
  213. gaia/eval/webapp/node_modules/debug/src/browser.js +185 -0
  214. gaia/eval/webapp/node_modules/debug/src/debug.js +202 -0
  215. gaia/eval/webapp/node_modules/debug/src/index.js +10 -0
  216. gaia/eval/webapp/node_modules/debug/src/inspector-log.js +15 -0
  217. gaia/eval/webapp/node_modules/debug/src/node.js +248 -0
  218. gaia/eval/webapp/node_modules/depd/History.md +103 -0
  219. gaia/eval/webapp/node_modules/depd/LICENSE +22 -0
  220. gaia/eval/webapp/node_modules/depd/Readme.md +280 -0
  221. gaia/eval/webapp/node_modules/depd/index.js +538 -0
  222. gaia/eval/webapp/node_modules/depd/lib/browser/index.js +77 -0
  223. gaia/eval/webapp/node_modules/depd/package.json +45 -0
  224. gaia/eval/webapp/node_modules/destroy/LICENSE +23 -0
  225. gaia/eval/webapp/node_modules/destroy/README.md +63 -0
  226. gaia/eval/webapp/node_modules/destroy/index.js +209 -0
  227. gaia/eval/webapp/node_modules/destroy/package.json +48 -0
  228. gaia/eval/webapp/node_modules/dunder-proto/.eslintrc +5 -0
  229. gaia/eval/webapp/node_modules/dunder-proto/.github/FUNDING.yml +12 -0
  230. gaia/eval/webapp/node_modules/dunder-proto/.nycrc +13 -0
  231. gaia/eval/webapp/node_modules/dunder-proto/CHANGELOG.md +24 -0
  232. gaia/eval/webapp/node_modules/dunder-proto/LICENSE +21 -0
  233. gaia/eval/webapp/node_modules/dunder-proto/README.md +54 -0
  234. gaia/eval/webapp/node_modules/dunder-proto/get.d.ts +5 -0
  235. gaia/eval/webapp/node_modules/dunder-proto/get.js +30 -0
  236. gaia/eval/webapp/node_modules/dunder-proto/package.json +76 -0
  237. gaia/eval/webapp/node_modules/dunder-proto/set.d.ts +5 -0
  238. gaia/eval/webapp/node_modules/dunder-proto/set.js +35 -0
  239. gaia/eval/webapp/node_modules/dunder-proto/test/get.js +34 -0
  240. gaia/eval/webapp/node_modules/dunder-proto/test/index.js +4 -0
  241. gaia/eval/webapp/node_modules/dunder-proto/test/set.js +50 -0
  242. gaia/eval/webapp/node_modules/dunder-proto/tsconfig.json +9 -0
  243. gaia/eval/webapp/node_modules/ee-first/LICENSE +22 -0
  244. gaia/eval/webapp/node_modules/ee-first/README.md +80 -0
  245. gaia/eval/webapp/node_modules/ee-first/index.js +95 -0
  246. gaia/eval/webapp/node_modules/ee-first/package.json +29 -0
  247. gaia/eval/webapp/node_modules/encodeurl/LICENSE +22 -0
  248. gaia/eval/webapp/node_modules/encodeurl/README.md +109 -0
  249. gaia/eval/webapp/node_modules/encodeurl/index.js +60 -0
  250. gaia/eval/webapp/node_modules/encodeurl/package.json +40 -0
  251. gaia/eval/webapp/node_modules/es-define-property/.eslintrc +13 -0
  252. gaia/eval/webapp/node_modules/es-define-property/.github/FUNDING.yml +12 -0
  253. gaia/eval/webapp/node_modules/es-define-property/.nycrc +9 -0
  254. gaia/eval/webapp/node_modules/es-define-property/CHANGELOG.md +29 -0
  255. gaia/eval/webapp/node_modules/es-define-property/LICENSE +21 -0
  256. gaia/eval/webapp/node_modules/es-define-property/README.md +49 -0
  257. gaia/eval/webapp/node_modules/es-define-property/index.d.ts +3 -0
  258. gaia/eval/webapp/node_modules/es-define-property/index.js +14 -0
  259. gaia/eval/webapp/node_modules/es-define-property/package.json +81 -0
  260. gaia/eval/webapp/node_modules/es-define-property/test/index.js +56 -0
  261. gaia/eval/webapp/node_modules/es-define-property/tsconfig.json +10 -0
  262. gaia/eval/webapp/node_modules/es-errors/.eslintrc +5 -0
  263. gaia/eval/webapp/node_modules/es-errors/.github/FUNDING.yml +12 -0
  264. gaia/eval/webapp/node_modules/es-errors/CHANGELOG.md +40 -0
  265. gaia/eval/webapp/node_modules/es-errors/LICENSE +21 -0
  266. gaia/eval/webapp/node_modules/es-errors/README.md +55 -0
  267. gaia/eval/webapp/node_modules/es-errors/eval.d.ts +3 -0
  268. gaia/eval/webapp/node_modules/es-errors/eval.js +4 -0
  269. gaia/eval/webapp/node_modules/es-errors/index.d.ts +3 -0
  270. gaia/eval/webapp/node_modules/es-errors/index.js +4 -0
  271. gaia/eval/webapp/node_modules/es-errors/package.json +80 -0
  272. gaia/eval/webapp/node_modules/es-errors/range.d.ts +3 -0
  273. gaia/eval/webapp/node_modules/es-errors/range.js +4 -0
  274. gaia/eval/webapp/node_modules/es-errors/ref.d.ts +3 -0
  275. gaia/eval/webapp/node_modules/es-errors/ref.js +4 -0
  276. gaia/eval/webapp/node_modules/es-errors/syntax.d.ts +3 -0
  277. gaia/eval/webapp/node_modules/es-errors/syntax.js +4 -0
  278. gaia/eval/webapp/node_modules/es-errors/test/index.js +19 -0
  279. gaia/eval/webapp/node_modules/es-errors/tsconfig.json +49 -0
  280. gaia/eval/webapp/node_modules/es-errors/type.d.ts +3 -0
  281. gaia/eval/webapp/node_modules/es-errors/type.js +4 -0
  282. gaia/eval/webapp/node_modules/es-errors/uri.d.ts +3 -0
  283. gaia/eval/webapp/node_modules/es-errors/uri.js +4 -0
  284. gaia/eval/webapp/node_modules/es-object-atoms/.eslintrc +16 -0
  285. gaia/eval/webapp/node_modules/es-object-atoms/.github/FUNDING.yml +12 -0
  286. gaia/eval/webapp/node_modules/es-object-atoms/CHANGELOG.md +37 -0
  287. gaia/eval/webapp/node_modules/es-object-atoms/LICENSE +21 -0
  288. gaia/eval/webapp/node_modules/es-object-atoms/README.md +63 -0
  289. gaia/eval/webapp/node_modules/es-object-atoms/RequireObjectCoercible.d.ts +3 -0
  290. gaia/eval/webapp/node_modules/es-object-atoms/RequireObjectCoercible.js +11 -0
  291. gaia/eval/webapp/node_modules/es-object-atoms/ToObject.d.ts +7 -0
  292. gaia/eval/webapp/node_modules/es-object-atoms/ToObject.js +10 -0
  293. gaia/eval/webapp/node_modules/es-object-atoms/index.d.ts +3 -0
  294. gaia/eval/webapp/node_modules/es-object-atoms/index.js +4 -0
  295. gaia/eval/webapp/node_modules/es-object-atoms/isObject.d.ts +3 -0
  296. gaia/eval/webapp/node_modules/es-object-atoms/isObject.js +6 -0
  297. gaia/eval/webapp/node_modules/es-object-atoms/package.json +80 -0
  298. gaia/eval/webapp/node_modules/es-object-atoms/test/index.js +38 -0
  299. gaia/eval/webapp/node_modules/es-object-atoms/tsconfig.json +6 -0
  300. gaia/eval/webapp/node_modules/escape-html/LICENSE +24 -0
  301. gaia/eval/webapp/node_modules/escape-html/Readme.md +43 -0
  302. gaia/eval/webapp/node_modules/escape-html/index.js +78 -0
  303. gaia/eval/webapp/node_modules/escape-html/package.json +24 -0
  304. gaia/eval/webapp/node_modules/etag/HISTORY.md +83 -0
  305. gaia/eval/webapp/node_modules/etag/LICENSE +22 -0
  306. gaia/eval/webapp/node_modules/etag/README.md +159 -0
  307. gaia/eval/webapp/node_modules/etag/index.js +131 -0
  308. gaia/eval/webapp/node_modules/etag/package.json +47 -0
  309. gaia/eval/webapp/node_modules/express/History.md +3656 -0
  310. gaia/eval/webapp/node_modules/express/LICENSE +24 -0
  311. gaia/eval/webapp/node_modules/express/Readme.md +260 -0
  312. gaia/eval/webapp/node_modules/express/index.js +11 -0
  313. gaia/eval/webapp/node_modules/express/lib/application.js +661 -0
  314. gaia/eval/webapp/node_modules/express/lib/express.js +116 -0
  315. gaia/eval/webapp/node_modules/express/lib/middleware/init.js +43 -0
  316. gaia/eval/webapp/node_modules/express/lib/middleware/query.js +47 -0
  317. gaia/eval/webapp/node_modules/express/lib/request.js +525 -0
  318. gaia/eval/webapp/node_modules/express/lib/response.js +1179 -0
  319. gaia/eval/webapp/node_modules/express/lib/router/index.js +673 -0
  320. gaia/eval/webapp/node_modules/express/lib/router/layer.js +181 -0
  321. gaia/eval/webapp/node_modules/express/lib/router/route.js +230 -0
  322. gaia/eval/webapp/node_modules/express/lib/utils.js +303 -0
  323. gaia/eval/webapp/node_modules/express/lib/view.js +182 -0
  324. gaia/eval/webapp/node_modules/express/package.json +102 -0
  325. gaia/eval/webapp/node_modules/finalhandler/HISTORY.md +210 -0
  326. gaia/eval/webapp/node_modules/finalhandler/LICENSE +22 -0
  327. gaia/eval/webapp/node_modules/finalhandler/README.md +147 -0
  328. gaia/eval/webapp/node_modules/finalhandler/SECURITY.md +25 -0
  329. gaia/eval/webapp/node_modules/finalhandler/index.js +341 -0
  330. gaia/eval/webapp/node_modules/finalhandler/package.json +47 -0
  331. gaia/eval/webapp/node_modules/forwarded/HISTORY.md +21 -0
  332. gaia/eval/webapp/node_modules/forwarded/LICENSE +22 -0
  333. gaia/eval/webapp/node_modules/forwarded/README.md +57 -0
  334. gaia/eval/webapp/node_modules/forwarded/index.js +90 -0
  335. gaia/eval/webapp/node_modules/forwarded/package.json +45 -0
  336. gaia/eval/webapp/node_modules/fresh/HISTORY.md +70 -0
  337. gaia/eval/webapp/node_modules/fresh/LICENSE +23 -0
  338. gaia/eval/webapp/node_modules/fresh/README.md +119 -0
  339. gaia/eval/webapp/node_modules/fresh/index.js +137 -0
  340. gaia/eval/webapp/node_modules/fresh/package.json +46 -0
  341. gaia/eval/webapp/node_modules/fs/README.md +9 -0
  342. gaia/eval/webapp/node_modules/fs/package.json +20 -0
  343. gaia/eval/webapp/node_modules/function-bind/.eslintrc +21 -0
  344. gaia/eval/webapp/node_modules/function-bind/.github/FUNDING.yml +12 -0
  345. gaia/eval/webapp/node_modules/function-bind/.github/SECURITY.md +3 -0
  346. gaia/eval/webapp/node_modules/function-bind/.nycrc +13 -0
  347. gaia/eval/webapp/node_modules/function-bind/CHANGELOG.md +136 -0
  348. gaia/eval/webapp/node_modules/function-bind/LICENSE +20 -0
  349. gaia/eval/webapp/node_modules/function-bind/README.md +46 -0
  350. gaia/eval/webapp/node_modules/function-bind/implementation.js +84 -0
  351. gaia/eval/webapp/node_modules/function-bind/index.js +5 -0
  352. gaia/eval/webapp/node_modules/function-bind/package.json +87 -0
  353. gaia/eval/webapp/node_modules/function-bind/test/.eslintrc +9 -0
  354. gaia/eval/webapp/node_modules/function-bind/test/index.js +252 -0
  355. gaia/eval/webapp/node_modules/get-intrinsic/.eslintrc +42 -0
  356. gaia/eval/webapp/node_modules/get-intrinsic/.github/FUNDING.yml +12 -0
  357. gaia/eval/webapp/node_modules/get-intrinsic/.nycrc +9 -0
  358. gaia/eval/webapp/node_modules/get-intrinsic/CHANGELOG.md +186 -0
  359. gaia/eval/webapp/node_modules/get-intrinsic/LICENSE +21 -0
  360. gaia/eval/webapp/node_modules/get-intrinsic/README.md +71 -0
  361. gaia/eval/webapp/node_modules/get-intrinsic/index.js +378 -0
  362. gaia/eval/webapp/node_modules/get-intrinsic/package.json +97 -0
  363. gaia/eval/webapp/node_modules/get-intrinsic/test/GetIntrinsic.js +274 -0
  364. gaia/eval/webapp/node_modules/get-proto/.eslintrc +10 -0
  365. gaia/eval/webapp/node_modules/get-proto/.github/FUNDING.yml +12 -0
  366. gaia/eval/webapp/node_modules/get-proto/.nycrc +9 -0
  367. gaia/eval/webapp/node_modules/get-proto/CHANGELOG.md +21 -0
  368. gaia/eval/webapp/node_modules/get-proto/LICENSE +21 -0
  369. gaia/eval/webapp/node_modules/get-proto/Object.getPrototypeOf.d.ts +5 -0
  370. gaia/eval/webapp/node_modules/get-proto/Object.getPrototypeOf.js +6 -0
  371. gaia/eval/webapp/node_modules/get-proto/README.md +50 -0
  372. gaia/eval/webapp/node_modules/get-proto/Reflect.getPrototypeOf.d.ts +3 -0
  373. gaia/eval/webapp/node_modules/get-proto/Reflect.getPrototypeOf.js +4 -0
  374. gaia/eval/webapp/node_modules/get-proto/index.d.ts +5 -0
  375. gaia/eval/webapp/node_modules/get-proto/index.js +27 -0
  376. gaia/eval/webapp/node_modules/get-proto/package.json +81 -0
  377. gaia/eval/webapp/node_modules/get-proto/test/index.js +68 -0
  378. gaia/eval/webapp/node_modules/get-proto/tsconfig.json +9 -0
  379. gaia/eval/webapp/node_modules/gopd/.eslintrc +16 -0
  380. gaia/eval/webapp/node_modules/gopd/.github/FUNDING.yml +12 -0
  381. gaia/eval/webapp/node_modules/gopd/CHANGELOG.md +45 -0
  382. gaia/eval/webapp/node_modules/gopd/LICENSE +21 -0
  383. gaia/eval/webapp/node_modules/gopd/README.md +40 -0
  384. gaia/eval/webapp/node_modules/gopd/gOPD.d.ts +1 -0
  385. gaia/eval/webapp/node_modules/gopd/gOPD.js +4 -0
  386. gaia/eval/webapp/node_modules/gopd/index.d.ts +5 -0
  387. gaia/eval/webapp/node_modules/gopd/index.js +15 -0
  388. gaia/eval/webapp/node_modules/gopd/package.json +77 -0
  389. gaia/eval/webapp/node_modules/gopd/test/index.js +36 -0
  390. gaia/eval/webapp/node_modules/gopd/tsconfig.json +9 -0
  391. gaia/eval/webapp/node_modules/has-symbols/.eslintrc +11 -0
  392. gaia/eval/webapp/node_modules/has-symbols/.github/FUNDING.yml +12 -0
  393. gaia/eval/webapp/node_modules/has-symbols/.nycrc +9 -0
  394. gaia/eval/webapp/node_modules/has-symbols/CHANGELOG.md +91 -0
  395. gaia/eval/webapp/node_modules/has-symbols/LICENSE +21 -0
  396. gaia/eval/webapp/node_modules/has-symbols/README.md +46 -0
  397. gaia/eval/webapp/node_modules/has-symbols/index.d.ts +3 -0
  398. gaia/eval/webapp/node_modules/has-symbols/index.js +14 -0
  399. gaia/eval/webapp/node_modules/has-symbols/package.json +111 -0
  400. gaia/eval/webapp/node_modules/has-symbols/shams.d.ts +3 -0
  401. gaia/eval/webapp/node_modules/has-symbols/shams.js +45 -0
  402. gaia/eval/webapp/node_modules/has-symbols/test/index.js +22 -0
  403. gaia/eval/webapp/node_modules/has-symbols/test/shams/core-js.js +29 -0
  404. gaia/eval/webapp/node_modules/has-symbols/test/shams/get-own-property-symbols.js +29 -0
  405. gaia/eval/webapp/node_modules/has-symbols/test/tests.js +58 -0
  406. gaia/eval/webapp/node_modules/has-symbols/tsconfig.json +10 -0
  407. gaia/eval/webapp/node_modules/hasown/.eslintrc +5 -0
  408. gaia/eval/webapp/node_modules/hasown/.github/FUNDING.yml +12 -0
  409. gaia/eval/webapp/node_modules/hasown/.nycrc +13 -0
  410. gaia/eval/webapp/node_modules/hasown/CHANGELOG.md +40 -0
  411. gaia/eval/webapp/node_modules/hasown/LICENSE +21 -0
  412. gaia/eval/webapp/node_modules/hasown/README.md +40 -0
  413. gaia/eval/webapp/node_modules/hasown/index.d.ts +3 -0
  414. gaia/eval/webapp/node_modules/hasown/index.js +8 -0
  415. gaia/eval/webapp/node_modules/hasown/package.json +92 -0
  416. gaia/eval/webapp/node_modules/hasown/tsconfig.json +6 -0
  417. gaia/eval/webapp/node_modules/http-errors/HISTORY.md +180 -0
  418. gaia/eval/webapp/node_modules/http-errors/LICENSE +23 -0
  419. gaia/eval/webapp/node_modules/http-errors/README.md +169 -0
  420. gaia/eval/webapp/node_modules/http-errors/index.js +289 -0
  421. gaia/eval/webapp/node_modules/http-errors/package.json +50 -0
  422. gaia/eval/webapp/node_modules/iconv-lite/Changelog.md +162 -0
  423. gaia/eval/webapp/node_modules/iconv-lite/LICENSE +21 -0
  424. gaia/eval/webapp/node_modules/iconv-lite/README.md +156 -0
  425. gaia/eval/webapp/node_modules/iconv-lite/encodings/dbcs-codec.js +555 -0
  426. gaia/eval/webapp/node_modules/iconv-lite/encodings/dbcs-data.js +176 -0
  427. gaia/eval/webapp/node_modules/iconv-lite/encodings/index.js +22 -0
  428. gaia/eval/webapp/node_modules/iconv-lite/encodings/internal.js +188 -0
  429. gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-codec.js +72 -0
  430. gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-data-generated.js +451 -0
  431. gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-data.js +174 -0
  432. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/big5-added.json +122 -0
  433. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp936.json +264 -0
  434. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp949.json +273 -0
  435. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp950.json +177 -0
  436. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/eucjp.json +182 -0
  437. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +1 -0
  438. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/gbk-added.json +55 -0
  439. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/shiftjis.json +125 -0
  440. gaia/eval/webapp/node_modules/iconv-lite/encodings/utf16.js +177 -0
  441. gaia/eval/webapp/node_modules/iconv-lite/encodings/utf7.js +290 -0
  442. gaia/eval/webapp/node_modules/iconv-lite/lib/bom-handling.js +52 -0
  443. gaia/eval/webapp/node_modules/iconv-lite/lib/extend-node.js +217 -0
  444. gaia/eval/webapp/node_modules/iconv-lite/lib/index.d.ts +24 -0
  445. gaia/eval/webapp/node_modules/iconv-lite/lib/index.js +153 -0
  446. gaia/eval/webapp/node_modules/iconv-lite/lib/streams.js +121 -0
  447. gaia/eval/webapp/node_modules/iconv-lite/package.json +46 -0
  448. gaia/eval/webapp/node_modules/inherits/LICENSE +16 -0
  449. gaia/eval/webapp/node_modules/inherits/README.md +42 -0
  450. gaia/eval/webapp/node_modules/inherits/inherits.js +9 -0
  451. gaia/eval/webapp/node_modules/inherits/inherits_browser.js +27 -0
  452. gaia/eval/webapp/node_modules/inherits/package.json +29 -0
  453. gaia/eval/webapp/node_modules/ipaddr.js/LICENSE +19 -0
  454. gaia/eval/webapp/node_modules/ipaddr.js/README.md +233 -0
  455. gaia/eval/webapp/node_modules/ipaddr.js/ipaddr.min.js +1 -0
  456. gaia/eval/webapp/node_modules/ipaddr.js/lib/ipaddr.js +673 -0
  457. gaia/eval/webapp/node_modules/ipaddr.js/lib/ipaddr.js.d.ts +68 -0
  458. gaia/eval/webapp/node_modules/ipaddr.js/package.json +35 -0
  459. gaia/eval/webapp/node_modules/math-intrinsics/.eslintrc +16 -0
  460. gaia/eval/webapp/node_modules/math-intrinsics/.github/FUNDING.yml +12 -0
  461. gaia/eval/webapp/node_modules/math-intrinsics/CHANGELOG.md +24 -0
  462. gaia/eval/webapp/node_modules/math-intrinsics/LICENSE +21 -0
  463. gaia/eval/webapp/node_modules/math-intrinsics/README.md +50 -0
  464. gaia/eval/webapp/node_modules/math-intrinsics/abs.d.ts +1 -0
  465. gaia/eval/webapp/node_modules/math-intrinsics/abs.js +4 -0
  466. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxArrayLength.d.ts +3 -0
  467. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxArrayLength.js +4 -0
  468. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts +3 -0
  469. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxSafeInteger.js +5 -0
  470. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxValue.d.ts +3 -0
  471. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxValue.js +5 -0
  472. gaia/eval/webapp/node_modules/math-intrinsics/floor.d.ts +1 -0
  473. gaia/eval/webapp/node_modules/math-intrinsics/floor.js +4 -0
  474. gaia/eval/webapp/node_modules/math-intrinsics/isFinite.d.ts +3 -0
  475. gaia/eval/webapp/node_modules/math-intrinsics/isFinite.js +12 -0
  476. gaia/eval/webapp/node_modules/math-intrinsics/isInteger.d.ts +3 -0
  477. gaia/eval/webapp/node_modules/math-intrinsics/isInteger.js +16 -0
  478. gaia/eval/webapp/node_modules/math-intrinsics/isNaN.d.ts +1 -0
  479. gaia/eval/webapp/node_modules/math-intrinsics/isNaN.js +6 -0
  480. gaia/eval/webapp/node_modules/math-intrinsics/isNegativeZero.d.ts +3 -0
  481. gaia/eval/webapp/node_modules/math-intrinsics/isNegativeZero.js +6 -0
  482. gaia/eval/webapp/node_modules/math-intrinsics/max.d.ts +1 -0
  483. gaia/eval/webapp/node_modules/math-intrinsics/max.js +4 -0
  484. gaia/eval/webapp/node_modules/math-intrinsics/min.d.ts +1 -0
  485. gaia/eval/webapp/node_modules/math-intrinsics/min.js +4 -0
  486. gaia/eval/webapp/node_modules/math-intrinsics/mod.d.ts +3 -0
  487. gaia/eval/webapp/node_modules/math-intrinsics/mod.js +9 -0
  488. gaia/eval/webapp/node_modules/math-intrinsics/package.json +86 -0
  489. gaia/eval/webapp/node_modules/math-intrinsics/pow.d.ts +1 -0
  490. gaia/eval/webapp/node_modules/math-intrinsics/pow.js +4 -0
  491. gaia/eval/webapp/node_modules/math-intrinsics/round.d.ts +1 -0
  492. gaia/eval/webapp/node_modules/math-intrinsics/round.js +4 -0
  493. gaia/eval/webapp/node_modules/math-intrinsics/sign.d.ts +3 -0
  494. gaia/eval/webapp/node_modules/math-intrinsics/sign.js +11 -0
  495. gaia/eval/webapp/node_modules/math-intrinsics/test/index.js +192 -0
  496. gaia/eval/webapp/node_modules/math-intrinsics/tsconfig.json +3 -0
  497. gaia/eval/webapp/node_modules/media-typer/HISTORY.md +22 -0
  498. gaia/eval/webapp/node_modules/media-typer/LICENSE +22 -0
  499. gaia/eval/webapp/node_modules/media-typer/README.md +81 -0
  500. gaia/eval/webapp/node_modules/media-typer/index.js +270 -0
  501. gaia/eval/webapp/node_modules/media-typer/package.json +26 -0
  502. gaia/eval/webapp/node_modules/merge-descriptors/HISTORY.md +21 -0
  503. gaia/eval/webapp/node_modules/merge-descriptors/LICENSE +23 -0
  504. gaia/eval/webapp/node_modules/merge-descriptors/README.md +49 -0
  505. gaia/eval/webapp/node_modules/merge-descriptors/index.js +60 -0
  506. gaia/eval/webapp/node_modules/merge-descriptors/package.json +39 -0
  507. gaia/eval/webapp/node_modules/methods/HISTORY.md +29 -0
  508. gaia/eval/webapp/node_modules/methods/LICENSE +24 -0
  509. gaia/eval/webapp/node_modules/methods/README.md +51 -0
  510. gaia/eval/webapp/node_modules/methods/index.js +69 -0
  511. gaia/eval/webapp/node_modules/methods/package.json +36 -0
  512. gaia/eval/webapp/node_modules/mime/.npmignore +0 -0
  513. gaia/eval/webapp/node_modules/mime/CHANGELOG.md +164 -0
  514. gaia/eval/webapp/node_modules/mime/LICENSE +21 -0
  515. gaia/eval/webapp/node_modules/mime/README.md +90 -0
  516. gaia/eval/webapp/node_modules/mime/cli.js +8 -0
  517. gaia/eval/webapp/node_modules/mime/mime.js +108 -0
  518. gaia/eval/webapp/node_modules/mime/package.json +44 -0
  519. gaia/eval/webapp/node_modules/mime/src/build.js +53 -0
  520. gaia/eval/webapp/node_modules/mime/src/test.js +60 -0
  521. gaia/eval/webapp/node_modules/mime/types.json +1 -0
  522. gaia/eval/webapp/node_modules/mime-db/HISTORY.md +507 -0
  523. gaia/eval/webapp/node_modules/mime-db/LICENSE +23 -0
  524. gaia/eval/webapp/node_modules/mime-db/README.md +100 -0
  525. gaia/eval/webapp/node_modules/mime-db/db.json +8519 -0
  526. gaia/eval/webapp/node_modules/mime-db/index.js +12 -0
  527. gaia/eval/webapp/node_modules/mime-db/package.json +60 -0
  528. gaia/eval/webapp/node_modules/mime-types/HISTORY.md +397 -0
  529. gaia/eval/webapp/node_modules/mime-types/LICENSE +23 -0
  530. gaia/eval/webapp/node_modules/mime-types/README.md +113 -0
  531. gaia/eval/webapp/node_modules/mime-types/index.js +188 -0
  532. gaia/eval/webapp/node_modules/mime-types/package.json +44 -0
  533. gaia/eval/webapp/node_modules/ms/index.js +152 -0
  534. gaia/eval/webapp/node_modules/ms/license.md +21 -0
  535. gaia/eval/webapp/node_modules/ms/package.json +37 -0
  536. gaia/eval/webapp/node_modules/ms/readme.md +51 -0
  537. gaia/eval/webapp/node_modules/negotiator/HISTORY.md +108 -0
  538. gaia/eval/webapp/node_modules/negotiator/LICENSE +24 -0
  539. gaia/eval/webapp/node_modules/negotiator/README.md +203 -0
  540. gaia/eval/webapp/node_modules/negotiator/index.js +82 -0
  541. gaia/eval/webapp/node_modules/negotiator/lib/charset.js +169 -0
  542. gaia/eval/webapp/node_modules/negotiator/lib/encoding.js +184 -0
  543. gaia/eval/webapp/node_modules/negotiator/lib/language.js +179 -0
  544. gaia/eval/webapp/node_modules/negotiator/lib/mediaType.js +294 -0
  545. gaia/eval/webapp/node_modules/negotiator/package.json +42 -0
  546. gaia/eval/webapp/node_modules/object-inspect/.eslintrc +53 -0
  547. gaia/eval/webapp/node_modules/object-inspect/.github/FUNDING.yml +12 -0
  548. gaia/eval/webapp/node_modules/object-inspect/.nycrc +13 -0
  549. gaia/eval/webapp/node_modules/object-inspect/CHANGELOG.md +424 -0
  550. gaia/eval/webapp/node_modules/object-inspect/LICENSE +21 -0
  551. gaia/eval/webapp/node_modules/object-inspect/example/all.js +23 -0
  552. gaia/eval/webapp/node_modules/object-inspect/example/circular.js +6 -0
  553. gaia/eval/webapp/node_modules/object-inspect/example/fn.js +5 -0
  554. gaia/eval/webapp/node_modules/object-inspect/example/inspect.js +10 -0
  555. gaia/eval/webapp/node_modules/object-inspect/index.js +544 -0
  556. gaia/eval/webapp/node_modules/object-inspect/package-support.json +20 -0
  557. gaia/eval/webapp/node_modules/object-inspect/package.json +105 -0
  558. gaia/eval/webapp/node_modules/object-inspect/readme.markdown +84 -0
  559. gaia/eval/webapp/node_modules/object-inspect/test/bigint.js +58 -0
  560. gaia/eval/webapp/node_modules/object-inspect/test/browser/dom.js +15 -0
  561. gaia/eval/webapp/node_modules/object-inspect/test/circular.js +16 -0
  562. gaia/eval/webapp/node_modules/object-inspect/test/deep.js +12 -0
  563. gaia/eval/webapp/node_modules/object-inspect/test/element.js +53 -0
  564. gaia/eval/webapp/node_modules/object-inspect/test/err.js +48 -0
  565. gaia/eval/webapp/node_modules/object-inspect/test/fakes.js +29 -0
  566. gaia/eval/webapp/node_modules/object-inspect/test/fn.js +76 -0
  567. gaia/eval/webapp/node_modules/object-inspect/test/global.js +17 -0
  568. gaia/eval/webapp/node_modules/object-inspect/test/has.js +15 -0
  569. gaia/eval/webapp/node_modules/object-inspect/test/holes.js +15 -0
  570. gaia/eval/webapp/node_modules/object-inspect/test/indent-option.js +271 -0
  571. gaia/eval/webapp/node_modules/object-inspect/test/inspect.js +139 -0
  572. gaia/eval/webapp/node_modules/object-inspect/test/lowbyte.js +12 -0
  573. gaia/eval/webapp/node_modules/object-inspect/test/number.js +58 -0
  574. gaia/eval/webapp/node_modules/object-inspect/test/quoteStyle.js +26 -0
  575. gaia/eval/webapp/node_modules/object-inspect/test/toStringTag.js +40 -0
  576. gaia/eval/webapp/node_modules/object-inspect/test/undef.js +12 -0
  577. gaia/eval/webapp/node_modules/object-inspect/test/values.js +261 -0
  578. gaia/eval/webapp/node_modules/object-inspect/test-core-js.js +26 -0
  579. gaia/eval/webapp/node_modules/object-inspect/util.inspect.js +1 -0
  580. gaia/eval/webapp/node_modules/on-finished/HISTORY.md +98 -0
  581. gaia/eval/webapp/node_modules/on-finished/LICENSE +23 -0
  582. gaia/eval/webapp/node_modules/on-finished/README.md +162 -0
  583. gaia/eval/webapp/node_modules/on-finished/index.js +234 -0
  584. gaia/eval/webapp/node_modules/on-finished/package.json +39 -0
  585. gaia/eval/webapp/node_modules/parseurl/HISTORY.md +58 -0
  586. gaia/eval/webapp/node_modules/parseurl/LICENSE +24 -0
  587. gaia/eval/webapp/node_modules/parseurl/README.md +133 -0
  588. gaia/eval/webapp/node_modules/parseurl/index.js +158 -0
  589. gaia/eval/webapp/node_modules/parseurl/package.json +40 -0
  590. gaia/eval/webapp/node_modules/path/.npmignore +1 -0
  591. gaia/eval/webapp/node_modules/path/LICENSE +18 -0
  592. gaia/eval/webapp/node_modules/path/README.md +15 -0
  593. gaia/eval/webapp/node_modules/path/package.json +24 -0
  594. gaia/eval/webapp/node_modules/path/path.js +628 -0
  595. gaia/eval/webapp/node_modules/path-to-regexp/LICENSE +21 -0
  596. gaia/eval/webapp/node_modules/path-to-regexp/Readme.md +35 -0
  597. gaia/eval/webapp/node_modules/path-to-regexp/index.js +156 -0
  598. gaia/eval/webapp/node_modules/path-to-regexp/package.json +30 -0
  599. gaia/eval/webapp/node_modules/process/.eslintrc +21 -0
  600. gaia/eval/webapp/node_modules/process/LICENSE +22 -0
  601. gaia/eval/webapp/node_modules/process/README.md +26 -0
  602. gaia/eval/webapp/node_modules/process/browser.js +184 -0
  603. gaia/eval/webapp/node_modules/process/index.js +2 -0
  604. gaia/eval/webapp/node_modules/process/package.json +27 -0
  605. gaia/eval/webapp/node_modules/process/test.js +199 -0
  606. gaia/eval/webapp/node_modules/proxy-addr/HISTORY.md +161 -0
  607. gaia/eval/webapp/node_modules/proxy-addr/LICENSE +22 -0
  608. gaia/eval/webapp/node_modules/proxy-addr/README.md +139 -0
  609. gaia/eval/webapp/node_modules/proxy-addr/index.js +327 -0
  610. gaia/eval/webapp/node_modules/proxy-addr/package.json +47 -0
  611. gaia/eval/webapp/node_modules/qs/.editorconfig +46 -0
  612. gaia/eval/webapp/node_modules/qs/.eslintrc +38 -0
  613. gaia/eval/webapp/node_modules/qs/.github/FUNDING.yml +12 -0
  614. gaia/eval/webapp/node_modules/qs/.nycrc +13 -0
  615. gaia/eval/webapp/node_modules/qs/CHANGELOG.md +600 -0
  616. gaia/eval/webapp/node_modules/qs/LICENSE.md +29 -0
  617. gaia/eval/webapp/node_modules/qs/README.md +709 -0
  618. gaia/eval/webapp/node_modules/qs/dist/qs.js +90 -0
  619. gaia/eval/webapp/node_modules/qs/lib/formats.js +23 -0
  620. gaia/eval/webapp/node_modules/qs/lib/index.js +11 -0
  621. gaia/eval/webapp/node_modules/qs/lib/parse.js +296 -0
  622. gaia/eval/webapp/node_modules/qs/lib/stringify.js +351 -0
  623. gaia/eval/webapp/node_modules/qs/lib/utils.js +265 -0
  624. gaia/eval/webapp/node_modules/qs/package.json +91 -0
  625. gaia/eval/webapp/node_modules/qs/test/empty-keys-cases.js +267 -0
  626. gaia/eval/webapp/node_modules/qs/test/parse.js +1170 -0
  627. gaia/eval/webapp/node_modules/qs/test/stringify.js +1298 -0
  628. gaia/eval/webapp/node_modules/qs/test/utils.js +136 -0
  629. gaia/eval/webapp/node_modules/range-parser/HISTORY.md +56 -0
  630. gaia/eval/webapp/node_modules/range-parser/LICENSE +23 -0
  631. gaia/eval/webapp/node_modules/range-parser/README.md +84 -0
  632. gaia/eval/webapp/node_modules/range-parser/index.js +162 -0
  633. gaia/eval/webapp/node_modules/range-parser/package.json +44 -0
  634. gaia/eval/webapp/node_modules/raw-body/HISTORY.md +308 -0
  635. gaia/eval/webapp/node_modules/raw-body/LICENSE +22 -0
  636. gaia/eval/webapp/node_modules/raw-body/README.md +223 -0
  637. gaia/eval/webapp/node_modules/raw-body/SECURITY.md +24 -0
  638. gaia/eval/webapp/node_modules/raw-body/index.d.ts +87 -0
  639. gaia/eval/webapp/node_modules/raw-body/index.js +336 -0
  640. gaia/eval/webapp/node_modules/raw-body/package.json +49 -0
  641. gaia/eval/webapp/node_modules/safe-buffer/LICENSE +21 -0
  642. gaia/eval/webapp/node_modules/safe-buffer/README.md +584 -0
  643. gaia/eval/webapp/node_modules/safe-buffer/index.d.ts +187 -0
  644. gaia/eval/webapp/node_modules/safe-buffer/index.js +65 -0
  645. gaia/eval/webapp/node_modules/safe-buffer/package.json +51 -0
  646. gaia/eval/webapp/node_modules/safer-buffer/LICENSE +21 -0
  647. gaia/eval/webapp/node_modules/safer-buffer/Porting-Buffer.md +268 -0
  648. gaia/eval/webapp/node_modules/safer-buffer/Readme.md +156 -0
  649. gaia/eval/webapp/node_modules/safer-buffer/dangerous.js +58 -0
  650. gaia/eval/webapp/node_modules/safer-buffer/package.json +34 -0
  651. gaia/eval/webapp/node_modules/safer-buffer/safer.js +77 -0
  652. gaia/eval/webapp/node_modules/safer-buffer/tests.js +406 -0
  653. gaia/eval/webapp/node_modules/send/HISTORY.md +526 -0
  654. gaia/eval/webapp/node_modules/send/LICENSE +23 -0
  655. gaia/eval/webapp/node_modules/send/README.md +327 -0
  656. gaia/eval/webapp/node_modules/send/SECURITY.md +24 -0
  657. gaia/eval/webapp/node_modules/send/index.js +1142 -0
  658. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/HISTORY.md +14 -0
  659. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/LICENSE +22 -0
  660. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/README.md +128 -0
  661. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/index.js +60 -0
  662. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/package.json +40 -0
  663. gaia/eval/webapp/node_modules/send/node_modules/ms/index.js +162 -0
  664. gaia/eval/webapp/node_modules/send/node_modules/ms/license.md +21 -0
  665. gaia/eval/webapp/node_modules/send/node_modules/ms/package.json +38 -0
  666. gaia/eval/webapp/node_modules/send/node_modules/ms/readme.md +59 -0
  667. gaia/eval/webapp/node_modules/send/package.json +62 -0
  668. gaia/eval/webapp/node_modules/serve-static/HISTORY.md +487 -0
  669. gaia/eval/webapp/node_modules/serve-static/LICENSE +25 -0
  670. gaia/eval/webapp/node_modules/serve-static/README.md +257 -0
  671. gaia/eval/webapp/node_modules/serve-static/index.js +209 -0
  672. gaia/eval/webapp/node_modules/serve-static/package.json +42 -0
  673. gaia/eval/webapp/node_modules/setprototypeof/LICENSE +13 -0
  674. gaia/eval/webapp/node_modules/setprototypeof/README.md +31 -0
  675. gaia/eval/webapp/node_modules/setprototypeof/index.d.ts +2 -0
  676. gaia/eval/webapp/node_modules/setprototypeof/index.js +17 -0
  677. gaia/eval/webapp/node_modules/setprototypeof/package.json +38 -0
  678. gaia/eval/webapp/node_modules/setprototypeof/test/index.js +24 -0
  679. gaia/eval/webapp/node_modules/side-channel/.editorconfig +9 -0
  680. gaia/eval/webapp/node_modules/side-channel/.eslintrc +12 -0
  681. gaia/eval/webapp/node_modules/side-channel/.github/FUNDING.yml +12 -0
  682. gaia/eval/webapp/node_modules/side-channel/.nycrc +13 -0
  683. gaia/eval/webapp/node_modules/side-channel/CHANGELOG.md +110 -0
  684. gaia/eval/webapp/node_modules/side-channel/LICENSE +21 -0
  685. gaia/eval/webapp/node_modules/side-channel/README.md +61 -0
  686. gaia/eval/webapp/node_modules/side-channel/index.d.ts +14 -0
  687. gaia/eval/webapp/node_modules/side-channel/index.js +43 -0
  688. gaia/eval/webapp/node_modules/side-channel/package.json +85 -0
  689. gaia/eval/webapp/node_modules/side-channel/test/index.js +104 -0
  690. gaia/eval/webapp/node_modules/side-channel/tsconfig.json +9 -0
  691. gaia/eval/webapp/node_modules/side-channel-list/.editorconfig +9 -0
  692. gaia/eval/webapp/node_modules/side-channel-list/.eslintrc +11 -0
  693. gaia/eval/webapp/node_modules/side-channel-list/.github/FUNDING.yml +12 -0
  694. gaia/eval/webapp/node_modules/side-channel-list/.nycrc +13 -0
  695. gaia/eval/webapp/node_modules/side-channel-list/CHANGELOG.md +15 -0
  696. gaia/eval/webapp/node_modules/side-channel-list/LICENSE +21 -0
  697. gaia/eval/webapp/node_modules/side-channel-list/README.md +62 -0
  698. gaia/eval/webapp/node_modules/side-channel-list/index.d.ts +13 -0
  699. gaia/eval/webapp/node_modules/side-channel-list/index.js +113 -0
  700. gaia/eval/webapp/node_modules/side-channel-list/list.d.ts +14 -0
  701. gaia/eval/webapp/node_modules/side-channel-list/package.json +77 -0
  702. gaia/eval/webapp/node_modules/side-channel-list/test/index.js +104 -0
  703. gaia/eval/webapp/node_modules/side-channel-list/tsconfig.json +9 -0
  704. gaia/eval/webapp/node_modules/side-channel-map/.editorconfig +9 -0
  705. gaia/eval/webapp/node_modules/side-channel-map/.eslintrc +11 -0
  706. gaia/eval/webapp/node_modules/side-channel-map/.github/FUNDING.yml +12 -0
  707. gaia/eval/webapp/node_modules/side-channel-map/.nycrc +13 -0
  708. gaia/eval/webapp/node_modules/side-channel-map/CHANGELOG.md +22 -0
  709. gaia/eval/webapp/node_modules/side-channel-map/LICENSE +21 -0
  710. gaia/eval/webapp/node_modules/side-channel-map/README.md +62 -0
  711. gaia/eval/webapp/node_modules/side-channel-map/index.d.ts +15 -0
  712. gaia/eval/webapp/node_modules/side-channel-map/index.js +68 -0
  713. gaia/eval/webapp/node_modules/side-channel-map/package.json +80 -0
  714. gaia/eval/webapp/node_modules/side-channel-map/test/index.js +114 -0
  715. gaia/eval/webapp/node_modules/side-channel-map/tsconfig.json +9 -0
  716. gaia/eval/webapp/node_modules/side-channel-weakmap/.editorconfig +9 -0
  717. gaia/eval/webapp/node_modules/side-channel-weakmap/.eslintrc +12 -0
  718. gaia/eval/webapp/node_modules/side-channel-weakmap/.github/FUNDING.yml +12 -0
  719. gaia/eval/webapp/node_modules/side-channel-weakmap/.nycrc +13 -0
  720. gaia/eval/webapp/node_modules/side-channel-weakmap/CHANGELOG.md +28 -0
  721. gaia/eval/webapp/node_modules/side-channel-weakmap/LICENSE +21 -0
  722. gaia/eval/webapp/node_modules/side-channel-weakmap/README.md +62 -0
  723. gaia/eval/webapp/node_modules/side-channel-weakmap/index.d.ts +15 -0
  724. gaia/eval/webapp/node_modules/side-channel-weakmap/index.js +84 -0
  725. gaia/eval/webapp/node_modules/side-channel-weakmap/package.json +87 -0
  726. gaia/eval/webapp/node_modules/side-channel-weakmap/test/index.js +114 -0
  727. gaia/eval/webapp/node_modules/side-channel-weakmap/tsconfig.json +9 -0
  728. gaia/eval/webapp/node_modules/statuses/HISTORY.md +82 -0
  729. gaia/eval/webapp/node_modules/statuses/LICENSE +23 -0
  730. gaia/eval/webapp/node_modules/statuses/README.md +136 -0
  731. gaia/eval/webapp/node_modules/statuses/codes.json +65 -0
  732. gaia/eval/webapp/node_modules/statuses/index.js +146 -0
  733. gaia/eval/webapp/node_modules/statuses/package.json +49 -0
  734. gaia/eval/webapp/node_modules/toidentifier/HISTORY.md +9 -0
  735. gaia/eval/webapp/node_modules/toidentifier/LICENSE +21 -0
  736. gaia/eval/webapp/node_modules/toidentifier/README.md +61 -0
  737. gaia/eval/webapp/node_modules/toidentifier/index.js +32 -0
  738. gaia/eval/webapp/node_modules/toidentifier/package.json +38 -0
  739. gaia/eval/webapp/node_modules/type-is/HISTORY.md +259 -0
  740. gaia/eval/webapp/node_modules/type-is/LICENSE +23 -0
  741. gaia/eval/webapp/node_modules/type-is/README.md +170 -0
  742. gaia/eval/webapp/node_modules/type-is/index.js +266 -0
  743. gaia/eval/webapp/node_modules/type-is/package.json +45 -0
  744. gaia/eval/webapp/node_modules/unpipe/HISTORY.md +4 -0
  745. gaia/eval/webapp/node_modules/unpipe/LICENSE +22 -0
  746. gaia/eval/webapp/node_modules/unpipe/README.md +43 -0
  747. gaia/eval/webapp/node_modules/unpipe/index.js +69 -0
  748. gaia/eval/webapp/node_modules/unpipe/package.json +27 -0
  749. gaia/eval/webapp/node_modules/util/LICENSE +18 -0
  750. gaia/eval/webapp/node_modules/util/README.md +15 -0
  751. gaia/eval/webapp/node_modules/util/node_modules/inherits/LICENSE +16 -0
  752. gaia/eval/webapp/node_modules/util/node_modules/inherits/README.md +42 -0
  753. gaia/eval/webapp/node_modules/util/node_modules/inherits/inherits.js +7 -0
  754. gaia/eval/webapp/node_modules/util/node_modules/inherits/inherits_browser.js +23 -0
  755. gaia/eval/webapp/node_modules/util/node_modules/inherits/package.json +29 -0
  756. gaia/eval/webapp/node_modules/util/package.json +35 -0
  757. gaia/eval/webapp/node_modules/util/support/isBuffer.js +3 -0
  758. gaia/eval/webapp/node_modules/util/support/isBufferBrowser.js +6 -0
  759. gaia/eval/webapp/node_modules/util/util.js +586 -0
  760. gaia/eval/webapp/node_modules/utils-merge/.npmignore +9 -0
  761. gaia/eval/webapp/node_modules/utils-merge/LICENSE +20 -0
  762. gaia/eval/webapp/node_modules/utils-merge/README.md +34 -0
  763. gaia/eval/webapp/node_modules/utils-merge/index.js +23 -0
  764. gaia/eval/webapp/node_modules/utils-merge/package.json +40 -0
  765. gaia/eval/webapp/node_modules/vary/HISTORY.md +39 -0
  766. gaia/eval/webapp/node_modules/vary/LICENSE +22 -0
  767. gaia/eval/webapp/node_modules/vary/README.md +101 -0
  768. gaia/eval/webapp/node_modules/vary/index.js +149 -0
  769. gaia/eval/webapp/node_modules/vary/package.json +43 -0
  770. gaia/eval/webapp/package-lock.json +875 -0
  771. gaia/eval/webapp/package.json +21 -0
  772. gaia/eval/webapp/public/app.js +3403 -0
  773. gaia/eval/webapp/public/index.html +88 -0
  774. gaia/eval/webapp/public/styles.css +3661 -0
  775. gaia/eval/webapp/server.js +416 -0
  776. gaia/eval/webapp/test-setup.js +73 -0
  777. gaia/llm/__init__.py +2 -0
  778. gaia/llm/lemonade_client.py +3083 -0
  779. gaia/llm/lemonade_manager.py +269 -0
  780. gaia/llm/llm_client.py +729 -0
  781. gaia/llm/vlm_client.py +307 -0
  782. gaia/logger.py +189 -0
  783. gaia/mcp/agent_mcp_server.py +245 -0
  784. gaia/mcp/blender_mcp_client.py +138 -0
  785. gaia/mcp/blender_mcp_server.py +648 -0
  786. gaia/mcp/context7_cache.py +332 -0
  787. gaia/mcp/external_services.py +518 -0
  788. gaia/mcp/mcp_bridge.py +550 -0
  789. gaia/mcp/servers/__init__.py +6 -0
  790. gaia/mcp/servers/docker_mcp.py +83 -0
  791. gaia/rag/__init__.py +10 -0
  792. gaia/rag/app.py +293 -0
  793. gaia/rag/demo.py +304 -0
  794. gaia/rag/pdf_utils.py +235 -0
  795. gaia/rag/sdk.py +2194 -0
  796. gaia/security.py +163 -0
  797. gaia/talk/app.py +289 -0
  798. gaia/talk/sdk.py +538 -0
  799. gaia/util.py +46 -0
  800. gaia/version.py +100 -0
@@ -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())