amd-gaia 0.14.1__py3-none-any.whl → 0.14.3__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 (794) hide show
  1. amd_gaia-0.14.3.dist-info/METADATA +223 -0
  2. amd_gaia-0.14.3.dist-info/RECORD +168 -0
  3. {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.3.dist-info}/entry_points.txt +1 -0
  4. gaia/__init__.py +28 -1
  5. gaia/agents/__init__.py +1 -1
  6. gaia/agents/base/__init__.py +1 -1
  7. gaia/agents/base/agent.py +142 -37
  8. gaia/agents/base/api_agent.py +1 -1
  9. gaia/agents/base/console.py +400 -16
  10. gaia/agents/base/errors.py +237 -0
  11. gaia/agents/base/mcp_agent.py +1 -1
  12. gaia/agents/base/tools.py +1 -1
  13. gaia/agents/blender/agent.py +1 -1
  14. gaia/agents/blender/agent_simple.py +1 -1
  15. gaia/agents/blender/app.py +1 -1
  16. gaia/agents/blender/app_simple.py +1 -1
  17. gaia/agents/blender/core/__init__.py +1 -1
  18. gaia/agents/blender/core/materials.py +1 -1
  19. gaia/agents/blender/core/objects.py +1 -1
  20. gaia/agents/blender/core/rendering.py +1 -1
  21. gaia/agents/blender/core/scene.py +1 -1
  22. gaia/agents/blender/core/view.py +1 -1
  23. gaia/agents/chat/__init__.py +1 -1
  24. gaia/agents/chat/agent.py +41 -181
  25. gaia/agents/chat/app.py +1 -1
  26. gaia/agents/chat/session.py +1 -1
  27. gaia/agents/chat/tools/__init__.py +1 -1
  28. gaia/agents/chat/tools/file_tools.py +1 -1
  29. gaia/agents/chat/tools/rag_tools.py +1 -1
  30. gaia/agents/chat/tools/shell_tools.py +1 -1
  31. gaia/agents/code/__init__.py +1 -1
  32. gaia/agents/code/agent.py +3 -1
  33. gaia/agents/code/orchestration/__init__.py +1 -1
  34. gaia/agents/code/orchestration/checklist_executor.py +27 -3
  35. gaia/agents/code/orchestration/checklist_generator.py +8 -4
  36. gaia/agents/code/orchestration/factories/__init__.py +1 -1
  37. gaia/agents/code/orchestration/factories/base.py +1 -1
  38. gaia/agents/code/orchestration/factories/nextjs_factory.py +1 -1
  39. gaia/agents/code/orchestration/factories/python_factory.py +1 -1
  40. gaia/agents/code/orchestration/orchestrator.py +276 -45
  41. gaia/agents/code/orchestration/project_analyzer.py +1 -1
  42. gaia/agents/code/orchestration/steps/__init__.py +1 -1
  43. gaia/agents/code/orchestration/steps/base.py +1 -1
  44. gaia/agents/code/orchestration/steps/error_handler.py +2 -2
  45. gaia/agents/code/orchestration/steps/nextjs.py +1 -1
  46. gaia/agents/code/orchestration/steps/python.py +1 -1
  47. gaia/agents/code/orchestration/template_catalog.py +8 -2
  48. gaia/agents/code/orchestration/workflows/__init__.py +1 -1
  49. gaia/agents/code/orchestration/workflows/base.py +1 -1
  50. gaia/agents/code/orchestration/workflows/nextjs.py +1 -1
  51. gaia/agents/code/orchestration/workflows/python.py +1 -1
  52. gaia/agents/code/prompts/__init__.py +1 -1
  53. gaia/agents/code/prompts/base_prompt.py +1 -1
  54. gaia/agents/code/prompts/code_patterns.py +129 -18
  55. gaia/agents/code/prompts/nextjs_prompt.py +1 -1
  56. gaia/agents/code/prompts/python_prompt.py +1 -1
  57. gaia/agents/code/schema_inference.py +1 -1
  58. gaia/agents/code/system_prompt.py +1 -1
  59. gaia/agents/code/tools/__init__.py +1 -1
  60. gaia/agents/code/tools/cli_tools.py +1 -1
  61. gaia/agents/code/tools/code_formatting.py +2 -2
  62. gaia/agents/code/tools/code_tools.py +2 -2
  63. gaia/agents/code/tools/error_fixing.py +1 -1
  64. gaia/agents/code/tools/external_tools.py +1 -1
  65. gaia/agents/code/tools/prisma_tools.py +1 -1
  66. gaia/agents/code/tools/project_management.py +1 -1
  67. gaia/agents/code/tools/testing.py +1 -1
  68. gaia/agents/code/tools/typescript_tools.py +1 -1
  69. gaia/agents/code/tools/validation_parsing.py +1 -1
  70. gaia/agents/code/tools/validation_tools.py +5 -2
  71. gaia/agents/code/tools/web_dev_tools.py +17 -3
  72. gaia/agents/docker/__init__.py +1 -1
  73. gaia/agents/emr/__init__.py +8 -0
  74. gaia/agents/emr/agent.py +1506 -0
  75. gaia/agents/emr/cli.py +1322 -0
  76. gaia/agents/emr/constants.py +475 -0
  77. gaia/agents/emr/dashboard/__init__.py +4 -0
  78. gaia/agents/emr/dashboard/server.py +1974 -0
  79. gaia/agents/routing/__init__.py +1 -1
  80. gaia/agents/routing/agent.py +65 -7
  81. gaia/agents/routing/system_prompt.py +1 -1
  82. gaia/api/__init__.py +1 -1
  83. gaia/api/agent_registry.py +1 -1
  84. gaia/api/app.py +1 -1
  85. gaia/api/openai_server.py +1 -1
  86. gaia/api/schemas.py +1 -1
  87. gaia/api/sse_handler.py +5 -2
  88. gaia/apps/__init__.py +1 -1
  89. gaia/apps/llm/__init__.py +1 -1
  90. gaia/apps/summarize/pdf_formatter.py +1 -1
  91. gaia/audio/__init__.py +1 -1
  92. gaia/audio/audio_client.py +3 -3
  93. gaia/audio/audio_recorder.py +1 -1
  94. gaia/audio/kokoro_tts.py +3 -3
  95. gaia/audio/whisper_asr.py +3 -3
  96. gaia/chat/__init__.py +1 -1
  97. gaia/chat/prompts.py +1 -1
  98. gaia/chat/sdk.py +26 -1
  99. gaia/cli.py +18 -18
  100. gaia/database/__init__.py +10 -0
  101. gaia/database/agent.py +176 -0
  102. gaia/database/mixin.py +290 -0
  103. gaia/database/testing.py +64 -0
  104. gaia/eval/batch_experiment.py +2 -2
  105. gaia/eval/claude.py +5 -5
  106. gaia/eval/config.py +1 -1
  107. gaia/eval/email_generator.py +1 -1
  108. gaia/eval/eval.py +1 -1
  109. gaia/eval/groundtruth.py +1 -1
  110. gaia/eval/transcript_generator.py +1 -1
  111. gaia/eval/webapp/public/app.js +1 -1
  112. gaia/eval/webapp/server.js +1 -1
  113. gaia/eval/webapp/test-setup.js +1 -1
  114. gaia/llm/__init__.py +1 -1
  115. gaia/llm/lemonade_client.py +149 -11
  116. gaia/llm/lemonade_manager.py +36 -11
  117. gaia/llm/llm_client.py +2 -2
  118. gaia/llm/vlm_client.py +93 -18
  119. gaia/logger.py +1 -1
  120. gaia/mcp/agent_mcp_server.py +1 -1
  121. gaia/mcp/blender_mcp_client.py +1 -1
  122. gaia/mcp/blender_mcp_server.py +1 -1
  123. gaia/mcp/context7_cache.py +1 -1
  124. gaia/mcp/servers/__init__.py +1 -1
  125. gaia/mcp/servers/docker_mcp.py +1 -1
  126. gaia/rag/demo.py +5 -5
  127. gaia/rag/pdf_utils.py +1 -1
  128. gaia/rag/sdk.py +2 -2
  129. gaia/security.py +1 -1
  130. gaia/talk/sdk.py +1 -1
  131. gaia/testing/__init__.py +87 -0
  132. gaia/testing/assertions.py +330 -0
  133. gaia/testing/fixtures.py +333 -0
  134. gaia/testing/mocks.py +493 -0
  135. gaia/util.py +1 -1
  136. gaia/utils/__init__.py +33 -0
  137. gaia/utils/file_watcher.py +675 -0
  138. gaia/utils/parsing.py +223 -0
  139. gaia/version.py +2 -2
  140. amd_gaia-0.14.1.dist-info/METADATA +0 -768
  141. amd_gaia-0.14.1.dist-info/RECORD +0 -800
  142. gaia/eval/webapp/node_modules/.bin/mime +0 -16
  143. gaia/eval/webapp/node_modules/.bin/mime.cmd +0 -17
  144. gaia/eval/webapp/node_modules/.bin/mime.ps1 +0 -28
  145. gaia/eval/webapp/node_modules/.package-lock.json +0 -865
  146. gaia/eval/webapp/node_modules/accepts/HISTORY.md +0 -243
  147. gaia/eval/webapp/node_modules/accepts/LICENSE +0 -23
  148. gaia/eval/webapp/node_modules/accepts/README.md +0 -140
  149. gaia/eval/webapp/node_modules/accepts/index.js +0 -238
  150. gaia/eval/webapp/node_modules/accepts/package.json +0 -47
  151. gaia/eval/webapp/node_modules/array-flatten/LICENSE +0 -21
  152. gaia/eval/webapp/node_modules/array-flatten/README.md +0 -43
  153. gaia/eval/webapp/node_modules/array-flatten/array-flatten.js +0 -64
  154. gaia/eval/webapp/node_modules/array-flatten/package.json +0 -39
  155. gaia/eval/webapp/node_modules/body-parser/HISTORY.md +0 -672
  156. gaia/eval/webapp/node_modules/body-parser/LICENSE +0 -23
  157. gaia/eval/webapp/node_modules/body-parser/README.md +0 -476
  158. gaia/eval/webapp/node_modules/body-parser/SECURITY.md +0 -25
  159. gaia/eval/webapp/node_modules/body-parser/index.js +0 -156
  160. gaia/eval/webapp/node_modules/body-parser/lib/read.js +0 -205
  161. gaia/eval/webapp/node_modules/body-parser/lib/types/json.js +0 -247
  162. gaia/eval/webapp/node_modules/body-parser/lib/types/raw.js +0 -101
  163. gaia/eval/webapp/node_modules/body-parser/lib/types/text.js +0 -121
  164. gaia/eval/webapp/node_modules/body-parser/lib/types/urlencoded.js +0 -307
  165. gaia/eval/webapp/node_modules/body-parser/package.json +0 -56
  166. gaia/eval/webapp/node_modules/bytes/History.md +0 -97
  167. gaia/eval/webapp/node_modules/bytes/LICENSE +0 -23
  168. gaia/eval/webapp/node_modules/bytes/Readme.md +0 -152
  169. gaia/eval/webapp/node_modules/bytes/index.js +0 -170
  170. gaia/eval/webapp/node_modules/bytes/package.json +0 -42
  171. gaia/eval/webapp/node_modules/call-bind-apply-helpers/.eslintrc +0 -17
  172. gaia/eval/webapp/node_modules/call-bind-apply-helpers/.github/FUNDING.yml +0 -12
  173. gaia/eval/webapp/node_modules/call-bind-apply-helpers/.nycrc +0 -9
  174. gaia/eval/webapp/node_modules/call-bind-apply-helpers/CHANGELOG.md +0 -30
  175. gaia/eval/webapp/node_modules/call-bind-apply-helpers/LICENSE +0 -21
  176. gaia/eval/webapp/node_modules/call-bind-apply-helpers/README.md +0 -62
  177. gaia/eval/webapp/node_modules/call-bind-apply-helpers/actualApply.d.ts +0 -1
  178. gaia/eval/webapp/node_modules/call-bind-apply-helpers/actualApply.js +0 -10
  179. gaia/eval/webapp/node_modules/call-bind-apply-helpers/applyBind.d.ts +0 -19
  180. gaia/eval/webapp/node_modules/call-bind-apply-helpers/applyBind.js +0 -10
  181. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionApply.d.ts +0 -1
  182. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionApply.js +0 -4
  183. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionCall.d.ts +0 -1
  184. gaia/eval/webapp/node_modules/call-bind-apply-helpers/functionCall.js +0 -4
  185. gaia/eval/webapp/node_modules/call-bind-apply-helpers/index.d.ts +0 -64
  186. gaia/eval/webapp/node_modules/call-bind-apply-helpers/index.js +0 -15
  187. gaia/eval/webapp/node_modules/call-bind-apply-helpers/package.json +0 -85
  188. gaia/eval/webapp/node_modules/call-bind-apply-helpers/reflectApply.d.ts +0 -3
  189. gaia/eval/webapp/node_modules/call-bind-apply-helpers/reflectApply.js +0 -4
  190. gaia/eval/webapp/node_modules/call-bind-apply-helpers/test/index.js +0 -63
  191. gaia/eval/webapp/node_modules/call-bind-apply-helpers/tsconfig.json +0 -9
  192. gaia/eval/webapp/node_modules/call-bound/.eslintrc +0 -13
  193. gaia/eval/webapp/node_modules/call-bound/.github/FUNDING.yml +0 -12
  194. gaia/eval/webapp/node_modules/call-bound/.nycrc +0 -9
  195. gaia/eval/webapp/node_modules/call-bound/CHANGELOG.md +0 -42
  196. gaia/eval/webapp/node_modules/call-bound/LICENSE +0 -21
  197. gaia/eval/webapp/node_modules/call-bound/README.md +0 -53
  198. gaia/eval/webapp/node_modules/call-bound/index.d.ts +0 -94
  199. gaia/eval/webapp/node_modules/call-bound/index.js +0 -19
  200. gaia/eval/webapp/node_modules/call-bound/package.json +0 -99
  201. gaia/eval/webapp/node_modules/call-bound/test/index.js +0 -61
  202. gaia/eval/webapp/node_modules/call-bound/tsconfig.json +0 -10
  203. gaia/eval/webapp/node_modules/content-disposition/HISTORY.md +0 -60
  204. gaia/eval/webapp/node_modules/content-disposition/LICENSE +0 -22
  205. gaia/eval/webapp/node_modules/content-disposition/README.md +0 -142
  206. gaia/eval/webapp/node_modules/content-disposition/index.js +0 -458
  207. gaia/eval/webapp/node_modules/content-disposition/package.json +0 -44
  208. gaia/eval/webapp/node_modules/content-type/HISTORY.md +0 -29
  209. gaia/eval/webapp/node_modules/content-type/LICENSE +0 -22
  210. gaia/eval/webapp/node_modules/content-type/README.md +0 -94
  211. gaia/eval/webapp/node_modules/content-type/index.js +0 -225
  212. gaia/eval/webapp/node_modules/content-type/package.json +0 -42
  213. gaia/eval/webapp/node_modules/cookie/LICENSE +0 -24
  214. gaia/eval/webapp/node_modules/cookie/README.md +0 -317
  215. gaia/eval/webapp/node_modules/cookie/SECURITY.md +0 -25
  216. gaia/eval/webapp/node_modules/cookie/index.js +0 -334
  217. gaia/eval/webapp/node_modules/cookie/package.json +0 -44
  218. gaia/eval/webapp/node_modules/cookie-signature/.npmignore +0 -4
  219. gaia/eval/webapp/node_modules/cookie-signature/History.md +0 -38
  220. gaia/eval/webapp/node_modules/cookie-signature/Readme.md +0 -42
  221. gaia/eval/webapp/node_modules/cookie-signature/index.js +0 -51
  222. gaia/eval/webapp/node_modules/cookie-signature/package.json +0 -18
  223. gaia/eval/webapp/node_modules/debug/.coveralls.yml +0 -1
  224. gaia/eval/webapp/node_modules/debug/.eslintrc +0 -11
  225. gaia/eval/webapp/node_modules/debug/.npmignore +0 -9
  226. gaia/eval/webapp/node_modules/debug/.travis.yml +0 -14
  227. gaia/eval/webapp/node_modules/debug/CHANGELOG.md +0 -362
  228. gaia/eval/webapp/node_modules/debug/LICENSE +0 -19
  229. gaia/eval/webapp/node_modules/debug/Makefile +0 -50
  230. gaia/eval/webapp/node_modules/debug/README.md +0 -312
  231. gaia/eval/webapp/node_modules/debug/component.json +0 -19
  232. gaia/eval/webapp/node_modules/debug/karma.conf.js +0 -70
  233. gaia/eval/webapp/node_modules/debug/node.js +0 -1
  234. gaia/eval/webapp/node_modules/debug/package.json +0 -49
  235. gaia/eval/webapp/node_modules/debug/src/browser.js +0 -185
  236. gaia/eval/webapp/node_modules/debug/src/debug.js +0 -202
  237. gaia/eval/webapp/node_modules/debug/src/index.js +0 -10
  238. gaia/eval/webapp/node_modules/debug/src/inspector-log.js +0 -15
  239. gaia/eval/webapp/node_modules/debug/src/node.js +0 -248
  240. gaia/eval/webapp/node_modules/depd/History.md +0 -103
  241. gaia/eval/webapp/node_modules/depd/LICENSE +0 -22
  242. gaia/eval/webapp/node_modules/depd/Readme.md +0 -280
  243. gaia/eval/webapp/node_modules/depd/index.js +0 -538
  244. gaia/eval/webapp/node_modules/depd/lib/browser/index.js +0 -77
  245. gaia/eval/webapp/node_modules/depd/package.json +0 -45
  246. gaia/eval/webapp/node_modules/destroy/LICENSE +0 -23
  247. gaia/eval/webapp/node_modules/destroy/README.md +0 -63
  248. gaia/eval/webapp/node_modules/destroy/index.js +0 -209
  249. gaia/eval/webapp/node_modules/destroy/package.json +0 -48
  250. gaia/eval/webapp/node_modules/dunder-proto/.eslintrc +0 -5
  251. gaia/eval/webapp/node_modules/dunder-proto/.github/FUNDING.yml +0 -12
  252. gaia/eval/webapp/node_modules/dunder-proto/.nycrc +0 -13
  253. gaia/eval/webapp/node_modules/dunder-proto/CHANGELOG.md +0 -24
  254. gaia/eval/webapp/node_modules/dunder-proto/LICENSE +0 -21
  255. gaia/eval/webapp/node_modules/dunder-proto/README.md +0 -54
  256. gaia/eval/webapp/node_modules/dunder-proto/get.d.ts +0 -5
  257. gaia/eval/webapp/node_modules/dunder-proto/get.js +0 -30
  258. gaia/eval/webapp/node_modules/dunder-proto/package.json +0 -76
  259. gaia/eval/webapp/node_modules/dunder-proto/set.d.ts +0 -5
  260. gaia/eval/webapp/node_modules/dunder-proto/set.js +0 -35
  261. gaia/eval/webapp/node_modules/dunder-proto/test/get.js +0 -34
  262. gaia/eval/webapp/node_modules/dunder-proto/test/index.js +0 -4
  263. gaia/eval/webapp/node_modules/dunder-proto/test/set.js +0 -50
  264. gaia/eval/webapp/node_modules/dunder-proto/tsconfig.json +0 -9
  265. gaia/eval/webapp/node_modules/ee-first/LICENSE +0 -22
  266. gaia/eval/webapp/node_modules/ee-first/README.md +0 -80
  267. gaia/eval/webapp/node_modules/ee-first/index.js +0 -95
  268. gaia/eval/webapp/node_modules/ee-first/package.json +0 -29
  269. gaia/eval/webapp/node_modules/encodeurl/LICENSE +0 -22
  270. gaia/eval/webapp/node_modules/encodeurl/README.md +0 -109
  271. gaia/eval/webapp/node_modules/encodeurl/index.js +0 -60
  272. gaia/eval/webapp/node_modules/encodeurl/package.json +0 -40
  273. gaia/eval/webapp/node_modules/es-define-property/.eslintrc +0 -13
  274. gaia/eval/webapp/node_modules/es-define-property/.github/FUNDING.yml +0 -12
  275. gaia/eval/webapp/node_modules/es-define-property/.nycrc +0 -9
  276. gaia/eval/webapp/node_modules/es-define-property/CHANGELOG.md +0 -29
  277. gaia/eval/webapp/node_modules/es-define-property/LICENSE +0 -21
  278. gaia/eval/webapp/node_modules/es-define-property/README.md +0 -49
  279. gaia/eval/webapp/node_modules/es-define-property/index.d.ts +0 -3
  280. gaia/eval/webapp/node_modules/es-define-property/index.js +0 -14
  281. gaia/eval/webapp/node_modules/es-define-property/package.json +0 -81
  282. gaia/eval/webapp/node_modules/es-define-property/test/index.js +0 -56
  283. gaia/eval/webapp/node_modules/es-define-property/tsconfig.json +0 -10
  284. gaia/eval/webapp/node_modules/es-errors/.eslintrc +0 -5
  285. gaia/eval/webapp/node_modules/es-errors/.github/FUNDING.yml +0 -12
  286. gaia/eval/webapp/node_modules/es-errors/CHANGELOG.md +0 -40
  287. gaia/eval/webapp/node_modules/es-errors/LICENSE +0 -21
  288. gaia/eval/webapp/node_modules/es-errors/README.md +0 -55
  289. gaia/eval/webapp/node_modules/es-errors/eval.d.ts +0 -3
  290. gaia/eval/webapp/node_modules/es-errors/eval.js +0 -4
  291. gaia/eval/webapp/node_modules/es-errors/index.d.ts +0 -3
  292. gaia/eval/webapp/node_modules/es-errors/index.js +0 -4
  293. gaia/eval/webapp/node_modules/es-errors/package.json +0 -80
  294. gaia/eval/webapp/node_modules/es-errors/range.d.ts +0 -3
  295. gaia/eval/webapp/node_modules/es-errors/range.js +0 -4
  296. gaia/eval/webapp/node_modules/es-errors/ref.d.ts +0 -3
  297. gaia/eval/webapp/node_modules/es-errors/ref.js +0 -4
  298. gaia/eval/webapp/node_modules/es-errors/syntax.d.ts +0 -3
  299. gaia/eval/webapp/node_modules/es-errors/syntax.js +0 -4
  300. gaia/eval/webapp/node_modules/es-errors/test/index.js +0 -19
  301. gaia/eval/webapp/node_modules/es-errors/tsconfig.json +0 -49
  302. gaia/eval/webapp/node_modules/es-errors/type.d.ts +0 -3
  303. gaia/eval/webapp/node_modules/es-errors/type.js +0 -4
  304. gaia/eval/webapp/node_modules/es-errors/uri.d.ts +0 -3
  305. gaia/eval/webapp/node_modules/es-errors/uri.js +0 -4
  306. gaia/eval/webapp/node_modules/es-object-atoms/.eslintrc +0 -16
  307. gaia/eval/webapp/node_modules/es-object-atoms/.github/FUNDING.yml +0 -12
  308. gaia/eval/webapp/node_modules/es-object-atoms/CHANGELOG.md +0 -37
  309. gaia/eval/webapp/node_modules/es-object-atoms/LICENSE +0 -21
  310. gaia/eval/webapp/node_modules/es-object-atoms/README.md +0 -63
  311. gaia/eval/webapp/node_modules/es-object-atoms/RequireObjectCoercible.d.ts +0 -3
  312. gaia/eval/webapp/node_modules/es-object-atoms/RequireObjectCoercible.js +0 -11
  313. gaia/eval/webapp/node_modules/es-object-atoms/ToObject.d.ts +0 -7
  314. gaia/eval/webapp/node_modules/es-object-atoms/ToObject.js +0 -10
  315. gaia/eval/webapp/node_modules/es-object-atoms/index.d.ts +0 -3
  316. gaia/eval/webapp/node_modules/es-object-atoms/index.js +0 -4
  317. gaia/eval/webapp/node_modules/es-object-atoms/isObject.d.ts +0 -3
  318. gaia/eval/webapp/node_modules/es-object-atoms/isObject.js +0 -6
  319. gaia/eval/webapp/node_modules/es-object-atoms/package.json +0 -80
  320. gaia/eval/webapp/node_modules/es-object-atoms/test/index.js +0 -38
  321. gaia/eval/webapp/node_modules/es-object-atoms/tsconfig.json +0 -6
  322. gaia/eval/webapp/node_modules/escape-html/LICENSE +0 -24
  323. gaia/eval/webapp/node_modules/escape-html/Readme.md +0 -43
  324. gaia/eval/webapp/node_modules/escape-html/index.js +0 -78
  325. gaia/eval/webapp/node_modules/escape-html/package.json +0 -24
  326. gaia/eval/webapp/node_modules/etag/HISTORY.md +0 -83
  327. gaia/eval/webapp/node_modules/etag/LICENSE +0 -22
  328. gaia/eval/webapp/node_modules/etag/README.md +0 -159
  329. gaia/eval/webapp/node_modules/etag/index.js +0 -131
  330. gaia/eval/webapp/node_modules/etag/package.json +0 -47
  331. gaia/eval/webapp/node_modules/express/History.md +0 -3656
  332. gaia/eval/webapp/node_modules/express/LICENSE +0 -24
  333. gaia/eval/webapp/node_modules/express/Readme.md +0 -260
  334. gaia/eval/webapp/node_modules/express/index.js +0 -11
  335. gaia/eval/webapp/node_modules/express/lib/application.js +0 -661
  336. gaia/eval/webapp/node_modules/express/lib/express.js +0 -116
  337. gaia/eval/webapp/node_modules/express/lib/middleware/init.js +0 -43
  338. gaia/eval/webapp/node_modules/express/lib/middleware/query.js +0 -47
  339. gaia/eval/webapp/node_modules/express/lib/request.js +0 -525
  340. gaia/eval/webapp/node_modules/express/lib/response.js +0 -1179
  341. gaia/eval/webapp/node_modules/express/lib/router/index.js +0 -673
  342. gaia/eval/webapp/node_modules/express/lib/router/layer.js +0 -181
  343. gaia/eval/webapp/node_modules/express/lib/router/route.js +0 -230
  344. gaia/eval/webapp/node_modules/express/lib/utils.js +0 -303
  345. gaia/eval/webapp/node_modules/express/lib/view.js +0 -182
  346. gaia/eval/webapp/node_modules/express/package.json +0 -102
  347. gaia/eval/webapp/node_modules/finalhandler/HISTORY.md +0 -210
  348. gaia/eval/webapp/node_modules/finalhandler/LICENSE +0 -22
  349. gaia/eval/webapp/node_modules/finalhandler/README.md +0 -147
  350. gaia/eval/webapp/node_modules/finalhandler/SECURITY.md +0 -25
  351. gaia/eval/webapp/node_modules/finalhandler/index.js +0 -341
  352. gaia/eval/webapp/node_modules/finalhandler/package.json +0 -47
  353. gaia/eval/webapp/node_modules/forwarded/HISTORY.md +0 -21
  354. gaia/eval/webapp/node_modules/forwarded/LICENSE +0 -22
  355. gaia/eval/webapp/node_modules/forwarded/README.md +0 -57
  356. gaia/eval/webapp/node_modules/forwarded/index.js +0 -90
  357. gaia/eval/webapp/node_modules/forwarded/package.json +0 -45
  358. gaia/eval/webapp/node_modules/fresh/HISTORY.md +0 -70
  359. gaia/eval/webapp/node_modules/fresh/LICENSE +0 -23
  360. gaia/eval/webapp/node_modules/fresh/README.md +0 -119
  361. gaia/eval/webapp/node_modules/fresh/index.js +0 -137
  362. gaia/eval/webapp/node_modules/fresh/package.json +0 -46
  363. gaia/eval/webapp/node_modules/fs/README.md +0 -9
  364. gaia/eval/webapp/node_modules/fs/package.json +0 -20
  365. gaia/eval/webapp/node_modules/function-bind/.eslintrc +0 -21
  366. gaia/eval/webapp/node_modules/function-bind/.github/FUNDING.yml +0 -12
  367. gaia/eval/webapp/node_modules/function-bind/.github/SECURITY.md +0 -3
  368. gaia/eval/webapp/node_modules/function-bind/.nycrc +0 -13
  369. gaia/eval/webapp/node_modules/function-bind/CHANGELOG.md +0 -136
  370. gaia/eval/webapp/node_modules/function-bind/LICENSE +0 -20
  371. gaia/eval/webapp/node_modules/function-bind/README.md +0 -46
  372. gaia/eval/webapp/node_modules/function-bind/implementation.js +0 -84
  373. gaia/eval/webapp/node_modules/function-bind/index.js +0 -5
  374. gaia/eval/webapp/node_modules/function-bind/package.json +0 -87
  375. gaia/eval/webapp/node_modules/function-bind/test/.eslintrc +0 -9
  376. gaia/eval/webapp/node_modules/function-bind/test/index.js +0 -252
  377. gaia/eval/webapp/node_modules/get-intrinsic/.eslintrc +0 -42
  378. gaia/eval/webapp/node_modules/get-intrinsic/.github/FUNDING.yml +0 -12
  379. gaia/eval/webapp/node_modules/get-intrinsic/.nycrc +0 -9
  380. gaia/eval/webapp/node_modules/get-intrinsic/CHANGELOG.md +0 -186
  381. gaia/eval/webapp/node_modules/get-intrinsic/LICENSE +0 -21
  382. gaia/eval/webapp/node_modules/get-intrinsic/README.md +0 -71
  383. gaia/eval/webapp/node_modules/get-intrinsic/index.js +0 -378
  384. gaia/eval/webapp/node_modules/get-intrinsic/package.json +0 -97
  385. gaia/eval/webapp/node_modules/get-intrinsic/test/GetIntrinsic.js +0 -274
  386. gaia/eval/webapp/node_modules/get-proto/.eslintrc +0 -10
  387. gaia/eval/webapp/node_modules/get-proto/.github/FUNDING.yml +0 -12
  388. gaia/eval/webapp/node_modules/get-proto/.nycrc +0 -9
  389. gaia/eval/webapp/node_modules/get-proto/CHANGELOG.md +0 -21
  390. gaia/eval/webapp/node_modules/get-proto/LICENSE +0 -21
  391. gaia/eval/webapp/node_modules/get-proto/Object.getPrototypeOf.d.ts +0 -5
  392. gaia/eval/webapp/node_modules/get-proto/Object.getPrototypeOf.js +0 -6
  393. gaia/eval/webapp/node_modules/get-proto/README.md +0 -50
  394. gaia/eval/webapp/node_modules/get-proto/Reflect.getPrototypeOf.d.ts +0 -3
  395. gaia/eval/webapp/node_modules/get-proto/Reflect.getPrototypeOf.js +0 -4
  396. gaia/eval/webapp/node_modules/get-proto/index.d.ts +0 -5
  397. gaia/eval/webapp/node_modules/get-proto/index.js +0 -27
  398. gaia/eval/webapp/node_modules/get-proto/package.json +0 -81
  399. gaia/eval/webapp/node_modules/get-proto/test/index.js +0 -68
  400. gaia/eval/webapp/node_modules/get-proto/tsconfig.json +0 -9
  401. gaia/eval/webapp/node_modules/gopd/.eslintrc +0 -16
  402. gaia/eval/webapp/node_modules/gopd/.github/FUNDING.yml +0 -12
  403. gaia/eval/webapp/node_modules/gopd/CHANGELOG.md +0 -45
  404. gaia/eval/webapp/node_modules/gopd/LICENSE +0 -21
  405. gaia/eval/webapp/node_modules/gopd/README.md +0 -40
  406. gaia/eval/webapp/node_modules/gopd/gOPD.d.ts +0 -1
  407. gaia/eval/webapp/node_modules/gopd/gOPD.js +0 -4
  408. gaia/eval/webapp/node_modules/gopd/index.d.ts +0 -5
  409. gaia/eval/webapp/node_modules/gopd/index.js +0 -15
  410. gaia/eval/webapp/node_modules/gopd/package.json +0 -77
  411. gaia/eval/webapp/node_modules/gopd/test/index.js +0 -36
  412. gaia/eval/webapp/node_modules/gopd/tsconfig.json +0 -9
  413. gaia/eval/webapp/node_modules/has-symbols/.eslintrc +0 -11
  414. gaia/eval/webapp/node_modules/has-symbols/.github/FUNDING.yml +0 -12
  415. gaia/eval/webapp/node_modules/has-symbols/.nycrc +0 -9
  416. gaia/eval/webapp/node_modules/has-symbols/CHANGELOG.md +0 -91
  417. gaia/eval/webapp/node_modules/has-symbols/LICENSE +0 -21
  418. gaia/eval/webapp/node_modules/has-symbols/README.md +0 -46
  419. gaia/eval/webapp/node_modules/has-symbols/index.d.ts +0 -3
  420. gaia/eval/webapp/node_modules/has-symbols/index.js +0 -14
  421. gaia/eval/webapp/node_modules/has-symbols/package.json +0 -111
  422. gaia/eval/webapp/node_modules/has-symbols/shams.d.ts +0 -3
  423. gaia/eval/webapp/node_modules/has-symbols/shams.js +0 -45
  424. gaia/eval/webapp/node_modules/has-symbols/test/index.js +0 -22
  425. gaia/eval/webapp/node_modules/has-symbols/test/shams/core-js.js +0 -29
  426. gaia/eval/webapp/node_modules/has-symbols/test/shams/get-own-property-symbols.js +0 -29
  427. gaia/eval/webapp/node_modules/has-symbols/test/tests.js +0 -58
  428. gaia/eval/webapp/node_modules/has-symbols/tsconfig.json +0 -10
  429. gaia/eval/webapp/node_modules/hasown/.eslintrc +0 -5
  430. gaia/eval/webapp/node_modules/hasown/.github/FUNDING.yml +0 -12
  431. gaia/eval/webapp/node_modules/hasown/.nycrc +0 -13
  432. gaia/eval/webapp/node_modules/hasown/CHANGELOG.md +0 -40
  433. gaia/eval/webapp/node_modules/hasown/LICENSE +0 -21
  434. gaia/eval/webapp/node_modules/hasown/README.md +0 -40
  435. gaia/eval/webapp/node_modules/hasown/index.d.ts +0 -3
  436. gaia/eval/webapp/node_modules/hasown/index.js +0 -8
  437. gaia/eval/webapp/node_modules/hasown/package.json +0 -92
  438. gaia/eval/webapp/node_modules/hasown/tsconfig.json +0 -6
  439. gaia/eval/webapp/node_modules/http-errors/HISTORY.md +0 -180
  440. gaia/eval/webapp/node_modules/http-errors/LICENSE +0 -23
  441. gaia/eval/webapp/node_modules/http-errors/README.md +0 -169
  442. gaia/eval/webapp/node_modules/http-errors/index.js +0 -289
  443. gaia/eval/webapp/node_modules/http-errors/package.json +0 -50
  444. gaia/eval/webapp/node_modules/iconv-lite/Changelog.md +0 -162
  445. gaia/eval/webapp/node_modules/iconv-lite/LICENSE +0 -21
  446. gaia/eval/webapp/node_modules/iconv-lite/README.md +0 -156
  447. gaia/eval/webapp/node_modules/iconv-lite/encodings/dbcs-codec.js +0 -555
  448. gaia/eval/webapp/node_modules/iconv-lite/encodings/dbcs-data.js +0 -176
  449. gaia/eval/webapp/node_modules/iconv-lite/encodings/index.js +0 -22
  450. gaia/eval/webapp/node_modules/iconv-lite/encodings/internal.js +0 -188
  451. gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-codec.js +0 -72
  452. gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-data-generated.js +0 -451
  453. gaia/eval/webapp/node_modules/iconv-lite/encodings/sbcs-data.js +0 -174
  454. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/big5-added.json +0 -122
  455. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp936.json +0 -264
  456. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp949.json +0 -273
  457. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/cp950.json +0 -177
  458. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/eucjp.json +0 -182
  459. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/gb18030-ranges.json +0 -1
  460. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/gbk-added.json +0 -55
  461. gaia/eval/webapp/node_modules/iconv-lite/encodings/tables/shiftjis.json +0 -125
  462. gaia/eval/webapp/node_modules/iconv-lite/encodings/utf16.js +0 -177
  463. gaia/eval/webapp/node_modules/iconv-lite/encodings/utf7.js +0 -290
  464. gaia/eval/webapp/node_modules/iconv-lite/lib/bom-handling.js +0 -52
  465. gaia/eval/webapp/node_modules/iconv-lite/lib/extend-node.js +0 -217
  466. gaia/eval/webapp/node_modules/iconv-lite/lib/index.d.ts +0 -24
  467. gaia/eval/webapp/node_modules/iconv-lite/lib/index.js +0 -153
  468. gaia/eval/webapp/node_modules/iconv-lite/lib/streams.js +0 -121
  469. gaia/eval/webapp/node_modules/iconv-lite/package.json +0 -46
  470. gaia/eval/webapp/node_modules/inherits/LICENSE +0 -16
  471. gaia/eval/webapp/node_modules/inherits/README.md +0 -42
  472. gaia/eval/webapp/node_modules/inherits/inherits.js +0 -9
  473. gaia/eval/webapp/node_modules/inherits/inherits_browser.js +0 -27
  474. gaia/eval/webapp/node_modules/inherits/package.json +0 -29
  475. gaia/eval/webapp/node_modules/ipaddr.js/LICENSE +0 -19
  476. gaia/eval/webapp/node_modules/ipaddr.js/README.md +0 -233
  477. gaia/eval/webapp/node_modules/ipaddr.js/ipaddr.min.js +0 -1
  478. gaia/eval/webapp/node_modules/ipaddr.js/lib/ipaddr.js +0 -673
  479. gaia/eval/webapp/node_modules/ipaddr.js/lib/ipaddr.js.d.ts +0 -68
  480. gaia/eval/webapp/node_modules/ipaddr.js/package.json +0 -35
  481. gaia/eval/webapp/node_modules/math-intrinsics/.eslintrc +0 -16
  482. gaia/eval/webapp/node_modules/math-intrinsics/.github/FUNDING.yml +0 -12
  483. gaia/eval/webapp/node_modules/math-intrinsics/CHANGELOG.md +0 -24
  484. gaia/eval/webapp/node_modules/math-intrinsics/LICENSE +0 -21
  485. gaia/eval/webapp/node_modules/math-intrinsics/README.md +0 -50
  486. gaia/eval/webapp/node_modules/math-intrinsics/abs.d.ts +0 -1
  487. gaia/eval/webapp/node_modules/math-intrinsics/abs.js +0 -4
  488. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxArrayLength.d.ts +0 -3
  489. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxArrayLength.js +0 -4
  490. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxSafeInteger.d.ts +0 -3
  491. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxSafeInteger.js +0 -5
  492. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxValue.d.ts +0 -3
  493. gaia/eval/webapp/node_modules/math-intrinsics/constants/maxValue.js +0 -5
  494. gaia/eval/webapp/node_modules/math-intrinsics/floor.d.ts +0 -1
  495. gaia/eval/webapp/node_modules/math-intrinsics/floor.js +0 -4
  496. gaia/eval/webapp/node_modules/math-intrinsics/isFinite.d.ts +0 -3
  497. gaia/eval/webapp/node_modules/math-intrinsics/isFinite.js +0 -12
  498. gaia/eval/webapp/node_modules/math-intrinsics/isInteger.d.ts +0 -3
  499. gaia/eval/webapp/node_modules/math-intrinsics/isInteger.js +0 -16
  500. gaia/eval/webapp/node_modules/math-intrinsics/isNaN.d.ts +0 -1
  501. gaia/eval/webapp/node_modules/math-intrinsics/isNaN.js +0 -6
  502. gaia/eval/webapp/node_modules/math-intrinsics/isNegativeZero.d.ts +0 -3
  503. gaia/eval/webapp/node_modules/math-intrinsics/isNegativeZero.js +0 -6
  504. gaia/eval/webapp/node_modules/math-intrinsics/max.d.ts +0 -1
  505. gaia/eval/webapp/node_modules/math-intrinsics/max.js +0 -4
  506. gaia/eval/webapp/node_modules/math-intrinsics/min.d.ts +0 -1
  507. gaia/eval/webapp/node_modules/math-intrinsics/min.js +0 -4
  508. gaia/eval/webapp/node_modules/math-intrinsics/mod.d.ts +0 -3
  509. gaia/eval/webapp/node_modules/math-intrinsics/mod.js +0 -9
  510. gaia/eval/webapp/node_modules/math-intrinsics/package.json +0 -86
  511. gaia/eval/webapp/node_modules/math-intrinsics/pow.d.ts +0 -1
  512. gaia/eval/webapp/node_modules/math-intrinsics/pow.js +0 -4
  513. gaia/eval/webapp/node_modules/math-intrinsics/round.d.ts +0 -1
  514. gaia/eval/webapp/node_modules/math-intrinsics/round.js +0 -4
  515. gaia/eval/webapp/node_modules/math-intrinsics/sign.d.ts +0 -3
  516. gaia/eval/webapp/node_modules/math-intrinsics/sign.js +0 -11
  517. gaia/eval/webapp/node_modules/math-intrinsics/test/index.js +0 -192
  518. gaia/eval/webapp/node_modules/math-intrinsics/tsconfig.json +0 -3
  519. gaia/eval/webapp/node_modules/media-typer/HISTORY.md +0 -22
  520. gaia/eval/webapp/node_modules/media-typer/LICENSE +0 -22
  521. gaia/eval/webapp/node_modules/media-typer/README.md +0 -81
  522. gaia/eval/webapp/node_modules/media-typer/index.js +0 -270
  523. gaia/eval/webapp/node_modules/media-typer/package.json +0 -26
  524. gaia/eval/webapp/node_modules/merge-descriptors/HISTORY.md +0 -21
  525. gaia/eval/webapp/node_modules/merge-descriptors/LICENSE +0 -23
  526. gaia/eval/webapp/node_modules/merge-descriptors/README.md +0 -49
  527. gaia/eval/webapp/node_modules/merge-descriptors/index.js +0 -60
  528. gaia/eval/webapp/node_modules/merge-descriptors/package.json +0 -39
  529. gaia/eval/webapp/node_modules/methods/HISTORY.md +0 -29
  530. gaia/eval/webapp/node_modules/methods/LICENSE +0 -24
  531. gaia/eval/webapp/node_modules/methods/README.md +0 -51
  532. gaia/eval/webapp/node_modules/methods/index.js +0 -69
  533. gaia/eval/webapp/node_modules/methods/package.json +0 -36
  534. gaia/eval/webapp/node_modules/mime/.npmignore +0 -0
  535. gaia/eval/webapp/node_modules/mime/CHANGELOG.md +0 -164
  536. gaia/eval/webapp/node_modules/mime/LICENSE +0 -21
  537. gaia/eval/webapp/node_modules/mime/README.md +0 -90
  538. gaia/eval/webapp/node_modules/mime/cli.js +0 -8
  539. gaia/eval/webapp/node_modules/mime/mime.js +0 -108
  540. gaia/eval/webapp/node_modules/mime/package.json +0 -44
  541. gaia/eval/webapp/node_modules/mime/src/build.js +0 -53
  542. gaia/eval/webapp/node_modules/mime/src/test.js +0 -60
  543. gaia/eval/webapp/node_modules/mime/types.json +0 -1
  544. gaia/eval/webapp/node_modules/mime-db/HISTORY.md +0 -507
  545. gaia/eval/webapp/node_modules/mime-db/LICENSE +0 -23
  546. gaia/eval/webapp/node_modules/mime-db/README.md +0 -100
  547. gaia/eval/webapp/node_modules/mime-db/db.json +0 -8519
  548. gaia/eval/webapp/node_modules/mime-db/index.js +0 -12
  549. gaia/eval/webapp/node_modules/mime-db/package.json +0 -60
  550. gaia/eval/webapp/node_modules/mime-types/HISTORY.md +0 -397
  551. gaia/eval/webapp/node_modules/mime-types/LICENSE +0 -23
  552. gaia/eval/webapp/node_modules/mime-types/README.md +0 -113
  553. gaia/eval/webapp/node_modules/mime-types/index.js +0 -188
  554. gaia/eval/webapp/node_modules/mime-types/package.json +0 -44
  555. gaia/eval/webapp/node_modules/ms/index.js +0 -152
  556. gaia/eval/webapp/node_modules/ms/license.md +0 -21
  557. gaia/eval/webapp/node_modules/ms/package.json +0 -37
  558. gaia/eval/webapp/node_modules/ms/readme.md +0 -51
  559. gaia/eval/webapp/node_modules/negotiator/HISTORY.md +0 -108
  560. gaia/eval/webapp/node_modules/negotiator/LICENSE +0 -24
  561. gaia/eval/webapp/node_modules/negotiator/README.md +0 -203
  562. gaia/eval/webapp/node_modules/negotiator/index.js +0 -82
  563. gaia/eval/webapp/node_modules/negotiator/lib/charset.js +0 -169
  564. gaia/eval/webapp/node_modules/negotiator/lib/encoding.js +0 -184
  565. gaia/eval/webapp/node_modules/negotiator/lib/language.js +0 -179
  566. gaia/eval/webapp/node_modules/negotiator/lib/mediaType.js +0 -294
  567. gaia/eval/webapp/node_modules/negotiator/package.json +0 -42
  568. gaia/eval/webapp/node_modules/object-inspect/.eslintrc +0 -53
  569. gaia/eval/webapp/node_modules/object-inspect/.github/FUNDING.yml +0 -12
  570. gaia/eval/webapp/node_modules/object-inspect/.nycrc +0 -13
  571. gaia/eval/webapp/node_modules/object-inspect/CHANGELOG.md +0 -424
  572. gaia/eval/webapp/node_modules/object-inspect/LICENSE +0 -21
  573. gaia/eval/webapp/node_modules/object-inspect/example/all.js +0 -23
  574. gaia/eval/webapp/node_modules/object-inspect/example/circular.js +0 -6
  575. gaia/eval/webapp/node_modules/object-inspect/example/fn.js +0 -5
  576. gaia/eval/webapp/node_modules/object-inspect/example/inspect.js +0 -10
  577. gaia/eval/webapp/node_modules/object-inspect/index.js +0 -544
  578. gaia/eval/webapp/node_modules/object-inspect/package-support.json +0 -20
  579. gaia/eval/webapp/node_modules/object-inspect/package.json +0 -105
  580. gaia/eval/webapp/node_modules/object-inspect/readme.markdown +0 -84
  581. gaia/eval/webapp/node_modules/object-inspect/test/bigint.js +0 -58
  582. gaia/eval/webapp/node_modules/object-inspect/test/browser/dom.js +0 -15
  583. gaia/eval/webapp/node_modules/object-inspect/test/circular.js +0 -16
  584. gaia/eval/webapp/node_modules/object-inspect/test/deep.js +0 -12
  585. gaia/eval/webapp/node_modules/object-inspect/test/element.js +0 -53
  586. gaia/eval/webapp/node_modules/object-inspect/test/err.js +0 -48
  587. gaia/eval/webapp/node_modules/object-inspect/test/fakes.js +0 -29
  588. gaia/eval/webapp/node_modules/object-inspect/test/fn.js +0 -76
  589. gaia/eval/webapp/node_modules/object-inspect/test/global.js +0 -17
  590. gaia/eval/webapp/node_modules/object-inspect/test/has.js +0 -15
  591. gaia/eval/webapp/node_modules/object-inspect/test/holes.js +0 -15
  592. gaia/eval/webapp/node_modules/object-inspect/test/indent-option.js +0 -271
  593. gaia/eval/webapp/node_modules/object-inspect/test/inspect.js +0 -139
  594. gaia/eval/webapp/node_modules/object-inspect/test/lowbyte.js +0 -12
  595. gaia/eval/webapp/node_modules/object-inspect/test/number.js +0 -58
  596. gaia/eval/webapp/node_modules/object-inspect/test/quoteStyle.js +0 -26
  597. gaia/eval/webapp/node_modules/object-inspect/test/toStringTag.js +0 -40
  598. gaia/eval/webapp/node_modules/object-inspect/test/undef.js +0 -12
  599. gaia/eval/webapp/node_modules/object-inspect/test/values.js +0 -261
  600. gaia/eval/webapp/node_modules/object-inspect/test-core-js.js +0 -26
  601. gaia/eval/webapp/node_modules/object-inspect/util.inspect.js +0 -1
  602. gaia/eval/webapp/node_modules/on-finished/HISTORY.md +0 -98
  603. gaia/eval/webapp/node_modules/on-finished/LICENSE +0 -23
  604. gaia/eval/webapp/node_modules/on-finished/README.md +0 -162
  605. gaia/eval/webapp/node_modules/on-finished/index.js +0 -234
  606. gaia/eval/webapp/node_modules/on-finished/package.json +0 -39
  607. gaia/eval/webapp/node_modules/parseurl/HISTORY.md +0 -58
  608. gaia/eval/webapp/node_modules/parseurl/LICENSE +0 -24
  609. gaia/eval/webapp/node_modules/parseurl/README.md +0 -133
  610. gaia/eval/webapp/node_modules/parseurl/index.js +0 -158
  611. gaia/eval/webapp/node_modules/parseurl/package.json +0 -40
  612. gaia/eval/webapp/node_modules/path/.npmignore +0 -1
  613. gaia/eval/webapp/node_modules/path/LICENSE +0 -18
  614. gaia/eval/webapp/node_modules/path/README.md +0 -15
  615. gaia/eval/webapp/node_modules/path/package.json +0 -24
  616. gaia/eval/webapp/node_modules/path/path.js +0 -628
  617. gaia/eval/webapp/node_modules/path-to-regexp/LICENSE +0 -21
  618. gaia/eval/webapp/node_modules/path-to-regexp/Readme.md +0 -35
  619. gaia/eval/webapp/node_modules/path-to-regexp/index.js +0 -156
  620. gaia/eval/webapp/node_modules/path-to-regexp/package.json +0 -30
  621. gaia/eval/webapp/node_modules/process/.eslintrc +0 -21
  622. gaia/eval/webapp/node_modules/process/LICENSE +0 -22
  623. gaia/eval/webapp/node_modules/process/README.md +0 -26
  624. gaia/eval/webapp/node_modules/process/browser.js +0 -184
  625. gaia/eval/webapp/node_modules/process/index.js +0 -2
  626. gaia/eval/webapp/node_modules/process/package.json +0 -27
  627. gaia/eval/webapp/node_modules/process/test.js +0 -199
  628. gaia/eval/webapp/node_modules/proxy-addr/HISTORY.md +0 -161
  629. gaia/eval/webapp/node_modules/proxy-addr/LICENSE +0 -22
  630. gaia/eval/webapp/node_modules/proxy-addr/README.md +0 -139
  631. gaia/eval/webapp/node_modules/proxy-addr/index.js +0 -327
  632. gaia/eval/webapp/node_modules/proxy-addr/package.json +0 -47
  633. gaia/eval/webapp/node_modules/qs/.editorconfig +0 -46
  634. gaia/eval/webapp/node_modules/qs/.eslintrc +0 -38
  635. gaia/eval/webapp/node_modules/qs/.github/FUNDING.yml +0 -12
  636. gaia/eval/webapp/node_modules/qs/.nycrc +0 -13
  637. gaia/eval/webapp/node_modules/qs/CHANGELOG.md +0 -600
  638. gaia/eval/webapp/node_modules/qs/LICENSE.md +0 -29
  639. gaia/eval/webapp/node_modules/qs/README.md +0 -709
  640. gaia/eval/webapp/node_modules/qs/dist/qs.js +0 -90
  641. gaia/eval/webapp/node_modules/qs/lib/formats.js +0 -23
  642. gaia/eval/webapp/node_modules/qs/lib/index.js +0 -11
  643. gaia/eval/webapp/node_modules/qs/lib/parse.js +0 -296
  644. gaia/eval/webapp/node_modules/qs/lib/stringify.js +0 -351
  645. gaia/eval/webapp/node_modules/qs/lib/utils.js +0 -265
  646. gaia/eval/webapp/node_modules/qs/package.json +0 -91
  647. gaia/eval/webapp/node_modules/qs/test/empty-keys-cases.js +0 -267
  648. gaia/eval/webapp/node_modules/qs/test/parse.js +0 -1170
  649. gaia/eval/webapp/node_modules/qs/test/stringify.js +0 -1298
  650. gaia/eval/webapp/node_modules/qs/test/utils.js +0 -136
  651. gaia/eval/webapp/node_modules/range-parser/HISTORY.md +0 -56
  652. gaia/eval/webapp/node_modules/range-parser/LICENSE +0 -23
  653. gaia/eval/webapp/node_modules/range-parser/README.md +0 -84
  654. gaia/eval/webapp/node_modules/range-parser/index.js +0 -162
  655. gaia/eval/webapp/node_modules/range-parser/package.json +0 -44
  656. gaia/eval/webapp/node_modules/raw-body/HISTORY.md +0 -308
  657. gaia/eval/webapp/node_modules/raw-body/LICENSE +0 -22
  658. gaia/eval/webapp/node_modules/raw-body/README.md +0 -223
  659. gaia/eval/webapp/node_modules/raw-body/SECURITY.md +0 -24
  660. gaia/eval/webapp/node_modules/raw-body/index.d.ts +0 -87
  661. gaia/eval/webapp/node_modules/raw-body/index.js +0 -336
  662. gaia/eval/webapp/node_modules/raw-body/package.json +0 -49
  663. gaia/eval/webapp/node_modules/safe-buffer/LICENSE +0 -21
  664. gaia/eval/webapp/node_modules/safe-buffer/README.md +0 -584
  665. gaia/eval/webapp/node_modules/safe-buffer/index.d.ts +0 -187
  666. gaia/eval/webapp/node_modules/safe-buffer/index.js +0 -65
  667. gaia/eval/webapp/node_modules/safe-buffer/package.json +0 -51
  668. gaia/eval/webapp/node_modules/safer-buffer/LICENSE +0 -21
  669. gaia/eval/webapp/node_modules/safer-buffer/Porting-Buffer.md +0 -268
  670. gaia/eval/webapp/node_modules/safer-buffer/Readme.md +0 -156
  671. gaia/eval/webapp/node_modules/safer-buffer/dangerous.js +0 -58
  672. gaia/eval/webapp/node_modules/safer-buffer/package.json +0 -34
  673. gaia/eval/webapp/node_modules/safer-buffer/safer.js +0 -77
  674. gaia/eval/webapp/node_modules/safer-buffer/tests.js +0 -406
  675. gaia/eval/webapp/node_modules/send/HISTORY.md +0 -526
  676. gaia/eval/webapp/node_modules/send/LICENSE +0 -23
  677. gaia/eval/webapp/node_modules/send/README.md +0 -327
  678. gaia/eval/webapp/node_modules/send/SECURITY.md +0 -24
  679. gaia/eval/webapp/node_modules/send/index.js +0 -1142
  680. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/HISTORY.md +0 -14
  681. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/LICENSE +0 -22
  682. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/README.md +0 -128
  683. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/index.js +0 -60
  684. gaia/eval/webapp/node_modules/send/node_modules/encodeurl/package.json +0 -40
  685. gaia/eval/webapp/node_modules/send/node_modules/ms/index.js +0 -162
  686. gaia/eval/webapp/node_modules/send/node_modules/ms/license.md +0 -21
  687. gaia/eval/webapp/node_modules/send/node_modules/ms/package.json +0 -38
  688. gaia/eval/webapp/node_modules/send/node_modules/ms/readme.md +0 -59
  689. gaia/eval/webapp/node_modules/send/package.json +0 -62
  690. gaia/eval/webapp/node_modules/serve-static/HISTORY.md +0 -487
  691. gaia/eval/webapp/node_modules/serve-static/LICENSE +0 -25
  692. gaia/eval/webapp/node_modules/serve-static/README.md +0 -257
  693. gaia/eval/webapp/node_modules/serve-static/index.js +0 -209
  694. gaia/eval/webapp/node_modules/serve-static/package.json +0 -42
  695. gaia/eval/webapp/node_modules/setprototypeof/LICENSE +0 -13
  696. gaia/eval/webapp/node_modules/setprototypeof/README.md +0 -31
  697. gaia/eval/webapp/node_modules/setprototypeof/index.d.ts +0 -2
  698. gaia/eval/webapp/node_modules/setprototypeof/index.js +0 -17
  699. gaia/eval/webapp/node_modules/setprototypeof/package.json +0 -38
  700. gaia/eval/webapp/node_modules/setprototypeof/test/index.js +0 -24
  701. gaia/eval/webapp/node_modules/side-channel/.editorconfig +0 -9
  702. gaia/eval/webapp/node_modules/side-channel/.eslintrc +0 -12
  703. gaia/eval/webapp/node_modules/side-channel/.github/FUNDING.yml +0 -12
  704. gaia/eval/webapp/node_modules/side-channel/.nycrc +0 -13
  705. gaia/eval/webapp/node_modules/side-channel/CHANGELOG.md +0 -110
  706. gaia/eval/webapp/node_modules/side-channel/LICENSE +0 -21
  707. gaia/eval/webapp/node_modules/side-channel/README.md +0 -61
  708. gaia/eval/webapp/node_modules/side-channel/index.d.ts +0 -14
  709. gaia/eval/webapp/node_modules/side-channel/index.js +0 -43
  710. gaia/eval/webapp/node_modules/side-channel/package.json +0 -85
  711. gaia/eval/webapp/node_modules/side-channel/test/index.js +0 -104
  712. gaia/eval/webapp/node_modules/side-channel/tsconfig.json +0 -9
  713. gaia/eval/webapp/node_modules/side-channel-list/.editorconfig +0 -9
  714. gaia/eval/webapp/node_modules/side-channel-list/.eslintrc +0 -11
  715. gaia/eval/webapp/node_modules/side-channel-list/.github/FUNDING.yml +0 -12
  716. gaia/eval/webapp/node_modules/side-channel-list/.nycrc +0 -13
  717. gaia/eval/webapp/node_modules/side-channel-list/CHANGELOG.md +0 -15
  718. gaia/eval/webapp/node_modules/side-channel-list/LICENSE +0 -21
  719. gaia/eval/webapp/node_modules/side-channel-list/README.md +0 -62
  720. gaia/eval/webapp/node_modules/side-channel-list/index.d.ts +0 -13
  721. gaia/eval/webapp/node_modules/side-channel-list/index.js +0 -113
  722. gaia/eval/webapp/node_modules/side-channel-list/list.d.ts +0 -14
  723. gaia/eval/webapp/node_modules/side-channel-list/package.json +0 -77
  724. gaia/eval/webapp/node_modules/side-channel-list/test/index.js +0 -104
  725. gaia/eval/webapp/node_modules/side-channel-list/tsconfig.json +0 -9
  726. gaia/eval/webapp/node_modules/side-channel-map/.editorconfig +0 -9
  727. gaia/eval/webapp/node_modules/side-channel-map/.eslintrc +0 -11
  728. gaia/eval/webapp/node_modules/side-channel-map/.github/FUNDING.yml +0 -12
  729. gaia/eval/webapp/node_modules/side-channel-map/.nycrc +0 -13
  730. gaia/eval/webapp/node_modules/side-channel-map/CHANGELOG.md +0 -22
  731. gaia/eval/webapp/node_modules/side-channel-map/LICENSE +0 -21
  732. gaia/eval/webapp/node_modules/side-channel-map/README.md +0 -62
  733. gaia/eval/webapp/node_modules/side-channel-map/index.d.ts +0 -15
  734. gaia/eval/webapp/node_modules/side-channel-map/index.js +0 -68
  735. gaia/eval/webapp/node_modules/side-channel-map/package.json +0 -80
  736. gaia/eval/webapp/node_modules/side-channel-map/test/index.js +0 -114
  737. gaia/eval/webapp/node_modules/side-channel-map/tsconfig.json +0 -9
  738. gaia/eval/webapp/node_modules/side-channel-weakmap/.editorconfig +0 -9
  739. gaia/eval/webapp/node_modules/side-channel-weakmap/.eslintrc +0 -12
  740. gaia/eval/webapp/node_modules/side-channel-weakmap/.github/FUNDING.yml +0 -12
  741. gaia/eval/webapp/node_modules/side-channel-weakmap/.nycrc +0 -13
  742. gaia/eval/webapp/node_modules/side-channel-weakmap/CHANGELOG.md +0 -28
  743. gaia/eval/webapp/node_modules/side-channel-weakmap/LICENSE +0 -21
  744. gaia/eval/webapp/node_modules/side-channel-weakmap/README.md +0 -62
  745. gaia/eval/webapp/node_modules/side-channel-weakmap/index.d.ts +0 -15
  746. gaia/eval/webapp/node_modules/side-channel-weakmap/index.js +0 -84
  747. gaia/eval/webapp/node_modules/side-channel-weakmap/package.json +0 -87
  748. gaia/eval/webapp/node_modules/side-channel-weakmap/test/index.js +0 -114
  749. gaia/eval/webapp/node_modules/side-channel-weakmap/tsconfig.json +0 -9
  750. gaia/eval/webapp/node_modules/statuses/HISTORY.md +0 -82
  751. gaia/eval/webapp/node_modules/statuses/LICENSE +0 -23
  752. gaia/eval/webapp/node_modules/statuses/README.md +0 -136
  753. gaia/eval/webapp/node_modules/statuses/codes.json +0 -65
  754. gaia/eval/webapp/node_modules/statuses/index.js +0 -146
  755. gaia/eval/webapp/node_modules/statuses/package.json +0 -49
  756. gaia/eval/webapp/node_modules/toidentifier/HISTORY.md +0 -9
  757. gaia/eval/webapp/node_modules/toidentifier/LICENSE +0 -21
  758. gaia/eval/webapp/node_modules/toidentifier/README.md +0 -61
  759. gaia/eval/webapp/node_modules/toidentifier/index.js +0 -32
  760. gaia/eval/webapp/node_modules/toidentifier/package.json +0 -38
  761. gaia/eval/webapp/node_modules/type-is/HISTORY.md +0 -259
  762. gaia/eval/webapp/node_modules/type-is/LICENSE +0 -23
  763. gaia/eval/webapp/node_modules/type-is/README.md +0 -170
  764. gaia/eval/webapp/node_modules/type-is/index.js +0 -266
  765. gaia/eval/webapp/node_modules/type-is/package.json +0 -45
  766. gaia/eval/webapp/node_modules/unpipe/HISTORY.md +0 -4
  767. gaia/eval/webapp/node_modules/unpipe/LICENSE +0 -22
  768. gaia/eval/webapp/node_modules/unpipe/README.md +0 -43
  769. gaia/eval/webapp/node_modules/unpipe/index.js +0 -69
  770. gaia/eval/webapp/node_modules/unpipe/package.json +0 -27
  771. gaia/eval/webapp/node_modules/util/LICENSE +0 -18
  772. gaia/eval/webapp/node_modules/util/README.md +0 -15
  773. gaia/eval/webapp/node_modules/util/node_modules/inherits/LICENSE +0 -16
  774. gaia/eval/webapp/node_modules/util/node_modules/inherits/README.md +0 -42
  775. gaia/eval/webapp/node_modules/util/node_modules/inherits/inherits.js +0 -7
  776. gaia/eval/webapp/node_modules/util/node_modules/inherits/inherits_browser.js +0 -23
  777. gaia/eval/webapp/node_modules/util/node_modules/inherits/package.json +0 -29
  778. gaia/eval/webapp/node_modules/util/package.json +0 -35
  779. gaia/eval/webapp/node_modules/util/support/isBuffer.js +0 -3
  780. gaia/eval/webapp/node_modules/util/support/isBufferBrowser.js +0 -6
  781. gaia/eval/webapp/node_modules/util/util.js +0 -586
  782. gaia/eval/webapp/node_modules/utils-merge/.npmignore +0 -9
  783. gaia/eval/webapp/node_modules/utils-merge/LICENSE +0 -20
  784. gaia/eval/webapp/node_modules/utils-merge/README.md +0 -34
  785. gaia/eval/webapp/node_modules/utils-merge/index.js +0 -23
  786. gaia/eval/webapp/node_modules/utils-merge/package.json +0 -40
  787. gaia/eval/webapp/node_modules/vary/HISTORY.md +0 -39
  788. gaia/eval/webapp/node_modules/vary/LICENSE +0 -22
  789. gaia/eval/webapp/node_modules/vary/README.md +0 -101
  790. gaia/eval/webapp/node_modules/vary/index.js +0 -149
  791. gaia/eval/webapp/node_modules/vary/package.json +0 -43
  792. {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.3.dist-info}/WHEEL +0 -0
  793. {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.3.dist-info}/licenses/LICENSE.md +0 -0
  794. {amd_gaia-0.14.1.dist-info → amd_gaia-0.14.3.dist-info}/top_level.txt +0 -0
gaia/agents/emr/cli.py ADDED
@@ -0,0 +1,1322 @@
1
+ # Copyright(C) 2025-2026 Advanced Micro Devices, Inc. All rights reserved.
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ """CLI for Medical Intake Agent."""
5
+
6
+ import argparse
7
+ import logging
8
+ import sys
9
+ from pathlib import Path
10
+
11
+ from rich.console import Console
12
+ from rich.panel import Panel
13
+ from rich.table import Table
14
+
15
+ from gaia.agents.emr.agent import MedicalIntakeAgent
16
+
17
+ logger = logging.getLogger(__name__)
18
+ console = Console()
19
+
20
+
21
+ def _print_header(watch_dir: str, db_path: str):
22
+ """Print a styled header for the CLI."""
23
+ console.print()
24
+ console.print(
25
+ Panel.fit(
26
+ "[bold cyan]Medical Intake Agent[/bold cyan]\n"
27
+ "[dim]Automatic Patient Form Processing[/dim]",
28
+ border_style="cyan",
29
+ )
30
+ )
31
+
32
+ # Status table
33
+ table = Table(show_header=False, box=None, padding=(0, 2))
34
+ table.add_column(style="dim")
35
+ table.add_column()
36
+ table.add_row("📁 Watch folder:", watch_dir)
37
+ table.add_row("💾 Database:", db_path)
38
+ console.print(table)
39
+ console.print()
40
+
41
+ # Commands help
42
+ console.print("[dim]Commands:[/dim]")
43
+ console.print(" [cyan]stats[/cyan] Show processing statistics")
44
+ console.print(" [cyan]quit[/cyan] Stop and exit")
45
+ console.print(" [dim]Or type questions about patients[/dim]")
46
+ console.print()
47
+
48
+
49
+ def _print_prompt():
50
+ """Print the input prompt with visual separators."""
51
+ console.print("─" * 80, style="dim")
52
+ console.print("> ", end="", style="bold green")
53
+ sys.stdout.flush() # Ensure prompt is displayed before input() blocks
54
+
55
+
56
+ def cmd_watch(args):
57
+ """Start watching directory for intake forms."""
58
+ _print_header(args.watch_dir, args.db)
59
+
60
+ console.print("[dim]Starting agent...[/dim]")
61
+
62
+ agent = MedicalIntakeAgent(
63
+ watch_dir=args.watch_dir,
64
+ db_path=args.db,
65
+ vlm_model=args.vlm_model,
66
+ )
67
+
68
+ console.print("[green]✓ Ready![/green] Drop intake forms to process them.\n")
69
+ sys.stdout.flush() # Ensure Ready message appears before prompt
70
+
71
+ try:
72
+ while True:
73
+ try:
74
+ _print_prompt()
75
+ user_input = input().strip()
76
+ except EOFError:
77
+ break
78
+
79
+ if not user_input:
80
+ continue
81
+
82
+ if user_input.lower() in ("quit", "exit", "q"):
83
+ break
84
+
85
+ console.print("─" * 80, style="dim")
86
+
87
+ if user_input.lower() == "stats":
88
+ cmd_stats_inline(agent)
89
+ else:
90
+ # Process the query
91
+ agent.process_query(user_input)
92
+ print()
93
+
94
+ except KeyboardInterrupt:
95
+ print()
96
+ finally:
97
+ console.print("[dim]Stopping agent...[/dim]")
98
+ agent.stop()
99
+ console.print("[green]✓ Stopped[/green]")
100
+
101
+
102
+ def cmd_stats_inline(agent):
103
+ """Show stats inline during watch mode."""
104
+ try:
105
+ stats = agent.get_stats()
106
+ _print_stats_table(stats)
107
+ except Exception as e:
108
+ console.print(f"[red]Error getting stats: {e}[/red]")
109
+
110
+
111
+ def cmd_process(args):
112
+ """Process a single intake form file."""
113
+ if not Path(args.file).exists():
114
+ console.print(f"[red]Error: File not found: {args.file}[/red]")
115
+ return 1
116
+
117
+ console.print(f"[dim]Processing: {args.file}[/dim]")
118
+
119
+ agent = MedicalIntakeAgent(
120
+ watch_dir=args.watch_dir,
121
+ db_path=args.db,
122
+ vlm_model=args.vlm_model,
123
+ auto_start_watching=False,
124
+ )
125
+
126
+ try:
127
+ # pylint: disable=protected-access
128
+ patient_data = agent._process_intake_form(args.file)
129
+
130
+ if patient_data:
131
+ # Agent already prints success and patient details
132
+ return 0
133
+ else:
134
+ console.print(f"[red]Failed to process: {args.file}[/red]")
135
+ return 1
136
+
137
+ finally:
138
+ agent.stop()
139
+
140
+
141
+ def cmd_query(args):
142
+ """Query patient database."""
143
+ agent = MedicalIntakeAgent(
144
+ watch_dir=args.watch_dir,
145
+ db_path=args.db,
146
+ auto_start_watching=False,
147
+ )
148
+
149
+ try:
150
+ agent.process_query(args.question)
151
+ return 0
152
+ finally:
153
+ agent.stop()
154
+
155
+
156
+ def _print_stats_table(stats: dict):
157
+ """Print statistics using Rich formatting."""
158
+ console.print()
159
+
160
+ # Time savings highlight
161
+ time_table = Table(show_header=False, box=None, padding=(0, 1))
162
+ time_table.add_column(style="bold green")
163
+ time_table.add_column(style="green")
164
+ time_table.add_row(
165
+ f"⏱️ {stats['time_saved_minutes']} min saved",
166
+ f"({stats['time_saved_percent']} faster)",
167
+ )
168
+ console.print(Panel(time_table, title="Time Savings", border_style="green"))
169
+
170
+ # Main stats grid
171
+ grid = Table.grid(expand=True, padding=(0, 2))
172
+ grid.add_column()
173
+ grid.add_column()
174
+
175
+ # Patients table
176
+ patients = Table(show_header=False, box=None)
177
+ patients.add_column(style="dim")
178
+ patients.add_column(style="bold")
179
+ patients.add_row("Total", str(stats["total_patients"]))
180
+ patients.add_row("New", str(stats["new_patients"]))
181
+ patients.add_row("Returning", str(stats["returning_patients"]))
182
+ patients.add_row("Today", str(stats["processed_today"]))
183
+
184
+ # Processing table
185
+ processing = Table(show_header=False, box=None)
186
+ processing.add_column(style="dim")
187
+ processing.add_column(style="bold")
188
+ processing.add_row("Processed", str(stats["files_processed"]))
189
+ processing.add_row("Success", str(stats["extraction_success"]))
190
+ processing.add_row("Failed", str(stats["extraction_failed"]))
191
+ processing.add_row("Rate", stats["success_rate"])
192
+
193
+ grid.add_row(
194
+ Panel(patients, title="👥 Patients", border_style="cyan"),
195
+ Panel(processing, title="📋 Processing", border_style="cyan"),
196
+ )
197
+ console.print(grid)
198
+
199
+ # Alerts (if any)
200
+ if stats.get("unacknowledged_alerts", 0) > 0:
201
+ console.print(
202
+ f"[bold red]🚨 {stats['unacknowledged_alerts']} unacknowledged alert(s)[/bold red]"
203
+ )
204
+ console.print()
205
+
206
+
207
+ def cmd_stats(args):
208
+ """Show processing statistics."""
209
+ agent = MedicalIntakeAgent(
210
+ watch_dir=args.watch_dir,
211
+ db_path=args.db,
212
+ auto_start_watching=False,
213
+ silent_mode=True,
214
+ )
215
+
216
+ try:
217
+ stats = agent.get_stats()
218
+ _print_stats_table(stats)
219
+ return 0
220
+ finally:
221
+ agent.stop()
222
+
223
+
224
+ def cmd_reset(args):
225
+ """Reset by deleting the database file."""
226
+ import os
227
+
228
+ from rich.prompt import Confirm
229
+
230
+ db_path = Path(args.db)
231
+
232
+ # Check if database exists
233
+ if not db_path.exists():
234
+ console.print("[dim]Database file does not exist. Nothing to reset.[/dim]")
235
+ return 0
236
+
237
+ # Get stats before deletion to show what will be deleted
238
+ total_patients = 0
239
+ agent = None
240
+ try:
241
+ agent = MedicalIntakeAgent(
242
+ watch_dir=args.watch_dir,
243
+ db_path=args.db,
244
+ auto_start_watching=False,
245
+ silent_mode=True,
246
+ )
247
+ stats = agent.get_stats()
248
+ total_patients = stats.get("total_patients", 0)
249
+ except Exception:
250
+ pass # If we can't read stats, proceed anyway
251
+ finally:
252
+ if agent:
253
+ agent.stop()
254
+
255
+ # Confirmation prompt unless --force is used
256
+ if not args.force:
257
+ console.print()
258
+ console.print(
259
+ "[bold yellow]⚠️ WARNING:[/bold yellow] This will permanently delete:"
260
+ )
261
+ if total_patients > 0:
262
+ console.print(f" • {total_patients} patient record(s)")
263
+ console.print(" • All associated alerts and intake sessions")
264
+ console.print(f" • Database file: {db_path}")
265
+ console.print()
266
+
267
+ if not Confirm.ask("[bold red]Are you sure you want to continue?[/bold red]"):
268
+ console.print("[dim]Cancelled.[/dim]")
269
+ return 0
270
+
271
+ # Delete the database file
272
+ try:
273
+ os.remove(db_path)
274
+ console.print()
275
+ console.print("[bold green]✓ Database deleted successfully[/bold green]")
276
+ console.print(f" Removed: {db_path}")
277
+ console.print()
278
+ console.print(
279
+ "[dim]A fresh database will be created when you next run the agent.[/dim]"
280
+ )
281
+ return 0
282
+ except Exception as e:
283
+ console.print(f"[red]Error deleting database: {e}[/red]")
284
+ return 1
285
+
286
+
287
+ def cmd_init(args):
288
+ """Initialize EMR agent by downloading and loading required models."""
289
+ import time
290
+
291
+ from gaia.llm.lemonade_client import LemonadeClient
292
+
293
+ console.print()
294
+ console.print(
295
+ Panel.fit(
296
+ "[bold cyan]EMR Agent Setup[/bold cyan]\n"
297
+ "[dim]Downloading and loading required models[/dim]",
298
+ border_style="cyan",
299
+ )
300
+ )
301
+ console.print()
302
+
303
+ # Required models for EMR agent
304
+ vlm_model = args.vlm_model # Default: Qwen3-VL-4B-Instruct-GGUF
305
+ llm_model = "Qwen3-Coder-30B-A3B-Instruct-GGUF" # For chat/query processing
306
+ embed_model = "nomic-embed-text-v2-moe-GGUF" # For similarity search
307
+
308
+ REQUIRED_CONTEXT_SIZE = 32768
309
+
310
+ # Step 1: Check Lemonade server and context size
311
+ console.print("[bold]Step 1:[/bold] Checking Lemonade server...")
312
+ try:
313
+ client = LemonadeClient(model=vlm_model)
314
+ health = client.health_check()
315
+ if health.get("status") == "ok":
316
+ console.print(" [green]✓[/green] Lemonade server is running")
317
+
318
+ # Check context size
319
+ context_size = health.get("context_size", 0)
320
+ if context_size >= REQUIRED_CONTEXT_SIZE:
321
+ console.print(
322
+ f" [green]✓[/green] Context size: [cyan]{context_size:,}[/cyan] tokens (recommended: {REQUIRED_CONTEXT_SIZE:,})"
323
+ )
324
+ elif context_size > 0:
325
+ console.print(
326
+ f" [yellow]⚠[/yellow] Context size: [yellow]{context_size:,}[/yellow] tokens"
327
+ )
328
+ console.print(
329
+ f" [yellow]Warning:[/yellow] Context size should be at least [cyan]{REQUIRED_CONTEXT_SIZE:,}[/cyan] for reliable form processing"
330
+ )
331
+ console.print(
332
+ " [dim]To fix: Right-click Lemonade tray → Settings → Context Size → 32768[/dim]"
333
+ )
334
+ else:
335
+ console.print(
336
+ " [dim]Context size: Not reported (will check after model load)[/dim]"
337
+ )
338
+ else:
339
+ console.print(" [red]✗[/red] Lemonade server not responding")
340
+ console.print()
341
+ console.print("[yellow]Please start Lemonade server first:[/yellow]")
342
+ console.print(" 1. Open Lemonade from the system tray")
343
+ console.print(" 2. Or run: [cyan]lemonade-server[/cyan]")
344
+ return 1
345
+ except Exception as e:
346
+ console.print(f" [red]✗[/red] Cannot connect to Lemonade: {e}")
347
+ console.print()
348
+ console.print("[yellow]Please start Lemonade server first:[/yellow]")
349
+ console.print(" 1. Open Lemonade from the system tray")
350
+ console.print(" 2. Or run: [cyan]lemonade-server[/cyan]")
351
+ return 1
352
+
353
+ # Step 2: Check required models
354
+ console.print()
355
+ console.print("[bold]Step 2:[/bold] Checking required models...")
356
+
357
+ try:
358
+ models_response = client.list_models()
359
+ available_models = models_response.get("data", [])
360
+ downloaded_model_ids = [m.get("id", "") for m in available_models]
361
+
362
+ # Check each required model
363
+ required_models = [
364
+ ("VLM", vlm_model, "Form extraction"),
365
+ ("LLM", llm_model, "Chat/query processing"),
366
+ ("Embedding", embed_model, "Similarity search"),
367
+ ]
368
+
369
+ models_to_download = []
370
+ for model_type, model_name, _purpose in required_models:
371
+ is_downloaded = model_name in downloaded_model_ids
372
+ if is_downloaded:
373
+ console.print(
374
+ f" [green]✓[/green] {model_type}: [cyan]{model_name}[/cyan]"
375
+ )
376
+ else:
377
+ console.print(
378
+ f" [dim]○[/dim] {model_type}: [cyan]{model_name}[/cyan] [dim](not downloaded)[/dim]"
379
+ )
380
+ models_to_download.append((model_type, model_name))
381
+
382
+ if models_to_download:
383
+ console.print()
384
+ console.print(
385
+ f" [yellow]⚠️ {len(models_to_download)} model(s) need to be downloaded[/yellow]"
386
+ )
387
+
388
+ except Exception as e:
389
+ console.print(f" [red]✗[/red] Failed to check models: {e}")
390
+ return 1
391
+
392
+ # Step 3: Load all required models
393
+ console.print()
394
+ console.print("[bold]Step 3:[/bold] Loading required models...")
395
+ console.print(" [dim]Loading models into memory for fast inference...[/dim]")
396
+ console.print()
397
+
398
+ models_loaded = {}
399
+
400
+ # Load VLM model first (most important for form processing)
401
+ for model_type, model_name in [
402
+ ("VLM", vlm_model),
403
+ ("LLM", llm_model),
404
+ ("Embedding", embed_model),
405
+ ]:
406
+ console.print(f" Loading {model_type}: [cyan]{model_name}[/cyan]...")
407
+
408
+ try:
409
+ start_time = time.time()
410
+ client.load_model(model_name, timeout=1800, auto_download=True)
411
+ elapsed = time.time() - start_time
412
+ models_loaded[model_type] = True
413
+ console.print(f" [green]✓[/green] {model_type} loaded ({elapsed:.1f}s)")
414
+ except Exception as e:
415
+ error_msg = str(e)
416
+ models_loaded[model_type] = False
417
+
418
+ # Check for common errors
419
+ if "being used by another process" in error_msg:
420
+ console.print(
421
+ f" [yellow]![/yellow] {model_type}: File locked, try again later"
422
+ )
423
+ elif (
424
+ "not found" in error_msg.lower()
425
+ or "does not exist" in error_msg.lower()
426
+ ):
427
+ console.print(
428
+ f" [yellow]![/yellow] {model_type}: Model not available in registry"
429
+ )
430
+ else:
431
+ console.print(f" [yellow]![/yellow] {model_type}: {error_msg[:50]}...")
432
+
433
+ # Check if critical models loaded
434
+ if not models_loaded.get("VLM"):
435
+ console.print()
436
+ console.print(
437
+ "[red]✗ VLM model failed to load - form processing will not work[/red]"
438
+ )
439
+ return 1
440
+
441
+ # Clear VLM context to ensure fresh memory allocation
442
+ console.print()
443
+ console.print(" [dim]Clearing VLM context for clean memory...[/dim]")
444
+ try:
445
+ client.unload_model()
446
+ client.load_model(vlm_model, timeout=300, auto_download=True)
447
+ console.print(" [green]✓[/green] VLM context cleared")
448
+ except Exception as e:
449
+ console.print(f" [dim]Context clear skipped: {e}[/dim]")
450
+
451
+ # Step 4: Verify models and check context size
452
+ console.print()
453
+ console.print("[bold]Step 4:[/bold] Verifying models are ready...")
454
+
455
+ vlm_ready = False
456
+ llm_ready = False
457
+ embed_ready = False
458
+ final_context_size = 0
459
+
460
+ try:
461
+ # Check health for context size
462
+ health = client.health_check()
463
+ final_context_size = health.get("context_size", 0)
464
+
465
+ # Check each model
466
+ vlm_ready = client.check_model_loaded(vlm_model)
467
+ llm_ready = client.check_model_loaded(llm_model)
468
+ embed_ready = client.check_model_loaded(embed_model)
469
+
470
+ if vlm_ready:
471
+ console.print(" [green]✓[/green] VLM: Ready for form extraction")
472
+ else:
473
+ console.print(" [yellow]![/yellow] VLM: Will load on first use")
474
+
475
+ if llm_ready:
476
+ console.print(" [green]✓[/green] LLM: Ready for chat queries")
477
+ else:
478
+ console.print(" [dim]○[/dim] LLM: Will load on first use")
479
+
480
+ if embed_ready:
481
+ console.print(" [green]✓[/green] Embedding: Ready for search")
482
+ else:
483
+ console.print(" [dim]○[/dim] Embedding: Will load on first use")
484
+
485
+ # Report context size
486
+ if final_context_size >= REQUIRED_CONTEXT_SIZE:
487
+ console.print(
488
+ f" [green]✓[/green] Context size: [cyan]{final_context_size:,}[/cyan] tokens"
489
+ )
490
+ elif final_context_size > 0:
491
+ console.print(
492
+ f" [yellow]⚠[/yellow] Context size: [yellow]{final_context_size:,}[/yellow] tokens (need {REQUIRED_CONTEXT_SIZE:,})"
493
+ )
494
+
495
+ except Exception as e:
496
+ console.print(f" [yellow]![/yellow] Could not verify: {e}")
497
+
498
+ # Step 5: Show all downloaded and loaded models
499
+ console.print()
500
+ console.print("[bold]Step 5:[/bold] Model inventory...")
501
+
502
+ try:
503
+ models_response = client.list_models()
504
+ all_models = models_response.get("data", [])
505
+
506
+ # Categorize models
507
+ vlm_models = []
508
+ llm_models = []
509
+ embed_models = []
510
+
511
+ for m in all_models:
512
+ model_id = m.get("id", "")
513
+ model_lower = model_id.lower()
514
+
515
+ if "vl" in model_lower or "vision" in model_lower or "vlm" in model_lower:
516
+ vlm_models.append(model_id)
517
+ elif (
518
+ "embed" in model_lower
519
+ or "bge" in model_lower
520
+ or "e5" in model_lower
521
+ or "nomic" in model_lower
522
+ ):
523
+ embed_models.append(model_id)
524
+ else:
525
+ llm_models.append(model_id)
526
+
527
+ # Show categorized models
528
+ if vlm_models:
529
+ console.print(
530
+ f" [cyan]VLM Models:[/cyan] {', '.join(vlm_models[:3])}"
531
+ + (f" (+{len(vlm_models)-3} more)" if len(vlm_models) > 3 else "")
532
+ )
533
+ if llm_models:
534
+ console.print(
535
+ f" [cyan]LLM Models:[/cyan] {', '.join(llm_models[:3])}"
536
+ + (f" (+{len(llm_models)-3} more)" if len(llm_models) > 3 else "")
537
+ )
538
+ if embed_models:
539
+ console.print(
540
+ f" [cyan]Embedding Models:[/cyan] {', '.join(embed_models[:3])}"
541
+ + (f" (+{len(embed_models)-3} more)" if len(embed_models) > 3 else "")
542
+ )
543
+
544
+ console.print(f" [dim]Total models available: {len(all_models)}[/dim]")
545
+
546
+ except Exception as e:
547
+ console.print(f" [dim]Could not list models: {e}[/dim]")
548
+
549
+ # Success summary
550
+ console.print()
551
+
552
+ # Build model status lines
553
+ model_status_lines = []
554
+
555
+ # VLM status
556
+ if vlm_ready:
557
+ model_status_lines.append(
558
+ f"[green]✓[/green] VLM: [cyan]{vlm_model}[/cyan] - Ready"
559
+ )
560
+ else:
561
+ model_status_lines.append(
562
+ f"[yellow]![/yellow] VLM: [cyan]{vlm_model}[/cyan] - Will load on first use"
563
+ )
564
+
565
+ # LLM status
566
+ if llm_ready:
567
+ model_status_lines.append(
568
+ f"[green]✓[/green] LLM: [cyan]{llm_model}[/cyan] - Ready"
569
+ )
570
+ else:
571
+ model_status_lines.append(
572
+ f"[dim]○[/dim] LLM: [cyan]{llm_model}[/cyan] - Will load on first use"
573
+ )
574
+
575
+ # Embedding status
576
+ if embed_ready:
577
+ model_status_lines.append(
578
+ f"[green]✓[/green] Embedding: [cyan]{embed_model}[/cyan] - Ready"
579
+ )
580
+ else:
581
+ model_status_lines.append(
582
+ f"[dim]○[/dim] Embedding: [cyan]{embed_model}[/cyan] - Will load on first use"
583
+ )
584
+
585
+ # Context size status
586
+ if final_context_size >= REQUIRED_CONTEXT_SIZE:
587
+ model_status_lines.append(
588
+ f"[green]✓[/green] Context size: {final_context_size:,} tokens"
589
+ )
590
+ elif final_context_size > 0:
591
+ model_status_lines.append(
592
+ f"[yellow]⚠[/yellow] Context size: {final_context_size:,} tokens (need {REQUIRED_CONTEXT_SIZE:,})"
593
+ )
594
+
595
+ # Count ready models
596
+ ready_count = sum([vlm_ready, llm_ready, embed_ready])
597
+
598
+ console.print(
599
+ Panel.fit(
600
+ f"[bold green]✓ EMR Agent initialized ({ready_count}/3 models ready)[/bold green]\n\n"
601
+ + "\n".join(model_status_lines)
602
+ + "\n\n"
603
+ "[dim]You can now run:[/dim]\n"
604
+ " [cyan]gaia-emr dashboard[/cyan] - Start the web dashboard\n"
605
+ " [cyan]gaia-emr watch[/cyan] - Watch folder for intake forms\n"
606
+ " [cyan]gaia-emr process <file>[/cyan] - Process a single file",
607
+ border_style="green",
608
+ )
609
+ )
610
+ console.print()
611
+
612
+ # Context size warning if needed
613
+ if 0 < final_context_size < REQUIRED_CONTEXT_SIZE:
614
+ console.print(
615
+ Panel.fit(
616
+ "[yellow]⚠️ Context Size Warning[/yellow]\n\n"
617
+ f"Current context size ({final_context_size:,}) may be too small for processing intake forms.\n"
618
+ "Large images can require 4,000-8,000+ tokens.\n\n"
619
+ "[bold]To fix:[/bold]\n"
620
+ " 1. Right-click Lemonade tray icon → Settings\n"
621
+ " 2. Set Context Size to [cyan]32768[/cyan]\n"
622
+ " 3. Click Apply and restart the model",
623
+ border_style="yellow",
624
+ )
625
+ )
626
+ console.print()
627
+
628
+ return 0
629
+
630
+
631
+ def cmd_test(args):
632
+ """Test VLM extraction pipeline on a single file."""
633
+ import io
634
+ import json
635
+ import time
636
+
637
+ from PIL import Image
638
+
639
+ from gaia.llm.vlm_client import VLMClient
640
+
641
+ file_path = Path(args.file)
642
+ if not file_path.exists():
643
+ console.print(f"[red]Error: File not found: {file_path}[/red]")
644
+ return 1
645
+
646
+ console.print()
647
+ console.print(
648
+ Panel.fit(
649
+ "[bold cyan]EMR Agent - VLM Pipeline Test[/bold cyan]\n"
650
+ f"[dim]Testing extraction on: {file_path.name}[/dim]",
651
+ border_style="cyan",
652
+ )
653
+ )
654
+ console.print()
655
+
656
+ # Step 1: Read and analyze file
657
+ console.print("[bold]Step 1:[/bold] Reading file...")
658
+ try:
659
+ raw_bytes = file_path.read_bytes()
660
+ file_size_kb = len(raw_bytes) / 1024
661
+ console.print(f" File size: {file_size_kb:.1f} KB")
662
+
663
+ # Get image dimensions
664
+ img = Image.open(io.BytesIO(raw_bytes))
665
+ orig_width, orig_height = img.size
666
+ console.print(f" Dimensions: {orig_width}x{orig_height} pixels")
667
+
668
+ # Auto-rotate based on EXIF orientation
669
+ try:
670
+ from PIL import ExifTags
671
+
672
+ exif = img._getexif() # pylint: disable=protected-access
673
+ if exif:
674
+ for tag, value in exif.items():
675
+ if ExifTags.TAGS.get(tag) == "Orientation":
676
+ if value == 3:
677
+ img = img.rotate(180, expand=True)
678
+ console.print(" [dim]Auto-rotated 180°[/dim]")
679
+ elif value == 6:
680
+ img = img.rotate(270, expand=True)
681
+ console.print(" [dim]Auto-rotated 90° CW[/dim]")
682
+ elif value == 8:
683
+ img = img.rotate(90, expand=True)
684
+ console.print(" [dim]Auto-rotated 90° CCW[/dim]")
685
+ orig_width, orig_height = img.size
686
+ break
687
+ except Exception:
688
+ pass # No EXIF or rotation info
689
+ except Exception as e:
690
+ console.print(f" [red]✗[/red] Failed to read file: {e}")
691
+ return 1
692
+
693
+ # Step 2: Optimize image (same as agent)
694
+ console.print()
695
+ console.print("[bold]Step 2:[/bold] Optimizing image...")
696
+ max_dimension = args.max_dimension
697
+ jpeg_quality = args.jpeg_quality
698
+
699
+ try:
700
+ if orig_width > max_dimension or orig_height > max_dimension:
701
+ scale = min(max_dimension / orig_width, max_dimension / orig_height)
702
+ new_width = int(orig_width * scale)
703
+ new_height = int(orig_height * scale)
704
+ img = img.resize((new_width, new_height), Image.Resampling.LANCZOS)
705
+ console.print(
706
+ f" Resized: {orig_width}x{orig_height} → {new_width}x{new_height}"
707
+ )
708
+ else:
709
+ new_width, new_height = orig_width, orig_height
710
+ console.print(f" No resize needed (under {max_dimension}px)")
711
+
712
+ # Convert to RGB and JPEG
713
+ if img.mode in ("RGBA", "P"):
714
+ img = img.convert("RGB")
715
+
716
+ output = io.BytesIO()
717
+ img.save(output, format="JPEG", quality=jpeg_quality, optimize=True)
718
+ image_bytes = output.getvalue()
719
+
720
+ opt_size_kb = len(image_bytes) / 1024
721
+ reduction = (1 - opt_size_kb / file_size_kb) * 100
722
+ console.print(
723
+ f" Optimized: {file_size_kb:.0f}KB → {opt_size_kb:.0f}KB ({reduction:.0f}% smaller)"
724
+ )
725
+
726
+ # Estimate image tokens (rough: ~1 token per 14x14 pixel patch)
727
+ est_img_tokens = (new_width // 14) * (new_height // 14)
728
+ console.print(f" Est. image tokens: ~{est_img_tokens:,}")
729
+ except Exception as e:
730
+ console.print(f" [red]✗[/red] Failed to optimize: {e}")
731
+ return 1
732
+
733
+ # Step 3: Initialize VLM
734
+ console.print()
735
+ console.print("[bold]Step 3:[/bold] Initializing VLM...")
736
+ try:
737
+ vlm = VLMClient(vlm_model=args.vlm_model)
738
+
739
+ # Clear context if requested (unload and reload model)
740
+ if getattr(args, "clear_context", False):
741
+ console.print(" [dim]Clearing VLM context (unload + reload)...[/dim]")
742
+ try:
743
+ vlm.client.unload_model()
744
+ vlm.client.load_model(args.vlm_model, timeout=300, auto_download=True)
745
+ console.print(" [green]✓[/green] Context cleared")
746
+ except Exception as e:
747
+ console.print(f" [yellow]⚠[/yellow] Could not clear context: {e}")
748
+
749
+ console.print(f" [green]✓[/green] VLM ready: [cyan]{vlm.vlm_model}[/cyan]")
750
+ except Exception as e:
751
+ console.print(f" [red]✗[/red] Failed to initialize VLM: {e}")
752
+ return 1
753
+
754
+ # Step 4: Extract data with auto-retry on memory errors
755
+ console.print()
756
+ console.print("[bold]Step 4:[/bold] Extracting patient data...")
757
+
758
+ extraction_prompt = """Extract ALL patient information from this medical intake form.
759
+
760
+ Return a JSON object with these fields (use null for missing/unclear):
761
+ {
762
+ "form_date": "YYYY-MM-DD (date form was filled, today's date)",
763
+ "first_name": "...",
764
+ "last_name": "...",
765
+ "date_of_birth": "YYYY-MM-DD",
766
+ "age": "patient's age if listed",
767
+ "gender": "Male/Female/Other",
768
+ "preferred_pronouns": "he/him, she/her, they/them if listed",
769
+ "ssn": "XXX-XX-XXXX (social security number)",
770
+ "marital_status": "Single/Married/Divorced/Widowed/Partnered",
771
+ "spouse_name": "spouse's name if listed",
772
+ "phone": "home phone number",
773
+ "mobile_phone": "cell/mobile phone number",
774
+ "work_phone": "work phone number",
775
+ "email": "...",
776
+ "address": "street address",
777
+ "city": "...",
778
+ "state": "...",
779
+ "zip_code": "...",
780
+ "preferred_language": "English/Spanish/etc if listed",
781
+ "race": "if listed",
782
+ "ethnicity": "if listed",
783
+ "contact_preference": "preferred contact method if listed",
784
+ "emergency_contact_name": "name of emergency contact person",
785
+ "emergency_contact_relationship": "relationship to patient (e.g. Mom, Spouse, Friend)",
786
+ "emergency_contact_phone": "emergency contact's phone number",
787
+ "referring_physician": "name of referring physician/doctor",
788
+ "referring_physician_phone": "phone number next to referring physician",
789
+ "primary_care_physician": "PCP name if different from referring",
790
+ "preferred_pharmacy": "pharmacy name if listed",
791
+ "employment_status": "Employed/Self Employed/Unemployed/Retired/Student/Disabled/Military",
792
+ "occupation": "job title if listed",
793
+ "employer": "employer/company name",
794
+ "employer_address": "employer address if listed",
795
+ "insurance_provider": "insurance company name",
796
+ "insurance_id": "policy number",
797
+ "insurance_group_number": "group number",
798
+ "insured_name": "name of insured person (may differ from patient)",
799
+ "insured_dob": "YYYY-MM-DD",
800
+ "insurance_phone": "insurance contact number",
801
+ "billing_address": "billing address if different from home",
802
+ "guarantor_name": "person responsible for payment if listed",
803
+ "reason_for_visit": "chief complaint or reason for visit",
804
+ "date_of_injury": "YYYY-MM-DD (date of injury or onset of symptoms)",
805
+ "pain_location": "where pain is located if listed",
806
+ "pain_onset": "when pain began (e.g. three months ago)",
807
+ "pain_cause": "what caused the pain/condition",
808
+ "pain_progression": "Improved/Worsened/Stayed the same",
809
+ "work_related_injury": "Yes/No",
810
+ "car_accident": "Yes/No",
811
+ "medical_conditions": "existing medical conditions",
812
+ "allergies": "known allergies",
813
+ "medications": "current medications",
814
+ "signature_date": "YYYY-MM-DD (date signed)"
815
+ }
816
+
817
+ IMPORTANT: Return ONLY the JSON object, no other text."""
818
+
819
+ # Retry loop with progressively smaller images on memory errors
820
+ max_retries = 3
821
+ current_img = img
822
+ current_bytes = image_bytes
823
+ current_width, current_height = new_width, new_height
824
+ current_size_kb = opt_size_kb
825
+
826
+ for attempt in range(max_retries):
827
+ est_img_tokens = (current_width // 14) * (current_height // 14)
828
+ console.print(
829
+ f" Image: {current_width}x{current_height}, {current_size_kb:.0f}KB (~{est_img_tokens:,} tokens)"
830
+ )
831
+
832
+ if attempt == 0:
833
+ console.print(" [dim]This may take 30-60 seconds...[/dim]")
834
+ else:
835
+ console.print(
836
+ f" [dim]Retry {attempt}/{max_retries-1} with smaller image...[/dim]"
837
+ )
838
+
839
+ try:
840
+ start_time = time.time()
841
+ raw_text = vlm.extract_from_image(
842
+ image_bytes=current_bytes,
843
+ prompt=extraction_prompt,
844
+ )
845
+ extraction_time = time.time() - start_time
846
+
847
+ # Check for memory-related errors
848
+ if (
849
+ "failed to process image" in raw_text
850
+ or "memory slot" in raw_text.lower()
851
+ ):
852
+ if attempt < max_retries - 1:
853
+ console.print(
854
+ " [yellow]⚠[/yellow] Memory error, reducing image size..."
855
+ )
856
+ # Reduce image to 75% of current size
857
+ scale = 0.75
858
+ current_width = int(current_width * scale)
859
+ current_height = int(current_height * scale)
860
+ current_img = current_img.resize(
861
+ (current_width, current_height), Image.Resampling.LANCZOS
862
+ )
863
+ output = io.BytesIO()
864
+ current_img.save(
865
+ output, format="JPEG", quality=jpeg_quality, optimize=True
866
+ )
867
+ current_bytes = output.getvalue()
868
+ current_size_kb = len(current_bytes) / 1024
869
+ continue
870
+ else:
871
+ console.print(f" [red]✗[/red] {raw_text}")
872
+ console.print()
873
+ console.print("[yellow]Suggestions:[/yellow]")
874
+ console.print(" 1. Try with smaller image: --max-dimension 640")
875
+ console.print(" 2. Restart Lemonade Server to clear memory")
876
+ console.print(" 3. Reload the VLM model in Lemonade")
877
+ return 1
878
+
879
+ if raw_text.startswith("[VLM extraction failed:"):
880
+ console.print(f" [red]✗[/red] {raw_text}")
881
+ return 1
882
+
883
+ # Success!
884
+ console.print(
885
+ f" [green]✓[/green] Extraction complete ({len(raw_text)} chars, {extraction_time:.1f}s)"
886
+ )
887
+
888
+ # Estimate tokens/sec (output tokens only)
889
+ est_output_tokens = len(raw_text) / 4
890
+ tps = est_output_tokens / extraction_time if extraction_time > 0 else 0
891
+ console.print(
892
+ f" Output: ~{est_output_tokens:.0f} tokens at ~{tps:.1f} TPS"
893
+ )
894
+
895
+ # Total throughput including prompt processing
896
+ total_tokens = (
897
+ est_img_tokens + 200 + est_output_tokens
898
+ ) # img + prompt + output
899
+ total_tps = total_tokens / extraction_time if extraction_time > 0 else 0
900
+ console.print(
901
+ f" Total throughput: ~{total_tps:.0f} TPS (incl. {est_img_tokens:,} image tokens)"
902
+ )
903
+
904
+ # Update dimensions for final report
905
+ new_width, new_height = current_width, current_height
906
+ break
907
+
908
+ except Exception as e:
909
+ console.print(f" [red]✗[/red] Extraction failed: {e}")
910
+ return 1
911
+ else:
912
+ # All retries exhausted
913
+ console.print(" [red]✗[/red] All retries failed")
914
+ return 1
915
+
916
+ # Step 5: Parse JSON
917
+ console.print()
918
+ console.print("[bold]Step 5:[/bold] Parsing JSON...")
919
+ try:
920
+ # Try direct parse
921
+ patient_data = json.loads(raw_text)
922
+ console.print(" [green]✓[/green] JSON parsed successfully")
923
+ except json.JSONDecodeError:
924
+ # Try to find JSON in text
925
+ try:
926
+ start = raw_text.find("{")
927
+ end = raw_text.rfind("}") + 1
928
+ if start >= 0 and end > start:
929
+ patient_data = json.loads(raw_text[start:end])
930
+ console.print(" [green]✓[/green] JSON extracted from response")
931
+ else:
932
+ console.print(" [red]✗[/red] No JSON found in response")
933
+ console.print()
934
+ console.print("[bold]Raw VLM Output:[/bold]")
935
+ console.print(raw_text[:500])
936
+ return 1
937
+ except json.JSONDecodeError as e:
938
+ console.print(f" [red]✗[/red] JSON parse failed: {e}")
939
+ return 1
940
+
941
+ # Display results
942
+ console.print()
943
+ console.print(
944
+ Panel.fit(
945
+ "[bold green]✓ Extraction Successful[/bold green]",
946
+ border_style="green",
947
+ )
948
+ )
949
+
950
+ # Show extracted fields
951
+ console.print()
952
+ console.print("[bold]Extracted Fields:[/bold]")
953
+ fields_found = 0
954
+ for key, value in patient_data.items():
955
+ if value and value != "null":
956
+ fields_found += 1
957
+ console.print(f" [cyan]{key}:[/cyan] {value}")
958
+
959
+ console.print()
960
+ console.print(f"[dim]Fields extracted: {fields_found}/53[/dim]")
961
+ console.print()
962
+
963
+ # Timing breakdown section
964
+ console.print("[bold]⏱️ TIMING BREAKDOWN[/bold]")
965
+ console.print("-" * 40)
966
+ console.print(f" Model: {args.vlm_model}")
967
+ console.print(f" Image dimensions: {new_width}x{new_height}")
968
+ console.print(f" VLM extraction: {extraction_time:.2f}s")
969
+ console.print(f" Est. image tokens: ~{est_img_tokens:,}")
970
+ console.print(f" Est. output tokens: ~{int(est_output_tokens)}")
971
+ console.print(f" Est. tokens/sec: ~{tps:.1f} TPS")
972
+ console.print()
973
+
974
+ # Success summary
975
+ if patient_data.get("first_name") and patient_data.get("last_name"):
976
+ console.print(
977
+ f" Patient: {patient_data.get('first_name', '')} {patient_data.get('last_name', '')}"
978
+ )
979
+ console.print(" [green]✓ Pipeline test PASSED[/green]")
980
+ else:
981
+ console.print(" [yellow]⚠ Missing required name fields[/yellow]")
982
+ console.print(" [red]✗ Pipeline test FAILED[/red]")
983
+ console.print()
984
+
985
+ return 0
986
+
987
+
988
+ def _launch_electron(url: str, delay: float = 1.5) -> bool:
989
+ """
990
+ Launch Electron app to display the dashboard.
991
+
992
+ Returns True if Electron was launched successfully, False otherwise.
993
+ """
994
+ import os
995
+ import platform
996
+ import shutil
997
+ import subprocess
998
+ import time
999
+
1000
+ time.sleep(delay) # Wait for server to start
1001
+
1002
+ # Find the Electron wrapper directory
1003
+ electron_dir = Path(__file__).parent / "dashboard" / "electron"
1004
+ main_js = electron_dir / "main.js"
1005
+
1006
+ if not main_js.exists():
1007
+ logger.warning(f"Electron wrapper not found at {electron_dir}")
1008
+ return False
1009
+
1010
+ # On Windows, use npm.cmd and npx.cmd
1011
+ is_windows = platform.system() == "Windows"
1012
+ npm_cmd = "npm.cmd" if is_windows else "npm"
1013
+ npx_cmd = "npx.cmd" if is_windows else "npx"
1014
+
1015
+ # Check if npx/electron is available
1016
+ npx_path = shutil.which(npx_cmd)
1017
+ if not npx_path:
1018
+ logger.warning(f"{npx_cmd} not found in PATH, cannot launch Electron")
1019
+ return False
1020
+
1021
+ try:
1022
+ # Check if node_modules exists, if not run npm install first
1023
+ node_modules = electron_dir / "node_modules"
1024
+ if not node_modules.exists():
1025
+ console.print("[dim]Installing Electron dependencies...[/dim]")
1026
+ subprocess.run(
1027
+ [npm_cmd, "install"],
1028
+ cwd=str(electron_dir),
1029
+ capture_output=True,
1030
+ check=True,
1031
+ shell=is_windows, # Use shell on Windows for .cmd files
1032
+ )
1033
+
1034
+ # Launch Electron with the dashboard URL
1035
+ env = os.environ.copy()
1036
+ env["EMR_DASHBOARD_URL"] = url
1037
+
1038
+ subprocess.Popen(
1039
+ [npx_cmd, "electron", "."],
1040
+ cwd=str(electron_dir),
1041
+ env=env,
1042
+ stdout=subprocess.DEVNULL,
1043
+ stderr=subprocess.DEVNULL,
1044
+ shell=is_windows, # Use shell on Windows for .cmd files
1045
+ )
1046
+ return True
1047
+ except Exception as e:
1048
+ logger.warning(f"Failed to launch Electron: {e}")
1049
+ return False
1050
+
1051
+
1052
+ def cmd_dashboard(args):
1053
+ """Start web dashboard."""
1054
+ import threading
1055
+ import time
1056
+ import webbrowser
1057
+
1058
+ def open_browser(url: str, delay: float = 1.5):
1059
+ """Open browser after a short delay to allow server to start."""
1060
+ time.sleep(delay)
1061
+ webbrowser.open(url)
1062
+
1063
+ def open_electron_or_browser(url: str, use_browser: bool, delay: float = 1.5):
1064
+ """Open Electron app, falling back to browser if needed."""
1065
+ if use_browser:
1066
+ open_browser(url, delay)
1067
+ else:
1068
+ if not _launch_electron(url, delay):
1069
+ console.print(
1070
+ "[yellow]Electron not available, opening in browser instead...[/yellow]"
1071
+ )
1072
+ open_browser(url, delay)
1073
+
1074
+ try:
1075
+ from gaia.agents.emr.dashboard.server import run_dashboard
1076
+
1077
+ console.print()
1078
+ console.print(
1079
+ Panel.fit(
1080
+ "[bold cyan]EMR Dashboard[/bold cyan]\n"
1081
+ "[dim]Real-time Patient Processing Monitor[/dim]",
1082
+ border_style="cyan",
1083
+ )
1084
+ )
1085
+
1086
+ url = f"http://localhost:{args.port}"
1087
+
1088
+ table = Table(show_header=False, box=None, padding=(0, 2))
1089
+ table.add_column(style="dim")
1090
+ table.add_column()
1091
+ table.add_row("📁 Watch folder:", args.watch_dir)
1092
+ table.add_row("💾 Database:", args.db)
1093
+ table.add_row("🌐 URL:", f"[bold cyan]{url}[/bold cyan]")
1094
+ console.print(table)
1095
+ console.print("\n[dim]Press Ctrl+C to stop[/dim]\n")
1096
+
1097
+ # Auto-open unless --no-open flag is set
1098
+ if not getattr(args, "no_open", False):
1099
+ use_browser = getattr(args, "browser", False)
1100
+ if use_browser:
1101
+ console.print("[dim]Opening dashboard in browser...[/dim]\n")
1102
+ else:
1103
+ console.print("[dim]Opening dashboard in Electron app...[/dim]\n")
1104
+
1105
+ open_thread = threading.Thread(
1106
+ target=open_electron_or_browser,
1107
+ args=(url, use_browser),
1108
+ daemon=True,
1109
+ )
1110
+ open_thread.start()
1111
+
1112
+ run_dashboard(
1113
+ watch_dir=args.watch_dir,
1114
+ db_path=args.db,
1115
+ host=args.host,
1116
+ port=args.port,
1117
+ )
1118
+ except ImportError:
1119
+ console.print("[red]Error: Dashboard dependencies not installed[/red]")
1120
+ console.print("Install with: [cyan]pip install 'amd-gaia[api]'[/cyan]")
1121
+ return 1
1122
+ except KeyboardInterrupt:
1123
+ console.print("\n[dim]Shutting down dashboard...[/dim]")
1124
+ return 0
1125
+
1126
+
1127
+ def _add_common_args(parser):
1128
+ """Add common arguments to a parser."""
1129
+ parser.add_argument(
1130
+ "--watch-dir",
1131
+ default="./intake_forms",
1132
+ help="Directory to watch for intake forms (default: ./intake_forms)",
1133
+ )
1134
+ parser.add_argument(
1135
+ "--db",
1136
+ default="./data/patients.db",
1137
+ help="Path to patient database (default: ./data/patients.db)",
1138
+ )
1139
+ parser.add_argument(
1140
+ "--vlm-model",
1141
+ default="Qwen3-VL-4B-Instruct-GGUF",
1142
+ help="VLM model for extraction (default: Qwen3-VL-4B-Instruct-GGUF)",
1143
+ )
1144
+ parser.add_argument(
1145
+ "--debug",
1146
+ action="store_true",
1147
+ help="Enable debug logging",
1148
+ )
1149
+
1150
+
1151
+ def main():
1152
+ """Main CLI entry point."""
1153
+ parser = argparse.ArgumentParser(
1154
+ description="Medical Intake Agent CLI",
1155
+ formatter_class=argparse.RawDescriptionHelpFormatter,
1156
+ )
1157
+
1158
+ subparsers = parser.add_subparsers(dest="command", help="Command to run")
1159
+
1160
+ # Watch command
1161
+ parser_watch = subparsers.add_parser(
1162
+ "watch",
1163
+ help="Watch directory for new intake forms",
1164
+ )
1165
+ _add_common_args(parser_watch)
1166
+ parser_watch.set_defaults(func=cmd_watch)
1167
+
1168
+ # Process command
1169
+ parser_process = subparsers.add_parser(
1170
+ "process",
1171
+ help="Process a single intake form",
1172
+ )
1173
+ _add_common_args(parser_process)
1174
+ parser_process.add_argument("file", help="Path to intake form file")
1175
+ parser_process.set_defaults(func=cmd_process)
1176
+
1177
+ # Query command
1178
+ parser_query = subparsers.add_parser(
1179
+ "query",
1180
+ help="Query patient database",
1181
+ )
1182
+ _add_common_args(parser_query)
1183
+ parser_query.add_argument("question", help="Question to ask")
1184
+ parser_query.set_defaults(func=cmd_query)
1185
+
1186
+ # Stats command
1187
+ parser_stats = subparsers.add_parser(
1188
+ "stats",
1189
+ help="Show processing statistics",
1190
+ )
1191
+ _add_common_args(parser_stats)
1192
+ parser_stats.set_defaults(func=cmd_stats)
1193
+
1194
+ # Reset command
1195
+ parser_reset = subparsers.add_parser(
1196
+ "reset",
1197
+ help="Clear all patient data from the database",
1198
+ )
1199
+ _add_common_args(parser_reset)
1200
+ parser_reset.add_argument(
1201
+ "--force",
1202
+ "-f",
1203
+ action="store_true",
1204
+ help="Skip confirmation prompt",
1205
+ )
1206
+ parser_reset.set_defaults(func=cmd_reset)
1207
+
1208
+ # Init command
1209
+ parser_init = subparsers.add_parser(
1210
+ "init",
1211
+ help="Download and setup required VLM models",
1212
+ )
1213
+ parser_init.add_argument(
1214
+ "--vlm-model",
1215
+ default="Qwen3-VL-4B-Instruct-GGUF",
1216
+ help="VLM model to download (default: Qwen3-VL-4B-Instruct-GGUF)",
1217
+ )
1218
+ parser_init.add_argument(
1219
+ "--debug",
1220
+ action="store_true",
1221
+ help="Enable debug logging",
1222
+ )
1223
+ parser_init.set_defaults(func=cmd_init)
1224
+
1225
+ # Test command
1226
+ parser_test = subparsers.add_parser(
1227
+ "test",
1228
+ help="Test VLM extraction pipeline on a single file",
1229
+ )
1230
+ parser_test.add_argument(
1231
+ "file",
1232
+ help="Path to intake form image (PNG, JPG, PDF)",
1233
+ )
1234
+ parser_test.add_argument(
1235
+ "--vlm-model",
1236
+ default="Qwen3-VL-4B-Instruct-GGUF",
1237
+ help="VLM model to use (default: Qwen3-VL-4B-Instruct-GGUF)",
1238
+ )
1239
+ parser_test.add_argument(
1240
+ "--max-dimension",
1241
+ type=int,
1242
+ default=1024,
1243
+ help="Max image dimension in pixels (default: 1024)",
1244
+ )
1245
+ parser_test.add_argument(
1246
+ "--jpeg-quality",
1247
+ type=int,
1248
+ default=85,
1249
+ help="JPEG compression quality (default: 85)",
1250
+ )
1251
+ parser_test.add_argument(
1252
+ "--clear-context",
1253
+ action="store_true",
1254
+ help="Clear VLM context before processing (fixes memory errors)",
1255
+ )
1256
+ parser_test.add_argument(
1257
+ "--debug",
1258
+ action="store_true",
1259
+ help="Enable debug logging",
1260
+ )
1261
+ parser_test.set_defaults(func=cmd_test)
1262
+
1263
+ # Dashboard command
1264
+ parser_dashboard = subparsers.add_parser(
1265
+ "dashboard",
1266
+ help="Start web dashboard",
1267
+ )
1268
+ _add_common_args(parser_dashboard)
1269
+ parser_dashboard.add_argument(
1270
+ "--host",
1271
+ default="127.0.0.1",
1272
+ help="Dashboard host (default: 127.0.0.1)",
1273
+ )
1274
+ parser_dashboard.add_argument(
1275
+ "--port",
1276
+ type=int,
1277
+ default=8080,
1278
+ help="Dashboard port (default: 8080)",
1279
+ )
1280
+ parser_dashboard.add_argument(
1281
+ "--no-open",
1282
+ action="store_true",
1283
+ help="Don't automatically open dashboard",
1284
+ )
1285
+ parser_dashboard.add_argument(
1286
+ "--browser",
1287
+ action="store_true",
1288
+ help="Open in web browser instead of Electron app",
1289
+ )
1290
+ parser_dashboard.set_defaults(func=cmd_dashboard)
1291
+
1292
+ args = parser.parse_args()
1293
+
1294
+ # Run command
1295
+ if not args.command:
1296
+ parser.print_help()
1297
+ return 0
1298
+
1299
+ # Configure logging - WARNING by default, DEBUG with --debug flag
1300
+ if getattr(args, "debug", False):
1301
+ logging.basicConfig(
1302
+ level=logging.DEBUG,
1303
+ format="%(asctime)s | %(levelname)s | %(name)s | %(message)s",
1304
+ datefmt="%H:%M:%S",
1305
+ )
1306
+ else:
1307
+ # Suppress all logs from gaia modules for cleaner output
1308
+ logging.basicConfig(level=logging.WARNING)
1309
+ for logger_name in [
1310
+ "gaia",
1311
+ "gaia.llm",
1312
+ "gaia.database",
1313
+ "gaia.agents",
1314
+ "gaia.utils",
1315
+ ]:
1316
+ logging.getLogger(logger_name).setLevel(logging.WARNING)
1317
+
1318
+ return args.func(args)
1319
+
1320
+
1321
+ if __name__ == "__main__":
1322
+ sys.exit(main())