From bacd0e4c3c9e29870dd823f295d92f5779f16439 Mon Sep 17 00:00:00 2001 From: Will Jones Date: Fri, 21 Aug 2026 09:30:12 -0700 Subject: [PATCH 1/3] ci: group arrow and datafusion dependabot updates into one PR (#3738) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The arrow-rs and datafusion crates are released in lockstep, but Dependabot has been opening one PR per sub-crate for them — the 58.3.0 to 58.4.0 wave produced four separate PRs for `arrow`, `arrow-array`, `arrow-schema`, and `arrow-buffer`. The existing `rust-minor-patch` group did not catch them because it only filters on `update-types` and declares no patterns. This PR adds an explicit `arrow-datafusion` group matching `arrow*`, `parquet*`, `datafusion*`, and `object_store`, so those bumps arrive as a single PR. It is listed before `rust-minor-patch` because a dependency joins the first group it matches, and it deliberately omits `update-types` so major bumps are grouped too. Co-authored-by: Claude Opus 5 (1M context) --- .github/dependabot.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index d5d4cab08..eee966f76 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -17,6 +17,18 @@ updates: # newer minimum versions. versioning-strategy: lockfile-only groups: + # The arrow-rs and datafusion crates are released in lockstep and have to + # move together, so keep them in one PR instead of one per sub-crate. + # Listed first: a dependency joins the first group it matches. + arrow-datafusion: + patterns: + - arrow + - arrow-* + - parquet + - parquet-* + - datafusion + - datafusion-* + - object_store rust-minor-patch: update-types: - minor From 217ea1a799e23d2badb02b8e638e2b778ef67769 Mon Sep 17 00:00:00 2001 From: Will Jones Date: Fri, 21 Aug 2026 09:30:20 -0700 Subject: [PATCH 2/3] ci: use thin LTO and a larger runner for the Windows wheel build (#3716) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Windows wheel job is the slowest job in the PyPI release workflow. Fat LTO of the cdylib is single-threaded and the peak-memory step of the build, so it does not get faster with more cores — and it has already caused rustc-LLVM OOM on the Windows runners for the nodejs builds. Switch the job to thin LTO with 16 codegen units on a `windows-2025-8x-x64` runner, trading some runtime performance on our least performance-sensitive platform for build time. This matches what the nodejs Windows builds in `npm-publish.yml` already do. `pypi-publish.yml` is in this workflow's `pull_request` paths filter, so this PR triggers a dry-run build that shows the new timing. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) --- .github/workflows/pypi-publish.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 4f5a927dc..b80c1b019 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -129,6 +129,12 @@ jobs: # link.exe is single-threaded and the long pole on Windows builds. Use # rustc's bundled lld-link instead. CARGO_TARGET_X86_64_PC_WINDOWS_MSVC_LINKER: rust-lld + # Fat LTO of the cdylib is single-threaded and the peak-memory step of the + # build. ThinLTO parallelizes it across the runner's cores, at some cost + # to runtime performance on our least performance-sensitive platform. + # Matches what the nodejs Windows builds already do in npm-publish.yml. + CARGO_PROFILE_RELEASE_LTO: thin + CARGO_PROFILE_RELEASE_CODEGEN_UNITS: 16 steps: - uses: actions/checkout@v6 with: From fa3d9b2ce2937c50e1f10eda8716b10491d84143 Mon Sep 17 00:00:00 2001 From: Dan Tasse <105866+dantasse@users.noreply.github.com> Date: Fri, 21 Aug 2026 12:33:57 -0400 Subject: [PATCH 3/3] refactor: move plugin/skills to lancedb-agent-plugins repo (#4009) Moving the skills and plugins to https://github.com/lancedb/lancedb-agent-plugins --- plugins/lancedb/.claude-plugin/plugin.json | 21 -- plugins/lancedb/.codex-plugin/plugin.json | 33 ---- plugins/lancedb/assets/logo-dark.png | Bin 10619 -> 0 bytes plugins/lancedb/assets/logo.png | Bin 36230 -> 0 bytes plugins/lancedb/skills/lancedb/SKILL.md | 102 ---------- .../lancedb/skills/lancedb/agents/openai.yaml | 6 - .../lancedb/skills/lancedb/assets/icon.png | Bin 23274 -> 0 bytes .../skills/lancedb/references/branch_ops.md | 16 -- .../lancedb/references/column_metadata.md | 183 ------------------ .../lancedb/references/remote_connect.md | 45 ----- .../skills/lancedb/references/remote_jobs.md | 151 --------------- .../lancedb/scripts/check_materialization.py | 137 ------------- 12 files changed, 694 deletions(-) delete mode 100644 plugins/lancedb/.claude-plugin/plugin.json delete mode 100644 plugins/lancedb/.codex-plugin/plugin.json delete mode 100644 plugins/lancedb/assets/logo-dark.png delete mode 100644 plugins/lancedb/assets/logo.png delete mode 100644 plugins/lancedb/skills/lancedb/SKILL.md delete mode 100644 plugins/lancedb/skills/lancedb/agents/openai.yaml delete mode 100644 plugins/lancedb/skills/lancedb/assets/icon.png delete mode 100644 plugins/lancedb/skills/lancedb/references/branch_ops.md delete mode 100644 plugins/lancedb/skills/lancedb/references/column_metadata.md delete mode 100644 plugins/lancedb/skills/lancedb/references/remote_connect.md delete mode 100644 plugins/lancedb/skills/lancedb/references/remote_jobs.md delete mode 100644 plugins/lancedb/skills/lancedb/scripts/check_materialization.py diff --git a/plugins/lancedb/.claude-plugin/plugin.json b/plugins/lancedb/.claude-plugin/plugin.json deleted file mode 100644 index 9fe3d4b67..000000000 --- a/plugins/lancedb/.claude-plugin/plugin.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "lancedb", - "description": "Write, review, debug, and document LanceDB pipelines in Python and TypeScript that work across local LanceDB OSS tables and remote LanceDB Enterprise/Cloud tables, with idiomatic query/search patterns and performance defaults for ingestion, indexing, filtering, and diagnostics.", - "version": "0.1.0", - "author": { - "name": "LanceDB" - }, - "homepage": "https://www.lancedb.com", - "keywords": [ - "lancedb", - "vector-search", - "full-text-search", - "hybrid-search", - "python", - "typescript", - "pipelines", - "ingestion", - "indexing", - "performance" - ] -} diff --git a/plugins/lancedb/.codex-plugin/plugin.json b/plugins/lancedb/.codex-plugin/plugin.json deleted file mode 100644 index bb824ceb4..000000000 --- a/plugins/lancedb/.codex-plugin/plugin.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "lancedb", - "version": "0.1.0", - "description": "Codex plugin for building LanceDB pipelines in Python and TypeScript.", - "author": { - "name": "LanceDB" - }, - "keywords": [ - "lancedb", - "vector-search", - "full-text-search", - "hybrid-search", - "python", - "typescript", - "pipelines" - ], - "skills": "./skills/", - "interface": { - "displayName": "LanceDB", - "shortDescription": "Build LanceDB pipelines in Python and TypeScript.", - "longDescription": "Write, review, debug, and document LanceDB pipelines in Python and TypeScript that work across local LanceDB OSS tables and remote LanceDB Enterprise/Cloud tables, with idiomatic query/search patterns and performance defaults for ingestion, indexing, filtering, and diagnostics.", - "developerName": "LanceDB", - "websiteURL": "https://www.lancedb.com", - "category": "Developer Tools", - "capabilities": [ - "Developer Tools" - ], - "defaultPrompt": "Create a LanceDB table, embed sample text, and run a vector search.", - "composerIcon": "./assets/logo.png", - "logo": "./assets/logo.png", - "logoDark": "./assets/logo-dark.png" - } -} diff --git a/plugins/lancedb/assets/logo-dark.png b/plugins/lancedb/assets/logo-dark.png deleted file mode 100644 index 8fd8f220ed6ed02531d28815e826b6aa56fc7346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10619 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 GzWRSDp*6+; diff --git a/plugins/lancedb/assets/logo.png b/plugins/lancedb/assets/logo.png deleted file mode 100644 index de3e82aeff99fa85f609ac16b32eff999d6b7ed6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 36230 zcmcdz1y@yFx2C(hyQI6jq)SS=ySuv^5s+>XX%RRyNJxjg(j|>_H{9j-Bd$ZoP&}No z_u6aC`P3v{L+vd(3JD4n6coCmf~*!46g1@DA0!0u6@k%hLH!y0oY@5e6+dI65lF({FY#U#JplzEC+kJ1#aPI6|Y=!N1Xx zm5iY3Qiz2^s^YnQE!Ydbm!K)I&k^c54K)1_uCkWzduo5X;t3A}Cx!L@{yQx!1{;nj z3hQoM<^B7dv;CQ}@x>lpR$IGo5 zRqrZ=yUvLX+MmWoM?Zc1h-b4inknsf{F5@&>hIxU&T5Bmf9m-4aL<=7NG6PE{SB`v zD+@gO?Os)Gk2l9?!^ui!hw`^>0}JAAxLpRflInb_Fyv$C=hl$Dg|iW%Wy z!iS?>IhvP`wfsV*Ar)JdbABA=p%!tR9nn>qa;sSgRWB0nu&}WBYS8S^ zY+R*X__eC)&#SMZqGEinO_LCePdY!LIO&f4DGEeLZp=2?s!hIPPJ~u%iUHg z_S+P)8Rvxt>h^Enw1OY5>>*x8+6bqX%?49{uOCRNe+MuK3qLsJ@jKsOQi%GQT3Ky# zWsH2k9nax;l3@F`d|dkN8~0mH&2*l$G7-)@ENTuT2-dEj*loK~1&$HKP3pa=Y0=fg zVLcuE#_u z^ZH@JHy{dh?HgYF=-zjRX8V#Slaht7NSj#-;Q>`o^O4ycrsDfI%dQ+eB*~^vZ+sZ^@L1o4`uC+x(?HmUa|N**!*_q5{BOu%YIkhf_)acl}v^%7Rqo4^tEWyKrOT)``n>%8KbF|P{HoHBN!8rKy=c_V%c0FH? zieatpp?O-*j9up!-Rk$m%5)!khAFiy&s<58V~EgV0ul#3hQOyZ=(FN`v;`R}DUFhX zLp5bd$Zj-D6%}_sgmD6YqKHKmX8D!}Usdy)HgmL4+Qp>EDVnmnx+!a>Qs{pU%@T&J zSzT1h86#dMm9s)pLmq8U92bNr(Qvzn!<4&FL_$Qb1c}zMy49;r{CN^@n3)6WIy*Zh zs0WbL=rH-eS$+!3fkE0d=ncaoAc(MV)Ut|7E8Z&%JQ2^ExG}BOeIzBKFHoDO!ij(3 z4$m`A&TgxF5aB#mWq6l4W4BWM+hLvnAAf=>sywn%#awdc!Sf-81e;4j$?%)i$QKN9 z;qmMdD+$BeIa-9sKTkV&c1>gM#P=fgHzLKK&=F*kN353WwV7MJ4u0+Y=ID9)MoAr2 zZ$HSJe3YF_FhtXxa`LgpPe7vtL+v`_kd9MP$d)qyuhBiUm+ zD{P4g2? z{gKZ@gr?)r9H1T)^u*}ec|KI|G>$+b4A&N8UZ#}5hnGe`%w;iv%AEPv7hEcWmcax= z#TEj?xvFvJt*aKKSpPo|&$Zh>_P4_` z@^&b3+0YxQ){&yymlUwEtAA6pE+3nUpAX=sp3%e+7-LCEynQ#If}}V$Ir$=4t4lfK z(Cj^tWRPKg@%_n~n^@L&uSWNHAYu5%R@s2w&3{@?yX2ufM+Ba^_96 zNY&~VMKuJ@%fYcuO48`Qo8|NXBDQ&NZeS%FPyja$T6Jf2&n*7*ciFvx`*0>1wl?$i4AOE*-IZXe~XB|639 zB+d~E`KV-Ft5&&uJ!j~e%n&ua!P6Wijpq<2w8vfr_6H>sUc#u2{aqGSXskA~n7H|m zDEla^ItyHJy+n6jtbxo1Sju04m%9_BE=`L*V>=fJltusP73?=~y7H2!uLa+(PT@#z zcau$=&k4gPU)?Z3ZyRZoy0^)&)9+lP*}&MJoc@LFB4Uaj zC;qQX$8k$^6jpM*-#4QrjL`{P9Gnn>#6dQl9Ft3&#KDyR{`=1x^peq?P#;Qnb`_ae z3}d=N$yIdG)e4?cxag}{1=>38@z2RS(W)eTjOHQuB1HK?6Syj=@)Rd+3C zZ5vLlyDZvlaD4SM?vF#ZR+ZQ8_V)Pv;dS=#K!zms6vTZCAy0*2;U@v-w^-EO zAZ_jcPC-xoqm_lUNhzuGXWlfl0H1;)WO^BQA~73QshcwBtPk1DPLwGGAs=-iWTwuz z1G9K@7SZa@K_VXm)$7yK6MYmGpEJ)67cHV8k$f_VHzC_&j}0SvXjf@zsZYIOD|^8_ zI=qwtdqe%+^X>X+-R!~FPO-MmVB~1&7A3E%{h0f1>n4<6U1Sb_4ZX__+^}@(Ok}jEW5(;p5Mh zHqW2;kHY=QMgTF%y9~r(yLNc0!U!w%=FaBu*!}`n)bgu`ydfP{{iO!&!-o$oE=%9v z;3nmZEC+?tdj2H$9S?V%fjqx@VkHhHClYc{%+$p5M0`ggI-7hsPYq2fJ9G{`U?UnP zth9>7qaOfPFi#Szasql~RzAEMH} zeELMh&o;uT(px#mP8+Jr;L{Q8?d`i+$E>c>WV zQa-atgwv2QcNm&vM1~Yvg4-E;CG|7r%KO7fgci&1yz~(vB`4K+_-&fRAClGX*O$i; zY;5eujqgtR|IKICIfae3Kc4pV{H)c!Ip@c!_Vn-|n2t0tucsD|tsd*4xGAgn{JDFm zS+65nAp)9S%>Gw7v=@sc?C9%~C)742KK}LL#m<=Jy(O_!5Da@Ph9ic#x%slaCNlHf z;q3}38-el!&y;9}dq!$lMo$AciEcy;owmKl&Fwjf@@>}!wOM$0cuxhN6La#sc}+s@ zcT}1d$H~tUE_%B6HlmszK7IOB)W&CTy8jSKrK%eE$LyD8nS2*(_82vNWYq|%UQ5dN z@887)-oJknfwx!lzA1o#j;`0FKR^Z3wCAX*=C36HttUONFE5>2kuC}&(vP(f5fR>I zE1Z$;GL}VRN4gbS#$-G;<0^vaKeF?zXrbZqE#d8R^i2G%zsu58UH{qA33}KptzCBQ z2`-T?fw*91u`u6*^RRW~^N8@Z!F~03mzjk;Cntxr)n%2$llD;Rtj28BdAeB2^|FZG zL_qYV042KA2K0|D`x#7^k20Nz^PO2(I272}jjD7wCGH)3v_Iv$!6h)2(sXB~Z_TZK zeE>)p>z!wN=wJZ8i~9^1#FGVw#lyH*=eGPeAAzDAvX>COi` zlVS--9y;}zpRu>Q0;+{X#B{F~DTr@EB z|8q;!QtK8EB6j1lUnld@XSZvCZgQTS*z1F4As=s z6cMuO_sV1Iy=yp2Vo>=6RiNayy6F8LEmp0vI%p#t@nrLm1QcVhA2L@qNpW%dn0w-X z+9MCq$cAw+!i~EEyeaVgJ!yaH-uGDqxx1h9OiL2Kv#iUII5Lj(a(#Vyri?;g)>D4R zZrD-u;O^&UPF{laSeQ z0No|z$N67^dy#P)&)*A;mZ!1oj6{Rf6yeN<*wl3L0OS~Gsq)$V;b(ix+Xf)ZGT25jz*O#}W`i?6^^U2G;@)xU5rH-JRXa3Qg$U(wEtTzhDVO z$mjA(HU^d-FwZTEH=r2=sOfa;=TD1au^AzxUA~R_MvoH$>u53Fg6yiW2=#%tCmffw z=$%F!uxc%|@=1OPiJOqGqxdYkSCTm$zANs*+7mXH4$^V>DcJ-3CUMLAi%pei-56wo zXPVW&4f->$H)VYf(`i!f?(Q;!FmC`EQ&3e^6+@qd_ZfG4ZGrAs4S|%GN7a5QKk!%7 z()uOesGoFLc#_@I@6cR$IA6csMHQ5^iPgI^p+wF1dB%>U;Bw1 zXz%(dh#vD(;^X6m?l%)TZeqPP)Cj5LSkfg^2hPsU^ogugvb$1UEMiNI-JF} z%b!N~0%~{q}-ms(fGl|}{Vhhhn z-HKlS_s-2`6Z&h$^oYDs1YSGxr-@y?a;-Ozx&`eyR6;V8H`!y3UFWUm7PA8wRoW=% zwVD)#l(^{AAK00g>`0Da;R~YL#oXNAd&#k6k$_)UT2;Iy-Q5%({B;3=+X!yL1rbY2 z20qmYoBqWP-@t!h+{&E?61g$|{reZrp;@@Bu@PHs$*$L7w0F=N!R6pr#hHoK^TYKB z_`hGjPg7SozZj=Wf&#Pc;lKIKdhCN41s)+`8HKb<7ayUlQ|qeFa#V3K)s3XW%1ZJZ z5ta9wL}x?s>p&ZzW@NM#-Dg<2B8Nb@W0AbunrYJQvLvbe{`=$ByT-ygD~B~O%Zn5( z9WP&&qxtR~Pg{4liS!|K8dN`hiOBJzF5+Xow6ydlIR;`~4>i(ev$vprEC%>hUtJy9 zYM0nmEKnHV;llnYXf`GU6~V3EO6GVbK;Ztn5n%8H8S?+QQ<3?%C3 zl)AEJEs@0;sjgM)+q={`_AnD@;hy4JDa&TsDB zrv2{!t9s`oF|C@%Zw^No2C*tKkduQK@$)%Zu`l6}de43nCWAF#C5tfXRulr;B zT;Tbk>#x!R_65M~WZ$hrGs(3k)aEZdYoN9Hrz?2%WuC@UA$icc9ljdW-kgCZ{Tg;! ztII+Hff}GksH>?#ONl2$BjMfmjWNfV$#$0n@5mP={b$5wwY^~AEfxe)u0zOYlQd`{ z#7>Z?K0V*N--w7w1D+y^G?KPj!eoJnuOt=xMw7+E~kSW`V#ECD5Ze@dKXE%(DqBP1_=x32PV;AKuNTdzH*y~bE`F4x5zu=FrPht)v zxbSq^w4g@@;`q2;4bGr3!S? zi-A%%X#KpSR@^w)*ys5w46p@s^0BmT?g!$K4y(IQXz)jK)JGh`Gj0v*HIcg=rK`|dpx-kc@f zUgJLWP`l@UUo@M*&GX1IXBJ8=2J#0)W^`_CZH3Z-)~`krwULtzouo_|;_lAHx|?9l zy=dNS(4||Y{X-ZFgA)__z`V^Ugz3$jgG<`CDK(&}B@6b6Ax2?>4cg}R=SL`jzug{! zWJG=bNOAed)Gz?=bb_zzf&vk^K@}NAoCGzrGgMh#E~{Z`IwktBU$zd!z;|Z?ZfX8- z^6c3n9-f||)yoC3#z=4p6iZ0Z5KW`ozavxvoJ?lY?s2Z}M~Uj+cy zdS_t3Ocynbh)!}P(9RxZuOyHvQKF%bX! z)x79r+T!pVrNycD5=t%%B6AlystaU%uPCfUg4J8Q1KyL#9pCY!2ut_)!fd`j!hQdiw)2E zbm_lOxK?=|K6q?&Kb|DUN>jRIh>61bF(4x&8xC4>;DT|wj^eca<4;9%DURy+drPP?G@4)d<{`F zhh@7L$tr3ZE8{djhWi z4*MK0)rNme(O??TKCd04u+m=#@(McG?mkyLr2-U30sCJx%LpuUe>KnK0Y!|*dFgv& z!_CM6;5bY^9mXj3xj@zqD%NIh8-^`|7-}~VB<>JV%X-!xQ+TNp%mM>yIWjVGF-udIRmqZcNB{P@Pz2@CMP(5jCbXlD8`gj{r(a3ncQd3e))NZ?^Y^_&rWBe%C z6T%{Jn--r)ue+y*SD)Z)t#3zJ>hUzOdFJ1QDgx?4mC)-9%dVihbbMp$Uo~>5RRO3yU-TCGCMztB+Phr-D&+KRF7D&ML6 zWH2l|)J6T5FABrM!(rO=hE(AfJ?2{o+>YZD6VLVlMR5Vq6MF|`^~4oucCTmT_?<3- zduhX?)D)2N79y>`+yC3VQK^+n~E{gNq7~&>WYc^OF^gG*V!xFQ# zvDqvX7_i;=`mo*D*hqS=F`UQaf=a+T42iadx*%+EoIgW@t zW03~|H?fnyhc0v?B9D)`xw&>~G3=iZfBbtPN~VM`v7Wjr4tQ7(t?MCWLyTxZ3ge`r?wMJ@R1{G zN=gy4y?I*F&>=#CTQ`?e5|xojD|kX~j-{i39I-|5X|g`F4M2>aeoDM>rKjkqDATav z_b^!hm{(o3{9|T$aY3Od{mT$d{ybSKbA%y+uIEmSH;EGuh-~?Y@F#AqD93 zKyAzCJuTwf!{V|&lGaOLG4#aFa3u_(+s`y)1g*Av7XZc^qQNO%d?Xs8x#e>XOq%Ej z9F4E@T{(}s8{{8I@-j28a}?-M7PN_pJ^_)M1BtpMXc0m@IjjiGsaqH_Gtw_92;;%P zx!CJC?LI{3mfDKBgYU$-DTY8GY}`3Xq*pJ6+?EoQOuWqo!9GJt#By41NFn~;(Q>nT zP`!l)BU5n3<&Q<HVU^4;Ct^RhThO@?2O)}lyZIT;>qPkST* z-1<{0B*83gpRly;ai31FoV6k)Aub3ZYNLKZMRQxD!%PM$Q{``mdw8alte_P9AYdVq zgH9jFMd~*wPE=SDbq@5Nc>x z+iffE9JA4nZ!iJ8a3)C}n)!uBzTO};s#rEdb^x3|2}p}f8o||Iyy|?h{$YppSQbpv zVyArlyx#fFIu07S>5H2^Z*F2$RaKGGdbe0nh;}0f0Z;FzxWvSanbY3|!rlhuvj-T= zcnJjbp$}-e+x5EDCC77FwuSz?6m{2RC+;#ZIA8DRjWEYRZy%pK@WK}^sI&hut@~Du zlJ!0|(95lg2pGaNLPGarK-4hOw+;77;wY!9m($e5&T9eQVgo-f5Qyq|a#Vt35c5id zCl`xv|N9R?xqf~gtc>%&L){PL-Djui^fkhQ#4*`fC(9^M7p%U6v%g}-Nw!yc60G^+ zrN%#ETA|fPwlEKRP+YF+)s|w=Oq(066AFPikM9huXMMo=tHe`xed_ydgg>M((hC1X z9b3}mA?JXuwMCK`cXvDu{kx~hs&HdHGT z56)MsG<0s%|C$>dQeUV66`Ch3s*191#`zy`msQK;lXF#&?k}N{;IvGYkWEpESXLg2 zLB62#VwC0C($caAFmLhkYQdWavf_&#D~#SZXdnpS>*I4H0WN4cCWKDoLi}`Pl{uel zOKXxnB=9C!sBCZZR$dfcR3QW#ikhzcU8R~QfPMeM0Y9>DFb=$gaq#fI585<62fjSr zM_vWA2%@F6YUDAia*cs%sHKA&y@SLhZTuFx|r+aSw5UF)$o+7AEaeq@#%=g&KC zFk*iV*q<(O8$iE>iekGb<8t_DZ6w=e-XG%vI^L;%?c6g$WZ&UdVd(qXIfpKjo_3(X za9~USvY&%FyZ>^pyHS9Dm+g;%!Op6Bw9>}oHJL9I|NMCCnwOKaXi}x^Lx=>|#qK*e zIEYU`NN6kibk<+RqFWOekuhE}O4#zzXmaDe$qDxN^cw)IX3}-5uP=*>i^)lnKLb1+ zAZq=O@d7sBlPrJfY+|y88kNSh=A8IEXjx%mpHb3eP#b|M@zkIWNbn)JNz#bO$SFP^ zAGh#E#|_dhQm&wt*S#cSG3Y-Z*q_qAp`xRUnKv!YFP$Trf9ZN{5SRT*&e zBYkNA5&*6Xtm&kn?Fz;ex zW9#P*uU*Fr#X68~G%s9mX>6(_>Mp~cfDR9J;reY8+|o3*ofCK<20%j|vGmIaCPe`7 z-FBkVTGHez8a%H6eY-~8J7Jz#Dk9a7miALMG%#2a=H~XW14y(6hz`MdpFa6@zGuz} z4Nr*>>*3Rb)cNJ>czJnwgSVX$3%oJ<54282073%A|7ArmF^gDBrRyw7p<5ZQ{=`z+ ze0TWm;0NAR+07?gtx{yd|E2KL#`GF94UL5bo^3SRP?H5XSZ*n z-rTvh`$@h`C@(9kMTnk$XJ=tyL6b7%&iw15lS{j8=n_INpWH?W!rs4=>S_QSpqQJ# zza13=0v=MvthoMeoEZsPrkTuV{@CLtOv{W|4_~i{J@ZKB%w>;567fBG;^!o&25f{+TGpx_-4BX`6g8-dZ%jYKbO zf`WcFK=3aDTz7LgRpJFQdw;n%Tdc>Z{yCe7FEoqe*$KzwyV=1?+odxAvWYz0+&5C% zhsWnrwNkdWw)F?oCHj1gq1TB;{$C z$;B6BcJ=ojL7kPL-=63Z1qEgI`ee1^4s43V7$G7g;V*L1p0|L(U7xOpYJm9C5#ZYW zoroB)RTQG+t~C<9>*b7+0_eO7Q`XkjZ2znN#)RWH3$&jbL|9&OZe!NX6EIGAR7)c zayxIMmlY@e3?Qwu9xgO)2@a>vrvA*tM1(UtlT-|og0WUbFG?~g?z|6-*a$pXuQ&_+ z(;J?Z(^<4*4^@v(>;aS_V+o@+s%HS&;!y4uK%0h zqQAv>8g5lk0ouVXMn)@R02n^r$4tBxfS7R4*!RIX?z0l0DyphJ-@QDZayV24Zmz($ zhT{u-d+8B{IG7W$SOO?&)w)cbJf`>6B!14t0)v;h9n`E*kTVE2H-KYgUcU5HfCJRhKRS+C| zSEE-`bNM?_-rL*gj|NCzJlq^FOZ*V>?QW4s@1UHP0@+Ro2RPQYCbNeGm633v^4_Z0 z#vpvy2rjz~9Hit*N@D(`GK>ptr3;XE8c|kI2rGp>fxho-^(x57zb-G1-~=wjZxFTd zMQn|wPt(d8-ud%Yf|{J)dK7QL=K}W1wH)PZ9X<1$jc0MyEOPmKTwL7se`{d)aNgC; zKH!S!2ZEBiz_fb}r$-2QMSm%dBqGt2fjtF`+B;SBVi>F0U?L7B(+;v3sbadM*VbHLJf7+dk(@~B5a!|bi;<1U2jV-#^2`Oq7 zL|mZw#`zOSi>(sRSF^3NKWOTk3pX)dqS>i|1@?~%^ze3=hJNUYG!#Y#NQdvAj^n?K zGCkZzJCDAz4n&L`LJ%=Y5=SaBwS;6Q>KaEd9y+bIUuSEO$HKCjnP-lIV@;a*>C+v4 zO{SY=RCeKQb>gJ+oLd-|E7)vg?d;p44eX+Go?*RLUv+3ciFSGB?Bz5*xaC~w`~1)E zbK=hNnYEj6Eo*UPdT)0RpZrY^M;hloJ+otDDGpm&3oP%v$4{(#$Nv~0F&Hqkw#^2< zz!j;l*B&J}FHP@|+nQtM<^BHSU2SyG{pQy#;27*A5%VZXirZ~JtwY3s8+Hp6g{>zp ztYWRv06MppVc;0e%mA8U z`!76@P|fKb{q#)mwVb-LT1iFasZb*A{9z2r)6L{RP_R~F870cC`+XemHzF|u?3$O9 zcwO`g9*@Wx7M&c;`HWLNcu+0=M=L8zU|EVyh-wkl;4>O=epff&v z;QtX1xA3ca2WF-pY`z~LKhTCg@F}ZPO$@5i#Ma8H6GM30W+}j3XJq=j80e5GDh&PC zYJKQ@sf-5)2c#y!*E$Q;iMl5qLZ_iGmqq>F!sH#{IQ66%&}a=NT>)$r2{^NGY#*0F z@=c6saEPy!)b}Du-tzkDVD@b!S=&}*9bujOHSmm1L1@?s8(w}Yg47=YW4K*4m-m2j zq3NQ28T!-c=qPLA;E#fWDEsidD~t7j!`gKAxwbe&s7fo4Pf1m%(DLaa6!sJNErb2* z`Z477`L>f(=x?;}!ViFjcizg%9+gc@aRm^pG+=lPTYZc9$0nh9J-oDJ450WOTb!3~ zEbB-GOawS!b5wkw=eG>V&}upqD}H^pv^;BnL+sYYA`#vEbSU&aqvyu8QD3}-be~J? z4dkB7j+cZZ2p|Y#=pKrn71%?ml&|G#m0M~#a;Mh>_++&&Fr0*I(s3y%yQ4Gb?f%3K z?K1WA0vN>HR@@TTe)J$Yx==6*(&$snnWK{H1FA09o4?ut3teBg%U!77_=U*J=Z}?~ zcZfjz9XA(jZ&)f*R^jtt6aSse_=T#U)+kx3Y%wu0Cjb^12Bw{6YGtl0z51>PXM=!K zbN1__AF|8HaGzfxkfZ$Cy{XIuJo^uzDEpSMF_`Ann41>S3=vtq4xtDN?wEibWd3i% zxIcAtZ%~714Oz)KN}*xXA}a``QvO;;-R8F&0J1@)$m>qFsR6uroZ&k|fN#v^ z3SJ-Pdmcbu10oX~EcWprLIaCXQ%47%-)cCGP_hmb>Q7&<#PlmIHwWS?5HZN&u5Tvp za5XO07Z#X+(@p+Qx+W#6+kIwc1Th;45eBtm;XYF>o*jBvZwOSG02*i^9K@{_6uJGKW7EQmvf|IEGGk&nD z@u|PC0`C|L<4q}cq1@rvlFu>_Qy*x*j@)X@!MbNkA`cdyisTDc&kte z*^e;V_kh5aEqUd$9(;?g&4g#Xza(KJumW-{$-BUb35Mz!muxB8k2SH;(Oq&#(1@g7X@ab* zN6txWa1^AWfT4YmcTX~vcheZu27n zxICN_5)&8WEC9EJ-S!ZwyZ3|AKlBnVfT_^Rc?3TEE)rbCLo_O3%lv^?8&Q{k3dn6- zCvtQPo~TPqVFvC*@Vu}$Qilm|`9K(sfX@$kDJ!MXpcWs} zxXfc&^p~h|#L8iOY%CA$akI3n?6pp-YGEJ4JFVAJ7)-YuzwL1n?^|AA6Udt|{q-Ml z)=mJYYSoNg3a&JFZ`pMR^c>7a=9fxEx(`iHwvpM($z;`zKYsk^j+*TOO;zGE20uYI zlBn>D12Q#rw?-qg*UzDoDT!B6y~a*H`T2Q4{*?(2O*X47=gblb8ev6%1?yt+~$r}scuAqKq6cc%A<1II-mmnr2yv@^Q zwicMT4A9z`*@LPaq@$;=-TZY8BcZIG0ERdiwHGY{e)S_@bUQQ~?5i)L6egPbYp^kj z5i@3tsGSudn=nN}k;49tN~6l9zcN7Rw;px z{(ubJb560{#lMQs+Nbe@77KOZe$WAFZv+YAveU+P#zCla9nnb|aN02eHx|7*tM$Xv z(AU5`U>DHo!%D;Mxi5rk>*-a7fb-hkI|YuxOFE4m^wDZZb^$D~0*%T3rB3|0J`81i z?n<0J_!xXXNO(kICnpzeD!6!b69(`pcZC-6+(dYrYkfHanRLlCi0aIbS{)ImF39yq zI!+fGCChIih&HbszTxhKTg!m1kw8R5bPdl%)6XXGL)LpXZ_!kXPr(gQRiAH<(YFay0#MN8 zUSM#>ZNElV{g++a8>L*!XyRJ#92MbqF(}3sU$Y%{Fh~UMe>|#BS64SCn!)8Wh*E5; zrBF%~0tI=xQ3fu&E)pCMFMdUsqGdy4Rin~7&?zCV6KMVW`wyg>J7jmj4h{O+)GE=B zf7$tX($R2Id~x$k6^B`@|IJE~p$DqEf<*8p*d*Yf0`l}2e-EeejA`JU&0+&r&O>y{fow;%z2eP6e zPmt1*5~-8XTUi$rEmKpDg`UtJ{48lO*p+PI#e4w^hyf?S&+h@xfP~ZVZ$b)e z^z$b+-ol}Zojl;_X!7&(|LA7PUs;P5B*WN!y1!g8VI6=C<8cS|#>_w}o(dYBT2{l* z@bGuoPkLQ%5V|{h1j^y8*U5^|UCRu|6pVwpBp+okMuRnMQEXs1zjqo*Oqs{ZQzcfp zoZw;v$S60y83jbve}}<{gkM)rPbLAUdyx197CiPkBl4nH(vnG7L2sIP*$6{8EZH+# zI6Y(I+Uw7pMg@d}69eK=vj?*MyF!w4(&-9OwKG`TukLrr;bm|8X%%`S&@r$Ee4Qec z(aFl~jP65*YpL;2+*c<&Gl+&lERBr|=9h4&aFZr z%SxQ2#=Cc(n#`HsMhS~z-$n@R_r=-=z+od14bR0!MUg?9TiJX=S2gf~19KFl2RLx@ z7~)X-1_oD=Q~l2k7zMi3wK4Dbu;`}Ei4dHmy97@A=y|{(T|VghiEtA&)Uv(9poL#q5kwrmY2s zG!aC5hCsGxg|nst<+N8aJraBn4IavrWHRze_~nX?tAhGh?XMa7it%vm7!H8g5_}>A z?vqNQfExf_M+ozbML`#gz+*`37ElQoXyOEACJl^zkmnZI0Hb-x5>r!Oe|WTAuiiug zB=SCr;52}Af-O+(_ye1I2P#1Bs>z&*nvS2H-Gv-o^UwBM6>L92zT){q^kw%Lx}G~|cL^_={x&z1cv+9QSCzAid^DmMcdh5h>|RHN6Etes(_<2-Y-Wjl0o`}+ zX!k*u;sL}KIbCp!UeAL9xWQl&OFt*#kxz#gn2!3yeEIQ=IL6Ax=7+G6s*1`udjN0# zx?g=aMx`T|)oKKWwzF2%f7Q;VF!-QZ?yq${&ZG5fgF!yzE_>LhlZ7K;|BLOS9SOf?o=lj?mo&p{ZA}A-|Z3p;kLuaW9?|ng*R;gTR0CS(66S z)!!Vea0KddcMy=GY`uGSohT{!qF+Cc3j7m9=@Kk)vXj_Lvj8n%9lf-2y4i7w9W)C; z+2`m3>VYzAMWL$7A2x}Mg7QE}EsH};e9s?Do~;B|7>EHd(g&>4%jl!%F-%b)BmEd1 zRk8tk|N8q{T|rXiBzvW)3P!+LLF{R_VbvwuEC96pZ*~grP85}tmS_kPpMOSPySMc( zT7rltJ8%Ke@gN{$U*s)pOv^8Pc7zNA&a3exr;3ifebqdA{#Z$5d{uR|GBP^)s*)I! z&n1`1NoF_*pa6O1VHHab4TGjU{TR)~rfFa(=p&|J{>OebE2MILH7mVahtXppkHx=MDzJM8> zsA(an*&k~aAPWMbWE}tGhQqWLsTIV1g8fLxMtzKlB8k_cy{RHXpQ8nAj7Mt*)!gsE zmMJL3U)A^8kB zq!m5_@+6nZ@_BfLHd4OL=mZoRgBsv*mL(DGLTC0&yR>pZlSd^p!kr`)7Xb5?ms*zo zjC!R7nMmnB5bl-(3dZ|#FgVB{EXh7?b~*?BpO&F$aD_5}mMig6d537(jo-Tycc zac5cS6KNbxZ-y3gW&}_kr}UWc8io^1Y7)g51s8bf=&T66rl4H$%LLYQuXsNop##w^ z0y{sjR6wvxoS**&U2p=<3qt_W?}G5(3=aG&W}+&bOZ)~HU`fG|{ttR*cxEjKM_M6a z(P`~x^f$p7WBvyH_v{AW_c6}iGl9L#`xA+}2pI>2z|(LtyY%l>Vy1w_iAX^L!lKewzGAh|g?gHe19 z^FJHy;orjyYGc0l_G=f0=MmVIxJ@~Mg-HFP&CF`p;|}{4aI%!+)eZsj?S)Q<3j?>R z@xesGR&-2E309nV&JP4et?rTa*Ts=w=qjYn0mplK2LVi_^v5t~D#e1p90udO?aG2l z0QeyQIna;6oP3Ml$i?>O=Rqha^sI=@WL_=#4PL_KKR*F3n8Ecwh=!ti54HSAB8fWk%ZH{kUjH-J;99NtsyXjrAz07U0bf`LvY7W@hm6Af3a9$uYCxnxvUn7@!DeAuu!0{45RD>WrtEuQ!7kFU)av>= zn}E-v8 z`Gg_1;tj2v&)~{bVd*g~X~K4)NSi^XVoBt*vx!n$D1e)9ipS&YOxasZP|54iWXa35 znM*7J`K^9K+~ajJ*m*q~-dY3oI~oX+q+d3k1OBhKv+&9~>)t*k-7Q^$G$P$4pro{P zh;)a9bW4kfG=hNANOy`T(o%x7gmk0SZ{PF0f5SU#)|xfWD0iIiIcM+dx;|SibQXgQ zst>o-{^YZHG$eeDu^3~ zK1^YKF!rd8Rn&*d8UN*HOIZ+^^A+PL5765d6s3R2svEe3?}5H5Joxrr!TmoB!}vmK zj~|cj=#{4W-{o!(qUUC@kknI_huvy#0@ksAfF-lktsYUog}@6ZSFj4;Dx38*6UNa> zzeQEkeT9e<>~9n#;)nfUxT(3o)}-chU+t$8$}E2~o3>7HNHJChd8iP{$l>kzwpnb& zUlh3^9fvjp$Z%=T=>^1tbA@`b6`s6G_Uasy*oy`DC{Li@zvHpLDEr`OIF8}68p&=8 zcE2hcXXjl#u{Si_f*FguMyx5x2*V%`H#c4ws!D+8rSN7RDAiGkl=qgMuGeih#qM%) zZlyh`dFJ(-J60gzS#KCBZm@PTLhcn87CxhxXK^9YRX>)RiGhmpiSMxF*<6jwf|R5x z4UJC!$#>-a3hBSABu8L=cGH0PHoI6ol~FfM9+6RsQ|64fy2@zwaug7!VQ zKz63<9H#bsb1NS>I#}{d$QI`W{@c645#f{3 z`zHYK=;NOU6Lq-;RUIV6?uW0p1Qr-@~tLdjvQ*;yt&; z=;?0M&Qiez?*o>!=g>}(A4kzXR1@2n&^OZsZ&QmlJS8(i4y}=c>h!4{sDTJ4)XlV2 zqGY}8Xg)(l62^h7d6Lsy+9RJTsLL91t)pOB!x9^o<0=6U0|Y++V7)wL6bitpU*nn`rC8f z!{EPJm{toOhEuTRBpOv)etrv$+p27=RyB~s0|Ov=nsW`&yY{=hyp>V$Tj8BPII1#? zdkY=Xn`vf&)iTlji^_zd%o2gN1@Hto}0`SaVMd(0?A4;avCj#BV2@GC| zaumeVBHv;sQP6$xjl&P1k3EaqM9-1NOk*0S^<;W;VaojN2O*MYA--LP* zOusgqDO5@O&D*-)T>v4>;pNtGnYp*vR(Ma_VPjl{Z~G~$hyi4-m?Q4a(P)3vp#URA z`z0htX^zG!YQwSi$m zPmMbUWqPIEZ;|dl?SQob!NjKuOryRUXX+%7^0%*RMkLax!nzi@I60X?J|Rp(QDh!G5BoZ{V`R48lj0lrHcYB4SIvKhwKc-q5v*L4_?_Iw3cSLR!f{ z2(k-`{YEJyv54jRiAQb$OljZ-91l3s7uz)zVDeFQ6U(-o|99v$9Q!PR+GZ{bArAqg z=rjN<2}N*T1m!~;T>5m{YWoUJEHF7AYNwYv#pAy(fjLAX1+m~z2=|1KNA1-OV{GBW za^6DNRrDbMO3@RECyt6bv_Q(;kH~8tR|Z`TG=p380>LcG%g<+exQMEts7U9xnyge5 z5gB>SXFHPDmbZVUb}jILJ#gb)6brl>)CIuFLelBuiVq!{2OHKWCwcD~s#qjL_BawXd2IOE4*b9DmfcjMlN`?^aw!FT!Ar*cN z4Y*BTft0~2gHuMH!+%k8w3GX|`srx?gRk%?a)Zr~Ei=g3tQkB<&&4lu9D@;yWS_ zkiSio7G8IZU>}Fa6B4^;-xB3Ed&dwYCocYBQz(SH^&#Gc;|n);;na=3-d-9`ZfP00ETvbz^EM#I6ulAnY7yI0kSImPZ`m9D zIVtqFWY`;q8&-K}QFe{AAvQQU1vY!+Ll^tmland4%$yg8UppQsD!LOH$*W9n3}&Kk z8?fKKYj8HE!Yhk`=X*39!w@2;otXvBMkNAjp=~Gi>iR_?(W?F7)8Mf9Kj0bjL8inH zNgN1*z2qPGxBr=D4tnPVzInrOQ{;>wKjfh^Gje8A|e>C7d!kwy`vg2_xr|2Tl9%z`*R`h&;i`KKwD5%jAtAxMorKw1$q=23g2H#xI}| zf_&#S=?mdH|8#&f zM}zqX+<+>sdJJvFG8w3@QZt|7vUIYp)i*-aFMp^+IMst^F0x+*^_N?O+^A&&vRn15 zh|2AEFX2F0C^K!#nC0U>4!?vRl{vIBvwOO`Pe=SM3!;!(rj-G?_3R9Xw{;{+<+i`f z*H3#LP`&gbGGn`y>|Y&BMndu4Fn2a4(uf|i%VD_Sp}9&>+n86#0o?nLF6oe1-IYF6?!hD^CZlD;&^W%_r5bSwV?4Xag0Kl1RUs7a2tLZ zyGlv%Eq6!YdcTK2gCFj9GVco9S`@Cg_3%X;oDkap)YkeGIaPZ{U)ge>0+-3{KQm5b zf>%AnA#Q}SigpUS>Cu`3Z6h)aN++=Yoot=)2QjR8Su-nPVy!FqaIWByDm;5uqySMU z#3j=L{Gz0S&d86yyWUsif#Y!lJp0ZC-*mT8?hIJ-GKs8^_uDO%nq)asLI>rDH6><( z7T7hpg3fuyWY`hrWA7hYZ6Yat_Vc3Qfv-3lz<+1jzhC0_ zO~lh+5fChxnVROPoY}=Vd*#xQR(V2UFE8LcCE%{+G}#B*8&-*tY}C2@xO?v~WL+)l zdcf!s)s?QBBbHQMXqNSS0pJR^lQ`f(YyS9VyDAd7ZwHFhx~Ry=3fbR&R)>kuAG!i& zi&7Y_i??Jnog6z4xQE|(*LC&p{9_VDgoojd;26}-BTJYYEdInBGAf(kPqXovPoKh5 zR%vATrd2wz3P`(jH22oWw+6n_|I8(WO&=|@ag)`rGN}H|r`xxmzRAqISU5a%Us2Q3 z`(*J2KqB-Zl8JNmXss10=$bxqjzY85kN{>2^B{NDyvAJivmG+VwxNL@;;DbK@{iZv zom-Jl7csH0J{mWB+Rdx=(@*mJK(IBwISR?gRyE7aI{3sY;`cdb139uMiXiB%vqGfp zwxYXrHyruDAvA}>U1w28!K-JZ%tHJsIr)H=k>%|l((k%V^Qi8>A@*iI^(*f~xX{kY z#8D4mZAhW5ydaA?YO;4N5-pH-%Mc36Gw{-JXjXV?mrqG+t2BT3{zqP3os$-T2cw+${_wj&Da*)Hz=4K{;1I2xaOJK(!|)) z)+^_iU{IGtbsB+ZyVHfm`++rQSrk5<#QEmdT<&Lt)hJ>l6uUIiCEzkF3}j%2lmli) z7E)Xq1mXrYwlj%}8nyv}CS&}^sEW=!$8*562?8BT-`FwgAwiTcoO}0qrKGMYYh}8B zymuhw>W5Cw;W4bSTvYyctqj~8WXHXJ=#550>-FQK2)V}#&~UP2uqi81kigb$UWSf3 zGpB&SF;ZC@kZx4Qwba3fAO2Dz>G@GPs({}!@4b1aor%(^4%zF*^x2b--yo*b3iTk5 zEjDgsSyQT2B7+|Y@+!7<91u>u@9vl}^{i$GT;c|t{iGJUcb17dGojN;Dj)R^qGM-w zh_P@L=Z@AQ54~z;Uf}wjbO|8^k|KX27rOHtMDSiIBRW^ei?j!4&=&z zCLkyuMs1XXrMOL(gRFMB+X;C$2pta;q~?5xMi7xbNY6h)FoU9^cd@}NDJ3sU&3mGGN1MA=bd3Y z>#ic2*K}xoVvGu|2g{#%Am_~c?h*OHA~RApGkI(ZTq<56DN5hDb8EaO+F?-(1-4aQ za6ec4F2>(KjKj^#W8~nlH-lh;(Cdz=v8NX)DJelcJuljrf}*<2T_M5p2YLP#7I7Y5 zg{np zqf2HIr03g(dygTrw;dyh~9dMOcqEX~EItG;G=c9<(VM4F@jr;YbuTRWi zM9ZHmAf!~>7hKQ;%o?2UM6TWPfMg-fWk8Nrk)Up#dJh#hj$!5?Ic}xw=NQg;YFWZn z#YImIU=%2LdDUf*x4e_WMi5_o{ME{slB1o3VmBWmpeqe$dMv~dxnf=%xb3_=JbePz zKtzeUMwlYA)!DLQB7m%-OGQns2KPF?Wh+c$_%m{Xu6<7fqySa152PBQ2Qfr6p$zlE zDoUoUKBKMn6C9IEQf|v=MR!pN(-d8S_NO;BH8rr2D3S+=81%B;j};X{IyyQVOBc`! z%KP8z0+!5l7topL^K428J?sjm1A{MC<`4CibAc^7qY52@cwb~c(Bdk zeQ$e<`=1;6_?(N{I%Au-?+44m%ZMh-a!P%q8>PXBz}6H4feNmu+adCm@KY)~`EWNF zsz+@d9U-UU=2Ko(MR>M`j(C;iu@STqko^d<70B?gU4##YKMt6)2?+_$hIi%QrBXJ+ zwd<1^;6sLhIgE2`E#w4nnq>^#fs#_qzkd6=e8i`hkq@3fac=V1;pW5t5JYIZ zcj3TuYlhZA@ngS`SQT93Cr@r?=6@d=n*Z%7MlgmPNk@YC%7XEUu_KgfYHDs4DY_X$ zBBmo^o0-D8ToWwb)`SyMs%|?}_ynQJCT)G*^bFl)RD#CyT|!Lt5N2sWS8?$JLnu9; zG+WaD&FI$21^7h5T^n_gWC;`H8rWhc>;*~Fw?j*IK_K_6MI}wUjX=IA<0OIO#_apE zquc-H-;&Gx_aG1f7{ddk=lL@mz9=*fp8KwFVp%JVL7%QpsZfh{jogoD7&QT1jhcBr zMOy5+sc{e(P&*Ksc*{}*SQ)Z#qE)E4V=)=Av(?Y;oxK0Eso$!JE`sig+Zce$hl?uq z__bt0CXu)`XhQ)WYi9ia}Dv|(usOslYFqQCtM}CGpGw}!xWr<#j8{b6a_NZvy!@}bTdwRDrnzx50XPv-uKqz! z76PtZY;UEHUW2hBT8E4|1fd z`%68~!S5w&X~|TP%D{t)p7NG3f6TsaU{fyyU3JihMe@rV#et`vtiqG#K+cowQkgOL z8$spI`{WHfyaf#-iv|m^?z?Tt+#FmyJQGFC$6=^uhK4Vdd~Weo1fKUgH^^sv5)&2m zjW?}~3W;Jz8SVs6NJy8t2m>KzU`a)V>1}Fie-tgDw?)SWesT9Gak~-0i3l4)TG}g4 z36fr`LkfpF!#-O9XVMr23h=2=o^{+3;yH5$$z$3p3L5j}@SCD+b)xJZ5#(v!wcl;t zsz}TWb%*->f*-DL!Be**-F%k!F!&ifA}zw9V`Oj+;d41*`Y(v?A8G98q%N5`0{@q= zc&<*&z=@4LP1m`}gytrgRP-9{)~x^*QtYnAkkHQp>6zmx;6Y&$x?lc`43YQ)mPbU; z7lFcyaVytd%BHP~7WDq#?r%}$LUTtm-RU(2Ck=FTYQa*R!@{xWPi#Yc%O`8Z}~mAxMd9HeM$jH%~aMX=wP3?h8n2 zd${?JX{MNow5@qwg&1&o&wEXo@P=gpZ=2`i!}U|7a)WB7lBz0KLBYr}xz2$*3AZ>0 zKmtF3Vk#Qxi5aV4->Eny$Yhp=t`TWlSvY!Wz$Vg{f@ZFj%rrQhlJXS@6B!?W)Cq-e zJg(Aw-GGHrm-V**O5dKj<#udvRq<<`VTXBP?Z)A3*Q>&5UCtD&}Z^ldZc73o$}$ zz>sOz|1;g$hR^<;PSTGnq7KWTSmuHMz^D;wzdOjxE+lftI(_=O6~OjB{Pp8&&(zl>l@rheJ`O+w$eN9Xg=U2l zv(?$KNvvGY!2~?X;v8$hlR>BsDAv0fZpEXvSrD^(`*rFbP)Is!pe6|)Tu_CuZbNN1 zmUe2xn~WwP2$?W)&(H`3VBKN^w<{O;FZ1%;xOdlnn_)QQ{{8#+dADBN)(iCQo7p;t zv|pChS#r$JRr&@W3VQ|F^LLSUb`$pwj2wr!f>$vc>}eLxdCLkN2Uz&O9s>VAU>NVN z9*-`T?wd&-ljhg*x}1)EN`Dtzk0+5nZ2@Z`2$QjkVVv4&LmWXgNiyv_2+|(CU#q|j ziJ|{OFcKr|2;NIci97U@drthWZs}AAOLbY`6@$}H#YOSjxa1HN4%M&y{nMdaZo;O5 z4~He^Obrb)deb)XI>qiF^aE-J^OAEgX`I^&P?f?pPl{?aS~n$H1Nq~l4}Z3P)@@0^ znaOGQGB|4vESXz*_J_|Bk&z>~NU<$Y&z+#f;>EA|)l`4Av*JmHYEcO^hw+R2=chlM zE9N3gw7><<9zsVABWGVuMz;LX72auzKyH^D`T!z9#0_W+?YGJWtfp2z!C@P3gi+yO zS<}Z2<>x+LS&NC-Sq)F2-1hlq^&&kq8pyg9thZy+5WYQ zm!-#{FjaggaF5_=)jFrfp9>Fqu%1tp@#Ji4$_2ev0(GWokwFceX|uB9S`1A6|8rW1 z+%$0`C$%NH(!O$j3@sBWTO(Qv6BCn6c$#S6mNdB=emCdS0ZWVn3R$)atB~%<;w=X- zTs8wVMo#w*Ra3{e1;(_2cORZ&{n}gmrk($U8KH_XIjd2{&;8au0x(AhvD_<@Rbz(e zFL5+4)POMXJB~)tJ%~fBK5pSDzb;hzDT2-wIn%ZOa5*@20itIrH=KaVOtHWDh=&`i zuN+9Id!s2-l)^gOSY7>UITC-7;SQ5?vwiUIzI$wR^t3y)=(yU4WRl2{i}^bHBf`TS zy8;7(-sFcVBeXwgY`mU(S~u^7tVA_RuJi_mb+loXC!$DZtl`3??D_Hb%n_dboXC?V zDj^fxVmwv&2~tqoM$XGKxGcH4Cpd$e{7g=nxC5J7*3h1XA_WR`n$~BOiy`C>NAUK` z+!4kyf#$om(aHC>1wo(X6kS&%+q*#o@{RywH;Pqygy~H=X9ynFY5_Fg(oW>o{ z{uD?y__&~pqXH^yZMYw1t6@G4rD?5;A=Ao72??Iq1>$>vA|L{7U^2&fL4m9^j)M$L zmG}xH5B5M^n|kw7PSJWP^%>@VDxu|F4vq{uQc}<4d5`iAQL4GDqP9B?8tMGjcfEM_ z7qxmjgu{ByKst2HhEJgVv*i-&11pu>)!JM-hiM%SGOqWP@c({us&%WJ(&o>bMvRHD zzb&V%2|S7-xTs`1SG>MtuwN@VK7}^Pl^fsP{q&~cT{RJA3>$X1*n5{v*qdmS8qfH< zY$l*DG~r-ly92Miy$RHXp{7o?Ic4)K8JP|W=z$!C01I(&js?bncyYVEIwEs`)%F#T z&Y}pQD9zQhC4!TqTP`ag30}G`g!o-KYP%X|6rdtOn>FttnMNG>VdrCU&L6n~^xTpk z1y&)n1aLY%1e)z%8%IYj|2d*KMrEV1?)T)IbFx34HOvOl@|hzw%*X6BBz1 znq$yM^a~0KnpPC2zb*(-lo}pR z_zPO>dywSRy`@n-`M3F9!J*6QDuII&1TGz*owrv|{0^1h%$?^vf$sTax@jeaYNk+m z5JZ!|C>A7Nyuh1VDwVp%%`=Eel{SVY^<{Zw#mun%g=kC1pqf9f5zT&UrrCTuTkqgV z6xR~ACW2ij#m>&|0(z_75i61Eu_8Uccb*RI4rk4g)^CeNf7l9O4_KJ14(1dRs^^DJ>Jr#YMpHa?QOZxqMYNLGgK;K* zene$1NP8;2aFiiF6sa8T@v&P59$Dbbx zMa%09DtgWHc^lV$Pb4?bzR$_&5FjVlJr08jWYNnUkn^}++_P`Vsg+c?2q!cG8_+o{ zs^L84NVX_34%DcIII8l0j{h#;1NDc4Y%PIC)E%jkUyyLf-HKV8Px(iZ$;ql4;87t_ ziK09scZdB20WAB|Yx7HUuAT+EhyT!;`dEskIl;r~2TYhtMCum$=8GDQe(E#L1B-&0 zBXx6IReEpJ(|z+`iMgC?jH0r75z-vU+C6@Gf}Ma~`nD4%SNyrNH(aynfC_VSmxZO* zhAA5QsR*pWFnms|2u;R&s466FjyQjfQ}zqK_*?S@sD)VI?OFmS& z>;C)OC0J3K7GN>66%`k2z}<)!2QAbWnxV9%6aPZM3)S6xwg>`3Ez&hNT+gV=^wk0F zA#f?h$a2h2y%=GxY#08;=Tw{7`C~1bdDtPyKO|r@6|aTHr3W}njoi|Y*7EowGWQ)H zr4$imPgU~`713<&b?!|*4)cx~18a53A29ew!9^@l0(!$uRnDJVoPz902lmIG5srrB z1D5B~Qk0za`Ix;G7)6 z(Lv93_wG3pBjeJxwc$dS9;#6HN*rBV))duE7GpujfLP+?F|+ZaInYq9$6#}RF6Q+| z0KsB-7}9hbGZIgVLhZNk1G`0Na1tXNEX$Bg*tDCOwOSrzahY3aLpDlfT!J?W1H=MDs(9mnkZA_=-MY4AcJh2;;rhgRq zVSDv#`6bl~-P;=Y@yF%AoTU|wf=zbaHLY|#B5+#A1~`J@T!@5S3J<&zLHB`}_5#c~ zIE;oX4{)UPX*VC4AHo?(g|F(@Wl;S5)gNTKN5ILu}Y5_C+W0+aO0@Y81fS@6qz67gcU7FLRMGT$$ z#mHY?zj?zCy-w>58S}QEkPkS3T7vlWPidv0eueREVyGc2$2Yg(eZ+kzDZvI>*(kh? zNx$Qb$JOIlE8CSa_74iRbOGfh?J4%_F~o9ftE&$df$I^N000j}H-nZ|z;*-+d{$4) z2v+tr%(c?e(!$npP)93~tOYH)(GH;VNZqLOJO4rKKghbUk7taSCADa?qVj&fxX6yMgLa(H1P7#KtcC}267Vo`{%IYATYgbfkc0Em{WC)I!yk$-mts^eCJ96RD+L! z$XiuXVt)Y#?J1z%uQyb9+l~>u7$ z+|t68P)OT@(bWn10?El)S;nqS)x5+peqc)SR##EkLQwI`AOUm_YYqSXeAm9oGY6c^ z^8G2>^1qXK|2#?|m!=OSv=UGyN}jD$E%}XgHu$-*udXH6!^E{|$NE8tMAKivejITu z;5RgK%UEGOEi74h#^g$7=IrUMRBxC>vCP%@ktUJ{~Pd+1qLF zQ=xz@gwBsI1dc|k!?pj-ZwPMgh%Wva9;k3Y2dAdHqai*h72=*7`^__s*V$7;32JA} zvw0>f|6;3C9u@Lo;6oZaun`7Q;cIQ?o~Bof{yp))5ttrK@#MvRE>^SQ$FqBb@e^Iu z?3g(>7iCMgC}ot_8NWcCje2=A zd=f{7hN+`yY;(s6E_&p^Ae7WRA9ch(|1PE3RoFMwRX&xjS|ksLFuksh&gvL9X4aA- z+@Th}B6#)@P@0)-c#2)4Uy!?H;kSKZMRnw(9Qx^4zXy%g3^nPJZZn*aB%?5u-?EQR z!5z`6@=<4Zky^;ibGyQOGAEcytj#p&J(RpSi&a(?7!C}gyUM{mzFtXvFxM*wSiFfx zlhYZjDmX0}xU}0800vZoX)@2;3b!}DGU;zbWxj^O1ax%wC}a$8MDc@mx1nh<@sP4lKz?)Qh}*oQ6>LZZZ0cG4 z!NaO5?a4@yiu{fW(%>??fFvA!YnwgySQQqJ%Z7oH25XA0*UrxqZn@}>g|(IPNz{?# zCeh|Ar|=EY!If9++bq{MLFA5mWJ2~TI39k0%9s1zpK``DNF*GEfJY6()@_D5H-+3B4?TB zTWP>`dWIEH_i(prc4qwLM4J)NW=;z*GzY_XWhi-X1c^SGx@E*t?)ZpFAKP?;dy9KYfD5a%;PSfMK==4d2@%VNG}hWO1Mk6=C-RP z3PSc|5lO(3eL-9i#gIjo3fD8@U#&0uc77_hAwNxp=n&KMm;5}<4XTSxqaMslbA8#@ zwZ5~1`ph&;l5Werrk*&+q35gUdPUF`7`K&{G;<_Wc~NI~pT=;e(o9+;dGXazYZ7@{ z+sHJaj(jfW_KA%bXfUy{OZ>r-FjFCoxvWxE%%PDbQXK@0EIUK?=$x$+ut#wEgJgx^ zyIhQ@Z#U9Sxg*)2B}5T@2Kqzc&iY7GON?kzTH4tFBvdU=Pf;Hvu?~}w9wKrWh|Yh+ z?n(EL)j_gs5xDNPw1I(%te+I{EJJT70SNB{CTT?j2tT&d&`NZvS>HD(_5ojcl~O{v z+yg?F?n3ML;Ir`fm|yX^_WNLAVYnRQYFw>k#KFG9C&=44A=*hNo(f;#bLi^5Em3G~Nj{Oj`KzG?6&kN5UjNQc_tu)V zjP*3)jgJFqkjYk;j!KkXO-+u&7kupU;JW+FRkoe}biBI=gBFxrKEczeQD7&?#pTw9F+iRLE*e|9`g?~n-LKw8 zM`M1V>BEie3{WAt`8ymW=6jLOj9kyXSkba;pABApw0g9~NaraH`y}?VF9^&Ry>#FU za!IV)jKLX$=_UBi)rwIG z3xvU<{#~?Zx+pw_(7F1Te9M>23iy|=D`iF-TixQCwM0k~4s#t$QzaI;5pfvIGRSq$o0Y@?{#DbvI zA4!W`6D3kMLH}5-b7Qc^!41M*ApvexKNHZ0T2fO8+hzcSsXw+JHk#RabtJ<@KIJsu zD*9Q!{=4~u?3*t2U2vKAeu4)~d?QlN@oFcKg<%WwekTXAVd!?7;b$=q>1MB@_0t5G}ZWT#Mx0!8C*%!p48Q7g()|%p#Q-nx-Ady}y&-()+;2$EOmc zXbf-4eV||vj#&;t)wc`i2A{)fir^1Ruxb-mKq#)}NG;I@tj}GOXs%W_abyfICBPWH zMwj-#Ma+^PyGozn3bIr?6DzPjK5x5TH1k$G)CKtJJi^uU>CGwRExa@Gi}QvBhfYM=iAGJdp13>)pI0n z2f&%Gb3U3$mU@1Ch2c$j1$l~}&}2M)zlDGPLXu#1?l}za`U?xoX85JNL=T*2Uvjbz zj>k3FAYt33zK%A8%*&8A@W7?*M9;-_A8DIUh-yq9ls@G6X@kT$#s4 ze9CvQ(_&*osnd-NvRqhTys27DaFCuiiDHJGauYuawLq9a6Q(1%d*?_8nK}z)_Pl%b z>YXlIw0>Vl9soL?Xlq-A$3-?wE{$~lC4xXn)foqB`xlReR(x$EBkEX>?<;7KDd*e0 z?Q=cMOr!Nt2Z~Rgy8?_qkPk#`7cZlMqpS>B6sFBYk)}2b&I^#Qe*)MvmbzV12CNyJ zM-Z3{*VEPgJeu~n!Ho%=U3TxQu1xD}q;_4AI2PbC)z_CV{u<^1e-i_82eEKw| zV`i2}l!bwCeLcAaxdrl+o+YF&Z3%=-N4*P*6|GDD5b3MJ=WcXeLZK2_ot&<mJxo1$kZ6SVVnv6f3#?2tFDL&8B7xCC(bVbST10a`J;klsQDaIre>5HCDnesw zf-a95#o(;Kn)0sugaNwQ%+D4=eU1_fLgWdBL$N7jTQT$=GeuJ)5>*6w!9=~{=4k6m zU`Q9KHROH~J4}XEEAaLlK9?$jU6Biv-NRF%I0G(nIO=G^>7fJC=1%ef^9nQe^D>M@ znAkV2p7}Io0hlIc78bOra0yJB!&u2T0jQA{Xo>~Z#O?Z}6Q=1Hh($0mq8YttE(0_R zUb$=>U{6fTw*11kdBx~lR8^Ivn+Jt}E^7)_J6S=>dH|{oT=spB=nxAI8aZAdZee@~ z>FMtp0G*}=MnaD8V;>O0uTlWCAuA%fd2k>&42I1N`yJ7_5}sp}-J=$9H7}U3mqc4A zIQw(84q>N8#APtgkw_T)yid|8$jE4G47e^fOkF&AS}|!vW+9UWe&;Xac_By4a5w#f zhu#zTk6F=mJ}ea`#YWmvX}_lHbZ)5O--8FbQ0|?`*C71p=M3RL5LrRt>!Sk!c$=6_ z#-_kX3Jlq+e)+w$D&m1+ccE)c0y2y@LC56 zVCadl8ZdO2_K7LG{u1EQXfT4~1%Vvx;^42;(|ie3V)dyXKXgWS3=Agz+-}0*HEqSb zsKnnm@xx$5JIQ<=Y$F3Vu;beEaWUdGyWTJxHRDi$( zRI(Ru^N;gzMbd$n+Jwf8IjjYGw%B$!p#yM}i<3A|AH;gdEV|J$kYe*r!no+*n)RLg zON2Mbj|y&qrQE(y>!bbBrBc>hPWCiRNP@Sl1!Wag;@1N%on&l5Dm>E6?{aJ!i)8EM z`9kG-{xTfa!^Wq7?5NJVGf74g7 zzT9%j*<YH=054Qfv=2{B)w54!By#rk~z zuLK6A0ElS<07a&rrf{ME6O2A|V@`t~WezdO3$QB$g?z>Tc;98=bq6Yc6GzQ{`ugtrjJKjV(gkL^?F2~2h5>?`SIr{a85b|1=2y+j-LyfD4EJ)+85hHA) zHu8Ck*nj2bJQXIBJ|2;`s`eXek(or%0w044Fjj0tFwp2!GyvLP!fjN~(tUs5+mE;t zbLfV_({%zM3d7o3TISM(mvMAunR%bAAtI$t4=!b!4NG9;JOp#yZXI2NLcD+KIVCfce2pWkCa&qHJW>=B)O2 z?_xTB8yI-tiQmh{%6k3XX=(q|;NWZvz!*F0Dz|ZSn}~Y7g4cCmxdkt`fs(2Z3hGEO zd4Y(qq6_#)*=h}U{9#B|94+~&Px|t*r46j?jfP*33f!Ay`^y>i1Ve3M-}7pY1O?4ZUETwCz= z5)!F}dGMabJH@<+g>MCrW04-qIYQ~Gb>@pA5pijqWc)}^#Nhkx2z%*7a}&*GVMIYB z#{$Z|FY%b&oF9>C0}rb50GN6ZA**6HtA^pq&re`4&^w|bf$P)McVrk+-2$$2RTpUo zmSF0Up-f@kdyYgYnTtoE+vsK z)KObHvQ}MRxyj!EfrIN3ZfCkbJRa;#L?N>gv_q=6&t4#-&DakQFKe;rJ|!UicT@FE zH@E()=}L&lFcGLhN#G~zXDteMtRcnzfghYXS!qU(`jM9hFYY|BD+VTlRf14^#jZSM zRRZJQJc8q>1ns5D_N?sb4#=iCieVVUi5g&)@!9Z>MQByWjTd^+pG?5wqeIk>57~r@ zSdC0ewC2D*FAUPBgub$_rEcM3vvvv}1{K_J4_Dd)E<)R`REbvIbyHPAt0@}C!Z*Tj z4K-WHK&_Q#20o2nD2IxwT0Ng_?cn9Vt;#-VmJ7OyaC3Vpv1zylcyt1m8;&PEo%e4u zlwM%)WTR7eBIY0iY00^ZmhG?Z%SU;97%xc>Yy;w~2Bpt2AHTkl#Bc-}N2ng^@;Qa^ zY~$^CMSke263qujV!A(QR9`S(g?(0ch~4$rveHzC800-E(m#uDkZ$gZg$QnfPFkNj z@SCj(ZvY;8eSTLj814c$_xRTXzfGn4No6ZaH&)@;_zL&Q%uR;AZ{Iqog#Vi&tp;Wv z8dXOwj)Po1)2h!a+Z~XHk^3>cV$=z0BDM-4W4g7W=>c913G$!d8 zFFFAoSX1*0KFO^_)_(WAla-B-+iA1skj1|?B^<%UWDAS&Ap^Cl3VPqqc0W%DU%j$8COs_{}xJCxP*ouQu^@Z!^Wz~9OOg5XW$Yux8PWexQB%eOnz zXF$Pv1J@GLyrFE8wP4dq7aB0~v&^$PXQ4(fWHGXR@9+09;z`3WCN0+C$c9Guk?*I@ z7+P~pCEmM0;wpuKJOZdn(3~r|K5gj0i?Dx)cA!LQkd`SObo~L^%~ph?X#KrXQlMJj zt9^?$HH$(cr@Rm89Tiv7c@4bIQiyb>$UX=jqFtU^x5a|uEM)>>vZ?&( z-(8ISfYGP~LQXT>H-8^Wi-#ip2iXCh+WEVJ_0_mcz&cUGo+pjTxGjbB-IyWd$AK)o zo~v?IU@{*Rzs7q(UNCCl3$xB8dem&WSYqNpCr)krjSzG(}2t`{9ZtMLZJ131mBPkyt;CYq^TWOkCI4g97cCMKRl zJQ}o%HP+9bS?YVPzVry@?EVKAlt?J;uQ*`V4!0*hq5X8UUa2Isz(*(=Kg4IQV-mZ% z+KGSQx;$S=i~^knHu_J#qIJCL$3^}q!$u!%myKE< z=SsCc{;}2fHcQ{ww(Ggnc@Me^;FUVmvc*o2MSf)+8Ms+83wux@XQS4Go7YAzPUjxEphf{U>UNMK626isAX^XB{U^ zS51$tKu&91^$KoIn0S7a@V!b0;-kQ*fZVkX9K}KSZ?IdCL2K1-2ei-4avgW>V>IGp z1ES|;8soX2VPq9GG^YPX7?xj~z;bbUww-}X7j(JM`B+!&CYMg)o5`gpin>V{T#)ni zN`o?B^aH7!GA2b~m*IV}=a}xODXq1&I*tvqg{@OhtNJFOteb*k=5E75|t2I z)2+_vk(l|~hg7(O@LJq~V|=b)X}N6ls1QNm`ve}qZRl0l;GxTh>6KcuZT@DJrsNZO zO{P8uXZi%>YKVW{1%U)eppJ05^haq(9Q3}2Dw!Ov>DN0|XQ7dJ2emaYQL?kiQl8b8 zN(QqUki9MPk>F4hgv66oykgBL5a98EAlKt4lnb5W_$1$8x4@=0??uY)4jA17xZ7s) zI>SWJ6$AX*0&8?QuBsv1wChmWCIo)w3a^@7X066t86igl(XdAAd|s1g9Roc*){+k& z79}*{qvaCuJ$(8!AfU|+E~$2z!Y&CgllgVYr%zfn&-YA$J7Xj0nM-sb1x>Uv2x#5Q z9MlD)!Y_JaV)qKrAur&J3ItCp8z(2{-ykZchZc_?C)bpfeeY@`2=$?&Y~i~GnFzb@ zR`VfFsjcKSOWJ^9l1A6<+{CmC2 zf;!+@ryqE|2v=6|{AYd{HYyGt(i-2RXWnyg{295Hi<;NWEY{+H`!JLN@)rNU|7L0w ayTK48KYCGqTDOb@e?5Glu23Oo9{PWJ24)oi diff --git a/plugins/lancedb/skills/lancedb/SKILL.md b/plugins/lancedb/skills/lancedb/SKILL.md deleted file mode 100644 index 47537f31a..000000000 --- a/plugins/lancedb/skills/lancedb/SKILL.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -name: lancedb -description: Use when writing, reviewing, debugging, or documenting LanceDB pipelines in Python or TypeScript, especially code that should work across local LanceDB OSS tables and remote LanceDB Enterprise/Cloud tables. Helps avoid non-portable full-table materialization, choose idiomatic query/search patterns, apply LanceDB performance defaults for ingestion, indexing, filtering, and diagnostics, and resolve connections to the remote server for Enterprise-only operations such as jobs. ---- - -# Building LanceDB Pipelines - -Use this skill to produce LanceDB pipelines that are portable between local and remote tables (for LanceDB Enterprise/Cloud) and idiomatic for the selected SDK. - -## LanceDB Table Modes - -LanceDB has two common execution modes: - -- **Local table**: embedded, open source, in-process LanceDB. The client opens data from a local path or object storage URI and executes queries in the application process. -- **Remote table**: LanceDB Enterprise/Cloud table opened through a `db://...` URI. The data may be very large, commonly backed by object storage, and queried through a remote service. - -Do NOT assume local-only table helpers exist on remote tables. If the user asks for LanceDB Enterprise, Cloud, `db://...`, production remote access, or a remote table, focus on the remote table path: use `search()` / `query()`, keep reads bounded with `select()` and `limit()`, and avoid table-level full materialization APIs. - -## Workflow - -1. Identify the SDK: Python, TypeScript, or both. -2. Identify the table mode: local/embedded OSS, remote Enterprise/Cloud, or portable across both. If the user says "LanceDB Enterprise", choose the remote table path. If the task involves jobs in any way (listing, inspecting, creating, or canceling jobs), it is always the remote path and requires a remote server connection — see "Connecting to the LanceDB remote server" below before doing anything else. -3. Read the matching topic reference before writing or changing code: - - Column metadata authoring (both SDKs): `references/column_metadata.md` - - Branch operations (both SDKs): `references/branch_ops.md` - - Remote server connection resolution (jobs, raw REST): `references/remote_connect.md` - - Job operations REST API (list/describe/cancel/query_events): `references/remote_jobs.md` - - There is no bundled per-language guide. For exact method names, signatures, and options, look them up in the canonical sources instead of relying on memory: - - Python: `docs/src/python/python.md` (the hand-maintained API reference) and the source under `python/python/lancedb/` when working inside the LanceDB repo; otherwise . - - TypeScript: the generated typedoc under `docs/src/js/` and the source under `nodejs/lancedb/` when working inside the LanceDB repo; otherwise . -4. Apply the SDK invariants in "Per-SDK Invariants" below. Read `column_metadata.md` when the task is documenting, tagging, classifying, or grouping table columns (field descriptions, `lancedb:tag:*` tags, logical column families). Read `branch_ops.md` when the task involves branch lifecycle (list/create/delete), writing to a non-main branch, or verifying a change stayed off main. Read `remote_connect.md` when the task involves jobs or direct REST access to an Enterprise deployment, and `remote_jobs.md` for the job REST methods themselves (list, describe, cancel, query_events). -5. For Python schemas, favor Pydantic models and validate records before writing. Use PyArrow schemas when Arrow-native, streaming, or highly dynamic data makes them materially better suited. -6. Prefer `search()` or `query()` builders with explicit `select()` and `limit()` for reads. -7. Avoid table-level full materialization in remote or portable code. This is the main local-vs-remote read pitfall. -8. After a successful embedded OSS ingestion, call `table.optimize()`. Do not call it for Enterprise/Cloud; remote maintenance is automatic. -9. For remote Enterprise/Cloud writes, never drop-then-reuse or `mode="overwrite"` the same table name — see "Enterprise: never drop-then-reuse the same table name" below. This is the main local-vs-remote write pitfall. -10. If reviewing an existing file or repo, run `scripts/check_materialization.py` on the relevant paths and inspect each finding before editing. -11. Cross-check unfamiliar or non-trivial API claims against the source tree instead of relying on memory. - -## Core Portability Rule - -Do not write code that assumes a local table API will exist on a remote table. Remote tables can be very large, so whole-table materialization helpers are intentionally unavailable or unsafe. - -This does **not** mean result conversion is forbidden. Bounded query/search result collection is normal: - -- Python: `table.search(...).select([...]).limit(10).to_pandas()` -- TypeScript: `await table.search(...).select([...]).limit(10).toArray()` - -The unsafe pattern is table-level or unbounded collection, plus local-only dataset escape hatches in remote code: - -- Python: `table.to_pandas()`, `table.to_arrow()`, `table.to_polars()`; `table.to_lance()` is local/OSS-only dataset access, not materialization -- TypeScript: `await table.toArrow()`, `await table.query().toArray()` without `limit()` - -## Per-SDK Invariants - -Python: - -- Result collectors: default to `.to_list()` (plain dicts, no extra dependency) or `.to_arrow()` (PyArrow ships with LanceDB). Use `.to_pandas()` / `.to_polars()` only when the project already declares that dependency — do not assume pandas or polars is installed. -- Plain scans differ by client: the sync client has no `.query()` method — use `table.search()` with no argument; the async client uses `await async_table.query()`. - -TypeScript: - -- Collect bounded results with `.toArray()` (objects) or `.toArrow()` (Arrow) after `select()` and `limit()`. -- For large reads, stream batches instead of collecting: `for await (const batch of table.query().where(...).select(...).limit(...)) { ... }`. - -Both SDKs: - -- Ingest in bulk or in batches of thousands of rows; never write per-row in a loop — each write creates a version and fragment, slowing ingestion and later queries. -- Build a vector index once brute-force search is too slow (rule of thumb: beyond roughly 100K vectors locally), and scalar indexes for filtered columns and merge/upsert keys. Use index defaults unless the task states recall/latency requirements. - -## Enterprise: never drop-then-reuse the same table name - -LanceDB Enterprise/Cloud splits a **control plane** (DDL: create/drop/rename) from a **data plane** (query nodes that serve reads). Query nodes cache the resolved dataset for a table name for up to `table_cache_ttl` — **default 300 seconds (5 minutes)**. After you drop or overwrite a table, the control plane updates immediately but the data plane keeps serving the *old* dataset until that cache entry expires. During the window the two planes disagree. - -The failure this causes: you `drop_table("t")` then immediately `create_table("t", ...)` (or `create_table("t", ..., mode="overwrite")`). The DDL returns success, but every query against `t` returns **`500 Internal Server Error`** (the query node resolves the stale/deleted dataset), and a fresh `describe` may still show the *old* schema/version. It looks like your write silently failed; it didn't — the name is cached. - -**`mode="overwrite"` has the same problem** — it is a drop+create of the same name under the hood. - -Rules for portable Enterprise ingestion: - -1. **Never reuse a table name you just dropped/overwrote within the cache TTL.** Do not use `mode="overwrite"` to replace an existing Enterprise table in place. -2. To (re)load data, **write to a fresh table name** (e.g. `_v2`, or a run-stamped suffix). A brand-new name has no cached data-plane entry, so writes and reads work immediately. -3. Before creating, `list_tables()` and **fail loudly if the name already exists** rather than overwriting — prompt for a new name. -4. To land on a specific final name that is currently occupied by an old table: drop the old table, **wait out the TTL (~5 min), then `rename_table(fresh_name, final_name)`**. Renaming onto a name whose old dataset is still cached hits the same race, so the wait is mandatory. `rename_table` is a supported control-plane op. -5. When you hand a table name back to a human, tell them which step still needs the propagation wait (usually: "the old `t` was dropped; run the rename in ~5 minutes"). - -This is Enterprise/Cloud-specific. Local/OSS tables have no separate data plane, so `mode="overwrite"` and immediate same-name reuse are fine there. - -## Connecting to the LanceDB remote server - -LanceDB Enterprise/Cloud deployments are served by a server implementing the lance-namespace OpenAPI spec (). Every remote (`db://...`) connection talks to such a server, and some operations exist only there. In particular, **all operations around jobs (listing, inspecting, creating, or canceling jobs) run server-side** — there is no local/OSS equivalent. Before any job work, or any direct REST call to an Enterprise deployment, read `references/remote_connect.md` to resolve the base URL, credentials, and database header and to validate the connection. Then use the four job REST methods documented in `references/remote_jobs.md` (list, describe, cancel, query_events). - -## Script - -Run the scanner when reviewing or modifying an existing codebase: - -```bash -python skills/lancedb/scripts/check_materialization.py path/to/file_or_dir -``` - -The script reports likely unsafe full-table materialization in Python and TypeScript. Treat results as review prompts, not automatic proof of a bug. diff --git a/plugins/lancedb/skills/lancedb/agents/openai.yaml b/plugins/lancedb/skills/lancedb/agents/openai.yaml deleted file mode 100644 index 5a5b2d5cd..000000000 --- a/plugins/lancedb/skills/lancedb/agents/openai.yaml +++ /dev/null @@ -1,6 +0,0 @@ -interface: - display_name: "LanceDB" - short_description: "Build LanceDB pipelines in Python and TypeScript" - default_prompt: "Use $lancedb to create a table, embed sample text, and run a vector search." - icon_small: "./assets/icon.png" - icon_large: "./assets/icon.png" diff --git a/plugins/lancedb/skills/lancedb/assets/icon.png b/plugins/lancedb/skills/lancedb/assets/icon.png deleted file mode 100644 index 94cdd637a6b890494db48c78876675f322ffdb4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23274 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 diff --git a/plugins/lancedb/skills/lancedb/references/branch_ops.md b/plugins/lancedb/skills/lancedb/references/branch_ops.md deleted file mode 100644 index d79e5c8bc..000000000 --- a/plugins/lancedb/skills/lancedb/references/branch_ops.md +++ /dev/null @@ -1,16 +0,0 @@ -# Branch Operations - -Branches are isolated, writable lines of history forked from `main` by default (or from another branch/version via `create`'s `from_ref`/`from_version`). There is no global "switch branch" state: `branches.create(...)` / `branches.checkout(...)` return a **table handle scoped to that branch**, and every read/write on that handle lands on the branch while the original main handle is unaffected. Unpinned handles track the branch's latest version and are writable; `checkout(name, version=...)` pins the handle to that version and is read-only. - -Don't work from memory — read the public docs for the current API: - -- **Branching guide (concepts + Python/TypeScript examples):** — covers creating, writing to, reopening, and deleting branches; applying branch-tested changes back to main; diff/merge (Enterprise only); and building indexes on a branch. -- **How branches relate to versions and tags:** -- **Python API reference** (`Table.branches`, `Table.current_branch`, `Branches`/`AsyncBranches` with `list`/`create`/`checkout`/`delete`/`diff`/`merge`): -- **TypeScript API reference** (`Branches` class, same methods; `table.branches()` is async, `table.currentBranch()` returns `null` for main): - -Notes the docs may not state prominently: - -- Branch lifecycle works on local/OSS and remote Cloud/Enterprise tables; **merging into main is Enterprise-only** (others raise `NotSupported`). A rejected merge is not an exception — inspect the returned `status` and `diff.mergeBlockers`. -- To verify isolation after a branch write, read through both handles: the branch handle sees the change, the main handle must not. - diff --git a/plugins/lancedb/skills/lancedb/references/column_metadata.md b/plugins/lancedb/skills/lancedb/references/column_metadata.md deleted file mode 100644 index 2fe1c7c5d..000000000 --- a/plugins/lancedb/skills/lancedb/references/column_metadata.md +++ /dev/null @@ -1,183 +0,0 @@ -# Column Metadata Authoring - -Write column-level descriptions, tags, and logical groupings onto a LanceDB table's schema. Use this when the user wants to document, annotate, tag, or classify what their table columns ARE (embeddings vs labels vs eval metrics, model provenance, version families, etc.). - -Works on local/OSS and remote Enterprise/Cloud tables alike — read the schema through the table handle, write through `update_field_metadata` (Python) / `updateFieldMetadata` (TypeScript). - -## Metadata key conventions - -All metadata uses namespaced keys: - -| Key | Purpose | Example value | -|-----|---------|---------------| -| `lancedb:description` | Human-readable explanation of what the column contains | `"CLIP ViT-L/14 image embedding, L2-normalized (768-dim)"` | -| `lancedb:tag:` | Flexible key-value tag; the suffix names the tag category | `lancedb:tag:field_type: "embedding"`, `lancedb:tag:model: "clip"`, `lancedb:tag:project_id: "foo"` | -| `lancedb:logical-column` | Logical group/family this column belongs to | `"clip_features"` | - -Tags are open-ended — use whatever key suffix and value make sense given the user's intent. The tag suffix should describe *what is being classified* (e.g., `field_type`, `model`, `project_id`) and the value describes *how*. Multiple tags on the same column are fine — each is a separate key. All values are strings. - -## Step 1: Read the schema and existing metadata - -Read existing metadata before writing, to avoid redundant updates. - -Python — `table.schema` (sync property; async: `await table.schema()`) returns a `pyarrow.Schema`. **Arrow field metadata is bytes-keyed in Python**: - -```python -schema = table.schema -for field in schema: - meta = field.metadata or {} # dict[bytes, bytes], e.g. {b"lancedb:description": b"..."} - print(field.name, field.type, field.nullable, meta) -``` - -TypeScript — `await table.schema()` returns an Arrow `Schema`; field metadata is a `Map`: - -```typescript -const schema = await table.schema(); -for (const field of schema.fields) { - console.log(field.name, field.type, field.nullable, field.metadata); // Map - // field.metadata.get("lancedb:description") -} -``` - -For struct/nested fields, recurse into the field's children and address them as dot-paths (e.g., `parent.child`). - -If the user hasn't specified which columns to update, work with all columns. - -## Step 2: Generate metadata - -Decide what to generate based on the user's request. - -### Descriptions (`lancedb:description`) - -Base descriptions on: -- The column name and Arrow type (e.g., `FixedSizeList` of floats → likely an embedding) -- User-supplied context (upstream pipeline, sample values, domain knowledge) -- Name patterns: `_embedding`/`_vec`/`_embed` → vector; `_label`/`_class` → label; `_score`/`_eval`/`_metric` → evaluation metric - -Be specific and concise. Good: `"Sentence-BERT embedding of the query text (768-dim)."` Not: `"An embedding column."` - -### Tags (`lancedb:tag:`) - -Choose tag key names that match what the user asked to annotate. Common patterns: - -- Semantic field type → `lancedb:tag:field_type: "embedding"` / `"text"` / `"image"` / `"label"` / `"eval"` / `"id"` / `"metadata"` -- Model or source → `lancedb:tag:model: "clip"` / `"bert"` / `"vit"` -- Project affiliation → `lancedb:tag:project_id: ""` -- Version → `lancedb:tag:version: "v3"` (and `lancedb:tag:latest: "true"` for the newest) - -Use Arrow type as a hint: `FixedSizeList` + float → embedding; `Utf8`/`LargeUtf8` → text; `Binary` → image or blob. - -### Logical groupings (`lancedb:logical-column`) - -Look for naming patterns across columns: -- `clip_v1`, `clip_v2`, `clip_v3` → logical column `"clip"`, latest is `v3` -- `text_embed_20240101`, `text_embed_20240601` → logical column `"text_embed"`, latest is the most recent date suffix - -Write `lancedb:logical-column` on all members of a group. Mark the newest with `lancedb:tag:latest: "true"` (in addition to its version tag). - -## Step 3: Write the metadata - -Each update names a field by dot-path and carries a metadata map. Semantics (identical in both SDKs): - -- **Merge by default** (`replace` omitted/false) — preserves existing metadata the user didn't ask to change -- `replace: true` swaps the field's entire metadata map — only if the user explicitly asks to overwrite -- A value of `None`/`null` deletes that specific key -- Batch all field updates into a single call when possible -- Returns the new table version - -Python (sync and async take one dict per field, as varargs): - -```python -res = table.update_field_metadata( - { - "path": "clip_v3", - "metadata": { - "lancedb:description": "CLIP ViT-L/14 image embedding, L2-normalized (1024-dim).", - "lancedb:tag:field_type": "embedding", - "lancedb:tag:model": "clip", - "lancedb:tag:version": "v3", - "lancedb:tag:latest": "true", - "lancedb:logical-column": "clip", - }, - }, - { - "path": "clip_v2", - "metadata": { - "lancedb:description": "CLIP ViT-B/32 image embedding (768-dim), superseded by v3.", - "lancedb:tag:field_type": "embedding", - "lancedb:tag:model": "clip", - "lancedb:tag:version": "v2", - "lancedb:logical-column": "clip", - }, - }, -) -print(res.version) # new table version - -# merge semantics: add a key, delete one via None, keep the rest -table.update_field_metadata( - {"path": "clip_v2", "metadata": {"lancedb:tag:archived": "true", "lancedb:tag:latest": None}} -) -``` - -(`replace_field_metadata` is deprecated — use `update_field_metadata`.) - -TypeScript (takes an array of `FieldMetadataUpdate`): - -```typescript -const res = await table.updateFieldMetadata([ - { - path: "clip_v3", - metadata: { - "lancedb:description": "CLIP ViT-L/14 image embedding, L2-normalized (1024-dim).", - "lancedb:tag:field_type": "embedding", - "lancedb:tag:model": "clip", - "lancedb:tag:version": "v3", - "lancedb:tag:latest": "true", - "lancedb:logical-column": "clip", - }, - }, - { - path: "clip_v2", - metadata: { - "lancedb:description": "CLIP ViT-B/32 image embedding (768-dim), superseded by v3.", - "lancedb:tag:field_type": "embedding", - "lancedb:tag:model": "clip", - "lancedb:tag:version": "v2", - "lancedb:logical-column": "clip", - }, - }, -]); -console.log(res.version); // new table version - -// merge semantics: add a key, delete one via null, keep the rest -await table.updateFieldMetadata([ - { path: "clip_v2", metadata: { "lancedb:tag:archived": "true", "lancedb:tag:latest": null } }, -]); -``` - -## Step 4: Confirm - -Report back: -- Which columns were updated and what was written -- The new table version number (from the result) -- Any columns skipped (e.g., already had up-to-date metadata) - -## Quick examples - -**"Write descriptions for all columns in the `product_embeddings` table"** -1. Read `table.schema` → all fields + existing metadata -2. Generate a `lancedb:description` for each column based on name + type -3. One `update_field_metadata` call with all descriptions -4. Report - -**"Tag the columns in `model_outputs` with their field type and model"** -1. Read the schema -2. For each field, classify by name + Arrow type → set `lancedb:tag:field_type` and `lancedb:tag:model` where applicable -3. Write in one batched call -4. Report - -**"Group the feature columns in `training_features` into logical families and mark the latest version"** -1. Read the schema -2. Find version patterns → assign `lancedb:logical-column` and `lancedb:tag:version`; mark newest with `lancedb:tag:latest: "true"` -3. Write in one batched call -4. Show the grouping diff --git a/plugins/lancedb/skills/lancedb/references/remote_connect.md b/plugins/lancedb/skills/lancedb/references/remote_connect.md deleted file mode 100644 index 670242c94..000000000 --- a/plugins/lancedb/skills/lancedb/references/remote_connect.md +++ /dev/null @@ -1,45 +0,0 @@ -# Connecting to a LanceDB remote server - -LanceDB Enterprise/Cloud deployments are served by a server implementing the -lance-namespace OpenAPI spec -(). -Every remote (`db://...`) connection talks to such a server, and some operations -exist only there. In particular, all operations around jobs (listing, inspecting, -creating, or canceling jobs) run server-side — there is no local/OSS equivalent, so -resolve a server connection before attempting any job work. The job REST methods -themselves are documented in `references/remote_jobs.md`. - -Every request needs two things: - -1. **Base URL** — the server endpoint -2. **Credentials** — an API key (`x-api-key` header over REST), and usually a database name (`x-lancedb-database` header) - -## Resolution steps - -1. If the user already gave a URL and API key (or said which environment they're working against), use that. -2. Otherwise, look for credentials already available in the environment: - - Env vars like `LANCEDB_URI` / `LANCEDB_HOST` / `LANCEDB_API_KEY` - - A server endpoint already running or port-forwarded locally (the REST default port is 2333, i.e. `http://localhost:2333`) -3. If you didn't find both pieces, ask the user directly: **"What's your LanceDB endpoint's URL, and what's your API key?"** Also ask which database to use if it isn't obvious. Don't guess or probe further — the user knows their deployment. - -## Validating the connection - -Make a cheap authenticated request and check the status before starting real work: - -```bash -curl -s -w "\n%{http_code}" "{base_url}/v1/table/?limit=1" \ - -H "x-api-key: " \ - -H "x-lancedb-database: " -``` - -- `200` — connection, key, and database header all good -- `401` — API key missing or wrong -- `400` mentioning a database header — this deployment expects `x-lancedb-database` - -## Non-REST equivalents - -The same credentials work through the SDKs and CLI: - -- Python SDK: `lancedb.connect("db://", api_key="", host_override="")` -- TypeScript SDK: `await lancedb.connect("db://", { apiKey: "", hostOverride: "" })` -- `lancedb` CLI: a `[profiles.]` entry in `~/.lancedb/config.toml` with `http_server_url`, `api_key`, `database` diff --git a/plugins/lancedb/skills/lancedb/references/remote_jobs.md b/plugins/lancedb/skills/lancedb/references/remote_jobs.md deleted file mode 100644 index 175f0ce51..000000000 --- a/plugins/lancedb/skills/lancedb/references/remote_jobs.md +++ /dev/null @@ -1,151 +0,0 @@ -# Job operations over the LanceDB remote server REST API - -Jobs are server-side background operations on LanceDB Enterprise/Cloud — index builds, -column backfills, materialized view refreshes, and similar async work. Endpoints that -trigger async work (e.g. the column backfill or materialized view refresh endpoints) -return a `job_id`; these four methods are how you track and manage those jobs. - -Resolve the connection first — see `references/remote_connect.md`. All four methods -are **POST** requests under `{base_url}/v1/jobs/` with JSON bodies, and take the usual -`x-api-key` / `x-lancedb-database` headers. If every job call returns `501`, job APIs -are disabled on that deployment (the server has no job registry configured) — report -that rather than retrying. - -## 1. List jobs — `POST /v1/jobs/list` - -The body is optional; an empty body lists everything. All fields are filters: - -```json -{ - "limit": 100, - "table_name": "my_table", - "job_type": "...", - "job_subtype": "...", - "state": "...", - "page_token": "..." -} -``` - -```bash -curl -s -X POST "{base_url}/v1/jobs/list" \ - -H "x-api-key: " -H "x-lancedb-database: " \ - -H "content-type: application/json" \ - -d '{"table_name": "my_table"}' -``` - -Response: - -```json -{ - "jobs": [ - { - "job_id": "...", - "table": "my_table", - "job_type": "...", - "job_subtype": "...", - "state": "done", - "created_at_millis": 1720000000000 - } - ], - "page_token": "..." -} -``` - -A `page_token` in the response means there are more results — pass it back in the next -request to continue. Note list rows use a lowercase `state` string, while describe uses -an uppercase `job_state`. - -## 2. Describe a job — `POST /v1/jobs/describe` - -Body: `{"job_id": ""}`. Returns full detail for one job: - -```json -{ - "job_id": "...", - "job_type": "...", - "job_subtype": "...", - "job_state": "IN_PROGRESS", - "creation_ms": 1720000000000, - "spec": {}, - "status": {} -} -``` - -`job_state` is one of `IN_PROGRESS`, `CANCELLED`, `FAILED`, `DONE`. `spec` and `status` -are job-type-specific JSON objects (the job's input specification and its current -progress/status). Returns `404` for an unknown job id. - -## 3. Cancel a job — `POST /v1/jobs/cancel` - -Body: `{"job_id": ""}`; response echoes `{"job_id": ""}`. Cancellation is a -service-level operation requiring the same administrative authorization as the -`/admin` routes — a database-scoped API key that can list and describe jobs may still -get a permission error here. Other errors: `404` unknown job, `409` state conflict -(e.g. already in a terminal state), `429` too much write contention (safe to retry). - -## 4. Query job event history — `POST /v1/jobs/query_events` - -Returns the event history (state transitions, progress updates) for one or more jobs. -Body: `{"job_id": ""}` for one job, or `{"job_ids": ["", ...]}` for a batch. -Optional fields: `limit` (max event rows), `limit_per_job` (per job in a batch query), -and `filter` — a SQL-like expression over the columns `state`, `updated_by`, -`owner_component`, and `claim_entity`. (`full_text_search` is reserved and currently -rejected as not implemented.) - -The response is **not JSON** — it is an Arrow IPC stream -(`content-type: application/vnd.apache.arrow.stream`). Decode it, e.g. in Python: - -```python -import pyarrow.ipc -import requests - -resp = requests.post( - f"{base_url}/v1/jobs/query_events", - headers={"x-api-key": key, "x-lancedb-database": database}, - json={"job_id": job_id}, -) -resp.raise_for_status() -events = pyarrow.ipc.open_stream(resp.content).read_all() -``` - -## Feature engineering (Geneva) jobs - -Feature engineering jobs — UDF column backfills and materialized view refreshes run -through Geneva — are tracked **separately** from the `/v1/jobs` registry above. Their -records live in a `geneva_jobs` table inside the database itself (in the `__system` -namespace), and you access them through a Python `geneva` connection rather than the -REST endpoints above: - -```python -import geneva -from geneva.jobs import JobStateManager - -# Same credentials as lancedb.connect / the REST API -conn = geneva.connect("db://", api_key="", host_override="") -jsm = JobStateManager(conn) - -# List jobs. NOTE: status defaults to "RUNNING"; pass status=None for all jobs. -# Statuses: PENDING | RUNNING | DONE | FAILED | CANCELLED -jobs = jsm.list_jobs(table_name="my_table", status=None) - -# Fetch one job by id (returns a list of JobRecord) -records = jsm.get("") -``` - -Each `JobRecord` has `table_name`, `column_name`, `job_id`, `job_type`, `status`, -`launched_at`, `completed_at`, `config`, `launched_by`, `manifest_id`, `cluster_name`, -`metrics` (progress counters), `events` (human-readable history), and `updated_at`. -For filters `list_jobs` doesn't support (e.g. time ranges), query the underlying table -directly: `jsm.get_table(True).search().where("launched_at >= TIMESTAMP '...'")` — -pass `True` to check out the latest version, since other processes update job state. - -Stale-status caveat: nothing reaps dead Geneva jobs, so a job can sit in -`RUNNING`/`PENDING` forever if its worker died. Treat a job as effectively `FAILED` -when it has been running longer than ~36 hours, or its `updated_at` is more than ~2 -hours old (this matches the heuristic the Geneva console UI applies on read). - -## Workflow tips - -- To wait for async work (a backfill, an index build), poll `describe` until - `job_state` leaves `IN_PROGRESS`; on `FAILED`, pull `status` and `query_events` for - the failure detail. diff --git a/plugins/lancedb/skills/lancedb/scripts/check_materialization.py b/plugins/lancedb/skills/lancedb/scripts/check_materialization.py deleted file mode 100644 index 6b0f117a1..000000000 --- a/plugins/lancedb/skills/lancedb/scripts/check_materialization.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/env python3 -"""Scan Python and TypeScript for likely unsafe LanceDB materialization.""" - -from __future__ import annotations - -import argparse -import re -import sys -from dataclasses import dataclass -from pathlib import Path - - -PY_FULL_TABLE = re.compile(r"\b\w+\.(to_pandas|to_arrow|to_polars)\s*\(") -TS_TABLE_TO_ARROW = re.compile(r"\b\w+\.toArrow\s*\(") -TS_QUERY_COLLECTOR = re.compile(r"\.query\s*\(\s*\)[\s\S]*?\.to(Array|Arrow)\s*\(") - - -@dataclass -class Finding: - path: Path - line: int - message: str - text: str - - -def iter_files(paths: list[Path]) -> list[Path]: - files: list[Path] = [] - for path in paths: - if path.is_dir(): - files.extend( - p - for p in path.rglob("*") - if p.suffix in {".py", ".ts", ".tsx"} and "node_modules" not in p.parts - ) - elif path.suffix in {".py", ".ts", ".tsx"}: - files.append(path) - return sorted(set(files)) - - -def line_number(text: str, offset: int) -> int: - return text.count("\n", 0, offset) + 1 - - -def scan_python(path: Path, text: str) -> list[Finding]: - findings: list[Finding] = [] - for match in PY_FULL_TABLE.finditer(text): - line_start = text.rfind("\n", 0, match.start()) + 1 - line_end = text.find("\n", match.start()) - if line_end == -1: - line_end = len(text) - line = text[line_start:line_end].strip() - if ".search(" in line or ".query(" in line: - continue - findings.append( - Finding( - path, - line_number(text, match.start()), - f"Review Python `{match.group(1)}()` call; table-level materialization is not portable to remote tables.", - line, - ) - ) - return findings - - -def statement_around(text: str, start: int, end: int) -> str: - before = max(text.rfind(";", 0, start), text.rfind("\n\n", 0, start)) - after_candidates = [ - pos for pos in (text.find(";", end), text.find("\n\n", end)) if pos != -1 - ] - after = min(after_candidates) if after_candidates else len(text) - return text[before + 1 : after].strip() - - -def scan_typescript(path: Path, text: str) -> list[Finding]: - findings: list[Finding] = [] - for match in TS_TABLE_TO_ARROW.finditer(text): - stmt = statement_around(text, match.start(), match.end()) - if ".query(" in stmt or ".search(" in stmt: - continue - findings.append( - Finding( - path, - line_number(text, match.start()), - "Review TypeScript `table.toArrow()`-style call; table-level materialization is not portable for large/remote tables.", - stmt.splitlines()[0].strip(), - ) - ) - - for match in TS_QUERY_COLLECTOR.finditer(text): - stmt = statement_around(text, match.start(), match.end()) - if ".limit(" in stmt: - continue - findings.append( - Finding( - path, - line_number(text, match.start()), - "Review unbounded TypeScript query collection; add `limit()` or stream batches.", - stmt.splitlines()[0].strip(), - ) - ) - return findings - - -def scan_file(path: Path) -> list[Finding]: - text = path.read_text(encoding="utf-8", errors="replace") - if path.suffix == ".py": - return scan_python(path, text) - if path.suffix in {".ts", ".tsx"}: - return scan_typescript(path, text) - return [] - - -def main() -> int: - parser = argparse.ArgumentParser(description=__doc__) - parser.add_argument("paths", nargs="+", type=Path) - parser.add_argument( - "--no-fail", action="store_true", help="Always exit 0 after reporting findings." - ) - args = parser.parse_args() - - findings: list[Finding] = [] - for path in iter_files(args.paths): - findings.extend(scan_file(path)) - - for finding in findings: - print(f"{finding.path}:{finding.line}: {finding.message}") - print(f" {finding.text}") - - if findings: - print( - f"\n{len(findings)} finding(s). Review manually; bounded query result conversion may be OK." - ) - return 0 if args.no_fail or not findings else 1 - - -if __name__ == "__main__": - sys.exit(main())