Muse Spark Open·续1

// legs of lizard for(let i=0;i<4;i++){ const lg = clay(new THREE.Mesh(new THREE.CapsuleGeometry(0.018,0.08,6,8), matLizard)); const z = i%2===0?0.06:-0.06; const x = i<2?0.08:-0.08; lg.position.set(x,-0.06,z); lg.rotation.z = i%2===0?0.6:-0.6; lizardGroup.add(lg); } // tail const tailCurve = new THREE.CatmullRomCurve3([ new THREE.Vector3(-0.18,0,0), new THREE.Vector3(-0.30,0.04,0.02), new THREE.Vector3(-0.38,0.08,-0.02), new THREE.Vector3(-0.42,0.04,-0.05) ]); const tailGeo = new THREE.TubeGeometry(tailCurve, 12, 0.035, 8, false); const tail = clay(new THREE.Mesh(tailGeo, matLizard)); lizardGroup.add(tail);

bodyGroup.add(lizardGroup);

gnome.add(bodyGroup); gnome.position.y = 0; turntable.add(gnome); scene.add(turntable);

// soft shadow plane backdrop const backdropGeo = new THREE.PlaneGeometry(10,6); const backdropMat = new THREE.MeshStandardMaterial({color:0xd4d4d4, roughness:1}); const backdrop = new THREE.Mesh(backdropGeo, backdropMat); backdrop.position.set(0,3,-2.5); scene.add(backdrop);

let t=0; function animate(){ requestAnimationFrame(animate); t+=0.008; turntable.rotation.y += 0.006; // subtle breathing bodyGroup.position.y = Math.sin(t1.2)0.015; // lizard wiggle lizardGroup.rotation.z = 0.2 + Math.sin(t2)0.05; controls.update(); renderer.render(scene,camera); } animate();

addEventListener('resize',()=>{ camera.aspect = innerWidth/innerHeight; camera.updateProjectionMatrix(); renderer.setSize(innerWidth,innerHeight); }); </script> </body> </html>

````

```json
{
  "id": "chatcmpl-8aa40e6cb9984f6baa46095e6733dbbe",
  "object": "chat.completion",
  "created": 1792117582,
  "model": "accounts/fireworks/models/muse-spark-open",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "```html\n&lt;!DOCTYPE html>\n&lt;html lang=\"en\">\n&lt;head>\n&lt;meta charset=\"UTF-8\">\n&lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n&lt;title>Gnome Purple Hat - Clay 3D&lt;/title>\n&lt;script async src=\"https://unpkg.com/es-module-shims@1.8.0/dist/es-module-shims.js\">&lt;/script>\n&lt;script type=\"importmap\">\n{\n  \"imports\": {\n    \"three\": \"https://unpkg.com/three@0.160.0/build/three.module.js\",\n    \"three/addons/\": \"https://unpkg.com/three@0.160.0/examples/jsm/\"\n  }\n}\n&lt;/script>\n&lt;style>\n  html,body{margin:0;width:100%;height:100%;overflow:hidden;background:#d6d6d6;}\n  canvas{display:block;}\n&lt;/style>\n&lt;/head>\n&lt;body>\n&lt;script type=\"module\">\nimport * as THREE from 'three';\nimport { OrbitControls } from 'three/addons/controls/OrbitControls.js';\n\nconst scene = new THREE.Scene();\nscene.background = new THREE.Color(0xd4d4d4);\nscene.fog = new THREE.Fog(0xd4d4d4, 8, 20);\n\nconst renderer = new THREE.WebGLRenderer({antialias:true});\nrenderer.setSize(innerWidth, innerHeight);\nrenderer.setPixelRatio(devicePixelRatio);\nrenderer.shadowMap.enabled = true;\nrenderer.shadowMap.type = THREE.PCFSoftShadowMap;\ndocument.body.appendChild(renderer.domElement);\n\nconst camera = new THREE.PerspectiveCamera(35, innerWidth/innerHeight, 0.1, 100);\ncamera.position.set(0, 1.6, 4.5);\n\nconst controls = new OrbitControls(camera, renderer.domElement);\ncontrols.target.set(0, 0.75, 0);\ncontrols.enableDamping = true;\ncontrols.minDistance = 2;\ncontrols.maxDistance = 10;\ncontrols.update();\n\n// lighting - soft studio\nconst ambient = new THREE.HemisphereLight(0xffffff, 0xcccccc, 1.1);\nscene.add(ambient);\n\nconst dir1 = new THREE.DirectionalLight(0xfffaf0, 1.2);\ndir1.position.set(3, 5, 3);\ndir1.castShadow = true;\ndir1.shadow.mapSize.set(2048,2048);\ndir1.shadow.radius = 4;\nscene.add(dir1);\n\nconst dir2 = new THREE.DirectionalLight(0xffffff, 0.6);\ndir2.position.set(-3, 4, -2);\nscene.add(dir2);\n\nconst fill = new THREE.DirectionalLight(0xffffff, 0.4);\nfill.position.set(0, 2, -4);\nscene.add(fill);\n\n// backdrop + turntable\nconst groundGeo = new THREE.CircleGeometry(4, 64);\nconst groundMat = new THREE.MeshStandardMaterial({color:0xededed, roughness:0.9, metalness:0});\nconst ground = new THREE.Mesh(groundGeo, groundMat);\nground.rotation.x = -Math.PI/2;\nground.receiveShadow = true;\nscene.add(ground);\n\nconst turntableGeo = new THREE.CylinderGeometry(1.35, 1.35, 0.06, 64);\nconst turntableMat = new THREE.MeshStandardMaterial({color:0xe8e8e8, roughness:0.6});\nconst turntable = new THREE.Mesh(turntableGeo, turntableMat);\nturntable.position.y = 0.03;\nturntable.receiveShadow = true;\nturntable.castShadow = true;\nscene.add(turntable);\n\n// materials - clay colors matched to photo\nconst matSkin = new THREE.MeshStandardMaterial({color:0xf2b8a0, roughness:0.5, metalness:0});\nconst matSkinDark = new THREE.MeshStandardMaterial({color:0xe9a995, roughness:0.6});\nconst matHat = new THREE.MeshStandardMaterial({color:0x7b6bc2, roughness:0.6}); // purple hat\nconst matJacket = new THREE.MeshStandardMaterial({color:0x4fb3b0, roughness:0.65}); // teal jacket\nconst matPants = new THREE.MeshStandardMaterial({color:0x8e2f4a, roughness:0.7}); // maroon pants\nconst matShoes = new THREE.MeshStandardMaterial({color:0x8a7ac0, roughness:0.6});\nconst matButton = new THREE.MeshStandardMaterial({color:0xf2d83a, roughness:0.4});\nconst matLizard = new THREE.MeshStandardMaterial({color:0x7ed321, roughness:0.6});\nconst matLizardBelly = new THREE.MeshStandardMaterial({color:0xbde67a, roughness:0.7});\nconst matNose = new THREE.MeshStandardMaterial({color:0xe8a090});\nconst matMouth = new THREE.MeshStandardMaterial({color:0x6b3a3a});\n\nconst gnome = new THREE.Group();\n\n// body helper to make clay look\nfunction clay(mesh){ mesh.castShadow=true; mesh.receiveShadow=true; return mesh; }\n\nconst bodyGroup = new THREE.Group();\n\n// torso - teal jacket (box with rounded feel using capsule-like)\nconst torsoGeo = new THREE.CapsuleGeometry(0.38, 0.45, 8, 16);\nconst torso = clay(new THREE.Mesh(torsoGeo, matJacket));\ntorso.position.y = 0.95;\ntorso.scale.set(1,1,0.75);\nbodyGroup.add(torso);\n\n// jacket bottom edge\nconst hemGeo = new THREE.CylinderGeometry(0.4, 0.43, 0.12, 16);\nconst hem = clay(new THREE.Mesh(hemGeo, matJacket));\nhem.position.y = 0.68;\nbodyGroup.add(hem);\n\n// buttons 3 yellow\nfor(let i=0;i<3;i++){\n  const b = clay(new THREE.Mesh(new THREE.CylinderGeometry(0.055,0.055,0.02,16), matButton));\n  b.rotation.x = Math.PI/2;\n  b.position.set(0, 1.05 - i*0.18, 0.33);\n  // button holes\n  const holeMat = new THREE.MeshStandardMaterial({color:0x5a4a00});\n  bodyGroup.add(b);\n  // add 2 dots for button detail\n  const dot1 = new THREE.Mesh(new THREE.SphereGeometry(0.012,6,6), holeMat);\n  dot1.position.set(0.015, 1.05 - i*0.18, 0.345);\n  bodyGroup.add(dot1);\n  const dot2 = new THREE.Mesh(new THREE.SphereGeometry(0.012,6,6), holeMat);\n  dot2.position.set(-0.015, 1.05 - i*0.18, 0.345);\n  bodyGroup.add(dot2);\n}\n\n// collar\nconst collarGeo = new THREE.TorusGeometry(0.22, 0.04, 8, 16, Math.PI);\nconst collar = clay(new THREE.Mesh(collarGeo, matJacket));\ncollar.position.set(0,1.22,0.05);\ncollar.rotation.x = Math.PI/2;\ncollar.rotation.z = Math.PI;\nbodyGroup.add(collar);\n\n// head\nconst headGeo = new THREE.SphereGeometry(0.34, 32, 32);\nconst head = clay(new THREE.Mesh(headGeo, matSkin));\nhead.position.y = 1.42;\nhead.scale.set(1,0.9,0.95);\nbodyGroup.add(head);\n\n// ears - pointed elf ears\nconst earGeo = new THREE.ConeGeometry(0.07, 0.14, 12);\nconst earL = clay(new THREE.Mesh(earGeo, matSkin));\nearL.position.set(-0.32, 1.42, 0);\nearL.rotation.z = -0.6;\nearL.rotation.x = 0.2;\nbodyGroup.add(earL);\nconst earR = clay(new THREE.Mesh(earGeo, matSkin));\nearR.position.set(0.32, 1.42, 0);\nearR.rotation.z = 0.6;\nbodyGroup.add(earR);\n\n// nose\nconst noseGeo = new THREE.SphereGeometry(0.05, 16, 16);\nconst nose = clay(new THREE.Mesh(noseGeo, matNose));\nnose.position.set(0,1.38,0.30);\nnose.scale.set(1,0.8,1.2);\nbodyGroup.add(nose);\n\n// eyes - two dots\nconst eyeGeo = new THREE.SphereGeometry(0.032, 12, 12);\nconst eyeMat = new THREE.MeshStandardMaterial({color:0x8a5a4a});\nconst eyeL = clay(new THREE.Mesh(eyeGeo, eyeMat));\neyeL.position.set(-0.12,1.46,0.28);\nbodyGroup.add(eyeL);\nconst eyeR = clay(new THREE.Mesh(eyeGeo, eyeMat));\neyeR.position.set(0.12,1.46,0.28);\nbodyGroup.add(eyeR);\nconst highlightGeo = new THREE.SphereGeometry(0.012,8,8);\nconst hlMat = new THREE.MeshStandardMaterial({color:0xffffff});\nconst hlL = new THREE.Mesh(highlightGeo, hlMat);\nhlL.position.set(-0.11,1.48,0.30);\nbodyGroup.add(hlL);\nconst hlR = hlL.clone();\nhlR.position.set(0.13,1.48,0.30);\nbodyGroup.add(hlR);\n\n// mouth - small O\nconst mouthGeo = new THREE.TorusGeometry(0.035, 0.01, 8, 16);\nconst mouth = clay(new THREE.Mesh(mouthGeo, matMouth));\nmouth.position.set(0,1.30,0.30);\nmouth.rotation.x = 0.2;\nbodyGroup.add(mouth);\nconst mouthHole = new THREE.Mesh(new THREE.CircleGeometry(0.025,12), new THREE.MeshBasicMaterial({color:0x4a2222}));\nmouthHole.position.set(0,1.30,0.312);\nmouthHole.rotation.x = -0.2;\nbodyGroup.add(mouthHole);\n\n// hat - tall purple with bent tip\nconst hatBaseGeo = new THREE.CylinderGeometry(0.36,0.38,0.15,32);\nconst hatBase = clay(new THREE.Mesh(hatBaseGeo, matHat));\nhatBase.position.y = 1.62;\nbodyGroup.add(hatBase);\n\nconst hatConeGeo = new THREE.ConeGeometry(0.36, 0.9, 32);\nconst hatCone = clay(new THREE.Mesh(hatConeGeo, matHat));\nhatCone.position.y = 2.1;\nbodyGroup.add(hatCone);\n\n// bent tip - sphere + small cone bent\nconst tipStemGeo = new THREE.CylinderGeometry(0.08,0.12,0.35,16);\nconst tipStem = clay(new THREE.M
... response truncated ...

Examples

**Dress for the City** — Recognize a city from a photo, then call a weather tool before giving packing advice
const response = await env.AI.run(
  'meta/muse-spark-open',
  {
    messages: [
      {
        role: 'user',
        content: [
          {
            type: 'image_url',
            image_url: {
              url: 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Crissy_Field_beach_and_Golden_Gate_Bridge.jpg/1280px-Crissy_Field_beach_and_Golden_Gate_Bridge.jpg',
            },
          },
          {
            type: 'text',
            text: "I'm flying to the city in this photo tomorrow for a beach day. What should I pack?",
          },
        ],
      },
    ],
    tools: [
      {
        type: 'function',
        function: {
          name: 'get_weather_forecast',
          description: "Get tomorrow's hourly weather forecast for a city",
          parameters: {
            type: 'object',
            properties: {
              city: { type: 'string', description: 'City name' },
              country: { type: 'string', description: 'ISO 3166-1 alpha-2 country code' },
            },
            required: ['city', 'country'],
            additionalProperties: false,
          },
        },
      },
      {
        type: 'function',
        function: {
          name: 'book_restaurant',
          description: 'Book a restaurant table',
          parameters: {
            type: 'object',
            properties: {
              city: { type: 'string' },
              party_size: { type: 'integer' },
              time: { type: 'string' },
            },
            required: ['city', 'party_size', 'time'],
            additionalProperties: false,
          },
        },
      },
    ],
    reasoning_effort: 'medium',
  },
)
console.log(response)
curl https://api.cloudflare.com/client/v4/accounts/$CLOUDFLARE_ACCOUNT_ID/ai/v1/chat/completions \
  --header "Authorization: Bearer $CLOUDFLARE_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
  "model": "meta/muse-spark-open",
  "messages": [
    {
      "role": "user",
      "content": [
        {
          "type": "image_url",
          "image_url": {
            "url": "https://upload.wikimedia.org/wikipedia/commons/thumb/9/93/Crissy_Field_beach_and_Golden_Gate_Bridge.jpg/1280px-Crissy_Field_beach_and_Golden_Gate_Bridge.jpg"
          }
        },
        {
          "type": "text",
          "text": "I'\''m flying to the city in this photo tomorrow for a beach day. What should I pack?"
        }
      ]
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather_forecast",
        "description": "Get tomorrow'\''s hourly weather forecast for a city",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string",
              "description": "City name"
            },
            "country": {
              "type": "string",
              "description": "ISO 3166-1 alpha-2 country code"
            }
          },
          "required": [
            "city",
            "country"
          ],
          "additionalProperties": false
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "book_restaurant",
        "description": "Book a restaurant table",
        "parameters": {
          "type": "object",
          "properties": {
            "city": {
              "type": "string"
            },
            "party_size": {
              "type": "integer"
            },
            "time": {
              "type": "string"
            }
          },
          "required": [
            "city",
            "party_size",
            "time"
          ],
          "additionalProperties": false
        }
      }
    }
  ],
  "reasoning_effort": "medium"
}'