Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 84 additions & 0 deletions .github/workflows/deployment-operator-cd-browser-use.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
name: CD / Browser Use Sidecar

on:
pull_request:
branches:
- "master"
paths:
- ".github/workflows/deployment-operator-cd-browser-use.yaml"
- "go/deployment-operator/dockerfiles/browser-use/**"
push:
tags:
- 'go/deployment-operator/v*.*.*'
workflow_dispatch:
inputs:
version:
description: 'Semantic Version (e.g. 0.1.0)'
required: true
type: string
browser_use_version:
description: 'Pinned browser-use PyPI version baked into the image'
required: false
type: string

permissions:
contents: read

env:
DOCKER_METADATA_PR_HEAD_SHA: 'true'
REGISTRY_IMAGE: pluralsh/browser-use
BROWSER_USE_DEFAULT_VERSION: 0.1.0

jobs:
build-and-publish:
name: Build and push browser-use sidecar image
permissions:
contents: read
id-token: write
packages: write
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Docker meta
id: meta
uses: docker/metadata-action@v5
with:
images: |
ghcr.io/pluralsh/browser-use
docker.io/pluralsh/browser-use
tags: |
type=raw,value=${{ inputs.version }},enable=${{ inputs.version != '' }},priority=1100
type=semver,pattern={{version}},value=${{ github.ref_name }},match=go/deployment-operator/v(\d+\.\d+\.\d+)$,priority=1000
type=sha,priority=800
type=ref,event=pr,priority=600
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Login to GHCR
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: mjgpluralsh
password: ${{ secrets.DOCKER_ACCESS_TOKEN }}
- name: Build and push
uses: docker/build-push-action@v6
with:
context: "./go/deployment-operator/dockerfiles/browser-use"
file: "./go/deployment-operator/dockerfiles/browser-use/Dockerfile"
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
platforms: linux/amd64,linux/arm64
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
BROWSER_USE_VERSION=${{ inputs.browser_use_version || env.BROWSER_USE_DEFAULT_VERSION }}
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,24 @@ const columns = [
</Chip>
),
}),
columnHelper.accessor((runtime) => runtime.browserEnabled, {
id: 'browserEnabled',
header: 'Browser',
cell: ({ getValue }) => (
<Chip
fillLevel={0}
size="small"
severity={getValue() ? 'success' : 'neutral'}
tooltip={
getValue()
? 'A headless browser sidecar and the browser-use MCP tools are provisioned for runs on this runtime.'
: 'Runs on this runtime do not have browser capabilities. Set spec.browser.enabled on the AgentRuntime CRD to enable.'
}
>
{getValue() ? 'Enabled' : 'Disabled'}
</Chip>
),
}),
columnHelper.accessor((runtime) => runtime.cluster, {
id: 'cluster',
header: 'Cluster',
Expand Down
2 changes: 2 additions & 0 deletions assets/src/generated/graphql-plural.ts
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,8 @@ export type ClusterUsageAttributes = {
clusters?: InputMaybe<Scalars['Int']['input']>;
/** the number of services deployed on the cluster */
services?: InputMaybe<Scalars['Int']['input']>;
/** the number of tokens used by the cluster */
tokens?: InputMaybe<Scalars['Int']['input']>;
};

/** A record of the utilization in a given cluster */
Expand Down
13 changes: 9 additions & 4 deletions assets/src/generated/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,8 @@ export type AgentRuntime = {
allowedRepositories?: Maybe<Array<Maybe<Scalars['String']['output']>>>;
/** default interval in seconds between babysit checks for runs on this runtime */
babysitInterval?: Maybe<Scalars['Int']['output']>;
/** whether this runtime provisions a headless browser sidecar (and the browser-use MCP tools) for runs */
browserEnabled?: Maybe<Scalars['Boolean']['output']>;
/** the cluster this runtime is running on */
cluster?: Maybe<Cluster>;
/** the policy for creating runs on this runtime */
Expand Down Expand Up @@ -656,6 +658,8 @@ export type AgentRuntimeAttributes = {
allowedRepositories?: InputMaybe<Array<InputMaybe<Scalars['String']['input']>>>;
/** default interval in seconds between babysit checks for runs on this runtime */
babysitInterval?: InputMaybe<Scalars['Int']['input']>;
/** whether this runtime provisions a headless browser sidecar (and the browser-use MCP tools) for runs */
browserEnabled?: InputMaybe<Scalars['Boolean']['input']>;
/** the policy for creating runs on this runtime */
createBindings?: InputMaybe<Array<InputMaybe<AgentBindingAttributes>>>;
/** whether this is the default runtime for coding agents */
Expand Down Expand Up @@ -17101,7 +17105,7 @@ export type AgentRunTinyFragment = { __typename?: 'AgentRun', id: string, status

export type AgentRunFragment = { __typename?: 'AgentRun', id: string, status: AgentRunStatus, mode: AgentRunMode, babysit?: boolean | null, prompt: string, shared?: boolean | null, error?: string | null, repository: string, branch?: string | null, headBranch?: string | null, insertedAt?: string | null, updatedAt?: string | null, messages?: Array<{ __typename?: 'AgentMessage', id: string, seq: number, role: AiRole, message: string, cost?: { __typename?: 'AgentMessageCost', total: number, tokens?: { __typename?: 'AgentMessageTokens', input?: number | null, output?: number | null, reasoning?: number | null } | null } | null, metadata?: { __typename?: 'AgentMessageMetadata', reasoning?: { __typename?: 'AgentMessageReasoning', text?: string | null, start?: number | null, end?: number | null } | null, file?: { __typename?: 'AgentMessageFile', name?: string | null, text?: string | null, start?: number | null, end?: number | null } | null, tool?: { __typename?: 'AgentMessageTool', name?: string | null, state?: AgentMessageToolState | null, input?: string | null, output?: string | null } | null } | null } | null> | null, todos?: Array<{ __typename?: 'AgentTodo', title: string, description: string, done?: boolean | null } | null> | null, analysis?: { __typename?: 'AgentAnalysis', summary: string, analysis: string, bullets?: Array<string | null> | null } | null, runtime?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType } | null, pullRequests?: Array<{ __typename?: 'PullRequest', id: string, url: string, title?: string | null, creator?: string | null, status?: PrStatus | null, insertedAt?: string | null, updatedAt?: string | null } | null> | null, podReference?: { __typename?: 'AgentPodReference', name: string, namespace: string } | null, upload?: { __typename?: 'AgentRunUpload', id: string, session?: string | null } | null };

export type AgentRuntimeFragment = { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null };
export type AgentRuntimeFragment = { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, browserEnabled?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null };

export type AgentRuntimeReposFragment = { __typename?: 'AgentRuntime', id: string, allowedRepositories?: Array<string | null> | null };

Expand Down Expand Up @@ -17159,14 +17163,14 @@ export type AgentRuntimesQueryVariables = Exact<{
}>;


export type AgentRuntimesQuery = { __typename?: 'RootQueryType', agentRuntimes?: { __typename?: 'AgentRuntimeConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, endCursor?: string | null, hasPreviousPage: boolean, startCursor?: string | null }, edges?: Array<{ __typename?: 'AgentRuntimeEdge', node?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null } | null } | null> | null } | null };
export type AgentRuntimesQuery = { __typename?: 'RootQueryType', agentRuntimes?: { __typename?: 'AgentRuntimeConnection', pageInfo: { __typename?: 'PageInfo', hasNextPage: boolean, endCursor?: string | null, hasPreviousPage: boolean, startCursor?: string | null }, edges?: Array<{ __typename?: 'AgentRuntimeEdge', node?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, browserEnabled?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null } | null } | null> | null } | null };

export type AgentRuntimeQueryVariables = Exact<{
id: Scalars['ID']['input'];
}>;


export type AgentRuntimeQuery = { __typename?: 'RootQueryType', agentRuntime?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null } | null };
export type AgentRuntimeQuery = { __typename?: 'RootQueryType', agentRuntime?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, browserEnabled?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null } | null };

export type AgentRuntimeReposQueryVariables = Exact<{
id: Scalars['ID']['input'];
Expand Down Expand Up @@ -17213,7 +17217,7 @@ export type UpsertAgentRuntimeMutationVariables = Exact<{
}>;


export type UpsertAgentRuntimeMutation = { __typename?: 'RootMutationType', upsertAgentRuntime?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null } | null };
export type UpsertAgentRuntimeMutation = { __typename?: 'RootMutationType', upsertAgentRuntime?: { __typename?: 'AgentRuntime', id: string, name: string, type: AgentRuntimeType, aiProxy?: boolean | null, browserEnabled?: boolean | null, default?: boolean | null, cluster?: { __typename?: 'Cluster', self?: boolean | null, virtual?: boolean | null, id: string, name: string, handle?: string | null, distro?: ClusterDistro | null, upgradePlan?: { __typename?: 'ClusterUpgradePlan', compatibilities?: boolean | null, deprecations?: boolean | null, incompatibilities?: boolean | null } | null, provider?: { __typename?: 'ClusterProvider', name: string, cloud: string } | null } | null, createBindings?: Array<{ __typename?: 'PolicyBinding', id?: string | null, user?: { __typename?: 'User', id: string, name: string, email: string } | null, group?: { __typename?: 'Group', id: string, name: string } | null } | null> | null } | null };

export type ShareAgentRunMutationVariables = Exact<{
id: Scalars['ID']['input'];
Expand Down Expand Up @@ -21468,6 +21472,7 @@ export const AgentRuntimeFragmentDoc = gql`
name
type
aiProxy
browserEnabled
cluster {
...ClusterTiny
}
Expand Down
Loading
Loading