@graphysdk/agents-sdk 1.2.0-beta.1773268716508 → 1.2.0-beta.1773662483280
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.
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +243 -31
- package/dist/index.mjs +1 -1
- package/package.json +12 -3
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var t=require("tslib"),e=require("zod");class r extends Error{constructor(t){super(t),this.name="GraphyApiError"}}class
|
|
1
|
+
"use strict";var t=require("tslib"),e=require("zod");class r extends Error{constructor(t,e){var r;super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="GraphyApiError",this.status=null==e?void 0:e.status,this.code=null==e?void 0:e.code,this.retryable=null!==(r=null==e?void 0:e.retryable)&&void 0!==r&&r}}const i=t=>"progress"===t.type,o=t=>"complete"===t.type,s=t=>"error"===t.type;class n{constructor(t){if(this.tag="[GRAPHY]",!t.apiKey||0===t.apiKey.trim().length)throw new Error("apiKey is required and must not be empty");const e=new URL(t.baseUrl);if(!["http:","https:"].includes(e.protocol))throw new Error(`Invalid baseUrl protocol: ${e.protocol}. Only http(s) is allowed.`);this.apiKey=t.apiKey,this.baseUrl=e.origin+e.pathname.replace(/\/$/,""),this.timeout=t.timeout||6e4,this.retryConfig=t.retryConfig||{attempts:3,delay:1e3,backoff:2},this.logger=t.logger||{log:console.log,warn:console.warn,error:console.error,debug:console.debug}}static isProgressEvent(t){return i(t)}static isCompleteEvent(t){return o(t)}static isErrorEvent(t){return s(t)}stream(e,r,i){return t.__awaiter(this,void 0,void 0,function*(){const t=yield this.makeRequest(e,r,i);return this.parseSSE(t)})}fetch(e,n,a,l){return t.__awaiter(this,void 0,void 0,function*(){var c,g,h,u,d;const p=Date.now();this.logger.debug(`${this.tag} Fetch: ${e}`);try{const w=yield this.makeRequest(e,n,l),b=w.headers.get("content-type");if(null==b?void 0:b.includes("text/event-stream")){try{for(var y,f=!0,m=t.__asyncValues(this.parseSSE(w));!(c=(y=yield m.next()).done);f=!0){u=y.value,f=!1;const t=u;if(i(t)&&a&&a(t),o(t))return t.data;if(s(t)){const i=Date.now()-p;throw this.logger.error(`${this.tag} Server error: ${e} ${i}ms`,t.error),new r(t.error,{code:t.code,retryable:null!==(d=t.retryable)&&void 0!==d&&d})}}}catch(t){g={error:t}}finally{try{f||c||!(h=m.return)||(yield h.call(m))}finally{if(g)throw g.error}}const n=Date.now()-p;throw this.logger.error(`${this.tag} Stream incomplete: ${e} ${n}ms`),new r("Stream ended without completion")}return yield w.json()}catch(t){const i=Date.now()-p;if(this.logger.error(`${this.tag} Fetch failed: ${e} ${i}ms`,t),t instanceof r)throw t;throw t}finally{const t=Date.now()-p;this.logger.debug(`${this.tag} Fetch completed: ${e} ${t}ms`)}})}ping(){return t.__awaiter(this,void 0,void 0,function*(){const t=Date.now();try{return yield this.makeRequest("/health",void 0,void 0,this.retryConfig.attempts,"GET"),{ok:!0,latency:Date.now()-t}}catch(e){return{ok:!1,latency:Date.now()-t}}})}sleep(e){return t.__awaiter(this,void 0,void 0,function*(){return new Promise(t=>setTimeout(t,e))})}parseSSE(e){return t.__asyncGenerator(this,arguments,function*(){if(!e.body)throw new r("Response body is null");const i=e.body.getReader(),o=new TextDecoder;let s="",n="",a="";try{for(;;){const{done:e,value:r}=yield t.__await(i.read());if(e)break;s+=o.decode(r,{stream:!0});const l=s.split(/\r?\n/);s=l.pop()||"";for(const e of l)if(e.startsWith("event: "))n=e.slice(7).trim();else if(e.startsWith("data: "))a+=(a?"\n":"")+e.slice(6);else if(""===e.trim()&&a){try{const e=JSON.parse(a);let r;if("progress"===n){const t=e;r=Object.assign({type:"progress"},t)}else if("complete"===n)r={type:"complete",data:e};else{if("error"!==n){n="",a="";continue}{const t=e;r=Object.assign({type:"error"},t)}}if(yield yield t.__await(r),"complete"===n||"error"===n)return yield t.__await(void 0)}catch(t){this.logger.warn("Invalid SSE data format",a)}n="",a=""}}}finally{i.releaseLock()}})}makeRequest(e,i,o){return t.__awaiter(this,arguments,void 0,function*(t,e,i,o=1,s="POST"){if(!t.startsWith("/"))throw new r("Invalid endpoint: must start with /");const n=new URL(t,this.baseUrl);if(n.origin!==new URL(this.baseUrl).origin)throw new r("Endpoint resolved to unexpected origin");this.logger.debug(`${this.tag} Request ${o}/${this.retryConfig.attempts}: ${n}`);const a=new AbortController,l=setTimeout(()=>a.abort(),this.timeout),c=()=>a.abort();i&&i.addEventListener("abort",c);try{const l=yield fetch(n,Object.assign({method:s,headers:{"Content-Type":"application/json",Accept:"application/json, text/event-stream","Cache-Control":"no-cache",Authorization:`Bearer ${this.apiKey}`,"User-Agent":"Graphy-SDK/1.0"},signal:a.signal},"POST"===s&&{body:JSON.stringify(e)}));if(!l.ok){const n=l.status>=500||429===l.status;let a,c=`HTTP ${l.status}`;try{const t=yield l.json();if("object"==typeof t&&null!==t){const e=t;"string"==typeof e.message?c=e.message:"string"==typeof e.error&&(c=e.error),"string"==typeof e.code&&(a=e.code)}}catch(t){}const g=new r(c,{status:l.status,code:a,retryable:n});if(n&&o<this.retryConfig.attempts&&!(null==i?void 0:i.aborted)){const r=this.retryConfig.delay*Math.pow(this.retryConfig.backoff,o-1);return this.logger.warn(`${this.tag} Retrying ${t} in ${r}ms (attempt ${o+1})`),yield this.sleep(r),this.makeRequest(t,e,i,o+1,s)}throw this.logger.error(`${this.tag} Request failed: ${t} (${l.status}) - ${c}`),g}return this.logger.debug(`${this.tag} Connected: ${t}`),l}catch(n){if(n instanceof r)throw n;if(n instanceof Error&&"AbortError"===n.name)throw this.logger.debug(`${this.tag} Aborted: ${t}`),n;if(o<this.retryConfig.attempts&&!(null==i?void 0:i.aborted)){const r=this.retryConfig.delay*Math.pow(this.retryConfig.backoff,o-1);return this.logger.warn(`${this.tag} Network error, retrying ${t} in ${r}ms`),yield this.sleep(r),this.makeRequest(t,e,i,o+1,s)}throw this.logger.error(`${this.tag} Network error: ${t}`,n),new r("Network error",{retryable:!0})}finally{clearTimeout(l),i&&i.removeEventListener("abort",c)}})}}const a=e.z.enum(["EN_GB","EN_US"]),l=e.z.custom(t=>null!=t&&"object"==typeof t),c=e.z.enum(["none","low","medium","high"]);e.z.object({callId:e.z.string(),locale:a.optional(),storytellingEffort:c.optional().default("low")});const g=e.z.enum(["line","bar","groupedBar","stackedBar","100StackedBar","column","groupedColumn","stackedColumn","100StackedColumn","combo","pie","donut","funnel","heatmap","scatter","waterfall","table"]),h=e.z.object({dataPrepPrompt:e.z.string(),chartType:g,summary:e.z.string()}),u=e.z.object({title:e.z.string(),subtitle:e.z.string(),caption:e.z.string().nullable()}),d=e.z.object({config:l,suggestions:e.z.array(h),description:e.z.string().nullable()}),p=e.z.object({config:l,response:e.z.object({message:e.z.string(),steps:e.z.array(e.z.string()).optional()})}),y="/api/v0";exports.AiChartTypeEnum=g,exports.GenerateGraphNarrativeResponseSchema=u,exports.GenerateGraphResponseSchema=p,exports.GenerateGraphSuggestionsResponseSchema=d,exports.GraphyAiSdk=class{constructor(t){this.client=new n(t)}generateGraph(e,r,i){return t.__awaiter(this,void 0,void 0,function*(){const{storytellingOptions:o}=e,s=t.__rest(e,["storytellingOptions"]),n=yield this.client.fetch(`${y}/generate`,s,r,i),a=p.parse(n);return this.stripStorytelling(a,o)})}generateGraphStream(e,r){return t.__awaiter(this,void 0,void 0,function*(){const{storytellingOptions:i}=e,o=t.__rest(e,["storytellingOptions"]),s=yield this.client.stream(`${y}/generate`,o,r);return this.wrapStreamWithStorytellingStripping(s,i)})}generateNarrative(e,r,i){return t.__awaiter(this,void 0,void 0,function*(){const t=yield this.client.fetch(`${y}/narrative`,e,r,i);return u.parse(t)})}generateNarrativeStream(e,r){return t.__awaiter(this,void 0,void 0,function*(){return this.client.stream(`${y}/narrative`,e,r)})}generateSuggestions(e,r,i){return t.__awaiter(this,void 0,void 0,function*(){const t=yield this.client.fetch(`${y}/suggestions`,e,r,i);return d.parse(t)})}generateSuggestionsStream(e,r){return t.__awaiter(this,void 0,void 0,function*(){return this.client.stream(`${y}/suggestions`,e,r)})}stripStorytelling(t,e){return e&&t.config.content?Object.assign(Object.assign({},t),{config:Object.assign(Object.assign({},t.config),{content:Object.assign(Object.assign(Object.assign(Object.assign({},t.config.content),e.excludeTitle&&{title:void 0}),e.excludeSubtitle&&{subtitle:void 0}),e.excludeCaption&&{caption:void 0})})}):t}wrapStreamWithStorytellingStripping(e,r){return t.__asyncGenerator(this,arguments,function*(){var i,s,n,a;try{for(var l,c=!0,g=t.__asyncValues(e);!(i=(l=yield t.__await(g.next())).done);c=!0){a=l.value,c=!1;const e=a;if(o(e)){const i=this.stripStorytelling(e.data,r);yield yield t.__await(Object.assign(Object.assign({},e),{data:i}))}else yield yield t.__await(e)}}catch(t){s={error:t}}finally{try{c||i||!(n=g.return)||(yield t.__await(n.call(g)))}finally{if(s)throw s.error}}})}},exports.GraphyApiError=r,exports.StorytellingEffortSchema=c,exports.SuggestionSchema=h,exports.isCompleteEvent=o,exports.isErrorEvent=s,exports.isGraphyApiError=t=>t instanceof r,exports.isProgressEvent=i;
|
package/dist/index.d.ts
CHANGED
|
@@ -2,41 +2,101 @@ import * as _graphysdk_core_node from '@graphysdk/core/node';
|
|
|
2
2
|
import { GraphConfig } from '@graphysdk/core/node';
|
|
3
3
|
import { z } from 'zod';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* A progress update emitted during an SSE stream.
|
|
7
|
+
* Indicates how far along the server-side operation has progressed.
|
|
8
|
+
*/
|
|
5
9
|
interface ProgressEvent {
|
|
10
|
+
/** Discriminant literal identifying this as a progress event. */
|
|
6
11
|
type: 'progress';
|
|
12
|
+
/** Completion percentage from 0 to 100. */
|
|
7
13
|
percentage: number;
|
|
14
|
+
/** Optional human-readable progress message. */
|
|
8
15
|
message?: string;
|
|
16
|
+
/** Optional arbitrary metadata attached by the server. */
|
|
9
17
|
metadata?: Record<string, JsonValue>;
|
|
10
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* The final event emitted when an SSE stream completes successfully.
|
|
21
|
+
* Contains the full response payload.
|
|
22
|
+
*/
|
|
11
23
|
interface CompleteEvent<T> {
|
|
24
|
+
/** Discriminant literal identifying this as a completion event. */
|
|
12
25
|
type: 'complete';
|
|
26
|
+
/** The response data from the completed operation. */
|
|
13
27
|
data: T;
|
|
14
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* An error event emitted when the server encounters a failure during an SSE stream.
|
|
31
|
+
*/
|
|
15
32
|
interface ErrorEvent {
|
|
33
|
+
/** Discriminant literal identifying this as an error event. */
|
|
16
34
|
type: 'error';
|
|
35
|
+
/** Human-readable error description. */
|
|
17
36
|
error: string;
|
|
37
|
+
/** Machine-readable error code from the API (e.g. `"RATE_LIMIT_ERROR"`). */
|
|
18
38
|
code?: string;
|
|
39
|
+
/** Whether the consumer should retry the request. */
|
|
19
40
|
retryable?: boolean;
|
|
20
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Discriminated union of all SSE event types emitted during streaming operations.
|
|
44
|
+
* Use the type guards {@link isProgressEvent}, {@link isCompleteEvent}, and
|
|
45
|
+
* {@link isErrorEvent} to narrow the event type.
|
|
46
|
+
*/
|
|
21
47
|
type SSEEvent<T> = ProgressEvent | CompleteEvent<T> | ErrorEvent;
|
|
48
|
+
/**
|
|
49
|
+
* Logger interface for SDK diagnostic output.
|
|
50
|
+
* Falls back to `console` methods when not provided in {@link ClientConfig}.
|
|
51
|
+
*/
|
|
22
52
|
interface Logger {
|
|
23
53
|
log: (...args: Array<JsonValue | unknown>) => void;
|
|
24
54
|
warn: (...args: Array<JsonValue | unknown>) => void;
|
|
25
55
|
error: (...args: Array<JsonValue | unknown>) => void;
|
|
26
56
|
debug: (...args: Array<JsonValue | unknown>) => void;
|
|
27
57
|
}
|
|
58
|
+
/**
|
|
59
|
+
* Configuration for the automatic retry behavior on failed requests.
|
|
60
|
+
* Retries use exponential backoff: `delay * backoff^(attempt - 1)`.
|
|
61
|
+
*/
|
|
28
62
|
interface RetryConfig {
|
|
63
|
+
/** Maximum number of attempts (including the initial request). */
|
|
29
64
|
attempts: number;
|
|
65
|
+
/** Base delay in milliseconds before the first retry. */
|
|
30
66
|
delay: number;
|
|
67
|
+
/** Multiplier applied to the delay for each subsequent retry. */
|
|
31
68
|
backoff: number;
|
|
32
69
|
}
|
|
70
|
+
/**
|
|
71
|
+
* Configuration for initializing the SDK client.
|
|
72
|
+
*
|
|
73
|
+
* @example
|
|
74
|
+
* ```typescript
|
|
75
|
+
* const sdk = new GraphyAiSdk({
|
|
76
|
+
* apiKey: process.env.GRAPHY_API_KEY,
|
|
77
|
+
* baseUrl: 'https://agents.graphy.dev',
|
|
78
|
+
* });
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
33
81
|
interface ClientConfig {
|
|
82
|
+
/** API key for authenticating requests. */
|
|
34
83
|
apiKey: string;
|
|
84
|
+
/** Base URL of the Graphy Agents API (e.g. `"https://agents.graphy.dev"`). */
|
|
35
85
|
baseUrl: string;
|
|
86
|
+
/**
|
|
87
|
+
* Request timeout in milliseconds.
|
|
88
|
+
* @defaultValue 60000
|
|
89
|
+
*/
|
|
36
90
|
timeout?: number;
|
|
91
|
+
/** Custom logger implementation. Falls back to `console` methods if not provided. */
|
|
37
92
|
logger?: Logger;
|
|
93
|
+
/**
|
|
94
|
+
* Retry configuration for transient failures (5xx, 429, network errors).
|
|
95
|
+
* @defaultValue `{ attempts: 3, delay: 1000, backoff: 2 }`
|
|
96
|
+
*/
|
|
38
97
|
retryConfig?: RetryConfig;
|
|
39
98
|
}
|
|
99
|
+
/** A JSON-compatible value. */
|
|
40
100
|
type JsonValue = string | number | boolean | null | JsonObject | JsonArray;
|
|
41
101
|
interface JsonObject {
|
|
42
102
|
[key: string]: JsonValue;
|
|
@@ -45,6 +105,108 @@ type JsonArray = JsonValue[];
|
|
|
45
105
|
|
|
46
106
|
type ProgressHandler = (progress: ProgressEvent) => void;
|
|
47
107
|
|
|
108
|
+
/**
|
|
109
|
+
* Options for constructing a {@link GraphyApiError}.
|
|
110
|
+
*/
|
|
111
|
+
interface GraphyApiErrorOptions {
|
|
112
|
+
/** HTTP status code from the server response (e.g. 401, 429, 500). */
|
|
113
|
+
status?: number;
|
|
114
|
+
/** Machine-readable error code from the API (e.g. `"RATE_LIMIT_ERROR"`, `"VALIDATION_ERROR"`). */
|
|
115
|
+
code?: string;
|
|
116
|
+
/** Whether this request is safe to retry. Defaults to `false`. */
|
|
117
|
+
retryable?: boolean;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* Error thrown by the Graphy SDK when an API request fails.
|
|
121
|
+
*
|
|
122
|
+
* Covers HTTP errors, SSE stream errors, and network failures. Inspect
|
|
123
|
+
* {@link status}, {@link code}, and {@link retryable} to decide how to
|
|
124
|
+
* handle the failure programmatically.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* try {
|
|
129
|
+
* await sdk.generateGraph({ config, userPrompt });
|
|
130
|
+
* } catch (error) {
|
|
131
|
+
* if (isGraphyApiError(error)) {
|
|
132
|
+
* console.error(`[${error.code}] ${error.message} (HTTP ${error.status})`);
|
|
133
|
+
* if (error.retryable) {
|
|
134
|
+
* // schedule retry
|
|
135
|
+
* }
|
|
136
|
+
* }
|
|
137
|
+
* }
|
|
138
|
+
* ```
|
|
139
|
+
*/
|
|
140
|
+
declare class GraphyApiError extends Error {
|
|
141
|
+
/** HTTP status code, if the error originated from an HTTP response. */
|
|
142
|
+
readonly status: number | undefined;
|
|
143
|
+
/** Machine-readable error code from the API, if provided. */
|
|
144
|
+
readonly code: string | undefined;
|
|
145
|
+
/** Whether the SDK considers this error retryable (5xx, 429, network errors). */
|
|
146
|
+
readonly retryable: boolean;
|
|
147
|
+
/**
|
|
148
|
+
* @param message - Human-readable error description.
|
|
149
|
+
* @param options - Optional structured metadata about the error.
|
|
150
|
+
*/
|
|
151
|
+
constructor(message: string, options?: GraphyApiErrorOptions);
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Type guard that narrows an unknown value to {@link GraphyApiError}.
|
|
155
|
+
*
|
|
156
|
+
* @param error - The value to check.
|
|
157
|
+
* @returns `true` if `error` is an instance of `GraphyApiError`.
|
|
158
|
+
*/
|
|
159
|
+
declare const isGraphyApiError: (error: unknown) => error is GraphyApiError;
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Narrows an SSE event to a {@link ProgressEvent}.
|
|
163
|
+
*
|
|
164
|
+
* @param event - The SSE event to check.
|
|
165
|
+
* @returns `true` if the event is a progress event containing percentage and optional message.
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```typescript
|
|
169
|
+
* for await (const event of stream) {
|
|
170
|
+
* if (isProgressEvent(event)) {
|
|
171
|
+
* updateProgressBar(event.percentage);
|
|
172
|
+
* }
|
|
173
|
+
* }
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
declare const isProgressEvent: <T>(event: SSEEvent<T>) => event is ProgressEvent;
|
|
177
|
+
/**
|
|
178
|
+
* Narrows an SSE event to a {@link CompleteEvent} containing the final response data.
|
|
179
|
+
*
|
|
180
|
+
* @param event - The SSE event to check.
|
|
181
|
+
* @returns `true` if the event is a complete event.
|
|
182
|
+
*
|
|
183
|
+
* @example
|
|
184
|
+
* ```typescript
|
|
185
|
+
* for await (const event of stream) {
|
|
186
|
+
* if (isCompleteEvent(event)) {
|
|
187
|
+
* applyConfig(event.data.config);
|
|
188
|
+
* }
|
|
189
|
+
* }
|
|
190
|
+
* ```
|
|
191
|
+
*/
|
|
192
|
+
declare const isCompleteEvent: <T>(event: SSEEvent<T>) => event is CompleteEvent<T>;
|
|
193
|
+
/**
|
|
194
|
+
* Narrows an SSE event to an {@link ErrorEvent}.
|
|
195
|
+
*
|
|
196
|
+
* @param event - The SSE event to check.
|
|
197
|
+
* @returns `true` if the event is an error event containing error details.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```typescript
|
|
201
|
+
* for await (const event of stream) {
|
|
202
|
+
* if (isErrorEvent(event)) {
|
|
203
|
+
* console.error(`[${event.code}] ${event.error}`);
|
|
204
|
+
* }
|
|
205
|
+
* }
|
|
206
|
+
* ```
|
|
207
|
+
*/
|
|
208
|
+
declare const isErrorEvent: <T>(event: SSEEvent<T>) => event is ErrorEvent;
|
|
209
|
+
|
|
48
210
|
declare const StorytellingEffortSchema: z.ZodEnum<{
|
|
49
211
|
none: "none";
|
|
50
212
|
low: "low";
|
|
@@ -153,7 +315,7 @@ declare const GenerateGraphSuggestionsResponseSchema: z.ZodObject<{
|
|
|
153
315
|
description: z.ZodNullable<z.ZodString>;
|
|
154
316
|
}, z.core.$strip>;
|
|
155
317
|
type GenerateGraphSuggestionsResponse = z.infer<typeof GenerateGraphSuggestionsResponseSchema>;
|
|
156
|
-
interface
|
|
318
|
+
interface StorytellingOptions {
|
|
157
319
|
excludeTitle?: boolean;
|
|
158
320
|
excludeSubtitle?: boolean;
|
|
159
321
|
excludeCaption?: boolean;
|
|
@@ -162,65 +324,111 @@ type GenerateGraphParams = {
|
|
|
162
324
|
config: GraphConfig;
|
|
163
325
|
userPrompt: string;
|
|
164
326
|
metadata?: Metadata;
|
|
165
|
-
|
|
327
|
+
storytellingOptions?: StorytellingOptions;
|
|
166
328
|
};
|
|
167
|
-
declare const ChartNarrativeSchema: z.ZodObject<{
|
|
168
|
-
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
169
|
-
subtitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
170
|
-
caption: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
171
|
-
}, z.core.$strip>;
|
|
172
|
-
type ChartNarrative = z.infer<typeof ChartNarrativeSchema>;
|
|
173
329
|
declare const GenerateGraphResponseSchema: z.ZodObject<{
|
|
174
330
|
config: z.ZodType<GraphConfig, unknown, z.core.$ZodTypeInternals<GraphConfig, unknown>>;
|
|
175
331
|
response: z.ZodObject<{
|
|
176
332
|
message: z.ZodString;
|
|
177
333
|
steps: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
178
334
|
}, z.core.$strip>;
|
|
179
|
-
narrative: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
180
|
-
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
181
|
-
subtitle: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
182
|
-
caption: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
183
|
-
}, z.core.$strip>>>;
|
|
184
335
|
}, z.core.$strip>;
|
|
185
336
|
type GenerateGraphResponse = z.infer<typeof GenerateGraphResponseSchema>;
|
|
186
337
|
|
|
338
|
+
/**
|
|
339
|
+
* Client SDK for the Graphy AI Agents API.
|
|
340
|
+
*
|
|
341
|
+
* Provides methods for AI-powered chart generation, narrative text creation,
|
|
342
|
+
* and prompt suggestions. Each method has a request-response variant and a
|
|
343
|
+
* streaming variant returning an `AsyncIterableIterator` of SSE events.
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* const sdk = new GraphyAiSdk({
|
|
348
|
+
* apiKey: process.env.GRAPHY_API_KEY,
|
|
349
|
+
* baseUrl: 'https://agents.graphy.dev',
|
|
350
|
+
* });
|
|
351
|
+
*
|
|
352
|
+
* const result = await sdk.generateGraph({
|
|
353
|
+
* config: existingConfig,
|
|
354
|
+
* userPrompt: 'Add a trend line',
|
|
355
|
+
* });
|
|
356
|
+
* ```
|
|
357
|
+
*/
|
|
187
358
|
declare class GraphyAiSdk {
|
|
188
359
|
private client;
|
|
360
|
+
/**
|
|
361
|
+
* @param config - SDK configuration including API key and base URL.
|
|
362
|
+
* @throws {Error} If `apiKey` is empty or `baseUrl` is invalid.
|
|
363
|
+
*/
|
|
189
364
|
constructor(config: ClientConfig);
|
|
365
|
+
/**
|
|
366
|
+
* Generates a chart configuration from a natural language prompt.
|
|
367
|
+
*
|
|
368
|
+
* @param data - Generation parameters including the current config and user prompt.
|
|
369
|
+
* @param onProgress - Optional callback invoked with progress updates during generation.
|
|
370
|
+
* @param signal - Optional `AbortSignal` to cancel the request.
|
|
371
|
+
* @returns The generated chart configuration and agent response message.
|
|
372
|
+
* @throws {GraphyApiError} When the API returns an error or the network request fails.
|
|
373
|
+
*/
|
|
190
374
|
generateGraph(data: GenerateGraphParams, onProgress?: ProgressHandler, signal?: AbortSignal): Promise<{
|
|
191
375
|
config: _graphysdk_core_node.GraphConfig;
|
|
192
376
|
response: {
|
|
193
377
|
message: string;
|
|
194
378
|
steps?: string[] | undefined;
|
|
195
379
|
};
|
|
196
|
-
narrative?: {
|
|
197
|
-
title?: string | null | undefined;
|
|
198
|
-
subtitle?: string | null | undefined;
|
|
199
|
-
caption?: string | null | undefined;
|
|
200
|
-
} | null | undefined;
|
|
201
380
|
}>;
|
|
381
|
+
/**
|
|
382
|
+
* Streams chart generation events via SSE.
|
|
383
|
+
*
|
|
384
|
+
* @param data - Generation parameters including the current config and user prompt.
|
|
385
|
+
* @param signal - Optional `AbortSignal` to cancel the request.
|
|
386
|
+
* @returns An async iterator yielding {@link SSEEvent} objects.
|
|
387
|
+
* @throws {GraphyApiError} When the API returns an error or the network request fails.
|
|
388
|
+
*/
|
|
202
389
|
generateGraphStream(data: GenerateGraphParams, signal?: AbortSignal): Promise<AsyncIterableIterator<SSEEvent<{
|
|
203
390
|
config: _graphysdk_core_node.GraphConfig;
|
|
204
391
|
response: {
|
|
205
392
|
message: string;
|
|
206
393
|
steps?: string[] | undefined;
|
|
207
394
|
};
|
|
208
|
-
narrative?: {
|
|
209
|
-
title?: string | null | undefined;
|
|
210
|
-
subtitle?: string | null | undefined;
|
|
211
|
-
caption?: string | null | undefined;
|
|
212
|
-
} | null | undefined;
|
|
213
395
|
}>>>;
|
|
396
|
+
/**
|
|
397
|
+
* Generates narrative text (title, subtitle, caption) for a chart.
|
|
398
|
+
*
|
|
399
|
+
* @param data - Parameters including the chart config and a descriptive prompt.
|
|
400
|
+
* @param onProgress - Optional callback invoked with progress updates.
|
|
401
|
+
* @param signal - Optional `AbortSignal` to cancel the request.
|
|
402
|
+
* @returns The generated narrative containing title, subtitle, and optional caption.
|
|
403
|
+
* @throws {GraphyApiError} When the API returns an error or the network request fails.
|
|
404
|
+
*/
|
|
214
405
|
generateNarrative(data: GenerateGraphNarrativeParams, onProgress?: ProgressHandler, signal?: AbortSignal): Promise<{
|
|
215
406
|
title: string;
|
|
216
407
|
subtitle: string;
|
|
217
408
|
caption: string | null;
|
|
218
409
|
}>;
|
|
410
|
+
/**
|
|
411
|
+
* Streams narrative generation events via SSE.
|
|
412
|
+
*
|
|
413
|
+
* @param data - Parameters including the chart config and a descriptive prompt.
|
|
414
|
+
* @param signal - Optional `AbortSignal` to cancel the request.
|
|
415
|
+
* @returns An async iterator yielding {@link SSEEvent} objects.
|
|
416
|
+
* @throws {GraphyApiError} When the API returns an error or the network request fails.
|
|
417
|
+
*/
|
|
219
418
|
generateNarrativeStream(data: GenerateGraphNarrativeParams, signal?: AbortSignal): Promise<AsyncIterableIterator<SSEEvent<{
|
|
220
419
|
title: string;
|
|
221
420
|
subtitle: string;
|
|
222
421
|
caption: string | null;
|
|
223
422
|
}>>>;
|
|
423
|
+
/**
|
|
424
|
+
* Generates chart type and configuration suggestions from raw data.
|
|
425
|
+
*
|
|
426
|
+
* @param data - Parameters including the raw data string.
|
|
427
|
+
* @param onProgress - Optional callback invoked with progress updates.
|
|
428
|
+
* @param signal - Optional `AbortSignal` to cancel the request.
|
|
429
|
+
* @returns Suggested chart configurations and descriptions.
|
|
430
|
+
* @throws {GraphyApiError} When the API returns an error or the network request fails.
|
|
431
|
+
*/
|
|
224
432
|
generateSuggestions(data: GenerateGraphSuggestionsParams, onProgress?: ProgressHandler, signal?: AbortSignal): Promise<{
|
|
225
433
|
config: _graphysdk_core_node.GraphConfig;
|
|
226
434
|
suggestions: {
|
|
@@ -230,6 +438,14 @@ declare class GraphyAiSdk {
|
|
|
230
438
|
}[];
|
|
231
439
|
description: string | null;
|
|
232
440
|
}>;
|
|
441
|
+
/**
|
|
442
|
+
* Streams suggestion generation events via SSE.
|
|
443
|
+
*
|
|
444
|
+
* @param data - Parameters including the raw data string.
|
|
445
|
+
* @param signal - Optional `AbortSignal` to cancel the request.
|
|
446
|
+
* @returns An async iterator yielding {@link SSEEvent} objects.
|
|
447
|
+
* @throws {GraphyApiError} When the API returns an error or the network request fails.
|
|
448
|
+
*/
|
|
233
449
|
generateSuggestionsStream(data: GenerateGraphSuggestionsParams, signal?: AbortSignal): Promise<AsyncIterableIterator<SSEEvent<{
|
|
234
450
|
config: _graphysdk_core_node.GraphConfig;
|
|
235
451
|
suggestions: {
|
|
@@ -239,13 +455,9 @@ declare class GraphyAiSdk {
|
|
|
239
455
|
}[];
|
|
240
456
|
description: string | null;
|
|
241
457
|
}>>>;
|
|
242
|
-
private
|
|
243
|
-
private
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
declare class GraphyApiError extends Error {
|
|
247
|
-
constructor(message: string);
|
|
458
|
+
private stripStorytelling;
|
|
459
|
+
private wrapStreamWithStorytellingStripping;
|
|
248
460
|
}
|
|
249
461
|
|
|
250
|
-
export { AiChartTypeEnum,
|
|
251
|
-
export type { AiChartType,
|
|
462
|
+
export { AiChartTypeEnum, GenerateGraphNarrativeResponseSchema, GenerateGraphResponseSchema, GenerateGraphSuggestionsResponseSchema, GraphyAiSdk, GraphyApiError, StorytellingEffortSchema, SuggestionSchema, isCompleteEvent, isErrorEvent, isGraphyApiError, isProgressEvent };
|
|
463
|
+
export type { AiChartType, ClientConfig, CompleteEvent, ErrorEvent, GenerateGraphNarrativeParams, GenerateGraphNarrativeResponse, GenerateGraphParams, GenerateGraphResponse, GenerateGraphSuggestionsParams, GenerateGraphSuggestionsResponse, GraphyApiErrorOptions, Logger, ProgressEvent, ProgressHandler, RetryConfig, SSEEvent, StorytellingEffort, StorytellingOptions, Suggestion };
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{__awaiter as t,__asyncValues as e,__asyncGenerator as r,__await as i,__rest as o}from"tslib";import{z as n}from"zod";class s extends Error{constructor(t){super(t),this.name="GraphyApiError"}}class
|
|
1
|
+
import{__awaiter as t,__asyncValues as e,__asyncGenerator as r,__await as i,__rest as o}from"tslib";import{z as n}from"zod";class s extends Error{constructor(t,e){var r;super(t),Object.setPrototypeOf(this,new.target.prototype),this.name="GraphyApiError",this.status=null==e?void 0:e.status,this.code=null==e?void 0:e.code,this.retryable=null!==(r=null==e?void 0:e.retryable)&&void 0!==r&&r}}const a=t=>t instanceof s,l=t=>"progress"===t.type,c=t=>"complete"===t.type,g=t=>"error"===t.type;class h{constructor(t){if(this.tag="[GRAPHY]",!t.apiKey||0===t.apiKey.trim().length)throw new Error("apiKey is required and must not be empty");const e=new URL(t.baseUrl);if(!["http:","https:"].includes(e.protocol))throw new Error(`Invalid baseUrl protocol: ${e.protocol}. Only http(s) is allowed.`);this.apiKey=t.apiKey,this.baseUrl=e.origin+e.pathname.replace(/\/$/,""),this.timeout=t.timeout||6e4,this.retryConfig=t.retryConfig||{attempts:3,delay:1e3,backoff:2},this.logger=t.logger||{log:console.log,warn:console.warn,error:console.error,debug:console.debug}}static isProgressEvent(t){return l(t)}static isCompleteEvent(t){return c(t)}static isErrorEvent(t){return g(t)}stream(e,r,i){return t(this,void 0,void 0,function*(){const t=yield this.makeRequest(e,r,i);return this.parseSSE(t)})}fetch(r,i,o,n){return t(this,void 0,void 0,function*(){var t,a,h,d,u;const p=Date.now();this.logger.debug(`${this.tag} Fetch: ${r}`);try{const b=yield this.makeRequest(r,i,n),v=b.headers.get("content-type");if(null==v?void 0:v.includes("text/event-stream")){try{for(var y,f=!0,m=e(this.parseSSE(b));!(t=(y=yield m.next()).done);f=!0){d=y.value,f=!1;const t=d;if(l(t)&&o&&o(t),c(t))return t.data;if(g(t)){const e=Date.now()-p;throw this.logger.error(`${this.tag} Server error: ${r} ${e}ms`,t.error),new s(t.error,{code:t.code,retryable:null!==(u=t.retryable)&&void 0!==u&&u})}}}catch(t){a={error:t}}finally{try{f||t||!(h=m.return)||(yield h.call(m))}finally{if(a)throw a.error}}const i=Date.now()-p;throw this.logger.error(`${this.tag} Stream incomplete: ${r} ${i}ms`),new s("Stream ended without completion")}return yield b.json()}catch(t){const e=Date.now()-p;if(this.logger.error(`${this.tag} Fetch failed: ${r} ${e}ms`,t),t instanceof s)throw t;throw t}finally{const t=Date.now()-p;this.logger.debug(`${this.tag} Fetch completed: ${r} ${t}ms`)}})}ping(){return t(this,void 0,void 0,function*(){const t=Date.now();try{return yield this.makeRequest("/health",void 0,void 0,this.retryConfig.attempts,"GET"),{ok:!0,latency:Date.now()-t}}catch(e){return{ok:!1,latency:Date.now()-t}}})}sleep(e){return t(this,void 0,void 0,function*(){return new Promise(t=>setTimeout(t,e))})}parseSSE(t){return r(this,arguments,function*(){if(!t.body)throw new s("Response body is null");const e=t.body.getReader(),r=new TextDecoder;let o="",n="",a="";try{for(;;){const{done:t,value:s}=yield i(e.read());if(t)break;o+=r.decode(s,{stream:!0});const l=o.split(/\r?\n/);o=l.pop()||"";for(const t of l)if(t.startsWith("event: "))n=t.slice(7).trim();else if(t.startsWith("data: "))a+=(a?"\n":"")+t.slice(6);else if(""===t.trim()&&a){try{const t=JSON.parse(a);let e;if("progress"===n){const r=t;e=Object.assign({type:"progress"},r)}else if("complete"===n)e={type:"complete",data:t};else{if("error"!==n){n="",a="";continue}{const r=t;e=Object.assign({type:"error"},r)}}if(yield yield i(e),"complete"===n||"error"===n)return yield i(void 0)}catch(t){this.logger.warn("Invalid SSE data format",a)}n="",a=""}}}finally{e.releaseLock()}})}makeRequest(e,r,i){return t(this,arguments,void 0,function*(t,e,r,i=1,o="POST"){if(!t.startsWith("/"))throw new s("Invalid endpoint: must start with /");const n=new URL(t,this.baseUrl);if(n.origin!==new URL(this.baseUrl).origin)throw new s("Endpoint resolved to unexpected origin");this.logger.debug(`${this.tag} Request ${i}/${this.retryConfig.attempts}: ${n}`);const a=new AbortController,l=setTimeout(()=>a.abort(),this.timeout),c=()=>a.abort();r&&r.addEventListener("abort",c);try{const l=yield fetch(n,Object.assign({method:o,headers:{"Content-Type":"application/json",Accept:"application/json, text/event-stream","Cache-Control":"no-cache",Authorization:`Bearer ${this.apiKey}`,"User-Agent":"Graphy-SDK/1.0"},signal:a.signal},"POST"===o&&{body:JSON.stringify(e)}));if(!l.ok){const n=l.status>=500||429===l.status;let a,c=`HTTP ${l.status}`;try{const t=yield l.json();if("object"==typeof t&&null!==t){const e=t;"string"==typeof e.message?c=e.message:"string"==typeof e.error&&(c=e.error),"string"==typeof e.code&&(a=e.code)}}catch(t){}const g=new s(c,{status:l.status,code:a,retryable:n});if(n&&i<this.retryConfig.attempts&&!(null==r?void 0:r.aborted)){const n=this.retryConfig.delay*Math.pow(this.retryConfig.backoff,i-1);return this.logger.warn(`${this.tag} Retrying ${t} in ${n}ms (attempt ${i+1})`),yield this.sleep(n),this.makeRequest(t,e,r,i+1,o)}throw this.logger.error(`${this.tag} Request failed: ${t} (${l.status}) - ${c}`),g}return this.logger.debug(`${this.tag} Connected: ${t}`),l}catch(n){if(n instanceof s)throw n;if(n instanceof Error&&"AbortError"===n.name)throw this.logger.debug(`${this.tag} Aborted: ${t}`),n;if(i<this.retryConfig.attempts&&!(null==r?void 0:r.aborted)){const n=this.retryConfig.delay*Math.pow(this.retryConfig.backoff,i-1);return this.logger.warn(`${this.tag} Network error, retrying ${t} in ${n}ms`),yield this.sleep(n),this.makeRequest(t,e,r,i+1,o)}throw this.logger.error(`${this.tag} Network error: ${t}`,n),new s("Network error",{retryable:!0})}finally{clearTimeout(l),r&&r.removeEventListener("abort",c)}})}}const d=n.enum(["EN_GB","EN_US"]),u=n.custom(t=>null!=t&&"object"==typeof t),p=n.enum(["none","low","medium","high"]);n.object({callId:n.string(),locale:d.optional(),storytellingEffort:p.optional().default("low")});const y=n.enum(["line","bar","groupedBar","stackedBar","100StackedBar","column","groupedColumn","stackedColumn","100StackedColumn","combo","pie","donut","funnel","heatmap","scatter","waterfall","table"]),f=n.object({dataPrepPrompt:n.string(),chartType:y,summary:n.string()}),m=n.object({title:n.string(),subtitle:n.string(),caption:n.string().nullable()}),b=n.object({config:u,suggestions:n.array(f),description:n.string().nullable()}),v=n.object({config:u,response:n.object({message:n.string(),steps:n.array(n.string()).optional()})}),w="/api/v0";class ${constructor(t){this.client=new h(t)}generateGraph(e,r,i){return t(this,void 0,void 0,function*(){const{storytellingOptions:t}=e,n=o(e,["storytellingOptions"]),s=yield this.client.fetch(`${w}/generate`,n,r,i),a=v.parse(s);return this.stripStorytelling(a,t)})}generateGraphStream(e,r){return t(this,void 0,void 0,function*(){const{storytellingOptions:t}=e,i=o(e,["storytellingOptions"]),n=yield this.client.stream(`${w}/generate`,i,r);return this.wrapStreamWithStorytellingStripping(n,t)})}generateNarrative(e,r,i){return t(this,void 0,void 0,function*(){const t=yield this.client.fetch(`${w}/narrative`,e,r,i);return m.parse(t)})}generateNarrativeStream(e,r){return t(this,void 0,void 0,function*(){return this.client.stream(`${w}/narrative`,e,r)})}generateSuggestions(e,r,i){return t(this,void 0,void 0,function*(){const t=yield this.client.fetch(`${w}/suggestions`,e,r,i);return b.parse(t)})}generateSuggestionsStream(e,r){return t(this,void 0,void 0,function*(){return this.client.stream(`${w}/suggestions`,e,r)})}stripStorytelling(t,e){return e&&t.config.content?Object.assign(Object.assign({},t),{config:Object.assign(Object.assign({},t.config),{content:Object.assign(Object.assign(Object.assign(Object.assign({},t.config.content),e.excludeTitle&&{title:void 0}),e.excludeSubtitle&&{subtitle:void 0}),e.excludeCaption&&{caption:void 0})})}):t}wrapStreamWithStorytellingStripping(t,o){return r(this,arguments,function*(){var r,n,s,a;try{for(var l,g=!0,h=e(t);!(r=(l=yield i(h.next())).done);g=!0){a=l.value,g=!1;const t=a;if(c(t)){const e=this.stripStorytelling(t.data,o);yield yield i(Object.assign(Object.assign({},t),{data:e}))}else yield yield i(t)}}catch(t){n={error:t}}finally{try{g||r||!(s=h.return)||(yield i(s.call(h)))}finally{if(n)throw n.error}}})}}export{y as AiChartTypeEnum,m as GenerateGraphNarrativeResponseSchema,v as GenerateGraphResponseSchema,b as GenerateGraphSuggestionsResponseSchema,$ as GraphyAiSdk,s as GraphyApiError,p as StorytellingEffortSchema,f as SuggestionSchema,c as isCompleteEvent,g as isErrorEvent,a as isGraphyApiError,l as isProgressEvent};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@graphysdk/agents-sdk",
|
|
3
3
|
"author": "Graphy",
|
|
4
|
-
"version": "1.2.0-beta.
|
|
4
|
+
"version": "1.2.0-beta.1773662483280",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"files": [
|
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"zod": "^4.3.6",
|
|
21
|
-
"@graphysdk/core": "1.2.0-beta.
|
|
21
|
+
"@graphysdk/core": "1.2.0-beta.1773662483280"
|
|
22
22
|
},
|
|
23
23
|
"devDependencies": {
|
|
24
24
|
"@rollup/plugin-commonjs": "^28.0.6",
|
|
25
25
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
26
26
|
"@rollup/plugin-terser": "^0.4.4",
|
|
27
27
|
"@rollup/plugin-typescript": "^12.1.4",
|
|
28
|
-
"lodash-es": "^4.17.
|
|
28
|
+
"lodash-es": "^4.17.23",
|
|
29
29
|
"rollup": "^4.59.0",
|
|
30
30
|
"rollup-plugin-clear": "^2.0.7",
|
|
31
31
|
"rollup-plugin-copy": "^3.5.0",
|
|
@@ -37,12 +37,21 @@
|
|
|
37
37
|
"@graphytools/typescript-config": "0.0.1",
|
|
38
38
|
"@graphytools/vitest-config": "1.0.0"
|
|
39
39
|
},
|
|
40
|
+
"lint-staged": {
|
|
41
|
+
"*.{ts,tsx,js,jsx,json,css,md}": [
|
|
42
|
+
"prettier --write"
|
|
43
|
+
],
|
|
44
|
+
"*.{ts,tsx}": [
|
|
45
|
+
"eslint --max-warnings=0 --fix"
|
|
46
|
+
]
|
|
47
|
+
},
|
|
40
48
|
"scripts": {
|
|
41
49
|
"build": "rollup -c --bundleConfigAsCjs",
|
|
42
50
|
"build:dev": "rollup -c --bundleConfigAsCjs --watch",
|
|
43
51
|
"test": "vitest run",
|
|
44
52
|
"test:watch": "TZ=utc vitest",
|
|
45
53
|
"lint": "eslint . --max-warnings 0",
|
|
54
|
+
"lint:fix": "eslint . --fix",
|
|
46
55
|
"format": "prettier --write .",
|
|
47
56
|
"format:check": "prettier --check .",
|
|
48
57
|
"typecheck": "tsc --noEmit",
|