haiku.rag/tests/cassettes/test_rlm/TestClientRLMIntegration.test_rlm_aggregation.yaml
2026-02-06 12:07:03 +01:00

2824 lines
197 KiB
YAML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

interactions:
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '108'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
encoding_format: base64
input:
- 'Sales report Q1: Revenue was $100,000.'
model: qwen3-embedding:4b
uri: http://localhost:11434/v1/embeddings
response:
headers:
content-type:
- application/json
transfer-encoding:
- chunked
parsed_body:
data:
- embedding: MEiTuB+tUrxEqQi9spEBPZZ3JLqnuS49puRkPcaWbz3YXoI8I6hwO96m87zf65u8U5ywO7sYH73xPZ48RFiRvHy6KzyWNE+7kZIFPMxAHbtl/i27XWBfPTkjJj2U8Yu9X/ZuvB/SprxBh6q8GsguvZeUaLz5cpq8YOcvvdXPAb3SQio9uryKvLTGZjpH1qE7VfOHPBw/b7sgJ5Y7GTxSO4i0OzyYDai8InEWPLi0xzv9qKu8Y80uvL9jDDx9em88f4kUvFigBL1iAsy6MtmiOx1XZ7365nq8s/SAPLU0LDwk2qc8ccmJujMPMb2mfWi7kHbtu4yDsrkhrMi82mHGO4IfHLzKFdm8GYn3uzf1Ab0oxJ47HhSZPEpzsjz0z2y6d3FOvKPr4bjQqpY7/glrvEaXhbwUE588NwHUu7OkADyIxLI8C/T9u5MhAjx2t4I7sAZEOxMzODzgA3G8/0aGu1pLE719QtK7QYPpOeXcED1yooA7zuyDPDQ0MTxfTQA8xlJ/vGUTX7xUiKg6IyKcO6S4mrvooIq6pTkYvTRGmLwq6vO8XBAFvM5QNTpKZp88NIazO4IjWjwoxnO8qpnQu+ZTZDw3VrQ6raASvEwcITzAwgW9o3m0PD0Is7srrFi8TR4yvCB/4TwTxyU7BsVsu2o4ADx34a08/vzsugQZkDz3ezy8rDbLPBaMW7xH+wm78PxnPAhmjDk94Hu9evtIvF9BbLwtv6c7IfVIvBdqlzykWXK76GMDPNMa+TvQ4jm8QFsavDWyRLwcmuk7jrYwOp1alzwtAFc7Gf2gPN7jrryTWiC66lHVPHFkLzq19oc8EVg/vBd8RTxOp3S70WvAPNzmhrxjsIE8j0KqvAFfVD3mPHs7rbNmPGbMy7sNnYE85Hl6vA+bWDxscUg8Gi2bPHKYtryozj+8trOXvHxTUTyRF428uulavBvm07v7J7G8kDPZuwTgLDyFbGI8hzWGO4aJFzzo9S47TE0wvLqDVDuom4u7AZyCu/6Ul7zT+Za72KROPF4GPjwxdp+7EolivBhL37sOAIA7zcdJO3Q6OTydZGk8YRasO4U/kLyTZTW7lLiuvJ/ymTvkM0y8otu7O8vGMzwtK7y7PLyMPBBln7zy9Gm8q1acvCceM7o0wCM7y+eBvH2gK7yy3Tk7oLQrPenuczy1wsm7+sV7PHsDobyU7vy8tWO5PE89cLwVxZs7kjkbuu6aTzzIVUc9u1SAPMkIu7sJ1Ya7m/41vPx1ET3xoMO8x2Cyus0NSbstelK89na3PGefRLynt3A7jxKwu7xyCTx+q7m8lX6fuy3cdLvo3EQ6CK0evI2uqbn8SKo8jtMBO99tmbzce9c7QsjeO2zPIzy+b0y7gu+iOxTYXTvtwPo70D9KvGUAubz32hs7dwuavN5KSTv07oE7K9kMPCLj8jvYdQq9JciyufksxLxD0VS8DNmAvJC/7Lsc1Va8+DKDO9KGRjsz4kM73Y3OPKfS+bxB8hM81VGDvDLPmbyk0IW8wXXQPKQY7TzJYiA7W4rYvC7e+LqwnZA7Elw1vaJ1hjyYDCA7r0TpvGA+Dj3bk7U8tikUvFyjBrtWCJy8EJNsPM7gxbkpsrW6vGIQPD3hpTtoPyg8xpOmvA5+vDwcycs8I6iGvZpKCbzvJnI7pIrYuyK8NDx+BBW8ofCpOm/NK7yFsQS8V/wRvV9O1rzUzgU8AT/zvEH+aLpoHEu8R+6qvJwebjs/eas7fpHku3zswDx+IDI8gvoXPXIB0zzlaR29mBUXvIZIo7pUZkM7zURWvIjR5Tykr2o8E/ejO/Q7ULbgOaS89NqhvOYfCb0zjL+83ZOzvJYORbxsjqA81ks3vYCk8rzQZJS8ciTDvBgG3rplv2y8SBNbvGrs0TqxWU27O3rAO4EsnDxV3zq8duB9u/3AtTxBs4w69+FkvOY9Kjuuiim8FIKoO7ST9zximT88he3avPP1lDqu4pO7PwFLu2E8I72rWKS74fGCu/0fA7x5Z9i8jscvPG2RKzw3KV48y/v+PJVYa7x8I0U8Moe7uyHPQrxmV9m8YknovFTtqDwPOQk9aEjbO3DXR7zCkw88EEc7PCYRIb2rU9c7iXOIuuIwfbwMgba8sAvuvHwaDjxA71W94II+vaHdorzi9Qi9Gz7zvP5KXLtShcg8wq2QPN/rZrsUnOI7cD0cPE5y47m9TQu88R+ovCl0g7taaQQ8acedvKV8BLwpii08MQcoPFzI2buJrLC8ZzCXu0qSOLsS+YA864OSu2DWSLzfmZC8joIFvI8KXTyPC6o7NsTwPGrOVjzZxie84PQjPbY3orx3N808+fWQPOO5T725hoo7MD0MvIXmuTyD1pu75HqlvDzc/jurL6o7h0VHuvXlYD1wp5U8PB8fuyqvITu3M/y7GA2vu/oerbyf85U8aR/vPCxOx7zKca28qVCIPG5pV71Fpuk87D3QPDsPjLw15zq8sQ7luyFGBb3+vpw83fikPPxd7LsIodK7xCS9NvC6zjwBmZi83NIFPBpC8jxZlke8I+Wiu/gPWzyYWss8aC2APYNLbTyLepc89w8NPQjqvrw+FnM7ssO8PICNSzxZBIQ7t8Pyu69+mzxAqcA8CxIOvfzp57vIZpE8eGYPvM1iDztLldG8Hya9OgFvCjxBt8M8wCuDu7KBHLw9DUq88GGsPN1ng7o0H6u8R37XuX73l7ycuZo7BwCqPJFl+DtNFkI6e30Kvb05jDzWagk8RHkCvQhTmLy2EAU9btjdvEnj/bs4pf+7OSkbvDsyjDzqFai8tmIZPdXfcTzP2o+8HG1hPHuqSrz//Ss8piaePPjtED0pQAg9tmeDvVY8zLzvXgA9uHh2PFUXPbztFQ48tzugvJTOALxMqGm8AnbWvI7i2zxJ91U8Vmf1u1eFOr3+aVC8MGr1PDhipDxZQkA6TnMlPS41rrxqpgU98K5kPQmmsDtzAIc8zzYEPG6lWzkahhA9DnZpvM+DNLzj46g8cG68PHzHF70n7aw82Rt7ulMuxzu2LYC8fDYPuCEezDwrmHK7H5+wPGr0jzyywXG8MXTqu739lbw8o9c8UzLwOxK3F7nVSne8Ue1mvGc/aDzDoTE85acaO0KBPb1XL6Q808CiPJDOzDyORY+7yn+BPFuXAT0NPCM8FYuxPCC10Lw3VWY8gTsQvBNt4byuTH+8HOmJPPWR37s4Awi8glVzOu1Y8bx2+t07KPfcO/3vozwV21I8Bn5JPKtyILt8g8E76jrTvGWXiTw8tzg8tM/fPFCFmzroUhO6hv1VvJIH57vWpiq8QfG9vHdnML1iO2S5MLuHu7CSW7kdgE+8FG2tPPbRgrzHYtc8n8HcPPxuTDzAEb48KjzSvE3LfjzV4QC9jtUivT1Bhrwm8qY8rZv7PPxajTxvPlA8b2C0PLSmXTy7EiQ85+WqvIOs3bxRstY8hxiivJDqFD0jC3m8oImFO7e9frswz528zwmkuLwICb2OeFe7oL9yvDHl3DyFT4W7/lYFvfQN+ryox/87p+ZoPB8N87ySTxO6nOjNu+MN6bwi7xQ9GjZRPILnFjtAmjS8LcgzvB8bt7oTNtE7HN2ovPT5nDyrm1K8n8kOvMXNZLt3gaq8eXJFu+NbjjuGyK86PSIMO10oKLzbLHQ8C+fXPIiY1TyvKhI9vbusu/z6Mr290gg6UU6BPHBwsztxypq8ToQ/vEsJ2DxlCDy8TE8jPI8/Pjyryus8UGwTvHghhTwOf4+84T3yPMJtrjzbA5o8XuBlPGAJ7juMFai7Z/CYvKumETtloCM6rPRtu79Gv7vDdkm8hgXrOwc6irueBc+730ugOOTOp7yAlu+7BrmJPOhCIDyXaFg5fM20u5o1hryEL447cUQePSfiHLsI6DU70dAgOwK6EzwmTzA8xD+Ru1VYSr1MXce72h4JvHs3sbyrtLC7iv3Yu7cTzTthO888uLNrvIumAz2o9wg8jYuvvFYSGLx+0Kq8PraOvKS6azzoCw87nG8SPOcGGL3QA7w8i+uePLO5ejv3OBE9RP3Nu+HX+TqEitM7z2YkvB66vbxAk+y8zDnUPB4xtTwyrlS8B/8+vOjDZTvLegO9akSZPKju5js/Vvy7UwFRvDL7VTyj+iC8SINWOypLGTyKGwc7rbdovLdKiTsiAUk79d/GO77om7uYHww8ltZtvYZ1AbzGw3g8a6NdvKDP3TyT8Rs8pOnyvP7iILuzWAw9suMtPAqXHL0GjlG9tJdjvYmVT71VFqQ8FLmuvINqlTxmFy89qCLGPFi9WDwhhRQ7dMfruwh8bTt6Eee6Vgb6PNdybr2eYw+9ruXlvKc9NLslTJS8HJPBPOB1VLwXJIw8KckVu396ojwMxQQ8iKCEPKYVULyrTnM81SoPvL9YDzxq7BK9OiuiOjxK3TwcfIq8aDnQvDPF1LyzIBw8aJPru9TVDL0RZ4Q8NFtjvXDZYr1QNtW8MOAlvP1BtDuLL9Y8ebk0vMVCBL07Ffg8w00WPRsYBTxRgue8LkhlPL1CrjzNnkU9hvMtvY8q4jzTjF87ZqgvPOaICzz8T588WZPcO3bIJ7yi1E28eSk+PB9Qh7uV2hO8LqN5PINYmzxmC6E8UgwRPMNWnzzzgwO9VlYhPWC5tjwmVyo9cLERPFHLKDz2hSA8QSO6vLLl6rqPK927tNiIPK6C+zvNiou8n1oIPb4jkzxkFpy8j9GFPYXKyjwodJk8mIeRvHAAz7u9GpC8nTGrPCM2m7sqKyK8B1KsvDDgejwutAM8HQL9vM4e8Tw4eI+86aj+Ovc1mzwmAnG7amuoPChJAj32a5s8JDwMve0cMjzOgM07/sotOz67WbrcvoW8dC04vFdXV7p76wM7gQRlPE9Il7x60Aa8py75vBO1wLz9UCQ7SY+6O54vUbvNVk68Q7OjPPy1Srzhq9w5nkCFvBf+rbzByAq7JkLbvE9zJbxD1RS8Jwv9uy7xzrvIArm72asVPW2ERT33DYk8WRxNvOZQy7t+iUG7/x/4uxy+BD0wSza8CKPoO39iKj1fKvk8ZgudPFD5F7tEKAs8xBm3vGGHWT3UtNE8atSBvJEqr7mqpIo8MCHHvH1DaTyZtI88No4ivdbP/ru/WJk8/xClPFcd2DzvF9m8+4BlPB+IeTr+TAE7lv3QvPSdxLxlMQq74oSBvGH4hbxYoY6832g1u39v6zt9tqY8fYnePB4ZpzxiPOi8qfQ9OwMPejyJeEe871nSvC52Ab3znaw7c3LrvJ41bDu7LEW8y0l9ukbIT7yzKd274y+Wu9EwJzzmD748d8akvOC1kTxlCJ48VKIiu6alnTxYkwc8jsBbuto0z7xe1k88VuMyvX5dHz18oq88d96tPLeyTby4fAK66W8MvK8zZjxuRtm77tJGu4zBp7x8uho8PVGKPAz5B7zv21w68iiAvFBc0rzDfYm82zQJPbsShTxnuTC9+OMGPFW+C7x9k4I8qN7WO9eCvjsAFpi7q4cKvFNT0zu/emq8LpANvK2YYTz69+Y7FAMEPBvt/LuEm8C8SIRvO4YyTju/o1Q7/dd0vFEGQTz3GsI79X1wu5sWibw7nJ88QAnou+3Dczx6rfM6LyV8PL9/ELyqhiM9Yx5eOubJf7vlRMo7nyCLPEuzu7xWY9a8MXACveVk3zy9oaa8ydXEvMiSyjoOvJI7Ukohve+jGjvu6w29GP0FPCtY3LskMnO7YXNZO7OUlbz426+7wnBfPFoA/rtzHHu8Dd2+vDXYmDvgTW+88zgEvD3Ig7wwwU27Cqq1PIQaurw0wVE8Bp1YPFXyDLx8J568nGtOvbZAbTz9tS08PV+uu5tXqzwlF5g85UhxvGGCBjxxPYy8L95xPRrUETxMrX48dkCFvHd4pTxr9Wy9kBM+vGDedbzMS+Y8lqS5Ox70jDzo2k467GQCPTsb7zsp0Tw8tgjsu/4KKbz80m68/PURvdn7vDxBo2O8uy8nvJ+EQTz3Riq9mgptu5ixQTv7Zzs9+cqvPINY2jrk3mw7oEavPFPEfjvHMcm8Zc7qPHLg9zxr+xU7QVMSvQlgGjwJdEE7tDj1OzqHvztc/M48ZuW4vM1U+LvqMzw9JQylvJtwAj3RouE8cycevUvaN7yMrdM6WRvwvEqWjbsPBuQ7WG5qvCEebjrxmQg9BZvkO+A3CT3vddk7Q9N1PLtFuDsGvIY84K2GO9oZCj02E9i8ixNMPIULpDvYdIi8GhGEu8j07rwocb86kNkdux4dHbxJDwu6n6MkPZOD9Lt0KIM8PIAOvcHx3Ts3Px28O/hUPICotbw1taI88eDNurOEMD0MGrO7ePSTvGfGJjx6YJY8LZzbvCqX7byU17a7SwhxPOCsk7wv93s8cweDvEILK71PHSa9opShPKJlkLrTW5O8e6Dgu08gULyW09Y8+bGqPOOMELzRzwG8a9BvPSyFvDtIJJs8zM5BPBjwcDyFilC9MeYeuj53iTwIgJk8rGYsPHf5vrs2c4G7OB4QPNQKlTpi45C8Gr+hvMQrB7xKV0e8HB67u9DWyTxnbzY6eP8TPQsplTuLEyo9iFpSPNu0YbvdiuG7fC9yPPThqbzZgKo8OLewPAnVqzzv+5s7xXcOu55U0TvilUY9OsFNvPd4urwkvEk8RgofPKdeuzv1CEs82Br6O+fZH7lv+7o8Aie6PHGalTx6EuY8ZXWYvCPTX7yOMaQ8Qs35vFr+z7z8osW7Hno6ujr3mjyCSRm7PVa3OnZv2jtTbJa8KJYZPQkP1zyBXOA8F8EHvObWMj3atpa7nD9UvEo9Kr3zyaC77iVEPKckk7qLo5K8/4D/u6Ncsbzl+MY7Py8DPaUFsLziQ8i8bkQQPWEebDx9Q+y7nUNjPE+B4Tykpca7GGhlvHAZwzy0PRM80OBsPE4etrvscS498nVNu1THw7sTz+K6FkLHvFuleLyUMuO7ND/+vLbyBT2jDRa78BkVPFvvwTwgffQ86KkmvFxcZzz12Ks7BoM4O6D1MzzdKYi8hpMhvbrOvbk3Uok698OiO//Wy7wYwzo89SSBPLqNBrsLaJM8+FiQvEMvCrzLqey70qzgPIto5DrcpKg8A4o3vOxZmjzAdri6HA+rO9HbZzxy3UE888GAu1VN1bzoy3+7MXCHO5p/w7xRxyK8n+FrvLhMt7waPa+8Whjjupe/qLxCHam86Nk+vLGSx7xKE+07f4+NPHKnc7w8L/O8+wWrPBIkVTvz9qO7SX1POlcCBD0U6O28vrgKPSDXjTwKVjq8s3wnOz3bnTyXNwG8kUgtvFMJUrsls6M5TygBPSGjBL0ASNE79PAhPYelQbtK1Pq7Ojm4PCNKYLumPzI8Huf2PJ+iezvdA9g714UXvBZBAz2kHgs8YGSmO3zs6Tyx2aw8IJSHPGcmDL20tQW8uZX4vHLEFjxJohk88eSHvNkivjzkkA68y5qFPPzsWTwK5Zg8RMiQvL0vbrzZc5087frLuyR5P7t/ReM7cwJLvB9CLb0RoWa8YqQHvReNJj1jG9G8k05XvNq0groR8RG9oo/NO0JpAL3yap+7QsLNO/Jpjzy/+Pi8paCCPPtJVzssaua7A8/HvDPxmDzlpAc7+adMPACJPTs/+9c8gRpbvFFuMLy9wQe98YCoO81tg7yZkVU8CYiqO7ofjTzSNtA8vuwvugNljrzwNP08DbAbPC8qODqZ21q8pNm4vGMM1rybnok7cQQWPEJMgbzTae08IrEzOw63t7uq7qw8NGTAu8dW/zxCJCK8TfzTPKZZnDweN7W6GLMIPLAJ5rwztVE6jUowPXJ5kLuBNI+8lAQjvGn8zbwx7xu902r9vIY2WDx/CY+8D3q0O5dVlTz8VG08wJ5iPKdHLr0bj988Fle4u3mZpTlkv0c85UmEOxjUWLyCQtm8nhqQPNq+BjxnfdW8Oei3PJQalDjbZlq8V+EJvdlNhjxoh4g869qEPD8EezseEQi9atwaOxahpTyju6i8d466usOekLuoaco8Odn4vCmIczwzihK8hRK1OyQrfLu65k08tuaTvH4drDwNypC8Vs89vFUm5ro/Wgy9y1ANvAS4JT0aQrw8VwoMPKcqGTxTuJC8SBXGvJ75A7zl4N28x6g0Pbn137yHQhM8sTUxuz40LzwO9KA8KSBYPHtQ1rx1dkg8RxXwu7oSIL31hJS7rxOVu4VP0jx78Bk9PaWAuur2MDy8Eci8TJhBvIWQBjxfbsQ8iTysvDCTzbrnMJg8dBDhuwaBtTycizs8V4rPukGAcjx4MJg8QeLavIZzozmLFoE8QH6XO8dT7DoZJAI7Ek23PJoWozwQtIS8+gIBvTCSDr35tt88feTKPKb1oDyKYd677B4BvEHiqbuEGJI8ze8MPfkOUrum9Y88p8hQu0+X1bsapvE8BOhsOwgiEzuhKQK7E08BvU2ehbxEqLC88/U8PJ52wbzfSZc85QaBPRMSdTv26fK891j6utzL2Lt3H0M9cqyHPDaBZ7zcdJm7fe+Uu2B5GLxYG0M9ETXxvF6ddzydvtw7ueW6PFYsz7w37Q+8qJotu80gqTwc/ow7jNwLvF5L1Tu6uDw9uS43vJM94bzsrZY8T+9yu9Fm+TzwlQU8y0zUPDJ1Jrw3gKg6mP19vHTpWDkzu+u7giZKvLFwFLuOWsw7hVayO0oWQbxqiac8KBQ1vYJw9Txi1Nm82eeCu3Adojx5olq9ts3DuvQjgzxn3Rk9VFqnPHbmlDvUVkI7RGPyvP87mTz6qwu8tPLtvJa9abxceBy7JrsIvCDsxTyofyy9VYurPMZHiTye44u8WN4cPGy+Tbw7Wt476PHBPN1ImLz2kai8WbKDvDXULL2FIRc7zQ7KO0j4jbv7MY68NNwGPRKsULyqWQY9yqcvvBWXBDwqy4g8a8GRvMyd+LvjPqQ8+9wwvOCXoTyYqZO8fHDEPG3Ggrqh/km8ci99PHqQDbyMNoC7r1jyu1WtOrx+OeQ7cZmgvJ4h3jy29UA73dogvMciBDzY4hE9RgtHvGxBWDvOWp66L0BfvOSx4LsKSag6f25avFBeu7i/sUK9V69BPAkXlrteXF+8KbA0PKETO7lBmga9/lU8vAbYF71Q1GG7ToKUOj+zujzRwZk7qlHZO3+uwjy4VAw55fkvPGIvzTw2WxQ9m5CoPMsUJTyPW2o8zNiQPAS6KTzSnHo7rEXhO1tZszxYW787mEe8usvapzu6+RM9odHUOolOAz1GkDy9AECgvIX3+LwCR5G8KUOwPHbVkLw3Gdi8mzO5uwG3xTy3mOC66ckuPOYBpLxuiKI85yDdO/kIWzxYlsw8l8pGvHVD3TxxPwg8NZyoPG6UqLmt93G8rMgKPYMewjvYI648cASOvGxLgTuZLfq8V5LNvL+hGr195Cs7ld4+vF0pqbzmU4S7wkoJOxNIpLxYAKK8F9cMvCiS8TzIwC4898pKPF/yqryXUwO9nkQTPGhOAT2xhzw8nRqRvCKbPjx8bq88EVXrvBB8Hbspyxk8vbSLO67vdrsHroa8N9OrO2E6t7xRaIq817/qPDA0wLswwp281YnaO5/syzynZGy8mHsOO8oh5blBkx48oSeMu0sjDb3cpHE8PbImuzuIa7x2+3c8VC+LOs1V+jxKPwU8o1c/vO/2ijxRH1c9T2nTu6HxhLvKQy+8b5FsOgAuEb3GLt08hkbFvAuzTbvwb7C8tLCYvP6dizxsBMM8mSqyvN89prz9SCU9hKT2vLXm1jucLRg865mgOxQyrjtpRUy9FMwIva77sTya1dm8QymzPJzfRLxpE1894QSsvPISiDw2ctw8bYpAPNLf6zw8H5i8FA5pvHINgDtZaUY8og6BubBvuTyCtGe8LA8qvJ+8s7xgoow7GZYbOxmXKrtA/j47uSRCvBW0nTsvJK08jcQ5vAUidbySZjW5ZT2TPGZo2DwqWz48hpM5vNLPLb2r+cA7t2G2u4YoIzzIvwe9LQgHPM2TR7sHrfo8rbuDOyAkHT3W44m7LG1gu/eSrrxT2+E8cDmFPL+glTyQCgI9QdfKPMqhDzsI4qE878/fPBBo1LxnGS69/lETujioHT0Sn4w7g2K0OyS8zTvlCyK6JQcavKuPAjyQzIG6m7CrO/YnO71QAgY8AXzGPMqVkjk2zfi8daf+vFucYbxEKNG8QNMPO6SP8TzdG4k7yeyrun8hvLwChpQ7kOLcOlYzvzykE5+8/89KPAv3drzfqEm8O8F5PAO9YzzrGkc8LCGivMqVMbw+DwM7n04Tuy0T9Lux2N87hsXQO+9K/jz4jQa8hAZ9PHM4IbyTBDC6i2PCPOiq3rqqCnw7iD+DO+h9sLyZYqi8nX/5PKJnsryHeLU5ea17PIxaxrw4dhW9YKi2vNMhELwaut07GGpvvET7QDwIj0+8/UQ3Pf7CzztMDqq7yYjiPKmBJbyzrTK9HTN2vDXb0DxwfTI7+eJsvMtZITp3rEi7Z0QkPJdGyDsDRLG8fsdeOzJrvrzn8xq6DkNmuzXszLwClxw87gE9PfbPebspd8c7OtYmPIRecrxUaqK89EEfvK/FnDuQHZq8bswsu924EbzWkR49+0a6PBrSJDw7Lzs82vIfPA4VTz3Ccxs8z0uYu5Fj9jzX+DS8IZ9cvAzaxTyDkw09QZ1XPGUWKjxakKe8Eu3xOxKdWDpviwA8GbKTu5rjxLyiPNo7X33aPLizv7xo1gO93+x/vFISwrxEP9C7bzTDuXBRhDvN5eE8Mqn9O8tG7TwfpmW77X/ivK4xPD14WtW749dKO+Y14LzUB5y8nT0sPPYKgrvNWmS8mJsovJ+2Qby6Nl28N3jtvIDNWzySM9M8c5W6PEwJhrwkY1C9nRcQvSXwirwL8Pq7iCCnPO5+GrwBvrG6qA/GuzJIHrzBirK8e7SyPEqQuLtzGjy9y+WPu6julLu5vlS760TlPO8AwjsA3I28RiYQvA0LqruTvwM8MdwcvLWMRrr6d7a8dXBpPfodpbsz8e68plnpOkpBarySLX47c8zFPMLAkTwMx3C7/zwXvZXavzuxBZi7J52yugbAQznfOK28+YE+u+QByjtLOw29kyn2vCWgpDvbm/e6prstOwEwojyqxdS7SvoDvX7BlLw5kMK8417muvPZHr0z3o281Q/Zu38GDLy+1K+8983gPDHSxjvu8MY7Ib0BPGwk8jxC1Ew5SY7PvNdDjTzxocm71BKjPBMCQrxmvw88DAUBPT6NkzzLvIK8bvjpPGtlAjw1IUe8i9J/POIB3zs4cIe8S7HjPEBjuDu51uG8L0f4u+hMGT38F/c8XV+gPLpi97xzg3k8331svEoxAL3OYv+7Vq0XvFUEEb3ySbI7q9miu/z2L7uqbXa8zNL4uwdGjrx5BRq8foVqvLCwhrys07G8CwRJPK/enDyFNZg8lBGPvG4LMD0wvSq8NDiTOzlH2jwGeMo7EhTUO539FT3/xDu4NsQZvOsaXbyiDgy9GTW4O0rWCr0I4CY9qIEOPdctsTzi9aO8DcOduxzE4Ds+rwK9/MOdu86sQLupP847uf+CO8Yhj7zfVdg8oR04vW2HiDy96dK7wDH8vEWzADz+4YQ8EgZDvCYrwbtBcyM8tBXzu0T81DwH0qS8Je77Oyyqv7ylAXY8Ltvlu/hTHjz96LQ850MPvM3QzzpTd088pg7DPMBAD7xmcsE8QtcYvBdNabwavO46S6KAPItYeDwzLs68u377u/VivbwYSjI8OIGrvPydjzxz5PO8G8EgvU97t7yST/e8rE4HvA7lVbwVNN6862g4vGFDLL2vkeQ7ziM1va2CIzyS3f+7/itnvO301bygyTe8z5qJO8L4lTybEUO8gajcPFtBert3otC8aH1EPBe5SzyqKX28budHPBx7MTyOfQA9Yhv/PKSASrxewi+7YpEnPdmDYrytrtA7DLnruoY3vztJhmM7yijQvBY4a7xvWom7ebfruwBud7y72fK7aI/ovIuxN7ym8gE8zY3FvKsh+joRp/682n0FPSI2JLvVvXm7r7w9vH6KUbxo0KA8WZi1vCZhNTwbE+E7bGFsvCZXaD3G5588+ceVOxOZqzzReMC84xeGvH2WIr2UJY68T4YnvNneL7y+Yk28/hAvPK0miby/ES68jg74u0Z3ErsSE/a8O+TMu3PjebyWbJE8lGM2u6H6A72E93C80DNCvGfpA70kfVM8F5MIPK7pDTwD5C09SNEDPIwKpTze/4U7Gy7SvBZaertZEzM8eW0BvYRfqjx81xo9TmqgPMWiq7xHYTU8yycwPHQtyjvmmsE8tjVhvPGNOrzgeEI8bRP+vJm5ubzM7FQ8NG/QvH2bi7qUeaK84KwaPJJrXbz1Bhi8ZWtBvYnttrzmt6o83eqduyzHhDq8KVu8uXNIOq1/SzraZgy8yfgOvE4SALwZuLC73sywu/SvlLyPxpS8drs2PB1NbDk2fQk80q2SO/1WoDq/d2q8qW3VvKV5Fjv0YCC8FWOwPHCImrtTdXA5qFIJvABN2zt7iw28SDO4vBjpRjyL4G68ZknTPJhKCbwx7DK8XJAqvFDFujyrMk28bse+vPnWEb04odO7hfSEPNtKYzzJSJY8yA9EPGOu7LykHVW8UFGrPIxWALz9XWC8jRPAvGxyH7vNi5O5dynMPMIC+br/1bu8ixWPPNdl0Tylwqw8M2dWPEfCxTxGeb+6QsXgvGFYU7rhu6o7ZbR5vAJ1cDpkSrc79gMfOxdaxDpkAY26HFHkvF3l6bxFYos9rNAwPA9Q47z/faq8hWl1PFONxjzNu2G826fOPJCMDr23su48YN2LuwFQbbxUpWM8YXEdvDuQWzxm7QI7el8yvNrNx7sfalm8TbTOvOaUZrvKuP47muqVvOiQ4TxulGY8i+nlvFCdmLwJ+a08bueAPFnhKzxI3yc9gB0Fu5GRwLxPJhk8dwPpOuO6P7w9jJO8ejY8vFSqxbvVk3Q7bdpPvOE7AT1R0AE76zYZPOKeYbuC+DO83v2KvAFXpTyEcie9TYb5O18+1bzozTs8Y1T7PCXtpzucOzs8y7srPDafpjz3B5W8irIyPUTe27xDoFo58aXMO8RktbwPYim8Cj2GPPW07jwKYG+8ZNPTOwFk9LsQOLO8BYMVPAfFArxCG+q732vNu3g8QLsiW4+80/jXu76t1zwOwKa85diuu4pIsztgOHO84F1GvIjrXz0XeQm9l/rkvBG1gLw5TgK6UHTsPDPQezwkxy08IrXvOuMb6LrW7QC88toJvbpCoDw4+jo8Rm4aPP9TsLzCzcE8irEXPHS0zTygsVm8r98FPYyN8LqKDso8L3hhPLBvy7xC3bw8KPuHu1x6+Ly/ZDO8fdgOvaDH5boUMKU8pmahvKOqDruYbXM8vU+vuQCoiDzaCAY9gs2XO0O3T7zRVQO9g3IGve4tCz17V5y8EKBwPC1uCb1kfw28zL2bPCIulbqwAMc8wVC4vBwcoLxaMkc8nlLuOvX91byWqwg9A+mSvCj3/7wxILA5hungPC+1M7zksLW64tl3PKto6ztlb2I8e4kEvakJLzvOCzO8c6ldvKGFhLylkzS7uN6XO8OFMLw6Nkq8xw8lPUFZnLvFFVG8/fqyPC6U9jvKp9M8ne1LvPcsRbyIP1Q7dtUUvA==
index: 0
object: embedding
model: qwen3-embedding:4b
object: list
usage:
prompt_tokens: 17
total_tokens: 17
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '108'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
encoding_format: base64
input:
- 'Sales report Q2: Revenue was $150,000.'
model: qwen3-embedding:4b
uri: http://localhost:11434/v1/embeddings
response:
headers:
content-type:
- application/json
transfer-encoding:
- chunked
parsed_body:
data:
- embedding: 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
index: 0
object: embedding
model: qwen3-embedding:4b
object: list
usage:
prompt_tokens: 17
total_tokens: 17
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '108'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
encoding_format: base64
input:
- 'Sales report Q3: Revenue was $200,000.'
model: qwen3-embedding:4b
uri: http://localhost:11434/v1/embeddings
response:
headers:
content-type:
- application/json
transfer-encoding:
- chunked
parsed_body:
data:
- embedding: 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
index: 0
object: embedding
model: qwen3-embedding:4b
object: list
usage:
prompt_tokens: 17
total_tokens: 17
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '7702'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '695'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: ''
reasoning: We need revenue from quarterly reports. Search for "quarterly report" and revenue.
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in
results[:5]:\n print(r[''document_title''], r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
index: 0
type: function
created: 1769703355
id: chatcmpl-273
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 87
prompt_tokens: 1601
total_tokens: 1688
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '94'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
encoding_format: base64
input:
- quarterly report revenue
model: qwen3-embedding:4b
uri: http://localhost:11434/v1/embeddings
response:
headers:
content-type:
- application/json
transfer-encoding:
- chunked
parsed_body:
data:
- embedding: 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
index: 0
object: embedding
model: qwen3-embedding:4b
object: list
usage:
prompt_tokens: 5
total_tokens: 5
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '8540'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '635'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: ''
reasoning: 'We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.'
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
index: 0
type: function
created: 1769703357
id: chatcmpl-775
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 85
prompt_tokens: 1812
total_tokens: 1897
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '79'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
encoding_format: base64
input:
- Q4 Report
model: qwen3-embedding:4b
uri: http://localhost:11434/v1/embeddings
response:
headers:
content-type:
- application/json
transfer-encoding:
- chunked
parsed_body:
data:
- embedding: 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
index: 0
object: embedding
model: qwen3-embedding:4b
object: list
usage:
prompt_tokens: 4
total_tokens: 4
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '9198'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
- content: |-
<think>
We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
type: function
- content: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_mgo4t2ty
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '663'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: ''
reasoning: All quarterly reports 1-3 only? Maybe Q4 is in separate doc. Search “Quarterly Report 4”.
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_3d3jutqn
index: 0
type: function
created: 1769703359
id: chatcmpl-718
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 84
prompt_tokens: 1975
total_tokens: 2059
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '88'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
encoding_format: base64
input:
- Quarterly Report 4
model: qwen3-embedding:4b
uri: http://localhost:11434/v1/embeddings
response:
headers:
content-type:
- application/json
transfer-encoding:
- chunked
parsed_body:
data:
- embedding: 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
index: 0
object: embedding
model: qwen3-embedding:4b
object: list
usage:
prompt_tokens: 6
total_tokens: 6
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '9893'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
- content: |-
<think>
We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
type: function
- content: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_mgo4t2ty
- content: |-
<think>
All quarterly reports 1-3 only? Maybe Q4 is in separate doc. Search “Quarterly Report 4”.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_3d3jutqn
type: function
- content: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_3d3jutqn
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '1144'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: |-
<think>
It appears only Q1Q3 reports are present in the index. We need revenue figures from each. We'll retrieve the full text of each report and extract numbers labeled “Revenue”.
role: assistant
tool_calls:
- function:
arguments: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in
docs:\n content = get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n"}'
name: execute_code
id: call_2rg8jz4m
index: 0
type: function
created: 1769703364
id: chatcmpl-874
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 204
prompt_tokens: 2139
total_tokens: 2343
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '11457'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
- content: |-
<think>
We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
type: function
- content: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_mgo4t2ty
- content: |-
<think>
All quarterly reports 1-3 only? Maybe Q4 is in separate doc. Search “Quarterly Report 4”.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_3d3jutqn
type: function
- content: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_3d3jutqn
- content: |2-
It appears only Q1Q3 reports are present in the index. We need revenue figures from each. We'll retrieve the full text of each report and extract numbers labeled “Revenue”.
role: assistant
tool_calls:
- function:
arguments: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in
docs:\n content = get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n"}'
name: execute_code
id: call_2rg8jz4m
type: function
- content: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in docs:\n content
= get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n","stdout":"{''Q1
Report'': None, ''Q2 Report'': None, ''Q3 Report'': None}\n","stderr":"","success":true}'
role: tool
tool_call_id: call_2rg8jz4m
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '558'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: ''
reasoning: No revenue found by pattern. Let's inspect content snippet.
role: assistant
tool_calls:
- function:
arguments: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n"}'
name: execute_code
id: call_oqz8cbe0
index: 0
type: function
created: 1769703365
id: chatcmpl-151
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 52
prompt_tokens: 2528
total_tokens: 2580
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '11977'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
- content: |-
<think>
We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
type: function
- content: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_mgo4t2ty
- content: |-
<think>
All quarterly reports 1-3 only? Maybe Q4 is in separate doc. Search “Quarterly Report 4”.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_3d3jutqn
type: function
- content: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_3d3jutqn
- content: |2-
It appears only Q1Q3 reports are present in the index. We need revenue figures from each. We'll retrieve the full text of each report and extract numbers labeled “Revenue”.
role: assistant
tool_calls:
- function:
arguments: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in
docs:\n content = get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n"}'
name: execute_code
id: call_2rg8jz4m
type: function
- content: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in docs:\n content
= get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n","stdout":"{''Q1
Report'': None, ''Q2 Report'': None, ''Q3 Report'': None}\n","stderr":"","success":true}'
role: tool
tool_call_id: call_2rg8jz4m
- content: |-
<think>
No revenue found by pattern. Let's inspect content snippet.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n"}'
name: execute_code
id: call_oqz8cbe0
type: function
- content: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n","stdout":"Sales report Q1: Revenue
was $100,000.\n","stderr":"","success":true}'
role: tool
tool_call_id: call_oqz8cbe0
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '855'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: ''
reasoning: Need to handle different phrasing. Search for "$" pattern.
role: assistant
tool_calls:
- function:
arguments: '{"code":"import re\nrevs={}\nfor d in [''Q1 Report'',''Q2 Report'',''Q3 Report'']:\n content=get_document(d)\n if
content:\n vals=re.findall(r''\\$([\\d,]+)'',content)\n if vals:\n rev=sum(int(v.replace('','',''''))
for v in vals)\n else:\n rev=None\n else:\n rev=None\n revs[d]=rev\nprint(revs)\n"}'
name: execute_code
id: call_2j8yqv8s
index: 0
type: function
created: 1769703369
id: chatcmpl-192
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 139
prompt_tokens: 2641
total_tokens: 2780
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '13113'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
- content: |-
<think>
We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
type: function
- content: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_mgo4t2ty
- content: |-
<think>
All quarterly reports 1-3 only? Maybe Q4 is in separate doc. Search “Quarterly Report 4”.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_3d3jutqn
type: function
- content: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_3d3jutqn
- content: |2-
It appears only Q1Q3 reports are present in the index. We need revenue figures from each. We'll retrieve the full text of each report and extract numbers labeled “Revenue”.
role: assistant
tool_calls:
- function:
arguments: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in
docs:\n content = get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n"}'
name: execute_code
id: call_2rg8jz4m
type: function
- content: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in docs:\n content
= get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n","stdout":"{''Q1
Report'': None, ''Q2 Report'': None, ''Q3 Report'': None}\n","stderr":"","success":true}'
role: tool
tool_call_id: call_2rg8jz4m
- content: |-
<think>
No revenue found by pattern. Let's inspect content snippet.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n"}'
name: execute_code
id: call_oqz8cbe0
type: function
- content: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n","stdout":"Sales report Q1: Revenue
was $100,000.\n","stderr":"","success":true}'
role: tool
tool_call_id: call_oqz8cbe0
- content: |-
<think>
Need to handle different phrasing. Search for "$" pattern.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"import re\nrevs={}\nfor d in [''Q1 Report'',''Q2 Report'',''Q3 Report'']:\n content=get_document(d)\n if
content:\n vals=re.findall(r''\\$([\\d,]+)'',content)\n if vals:\n rev=sum(int(v.replace('','',''''))
for v in vals)\n else:\n rev=None\n else:\n rev=None\n revs[d]=rev\nprint(revs)\n"}'
name: execute_code
id: call_2j8yqv8s
type: function
- content: '{"code":"import re\nrevs={}\nfor d in [''Q1 Report'',''Q2 Report'',''Q3 Report'']:\n content=get_document(d)\n if
content:\n vals=re.findall(r''\\$([\\d,]+)'',content)\n if vals:\n rev=sum(int(v.replace('','',''''))
for v in vals)\n else:\n rev=None\n else:\n rev=None\n revs[d]=rev\nprint(revs)\n","stdout":"{''Q1
Report'': 100000, ''Q2 Report'': 150000, ''Q3 Report'': 200000}\n","stderr":"","success":true}'
role: tool
tool_call_id: call_2j8yqv8s
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '995'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: stop
index: 0
message:
content: "**Answer**\n\nThe total revenue reported across the three quarterly reports is:\n\n\\- Q1 Report: **$100,000**
\ \n\\- Q2 Report: **$150,000** \n\\- Q3 Report: **$200,000**\n\n**Total Revenue (all quarters combined): $450,000**\n\n**Key
Findings & Sources**\n\n1. **Q1 Report** revenue extraction from the text \"Revenue was $100,000.\"\n - Source
snippet: *“Sales report Q1: Revenue was $100,000.”*\n2. **Q2 Report** revenue extracted from \"$150,000\" in
the document.\n3. **Q3 Report** revenue extracted from \"$200,000\" in the document.\n\nAll figures were obtained
by searching each document for dollar amounts and summing them. No Q4 report was found in the available documents."
role: assistant
created: 1769703373
id: chatcmpl-568
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 180
prompt_tokens: 2941
total_tokens: 3121
status:
code: 200
message: OK
- request:
headers:
accept:
- application/json
accept-encoding:
- gzip, deflate, zstd
connection:
- keep-alive
content-length:
- '14838'
content-type:
- application/json
host:
- localhost:11434
method: POST
parsed_body:
messages:
- content: |-
You are a Recursive Language Model (RLM) agent that solves complex research questions by writing and executing Python code.
IMPORTANT: You MUST use the `execute_code` tool to run Python code. The functions described below are ONLY available inside the execute_code tool - you cannot access them any other way. Always execute code to answer questions; do not just describe what code would do.
CRITICAL: Inside execute_code, these functions are ALREADY available in the namespace. Do NOT import them - just use them directly:
- search("query") ✓ CORRECT
- from haiku.rag import search ✗ WRONG - will fail
You have access to a sandboxed Python environment with these haiku.rag functions (use them directly, no imports needed):
## Available Functions
### search(query, limit=10) -> list[dict]
Search the knowledge base using hybrid search (vector + full-text).
Returns list of dicts with keys: chunk_id, content, document_id, document_title, document_uri, score, page_numbers, headings
### list_documents(limit=10, offset=0) -> list[dict]
List available documents in the knowledge base.
Returns list of dicts with keys: id, title, uri, created_at
### get_document(id_or_title) -> str | None
Get the full text content of a document by ID, title, or URI.
Returns the document content as a string, or None if not found.
### get_docling_document(id_or_title) -> DoclingDocument | None
Get the structured DoclingDocument object for advanced analysis.
Returns a DoclingDocument object, or None if not found.
See "DoclingDocument API" section below for how to use it.
### ask(question) -> str
Ask a question using the QA agent with RAG. Returns the answer as a string.
Use this for semantic analysis that benefits from LLM reasoning.
## Standard Library Modules
You can import: json, re, collections, math, statistics, itertools, functools, datetime, typing
## Strategy Guide
1. **Explore First**: Start by listing documents or searching to understand what's available. Document names may differ from filenames (e.g., "tbmed593.pdf" might be stored as "TB MED 593" or similar).
2. **If get_document returns None**: Use `list_documents()` to see actual document titles, or `search()` to find relevant content.
3. **Iterative Refinement**: Run code, examine results, adjust your approach based on what you find.
4. **Use print() Liberally**: The REPL captures stdout - print intermediate results to see what you're working with.
5. **Aggregate with Code**: For counting, averaging, or comparing across documents, write loops and use collections.
6. **Use ask() for Semantic Analysis**: When you need to understand meaning or interpret content, use the ask() function.
7. **Cite Your Sources**: Track which documents/chunks informed your answer for citation.
## DoclingDocument API
When you call `get_docling_document(id_or_title)`, you get a DoclingDocument object for structured document analysis.
### Properties
- `doc.texts` - List of all text items (paragraphs, headings, etc.)
- `doc.tables` - List of all tables
- `doc.pictures` - List of all pictures/figures
- `doc.name` - Document name
### Methods
- `doc.iterate_items(with_groups=False)` - Iterate all items with hierarchy level
Returns tuples of (item, level) where level is nesting depth
- `doc.export_to_markdown()` - Export entire document as markdown string
### Text Item Properties
- `item.text` - The text content
- `item.label` - Type: TITLE, PARAGRAPH, SECTION_HEADER, LIST_ITEM, etc.
- `item.prov` - Provenance (page numbers, bounding boxes)
### Table Access
- `table.data.num_rows`, `table.data.num_cols` - Dimensions
- `table.data.table_cells` - List of TableCell objects
- `cell.text`, `cell.start_row_offset_idx`, `cell.start_col_offset_idx`
### Example Usage
```python
doc = get_docling_document("My Document")
# Get all headings
headings = [t.text for t in doc.texts if "HEADER" in str(t.label)]
# Iterate with structure
for item, level in doc.iterate_items():
print(" " * level + item.text[:50])
# Extract table data
for table in doc.tables:
for cell in table.data.table_cells:
print(f"Row {cell.start_row_offset_idx}, Col {cell.start_col_offset_idx}: {cell.text}")
```
## Example Patterns
### Counting documents matching a condition
```python
docs = list_documents(limit=100)
count = 0
for doc in docs:
content = get_document(doc['id'])
if content and 'keyword' in content.lower():
count += 1
print(f"Found in: {doc['title']}")
print(f"Total: {count}")
```
### Aggregating data across documents
```python
import re
numbers = []
results = search("financial data", limit=20)
for r in results:
matches = re.findall(r'\$([\d,]+)', r['content'])
for m in matches:
numbers.append(int(m.replace(',', '')))
print(f"Average: ${sum(numbers)/len(numbers):,.2f}")
```
### Using ask() for semantic analysis
```python
# First search to find relevant content
results = search("machine learning approaches")
# Then use ask() to synthesize an answer
summary = ask("What are the main machine learning approaches discussed?")
print(summary)
```
## Workflow
1. **ALWAYS start by using execute_code** to explore the knowledge base
2. Run multiple code blocks as needed to gather information
3. After collecting data, provide your final answer
## Output Format
After executing code and gathering information, provide:
1. A clear answer to the user's question
2. Key findings from your analysis
3. References to specific documents/chunks that informed your answer
CRITICAL: You MUST call execute_code at least once before providing your answer. Never give up without trying to execute code first.
role: system
- content: What is the total revenue across all quarterly reports?
role: user
- content: |-
<think>
We need revenue from quarterly reports. Search for "quarterly report" and revenue.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n"}'
name: execute_code
id: call_8cd1wnf6
type: function
- content: '{"code":"results = search(\"quarterly report revenue\", limit=50)\nprint(len(results))\nfor r in results[:5]:\n print(r[''document_title''],
r[''score''], r[''page_numbers''])\n","stdout":"3\nQ1 Report 0.03226645663380623 []\nQ2 Report 0.03226645663380623
[]\nQ3 Report 0.032258063554763794 []\n","stderr":"","success":true}'
role: tool
tool_call_id: call_8cd1wnf6
- content: |-
<think>
We have 3 reports: Q1, Q2, Q3. Likely Q4 also exists. Search again for Q4.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_mgo4t2ty
type: function
- content: '{"code":"results = search(\"Q4 Report\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_mgo4t2ty
- content: |-
<think>
All quarterly reports 1-3 only? Maybe Q4 is in separate doc. Search “Quarterly Report 4”.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n"}'
name: execute_code
id: call_3d3jutqn
type: function
- content: '{"code":"results = search(\"Quarterly Report 4\", limit=10)\nprint(len(results))\nfor r in results:\n print(r[''document_title''])\n","stdout":"3\nQ1
Report\nQ2 Report\nQ3 Report\n","stderr":"","success":true}'
role: tool
tool_call_id: call_3d3jutqn
- content: |2-
It appears only Q1Q3 reports are present in the index. We need revenue figures from each. We'll retrieve the full text of each report and extract numbers labeled “Revenue”.
role: assistant
tool_calls:
- function:
arguments: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in
docs:\n content = get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n"}'
name: execute_code
id: call_2rg8jz4m
type: function
- content: '{"code":"docs = [''Q1 Report'', ''Q2 Report'', ''Q3 Report'']\nrevenues = {}\nimport re\nfor d in docs:\n content
= get_document(d)\n if content:\n # Find revenue lines\n matches = re.findall(r''Revenue.*?:\\s*\\$([\\d,\\.]+)'',
content, re.IGNORECASE)\n if matches:\n # take first match\n rev = float(matches[0].replace('','',''''))\n revenues[d]
= rev\n else:\n revenues[d] = None\n else:\n revenues[d] = None\nprint(revenues)\n","stdout":"{''Q1
Report'': None, ''Q2 Report'': None, ''Q3 Report'': None}\n","stderr":"","success":true}'
role: tool
tool_call_id: call_2rg8jz4m
- content: |-
<think>
No revenue found by pattern. Let's inspect content snippet.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n"}'
name: execute_code
id: call_oqz8cbe0
type: function
- content: '{"code":"content = get_document(''Q1 Report'')\nprint(content[:500])\n","stdout":"Sales report Q1: Revenue
was $100,000.\n","stderr":"","success":true}'
role: tool
tool_call_id: call_oqz8cbe0
- content: |-
<think>
Need to handle different phrasing. Search for "$" pattern.
</think>
role: assistant
tool_calls:
- function:
arguments: '{"code":"import re\nrevs={}\nfor d in [''Q1 Report'',''Q2 Report'',''Q3 Report'']:\n content=get_document(d)\n if
content:\n vals=re.findall(r''\\$([\\d,]+)'',content)\n if vals:\n rev=sum(int(v.replace('','',''''))
for v in vals)\n else:\n rev=None\n else:\n rev=None\n revs[d]=rev\nprint(revs)\n"}'
name: execute_code
id: call_2j8yqv8s
type: function
- content: '{"code":"import re\nrevs={}\nfor d in [''Q1 Report'',''Q2 Report'',''Q3 Report'']:\n content=get_document(d)\n if
content:\n vals=re.findall(r''\\$([\\d,]+)'',content)\n if vals:\n rev=sum(int(v.replace('','',''''))
for v in vals)\n else:\n rev=None\n else:\n rev=None\n revs[d]=rev\nprint(revs)\n","stdout":"{''Q1
Report'': 100000, ''Q2 Report'': 150000, ''Q3 Report'': 200000}\n","stderr":"","success":true}'
role: tool
tool_call_id: call_2j8yqv8s
- content: "**Answer**\n\nThe total revenue reported across the three quarterly reports is:\n\n\\- Q1 Report: **$100,000**
\ \n\\- Q2 Report: **$150,000** \n\\- Q3 Report: **$200,000**\n\n**Total Revenue (all quarters combined): $450,000**\n\n**Key
Findings & Sources**\n\n1. **Q1 Report** revenue extraction from the text \"Revenue was $100,000.\"\n - Source
snippet: *“Sales report Q1: Revenue was $100,000.”*\n2. **Q2 Report** revenue extracted from \"$150,000\" in the
document.\n3. **Q3 Report** revenue extracted from \"$200,000\" in the document.\n\nAll figures were obtained
by searching each document for dollar amounts and summing them. No Q4 report was found in the available documents."
role: assistant
- content: |-
1 validation error:
```json
[
{
"type": "json_invalid",
"loc": [],
"msg": "Invalid JSON: expected value at line 1 column 1",
"input": "**Answer**\n\nThe total revenue reported across the three quarterly reports is:\n\n\\- Q1 Report: **$100,000** \n\\- Q2 Report: **$150,000** \n\\- Q3 Report: **$200,000**\n\n**Total Revenue (all quarters combined): $450,000**\n\n**Key Findings & Sources**\n\n1. **Q1 Report** revenue extraction from the text \"Revenue was $100,000.\"\n - Source snippet: *“Sales report Q1: Revenue was $100,000.”*\n2. **Q2 Report** revenue extracted from \"$150,000\" in the document.\n3. **Q3 Report** revenue extracted from \"$200,000\" in the document.\n\nAll figures were obtained by searching each document for dollar amounts and summing them. No Q4 report was found in the available documents."
}
]
```
Fix the errors and try again.
role: user
model: gpt-oss
reasoning_effort: low
stream: false
tool_choice: auto
tools:
- function:
description: |-
<summary>Execute Python code in the sandboxed environment.
The code has access to haiku.rag functions (search, list_documents,
get_document, get_docling_document, ask) and safe standard library
modules (json, re, collections, math, statistics, itertools,
functools, datetime, typing).
Use print() to output results. Variables persist between executions.</summary>
<returns>
<description>Structured result with success status, stdout, and stderr.</description>
</returns>
name: execute_code
parameters:
additionalProperties: false
properties:
code:
description: Python code to execute.
type: string
required:
- code
type: object
strict: true
type: function
- function:
description: Result from RLM agent execution.
name: final_result
parameters:
$defs:
CodeExecution:
additionalProperties: false
description: Result of executing a code block in the RLM sandbox.
properties:
code:
description: The Python code that was executed
type: string
stderr:
description: Standard error captured during execution
type: string
stdout:
description: Standard output captured during execution
type: string
success:
description: Whether execution completed without error
type: boolean
required:
- code
- stdout
- stderr
- success
type: object
additionalProperties: false
properties:
answer:
description: The answer to the user's question
type: string
code_executions:
description: History of code executions during the RLM session
items:
$ref: '#/$defs/CodeExecution'
type: array
required:
- answer
type: object
type: function
uri: http://localhost:11434/v1/chat/completions
response:
headers:
content-length:
- '1126'
content-type:
- application/json
parsed_body:
choices:
- finish_reason: tool_calls
index: 0
message:
content: ''
reasoning: Need to output JSON.
role: assistant
tool_calls:
- function:
arguments: '{"answer":"The total revenue reported across the three quarterly reports is:\n- Q1 Report: $100,000\n-
Q2 Report: $150,000\n- Q3 Report: $200,000\n\n**Total Revenue (all quarters combined): $450,000**\n\n**Key
Findings \u0026 Sources**\n1. Q1 Report revenue extracted from the text \"Revenue was $100,000.\" (Source:
Sales report Q1 text)\n2. Q2 Report revenue extracted from \"$150,000\" in the document.\n3. Q3 Report
revenue extracted from \"$200,000\" in the document.\n\nAll figures were obtained by searching each document
for dollar amounts and summing them. No Q4 report was found in the available documents.","code_executions":[]}'
name: final_result
id: call_1ouq42ea
index: 0
type: function
created: 1769703378
id: chatcmpl-830
model: gpt-oss
object: chat.completion
system_fingerprint: fp_ollama
usage:
completion_tokens: 195
prompt_tokens: 3387
total_tokens: 3582
status:
code: 200
message: OK
version: 1