8 |
9 |
10 |
11 |
12 | )
13 | }
14 |
--------------------------------------------------------------------------------
/src/pages/deploy/kubernetes.mdx:
--------------------------------------------------------------------------------
1 | # Deploy to Kubernetes
2 |
3 | Golem currently does not provide an official Helm chart or equivalent for Kubernetes deployments. However all the Golem services are containerized and deployed to Docker Hub, and configurable though environment variables, so it is possible to create your own Kubernetes manifests.
--------------------------------------------------------------------------------
/src/pages/cli/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "app-manifest": "Application Manifest",
3 | "components": "Components",
4 | "agents": "Agents",
5 | "profiles": "Profiles",
6 | "permissions": "Permissions",
7 | "plugins": "Plugins",
8 | "shell-completion": "Shell Completion",
9 | "install-from-source": "Install from Source"
10 | }
11 |
--------------------------------------------------------------------------------
/src/pages/concepts/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "reliability": "Reliability",
3 | "components": "Components",
4 | "agents": "Agents",
5 | "invocations": "Invocations",
6 | "worker-gateway": "Worker Gateway",
7 | "agent-to-agent-communication": "Agent to Agent Communication",
8 | "api-definitions": "API Definitions",
9 | "plugins": "Plugins"
10 | }
11 |
--------------------------------------------------------------------------------
/src/pages/deploy/golem-cloud.mdx:
--------------------------------------------------------------------------------
1 | # Deploy to Golem Cloud
2 |
3 | Golem Cloud is hosted version of Golem. It is easiest and fastest way to run Golem [agents](/concepts/agents),
4 | in the cloud, at scale, without any infrastructure setup or maintenance required.
5 |
6 | Golem Cloud can be managed by:
7 |
8 | - [Web management console](https://console.golem.cloud/)
9 | - [golem-cloud-cli](/cli)
10 | - [REST API](/rest-api)
11 |
--------------------------------------------------------------------------------
/src/pages/usage.mdx:
--------------------------------------------------------------------------------
1 | import { Cards, Card } from "nextra/components"
2 |
3 | # Usage
4 |
5 | Learn about deploying, invoking and debugging agents, using the command line interface and more.
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 |
4 | .idea/
5 |
6 | # dependencies
7 | /node_modules
8 | /.pnp
9 | .pnp.js
10 | .yarn/install-state.gz
11 |
12 | # testing
13 | /coverage
14 |
15 | # next.js
16 | /.next/
17 | /out/
18 |
19 | # production
20 | /build
21 |
22 | # misc
23 | .DS_Store
24 | *.pem
25 |
26 | # debug
27 | npm-debug.log*
28 | yarn-debug.log*
29 | yarn-error.log*
30 |
31 | # local env files
32 | .env*.local
33 |
34 | # vercel
35 | .vercel
36 |
37 | # typescript
38 | *.tsbuildinfo
39 | next-env.d.ts
40 |
--------------------------------------------------------------------------------
/src/pages/develop/building-components.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Steps } from "nextra/components"
3 |
4 | # Building Golem Components
5 | Building Golem components having an [application manifest](/app-manifest) is straightforward.
6 |
7 | Use the `golem` command line interface to run the build:
8 |
9 | ```shell copy
10 | golem app build
11 | ```
12 |
13 | The result of the `golem app build` command is a WebAssembly component file ready to be deployed to Golem. To deploy it, use the `deploy` command:
14 |
15 | ```shell copy
16 | golem app deploy
17 | ```
18 |
--------------------------------------------------------------------------------
/src/styles/globals.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
5 | /* Table of contents */
6 | .nextra-toc > div.nextra-scrollbar > div:last-child {
7 | @apply bg-background-light shadow-none dark:bg-background-dark;
8 | }
9 |
10 | /* Theme switcher and collapse */
11 | aside.nextra-sidebar-container > div:last-child {
12 | @apply bg-background-light shadow-none dark:bg-background-dark;
13 | }
14 |
15 | @layer base {
16 | * {
17 | /* Handle overly bold fonts in safari */
18 | -webkit-font-smoothing: antialiased;
19 | min-width: 0;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "strict": true,
8 | "noImplicitAny": true,
9 | "noEmit": true,
10 | "esModuleInterop": true,
11 | "module": "esnext",
12 | "moduleResolution": "bundler",
13 | "resolveJsonModule": true,
14 | "isolatedModules": true,
15 | "jsx": "preserve",
16 | "incremental": true,
17 | "paths": {
18 | "@/*": ["./src/*"]
19 | }
20 | },
21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
22 | "exclude": ["node_modules"]
23 | }
24 |
--------------------------------------------------------------------------------
/src/pages/_app.tsx:
--------------------------------------------------------------------------------
1 | import "../styles/globals.css"
2 |
3 | import type { AppProps } from "next/app"
4 |
5 | import { Inter } from "next/font/google"
6 |
7 | const font = Inter({
8 | subsets: ["latin"],
9 | display: "swap",
10 | variable: "--font-sans",
11 | })
12 |
13 | export default function MyApp({ Component, pageProps }: AppProps) {
14 | return (
15 |
22 |
23 |
24 | )
25 | }
26 |
--------------------------------------------------------------------------------
/src/pages/invoke/repl.mdx:
--------------------------------------------------------------------------------
1 | ## Golem REPL
2 |
3 | Once you have a component using `golem app` commands,
4 | you can spin up a REPL to interact with your functions.
5 |
6 | Golem REPL is backed by the language [Rib](/rib)
7 |
8 | For example, using the [quickstart example](/quickstart):
9 |
10 | ```shell
11 | golem repl
12 | ```
13 |
14 | ```shell
15 | >>> let a1 = counter-agent("agent-1")
16 | ()
17 | >>> let a2 = counter-agent("another")
18 | ()
19 | >>> a1.increment()
20 | 1
21 | >>> a1.increment()
22 | 2
23 | >>> a2.increment()
24 | 1
25 | ```
26 |
27 | REPL is a great way to test the component and its functions,
28 | however note that it's a brand new feature and is experimental in nature.
--------------------------------------------------------------------------------
/src/pages/develop/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "-- getting-started": {
3 | "type": "separator",
4 | "title": "Getting Started"
5 | },
6 | "setup": "Setup",
7 | "defining-components": "Defining Components",
8 | "building-components": "Building Components",
9 | "next-steps": "Next Steps",
10 | "-- golem-sdk": {
11 | "type": "separator",
12 | "title": "Golem SDK"
13 | },
14 | "http": "HTTP client",
15 | "durability": "Durability",
16 | "retries": "Retries",
17 | "transactions": "Transactions",
18 | "promises": "Promises",
19 | "updating": "Updating Agents",
20 | "additional": "Additional runtime APIs",
21 | "rpc": "Agent to Agent Communication",
22 | "agent-filesystem": "Agent Filesystem",
23 | "ai": "Using AI Providers",
24 | "rdbms": "Using Relational Databases",
25 | "forking": "Forking Agents"
26 | }
27 |
--------------------------------------------------------------------------------
/tailwind.config.ts:
--------------------------------------------------------------------------------
1 | import type { Config } from "tailwindcss"
2 |
3 | const config: Config = {
4 | content: [
5 | "./src/pages/**/*.{js,ts,jsx,tsx,mdx}",
6 | "./src/components/**/*.{js,ts,jsx,tsx,mdx}",
7 | "./src/app/**/*.{js,ts,jsx,tsx,mdx}",
8 | "./theme.config.tsx",
9 | ],
10 | theme: {
11 | extend: {
12 | fontFamily: {
13 | sans: ["var(--font-sans)"],
14 | },
15 | backgroundImage: {
16 | "gradient-radial": "radial-gradient(var(--tw-gradient-stops))",
17 | "gradient-conic": "conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",
18 | },
19 | colors: {
20 | "background-dark": "#0a0a0a",
21 | "background-light": "#ffffff",
22 | },
23 | },
24 | },
25 | plugins: [],
26 | darkMode: "class",
27 | }
28 | export default config
29 |
--------------------------------------------------------------------------------
/src/pages/_meta.json:
--------------------------------------------------------------------------------
1 | {
2 | "index": "Home",
3 | "-- Getting Started": {
4 | "type": "separator",
5 | "title": "Getting Started"
6 | },
7 | "why-golem": "Why Golem?",
8 | "fundamentals": "Fundamentals",
9 | "quickstart": "Quickstart",
10 | "concepts": {
11 | "title": "Concepts"
12 | },
13 | "-- Develop": {
14 | "type": "separator",
15 | "title": "Develop"
16 | },
17 | "develop": "Develop",
18 | "-- Usage": {
19 | "type": "separator",
20 | "title": "Usage"
21 | },
22 | "deploy": {
23 | "title": "Deploy"
24 | },
25 | "invoke": {
26 | "title": "Invoke"
27 | },
28 | "debug": {
29 | "title": "Debug"
30 | },
31 | "operate": {
32 | "title": "Operate"
33 | },
34 | "cli": {
35 | "title": "CLI"
36 | },
37 | "desktop": {
38 | "title": "Desktop"
39 | },
40 | "-- References": {
41 | "type": "separator",
42 | "title": "References"
43 | },
44 | "app-manifest": "Application Manifest",
45 | "name-mapping": "Name Mapping",
46 | "type-mapping": "Type Mapping",
47 | "rest-api": "REST API",
48 | "rib": "Rib",
49 | "js-apis": "JavaScript APIs"
50 | }
51 |
--------------------------------------------------------------------------------
/src/pages/rest-api.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 | import { GolemIcon } from "src/components/golem-logo"
4 |
5 | # REST API
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/pages/cli/shell-completion.mdx:
--------------------------------------------------------------------------------
1 | import { Callout, Tabs } from "nextra/components"
2 |
3 | # Golem CLI shell completion
4 |
5 | The `golem completion` command can be used to generate shell completions for many popular shells:
6 |
7 |
8 |
9 | ```shell copy
10 | golem completion bash
11 | ```
12 |
13 |
14 | ```shell copy
15 | golem completion elvish
16 | ```
17 |
18 |
19 | ```shell copy
20 | golem completion fish
21 | ```
22 |
23 |
24 | ```shell copy
25 | golem completion powershell
26 | ```
27 |
28 |
29 | ```shell copy
30 | golem completion zsh
31 | ```
32 |
33 |
34 |
35 | The above command will generate and print the shell completion script to standard output. Redirect the output to a file to save the script. Consult your shell documentation about where to place it.
36 |
37 |
38 | After every Golem update, it is recommended to regenerate the shell completions to include the latest commands and flags.
39 |
40 |
--------------------------------------------------------------------------------
/src/pages/rest-api/limits.mdx:
--------------------------------------------------------------------------------
1 | # Limits API
2 | The limits API allows users to query their current resource limits.
3 | ## Get resource limits for a given account.
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/resource-limits`|GET|Yes
7 |
8 |
9 |
10 | **Query Parameters**
11 |
12 | Name|Type|Required|Description
13 | ---|---|---|---
14 | account-id|string|Yes|The Account ID to check resource limits for.
15 |
16 |
17 |
18 | **Example Response JSON**
19 |
20 | ```json copy
21 | {
22 | "availableFuel": 0,
23 | "maxMemoryPerWorker": 0
24 | }
25 | ```
26 |
27 | ## Update resource limits for a given account.
28 | Path|Method|Protected
29 | ---|---|---
30 | `/v1/resource-limits`|POST|Yes
31 |
32 |
33 |
34 |
35 |
36 | **Example Request JSON**
37 | ```json copy
38 | {
39 | "updates": {
40 | "property1": 0,
41 | "property2": 0
42 | }
43 | }
44 | ```
45 |
46 | **Example Response JSON**
47 |
48 | ```json copy
49 | {}
50 | ```
51 | ## Limits API Errors
52 | Status Code|Description|Body
53 | ---|---|---
54 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
55 | 401|Unauthorized request|`{"error":"string"}`
56 | 403||`{"error":"string"}`
57 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/lefthook.yml:
--------------------------------------------------------------------------------
1 | lint_glob: &lint_glob "*.{js,jsx,ts,tsx,cjs,mjs}"
2 | prettier_glob: &prettier_glob "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc,md,mdx}"
3 |
4 | pre-commit:
5 | parallel: false
6 | commands:
7 | lint:
8 | glob: *lint_glob
9 | run: bunx eslint --fix {staged_files}
10 | lint-add:
11 | glob: *lint_glob
12 | run: git add {staged_files}
13 | prettier:
14 | glob: *prettier_glob
15 | run: bunx prettier --log-level warn --write {staged_files}
16 | prettier-add:
17 | glob: *prettier_glob
18 | run: git add {staged_files}
19 | typecheck:
20 | run: bunx tsc
21 | check-links:
22 | run: bun run check-links {staged_files}
23 |
24 | pre-build:
25 | parallel: true
26 | commands:
27 | lint:
28 | glob: *lint_glob
29 | run: bunx eslint {all_files}
30 | prettier:
31 | glob: *prettier_glob
32 | run: bunx prettier --log-level warn --check {all_files}
33 | typecheck:
34 | run: bunx tsc
35 | check-links:
36 | run: bun run check-links {all_files}
37 |
38 | fix:
39 | parallel: false
40 | commands:
41 | lint:
42 | glob: *lint_glob
43 | run: next lint --fix .
44 | prettier:
45 | glob: *prettier_glob
46 | run: bunx prettier --log-level silent --write ./src
--------------------------------------------------------------------------------
/next.config.js:
--------------------------------------------------------------------------------
1 | const shiki = require("shiki")
2 | const nextra = require("nextra")
3 |
4 | const withNextra = nextra({
5 | theme: "nextra-theme-docs",
6 | themeConfig: "./theme.config.tsx",
7 | mdxOptions: {
8 | rehypePrettyCodeOptions: {
9 | getHighlighter: options =>
10 | shiki.getHighlighter({
11 | ...options,
12 | langs: [
13 | ...shiki.BUNDLED_LANGUAGES,
14 | {
15 | id: "wit",
16 | scopeName: "source.wit",
17 | aliases: [""], // Along with id, aliases will be included in the allowed names you can use when writing markdown.
18 | // this is relative path from node_modules/shiki/index.js
19 | path: "../../wit-grammar.json",
20 | },
21 | {
22 | id: "rib",
23 | scopeName: "source.rib",
24 | aliases: [""], // Along with id, aliases will be included in the allowed names you can use when writing markdown.
25 | // this is relative path from node_modules/shiki/index.js
26 | path: "../../rib-grammar.json",
27 | },
28 | ],
29 | }),
30 | },
31 | },
32 | })
33 |
34 | module.exports = withNextra({
35 | reactStrictMode: true,
36 | experimental: {
37 | scrollRestoration: true,
38 | },
39 | })
40 |
--------------------------------------------------------------------------------
/src/pages/develop/next-steps.mdx:
--------------------------------------------------------------------------------
1 | import { Steps } from "nextra/components"
2 |
3 | # Next steps
4 |
5 | After [setting up the TypeScript development environment](/develop/setup) and learning the basic steps [writing a Golem component](/develop/defining-components) and [building them](/develop/building-components),
6 | consider learning about the following topics for creating more advanced Golem agents, or proceed to the [Invoke section](/invoke) to learn how to call these agents:
7 |
8 |
9 |
10 | ### Making HTTP requests from a Golem component
11 | Learn how to [send HTTP requests from a Golem component written in TypeScript](/develop/http).
12 |
13 | ### Control durability guarantees
14 |
15 | Check how the TypeScript Golem SDK can [control various durability settings](/develop/durability) of Golem.
16 |
17 | ### Automatic retries
18 |
19 | Learn about Golem's retry mechanism and [how it can be customized](/develop/retries).
20 |
21 | ### Transactions
22 |
23 | Use the higher level [transactions library](/develop/transactions) to implement the _Saga pattern_.
24 |
25 | ### Promises
26 |
27 | Create and use [promises](/develop/promises) to await external events from within a running agent.
28 |
29 | ### Call other agents from an agent
30 |
31 | [Agent to Agent communication](/develop/rpc)
32 |
33 | ### Set up the agent's filesystem
34 |
35 | [Agent filesystem](/develop/agent-filesystem)
36 |
37 | ### Use LLMs
38 |
39 | [LLMs](/develop/ai)
40 |
41 | ### Use fork to achieve parallelism
42 |
43 | [Forking agents](/develop/forking)
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/pages/rest-api/api-security.mdx:
--------------------------------------------------------------------------------
1 | # API Security API
2 |
3 | ## Get a security scheme
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/api/security/{project_id}/{security_scheme_identifier}`|GET|Yes
7 |
8 | Get a security scheme by name
9 |
10 |
11 |
12 |
13 |
14 | **Example Response JSON**
15 |
16 | ```json copy
17 | {
18 | "providerType": "Google",
19 | "schemeIdentifier": "string",
20 | "clientId": "string",
21 | "clientSecret": "string",
22 | "redirectUrl": "string",
23 | "scopes": [
24 | "string"
25 | ]
26 | }
27 | ```
28 |
29 | ## Create a security scheme
30 | Path|Method|Protected
31 | ---|---|---
32 | `/v1/api/security/{project_id}`|POST|Yes
33 |
34 |
35 |
36 |
37 |
38 | **Example Request JSON**
39 | ```json copy
40 | {
41 | "providerType": "Google",
42 | "schemeIdentifier": "string",
43 | "clientId": "string",
44 | "clientSecret": "string",
45 | "redirectUrl": "string",
46 | "scopes": [
47 | "string"
48 | ]
49 | }
50 | ```
51 |
52 | **Example Response JSON**
53 |
54 | ```json copy
55 | {
56 | "providerType": "Google",
57 | "schemeIdentifier": "string",
58 | "clientId": "string",
59 | "clientSecret": "string",
60 | "redirectUrl": "string",
61 | "scopes": [
62 | "string"
63 | ]
64 | }
65 | ```
66 | ## API Security API Errors
67 | Status Code|Description|Body
68 | ---|---|---
69 | 400||`{"errors":["string"]}`
70 | 401||`{"error":"string"}`
71 | 403||`{"error":"string"}`
72 | 404||`{"error":"string"}`
73 | 409||`{"error":"string"}`
74 | 500||`{"error":"string","workerError":{"cause":"string","stderr":"string"}}`
--------------------------------------------------------------------------------
/rib-grammar.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "https://raw.githubusercontent.com/martinring/tmlanguage/master/tmlanguage.json",
3 | "name": "Rib",
4 | "scopeName": "source.rib",
5 | "patterns": [
6 | { "include": "#keywords" },
7 | { "include": "#operators" },
8 | { "include": "#literals" },
9 | { "include": "#types" },
10 | { "include": "#identifiers" }
11 | ],
12 | "repository": {
13 | "keywords": {
14 | "patterns": [
15 | {
16 | "match": "\\b(let|if|then|else|for|in|yield|reduce|from|some|none|ok|error|instance)\\b",
17 | "name": "keyword.control.rib"
18 | }
19 | ]
20 | },
21 | "operators": {
22 | "patterns": [
23 | { "match": "\\b(>=|<=|==|<|>|&&|\\|\\||\\+|\\-|\\*|/)\\b", "name": "keyword.operator.rib" },
24 | { "match": "\\.{2,3}=?", "name": "keyword.operator.range.rib" }
25 | ]
26 | },
27 | "literals": {
28 | "patterns": [
29 | { "match": "\\b(true|false)\\b", "name": "constant.language.boolean.rib" },
30 | { "match": "\\d+", "name": "constant.numeric.rib" },
31 | { "match": "\"(\\\\.|[^\"])*\"", "name": "string.quoted.double.rib" }
32 | ]
33 | },
34 | "types": {
35 | "patterns": [
36 | {
37 | "match": "\\b(bool|s8|u8|s16|u16|s32|u32|s64|u64|f32|f64|char|string|list|tuple|option|result)\\b",
38 | "name": "storage.type.rib"
39 | }
40 | ]
41 | },
42 | "identifiers": {
43 | "patterns": [{ "match": "[a-zA-Z_][a-zA-Z0-9_-]*", "name": "variable.rib" }]
44 | }
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Getting Started
2 |
3 | 1. [Install Bun](https://bun.sh/docs/installation)
4 | 2. Install dependencies
5 |
6 | `bun install`
7 |
8 | 3. Run the development server
9 |
10 | `bun run dev`
11 |
12 | 4. Open http://localhost:3001 with your browser to see the result.
13 |
14 | ## Development Guide
15 |
16 | This docs site is built with [Nextra](https://nextra.site/).
17 |
18 | ## Adding a new page
19 |
20 | Each documentation page is created from a .mdx file. To add a new page, create a new .mdx file in the `src/pages` directory. The file name will be the URL path.
21 |
22 | For example, `src/pages/docs/getting-started.mdx` will be available at `/docs/getting-started`.
23 |
24 | ### Changing page metadata
25 |
26 | To change the page title or its position in the left-hand sidebar, create a `_meta.json` file in the same directory as the .mdx file.
27 |
28 | [Read more about Nextra's \_meta.json files](https://nextra.site/docs/guide/organize-files#_metajson).
29 |
30 | [Read more about Nextra's docs theme](https://nextra.site/docs/docs-theme).
31 |
32 | If we had a page `/src/pages/docs/getting-started.mdx`, we could add a `_meta.json` file to change the title and make it the first entry in the sidebar.
33 |
34 | ```json
35 | {
36 | "getting-started": {
37 | "title": "Getting Started - Overview"
38 | },
39 | "other-page": "Other Page"
40 | }
41 | ```
42 |
43 | Note how the key in the JSON object matches the file name. This is how Nextra knows which page to apply the metadata to.
44 |
45 | > If the value is a JSON object, you can set multiple parameters. If it's a string, it will just change the title.
46 |
--------------------------------------------------------------------------------
/src/pages/index.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 | import {
4 | Code,
5 | Cog,
6 | Gamepad,
7 | LibraryBig,
8 | Terminal,
9 | ArrowUpDown,
10 | SquareFunction,
11 | HardHat,
12 | CircleHelp,
13 | Rocket,
14 | } from "lucide-react"
15 | import { GolemIcon } from "src/components/golem-logo"
16 |
17 | # Golem Developer Documentation
18 |
19 | Welcome to the Golem developer documentation portal! Here you will find comprehensive documentation on how to build, deploy, and manage applications on Golem.
20 |
21 |
22 |
23 | Golem is available in both an open source version that you can deploy yourself and a hosted
24 | version that we manage for you. This documentation covers both versions, and we will discuss any
25 | differences between the two.
26 |
15 | ),
16 | },
17 | primaryHue: {
18 | dark: 213,
19 | light: 226,
20 | },
21 | primarySaturation: {
22 | light: 90,
23 | dark: 93,
24 | },
25 | sidebar: {
26 | toggleButton: true,
27 | defaultMenuCollapseLevel: 1,
28 | },
29 | project: {
30 | link: "https://github.com/golemcloud/docs",
31 | },
32 | chat: {
33 | link: "https://discord.gg/UjXeH8uG4x",
34 | },
35 | docsRepositoryBase: "https://github.com/golemcloud/docs/blob/main",
36 | footer: {
37 | component: ,
38 | },
39 | nextThemes: {
40 | defaultTheme: "dark",
41 | },
42 | useNextSeoProps() {
43 | const { asPath } = useRouter()
44 | if (asPath !== "/") {
45 | return {
46 | titleTemplate: "%s – Golem Cloud",
47 | }
48 | }
49 | },
50 | head: (
51 | <>
52 |
53 |
54 |
58 | >
59 | ),
60 | }
61 |
62 | export default config
63 |
--------------------------------------------------------------------------------
/src/pages/concepts/worker-gateway.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 |
4 | # Introduction
5 |
6 | Golem is a durable computing platform that makes it simple to build and deploy
7 | highly reliable distributed systems.
8 |
9 | Golem is highly scalable, and partitions [agents](/concepts/agents) across
10 | many worker executor nodes, which are each in charge of running a different
11 | subset of agents.
12 |
13 | Although partitioning agents across many nodes provides the benefit of
14 | horizontal scalability, it makes it more difficult to know which node is
15 | executing a particular agent.
16 |
17 | Even if you know which node is executing an agent, it would not be convenient to
18 | interact with the node directly, because it could fail, and you would have to
19 | implement logic that detects failure and waits until the agent is recovered on
20 | a new node before retrying the invocation.
21 |
22 | To address these issues, Golem has a _Worker Gateway_ service, which is
23 | effectively stateless and scaled independently of worker executor nodes.
24 |
25 | The primary functions of the _Worker Gateway_ are as follows:
26 |
27 | 1. Identify the node that is responsible for executing the agent being invoked,
28 | and route the invocation request to the node.
29 | 2. Transparently handle executor node failures by detecting failure, awaiting
30 | recovery, and retrying the invocation.
31 | 3. Support the execution of custom APIs, which satisfy arbitrary business and
32 | technical requirements.
33 |
34 | To learn more about how the Worker Gateway supports custom APIs, read the [API definitions](/concepts/api-definitions) page.
35 |
--------------------------------------------------------------------------------
/src/components/multi-platform-command.tsx:
--------------------------------------------------------------------------------
1 | import { Code, Pre, Tabs } from "nextra/components"
2 | import { Fragment } from "react"
3 | import { ComponentProps } from "react"
4 |
5 | type Props = {
6 | commands: Command[]
7 | language?: string
8 | } & Omit, "children">
9 |
10 | type Command = {
11 | label: string
12 | command: string
13 | }
14 |
15 | export const MultiPlatformCommand = ({ commands: command, language, ...props }: Props) => {
16 | const labels = command.map(c => c.label)
17 |
18 | // Mimicking the shiki theme
19 | const commands = command.map(c =>
20 | c.command.split("\n").map((line, i) => {
21 | const lines = line.split(" ")
22 | return (
23 |
24 | {lines.map((word, i) => (
25 |
26 | {i === 0 ? (
27 | {word}
28 | ) : (
29 | {word}
30 | )}
31 | {i < lines.length - 1 && }
32 |
33 | ))}
34 |
35 | )
36 | })
37 | )
38 |
39 | return (
40 |
41 | {commands.map((cmd, i) => (
42 |
43 |
49 | {cmd}
50 |
51 |
52 | ))}
53 |
54 | )
55 | }
56 |
--------------------------------------------------------------------------------
/src/pages/rest-api/project-policy.mdx:
--------------------------------------------------------------------------------
1 | # Project Policy API
2 | Project policies describe a set of actions one account can perform when it was associated with a grant for a project.
3 | ## Get a project policy
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/project-policies/{project_policy_id}`|GET|Yes
7 |
8 | Returns a given project policy by it's ID. Project policy identifiers are used in project grants.
9 |
10 |
11 |
12 |
13 |
14 | **Example Response JSON**
15 |
16 | ```json copy
17 | {
18 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
19 | "name": "string",
20 | "projectActions": {
21 | "actions": [
22 | "ViewComponent"
23 | ]
24 | }
25 | }
26 | ```
27 |
28 | ## Create a project policy
29 | Path|Method|Protected
30 | ---|---|---
31 | `/v1/project-policies`|POST|Yes
32 |
33 | Creates a new project policy and returns the object describing it, including the newly created policy's id.
34 |
35 |
36 |
37 | **Example Request JSON**
38 | ```json copy
39 | {
40 | "name": "string",
41 | "projectActions": {
42 | "actions": [
43 | "ViewComponent"
44 | ]
45 | }
46 | }
47 | ```
48 |
49 | **Example Response JSON**
50 |
51 | ```json copy
52 | {
53 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
54 | "name": "string",
55 | "projectActions": {
56 | "actions": [
57 | "ViewComponent"
58 | ]
59 | }
60 | }
61 | ```
62 | ## Project Policy API Errors
63 | Status Code|Description|Body
64 | ---|---|---
65 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
66 | 401|Unauthorized request|`{"error":"string"}`
67 | 403|Forbidden Request|`{"error":"string"}`
68 | 404|Entity not found|`{"error":"string"}`
69 | 409||`{"error":"string"}`
70 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "golem-docs",
3 | "version": "0.1.0",
4 | "private": true,
5 | "scripts": {
6 | "postinstall": "lefthook install",
7 | "dev": "next dev",
8 | "build:check": "lefthook run pre-build",
9 | "build": "next build",
10 | "start": "next start",
11 | "lint": "next lint --fix",
12 | "format": "prettier --log-level silent --write ./src",
13 | "check-links": "bun ./check-links/check-links.ts",
14 | "fix": "concurrently -m 1 'npm run lint' 'npm run format'",
15 | "generate-local": "concurrently -m 1 'bun run openapi/gen-openapi.ts --local' 'bun run fix'",
16 | "generate-dev": "concurrently -m 1 'bun run openapi/gen-openapi.ts --dev' 'bun run fix'",
17 | "generate-prod": "concurrently -m 1 'bun run openapi/gen-openapi.ts --prod' 'bun run fix'"
18 | },
19 | "dependencies": {
20 | "@radix-ui/react-icons": "^1.3.0",
21 | "lucide-react": "^0.412.0",
22 | "next": "14.0.0",
23 | "nextra": "^2.13.2",
24 | "nextra-theme-docs": "^2.13.2",
25 | "react": "^18",
26 | "react-dom": "^18",
27 | "shiki": "^0.14.3"
28 | },
29 | "devDependencies": {
30 | "@apidevtools/swagger-parser": "^10.1.0",
31 | "@types/bun": "^1.0.1",
32 | "@types/node": "^20",
33 | "@types/react": "^18",
34 | "@types/react-dom": "^18",
35 | "autoprefixer": "^10",
36 | "concurrently": "^8.2.2",
37 | "eslint": "^8",
38 | "eslint-config-next": "14.0.0",
39 | "glob": "^11.0.0",
40 | "lefthook": "^1.6.1",
41 | "markdown-link-extractor": "^4.0.2",
42 | "openapi-sampler": "^1.4.0",
43 | "openapi-types": "^12.1.3",
44 | "postcss": "^8",
45 | "prettier": "^3.4.2",
46 | "prettier-plugin-tailwindcss": "^0.6.11",
47 | "tailwindcss": "^3",
48 | "typescript": "^5"
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/pages/rest-api/api-domain.mdx:
--------------------------------------------------------------------------------
1 | # Api Domain API
2 |
3 | ## Get all API domains
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/api/domains`|GET|Yes
7 |
8 | Returns a list of API domains for the given project.
9 |
10 | **Query Parameters**
11 |
12 | Name|Type|Required|Description
13 | ---|---|---|---
14 | project-id|string|Yes|-
15 |
16 |
17 |
18 | **Example Response JSON**
19 |
20 | ```json copy
21 | [
22 | {
23 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
24 | "domainName": "string",
25 | "nameServers": [
26 | "string"
27 | ],
28 | "createdAt": "2019-08-24T14:15:22Z"
29 | }
30 | ]
31 | ```
32 |
33 | ## Create or update an API domain
34 | Path|Method|Protected
35 | ---|---|---
36 | `/v1/api/domains`|PUT|Yes
37 |
38 |
39 |
40 |
41 |
42 | **Example Request JSON**
43 | ```json copy
44 | {
45 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
46 | "domainName": "string"
47 | }
48 | ```
49 |
50 | **Example Response JSON**
51 |
52 | ```json copy
53 | {
54 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
55 | "domainName": "string",
56 | "nameServers": [
57 | "string"
58 | ],
59 | "createdAt": "2019-08-24T14:15:22Z"
60 | }
61 | ```
62 |
63 | ## Delete an API domain
64 | Path|Method|Protected
65 | ---|---|---
66 | `/v1/api/domains`|DELETE|Yes
67 |
68 |
69 |
70 | **Query Parameters**
71 |
72 | Name|Type|Required|Description
73 | ---|---|---|---
74 | project-id|string|Yes|-
75 | domain|string|Yes|-
76 |
77 |
78 |
79 | **Example Response JSON**
80 |
81 | ```json copy
82 | "string"
83 | ```
84 | ## Api Domain API Errors
85 | Status Code|Description|Body
86 | ---|---|---
87 | 400||`{"errors":["string"]}`
88 | 401||`{"error":"string"}`
89 | 403||`{"error":"string"}`
90 | 404||`{"error":"string"}`
91 | 409||`{"error":"string"}`
92 | 500||`{"error":"string","workerError":{"cause":"string","stderr":"string"}}`
--------------------------------------------------------------------------------
/src/pages/deploy/docker.mdx:
--------------------------------------------------------------------------------
1 | # Deploy using Docker
2 |
3 | To get started we recommend using the Docker Compose file from the [Golem Docker examples](https://github.com/golemcloud/golem/tree/main/docker-examples). You will need to have [Docker](https://docs.docker.com/get-docker/) and [Docker Compose](https://docs.docker.com/compose/install/) installed on your system.
4 |
5 | Once you have Docker Compose installed, you can make use of docker-compose file in Golem repository to spin up Golem.
6 |
7 | ```bash filename="Terminal" copy
8 | # Download an example docker-compose file along with .env file that has a few common configurations
9 | curl -O https://raw.githubusercontent.com/golemcloud/golem/main/docker-examples/published-postgres/compose.yaml -O https://raw.githubusercontent.com/golemcloud/golem/main/docker-examples/published-postgres/.env
10 |
11 | # Start Golem with backend storage as PostgreSQL and Redis
12 | docker compose -f compose.yaml up
13 | ```
14 |
15 | You may need to modify it to suit your needs.
16 |
17 | ### Troubleshooting
18 |
19 | - If you are running into any port conflicts you can modify the [.env](https://github.com/golemcloud/golem/blob/main/docker-examples/.env) file that was downloaded as part of the above curl command.
20 | - It has come to our note that, in some cases, the docker compose result in the following error:
21 |
22 | ```bash
23 | error getting credentials - err: exec: "docker-credential-desktop": executable file not found in $PATH, out: `
24 | ```
25 |
26 | In this situation, the best possible solution is to rename `credsStore` to `credStore` in the `.docker/config.json` file.
27 |
28 | - If you still face issues, try the sqlite version of the docker-compose file:
29 |
30 | ```bash
31 | docker compose -f docker-compose-sqlite.yaml up
32 | ```
33 |
34 | ### Accessing Golem APIs
35 |
36 | [Golem APIs](/rest-api) are exposed on port 9881 by default. Worker [API Gateway](/concepts/worker-gateway) endpoint is exposed under port 9006.
37 |
--------------------------------------------------------------------------------
/src/pages/invoke/making-custom-apis/troubleshooting.mdx:
--------------------------------------------------------------------------------
1 | ## Watch out for errors during deployment
2 |
3 | ### Route conflict errors during deployment
4 |
5 | Please note the following: If you already deployed an API definition before with the same path `/{user-id}/get-cart-contents`,
6 | then you will receive a conflict error as given below.
7 |
8 | ```bash filename="Terminal" copy
9 | API deployment definitions conflict error: /{user-id}/get-cart-contents
10 | ```
11 |
12 | This implies, when you update the version, you have to update the path as well, such as `/v5/{user-id}/get-cart-contents`
13 | under the `path` field in `route`.
14 |
15 | ### BadRequest errors when invoking the API with inputs
16 |
17 | If your API's implementation (Rib script which internally calls agents) gets a wrong input (Example: wrong types in http request),
18 | it produces a `BadRequest`. This makes Golem Gateway much more type safe than a typical Gateway
19 | where it always routes to the backend regardless of wrong inputs.
20 |
21 | Here is an example:
22 |
23 | ```rib copy
24 | let user: u64 = request.path.user-id;
25 | let agent = user-agent(user);
26 | agent.add-cart(request.body.product);
27 | ```
28 |
29 | Here we expect the request body to have a product field, with all the fields of the record type that `add-cart` function expects.
30 | If the request body is wrong, we get a bad request error as shown below.
31 |
32 | ```bash copy
33 | >
34 | * Request completely sent off
35 | < HTTP/1.1 400 Bad Request
36 | < access-control-allow-origin: *
37 | < content-length: 392
38 | < date: Tue, 10 Dec 2024 03:42:54 GMT
39 | <
40 | * Connection #1 to host localhost left intact
41 | Input request details don't match the requirements for rib expression to execute: Invalid value for the key path.
42 | Error: Invalid value for the key product. Error: Expected function parameter type is u64. But found string.
43 | Requirements. Record(TypeRecord { fields: [NameTypePair { name: "product-id", typ: U64)%
44 |
45 | ```
46 |
--------------------------------------------------------------------------------
/src/pages/concepts/agent-to-agent-communication.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 |
4 | # Introduction
5 |
6 | Golem is a durable computing platform that makes it simple to build and deploy
7 | highly reliable distributed systems.
8 |
9 | The WASM component model eliminates the need for microservice architectures,
10 | since components written in different languages can interact with each other
11 | in-process (through component composition), without having to go through
12 | remote protocols like HTTP, gRPC, or JSON RPC.
13 |
14 | Despite this, however, there are times when remote procedure calls (RPC) are
15 | useful or necessary when developing applications on Golem:
16 |
17 | 1. You want to parallelize computation that cannot be done on a single agent,
18 | either due to lack of memory or lack of compute.
19 | 2. You want to partition state that is too large to store in a single agent;
20 | or, perhaps, you want to partition state that can fit in a single agent, but
21 | cannot be read and written fast enough due to contention.
22 |
23 | Both of these are examples require the development of a distributed system,
24 | where some combination of state and computation is distributed to improve
25 | performance, reduce latency, or improve scalability.
26 |
27 | To build a system that distributes state or compute, it is necessary to
28 | coordinate work, which requires RPC of some kind.
29 |
30 | Recognizing the critical nature of internal communication for many distributed
31 | systems, Golem provides a feature called _agent-to-agent communication_. This
32 | feature allows you to simply, and in a type-safe way, communicate between
33 | agents, with strong guarantees, such as reliable, exactly-once invocation
34 | semantics.
35 |
36 | # Technical details
37 |
38 | For agent-to-agent communication, Golem generates a type-safe client interface for each remotely callable agent type. These client interfaces are matching the agent type's interface.
39 |
40 | # Learn More
41 |
42 | - [Agent to Agent Communication](/develop/rpc)
43 |
--------------------------------------------------------------------------------
/src/pages/cli/install-from-source.mdx:
--------------------------------------------------------------------------------
1 | import { Callout, Tabs } from "nextra/components"
2 | import { Steps } from "nextra/components"
3 |
4 | # Golem CLI installation from source
5 |
6 | If the precompiled binaries are not available for your platform, or you prefer to install from source, you can build it with the Rust toolchain.
7 |
8 | ## Prerequisites
9 | To build `golem-cli` you need to use `cargo`, Rust's build tool.
10 |
11 | To get `cargo` on your system, we recommend using [rustup](https://rustup.rs/):
12 |
13 | ```bash filename="Terminal" copy
14 | curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
15 | rustup install stable
16 | rustup default stable
17 | ```
18 |
19 | ## Installing `golem-cli`
20 |
21 | The `golem-cli` command is the lightweight version of Golem's command line interface, which allows you to interact with a running Golem cluster, but it does not include a built-in local version of Golem itself.
22 |
23 | To install `golem-cli` from source, use `cargo install`:
24 |
25 | ```bash copy
26 | cargo install golem-cli --git https://github.com/golemcloud/golem --tag v1.3.1
27 | ```
28 |
29 |
30 | Note that currently installing from crates.io is not possible because the package requires a patched wasmtime version. Always use the `--git` parameter or our precompiled binaries.
31 |
32 |
33 | This will create a binary file named `golem-cli` in the `~/.cargo/bin` directory.
34 |
35 | ## Installing `golem`
36 |
37 | The `golem` binary is the full version of Golem's command line interface, containing everything `golem-cli` has, and it also includes a built-in local version of Golem itself.
38 |
39 | The `golem` package is not published to [crates.io](https://crates.io/), so to install it from source, follow the steps below.
40 |
41 |
42 | ### Clone the repository
43 | Clone the [GitHub repository](https://github.com/golemcloud/golem-cli):
44 |
45 | ```bash copy
46 | git clone https://github.com/golemcloud/golem-cli.git
47 | ```
48 | ### Install cargo-make
49 | Install cargo-make using `cargo install`:
50 |
51 | ```bash copy
52 | cargo install cargo-make --locked
53 | ```
54 |
55 | ### Build the project
56 | Build the project using `cargo make`:
57 |
58 | ```bash copy
59 | cargo make build
60 | ```
61 |
62 |
--------------------------------------------------------------------------------
/src/pages/rest-api/api-certificate.mdx:
--------------------------------------------------------------------------------
1 | # Api Certificate API
2 |
3 | ## Gets one or all certificates for a given project
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/api/certificates`|GET|Yes
7 |
8 | If `certificate-id` is not set, it returns all certificates associated with the project.
9 | If `certificate-id` is set, it returns a single certificate if it exists.
10 |
11 | **Query Parameters**
12 |
13 | Name|Type|Required|Description
14 | ---|---|---|---
15 | project-id|string|Yes|-
16 | certificate-id|string|No|-
17 |
18 |
19 |
20 | **Example Response JSON**
21 |
22 | ```json copy
23 | [
24 | {
25 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
26 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
27 | "domainName": "string",
28 | "createdAt": "2019-08-24T14:15:22Z"
29 | }
30 | ]
31 | ```
32 |
33 | ## Creates a new certificate
34 | Path|Method|Protected
35 | ---|---|---
36 | `/v1/api/certificates`|POST|Yes
37 |
38 | A certificate is associated with a given Golem project and domain, and consists of
39 | a key pair.
40 |
41 | The created certificate will be associated with a certificate ID returned by this endpoint.
42 |
43 |
44 |
45 | **Example Request JSON**
46 | ```json copy
47 | {
48 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
49 | "domainName": "string",
50 | "certificateBody": "string",
51 | "certificatePrivateKey": "string"
52 | }
53 | ```
54 |
55 | **Example Response JSON**
56 |
57 | ```json copy
58 | {
59 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
60 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
61 | "domainName": "string",
62 | "createdAt": "2019-08-24T14:15:22Z"
63 | }
64 | ```
65 |
66 | ## Deletes a certificate
67 | Path|Method|Protected
68 | ---|---|---
69 | `/v1/api/certificates`|DELETE|Yes
70 |
71 | Deletes the certificate associated with the given certificate ID and project ID.
72 |
73 | **Query Parameters**
74 |
75 | Name|Type|Required|Description
76 | ---|---|---|---
77 | project-id|string|Yes|-
78 | certificate-id|string|Yes|-
79 |
80 |
81 |
82 | **Example Response JSON**
83 |
84 | ```json copy
85 | "string"
86 | ```
87 | ## Api Certificate API Errors
88 | Status Code|Description|Body
89 | ---|---|---
90 | 400||`{"errors":["string"]}`
91 | 401||`{"error":"string"}`
92 | 403||`{"error":"string"}`
93 | 404||`{"error":"string"}`
94 | 409||`{"error":"string"}`
95 | 500||`{"error":"string","workerError":{"cause":"string","stderr":"string"}}`
--------------------------------------------------------------------------------
/src/pages/develop/setup.mdx:
--------------------------------------------------------------------------------
1 | import { Callout, Tabs } from "nextra/components"
2 |
3 | ## Setting up the development environment
4 |
5 |
6 |
7 | Golem's TypeScript toolchain uses npm as the underlying build tool.
8 | Install **Node.js** and **npm** on your system by following the official [instructions](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm).
9 |
10 |
11 |
12 | ### Setup Rust
13 |
14 | Developing **Golem agents** in **Rust** requires installing the latest stable compiler, enabling the WASM target and installing a specific version of `cargo-component`.
15 |
16 | #### Installing Rust
17 |
18 | Use the [official guide](https://www.rust-lang.org/learn/get-started) to install the latest **stable** version of the Rust compiler.
19 |
20 |
21 | For MacOS the recommended way is using `rustup` by running the following installation script:
22 |
23 | ```shell
24 | $ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
25 | ```
26 |
27 |
28 |
29 | #### Enabling WebAssembly targets
30 |
31 | With `rust` and `rustup` installed, the next step is to **enable the WebAssembly** support by running:
32 |
33 | ```shell
34 | $ rustup target add wasm32-wasip1
35 | ```
36 |
37 | To verify if this step was successful, run:
38 |
39 | ```shell
40 | $ rustup target list --installed | grep wasm32-wasip1
41 | wasm32-wasip1
42 | ```
43 |
44 | #### Installing `cargo-component`
45 |
46 | The last step is installing the `cargo-component` extension for Rust's `cargo` build tool. This will enable a set of subcommands for `cargo` which allows compiling Rust projects into **WebAssembly components**, required by the `golem` CLI to build Rust agents.
47 |
48 |
49 | Golem requires a **specific version** of `cargo-component`. Please make sure the correct version
50 | is installed with the commands described below.
51 |
52 |
53 | Install the version `0.21.1` of `cargo-component` with `cargo` itself:
54 |
55 | ```shell
56 | $ cargo install --force cargo-component@0.21.1
57 | ```
58 |
59 | Verify that the correct version is installed:
60 |
61 | ```shell
62 | $ cargo component --version
63 | cargo-component 0.21.1
64 | ```
65 |
66 | Please refer [to the cargo-component website](http://github.com/bytecodealliance/cargo-component) for more information.
67 |
68 |
69 |
--------------------------------------------------------------------------------
/src/pages/rest-api/token.mdx:
--------------------------------------------------------------------------------
1 | # Token API
2 | The token API allows creating custom access tokens for the Golem Cloud REST API to be used by tools and services.
3 | ## Get all tokens
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/accounts/{account_id}/tokens`|GET|Yes
7 |
8 | Gets all created tokens of an account.
9 | The format of each element is the same as the data object in the oauth2 endpoint's response.
10 |
11 |
12 |
13 |
14 |
15 | **Example Response JSON**
16 |
17 | ```json copy
18 | [
19 | {
20 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
21 | "accountId": "string",
22 | "createdAt": "2019-08-24T14:15:22Z",
23 | "expiresAt": "2019-08-24T14:15:22Z"
24 | }
25 | ]
26 | ```
27 |
28 | ## Create new token
29 | Path|Method|Protected
30 | ---|---|---
31 | `/v1/accounts/{account_id}/tokens`|POST|Yes
32 |
33 | Creates a new token with a given expiration date.
34 | The response not only contains the token data but also the secret which can be passed as a bearer token to the Authorization header to the Golem Cloud REST API.
35 |
36 |
37 |
38 |
39 | **Example Request JSON**
40 | ```json copy
41 | {
42 | "expiresAt": "2019-08-24T14:15:22Z"
43 | }
44 | ```
45 |
46 | **Example Response JSON**
47 |
48 | ```json copy
49 | {
50 | "data": {
51 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
52 | "accountId": "string",
53 | "createdAt": "2019-08-24T14:15:22Z",
54 | "expiresAt": "2019-08-24T14:15:22Z"
55 | },
56 | "secret": {
57 | "value": "a860a344-d7b2-406e-828e-8d442f23f344"
58 | }
59 | }
60 | ```
61 |
62 | ## Get a specific token
63 | Path|Method|Protected
64 | ---|---|---
65 | `/v1/accounts/{account_id}/tokens/{token_id}`|GET|Yes
66 |
67 | Gets information about a token given by its identifier.
68 | The JSON is the same as the data object in the oauth2 endpoint's response.
69 |
70 |
71 |
72 |
73 |
74 | **Example Response JSON**
75 |
76 | ```json copy
77 | {
78 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
79 | "accountId": "string",
80 | "createdAt": "2019-08-24T14:15:22Z",
81 | "expiresAt": "2019-08-24T14:15:22Z"
82 | }
83 | ```
84 |
85 | ## Delete a token
86 | Path|Method|Protected
87 | ---|---|---
88 | `/v1/accounts/{account_id}/tokens/{token_id}`|DELETE|Yes
89 |
90 | Deletes a previously created token given by its identifier.
91 |
92 |
93 |
94 |
95 |
96 | **Example Response JSON**
97 |
98 | ```json copy
99 | {}
100 | ```
101 | ## Token API Errors
102 | Status Code|Description|Body
103 | ---|---|---
104 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
105 | 401|Unauthorized request|`{"error":"string"}`
106 | 403|Forbidden Request|`{"error":"string"}`
107 | 404|Entity not found|`{"error":"string"}`
108 | 409||`{"error":"string"}`
109 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/src/pages/operate/invocation_context.mdx:
--------------------------------------------------------------------------------
1 | # Invocation Context
2 |
3 | Golem associates an **invocation context** with each agent invocation. This invocation context consists of a stack of **spans**, each having a collection of **attributes**. Currently only string attributes are supported.
4 |
5 | The invocation context can be queried and manipulated (by adding custom spans with custom attributes) using [the SDK](/develop/additional).
6 |
7 | By default, the invocation context's spans are not used by Golem for anything; they are just information propagated among agents to be used by either the agents or **oplog processor plugins** installed to them. It is possible to reconstruct all information about invocation context from the oplog, so oplog processor plugins can be used, for example, to provide live traces of agents through OpenTelemetry.
8 |
9 | ## Automatic invocation context spans
10 |
11 | ### Incoming HTTP requests
12 | The root spans of an invocation contain information depending on how that invocation was started. When invoking through the [invocation REST API](/invoke/http), [W3C Trace Context](https://www.w3.org/TR/trace-context/) headers are automatically processed to set the root **trace-id** and **parent span-id**.
13 |
14 | When using [custom APIs](/invoke/making-custom-apis), the same headers are also taken into account by default, but it is also possible to write a **custom Rib script** per endpoint to extract more information from the HTTP requests and define custom **span attributes** with them.
15 |
16 | In both cases, when the invocation's trigger is an HTTP request, a span is added with the following attributes:
17 |
18 | - `request.method`
19 | - `request.uri`
20 | - `request.remote_addr`
21 |
22 | ### Invocations
23 | When an invocation reaches an agent, a new span is created containing the following attributes:
24 |
25 | - `name`: span's name (`invoke-exported-function`)
26 | - `idempotency_key`: unique identifier of the invocation
27 | - `function_name`: the fully qualified function name
28 | - `worker_id`: worker's ID (consists of component ID and agent ID)
29 | - `agent_type`: the agent type of this agent
30 | - `agent_parameters`: constructor parameter values of the agent
31 |
32 | ### Outgoing HTTP requests
33 | Outgoing HTTP requests are also represented by their own automatic spans with the following attributes:
34 |
35 | - `name`: span's name (`outgoing-http-request`)
36 | - `request.method`: the outgoing request's HTTP method
37 | - `request.uri`: the outgoing request's URI
38 |
39 | ### RPC calls
40 | RPC calls on the caller side are also represented by custom spans. First, a span is created when the underlying RPC resource is initialized, with the following attributes:
41 |
42 | - `name`: span's name (`rpc-connection`)
43 | - `target_worker_id`: the target worker's ID
44 |
45 | Within this span, a new span is created for each remote invocation, with the following attributes:
46 |
47 | - `name`: span's name (`rpc-invocation`)
48 | - `function_name`: the invoked function's fully qualified name
49 | - `idempotency_key`: the unique identifier of the invocation
50 |
--------------------------------------------------------------------------------
/src/pages/develop/http.mdx:
--------------------------------------------------------------------------------
1 | import { Tabs } from "nextra/components"
2 |
3 | # HTTP requests
4 |
5 |
6 |
7 | HTTP requests can be made with the standard `fetch` function.
8 |
9 | For example:
10 |
11 | ```typescript
12 | const response = await fetch(`http://localhost:${port}/todos`, {
13 | method: "POST",
14 | headers: {
15 | "Content-Type": "application/json"
16 | },
17 | body: JSON.stringify({
18 | title: "foo",
19 | body: "bar",
20 | userId: 1
21 | })
22 | const data = await response.json();
23 | console.log("Body: ", data);
24 | });
25 | ```
26 |
27 |
28 |
29 | HTTP requests can be made using `wstd` crate. Make sure to have the crate added to your `Cargo.toml`:
30 |
31 | ```toml
32 | [dependencies]
33 | # note the version as of now has to be 0.5.4 since Golem SDK depends on this specific version
34 | wstd = {version = "0.5.4", features = ["default", "json"] }
35 | ```
36 |
37 | ```rust
38 | use serde::Deserialize;
39 | use serde::Serialize;
40 | use wstd::http::{Body, Client, HeaderValue, IntoBody, Request};
41 | use wstd::http::request::JsonRequest;
42 |
43 | #[derive(Serialize, Deserialize)]
44 | struct ExampleRequest {
45 | title: String,
46 | body: String,
47 | user_id: u16
48 | }
49 |
50 | #[derive(Debug, Serialize, Deserialize)]
51 | struct ExampleResponse {
52 | message: Option,
53 | }
54 |
55 | let port = std::env::var("PORT").unwrap_or("9999".to_string());
56 |
57 | let request = Request::post("https://postman-echo.com/post")
58 | .header("X-Test", HeaderValue::from_str("Golem").unwrap())
59 | .json(&my_payload).map_err(|err| err.to_string())?;
60 |
61 | let port = std::env::var("PORT").unwrap_or("9999".to_string());
62 |
63 | let mut response =
64 | Client::new().send(request).await.map_err(|err| err.to_string())?.into_body();
65 |
66 | let result: ExampleResponse = response.json().unwrap();
67 |
68 | println!("Received {:?}", result);
69 | ```
70 |
71 | It's recommended to use `wstd`, however you can also `golem-wasi-http` to write http client.
72 | Make sure to have the crate added to your `Cargo.toml`:
73 |
74 | ```toml
75 | [dependencies]
76 | golem-wasi-http = {version = "0.1", features = ["json"] }
77 | ```
78 |
79 |
80 | ```rust
81 | use golem_wasi_http::Client;
82 |
83 | let response = Client::new()
84 | .post(&format!("http://localhost:{port}/todos"))
85 | .header("X-Test", "Golem")
86 | .json(&request_body)
87 | .basic_auth("some", Some("body"))
88 | .send()
89 | .unwrap();
90 |
91 | let result: ExampleResponse = response.json().unwrap();
92 |
93 | println!("Received {:?}", result);
94 | ```
95 |
96 | If you need the async client, add `async` into the list of features for `golem-wasi-http` in your `Cargo.toml`:
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/src/pages/concepts/api-definitions.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 |
4 | # Introduction
5 |
6 | Golem is a durable computing platform that makes it simple to build and deploy
7 | highly reliable distributed systems.
8 |
9 | As a serverless platform, Golem allows you to deploy components of your
10 | application, without having to write servers or implement protocols like HTTP,
11 | gRPC, or GraphQL.
12 |
13 | Without having to write any additional code, Golem provides you with the ability
14 | to trigger the creation of agents from your components based on HTTP API calls.
15 |
16 | Although useful for building tooling or quick prototypes, the generic APIs that
17 | Golem gives you to create and interact with your agents are usually not the
18 | polished, engineered APIs that you want to expose to other organizations,
19 | developers of mobile or web applications, or other backend teams.
20 |
21 | To allow you to stand up a custom API for your components, Golem supports a
22 | feature called _API Definitions_. API definitions give you the flexibility of
23 | having a precisely engineered API, but without any of the typical boilerplate.
24 |
25 | This page contains a high-level introduction to API definitions, with links to
26 | technical reference material.
27 |
28 | # API Definitions
29 |
30 | In Golem, an API Definition is similar to an OpenAPI specification for an API.
31 | Like OpenAPI specifications, API Definitions contain the following elements:
32 |
33 | - **Version**. The version defines the version of the API.
34 | - **Status**. The status defines whether the API is a draft, or whether it is
35 | published. Currently, published APIs may not be modified.
36 | - **Routes**. The routes are a list of individual HTTP endpoints.
37 |
38 | In an API definition, the routes define not just the structure of the overall
39 | HTTP, but also how invocation of these APIs triggers the creation and activation
40 | of agents.
41 |
42 | The next section introduces routes in more detail.
43 |
44 | ## Routes
45 |
46 | The elements of a route are as follows:
47 |
48 | - **Path**. The path of the route, such as `/users/{user-id}`. Paths may
49 | contain variables, which may be accessed inside the route binding.
50 | - **Method**. The method of the route, such as GET, PUT, POST, or DELETE.
51 | - **Binding**. The binding defines what agent will be created and invoked
52 | when the endpoint itself is invoked.
53 |
54 | In the following section, you will learn more about the binding.
55 |
56 | ### Bindings
57 |
58 | Bindings are the glue that connects your endpoint to an actual agent.
59 | Examples of what binding can do include invoking an agent or retrieving files from the agent filesystem.
60 |
61 | # Management
62 |
63 | There are a variety of ways to create and manage API Definition:
64 |
65 | - **Golem CLI**. The command-line interface lets you manage API definition.
66 | - **REST API**. The Golem REST API lets you manage API definition
67 |
68 | Both the CLI and REST API let you import an existing OpenAPI definition, with
69 | a custom per-endpoint extension that contains the binding.
70 |
71 | See more examples of implementing custom APIs [here](/invoke/making-custom-apis).
72 |
--------------------------------------------------------------------------------
/src/pages/invoke/cli.mdx:
--------------------------------------------------------------------------------
1 | # Invoke using Golem CLI
2 |
3 | The `golem` command line interface exposes one invocation subcommand:
4 |
5 | - `golem agent invoke` triggers a function invocation on an agent and awaits its result
6 | - `golem agent invoke --enqueue` just enqueues an invocation and returns immediately
7 |
8 | ## Specifying what to invoke
9 |
10 | The command requires specifying which agent to invoke, and the name of the function.
11 |
12 | There are multiple options for selecting the agent:
13 |
14 | - `agent-type(agent-parameters)`
15 | - `component-name/agent-type(agent-parameters)`
16 | - `project-name/component-name/agent-type(agent-parameters)`
17 | - `account-name/project-name/component-name/agent-type(agent-parameters)`
18 |
19 | Note that the `agent-type(agent-parameters)` part is also referred as the _agent ID_, or in previous versions, the _worker name_.
20 |
21 | Also note that you can only omit the component name if it can be inferred from the context, for example if the current directory is a component directory or the application root with a single component only.
22 |
23 | The function to be invoked is selected by the second parameter. Read the [page about name mapping](/name-mapping) for more information about the possible function names.
24 |
25 | ## Encoding parameters
26 |
27 | The CLI requires you to encode the function parameters using the [WebAssembly Value Encoding](https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-wave) with one or more parameters following the function name (one for each invocation parameter).
28 |
29 | ## Getting results
30 |
31 | When using `invoke` without the `--enqueue` flag, the CLI awaits the result of the invocation and prints the result value to the standard output. By default it uses the `text` format, in which case it prints the result value using the [WebAssembly Value Encoding](https://github.com/bytecodealliance/wasm-tools/tree/main/crates/wasm-wave).
32 |
33 | This can be changed with `--format json` or `--format yaml` to print the invocation result in JSON or YAML, using the [mapping described on Type Mapping page](/type-mapping).
34 |
35 | ## Logs
36 |
37 | Both invocation commands accept an optional `--stream` flag for connecting to the invoked agent's event stream and showing its logs. This works the same as running a separate `golem agent stream` command during the invocation. The logs consists of everything the agent writes to its standard output and standard error, as well as through the logging API.
38 |
39 | The `--stream` option's output (and also the `stream` subcommand) can be customized with the following parameters:
40 |
41 | - `--format text|json|yaml` for different encodings of the log lines
42 | - `--colors=yes|no` to enable/disable colors for the `text` format
43 | - `--show-timestamps=yes|no` to enable/disable showing timestamps for each log line
44 | - `--show-level=yes|no` to enable/disable showing the log level (or stdout/stderr) for each log line
45 |
46 | ## Cancelling pending invocations
47 |
48 | As invocations are executed sequentially, it is possible to cancel a pending invocation before it starts executing. This can be done using the command line interface by running the `agent cancel-invocation` subcommand:
49 |
50 | ```shell copy
51 | golem agent cancel-invocation / --idempotency-key
52 | ```
53 |
--------------------------------------------------------------------------------
/src/pages/debug.mdx:
--------------------------------------------------------------------------------
1 | # Debugging agents
2 |
3 | There are many scenarios where looking into an agent's state can be useful. It is possible that an agent ran into a **failed state**, for example. Although transient errors are automatically retried, it is possible that an agent gets permanently failed due to a programming error. It is also possible that the agent is running, but not behaving as expected.
4 |
5 | There are several tools available in Golem to help in these situations.
6 |
7 | ### Querying the agent state
8 |
9 | By querying the agent state you can get some basic information about whether the agent is running, is suspended or failed, how many pending invocations it has, and what was the error message if it failed.
10 |
11 | To query the agent state using the `golem` command line tool, you can use the following command:
12 |
13 | ```shell copy
14 | golem agent get
15 | ```
16 |
17 | ### Getting the agent's logs
18 |
19 | An agent can log messages in various ways:
20 |
21 | - Writing to the standard output (stdout)
22 | - Writing to the standard error (stderr)
23 | - Using logging APIs
24 |
25 | All of these log sources are preserved and can be streamed live by **connecting** to the agent:
26 |
27 | ```shell copy
28 | golem agent stream
29 | ```
30 |
31 | There are also parameters for *invocation* that capture logs of the agent while an invocation is running. For more information see the [CLI agent reference](/cli/agents).
32 |
33 | ### Getting an agent's oplog
34 |
35 | The oplog of an agent is a journal of all the operations and events happened during the agent's lifetime. It is possible to retrieve an agent's oplog, as well as to filter it with search expressions.
36 |
37 | To get the whole oplog of an agent, you can use the following command:
38 |
39 | ```shell copy
40 | golem agent oplog
41 | ```
42 |
43 | See the [CLI agent reference](/cli/agents) for more information about how to search the oplog. One debugging scenario can be to look for all oplog entries belonging to a given **idempotency key** that was provided with an invocation that did not behave as expected. Another can be looking for occurrences of external HTTP requests or log entries.
44 |
45 | ### Applying changes to an agent
46 |
47 | If the available information is not enough, it often helps to add more log lines to the agent. Recompiling the agent, updating the component and then updating the faulty agent will always succeed, if the only change was adding or removing log lines.
48 |
49 | ### Reverting changes to an agent
50 |
51 | The final tool available is **reverting** the agent. This can be done in two different ways:
52 |
53 | 1. **Undoing a given number of invocations**. In this case we specify a number (N), and the last N invocations will be treated as if they never happened. The agent's state will be restored to the point before these last N invocations.
54 | 2. **Reverting to a specific oplog index**. A more advanced use case is to revert the agent to a specific point in the oplog. This can be used to force rerunning some side effects such as external HTTP requests or database operations.
55 |
56 | To revert an agent using the `golem` command line interface, you can use the following command:
57 |
58 | ```shell copy
59 | golem agent revert --number-of-invocations 3
60 | ```
61 |
62 | or
63 |
64 | ```shell copy
65 | golem agent revert --last-oplog-index 12345
66 | ```
67 |
--------------------------------------------------------------------------------
/src/pages/develop.mdx:
--------------------------------------------------------------------------------
1 | import { Cards, Card, Steps } from "nextra/components"
2 |
3 | # Develop an application Golem
4 |
5 | Developing an application on golem consists of two major steps:
6 |
7 | - Writing one or more **Golem components** in one of the supported programming languages.
8 | - Defining external HTTP endpoints
9 |
10 | This page summarizes the workflow of developing an application on Golem, with links to more specific guides for each step.
11 |
12 | ## Creating an application
13 | The primary tool for developing an application on Golem is the [Golem CLI](/cli).
14 |
15 | To create a new application, use the `golem app new` command, passing the name of the application and it's default programming language (note: it is possible to add components using different languages later).
16 |
17 | ```shell copy
18 | golem app new my-app
19 | ```
20 |
21 | ## Writing the code
22 | The application is just a project directory that can contain multiple components. To learn how to add a new component and implement it, check the specific guides in this chapter.
23 |
24 | ### Iterations
25 | During development the whole application can be built using
26 |
27 | ```shell copy
28 | golem app build
29 | ```
30 |
31 | and every component can be deployed using
32 |
33 | ```shell copy
34 | golem app deploy
35 | ```
36 |
37 | This is going to create a new **version** of each component. If there are agents created already, those are not going to be updated automatically to these new versions. Check the [agents page](/concepts/agents) for more information about updating agents.
38 |
39 | ## Defining APIs
40 |
41 | Most applications require a public HTTP API (but this is not mandatory - you can always use Golem's invocation API to directly communicate with your Golem application).
42 |
43 | ### Guidelines
44 |
45 | Check the [defining custom APIs](/invoke/making-custom-apis) page as a starting point for learning how to define custom APIs.
46 |
47 | The recommended way to manage these custom APIs is to create a single API definition YAML in the application's root directory. Future Golem versions will integrate API definitions into the _application manifest_ itself.
48 |
49 | ### Iterations
50 |
51 | Use the `golem api` commands to iterate on your APIs.
52 |
53 |
54 | ### Incrementing the version
55 |
56 | Every time you make changes, the API's version must be incremented in the YAML file.
57 |
58 | ### Uploading
59 |
60 | Upload the new API definition using the `golem api upload` command:
61 |
62 | ```shell copy
63 | golem api definition update api.yaml
64 | ```
65 |
66 | (Use `golem api definition new api.yaml` the first time)
67 |
68 | ### Deleting the previous deployment
69 |
70 | Before deploying the new API version, the previous deployment must be deleted using the `golem api deployment delete` command:
71 |
72 | ```shell copy
73 | golem api deployment delete my-definition/0.0.1
74 | ```
75 |
76 | ### Deploying
77 |
78 | To try out the actual API, you also have to **deploy** it using the `golem api deploy` command:
79 |
80 | ```shell copy
81 | golem api deployment deploy my-definition/0.0.2
82 | ```
83 |
84 | ### Breaking the component APIs
85 |
86 | When an API is using a component's **exported interface**, it is not possible to deploy a new version of that component if it is breaking that used interface (`golem app deploy` will fail). To resolve this, delete the deployment first as shown above.
87 |
88 |
89 |
--------------------------------------------------------------------------------
/src/pages/fundamentals.mdx:
--------------------------------------------------------------------------------
1 | # Fundamentals
2 |
3 | Golem is a serverless computing platform that helps you build and deploy reliable distributed systems with simple code.
4 |
5 | In this section, you will learn some key terms and architecture that will help you better understand Golem.
6 |
7 | ## Key Terms
8 |
9 | - **WASM**. [WebAssembly](https://webassembly.org/), or WASM, for short, is a specification for a portable and secure
10 | virtual machine. Software compiled to WASM can execute on any platform and architecture using a _WASM Runtime_.
11 | - **Components**. In WebAssembly, _components_ are the basic building block of applications, backends, and web services.
12 | Components requires certain capabilities from the host platform (like input/output), and expose a typed public API.
13 | - **Workers**. In Golem, workers are running instances created from components, with their own resources, such as RAM,
14 | file system, and environment variables. Workers are created from external events like requests or by other workers.
15 | - **Invocations**. In Golem, the fundamental unit of work is an invocation of a function that is part of a worker's
16 | typed public API. Functions may require typed parameters as input and may return typed values as output.
17 | - **High-Reliability**. Highly reliable systems must execute critical logic uninterrupted, even through faults,
18 | updates, and cloud flakiness. Golem provides transparent high-reliability, regardless of language or technology stack.
19 | - **WIT**. WIT is a standard of WASM, similar to Protobuf, which allows developers to export a typed public API from
20 | components. Through the Worker Gateway, Golem lets you build HTTP or gRPC APIs atop these typed public APIs.
21 |
22 | ## Golem Architecture
23 |
24 | Golem is architected as a series of independent and modular components, ranging from command-line tools to core systems
25 | responsible for deployment and execution.
26 |
27 | - **CLI**. _Golem CLI_ is a command-line interface to Golem, which has the ability to create and manage components
28 | and workers, perform invocations, and even connect to live workers for diagnostics and troubleshooting.
29 | - **Worker Gateway**. _Worker Gateway_ executes requests by delegating their processing to specific functions on
30 | specified workers. Worker Gateway can extract worker input from JSON, and produce JSON from worker output.
31 | - **Worker Executor**. _Worker Executor_ creates and executes the logic of many individual workers, potentially
32 | created from different components, exposing their public typed API via the Worker Gateway.
33 | - **Golem Services**. _Golem Services_ runs a variety of different HTTP endpoints that allow programmatic management
34 | of all the features of Golem. CLI and Console are both implemented atop Golem Services.
35 | - **Shard Manager**. _Shard Manager_ handles both supervision of individual executor nodes in the Golem cluster and the
36 | task of partitioning all workers across the available executor nodes in a Golem cluster.
37 | - **Golem Cloud**. _Golem Cloud_ is the fully managed version of Golem, suitable for companies looking for a true
38 | zero-ops approach to building highly-reliable distributed systems with simple code.
39 | - **Console**. _Console_ is a graphical user-interface designed to help manage accounts, components, and workers on
40 | Golem Cloud. It provides high-level ways of performing many of the same tasks that are supported by CLI.
41 |
--------------------------------------------------------------------------------
/src/pages/rest-api/account.mdx:
--------------------------------------------------------------------------------
1 | # Account API
2 | The account API allows users to query and manipulate their own account data.
3 | ## Find accounts
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/accounts`|GET|Yes
7 |
8 | Find matching accounts. Only your own account or accounts you have at least one grant from will be returned
9 |
10 | **Query Parameters**
11 |
12 | Name|Type|Required|Description
13 | ---|---|---|---
14 | email|string|No|-
15 |
16 |
17 |
18 | **Example Response JSON**
19 |
20 | ```json copy
21 | {
22 | "values": [
23 | {
24 | "id": "string",
25 | "name": "string",
26 | "email": "string",
27 | "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d"
28 | }
29 | ]
30 | }
31 | ```
32 |
33 | ## Create account
34 | Path|Method|Protected
35 | ---|---|---
36 | `/v1/accounts`|POST|Yes
37 |
38 | Create a new account. The response is the created account data.
39 |
40 |
41 |
42 | **Example Request JSON**
43 | ```json copy
44 | {
45 | "name": "string",
46 | "email": "string"
47 | }
48 | ```
49 |
50 | **Example Response JSON**
51 |
52 | ```json copy
53 | {
54 | "id": "string",
55 | "name": "string",
56 | "email": "string",
57 | "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d"
58 | }
59 | ```
60 |
61 | ## Get account
62 | Path|Method|Protected
63 | ---|---|---
64 | `/v1/accounts/{account_id}`|GET|Yes
65 |
66 | Retrieve an account for a given Account ID
67 |
68 |
69 |
70 |
71 |
72 | **Example Response JSON**
73 |
74 | ```json copy
75 | {
76 | "id": "string",
77 | "name": "string",
78 | "email": "string",
79 | "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d"
80 | }
81 | ```
82 |
83 | ## Update account
84 | Path|Method|Protected
85 | ---|---|---
86 | `/v1/accounts/{account_id}`|PUT|Yes
87 |
88 | Allows the user to change the account details such as name and email.
89 |
90 | Changing the planId is not allowed and the request will be rejected.
91 | The response is the updated account data.
92 |
93 |
94 |
95 | **Example Request JSON**
96 | ```json copy
97 | {
98 | "name": "string",
99 | "email": "string"
100 | }
101 | ```
102 |
103 | **Example Response JSON**
104 |
105 | ```json copy
106 | {
107 | "id": "string",
108 | "name": "string",
109 | "email": "string",
110 | "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d"
111 | }
112 | ```
113 |
114 | ## Delete account
115 | Path|Method|Protected
116 | ---|---|---
117 | `/v1/accounts/{account_id}`|DELETE|Yes
118 |
119 | Delete an account.
120 |
121 |
122 |
123 |
124 |
125 | **Example Response JSON**
126 |
127 | ```json copy
128 | {}
129 | ```
130 |
131 | ## Get account's plan
132 | Path|Method|Protected
133 | ---|---|---
134 | `/v1/accounts/{account_id}/plan`|GET|Yes
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 | **Example Response JSON**
143 |
144 | ```json copy
145 | {
146 | "planId": "b3f60ba2-c1fd-4b3a-a23d-8e876e0ef75d",
147 | "planData": {
148 | "projectLimit": 0,
149 | "componentLimit": 0,
150 | "workerLimit": 0,
151 | "storageLimit": 0,
152 | "monthlyGasLimit": 0,
153 | "monthlyUploadLimit": 0
154 | }
155 | }
156 | ```
157 | ## Account API Errors
158 | Status Code|Description|Body
159 | ---|---|---
160 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
161 | 401|Unauthorized request|`{"error":"string"}`
162 | 403|Forbidden Request|`{"error":"string"}`
163 | 404|Entity not found|`{"error":"string"}`
164 | 409||`{"error":"string"}`
165 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/src/pages/develop/updating.mdx:
--------------------------------------------------------------------------------
1 | import { Tabs } from "nextra/components"
2 |
3 | # Updating agents to newer versions of components
4 |
5 | As described in the general [Agents](/concepts/agents) page, each agent runs on a specific version of the component it is based on, but it is possible to **update** an agent to a different version of the same component.
6 |
7 | ## Automatic update
8 |
9 | The **automatic update** mode works as it is described in the general [Agents](/concepts/agents) page.
10 |
11 | ## Manual snapshot-based update
12 |
13 | It is also possible to manually implement a pair of functions for saving and loading an agent's state into an arbitrary byte array. This is useful when making significant changes to the implementation of an agent, such that the automatic replay based update mechanism is no longer working. Future versions of Golem may also use the same snapshotting functions for optimizing recovery time of agents.
14 |
15 |
16 |
17 |
18 | In TypeScript, all agents are inheriting the `BaseAgent` class. There are two methods in `BaseAgent` that can
19 | be overridden to implement snapshot saving and loading for an agent.
20 |
21 | The following example implements these methods for the simple counter example used [on the Quickstart page](/quickstart):
22 | ```typescript
23 | override async saveSnapshot(): Promise {
24 | const snapshot = new Uint8Array(4);
25 | const view = new DataView(snapshot.buffer);
26 | view.setUint32(0, this.value);
27 | return snapshot;
28 | }
29 |
30 | override async loadSnapshot(bytes: Uint8Array): Promise {
31 | let view = new DataView(bytes.buffer);
32 | this.value = view.getUint32(0);
33 | }
34 | ```
35 |
36 |
37 | In Rust, all agent traits (i.e, annotated with `#[agent_definition]` macros) will be generated with two extra methods along with the methods defined in the trait. These methods are `save_snapshot` and `load_snapshot`.
38 | These methods can be overridden to implement snapshot saving and loading for an agent.
39 |
40 | The following example implements these methods for the simple counter example used [on the Quickstart page](/quickstart):
41 | ```rust
42 |
43 | #[agent_definition]
44 | trait CounterAgent{
45 | fn new(init: String) -> Self;
46 | fn increment(&mut self) -> u32;
47 | }
48 |
49 | struct CounterAgentImpl{}
50 |
51 | #[agent_implementation]
52 | impl CounterAgent for CounterAgentImpl {
53 | async fn load_snapshot(&self, _bytes: Vec) -> Result<(), String> {
54 | let arr: [u8; 4] = bytes.try_into().unwrap();
55 | self.value = u32::from_be_bytes(arr);
56 | }
57 |
58 | async fn save_snapshot(&self) -> Result, String> {
59 | Ok(self.value.to_be_bytes().to_vec())
60 | }
61 | }
62 | ```
63 |
64 |
65 |
66 | After making a change that requires a manual update, you need to build and deploy the updated component. Then, to update a specific agent, run the following command:
67 |
68 | ```shell copy
69 | golem agent update manual
70 | ```
71 |
72 | Alternatively, you can update all agents when deploying the updated component:
73 |
74 | ```shell copy
75 | golem app deploy --update-agents manual
76 | ```
77 |
--------------------------------------------------------------------------------
/src/pages/develop/retries.mdx:
--------------------------------------------------------------------------------
1 | import { Callout, Tabs } from "nextra/components"
2 |
3 | # Control the retry policy
4 |
5 | ### Using Golem's retry mechanism
6 |
7 | Golem applies a retry mechanism to all agents. In case of a failure, Golem will automatically recover the agent to the point before the failure and retry the operation. An exponential backoff and an upper limit on the number of retries are applied.
8 |
9 | If the maximum number of retries is reached, the agent will be marked as failed and no further invocations will be possible on it.
10 |
11 | This mechanism is automatic and applied to all kinds of failures. To rely on it, throw an unhandled exception.
12 |
13 |
14 | Golem will retry from the point the unhandled exception was thrown. It is possible that a previous operation's
15 | unwanted result (if it did not end in an exception) has been already persisted, in which case it won't be retried.
16 |
17 |
18 | ### Customizing the retry policy
19 |
20 | The retry policy which controls the maximum number of retries and the exponential backoff is a global configuration of the Golem servers, but it can be customized for each agent.
21 |
22 |
23 |
24 | The `golem-ts-sdk` library exports the `withRetryPolicy` function to temporarily change the retry policy:
25 |
26 | ```typescript
27 | import {withRetryPolicy} from "@golemcloud/golem-ts"
28 |
29 | // Durations are expected as nanoseconds
30 | const result: string = withRetryPolicy(
31 | {
32 | maxAttempts: 3,
33 | minDelay: BigInt(100 * 1000 * 1000), // 100 milliseconds
34 | maxDelay: BigInt(2 * 1000 * 1000 * 1000), // 2 seconds
35 | multiplier: 1.5,
36 | maxJitterFactor: null,
37 | },
38 | () => {
39 | // this closure runs with the custom retry policy
40 | return "hello"
41 | })
42 | ```
43 |
44 | The `RetryPolicy` interface required by `withRetryPolicy` is the following:
45 |
46 | ```typescript
47 | /**
48 | * Configures how the executor retries failures
49 | */
50 | export type RetryPolicy = {
51 | maxAttempts: number;
52 | minDelay: Duration;
53 | maxDelay: Duration;
54 | multiplier: number;
55 | maxJitterFactor?: number;
56 | };
57 | ```
58 |
59 |
60 | The `golem-rust` library exports the `with_retry_policy` function to temporarily change the retry policy:
61 |
62 | ```rust
63 | use golem_rust::with_retry_policy;
64 |
65 | let policy = RetryPolicy {
66 | max_attempts: 3,
67 | min_delay: 100 * 1000 * 1000, // 100 milliseconds
68 | max_delay: 2 * 1000 * 1000 * 1000, // 2 seconds
69 | multiplier: 1.5,
70 | max_jitter_factor: None
71 | };
72 |
73 | with_retry_policy(policy, || {
74 | "hello".to_string()
75 | })
76 |
77 | ```
78 |
79 | The `RetryPolicy` required by `with_retry_policy` is the following:
80 |
81 | ```rust
82 | /**
83 | * Configures how the executor retries failures
84 | */
85 | pub struct RetryPolicy {
86 | pub max_attempts: u32,
87 | pub min_delay: std::time::Duration,
88 | pub max_delay: std::time::Duration,
89 | pub multiplier: f64,
90 | pub max_jitter_factor: Option,
91 | }
92 | ```
93 |
94 |
--------------------------------------------------------------------------------
/src/pages/rest-api/project-grant.mdx:
--------------------------------------------------------------------------------
1 | # Project Grant API
2 | Projects can have grants providing access to other accounts than the project's owner.
3 |
4 | The project grant API allows listing, creating and deleting such grants. What the grants allow exactly are defined by policies, covered by the Project policy API.
5 | ## Get a project's grants
6 | Path|Method|Protected
7 | ---|---|---
8 | `/v1/projects/{project_id}/grants`|GET|Yes
9 |
10 | Returns all projects grants associated with the given project.
11 |
12 | For each grant:
13 | - `id`` is the identifier of the grant itself
14 | - `granteeAccountId` the account that gets access for the project
15 | - `grantorProjectId` the project ID
16 | - `projectPolicyId` the associated policy - see the project policy API below
17 |
18 |
19 |
20 |
21 |
22 | **Example Response JSON**
23 |
24 | ```json copy
25 | [
26 | {
27 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
28 | "data": {
29 | "granteeAccountId": "string",
30 | "grantorProjectId": "fe216e71-e471-414b-9530-d000f4582d33",
31 | "projectPolicyId": "46e8c3fb-5136-4f2a-a8be-e5188bef1348"
32 | }
33 | }
34 | ]
35 | ```
36 |
37 | ## Create a project grant
38 | Path|Method|Protected
39 | ---|---|---
40 | `/v1/projects/{project_id}/grants`|POST|Yes
41 |
42 | Creates a new project grant from the following information:
43 | - `granteeAccountId` the account that gets access for the project
44 | - `projectPolicyId` the associated policy - see the project policy API below
45 |
46 | The response describes the new project grant including its id that can be used to query specifically this grant in the future.
47 |
48 |
49 |
50 | **Example Request JSON**
51 | ```json copy
52 | {
53 | "granteeAccountId": "string",
54 | "granteeEmail": "string",
55 | "projectPolicyId": "46e8c3fb-5136-4f2a-a8be-e5188bef1348",
56 | "projectActions": [
57 | "ViewComponent"
58 | ],
59 | "projectPolicyName": "string"
60 | }
61 | ```
62 |
63 | **Example Response JSON**
64 |
65 | ```json copy
66 | {
67 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
68 | "data": {
69 | "granteeAccountId": "string",
70 | "grantorProjectId": "fe216e71-e471-414b-9530-d000f4582d33",
71 | "projectPolicyId": "46e8c3fb-5136-4f2a-a8be-e5188bef1348"
72 | }
73 | }
74 | ```
75 |
76 | ## Get a specific grant of a project
77 | Path|Method|Protected
78 | ---|---|---
79 | `/v1/projects/{project_id}/grants/{grant_id}`|GET|Yes
80 |
81 | Returns a specific grant of a specific project. The returned object is the same as the elements of the grants endpoint's response described above.
82 |
83 |
84 |
85 |
86 |
87 | **Example Response JSON**
88 |
89 | ```json copy
90 | {
91 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
92 | "data": {
93 | "granteeAccountId": "string",
94 | "grantorProjectId": "fe216e71-e471-414b-9530-d000f4582d33",
95 | "projectPolicyId": "46e8c3fb-5136-4f2a-a8be-e5188bef1348"
96 | }
97 | }
98 | ```
99 |
100 | ## Delete a project grant
101 | Path|Method|Protected
102 | ---|---|---
103 | `/v1/projects/{project_id}/grants/{grant_id}`|DELETE|Yes
104 |
105 | Deletes an existing grant of a specific project.
106 |
107 |
108 |
109 |
110 |
111 | **Example Response JSON**
112 |
113 | ```json copy
114 | {}
115 | ```
116 | ## Project Grant API Errors
117 | Status Code|Description|Body
118 | ---|---|---
119 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
120 | 401|Unauthorized request|`{"error":"string"}`
121 | 403|Forbidden Request|`{"error":"string"}`
122 | 404|Entity not found|`{"error":"string"}`
123 | 409||`{"error":"string"}`
124 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/src/pages/name-mapping.mdx:
--------------------------------------------------------------------------------
1 | # Agent type and method name mapping
2 |
3 | The agents defined by code are compiled to WebAssembly and there are some specific rules of how the agent methods can be referred to from outside the source code, such as from Rib scripts or the CLI.
4 |
5 | ## Component name
6 | The _component name_ must always be in the form of `namespace:name`. This is enforced when the component is created.
7 |
8 | ## Agent types
9 | The agent types have names idiomatic to the used programming language (for example `SampleAgent` in TypeScript). However, when referring to them in agent IDs, invocations, etc., we always use the name converted to **kebab-case** (for example `sample-agent`).
10 |
11 | ## Agent IDs
12 | Every agent is identified by a unique ID which consists of the **agent type** (in kebab-case) and its constructor arguments. The constructor arguments are specified in a specific text format in these IDs.
13 |
14 | - For regular data types, the WAVE encoding is used, same as in Rib scripts. See the [Type Mapping](/type-mapping) page for more details.
15 | - Unstructured text parameters are either inlined between `"`, or a remote URL (not in quotes). The inline string can be optionally prefixed with a language code in square brackets.
16 | - Unstructured binary parameters are either base64 encoded between `"` and prefixed with a mimetype in square brackets, or a remote URL (not in quotes)
17 | - Multimodal values are specified as a list of values, where each value is prefixed with the multimodal type name.
18 |
19 | See the following examples of valid agent IDs:
20 |
21 | ### Singleton agent with no parameters
22 | ```
23 | agent-1()
24 | ```
25 |
26 | ### Agent with one numeric parameter
27 |
28 | ```
29 | agent-2(12)
30 | ```
31 |
32 | ### Agent with multiple parameters
33 |
34 | ```
35 | agent-3(12,{x: 1, y: 2, properties: {a, c}})
36 | ```
37 |
38 | ### Agent with two unstructured text parameters
39 |
40 | ```
41 | agent-4(https://url1.com/,https://url2.com/) // tuple with two unstructured text params pointing to a remote URL
42 | agent-4("hello, world!",[en]"\"hello,\" world!") // tuple with two unstructured inline text params, second having a language code prefix
43 | ```
44 |
45 | ### Agent with two unstructured binary parameters
46 |
47 | ```
48 | agent-5(https://url1.com/,https://url2.com/) // tuple with two unstructured binary params pointing to a remote URL
49 | agent-5([application/json]"SGVsbG8gd29ybGQh",[image/png]"SGVsbG8gd29ybGQh") // tuple with two unstructured inline binary params with MIME type prefixes
50 | ```
51 |
52 | ### Agent with multimodal parameters
53 |
54 | ```
55 | agent-6(z([application/json]"SGVsbG8gd29ybGQh"),x(101)) // multimodal with two values, one named `z` which is a binary and one named `x` which is a wit value
56 | ```
57 |
58 | ## Method names
59 | Agent method names are also converted to **kebab-case**.
60 |
61 | ### Method names in Rib scripts
62 | When calling methods from Rib, first we get an instance of the agent using the constructor syntax:
63 |
64 | ```rib
65 | let agent1 = sample-agent(1, 2, 3);
66 | ```
67 |
68 | Then each exported agent method can be called using the dot syntax, using the kebab-cased method name:
69 |
70 | ```rib
71 | agent1.the-first-method();
72 | ```
73 |
74 | ### Method calls from the CLI or the REST APIs
75 | When directly calling agent methods using `golem agent invoke` or the REST API, the method name must be constructed to point to the WebAssembly export. This indirection is going to be removed in the future.
76 |
77 | The rule to construct the method name is:
78 |
79 | ```
80 | namespace:name/agent-type.{method-name}
81 | ```
82 |
83 | Here `namespace:name` is the component name, `agent-type` is the agent type name in kebab-case, and `method-name` is the method name in kebab-case.
84 |
--------------------------------------------------------------------------------
/src/pages/cli.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 | import { Tabs } from "nextra/components"
4 |
5 | # Golem CLI Introduction
6 |
7 | Golem CLI is a command-line interface for interacting with Golem. Golem CLI allows users to upload their components, launch new agents based on these components and call functions on running agents.
8 |
9 | ## Golem CLI versions
10 | There are precompiled binaries of two variants of the CLI:
11 |
12 | - `golem` is the full version of the command line interface, including a locally runnable version of Golem itself.
13 | - `golem-cli` is a lightweight version of the command line interface, requiring a running Golem cluster.
14 |
15 | In this documentation we will use the `golem` command in the snippets.
16 |
17 | ## Installation
18 |
19 | There are two ways to install any of the above described versions of Golem CLI:
20 |
21 | - Downloading a precompiled platform-specific binary
22 | - Installing from source using Rust tooling
23 |
24 | ### Downloading precompiled binaries
25 |
26 | You can download the precompiled version of `golem` (and `golem-cli`) from the following pages:
27 |
28 |
29 |
30 | ##### Full version, including a locally executable Golem server
31 | | Platform | Link |
32 | | -------- | ---- |
33 | | Mac ARM64| https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-aarch64-apple-darwin |
34 | | Mac x86_64 | https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-x86_64-apple-darwin |
35 | | Linux ARM64 | https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-aarch64-unknown-linux-gnu |
36 | | Linux x86_64 | https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-x86_64-unknown-linux-gnu |
37 |
38 |
39 | Windows is not supported for the current version, and expected to be added in Golem 1.3.1.
40 |
41 |
42 |
43 | ##### Lightweight client version, to work with an existing Golem cluster
44 | | Platform | Link |
45 | | -------- | ---- |
46 | | Mac ARM64| https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-cli-aarch64-apple-darwin |
47 | | Mac x86_64 | https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-cli-x86_64-apple-darwin |
48 | | Linux ARM64 | https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-cli-aarch64-unknown-linux-gnu |
49 | | Linux x86_64 | https://github.com/golemcloud/golem/releases/download/v1.3.1/golem-cli-x86_64-unknown-linux-gnu |
50 |
51 |
52 | Windows is not supported for the current version, and expected to be added in future patch version of Golem 1.3.
53 |
54 |
55 |
56 |
57 |
58 | Some platforms may prevent downloaded binaries from running by default. You may need to
59 | allow them in your system settings.
60 |
61 |
62 | ### Installing from source
63 |
64 | It is also possible to build it from source for yourself using Rust tooling. Refer to [the page about building Golem CLI for yourself](/cli/install-from-source) for more information.
65 |
66 | ## Profiles
67 |
68 | The Golem CLI can have multiple profiles configured, each selecting a specific Golem cluster to connect to, as well as some settings like the default output format.
69 |
70 | See the [Golem CLI profiles page](/cli/profiles) for more information.
71 |
72 | ## Working with components
73 |
74 | Golem CLI can manage components. See the [Golem CLI components page](/cli/components) for details.
75 |
76 | ## Interacting with agents
77 |
78 | Golem CLI allows creating, invoking and observing [agents](/concepts/agents). See the [Golem CLI agents page](/cli/agents) for more information.
79 |
--------------------------------------------------------------------------------
/src/components/all-wit-deps.tsx:
--------------------------------------------------------------------------------
1 | import { FileTree } from "nextra/components"
2 |
3 | export const AllWitDeps = () => {
4 | return (
5 |
6 |
7 | {null}
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | )
88 | }
89 |
--------------------------------------------------------------------------------
/src/pages/rest-api/api-deployment.mdx:
--------------------------------------------------------------------------------
1 | # Api Deployment API
2 |
3 | ## Creates or updates a deployment
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/api/deployments/deploy`|POST|Yes
7 |
8 | Deploys a set of API definitions to a site (specific host and subdomain).
9 |
10 |
11 |
12 | **Example Request JSON**
13 | ```json copy
14 | {
15 | "apiDefinitions": [
16 | {
17 | "id": "string",
18 | "version": "string"
19 | }
20 | ],
21 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
22 | "site": {
23 | "host": "string",
24 | "subdomain": "string"
25 | }
26 | }
27 | ```
28 |
29 | **Example Response JSON**
30 |
31 | ```json copy
32 | {
33 | "apiDefinitions": [
34 | {
35 | "id": "string",
36 | "version": "string"
37 | }
38 | ],
39 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
40 | "site": {
41 | "host": "string",
42 | "subdomain": "string"
43 | },
44 | "createdAt": "2019-08-24T14:15:22Z"
45 | }
46 | ```
47 |
48 | ## Get one or more API deployments
49 | Path|Method|Protected
50 | ---|---|---
51 | `/v1/api/deployments`|GET|Yes
52 |
53 | If `api-definition-id` is not set, it lists all API deployments.
54 | If `api-definition-id` is set, returns a single API deployment.
55 |
56 | **Query Parameters**
57 |
58 | Name|Type|Required|Description
59 | ---|---|---|---
60 | project-id|string|Yes|-
61 | api-definition-id|string|No|-
62 |
63 |
64 |
65 | **Example Response JSON**
66 |
67 | ```json copy
68 | [
69 | {
70 | "apiDefinitions": [
71 | {
72 | "id": "string",
73 | "version": "string"
74 | }
75 | ],
76 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
77 | "site": {
78 | "host": "string",
79 | "subdomain": "string"
80 | },
81 | "createdAt": "2019-08-24T14:15:22Z"
82 | }
83 | ]
84 | ```
85 |
86 | ## Get API deployment by site
87 | Path|Method|Protected
88 | ---|---|---
89 | `/v1/api/deployments/{site}`|GET|Yes
90 |
91 | Gets an API deployment by the host name (optionally with a subdomain) it is deployed to.
92 |
93 | **Query Parameters**
94 |
95 | Name|Type|Required|Description
96 | ---|---|---|---
97 | project-id|string|Yes|-
98 |
99 |
100 |
101 | **Example Response JSON**
102 |
103 | ```json copy
104 | {
105 | "apiDefinitions": [
106 | {
107 | "id": "string",
108 | "version": "string"
109 | }
110 | ],
111 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
112 | "site": {
113 | "host": "string",
114 | "subdomain": "string"
115 | },
116 | "createdAt": "2019-08-24T14:15:22Z"
117 | }
118 | ```
119 |
120 | ## Delete API deployment by site
121 | Path|Method|Protected
122 | ---|---|---
123 | `/v1/api/deployments/{site}`|DELETE|Yes
124 |
125 | Deletes an API deployment by the host name (optionally with a subdomain) it is deployed to.
126 |
127 | **Query Parameters**
128 |
129 | Name|Type|Required|Description
130 | ---|---|---|---
131 | project-id|string|Yes|-
132 |
133 |
134 |
135 | **Example Response JSON**
136 |
137 | ```json copy
138 | "string"
139 | ```
140 |
141 | ## Undeploy a single API definition from a site
142 | Path|Method|Protected
143 | ---|---|---
144 | `/v1/api/deployments/{site}/{id}/{version}`|DELETE|Yes
145 |
146 | Removes a specific API definition (by id and version) from a site without deleting the entire deployment.
147 |
148 | **Query Parameters**
149 |
150 | Name|Type|Required|Description
151 | ---|---|---|---
152 | project-id|string|Yes|-
153 |
154 |
155 |
156 | **Example Response JSON**
157 |
158 | ```json copy
159 | "string"
160 | ```
161 | ## Api Deployment API Errors
162 | Status Code|Description|Body
163 | ---|---|---
164 | 400||`{"errors":["string"]}`
165 | 401||`{"error":"string"}`
166 | 403||`{"error":"string"}`
167 | 404||`{"error":"string"}`
168 | 409||`{"error":"string"}`
169 | 500||`{"error":"string","workerError":{"cause":"string","stderr":"string"}}`
--------------------------------------------------------------------------------
/src/pages/invoke/http.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 |
3 | # Invoke through the REST API
4 |
5 |
6 | Previously Golem called _agents_ as workers, and the new name has not been applied everywhere yet. The APIs described in this section are still using the _worker_ name.
7 |
8 |
9 | The Golem REST API exposes two endpoints for invoking agents. See the [Worker REST API reference](/rest-api/worker) for details.
10 | These endpoints provide a direct, low level API for calling the exported functions of the agents. They use a special JSON format for encoding WASM values and types. It is possible, and recommended, to create [custom HTTP APIs](/invoke/making-custom-apis) for exposing agents to the world.
11 |
12 | ## Endpoints
13 |
14 | ### Invoke agents
15 |
16 | The `invoke` endpoint enqueues an invocation for the given agent and returns immediately.
17 |
18 | ```
19 | POST /v1/components/{component_id}/workers/{agent_id}/invoke?function={function_name}
20 | ```
21 |
22 | This POST request invokes the agent called `agent_id` of the component identified by `component_id` (a UUID), calling the function `function_name`.
23 | Read the [name mapping page](/name-mapping) to learn how the function names are mapped.
24 |
25 | The **body** of the POST request must be a JSON object containing a single field called `params`, which is an **array** of typed JSON values. The format of typed JSON values is described below.
26 |
27 | ### Invoke and await agents
28 |
29 | The `invoke-and-await` endpoint enqueues an invocation for a given agent and then awaits its completion, returning the successful result value or failure in the response body.
30 |
31 | ```
32 | POST /v1/components/{component_id}/workers/{agent_id}/invoke-and-await?function={function_name}
33 | ```
34 |
35 | This POST request invokes the agent called `agent_id` (consisting of the agent type name and the parameter values) of the component identified by `component_id` (a UUID), calling the function `function_name`.
36 | Read the [name mapping page](/name-mapping) to learn how the function names are mapped.
37 |
38 | The **body** of the POST request must be a JSON object containing a single field called `params`, which is an **array** of typed JSON values. The format of typed JSON values is described below.
39 |
40 | The **response body** is a JSON object with a single field `result`, containing the invoked function's result encoded as a typed JSON value.
41 |
42 | ## Implicit agent creation
43 |
44 | If the invoked agent does not exist, it is automatically created by the invocation.
45 |
46 | ## Cancelling pending invocations
47 |
48 | As invocations are executed sequentially, it is possible to cancel a pending invocation before it starts executing. This can be done using the cancel invocation endpoint:
49 |
50 | ```
51 | DELETE /v1/components/{component_id}/workers/{agent_id}/invocations/{idempotency_key}
52 | ```
53 |
54 | ## Typed JSON values
55 |
56 | Typed JSON values are JSON **objects** with two fields:
57 |
58 | - `typ` describes the type of the value
59 | - `value` is the actual value
60 |
61 | The invocation API **does not require** type information beside the values, but providing it makes the invocation much faster. Invocations without provided type information are intended to be used only for testing, as they involve gathering the missing information for each invocation separately.
62 |
63 | ### Value format
64 |
65 | Read the [Type Mapping](/type-mapping) page to see how every WebAssembly value is encoded in JSON, and how the data types defined in the Golem component's source code are mapped to these.
66 |
67 | ### Getting the type
68 |
69 | When constructing invocation requests, the easiest way to get the type part of the request body is to get **the component metadata** using the REST API:
70 |
71 | ```
72 | GET /v1/components/{component_id}/latest
73 | ```
74 |
75 | This request returns the metadata of the **latest version** of the component given by its identifier (a UUID). This metadata lists all the exported functions and their expected parameter types. These parameter types encode type information in the same format as the invocation API, so it is possible to copy them when constructing invocations.
76 |
77 | Note that it is not recommended to do this dynamically; the client using the invocation API should target a specific component version, with parameter types known in advance.
78 |
--------------------------------------------------------------------------------
/src/pages/cli/permissions.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 |
3 | # Golem CLI Permissions
4 |
5 | This page only applies to the hosted **Golem Cloud**.
6 |
7 | ## Tokens
8 |
9 | Tokens are API keys that allow accessing **Golem Cloud** APIs from external services. The `golem-cloud-cli` tool allows managing these tokens.
10 | To manage them programmatically, check [the token API](/rest-api/token).
11 |
12 | ### Listing existing tokens
13 |
14 | The following command lists all the tokens associated with your account:
15 |
16 | ```shell copy
17 | golem token list
18 | ```
19 |
20 | ### Creating a new token
21 |
22 | To create a new token, use the following command:
23 |
24 | ```shell copy
25 | golem token add
26 | ```
27 |
28 | ```
29 | New token created with id 08bc0eac-5c51-40a5-8bc6-5c8928efb475 and expiration date 2100-01-01 00:00:00 UTC.
30 | Please save this token secret, you can't get this data later:
31 | 64cf566c-ed72-48e5-b786-b88aa0298fb4
32 | ```
33 |
34 | Optionally, an expiration date can be specified with `--expires-at`. If not specified, default expiration date is `2100-01-01 00:00:00 UTC`.
35 |
36 | ### Deleting a token
37 |
38 | Each token has a **token ID**. Use the `token delete` command to remove a token using it's identifier:
39 |
40 | ```shell copy
41 | golem token delete 08bc0eac-5c51-40a5-8bc6-5c8928efb475
42 | ```
43 |
44 | ## Project sharing
45 |
46 | On **Golem Cloud** components are organized into **projects**.
47 |
48 | ### Listing projects
49 |
50 | Existing projects can be listed using the `project list` subcommand:
51 |
52 | ```shell copy
53 | golem project list
54 | ```
55 |
56 | ### Adding projects
57 |
58 | A new project can be created using `project add`. The command expects a project name and description:
59 |
60 | ```shell copy
61 | golem project add --project-name "Golem Demo" --project-description "A new project for demonstrating the project feature"
62 | ```
63 |
64 | When creating components or agents, the project can be specified with the `--project-name` flag. Every user has a **default project** which is used when no explicit project is specified.
65 |
66 | ### Sharing projects with other accounts
67 |
68 |
69 | The share command still uses the old terminology of _workers_ instead of talking about _agents_. This is going to be changed in the next version.
70 |
71 |
72 | Projects can be shared among multiple Golem Cloud accounts.
73 |
74 | To share a project, use the `share` subcommand:
75 |
76 | ```shell copy
77 | golem share --project-name "Golem Demo" --recipient-account-id 08bc0eac-5c51-40a5-8bc6-5c8928efb475 --project-actions ViewWorker --project-actions ViewComponent
78 | ```
79 |
80 | This example shares the "Golem Demo" project with the account identified by `08bc0eac-5c51-40a5-8bc6-5c8928efb475` and grants component and agent **view** permissions for it.
81 |
82 |
83 | Alternatively it is possible to create and manage **project policies** using the `project-policy`
84 | subcommand, and refer to these policies in the `share` command later.
85 |
86 |
87 | The following table lists all the **actions** that can be granted to a project:
88 |
89 | | Action | Description |
90 | | --------------------- | --------------------------------------------- |
91 | | `ViewComponent` | List, download and get metadata of components |
92 | | `CreateComponent` | Create new components |
93 | | `UpdateComponent` | Update existing components |
94 | | `DeleteComponent` | Delete components |
95 | | `ViewWorker` | List and get metadata of workers |
96 | | `CreateWorker` | Create new workers |
97 | | `UpdateWorker` | Update existing workers |
98 | | `DeleteWorker` | Delete workers |
99 | | `ViewProjectGrants` | List existing project grants |
100 | | `CreateProjectGrants` | Grant more access for the project |
101 | | `DeleteProjectGrants` | Revoke access for the project |
102 | | `ViewApiDefinition` | View API definitions |
103 | | `CreateApiDefinition` | Create new API definitions |
104 | | `UpdateApiDefinition` | Update existing API definitions |
105 | | `DeleteApiDefinition` | Delete API definitions |
106 |
--------------------------------------------------------------------------------
/src/pages/concepts/plugins.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 |
3 | # Introduction
4 |
5 | Golem Plugins provide ways to extend the functionality of Golem without having to modify the core codebase. Plugins can be installed to both the open-source and the hosted versions of Golem.
6 |
7 | This page introduces the types of plugins Golem supports and explains their lifecycle.
8 |
9 |
10 | Plugin support is experimental and not fully available in Golem 1.1 yet. The next release will
11 | include stronger guarantees, UI support and better documentation and examples.
12 |
13 |
14 | ## Types of plugins
15 |
16 | Golem supports the following types of plugins:
17 |
18 | - **Component transformer** plugins can alter an uploaded component when it gets uploaded to Golem
19 | - **Oplog processor** plugins can observe running agents
20 | - **Library plugins** and **application plugins** are special, easier to use versions of component transformer plugins
21 |
22 | ### Component transformer plugins
23 |
24 | Component transformer plugins are external web services providing an HTTP endpoint that receives a WASM component and returns a transformed WASM component. The most common use case for this type of plugin is to use **component composition** to achieve one of the following goals:
25 |
26 | - Replace one or more of the host interfaces provided by Golem. For example a component transformer plugin may implement the WASI KeyValue store interface for a component by connecting to a third party database, instead of using the one provided by Golem.
27 | - Wrap the host interfaces provided by Golem. In this case the adapter the plugin composes the uploaded component with both imports and exports the same interfaces, and by that wraps Golem's implementation for example to publish metrics or perform logging.
28 | - Extend the provided interface of the component by exporting additional invokable functions.
29 |
30 | #### Library plugins
31 |
32 | Library plugins are special component transformer plugins that do not require any external HTTP service to be running. A library plugin is a WASM component that is going to be composed with the user's uploaded components in a way that every exported interface of the plugin's WASM is plugged into the user component's matching imports.
33 |
34 | #### Application plugins
35 |
36 | Application plugins are similar to library plugins with the difference that the user's component's exported interface is getting plugged into the plugin's matching imports.
37 |
38 | ### Oplog processor plugins
39 |
40 | Oplog processor plugins are special **golem agents** implementing the `golem:api@1.1.7/oplog-processor` interface. These plugins are instantiated by Golem and are periodically invoked with oplog entries, a journal of operations performed by agents where the plugin is installed.
41 |
42 |
43 | Oplog processor plugin support is experimental. The final version will guarantee **exactly-once**
44 | semantics for processing the oplog of the agents, which means that if the plugin is installed and
45 | activated for an agent, we guarantee that the plugin will receive _all of the oplog entries_ of
46 | that agent (even from before the plugin was active), and each entry will be only sent exactly
47 | once. This guarantee is not implemented yet.
48 |
49 |
50 | ## Plugin configuration
51 |
52 | Plugins can have **configuration** in the form of key-value pairs, which are customizable for each **plugin installation**. Golem sends these configuration values to the plugins when they are invoked.
53 |
54 | ## Plugin lifecycle
55 |
56 | Plugins are first **defined** using Golem's Plugin API (using the REST API, CLI or the Console). Each defined plugin is identified by a _name_ and a _version_. In _Golem Cloud_ plugins are defined per account.
57 |
58 | Defining a plugin does not immediately make that plugin used by Golem. To make use of a plugin, it must be **installed** to a **component**. This can be done either when a component is created, or later using the Component API. In _Golem Cloud_ plugins can also be installed to _projects_, in which case each new component created in the given project will have those plugins installed.
59 |
60 | Installing a plugin to a component creates a new **component version**, similarly how updating a component's WASM file does. This guarantees that already running agents are not affected by the plugin installation process. To make an existing agent use of an installed plugin, the agent must be **updated** to the new component version.
61 |
62 | Oplog processor plugins can also be **activated** and **deactivated** on a running agent dynamically using the Agent API. This is an advanced feature which allows the user to temporarily pause an effect of a plugin for a given agent.
63 |
--------------------------------------------------------------------------------
/src/pages/rest-api/plugin.mdx:
--------------------------------------------------------------------------------
1 | # Plugin API
2 |
3 | ## Lists all the registered plugins (including all versions of each).
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/plugins`|GET|Yes
7 |
8 |
9 |
10 | **Query Parameters**
11 |
12 | Name|Type|Required|Description
13 | ---|---|---|---
14 | scope|#/components/schemas/PluginScope|Yes|-
15 |
16 |
17 |
18 | **Example Response JSON**
19 |
20 | ```json copy
21 | [
22 | {
23 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
24 | "name": "string",
25 | "version": "string",
26 | "description": "string",
27 | "icon": [
28 | 0
29 | ],
30 | "homepage": "string",
31 | "specs": {
32 | "type": "ComponentTransformer",
33 | "providedWitPackage": "string",
34 | "jsonSchema": "string",
35 | "validateUrl": "string",
36 | "transformUrl": "string"
37 | },
38 | "scope": {
39 | "type": "Global"
40 | },
41 | "owner": {
42 | "accountId": "string"
43 | },
44 | "deleted": true
45 | }
46 | ]
47 | ```
48 |
49 | ## Registers a new plugin
50 | Path|Method|Protected
51 | ---|---|---
52 | `/v1/plugins`|POST|Yes
53 |
54 |
55 |
56 |
57 |
58 | **Example Request JSON**
59 | ```json copy
60 | {
61 | "name": "string",
62 | "version": "string",
63 | "description": "string",
64 | "icon": [
65 | 0
66 | ],
67 | "homepage": "string",
68 | "specs": {
69 | "type": "ComponentTransformer",
70 | "providedWitPackage": "string",
71 | "jsonSchema": "string",
72 | "validateUrl": "string",
73 | "transformUrl": "string"
74 | },
75 | "scope": {
76 | "type": "Global"
77 | }
78 | }
79 | ```
80 |
81 | **Example Response JSON**
82 |
83 | ```json copy
84 | {}
85 | ```
86 |
87 | ## Gets a registered plugin by its name and version
88 | Path|Method|Protected
89 | ---|---|---
90 | `/v1/plugins/{account_id}/{name}/{version}`|GET|Yes
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | **Example Response JSON**
99 |
100 | ```json copy
101 | {
102 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
103 | "name": "string",
104 | "version": "string",
105 | "description": "string",
106 | "icon": [
107 | 0
108 | ],
109 | "homepage": "string",
110 | "specs": {
111 | "type": "ComponentTransformer",
112 | "providedWitPackage": "string",
113 | "jsonSchema": "string",
114 | "validateUrl": "string",
115 | "transformUrl": "string"
116 | },
117 | "scope": {
118 | "type": "Global"
119 | },
120 | "owner": {
121 | "accountId": "string"
122 | },
123 | "deleted": true
124 | }
125 | ```
126 |
127 | ## Deletes a registered plugin by its name and version
128 | Path|Method|Protected
129 | ---|---|---
130 | `/v1/plugins/{account_id}/{name}/{version}`|DELETE|Yes
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 | **Example Response JSON**
139 |
140 | ```json copy
141 | {}
142 | ```
143 |
144 | ## Registers a new library plugin
145 | Path|Method|Protected
146 | ---|---|---
147 | `/v1/plugins/library-plugins`|POST|Yes
148 |
149 |
150 |
151 |
152 |
153 | **Request Form**: `multipart/form-data`
154 |
155 | > Make sure to include `Content-Type: multipart/form-data` Header
156 |
157 | **Field `name`**: string undefined
158 |
159 | **Field `version`**: string undefined
160 |
161 | **Field `description`**: string undefined
162 |
163 | **Field `icon`**: string binary
164 |
165 | **Field `homepage`**: string undefined
166 |
167 | **Field `scope`**: JSON
168 | ```json copy
169 | {
170 | "type": "Global"
171 | }
172 | ```
173 |
174 | **Field `wasm`**: string binary
175 |
176 | **Example Response JSON**
177 |
178 | ```json copy
179 | {}
180 | ```
181 |
182 | ## Registers a new app plugin
183 | Path|Method|Protected
184 | ---|---|---
185 | `/v1/plugins/app-plugins`|POST|Yes
186 |
187 |
188 |
189 |
190 |
191 | **Request Form**: `multipart/form-data`
192 |
193 | > Make sure to include `Content-Type: multipart/form-data` Header
194 |
195 | **Field `name`**: string undefined
196 |
197 | **Field `version`**: string undefined
198 |
199 | **Field `description`**: string undefined
200 |
201 | **Field `icon`**: string binary
202 |
203 | **Field `homepage`**: string undefined
204 |
205 | **Field `scope`**: JSON
206 | ```json copy
207 | {
208 | "type": "Global"
209 | }
210 | ```
211 |
212 | **Field `wasm`**: string binary
213 |
214 | **Example Response JSON**
215 |
216 | ```json copy
217 | {}
218 | ```
219 | ## Plugin API Errors
220 | Status Code|Description|Body
221 | ---|---|---
222 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
223 | 401|Unauthorized|`{"error":"string"}`
224 | 403|Maximum number of components exceeded|`{"error":"string"}`
225 | 404|Component not found|`{"error":"string"}`
226 | 409|Component already exists|`{"error":"string"}`
227 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/public/icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/components/footer.tsx:
--------------------------------------------------------------------------------
1 | import {
2 | DiscordLogoIcon,
3 | EnvelopeClosedIcon,
4 | GitHubLogoIcon,
5 | TwitterLogoIcon,
6 | } from "@radix-ui/react-icons"
7 | import { GolemLogo } from "./golem-logo"
8 |
9 | export function Footer() {
10 | const year = new Date().getFullYear()
11 | return (
12 |
84 | )
85 | }
86 |
87 | const support = [
88 | { name: "Blog", href: "https://www.golem.cloud/blog" },
89 | { name: "Help Center", href: "https://help.golem.cloud" },
90 | ]
91 |
92 | const golem = [
93 | { name: "About", href: "https://www.golem.cloud" },
94 | { name: "Console", href: "https://console.golem.cloud" },
95 | ]
96 |
97 | const socials = [
98 | {
99 | name: "Github",
100 | href: "https://github.com/golemcloud",
101 | icon: GitHubLogoIcon,
102 | },
103 | {
104 | name: "Twitter",
105 | href: "https://twitter.com/golemcloud",
106 | icon: TwitterLogoIcon,
107 | },
108 | {
109 | name: "Email",
110 | href: "mailto:contact@golem.cloud",
111 | icon: EnvelopeClosedIcon,
112 | },
113 | {
114 | name: "Discord",
115 | href: "https://discord.gg/UjXeH8uG4x",
116 | icon: DiscordLogoIcon,
117 | },
118 | ] as const
119 |
--------------------------------------------------------------------------------
/src/pages/invoke/making-custom-apis/authentication.mdx:
--------------------------------------------------------------------------------
1 | import { Steps } from "nextra/components"
2 |
3 | # Make Secure HTTP APIs
4 |
5 | Golem API gateway has built-in authentication support to identify users using OpenID protocol.
6 | This allows you to refer to the claims such as `request.auth.email` (as an example) once authenticated in your Rib expression.
7 | You can choose to pass this information into the agent method that exist in the Rib expression, and do further logic with it.
8 | Currently, this is tested with Google Identity connector.
9 |
10 | ## Setup Security for your API routes in Golem
11 |
12 | ### Register an app with Google Identity Provider and get a client-id and client-secret.
13 |
14 | Here is the direct link to register your app with [Google Identity Provider](https://console.cloud.google.com/apis/credentials).
15 | Make sure your app with a redirect URL and get the client-id and client secret.
16 |
17 | When using a locally executed Golem instance during development, the redirect URI can be `http://localhost:9006/auth/callback`. Otherwise it should be be `https://mydomain.com/auth/callback`, where `mydomain.com` is the domain in which you will be deploying your API definition in Golem.
18 |
19 | The `/auth/callback` part is just an example and it can be anything, as far as it doesn't collide with any other existing routes.
20 |
21 | We call these details "Api Security Scheme" in Golem API Gateway. Next step is to register this scheme in Golem.
22 |
23 | ### Register API Security Scheme with your app's client-id and client-secret with Golem
24 |
25 | Make sure you name your security scheme uniquely, and provide the client-id, client-secret and redirect-url as given below.
26 |
27 | ```shell copy
28 |
29 | golem api security-scheme create \
30 | --provider-type google \
31 | --client-id REPLACE_WITH_GOOGLE_CLIENT_ID \
32 | --client-secret REPLACE_WITH_GOOGLE_CLIENT_SECRET \
33 | --redirect-url http://localhost:9006/auth/callback
34 | --scope openid,email,profile \
35 | my-security
36 | ```
37 |
38 | By now, you are having a security scheme registered with `golem` which you can refer in API definitions.
39 |
40 | ### Reference the security scheme name in API definition
41 |
42 | This name (`my-security` in the above example) is the one to be used in the route's `security` field, as described in the [Making Custom APIs](/invoke/making-custom-apis) page.
43 |
44 | ### New fields available on the Rib `request` object
45 |
46 | Attaching a security scheme to a route adds an additional `auth` field to the Rib `request` object, which contains the claims from the authenticated user's ID token. For example, to get the authenticated user's email and use it to access an agent (with agent type `example-agent`) associated with this user:
47 |
48 | ```rib
49 | let email: string = request.auth.email;
50 | let agent = example-agent(email);
51 | ```
52 |
53 | #### Redirects and Cookies
54 |
55 | Internally, there are a couple of redirects that's going on when you access the protected endpoint.
56 | The first redirect is to the Google Identity Provider login page as explained below, and internally this is followed by identity provider hitting the redirect URL (
57 | which is exposed on your behalf by Golem API gateway) with all the details of the user.
58 | This is followed by another redirect to the original URL that you tried to access, and this time the session-id, tokens/secrets set in a secure Cookie, which your
59 | browser will resend. Once the browser sends the cookie, Golem API gateway will validate the cookie and allow you to access the protected endpoint.
60 |
61 | We will be adding more support for various clients and use-cases in future releases based on the user feedback.
62 |
63 | #### Unexposed CallBack Endpoint
64 |
65 | Note that the callback endpoint is exposed automatically based on the re-direct url specified in the API security scheme. Users cannot customise or add
66 | these call back endpoints manually. This is to avoid any security issues that may arise due to misconfiguration of the callback endpoint.
67 |
68 | #### Troubleshooting
69 |
70 | Most of the errors in this use-case are originated from a wrong security scheme configuration. For example, a wrong `redirect-url`
71 | can result in odd errors that is difficult to spot, as this is originated from the providers and not Golem.
72 |
73 | Make sure the scope is correct and includes email. Trying to specify `request.auth.email` while the scope doesn't have it in the security scheme,
74 | will result in errors such as `email` not found in the request object
75 |
76 | #### Known Issues
77 |
78 | Using multiple security schemes (with the names foo-security-scheme, and bar-security-scheme ) with the same redirect-url is not supported and leads to an internal error.
79 |
80 | ```sh
81 | Selected profile: local
82 |
83 | error: API Security Scheme Service - Error: 500 Internal Server Error, InternalError: Internal repository error (unique
84 | key violation)
85 | ```
86 |
87 |
--------------------------------------------------------------------------------
/src/pages/operate/logs.mdx:
--------------------------------------------------------------------------------
1 | import { Tabs } from "nextra/components"
2 |
3 | # Logs
4 |
5 | ## Golem server logs
6 |
7 | Every Golem service emits structured logs with with configurable format and level. The default configuration for our dockerized builds is to log to the container's standard output using JSON format. Each service supports the same set of configuration keys controlling the logging behavior, which can be overwritten using **environment variables**.
8 |
9 | The **default log level and filtering** can be configured using the `RUST_LOG` environment variable, as described in the [tracing-subscriber](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html) crate's documentation. The simplest way to use this environment variable is to set a global log level, for example `RUST_LOG=debug`.
10 |
11 | The Golem specific config keys are the following:
12 |
13 | ```toml
14 | [tracing]
15 | console = false
16 | dtor_friendly = false
17 | file_name = "worker-executor.log"
18 | file_truncate = true
19 |
20 | [tracing.file]
21 | ansi = false
22 | compact = false
23 | enabled = false
24 | json = true
25 | json_flatten = true
26 | json_flatten_span = true
27 | pretty = false
28 | span_events_active = false
29 | span_events_full = false
30 | without_time = false
31 |
32 | [tracing.stdout]
33 | ansi = true
34 | compact = false
35 | enabled = true
36 | json = false
37 | json_flatten = true
38 | json_flatten_span = true
39 | pretty = false
40 | span_events_active = false
41 | span_events_full = false
42 | without_time = false
43 | ```
44 |
45 | ### Overwriting config
46 |
47 | To overwrite any of the above config keys using **environment variables**, use the `GOLEM_` prefix and the `__` separator for levels. For example to disable logging to the standard output, and instead enable logging to a file, set the following two variables:
48 |
49 | ```
50 | GOLEM_TRACING__FILE__ENABLED=true
51 | GOLEM_TRACING__STDOUT__ENABLED=false
52 | ```
53 |
54 | ### Configurable options
55 |
56 | The top-level `tracing` block allows setting the file name and truncate behavior for file logging, as well as enabling connection to [`tokio-console`](https://github.com/tokio-rs/console).
57 |
58 | For both `file` and `stdout` logging, a set of boolean flags control the format of the emitted log lines:
59 |
60 | | Flag | Description |
61 | | -------------------- | ----------------------------------------------------- |
62 | | `ansi` | Use ANSI colors for the output |
63 | | `compact` | Use the **compact formatter**. |
64 | | `enabled` | Enables logging to file or stdout |
65 | | `json` | Use JSON logging |
66 | | `json_flatten` | Flatten event metadata |
67 | | `json_flatten_span` | Flatten nested span fields |
68 | | `pretty` | Use the **pretty formatter** |
69 | | `span_events_active` | Emit one event per enter/exit of a span |
70 | | `span_events_full` | Emit one event at all points (new, enter, exit, drop) |
71 | | `without_time` | Do not emit timestamps for the log entries |
72 |
73 | ## Golem agent logs
74 |
75 |
76 |
77 | In TypeScript agents, use the standard functions of `console` to log messages. `console.log` writes to the agent's standard output,
78 | while `console.debug`, `console.info`, etc. are writing log entries with the specific log level.
79 |
80 |
81 | In Rust agents, anything written to the agent's standard output and error channels for example with `println!` or `eprintln!` are logged.
82 |
83 | In addition to that it is possible to use `log` method in `golem_rust::bindings::wasi::logging::logging` module directly to write log entries with specific log levels:
84 | ```rust
85 | use golem_rust::bindings::wasi::logging::logging;
86 |
87 | logging::log(logging::Level::Info, "my_context", "my_message");
88 | ```
89 |
90 | The recommended way is to just use the `log` package, already initialized in the Rust agent templates:
91 |
92 | ```rust
93 | use log;
94 |
95 | log::info!("my_message");
96 | ```
97 |
98 |
99 |
100 | ### Getting agent logs
101 |
102 | Agent logs (both stdout/err and WASI logging entries) are persisted for each agent, and they can be watched in live by using the **connect API**. There are three ways to connect to an agent:
103 |
104 | - Using `golem`
105 | - Using the connect WebSocket API
106 | - Using the [Golem Console](https://console.golem.cloud/) (Golem Cloud only)
107 |
108 | To connect to a agent's log with `golem`, use either the `golem agent stream` command or the `--stream` flag when making an invocation. See the [CLI documentation](/cli/agents) for more details.
109 |
--------------------------------------------------------------------------------
/src/pages/deploy.mdx:
--------------------------------------------------------------------------------
1 | import { Cards, Card } from "nextra/components"
2 |
3 | # Deployment
4 |
5 | Golem Services are distributed as Docker images. They are available in [Golem Services Docker Hub](https://hub.docker.com/u/golemservices). Each Docker image is built for the following architectures:
6 |
7 | - linux/amd64
8 | - linux/arm64
9 |
10 | The services are using the following storage backends:
11 |
12 | - Relational Database (RDB) - [PostgreSQL](https://www.postgresql.org/) or SQLite (for running locally)
13 | - [Redis](https://redis.io/)
14 | - Blob storage - Shared File System or S3
15 |
16 | ## Golem Services
17 |
18 | The following sections provide a description of each service.
19 |
20 | ### Cloud Service
21 |
22 | [cloud-service](https://github.com/golemcloud/golem/tree/main/cloud-service) is responsible for storing entities like projects and accounts in RDB.
23 |
24 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/cloud-service/config/cloud-service.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/cloud-service/config/cloud-service.sample.env), [docker image](https://hub.docker.com/r/golemservices/cloud-service)
25 |
26 | ### Component Service
27 |
28 | [golem-component-service](https://github.com/golemcloud/golem/tree/main/golem-component-service) is a component registry/management service. The service is using RDB and Blob storage as data storage.
29 |
30 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-component-service/config/component-service.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/golem-component-service/config/component-service.sample.env), [docker image](https://hub.docker.com/r/golemservices/golem-component-service)
31 |
32 | ### Debugging Service
33 |
34 | [golem-debugging-service](https://github.com/golemcloud/golem/tree/main/golem-debugging-service) is a special executor for running debugging sessions, controlling the execution of agents step by step.
35 |
36 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-debugging-service/config/debug-worker-executor.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/golem-debugging-service/config/debug-worker-executor.sample.env), [docker image](https://hub.docker.com/r/golemservices/golem-debugging-service)
37 |
38 | ### Worker Service
39 |
40 | [golem-worker-service](https://github.com/golemcloud/golem/tree/main/golem-worker-service) provides APIs and [API Gateway](/concepts/worker-gateway) functionality for agents and acts as a routing service for worker executors. The service uses an RDB as data storage.
41 |
42 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-worker-service/config/worker-service.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/golem-worker-service/config/worker-service.sample.env), [docker image](https://hub.docker.com/r/golemservices/golem-worker-service)
43 |
44 | ### Worker Executor
45 |
46 | [golem-worker-executor](https://github.com/golemcloud/golem/tree/main/golem-worker-executor) is responsible for running the [agents](/concepts/agents) that belong to assigned shards. The service uses Redis and Blob storage as data storage.
47 |
48 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-worker-executor/config/worker-executor.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/golem-worker-executor/config/worker-executor.sample.env), [docker image](https://hub.docker.com/r/golemservices/golem-worker-executor)
49 |
50 | ### Shard Manager
51 |
52 | [golem-shard-manager](https://github.com/golemcloud/golem/tree/main/golem-shard-manager) is a single node in charge of maintaining the worker executors' shard assignments; only one instance can be alive at any given time. The service uses Redis as data storage.
53 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-shard-manager/config/shard-manager.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/golem-shard-manager/config/shard-manager.sample.env), [docker image](https://hub.docker.com/r/golemservices/golem-shard-manager)
54 |
55 | ### Component Compilation Service
56 |
57 | [golem-component-compilation-service](https://github.com/golemcloud/golem/tree/main/golem-component-compilation-service) is a sidecar service responsible for compiling components. The service uses Blob storage as data storage.
58 |
59 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-component-compilation-service/config/component-compilation-service.toml), [environment variables](https://github.com/golemcloud/golem/blob/main/golem-component-compilation-service/config/component-compilation-service.sample.env), [docker image](https://hub.docker.com/r/golemservices/golem-component-compilation-service)
60 |
61 | ### Golem Router
62 |
63 | [golem-router](https://github.com/golemcloud/golem/tree/main/golem-router) is an [Nginx](https://nginx.org/) proxy for Golem APIs.
64 |
65 | See also: [configuration](https://github.com/golemcloud/golem/blob/main/golem-router/golem-services.conf.template), [docker image](https://hub.docker.com/r/golemservices/golem-router)
66 |
67 | ## Deployment Variants
68 |
69 | For deployment variants, see the following sections:
70 |
71 |
72 |
73 |
74 |
75 |
76 |
--------------------------------------------------------------------------------
/src/pages/cli/profiles.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 |
3 | # Golem CLI Profiles
4 |
5 | Using different profiles you can use `golem` with multiple installations of an open source Golem and the hosted Golem Cloud at the same time.
6 |
7 | ## Interactive profile creation
8 |
9 | To start interactive profile creation run the following command:
10 |
11 | ```shell copy
12 | golem init
13 | ```
14 |
15 | If you want to specify a custom profile name for the interactive profile creation process, you can use the following command:
16 |
17 | ```shell copy
18 | golem profile init custom-name
19 | ```
20 |
21 | In the first step you'll see three options:
22 |
23 | - Golem Default. Use this option for the default local Docker Compose installation.
24 | - Golem. Use this option in case of a customized Golem installation, i.e. a custom `GOLEM_ROUTER_PORT` in the `.env` file.
25 | - Golem Cloud. Use this option for a hosted version of Golem.
26 |
27 | With the Golem Default and the hosted Golem Cloud options, there are no other specific configuration options.
28 | To specify a custom location for your local open source Golem installation, please use the `Golem` option.
29 |
30 | ## Non-interactive profile creation
31 |
32 | ### Hosted Golem Cloud profile
33 |
34 | To create a profile for a hosted Golem Cloud use the following command:
35 |
36 | ```shell copy
37 | golem profile add --set-active golem-cloud --default-format json my-profile-name
38 | ```
39 |
40 | This command creates a new Golem Cloud profile named `my-profile-name` with default output format `json` and sets it as a new active profile.
41 | If you want to keep default output format `text` - you can omit `--default-format json` part. If you don't want to make the new profile as the new active profile - you can omit `--set-active`.
42 |
43 | If you are using `golem-cloud-cli` binary you should omit profile type (`golem-cloud`) since `golem-cloud-cli` does not support other profile types:
44 |
45 | ```bash filename="Terminal" copy
46 | golem-cloud-cli profile add my-profile-name
47 | ```
48 |
49 | ### Local open source Golem
50 |
51 | To create a profile for your local open source Golem installation use the following command:
52 |
53 | ```shell copy
54 | golem profile add --set-active golem --component-url http://localhost:9881 my-oss-profile-name
55 | ```
56 |
57 | This command creates a new open source Golem profile named `my-oss-profile-name` with both component and worker service location as `http://localhost:9881` and sets it as the new active profile.
58 |
59 | Additionally, you can specify the `--default-format` option (`json` or `yaml`) instead of the human-readable `text`, and `--worker-url` in case you want to have worker and component services at different locations.
60 |
61 | If you are using an open source specific `golem` - you should omit profile type (`golem`). If you are using a Golem Cloud specific `golem-cloud-cli` - you can't create an open source Golem profile.
62 |
63 | ## Profile authentication
64 |
65 | This section is specific to Golem Cloud.
66 |
67 | To authenticate your Golem Cloud profile, you can run any command that requires authentication, for example, any command that accesses Golem Cloud servers.
68 | The easiest way to authenticate your profile would be to run the following command:
69 |
70 | ```bash copy
71 | golem cloud account get
72 | ```
73 |
74 | At the moment, the only way to authenticate your account is to use GitHub OAuth2 authorization. Please follow the instructions in your terminal and authorize the ZivergeTech organization to use OAuth2:
75 |
76 | ```
77 | >>
78 | >> Application requests to perform OAuth2
79 | >> authorization.
80 | >>
81 | >> Visit following URL in a browser:
82 | >>
83 | >> ┏---------------------------------┓
84 | >> ┃ https://github.com/login/device ┃
85 | >> ┗---------------------------------┛
86 | >>
87 | >> And enter following code:
88 | >>
89 | >> ┏-----------┓
90 | >> ┃ ADFC-A318 ┃
91 | >> ┗-----------┛
92 | >>
93 | >> Code will expire in 14 minutes at 15:15:27.
94 | >>
95 | Waiting...
96 | Account with id account-id for name Your Name with email your@email.com.
97 | ```
98 |
99 | ## Switch profiles
100 |
101 | To get the list of your profiles use the following command:
102 |
103 | ```shell copy
104 | golem profile list
105 | ```
106 |
107 | You'll get all available profiles with the active profile marked by `*`:
108 |
109 | ```
110 | * my-oss-profile-name
111 | my-profile-name
112 | ```
113 |
114 | To switch the active profile, use the `profile switch` command:
115 |
116 | ```shell copy
117 | golem profile switch my-profile-name
118 | ```
119 |
120 | ## Golem profile configuration
121 |
122 | At the moment, the only configurable option is the default output format.
123 |
124 | To change the default output format for the current active profile, you can use the `profile config format` command as follows:
125 |
126 | ```shell copy
127 | golem profile config format text
128 | ```
129 |
130 | ### Output formats
131 |
132 | There are 3 output formats:
133 |
134 | - text - human-readable format
135 | - json
136 | - yaml
137 |
138 | Almost all commands can change the output format based on the `--format` option or the default output format configured for the current active profile.
139 |
140 | ## Profile configuration files
141 |
142 | All `golem` configuration files are stored in the `.golem` directory in your home directory. This includes the cached authentication token for your Golem Cloud profile.
143 | It is safe to remove the `$HOME/.golem` directory in case of any issues with profiles—you will keep access to your Golem Cloud account as long as you have access to your GitHub account linked to your Golem Cloud account.
144 |
--------------------------------------------------------------------------------
/src/pages/rest-api/login.mdx:
--------------------------------------------------------------------------------
1 | # Login API
2 | The login endpoints are implementing an OAuth2 flow.
3 | ## Acquire token with OAuth2 authorization
4 | Path|Method|Protected
5 | ---|---|---
6 | `/v1/oauth2`|POST|No
7 |
8 | Gets a token by authorizing with an external OAuth2 provider. Currently only github is supported.
9 |
10 | In the response:
11 | - `id` is the identifier of the token itself
12 | - `accountId` is the account's identifier, can be used on the account API
13 | - `secret` is the secret key to be sent in the Authorization header as a bearer token for all the other endpoints
14 |
15 |
16 | **Query Parameters**
17 |
18 | Name|Type|Required|Description
19 | ---|---|---|---
20 | provider|string|Yes|Currently only `github` is supported.
21 | access-token|string|Yes|OAuth2 access token
22 |
23 |
24 |
25 | **Example Response JSON**
26 |
27 | ```json copy
28 | {
29 | "data": {
30 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
31 | "accountId": "string",
32 | "createdAt": "2019-08-24T14:15:22Z",
33 | "expiresAt": "2019-08-24T14:15:22Z"
34 | },
35 | "secret": {
36 | "value": "a860a344-d7b2-406e-828e-8d442f23f344"
37 | }
38 | }
39 | ```
40 |
41 | ## Get information about a token
42 | Path|Method|Protected
43 | ---|---|---
44 | `/v1/login/token`|GET|Yes
45 |
46 | Gets information about a token that is selected by the secret key passed in the Authorization header.
47 | The JSON is the same as the data object in the oauth2 endpoint's response.
48 |
49 |
50 |
51 |
52 |
53 | **Example Response JSON**
54 |
55 | ```json copy
56 | {
57 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
58 | "accountId": "string",
59 | "createdAt": "2019-08-24T14:15:22Z",
60 | "expiresAt": "2019-08-24T14:15:22Z"
61 | }
62 | ```
63 |
64 | ## Start GitHub OAuth2 interactive flow
65 | Path|Method|Protected
66 | ---|---|---
67 | `/login/oauth2/device/start`|POST|No
68 |
69 | Starts an interactive authorization flow.
70 | The user must open the returned url and enter the userCode in a form before the expires deadline.
71 | Then the finish GitHub OAuth2 interactive flow endpoint must be called with the encoded session to finish the flow.
72 |
73 |
74 |
75 |
76 |
77 | **Example Response JSON**
78 |
79 | ```json copy
80 | {
81 | "url": "string",
82 | "userCode": "string",
83 | "expires": "2019-08-24T14:15:22Z",
84 | "encodedSession": "string"
85 | }
86 | ```
87 |
88 | ## Finish GitHub OAuth2 interactive flow
89 | Path|Method|Protected
90 | ---|---|---
91 | `/login/oauth2/device/complete`|POST|No
92 |
93 | Finishes an interactive authorization flow. The returned JSON is equivalent to the oauth2 endpoint's response.
94 | Returns a JSON string containing the encodedSession from the start endpoint's response.
95 |
96 |
97 |
98 | **Example Request JSON**
99 | ```json copy
100 | "string"
101 | ```
102 |
103 | **Example Response JSON**
104 |
105 | ```json copy
106 | {
107 | "data": {
108 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
109 | "accountId": "string",
110 | "createdAt": "2019-08-24T14:15:22Z",
111 | "expiresAt": "2019-08-24T14:15:22Z"
112 | },
113 | "secret": {
114 | "value": "a860a344-d7b2-406e-828e-8d442f23f344"
115 | }
116 | }
117 | ```
118 |
119 | ## Initiate OAuth2 Web Flow
120 | Path|Method|Protected
121 | ---|---|---
122 | `/v1/login/oauth2/web/authorize`|GET|No
123 |
124 | Starts the OAuth2 web flow authorization process by returning the authorization URL for the given provider.
125 |
126 | **Query Parameters**
127 |
128 | Name|Type|Required|Description
129 | ---|---|---|---
130 | provider|string|Yes|Currently only `github` is supported.
131 | redirect|string|No|The redirect URL to redirect to after the user has authorized the application
132 |
133 |
134 |
135 | **Example Response JSON**
136 |
137 | ```json copy
138 | {
139 | "url": "string",
140 | "state": "string"
141 | }
142 | ```
143 |
144 | ## GitHub OAuth2 Web Flow callback
145 | Path|Method|Protected
146 | ---|---|---
147 | `/v1/login/oauth2/web/callback/github`|GET|No
148 |
149 | This endpoint handles the callback from GitHub after the user has authorized the application.
150 | It exchanges the code for an access token and then uses that to log the user in.
151 |
152 | **Query Parameters**
153 |
154 | Name|Type|Required|Description
155 | ---|---|---|---
156 | code|string|Yes|The authorization code returned by GitHub
157 | state|string|Yes|The state parameter for CSRF protection
158 |
159 |
160 |
161 | **Example Response JSON**
162 |
163 | ```json copy
164 | {}
165 | ```
166 |
167 | ## Poll for OAuth2 Web Flow token
168 | Path|Method|Protected
169 | ---|---|---
170 | `/v1/login/oauth2/web/poll`|GET|No
171 |
172 | This endpoint is used by clients to poll for the token after the user has authorized the application via the web flow.
173 |
174 | **Query Parameters**
175 |
176 | Name|Type|Required|Description
177 | ---|---|---|---
178 | state|string|Yes|The state parameter for identifying the session
179 |
180 |
181 |
182 | **Example Response JSON**
183 |
184 | ```json copy
185 | {
186 | "data": {
187 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
188 | "accountId": "string",
189 | "createdAt": "2019-08-24T14:15:22Z",
190 | "expiresAt": "2019-08-24T14:15:22Z"
191 | },
192 | "secret": {
193 | "value": "a860a344-d7b2-406e-828e-8d442f23f344"
194 | }
195 | }
196 | ```
197 | ## Login API Errors
198 | Status Code|Description|Body
199 | ---|---|---
200 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
201 | 401|Unauthorized request|`{"error":"string"}`
202 | 403|Forbidden Request|`{"error":"string"}`
203 | 404|Entity not found|`{"error":"string"}`
204 | 409||`{"error":"string"}`
205 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/src/pages/develop/promises.mdx:
--------------------------------------------------------------------------------
1 | import {Callout, Tabs} from "nextra/components"
2 |
3 | # Working with Golem Promises
4 |
5 | Golem **promises** provide a way for Golem agents to wait for an external condition. The agent creates the promise and somehow sends its identifier to the external system responsible for **completing** the promise. Then the agent can **await** the promise, being suspended until the external system completes the promise using Golem's REST API.
6 |
7 | It is also possible to complete a promise from within a Golem agent using the Golem SDK, which is especially useful when used together with [forking](/develop/forking).
8 |
9 | When a promise is completed, an arbitrary byte array can be attached to it as a payload; this data is returned to the awaiting agent when it continues execution.
10 |
11 | ### Creating a promise
12 |
13 |
14 |
15 | To create a promise simply call the `createPromise` function:
16 |
17 | ```typescript
18 | import {createPromise, PromiseId} from "@golemcloud/golem-ts-sdk"
19 |
20 | const promiseId: PromiseId = createPromise()
21 | ```
22 |
23 |
24 | To create a promise simply call the `create_promise` function:
25 |
26 | ```rust
27 | use golem_rust::bindings::golem::api::host::create_promise;
28 |
29 | let promise_id: PromiseId = create_promise()
30 | ```
31 |
32 |
33 |
34 | The returned value has the type `PromiseId`, and defined as the following (including the nested types):
35 |
36 |
37 |
38 | ```typescript
39 | export type OplogIndex = bigint
40 |
41 | export interface Uuid {
42 | highBits: bigint
43 | lowBits: bigint
44 | }
45 |
46 | // Represents a Component
47 | export interface ComponentId {
48 | uuid: Uuid
49 | }
50 |
51 | // Represents an agent
52 | export interface AgentId {
53 | componentId: ComponentId
54 | agentId: string
55 | }
56 |
57 | // A promise ID is a value that can be passed to an external Golem API to complete that promise
58 | // from an arbitrary external source, while Golem agents can await for this completion.
59 | export interface PromiseId {
60 | agentId: AgentId
61 | oplogIdx: OplogIndex
62 | }
63 | ```
64 |
65 |
66 |
67 | ```rust
68 | pub type OplogIndex = u64;
69 |
70 | pub struct Uuid {
71 | high_bits: u64
72 | low_bits: u64
73 | }
74 |
75 | // Represents a Component
76 | pub struct ComponentId {
77 | uuid: Uuid
78 | }
79 |
80 | // Represents an agent
81 | pub struct AgentId {
82 | component_id: ComponentId
83 | agent_id: string
84 | }
85 |
86 | // A promise ID is a value that can be passed to an external Golem API to complete that promise
87 | // from an arbitrary external source, while Golem agents can await for this completion.
88 | pub struct PromiseId {
89 | pub agent_id: AgentId,
90 | pub oplog_idx: OplogIndex,
91 | }
92 | ```
93 |
94 |
95 |
96 | ### Awaiting a promise
97 |
98 | To await a promise, use the async `awaitPromise` function, which returns the promise result as a byte array payload.
99 | Here's an example that awaits a promise, then decodes the payload from JSON format:
100 |
101 |
102 |
103 | ```typescript
104 | import { awaitPromise, PromiseId } from "@golemcloud/golem-ts-sdk"
105 |
106 | const byteArrayPayload: Uint8Array = await awaitPromise(promiseId)
107 | const payload = JSON.parse(new TextDecoder().decode(byteArrayPayload))
108 | ```
109 |
110 |
111 | ```rust
112 | use golem_rust::await_promise_json;
113 | use serde::{Serialize, Deserialize}
114 |
115 | #[derive(Serialize, Deserialize)]
116 | struct MyPayload {
117 | id: String,
118 | }
119 |
120 | const payload: MyPayload = await_promise_json(&promise_id);
121 | ```
122 |
123 |
124 |
125 | Note that if an agent is only **awaiting** Golem promises (one or more), the agent gets suspended and is not going to consume any resources while waiting.
126 |
127 | ### Completing a promise from within an agent
128 |
129 |
130 |
131 | To complete a promise from within an agent, use the `completePromise` function.
132 | The following example completes a promise with a value encoded as JSON:
133 |
134 | ```typescript
135 | import { completePromise, PromiseId } from "@golemcloud/golem-ts-sdk"
136 |
137 | const payload = {
138 | id: "value",
139 | meta: "data",
140 | }
141 | const byteArrayPayload: Uint8Array = new TextEncoder().encode(JSON.stringify(payload))
142 | const success: boolean = completePromise(promiseId, byteArrayPayload)
143 | ```
144 |
145 |
146 | To complete a promise from within an agent, use the `complete_promise` function.
147 |
148 | ```rust
149 | use golem_rust::bindings::golem::api::host::{PromiseId};
150 | use golem_rust::complete_promise_json;
151 | use serde::Serialize;
152 |
153 | #[derive(Serialize)]
154 | struct Data {
155 | id: String,
156 | meta: String,
157 | }
158 |
159 | let data = Data {
160 | id: "value".to_string(),
161 | meta: "data".to_string(),
162 | };
163 |
164 | let result: Result = complete_promise_json(&promise_id, data);
165 | ```
166 |
167 |
168 |
169 | ### Completing a promise from an external source
170 |
171 | To see how to use the **promise ID** to complete a promise through the external REST API, check [the REST API documentation](/rest-api/worker#complete-a-promise).
172 |
--------------------------------------------------------------------------------
/src/pages/operate/persistence.mdx:
--------------------------------------------------------------------------------
1 | # Persistence
2 |
3 | ## Introduction
4 |
5 | The Golem Worker Executor uses a set of storage layers for persisting worker state and everything related to the execution of workers. This page gives an overview of what is stored where, as well as some pointers for extending Golem OSS with new storage implementations.
6 |
7 | ## Storage types
8 |
9 | The worker executor requires three types of storage backends:
10 |
11 | - A **blob storage** for storing and retrieving arbitrary sized binary blobs
12 | - A **key-value storge** with some extra requirements for set/sorted-set-like operations
13 | - An **indexed storage** for an append-only, indexable store for agent's operation log (oplog)
14 |
15 | Currently Golem provides the following implementations, configurable through the worker executor's config file:
16 |
17 | | Storage type | Implementations |
18 | | ------------------ | -------------------------- |
19 | | Blob storage | S3, file system, in-memory |
20 | | Key-values storage | Redis, in-memory |
21 | | Indexed storage | Redis (streams), in-memory |
22 |
23 | ## Compilation cache
24 |
25 | The Golem **component service** stores the component WASM files in its own storage layer (configured to be either S3 or a persistent volume) and exposes them through its [download API](/rest-api/component) for the worker executor. The WASM files need to be **compiled** to native code before execution, which is a time-consuming task. To reduce the time required for instantiating agents, these compiled binaries are cached in the worker executor's **blob storage**.
26 |
27 | The **component compilation service** is a special, horizontally scalable component of the Golem system which shares this storage with worker executors and is capable of precompiling components before they are being used by any of the executors.
28 |
29 | ## Oplog
30 |
31 | Running agents continuously persist operations into the worker's **oplog**. The oplog is append-only (persisted entries are never modified) and it is indexable (during the recovery of an agent it is read from the earliest entry to the latest one).
32 | The oplog is stored in multiple configurable layers. The default configuration is the following:
33 |
34 | - The **primary oplog layer** uses the **indexed storage**. This is the one where running agent's entries are appended to
35 | - There is a **secondary layer** that is also persisted to the **indexed storage**, but on this level each entry holds a compressed set of oplog entries.
36 | - A **tertiary layer** holds even larger chunks of compressed oplog entries and stores them in the **blob storage**.
37 |
38 | Oplogs are continuously moved towards the lower layers to prevent the primary oplog storage (Redis) from getting full. Agents which were not active for a while are fully stored in the blob storage only.
39 |
40 | In addition to the above, there are oplog entries holding user-defined data (such as invocation parameters). As these user-defined payloads can have an arbitrary size, the worker executor has to protect its storage layer against putting too large entries into the primary oplog. For this reason large payloads are written to the **blob storage** and the corresponding oplog entry only stores a reference to them. Payloads below a configurable limit are stored inline in the oplog entry.
41 |
42 | ### Configuration
43 |
44 | The `[oplog]` section of the worker executor configuration allows customizing the above described behavior.
45 |
46 | The default configuration is the following:
47 |
48 | ```toml
49 | [oplog]
50 | archive_interval = "1day"
51 | blob_storage_layers = 1
52 | entry_count_limit = 1024
53 | indexed_storage_layers = 2
54 | max_operations_before_commit = 128
55 | max_payload_size = 65536
56 | ```
57 |
58 | These options have the following meaning:
59 |
60 | | Option | Description |
61 | | ------------------------------ | ------------------------------------------------------------------------------------------------------- |
62 | | `archive_interval` | The period after the old sections of the oplog get moved to one layer down in the layered oplog storage |
63 | | `blob_storage_layers` | The number of archive layers using the **blob storage** |
64 | | `indexed_storage_layers` | The total number of layers (one primary + archives) using the **indexed storage** |
65 | | `entry_count_limit` | The number of oplog entries triggering the archivation of a chunk to the lower oplog layer |
66 | | `max_operations_before_commit` | The number of non-critical oplog entries that can be buffered before committed to the oplog |
67 | | `max_payload_size` | The maximum size of user-defined payloads that can be stored inline in an oplog entry |
68 |
69 | ## Worker metadata
70 |
71 | The **oplog** is the primary source of truth for everything we need to store about an agent, but for performance reasons the **key value store** is also used to store aggregated agent metadata for agents. This metadata is not always completely up-to-date; it store the last oplog index it was calculated from, and its latest version can be reproduced by reading and processing the newer oplog entries. For agents which has no longer data in the primary oplog, we don't store agent metadata either. When these agents have to be recovered, their metadata is reconstructed by reading the whole archived oplog.
72 |
73 | ## Promises and schedules
74 |
75 | The worker executor also stores **promise information** in its **key-value storage**. This is simply an entry for each created Golem promise, storing it's completion state. Internally Golem also uses scheduled promise completion (for example for waking up agents after long sleeps). These scheduled events are also stored in the **key-value storage**.
76 |
77 | ## WASI Blob store and Key Value store
78 |
79 | Golem implements (partially) the [WASI Blob Store](https://github.com/WebAssembly/wasi-blobstore) and [WASI Key-Value Store](https://github.com/WebAssembly/wasi-keyvalue) proposals. These interfaces allow agents to store blobs and key-value data in the worker executor's configured **blob storage** and **key-value storage** layers.
80 |
81 | ## Adding new storage implementations
82 |
83 | The open-source version of Golem can be easily extended to support alternative databases than the built-in Redis and S3 implementations. Take a look at the following traits:
84 |
85 | - [`BlobStorage`](https://github.com/golemcloud/golem/blob/main/golem-worker-executor-base/src/storage/blob/mod.rs)
86 | - [`KeyValueStorage`](https://github.com/golemcloud/golem/blob/main/golem-worker-executor-base/src/storage/keyvalue/mod.rs)
87 | - [`IndexedStorage`](https://github.com/golemcloud/golem/blob/main/golem-worker-executor-base/src/storage/indexed/mod.rs)
88 |
--------------------------------------------------------------------------------
/src/pages/why-golem.mdx:
--------------------------------------------------------------------------------
1 | ## Why Golem?
2 |
3 | **Because agents are distributed systems.**
4 |
5 | Most "agent frameworks" stop at prompt chaining. Real agents run for minutes to months, cross many tools and APIs, pause for people, and must never lose state or double-fire.
6 |
7 | Golem is an agent-native runtime that gives you durability, exactly-once effects, full observability, and suspend-to-zero — without the need to build queues, schedulers, or idempotency plumbing.
8 |
9 | ## What You Get (Day One)
10 |
11 | ### Production Guarantees Built In
12 |
13 | - **Durable state:** After a crash or restart, an agent resumes at the last successful point—no lost context or rework.
14 |
15 | - **Exactly-once external effects:** Retries won't double-charge cards, re-open tickets, or post duplicate webhooks.
16 |
17 | - **Durable internal delivery:** Agent-to-agent messages are persisted and delivered once.
18 |
19 | - **Suspend & resume:** Park idle agents (human approval, scheduled wake, long waits) at zero compute; resume instantly.
20 |
21 | - **Automatic recovery & back-off:** Transient failures are retried to policy; agents are rescheduled on healthy nodes.
22 |
23 | - **Isolation & permissions:** Per-agent sandboxes and scoped capabilities prevent cross-talk or privilege bleed.
24 |
25 | - **Observability with rewind:** Inspect the full history of prompts, tools, and data and replay safely—no duplicate effects.
26 |
27 | - **Zero-downtime upgrades:** Run versions side-by-side or migrate live agents forward.
28 |
29 | ### The Code You Write; The Runtime You Don't
30 |
31 | Use normal TypeScript to write agents and tools. Beneath it, Golem runs a complete runtime—persistence, exactly-once I/O, observability, autoscaling, isolation, and safe upgrades—so your agents survive reality without bespoke infra.
32 |
33 | ## What You Stop Building
34 |
35 | - Durable queues & outboxes
36 | - Idempotency keys & dedupe logic
37 | - Cron catch-ups & retry schedulers
38 | - Long-poll loops & timeout workarounds
39 | - Ad-hoc audit logs & incident recon tooling
40 | - DIY "workflow engines" glued to lambdas
41 |
42 | > Frameworks chain steps; Golem makes those steps durable, replayable, and exactly-once.
43 |
44 | ## Where Golem Shines
45 |
46 | ### Use Cases
47 |
48 | - **Human-in-the-Loop Workflows**
49 | Agents pause for review, capture the outcome, and resume with full state—no repeated actions.
50 |
51 | - **Intelligent Incident Response**
52 | Investigate, coordinate remediation, and escalate without losing track or duplicating fixes.
53 |
54 | - **Reliable Data & Transactions Across Systems**
55 | Synchronize CRMs/ERPs/APIs/payments with exactly-once guarantees.
56 |
57 | - **Personalized Content & Offers at Scale**
58 | Assemble and deliver tailored experiences with no duplicates or misses—even during spikes.
59 |
60 | - **Multi-Agent Research & Analysis**
61 | Collaborating agents that run for hours to weeks, preserving context and avoiding re-work.
62 |
63 | - **Continuous Risk Monitoring & Alerting**
64 | Real-time detection and actions without false repeats or missed alerts.
65 |
66 | *If your workflows are long-running, stateful, cross many tools, or HITL, Golem turns fragile prototypes into production-grade agents.*
67 |
68 | ## Is Golem a Fit for You?
69 |
70 | ### ✅ Strong Fit If You Need:
71 |
72 | - Agents that must never lose progress or repeat side-effects
73 | - HITL pauses, external API waits, or long-tail tasks (minutes → months)
74 | - Auditable execution with full traces of prompts, tools, and data
75 | - Multi-agent coordination with guaranteed messaging
76 | - To ship now without building durable infra yourself
77 |
78 | ### ❌ Probably Not a Fit Right Now If:
79 |
80 | - Your app is stateless or completes in a single request/response
81 | - You only need a prompt library or a light orchestration DSL and reliability doesn't matter to you
82 | - You require a programming language other than TypeScript today (more languages are on the way)
83 | - You already run on a durable runtime that guarantees exactly-once and you're satisfied with its ops/tooling
84 |
85 | *Our goal is to help you decide quickly — even if the answer is "not yet."*
86 |
87 | ## How Golem Fits Your Stack
88 |
89 | 1. **Build** agents and tools in TypeScript.
90 | 2. **Grant** capabilities (APIs, tools, other agents).
91 | 3. **Deploy** agent types to the runtime.
92 | 4. **Trigger** via secure APIs; send commands or messages.
93 | 5. **Observe** execution with searchable traces and safe replay.
94 |
95 | **Interop:** Agents call your services over HTTP under exactly-once mediation. Connect tools (including MCP) and other agents with durable delivery. Start with one use case; retire bespoke queues and schedulers over time.
96 |
97 | ## Why a Runtime (Not Just a Library)?
98 |
99 | Libraries help you write flows; runtimes keep them correct under failures, retries, and upgrades.
100 |
101 | - **Failure semantics:** Exactly-once effects and durable delivery are properties of the runtime, not application glue.
102 | - **State correctness:** Snapshots + durable logs let agents resume exactly where they left off.
103 | - **Operate at scale:** Millions of agents can suspend to zero and wake as events arrive—without cost spikes.
104 | - **Debug the truth:** Full, replayable traces beat partial logs stitched across services.
105 |
106 | If you like, use your favorite agent libraries for control flow; but run them on Golem for durability and correctness.
107 |
108 | ## What Changes in Your Day-to-Day
109 |
110 | - Fewer incidents about "what ran twice?" or "where did we lose state?"
111 | - Faster iteration—upgrade logic without draining in-flight agents
112 | - Straight-line agent code instead of scattered jobs and compensations
113 | - Real root-cause analysis at 2 a.m. with full, searchable history
114 |
115 | ## FAQs
116 |
117 | **Do I have to re-write everything?**
118 |
119 | No. Start by running the stateful, failure-sensitive parts of your agents on Golem. Keep your existing APIs and data stores.
120 |
121 | **What languages are supported?**
122 |
123 | TypeScript today, with more languages on the way.
124 |
125 | **How does Golem prevent duplicate effects?**
126 |
127 | An I/O gateway mediates external calls with durable logs and idempotent commits to ensure exactly-once behavior—even under retries and failover.
128 |
129 | **Can agents pause for humans or slow APIs?**
130 |
131 | Yes. Agents suspend & resume with full state intact and zero compute while waiting.
132 |
133 | ## Next Steps
134 |
135 | - Check the [Quickstart](/quickstart) guide to learn how to install and build your first Golem agent
136 | - Explore the [Develop](/develop) section to learn in details how to write Golem agents
137 | - The [Usage](/usage) section contains detailed information about deploying, invoking and debugging agents, using the command line interface and more.
138 |
139 | ---
140 |
141 | **Agents that don't forget. Actions that don't repeat.**
142 | *Ship agents you can trust—without rebuilding distributed systems infrastructure.*
--------------------------------------------------------------------------------
/src/pages/rest-api/project.mdx:
--------------------------------------------------------------------------------
1 | # Project API
2 | Projects are groups of components and their workers, providing both a separate namespace for these entities and allows sharing between accounts.
3 |
4 | Every account has a default project which is assumed when no specific project ID is passed in some component and worker related APIs.
5 | ## Get the default project
6 | Path|Method|Protected
7 | ---|---|---
8 | `/v1/projects/default`|GET|Yes
9 |
10 | - name of the project can be used for lookup the project if the ID is now known
11 | - defaultEnvironmentId is currently always default
12 | - projectType is either Default
13 |
14 |
15 |
16 |
17 |
18 | **Example Response JSON**
19 |
20 | ```json copy
21 | {
22 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
23 | "projectData": {
24 | "name": "string",
25 | "ownerAccountId": "string",
26 | "description": "string",
27 | "defaultEnvironmentId": "string",
28 | "projectType": "Default"
29 | }
30 | }
31 | ```
32 |
33 | ## List all projects
34 | Path|Method|Protected
35 | ---|---|---
36 | `/v1/projects`|GET|Yes
37 |
38 | Returns all projects of the account if no project-name is specified.
39 | Otherwise, returns all projects of the account that has the given name.
40 | As unique names are not enforced on the API level, the response may contain multiple entries.
41 |
42 | **Query Parameters**
43 |
44 | Name|Type|Required|Description
45 | ---|---|---|---
46 | project-name|string|No|Filter by project name
47 |
48 |
49 |
50 | **Example Response JSON**
51 |
52 | ```json copy
53 | [
54 | {
55 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
56 | "projectData": {
57 | "name": "string",
58 | "ownerAccountId": "string",
59 | "description": "string",
60 | "defaultEnvironmentId": "string",
61 | "projectType": "Default"
62 | }
63 | }
64 | ]
65 | ```
66 |
67 | ## Create project
68 | Path|Method|Protected
69 | ---|---|---
70 | `/v1/projects`|POST|Yes
71 |
72 | Creates a new project. The ownerAccountId must be the caller's account ID.
73 |
74 |
75 |
76 | **Example Request JSON**
77 | ```json copy
78 | {
79 | "name": "string",
80 | "ownerAccountId": "string",
81 | "description": "string"
82 | }
83 | ```
84 |
85 | **Example Response JSON**
86 |
87 | ```json copy
88 | {
89 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
90 | "projectData": {
91 | "name": "string",
92 | "ownerAccountId": "string",
93 | "description": "string",
94 | "defaultEnvironmentId": "string",
95 | "projectType": "Default"
96 | }
97 | }
98 | ```
99 |
100 | ## Get project by ID
101 | Path|Method|Protected
102 | ---|---|---
103 | `/v1/projects/{project_id}`|GET|Yes
104 |
105 | Gets a project by its identifier. Response is the same as for the default project.
106 |
107 |
108 |
109 |
110 |
111 | **Example Response JSON**
112 |
113 | ```json copy
114 | {
115 | "projectId": "5a8591dd-4039-49df-9202-96385ba3eff8",
116 | "projectData": {
117 | "name": "string",
118 | "ownerAccountId": "string",
119 | "description": "string",
120 | "defaultEnvironmentId": "string",
121 | "projectType": "Default"
122 | }
123 | }
124 | ```
125 |
126 | ## Delete project
127 | Path|Method|Protected
128 | ---|---|---
129 | `/v1/projects/{project_id}`|DELETE|Yes
130 |
131 | Deletes a project given by its identifier.
132 |
133 |
134 |
135 |
136 |
137 | **Example Response JSON**
138 |
139 | ```json copy
140 | {}
141 | ```
142 |
143 | ## Get project actions
144 | Path|Method|Protected
145 | ---|---|---
146 | `/v1/projects/{project_id}/actions`|GET|Yes
147 |
148 | Returns a list of actions that can be performed on the project.
149 |
150 |
151 |
152 |
153 |
154 | **Example Response JSON**
155 |
156 | ```json copy
157 | [
158 | "ViewComponent"
159 | ]
160 | ```
161 |
162 | ## Gets the list of plugins installed for the given project
163 | Path|Method|Protected
164 | ---|---|---
165 | `/v1/projects/{project_id}/plugins/installs`|GET|Yes
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 | **Example Response JSON**
174 |
175 | ```json copy
176 | [
177 | {
178 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
179 | "pluginName": "string",
180 | "pluginVersion": "string",
181 | "pluginRegistered": true,
182 | "priority": 0,
183 | "parameters": {
184 | "property1": "string",
185 | "property2": "string"
186 | }
187 | }
188 | ]
189 | ```
190 |
191 | ## Installs a new plugin for this project
192 | Path|Method|Protected
193 | ---|---|---
194 | `/v1/projects/{project_id}/plugins/installs`|POST|Yes
195 |
196 |
197 |
198 |
199 |
200 | **Example Request JSON**
201 | ```json copy
202 | {
203 | "name": "string",
204 | "version": "string",
205 | "priority": 0,
206 | "parameters": {
207 | "property1": "string",
208 | "property2": "string"
209 | }
210 | }
211 | ```
212 |
213 | **Example Response JSON**
214 |
215 | ```json copy
216 | {
217 | "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
218 | "pluginName": "string",
219 | "pluginVersion": "string",
220 | "pluginRegistered": true,
221 | "priority": 0,
222 | "parameters": {
223 | "property1": "string",
224 | "property2": "string"
225 | }
226 | }
227 | ```
228 |
229 | ## Updates the priority or parameters of a plugin installation
230 | Path|Method|Protected
231 | ---|---|---
232 | `/v1/projects/{project_id}/plugins/installs/{installation_id}`|PUT|Yes
233 |
234 |
235 |
236 |
237 |
238 | **Example Request JSON**
239 | ```json copy
240 | {
241 | "priority": 0,
242 | "parameters": {
243 | "property1": "string",
244 | "property2": "string"
245 | }
246 | }
247 | ```
248 |
249 | **Example Response JSON**
250 |
251 | ```json copy
252 | {}
253 | ```
254 |
255 | ## Uninstalls a plugin from this project
256 | Path|Method|Protected
257 | ---|---|---
258 | `/v1/projects/{project_id}/latest/plugins/installs/{installation_id}`|DELETE|Yes
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 | **Example Response JSON**
267 |
268 | ```json copy
269 | {}
270 | ```
271 |
272 | ## Applies a batch of changes to the installed plugins of a component
273 | Path|Method|Protected
274 | ---|---|---
275 | `/v1/projects/{project_id}/latest/plugins/installs/batch`|POST|Yes
276 |
277 |
278 |
279 |
280 |
281 | **Example Request JSON**
282 | ```json copy
283 | {
284 | "actions": [
285 | {
286 | "type": "Install",
287 | "name": "string",
288 | "version": "string",
289 | "priority": 0,
290 | "parameters": {
291 | "property1": "string",
292 | "property2": "string"
293 | }
294 | }
295 | ]
296 | }
297 | ```
298 |
299 | **Example Response JSON**
300 |
301 | ```json copy
302 | {}
303 | ```
304 | ## Project API Errors
305 | Status Code|Description|Body
306 | ---|---|---
307 | 400|Invalid request, returning with a list of issues detected in the request|`{"errors":["string"]}`
308 | 401|Unauthorized request|`{"error":"string"}`
309 | 403|Forbidden Request|`{"error":"string"}`
310 | 404|Entity not found|`{"error":"string"}`
311 | 409||`{"error":"string"}`
312 | 500|Internal server error|`{"error":"string"}`
--------------------------------------------------------------------------------
/src/pages/develop/durability.mdx:
--------------------------------------------------------------------------------
1 | import { Tabs } from "nextra/components"
2 |
3 | # Control durability guarantees
4 |
5 | Golem provides a set of functions components can call to control details of the durable execution engine.
6 |
7 | ### General concepts
8 |
9 | The library allows controlling four main aspects of the durable execution engine: the current persistence level, the idempotence mode, defining atomic regions and changing retry policies (discussed in [the next page](/develop/retries)).
10 |
11 | All these features are regional - they can be changed for a section of the code within a single exported function.
12 |
13 |
14 |
15 | To make this easy to use in TypeScript, the library provides functions starting with `with`, they take a closure
16 | parameter which will be executed with the requested mode, and then they restore the previous settings.
17 |
18 |
19 | `golem_rust` library provides functions starting with `with`, they take a closure
20 | parameter which will be executed with the requested mode, and then they restore the previous settings.
21 |
22 |
23 |
24 | ### Persistence level
25 |
26 | The persistence level can be one of the following:
27 |
28 | | Level | Description |
29 | |--------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
30 | | PersistNothing | Turns off persistence for a section. In case the agent is recovered or restarted, all the side-effecting functions will be reexecuted |
31 | | PersistRemoteSideEffects | Persists all the side-effects that are affecting the outside world. In case of recovery the side-effects won't be reexecuted and the persisted results will be used. |
32 | | Smart | The default setting; Let Golem decide what to persist to optimize performance |
33 |
34 |
35 |
36 | To change the persistence level for a section of the code, use the `withPersistenceLevel` function:
37 |
38 | ```typescript
39 | import {withPersistenceLevel} from "@golemcloud/golem-ts-sdk"
40 |
41 | const result: string = withPersistenceLevel({tag: "persist-nothing"}, () => {
42 | // this closure runs in PersistNothing mode
43 | return "hello"
44 | })
45 | ```
46 |
47 |
48 | To change the persistence level for a section of the code, use the `with_persistance_level` function:
49 |
50 | ```rust
51 | use golem_rust::{PersistenceLevel, with_persistence_level}
52 |
53 | let result = with_persistence_level(PersistenceLevel::PersistNothing, || {
54 | // this block run in PersistNothing mode
55 | "hello"
56 | });
57 |
58 | ```
59 |
60 |
61 |
62 | ### Idempotence mode
63 |
64 | Golem assumes that HTTP requests are idempotent by default. This means that in case of a failure, if the system cannot determine whether the request successfully reached the target or not, it will be retried.
65 |
66 |
67 |
68 | This behavior can be changed using the `withIdempotenceMode` function:
69 |
70 | ```typescript
71 | import {withIdempotenceMode} from "@golemcloud/golem-ts-sdk"
72 |
73 | const result: string = withIdempotenceMode(false, () => {
74 | // this closure runs with idempotence mode disabled
75 | return "hello"
76 | })
77 | ```
78 |
79 |
80 | This behavior can be changed using the `withIdempotenceMode` function:
81 |
82 | ```typescript
83 | use golem_rust::with_idempotence_mode;
84 |
85 | let result = with_idempotence_mode(false, || {
86 | // this block runs with idempotence mode disabled
87 | "hello"
88 | });
89 | ```
90 |
91 |
92 |
93 | With disabled idempotence mode, in case Golem cannot determine if the request was sent or not, it won't retry it, but the agent will fail.
94 |
95 | ### Atomic regions
96 |
97 | By default, side effects are persisted and retried one by one. It is possible to group them together into atomic regions, in which case the execution is retried for some reason (the agent failed or interrupted within the region), all the side effects will be reexecuted.
98 |
99 |
100 |
101 | The `golem-ts-sdk` library exports the `atomically` function for using atomic regions:
102 |
103 | ```typescript
104 | import {atomically} from "@golemcloud/golem-ts-sdk"
105 |
106 | const result: [string, string] = atomically(() => {
107 | const firstResult: string = firstSideEffect()
108 | const secondResult: string = secondSideEffect(firstResult)
109 | return [firstResult, secondResult]
110 | })
111 | ```
112 |
113 |
114 | The `golem-ts-sdk` library exports the `atomically` function for using atomic regions:
115 |
116 | ```rust
117 | use golem_rust::atomically;
118 |
119 | let result = atomically(|| {
120 | let first_result = first_side_effect();
121 | let second_result = second_side_effect();
122 | (first_result, second_result)
123 | });
124 | ```
125 |
126 |
127 |
128 |
129 | ### Commit oplog
130 |
131 |
132 |
133 | The `oplogCommit` function in `"@golemcloud/golem-ts-sdk` waits until the oplog is committed to its persistent
134 | storage. The function takes a single argument, `replicas`, with the desired number of storage replicas the
135 | agent's journal is replicated to. The function will block until the oplog is committed to the specified number
136 | of replicas, or, if this number is larger than the available number of replicas, until it is written to all the
137 | replicas.
138 |
139 |
140 | The `oplog_commit` function in `golem_rust` waits until the oplog is committed to its persistent
141 | storage. The function takes a single argument, `replicas`, with the desired number of storage replicas the
142 | agent's journal is replicated to. The function will block until the oplog is committed to the specified number
143 | of replicas, or, if this number is larger than the available number of replicas, until it is written to all the
144 | replicas.
145 |
146 |
--------------------------------------------------------------------------------
/src/pages/cli/components.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 |
3 | # Golem CLI Components
4 |
5 | Golem components are WASM components deployed to Golem for execution.
6 |
7 | To create, list, build and deploy components you can use `golem component` command.
8 |
9 | ## Creating a new component
10 |
11 | To create a new component in an application directory (previously created with `golem app new`) use the `component new` command in the following way:
12 |
13 | ```shell copy
14 | golem component new
15 | ```
16 |
17 | To see all the available component templates, just run the command without providing one.
18 |
19 | This command only modifies the source code of the application, does not create anything on the server.
20 |
21 | ## Building a component
22 |
23 | To build a component, use the `component build` command in the following way:
24 |
25 | ```shell copy
26 | golem component build
27 | ```
28 |
29 | To build the whole application, use the `app build` command in the following way:
30 |
31 | ```shell copy
32 | golem app build
33 | ```
34 |
35 | Both commands accept a `--build-profile ` argument. Some of the built-in templates define a separate `release` profile which creates a more optimized version of the components. Build profiles can be fully customized by editing the _application manifest files_.
36 |
37 | ## Deploying a component
38 |
39 | To deploy a component, use the `component deploy` or `app deploy` commands in the following way:
40 |
41 | ```shell copy
42 | golem component deploy
43 | ```
44 | or
45 |
46 | ```shell copy
47 | golem app deploy
48 | ```
49 |
50 | to deploy a specific component only.
51 |
52 | The output of the command will be something like the following:
53 | ```
54 | New component created with URN urn:component:d8bc9194-a4a2-4a57-8545-43408fc38799, version 0, and size of 89735 bytes.
55 | Component name: my-component.
56 | Exports:
57 | rpc:counters/api.{[constructor]counter}(name: string) -> handle<0>
58 | rpc:counters/api.{[method]counter.inc-by}(self: &handle<0>, value: u64)
59 | rpc:counters/api.{[method]counter.get-value}(self: &handle<0>) -> u64
60 | rpc:counters/api.{[method]counter.get-args}(self: &handle<0>) -> list
61 | rpc:counters/api.{[method]counter.get-env}(self: &handle<0>) -> list>
62 | rpc:counters/api.{inc-global-by}(value: u64)
63 | rpc:counters/api.{get-global-value}() -> u64
64 | rpc:counters/api.{get-all-dropped}() -> list>
65 | rpc:counters/api.{bug-wasm-rpc-i32}(in: variant { leaf }) -> variant { leaf }
66 | rpc:counters/api.{[drop]counter}(self: handle<0>)
67 | ```
68 |
69 | The returned output contains the following information:
70 |
71 | - **Component URN** - URN for the new component. You can use this URN whenever you want to specify the component instead of component name.
72 | - **Component version** - incremental component version - used for updating the agents.
73 | - **Component size** - size of the `wasm` file - it is important for the storage limit in the hosted Golem Cloud.
74 | - **Exports** - exported function you can call. You can copy function name (the part before parameters) to call the function. All Golem API expect function names in exactly this format. See the [name mapping page](/name-mapping) for more details.
75 |
76 | To deploy **all components** of an application, use:
77 |
78 | ```shell copy
79 | golem app deploy
80 | ```
81 |
82 | To deploy the **component** based on the current directory, use:
83 |
84 | ```shell copy
85 | golem component deploy
86 | ```
87 |
88 | ### Ephemeral components
89 |
90 | Components created are **durable** by default. To create an **ephemeral component** instead, change the component's application manifest (`golem.yaml`) to contain:
91 |
92 | ```yaml
93 | components:
94 | example:component:
95 | componentType: ephemeral
96 | ```
97 |
98 | ## Component search
99 |
100 | ### Using component name and the latest version
101 |
102 | If you want to get the latest version of the component using its name you can you can use the `component get` command.
103 |
104 | ```shell copy
105 | golem get example:component
106 | ```
107 |
108 | ### Using component name and specific version
109 |
110 | To get a specific version of a component, just pass the desired version number as well:
111 |
112 | ```shell copy
113 | golem get example:component 2
114 | ```
115 |
116 | ### Getting component list
117 |
118 | To get all component versions for specific component name you can use `component list` command with a given component name. Note if you are in a component's source directory, the command will automatically list that component's versions.
119 |
120 | ```shell copy
121 | golem component list example:component
122 | ```
123 |
124 | To get all component available you can use `component list` command this way:
125 |
126 | ```shell copy
127 | golem component list
128 | ```
129 |
130 |
131 | If you want to restrict component search to some specific project on Golem Cloud you can specify
132 | project via `--project` or `--project-name` option. It works for all commands that accept
133 | `--component-name` parameter.
134 |
135 |
136 | ## Updating component
137 |
138 | To update a component just run the `component deploy` (or `app deploy`) command again.
139 |
140 | If you want to trigger an update all agents to the new latest version right after creating this version you can use `--try-update-agents` option.
141 |
142 | It is possible to change the **component's type** (from durable to ephemeral, or from ephemeral to durable) when
143 | updating the component by changing the manifest file.
144 |
145 | ## Updating agents
146 |
147 | If you want to update all agents you can use `component try-update-agents` command.
148 |
149 | This command gets all agents for the component that are not using the latest version and triggers an update for them one by one:
150 |
151 | ```shell copy
152 | golem component try-update-agents example:component
153 | ```
154 |
155 | The update request is enqueued and processed by the agents asynchronously, `golem` cannot await for the update to finish.
156 |
157 |
158 | Note that automatic agent update is not guaranteed to succeed, if the updated component differs
159 | too much from the previous one.
160 |
161 |
162 | You can use URL or `--component-name` instead.
163 |
164 | ## Redeploying agents
165 |
166 | During the development of a Golem Component, it is often necessary to quickly rebuild the code, update the component and just restart all the test agents from scratch to test the changes.
167 |
168 | This is different from updating the agents as they will loose their state, but it can speed up the feedback loop during development.
169 |
170 | This workflow is supported by the `component redeploy` command:
171 |
172 | ```shell copy
173 | golem component redeploy example:component
174 | ```
175 |
176 | This command deletes all agents that are not using the latest version of component and re-creates them with the same name, parameters and environment variables.
177 |
178 | You can use URL or `--component-name` instead.
179 |
--------------------------------------------------------------------------------
/src/pages/cli/app-manifest.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 |
3 | # Golem Application Manifest
4 |
5 | The _Golem Application Manifest_ document format is used by `golem`, usually stored in files named `golem.yaml`, which can help working with components. Currently, the Application Manifest covers:
6 |
7 | - defining components and their metadata, including:
8 | - component type
9 | - location of user defined and generated WIT folders
10 | - location of built and composed WASM binaries
11 | - build commands
12 | - Initial File System
13 | - configuration values and environment variables
14 | - defining component dependencies on libraries
15 | - defining HTTP APIs
16 | - building components
17 | - deploying components
18 |
19 | The Application Manifest uses _YAML_ format, see the [reference](/app-manifest) for more information on the schema and for the field reference.
20 |
21 | # Application Manifest Quickstart
22 |
23 | Application manifest documents can be explicitly passed as `golem` arguments, but the recommended way to use them is with _auto discovery_ mode: when `golem` is called with an application manifest compatible command it keeps searching for `golem.yaml` documents in current working directory and parent directories. Once it found the top level `golem.yaml` document, more documents are searched using the [includes](/app-manifest#fields_includes) field.
24 |
25 | Once all manifest documents are found, the paths in them are resolved based on their directory, and then the documents are merged. For the field specific merge rules see the [field reference](/app-manifest#field-reference).
26 |
27 | ## Using composable templates
28 |
29 | Golem projects can be created with `golem app new` command. This creates a new application that may consist of multiple components. To add a new component to an existing application, use `golem component new`. E.g.: let's add a new _c_ and _ts_ component in a new and empty directory:
30 |
31 | ```shell
32 | golem app new app:component-a c
33 | cd app:component-a
34 | golem component new ts app:component-b
35 | ```
36 |
37 | When using the `app new` command, it will create:
38 |
39 | - common directory for the given language (`common-cpp` and `common-ts`):
40 | - this directory contains the languages specific _Application Manifest Template_, which defines how to
41 | build the components
42 | - can be used for shared subprojects
43 | - might contain other shared configurations
44 | - directory for components for the given language (`components-cpp` and `components-ts`)
45 | - directory called `wit/deps` for common WIT dependencies, and populates it with WASI and Golem packages
46 | - depending on the language it might add `common-adapters`.
47 |
48 | Now that we added our components, let's use the `app` command list our project metadata:
49 |
50 | ```shell
51 | $ golem app
52 |
53 | Build, deploy application
54 |
55 | Usage: golem app [OPTIONS]
56 |
57 | Commands:
58 | new Create new application
59 | build Build all or selected components in the application
60 | deploy Deploy all or selected components in the application, includes building
61 | clean Clean all components in the application or by selection
62 | help Print this message or the help of the given subcommand(s)
63 |
64 | Options:
65 | -f, --format
66 | Output format, defaults to text, unless specified by the selected profile
67 | -p, --profile
68 | Select Golem profile by name
69 | -l, --local
70 | Select builtin "local" profile, to use services provided by the "golem server" command
71 | -c, --cloud
72 | Select builtin "cloud" profile to use Golem Cloud
73 | -a, --app-manifest-path
74 | Custom path to the root application manifest (golem.yaml)
75 | -A, --disable-app-manifest-discovery
76 | Disable automatic searching for application manifests
77 | -b, --build-profile
78 | Select build profile
79 | --config-dir
80 | Custom path to the config directory (defaults to $HOME/.golem)
81 | -v, --verbose...
82 | Increase logging verbosity
83 | -q, --quiet...
84 | Decrease logging verbosity
85 | -h, --help
86 | Print help
87 |
88 | Components:
89 | app:component-a
90 | Selected: yes
91 | Source: /Users/<...>/app-demo/components-cpp/app-component-a/golem.yaml
92 | Template: cpp
93 | Profiles: debug, release
94 | app:component-b
95 | Selected: yes
96 | Source: /Users/<...>/app-demo/components-ts/app-component-b/golem.yaml
97 | Template: ts
98 |
99 | Custom commands:
100 | npm-install
101 | ```
102 |
103 | Because the _ts_ components use npm, we have to use `npm install` before building the components. We can also see that this has a wrapper custom command in the manifest called `npm-install`. Let's use that, then build our components:
104 |
105 | ```sh
106 | $ golem app npm-install
107 | <..>
108 | $ golem app build
109 | Collecting sources
110 | Found sources: /Users/<...>/app-demo/common-cpp/golem.yaml, /Users/<...>/app-demo/common-ts/golem.yaml, /Users/<...>/app-demo/components-cpp/app-component-a/golem.yaml, /Users/<...>/app-demo/components-ts/app-component-b/golem.yaml, /Users/<...>/app-demo/golem.yaml
111 | Collecting components
112 | Found components: app:component-a, app:component-b
113 | Resolving application wit directories
114 | Resolving component wit dirs for app:component-a (/Users/<...>/app-demo/components-cpp/app-component-a/wit, /Users/<...>/app-demo/components-cpp/app-component-a/wit-generated)
115 | Resolving component wit dirs for app:component-b (/Users/<...>/app-demo/components-ts/app-component-b/wit, /Users/<...>/app-demo/components-ts/app-component-b/wit-generated)
116 | Selecting profiles, no profile was requested
117 | Selected default profile debug for app:component-a using template cpp
118 | Selected default build for app:component-b using template ts
119 | <...>
120 | Linking RPC
121 | Copying app:component-a without linking, no static WASM RPC dependencies were found
122 | Copying app:component-b without linking, no static WASM RPC dependencies were found
123 | ```
124 |
125 | Then we can check that the components are built:
126 |
127 | ```sh
128 | $ ls golem-temp/components
129 | app_component_a_debug.wasm app_component_b.wasm
130 | ```
131 |
132 | To deploy (add or update) or components we can use
133 |
134 | ```sh copy
135 | golem component deploy
136 | ```
137 |
138 | in the project root folder, and the CLI will add or update all or components.
139 |
140 | If we want to only update some components, we can do so by explicitly selecting them with the `--component-name` flag, or we can implicitly select them by changing our current working directory, e.g.:
141 |
142 | ```shell
143 | $ cd components-cpp
144 | $ golem app
145 | <...>
146 | Components:
147 | app:component-a
148 | Selected: yes
149 | Source: /Users/noise64/workspace/examples/app-demo/components-cpp/app-component-a/golem.yaml
150 | Template: cpp
151 | Profiles: debug, release
152 | app:component-b
153 | Selected: no
154 | Source: /Users/noise64/workspace/examples/app-demo/components-ts/app-component-b/golem.yaml
155 | Template: ts
156 | <...>
157 | ```
158 |
159 | Notice, how only app:component-a is selected in the above example, the same selection logic is used when
160 | adding or updating components.
161 |
--------------------------------------------------------------------------------
/check-links/check-links.ts:
--------------------------------------------------------------------------------
1 | import { glob } from "glob"
2 | import path from "path"
3 | import { promises as fs } from "fs"
4 | import markdownLinkExtractor from "markdown-link-extractor"
5 |
6 | type BaseResult = { link: string }
7 |
8 | type LinkCheckResult =
9 | | (BaseResult &
10 | (
11 | | {
12 | status: "ignored"
13 | }
14 | | {
15 | status: "alive"
16 | filePath?: string
17 | }
18 | ))
19 | | CheckLinkError
20 |
21 | type CheckLinkError = BaseResult &
22 | (
23 | | {
24 | status: "dead"
25 | }
26 | | {
27 | status: "error"
28 | error: Error
29 | }
30 | )
31 |
32 | type CheckFileResult =
33 | | {
34 | type: "success"
35 | }
36 | | {
37 | type: "dead-links"
38 | file: string
39 | deadLinks: CheckLinkError[]
40 | }
41 | | {
42 | type: "fatal"
43 | file: string
44 | error: Error
45 | }
46 |
47 | // Helper to get base URL for file system paths
48 | const makeBaseUrl = (file: string) =>
49 | process.platform === "win32" ? path.resolve(file).replace(/\\/g, "/") : path.resolve(file)
50 |
51 | const codeBlockRegex = /^```[\S\s]+?^```$/gm
52 | const headingRegex = /^#+ (.+)$/gm
53 |
54 | // Extract all links from markdown content
55 | const extractLinks = (content: string): string[] => {
56 | const links = markdownLinkExtractor(content)
57 | return Array.from(new Set(links)).filter(
58 | link => link.length > 0 && !link.startsWith("mailto:")
59 | )
60 | }
61 |
62 | // Extract all headings and convert to valid anchor links
63 | const extractHeadings = (content: string): string[] => {
64 | // First remove code blocks
65 | const contentWithoutCode = content.replace(codeBlockRegex, "")
66 |
67 | const headings: string[] = []
68 | let match
69 |
70 | while ((match = headingRegex.exec(contentWithoutCode)) !== null) {
71 | const heading = match[1]
72 | .toLowerCase()
73 | .replace(/[^\w\s-]/g, "")
74 | .replace(/\s+/g, "-")
75 | headings.push(heading)
76 | }
77 |
78 | // Handle duplicate headings by adding numbers
79 | const uniqueHeadings = new Map()
80 | return headings.map(heading => {
81 | const count = uniqueHeadings.get(heading) || 0
82 | uniqueHeadings.set(heading, count + 1)
83 | return count === 0 ? heading : `${heading}-${count}`
84 | })
85 | }
86 |
87 | namespace MarkdownPath {
88 | const cache = new Map()
89 | export const resolve = async (markdownPath: string): Promise => {
90 | if (cache.has(markdownPath)) {
91 | return cache.get(markdownPath)!
92 | }
93 |
94 | try {
95 | // handle all page layout variants
96 | const variants = [
97 | markdownPath,
98 | `${markdownPath}.mdx`,
99 | `${markdownPath}.md`,
100 | path.join(markdownPath, "index.mdx"),
101 | path.join(markdownPath, "index.md"),
102 | ]
103 | const filePath = await Promise.any(
104 | variants.map(variant => fs.access(variant).then(() => variant))
105 | )
106 | cache.set(markdownPath, filePath)
107 | return filePath
108 | } catch {
109 | return null
110 | }
111 | }
112 | }
113 |
114 | const checkLink = async (params: {
115 | link: string
116 | baseUrl: string
117 | headings: string[]
118 | ignorePatterns?: RegExp[]
119 | }): Promise => {
120 | let { link, baseUrl, headings, ignorePatterns = [] } = params
121 | // Check if link should be ignored
122 | if (ignorePatterns.some(pattern => pattern.test(link))) {
123 | return { link, status: "ignored" }
124 | }
125 |
126 | try {
127 | // Handle same page anchor links
128 | if (link.startsWith("#")) {
129 | const anchorId = link.slice(1)
130 | return {
131 | link,
132 | status: headings.includes(anchorId) ? "alive" : "dead",
133 | }
134 | }
135 |
136 | // For other page anchors links only check the base link
137 | const anchorIdx = link.indexOf("#")
138 | if (anchorIdx !== -1) {
139 | link = link.substring(0, anchorIdx)
140 | }
141 |
142 | // Handle absolute links from `src/pages/docs/`
143 | if (link.startsWith("/")) {
144 | const docPath = path.join(process.cwd(), "src/pages", link)
145 | const filePath = await MarkdownPath.resolve(docPath)
146 | return filePath !== null ? { link, status: "alive", filePath } : { link, status: "dead" }
147 | }
148 |
149 | // Handle relative links
150 | if (!link.startsWith("http")) {
151 | const absolutePath = path.resolve(path.dirname(baseUrl), link)
152 | const filePath = await MarkdownPath.resolve(absolutePath)
153 | return filePath !== null ? { link, status: "alive", filePath } : { link, status: "dead" }
154 | }
155 |
156 | // Handle external links
157 | const response = await fetch(link, { method: "HEAD" })
158 | return {
159 | link,
160 | status: response.ok ? "alive" : "dead",
161 | }
162 | } catch (error) {
163 | return {
164 | link,
165 | status: "error",
166 | error: error as Error,
167 | }
168 | }
169 | }
170 |
171 | const checkFile = async (fileStr: string): Promise => {
172 | try {
173 | const content = await fs.readFile(fileStr, "utf8")
174 | const links = extractLinks(content)
175 | const headings = extractHeadings(content)
176 | const baseUrl = makeBaseUrl(fileStr)
177 |
178 | const results = await Promise.all(
179 | links.map(link =>
180 | checkLink({
181 | link,
182 | baseUrl,
183 | headings,
184 | ignorePatterns: [/^https?:\/\//], // Ignore external links for now
185 | })
186 | )
187 | )
188 |
189 | const deadLinks: CheckLinkError[] = results.filter(
190 | (result): result is CheckLinkError => result.status === "dead" || result.status === "error"
191 | )
192 |
193 | if (deadLinks.length > 0) {
194 | return { type: "dead-links", file: fileStr, deadLinks }
195 | }
196 | return { type: "success" }
197 | } catch (err) {
198 | return { type: "fatal", file: fileStr, error: err as Error }
199 | }
200 | }
201 |
202 | const execute = async (files: string[]) => {
203 | const markdownFiles = files.filter(file => file.endsWith(".mdx") || file.endsWith(".md"))
204 | console.log(`Checking links in ${markdownFiles.length} files`)
205 |
206 | const errors = (await Promise.all(markdownFiles.map(checkFile))).filter(
207 | result => result.type !== "success"
208 | )
209 |
210 | if (errors.length > 0) {
211 | console.error(`\nFound ${errors.length} files with broken links:`)
212 | errors.forEach(error => {
213 | switch (error.type) {
214 | case "dead-links":
215 | console.error(`- ${error.file}:`)
216 | error.deadLinks.forEach(link => {
217 | if (link.status === "error") {
218 | console.error(` - ${link.link} (${link.status} - ${link.error.message})`)
219 | } else {
220 | console.error(` - ${link.link} (${link.status})`)
221 | }
222 | })
223 | break
224 | case "fatal":
225 | console.error(`- ${error.file}: ${error.error.message}`)
226 | break
227 | }
228 | })
229 | process.exit(1)
230 | }
231 | }
232 |
233 | const main = async () => {
234 | const args = process.argv.slice(2)
235 | const files =
236 | args.length > 0 ? args : await glob("src/pages/**/*.{mdx,md}", { ignore: "node_modules/**" })
237 | await execute(files)
238 | }
239 |
240 | main()
241 | .then(() => process.exit(0))
242 | .catch(err => {
243 | console.error("Failed to check links:", err)
244 | process.exit(1)
245 | })
246 |
--------------------------------------------------------------------------------
/src/pages/desktop.mdx:
--------------------------------------------------------------------------------
1 | import { Callout } from "nextra/components"
2 | import { Card, Cards } from "nextra/components"
3 | import { Tabs } from 'nextra/components'
4 | import { useEffect } from 'react'
5 |
6 | # Golem Desktop Introduction
7 |
8 | Golem Desktop provides a native application experience across Windows, Linux, and macOS. Since the application is currently unsigned, please follow the platform-specific instructions below to install it.
9 |
10 |
11 | Please note that the Golem Desktop application is only supported for the open source version of Golem.
12 |
13 |
14 | ## Download and Installation Instructions
15 |
16 |
17 |
18 |
19 |
20 | 1. Download the `.exe` installer from the [release page](https://github.com/golemcloud/golem/releases/tag/v1.3.1)
21 | 2. When you run the installer, Windows may show a SmartScreen warning
22 | 3. Click "More info" and then "Run anyway" to proceed with installation
23 | 4. Follow the on-screen instructions to complete installation
24 |
25 |
26 |
27 |
28 |
29 |
30 | 1. Download the Intel x64 `.dmg` file from the [release page](https://github.com/golemcloud/golem/releases/tag/v1.3.1)
31 | 2. Open the downloaded `.dmg` file
32 | 3. Drag the application to your Applications folder
33 | 4. When first launching, macOS may block the app with a message "Golem is damaged and can’t be opened. You should move it to the Trash"
34 | 5. To open the app, try one of these methods:
35 | - Method 1: Right-click (or Control-click) on the app icon and select "Open", then click "Open" in the dialog box
36 | - Method 2: If the above doesn't work, open Terminal and run the following command:
37 | ```bash
38 | xattr -rd com.apple.quarantine "/Applications/Golem.app"
39 | ```
40 | - The app should now open and subsequent launches won't require these steps
41 |
42 |
43 | 1. Download the ARM64 `.dmg` file from the [release page](https://github.com/golemcloud/golem/releases/tag/v1.3.1)
44 | 2. Open the downloaded `.dmg` file
45 | 3. Drag the application to your Applications folder
46 | 4. When first launching, macOS may block the app with a message "Golem is damaged and can’t be opened. You should move it to the Trash"
47 | 5. To open the app, try one of these methods:
48 | - Method 1: Right-click (or Control-click) on the app icon and select "Open", then click "Open" in the dialog box
49 | - Method 2: If the above doesn't work, open Terminal and run the following command:
50 | ```bash
51 | xattr -rd com.apple.quarantine "/Applications/Golem.app"
52 | ```
53 | - The app should now open and subsequent launches won't require these steps
54 |
55 |
56 | For older macOS versions (pre-Catalina), you may need to adjust your security settings:
57 |
58 | 1. After downloading and attempting to open the app, go to **System Preferences** → **Security & Privacy**
59 | 2. In the **General** tab, you should see a message about Golem being blocked
60 | 3. Click the **Open Anyway** button (you may need to unlock the settings with the padlock icon first)
61 | 4. If you don't see this option, try these alternative steps:
62 | - Open **System Preferences** → **Security & Privacy**
63 | - Click the padlock icon to make changes
64 | - Under **Allow apps downloaded from**, select **Anywhere** (if available) or **App Store and identified developers**
65 |
66 |
67 |
68 |
69 |
70 |
71 | 1. Download the `.deb` file from the [release page](https://github.com/golemcloud/golem/releases/tag/v1.3.1)
72 |
73 | ```bash
74 | # Install the downloaded .deb file
75 | sudo dpkg -i golem-desktop_x.x.x_amd64.deb
76 |
77 | # If there are dependency issues, run
78 | sudo apt-get install -f
79 | ```
80 |
81 |
82 | 1. Download the `.rpm` file from the [release page](https://github.com/golemcloud/golem/releases/tag/v1.3.1)
83 |
84 | ```bash
85 | # Install the downloaded .rpm file
86 | sudo rpm -i golem-desktop-x.x.x.x86_64.rpm
87 |
88 | # Alternatively, using dnf
89 | sudo dnf install golem-desktop-x.x.x.x86_64.rpm
90 | ```
91 |
92 |
93 | 1. Download the Linux `.AppImage` from the [release page](https://github.com/golemcloud/golem/releases/tag/v1.3.1)
94 |
95 | ```bash
96 | # Make the AppImage executable
97 | chmod +x golem-desktop-x.x.x.AppImage
98 |
99 | # Run the AppImage
100 | ./golem-desktop-x.x.x.AppImage
101 | ```
102 |
103 |
104 |
105 |
106 |
107 | export function PlatformDetector() {
108 | useEffect(() => {
109 | if (typeof window !== 'undefined') {
110 | const platform = navigator.platform.toLowerCase();
111 | const userAgent = navigator.userAgent.toLowerCase();
112 | const tabButtons = document.querySelectorAll('[role="tab"]');
113 | if (tabButtons.length > 0) {
114 | let osTabIndex = 0;
115 |
116 | if (platform.includes('mac') || userAgent.includes('mac') || userAgent.includes('darwin')) {
117 | osTabIndex = 1;
118 | } else if (platform.includes('linux') || platform.includes('x11')) {
119 | osTabIndex = 2;
120 | }
121 |
122 | if (tabButtons[osTabIndex]) {
123 | setTimeout(() => {
124 | tabButtons[osTabIndex].click();
125 |
126 | if (osTabIndex === 1) {
127 | setTimeout(() => {
128 | const macTabs = document.querySelectorAll('[role="tabpanel"]:not([hidden]) [role="tab"]');
129 | if (macTabs.length > 0) {
130 | const isAppleSilicon =
131 | /arm|aarch64/i.test(navigator.platform) ||
132 | (userAgent.includes('mac') &&
133 | (/macbookpro1[78]|macbookair1[01]|macmini9|imac2[34]/i.test(userAgent) ||
134 | (typeof window.navigator.hardwareConcurrency !== 'undefined' &&
135 | window.navigator.hardwareConcurrency >= 8))) ||
136 | (typeof navigator.cpuClass !== 'undefined' &&
137 | navigator.cpuClass === 'arm64');
138 |
139 | console.log("Is Apple Silicon:", isAppleSilicon);
140 | const archIndex = isAppleSilicon ? 1 : 0;
141 |
142 | if (macTabs[archIndex]) {
143 | macTabs[archIndex].click();
144 | }
145 | }
146 | }, 300);
147 | } else if (osTabIndex === 2) {
148 | // For Linux, we can't reliably detect the distro Leave all as default, might need some time to test this with some linux machine
149 | }
150 | }, 300);
151 | }
152 | }
153 | }
154 | }, []);
155 |
156 | return null;
157 | }
158 |
159 |
160 |
161 |
162 | These instructions are for the unsigned version of Golem Desktop. Signed versions with proper verification will be available in future releases.
163 |
164 |
--------------------------------------------------------------------------------