@spendgraph/sdk 0.5.0 → 0.6.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 (46) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +25 -80
  3. package/dist/ai.js +1 -25
  4. package/dist/client.js +1 -38
  5. package/dist/core/client/client.d.ts +2 -0
  6. package/dist/core/client/client.js +1 -132
  7. package/dist/core/client/errors.js +1 -17
  8. package/dist/core/client/index.js +1 -2
  9. package/dist/core/types.d.ts +4 -0
  10. package/dist/core/types.js +0 -1
  11. package/dist/index.d.ts +2 -1
  12. package/dist/index.js +1 -5
  13. package/dist/langchain.js +1 -69
  14. package/dist/resources/alerts.js +1 -9
  15. package/dist/resources/cli.js +1 -21
  16. package/dist/resources/credentials.js +1 -15
  17. package/dist/resources/events.js +1 -18
  18. package/dist/resources/index.d.ts +2 -2
  19. package/dist/resources/index.js +1 -13
  20. package/dist/resources/ingest.js +1 -27
  21. package/dist/resources/keys.js +1 -15
  22. package/dist/resources/playground.js +1 -9
  23. package/dist/resources/pricing.js +1 -36
  24. package/dist/resources/projects.d.ts +17 -3
  25. package/dist/resources/projects.js +1 -49
  26. package/dist/resources/prompts-admin.js +1 -21
  27. package/dist/resources/prompts.d.ts +1 -1
  28. package/dist/resources/prompts.js +1 -49
  29. package/dist/resources/stats.js +1 -21
  30. package/dist/resources/tools.d.ts +1 -1
  31. package/dist/resources/tools.js +1 -21
  32. package/dist/rollout/index.d.ts +1 -0
  33. package/dist/rollout/index.js +1 -1
  34. package/dist/rollout/rollout.d.ts +12 -0
  35. package/dist/rollout/rollout.js +1 -1
  36. package/dist/schema/index.d.ts +1 -1
  37. package/dist/schema/index.js +1 -2
  38. package/dist/schema/serialize/index.js +1 -1
  39. package/dist/schema/serialize/serialize.js +1 -31
  40. package/dist/schema/types/index.js +0 -1
  41. package/dist/schema/types/types.js +0 -1
  42. package/dist/schema/validate/index.js +1 -1
  43. package/dist/schema/validate/validate.js +1 -92
  44. package/dist/track/index.js +1 -1
  45. package/dist/track/track.js +1 -331
  46. package/package.json +5 -4
package/dist/langchain.js CHANGED
@@ -1,69 +1 @@
1
- export function spendGraphHandler(meter, options = {}) {
2
- const models = new Map();
3
- const rememberModel = (llm, runId, extraParams) => {
4
- try {
5
- const model = extraParams?.invocation_params?.model ??
6
- extraParams?.invocation_params?.model_name ??
7
- extraParams?.invocation_params?.modelId ??
8
- llm?.kwargs?.model ??
9
- llm?.kwargs?.model_name;
10
- if (model)
11
- models.set(runId, model);
12
- }
13
- catch {
14
- }
15
- };
16
- return {
17
- name: "spendgraph",
18
- handleLLMStart(llm, _prompts, runId, _parentRunId, extraParams) {
19
- rememberModel(llm, runId, extraParams);
20
- },
21
- handleChatModelStart(llm, _messages, runId, _parentRunId, extraParams) {
22
- rememberModel(llm, runId, extraParams);
23
- },
24
- handleLLMEnd(output, runId) {
25
- const startedAs = models.get(runId);
26
- models.delete(runId);
27
- try {
28
- const msg = output.generations?.[0]?.[0]?.message;
29
- const um = msg?.usage_metadata;
30
- const tu = output.llmOutput?.tokenUsage;
31
- const au = output.llmOutput?.usage;
32
- let inputTokens = um?.input_tokens ?? au?.input_tokens ?? tu?.promptTokens;
33
- const outputTokens = um?.output_tokens ?? au?.output_tokens ?? tu?.completionTokens;
34
- if (typeof inputTokens !== "number" || typeof outputTokens !== "number")
35
- return;
36
- let cacheReadTokens = 0;
37
- let cacheWriteTokens = 0;
38
- if (um?.input_token_details && typeof um.input_tokens === "number") {
39
- cacheReadTokens = um.input_token_details.cache_read ?? 0;
40
- cacheWriteTokens = um.input_token_details.cache_creation ?? 0;
41
- inputTokens = Math.max(0, inputTokens - cacheReadTokens - cacheWriteTokens);
42
- }
43
- else if (au) {
44
- cacheReadTokens = au.cache_read_input_tokens ?? 0;
45
- cacheWriteTokens = au.cache_creation_input_tokens ?? 0;
46
- }
47
- const model = msg?.response_metadata?.model ??
48
- msg?.response_metadata?.model_name ??
49
- output.llmOutput?.model ??
50
- startedAs ??
51
- options.defaultModel ??
52
- "unknown";
53
- meter.track({
54
- model,
55
- inputTokens,
56
- outputTokens,
57
- cacheReadTokens,
58
- cacheWriteTokens,
59
- metadata: options.metadata,
60
- });
61
- }
62
- catch {
63
- }
64
- },
65
- handleLLMError(_err, runId) {
66
- models.delete(runId);
67
- },
68
- };
69
- }
1
+ function h(i,l={}){const d=new Map,_=(e,a,n)=>{try{const o=n?.invocation_params?.model??n?.invocation_params?.model_name??n?.invocation_params?.modelId??e?.kwargs?.model??e?.kwargs?.model_name;o&&d.set(a,o)}catch{}};return{name:"spendgraph",handleLLMStart(e,a,n,o,t){_(e,n,t)},handleChatModelStart(e,a,n,o,t){_(e,n,t)},handleLLMEnd(e,a){const n=d.get(a);d.delete(a);try{const o=e.generations?.[0]?.[0]?.message,t=o?.usage_metadata,p=e.llmOutput?.tokenUsage,s=e.llmOutput?.usage;let m=t?.input_tokens??s?.input_tokens??p?.promptTokens;const u=t?.output_tokens??s?.output_tokens??p?.completionTokens;if(typeof m!="number"||typeof u!="number")return;let r=0,c=0;t?.input_token_details&&typeof t.input_tokens=="number"?(r=t.input_token_details.cache_read??0,c=t.input_token_details.cache_creation??0,m=Math.max(0,m-r-c)):s&&(r=s.cache_read_input_tokens??0,c=s.cache_creation_input_tokens??0);const k=o?.response_metadata?.model??o?.response_metadata?.model_name??e.llmOutput?.model??n??l.defaultModel??"unknown";i.track({model:k,inputTokens:m,outputTokens:u,cacheReadTokens:r,cacheWriteTokens:c,metadata:l.metadata})}catch{}},handleLLMError(e,a){d.delete(a)}}}export{h as spendGraphHandler};
@@ -1,9 +1 @@
1
- export class Alerts {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list(query = {}) {
7
- return this.client.get("/api/v1/alerts", { ...query });
8
- }
9
- }
1
+ class s{client;constructor(t){this.client=t}list(t={}){return this.client.get("/api/v1/alerts",{...t})}}export{s as Alerts};
@@ -1,21 +1 @@
1
- export class Cli {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- start(body) {
7
- return this.client.postAnonymous("/api/v1/cli/auth", body);
8
- }
9
- exchange(body) {
10
- return this.client.postAnonymous("/api/v1/cli/token", body);
11
- }
12
- terminals() {
13
- return this.client.get("/api/v1/cli/tokens");
14
- }
15
- revoke(id) {
16
- return this.client.delete(`/api/v1/cli/tokens/${encodeURIComponent(id)}`);
17
- }
18
- revokeSelf() {
19
- return this.client.delete("/api/v1/cli/tokens/current");
20
- }
21
- }
1
+ class n{client;constructor(e){this.client=e}start(e){return this.client.postAnonymous("/api/v1/cli/auth",e)}exchange(e){return this.client.postAnonymous("/api/v1/cli/token",e)}terminals(){return this.client.get("/api/v1/cli/tokens")}revoke(e){return this.client.delete(`/api/v1/cli/tokens/${encodeURIComponent(e)}`)}revokeSelf(){return this.client.delete("/api/v1/cli/tokens/current")}}export{n as Cli};
@@ -1,15 +1 @@
1
- export class Credentials {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list() {
7
- return this.client.get("/api/v1/credentials");
8
- }
9
- set(body) {
10
- return this.client.put("/api/v1/credentials", body);
11
- }
12
- remove(provider) {
13
- return this.client.delete("/api/v1/credentials", { provider });
14
- }
15
- }
1
+ class i{client;constructor(e){this.client=e}list(){return this.client.get("/api/v1/credentials")}set(e){return this.client.put("/api/v1/credentials",e)}remove(e){return this.client.delete("/api/v1/credentials",{provider:e})}}export{i as Credentials};
@@ -1,18 +1 @@
1
- export class Events {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list(query = {}) {
7
- return this.client.get("/api/v1/events", { ...query });
8
- }
9
- async *all(query = {}) {
10
- let cursor = query.cursor;
11
- do {
12
- const page = await this.list({ ...query, cursor });
13
- for (const event of page.events)
14
- yield event;
15
- cursor = page.nextCursor ?? undefined;
16
- } while (cursor);
17
- }
18
- }
1
+ class c{client;constructor(t){this.client=t}list(t={}){return this.client.get("/api/v1/events",{...t})}async*all(t={}){let e=t.cursor;do{const s=await this.list({...t,cursor:e});for(const n of s.events)yield n;e=s.nextCursor??void 0}while(e)}}export{c as Events};
@@ -17,7 +17,7 @@ export { Invites, Projects } from "./projects.js";
17
17
  export type { DatasetCase, PromptBlock, RenderedMessage, ReportRolloutInput, Role, RunPromptInput, SavePromptInput, Scoped, } from "./prompts.js";
18
18
  export { Prompts } from "./prompts.js";
19
19
  export { PromptsAdmin } from "./prompts-admin.js";
20
- export type { SaveToolInput, ToolEffect, ToolRow } from "./tools.js";
21
- export { Tools } from "./tools.js";
22
20
  export type { ModelRow, RangeQuery, Summary, Timeseries, TimeseriesPoint, Totals, } from "./stats.js";
23
21
  export { Stats } from "./stats.js";
22
+ export type { SaveToolInput, ToolEffect, ToolRow } from "./tools.js";
23
+ export { Tools } from "./tools.js";
@@ -1,13 +1 @@
1
- export { Alerts } from "./alerts.js";
2
- export { Cli } from "./cli.js";
3
- export { Credentials } from "./credentials.js";
4
- export { Events } from "./events.js";
5
- export { Ingest, MAX_EVENTS } from "./ingest.js";
6
- export { Keys } from "./keys.js";
7
- export { Playground } from "./playground.js";
8
- export { Models, Pricing } from "./pricing.js";
9
- export { Invites, Projects } from "./projects.js";
10
- export { Prompts } from "./prompts.js";
11
- export { PromptsAdmin } from "./prompts-admin.js";
12
- export { Tools } from "./tools.js";
13
- export { Stats } from "./stats.js";
1
+ import{Alerts as t}from"./alerts.js";import{Cli as m}from"./cli.js";import{Credentials as f}from"./credentials.js";import{Events as s}from"./events.js";import{Ingest as i,MAX_EVENTS as l}from"./ingest.js";import{Keys as d}from"./keys.js";import{Playground as g}from"./playground.js";import{Models as E,Pricing as c}from"./pricing.js";import{Invites as y,Projects as C}from"./projects.js";import{Prompts as M}from"./prompts.js";import{PromptsAdmin as T}from"./prompts-admin.js";import{Stats as u}from"./stats.js";import{Tools as N}from"./tools.js";export{t as Alerts,m as Cli,f as Credentials,s as Events,i as Ingest,y as Invites,d as Keys,l as MAX_EVENTS,E as Models,g as Playground,c as Pricing,C as Projects,M as Prompts,T as PromptsAdmin,u as Stats,N as Tools};
@@ -1,27 +1 @@
1
- export const MAX_EVENTS = 100;
2
- export class Ingest {
3
- client;
4
- project;
5
- constructor(client, project) {
6
- this.client = client;
7
- this.project = project;
8
- }
9
- async send(events) {
10
- await this.report(events);
11
- }
12
- async report(events) {
13
- const total = { accepted: 0, rejected: 0, unpricedModels: [] };
14
- if (events.length === 0)
15
- return total;
16
- const unpriced = new Set();
17
- for (let i = 0; i < events.length; i += MAX_EVENTS) {
18
- const res = await this.client.post("/api/v1/ingest", { events: events.slice(i, i + MAX_EVENTS) }, { project: this.project });
19
- total.accepted += res?.accepted ?? 0;
20
- total.rejected += res?.rejected ?? 0;
21
- for (const model of res?.unpricedModels ?? [])
22
- unpriced.add(model);
23
- }
24
- total.unpricedModels = [...unpriced];
25
- return total;
26
- }
27
- }
1
+ const i=100;class p{client;project;constructor(c,e){this.client=c,this.project=e}async send(c){await this.report(c)}async report(c){const e={accepted:0,rejected:0,unpricedModels:[]};if(c.length===0)return e;const r=new Set,o=c.map(t=>({...t,eventId:t.eventId??crypto.randomUUID()}));for(let t=0;t<o.length;t+=100){const n=await this.client.post("/api/v1/ingest",{events:o.slice(t,t+100)},{project:this.project});e.accepted+=n?.accepted??0,e.rejected+=n?.rejected??0;for(const s of n?.unpricedModels??[])r.add(s)}return e.unpricedModels=[...r],e}}export{p as Ingest,i as MAX_EVENTS};
@@ -1,15 +1 @@
1
- export class Keys {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list(query = {}) {
7
- return this.client.get("/api/v1/keys", { ...query });
8
- }
9
- create(body) {
10
- return this.client.post("/api/v1/keys", body);
11
- }
12
- revoke(keyId) {
13
- return this.client.delete(`/api/v1/keys/${encodeURIComponent(keyId)}`);
14
- }
15
- }
1
+ class i{client;constructor(e){this.client=e}list(e={}){return this.client.get("/api/v1/keys",{...e})}create(e){return this.client.post("/api/v1/keys",e)}revoke(e){return this.client.delete(`/api/v1/keys/${encodeURIComponent(e)}`)}}export{i as Keys};
@@ -1,9 +1 @@
1
- export class Playground {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- run(body) {
7
- return this.client.post("/api/v1/playground/run", body);
8
- }
9
- }
1
+ class r{client;constructor(t){this.client=t}run(t){return this.client.post("/api/v1/playground/run",t)}}export{r as Playground};
@@ -1,36 +1 @@
1
- export class Pricing {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list() {
7
- return this.client.get("/api/v1/pricing");
8
- }
9
- override(model, body) {
10
- return this.client.put(`/api/v1/pricing/${encodeURIComponent(model)}`, body);
11
- }
12
- coverage() {
13
- return this.client.get("/api/v1/pricing/coverage");
14
- }
15
- readiness() {
16
- return this.client.get("/api/v1/pricing/readiness");
17
- }
18
- sync(body = {}) {
19
- return this.client.post("/api/v1/pricing/sync", body);
20
- }
21
- }
22
- export class Models {
23
- client;
24
- constructor(client) {
25
- this.client = client;
26
- }
27
- list(query = {}) {
28
- return this.client.get("/api/v1/models", { ...query });
29
- }
30
- offers(query = {}) {
31
- return this.client.get("/api/v1/offers", { ...query });
32
- }
33
- compare(query = {}) {
34
- return this.client.get("/api/v1/compare", { ...query });
35
- }
36
- }
1
+ class r{client;constructor(e){this.client=e}list(){return this.client.get("/api/v1/pricing")}override(e,t){return this.client.put(`/api/v1/pricing/${encodeURIComponent(e)}`,t)}coverage(){return this.client.get("/api/v1/pricing/coverage")}readiness(){return this.client.get("/api/v1/pricing/readiness")}sync(e={}){return this.client.post("/api/v1/pricing/sync",e)}}class n{client;constructor(e){this.client=e}list(e={}){return this.client.get("/api/v1/models",{...e})}offers(e={}){return this.client.get("/api/v1/offers",{...e})}compare(e={}){return this.client.get("/api/v1/compare",{...e})}}export{n as Models,r as Pricing};
@@ -33,9 +33,23 @@ export declare class Projects {
33
33
  removeMember(projectId: string, userId: string): Promise<{
34
34
  ok: boolean;
35
35
  }>;
36
- invite(projectId: string, body: Record<string, unknown>): Promise<{
37
- ok: boolean;
38
- added?: unknown;
36
+ /**
37
+ * Invites by GitHub login, or mints a shareable link when none is given.
38
+ *
39
+ * Typed rather than `Record<string, unknown>`: the route reads `githubLogin`
40
+ * and nothing else, so an untyped body let a caller send `email`, have it
41
+ * silently dropped, and get a link invite it never asked for under a 200.
42
+ */
43
+ invite(projectId: string, body: {
44
+ githubLogin?: string;
45
+ role?: "owner" | "member";
46
+ }): Promise<{
47
+ added: boolean;
48
+ githubLogin: string | null;
49
+ role: "owner" | "member";
50
+ expiresAt?: string;
51
+ /** Present only for a link invite, and only this once. */
52
+ token?: string | null;
39
53
  }>;
40
54
  revokeInvite(projectId: string, inviteId: string): Promise<{
41
55
  ok: boolean;
@@ -1,49 +1 @@
1
- export class Projects {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list() {
7
- return this.client.get("/api/v1/projects");
8
- }
9
- create(body) {
10
- return this.client.post("/api/v1/projects", body);
11
- }
12
- budget(projectId) {
13
- return this.client.get(`/api/v1/projects/${encodeURIComponent(projectId)}/budget`);
14
- }
15
- setBudget(projectId, body) {
16
- return this.client.put(`/api/v1/projects/${encodeURIComponent(projectId)}/budget`, body);
17
- }
18
- members(projectId) {
19
- return this.client.get(`/api/v1/projects/${encodeURIComponent(projectId)}/members`);
20
- }
21
- addMember(projectId, body) {
22
- return this.client.post(`/api/v1/projects/${encodeURIComponent(projectId)}/members`, body);
23
- }
24
- removeMember(projectId, userId) {
25
- return this.client.delete(`/api/v1/projects/${encodeURIComponent(projectId)}/members`, {
26
- userId,
27
- });
28
- }
29
- invite(projectId, body) {
30
- return this.client.post(`/api/v1/projects/${encodeURIComponent(projectId)}/invites`, body);
31
- }
32
- revokeInvite(projectId, inviteId) {
33
- return this.client.delete(`/api/v1/projects/${encodeURIComponent(projectId)}/invites`, {
34
- inviteId,
35
- });
36
- }
37
- }
38
- export class Invites {
39
- client;
40
- constructor(client) {
41
- this.client = client;
42
- }
43
- preview(token) {
44
- return this.client.get("/api/v1/invites/accept", { token });
45
- }
46
- accept(token) {
47
- return this.client.post("/api/v1/invites/accept", { token });
48
- }
49
- }
1
+ class i{client;constructor(e){this.client=e}list(){return this.client.get("/api/v1/projects")}create(e){return this.client.post("/api/v1/projects",e)}budget(e){return this.client.get(`/api/v1/projects/${encodeURIComponent(e)}/budget`)}setBudget(e,t){return this.client.put(`/api/v1/projects/${encodeURIComponent(e)}/budget`,t)}members(e){return this.client.get(`/api/v1/projects/${encodeURIComponent(e)}/members`)}addMember(e,t){return this.client.post(`/api/v1/projects/${encodeURIComponent(e)}/members`,t)}removeMember(e,t){return this.client.delete(`/api/v1/projects/${encodeURIComponent(e)}/members`,{userId:t})}invite(e,t){return this.client.post(`/api/v1/projects/${encodeURIComponent(e)}/invites`,t)}revokeInvite(e,t){return this.client.delete(`/api/v1/projects/${encodeURIComponent(e)}/invites`,{inviteId:t})}}class r{client;constructor(e){this.client=e}preview(e){return this.client.get("/api/v1/invites/accept",{token:e})}accept(e){return this.client.post("/api/v1/invites/accept",{token:e})}}export{r as Invites,i as Projects};
@@ -1,21 +1 @@
1
- export class PromptsAdmin {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- publish(promptId, body = {}) {
7
- return this.client.post(`/api/v1/prompts/${encodeURIComponent(promptId)}/publish`, body);
8
- }
9
- archive(promptId, query = {}) {
10
- return this.client.post(`/api/v1/prompts/${encodeURIComponent(promptId)}/archive`, {}, { ...query });
11
- }
12
- assay(promptId, body) {
13
- return this.client.post(`/api/v1/prompts/${encodeURIComponent(promptId)}/assay`, body);
14
- }
15
- runs(query = {}) {
16
- return this.client.get("/api/v1/prompts/runs", { ...query });
17
- }
18
- run(runId) {
19
- return this.client.get(`/api/v1/prompts/runs/${encodeURIComponent(runId)}`);
20
- }
21
- }
1
+ class s{client;constructor(t){this.client=t}publish(t,n={}){return this.client.post(`/api/v1/prompts/${encodeURIComponent(t)}/publish`,n)}archive(t,n={}){return this.client.post(`/api/v1/prompts/${encodeURIComponent(t)}/archive`,{},{...n})}assay(t,n){return this.client.post(`/api/v1/prompts/${encodeURIComponent(t)}/assay`,n)}runs(t={}){return this.client.get("/api/v1/prompts/runs",{...t})}run(t){return this.client.get(`/api/v1/prompts/runs/${encodeURIComponent(t)}`)}}export{s as PromptsAdmin};
@@ -68,7 +68,7 @@ export declare class Prompts {
68
68
  list(query?: Scoped & {
69
69
  limit?: number;
70
70
  cursor?: string;
71
- archived?: boolean;
71
+ archived?: "only" | "active" | "all";
72
72
  }): Promise<{
73
73
  prompts: unknown[];
74
74
  nextCursor?: string | null;
@@ -1,49 +1 @@
1
- export class Prompts {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list(query = {}) {
7
- return this.client.get("/api/v1/prompts", { ...query });
8
- }
9
- create(body) {
10
- return this.client.post("/api/v1/prompts", body);
11
- }
12
- get(promptId, query = {}) {
13
- return this.client.get(`/api/v1/prompts/${encodeURIComponent(promptId)}`, { ...query });
14
- }
15
- update(promptId, body, query = {}) {
16
- return this.client.put(`/api/v1/prompts/${encodeURIComponent(promptId)}`, body, { ...query });
17
- }
18
- versions(promptId, query = {}) {
19
- return this.client.get(`/api/v1/prompts/${encodeURIComponent(promptId)}/versions`, {
20
- ...query,
21
- });
22
- }
23
- promote(promptId, versionId, query = {}) {
24
- return this.client.post(`/api/v1/prompts/${encodeURIComponent(promptId)}/versions`, { versionId }, { ...query });
25
- }
26
- cases(promptId, query = {}) {
27
- return this.client.get(`/api/v1/prompts/${encodeURIComponent(promptId)}/cases`, {
28
- ...query,
29
- });
30
- }
31
- putCases(promptId, cases, query = {}) {
32
- return this.client.put(`/api/v1/prompts/${encodeURIComponent(promptId)}/cases`, { cases }, { ...query });
33
- }
34
- rollouts(promptId, query = {}) {
35
- return this.client.get(`/api/v1/prompts/${encodeURIComponent(promptId)}/rollouts`, {
36
- ...query,
37
- });
38
- }
39
- report(promptId, body, query = {}) {
40
- return this.client.post(`/api/v1/prompts/${encodeURIComponent(promptId)}/rollouts`, body, {
41
- ...query,
42
- });
43
- }
44
- run(promptId, body, query = {}) {
45
- return this.client.post(`/api/v1/prompts/${encodeURIComponent(promptId)}/run`, body, {
46
- ...query,
47
- });
48
- }
49
- }
1
+ class p{client;constructor(t){this.client=t}list(t={}){return this.client.get("/api/v1/prompts",{...t})}create(t){return this.client.post("/api/v1/prompts",t)}get(t,e={}){return this.client.get(`/api/v1/prompts/${encodeURIComponent(t)}`,{...e})}update(t,e,o={}){return this.client.put(`/api/v1/prompts/${encodeURIComponent(t)}`,e,{...o})}versions(t,e={}){return this.client.get(`/api/v1/prompts/${encodeURIComponent(t)}/versions`,{...e})}promote(t,e,o={}){return this.client.post(`/api/v1/prompts/${encodeURIComponent(t)}/versions`,{versionId:e},{...o})}cases(t,e={}){return this.client.get(`/api/v1/prompts/${encodeURIComponent(t)}/cases`,{...e})}putCases(t,e,o={}){return this.client.put(`/api/v1/prompts/${encodeURIComponent(t)}/cases`,{cases:e},{...o})}rollouts(t,e={}){return this.client.get(`/api/v1/prompts/${encodeURIComponent(t)}/rollouts`,{...e})}report(t,e,o={}){return this.client.post(`/api/v1/prompts/${encodeURIComponent(t)}/rollouts`,e,{...o})}run(t,e,o={}){return this.client.post(`/api/v1/prompts/${encodeURIComponent(t)}/run`,e,{...o})}}export{p as Prompts};
@@ -1,21 +1 @@
1
- export class Stats {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- summary(query = {}) {
7
- return this.client.get("/api/v1/stats/summary", { ...query });
8
- }
9
- timeseries(query = {}) {
10
- return this.client.get("/api/v1/stats/timeseries", { ...query });
11
- }
12
- byModel(query = {}) {
13
- return this.client.get("/api/v1/stats/by-model", { ...query });
14
- }
15
- byKey(query = {}) {
16
- return this.client.get("/api/v1/stats/by-key", { ...query });
17
- }
18
- byTag(query = {}) {
19
- return this.client.get("/api/v1/stats/by-tag", { ...query });
20
- }
21
- }
1
+ class s{client;constructor(t){this.client=t}summary(t={}){return this.client.get("/api/v1/stats/summary",{...t})}timeseries(t={}){return this.client.get("/api/v1/stats/timeseries",{...t})}byModel(t={}){return this.client.get("/api/v1/stats/by-model",{...t})}byKey(t={}){return this.client.get("/api/v1/stats/by-key",{...t})}byTag(t={}){return this.client.get("/api/v1/stats/by-tag",{...t})}}export{s as Stats};
@@ -1,5 +1,5 @@
1
- import type { FieldSpec } from "../schema/index.js";
2
1
  import type { Client } from "../core/client/index.js";
2
+ import type { FieldSpec } from "../schema/index.js";
3
3
  import type { Scoped } from "./prompts.js";
4
4
  /** What calling a tool does outside the process. Null means nobody has said. */
5
5
  export type ToolEffect = "readonly" | "idempotent" | "destructive";
@@ -1,21 +1 @@
1
- export class Tools {
2
- client;
3
- constructor(client) {
4
- this.client = client;
5
- }
6
- list(query = {}) {
7
- return this.client.get("/api/v1/tools", { ...query });
8
- }
9
- get(name, query = {}) {
10
- return this.client.get(`/api/v1/tools/${encodeURIComponent(name)}`, { ...query });
11
- }
12
- create(body) {
13
- return this.client.post("/api/v1/tools", body);
14
- }
15
- update(id, body, query = {}) {
16
- return this.client.patch(`/api/v1/tools/${encodeURIComponent(id)}`, body, { ...query });
17
- }
18
- archive(id, archived, query = {}) {
19
- return this.client.post(`/api/v1/tools/${encodeURIComponent(id)}/archive`, { archived }, { ...query });
20
- }
21
- }
1
+ class i{client;constructor(t){this.client=t}list(t={}){return this.client.get("/api/v1/tools",{...t})}get(t,e={}){return this.client.get(`/api/v1/tools/${encodeURIComponent(t)}`,{...e})}create(t){return this.client.post("/api/v1/tools",t)}update(t,e,o={}){return this.client.patch(`/api/v1/tools/${encodeURIComponent(t)}`,e,{...o})}archive(t,e,o={}){return this.client.post(`/api/v1/tools/${encodeURIComponent(t)}/archive`,{archived:e},{...o})}}export{i as Tools};
@@ -1 +1,2 @@
1
1
  export type { RolloutInput, RolloutRecord, RolloutStep } from "./rollout.js";
2
+ export { totalTokens } from "./rollout.js";
@@ -1 +1 @@
1
- export {};
1
+ import{totalTokens as e}from"./rollout.js";export{e as totalTokens};
@@ -23,6 +23,18 @@ export interface RolloutStep {
23
23
  outputTokens?: number;
24
24
  latencyMs?: number;
25
25
  }
26
+ /**
27
+ * What every step in a rollout adds up to.
28
+ *
29
+ * Here rather than in each caller for the reason `RolloutStep` is: a second
30
+ * copy is how two capabilities end up disagreeing about what a run cost. They
31
+ * had — one guarded the counts and one did not, so the same nested steps
32
+ * totalled a number in a graph run and `NaN` in a refine loop.
33
+ */
34
+ export declare function totalTokens(steps: RolloutStep[]): {
35
+ inputTokens: number;
36
+ outputTokens: number;
37
+ };
26
38
  /** What a caller hands back after running something itself. */
27
39
  export interface RolloutInput {
28
40
  /** Dedupe key. Generated if omitted; supply your own to make a retry safe. */
@@ -1 +1 @@
1
- export {};
1
+ function u(t){return typeof t!="number"||!Number.isFinite(t)||t<0?0:Math.trunc(t)}function r(t){let n=0,o=0;for(const e of t)n+=u(e.inputTokens),o+=u(e.outputTokens);return{inputTokens:n,outputTokens:o}}export{r as totalTokens};
@@ -1,3 +1,3 @@
1
1
  export { serializeFields } from "./serialize/index.js";
2
2
  export type { FieldSpec, FieldType } from "./types/index.js";
3
- export { type FieldError, FieldValidationError, validateFields } from "./validate/index.js";
3
+ export { type FieldError, FieldValidationError, isMissing, toBoolean, toNumber, validateFields, } from "./validate/index.js";
@@ -1,2 +1 @@
1
- export { serializeFields } from "./serialize/index.js";
2
- export { FieldValidationError, validateFields } from "./validate/index.js";
1
+ import{serializeFields as o}from"./serialize/index.js";import{FieldValidationError as l,isMissing as a,toBoolean as s,toNumber as t,validateFields as d}from"./validate/index.js";export{l as FieldValidationError,a as isMissing,o as serializeFields,s as toBoolean,t as toNumber,d as validateFields};
@@ -1 +1 @@
1
- export { serializeFields } from "./serialize.js";
1
+ import{serializeFields as r}from"./serialize.js";export{r as serializeFields};
@@ -1,31 +1 @@
1
- import { FieldValidationError, isMissing, toBoolean, toNumber, validateFields, } from "../validate/index.js";
2
- function renderOne(field, value) {
3
- switch (field.type) {
4
- case "number":
5
- return String(toNumber(value));
6
- case "boolean":
7
- return toBoolean(value) ? (field.trueText ?? "true") : (field.falseText ?? "false");
8
- case "list":
9
- return value.map(String).join(field.separator ?? ", ");
10
- case "json":
11
- return JSON.stringify(value, null, 2);
12
- default:
13
- return String(value);
14
- }
15
- }
16
- export function serializeFields(values, spec) {
17
- const errors = validateFields(values, spec);
18
- if (errors.length)
19
- throw new FieldValidationError(errors);
20
- const out = {};
21
- for (const field of spec) {
22
- const value = values[field.name];
23
- if (isMissing(value)) {
24
- if (field.default !== undefined)
25
- out[field.name] = field.default;
26
- continue;
27
- }
28
- out[field.name] = renderOne(field, value);
29
- }
30
- return out;
31
- }
1
+ import{FieldValidationError as s,isMissing as a,toBoolean as u,toNumber as f,validateFields as c}from"../validate/index.js";function l(n,e){switch(n.type){case"number":return String(f(e));case"boolean":return u(e)?n.trueText??"true":n.falseText??"false";case"list":return e.map(String).join(n.separator??", ");case"json":return JSON.stringify(e,null,2);default:return String(e)}}function m(n,e){const o=c(n,e);if(o.length)throw new s(o);const r={};for(const t of e){const i=n[t.name];if(a(i)){t.default!==void 0&&(r[t.name]=t.default);continue}r[t.name]=l(t,i)}return r}export{m as serializeFields};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1 +1 @@
1
- export { FieldValidationError, isMissing, toBoolean, toNumber, validateFields, } from "./validate.js";
1
+ import{FieldValidationError as e,isMissing as r,toBoolean as a,toNumber as l,validateFields as t}from"./validate.js";export{e as FieldValidationError,r as isMissing,a as toBoolean,l as toNumber,t as validateFields};