Commit Graph
4 Commits
Author SHA1 Message Date
Nicky LeachandPaperclip 445547c989 feat(duplex): run the Daytona sandbox callback bridge over Node HTTP/2 (#12120)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Sandbox providers carry agent work through controlled execution
channels
> - The Daytona callback bridge uses a bespoke line-framed protocol over
its duplex channel
> - The bespoke protocol adds framing work and does not use the Node
transport that already supports multiplexed streams
> - This pull request carries raw bytes across the channel, adds a Node
HTTP/2 bridge, and selects it for Daytona
> - The benefit is one authenticated, multiplexed callback session with
queue_v1 as the bounded fallback

## Linked Issues or Issue Description

**Subsystem affected**

The packages/plugins Daytona provider and the shared duplex execution
path.

**Problem or motivation**

The Daytona callback bridge uses a bespoke line-framed protocol over the
provider duplex channel. This adds protocol work and limits stream
handling.

**Proposed solution**

Carry raw bytes through the cross-layer channel. Add an authenticated
Node HTTP/2 host server and sandbox client gateway. Select http2_v1 for
Daytona and retain queue_v1 as the fallback.

**Alternatives considered**

Keep the current duplex_v1 protocol. This keeps the bespoke framing path
and does not provide one HTTP/2 session for callback streams.

**Roadmap alignment**

ROADMAP.md lists Daytona under cloud and sandbox agents. This change
improves the shipped Daytona provider path.

**Additional context**

The branch adds no dependency. Node 24 provides the http2 module. The
host token check and canonical path parser remain the single dispatch
path.

## What Changed

- Carry raw Uint8Array chunks through the adapter, plugin, worker,
runtime, and Daytona layers.
- Encode bytes as base64 only across the JSON-RPC hop, because JSON has
no binary type.
- Add the bounded host HTTP/2 server and the in-sandbox HTTP/2 client
gateway.
- Authenticate every stream with the per-run bridge token before route
work.
- Parse the path once and reuse the canonical result for route and
forwarding work.
- Select http2_v1 for Daytona and fall back once to queue_v1 when the
client preface is absent.
- Add transport, session, stream, and fallback telemetry.
- Mark HTTP/2 as the preferred transport and queue_v1 as the
soft-deprecated fallback.

## Verification

- `npx vitest run packages/adapter-utils/src` — 990 passed and 4
skipped.
- `npx vitest run
server/src/__tests__/plugin-worker-manager-duplex.test.ts` — 32 passed.
- `npx vitest run --config
packages/plugins/sandbox-providers/daytona/vitest.config.ts` — 220
passed and 6 skipped.
- `npx tsc --noEmit` in `packages/adapter-utils`, `packages/shared`,
`packages/plugins/sdk`, and `server` — clean.
- No `package.json` or `pnpm-lock.yaml` file changed.
- The live Daytona test skips when `DAYTONA_API_KEY` is absent.
- The root `npx tsc --noEmit` command has a pre-existing missing
`packages/adapters/droid-local` reference on this branch and on
`master`.

## Risks

- The transport change affects several duplex layers and could expose
byte-boundary errors.
- A missing HTTP/2 client preface falls back once to queue_v1 and
records `preface_missing`.
- The host token check and canonical path parser must remain on the
shared dispatch path.
- The live Daytona test needs `DAYTONA_API_KEY` and does not run in this
agent sandbox.

## Model Used

OpenAI GPT-5, tool-enabled coding agent with repository inspection,
GitHub CLI, and shell execution.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-25 07:35:39 -07:00
Nicky LeachandPaperclip d1573244b5 refactor: disambiguate the Telemetry and Observability data paths (#12128)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip records first-party events, OpenTelemetry data, and local
run-log events
> - The code and documents used one term for these three data paths
> - This naming made the required review level unclear
> - This pull request names each data path in the module names,
documents, and code comments
> - The benefit is a clear review rule without a runtime change

## Linked Issues or Issue Description

**Issue type**

Unclear or confusing.

**Where is the issue?**

`packages/shared/src/telemetry/README.md`, `doc/observability.md`,
`doc/run-log-events.md`, and the duplex instrumentation modules.

**What's wrong?**

The repository used Telemetry for first-party events, OpenTelemetry
data, and local run-log events. This usage made the data path and review
level unclear.

**Suggested fix**

Use Telemetry only for Paperclip first-party events. Use Observability
for OpenTelemetry data. Use the run log for rows in
`heartbeat_run_events`.

Related public pull requests: #8476 and #9672.

## What Changed

- Rename the duplex instrumentation modules and identifiers from
`Telemetry` to `Observability`.
- Move the Observability and run-log contracts out of the Telemetry
README.
- Add `doc/observability.md` and `doc/run-log-events.md` as the
canonical documents.
- Add a file-path review rule to `AGENTS.md`.
- Correct the remaining code comments that name the wrong data path.
- Keep all event names, payloads, database records, spans, configuration
keys, environment variables, and runtime paths unchanged.

## Verification

- `npx vitest run packages/shared/src/telemetry/readme-contract.test.ts`
passes.
- `npx vitest run packages/adapter-utils/src/published-exports.test.ts`
passes.
- `npx vitest run
packages/adapter-utils/src/acpx-engine/startup-timing.test.ts` passes
with 42 tests.
- `pnpm --filter @paperclipai/adapter-utils typecheck` passes.
- `pnpm --filter server typecheck` passes.
- The old module name does not remain in TypeScript or JSON files,
except for the intentional publication guard.
- CI and Greptile checks remain pending after PR creation.

## Risks

- The old duplex module subpath no longer has a compatibility shim. The
board accepted this intentional hard break.
- The new duplex module subpath stays blocked from package publication.
- The change has no runtime effect. The main risk is an incorrect
document or module reference.

## Model Used

OpenAI GPT-5 Codex, exact model ID `gpt-5`, with tool use and code
review support.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have described the issue in-PR with the documentation issue
fields
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-24 16:42:33 -07:00
Nicky LeachandPaperclip 5a1ce7aed8 fix(server): stamp built commit into service.version (#11748)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The server emits OpenTelemetry spans so operators can trace agent
work
> - Each span needs a service version that identifies the code that
produced it
> - The current service version comes from a static environment value
and can become stale after a rebuild
> - This pull request records the built commit and resolves the service
version from the build stamp, runtime Git, the environment, or an
unknown fallback
> - The benefit is trace data that identifies the correct built commit
during development and deployment

## Linked Issues or Issue Description

**What happened?**

The server used a static `OTEL_SERVICE_VERSION` value for every
OpenTelemetry span. Rebuilds could produce traces with an old commit
value.

**Expected behavior**

The server should report the built commit when a build stamp exists. It
should use runtime Git, the environment value, or `unknown` as fallback.

**Steps to reproduce**

1. Set `OTEL_SERVICE_VERSION` to an old commit value.
2. Build the server at a different commit.
3. Start the server and inspect the OpenTelemetry service version.
4. Confirm that the built commit takes precedence over the old
environment value.

## What Changed

- Add a build script that writes the short Git commit to
`dist/build-info.json`.
- Resolve `service.version` from the build stamp, runtime Git, the
environment, or `unknown`.
- Log the resolved service version once during server startup.
- Add tests for the resolution order and safe behavior without Git.
- Document the resolution order in `doc/observability.md`.

## Verification

- `pnpm --filter @paperclipai/server build`
- `npx vitest run server/src/__tests__/service-version.test.ts`
- `pnpm --filter @paperclipai/server typecheck`
- Confirm that the build stamp contains the short commit.
- Confirm that the stamp wins over the environment value.
- Confirm that a build without Git exits successfully without a stamp.

## Risks

The server now prefers the built commit over `OTEL_SERVICE_VERSION`. A
build without Git uses the existing environment value or `unknown`. The
change needs no schema migration and has a single-commit rollback path.

## Model Used

OpenAI Codex, GPT-5, tool use and code execution. The runtime does not
expose the context window size or reasoning mode.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-19 21:20:40 -07:00
Jannes StubbemannandClaude Opus 4.7 362c30ccdc feat(server): opt-in OpenTelemetry auto-instrumentation (#3735)
## Thinking Path

> - Paperclip orchestrates AI agents for zero-human companies
> - Production self-hosters increasingly expect telemetry out of the box
— Jaeger, Tempo, Honeycomb, Datadog, Grafana Cloud, Dynatrace all speak
OTLP
> - Today there is no OpenTelemetry bootstrap in the server, so
operators who want traces have to patch their fork or run a sidecar that
captures only HTTP-level info
> - An opt-in bootstrap that costs nothing when disabled is the
minimum-viable surface for this audience
> - The OpenTelemetry packages are heavyweight enough that we don't want
them in the default dependency graph — they should load only when the
operator configures an OTLP endpoint
> - This pull request adds a self-contained
`server/src/instrumentation.ts` that dynamically imports the OTel SDK
and starts it when `OTEL_EXPORTER_OTLP_ENDPOINT` is set, and is a
complete no-op otherwise

## Linked Issues or Issue Description

No existing issue covers this directly — feature-gap description
following the feature-request template:

**Problem or motivation**

Production self-hosters increasingly expect telemetry out of the box —
Jaeger, Tempo, Honeycomb, Datadog, Grafana Cloud, Dynatrace all speak
OTLP — but the server has no OpenTelemetry bootstrap. Operators who want
traces today must patch their fork or run a sidecar that captures only
HTTP-level information.

**Proposed solution**

An opt-in OTel bootstrap gated on `OTEL_EXPORTER_OTLP_ENDPOINT`, loaded
via dynamic `import()` only when configured, so the heavyweight OTel
packages stay out of the default dependency graph.

**Alternatives considered**

Related open PRs found during the duplicate-PR search approach
observability differently: #4894 adds OTLP instrumentation to Paperclip
core unconditionally, and #3752 proposes an observability plugin. Not
duplicates — different layering: this PR keeps the default install
dependency-free via opt-in dynamic import.

## What Changed

- New `server/src/instrumentation.ts` — opt-in OpenTelemetry
auto-instrumentation. Gated on `OTEL_EXPORTER_OTLP_ENDPOINT`. Respects
the standard OTel env vars (`OTEL_SERVICE_NAME`, `OTEL_SERVICE_VERSION`,
`OTEL_EXPORTER_OTLP_ENDPOINT`). Skips the fs/dns/net
auto-instrumentations (too chatty). `sdk.start()` is wrapped in
try/catch so a bad endpoint or missing native bindings doesn't crash the
server. `process.once("SIGTERM" / "SIGINT", …)` for clean shutdown on
the first signal only. OTel packages are loaded via dynamic `import()`
so they are true optional runtime dependencies — no entries in
`package.json`, no lockfile churn.
- `server/src/index.ts` — import `./instrumentation.js` as the very
first statement so auto-instrumentation can patch `http` / `express` /
`pg` before they are evaluated by downstream modules.

## Verification

- `OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317 pnpm start` after
`pnpm install
@opentelemetry/{sdk-node,auto-instrumentations-node,exporter-trace-otlp-grpc,resources,semantic-conventions}`
in `server/` — traces show up in the configured collector; HTTP,
Express, and Postgres spans are populated.
- `OTEL_EXPORTER_OTLP_ENDPOINT` unset — server starts with no
OTel-shaped output in logs, no behavior change.
- `OTEL_EXPORTER_OTLP_ENDPOINT=…` set but packages not installed —
single `console.warn` at startup telling the operator which packages to
install.

## Risks

Low. No behavior change unless the env var is set. The bootstrap never
throws into the caller; every failure path ends in `console.warn` /
`console.error` and falls through to non-traced operation.

## Model Used

Claude Opus 4.6 (1M context), extended thinking mode.

## Checklist

- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] Thinking path traces from project context to this change
- [x] Model used specified
- [x] Tests run locally and pass
- [x] CI green
- [x] Greptile review addressed

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-06-12 10:44:22 -07:00