egress.allow entry. It is not the network.
Key/value: cursors, caches, counters
JSON.stringify of a Map, a Set, a Date or a class instance silently
loses information, and the person who chose the encoding should be the one who wrote it.
Concurrent runs are normal, so use the version
Up to ten runs of your processor execute at once. A read-modify-write without a version is a lost update. Two runs both read5, both write 6, and one increment vanishes.
err.code === 'version_conflict' and err.currentVersion, so you can re-read,
merge and retry rather than guess.
Bound your retries. Under real contention a tight loop can exhaust your attempts and your cpu_ms on
conflicts alone, and the buyer is charged for that run either way. A handful of attempts with a short
delay between them is enough; if you are consistently exhausting them, the contention is the problem, not
the loop.
Listing
cursor until it is null.
Limits: 10,000 keys, 1 KiB per key, 64 KiB per value.
Files: bytes, and links a buyer can fetch
.. in it is refused.
Handing a file to a buyer
- It is a bearer link. Anyone who obtains it can download until it expires, default one hour, maximum 24 hours. Treat it like a password in a URL, because that is what it is: do not print one into your logs, put one in a public page, or send one anywhere you would not send the file itself.
- It is always served as an attachment with a forced
application/octet-streamtype. Your declared content type is deliberately not echoed, so an HTML or SVG file you stored cannot execute in a visitor’s browser. If you need a file rendered inline, host it yourself.
Instructions for the model
A processor that calls a model can keep its standing instructions in the manifest instead of hard-coding them, and change them later without redeploying.processor.json
Editing it is free. Saving a new prompt writes the manifest and nothing else. It creates no new
isolate and does not count against your daily config changes, unlike editing code or limits. New
runs pick it up within about 15 seconds, the same window as rotating a secret, because it is
resolved per request rather than baked into your isolate.Read it once at the top of your handler. Two reads in one run can straddle an edit.
SGL. call.
Secrets: two modes, and the difference matters
Declare a secret in your manifest, then set its value withsingularity processors secrets NAME=value. We never hand a value back to you.
inject. The default, and the strong one
fetch() with no credential at all, and our egress
gateway adds the header on the way out, only for the hosts you declared.
An
inject secret is not readable from your code. SGL.secrets.get() returns null for one,
exactly as it does for a name you never declared. That is the whole point of choosing this mode.mode: "env". When the value has to be in your hands
env exists.
singularity processors env list shows which of yours is which.
singularity processors env list shows which secrets are which, and the State tab in the
dashboard shows what is in your key/value store, read-only, because it belongs to your code.