@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,61 @@
1
+ import { calculateCost } from '../cost.js';
2
+ export async function callAnthropic(model, options) {
3
+ const apiKey = process.env['ANTHROPIC_API_KEY'];
4
+ if (!apiKey) {
5
+ throw new Error('ANTHROPIC_API_KEY environment variable is not set');
6
+ }
7
+ let messages;
8
+ let systemPrompt;
9
+ if (options.messages) {
10
+ // Extract system messages and convert the rest
11
+ const systemMsgs = options.messages.filter(m => m.role === 'system');
12
+ if (systemMsgs.length > 0) {
13
+ systemPrompt = systemMsgs.map(m => m.content).join('\n');
14
+ }
15
+ messages = options.messages
16
+ .filter(m => m.role !== 'system')
17
+ .map(m => ({ role: m.role, content: m.content }));
18
+ }
19
+ else if (options.prompt) {
20
+ messages = [{ role: 'user', content: options.prompt }];
21
+ }
22
+ else {
23
+ throw new Error('Either prompt or messages must be provided');
24
+ }
25
+ const body = {
26
+ model,
27
+ max_tokens: options.maxTokens ?? 4096,
28
+ messages,
29
+ };
30
+ if (systemPrompt)
31
+ body.system = systemPrompt;
32
+ if (options.temperature !== undefined)
33
+ body.temperature = options.temperature;
34
+ const response = await fetch('https://api.anthropic.com/v1/messages', {
35
+ method: 'POST',
36
+ headers: {
37
+ 'x-api-key': apiKey,
38
+ 'anthropic-version': '2023-06-01',
39
+ 'Content-Type': 'application/json',
40
+ },
41
+ body: JSON.stringify(body),
42
+ });
43
+ if (!response.ok) {
44
+ const text = await response.text();
45
+ throw new Error(`Anthropic API error ${response.status}: ${text}`);
46
+ }
47
+ const data = await response.json();
48
+ const content = data.content[0]?.text ?? '';
49
+ const inputTokens = data.usage.input_tokens;
50
+ const outputTokens = data.usage.output_tokens;
51
+ const costUsd = calculateCost(model, inputTokens, outputTokens);
52
+ return {
53
+ content,
54
+ model: data.model,
55
+ provider: 'anthropic',
56
+ inputTokens,
57
+ outputTokens,
58
+ costUsd,
59
+ };
60
+ }
61
+ //# sourceMappingURL=anthropic.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../src/llm/anthropic.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { LlmOptions, LlmResult } from '../types.js';
2
+ export declare function callLlm(model: string, options: LlmOptions): Promise<LlmResult>;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEzD,wBAAsB,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAuBpF"}
@@ -0,0 +1,24 @@
1
+ export async function callLlm(model, options) {
2
+ const colonIdx = model.indexOf(':');
3
+ if (colonIdx === -1)
4
+ throw new Error(`Invalid model format: ${model}. Expected provider:model (e.g. anthropic:claude-sonnet-4-6)`);
5
+ const provider = model.slice(0, colonIdx);
6
+ const modelName = model.slice(colonIdx + 1);
7
+ switch (provider) {
8
+ case 'anthropic': {
9
+ const { callAnthropic } = await import('./anthropic.js');
10
+ return callAnthropic(modelName, options);
11
+ }
12
+ case 'openai': {
13
+ const { callOpenAI } = await import('./openai.js');
14
+ return callOpenAI(modelName, options);
15
+ }
16
+ case 'ollama': {
17
+ const { callOllama } = await import('./ollama.js');
18
+ return callOllama(modelName, options);
19
+ }
20
+ default:
21
+ throw new Error(`Unknown LLM provider: ${provider}. Supported: anthropic, openai, ollama`);
22
+ }
23
+ }
24
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/llm/index.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,KAAK,UAAU,OAAO,CAAC,KAAa,EAAE,OAAmB;IAC9D,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IACpC,IAAI,QAAQ,KAAK,CAAC,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,KAAK,8DAA8D,CAAC,CAAC;IAEnI,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IAC1C,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC;IAE5C,QAAQ,QAAQ,EAAE,CAAC;QACjB,KAAK,WAAW,CAAC,CAAC,CAAC;YACjB,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,gBAAgB,CAAC,CAAC;YACzD,OAAO,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACnD,OAAO,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD,KAAK,QAAQ,CAAC,CAAC,CAAC;YACd,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;YACnD,OAAO,UAAU,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QACxC,CAAC;QACD;YACE,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,wCAAwC,CAAC,CAAC;IAC/F,CAAC;AACH,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { LlmOptions, LlmResult } from '../types.js';
2
+ export declare function callOllama(model: string, options: LlmOptions): Promise<LlmResult>;
3
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../src/llm/ollama.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAoBzD,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAqCvF"}
@@ -0,0 +1,35 @@
1
+ export async function callOllama(model, options) {
2
+ let messages;
3
+ if (options.messages) {
4
+ messages = options.messages.map(m => ({ role: m.role, content: m.content }));
5
+ }
6
+ else if (options.prompt) {
7
+ messages = [{ role: 'user', content: options.prompt }];
8
+ }
9
+ else {
10
+ throw new Error('Either prompt or messages must be provided');
11
+ }
12
+ const body = { model, messages, stream: false };
13
+ const response = await fetch('http://localhost:11434/api/chat', {
14
+ method: 'POST',
15
+ headers: { 'Content-Type': 'application/json' },
16
+ body: JSON.stringify(body),
17
+ });
18
+ if (!response.ok) {
19
+ const text = await response.text();
20
+ throw new Error(`Ollama API error ${response.status}: ${text}`);
21
+ }
22
+ const data = await response.json();
23
+ const content = data.message.content;
24
+ const inputTokens = data.prompt_eval_count ?? 0;
25
+ const outputTokens = data.eval_count ?? 0;
26
+ return {
27
+ content,
28
+ model: data.model,
29
+ provider: 'ollama',
30
+ inputTokens,
31
+ outputTokens,
32
+ costUsd: 0,
33
+ };
34
+ }
35
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../src/llm/ollama.ts"],"names":[],"mappings":"AAoBA,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,OAAmB;IACjE,IAAI,QAAyB,CAAC;IAE9B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,IAAI,GAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAE/D,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,iCAAiC,EAAE;QAC9D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAoB,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;IACrC,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC;IAChD,MAAM,YAAY,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;IAE1C,OAAO;QACL,OAAO;QACP,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,QAAQ;QAClB,WAAW;QACX,YAAY;QACZ,OAAO,EAAE,CAAC;KACX,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { LlmOptions, LlmResult } from '../types.js';
2
+ export declare function callOpenAI(model: string, options: LlmOptions): Promise<LlmResult>;
3
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/llm/openai.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAyBzD,wBAAsB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC,CAgDvF"}
@@ -0,0 +1,48 @@
1
+ import { calculateCost } from '../cost.js';
2
+ export async function callOpenAI(model, options) {
3
+ const apiKey = process.env['OPENAI_API_KEY'];
4
+ if (!apiKey) {
5
+ throw new Error('OPENAI_API_KEY environment variable is not set');
6
+ }
7
+ let messages;
8
+ if (options.messages) {
9
+ messages = options.messages.map(m => ({ role: m.role, content: m.content }));
10
+ }
11
+ else if (options.prompt) {
12
+ messages = [{ role: 'user', content: options.prompt }];
13
+ }
14
+ else {
15
+ throw new Error('Either prompt or messages must be provided');
16
+ }
17
+ const body = { model, messages };
18
+ if (options.temperature !== undefined)
19
+ body.temperature = options.temperature;
20
+ if (options.maxTokens !== undefined)
21
+ body.max_tokens = options.maxTokens;
22
+ const response = await fetch('https://api.openai.com/v1/chat/completions', {
23
+ method: 'POST',
24
+ headers: {
25
+ 'Authorization': `Bearer ${apiKey}`,
26
+ 'Content-Type': 'application/json',
27
+ },
28
+ body: JSON.stringify(body),
29
+ });
30
+ if (!response.ok) {
31
+ const text = await response.text();
32
+ throw new Error(`OpenAI API error ${response.status}: ${text}`);
33
+ }
34
+ const data = await response.json();
35
+ const content = data.choices[0]?.message.content ?? '';
36
+ const inputTokens = data.usage.prompt_tokens;
37
+ const outputTokens = data.usage.completion_tokens;
38
+ const costUsd = calculateCost(model, inputTokens, outputTokens);
39
+ return {
40
+ content,
41
+ model: data.model,
42
+ provider: 'openai',
43
+ inputTokens,
44
+ outputTokens,
45
+ costUsd,
46
+ };
47
+ }
48
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/llm/openai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AA0B3C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAa,EAAE,OAAmB;IACjE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAC;IAC7C,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,QAAyB,CAAC;IAE9B,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;IAC/E,CAAC;SAAM,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QAC1B,QAAQ,GAAG,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,CAAC;SAAM,CAAC;QACN,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,IAAI,GAAkB,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAChD,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS;QAAE,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;IAC9E,IAAI,OAAO,CAAC,SAAS,KAAK,SAAS;QAAE,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;IAEzE,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,4CAA4C,EAAE;QACzE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,eAAe,EAAE,UAAU,MAAM,EAAE;YACnC,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;KAC3B,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QACnC,MAAM,IAAI,KAAK,CAAC,oBAAoB,QAAQ,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAoB,CAAC;IACrD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;IACvD,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC;IAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC;IAClD,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,YAAY,CAAC,CAAC;IAEhE,OAAO;QACL,OAAO;QACP,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,QAAQ;QAClB,WAAW;QACX,YAAY;QACZ,OAAO;KACR,CAAC;AACJ,CAAC"}