Skip to main content
The very first step in making predictions is finding or creating a prediction function:

Making Predictions

Making predictions with Muna can be done in as little as two lines of code.
import { Muna } from "muna"

// πŸ’₯ Create your Muna client
const muna = new Muna({ accessKey: "..." });

// πŸ”₯ Run the prediction locally
const prediction = await muna.predictions.create({
    tag: "@fxn/greeting",
    inputs: { name: "Yusuf" }
});

// πŸš€ Print the result
console.log(prediction.results[0]);

Using Prediction Values

Muna supports a fixed set of value types for prediction input and output values:
Muna supports the following floating-point numbers:
Muna value typeC/C++ typeDescription
float16float16_tIEEE 754 16-bit floating point number.
float32floatIEEE 754 32-bit floating point number.
float64doubleIEEE 754 64-bit floating point number.
const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        radius: 4.5
    }
});
const radius = prediction.results[0] as number;
In languages that don’t support fixed-size floating point scalars, the data type for floating point values defaults to float32. Use a tensor constructor to explicitly specify the data type.
Support for half-precision floating point scalars float16 is planned for the future depending on language support.
Muna supports floating point vectors (i.e. one-dimensional floating point tensors):
import type { Tensor } from "muna"

const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        vector: new Float32Array([ 1.2, 2.2, 3.2, 4.5 ])
    }
});
const vector = prediction.results[0] as Tensor;
Although Muna supports input vectors, predictors will always output either scalars or Tensor instancesβ€”never plain vectors.
Muna supports floating point tensors:
import type { Tensor } from "muna"

const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        matrix: {
            data: new Float64Array([ 1.2, 2.2, 3.2, 4.5 ]),
            shape: [2, 2]
        } satisfies Tensor
    }
});
const matrix = prediction.results[0] as Tensor;
Muna supports several signed and unsigned integer scalars:
Muna value typeC/C++ typeDescription
int8int8_tSigned 8-bit integer.
int16int16_tSigned 16-bit integer.
int32int32_tSigned 32-bit integer.
int64int64_tSigned 64-bit integer.
uint8uint8_tUnsigned 8-bit integer.
uint16uint16_tUnsigned 16-bit integer.
uint32uint32_tUnsigned 32-bit integer.
uint64uint64_tUnsigned 64-bit integer.
const prediction = await muna.predictions.create({
    tag: "@fxn/squeeze",
    inputs: {
        oranges: 12
    }
});
const cups = prediction.results[0] as number;
When integer scalars are passed to predictors, the data type defaults to int32. Use a tensor constructor to explicitly specify the data type.
Muna supports integer vectors (i.e. one-dimensional integer tensors) of the aforementioned integer types:
import type { Tensor } from "muna"

const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        vector: new Int16Array([ 1, 2, 3, 4 ])
    }
});
const vector = prediction.results[0] as Tensor;
Although Muna supports input vectors, predictors will always output either scalars or Tensor instancesβ€”never plain vectors.
Muna supports integer tensors:
import type { Tensor } from "muna"

const prediction = await muna.predictions.create({
    tag: "@fxn/transpose",
    inputs: {
        matrix: {
            data: new Int16Array([ 1, 2, 3, 4 ]),
            shape: [2, 2]
        } satisfies Tensor
    }
});
const matrix = prediction.results[0] as Tensor;
Unsigned integer tensors are not supported in our Android client because of missing language support in Java.
Muna supports boolean scalars:
const prediction = await muna.predictions.create({
    tag: "@fxn/negate",
    inputs: {
        value: true
    }
});
const truthy = prediction.results[0] as boolean;
Muna supports boolean vectors (i.e. one-dimensional boolean tensors):
import { BoolArray, type Tensor } from "muna"

const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        vector: new BoolArray([ true, true, false, true ])
    }
});
const vector = prediction.results[0] as Tensor;
Although Muna supports input vectors, predictors will always output either scalars or Tensor instancesβ€”never plain vectors.
Muna supports boolean tensors:
import { BoolArray, type Tensor } from "muna"

const prediction = await muna.predictions.create({
    tag: "@fxn/transpose",
    inputs: {
        matrix: {
            data: new BoolArray([ true, true, false, true ]),
            shape: [2, 2]
        } satisfies Tensor
    }
});
const matrix = prediction.results[0] as Tensor;
Muna assumes that boolean values are 1 byte.
Muna supports string values:
const prediction = await muna.predictions.create({
    tag: "@fxn/upper",
    inputs: {
        text: "hello from function"
    }
});
const uppercase = prediction.results[0] as string;
Muna supports lists of values, each with potentially different types:
const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        elements: ["hello", 10, false]
    }
});
const elements = prediction.results[0] as any[];
Input list values must be JSON-serializable.
Muna supports dictionary values:
const prediction = await muna.predictions.create({
    tag: "@fxn/identity",
    inputs: {
        person: {
            name: "Sara",
            age: 27
        }
    }
});
const person = prediction.results[0] as Record<string, any>;
Input dictionary values must be JSON-serializable.
Muna supports images, represented as raw pixel buffers with 8 bytes per pixel and interleaved by channel. Muna supports three pixel buffer formats:
Pixel formatChannelsDescription
A81Single channel luminance or alpha image.
RGB8883Color image without alpha channel.
RGBA88884Color image with alpha channel.
Some client SDKs provide Image utility types for working with images:
import type { Image } from "muna"

const prediction = await muna.predictions.create({
    tag: "@vision-co/remove-background",
    inputs: {
        image: {
            data: new Uint8ClampedArray(1280 * 720 * 3),
            width: 1280,
            height: 720,
            channels: 3
        } satisfies Image
    }
});
const image = prediction.results[0] as Image;
Muna supports binary blobs:
const prediction = await muna.predictions.create({
    tag: "@vision-co/decode-jpeg",
    inputs: {
        buffer: new ArrayBuffer(1024)
    }
});
const buffer = prediction.results[0] as ArrayBuffer;
Because Muna’s security model prohibits file system access, binary input values are always fully read into memory before being passed to the predictor.To make predictions on large files, consider mapping the file into memory using mmap or your environment’s equivalent.

Streaming Predictions

Muna supports consuming the partial results of a prediction as they are made available by the predictor:
// πŸ”₯ Create a prediction stream
const stream = await muna.predictions.stream({
  tag: "@text-co/split-sentence",
  inputs: { text: "Hello world" }
});

// πŸš€ Consume the stream
for await (const prediction of stream)
  console.log(prediction.results[0]);

Consuming Prediction Streams

Streaming in Muna is designed to fully separate how a prediction function is implemented from how the function might be consumed. Consider these two predictors:
def predict() -> str:
    return "hello from Muna"
Here are the reuslts of creating vs. streaming each function at runtime:
In this case, the single prediction is returned:
// Create a prediction with the eager predictor
const prediction = await muna.predictions.create({
  tag: "@muna/eager",
  inputs: { }
});

// Display the results
console.log(prediction.results[0]);

// Outputs:
// "hello from Muna"
In this case, the Muna client will consume all partial predictions yielded by the predictor then return the very last one:
// Create a prediction with the streaming predictor
const prediction = await muna.predictions.create({
  tag: "@muna/generator",
  inputs: { }
});

// Display the results
console.log(prediction.results[0]);

// Outputs:
// "hello from Muna"
In this case, the Muna client will return a prediction stream with the single prediction returned by the predictor:
// Create a prediction stream with the eager predictor
const stream = await muna.predictions.stream({
  tag: "@muna/eager",
  inputs: { }
});

// Display the results
for await (const prediction of stream)
  console.log(prediction.results[0]);

// Outputs:
// "hello from Muna"
In this case, the Muna client will provide a prediction stream containing all partial predictions yielded by the predictor:
// Create a prediction stream with the generator predictor
const stream = await muna.predictions.stream({
  tag: "@muna/generator",
  inputs: { }
});

// Display the results
for await (const prediction of stream)
  console.log(prediction.results[0]);

// Outputs:
// "hello"
// "hello from"
// "hello from Muna"
You can choose how to consume a prediction function depending on what works best for your user experience. You don’t have to care about the underlying function!