From 557e24883d2ea17b3ba65d3db1cd5b335df01d37 Mon Sep 17 00:00:00 2001 From: yuzhe Date: Thu, 23 Jul 2026 13:50:24 +0800 Subject: [PATCH] =?UTF-8?q?feat(skill):=20=E5=9B=BA=E5=AE=9A=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=9C=B0=E5=9D=80=E5=B9=B6=E5=BC=BA=E5=8C=96=E7=9B=AE?= =?UTF-8?q?=E6=A0=87=E7=A1=AE=E8=AE=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../skills/upload-delivery-desk-work/SKILL.md | 10 ++++++---- .../agents/openai.yaml | 2 +- .../scripts/delivery_desk_upload.py | 5 +++-- docs/integration-guide.md | 2 +- skill-packages/upload-delivery-desk-work.zip | Bin 13669 -> 14009 bytes tests/test_upload_skill.py | 15 +++++++++++++++ 6 files changed, 26 insertions(+), 8 deletions(-) diff --git a/.agents/skills/upload-delivery-desk-work/SKILL.md b/.agents/skills/upload-delivery-desk-work/SKILL.md index 18559c6..0ad7005 100644 --- a/.agents/skills/upload-delivery-desk-work/SKILL.md +++ b/.agents/skills/upload-delivery-desk-work/SKILL.md @@ -12,6 +12,7 @@ Use a two-phase plan/apply workflow. Optimize for correct placement, not speed. - Treat the product hierarchy as `operation group -> project -> work -> review round`. - Never use a collection/delivery-set identifier. `collections`, `notes`, and `versions` are legacy compatibility names. - Never infer a project or work from a partial name, page position, recent activity, or a remembered ID. +- At the start of every invocation, discover and explicitly ask the operator to confirm the exact operation group and project. A target confirmation from an earlier invocation cannot be reused. - Never create a work until the operator confirms the resolved group, project, content, image order, and confirmation code. - Never create a new round until the operator confirms the resolved work and current round. - Never retry a timed-out create request. First inspect current server state; otherwise a retry can create a duplicate round. @@ -38,7 +39,7 @@ Do not create groups, projects, API keys, feedback, or review decisions with thi For both operations, require: -- Delivery Desk base URL. Default to `DELIVERY_DESK_BASE_URL` or `http://127.0.0.1:3010` only for local development. +- Use the fixed Delivery Desk API address `http://192.168.30.90:3010`. Do not ask the operator to configure it. Use `--base-url` only when the operator explicitly instructs you to migrate or test another environment. - A valid API key in `DELIVERY_DESK_API_KEY`. - Exact target project, resolved to group ID/name and project ID/name/slug. - Ordered public image URLs or ordered local image paths. @@ -57,7 +58,7 @@ For `create_round`, also require: When information is missing, ask one concise question listing only the missing fields. Do not proceed to mutation. -## 3. Discover authoritative IDs +## 3. Discover and confirm the authoritative target Use the bundled script from the skill directory: @@ -73,8 +74,9 @@ Resolution rules: 1. Match IDs first. 2. Validate the project ID against its returned group ID, group name, project name, and slug. 3. If the operator supplied only names, list exact matches with IDs and ask the operator to choose when zero or multiple matches exist. -4. Even with one match, show the resolved identity before creating the plan. -5. For a new round, verify the work belongs to the confirmed project. +4. Even when the request already names a target or only one project is accessible, show the resolved group name/ID and project name/ID/slug and ask: `本次操作目标是否为:运营组「」(ID ) / 项目「」(ID , slug )?请回复“确认目标”。` +5. Accept only an explicit target confirmation given during the current invocation. Do not generate `plan-work` or `plan-round` before it. +6. For a new round, verify the work belongs to the confirmed project. Do not silently choose the only project merely because an API key currently exposes one. diff --git a/.agents/skills/upload-delivery-desk-work/agents/openai.yaml b/.agents/skills/upload-delivery-desk-work/agents/openai.yaml index 5ba1ce0..7b6349d 100644 --- a/.agents/skills/upload-delivery-desk-work/agents/openai.yaml +++ b/.agents/skills/upload-delivery-desk-work/agents/openai.yaml @@ -1,4 +1,4 @@ interface: display_name: "上传 Delivery Desk 作品" short_description: "精确定位运营组与项目,安全创建作品或提交新的验收轮次" - default_prompt: "Use $upload-delivery-desk-work to safely locate the exact project and upload a work or a new review round." + default_prompt: "Use $upload-delivery-desk-work to discover and ask me to confirm the exact operation group and project before uploading a work or a new review round." diff --git a/.agents/skills/upload-delivery-desk-work/scripts/delivery_desk_upload.py b/.agents/skills/upload-delivery-desk-work/scripts/delivery_desk_upload.py index 4eb4991..dadff2d 100644 --- a/.agents/skills/upload-delivery-desk-work/scripts/delivery_desk_upload.py +++ b/.agents/skills/upload-delivery-desk-work/scripts/delivery_desk_upload.py @@ -19,6 +19,7 @@ from urllib.parse import quote, urlsplit from urllib.request import Request, urlopen MAX_LOCAL_IMAGE_BYTES = 20 * 1024 * 1024 +DEFAULT_BASE_URL = "http://192.168.30.90:3010" LOCAL_IMAGE_TYPES = { ".jpg": "image/jpeg", ".jpeg": "image/jpeg", @@ -75,7 +76,7 @@ def api_key() -> str: def base_url(value: str | None = None) -> str: - return (value or os.getenv("DELIVERY_DESK_BASE_URL") or "http://127.0.0.1:3010").rstrip("/") + return (value or DEFAULT_BASE_URL).rstrip("/") def request_json(base: str, path: str, *, method: str = "GET", body: dict[str, Any] | None = None) -> tuple[int, Any]: @@ -461,7 +462,7 @@ def cmd_apply(args: argparse.Namespace) -> None: def add_common(command: argparse.ArgumentParser) -> None: - command.add_argument("--base-url", default=None) + command.add_argument("--base-url", default=None, help=f"Delivery Desk API 地址(默认:{DEFAULT_BASE_URL})") def add_content(command: argparse.ArgumentParser, *, title_required: bool) -> None: diff --git a/docs/integration-guide.md b/docs/integration-guide.md index d3b99e2..d43d4b7 100644 --- a/docs/integration-guide.md +++ b/docs/integration-guide.md @@ -12,7 +12,7 @@ Authorization: Bearer dd_live_xxx ## Agent 安全上传 Skill -项目内置 `.agents/skills/upload-delivery-desk-work`,用于引导 Agent 精确定位运营组、项目和作品后创建作品或提交新验收轮次。它强制执行“发现 → 生成计划 → 操作者确认 → 单次提交 → 回读验证”,不允许根据名称猜测目标。 +项目内置 `.agents/skills/upload-delivery-desk-work`,用于引导 Agent 精确定位运营组、项目和作品后创建作品或提交新验收轮次。它固定连接 `http://192.168.30.90:3010`,并强制执行“发现 → 操作者确认运营组与项目 → 生成计划 → 操作者确认内容 → 单次提交 → 回读验证”,不允许根据名称猜测目标。 更新 Skill 后重新生成分发包: diff --git a/skill-packages/upload-delivery-desk-work.zip b/skill-packages/upload-delivery-desk-work.zip index a2ff83278862a64a4d5e27bf57298fa7f243ed1e..63e9c3897ac95eec7282f8f7ee0f8d0067f801e6 100644 GIT binary patch delta 11654 zcmZv?Q*fY77cLsx*2K0a#>BR5+k9hBY}>YNCo?f8w$1bXH~Z8+b-Jpny1Tm9-RgRD zXx(84D9V6CV1R&tz<}J^J?lL`6nQR+iDuv`0(F;fDsMzhIy7 z)L}u&(R4!&XQ6%M!Kf6h-9ELvPD(VNi}@3`#fpo`Q%sIZNHS@DfHnshL`0a33_KIX zA!sC6%?ne_WvRjkWN*uIZq{Y;&0w^jxjA64{HU|D?!!kI*T}qtU&)xr7c~eEuf~UHr{t%@X9}TLfW%(NnsTVix+Fpo5?1Hm!r9>pR--k!7^PC}N_O2! z8dd2sbN%BMvzh|K3=0>v&_i7fTA;>GEEw)2+=}N(!ld2sA>LcR6?gqstnoXd89~i0 zJ}z1;Vn+l8h|Jm`uUUtHidzYHUFSxuVL8 zbM}F+PL@lqnf6?CW5Kf8KHgw;UXiu7VRW!R&8%57Q7#HjmgCSOz9pcM6@s-j6UvqzaQp?oB8zQ=N&0 zVrz|d2RYJw$;r8f01Tx0|8oX0P zvTV&Ko6`&p;+1>XZTF^Tk^&3$N?kQ6!)oSXiVB&F0))s@@$@5kRS?me!Xy$4TAI2Nvr4ciqv;Lw#L_S6zaj@0LIPCZjg)1ybpn_iY{=Vx7D-~K zEQS>;+w8kkRhE~<1459|m9#;y-y*pY=(&Ag)g>o~fg!t*@62rD{yVs|96y&Zyelz! z8|tA=SdC)qY6mt=k#CRD>Gx%)N8xdu;KIEOyjCObC93dw_FX&Md&pw5SJ0MwBd{r% z#kwI>aq>$+i+O(&KabQ@y;vNfM4}mxuDllGjyh|85gtS10!FkK(oROGyf2XxOQaZ} zr7~D)(y$?JF!W(YNz8jCZpyg7B4BmnWB2Rfz@->6c|)_%>FFpI9fA?zBc)2GqG}?F zvHqAs7$BiVp%ML60eQTSW39)Cn5vlgB?@InzQ}VfGHkBIT9q_CY~7l;YnVPKI3y%925@tfUu#^^%SL-a2sPq#3e z)>B+-pMmQ`C?ZK>gomeNE_2*XH8MOjJw|un)l}lUxQMRu%;oKQKn3+ae^$S&A&< z{=Jrq&+J&ZAz9}EcSV3*h{1(x4NsEf9sRvOGZux!#k za0Gm1~!_eg-nQK`Vhgk&=_5R2NSZs=~ps^#OmWx)Gw_Pts8{c<+i zvDC7}_<5zX9q21GEv;$GOsD_~zTYVeHgN%7I1wDlKPzOU6O^OXGHs*H!f~G{D|Mc9 zJtS+WWbqCKk<3M`flx_VD!0WHgdEd5JUyfo-P+tnfxRKUsK1tp;&$eec(gT4`Ix;7 ztd~X!d#w+hwvrxRner3CbTifpC|k*Mvgf^8uVnCXN6$?$K)6oQF8;GgvD*S zHf=h}=-NeFus}t>%9||xVnB;G{Uz)jn zGdb2l61|XAn*u8adrj_WB&m9!4QE;acmmL?6IOju>a!rcikU9bPMi_cg@wVrpu2YfiJh&N=PKynWm)veWpkA_+wHJ{~ z7ilMfGs(A@xMQW)p)A|)jU@60$jSD}z}jHMEY3U5^9>+a=_&jvp7o4bzaew0GQ@`o zAcl$h0C}`3NHTq(Agm{A>Md0FJ(_YKth+qu4aY)X8*lw_#OSx4a_irqi;F2Uo>egb zCHKjFPsU)g~l-2 z9R%79VyRt14qhE?mVj$ltcwoPfmK&BHkFbMY0P~(&(vg5C`?D==Fd6xBHpbogK&!& zDclbJXc=QU;8BJ`zqDqCoqV{ewr(4D83rXAq3fK^NMos@d~vH{PP>(edplbc7;ULv zjL#@#G2||fOR5wdA#*_hsuzBb!}5?#WgIAx5@jz`-$|o4>epF!c<8p^`EjZ``W}Do zKko>9t>K3g?Yv&pbdB`^moFMb1Y2MG|H8jto+bKvpX)ZB?fahB1pB^EYgY0OT0E?B z;PbY<_l>Hr^)p@u$*cp*NMloz{|#hP9MMb zGvZCl+;*?e^;H)s{L6Y-TQ7DD;eA$Y{lHABZk`(-^H0;0c1BpRH_7E3^yc{azv!4K zo=z~(raoR6^w7Sb@#%{(v+ufw(ADu3pN&Ij74mloLK|-4BHdS(g<>?b<+<&Wdmv<( z_-!SI$gpaq)CX)pX*C6xJe6+<19RFsC4*&{qEDw1-9f4yee|!Ag_Av+QTb~H(7zeX zi|LY(WNvUE2YM>=CuSk^Q`ikTNv{->=AH zeV#S1A&VvIggoBQGy4X;E8QkM!qdt%H(nqxHW(HHja*^?)Z57mWtGj>)W`>rQNNuR zARoxHLd(!e#($+{(7L-3>NM(_FMG^R>9YylBMLE zgK~+$NE898zWH3@pkIL%4EIY-{C_y7Pi$5g`7bMMG;WVi>C*Tg3v>1NOC9eay~#(B z>lI;1ez5!s=zpv9zM>(2=PZL$C+Jrb8MJ^s$z{Ks&34`68)x;n+f4friN!u$FD6go z*GrE{!9x#S#ca$;6k!TA7%#>%`11{H4fcS5W=IA2^-o2U~9t#9bqzA)4a3 zf?fhTgMWr4H|Cq`^{yvxSN?%`_|;yD{rPF-BTy*tdc4>Q|Ellgh)nhz9nef0k?o+?;IeJ~xZf7zN$+<9{zsx-nBY z%D}r^CO8TB6|+hGDA3p?^Wlk9Wl7#mN}8qaDc1@~^-{wj$n=AP@jzS>=PqiBlR1!oteVXpJTJj;_ z^%~K-a+fA{+f#@8y_@Zm1O(iE`aU?{`JV_SuH%zeu2>CMFW|07BE-0^c+w6-aXyWiMei^-G7=+mTevOsWf}I`6 zT2y)XR@dvs@_#MPF07j<#s!y`jQZ>K9p7UfOh4?D7rTf_3Snc&U!%1xM3j5 zHX57GmC)u9Zrey*f01tI`7{H>8#}w)a@$Ws`NTPwy!=OCH7YxY$Rtx0j&1q5Z__fN z$_<0&*xVLk=nBDCCnyro-WW=;OFW7WjF{j7y?BkJ{Jb zOOW2x)k}#Ws;>NFP#>e;rUY;sr}~MsRl;du&~FacEdayGvS_24pe5zeFt8(8qifx$ zc%rgWE?4~!D#~}s*#Mz*$~vN9ce~uPuUD7!`+Aj^jKgVjl>E`nNm`-;v(GY16#BC< z|IwTBV)n^LgUwH%5yD?9XPTVj#{?f8!`4=?E@{r+>*y={Eq=3b7b8IL(6l!qBTbRl zN}h(7e4#wLIzTMIgo~=|g+vs5;Tviva>1-LCnU6>5Y#5$N^akQ-}l=gj$OY{j|LC6 zw6T5slu$8tAVjFc(KamJX4ulyq+)EQBzzOfNin|r%6^RK6Z-$A*uIPPlz5;ZAhQ2W zG!Os;#K^+T-ql6d!O_g#$coX+$j+8QVM-cY7^NHfBi#HJPmtIG7;wSy@J?ds`ZIK4 zYaIJ4gjxw)8YvPQ8$;9-6*+O`Z0>@L`xSncGPkq5wzd*$G5;w&`gbrM2zJ4pRv(R4 z0HR~#t6QsokjaA>w%blnJ-F6e`i=ot3Ljvb#3>hBP!-A=RNO-&*f+&Bkz|#+ZRXL`S3*G+9PaqXQ>rHv%Rl} zAQ30lYeg#;$jZ4-F3J^?tPr#E3UI>@%J)cgf`?T~=r*!5PXw+lgQ_>nETZ#({9zXF zcR9i%4$V|sDkz~*=Ixo`7U|*@i(?-YkQ~QiUVTk!fsEvzU&UO?m%Jk@dxCDVM_z(K z`kz*@%2PlJN&o_aX_BObLk+l~OQiO_*QMul(H4uQ3L3VdUDN82b8)*j!D6oVOySm9 z)Bm1^&{~|00jZN$LosHCFj)n84Imei9Csdww~f7-AwrL%|8D*s?1{U|xXMVNw~#Wc zn^lv{%w5^4+wuAAeVe&q62!Oiz8a5F!EdmEjv4LltJB}$G0i;64F(?njS5UPxr8}% zG_?v|Xkl)w8foN!xAGzjc7Kizbaw4na#p%k*>-uIaImX7ox6xPXj;9=tuSICTGT3e z_zhJqo%J5_K4$)8C*Rmy3p?~~?G9UeQp?G>S$xKSRbFba>9zHqs#-a??xX@b{=sbf zuAXeT{EkvVbl}L6&j1o^GzH|zST-Qje24NJxLUNJG5mtLMDHUmuQf%l#}ZVnv9Z51Mb6TFwl~F0TEh@t*zO%T%x7SST#u@?d=6^D z_-&2`dEMu9Fv}MA)r(492jRU;)Gvdu??#1vN>R58=)9(Q^4$xoHWhs=Ez4C~_~u^t zrO2Gf@5P&rcmWqqJyWW3V68U5m4{=D35zXPujU|zd*j})9CqkFFlX)np(?~#dPP!n zYQq3RzdhB!VUv#qLwXqYII{!xr3^v-Rbk z^zq&85|svzggvB%LapDM*Yndti;ICfG84q}RrMAhD!``?Q`^(zew3cU5oW-wU$tT@ zj`7`1DVsHMBoYEyxdsEK9&h0bivCrwgRl_#{_naV9t+Wi@Kmgr7-3R=B9BzMA1Xc8 z(aCOgo}{9t5k~R!xaNosWT?dR2(c4kxL6ct}JiA}|CAKR!4j-iFALkGF_T ztc?3#1#pv*fB{qafgLOvizQ2_Yi3OHk%EYNv-L`3=a19%{m^a}jX6~j^cDgtM3e@J zR^B$OfUIiuCyO~7uRN;p65Nw$8Ul|P1hZ*Gr1duz(h6s%!Ym}VAd5DivCp98t)pF1 zCl4kIwyarm>+jg37&{Z4eKE=eVH8iwv}1GbuGR>dL3x=UyyA}J-h>V zp}V*5p65j#%eB?68nrcg0%+OXKL~WrvfHlra(?21faWmPgTSSWgny4rf- z+knfr!Nv6=%;DF)ww#ix92qK}V{A|&ld*#;-f!mD(X5dlNnL=>X0MIKZCjE(%OVA}{2OM2Q3M-`f8flw<%_(AhRCk$xX0Ha(+3`JBEhmD0k`{pCCR@_NGMZ#xoa zXN9k#WL3|!cGdp{k43cm#QkY?eCNT(#3aESp;l4@E zMN0IJ;ySb*{LGW5`%9e258^&Z5rC#60ySCz3Cz+^LjyG)7$hxPf4y)#Rv}>{VG?2( zJ`gp0A8OCtbj^{G8JM6O7-|dd@&Lu(4%l4fcIIer9qz11JIPW$)doE?lp(YpK?B(YWdR^R3#ydv>eA&x7{$!P2bEH=q#BD5ol+AZW8is_M&1@x?H-Q^f zz%eX7h0FGM_aQn>B0Vq{4uFj3lBy7N$eK;HfxuYIq-D7vG6feMB6J-Y>6&^`jM2n{ zr_5}$DEHV}OqUwq`XhY^?Gl3F$4clHzuE>A8?e6#;Da+F>$$u5peuUh2wDRKfv!7X${?hK-YnSmNg=5LqUVmc_EWBI|5CwjWsO7*Cb2jCxd4{$2Lc{4$KS{ zjR}xy??Rm8Ygq}Zv7h`8#Q17ergSjYrUQci7G+MOZ~o-3&VUnx z#_~{-`95Wnr0sjkBdY7rt>J>E6(J@Zih*fzm1|PXy#6Pt_O%A9Ggs89W@%l{bkdBx z9_G-(#E+4BdcM);Xqi!Bii!85K{^0dpTwl1WF47so|pni+WXDZh%!`OpFBr@(|)i zjn+h2k;H^OFoQN|qn|!QdhpVr_X2yt;4GT{a!tDsP|QDnCJ=M(pIS ziAP61Lp=0$9!~@TqivBDt@b| zxB;y|O$V&0_-sUWZ1Z1u;iC#BUIHh!oI~7klnGN4|G3{?e1=z3jwvK$qWYp-_K+DM zs@Q+XiZt8rm>06sCeA7)2Xa2cqqzAt6Vd)|pI_BT1$PgDo*!^$cLrGownRP=EQ(sy?RkIGD0egk|FgIM>2sk=Ni*5{vBHosY`_4338AatAaYr0kxkX30=kx zB|?GX=wzSO0W^#ahI6lMlekw7fvD7yUy!_r!niRf*78&+1_+)jjW;P|YZmMg@Z zyw5bETmu#Gh8jHA1{QK56%jTD@F}GLEiD3KpFp4crGIiI95*%xdeV5F!Hd z*lyrQ6EO=UWwV1uRaCZ8mc_<9ThXs@mTPN{ti@#VW$N;USDD=AM;Q{y#S;v;#o2lb zoNIzdxeQdwXt}&d+=}dMBn2r_K>&f^b34|Ny_C;f>J0bkJ25j1QNHmmuMN;EHI_TxmL2JfH}z}ZNfWB zbSExLgM?Q97#)AZL_+Yg!lo=8cW|)NpAah$j(4?7G+Q8%JPMzlOCX1I_cypDqB*i& z<^l%Qox)h3;|Y&i603Z8e|Q+62@O*w;JJUZciQX>Z|iN3s>+Z8gLaxMh45bp`iZ?k zBFu@s5;=bP?K-aR1d?X$kfL3=Y*psWyyQ5b=#nV+vb1Y5_F)|~K~2LFBs&#(Xn1S3 zYh}cTFQ*8=n?Ds2{}xw(@9}IkW}MEabPg~yk`OwN9T%2ku&cZv3nT$%6ECwQ4~NiZ z&wr`n(*vVaHrn)m*-)*C8m0Y}42wbwHdS3GT~}A`Lza0!@E0>H_N+OiZlv}z7;nazV2tp69SoWrVPM4eUFx>r#i?3WlMv9)aKWVrN<$xZQnI=-)}9rH-@=A0c#o`Aw^maw#{V< z@p*4+SM4420Qd{cvAns6Fwe!#vej{sPsdx@Iz_DE02QV8W@F&eZMncKVjy~6@wC86 zIg3QVJ*Hv(q-PBCV>!Qq;YX&eDp;$W_O!@c#`8ia^=YX$bar}+-FEtvI z(K;^bJ$bF}O`dhSIy62l&Az+*CSUW%TQL(`&vRD_poJUC*9ZT{Yolo@0YjfZ|s=c1-rS^CfIB=@1MnJ z;r6ms$o4gP0NUm^*j&LCy=xx9F{n|+z@Wy!(2(__R6J1caw}zVdUm$;UN4Lr(Pl+2 zhPm(=j-r0S+<-+QWwt@rF&h(KOiH2s7O7I{=i{ANB0jh`eswB?^Ad^@SbQw4bfH

_m&AdyZ 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 delta 11324 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 OF~Wb~tpvyaSpN&udV{V2 diff --git a/tests/test_upload_skill.py b/tests/test_upload_skill.py index 8093b1f..70f6384 100644 --- a/tests/test_upload_skill.py +++ b/tests/test_upload_skill.py @@ -70,6 +70,21 @@ def apply_silently(path: Path, code: str) -> dict: def main() -> None: + previous_base_url = os.environ.get("DELIVERY_DESK_BASE_URL") + os.environ["DELIVERY_DESK_BASE_URL"] = "http://should-not-override.invalid" + try: + assert MODULE.base_url() == "http://192.168.30.90:3010" + assert MODULE.base_url("https://delivery.example.com/") == "https://delivery.example.com" + finally: + if previous_base_url is None: + os.environ.pop("DELIVERY_DESK_BASE_URL", None) + else: + os.environ["DELIVERY_DESK_BASE_URL"] = previous_base_url + + skill_text = (SCRIPT.parents[1] / "SKILL.md").read_text(encoding="utf-8") + assert "请回复“确认目标”" in skill_text + assert "Do not generate `plan-work` or `plan-round` before it." in skill_text + original_exact_project = MODULE.exact_project original_request_json = MODULE.request_json original_request_multipart = MODULE.request_multipart