@supyagent/sdk 0.1.2 → 0.1.4

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 ADDED
@@ -0,0 +1,183 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var src_exports = {};
22
+ __export(src_exports, {
23
+ supyagent: () => supyagent
24
+ });
25
+ module.exports = __toCommonJS(src_exports);
26
+
27
+ // src/core/cache.ts
28
+ var TTLCache = class {
29
+ store = /* @__PURE__ */ new Map();
30
+ get(key) {
31
+ const entry = this.store.get(key);
32
+ if (!entry) return void 0;
33
+ if (Date.now() > entry.expiresAt) {
34
+ this.store.delete(key);
35
+ return void 0;
36
+ }
37
+ return entry.data;
38
+ }
39
+ set(key, data, ttlSeconds) {
40
+ this.store.set(key, {
41
+ data,
42
+ expiresAt: Date.now() + ttlSeconds * 1e3
43
+ });
44
+ }
45
+ clear() {
46
+ this.store.clear();
47
+ }
48
+ };
49
+
50
+ // src/core/tool-converter.ts
51
+ var import_ai = require("ai");
52
+
53
+ // src/core/http-executor.ts
54
+ function createExecutor(metadata, baseUrl, apiKey) {
55
+ return async (args) => {
56
+ const { method, path, bodyDefaults } = metadata;
57
+ const remainingArgs = { ...args };
58
+ let resolvedPath = path;
59
+ const pathParams = path.match(/\{(\w+)\}/g);
60
+ if (pathParams) {
61
+ for (const param of pathParams) {
62
+ const paramName = param.slice(1, -1);
63
+ if (paramName in remainingArgs) {
64
+ resolvedPath = resolvedPath.replace(
65
+ param,
66
+ encodeURIComponent(String(remainingArgs[paramName]))
67
+ );
68
+ delete remainingArgs[paramName];
69
+ }
70
+ }
71
+ }
72
+ let url = `${baseUrl}${resolvedPath}`;
73
+ const fetchOptions = {
74
+ method,
75
+ headers: {
76
+ Authorization: `Bearer ${apiKey}`,
77
+ "Content-Type": "application/json"
78
+ }
79
+ };
80
+ if (method === "GET" || method === "DELETE") {
81
+ const params = new URLSearchParams();
82
+ for (const [key, value] of Object.entries(remainingArgs)) {
83
+ if (value !== void 0 && value !== null) {
84
+ params.set(key, String(value));
85
+ }
86
+ }
87
+ const qs = params.toString();
88
+ if (qs) url += `?${qs}`;
89
+ } else {
90
+ const body = { ...bodyDefaults, ...remainingArgs };
91
+ fetchOptions.body = JSON.stringify(body);
92
+ }
93
+ const response = await fetch(url, fetchOptions);
94
+ const data = await response.json();
95
+ return data;
96
+ };
97
+ }
98
+
99
+ // src/core/tool-converter.ts
100
+ function convertTools(tools, baseUrl, apiKey) {
101
+ const result = {};
102
+ for (const t of tools) {
103
+ const { name, description, parameters } = t.function;
104
+ const metadata = t.metadata;
105
+ result[name] = (0, import_ai.tool)({
106
+ description,
107
+ parameters: (0, import_ai.jsonSchema)(parameters),
108
+ execute: createExecutor(metadata, baseUrl, apiKey)
109
+ });
110
+ }
111
+ return result;
112
+ }
113
+ function filterTools(tools, options) {
114
+ let filtered = tools;
115
+ if (options.only && options.only.length > 0) {
116
+ const onlySet = new Set(options.only.map((s) => s.toLowerCase()));
117
+ filtered = filtered.filter((t) => {
118
+ const name = t.function.name.toLowerCase();
119
+ const provider = t.metadata.provider.toLowerCase();
120
+ const service = t.metadata.service.toLowerCase();
121
+ return onlySet.has(name) || onlySet.has(provider) || onlySet.has(service);
122
+ });
123
+ }
124
+ if (options.except && options.except.length > 0) {
125
+ const exceptSet = new Set(options.except.map((s) => s.toLowerCase()));
126
+ filtered = filtered.filter((t) => {
127
+ const name = t.function.name.toLowerCase();
128
+ const provider = t.metadata.provider.toLowerCase();
129
+ const service = t.metadata.service.toLowerCase();
130
+ return !exceptSet.has(name) && !exceptSet.has(provider) && !exceptSet.has(service);
131
+ });
132
+ }
133
+ return filtered;
134
+ }
135
+
136
+ // src/core/client.ts
137
+ var DEFAULT_BASE_URL = "https://app.supyagent.com";
138
+ var CACHE_KEY = "tools";
139
+ function supyagent(options) {
140
+ const { apiKey, baseUrl = DEFAULT_BASE_URL } = options;
141
+ const cache = new TTLCache();
142
+ return {
143
+ async tools(filterOptions) {
144
+ const cacheTTL = resolveCacheTTL(filterOptions?.cache);
145
+ let response = cacheTTL > 0 ? cache.get(CACHE_KEY) : void 0;
146
+ if (!response) {
147
+ const res = await fetch(`${baseUrl}/api/v1/tools`, {
148
+ headers: {
149
+ Authorization: `Bearer ${apiKey}`,
150
+ "Content-Type": "application/json"
151
+ }
152
+ });
153
+ if (!res.ok) {
154
+ const error = await res.text();
155
+ throw new Error(
156
+ `Supyagent API error (${res.status}): ${error}`
157
+ );
158
+ }
159
+ response = await res.json();
160
+ if (cacheTTL > 0) {
161
+ cache.set(CACHE_KEY, response, cacheTTL);
162
+ }
163
+ }
164
+ const toolBaseUrl = response.base_url || baseUrl;
165
+ const toolsArray = Array.isArray(response.tools) ? response.tools : [];
166
+ const filtered = filterTools(toolsArray, {
167
+ only: filterOptions?.only,
168
+ except: filterOptions?.except
169
+ });
170
+ return convertTools(filtered, toolBaseUrl, apiKey);
171
+ }
172
+ };
173
+ }
174
+ function resolveCacheTTL(cache) {
175
+ if (cache === true) return 60;
176
+ if (typeof cache === "number") return cache;
177
+ return 0;
178
+ }
179
+ // Annotate the CommonJS export names for ESM import in node:
180
+ 0 && (module.exports = {
181
+ supyagent
182
+ });
183
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/core/cache.ts","../src/core/tool-converter.ts","../src/core/http-executor.ts","../src/core/client.ts"],"sourcesContent":["export { supyagent } from \"./core/client.js\";\nexport type {\n SupyagentOptions,\n SupyagentClient,\n ToolFilterOptions,\n ToolMetadata,\n OpenAITool,\n ToolsResponse,\n} from \"./core/types.js\";\n","interface CacheEntry<T> {\n data: T;\n expiresAt: number;\n}\n\nexport class TTLCache<T> {\n private store = new Map<string, CacheEntry<T>>();\n\n get(key: string): T | undefined {\n const entry = this.store.get(key);\n if (!entry) return undefined;\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n return entry.data;\n }\n\n set(key: string, data: T, ttlSeconds: number): void {\n this.store.set(key, {\n data,\n expiresAt: Date.now() + ttlSeconds * 1000,\n });\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n","import { tool, jsonSchema } from \"ai\";\nimport type { OpenAITool } from \"./types.js\";\nimport { createExecutor } from \"./http-executor.js\";\n\n/**\n * Converts an array of OpenAI-format tools from the supyagent API\n * into a Record of AI SDK tool() instances ready for streamText/generateText.\n */\nexport function convertTools(\n tools: OpenAITool[],\n baseUrl: string,\n apiKey: string\n): Record<string, import(\"ai\").Tool> {\n const result: Record<string, import(\"ai\").Tool> = {};\n\n for (const t of tools) {\n const { name, description, parameters } = t.function;\n const metadata = t.metadata;\n\n result[name] = tool({\n description,\n parameters: jsonSchema(parameters as Parameters<typeof jsonSchema>[0]),\n execute: createExecutor(metadata, baseUrl, apiKey),\n });\n }\n\n return result;\n}\n\n/**\n * Filter tools by provider, service, or tool name.\n */\nexport function filterTools(\n tools: OpenAITool[],\n options: { only?: string[]; except?: string[] }\n): OpenAITool[] {\n let filtered = tools;\n\n if (options.only && options.only.length > 0) {\n const onlySet = new Set(options.only.map((s) => s.toLowerCase()));\n filtered = filtered.filter((t) => {\n const name = t.function.name.toLowerCase();\n const provider = t.metadata.provider.toLowerCase();\n const service = t.metadata.service.toLowerCase();\n return onlySet.has(name) || onlySet.has(provider) || onlySet.has(service);\n });\n }\n\n if (options.except && options.except.length > 0) {\n const exceptSet = new Set(options.except.map((s) => s.toLowerCase()));\n filtered = filtered.filter((t) => {\n const name = t.function.name.toLowerCase();\n const provider = t.metadata.provider.toLowerCase();\n const service = t.metadata.service.toLowerCase();\n return (\n !exceptSet.has(name) &&\n !exceptSet.has(provider) &&\n !exceptSet.has(service)\n );\n });\n }\n\n return filtered;\n}\n","import type { ToolMetadata } from \"./types.js\";\n\n/**\n * Creates an execute function for a tool that calls the supyagent API.\n *\n * Handles:\n * - Path parameter substitution (e.g., {messageId} in /api/v1/gmail/messages/{messageId})\n * - GET/DELETE: remaining args → query string\n * - POST/PUT/PATCH: merge bodyDefaults + remaining args → JSON body\n */\nexport function createExecutor(\n metadata: ToolMetadata,\n baseUrl: string,\n apiKey: string\n): (args: Record<string, unknown>) => Promise<unknown> {\n return async (args: Record<string, unknown>) => {\n const { method, path, bodyDefaults } = metadata;\n\n // Extract path parameters and substitute into the path\n const remainingArgs = { ...args };\n let resolvedPath = path;\n\n const pathParams = path.match(/\\{(\\w+)\\}/g);\n if (pathParams) {\n for (const param of pathParams) {\n const paramName = param.slice(1, -1);\n if (paramName in remainingArgs) {\n resolvedPath = resolvedPath.replace(\n param,\n encodeURIComponent(String(remainingArgs[paramName]))\n );\n delete remainingArgs[paramName];\n }\n }\n }\n\n let url = `${baseUrl}${resolvedPath}`;\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n };\n\n if (method === \"GET\" || method === \"DELETE\") {\n // Remaining args go as query parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(remainingArgs)) {\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n } else {\n // POST/PUT/PATCH: merge bodyDefaults with remaining args\n const body = { ...bodyDefaults, ...remainingArgs };\n fetchOptions.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, fetchOptions);\n const data = await response.json();\n return data;\n };\n}\n","import type {\n SupyagentOptions,\n SupyagentClient,\n ToolFilterOptions,\n ToolsResponse,\n} from \"./types.js\";\nimport { TTLCache } from \"./cache.js\";\nimport { convertTools, filterTools } from \"./tool-converter.js\";\n\nconst DEFAULT_BASE_URL = \"https://app.supyagent.com\";\nconst CACHE_KEY = \"tools\";\n\n/**\n * Create a supyagent client for fetching and converting tools.\n *\n * @example\n * ```ts\n * import { supyagent } from '@supyagent/sdk';\n *\n * const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });\n * const tools = await client.tools({ cache: 300 });\n * ```\n */\nexport function supyagent(options: SupyagentOptions): SupyagentClient {\n const { apiKey, baseUrl = DEFAULT_BASE_URL } = options;\n const cache = new TTLCache<ToolsResponse>();\n\n return {\n async tools(filterOptions?: ToolFilterOptions) {\n const cacheTTL = resolveCacheTTL(filterOptions?.cache);\n\n // Check cache\n let response = cacheTTL > 0 ? cache.get(CACHE_KEY) : undefined;\n\n if (!response) {\n // Fetch from API\n const res = await fetch(`${baseUrl}/api/v1/tools`, {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!res.ok) {\n const error = await res.text();\n throw new Error(\n `Supyagent API error (${res.status}): ${error}`\n );\n }\n\n response = (await res.json()) as ToolsResponse;\n\n // Store in cache if TTL > 0\n if (cacheTTL > 0) {\n cache.set(CACHE_KEY, response, cacheTTL);\n }\n }\n\n // Use API-reported base_url for tool execution\n const toolBaseUrl = response.base_url || baseUrl;\n\n // Guard against non-array tools (e.g., API returns empty or unexpected shape)\n const toolsArray = Array.isArray(response.tools) ? response.tools : [];\n\n // Filter\n const filtered = filterTools(toolsArray, {\n only: filterOptions?.only,\n except: filterOptions?.except,\n });\n\n // Convert to AI SDK tools\n return convertTools(filtered, toolBaseUrl, apiKey);\n },\n };\n}\n\nfunction resolveCacheTTL(cache?: boolean | number): number {\n if (cache === true) return 60;\n if (typeof cache === \"number\") return cache;\n return 0;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACKO,IAAM,WAAN,MAAkB;AAAA,EACf,QAAQ,oBAAI,IAA2B;AAAA,EAE/C,IAAI,KAA4B;AAC9B,UAAM,QAAQ,KAAK,MAAM,IAAI,GAAG;AAChC,QAAI,CAAC,MAAO,QAAO;AACnB,QAAI,KAAK,IAAI,IAAI,MAAM,WAAW;AAChC,WAAK,MAAM,OAAO,GAAG;AACrB,aAAO;AAAA,IACT;AACA,WAAO,MAAM;AAAA,EACf;AAAA,EAEA,IAAI,KAAa,MAAS,YAA0B;AAClD,SAAK,MAAM,IAAI,KAAK;AAAA,MAClB;AAAA,MACA,WAAW,KAAK,IAAI,IAAI,aAAa;AAAA,IACvC,CAAC;AAAA,EACH;AAAA,EAEA,QAAc;AACZ,SAAK,MAAM,MAAM;AAAA,EACnB;AACF;;;AC5BA,gBAAiC;;;ACU1B,SAAS,eACd,UACA,SACA,QACqD;AACrD,SAAO,OAAO,SAAkC;AAC9C,UAAM,EAAE,QAAQ,MAAM,aAAa,IAAI;AAGvC,UAAM,gBAAgB,EAAE,GAAG,KAAK;AAChC,QAAI,eAAe;AAEnB,UAAM,aAAa,KAAK,MAAM,YAAY;AAC1C,QAAI,YAAY;AACd,iBAAW,SAAS,YAAY;AAC9B,cAAM,YAAY,MAAM,MAAM,GAAG,EAAE;AACnC,YAAI,aAAa,eAAe;AAC9B,yBAAe,aAAa;AAAA,YAC1B;AAAA,YACA,mBAAmB,OAAO,cAAc,SAAS,CAAC,CAAC;AAAA,UACrD;AACA,iBAAO,cAAc,SAAS;AAAA,QAChC;AAAA,MACF;AAAA,IACF;AAEA,QAAI,MAAM,GAAG,OAAO,GAAG,YAAY;AAEnC,UAAM,eAA4B;AAAA,MAChC;AAAA,MACA,SAAS;AAAA,QACP,eAAe,UAAU,MAAM;AAAA,QAC/B,gBAAgB;AAAA,MAClB;AAAA,IACF;AAEA,QAAI,WAAW,SAAS,WAAW,UAAU;AAE3C,YAAM,SAAS,IAAI,gBAAgB;AACnC,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,aAAa,GAAG;AACxD,YAAI,UAAU,UAAa,UAAU,MAAM;AACzC,iBAAO,IAAI,KAAK,OAAO,KAAK,CAAC;AAAA,QAC/B;AAAA,MACF;AACA,YAAM,KAAK,OAAO,SAAS;AAC3B,UAAI,GAAI,QAAO,IAAI,EAAE;AAAA,IACvB,OAAO;AAEL,YAAM,OAAO,EAAE,GAAG,cAAc,GAAG,cAAc;AACjD,mBAAa,OAAO,KAAK,UAAU,IAAI;AAAA,IACzC;AAEA,UAAM,WAAW,MAAM,MAAM,KAAK,YAAY;AAC9C,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,WAAO;AAAA,EACT;AACF;;;AD1DO,SAAS,aACd,OACA,SACA,QACmC;AACnC,QAAM,SAA4C,CAAC;AAEnD,aAAW,KAAK,OAAO;AACrB,UAAM,EAAE,MAAM,aAAa,WAAW,IAAI,EAAE;AAC5C,UAAM,WAAW,EAAE;AAEnB,WAAO,IAAI,QAAI,gBAAK;AAAA,MAClB;AAAA,MACA,gBAAY,sBAAW,UAA8C;AAAA,MACrE,SAAS,eAAe,UAAU,SAAS,MAAM;AAAA,IACnD,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAKO,SAAS,YACd,OACA,SACc;AACd,MAAI,WAAW;AAEf,MAAI,QAAQ,QAAQ,QAAQ,KAAK,SAAS,GAAG;AAC3C,UAAM,UAAU,IAAI,IAAI,QAAQ,KAAK,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AAChE,eAAW,SAAS,OAAO,CAAC,MAAM;AAChC,YAAM,OAAO,EAAE,SAAS,KAAK,YAAY;AACzC,YAAM,WAAW,EAAE,SAAS,SAAS,YAAY;AACjD,YAAM,UAAU,EAAE,SAAS,QAAQ,YAAY;AAC/C,aAAO,QAAQ,IAAI,IAAI,KAAK,QAAQ,IAAI,QAAQ,KAAK,QAAQ,IAAI,OAAO;AAAA,IAC1E,CAAC;AAAA,EACH;AAEA,MAAI,QAAQ,UAAU,QAAQ,OAAO,SAAS,GAAG;AAC/C,UAAM,YAAY,IAAI,IAAI,QAAQ,OAAO,IAAI,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;AACpE,eAAW,SAAS,OAAO,CAAC,MAAM;AAChC,YAAM,OAAO,EAAE,SAAS,KAAK,YAAY;AACzC,YAAM,WAAW,EAAE,SAAS,SAAS,YAAY;AACjD,YAAM,UAAU,EAAE,SAAS,QAAQ,YAAY;AAC/C,aACE,CAAC,UAAU,IAAI,IAAI,KACnB,CAAC,UAAU,IAAI,QAAQ,KACvB,CAAC,UAAU,IAAI,OAAO;AAAA,IAE1B,CAAC;AAAA,EACH;AAEA,SAAO;AACT;;;AEtDA,IAAM,mBAAmB;AACzB,IAAM,YAAY;AAaX,SAAS,UAAU,SAA4C;AACpE,QAAM,EAAE,QAAQ,UAAU,iBAAiB,IAAI;AAC/C,QAAM,QAAQ,IAAI,SAAwB;AAE1C,SAAO;AAAA,IACL,MAAM,MAAM,eAAmC;AAC7C,YAAM,WAAW,gBAAgB,eAAe,KAAK;AAGrD,UAAI,WAAW,WAAW,IAAI,MAAM,IAAI,SAAS,IAAI;AAErD,UAAI,CAAC,UAAU;AAEb,cAAM,MAAM,MAAM,MAAM,GAAG,OAAO,iBAAiB;AAAA,UACjD,SAAS;AAAA,YACP,eAAe,UAAU,MAAM;AAAA,YAC/B,gBAAgB;AAAA,UAClB;AAAA,QACF,CAAC;AAED,YAAI,CAAC,IAAI,IAAI;AACX,gBAAM,QAAQ,MAAM,IAAI,KAAK;AAC7B,gBAAM,IAAI;AAAA,YACR,wBAAwB,IAAI,MAAM,MAAM,KAAK;AAAA,UAC/C;AAAA,QACF;AAEA,mBAAY,MAAM,IAAI,KAAK;AAG3B,YAAI,WAAW,GAAG;AAChB,gBAAM,IAAI,WAAW,UAAU,QAAQ;AAAA,QACzC;AAAA,MACF;AAGA,YAAM,cAAc,SAAS,YAAY;AAGzC,YAAM,aAAa,MAAM,QAAQ,SAAS,KAAK,IAAI,SAAS,QAAQ,CAAC;AAGrE,YAAM,WAAW,YAAY,YAAY;AAAA,QACvC,MAAM,eAAe;AAAA,QACrB,QAAQ,eAAe;AAAA,MACzB,CAAC;AAGD,aAAO,aAAa,UAAU,aAAa,MAAM;AAAA,IACnD;AAAA,EACF;AACF;AAEA,SAAS,gBAAgB,OAAkC;AACzD,MAAI,UAAU,KAAM,QAAO;AAC3B,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,SAAO;AACT;","names":[]}
@@ -0,0 +1,66 @@
1
+ import * as ai from 'ai';
2
+
3
+ /** Mirrors the ToolSchema.metadata from supyagent_service tool-schemas.ts */
4
+ interface ToolMetadata {
5
+ provider: string;
6
+ service: string;
7
+ permission: string;
8
+ method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE";
9
+ path: string;
10
+ bodyDefaults?: Record<string, string>;
11
+ category?: string;
12
+ tags?: string[];
13
+ }
14
+ /** A single tool as returned by the /api/v1/tools endpoint */
15
+ interface OpenAITool {
16
+ type: "function";
17
+ function: {
18
+ name: string;
19
+ description: string;
20
+ parameters: {
21
+ type: "object";
22
+ properties: Record<string, unknown>;
23
+ required?: string[];
24
+ };
25
+ };
26
+ metadata: ToolMetadata;
27
+ }
28
+ /** Response shape from GET /api/v1/tools */
29
+ interface ToolsResponse {
30
+ tools: OpenAITool[];
31
+ base_url: string;
32
+ total: number;
33
+ }
34
+ /** Options for the supyagent() factory */
35
+ interface SupyagentOptions {
36
+ apiKey: string;
37
+ baseUrl?: string;
38
+ }
39
+ /** Options for the tools() method */
40
+ interface ToolFilterOptions {
41
+ /** Filter to only these providers, services, or tool names */
42
+ only?: string[];
43
+ /** Exclude these providers, services, or tool names */
44
+ except?: string[];
45
+ /** Cache TTL in seconds. true = 60s, number = custom TTL, false/undefined = no cache */
46
+ cache?: boolean | number;
47
+ }
48
+ /** The supyagent client interface */
49
+ interface SupyagentClient {
50
+ tools(options?: ToolFilterOptions): Promise<Record<string, ai.Tool>>;
51
+ }
52
+
53
+ /**
54
+ * Create a supyagent client for fetching and converting tools.
55
+ *
56
+ * @example
57
+ * ```ts
58
+ * import { supyagent } from '@supyagent/sdk';
59
+ *
60
+ * const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });
61
+ * const tools = await client.tools({ cache: 300 });
62
+ * ```
63
+ */
64
+ declare function supyagent(options: SupyagentOptions): SupyagentClient;
65
+
66
+ export { type OpenAITool, type SupyagentClient, type SupyagentOptions, type ToolFilterOptions, type ToolMetadata, type ToolsResponse, supyagent };
package/dist/index.js CHANGED
@@ -136,7 +136,8 @@ function supyagent(options) {
136
136
  }
137
137
  }
138
138
  const toolBaseUrl = response.base_url || baseUrl;
139
- const filtered = filterTools(response.tools, {
139
+ const toolsArray = Array.isArray(response.tools) ? response.tools : [];
140
+ const filtered = filterTools(toolsArray, {
140
141
  only: filterOptions?.only,
141
142
  except: filterOptions?.except
142
143
  });
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/cache.ts","../src/core/tool-converter.ts","../src/core/http-executor.ts","../src/core/client.ts"],"sourcesContent":["interface CacheEntry<T> {\n data: T;\n expiresAt: number;\n}\n\nexport class TTLCache<T> {\n private store = new Map<string, CacheEntry<T>>();\n\n get(key: string): T | undefined {\n const entry = this.store.get(key);\n if (!entry) return undefined;\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n return entry.data;\n }\n\n set(key: string, data: T, ttlSeconds: number): void {\n this.store.set(key, {\n data,\n expiresAt: Date.now() + ttlSeconds * 1000,\n });\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n","import { tool, jsonSchema } from \"ai\";\nimport type { OpenAITool } from \"./types.js\";\nimport { createExecutor } from \"./http-executor.js\";\n\n/**\n * Converts an array of OpenAI-format tools from the supyagent API\n * into a Record of AI SDK tool() instances ready for streamText/generateText.\n */\nexport function convertTools(\n tools: OpenAITool[],\n baseUrl: string,\n apiKey: string\n): Record<string, import(\"ai\").Tool> {\n const result: Record<string, import(\"ai\").Tool> = {};\n\n for (const t of tools) {\n const { name, description, parameters } = t.function;\n const metadata = t.metadata;\n\n result[name] = tool({\n description,\n parameters: jsonSchema(parameters as Parameters<typeof jsonSchema>[0]),\n execute: createExecutor(metadata, baseUrl, apiKey),\n });\n }\n\n return result;\n}\n\n/**\n * Filter tools by provider, service, or tool name.\n */\nexport function filterTools(\n tools: OpenAITool[],\n options: { only?: string[]; except?: string[] }\n): OpenAITool[] {\n let filtered = tools;\n\n if (options.only && options.only.length > 0) {\n const onlySet = new Set(options.only.map((s) => s.toLowerCase()));\n filtered = filtered.filter((t) => {\n const name = t.function.name.toLowerCase();\n const provider = t.metadata.provider.toLowerCase();\n const service = t.metadata.service.toLowerCase();\n return onlySet.has(name) || onlySet.has(provider) || onlySet.has(service);\n });\n }\n\n if (options.except && options.except.length > 0) {\n const exceptSet = new Set(options.except.map((s) => s.toLowerCase()));\n filtered = filtered.filter((t) => {\n const name = t.function.name.toLowerCase();\n const provider = t.metadata.provider.toLowerCase();\n const service = t.metadata.service.toLowerCase();\n return (\n !exceptSet.has(name) &&\n !exceptSet.has(provider) &&\n !exceptSet.has(service)\n );\n });\n }\n\n return filtered;\n}\n","import type { ToolMetadata } from \"./types.js\";\n\n/**\n * Creates an execute function for a tool that calls the supyagent API.\n *\n * Handles:\n * - Path parameter substitution (e.g., {messageId} in /api/v1/gmail/messages/{messageId})\n * - GET/DELETE: remaining args → query string\n * - POST/PUT/PATCH: merge bodyDefaults + remaining args → JSON body\n */\nexport function createExecutor(\n metadata: ToolMetadata,\n baseUrl: string,\n apiKey: string\n): (args: Record<string, unknown>) => Promise<unknown> {\n return async (args: Record<string, unknown>) => {\n const { method, path, bodyDefaults } = metadata;\n\n // Extract path parameters and substitute into the path\n const remainingArgs = { ...args };\n let resolvedPath = path;\n\n const pathParams = path.match(/\\{(\\w+)\\}/g);\n if (pathParams) {\n for (const param of pathParams) {\n const paramName = param.slice(1, -1);\n if (paramName in remainingArgs) {\n resolvedPath = resolvedPath.replace(\n param,\n encodeURIComponent(String(remainingArgs[paramName]))\n );\n delete remainingArgs[paramName];\n }\n }\n }\n\n let url = `${baseUrl}${resolvedPath}`;\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n };\n\n if (method === \"GET\" || method === \"DELETE\") {\n // Remaining args go as query parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(remainingArgs)) {\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n } else {\n // POST/PUT/PATCH: merge bodyDefaults with remaining args\n const body = { ...bodyDefaults, ...remainingArgs };\n fetchOptions.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, fetchOptions);\n const data = await response.json();\n return data;\n };\n}\n","import type {\n SupyagentOptions,\n SupyagentClient,\n ToolFilterOptions,\n ToolsResponse,\n} from \"./types.js\";\nimport { TTLCache } from \"./cache.js\";\nimport { convertTools, filterTools } from \"./tool-converter.js\";\n\nconst DEFAULT_BASE_URL = \"https://app.supyagent.com\";\nconst CACHE_KEY = \"tools\";\n\n/**\n * Create a supyagent client for fetching and converting tools.\n *\n * @example\n * ```ts\n * import { supyagent } from '@supyagent/sdk';\n *\n * const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });\n * const tools = await client.tools({ cache: 300 });\n * ```\n */\nexport function supyagent(options: SupyagentOptions): SupyagentClient {\n const { apiKey, baseUrl = DEFAULT_BASE_URL } = options;\n const cache = new TTLCache<ToolsResponse>();\n\n return {\n async tools(filterOptions?: ToolFilterOptions) {\n const cacheTTL = resolveCacheTTL(filterOptions?.cache);\n\n // Check cache\n let response = cacheTTL > 0 ? cache.get(CACHE_KEY) : undefined;\n\n if (!response) {\n // Fetch from API\n const res = await fetch(`${baseUrl}/api/v1/tools`, {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!res.ok) {\n const error = await res.text();\n throw new Error(\n `Supyagent API error (${res.status}): ${error}`\n );\n }\n\n response = (await res.json()) as ToolsResponse;\n\n // Store in cache if TTL > 0\n if (cacheTTL > 0) {\n cache.set(CACHE_KEY, response, cacheTTL);\n }\n }\n\n // Use API-reported base_url for tool execution\n const toolBaseUrl = response.base_url || baseUrl;\n\n // Filter\n const filtered = filterTools(response.tools, {\n only: filterOptions?.only,\n except: filterOptions?.except,\n });\n\n // Convert to AI SDK tools\n return convertTools(filtered, toolBaseUrl, apiKey);\n },\n };\n}\n\nfunction resolveCacheTTL(cache?: boolean | number): number {\n if (cache === true) return 60;\n if (typeof cache === \"number\") return cache;\n return 0;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/core/cache.ts","../src/core/tool-converter.ts","../src/core/http-executor.ts","../src/core/client.ts"],"sourcesContent":["interface CacheEntry<T> {\n data: T;\n expiresAt: number;\n}\n\nexport class TTLCache<T> {\n private store = new Map<string, CacheEntry<T>>();\n\n get(key: string): T | undefined {\n const entry = this.store.get(key);\n if (!entry) return undefined;\n if (Date.now() > entry.expiresAt) {\n this.store.delete(key);\n return undefined;\n }\n return entry.data;\n }\n\n set(key: string, data: T, ttlSeconds: number): void {\n this.store.set(key, {\n data,\n expiresAt: Date.now() + ttlSeconds * 1000,\n });\n }\n\n clear(): void {\n this.store.clear();\n }\n}\n","import { tool, jsonSchema } from \"ai\";\nimport type { OpenAITool } from \"./types.js\";\nimport { createExecutor } from \"./http-executor.js\";\n\n/**\n * Converts an array of OpenAI-format tools from the supyagent API\n * into a Record of AI SDK tool() instances ready for streamText/generateText.\n */\nexport function convertTools(\n tools: OpenAITool[],\n baseUrl: string,\n apiKey: string\n): Record<string, import(\"ai\").Tool> {\n const result: Record<string, import(\"ai\").Tool> = {};\n\n for (const t of tools) {\n const { name, description, parameters } = t.function;\n const metadata = t.metadata;\n\n result[name] = tool({\n description,\n parameters: jsonSchema(parameters as Parameters<typeof jsonSchema>[0]),\n execute: createExecutor(metadata, baseUrl, apiKey),\n });\n }\n\n return result;\n}\n\n/**\n * Filter tools by provider, service, or tool name.\n */\nexport function filterTools(\n tools: OpenAITool[],\n options: { only?: string[]; except?: string[] }\n): OpenAITool[] {\n let filtered = tools;\n\n if (options.only && options.only.length > 0) {\n const onlySet = new Set(options.only.map((s) => s.toLowerCase()));\n filtered = filtered.filter((t) => {\n const name = t.function.name.toLowerCase();\n const provider = t.metadata.provider.toLowerCase();\n const service = t.metadata.service.toLowerCase();\n return onlySet.has(name) || onlySet.has(provider) || onlySet.has(service);\n });\n }\n\n if (options.except && options.except.length > 0) {\n const exceptSet = new Set(options.except.map((s) => s.toLowerCase()));\n filtered = filtered.filter((t) => {\n const name = t.function.name.toLowerCase();\n const provider = t.metadata.provider.toLowerCase();\n const service = t.metadata.service.toLowerCase();\n return (\n !exceptSet.has(name) &&\n !exceptSet.has(provider) &&\n !exceptSet.has(service)\n );\n });\n }\n\n return filtered;\n}\n","import type { ToolMetadata } from \"./types.js\";\n\n/**\n * Creates an execute function for a tool that calls the supyagent API.\n *\n * Handles:\n * - Path parameter substitution (e.g., {messageId} in /api/v1/gmail/messages/{messageId})\n * - GET/DELETE: remaining args → query string\n * - POST/PUT/PATCH: merge bodyDefaults + remaining args → JSON body\n */\nexport function createExecutor(\n metadata: ToolMetadata,\n baseUrl: string,\n apiKey: string\n): (args: Record<string, unknown>) => Promise<unknown> {\n return async (args: Record<string, unknown>) => {\n const { method, path, bodyDefaults } = metadata;\n\n // Extract path parameters and substitute into the path\n const remainingArgs = { ...args };\n let resolvedPath = path;\n\n const pathParams = path.match(/\\{(\\w+)\\}/g);\n if (pathParams) {\n for (const param of pathParams) {\n const paramName = param.slice(1, -1);\n if (paramName in remainingArgs) {\n resolvedPath = resolvedPath.replace(\n param,\n encodeURIComponent(String(remainingArgs[paramName]))\n );\n delete remainingArgs[paramName];\n }\n }\n }\n\n let url = `${baseUrl}${resolvedPath}`;\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n };\n\n if (method === \"GET\" || method === \"DELETE\") {\n // Remaining args go as query parameters\n const params = new URLSearchParams();\n for (const [key, value] of Object.entries(remainingArgs)) {\n if (value !== undefined && value !== null) {\n params.set(key, String(value));\n }\n }\n const qs = params.toString();\n if (qs) url += `?${qs}`;\n } else {\n // POST/PUT/PATCH: merge bodyDefaults with remaining args\n const body = { ...bodyDefaults, ...remainingArgs };\n fetchOptions.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, fetchOptions);\n const data = await response.json();\n return data;\n };\n}\n","import type {\n SupyagentOptions,\n SupyagentClient,\n ToolFilterOptions,\n ToolsResponse,\n} from \"./types.js\";\nimport { TTLCache } from \"./cache.js\";\nimport { convertTools, filterTools } from \"./tool-converter.js\";\n\nconst DEFAULT_BASE_URL = \"https://app.supyagent.com\";\nconst CACHE_KEY = \"tools\";\n\n/**\n * Create a supyagent client for fetching and converting tools.\n *\n * @example\n * ```ts\n * import { supyagent } from '@supyagent/sdk';\n *\n * const client = supyagent({ apiKey: process.env.SUPYAGENT_API_KEY! });\n * const tools = await client.tools({ cache: 300 });\n * ```\n */\nexport function supyagent(options: SupyagentOptions): SupyagentClient {\n const { apiKey, baseUrl = DEFAULT_BASE_URL } = options;\n const cache = new TTLCache<ToolsResponse>();\n\n return {\n async tools(filterOptions?: ToolFilterOptions) {\n const cacheTTL = resolveCacheTTL(filterOptions?.cache);\n\n // Check cache\n let response = cacheTTL > 0 ? cache.get(CACHE_KEY) : undefined;\n\n if (!response) {\n // Fetch from API\n const res = await fetch(`${baseUrl}/api/v1/tools`, {\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n });\n\n if (!res.ok) {\n const error = await res.text();\n throw new Error(\n `Supyagent API error (${res.status}): ${error}`\n );\n }\n\n response = (await res.json()) as ToolsResponse;\n\n // Store in cache if TTL > 0\n if (cacheTTL > 0) {\n cache.set(CACHE_KEY, response, cacheTTL);\n }\n }\n\n // Use API-reported base_url for tool execution\n const toolBaseUrl = response.base_url || baseUrl;\n\n // Guard against non-array tools (e.g., API returns empty or unexpected shape)\n const toolsArray = Array.isArray(response.tools) ? response.tools : [];\n\n // Filter\n const filtered = filterTools(toolsArray, {\n only: filterOptions?.only,\n except: filterOptions?.except,\n });\n\n // Convert to AI SDK tools\n return convertTools(filtered, toolBaseUrl, apiKey);\n },\n };\n}\n\nfunction resolveCacheTTL(cache?: boolean | number): number {\n if (cache === true) return 60;\n if (typeof cache === \"number\") return cache;\n return 0;\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/prisma.ts
21
+ var prisma_exports = {};
22
+ __export(prisma_exports, {
23
+ createPrismaAdapter: () => createPrismaAdapter
24
+ });
25
+ module.exports = __toCommonJS(prisma_exports);
26
+
27
+ // src/persistence/prisma-adapter.ts
28
+ function createPrismaAdapter(prisma) {
29
+ return {
30
+ async saveChat(chatId, messages) {
31
+ const firstUserMsg = messages.find((m) => m.role === "user");
32
+ const title = extractTitle(firstUserMsg);
33
+ await prisma.chat.upsert({
34
+ where: { id: chatId },
35
+ create: { id: chatId, title },
36
+ update: { title }
37
+ });
38
+ const existingCount = await prisma.message.count({
39
+ where: { chatId }
40
+ });
41
+ const newMessages = messages.slice(existingCount);
42
+ if (newMessages.length > 0) {
43
+ await prisma.message.createMany({
44
+ data: newMessages.map((msg) => ({
45
+ id: msg.id,
46
+ chatId,
47
+ role: msg.role,
48
+ parts: JSON.stringify(msg.parts),
49
+ metadata: msg.metadata ? JSON.stringify(msg.metadata) : null
50
+ }))
51
+ });
52
+ }
53
+ },
54
+ async loadChat(chatId) {
55
+ const messages = await prisma.message.findMany({
56
+ where: { chatId },
57
+ orderBy: { createdAt: "asc" }
58
+ });
59
+ return messages.map((msg) => ({
60
+ id: msg.id,
61
+ role: msg.role,
62
+ parts: JSON.parse(msg.parts),
63
+ metadata: msg.metadata ? JSON.parse(msg.metadata) : void 0
64
+ }));
65
+ },
66
+ async listChats() {
67
+ return prisma.chat.findMany({
68
+ orderBy: { updatedAt: "desc" },
69
+ select: {
70
+ id: true,
71
+ title: true,
72
+ createdAt: true,
73
+ updatedAt: true
74
+ }
75
+ });
76
+ },
77
+ async deleteChat(chatId) {
78
+ await prisma.chat.delete({ where: { id: chatId } });
79
+ }
80
+ };
81
+ }
82
+ function extractTitle(message) {
83
+ if (!message) return "New Chat";
84
+ const textPart = message.parts.find((p) => p.type === "text");
85
+ if (textPart && typeof textPart.text === "string") {
86
+ return textPart.text.slice(0, 100);
87
+ }
88
+ return "New Chat";
89
+ }
90
+ // Annotate the CommonJS export names for ESM import in node:
91
+ 0 && (module.exports = {
92
+ createPrismaAdapter
93
+ });
94
+ //# sourceMappingURL=prisma.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/prisma.ts","../src/persistence/prisma-adapter.ts"],"sourcesContent":["export { createPrismaAdapter } from \"./persistence/prisma-adapter.js\";\nexport type { ChatAdapter, ChatSummary, UIMessageLike } from \"./persistence/types.js\";\n","import type { ChatAdapter, ChatSummary, UIMessageLike } from \"./types.js\";\n\n/**\n * Accepts any PrismaClient instance.\n * We use `any` here because Prisma generates unique client types per schema,\n * and a structural interface can't satisfy Prisma's branded enum types\n * (e.g. SortOrder). The implementation only calls standard Prisma methods.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype PrismaLike = any;\n\n/**\n * Create a ChatAdapter backed by Prisma.\n *\n * @example\n * ```ts\n * import { createPrismaAdapter } from '@supyagent/sdk/prisma';\n * import { prisma } from '@/lib/prisma';\n *\n * const adapter = createPrismaAdapter(prisma);\n * ```\n */\nexport function createPrismaAdapter(prisma: PrismaLike): ChatAdapter {\n return {\n async saveChat(chatId: string, messages: UIMessageLike[]) {\n // Extract title from first user message\n const firstUserMsg = messages.find((m) => m.role === \"user\");\n const title = extractTitle(firstUserMsg);\n\n // Upsert the chat record\n await prisma.chat.upsert({\n where: { id: chatId },\n create: { id: chatId, title },\n update: { title },\n });\n\n // Append-only: count existing messages, create only new ones\n const existingCount = await prisma.message.count({\n where: { chatId },\n });\n\n const newMessages = messages.slice(existingCount);\n if (newMessages.length > 0) {\n await prisma.message.createMany({\n data: newMessages.map((msg) => ({\n id: msg.id,\n chatId,\n role: msg.role,\n parts: JSON.stringify(msg.parts),\n metadata: msg.metadata ? JSON.stringify(msg.metadata) : null,\n })),\n });\n }\n },\n\n async loadChat(chatId: string) {\n const messages = await prisma.message.findMany({\n where: { chatId },\n orderBy: { createdAt: \"asc\" },\n });\n\n return messages.map((msg: { id: string; role: string; parts: string; metadata: string | null }) => ({\n id: msg.id,\n role: msg.role,\n parts: JSON.parse(msg.parts),\n metadata: msg.metadata ? JSON.parse(msg.metadata) : undefined,\n }));\n },\n\n async listChats() {\n return prisma.chat.findMany({\n orderBy: { updatedAt: \"desc\" },\n select: {\n id: true,\n title: true,\n createdAt: true,\n updatedAt: true,\n },\n });\n },\n\n async deleteChat(chatId: string) {\n await prisma.chat.delete({ where: { id: chatId } });\n },\n };\n}\n\nfunction extractTitle(message?: UIMessageLike): string {\n if (!message) return \"New Chat\";\n const textPart = message.parts.find((p) => p.type === \"text\");\n if (textPart && typeof textPart.text === \"string\") {\n return textPart.text.slice(0, 100);\n }\n return \"New Chat\";\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACsBO,SAAS,oBAAoB,QAAiC;AACnE,SAAO;AAAA,IACL,MAAM,SAAS,QAAgB,UAA2B;AAExD,YAAM,eAAe,SAAS,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAC3D,YAAM,QAAQ,aAAa,YAAY;AAGvC,YAAM,OAAO,KAAK,OAAO;AAAA,QACvB,OAAO,EAAE,IAAI,OAAO;AAAA,QACpB,QAAQ,EAAE,IAAI,QAAQ,MAAM;AAAA,QAC5B,QAAQ,EAAE,MAAM;AAAA,MAClB,CAAC;AAGD,YAAM,gBAAgB,MAAM,OAAO,QAAQ,MAAM;AAAA,QAC/C,OAAO,EAAE,OAAO;AAAA,MAClB,CAAC;AAED,YAAM,cAAc,SAAS,MAAM,aAAa;AAChD,UAAI,YAAY,SAAS,GAAG;AAC1B,cAAM,OAAO,QAAQ,WAAW;AAAA,UAC9B,MAAM,YAAY,IAAI,CAAC,SAAS;AAAA,YAC9B,IAAI,IAAI;AAAA,YACR;AAAA,YACA,MAAM,IAAI;AAAA,YACV,OAAO,KAAK,UAAU,IAAI,KAAK;AAAA,YAC/B,UAAU,IAAI,WAAW,KAAK,UAAU,IAAI,QAAQ,IAAI;AAAA,UAC1D,EAAE;AAAA,QACJ,CAAC;AAAA,MACH;AAAA,IACF;AAAA,IAEA,MAAM,SAAS,QAAgB;AAC7B,YAAM,WAAW,MAAM,OAAO,QAAQ,SAAS;AAAA,QAC7C,OAAO,EAAE,OAAO;AAAA,QAChB,SAAS,EAAE,WAAW,MAAM;AAAA,MAC9B,CAAC;AAED,aAAO,SAAS,IAAI,CAAC,SAA+E;AAAA,QAClG,IAAI,IAAI;AAAA,QACR,MAAM,IAAI;AAAA,QACV,OAAO,KAAK,MAAM,IAAI,KAAK;AAAA,QAC3B,UAAU,IAAI,WAAW,KAAK,MAAM,IAAI,QAAQ,IAAI;AAAA,MACtD,EAAE;AAAA,IACJ;AAAA,IAEA,MAAM,YAAY;AAChB,aAAO,OAAO,KAAK,SAAS;AAAA,QAC1B,SAAS,EAAE,WAAW,OAAO;AAAA,QAC7B,QAAQ;AAAA,UACN,IAAI;AAAA,UACJ,OAAO;AAAA,UACP,WAAW;AAAA,UACX,WAAW;AAAA,QACb;AAAA,MACF,CAAC;AAAA,IACH;AAAA,IAEA,MAAM,WAAW,QAAgB;AAC/B,YAAM,OAAO,KAAK,OAAO,EAAE,OAAO,EAAE,IAAI,OAAO,EAAE,CAAC;AAAA,IACpD;AAAA,EACF;AACF;AAEA,SAAS,aAAa,SAAiC;AACrD,MAAI,CAAC,QAAS,QAAO;AACrB,QAAM,WAAW,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM;AAC5D,MAAI,YAAY,OAAO,SAAS,SAAS,UAAU;AACjD,WAAO,SAAS,KAAK,MAAM,GAAG,GAAG;AAAA,EACnC;AACA,SAAO;AACT;","names":[]}
@@ -0,0 +1,53 @@
1
+ /** A chat summary for listing */
2
+ interface ChatSummary {
3
+ id: string;
4
+ title: string;
5
+ createdAt: Date;
6
+ updatedAt: Date;
7
+ }
8
+ /** Chat persistence adapter interface */
9
+ interface ChatAdapter {
10
+ /** Save or update a chat with its messages (append-only) */
11
+ saveChat(chatId: string, messages: UIMessageLike[]): Promise<void>;
12
+ /** Load all messages for a chat */
13
+ loadChat(chatId: string): Promise<UIMessageLike[]>;
14
+ /** List all chats (summary only) */
15
+ listChats(): Promise<ChatSummary[]>;
16
+ /** Delete a chat and all its messages */
17
+ deleteChat(chatId: string): Promise<void>;
18
+ }
19
+ /**
20
+ * Minimal UIMessage-compatible interface.
21
+ * Matches Vercel AI SDK's UIMessage shape without importing it directly.
22
+ */
23
+ interface UIMessageLike {
24
+ id: string;
25
+ role: string;
26
+ parts: Array<{
27
+ type: string;
28
+ [key: string]: unknown;
29
+ }>;
30
+ metadata?: Record<string, unknown>;
31
+ }
32
+
33
+ /**
34
+ * Accepts any PrismaClient instance.
35
+ * We use `any` here because Prisma generates unique client types per schema,
36
+ * and a structural interface can't satisfy Prisma's branded enum types
37
+ * (e.g. SortOrder). The implementation only calls standard Prisma methods.
38
+ */
39
+ type PrismaLike = any;
40
+ /**
41
+ * Create a ChatAdapter backed by Prisma.
42
+ *
43
+ * @example
44
+ * ```ts
45
+ * import { createPrismaAdapter } from '@supyagent/sdk/prisma';
46
+ * import { prisma } from '@/lib/prisma';
47
+ *
48
+ * const adapter = createPrismaAdapter(prisma);
49
+ * ```
50
+ */
51
+ declare function createPrismaAdapter(prisma: PrismaLike): ChatAdapter;
52
+
53
+ export { type ChatAdapter, type ChatSummary, type UIMessageLike, createPrismaAdapter };
package/dist/react.cjs ADDED
@@ -0,0 +1,427 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/react.tsx
22
+ var react_exports = {};
23
+ __export(react_exports, {
24
+ ProviderIcon: () => ProviderIcon,
25
+ SupyagentToolCall: () => SupyagentToolCall,
26
+ SupyagentToolResult: () => SupyagentToolResult,
27
+ getProviderFromToolName: () => getProviderFromToolName,
28
+ getProviderLabel: () => getProviderLabel,
29
+ humanizeToolName: () => humanizeToolName
30
+ });
31
+ module.exports = __toCommonJS(react_exports);
32
+
33
+ // src/ui/tool-call.tsx
34
+ var import_react = require("react");
35
+ var import_lucide_react2 = require("lucide-react");
36
+
37
+ // src/ui/provider-icon.tsx
38
+ var import_lucide_react = require("lucide-react");
39
+
40
+ // src/ui/utils.ts
41
+ function getProviderFromToolName(toolName) {
42
+ const idx = toolName.indexOf("_");
43
+ return idx > 0 ? toolName.slice(0, idx) : toolName;
44
+ }
45
+ function humanizeToolName(toolName) {
46
+ const idx = toolName.indexOf("_");
47
+ if (idx < 0) return toolName;
48
+ const action = toolName.slice(idx + 1);
49
+ const words = action.replace(/_/g, " ");
50
+ return words.charAt(0).toUpperCase() + words.slice(1);
51
+ }
52
+ var PROVIDER_LABELS = {
53
+ gmail: "Gmail",
54
+ calendar: "Calendar",
55
+ drive: "Drive",
56
+ slack: "Slack",
57
+ github: "GitHub",
58
+ discord: "Discord",
59
+ notion: "Notion",
60
+ hubspot: "HubSpot",
61
+ linkedin: "LinkedIn",
62
+ twitter: "Twitter",
63
+ telegram: "Telegram",
64
+ microsoft: "Microsoft",
65
+ outlook: "Outlook",
66
+ onedrive: "OneDrive",
67
+ whatsapp: "WhatsApp",
68
+ inbox: "Inbox",
69
+ docs: "Docs",
70
+ sheets: "Sheets",
71
+ slides: "Slides"
72
+ };
73
+ function getProviderLabel(provider) {
74
+ return PROVIDER_LABELS[provider] || provider.charAt(0).toUpperCase() + provider.slice(1);
75
+ }
76
+ function getFormatterType(toolName) {
77
+ const provider = getProviderFromToolName(toolName);
78
+ switch (provider) {
79
+ case "gmail":
80
+ return "email";
81
+ case "calendar":
82
+ return "calendar";
83
+ case "slack":
84
+ return "slack";
85
+ case "github":
86
+ return "github";
87
+ case "drive":
88
+ return "drive";
89
+ default:
90
+ return "generic";
91
+ }
92
+ }
93
+
94
+ // src/ui/provider-icon.tsx
95
+ var import_jsx_runtime = require("react/jsx-runtime");
96
+ var ICON_MAP = {
97
+ gmail: import_lucide_react.Mail,
98
+ calendar: import_lucide_react.Calendar,
99
+ drive: import_lucide_react.HardDrive,
100
+ slack: import_lucide_react.MessageSquare,
101
+ github: import_lucide_react.Github,
102
+ discord: import_lucide_react.MessageSquare,
103
+ notion: import_lucide_react.FileText,
104
+ inbox: import_lucide_react.Bell,
105
+ docs: import_lucide_react.FileText,
106
+ sheets: import_lucide_react.Table2,
107
+ slides: import_lucide_react.Presentation
108
+ };
109
+ function ProviderIcon({ toolName, className = "h-4 w-4" }) {
110
+ const provider = getProviderFromToolName(toolName);
111
+ const Icon = ICON_MAP[provider] || import_lucide_react.Wrench;
112
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Icon, { className });
113
+ }
114
+
115
+ // src/ui/tool-call.tsx
116
+ var import_jsx_runtime2 = require("react/jsx-runtime");
117
+ function SupyagentToolCall({ part }) {
118
+ const [expanded, setExpanded] = (0, import_react.useState)(false);
119
+ const toolName = part.toolName || part.toolInvocation?.toolName || "unknown";
120
+ const state = part.state || part.toolInvocation?.state || "input-available";
121
+ const args = part.args || part.toolInvocation?.args;
122
+ const provider = getProviderFromToolName(toolName);
123
+ const providerLabel = getProviderLabel(provider);
124
+ const actionLabel = humanizeToolName(toolName);
125
+ const isStreaming = state === "input-streaming";
126
+ const isError = state === "output-error";
127
+ const isDone = state === "output-available";
128
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "rounded-lg border border-zinc-800 bg-zinc-900/50 overflow-hidden", children: [
129
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
130
+ "button",
131
+ {
132
+ type: "button",
133
+ onClick: () => args && setExpanded(!expanded),
134
+ className: "flex items-center gap-2 w-full px-3 py-2 text-left hover:bg-zinc-800/50 transition-colors",
135
+ children: [
136
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "relative", children: [
137
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ProviderIcon, { toolName, className: "h-4 w-4 text-zinc-400" }),
138
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Loader2, { className: "absolute -top-1 -right-1 h-3 w-3 text-blue-400 animate-spin" })
139
+ ] }),
140
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-xs text-zinc-500", children: providerLabel }),
141
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-zinc-300 flex-1", children: actionLabel }),
142
+ isDone && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.Check, { className: "h-3.5 w-3.5 text-green-400" }),
143
+ isError && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.AlertCircle, { className: "h-3.5 w-3.5 text-red-400" }),
144
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-xs text-zinc-500 animate-pulse", children: "Running..." }),
145
+ args && (expanded ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.ChevronDown, { className: "h-3.5 w-3.5 text-zinc-500" }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react2.ChevronRight, { className: "h-3.5 w-3.5 text-zinc-500" }))
146
+ ]
147
+ }
148
+ ),
149
+ expanded && args && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "border-t border-zinc-800 px-3 py-2", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("pre", { className: "text-xs text-zinc-400 overflow-x-auto", children: JSON.stringify(args, null, 2) }) })
150
+ ] });
151
+ }
152
+
153
+ // src/ui/formatters/email.tsx
154
+ var import_lucide_react3 = require("lucide-react");
155
+ var import_jsx_runtime3 = require("react/jsx-runtime");
156
+ function isEmailData(data) {
157
+ return typeof data === "object" && data !== null && ("subject" in data || "from" in data || "snippet" in data);
158
+ }
159
+ function EmailCard({ email }) {
160
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-2", children: [
161
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-start gap-2", children: [
162
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Mail, { className: "h-4 w-4 text-zinc-400 mt-0.5 shrink-0" }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "min-w-0 flex-1", children: [
164
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-sm font-medium text-zinc-200 truncate", children: email.subject || "No subject" }),
165
+ email.from && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-zinc-400 truncate", children: email.from })
166
+ ] }),
167
+ email.hasAttachments && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react3.Paperclip, { className: "h-3.5 w-3.5 text-zinc-500 shrink-0" })
168
+ ] }),
169
+ email.snippet && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-zinc-400 line-clamp-2", children: email.snippet }),
170
+ email.date && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "text-xs text-zinc-500", children: email.date })
171
+ ] });
172
+ }
173
+ function EmailFormatter({ data }) {
174
+ if (isEmailData(data)) {
175
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EmailCard, { email: data });
176
+ }
177
+ if (Array.isArray(data)) {
178
+ const emails = data.filter(isEmailData);
179
+ if (emails.length > 0) {
180
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-2", children: emails.map((email, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EmailCard, { email }, email.id || i)) });
181
+ }
182
+ }
183
+ if (typeof data === "object" && data !== null && "messages" in data) {
184
+ const messages = data.messages;
185
+ if (Array.isArray(messages)) {
186
+ const emails = messages.filter(isEmailData);
187
+ if (emails.length > 0) {
188
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "space-y-2", children: emails.map((email, i) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(EmailCard, { email }, email.id || i)) });
189
+ }
190
+ }
191
+ }
192
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("pre", { className: "rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto", children: JSON.stringify(data, null, 2) });
193
+ }
194
+
195
+ // src/ui/formatters/calendar-event.tsx
196
+ var import_lucide_react4 = require("lucide-react");
197
+ var import_jsx_runtime4 = require("react/jsx-runtime");
198
+ function isCalendarEvent(data) {
199
+ return typeof data === "object" && data !== null && ("summary" in data || "start" in data);
200
+ }
201
+ function formatDateTime(dt) {
202
+ if (!dt) return "";
203
+ const raw = dt.dateTime || dt.date;
204
+ if (!raw) return "";
205
+ try {
206
+ const date = new Date(raw);
207
+ return dt.dateTime ? date.toLocaleString(void 0, { dateStyle: "medium", timeStyle: "short" }) : date.toLocaleDateString(void 0, { dateStyle: "medium" });
208
+ } catch {
209
+ return raw;
210
+ }
211
+ }
212
+ function EventCard({ event }) {
213
+ const startStr = formatDateTime(event.start);
214
+ const endStr = formatDateTime(event.end);
215
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-2", children: [
216
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-start gap-2", children: [
217
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.Calendar, { className: "h-4 w-4 text-zinc-400 mt-0.5 shrink-0" }),
218
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "min-w-0 flex-1", children: [
219
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "text-sm font-medium text-zinc-200", children: event.summary || "Untitled event" }),
220
+ startStr && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("p", { className: "text-xs text-zinc-400", children: [
221
+ startStr,
222
+ endStr ? ` \u2192 ${endStr}` : ""
223
+ ] })
224
+ ] })
225
+ ] }),
226
+ event.location && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1.5 text-xs text-zinc-400", children: [
227
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.MapPin, { className: "h-3 w-3 shrink-0" }),
228
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate", children: event.location })
229
+ ] }),
230
+ event.attendees && event.attendees.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-1.5 text-xs text-zinc-400", children: [
231
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_lucide_react4.Users, { className: "h-3 w-3 shrink-0" }),
232
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate", children: event.attendees.map((a) => a.displayName || a.email).join(", ") })
233
+ ] })
234
+ ] });
235
+ }
236
+ function CalendarEventFormatter({ data }) {
237
+ if (isCalendarEvent(data)) {
238
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EventCard, { event: data });
239
+ }
240
+ if (Array.isArray(data)) {
241
+ const events = data.filter(isCalendarEvent);
242
+ if (events.length > 0) {
243
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "space-y-2", children: events.map((event, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EventCard, { event }, event.id || i)) });
244
+ }
245
+ }
246
+ if (typeof data === "object" && data !== null && "events" in data) {
247
+ const events = data.events;
248
+ if (Array.isArray(events)) {
249
+ const calEvents = events.filter(isCalendarEvent);
250
+ if (calEvents.length > 0) {
251
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "space-y-2", children: calEvents.map((event, i) => /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(EventCard, { event }, event.id || i)) });
252
+ }
253
+ }
254
+ }
255
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("pre", { className: "rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto", children: JSON.stringify(data, null, 2) });
256
+ }
257
+
258
+ // src/ui/formatters/slack-message.tsx
259
+ var import_lucide_react5 = require("lucide-react");
260
+ var import_jsx_runtime5 = require("react/jsx-runtime");
261
+ function isSlackMessage(data) {
262
+ return typeof data === "object" && data !== null && ("text" in data || "channel" in data);
263
+ }
264
+ function MessageBubble({ message }) {
265
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-1.5", children: [
266
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2", children: [
267
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.MessageSquare, { className: "h-4 w-4 text-zinc-400 shrink-0" }),
268
+ message.channel && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("span", { className: "flex items-center gap-0.5 text-xs text-zinc-400", children: [
269
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_lucide_react5.Hash, { className: "h-3 w-3" }),
270
+ message.channel
271
+ ] }),
272
+ message.user && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-xs text-zinc-500", children: message.user })
273
+ ] }),
274
+ message.text && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "text-sm text-zinc-300", children: message.text })
275
+ ] });
276
+ }
277
+ function SlackMessageFormatter({ data }) {
278
+ if (isSlackMessage(data)) {
279
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: data });
280
+ }
281
+ if (Array.isArray(data)) {
282
+ const messages = data.filter(isSlackMessage);
283
+ if (messages.length > 0) {
284
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "space-y-2", children: messages.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: msg }, msg.ts || i)) });
285
+ }
286
+ }
287
+ if (typeof data === "object" && data !== null && "messages" in data) {
288
+ const messages = data.messages;
289
+ if (Array.isArray(messages)) {
290
+ const slackMsgs = messages.filter(isSlackMessage);
291
+ if (slackMsgs.length > 0) {
292
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "space-y-2", children: slackMsgs.map((msg, i) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(MessageBubble, { message: msg }, msg.ts || i)) });
293
+ }
294
+ }
295
+ }
296
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("pre", { className: "rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto", children: JSON.stringify(data, null, 2) });
297
+ }
298
+
299
+ // src/ui/formatters/github.tsx
300
+ var import_lucide_react6 = require("lucide-react");
301
+ var import_jsx_runtime6 = require("react/jsx-runtime");
302
+ function isGithubItem(data) {
303
+ return typeof data === "object" && data !== null && ("title" in data || "number" in data);
304
+ }
305
+ function GithubCard({ item }) {
306
+ const isPR = !!item.pull_request;
307
+ const stateColor = item.state === "open" ? "text-green-400" : item.state === "closed" ? "text-red-400" : "text-zinc-400";
308
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-1.5", children: [
309
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "flex items-start gap-2", children: [
310
+ isPR ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.GitPullRequest, { className: `h-4 w-4 mt-0.5 shrink-0 ${stateColor}` }) : /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_lucide_react6.CircleDot, { className: `h-4 w-4 mt-0.5 shrink-0 ${stateColor}` }),
311
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "min-w-0 flex-1", children: [
312
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("p", { className: "text-sm font-medium text-zinc-200", children: [
313
+ item.title,
314
+ item.number && /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className: "text-zinc-500 font-normal", children: [
315
+ " #",
316
+ item.number
317
+ ] })
318
+ ] }),
319
+ item.user?.login && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-zinc-400", children: item.user.login })
320
+ ] })
321
+ ] }),
322
+ item.body && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { className: "text-xs text-zinc-400 line-clamp-2", children: item.body })
323
+ ] });
324
+ }
325
+ function GithubFormatter({ data }) {
326
+ if (isGithubItem(data)) {
327
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GithubCard, { item: data });
328
+ }
329
+ if (Array.isArray(data)) {
330
+ const items = data.filter(isGithubItem);
331
+ if (items.length > 0) {
332
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { className: "space-y-2", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(GithubCard, { item }, item.number || i)) });
333
+ }
334
+ }
335
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("pre", { className: "rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto", children: JSON.stringify(data, null, 2) });
336
+ }
337
+
338
+ // src/ui/formatters/drive-file.tsx
339
+ var import_lucide_react7 = require("lucide-react");
340
+ var import_jsx_runtime7 = require("react/jsx-runtime");
341
+ function isDriveFile(data) {
342
+ return typeof data === "object" && data !== null && ("name" in data || "mimeType" in data);
343
+ }
344
+ function getFileIcon(mimeType) {
345
+ if (!mimeType) return import_lucide_react7.FileText;
346
+ if (mimeType.includes("folder")) return import_lucide_react7.Folder;
347
+ if (mimeType.includes("image")) return import_lucide_react7.Image;
348
+ if (mimeType.includes("video")) return import_lucide_react7.Film;
349
+ if (mimeType.includes("spreadsheet") || mimeType.includes("excel")) return import_lucide_react7.FileSpreadsheet;
350
+ return import_lucide_react7.FileText;
351
+ }
352
+ function FileCard({ file }) {
353
+ const Icon = getFileIcon(file.mimeType);
354
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex items-center gap-3 rounded-lg border border-zinc-800 bg-zinc-900/50 p-3", children: [
355
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Icon, { className: "h-4 w-4 text-zinc-400 shrink-0" }),
356
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "min-w-0 flex-1", children: [
357
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-sm text-zinc-200 truncate", children: file.name || "Untitled" }),
358
+ file.modifiedTime && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { className: "text-xs text-zinc-500", children: new Date(file.modifiedTime).toLocaleDateString() })
359
+ ] })
360
+ ] });
361
+ }
362
+ function DriveFileFormatter({ data }) {
363
+ if (isDriveFile(data)) {
364
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileCard, { file: data });
365
+ }
366
+ if (Array.isArray(data)) {
367
+ const files = data.filter(isDriveFile);
368
+ if (files.length > 0) {
369
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "space-y-1.5", children: files.map((file, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileCard, { file }, file.id || i)) });
370
+ }
371
+ }
372
+ if (typeof data === "object" && data !== null && "files" in data) {
373
+ const files = data.files;
374
+ if (Array.isArray(files)) {
375
+ const driveFiles = files.filter(isDriveFile);
376
+ if (driveFiles.length > 0) {
377
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("div", { className: "space-y-1.5", children: driveFiles.map((file, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(FileCard, { file }, file.id || i)) });
378
+ }
379
+ }
380
+ }
381
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("pre", { className: "rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto", children: JSON.stringify(data, null, 2) });
382
+ }
383
+
384
+ // src/ui/formatters/generic.tsx
385
+ var import_jsx_runtime8 = require("react/jsx-runtime");
386
+ function GenericFormatter({ data }) {
387
+ if (data === null || data === void 0) {
388
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("p", { className: "text-sm text-zinc-500 italic", children: "No data returned" });
389
+ }
390
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("pre", { className: "rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto", children: JSON.stringify(data, null, 2) });
391
+ }
392
+
393
+ // src/ui/tool-result.tsx
394
+ var import_jsx_runtime9 = require("react/jsx-runtime");
395
+ function SupyagentToolResult({ part }) {
396
+ const state = part.state ?? part.toolInvocation?.state;
397
+ const result = "result" in part ? part.result : part.toolInvocation?.result;
398
+ const toolName = part.toolName ?? part.toolInvocation?.toolName ?? "unknown";
399
+ if (state !== "output-available" || result === void 0) {
400
+ return null;
401
+ }
402
+ const formatterType = getFormatterType(toolName);
403
+ switch (formatterType) {
404
+ case "email":
405
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(EmailFormatter, { data: result });
406
+ case "calendar":
407
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(CalendarEventFormatter, { data: result });
408
+ case "slack":
409
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(SlackMessageFormatter, { data: result });
410
+ case "github":
411
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GithubFormatter, { data: result });
412
+ case "drive":
413
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DriveFileFormatter, { data: result });
414
+ default:
415
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(GenericFormatter, { data: result });
416
+ }
417
+ }
418
+ // Annotate the CommonJS export names for ESM import in node:
419
+ 0 && (module.exports = {
420
+ ProviderIcon,
421
+ SupyagentToolCall,
422
+ SupyagentToolResult,
423
+ getProviderFromToolName,
424
+ getProviderLabel,
425
+ humanizeToolName
426
+ });
427
+ //# sourceMappingURL=react.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/react.tsx","../src/ui/tool-call.tsx","../src/ui/provider-icon.tsx","../src/ui/utils.ts","../src/ui/formatters/email.tsx","../src/ui/formatters/calendar-event.tsx","../src/ui/formatters/slack-message.tsx","../src/ui/formatters/github.tsx","../src/ui/formatters/drive-file.tsx","../src/ui/formatters/generic.tsx","../src/ui/tool-result.tsx"],"sourcesContent":["export { SupyagentToolCall } from \"./ui/tool-call.js\";\nexport { SupyagentToolResult } from \"./ui/tool-result.js\";\nexport { ProviderIcon } from \"./ui/provider-icon.js\";\nexport { humanizeToolName, getProviderFromToolName, getProviderLabel } from \"./ui/utils.js\";\n","import React, { useState } from \"react\";\nimport { ChevronDown, ChevronRight, Check, AlertCircle, Loader2 } from \"lucide-react\";\nimport { ProviderIcon } from \"./provider-icon.js\";\nimport { humanizeToolName, getProviderLabel, getProviderFromToolName } from \"./utils.js\";\n\ninterface ToolCallPart {\n type: string;\n toolInvocation?: {\n toolName: string;\n state: string;\n args?: Record<string, unknown>;\n result?: unknown;\n };\n // AI SDK v4 tool-invocation parts\n toolName?: string;\n state?: string;\n args?: Record<string, unknown>;\n}\n\ninterface SupyagentToolCallProps {\n part: ToolCallPart;\n}\n\nexport function SupyagentToolCall({ part }: SupyagentToolCallProps) {\n const [expanded, setExpanded] = useState(false);\n\n const toolName = part.toolName || part.toolInvocation?.toolName || \"unknown\";\n const state = part.state || part.toolInvocation?.state || \"input-available\";\n const args = part.args || part.toolInvocation?.args;\n\n const provider = getProviderFromToolName(toolName);\n const providerLabel = getProviderLabel(provider);\n const actionLabel = humanizeToolName(toolName);\n\n const isStreaming = state === \"input-streaming\";\n const isError = state === \"output-error\";\n const isDone = state === \"output-available\";\n\n return (\n <div className=\"rounded-lg border border-zinc-800 bg-zinc-900/50 overflow-hidden\">\n <button\n type=\"button\"\n onClick={() => args && setExpanded(!expanded)}\n className=\"flex items-center gap-2 w-full px-3 py-2 text-left hover:bg-zinc-800/50 transition-colors\"\n >\n <div className=\"relative\">\n <ProviderIcon toolName={toolName} className=\"h-4 w-4 text-zinc-400\" />\n {isStreaming && (\n <Loader2 className=\"absolute -top-1 -right-1 h-3 w-3 text-blue-400 animate-spin\" />\n )}\n </div>\n\n <span className=\"text-xs text-zinc-500\">{providerLabel}</span>\n <span className=\"text-sm text-zinc-300 flex-1\">{actionLabel}</span>\n\n {isDone && <Check className=\"h-3.5 w-3.5 text-green-400\" />}\n {isError && <AlertCircle className=\"h-3.5 w-3.5 text-red-400\" />}\n {isStreaming && (\n <span className=\"text-xs text-zinc-500 animate-pulse\">Running...</span>\n )}\n\n {args && (\n expanded\n ? <ChevronDown className=\"h-3.5 w-3.5 text-zinc-500\" />\n : <ChevronRight className=\"h-3.5 w-3.5 text-zinc-500\" />\n )}\n </button>\n\n {expanded && args && (\n <div className=\"border-t border-zinc-800 px-3 py-2\">\n <pre className=\"text-xs text-zinc-400 overflow-x-auto\">\n {JSON.stringify(args, null, 2)}\n </pre>\n </div>\n )}\n </div>\n );\n}\n","import React from \"react\";\nimport {\n Mail,\n Calendar,\n HardDrive,\n MessageSquare,\n Github,\n type LucideIcon,\n Wrench,\n Bell,\n FileText,\n Table2,\n Presentation,\n} from \"lucide-react\";\nimport { getProviderFromToolName } from \"./utils.js\";\n\nconst ICON_MAP: Record<string, LucideIcon> = {\n gmail: Mail,\n calendar: Calendar,\n drive: HardDrive,\n slack: MessageSquare,\n github: Github,\n discord: MessageSquare,\n notion: FileText,\n inbox: Bell,\n docs: FileText,\n sheets: Table2,\n slides: Presentation,\n};\n\ninterface ProviderIconProps {\n toolName: string;\n className?: string;\n}\n\nexport function ProviderIcon({ toolName, className = \"h-4 w-4\" }: ProviderIconProps) {\n const provider = getProviderFromToolName(toolName);\n const Icon = ICON_MAP[provider] || Wrench;\n return <Icon className={className} />;\n}\n","/**\n * Extract provider/service prefix from a tool name.\n * Tool names follow `{service}_{action}` convention.\n */\nexport function getProviderFromToolName(toolName: string): string {\n const idx = toolName.indexOf(\"_\");\n return idx > 0 ? toolName.slice(0, idx) : toolName;\n}\n\n/**\n * Convert a tool name like \"gmail_list_messages\" to \"List messages\".\n */\nexport function humanizeToolName(toolName: string): string {\n const idx = toolName.indexOf(\"_\");\n if (idx < 0) return toolName;\n const action = toolName.slice(idx + 1);\n const words = action.replace(/_/g, \" \");\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\n/**\n * Provider display names.\n */\nexport const PROVIDER_LABELS: Record<string, string> = {\n gmail: \"Gmail\",\n calendar: \"Calendar\",\n drive: \"Drive\",\n slack: \"Slack\",\n github: \"GitHub\",\n discord: \"Discord\",\n notion: \"Notion\",\n hubspot: \"HubSpot\",\n linkedin: \"LinkedIn\",\n twitter: \"Twitter\",\n telegram: \"Telegram\",\n microsoft: \"Microsoft\",\n outlook: \"Outlook\",\n onedrive: \"OneDrive\",\n whatsapp: \"WhatsApp\",\n inbox: \"Inbox\",\n docs: \"Docs\",\n sheets: \"Sheets\",\n slides: \"Slides\",\n};\n\n/**\n * Get a display label for a provider.\n */\nexport function getProviderLabel(provider: string): string {\n return PROVIDER_LABELS[provider] || provider.charAt(0).toUpperCase() + provider.slice(1);\n}\n\n/**\n * Determine which formatter to use based on tool name prefix.\n */\nexport type FormatterType =\n | \"email\"\n | \"calendar\"\n | \"slack\"\n | \"github\"\n | \"drive\"\n | \"generic\";\n\nexport function getFormatterType(toolName: string): FormatterType {\n const provider = getProviderFromToolName(toolName);\n switch (provider) {\n case \"gmail\":\n return \"email\";\n case \"calendar\":\n return \"calendar\";\n case \"slack\":\n return \"slack\";\n case \"github\":\n return \"github\";\n case \"drive\":\n return \"drive\";\n default:\n return \"generic\";\n }\n}\n","import React from \"react\";\nimport { Mail, Paperclip } from \"lucide-react\";\n\ninterface EmailData {\n id?: string;\n subject?: string;\n from?: string;\n to?: string;\n date?: string;\n snippet?: string;\n body?: string;\n hasAttachments?: boolean;\n labels?: string[];\n}\n\ninterface EmailFormatterProps {\n data: unknown;\n}\n\nfunction isEmailData(data: unknown): data is EmailData {\n return typeof data === \"object\" && data !== null && (\"subject\" in data || \"from\" in data || \"snippet\" in data);\n}\n\nfunction EmailCard({ email }: { email: EmailData }) {\n return (\n <div className=\"rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-2\">\n <div className=\"flex items-start gap-2\">\n <Mail className=\"h-4 w-4 text-zinc-400 mt-0.5 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-zinc-200 truncate\">\n {email.subject || \"No subject\"}\n </p>\n {email.from && (\n <p className=\"text-xs text-zinc-400 truncate\">{email.from}</p>\n )}\n </div>\n {email.hasAttachments && (\n <Paperclip className=\"h-3.5 w-3.5 text-zinc-500 shrink-0\" />\n )}\n </div>\n {email.snippet && (\n <p className=\"text-xs text-zinc-400 line-clamp-2\">{email.snippet}</p>\n )}\n {email.date && (\n <p className=\"text-xs text-zinc-500\">{email.date}</p>\n )}\n </div>\n );\n}\n\nexport function EmailFormatter({ data }: EmailFormatterProps) {\n // Single email\n if (isEmailData(data)) {\n return <EmailCard email={data} />;\n }\n\n // Array of emails (list response)\n if (Array.isArray(data)) {\n const emails = data.filter(isEmailData);\n if (emails.length > 0) {\n return (\n <div className=\"space-y-2\">\n {emails.map((email, i) => (\n <EmailCard key={email.id || i} email={email} />\n ))}\n </div>\n );\n }\n }\n\n // Object with messages array\n if (typeof data === \"object\" && data !== null && \"messages\" in data) {\n const messages = (data as { messages: unknown[] }).messages;\n if (Array.isArray(messages)) {\n const emails = messages.filter(isEmailData);\n if (emails.length > 0) {\n return (\n <div className=\"space-y-2\">\n {emails.map((email, i) => (\n <EmailCard key={email.id || i} email={email} />\n ))}\n </div>\n );\n }\n }\n }\n\n // Fallback to raw\n return (\n <pre className=\"rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n}\n","import React from \"react\";\nimport { Calendar, MapPin, Users } from \"lucide-react\";\n\ninterface CalendarEventData {\n id?: string;\n summary?: string;\n description?: string;\n start?: { dateTime?: string; date?: string };\n end?: { dateTime?: string; date?: string };\n location?: string;\n attendees?: Array<{ email?: string; displayName?: string }>;\n status?: string;\n}\n\ninterface CalendarEventFormatterProps {\n data: unknown;\n}\n\nfunction isCalendarEvent(data: unknown): data is CalendarEventData {\n return typeof data === \"object\" && data !== null && (\"summary\" in data || \"start\" in data);\n}\n\nfunction formatDateTime(dt?: { dateTime?: string; date?: string }): string {\n if (!dt) return \"\";\n const raw = dt.dateTime || dt.date;\n if (!raw) return \"\";\n try {\n const date = new Date(raw);\n return dt.dateTime\n ? date.toLocaleString(undefined, { dateStyle: \"medium\", timeStyle: \"short\" })\n : date.toLocaleDateString(undefined, { dateStyle: \"medium\" });\n } catch {\n return raw;\n }\n}\n\nfunction EventCard({ event }: { event: CalendarEventData }) {\n const startStr = formatDateTime(event.start);\n const endStr = formatDateTime(event.end);\n\n return (\n <div className=\"rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-2\">\n <div className=\"flex items-start gap-2\">\n <Calendar className=\"h-4 w-4 text-zinc-400 mt-0.5 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-zinc-200\">\n {event.summary || \"Untitled event\"}\n </p>\n {startStr && (\n <p className=\"text-xs text-zinc-400\">\n {startStr}\n {endStr ? ` → ${endStr}` : \"\"}\n </p>\n )}\n </div>\n </div>\n {event.location && (\n <div className=\"flex items-center gap-1.5 text-xs text-zinc-400\">\n <MapPin className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">{event.location}</span>\n </div>\n )}\n {event.attendees && event.attendees.length > 0 && (\n <div className=\"flex items-center gap-1.5 text-xs text-zinc-400\">\n <Users className=\"h-3 w-3 shrink-0\" />\n <span className=\"truncate\">\n {event.attendees.map((a) => a.displayName || a.email).join(\", \")}\n </span>\n </div>\n )}\n </div>\n );\n}\n\nexport function CalendarEventFormatter({ data }: CalendarEventFormatterProps) {\n if (isCalendarEvent(data)) {\n return <EventCard event={data} />;\n }\n\n if (Array.isArray(data)) {\n const events = data.filter(isCalendarEvent);\n if (events.length > 0) {\n return (\n <div className=\"space-y-2\">\n {events.map((event, i) => (\n <EventCard key={event.id || i} event={event} />\n ))}\n </div>\n );\n }\n }\n\n if (typeof data === \"object\" && data !== null && \"events\" in data) {\n const events = (data as { events: unknown[] }).events;\n if (Array.isArray(events)) {\n const calEvents = events.filter(isCalendarEvent);\n if (calEvents.length > 0) {\n return (\n <div className=\"space-y-2\">\n {calEvents.map((event, i) => (\n <EventCard key={event.id || i} event={event} />\n ))}\n </div>\n );\n }\n }\n }\n\n return (\n <pre className=\"rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n}\n","import React from \"react\";\nimport { MessageSquare, Hash } from \"lucide-react\";\n\ninterface SlackMessageData {\n text?: string;\n channel?: string;\n user?: string;\n ts?: string;\n ok?: boolean;\n}\n\ninterface SlackMessageFormatterProps {\n data: unknown;\n}\n\nfunction isSlackMessage(data: unknown): data is SlackMessageData {\n return typeof data === \"object\" && data !== null && (\"text\" in data || \"channel\" in data);\n}\n\nfunction MessageBubble({ message }: { message: SlackMessageData }) {\n return (\n <div className=\"rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-1.5\">\n <div className=\"flex items-center gap-2\">\n <MessageSquare className=\"h-4 w-4 text-zinc-400 shrink-0\" />\n {message.channel && (\n <span className=\"flex items-center gap-0.5 text-xs text-zinc-400\">\n <Hash className=\"h-3 w-3\" />\n {message.channel}\n </span>\n )}\n {message.user && (\n <span className=\"text-xs text-zinc-500\">{message.user}</span>\n )}\n </div>\n {message.text && (\n <p className=\"text-sm text-zinc-300\">{message.text}</p>\n )}\n </div>\n );\n}\n\nexport function SlackMessageFormatter({ data }: SlackMessageFormatterProps) {\n if (isSlackMessage(data)) {\n return <MessageBubble message={data} />;\n }\n\n if (Array.isArray(data)) {\n const messages = data.filter(isSlackMessage);\n if (messages.length > 0) {\n return (\n <div className=\"space-y-2\">\n {messages.map((msg, i) => (\n <MessageBubble key={msg.ts || i} message={msg} />\n ))}\n </div>\n );\n }\n }\n\n if (typeof data === \"object\" && data !== null && \"messages\" in data) {\n const messages = (data as { messages: unknown[] }).messages;\n if (Array.isArray(messages)) {\n const slackMsgs = messages.filter(isSlackMessage);\n if (slackMsgs.length > 0) {\n return (\n <div className=\"space-y-2\">\n {slackMsgs.map((msg, i) => (\n <MessageBubble key={msg.ts || i} message={msg} />\n ))}\n </div>\n );\n }\n }\n }\n\n return (\n <pre className=\"rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n}\n","import React from \"react\";\nimport { Github, CircleDot, GitPullRequest } from \"lucide-react\";\n\ninterface GithubItemData {\n title?: string;\n number?: number;\n state?: string;\n html_url?: string;\n body?: string;\n user?: { login?: string };\n created_at?: string;\n pull_request?: unknown;\n}\n\ninterface GithubFormatterProps {\n data: unknown;\n}\n\nfunction isGithubItem(data: unknown): data is GithubItemData {\n return typeof data === \"object\" && data !== null && (\"title\" in data || \"number\" in data);\n}\n\nfunction GithubCard({ item }: { item: GithubItemData }) {\n const isPR = !!item.pull_request;\n const stateColor =\n item.state === \"open\"\n ? \"text-green-400\"\n : item.state === \"closed\"\n ? \"text-red-400\"\n : \"text-zinc-400\";\n\n return (\n <div className=\"rounded-lg border border-zinc-800 bg-zinc-900/50 p-3 space-y-1.5\">\n <div className=\"flex items-start gap-2\">\n {isPR ? (\n <GitPullRequest className={`h-4 w-4 mt-0.5 shrink-0 ${stateColor}`} />\n ) : (\n <CircleDot className={`h-4 w-4 mt-0.5 shrink-0 ${stateColor}`} />\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm font-medium text-zinc-200\">\n {item.title}\n {item.number && (\n <span className=\"text-zinc-500 font-normal\"> #{item.number}</span>\n )}\n </p>\n {item.user?.login && (\n <p className=\"text-xs text-zinc-400\">{item.user.login}</p>\n )}\n </div>\n </div>\n {item.body && (\n <p className=\"text-xs text-zinc-400 line-clamp-2\">{item.body}</p>\n )}\n </div>\n );\n}\n\nexport function GithubFormatter({ data }: GithubFormatterProps) {\n if (isGithubItem(data)) {\n return <GithubCard item={data} />;\n }\n\n if (Array.isArray(data)) {\n const items = data.filter(isGithubItem);\n if (items.length > 0) {\n return (\n <div className=\"space-y-2\">\n {items.map((item, i) => (\n <GithubCard key={item.number || i} item={item} />\n ))}\n </div>\n );\n }\n }\n\n return (\n <pre className=\"rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n}\n","import React from \"react\";\nimport { FileText, Folder, Image, Film, FileSpreadsheet } from \"lucide-react\";\n\ninterface DriveFileData {\n id?: string;\n name?: string;\n mimeType?: string;\n modifiedTime?: string;\n size?: string | number;\n webViewLink?: string;\n}\n\ninterface DriveFileFormatterProps {\n data: unknown;\n}\n\nfunction isDriveFile(data: unknown): data is DriveFileData {\n return typeof data === \"object\" && data !== null && (\"name\" in data || \"mimeType\" in data);\n}\n\nfunction getFileIcon(mimeType?: string) {\n if (!mimeType) return FileText;\n if (mimeType.includes(\"folder\")) return Folder;\n if (mimeType.includes(\"image\")) return Image;\n if (mimeType.includes(\"video\")) return Film;\n if (mimeType.includes(\"spreadsheet\") || mimeType.includes(\"excel\")) return FileSpreadsheet;\n return FileText;\n}\n\nfunction FileCard({ file }: { file: DriveFileData }) {\n const Icon = getFileIcon(file.mimeType);\n\n return (\n <div className=\"flex items-center gap-3 rounded-lg border border-zinc-800 bg-zinc-900/50 p-3\">\n <Icon className=\"h-4 w-4 text-zinc-400 shrink-0\" />\n <div className=\"min-w-0 flex-1\">\n <p className=\"text-sm text-zinc-200 truncate\">{file.name || \"Untitled\"}</p>\n {file.modifiedTime && (\n <p className=\"text-xs text-zinc-500\">\n {new Date(file.modifiedTime).toLocaleDateString()}\n </p>\n )}\n </div>\n </div>\n );\n}\n\nexport function DriveFileFormatter({ data }: DriveFileFormatterProps) {\n if (isDriveFile(data)) {\n return <FileCard file={data} />;\n }\n\n if (Array.isArray(data)) {\n const files = data.filter(isDriveFile);\n if (files.length > 0) {\n return (\n <div className=\"space-y-1.5\">\n {files.map((file, i) => (\n <FileCard key={file.id || i} file={file} />\n ))}\n </div>\n );\n }\n }\n\n if (typeof data === \"object\" && data !== null && \"files\" in data) {\n const files = (data as { files: unknown[] }).files;\n if (Array.isArray(files)) {\n const driveFiles = files.filter(isDriveFile);\n if (driveFiles.length > 0) {\n return (\n <div className=\"space-y-1.5\">\n {driveFiles.map((file, i) => (\n <FileCard key={file.id || i} file={file} />\n ))}\n </div>\n );\n }\n }\n }\n\n return (\n <pre className=\"rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n}\n","import React from \"react\";\n\ninterface GenericFormatterProps {\n data: unknown;\n}\n\nexport function GenericFormatter({ data }: GenericFormatterProps) {\n if (data === null || data === undefined) {\n return (\n <p className=\"text-sm text-zinc-500 italic\">No data returned</p>\n );\n }\n\n return (\n <pre className=\"rounded-lg border border-zinc-800 bg-zinc-950 p-3 text-xs text-zinc-300 overflow-x-auto max-h-96 overflow-y-auto\">\n {JSON.stringify(data, null, 2)}\n </pre>\n );\n}\n","import React from \"react\";\nimport { getFormatterType, getProviderFromToolName } from \"./utils.js\";\nimport { EmailFormatter } from \"./formatters/email.js\";\nimport { CalendarEventFormatter } from \"./formatters/calendar-event.js\";\nimport { SlackMessageFormatter } from \"./formatters/slack-message.js\";\nimport { GithubFormatter } from \"./formatters/github.js\";\nimport { DriveFileFormatter } from \"./formatters/drive-file.js\";\nimport { GenericFormatter } from \"./formatters/generic.js\";\n\ninterface ToolResultPart {\n type: string;\n toolInvocation?: {\n toolName: string;\n state: string;\n result?: unknown;\n };\n toolName?: string;\n state?: string;\n result?: unknown;\n}\n\ninterface SupyagentToolResultProps {\n part: ToolResultPart;\n}\n\nexport function SupyagentToolResult({ part }: SupyagentToolResultProps) {\n const state = part.state ?? part.toolInvocation?.state;\n const result = \"result\" in part ? part.result : part.toolInvocation?.result;\n const toolName = part.toolName ?? part.toolInvocation?.toolName ?? \"unknown\";\n\n // Only render when we have a result\n if (state !== \"output-available\" || result === undefined) {\n return null;\n }\n\n const formatterType = getFormatterType(toolName);\n\n // Route to provider-specific formatter\n switch (formatterType) {\n case \"email\":\n return <EmailFormatter data={result} />;\n case \"calendar\":\n return <CalendarEventFormatter data={result} />;\n case \"slack\":\n return <SlackMessageFormatter data={result} />;\n case \"github\":\n return <GithubFormatter data={result} />;\n case \"drive\":\n return <DriveFileFormatter data={result} />;\n default:\n return <GenericFormatter data={result} />;\n }\n}\n"],"mappings":"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","names":["import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_lucide_react","import_jsx_runtime","import_jsx_runtime","import_jsx_runtime"]}
@@ -0,0 +1,56 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface ToolCallPart {
4
+ type: string;
5
+ toolInvocation?: {
6
+ toolName: string;
7
+ state: string;
8
+ args?: Record<string, unknown>;
9
+ result?: unknown;
10
+ };
11
+ toolName?: string;
12
+ state?: string;
13
+ args?: Record<string, unknown>;
14
+ }
15
+ interface SupyagentToolCallProps {
16
+ part: ToolCallPart;
17
+ }
18
+ declare function SupyagentToolCall({ part }: SupyagentToolCallProps): react_jsx_runtime.JSX.Element;
19
+
20
+ interface ToolResultPart {
21
+ type: string;
22
+ toolInvocation?: {
23
+ toolName: string;
24
+ state: string;
25
+ result?: unknown;
26
+ };
27
+ toolName?: string;
28
+ state?: string;
29
+ result?: unknown;
30
+ }
31
+ interface SupyagentToolResultProps {
32
+ part: ToolResultPart;
33
+ }
34
+ declare function SupyagentToolResult({ part }: SupyagentToolResultProps): react_jsx_runtime.JSX.Element | null;
35
+
36
+ interface ProviderIconProps {
37
+ toolName: string;
38
+ className?: string;
39
+ }
40
+ declare function ProviderIcon({ toolName, className }: ProviderIconProps): react_jsx_runtime.JSX.Element;
41
+
42
+ /**
43
+ * Extract provider/service prefix from a tool name.
44
+ * Tool names follow `{service}_{action}` convention.
45
+ */
46
+ declare function getProviderFromToolName(toolName: string): string;
47
+ /**
48
+ * Convert a tool name like "gmail_list_messages" to "List messages".
49
+ */
50
+ declare function humanizeToolName(toolName: string): string;
51
+ /**
52
+ * Get a display label for a provider.
53
+ */
54
+ declare function getProviderLabel(provider: string): string;
55
+
56
+ export { ProviderIcon, SupyagentToolCall, SupyagentToolResult, getProviderFromToolName, getProviderLabel, humanizeToolName };
package/package.json CHANGED
@@ -1,22 +1,30 @@
1
1
  {
2
2
  "name": "@supyagent/sdk",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Supyagent SDK — AI SDK tools, persistence, and UI components",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": {
8
+ "types": "./dist/index.d.ts",
8
9
  "import": "./dist/index.js",
9
- "types": "./dist/index.d.ts"
10
+ "require": "./dist/index.cjs",
11
+ "default": "./dist/index.js"
10
12
  },
11
13
  "./prisma": {
14
+ "types": "./dist/prisma.d.ts",
12
15
  "import": "./dist/prisma.js",
13
- "types": "./dist/prisma.d.ts"
16
+ "require": "./dist/prisma.cjs",
17
+ "default": "./dist/prisma.js"
14
18
  },
15
19
  "./react": {
20
+ "types": "./dist/react.d.ts",
16
21
  "import": "./dist/react.js",
17
- "types": "./dist/react.d.ts"
22
+ "require": "./dist/react.cjs",
23
+ "default": "./dist/react.js"
18
24
  }
19
25
  },
26
+ "main": "./dist/index.cjs",
27
+ "module": "./dist/index.js",
20
28
  "files": [
21
29
  "dist"
22
30
  ],
@@ -27,7 +35,7 @@
27
35
  "clean": "rm -rf dist"
28
36
  },
29
37
  "dependencies": {
30
- "ai": "^4.1.0"
38
+ "ai": "^6.0.0"
31
39
  },
32
40
  "peerDependencies": {
33
41
  "@prisma/client": ">=5.0.0",