Skip to content
Merged
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
5 changes: 5 additions & 0 deletions .changeset/modern-duckdb-node-api.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"agentpond": patch
---

Replace the deprecated `duckdb` package with `@duckdb/node-api` to remove deprecated transitive install warnings from npm installs.
10 changes: 10 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Agent Instructions

## Changelog

This repository uses Changesets to generate package changelogs.

- Add a changeset in `.changeset/` for every user-facing change, package dependency change, CLI behavior change, or release-worthy bug fix.
- Use `patch` for fixes and dependency maintenance, `minor` for new features, and `major` for breaking changes.
- Keep changeset summaries concise and written for AgentPond users.
- Do not manually edit generated changelog output unless the release process has already run `pnpm changeset version`.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<p align="center">
<img src="docs/assets/agentpond-logo-gpt-image.png" alt="AgentPond - trace analytics for AI agents" width="720">
<img src="https://raw.githubusercontent.com/marcusschiesser/agentpond/main/docs/assets/agentpond-logo-gpt-image.png" alt="AgentPond - trace analytics for AI agents" width="720">
</p>

AgentPond is a data pond for AI agent traces with a agent-native CLI for local analytics. It accepts Langfuse SDK ingestion and its using the same data format, so you can use it as a drop-in replacement.
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.936.0",
"duckdb": "^1.4.2",
"@duckdb/node-api": "^1.5.4-r.1",
"protobufjs": "^7.6.4",
"zod": "^4.3.6"
}
Expand Down
2 changes: 1 addition & 1 deletion apps/cli/tsup.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@ export default defineConfig({
sourcemap: true,
splitting: false,
noExternal: [/^@agentpond\//],
external: ["duckdb"],
external: ["@duckdb/node-api", "@duckdb/node-bindings"],
});
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
},
"dependencies": {
"@aws-sdk/client-s3": "^3.936.0",
"@duckdb/node-api": "^1.5.4-r.1",
"@opentelemetry/otlp-transformer": "^0.208.0",
"duckdb": "^1.4.2",
"fastify": "^5.6.2",
"protobufjs": "^7.6.4",
"zod": "^4.3.6"
Expand Down
3 changes: 2 additions & 1 deletion packages/duckdb/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
".": "./src/index.ts"
},
"dependencies": {
"@agentpond/core": "workspace:*"
"@agentpond/core": "workspace:*",
"@duckdb/node-api": "^1.5.4-r.1"
}
}
59 changes: 17 additions & 42 deletions packages/duckdb/src/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,7 @@ import {
type ObjectStore,
otelResourceSpansToEvents,
} from "@agentpond/core";
import duckdb from "duckdb";

type DuckConnection = {
run(sql: string, callback: (err: Error | null) => void): void;
all<T = Record<string, unknown>>(
sql: string,
callback: (err: Error | null, rows: T[]) => void,
): void;
close(callback: (err: Error | null) => void): void;
};
import { type DuckDBConnection, DuckDBInstance } from "@duckdb/node-api";

export type SyncResult = {
manifestsProcessed: number;
Expand All @@ -25,12 +16,11 @@ export type SyncResult = {
};

export class AgentPondDuckDb {
private readonly db: duckdb.Database;
private connection?: DuckConnection;
private instance?: DuckDBInstance;
private connection?: DuckDBConnection;

constructor(readonly dbPath: string) {
mkdirSync(dirname(dbPath), { recursive: true });
this.db = new duckdb.Database(dbPath);
}

async init(): Promise<void> {
Expand Down Expand Up @@ -182,17 +172,13 @@ export class AgentPondDuckDb {
if (this.connection) {
const connection = this.connection;
this.connection = undefined;
await new Promise<void>((resolve, reject) => {
connection.close((err) =>
err && !isAlreadyClosedConnectionError(err) ? reject(err) : resolve(),
);
});
connection.closeSync();
}
if (this.instance) {
const instance = this.instance;
this.instance = undefined;
instance.closeSync();
}
await new Promise<void>((resolve, reject) => {
this.db.close((err) =>
err && !isAlreadyClosedConnectionError(err) ? reject(err) : resolve(),
);
});
}

private async projectEvent(
Expand Down Expand Up @@ -373,28 +359,23 @@ export class AgentPondDuckDb {
);
}

private getConnection(): DuckConnection {
if (!this.connection)
this.connection = this.db.connect() as unknown as DuckConnection;
private async getConnection(): Promise<DuckDBConnection> {
if (!this.connection) {
this.instance = await DuckDBInstance.create(this.dbPath);
this.connection = await this.instance.connect();
}
return this.connection;
}

private async exec(sqlText: string): Promise<void> {
await new Promise<void>((resolve, reject) => {
this.getConnection().run(sqlText, (err) =>
err ? reject(err) : resolve(),
);
});
await (await this.getConnection()).run(sqlText);
}

private async all<T = Record<string, unknown>>(
sqlText: string,
): Promise<T[]> {
return new Promise<T[]>((resolve, reject) => {
this.getConnection().all<T>(sqlText, (err, rows) =>
err ? reject(err) : resolve(rows),
);
});
const reader = await (await this.getConnection()).runAndReadAll(sqlText);
return reader.getRowObjectsJS() as T[];
}
}

Expand Down Expand Up @@ -474,12 +455,6 @@ function isScoreSource(
return value === "API" || value === "EVAL" || value === "ANNOTATION";
}

function isAlreadyClosedConnectionError(error: Error): boolean {
return error.message.includes(
"Connection was never established or has been closed already",
);
}

function scoreValue(
value: unknown,
declaredDataType: string | undefined,
Expand Down
Loading
Loading