Pinokio

repository·main·Indexed 42 days ago

https://github.com/pinokiocomputer/program.pinokio.computer

A browser-based platform for locally installing, running, and automating AI applications and workflows. It features a custom JSON-based scripting language, a dedicated isolated file system (pinokio home), and tools like Gepeto for generating app launchers including install, start, reset, and update scripts.

Tokens
23.5K
Snippets
81
Records
99
Agent score
53%

What's inside Pinokio

  1. Pass parameters to Pinokio scripts

    main

    When a menu item in pinokio.js defines a params object, those values are passed to the script specified by href. Inside the target script (e.g., a .json file), these parameters are accessible via the input variable.

    For example, if pinokio.js passes { url: "https://example.com" }, a script using the template string {{input.url}} will resolve to https://example.com.

    {
      "run": [{
        "method": "shell.run",
        "params": {
          "message": "git clone {{input.url}}"
        }
      }]
    }
  2. Use Relative File Paths in URIs

    main

    Pinokio allows you to reference local files using relative paths. The path is automatically resolved relative to the directory containing the currently running script.

    For example, if start.js is located in /PINOKIO_HOME/api/myapp, calling a script with the URI subroutine.json will cause the interpreter to look for and execute /PINOKIO_HOME/api/myapp/subroutine.json.

    // start.js
    module.exports = {
      "run": [{
        "method": "script.start",
        "params": {
          "uri": "subroutine.json"
        }
      }]
    }
  3. Manage state with `local` variables

    main

    Variables prefixed with local. (e.g., local.items, local.prompt) are used to store state within a script execution.

    Key characteristics:

    • They are reset whenever the script finishes running.
    • They persist across steps within a single execution run.
    • You can set or update them using the local.set API.
  4. Configure UI components (shortcut, app, and info)

    main

    Pinokio allows you to build user interfaces using JSON or JavaScript. A project's UI is composed of three primary components:

    1. shortcut: Defines how the application is displayed on the Pinokio home page after it is downloaded. This is configured using pinokio.js.
    2. app: Defines the actual layout and interface of the installed application page. This is configured using pinokio.js.
    3. info: Defines how the application is presented on the Pinokio discover page and the official website (https://pinokio.computer). This is configured using pinokio_meta.json.
  5. How Pinokio Virtual Drives and fs.link work

    main

    Pinokio Virtual Drives allow you to store data outside of individual applications to enable persistence, sharing across apps (e.g., AI models), and deduplication. The fs.link API manages these drives using symbolic links.

    1. Folder Linking

    Links a folder within the repository to a path in a virtual drive. This is useful for sharing large model files across multiple apps.

    2. Peer Linking

    Allows multiple applications to share the same virtual drive by declaring them as peers using their git repository URIs. When an app runs fs.link with a peers array, it first checks if a virtual drive already exists for any of those peers. If found, it uses the existing drive; otherwise, it creates a new one.

    3. Venv Linking

    An automated way to deduplicate Python packages across multiple venv environments. By calling fs.link with a venv path, Pinokio scans the installed pip packages and moves them into a centralized /drive/drives/pip/ directory, replacing the original files in the venv with symbolic links to the shared versions.

    // Example of Folder Linking with Peers
    {
      "method": "fs.link",
      "params": {
        "drive": {
          "checkpoints": "app/models/checkpoints"
        },
        "peers": [
          "https://github.com/cocktailpeanutlabs/comfyui.git"
        ]
      }
    }
  6. How script memory and the `input` variable work

    main

    Pinokio scripts execute step-by-step, and you can use the input variable to pass data between steps.

    There are two types of input:

    1. Return values between steps: For any step run[i] where i > 0, the input value is the return value from the previous step run[i-1].
    2. Initial script launch parameter: For the first step run[0], input is the parameter passed when the script is launched. This can be set via:
      • The params object in a script.start API call.
      • The params object in a pinokio.js menu item href.

    Use the {{input}} template syntax to access these values in your RPC params.

    {
      "run": [{
        "id": "run",
        "method": "gradio.predict",
        "params": {
          "uri": "http://127.0.0.1:7860",
          "path": "/answer_question_1",
          "params": [
            { "path": "https://media.timeout.com/images/105795964/750/422/image.jpg" },
            "Explain what is going on here"
          ]
        }
      }, {
        "method": "log",
        "params": {
          "json2": "{{input.data[0]}}"
        }
      }]
    }
  7. Access script metadata with `self`

    main

    The self keyword allows you to access custom key/value pairs defined within the script object itself. A Pinokio script is a JSON object that can contain a run array and any other custom keys.

    Example: Using self to handle platform-specific commands.

    {
      "cmds": {
        "win32": "dir",
        "darwin": "ls",
        "linux": "ls"
      },
      "run": [{
        "method": "shell.run",
        "params": {
          "message": "{{self.cmds[platform]}}"
        }
      }]
    }
  8. Understand the Pinokio File System and Directory Structure

    main

    Pinokio operates within an isolated folder called the pinokio home. This ensures that all installations (like Python, Node.js, or FFmpeg) do not interfere with your global system configuration. You can set or change this location in the settings tab.

    Inside the pinokio home folder, the following directories are used:

    • api: Stores all downloaded apps and scripts. Each subfolder here appears as an app in the Pinokio UI.
    • bin: Stores globally installed modules shared across multiple apps (e.g., ffmpeg, nodejs, python) to prevent redundant installations.
    • cache: Stores files automatically cached by apps. If an app fails, deleting this folder and restarting can often resolve issues.
    • drive: Stores virtual drives created via the fs.link API.
    • logs: Contains log files for each individual app.
  9. Use Template Expressions and Memory Variables

    main

    Pinokio uses a template interpreter to allow dynamic command generation.

    Template Syntax: Wrap expressions in {{ }}. These are evaluated at the beginning of every step in the run array.

    Capabilities:

    1. JavaScript Evaluation: Run any Node.js expression (e.g., {{Buffer.from(input.images[0], "base64")}}).
    2. Memory Variables: Access system and state variables (e.g., {{current}} returns the index of the currently executing step).
    3. Input Passing: The return value of a previous step is passed to the next step as the {{input}} variable.

    Example:

    {
      "method": "local.set",
      "params": {
        "name": "{{input}}"
      }
    }
  10. Understand Virtual Drives

    main

    Virtual drives allow you to store data outside of individual application repositories while making them appear as if they are inside, using symbolic links (Linux/Mac) or junctions (Windows). This is achieved via the fs.link API.

    Key Benefits

    • Persistence: Data stays in /PINOKIO_HOME/drive even if the application repository is deleted or updated.
    • Sharing (Peers): Multiple apps can share a single drive (e.g., sharing AI models like .safetensor files between ComfyUI and Stable Diffusion) by specifying a peer array. If a peer drive exists, fs.link will link to the existing one instead of creating a new one.
    • Disk Space Savings: Prevents redundant downloads of large libraries (like pytorch) or models across multiple applications.

    How it works

    When you create a link, Pinokio creates a symbolic link from the app's internal path to an external folder in /PINOKIO_HOME/drive. Applications do not need any special code to support this; they simply interact with their local file paths as usual, and the OS redirects the request to the virtual drive.