@womp/openai-plugin 0.9.0 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +2 -1
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -51,7 +51,7 @@ ${o.map(a=>`- ${a}`).join(`
51
51
  `)}let a=v(t.minimumOrder.amount,n);return r.push("- shipping: added at checkout, from the user's address",`- ships by: ${g(t.shipsBy,!0)}`,...t.price>t.minimumOrder.amount?[]:[t.minimumOrder.topUp?`- order minimum: ${a} in items, so an order of this alone is charged ${a} for them`:`- order minimum: more than ${a} in items, so this alone can't be checked out`],"- card: a Checkout button that opens the user's own checkout on the web, where they enter their address and pay. The checkout link is only in the card."),r.join(`
52
52
  `)}function de(t){let n=t.messages.find(i=>i.type==="error");return n?`Payment not completed (${n.code}): ${n.content}
53
53
  - card: its Pay button opens the payment sheet again, and its Checkout button pays on the web.`:`Order ${t.order?.id}: paid, ${v(A(t),t.currency)} in all. get_order_status shows where it is.`}var Q=864e5;function ce({order:t,orders:n},i){let o=l=>l.map(d=>`${d.id} (${d.statusLabel})`).join(", ");if(!t&&i!==void 0)return`No order ${i} among this user's orders. Theirs: ${n.length?o(n):"none paid yet"}. orderId only chooses between their own orders.`;if(!t)return"No paid order yet from this user's checkout links. A checkout that was started but not paid doesn't count.";let r=t.timeline,a=n.filter(l=>l.id!==t.id),s=[`Order ${t.id}:`,`- status: ${t.statusLabel}`];if(t.items.length&&s.push(`- items: ${t.items.map(l=>`${j(l.title,l.quantity)} (${l.summary})`).join(", ")}`),t.step==="canceled")s.push("- canceled");else if(r&&t.step==="delivered")s.push(`- delivered: ${g(r.deliveredAt)}`);else if(r&&t.step==="shipped")s.push(`- shipped: ${g(r.factoryShippingStartedAt)}`,`- arrives around: ${g(r.deliveredAt)}`);else if(r){let l=Math.floor(Date.parse(r.factoryShippingStartedAt)/Q)-Math.floor(Date.now()/Q),d=l>1?`in about ${l} days (by ${g(r.factoryShippingStartedAt)})`:l===1?"tomorrow":"any day now";s.push(`- ships: ${d}`,`- arrives around: ${g(r.deliveredAt)}`)}for(let l of t.tracking)s.push(`- tracking: ${l.carrier} ${l.trackingNumber}`);return a.length&&s.push(`- other orders: ${o(a)}; orderId shows one of them`),s.push("- card: a tracker and a Track button to the order's status page. The link is only in the card."),s.join(`
54
- `)}var m=require("zod");var J=(t,n)=>t.options.find(i=>i.material===n),Je=(t,n)=>J(t,n.material)?void 0:`Material: ${n.material} is not on offer; the materials are ${t.options.map(i=>i.material).join(", ")}.`,Fe=(t,n)=>{let i=J(t,n.material);return i&&n.finish&&!i.finishes.includes(n.finish)?`Finish: ${i.label} comes ${i.finishes.join(" or ")||"with no finish"}, not ${n.finish}.`:void 0},We=(t,n)=>{let i=J(t,n.material);return i?.colorRequired&&!n.color?`Colour: ${i.label} prints in one colour, which it needs as #rrggbb.`:void 0},Ve=t=>{let{width:n,height:i,depth:o}=t.sizeCm;return t.fits?void 0:`Size: ${[n,i,o].map(r=>r.toFixed(1)).join(" \xD7 ")} cm does not fit ${t.maxSizeCm.join(" \xD7 ")} cm in any orientation.`},He=(t,{pieces:n=1})=>t.pieces===n?void 0:`Pieces: it prints as ${t.pieces} separate piece${t.pieces===1?"":"s"}, not ${n}.`;function T(t,n){return[Je,Fe,We,Ve,He].flatMap(i=>i(t,n)??[])}var N=require("zod"),b=[{type:"oauth2",scopes:["mcp:generate"]}],_=t=>({content:[{type:"text",text:t}]}),x=(t,n)=>({"openai/toolInvocation/invoking":t,"openai/toolInvocation/invoked":n}),U=N.z.string().min(1).max(64).describe("The design's designId, from open_scene."),C={material:N.z.string().min(1).max(64).describe("The material it prints in, one of load_scene_skill's materials, such as polyjet."),finish:N.z.string().max(16).optional().describe("One of the material's finishes, such as glossy; its first when absent."),color:N.z.string().regex(/^#[0-9a-f]{6}$/i,"A colour is #rrggbb.").optional().describe("The one colour of a material that prints in one colour, such as Tinted clear, as #rrggbb."),pieces:N.z.number().int().min(1).max(100).optional().describe("How many separate pieces the design is meant to print as. Default 1.")};function F(t){try{return new URL(t).protocol==="https:"}catch{return!1}}function E(t){return t&&F(t.url)&&Number.isFinite(Date.parse(t.expiresAt))?{url:t.url,expiresAt:t.expiresAt}:void 0}function W(t){if(t)try{let n=new URL(t),i=/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/i.test(n.hostname);return n.protocol==="https:"&&i&&n.origin===t.replace(/\/$/,"")?n.origin:void 0}catch{return}}function me(t,n){if(!(!t||!n))try{return new URL(t.url).origin===n&&Number.isFinite(Date.parse(t.expiresAt))?{url:t.url,expiresAt:t.expiresAt}:void 0}catch{return}}var Be=m.z.object({parts:m.z.array(m.z.number().int().nonnegative()).min(1).max(50).optional().describe("The parts it prints, as the node ids of their Areas; the whole design when absent."),...C,quantity:m.z.number().int().min(1).max(100).optional().describe("Copies to print. Default 1.")}),Ke=m.z.object({name:m.z.string().min(1).max(255).describe("Who it is for, as on the parcel."),line1:m.z.string().min(1).max(255).describe("Street address."),line2:m.z.string().max(255).optional().describe("Apartment, suite or unit."),city:m.z.string().min(1).max(255),state:m.z.string().max(255).describe("State, province or region, such as CA."),postalCode:m.z.string().max(32).describe("ZIP or postal code."),country:m.z.string().length(2).describe("The country's ISO 3166-1 alpha-2 code, such as US."),phoneNumber:m.z.string().max(32).optional().describe("A phone number for the carrier.")}).optional().describe("Where it ships. With it the quote includes shipping, and the card offers ChatGPT's payment sheet.");function Ge(t,n){let{title:i,items:o,currency:r,session:a}=t,s=o.map(({parts:c,summary:p,quantity:k,price:w})=>{let S=j(c.join(", ")||i,k);return{label:o.length>1?`${S} \xB7 ${p}`:S,amount:v(w,r)}}),l=a?M(a).map(({label:c,amount:p})=>({label:c,amount:v(p,r)})):[],d=a&&q(a);return{title:i,summary:o.length>1?"":o[0].summary,lines:[...s,...l],total:a?v(A(a),r):v(t.price,r),shipsBy:g(t.shipsBy),...d&&{arrivesBy:g(d)},...a&&{session:a},checkout:n}}var Xe=({id:t,statusLabel:n,step:i,items:o,timeline:r,statusUrl:a})=>({id:t,statusLabel:n,step:i,items:o.map(({title:s,quantity:l})=>j(s,l)),deliveredAt:r&&g(r.deliveredAt),statusUrl:a&&F(a)?a:null}),pe=({id:t,statusLabel:n})=>({id:t,statusLabel:n});function fe(t,n,i){h(t,"checkout_design",{title:"Order a 3D print",description:`${y.checkout_design} ${(n.completeCheckout?P:ee).checkout_design}`,inputSchema:{designId:U,items:m.z.array(Be).min(1).max(10).describe("What the order prints: each item is the whole design or some of its parts, in one material, finish and colour."),longestSideCm:m.z.number().positive().max(100).optional().describe("Quote it scaled so its longest side is this many cm; its own size when absent."),...n.completeCheckout&&{shipTo:Ke}},annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},_meta:{ui:{visibility:["model"],resourceUri:z.quote.uri},securitySchemes:b,...x("Making a checkout link\u2026","Made a checkout link")}},i("checkout_design",async(o,{items:r,...a})=>{let l=(await Promise.all(r.map(async({parts:k,...w})=>T(await n.analyzePrint(o,{designId:a.designId,longestSideCm:a.longestSideCm,parts:k}),w)))).flatMap((k,w)=>k.map(S=>r.length>1?`Item ${w+1}: ${S}`:S));if(l.length>0)throw new $(`designId ${a.designId}: can't be ordered as it is now; these print checks failed:
54
+ `)}var m=require("zod");var J=(t,n)=>t.options.find(i=>i.material===n),Je=(t,n)=>J(t,n.material)?void 0:`Material: ${n.material} is not on offer; the materials are ${t.options.map(i=>i.material).join(", ")}.`,Fe=(t,n)=>{let i=J(t,n.material);return i&&n.finish&&!i.finishes.includes(n.finish)?`Finish: ${i.label} comes ${i.finishes.join(" or ")||"with no finish"}, not ${n.finish}.`:void 0},We=(t,n)=>{let i=J(t,n.material);return i?.colorRequired&&!n.color?`Colour: ${i.label} prints in one colour, which it needs as #rrggbb.`:void 0},Ve=t=>{let{width:n,height:i,depth:o}=t.sizeCm;return t.fits?void 0:`Size: ${[n,i,o].map(r=>r.toFixed(1)).join(" \xD7 ")} cm does not fit ${t.maxSizeCm.join(" \xD7 ")} cm in any orientation.`},He=(t,{pieces:n=1})=>t.pieces===n?void 0:t.pieces<n?`Pieces: it prints as ${t.pieces} solid${t.pieces===1?"":"s"}, not ${n}: parts in one Area, or touching or overlapping, print as one.`:`Pieces: it prints as ${t.pieces} separate pieces, not ${n}: some part does not overlap the rest.`;function T(t,n){return[Je,Fe,We,Ve,He].flatMap(i=>i(t,n)??[])}var N=require("zod"),b=[{type:"oauth2",scopes:["mcp:generate"]}],_=t=>({content:[{type:"text",text:t}]}),x=(t,n)=>({"openai/toolInvocation/invoking":t,"openai/toolInvocation/invoked":n}),U=N.z.string().min(1).max(64).describe("The design's designId, from open_scene."),C={material:N.z.string().min(1).max(64).describe("The material it prints in, one of load_scene_skill's materials, such as polyjet."),finish:N.z.string().max(16).optional().describe("One of the material's finishes, such as glossy; its first when absent."),color:N.z.string().regex(/^#[0-9a-f]{6}$/i,"A colour is #rrggbb.").optional().describe("The one colour of a material that prints in one colour, such as Tinted clear, as #rrggbb."),pieces:N.z.number().int().min(1).max(100).optional().describe("How many separate pieces the design is meant to print as. Default 1.")};function F(t){try{return new URL(t).protocol==="https:"}catch{return!1}}function E(t){return t&&F(t.url)&&Number.isFinite(Date.parse(t.expiresAt))?{url:t.url,expiresAt:t.expiresAt}:void 0}function W(t){if(t)try{let n=new URL(t),i=/^[a-z0-9]([a-z0-9.-]*[a-z0-9])?$/i.test(n.hostname);return n.protocol==="https:"&&i&&n.origin===t.replace(/\/$/,"")?n.origin:void 0}catch{return}}function me(t,n){if(!(!t||!n))try{return new URL(t.url).origin===n&&Number.isFinite(Date.parse(t.expiresAt))?{url:t.url,expiresAt:t.expiresAt}:void 0}catch{return}}var Be=m.z.object({parts:m.z.array(m.z.number().int().nonnegative()).min(1).max(50).optional().describe("The parts it prints, as the node ids of their Areas; the whole design when absent."),...C,quantity:m.z.number().int().min(1).max(100).optional().describe("Copies to print. Default 1.")}),Ke=m.z.object({name:m.z.string().min(1).max(255).describe("Who it is for, as on the parcel."),line1:m.z.string().min(1).max(255).describe("Street address."),line2:m.z.string().max(255).optional().describe("Apartment, suite or unit."),city:m.z.string().min(1).max(255),state:m.z.string().max(255).describe("State, province or region, such as CA."),postalCode:m.z.string().max(32).describe("ZIP or postal code."),country:m.z.string().length(2).describe("The country's ISO 3166-1 alpha-2 code, such as US."),phoneNumber:m.z.string().max(32).optional().describe("A phone number for the carrier.")}).optional().describe("Where it ships. With it the quote includes shipping, and the card offers ChatGPT's payment sheet.");function Ge(t,n){let{title:i,items:o,currency:r,session:a}=t,s=o.map(({parts:c,summary:p,quantity:k,price:w})=>{let S=j(c.join(", ")||i,k);return{label:o.length>1?`${S} \xB7 ${p}`:S,amount:v(w,r)}}),l=a?M(a).map(({label:c,amount:p})=>({label:c,amount:v(p,r)})):[],d=a&&q(a);return{title:i,summary:o.length>1?"":o[0].summary,lines:[...s,...l],total:a?v(A(a),r):v(t.price,r),shipsBy:g(t.shipsBy),...d&&{arrivesBy:g(d)},...a&&{session:a},checkout:n}}var Xe=({id:t,statusLabel:n,step:i,items:o,timeline:r,statusUrl:a})=>({id:t,statusLabel:n,step:i,items:o.map(({title:s,quantity:l})=>j(s,l)),deliveredAt:r&&g(r.deliveredAt),statusUrl:a&&F(a)?a:null}),pe=({id:t,statusLabel:n})=>({id:t,statusLabel:n});function fe(t,n,i){h(t,"checkout_design",{title:"Order a 3D print",description:`${y.checkout_design} ${(n.completeCheckout?P:ee).checkout_design}`,inputSchema:{designId:U,items:m.z.array(Be).min(1).max(10).describe("What the order prints: each item is the whole design or some of its parts, in one material, finish and colour."),longestSideCm:m.z.number().positive().max(100).optional().describe("Quote it scaled so its longest side is this many cm; its own size when absent."),...n.completeCheckout&&{shipTo:Ke}},annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!1,openWorldHint:!1},_meta:{ui:{visibility:["model"],resourceUri:z.quote.uri},securitySchemes:b,...x("Making a checkout link\u2026","Made a checkout link")}},i("checkout_design",async(o,{items:r,...a})=>{let l=(await Promise.all(r.map(async({parts:k,...w})=>T(await n.analyzePrint(o,{designId:a.designId,longestSideCm:a.longestSideCm,parts:k}),w)))).flatMap((k,w)=>k.map(S=>r.length>1?`Item ${w+1}: ${S}`:S));if(l.length>0)throw new $(`designId ${a.designId}: can't be ordered as it is now; these print checks failed:
55
55
  ${l.map(k=>`- ${k}`).join(`
56
56
  `)}`);let d=await n.checkoutDesign(o,{...a,items:r.map(({pieces:k,...w})=>w)}),c=E(d.link);if(!c)throw new Error("checkoutDesign's link is not an https link with an expiry");let p={designId:d.designId};return{..._(ue(d)),structuredContent:{...p},_meta:{quote:Ge(d,c)}}})),n.completeCheckout&&h(t,"complete_checkout",{title:"Pay for a print",description:y.complete_checkout,inputSchema:{checkout_session_id:m.z.string().max(64).describe("The checkout session's id, from the quote card."),buyer:m.z.object({name:m.z.string().max(256).optional(),email:m.z.string().max(256).optional()}).loose().optional().describe("The buyer the payment sheet names."),payment_data:m.z.object({token:m.z.string().min(1).max(512)}).loose().describe("The payment the sheet hands over.")},annotations:{readOnlyHint:!1,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},_meta:{ui:{visibility:["model","app"]},securitySchemes:b,...x("Placing your order\u2026","Order placed")}},i("complete_checkout",async(o,r)=>{let a=await n.completeCheckout(o,r);return{..._(de(a)),structuredContent:{...a}}})),h(t,"get_order_status",{title:"Check on an order",description:y.get_order_status,inputSchema:{orderId:m.z.number().int().optional().describe("One of the user's own order numbers, to show it instead of the newest.")},annotations:{readOnlyHint:!0,destructiveHint:!1,idempotentHint:!0,openWorldHint:!1},_meta:{ui:{visibility:["model"],resourceUri:z.order.uri},securitySchemes:b,...x("Checking your order\u2026","Checked your order")}},i("get_order_status",async(o,r)=>{let a=await n.getOrderStatus(o,r),s={...a.order&&{order:pe(a.order)},orders:a.orders.map(pe)};return{..._(ce(a,r.orderId)),structuredContent:{...s},...a.order&&{_meta:{order:Xe(a.order)}}}}))}var u=require("zod");var he=`The brief Every open_scene call carries a brief: the request expanded into what to build, written before any script runs. Fill only what the user left unsaid; each constraint the user stated (a colour, a size, a style, a name to engrave) goes into mustKeep in their words, one per entry, and wins over every default below; the request itself is not a constraint. When the user asks for exactly what they wrote, add nothing beyond mustKeep. The brief is the user's short request rewritten as the full spec a professional 3D artist would work from: however short the request ("make me a vespa"), the brief carries the real dimensions, proportions, every part's shape and build, counts, colours and finishes, so nothing is left to guess while modelling. Research before writing the brief: whenever the object is real or recognisable, or more detail would make it better, search the web for it first. Pick the specific version to build (for "a sports car", which make, model and year), and find its real dimensions, proportions, signature details and colours, from the maker's page, a datasheet or reference images where they exist; keep real photos of it from the side, the front and three-quarter, for the critic to compare against. Name the version and the sources in the reference. A photo from the user is only needed for a likeness of something private, such as their pet, face or own item. When the user shares a photo, describe its shape, proportions, colours and distinctive details in the reference, since scripts cannot see the photo. Unless the user asks for another style, the look is a premium scale model, not a toy: one continuous flowing form built with Curves and blends, with crisp feature lines where the real object has them, never stacked boxes. This holds for every organic or flowing object: a request for "a sports car" is a collector's scale model with a curved, sculpted body, not a blocky or cartoon toy. When the user gives no size, decide it before designing: an object people use at its real size (a chess piece, a phone stand, a case, a tool, a game piece, jewellery) is made at its real size, measured from the web search, such as a tournament chess set's king and pawn heights. Only miniatures and decorative objects with no real size use these: a keychain or charm measured on its longest side, about 7 cm for long objects such as a vehicle and about 5 cm for compact ones, a figurine 8 to 10 cm, a car or vehicle model about 10 cm long, a desk object or nameplate 10 to 12 cm. Pieces of one set share one scale. For a miniature of a real object, state the scale from its real size. Every size stays within the largest size in load_scene_skill's materials. List every visible part the real object has, down to its small details (mirrors, handles, cables, lamps, bolts, hinges, badges, vents, buttons, seams, stitching), each with its target shape in a sculptor's words (where it is widest, how it curves, how thick, how its edges end), how it is built, its Area and its operation, with counts taken from the reference. Set the proportions: the overall size and 3 to 5 key ratios from the reference that define the silhouette. Trace the silhouette: the main form from one end to the other as 6 to 10 stations, each with its position along the length, its height and width, and what happens there; the main body is built from it. Name the views and close-ups that will prove the result, including a close-up of each group of small details. A real vehicle, device or machine has 15 to 40 visible parts; a brief with a handful of parts has skipped the detail that makes it real. Ask a question first only when the answer would change the whole object, as it does for a case for a real device (see the hardware rules); otherwise build with the brief. Before the first script, tell the user the brief in one short line, such as "Building a 9 cm sleeping fox figurine in rust orange, sculpted with curves. Say if you want it different." Build to the brief, and review the result against its reviewViews before finish_scene. For an edit, reopen the same designId with open_scene; the brief is an edit brief: the change, any parts it adds or rebuilds, the earlier mustKeep and the views that prove it. Every part the change does not touch stays as it is.
57
57
 
@@ -111,6 +111,7 @@ Wall minimums grow with the print's size. Use the column at or above the print's
111
111
 
112
112
  ## Moving and separate parts
113
113
  - Print nothing already joined that is meant to move, such as chain links or hinges: the factory fills the gaps between joined parts with support, and they print as one.
114
+ - Each separately printed part, such as a lid, a base or a button cap, is its own Area, at least 2 from every other part: parts in one Area blend into one solid, and parts that touch print as one.
114
115
  - Separate pieces, such as the pieces of a chess set, print together in one order: give their number as pieces, and keep each one printable on its own.
115
116
  - Each separately printed part prints in one material, and the parts may differ in material and colour, such as a clear shell with grey buttons.`;var $e=`Create printable 3D designs. Start each build or edit with open_scene and its brief; reuse its designId for edits. Apply the printing constraints below. Repeat run_scene_script and render_scene until reviewed, then use finish_scene to complete the same card. Keep routine corrections internal; ask only for meaningful choices or essential missing information.
116
117
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@womp/openai-plugin",
3
- "version": "0.9.0",
3
+ "version": "0.9.1",
4
4
  "description": "Womp in ChatGPT: the MCP tools, prompts and cards swan-backend serves.",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",