@verityai/sdk 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,25 @@
1
+ # @verityai/sdk (TypeScript)
2
+
3
+ Live audit client wrappers for Node.js. Install **`@verityai/sdk`** plus the vendor SDK you use. (The unscoped npm name `verity` is already used by another project.)
4
+
5
+ ```bash
6
+ npm install @verityai/sdk openai
7
+ ```
8
+
9
+ ```typescript
10
+ import { VerityOpenAI } from "@verityai/sdk";
11
+
12
+ const client = new VerityOpenAI({
13
+ openaiApiKey: process.env.OPENAI_API_KEY!,
14
+ verityApiKey: process.env.VERITY_API_KEY!,
15
+ });
16
+
17
+ await client.chat.completions.create({
18
+ model: "gpt-4o-mini",
19
+ messages: [{ role: "user", content: "Hello" }],
20
+ });
21
+ ```
22
+
23
+ Optional peers: `@anthropic-ai/sdk` (`VerityAnthropic`), `@google/genai` (`VerityGemini`). Set `VERITY_API_KEY` (or pass `verityApiKey`) to your project upload token; optional `VERITY_API_URL` overrides the API host.
24
+
25
+ Python users: `pip install verity-audit` and `from verity import VerityOpenAI` (same behavior).
@@ -0,0 +1,12 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ export type VerityAnthropicClientOptions = ConstructorParameters<typeof Anthropic>[0] & {
3
+ verityApiKey?: string;
4
+ verityUploadToken?: string;
5
+ verityApiUrl?: string;
6
+ anthropicApiKey?: string;
7
+ };
8
+ /** Drop-in Anthropic client; `messages.create` sends prompt/response to Verity (non-blocking). */
9
+ export declare class VerityAnthropic extends Anthropic {
10
+ constructor(options?: VerityAnthropicClientOptions);
11
+ }
12
+ //# sourceMappingURL=anthropic.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../src/anthropic.ts"],"names":[],"mappings":"AAAA,OAAO,SAAS,MAAM,mBAAmB,CAAA;AAIzC,MAAM,MAAM,4BAA4B,GAAG,qBAAqB,CAAC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG;IACtF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAmDD,kGAAkG;AAClG,qBAAa,eAAgB,SAAQ,SAAS;gBAChC,OAAO,GAAE,4BAAiC;CAWvD"}
@@ -0,0 +1,56 @@
1
+ import Anthropic from '@anthropic-ai/sdk';
2
+ import { LiveAuditReporter } from './reporter.js';
3
+ import { anthropicMessagesPreview, anthropicResponseText } from './text.js';
4
+ function stripVerityFields(opts) {
5
+ const { verityApiKey: _vk, verityUploadToken: _vt, verityApiUrl: _vu, anthropicApiKey, apiKey, ...rest } = opts;
6
+ const key = anthropicApiKey ?? apiKey;
7
+ return { ...rest, apiKey: key };
8
+ }
9
+ function reporterFromOpts(opts) {
10
+ const token = opts.verityApiKey ||
11
+ opts.verityUploadToken ||
12
+ (typeof process !== 'undefined' && process.env && (process.env.VERITY_API_KEY || process.env.VERITY_UPLOAD_TOKEN)) ||
13
+ '';
14
+ const baseUrl = opts.verityApiUrl || (typeof process !== 'undefined' && process.env && process.env.VERITY_API_URL) || undefined;
15
+ return new LiveAuditReporter({ token, baseUrl });
16
+ }
17
+ function wrapMessages(real, reporter) {
18
+ const realCreate = real.create.bind(real);
19
+ return new Proxy(real, {
20
+ get(target, prop, recv) {
21
+ if (prop === 'create') {
22
+ return async (...args) => {
23
+ const params = args[0];
24
+ const reqPreview = anthropicMessagesPreview(params?.messages);
25
+ const resp = await realCreate(...args);
26
+ try {
27
+ reporter.send({
28
+ requestText: reqPreview,
29
+ responseText: anthropicResponseText(resp),
30
+ });
31
+ }
32
+ catch {
33
+ /* fail-open */
34
+ }
35
+ return resp;
36
+ };
37
+ }
38
+ const v = Reflect.get(target, prop, recv);
39
+ return typeof v === 'function' ? v.bind(target) : v;
40
+ },
41
+ });
42
+ }
43
+ /** Drop-in Anthropic client; `messages.create` sends prompt/response to Verity (non-blocking). */
44
+ export class VerityAnthropic extends Anthropic {
45
+ constructor(options = {}) {
46
+ const reporter = reporterFromOpts(options);
47
+ super(stripVerityFields(options));
48
+ const wrapped = wrapMessages(this.messages, reporter);
49
+ Object.defineProperty(this, 'messages', {
50
+ value: wrapped,
51
+ enumerable: true,
52
+ configurable: true,
53
+ writable: false,
54
+ });
55
+ }
56
+ }
@@ -0,0 +1,12 @@
1
+ import { GoogleGenAI } from '@google/genai';
2
+ export type VerityGeminiClientOptions = ConstructorParameters<typeof GoogleGenAI>[0] & {
3
+ verityApiKey?: string;
4
+ verityUploadToken?: string;
5
+ verityApiUrl?: string;
6
+ googleApiKey?: string;
7
+ };
8
+ /** Drop-in `@google/genai` client; `models.generateContent` sends prompt/response to Verity (non-blocking). */
9
+ export declare class VerityGemini extends GoogleGenAI {
10
+ constructor(options?: VerityGeminiClientOptions);
11
+ }
12
+ //# sourceMappingURL=gemini.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../src/gemini.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA;AAI3C,MAAM,MAAM,yBAAyB,GAAG,qBAAqB,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG;IACrF,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAsDD,+GAA+G;AAC/G,qBAAa,YAAa,SAAQ,WAAW;gBAC/B,OAAO,GAAE,yBAA8B;CAWpD"}
package/dist/gemini.js ADDED
@@ -0,0 +1,56 @@
1
+ import { GoogleGenAI } from '@google/genai';
2
+ import { LiveAuditReporter } from './reporter.js';
3
+ import { geminiContentsPreview, geminiResponseText } from './text.js';
4
+ function stripVerityFields(opts) {
5
+ const { verityApiKey: _vk, verityUploadToken: _vt, verityApiUrl: _vu, googleApiKey, apiKey, ...rest } = opts;
6
+ const key = googleApiKey ?? apiKey;
7
+ return { ...rest, apiKey: key };
8
+ }
9
+ function reporterFromOpts(opts) {
10
+ const token = opts.verityApiKey ||
11
+ opts.verityUploadToken ||
12
+ (typeof process !== 'undefined' && process.env && (process.env.VERITY_API_KEY || process.env.VERITY_UPLOAD_TOKEN)) ||
13
+ '';
14
+ const baseUrl = opts.verityApiUrl || (typeof process !== 'undefined' && process.env && process.env.VERITY_API_URL) || undefined;
15
+ return new LiveAuditReporter({ token, baseUrl });
16
+ }
17
+ function wrapModels(real, reporter) {
18
+ const realGen = real.generateContent.bind(real);
19
+ return new Proxy(real, {
20
+ get(target, prop, recv) {
21
+ if (prop === 'generateContent') {
22
+ return async (...args) => {
23
+ const params = args[0];
24
+ const reqPreview = geminiContentsPreview(params?.contents);
25
+ const resp = await realGen(...args);
26
+ try {
27
+ reporter.send({
28
+ requestText: reqPreview,
29
+ responseText: geminiResponseText(resp),
30
+ });
31
+ }
32
+ catch {
33
+ /* fail-open */
34
+ }
35
+ return resp;
36
+ };
37
+ }
38
+ const v = Reflect.get(target, prop, recv);
39
+ return typeof v === 'function' ? v.bind(target) : v;
40
+ },
41
+ });
42
+ }
43
+ /** Drop-in `@google/genai` client; `models.generateContent` sends prompt/response to Verity (non-blocking). */
44
+ export class VerityGemini extends GoogleGenAI {
45
+ constructor(options = {}) {
46
+ const reporter = reporterFromOpts(options);
47
+ super(stripVerityFields(options));
48
+ const wrapped = wrapModels(this.models, reporter);
49
+ Object.defineProperty(this, 'models', {
50
+ value: wrapped,
51
+ enumerable: true,
52
+ configurable: true,
53
+ writable: false,
54
+ });
55
+ }
56
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Verity live audit SDK (TypeScript) — swap-in clients that POST request/response pairs
3
+ * to `POST /v1/live-audits` using your project upload token (`VERITY_API_KEY` or `verityApiKey`).
4
+ */
5
+ export { LiveAuditReporter } from './reporter.js';
6
+ export type { LiveAuditSendPayload } from './reporter.js';
7
+ export { VerityOpenAI } from './openai.js';
8
+ export type { VerityOpenAIClientOptions } from './openai.js';
9
+ export { VerityAnthropic } from './anthropic.js';
10
+ export type { VerityAnthropicClientOptions } from './anthropic.js';
11
+ export { VerityGemini } from './gemini.js';
12
+ export type { VerityGeminiClientOptions } from './gemini.js';
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAA;AACjD,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAC5D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,YAAY,EAAE,4BAA4B,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAC1C,YAAY,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Verity live audit SDK (TypeScript) — swap-in clients that POST request/response pairs
3
+ * to `POST /v1/live-audits` using your project upload token (`VERITY_API_KEY` or `verityApiKey`).
4
+ */
5
+ export { LiveAuditReporter } from './reporter.js';
6
+ export { VerityOpenAI } from './openai.js';
7
+ export { VerityAnthropic } from './anthropic.js';
8
+ export { VerityGemini } from './gemini.js';
@@ -0,0 +1,16 @@
1
+ import OpenAI from 'openai';
2
+ import type { ClientOptions } from 'openai';
3
+ export type VerityOpenAIClientOptions = ClientOptions & {
4
+ verityApiKey?: string;
5
+ verityUploadToken?: string;
6
+ verityApiUrl?: string;
7
+ openaiApiKey?: string;
8
+ };
9
+ /**
10
+ * Drop-in OpenAI client; `chat.completions.create` sends prompt/response to Verity (non-blocking).
11
+ * Extends `OpenAI` so TypeScript sees the full surface (`chat`, `beta`, etc.), not only a Proxy.
12
+ */
13
+ export declare class VerityOpenAI extends OpenAI {
14
+ constructor(options?: VerityOpenAIClientOptions);
15
+ }
16
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../src/openai.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAA;AAC3B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAI3C,MAAM,MAAM,yBAAyB,GAAG,aAAa,GAAG;IACtD,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAyHD;;;GAGG;AACH,qBAAa,YAAa,SAAQ,MAAM;gBAC1B,OAAO,GAAE,yBAA8B;CAWpD"}
package/dist/openai.js ADDED
@@ -0,0 +1,124 @@
1
+ import OpenAI from 'openai';
2
+ import { LiveAuditReporter } from './reporter.js';
3
+ import { openaiCompletionText, openaiMessagesPreview } from './text.js';
4
+ function stripVerityFields(opts) {
5
+ const { verityApiKey: _vk, verityUploadToken: _vt, verityApiUrl: _vu, openaiApiKey, apiKey, ...rest } = opts;
6
+ const key = openaiApiKey ?? apiKey;
7
+ return { ...rest, apiKey: key };
8
+ }
9
+ function reporterFromOpts(opts) {
10
+ const token = opts.verityApiKey ||
11
+ opts.verityUploadToken ||
12
+ (typeof process !== 'undefined' && process.env && (process.env.VERITY_API_KEY || process.env.VERITY_UPLOAD_TOKEN)) ||
13
+ '';
14
+ const baseUrl = opts.verityApiUrl || (typeof process !== 'undefined' && process.env && process.env.VERITY_API_URL) || undefined;
15
+ return new LiveAuditReporter({ token, baseUrl });
16
+ }
17
+ function wrapChatCompletionsCreate(real, reporter) {
18
+ const realCreate = real.create.bind(real);
19
+ return new Proxy(real, {
20
+ get(target, prop, recv) {
21
+ if (prop === 'create') {
22
+ return async (...args) => {
23
+ const body = args[0];
24
+ const stream = body?.stream === true;
25
+ const reqPreview = openaiMessagesPreview(body?.messages);
26
+ const resp = await realCreate(...args);
27
+ if (stream && resp && typeof resp[Symbol.asyncIterator] === 'function') {
28
+ return wrapOpenAIStream(resp, reporter, reqPreview);
29
+ }
30
+ try {
31
+ reporter.send({
32
+ requestText: reqPreview,
33
+ responseText: openaiCompletionText(resp),
34
+ });
35
+ }
36
+ catch {
37
+ /* fail-open */
38
+ }
39
+ return resp;
40
+ };
41
+ }
42
+ const v = Reflect.get(target, prop, recv);
43
+ return typeof v === 'function' ? v.bind(target) : v;
44
+ },
45
+ });
46
+ }
47
+ function wrapOpenAIStream(stream, reporter, requestPreview) {
48
+ return {
49
+ [Symbol.asyncIterator]() {
50
+ const inner = stream[Symbol.asyncIterator]();
51
+ const pieces = [];
52
+ return {
53
+ async next() {
54
+ const n = await inner.next();
55
+ if (!n.done && n.value) {
56
+ try {
57
+ const v = n.value;
58
+ const c = v.choices?.[0]?.delta?.content;
59
+ if (typeof c === 'string' && c)
60
+ pieces.push(c);
61
+ }
62
+ catch {
63
+ /* ignore */
64
+ }
65
+ }
66
+ if (n.done) {
67
+ try {
68
+ reporter.send({
69
+ requestText: requestPreview,
70
+ responseText: pieces.join('').slice(0, 200_000),
71
+ });
72
+ }
73
+ catch {
74
+ /* ignore */
75
+ }
76
+ }
77
+ return n;
78
+ },
79
+ return: async (v) => {
80
+ try {
81
+ reporter.send({
82
+ requestText: requestPreview,
83
+ responseText: pieces.join('').slice(0, 200_000),
84
+ });
85
+ }
86
+ catch {
87
+ /* ignore */
88
+ }
89
+ if (inner.return)
90
+ return inner.return(v);
91
+ return Promise.resolve({ done: true, value: v });
92
+ },
93
+ };
94
+ },
95
+ };
96
+ }
97
+ function wrapChat(real, reporter) {
98
+ const wrappedCompletions = wrapChatCompletionsCreate(real.completions, reporter);
99
+ return new Proxy(real, {
100
+ get(target, prop, recv) {
101
+ if (prop === 'completions')
102
+ return wrappedCompletions;
103
+ const v = Reflect.get(target, prop, recv);
104
+ return typeof v === 'function' ? v.bind(target) : v;
105
+ },
106
+ });
107
+ }
108
+ /**
109
+ * Drop-in OpenAI client; `chat.completions.create` sends prompt/response to Verity (non-blocking).
110
+ * Extends `OpenAI` so TypeScript sees the full surface (`chat`, `beta`, etc.), not only a Proxy.
111
+ */
112
+ export class VerityOpenAI extends OpenAI {
113
+ constructor(options = {}) {
114
+ const reporter = reporterFromOpts(options);
115
+ super(stripVerityFields(options));
116
+ const wrappedChat = wrapChat(this.chat, reporter);
117
+ Object.defineProperty(this, 'chat', {
118
+ value: wrappedChat,
119
+ enumerable: true,
120
+ configurable: true,
121
+ writable: false,
122
+ });
123
+ }
124
+ }
@@ -0,0 +1,21 @@
1
+ /** POST /v1/live-audits — fail-open (never throws to callers). */
2
+ export type LiveAuditSendPayload = {
3
+ requestText: string;
4
+ responseText: string;
5
+ userId?: string;
6
+ conversationId?: string;
7
+ metadata?: Record<string, unknown>;
8
+ passed?: boolean;
9
+ };
10
+ export declare class LiveAuditReporter {
11
+ readonly baseUrl: string;
12
+ readonly token: string;
13
+ readonly timeoutSec: number;
14
+ constructor(opts?: {
15
+ baseUrl?: string;
16
+ token?: string;
17
+ timeoutSec?: number;
18
+ });
19
+ send(payload: LiveAuditSendPayload): void;
20
+ }
21
+ //# sourceMappingURL=reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.d.ts","sourceRoot":"","sources":["../src/reporter.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAIlE,MAAM,MAAM,oBAAoB,GAAG;IACjC,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAClC,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAED,qBAAa,iBAAiB;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;gBAEf,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE;IAW5E,IAAI,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI;CAyB1C"}
@@ -0,0 +1,42 @@
1
+ /** POST /v1/live-audits — fail-open (never throws to callers). */
2
+ const DEFAULT_VERITY_API_URL = 'https://api.verityapp.ai';
3
+ export class LiveAuditReporter {
4
+ baseUrl;
5
+ token;
6
+ timeoutSec;
7
+ constructor(opts) {
8
+ const envUrl = typeof process !== 'undefined' && process.env ? process.env.VERITY_API_URL : undefined;
9
+ const envTok = typeof process !== 'undefined' && process.env
10
+ ? process.env.VERITY_UPLOAD_TOKEN || process.env.VERITY_API_KEY
11
+ : undefined;
12
+ this.baseUrl = (opts?.baseUrl ?? envUrl ?? DEFAULT_VERITY_API_URL).replace(/\/$/, '');
13
+ this.token = opts?.token ?? envTok ?? '';
14
+ this.timeoutSec = opts?.timeoutSec ?? 8;
15
+ }
16
+ send(payload) {
17
+ if (!this.token)
18
+ return;
19
+ const url = `${this.baseUrl}/v1/live-audits`;
20
+ const body = JSON.stringify({
21
+ request_text: payload.requestText ?? '',
22
+ response_text: payload.responseText ?? '',
23
+ user_id: payload.userId,
24
+ conversation_id: payload.conversationId,
25
+ metadata: payload.metadata ?? {},
26
+ ...(payload.passed !== undefined ? { passed: payload.passed } : {}),
27
+ });
28
+ const ac = new AbortController();
29
+ const t = setTimeout(() => ac.abort(), this.timeoutSec * 1000);
30
+ void fetch(url, {
31
+ method: 'POST',
32
+ signal: ac.signal,
33
+ headers: {
34
+ Authorization: `Bearer ${this.token}`,
35
+ 'Content-Type': 'application/json',
36
+ },
37
+ body,
38
+ })
39
+ .catch(() => { })
40
+ .finally(() => clearTimeout(t));
41
+ }
42
+ }
package/dist/text.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ export declare function openaiMessagesPreview(messages: unknown): string;
2
+ export declare function openaiCompletionText(resp: unknown): string;
3
+ export declare function anthropicMessagesPreview(messages: unknown): string;
4
+ export declare function anthropicResponseText(resp: unknown): string;
5
+ export declare function geminiContentsPreview(contents: unknown): string;
6
+ export declare function geminiResponseText(resp: unknown): string;
7
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../src/text.ts"],"names":[],"mappings":"AAEA,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAc/D;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAY1D;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAOlE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAW3D;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAQ/D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,CAQxD"}
package/dist/text.js ADDED
@@ -0,0 +1,83 @@
1
+ const MAX = 200_000;
2
+ export function openaiMessagesPreview(messages) {
3
+ if (!messages || !Array.isArray(messages))
4
+ return '';
5
+ try {
6
+ const parts = [];
7
+ for (const m of messages) {
8
+ const role = typeof m?.role === 'string' ? m.role : '';
9
+ let content = m?.content;
10
+ if (Array.isArray(content))
11
+ content = JSON.stringify(content);
12
+ parts.push(`${role}: ${String(content ?? '')}`);
13
+ }
14
+ return parts.join('\n').slice(0, MAX);
15
+ }
16
+ catch {
17
+ return '';
18
+ }
19
+ }
20
+ export function openaiCompletionText(resp) {
21
+ try {
22
+ const r = resp;
23
+ const msg = r.choices?.[0]?.message;
24
+ if (!msg)
25
+ return '';
26
+ const content = msg.content;
27
+ if (typeof content === 'string')
28
+ return content.slice(0, MAX);
29
+ if (Array.isArray(content))
30
+ return JSON.stringify(content).slice(0, MAX);
31
+ return String(content ?? '').slice(0, MAX);
32
+ }
33
+ catch {
34
+ return '';
35
+ }
36
+ }
37
+ export function anthropicMessagesPreview(messages) {
38
+ if (!messages)
39
+ return '';
40
+ try {
41
+ return JSON.stringify(messages).slice(0, MAX);
42
+ }
43
+ catch {
44
+ return String(messages).slice(0, MAX);
45
+ }
46
+ }
47
+ export function anthropicResponseText(resp) {
48
+ try {
49
+ const r = resp;
50
+ const parts = [];
51
+ for (const block of r.content ?? []) {
52
+ if (block?.type === 'text' && block.text)
53
+ parts.push(String(block.text));
54
+ }
55
+ return parts.join('\n').slice(0, MAX);
56
+ }
57
+ catch {
58
+ return String(resp).slice(0, 50_000);
59
+ }
60
+ }
61
+ export function geminiContentsPreview(contents) {
62
+ if (contents == null)
63
+ return '';
64
+ if (typeof contents === 'string')
65
+ return contents.slice(0, MAX);
66
+ try {
67
+ return JSON.stringify(contents).slice(0, MAX);
68
+ }
69
+ catch {
70
+ return String(contents).slice(0, MAX);
71
+ }
72
+ }
73
+ export function geminiResponseText(resp) {
74
+ try {
75
+ const t = resp?.text;
76
+ if (t)
77
+ return String(t).slice(0, MAX);
78
+ }
79
+ catch {
80
+ /* ignore */
81
+ }
82
+ return String(resp).slice(0, 50_000);
83
+ }
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@verityai/sdk",
3
+ "version": "1.0.0",
4
+ "description": "Verity live audit SDK — TypeScript drop-in wrappers for OpenAI, Anthropic, and Google GenAI",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": ["dist"],
15
+ "scripts": {
16
+ "build": "tsc -p tsconfig.json",
17
+ "prepublishOnly": "npm run build"
18
+ },
19
+ "keywords": ["verity", "openai", "anthropic", "gemini", "audit", "governance"],
20
+ "license": "MIT",
21
+ "publishConfig": {
22
+ "access": "public"
23
+ },
24
+ "peerDependencies": {
25
+ "@anthropic-ai/sdk": ">=0.25.0",
26
+ "@google/genai": ">=1.0.0",
27
+ "openai": ">=4.0.0"
28
+ },
29
+ "peerDependenciesMeta": {
30
+ "@anthropic-ai/sdk": { "optional": true },
31
+ "@google/genai": { "optional": true },
32
+ "openai": { "optional": true }
33
+ },
34
+ "devDependencies": {
35
+ "@anthropic-ai/sdk": "^0.52.0",
36
+ "@google/genai": "^1.49.0",
37
+ "openai": "^4.104.0",
38
+ "typescript": "~5.6"
39
+ }
40
+ }