Skip to content

Releases: sixb-ai/sixb

Sixb 0.1.21

Choose a tag to compare

@quentinnippert quentinnippert released this 21 Oct 07:27

Sixb 0.1.21

The Agent now delivers its work as artifacts: versioned documents, sheets, slide decks and files that open beside the conversation, on their own page and in a gallery. Your app can record how people use it, an Agent step can work in its own repository sandbox and open pull requests, and pipeline steps can read marked columns while their markings follow the data.

This release has breaking changes and database migrations. Read Upgrading before you deploy.

Highlights

Artifacts

In a conversation, the Agent publishes what it makes as an artifact, then revises it in later turns: the thread's latest versions are installed in its sandbox before each turn.

Kind Shows as
document A page with its outline, callouts and figures
sheet A grid with its charts
slides A deck, in a sandboxed frame
file An image, PDF, Markdown, CSV/TSV table, text, or a download

Each artifact opens in a panel beside the chat, on its own page at /artifacts/:artifactId, and in the gallery at /artifacts, filtered by kind. Your code reaches them through sixb.artifacts, and other tools through /api/artifacts. A user or service account reaches only its own artifacts.

App activity

See who uses your app, what they view and what they do there:

createSixb({ activity: { enabled: true } })

Observability › Activity lists a period's users, visits and page views, each visit's timeline (pages, interactions, the runs it started, Agent runs) and a user's active days. Reading it takes can.observe(project.activity).

Mark what people click, or record what is not a click:

<Button data-sixb-track="invoices.export">Export</Button>
import { trackSixbEvent } from "@sixb/client/browser"

trackSixbEvent("invoices.filter.applied")

Sixb records the name, the page and the time, never URLs, values or element text. Activity is off by default.

An Agent step in its own sandbox

defineAgentStep accepts sandbox. Each run gets a fresh sandbox from that factory: Sixb clones the repository, runs setup, and destroys the sandbox when the run ends.

export const fixIncident = defineAgentStep("fix-incident", {
  instructions: "Fix the bug and add a test, then open a pull request.",
  groups: [engineering],
  sandbox: appRepo,
})

With a GitHub App and access: "write", the task pushes branches and opens pull requests with git and gh. The token is injected outside the sandbox and revoked when the run ends, and commits are attributed to the App's bot.

Markings follow the data

Pipeline steps can now read marked columns. Each dataset version records the source columns its values come from, so its markings follow that lineage through SQL and .run() steps, and a projected property declares what it derives. dataset.pick(...) narrows a step input to some columns. Objects keep the markings of the version their projection applied, so removing a marking from a step does not reveal values computed before.

Also in this release

  • DuckLake keeps the versions you still read. Maintenance no longer expires the snapshot holding a dataset's latest version or a projection's applied version, and version lookups read a few rows whatever the catalog history length.
  • Faster redaction. A clearance computes once per object type what it hides, instead of rebuilding every row.
  • Request credentials can match a path prefix and a list of methods, and Vercel sandboxes inject them into ephemeral sandboxes too.
  • Fixed: apps without a ThemeProvider no longer load dark on a dark OS, and githubApp accepts a private key stored with escaped newlines.

Upgrading

Upgrade the packages in the table below together, then rebuild your application assets.

Migrate the database

Run sixb db migrate before starting the new version. PostgreSQL migrations 063-artifacts to 068-activity-interactions and SQLite migrations 062-artifacts to 066-activity-interactions add artifacts and activity. PostgreSQL 064 and SQLite 063 also strip the output_* diagnostics from stored Agent runs.

Required changes

  • Observe logs by reference. The string form fails with a message naming its replacement.

    -import { can, defineRole } from "@sixb/core"
    +import { can, defineRole, project } from "@sixb/core"
    
    -  grants: [can.observe("logs")],
    +  grants: [can.observe(project.logs)],
  • Store tool files through context.files. Project tools that produced files used context.artifacts. The Agent's output directory is removed too: no $SIXB_OUTPUT_DIR, and nothing is collected after a run.

    -await context.artifacts.put({ fileName: "report.csv", body })
    +await context.files.put({ fileName: "report.csv", body })
  • Import githubApp from /sandbox. A GitHub App with write access also needs the Contents and Pull requests write permissions; a missing one fails with a message naming it.

    -import { githubApp } from "@sixb/connector-github/auth"
    +import { githubApp } from "@sixb/connector-github/sandbox"
  • Use @sixb/core/artifacts instead of @sixb/core/internal/artifacts. The document preview's renderer registry and AgentWorkspaceProvider are removed.

Behavior to check

  • Sandbox factories are checked at startup. createSixb rejects a recipe that asks for write access without auth, or sets auth on a provider that cannot inject credentials.
  • Wildcard hosts are rejected in sandbox networks, source URLs and credentials, and an Agent's sandbox network cannot be none: it always reaches the Sixb API.

Package versions

Version Packages
0.1.21 @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator, @sixb/pg, @sixb/sqlite, @sixb/agent-worker, @sixb/pipeline-worker, @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker
0.1.13 @sixb/app
0.1.9 @sixb/ducklake
0.1.7 @sixb/lake-local, @sixb/sandboxes-vercel
0.1.5 @sixb/ui, @sixb/connector-github

Changes since v0.1.20

Sixb 0.1.20

Choose a tag to compare

@demattosanthony demattosanthony released this 18 Oct 16:06

Sixb 0.1.20

Atlas is now part of your app. Settings, Data, Observability and Ontology are built-in sections of every project's app, alongside the agent, a page for every object, and search. @sixb/app is the one import for app code, and a project without an app/ folder still gets the app. There is one browser app to run, secure and deploy.

This release has breaking changes and a database migration. Read Upgrading before you deploy.

Highlights

Atlas's pages, in your app

Atlas is gone, and each of its pages is in the project's app, opened from the user menu:

Section Pages
Settings Personal, Developers, Members, Service accounts
Data Connectors, Syncs, Datasets, Pipelines, Projections
Observability Runs, Logs, AI usage
Ontology Object types, Objects, Graph, Actions, Workflows, Rules

Opening a section swaps the sidebar for its pages. A page of your own at the same path replaces the built-in one, so app/settings/members/page.tsx replaces Members.

sixb dev serves the app on port 3000 and the API on 3001:

before                       now
──────                       ───
:3000  Atlas                 :3000  app  (your pages + built-in sections)
:3001  custom app            :3001  API
:3002  API

See Building apps.

One shell for every app

AppShell frames every page with a sidebar: the app's name, Search on ⌘K, your navigation, and the user menu. When the project has an agent, it waits docked beside each page.

// app/layout.tsx
import { AppShell } from "@sixb/app"
import { FileText, MapPin } from "lucide-react"
import type { PropsWithChildren } from "react"

export default function RootLayout({ children }: PropsWithChildren) {
  return (
    <AppShell
      nav={[
        {
          group: "Operations",
          items: [
            { label: "Quotes", href: "/quotes", icon: FileText },
            { label: "Job sites", href: "/sites", icon: MapPin },
          ],
        },
      ]}
    >
      {children}
    </AppShell>
  )
}

To build your own sidebar, use the parts it is made from: AppShellProvider, Brand, NavItems, SearchCommand, SectionNav, UserMenu and AgentDock. useCurrentUser() and useSignOut() read the session the app already loaded.

Until you add app/page.tsx, the app serves a Home where people ask the project's agent. A project with no app/ folder at all gets the built-in pages in the default shell.

See Add a sidebar.

Choose who sees a section

Export visibility from app/layout.tsx:

import type { AppVisibility } from "@sixb/app"
import { admins } from "../security/groups/admins"

export const visibility = {
  settings: [admins],
  data: [admins],
  observability: [admins],
  ontology: [admins],
} satisfies AppVisibility
Value Who sees the section
Not set Everyone signed in
[admins, staff] Members of those groups
[] Nobody

Personal and Developers stay open to everyone signed in, and object pages stay open when Ontology is hidden. Visibility only hides screens: the API still checks each request against the caller's grants.

See Choose who sees a section.

A page for every object

Every object has a page at /objects/:objectTypeId/:primaryId, such as /objects/Deal/D-48231: its properties, its telemetry live with a trend over time, its links in both directions, and its type's actions. References to an object anywhere in the app open it, and Search finds objects as you type. Objects are named by the property their type declares as its title.

See Object pages.

Also in this release

  • Start a sync from your own pages with SyncButton. It reads Syncing… until the run ends.

    import { SyncButton } from "@sixb/app"
    
    <SyncButton sync="crm-accounts" showStatus />
  • ThemePicker in @sixb/ui, shown in the user menu and on Settings › Personal.

  • Vector indexing runs four embedding calls at once, where it ran one. Change it with --vector-concurrency or SIXB_VECTOR_CONCURRENCY on sixb dev, sixb worker projection and sixb worker-group:

    sixb worker projection --vector-concurrency 8
  • Vector indexing waits five minutes for an embedding. It was abandoned after 30 seconds, still billed, and the object stayed out of semantic search. Search keeps its 30-second deadline.

  • sixb api starts without an app origin, for deployments that run the API alone.

  • Direct S3 uploads work on stores that do not report checksums. When an S3-compatible service leaves the checksum out, Sixb reads the uploaded file back to verify it.

  • Fixed: an SFTP transfer that was aborted lost its abort reason when remote cleanup also failed.

Upgrading

Upgrade the packages in the table below together, then rebuild your application assets.

Migrate the database

PostgreSQL migration 062-drop-auth-audience and SQLite migration 061-drop-auth-audience remove the audience from sessions, magic links and OIDC sign-in attempts. Atlas's browser sessions end, so people signed in to Atlas sign in again. The app keeps its cookie names, so its sessions survive.

Run sixb db migrate with the old processes stopped, then start the new version. Upgrade @sixb/pg or @sixb/sqlite, @sixb/auth-magic-link and @sixb/auth-oidc with core: the auth strategies no longer send an audience.

Required changes

  • Remove Atlas. Uninstall @sixb/atlas and @sixb/agent-ui, and stop running sixb atlas. Remove the atlas service and port from sixb.deploy.ts. A config that still names it fails and says to configure app.

     // sixb.deploy.ts
     target: new SshTarget({
       host: "203.0.113.10",
    -  ports: { atlas: 3010, app: 3011, api: 3012 },
    +  ports: { app: 3011, api: 3012 },
     }),
    -SIXB_ATLAS_PUBLIC_ORIGIN=https://atlas.example.com
     SIXB_APP_PUBLIC_ORIGIN=https://app.example.com

    Point any proxy, domain or bookmark that opened Atlas at the app.

  • Install the app's React packages in the project. The app is bundled from the project, including when it has no app/ folder. sixb build names any that are missing.

    bun add @sixb/app react react-dom react-router-dom @tanstack/react-query
  • Import app code from @sixb/app. @sixb/app/agents and @sixb/app/auth are no longer import paths, and the CLI's tooling moves to @sixb/app/server. Agent components move from @sixb/agent-ui:

    -import { AgentPanel } from "@sixb/agent-ui"
    -import { SidebarUserMenu } from "@sixb/app/agents"
    +import { AgentPanel, UserMenu } from "@sixb/app"

    @sixb/app exports AgentPanel, AgentSurface, AgentChatPage, Composer, AgentContextProvider, useAgentContext, AgentWorkspaceProvider and agentContext. The rest of @sixb/agent-ui, including AgentChat and AgentLabelsProvider, is not public in this release.

  • Replace application grants with visibility. can.access(...) and applications are removed from @sixb/core, along with the session's applicationAccess.

     export const financeAccess = defineRole("finance-access", {
       grantedTo: [financeTeam],
       grants: [
    -    can.access(applications.app),
         can.view(Invoice),
         can.apply(markPaid),
       ],
     })
  • Give service account administrators the serviceAccounts operation. Creating and managing service accounts now takes a membership policy that allows it:

     export const financeMembers = defineMembershipPolicy("finance-members", {
       grantedTo: [financeAdmins],
       scope: [financeTeam],
    -  can: ["invite", "assignGroups", "suspend"],
    +  can: ["invite", "assignGroups", "suspend", "serviceAccounts"],
     })
  • Import defineGroup from @sixb/core/security in group files that app/layout.tsx imports. The browser loads the layout, and the @sixb/core root is not browser-safe.

Behavior to check

  • Every signed-in member opens the app. A role that granted applications.app used to keep everyone else out of the custom app. Roles now decide only what each member reads and does, and visibility decides which sections they see. Review the grants of anyone who should not open the app.
  • Ports moved. In development, the app is on 3000 and the API on 3001, where Atlas was on 3000, the custom app on 3001 and the API on 3002. --port on sixb dev sets the app's port, with the API on the next one.
  • Without SIXB_APP_PUBLIC_ORIGIN, the API admits no browser app. Set it on the API unless you run the API alone.
  • Projection workers make up to four embedding calls at once. Lower --vector-concurrency if your embedding provider's rate limit is tight.

Package versions

Version Packages
0.1.20 @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator, @sixb/pg, @sixb/sqlite, @sixb/agent-worker, @sixb/pipeline-worker, @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker
0.1.12 @sixb/app
0.1.6 @sixb/auth-magic-link, @sixb/auth-oidc
0.1.5 create-sixb
0.1.4 @sixb/ui, @sixb/blob-s3
0.1.3 @sixb/connector-sftp
0.1.2 @sixb/deploy-ssh

@sixb/atlas and @sixb/agent-ui have no 0.1.20 release. Remove them from your project.

Changes since v0.1.19

Sixb 0.1.19

Choose a tag to compare

@demattosanthony demattosanthony released this 14 Oct 13:50

Sixb 0.1.19

Actions now run in the process that requests them and return their finished run. There is no Action queue or worker to deploy: your app, the CLI, agents, workflows, and schedules all get the outcome from the request itself. Runs execute concurrently, retry when the data they read changes, and have a time limit. This release also limits request body sizes before authentication, so upgrading is recommended.

This release has breaking changes and a database migration. Read Upgrading before you deploy.

Highlights

Actions run when you request them

Requesting an Action runs it right away and returns the finished run. You don't poll, wait for an event, or run a worker.

const run = await sixb.objects(Invoice).byId("inv-1").requestAction({
  action: markPaid,
  params: {},
})

if (run.status === "failed") {
  console.error(run.error?.message)
}

A failed run is returned, not thrown. The request throws only when no run was requested, for example when the Action is unknown, the params are invalid, or the caller lacks permission. Over HTTP, a failed run is a 200 with status: "failed", and the client SDK returns the same run:

import { requestAction } from "@sixb/client"

const { data: run } = await requestAction({
  path: { actionId: "markPaid" },
  body: {
    subject: { kind: "object", objectTypeId: "Invoice", primaryId: "inv-1" },
    params: {},
  },
  throwOnError: true,
})

A run is recorded once, when it ends, together with the edits it commits, so edits are never saved without their run. Pass your own runId to make a request safe to retry: a repeated request returns the recorded run instead of running the Action again. Effects run after the response and don't hold it open.

See Request an action.

Concurrent runs retry their edits

Runs of an Action, including several runs of the same one, now execute at the same time. If an object or link a run read changes before it commits, Sixb runs .edits() again against the new data:

validate ──▶ writeback ──▶ edits ──▶ commit
                             ▲          │
                             └──────────┘
                        a read changed: run edits again

A run with a .writeback() reuses that writeback's result on every attempt, so it calls the external system only once. A run without a writeback also reruns .validate(). After three conflicting attempts, the run commits nothing and fails with action.read_conflict.

See Concurrent changes.

Time limits

Stage Limit When it runs out
Validation and writeback, or validation and edits when there is no writeback 30 seconds The run commits nothing and fails with action.timeout.
Edits and commit after a successful writeback None They always finish, so the external change is recorded.
Effects 30 seconds after the commit The run stays succeeded; run.effects records the timeout.

Handlers receive a signal that aborts at the limit. Forward it to the calls they await so they stop in time:

.writeback(async ({ target, sixb, run, signal }) => {
  const client = await sixb.connector(billing)
  const receipt = await client.recordPayment({
    invoiceNumber: target.properties.number,
    idempotencyKey: run.idempotencyKey,
    signal,
  })
  return { receiptId: receipt.id }
})

Sixb always waits for a writeback to return, because its result is the only record of whether the external change happened. Move work that takes longer than 30 seconds into a workflow.

Clean shutdown

A stopping API or worker process refuses new Actions with a 503 (runtime.stopping) and waits up to 65 seconds for the runs and effects already in progress. Deployments generated from sixb.deploy.ts give api and workers 70 seconds before killing them. Set process.killTimeoutMs to change this.

Also in this release

  • The CLI stops waiting after 25 seconds and does not cancel the run. Every sixb actions request names its run, so after a timeout you can read the run with sixb action-runs get <runId>. Pass --run-id to keep the same run when you repeat a request:

    sixb actions request markPaid --subject-type Invoice --subject-id inv-1 --run-id act_42
  • Atlas no longer waits indefinitely for effects. The run page shows when an effects outcome is not coming. In the agent chat, Action requests in threads saved before this release show as request receipts, not as runs that are still queued.

  • Fixed: direct and multipart file uploads failed in the browser because fetch was called with an invalid receiver.

Security fixes

  • Request size. The API accepted request bodies up to 128 MiB on every route and parsed them before checking authentication, so an anonymous caller could make it buffer that much. Bodies are now limited to 1 MiB as they arrive, and a larger body gets a 413 before authentication runs. Authenticated file uploads take files up to 25 MiB, and uploads sent directly to S3 or Azure Blob Storage are not affected. A WebSocket message larger than 64 KiB closes its connection.

Upgrading

Upgrade the packages in the table below together, then rebuild your application assets.

Migrate the database

PostgreSQL migration 061-terminal-action-runs and SQLite migration 060-terminal-action-runs remove queued_at and keep only finished runs. Old binaries cannot run against the new schema:

  1. Stop accepting new Actions, and let the old deployment drain or reconcile outstanding work.
  2. Stop every old process, including the action workers.
  3. Back up the database and rehearse the migration on a copy of it.
  4. Run sixb db migrate, then start the new version.

Rolling back requires both the old binaries and the database backup.

Runs that had not finished are migrated as follows. On SQLite, the migration rebuilds the run table.

Old run After the migration
Queued or running, edits committed succeeded. Interrupted effects are recorded as failed.
Queued or running, no edits committed failed, and not resumed
Cancelled failed

Required changes

  • Remove the action worker. Uninstall @sixb/action-worker, and remove action from your worker types, concurrency settings, and SIXB_ACTION_WORKER_CONCURRENCY. Custom queue providers drop queues.actions. A config or command that still names action fails and says where Actions run now.

     // sixb.deploy.ts
     workers: {
    -  types: ["action", "sync", "workflow"],
    -  concurrency: { action: 1, sync: 4 },
    +  types: ["sync", "workflow"],
    +  concurrency: { sync: 4 },
     },

    The package remains on npm for earlier releases. Never run it against the new schema, and do not delete shared Redis data to retire its old queue.

  • Read the run from the request. requestActionAndWait and waitForActionRun are removed, along with their option and result types.

    -import { requestActionAndWait } from "@sixb/client"
    +import { requestAction } from "@sixb/client"
    
    -const run = await requestActionAndWait({
    +const { data: run } = await requestAction({
       path: { actionId: "markPaid" },
       body: { subject, params: {} },
    -  timeoutMs: 30_000,
    +  throwOnError: true,
     })
    +
    +if (run.status === "failed") console.error(run.error?.message)

    ActionRunTimeoutError, the queued, running, and cancelled run states, and queuedAt are removed. When you call the API through the raw SDK, check status: a failed run is not an error response. useActionRunMutation still raises ActionRunFailedError for a failed run, and its timeoutMs option is removed.

  • Move off Action events. action.requested, action.completed, action.failed, the actions topic, events.action(...) selectors, and the actionId WebSocket filter are removed. React to the object and link events of the committed edits instead. They carry origin: { kind: "action", actionId, runId }. You can also move the dependent work into a workflow.

     export const invoicePaid = defineSchedule("invoice-paid")
    -  .on(events.action(markPaid).completed())
    +  .on(events.object(Invoice).updated())
    +  .where((event) => event.object.p.status.eq("paid"))

Behavior to check

  • There is no durable queue. A run is recorded when it ends. There is no automatic redelivery and no lock across processes. A crash can leave no record even after an external call, and two processes given the same runId can both execute. In the same process, a repeated runId gets action.run_in_progress (409) while the first request runs. Pass run.idempotencyKey to external systems, and reconcile an uncertain outcome before retrying. A missing run does not prove that no work happened.
  • The time limit is not a hard stop. A writeback that ignores its signal keeps the request open, and a handler that timed out can continue its own external work. Effects run only when edits are committed, are never replayed, and may never record an outcome. Review your proxy timeouts and process shutdown limits.
  • Not every read is checked for conflicts. Object and link reads are checked. New rows matching a query, count, exists, facets, telemetry, and file reads are not. A condition such as a limit on count() can pass in two concurrent runs, and both commit. An action.read_conflict can follow a successful writeback, so a new run must not repeat that external operation blindly.
  • Request bodies over 1 MiB now get a 413, except on file upload routes.

Package versions

Version Packages
0.1.19 @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator, @sixb/pg, @sixb/sqlite, @sixb/agent-worker, @sixb/pipeline-worker, @sixb/projection-worker, `@sixb...
Read more

Sixb 0.1.18

Choose a tag to compare

@demattosanthony demattosanthony released this 11 Oct 22:56

Sixb 0.1.18

This release adds markings for sensitive data, lets agent tools work with project data as the person who asked, gives the agent project instructions and ontology notes, and adds a project language and time zone. It also closes four access gaps, so upgrading is recommended. There are no database migrations.

Highlights

Hide sensitive properties and columns with markings

A role that can view Invoice used to read every invoice property. Mark the sensitive ones, and only roles with the matching clearance read them.

// security/markings/financial.ts
export const financial = defineMarking("financial", { label: "Financial" })

// ontology/invoice.ts
prop("amount", "decimal", { markings: [financial] })

// datasets/raw-invoices.ts
col("amount", "decimal", { markings: [financial] })

// security/roles/finance-analyst.ts
export const financeAnalyst = defineRole("finance-analyst", {
  grantedTo: [finance],
  grants: [can.view(Invoice)],
  clearances: [financial],
})

Readers without the clearance still get the object. The marked value is left out and listed in redactions:

{
  "primaryId": "inv-1",
  "properties": { "id": "inv-1", "title": "July maintenance" },
  "redactions": { "amount": { "reason": "missing_clearance" } }
}

Filtering, sorting, faceting, or searching by a property the caller is not cleared for is rejected with a 403. See Markings.

Agent tools act as the person who asked

A tool handler now receives sixb, which reads objects, requests actions, resolves connectors, and calls models with the requester's permissions: the signed-in user in a chat, the step's groups in a workflow. Model calls made by a tool count toward the run's usage and limits.

attachments.open(key) opens a file attached to the run, so a tool can pass it to an external service:

export const extractDocument = defineAgentTool("extract_document")
  .description("Extract the text and tables of an attachment. Pass its key.")
  .input({ key: "string" })
  .run(async ({ input, signal, sixb, attachments }) => {
    const file = await attachments.open(input.key)
    if (!file) throw new AgentToolPublicError("The attachment is no longer available.")
    const extraction = await sixb.connector(documentExtraction)
    return extraction.extract(file.body, { fileName: file.fileRef.fileName, signal })
  })

See Use project data in a tool.

Tell the agent about your project

Write guidance for every conversation in a SIXB.md at the project root:

Answer in French. Amounts are in euros, excluding VAT.
A "dossier" is a `Case`; always mention its reference.

The agent also reads a reference file for each object type, written from your ontology and limited to what its requester can see. Add what the definitions cannot say in a Markdown file next to the type:

<!-- ontology/invoice.md, next to ontology/invoice.ts -->
An invoice is overdue 30 days after it is sent, not after its due date.

Scripts in a scripts/ folder under ontology/ are mounted in the agent's sandbox, for work it would otherwise rebuild on every question.

Skills and SIXB.md are now discovered by createSixb(): sixb check validates them, and sixb dev restarts when they change.

See Project instructions and Explain it to the agent.

Project language and time zone

export const sixb = createSixb({
  id: "my-app",
  locale: "fr-FR",
  timeZone: "Europe/Paris",
})
Option Default Used by
locale "en" The language app pages declare, and the fallback language of the built-in chat.
timeZone "UTC" Cron schedules without their own time zone, and the local time the agent works in.

The text Sixb writes itself is now translated into English and French: @sixb/ui components, the agent chat, and the screens @sixb/app generates. It follows the user's browser languages and falls back to the project's locale. Your own content is shown as you wrote it, and Atlas stays in English.

Reword any message with UiLabelsProvider or AgentLabelsProvider:

<AgentLabelsProvider labels={{ chat: { placeholder: "Ask about an order" } }}>
  <AgentSurface />
</AgentLabelsProvider>

See Language and time zone.

Default reasoning per model

const glm = vercelGateway("zai/glm-5.3-flash", { reasoning: "low" })

createSixb({ models: { language: [glm, openaiModel] } })

The default applies wherever the model runs without an explicit choice: chat messages, AI workflow tasks, and generate() calls. Chat follows the project defaults until the user picks a model or an effort. See Default reasoning.

Also in this release

  • Read dataset rows as the caller with sixb.datasets.readRows(dataset, { limit: 100 }). Columns the caller is not cleared for are left out.
  • Open a file property through its object with sixb.objects(Invoice).byId("inv-001").file(Invoice.p.pdf).open(). It returns the fileRef and a body stream, checked against the caller's permissions.
  • Interrupted turns are no longer replayed. A chat turn whose worker stopped or died ends as interrupted, without calling the model again. The chat offers Continue when progress was saved and Try again otherwise.
  • Answers attach only what the agent produced: files returned by project tools and files published to $SIXB_OUTPUT_DIR. Files it only viewed stay in the work trace.
  • Object context shows the object's title instead of its id. Set your own with agentContext.object(Project, project.id, { label: project.name }).
  • sixb atlas and sixb app no longer load the project. They use about a third of the memory and need neither the project's secrets nor its database.
  • Atlas and custom apps show an error screen with a Retry button when the API is unreachable, instead of a blank page.
  • sixb dev starts agent turns once the API listens, and a turn that starts while the API restarts waits up to eight seconds for it.
  • Fixed: requesting several columns of dataset rows failed with a 422.
  • sixb objects query --help lists every query node and predicate shape, with examples.

Security fixes

  • Link traversal. Following or expanding a link could return rows of a subtype the caller was not allowed to view. Such a query is now denied.
  • OIDC sign-in. A callback URL opened in another browser could sign that browser in to the original person's account. Sign-in now completes only in the browser that started it.
  • Access tokens. An access token could create another token with more groups or a later expiry than its own. Creating a token now requires a signed-in session.
  • File responses. A crafted media type could make a stored file open as a page on the API origin. File routes now send only well-formed media types, with a Content-Security-Policy that blocks script.

Upgrading

Upgrade the packages in the table below together, then rebuild your application assets. No database migrations are needed.

Required changes

  • OIDC: upgrade @sixb/auth-oidc to 0.1.5 with the server. Sign-in fails against the earlier version. The provider's callback URL must use the same host as the API URL your app signs in through. A custom OIDC strategy must return state and expiresAt from startOidcSignIn.

  • Agent tools: connector moved to sixb.connector.

    // Before
    .run(async ({ input, connector }) => {
      const knowledge = await connector(knowledgeConnector)
    })
    
    // After
    .run(async ({ input, sixb }) => {
      const knowledge = await sixb.connector(knowledgeConnector)
    })
  • Workflow AI tasks now receive only the skills they list. They received every skill before.

    defineAgentStep("draft-reminder", {
      instructions: "Read the invoice and draft a reminder. Do not send it.",
      groups: [finance],
      skills: ["invoice-review"],
    })
  • Types: AgentReasoningLevel is removed. Use AgentReasoning.

  • Ontology folders: files in a scripts/ folder under ontology/ are no longer imported as definitions. Move any definition out of those folders.

Behavior to check

  • Token creation: scripts that created tokens with an access token now receive a 403. Create tokens in Atlas or from a profile signed in with sixb login. Access tokens can still list and revoke tokens and manage service accounts.
  • Excluded subtypes: a role such as can.view(every.object().except([ConfidentialDocument])) now also loses queries that follow or expand a link to that subtype's parent type.
  • Media types: a file's mediaType must be a single type such as application/pdf, and writes reject anything else. Files stored earlier with a malformed type download as application/octet-stream. Opened directly, only common raster images, PDF, plain text, Markdown, and JSON display in the browser. Other types, including HTML and SVG, download.
  • Startup checks: an invalid SKILL.md now fails sixb check and startup. So does a reasoning effort or token budget the model does not declare support for, on a workflow AI task or as a model default.
  • Agent runs over the API: handle finishReason: "interrupted" on a cancelled run and the step_limit_reached diagnostic with scope run. Continuing a cut-short answer is continue: true on the message request, and Sixb no longer writes its own text into the transcript.
  • Schedules: cron schedules without their own time zone keep running in UTC until you set timeZone.
  • Markings: a marked property is optional when read in TypeScript, even if require...
Read more

Sixb 0.1.17

Choose a tag to compare

@demattosanthony demattosanthony released this 09 Oct 13:45

Sixb 0.1.17

Highlights

  • Rerank vector search results with a model: register a reranker such as
    vercelGateway.reranking("voyage/rerank-2.5-lite") and opt in per query with
    .rerank({ model }).
  • Transcribe stored audio with sixb.models.audio.transcribe({ audio }), starting with Vercel AI
    Gateway transcription models. Atlas shows transcription duration and cost with other model calls.
  • Hand a stored file to services that fetch media from a URL, such as Instagram and TikTok, with
    sixb.blobs.createDownloadUrl(), and revoke one early with sixb.blobs.revokeDownloadUrl().
    Shared-link pages now play video and audio.
  • Let people connect their own Google accounts through Sixb-managed OAuth with
    google({ auth: { oauth: { clientId, clientSecret, scopes, hostedDomain } } }).
  • Read and sync Outlook contacts and contact folders, and the tenant's organizational contacts,
    with the Microsoft connector's client.contacts and client.directory.contacts.
  • Serve large PostgreSQL object lists, deep cursor pages, and relationship queries from bounded
    index scans, and prepare indexes from ontology declarations. Declare recurring sorts and text
    counts with defineObjectType({ query: { indexes } }); sixb db prepare prepares them on demand.
  • Plan projection publications outside the commit transaction and recheck only what intervening
    commits touched, so large publications no longer hold locks for minutes or restart under
    concurrent edits. Outbox events are stored as compact drafts, about 70% smaller.
  • Remove idle background polling: projection reconciliation tails a lake change feed, vector
    indexing is dispatched when its commit lands, the rules worker reconciles only at startup and
    after a failure, event sockets share one broker subscription per API process, queue claims wait
    for work, and source-version cleanup no longer walks history. Atlas polls projection runs only
    while one is pending.
  • Fix a redelivered agent resume re-running workflow steps after the run had moved past the agent
    node, and first-time sixb deploy setup on projects whose .env holds a GITHUB_TOKEN or whose
    server has no Node.

Upgrade notes

  • Upgrade core, exact worker/storage consumers, server, client, and CLI together to 0.1.17.
    Upgrade DuckLake to 0.1.8, lake-local to 0.1.6, and BullMQ queues to 0.1.6 at the same
    time: the orchestrator now requires the lake change feed, and queue workers require a claim that
    waits for work. Upgrade Atlas to 0.1.14 and the app package to 0.1.10, and rebuild
    application assets. Reranking and transcription require Vercel AI Gateway 0.1.6.
  • Apply PostgreSQL migrations 053–060 and SQLite migrations 053–059 with old runtime roles
    stopped. Migration 054 rewrites the outbox into compact drafts, refuses to convert if any stored
    event would not rebuild exactly, and drops requested_by and executor from commits. The
    migrations also add replacement-plan and commit-touch tables (UNLOGGED on PostgreSQL), drop
    PostgreSQL's whole-document JSON index on objects, and recount superseded source versions.
    Rehearse on a representative 0.1.16 database backup and measure downtime and disk/WAL
    requirements. Rollback requires a database backup and matching binaries, not just an older
    application commit. With SQLite, migrate once before starting additional roles with
    --no-migrate.
  • On PostgreSQL, startup and sixb db migrate now prepare declared query indexes after migrations.
    Initial text preparation rewrites the objects table and blocks writes: run sixb db migrate
    ahead of deployment when needed. --no-migrate and SIXB_SKIP_MIGRATION=1 skip preparation too.
    Indexes add disk and write cost, and removing a declaration does not drop its index.
  • .facets() returns { total, facets } instead of an array, in the SDK, HTTP API, generated
    client, and query hooks.
  • Queue workers no longer accept idlePollMs. A third-party queue provider must honor
    claim({ signal }) by waiting until it claims a job or the signal aborts: a worker now fails
    when a claim returns empty first. A third-party lake storage provider must implement
    listLatestVersionsSince(). /status no longer reports maintenance.terminalSources.
  • Token limits now apply only to token-billed calls: transcription and reranking skip them, while
    cost limits still apply, and a call is refused when an applicable budget cannot be evaluated.
    Reranking is bounded to 100 candidates, 1 MiB of input, and a 30-second model call. Neither
    reranking nor transcription inference is retried automatically.
  • Set SIXB_API_PUBLIC_ORIGIN for the API and every worker that creates download URLs. Anyone
    holding a URL can read its file until it expires (one hour by default) or is revoked.
  • Google OAuth requires an OAuth client registered for your deployment. Disconnecting deletes the
    stored tokens but does not revoke the Google grant. An interrupted Microsoft contact write is not
    retried and throws a MicrosoftContactMutationError with outcomeUnknown; check before writing
    again.

Package versions

  • 0.1.17: @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator,
    @sixb/pg, @sixb/sqlite, @sixb/action-worker, @sixb/agent-worker, @sixb/pipeline-worker,
    @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker.
  • 0.1.14: @sixb/atlas.
  • 0.1.10: @sixb/app.
  • 0.1.8: @sixb/ducklake.
  • 0.1.7: @sixb/connector-google.
  • 0.1.6: @sixb/lake-local, @sixb/queues-bullmq, @sixb/vercel-ai-gateway.
  • 0.1.5: @sixb/connector-meta, @sixb/connector-tiktok.
  • 0.1.3: @sixb/blob-s3, @sixb/connector-microsoft.
  • 0.1.1: @sixb/deploy-ssh.

Changes since v0.1.16

Sixb 0.1.16

Choose a tag to compare

@demattosanthony demattosanthony released this 09 Oct 12:25

Sixb 0.1.16

Highlights

  • Scope vector searches with traversals, explicit object references, or set operations before
    ranking. Resolve the vector profile on the resulting concrete object type and apply object,
    link, and source-property authorization before selecting the nearest results.
  • Send separate document and query purposes through embedding execution. Vercel AI Gateway
    translates them for Voyage 4, Voyage 4 Lite, Voyage 4 Large, and Cohere Embed v4.0, with
    retrieval-aware model identity, disabled truncation, and conservative batching bounds.
  • Preserve embedding purpose through Azure AI Foundry model resolution and expose optional
    inputMode in ontology API responses and generated client types.
  • Reduce SQLite vector-list work to one bounded candidate scan for admission, ranking, and
    totals, hydrate results after top-k selection, and improve authorized traversal query plans.

Upgrade notes

  • Upgrade core, exact worker/storage consumers, server, client, and CLI together to 0.1.16.
    Upgrade Vercel AI Gateway to 0.1.5 and Azure AI Foundry to 0.1.3 when used. No new SQL
    migration is introduced after 0.1.15; deployments upgrading from older releases must still
    apply their intervening migrations and upgrade notes.
  • Existing Voyage/Cohere vector profiles now use asymmetric document/query preparation. This
    changes their vector configuration identity: old vectors no longer match searches with the
    new configuration. Explicitly reindex existing objects; a configuration change alone does not
    trigger a historical backfill. Plan provider costs and reduced search coverage until indexing
    completes. Unchanged symmetric profiles retain their previous configuration identity.
  • Direct embedding calls to the supported Voyage/Cohere bindings must supply
    purpose: "document" or purpose: "query". Sixb indexing and text search supply it automatically.
    Custom embedding adapters and wrappers should preserve the optional purpose field and declare
    asymmetric input mode when preparation differs. Byte batching bounds are not token guarantees.
  • Vector ranking still requires one concrete result type. Pagination, expansion, traversal after
    ranking, and combined keyword/vector search remain unsupported. SQLite rejects candidate-budget
    overflow instead of silently ranking a truncated set; narrow the candidate scope when needed.
  • The Gateway adapter retains a route-specific Voyage output-dimension override because the
    common dimensions field was observed to be ignored on that route. Validate actual dimensions
    and retrieval quality against the configured live provider before reindexing production data.

Package versions

  • 0.1.16: @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator,
    @sixb/pg, @sixb/sqlite, @sixb/action-worker, @sixb/agent-worker, @sixb/pipeline-worker,
    @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker.
  • 0.1.5: @sixb/vercel-ai-gateway.
  • 0.1.3: @sixb/azure-ai-foundry.

Changes since v0.1.15

Sixb 0.1.15

Choose a tag to compare

@quentinnippert quentinnippert released this 05 Oct 14:20

Sixb 0.1.15

Highlights

  • Deploy committed projects over SSH with sixb deploy, defineDeploy from @sixb/core/deploy,
    and the new @sixb/deploy-ssh target. Set up servers, supervise services, configure HTTPS,
    manage deploy access, and generate a GitHub Actions deployment workflow.
  • Resume projection candidates across retries, supersede stale object/link projection runs, and
    show the last attempt's failure while a run is retrying. Rebind a projection to another dataset
    without changing its ID, withdrawing obsolete source values while preserving application edits.
  • Compact PostgreSQL and SQLite source storage and reclaim abandoned projection candidates sooner.
  • Improve PostgreSQL connection-loss handling, explain exhausted lock-table errors, and support
    explicit direct TLS connections with sslnegotiation=direct.
  • Add the FullEnrich connector for enrichment, reverse email lookup, search, signed webhooks, and
    agent tools. Add Microsoft drive-item previews and connector icons and sync filtering in Atlas.
  • Make sixb check exit after printing its report even when provider handles remain open.
  • Add the Plaud connector for recordings, transcripts, notes, and audio downloads, with
    Sixb-managed OAuth connections and token refresh.

Upgrade notes

  • Upgrade core, exact worker/storage consumers, server, client, and CLI together to 0.1.15,
    Atlas to 0.1.13, and the Microsoft connector to 0.1.2. Rebuild application assets.
  • Apply PostgreSQL and SQLite migrations 051–052 with old runtime roles stopped. Migration 051
    admits the terminal projection status superseded and errors on retrying runs; SQLite rebuilds
    projection_runs. Migration 052 rewrites source roots and rows with compact numeric references;
    SQLite also rebuilds the source-version table. Rehearse on a representative 0.1.14 database
    backup, measure downtime and disk/WAL requirements, and verify projections after migration.
    Rollback requires a database backup and matching binaries, not just an older application commit.
    With SQLite, migrate once before starting additional roles with --no-migrate.
  • Handle superseded in projection status consumers. A running run may now have an error
    describing its last failed attempt; it is not necessarily terminal. Telemetry runs are not
    superseded. Abandoned source candidates no longer wait for terminalSourceRetentionMs and
    are cleaned in larger batches independently of cleanupLimit.
  • Direct PostgreSQL TLS requires one TCP endpoint supporting PostgreSQL ALPN (PostgreSQL 17+
    without an incompatible proxy/pooler) and an explicit TLS mode. Prefer verify-full for
    certificate and hostname verification; require does not verify the certificate. Existing
    TLS negotiation remains the default. The installed postgres.js 3.4.9 still has a known crash
    window when a connection disappears between statements; retain process supervision.
  • SSH deployment initially targets Ubuntu/Debian with systemd and Caddy. Only committed source
    is uploaded; keep secrets in the server's .env. Setup requires an administrator, and generated
    CI setup changes repository secrets and authorizes a deploy key. Deployment includes downtime;
    a failure after stopping services leaves them stopped. Deploying an older ref does not undo
    migrations. Separate deploy accounts are not isolation from the shared network or Caddy.
  • Authorize Microsoft file access before returning a preview: anyone holding its URL can use it.
    FullEnrich search/enrichment spends provider credits; expose only the intended agent tools.
  • Plaud requires registering an OAuth client for your deployment and enabling cloud sync.
    It follows the official Plaud MCP protocol rather than a guaranteed public account API;
    provider endpoints may change independently. Validate authorization and real account access.

Package versions

  • 0.1.15: @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator,
    @sixb/pg, @sixb/sqlite, @sixb/action-worker, @sixb/agent-worker, @sixb/pipeline-worker,
    @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker.
  • 0.1.13: @sixb/atlas.
  • 0.1.2: @sixb/connector-microsoft.
  • Initial 0.1.0: @sixb/connector-fullenrich, @sixb/connector-plaud, @sixb/deploy-ssh.

Changes since v0.1.14

Sixb 0.1.14

Choose a tag to compare

@quentinnippert quentinnippert released this 29 Sep 09:03

Sixb 0.1.14

Highlights

  • Configure OIDC sign-in for a single Microsoft Entra tenant with trustedEmail. Standard claims
    are typed, and providers sending email_verified as the string "true" are supported.
  • Map provider claims to Sixb groups with the OIDC groups option. Reconcile directory-owned
    memberships at each sign-in without removing memberships granted manually or by invitation.
  • Show identity-provider-managed groups in Atlas and prevent their removal through member editing.
    Member API responses now include managedGroupIds.
  • Explain refused OIDC sign-ins with actionable messages for uninvited or suspended users,
    disallowed domains, and providers that supply no trusted address.

Upgrade notes

  • Upgrade core, its exact worker/storage consumers, server, client, and CLI together to 0.1.14.
    Upgrade OIDC to 0.1.4, magic-link to 0.1.5, and Atlas to 0.1.12; rebuild application assets.
  • Apply PostgreSQL and SQLite migration 050 before enabling directory-managed groups. PostgreSQL
    replaces a source constraint; SQLite rebuilds auth_group_memberships and its group index,
    preserving existing memberships. Rehearse against a backup of a 0.1.13 database, stop old
    runtime roles before migrating, and plan rollback with a database backup and matching binaries.
    With SQLite, migrate once before starting multiple roles with --no-migrate.
  • OIDC strategies must supply a trusted address on every sign-in. The default requires a verified
    email; Entra deployments must explicitly configure trustedEmail, normally from
    preferred_username, and use a tenant-specific issuer, not common or organizations.
    Review account linking and invitation addresses before enabling a custom trust callback.
  • UserInfo is fetched only when the ID token lacks a trusted address. When fetched, ID-token claims
    take precedence. Ensure claims needed by your groups mapping are available in that flow.
  • A nonempty provider group mapping permits account creation without an invitation. Validate the
    mapping and provider assignments carefully. Membership changes apply at the next sign-in; suspend
    a user in Sixb when access must stop immediately. Omitting groups leaves existing directory
    memberships untouched; returning an empty array removes only directory-owned memberships.
  • A group already granted manually or by invitation retains its original source. Removing that
    group at the provider does not revoke the independently granted membership. Directory-owned
    groups cannot be removed through the member API or Atlas; edit them at the provider.
  • Custom auth strategies calling completeOidcSignIn must validate address trust before storage:
    emailVerified and autoLinkByVerifiedEmail were removed. The unused
    requireNoActiveUsersForUserCreation input was removed from OIDC and magic-link completion.
    Update explicit member response types and fixtures for the required managedGroupIds field.

Package versions

  • 0.1.14: @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator,
    @sixb/pg, @sixb/sqlite, @sixb/action-worker, @sixb/agent-worker, @sixb/pipeline-worker,
    @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker.
  • 0.1.12: @sixb/atlas.
  • 0.1.4: @sixb/auth-oidc.
  • 0.1.5: @sixb/auth-magic-link.

Changes since v0.1.13

Sixb 0.1.13

Choose a tag to compare

@demattosanthony demattosanthony released this 14 Oct 13:50

Sixb 0.1.13

This release signs the CLI and other tools outside the browser in with renewable sessions and adds user references to the ontology. Large file uploads now survive restarts and work across replicas. Actions detect changes to the objects their queries and lists return, and every commit records who requested it and what wrote it. The release also closes three gaps in client addresses and CLI login, and it includes database migrations 046–049.

Highlights

Sessions for the CLI and tools outside the browser

sixb login now signs the CLI in as you with a session rather than a 90-day access token. The session renews itself while you use it and ends after the API's idle timeout (30 days by default). It appears with your other sessions in Atlas, and sixb logout ends it.

Your own command-line tools can sign in the same way through the client SDK:

import { client, configureSixbClient, startSixbDeviceLogin } from "@sixb/client"

const login = await startSixbDeviceLogin({ baseUrl, clientName: "Acme CLI" })
openInBrowser(login.verificationUriComplete) // the user approves, and sees login.userCode
await store.save(await login.complete())

configureSixbClient(client, {
  baseUrl,
  auth: { kind: "session", store, onSessionEnded: () => showSignIn() },
})

Every API function, query, hook, and live subscription then uses the session, WebSockets included. The client renews its 15-minute access token before it expires. signOutSixbSession({ baseUrl, store }) ends the session on the server and clears the store.

Tools outside the browser and access tokens are now authorized by their grants alone, not by web app access. A project that opens Atlas only to admins no longer locks everyone else out of the CLI, and every user can approve their own CLI login.

See Tools outside the browser.

Reference users from your ontology

Use ref.user() for a property or Action parameter that names a member of your project:

import { prop, ref } from "@sixb/core/ontology"

prop("assignee", ref.user(), {
  nullable: true,
  query: { searchable: true, filterable: true, facet: true },
})
prop("reviewers", { type: "array", items: ref.user() })

The value is { type: "user", id }, and a write can only set a user who exists and is active. Build a value with userRef(id) and query it with eq, neq, in, exists, contains, and facet:

import { userRef } from "@sixb/core"

const me = userRef("usr_1")

await sixb
  .objects(Task)
  .query()
  .where((task) => task.or(task.p.assignee.eq(me), task.p.reviewers.contains(me)))
  .list()

Atlas shows user references as users. It now renders every value from its declared schema, so a string that merely looks like a date or an object that looks like a reference is no longer displayed as one.

See Reference a user.

Upload sessions survive restarts

PostgreSQL and SQLite now store file upload sessions, so a large upload continues across API restarts and on any replica. Expired sessions are refused. The API's maintenance pass aborts abandoned uploads in blob storage, so their multipart parts are no longer left in your bucket.

Actions detect changed query results

An Action's commit now also fails when an object returned by list() or query() changed after the Action read it. The run fails with action.read_conflict, and nothing is committed.

Checked Not checked
The target object and get(), even for a missing object Objects that start matching a query later
list(), query(), and expanded objects count(), exists(), and facets()
listLinks() Telemetry history

To depend on an object not existing yet, give it a deterministic ID and read it with get(). See Concurrent changes.

Know who changed what

Commits and their events now record two facts. requestedBy is the person a write was made for, and executor is the request or run that made it. This covers writes made through Actions, workflows, projections, syncs, and webhooks, which previously named nobody:

{
  "type": "object.updated",
  "requestedBy": { "type": "user", "id": "usr_1" },
  "executor": { "type": "primitive", "kind": "action", "id": "markPaid", "runId": "act_1" }
}

An agent image with documents, rendering, and a browser

ghcr.io/sixb-ai/sixb-agent:1.2.0 gives agents shell tools, Python and Node, data analysis, PDF and Office authoring, OCR, document previews, and Playwright with Chromium. Everything works offline, and any sandbox provider that boots an OCI image can use it. SmolVM boots it from a local archive:

import { SmolvmSandboxFactory } from "@sixb/sandboxes-smolvm"

createSixb({
  sandboxes: new SmolvmSandboxFactory({ image: `${homedir()}/.cache/sixb/sixb-agent.tar` }),
})

Also in this release

  • Semantic search from the CLI. sixb objects search "late delivery" --type Ticket searches through the type's vector profile, and sixb ontology list lists each type's profiles.
  • Publish to Instagram and Facebook with the Meta connector: Instagram images, Reels, and carousels, and Facebook photos, multi-photo posts, videos, and Reels.
  • Pass queries around. Type a parameter as ObjectQueryBuilder<typeof Invoice> to accept any query that returns invoices, including one with expand() or reached through traverse().
  • One set of SDK types. Server objects, Action and workflow reads, edits, and browser queries are all typed from the same generated ontology registry, so a query has the same types wherever you write it.
  • Sandbox commands resolve a relative working directory against the workspace, and SmolVM runs them in the guest's /workspace.

Security fixes

  • Client addresses. Session and access-token IP addresses were read from the first X-Forwarded-For entry, which any client can set. The API now reads only the entries appended by proxies it trusts.
  • CLI login availability. Starting a CLI login needs no authentication, and all pending logins shared one project-wide cap, so a single machine could keep everyone from logging in. Starts are now limited to 10 per client address every 10 minutes.
  • CLI sign-out. sixb logout did not revoke the 90-day token that login created, and signing out everywhere did not end it. CLI login now creates a session that both of them end.

Upgrading

Upgrade the packages in the table below together, then rebuild your custom app and Atlas assets.

Migrate the database

Apply PostgreSQL and SQLite migrations 046–049:

Migration Change
046 Normalizes intervention actors to { type, id }.
047 Replaces commit actor with requestedBy and executor, backfills existing commits, and rewrites unpublished outbox events.
048 Adds persistent upload sessions.
049 Adds session state for tools outside the browser, and removes the token name and expiration columns from device authorizations.

Stop old processes before migrating, and rehearse on a backup of a 0.1.12 database. Time migration 047 against realistic commit and outbox volumes. Old and new binaries are not safe to run side by side, so rolling back requires the database backup and the old binaries. With SQLite, migrate once before starting several roles with --no-migrate.

Required changes

  • Event attribution: read requestedBy and executor instead of actor on events and commits. The migration rewrites the database outbox, but not events you archived elsewhere, so update consumers that replay old events as well.
  • Types: update explicit SDK annotations to the shared ontology registry. EventActor, SecurityContext, RegisteredObjectType, RegisteredValueTypes, ActionReadObjectByIdHandle, ActionReadObjectSet, and ActionReadObjectSetSource are removed. Use ObjectReader, ObjectReadByIdHandle, and ObjectReadSet.
  • SmolVM: set image explicitly. A local archive boots offline and must match the host's architecture.

Behavior to check

  • Read conflicts: custom Action interfaces and integrations should handle action.read_conflict explicitly. A run that fails this way wrote nothing.

  • CLI login: after sixb login, the CLI holds a renewable session. Profiles that use a personal access token still work. Check login, refresh, logout, and live subscriptions after upgrading, and deploy the new CLI and client with the new server.

  • Trusted proxies: by default the API trusts proxies on loopback, private, and link-local networks. If a proxy with a public address, such as a CDN, sits in front, add its ranges:

    export SIXB_TRUSTED_PROXIES=private,173.245.48.0/20,103.21.244.0/22
  • Upload sessions: the /api/files/uploads routes answer 501 when storage does not provide upload sessions. Single-request uploads through POST /api/files are not affected.

  • Agent image: the image is versioned separately from npm. Pin a verified digest in production; the framework version is not an image tag.

Package versions

Version Packages
0.1.13 @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator, @sixb/pg, @sixb/sqlite, @sixb/action-worker, @sixb/agent-worker, @sixb/pipeline-worker, @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker
0.1.11 @sixb/atlas
0.1.10 @sixb/agent-ui
0.1.6 @sixb/cli-core, @sixb/sandboxes-apple-container, @sixb/sandboxes-local, @sixb/sandboxes-smolvm, @sixb/sandboxes-vercel
0.1.4 @sixb/connector-github, @sixb/connector-mercury, @sixb/connector-meta
0.1.3 @sixb/connector-companycam, @sixb/connector-pandadoc, @sixb/connector-pipedrive, @sixb/connector-stripe, @sixb/connector-unipile

[Cha...

Read more

Sixb 0.1.12

Choose a tag to compare

@quentinnippert quentinnippert released this 24 Sep 21:43

Published packages are available on npm under latest.

Highlights

  • Introduce named vector profiles, automatic batched indexing, server-side text embedding for search, PostgreSQL and SQLite search, and Atlas profile visibility. Add Foundry embeddings with pinned representation identity and usage accounting.
  • Add typed decision evaluation, the TypeSafe provider, and Vercel AI Gateway decision models.
  • Persist conversation sandbox files across runs, recover confirmed lost state, and configure source/setup environments. Add execution-scoped GitHub App access to private repositories.
  • Unify Agent surfaces and preserve conversation state across navigation.
  • Add the Monday connector, LinkedIn and TikTok media publishing, Google Drive streaming downloads, and QuickBooks documents, attachments, and aging reports.
  • Preserve safe error explanations across runtime boundaries.

Upgrade notes

  • Upgrade core, exact worker/storage consumers, and CLI together to 0.1.12. Upgrade sandbox providers and rebuild custom-app and Atlas assets.
  • Apply PostgreSQL and SQLite migrations 041–045. SQLite 043 rebuilds executions; PostgreSQL 043 changes execution constraints. Stop old runtime roles and rehearse against a backup of a 0.1.11 database. Plan rollback through database restoration and matching old binaries. With SQLite, migrate once before starting multiple roles with --no-migrate.
  • Replace removed query.vector and search.vector metadata with named search.vectors profiles. Adapt queries and reindex; do not assume legacy embedding properties migrate automatically.
  • Vector persistence needs no extension. PostgreSQL search requires pgvector in the public schema. SQLite search loads sqlite-vec; macOS requires an extension-capable SQLite library configured before connections open. Search is exact and bounded to 10,000 eligible vectors and 16 million coordinates.
  • Review third-party sandbox implementations against the new creation, resume, and execution-prepared authentication contracts. Bound conversations require a persistence-capable provider; workflows and subagents remain ephemeral.
  • Confirmed lost sandbox state may be recreated without restoring local edits. Uncertain state blocks further runs until explicit recovery. Provider retention still applies. Normal cleanup revokes managed GitHub access; a worker crash cannot guarantee immediate revocation. Never put credentials in guest-readable environment variables or thread parameters.
  • Replace the removed ThreadSidebar export. AgentWorkspaceProvider no longer accepts sidebarHeader, sidebarFooter, or sidebarWidth; adapt custom Agent layouts.

Versions

  • 0.1.12: @sixb/core, @sixb/client, @sixb/server, @sixb/cli, @sixb/orchestrator, @sixb/pg, @sixb/sqlite, @sixb/action-worker, @sixb/agent-worker, @sixb/pipeline-worker, @sixb/projection-worker, @sixb/rules-worker, @sixb/sync-worker, @sixb/workflow-worker.
  • 0.1.9: @sixb/agent-ui, @sixb/app.
  • 0.1.10: @sixb/atlas.
  • 0.1.2: @sixb/azure-ai-foundry.
  • 0.1.4: @sixb/vercel-ai-gateway, @sixb/connector-tiktok.
  • 0.1.5: @sixb/queues-bullmq, @sixb/sandboxes-apple-container, @sixb/sandboxes-local, @sixb/sandboxes-smolvm, @sixb/sandboxes-vercel.
  • 0.1.1: @sixb/sandboxes-azure, @sixb/connector-quickbooks.
  • 0.1.3: @sixb/connector-github.
  • 0.1.6: @sixb/connector-google.
  • 0.1.7: @sixb/connector-linkedin.
  • 0.1.0, first publications: @sixb/typesafe, @sixb/connector-monday.

Full changelog: v0.1.11...v0.1.12