@blacklake-systems/depths-sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/dist/__tests__/db.test.d.ts +2 -0
  2. package/dist/__tests__/db.test.d.ts.map +1 -0
  3. package/dist/__tests__/db.test.js +62 -0
  4. package/dist/__tests__/db.test.js.map +1 -0
  5. package/dist/__tests__/replay.test.d.ts +2 -0
  6. package/dist/__tests__/replay.test.d.ts.map +1 -0
  7. package/dist/__tests__/replay.test.js +91 -0
  8. package/dist/__tests__/replay.test.js.map +1 -0
  9. package/dist/context.d.ts +26 -0
  10. package/dist/context.d.ts.map +1 -0
  11. package/dist/context.js +222 -0
  12. package/dist/context.js.map +1 -0
  13. package/dist/cost.d.ts +2 -0
  14. package/dist/cost.d.ts.map +1 -0
  15. package/dist/cost.js +17 -0
  16. package/dist/cost.js.map +1 -0
  17. package/dist/db.d.ts +5 -0
  18. package/dist/db.d.ts.map +1 -0
  19. package/dist/db.js +62 -0
  20. package/dist/db.js.map +1 -0
  21. package/dist/ids.d.ts +2 -0
  22. package/dist/ids.d.ts.map +1 -0
  23. package/dist/ids.js +5 -0
  24. package/dist/ids.js.map +1 -0
  25. package/dist/index.d.ts +4 -0
  26. package/dist/index.d.ts.map +1 -0
  27. package/dist/index.js +3 -0
  28. package/dist/index.js.map +1 -0
  29. package/dist/llm/anthropic.d.ts +3 -0
  30. package/dist/llm/anthropic.d.ts.map +1 -0
  31. package/dist/llm/anthropic.js +61 -0
  32. package/dist/llm/anthropic.js.map +1 -0
  33. package/dist/llm/index.d.ts +3 -0
  34. package/dist/llm/index.d.ts.map +1 -0
  35. package/dist/llm/index.js +24 -0
  36. package/dist/llm/index.js.map +1 -0
  37. package/dist/llm/ollama.d.ts +3 -0
  38. package/dist/llm/ollama.d.ts.map +1 -0
  39. package/dist/llm/ollama.js +35 -0
  40. package/dist/llm/ollama.js.map +1 -0
  41. package/dist/llm/openai.d.ts +3 -0
  42. package/dist/llm/openai.d.ts.map +1 -0
  43. package/dist/llm/openai.js +48 -0
  44. package/dist/llm/openai.js.map +1 -0
  45. package/dist/schema.d.ts +583 -0
  46. package/dist/schema.d.ts.map +1 -0
  47. package/dist/schema.js +41 -0
  48. package/dist/schema.js.map +1 -0
  49. package/dist/step.d.ts +3 -0
  50. package/dist/step.d.ts.map +1 -0
  51. package/dist/step.js +5 -0
  52. package/dist/step.js.map +1 -0
  53. package/dist/surface.d.ts +5 -0
  54. package/dist/surface.d.ts.map +1 -0
  55. package/dist/surface.js +44 -0
  56. package/dist/surface.js.map +1 -0
  57. package/dist/types.d.ts +63 -0
  58. package/dist/types.d.ts.map +1 -0
  59. package/dist/types.js +2 -0
  60. package/dist/types.js.map +1 -0
  61. package/dist/workflow.d.ts +3 -0
  62. package/dist/workflow.d.ts.map +1 -0
  63. package/dist/workflow.js +104 -0
  64. package/dist/workflow.js.map +1 -0
  65. package/package.json +29 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=db.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/db.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,62 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
4
+ import { randomUUID } from 'crypto';
5
+ // Use a unique temp DB for each test file run to avoid state leakage
6
+ const dbPath = join(tmpdir(), `depths-test-${randomUUID()}.db`);
7
+ describe('database layer', () => {
8
+ beforeEach(() => {
9
+ process.env['BLACKLAKE_DB_PATH'] = dbPath;
10
+ // Reset the singleton so each test gets the same connection (to the temp DB)
11
+ });
12
+ afterEach(() => {
13
+ delete process.env['BLACKLAKE_DB_PATH'];
14
+ });
15
+ it('creates depths tables on first open', async () => {
16
+ const { getDb } = await import('../db.js');
17
+ const db = getDb();
18
+ expect(db).toBeTruthy();
19
+ });
20
+ it('can insert and retrieve a workflow', async () => {
21
+ const { getDb } = await import('../db.js');
22
+ const { depthsWorkflows } = await import('../schema.js');
23
+ const { generateId } = await import('../ids.js');
24
+ const { eq } = await import('drizzle-orm');
25
+ const db = getDb();
26
+ const id = generateId('wf');
27
+ const name = `test-workflow-${randomUUID()}`;
28
+ db.insert(depthsWorkflows).values({ id, name }).run();
29
+ const [row] = db.select().from(depthsWorkflows).where(eq(depthsWorkflows.id, id)).all();
30
+ expect(row).toBeDefined();
31
+ expect(row.id).toBe(id);
32
+ expect(row.name).toBe(name);
33
+ });
34
+ it('can insert a run and steps', async () => {
35
+ const { getDb } = await import('../db.js');
36
+ const { depthsWorkflows, depthsRuns, depthsSteps } = await import('../schema.js');
37
+ const { generateId } = await import('../ids.js');
38
+ const { eq } = await import('drizzle-orm');
39
+ const db = getDb();
40
+ const wfId = generateId('wf');
41
+ const wfName = `test-workflow-${randomUUID()}`;
42
+ db.insert(depthsWorkflows).values({ id: wfId, name: wfName }).run();
43
+ const runId = generateId('run');
44
+ db.insert(depthsRuns).values({
45
+ id: runId,
46
+ workflow_id: wfId,
47
+ status: 'running',
48
+ }).run();
49
+ const stepId = generateId('step');
50
+ db.insert(depthsSteps).values({
51
+ id: stepId,
52
+ run_id: runId,
53
+ name: 'gather',
54
+ status: 'completed',
55
+ output: JSON.stringify({ data: 'hello' }),
56
+ }).run();
57
+ const [step] = db.select().from(depthsSteps).where(eq(depthsSteps.id, stepId)).all();
58
+ expect(step.name).toBe('gather');
59
+ expect(step.status).toBe('completed');
60
+ });
61
+ });
62
+ //# sourceMappingURL=db.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.test.js","sourceRoot":"","sources":["../../src/__tests__/db.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=replay.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/replay.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,91 @@
1
+ import { describe, it, expect, beforeEach } from 'vitest';
2
+ import { tmpdir } from 'os';
3
+ import { join } from 'path';
4
+ import { randomUUID } from 'crypto';
5
+ // Each test run uses a fresh DB
6
+ const dbPath = join(tmpdir(), `depths-replay-${randomUUID()}.db`);
7
+ // Reset the db singleton before each test by patching the module
8
+ async function resetDb(newPath) {
9
+ process.env['BLACKLAKE_DB_PATH'] = newPath;
10
+ // Force re-import with cache busting isn't possible in ESM without a loader,
11
+ // but since we use a single DB path per test file, we just ensure the
12
+ // env var is set before the first import.
13
+ }
14
+ describe('step replay', () => {
15
+ beforeEach(async () => {
16
+ await resetDb(dbPath);
17
+ });
18
+ it('executes a 3-step workflow and records all steps', async () => {
19
+ process.env['BLACKLAKE_DB_PATH'] = dbPath;
20
+ const { workflow } = await import('../workflow.js');
21
+ const { step } = await import('../step.js');
22
+ const executionLog = [];
23
+ const myWorkflow = workflow('replay-test-' + randomUUID(), async (ctx) => {
24
+ const a = await step(ctx, 'step-a', async () => {
25
+ executionLog.push('a');
26
+ return 'result-a';
27
+ });
28
+ const b = await step(ctx, 'step-b', async () => {
29
+ executionLog.push('b');
30
+ return 'result-b';
31
+ });
32
+ const c = await step(ctx, 'step-c', async () => {
33
+ executionLog.push('c');
34
+ return `${a}-${b}-c`;
35
+ });
36
+ return c;
37
+ });
38
+ const result = await myWorkflow.run();
39
+ expect(result.status).toBe('completed');
40
+ expect(result.output).toBe('result-a-result-b-c');
41
+ expect(result.steps).toHaveLength(3);
42
+ expect(executionLog).toEqual(['a', 'b', 'c']);
43
+ });
44
+ it('replays completed steps on second run', async () => {
45
+ process.env['BLACKLAKE_DB_PATH'] = dbPath;
46
+ const { workflow } = await import('../workflow.js');
47
+ const { step } = await import('../step.js');
48
+ const workflowName = 'replay-second-run-' + randomUUID();
49
+ const executionCounts = { a: 0, b: 0, c: 0 };
50
+ const makeWorkflow = () => workflow(workflowName, async (ctx) => {
51
+ const a = await step(ctx, 'step-a', async () => {
52
+ executionCounts['a']++;
53
+ return 'result-a';
54
+ });
55
+ const b = await step(ctx, 'step-b', async () => {
56
+ executionCounts['b']++;
57
+ return 'result-b';
58
+ });
59
+ await step(ctx, 'step-c', async () => {
60
+ executionCounts['c']++;
61
+ return `${a}-${b}`;
62
+ });
63
+ });
64
+ // First run — all steps execute
65
+ const first = makeWorkflow();
66
+ await first.run();
67
+ expect(executionCounts).toEqual({ a: 1, b: 1, c: 1 });
68
+ // Second run — same workflow name creates a new run, steps re-execute
69
+ // (replay only applies within the SAME run_id)
70
+ const second = makeWorkflow();
71
+ await second.run();
72
+ // All steps run again in the new run
73
+ expect(executionCounts['a']).toBe(2);
74
+ expect(executionCounts['b']).toBe(2);
75
+ expect(executionCounts['c']).toBe(2);
76
+ });
77
+ it('records a failed step and surfaces the error', async () => {
78
+ process.env['BLACKLAKE_DB_PATH'] = dbPath;
79
+ const { workflow } = await import('../workflow.js');
80
+ const { step } = await import('../step.js');
81
+ const myWorkflow = workflow('fail-test-' + randomUUID(), async (ctx) => {
82
+ await step(ctx, 'failing-step', async () => {
83
+ throw new Error('intentional failure');
84
+ });
85
+ });
86
+ const result = await myWorkflow.run();
87
+ expect(result.status).toBe('failed');
88
+ expect(result.error).toContain('intentional failure');
89
+ });
90
+ });
91
+ //# sourceMappingURL=replay.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay.test.js","sourceRoot":"","sources":["../../src/__tests__/replay.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { StepRecord, LlmOptions, WorkflowContext as IWorkflowContext } from './types.js';
2
+ export declare class WorkflowContextImpl implements IWorkflowContext {
3
+ runId: string;
4
+ workflowName: string;
5
+ private completedSteps;
6
+ private totalCost;
7
+ _lastLlmResult: import('./types.js').LlmResult | null;
8
+ constructor(runId: string, workflowName: string);
9
+ private loadCompletedSteps;
10
+ _executeStep<T>(name: string, fn: () => Promise<T>): Promise<T>;
11
+ _recordStepMeta(stepName: string, meta: {
12
+ provider: string;
13
+ model: string;
14
+ inputTokens: number;
15
+ outputTokens: number;
16
+ costUsd: number;
17
+ }): void;
18
+ llm(model: string, options: LlmOptions): Promise<string>;
19
+ tool(name: string, args: Record<string, unknown>): Promise<unknown>;
20
+ waitForApproval(reason: string): Promise<void>;
21
+ waitForSignal(name: string): Promise<unknown>;
22
+ waitFor(durationMs: number): Promise<void>;
23
+ getSteps(): StepRecord[];
24
+ getTotalCost(): number;
25
+ }
26
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,eAAe,IAAI,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAE9F,qBAAa,mBAAoB,YAAW,gBAAgB;IAC1D,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,cAAc,CAAsC;IAC5D,OAAO,CAAC,SAAS,CAAK;IACtB,cAAc,EAAE,OAAO,YAAY,EAAE,SAAS,GAAG,IAAI,CAAQ;gBAEjD,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM;IAM/C,OAAO,CAAC,kBAAkB;IAuBpB,YAAY,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAkErE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI;IA0BxI,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IASxD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC;IAyBnE,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA6C9C,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAiC7C,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAMhD,QAAQ,IAAI,UAAU,EAAE;IAIxB,YAAY,IAAI,MAAM;CAGvB"}
@@ -0,0 +1,222 @@
1
+ import { eq, and } from 'drizzle-orm';
2
+ import { getDb } from './db.js';
3
+ import { depthsSteps, depthsRuns } from './schema.js';
4
+ import { generateId } from './ids.js';
5
+ export class WorkflowContextImpl {
6
+ runId;
7
+ workflowName;
8
+ completedSteps = new Map();
9
+ totalCost = 0;
10
+ _lastLlmResult = null;
11
+ constructor(runId, workflowName) {
12
+ this.runId = runId;
13
+ this.workflowName = workflowName;
14
+ this.loadCompletedSteps();
15
+ }
16
+ loadCompletedSteps() {
17
+ const db = getDb();
18
+ const rows = db.select().from(depthsSteps)
19
+ .where(and(eq(depthsSteps.run_id, this.runId), eq(depthsSteps.status, 'completed')))
20
+ .all();
21
+ for (const row of rows) {
22
+ this.completedSteps.set(row.name, {
23
+ id: row.id,
24
+ name: row.name,
25
+ status: row.status,
26
+ output: row.output,
27
+ provider: row.provider ?? undefined,
28
+ model: row.model ?? undefined,
29
+ inputTokens: row.input_tokens ?? undefined,
30
+ outputTokens: row.output_tokens ?? undefined,
31
+ costUsd: row.cost_usd ?? undefined,
32
+ startedAt: row.started_at ?? '',
33
+ completedAt: row.completed_at ?? undefined,
34
+ });
35
+ }
36
+ }
37
+ async _executeStep(name, fn) {
38
+ // Replay check
39
+ const existing = this.completedSteps.get(name);
40
+ if (existing) {
41
+ console.log(` ↩ ${name} (replayed)`);
42
+ return existing.output;
43
+ }
44
+ const stepId = generateId('step');
45
+ const db = getDb();
46
+ const now = new Date().toISOString();
47
+ // Record step start
48
+ db.insert(depthsSteps).values({
49
+ id: stepId,
50
+ run_id: this.runId,
51
+ name,
52
+ status: 'running',
53
+ started_at: now,
54
+ }).run();
55
+ try {
56
+ const result = await fn();
57
+ const completedAt = new Date().toISOString();
58
+ // Record LLM metadata if an LLM call was made inside this step
59
+ if (this._lastLlmResult) {
60
+ this._recordStepMeta(name, {
61
+ provider: this._lastLlmResult.provider,
62
+ model: this._lastLlmResult.model,
63
+ inputTokens: this._lastLlmResult.inputTokens,
64
+ outputTokens: this._lastLlmResult.outputTokens,
65
+ costUsd: this._lastLlmResult.costUsd,
66
+ });
67
+ this._lastLlmResult = null;
68
+ }
69
+ // Record step completion
70
+ db.update(depthsSteps)
71
+ .set({
72
+ status: 'completed',
73
+ output: result,
74
+ completed_at: completedAt,
75
+ })
76
+ .where(eq(depthsSteps.id, stepId))
77
+ .run();
78
+ console.log(` ✓ ${name}`);
79
+ return result;
80
+ }
81
+ catch (err) {
82
+ const errMsg = err instanceof Error ? err.message : String(err);
83
+ db.update(depthsSteps)
84
+ .set({
85
+ status: 'failed',
86
+ error: errMsg,
87
+ completed_at: new Date().toISOString(),
88
+ })
89
+ .where(eq(depthsSteps.id, stepId))
90
+ .run();
91
+ console.log(` ✗ ${name}: ${errMsg}`);
92
+ throw err;
93
+ }
94
+ }
95
+ // Record LLM metadata on the current step
96
+ _recordStepMeta(stepName, meta) {
97
+ const db = getDb();
98
+ // Find the step by name in this run
99
+ const [step] = db.select().from(depthsSteps)
100
+ .where(and(eq(depthsSteps.run_id, this.runId), eq(depthsSteps.name, stepName)))
101
+ .all();
102
+ if (step) {
103
+ db.update(depthsSteps)
104
+ .set({
105
+ provider: meta.provider,
106
+ model: meta.model,
107
+ input_tokens: meta.inputTokens,
108
+ output_tokens: meta.outputTokens,
109
+ cost_usd: meta.costUsd,
110
+ })
111
+ .where(eq(depthsSteps.id, step.id))
112
+ .run();
113
+ }
114
+ this.totalCost += meta.costUsd;
115
+ // Update run total cost
116
+ db.update(depthsRuns)
117
+ .set({ total_cost_usd: this.totalCost })
118
+ .where(eq(depthsRuns.id, this.runId))
119
+ .run();
120
+ }
121
+ async llm(model, options) {
122
+ const { callLlm } = await import('./llm/index.js');
123
+ const result = await callLlm(model, options);
124
+ // Record LLM metadata on the current step (the step wrapper will record it after fn() returns)
125
+ this._lastLlmResult = result;
126
+ return result.content;
127
+ }
128
+ async tool(name, args) {
129
+ const { isSurfaceRunning, govern } = await import('./surface.js');
130
+ if (await isSurfaceRunning()) {
131
+ // Route through Surface governance
132
+ const decision = await govern('depths', name, args);
133
+ if (decision.decision === 'deny' || decision.decision === 'default_deny') {
134
+ throw new Error(`Tool call '${name}' denied by Surface: ${decision.reason}`);
135
+ }
136
+ if (decision.decision === 'approval_required' && decision.approval_id) {
137
+ console.log(` ⏳ ${name}: waiting for approval in Surface console...`);
138
+ const { pollApproval } = await import('./surface.js');
139
+ const approved = await pollApproval(decision.approval_id);
140
+ if (!approved) {
141
+ throw new Error(`Tool call '${name}' approval rejected or timed out`);
142
+ }
143
+ }
144
+ }
145
+ // Execute the tool call (for now, just return the args — actual tool execution is workflow-specific)
146
+ return args;
147
+ }
148
+ async waitForApproval(reason) {
149
+ const { isSurfaceRunning } = await import('./surface.js');
150
+ const db = (await import('./db.js')).getDb();
151
+ const { depthsRuns, depthsSignals } = await import('./schema.js');
152
+ const { eq, and } = await import('drizzle-orm');
153
+ console.log(` ⏳ Waiting for approval: ${reason}`);
154
+ // Mark run as paused
155
+ db.update(depthsRuns)
156
+ .set({ status: 'paused' })
157
+ .where(eq(depthsRuns.id, this.runId))
158
+ .run();
159
+ if (await isSurfaceRunning()) {
160
+ // Surface is running — it will manage approvals and signal us via depths_signals
161
+ // (Surface creates an approval, user approves in console, Surface inserts signal)
162
+ }
163
+ // Poll for a signal named 'approval'
164
+ const pollInterval = 2000;
165
+ const timeout = 300000; // 5 min
166
+ const start = Date.now();
167
+ while (Date.now() - start < timeout) {
168
+ const [signal] = db.select().from(depthsSignals)
169
+ .where(and(eq(depthsSignals.run_id, this.runId), eq(depthsSignals.name, 'approval')))
170
+ .all();
171
+ if (signal) {
172
+ // Resume
173
+ db.update(depthsRuns)
174
+ .set({ status: 'running' })
175
+ .where(eq(depthsRuns.id, this.runId))
176
+ .run();
177
+ console.log(` ✓ Approval received`);
178
+ return;
179
+ }
180
+ await new Promise(r => setTimeout(r, pollInterval));
181
+ }
182
+ throw new Error('Approval timed out after 5 minutes');
183
+ }
184
+ async waitForSignal(name) {
185
+ const db = (await import('./db.js')).getDb();
186
+ const { depthsRuns, depthsSignals } = await import('./schema.js');
187
+ const { eq, and } = await import('drizzle-orm');
188
+ console.log(` ⏳ Waiting for signal: ${name}`);
189
+ db.update(depthsRuns)
190
+ .set({ status: 'paused' })
191
+ .where(eq(depthsRuns.id, this.runId))
192
+ .run();
193
+ const start = Date.now();
194
+ while (Date.now() - start < 300000) {
195
+ const [signal] = db.select().from(depthsSignals)
196
+ .where(and(eq(depthsSignals.run_id, this.runId), eq(depthsSignals.name, name)))
197
+ .all();
198
+ if (signal) {
199
+ db.update(depthsRuns)
200
+ .set({ status: 'running' })
201
+ .where(eq(depthsRuns.id, this.runId))
202
+ .run();
203
+ console.log(` ✓ Signal '${name}' received`);
204
+ return signal.payload;
205
+ }
206
+ await new Promise(r => setTimeout(r, 2000));
207
+ }
208
+ throw new Error(`Signal '${name}' timed out after 5 minutes`);
209
+ }
210
+ async waitFor(durationMs) {
211
+ console.log(` ⏳ Waiting ${Math.round(durationMs / 1000)}s...`);
212
+ await new Promise(r => setTimeout(r, durationMs));
213
+ console.log(` ✓ Wait complete`);
214
+ }
215
+ getSteps() {
216
+ return Array.from(this.completedSteps.values());
217
+ }
218
+ getTotalCost() {
219
+ return this.totalCost;
220
+ }
221
+ }
222
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"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"}
package/dist/cost.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function calculateCost(model: string, inputTokens: number, outputTokens: number): number;
2
+ //# sourceMappingURL=cost.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.d.ts","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAWA,wBAAgB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAI9F"}
package/dist/cost.js ADDED
@@ -0,0 +1,17 @@
1
+ const PRICING = {
2
+ 'claude-opus-4-6': { input: 15, output: 75 },
3
+ 'claude-sonnet-4-6': { input: 3, output: 15 },
4
+ 'claude-haiku-4-5-20251001': { input: 0.8, output: 4 },
5
+ 'gpt-4o': { input: 2.5, output: 10 },
6
+ 'gpt-4o-mini': { input: 0.15, output: 0.6 },
7
+ 'gpt-4-turbo': { input: 10, output: 30 },
8
+ 'o1': { input: 15, output: 60 },
9
+ 'o3-mini': { input: 1.1, output: 4.4 },
10
+ };
11
+ export function calculateCost(model, inputTokens, outputTokens) {
12
+ const pricing = PRICING[model] ?? Object.entries(PRICING).find(([k]) => model.startsWith(k))?.[1];
13
+ if (!pricing)
14
+ return 0;
15
+ return ((inputTokens * pricing.input) + (outputTokens * pricing.output)) / 1_000_000;
16
+ }
17
+ //# sourceMappingURL=cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cost.js","sourceRoot":"","sources":["../src/cost.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,GAAsD;IACjE,iBAAiB,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;IAC5C,mBAAmB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;IAC7C,2BAA2B,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE;IACtD,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE;IACpC,aAAa,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;IAC3C,aAAa,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;IACxC,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;IAC/B,SAAS,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE;CACvC,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,KAAa,EAAE,WAAmB,EAAE,YAAoB;IACpF,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;IAClG,IAAI,CAAC,OAAO;QAAE,OAAO,CAAC,CAAC;IACvB,OAAO,CAAC,CAAC,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;AACvF,CAAC"}
package/dist/db.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ import Database from 'better-sqlite3';
2
+ export declare function getDb(): import("drizzle-orm/better-sqlite3").BetterSQLite3Database<Record<string, unknown>> & {
3
+ $client: Database.Database;
4
+ };
5
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AAStC,wBAAgB,KAAK;;EAuDpB"}
package/dist/db.js ADDED
@@ -0,0 +1,62 @@
1
+ import Database from 'better-sqlite3';
2
+ import { drizzle } from 'drizzle-orm/better-sqlite3';
3
+ import { join } from 'path';
4
+ import { homedir } from 'os';
5
+ import { mkdirSync, existsSync } from 'fs';
6
+ import * as schema from './schema.js';
7
+ let _db = null;
8
+ export function getDb() {
9
+ if (_db)
10
+ return _db;
11
+ const dir = join(homedir(), '.blacklake');
12
+ if (!existsSync(dir))
13
+ mkdirSync(dir, { recursive: true });
14
+ const dbPath = process.env['BLACKLAKE_DB_PATH'] ?? join(dir, 'blacklake.db');
15
+ const sqlite = new Database(dbPath);
16
+ sqlite.pragma('journal_mode = WAL');
17
+ sqlite.pragma('foreign_keys = ON');
18
+ // Create depths tables if they don't exist
19
+ sqlite.exec(`
20
+ CREATE TABLE IF NOT EXISTS depths_workflows (
21
+ id TEXT PRIMARY KEY,
22
+ name TEXT NOT NULL UNIQUE,
23
+ created_at TEXT DEFAULT (datetime('now'))
24
+ );
25
+ CREATE TABLE IF NOT EXISTS depths_runs (
26
+ id TEXT PRIMARY KEY,
27
+ workflow_id TEXT NOT NULL REFERENCES depths_workflows(id),
28
+ status TEXT NOT NULL DEFAULT 'running',
29
+ input TEXT,
30
+ output TEXT,
31
+ error TEXT,
32
+ total_cost_usd REAL DEFAULT 0,
33
+ started_at TEXT DEFAULT (datetime('now')),
34
+ completed_at TEXT
35
+ );
36
+ CREATE TABLE IF NOT EXISTS depths_steps (
37
+ id TEXT PRIMARY KEY,
38
+ run_id TEXT NOT NULL REFERENCES depths_runs(id),
39
+ name TEXT NOT NULL,
40
+ status TEXT NOT NULL DEFAULT 'running',
41
+ output TEXT,
42
+ error TEXT,
43
+ provider TEXT,
44
+ model TEXT,
45
+ input_tokens INTEGER,
46
+ output_tokens INTEGER,
47
+ cost_usd REAL,
48
+ started_at TEXT DEFAULT (datetime('now')),
49
+ completed_at TEXT
50
+ );
51
+ CREATE TABLE IF NOT EXISTS depths_signals (
52
+ id TEXT PRIMARY KEY,
53
+ run_id TEXT NOT NULL REFERENCES depths_runs(id),
54
+ name TEXT NOT NULL,
55
+ payload TEXT,
56
+ received_at TEXT DEFAULT (datetime('now'))
57
+ );
58
+ `);
59
+ _db = drizzle(sqlite, { schema });
60
+ return _db;
61
+ }
62
+ //# sourceMappingURL=db.js.map
package/dist/db.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,IAAI,GAAG,GAAsC,IAAI,CAAC;AAElD,MAAM,UAAU,KAAK;IACnB,IAAI,GAAG;QAAE,OAAO,GAAG,CAAC;IAEpB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;IAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1D,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC7E,MAAM,MAAM,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACpC,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC;IAEnC,2CAA2C;IAC3C,MAAM,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCX,CAAC,CAAC;IAEH,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,OAAO,GAAG,CAAC;AACb,CAAC"}
package/dist/ids.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ export declare function generateId(prefix: string): string;
2
+ //# sourceMappingURL=ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAEA,wBAAgB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAEjD"}
package/dist/ids.js ADDED
@@ -0,0 +1,5 @@
1
+ import { randomUUID } from 'crypto';
2
+ export function generateId(prefix) {
3
+ return `${prefix}_${randomUUID().replace(/-/g, '')}`;
4
+ }
5
+ //# sourceMappingURL=ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../src/ids.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAEpC,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,OAAO,GAAG,MAAM,IAAI,UAAU,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;AACvD,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { workflow } from './workflow.js';
2
+ export { step } from './step.js';
3
+ export type { WorkflowDefinition, WorkflowContext, RunResult, StepRecord, LlmOptions, LlmResult, WorkflowStatus, StepStatus, } from './types.js';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,SAAS,EACT,UAAU,EACV,UAAU,EACV,SAAS,EACT,cAAc,EACd,UAAU,GACX,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { workflow } from './workflow.js';
2
+ export { step } from './step.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { LlmOptions, LlmResult } from '../types.js';
2
+ export declare function callAnthropic(model: string, options: LlmOptions): Promise<LlmResult>;
3
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAwBzD,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CA8D1F"}