@genbounty/ailp 0.1.0 → 0.2.1
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 +109 -94
- package/dist/ailp.d.ts +28 -0
- package/dist/ailp.d.ts.map +1 -0
- package/dist/ailp.js +34 -0
- package/dist/ailp.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/react.d.ts +25 -5
- package/dist/react.d.ts.map +1 -1
- package/dist/react.js +120 -10
- package/dist/react.js.map +1 -1
- package/dist/types.d.ts +22 -20
- package/dist/types.d.ts.map +1 -1
- package/dist/wrap.d.ts +27 -37
- package/dist/wrap.d.ts.map +1 -1
- package/dist/wrap.js +16 -35
- package/dist/wrap.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,118 +1,114 @@
|
|
|
1
|
-
# ailp
|
|
1
|
+
# @genbounty/ailp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**LLM compliance risk assessment — drop one line into any AI call.**
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
Sends your LLM interactions to the [Genbounty AILP](https://github.com/genbounty/ailp) server for automated compliance scoring against frameworks like EU AI Act, OWASP LLM Top 10, NIST AI RMF, and more. Works with any LLM provider. No runtime dependencies — uses native `fetch`.
|
|
6
6
|
|
|
7
7
|
## Install
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
|
-
npm install ailp
|
|
11
|
-
# peer dep only needed for React hook:
|
|
12
|
-
npm install react
|
|
10
|
+
npm install @genbounty/ailp
|
|
13
11
|
```
|
|
14
12
|
|
|
15
13
|
## Quick start
|
|
16
14
|
|
|
17
|
-
|
|
18
|
-
import { AilpClient } from "ailp";
|
|
15
|
+
Configure once:
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
```typescript
|
|
18
|
+
import { createAilp } from "@genbounty/ailp";
|
|
21
19
|
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
input: {
|
|
27
|
-
messages: [{ role: "user", content: "hello how are you" }],
|
|
28
|
-
endpoint: "/api/chat",
|
|
29
|
-
},
|
|
30
|
-
output: "Hello! I'm here to help.",
|
|
31
|
-
promptTokens: 11,
|
|
32
|
-
completionTokens: 14,
|
|
33
|
-
totalTokens: 25,
|
|
34
|
-
responseTime: 830,
|
|
35
|
-
endpoint: "/api/chat",
|
|
36
|
-
status: "success",
|
|
37
|
-
genbounty: {
|
|
38
|
-
apiKey: "your-genbounty-key",
|
|
39
|
-
programId: "your-program-id",
|
|
40
|
-
frameworks: ["eu-ai-act", "owasp-llm"],
|
|
41
|
-
},
|
|
20
|
+
const ailp = createAilp({
|
|
21
|
+
baseUrl: "http://localhost:8000",
|
|
22
|
+
programId: "your-program-id",
|
|
23
|
+
frameworks: ["eu-ai-act", "owasp-llm"],
|
|
42
24
|
});
|
|
25
|
+
```
|
|
43
26
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
27
|
+
Drop in after **any LLM call**:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
const res = await ailp(messages, llmOutput);
|
|
31
|
+
|
|
32
|
+
console.log(res.risk_level); // "compliant"
|
|
33
|
+
console.log(res.frameworks); // ["EU AI Act", "OWASP LLM & Agent"]
|
|
34
|
+
console.log(res.experts); // [{ framework, risk_level, reasoning }, ...]
|
|
35
|
+
console.log(res.judge_reasoning); // "The interaction is benign and poses no risk..."
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Pass an optional model hint:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
const res = await ailp(messages, llmOutput, { model: "gpt-4o-mini" });
|
|
48
42
|
```
|
|
49
43
|
|
|
50
44
|
---
|
|
51
45
|
|
|
52
|
-
##
|
|
46
|
+
## Works with any LLM provider
|
|
53
47
|
|
|
54
|
-
|
|
55
|
-
counts are captured automatically. Assessment runs **fire-and-forget** in the
|
|
56
|
-
background — your LLM call is never blocked or delayed.
|
|
48
|
+
### OpenAI
|
|
57
49
|
|
|
58
50
|
```typescript
|
|
59
|
-
|
|
60
|
-
|
|
51
|
+
const response = await openai.chat.completions.create({ model, messages });
|
|
52
|
+
const res = await ailp(messages, response.choices[0].message.content ?? "");
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Anthropic
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const response = await anthropic.messages.create({ model, messages, max_tokens: 256 });
|
|
59
|
+
const res = await ailp(messages, response.content[0]?.text ?? "");
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Any other provider
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
const output = await myLlm(messages);
|
|
66
|
+
const res = await ailp(messages, output);
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
---
|
|
61
70
|
|
|
62
|
-
|
|
63
|
-
|
|
71
|
+
## Fire-and-forget wrapper (OpenAI)
|
|
72
|
+
|
|
73
|
+
Assessment runs in the background — your LLM response is never blocked or delayed:
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
import { wrapOpenAI, AilpClient } from "@genbounty/ailp";
|
|
64
77
|
|
|
65
|
-
const
|
|
78
|
+
const client = new AilpClient({ baseUrl: "http://localhost:8000" });
|
|
66
79
|
|
|
67
80
|
const response = await wrapOpenAI(
|
|
68
|
-
(
|
|
81
|
+
(p) => openai.chat.completions.create(p),
|
|
69
82
|
{ model: "gpt-4o-mini", messages },
|
|
70
83
|
{
|
|
71
|
-
client
|
|
84
|
+
client,
|
|
85
|
+
programId: "your-program-id",
|
|
72
86
|
frameworks: ["eu-ai-act", "owasp-llm"],
|
|
73
|
-
|
|
74
|
-
endpoint: "/api/chat",
|
|
75
|
-
genbounty: {
|
|
76
|
-
apiKey: "your-genbounty-key",
|
|
77
|
-
programId: "your-program-id",
|
|
78
|
-
},
|
|
79
|
-
onAssess: (result, entry) => {
|
|
80
|
-
console.log("Risk:", result.risk_level);
|
|
81
|
-
},
|
|
82
|
-
onAssessError: (err) => {
|
|
83
|
-
console.warn("AILP assess failed:", err);
|
|
84
|
-
},
|
|
87
|
+
onAssess: (result) => console.log("Risk:", result.risk_level),
|
|
85
88
|
},
|
|
86
89
|
);
|
|
87
|
-
|
|
88
|
-
console.log(response.choices[0].message.content);
|
|
89
90
|
```
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
## Generic LLM wrapper
|
|
92
|
+
## Generic fire-and-forget wrapper
|
|
94
93
|
|
|
95
|
-
Use `wrapLlmCall` for any async LLM function
|
|
96
|
-
You supply an `extractOutput` mapper to pull the text and token counts from
|
|
97
|
-
whatever response shape your LLM returns.
|
|
94
|
+
Use `wrapLlmCall` for any async LLM function:
|
|
98
95
|
|
|
99
96
|
```typescript
|
|
100
|
-
import { wrapLlmCall } from "ailp";
|
|
97
|
+
import { wrapLlmCall, AilpClient } from "@genbounty/ailp";
|
|
98
|
+
|
|
99
|
+
const client = new AilpClient({ baseUrl: "http://localhost:8000" });
|
|
101
100
|
|
|
102
101
|
const response = await wrapLlmCall(
|
|
103
|
-
(
|
|
102
|
+
(p) => anthropic.messages.create(p),
|
|
104
103
|
{ model: "claude-3-haiku-20240307", max_tokens: 256, messages },
|
|
105
104
|
{
|
|
106
|
-
client
|
|
105
|
+
client,
|
|
106
|
+
programId: "your-program-id",
|
|
107
107
|
frameworks: ["nist-ai-rmf"],
|
|
108
108
|
messages: messages.map((m) => ({ role: m.role, content: m.content })),
|
|
109
|
-
functionName: "chat",
|
|
110
109
|
extractOutput: (res) => ({
|
|
111
110
|
output: res.content[0]?.text ?? "",
|
|
112
111
|
model: res.model,
|
|
113
|
-
promptTokens: res.usage?.input_tokens,
|
|
114
|
-
completionTokens: res.usage?.output_tokens,
|
|
115
|
-
totalTokens: (res.usage?.input_tokens ?? 0) + (res.usage?.output_tokens ?? 0),
|
|
116
112
|
}),
|
|
117
113
|
},
|
|
118
114
|
);
|
|
@@ -120,28 +116,23 @@ const response = await wrapLlmCall(
|
|
|
120
116
|
|
|
121
117
|
---
|
|
122
118
|
|
|
123
|
-
## React
|
|
119
|
+
## React
|
|
124
120
|
|
|
125
|
-
Import from
|
|
121
|
+
Import from `@genbounty/ailp/react` to keep React out of the core bundle.
|
|
126
122
|
|
|
127
|
-
|
|
128
|
-
import { AilpClient } from "ailp";
|
|
129
|
-
import { useAssess } from "ailp/react";
|
|
123
|
+
### `useAilp()` — recommended
|
|
130
124
|
|
|
131
|
-
|
|
125
|
+
One hook: memoized client + `assess` / `result` / `loading` / `error` / `reset`.
|
|
126
|
+
Configure with **environment variables** (Next.js `NEXT_PUBLIC_*`, Vite `VITE_*`) so you do not need `useMemo` or `createAilp` in every component.
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import { useAilp } from "@genbounty/ailp/react";
|
|
132
130
|
|
|
133
131
|
function ChatWidget() {
|
|
134
|
-
const { assess, result, loading, error, reset } =
|
|
132
|
+
const { assess, result, loading, error, reset } = useAilp();
|
|
135
133
|
|
|
136
134
|
async function handleSend(userMessage: string, llmOutput: string) {
|
|
137
|
-
await assess({
|
|
138
|
-
timestamp: new Date().toISOString(),
|
|
139
|
-
function: "chat",
|
|
140
|
-
input: { messages: [{ role: "user", content: userMessage }] },
|
|
141
|
-
output: llmOutput,
|
|
142
|
-
status: "success",
|
|
143
|
-
genbounty: { frameworks: ["eu-ai-act"] },
|
|
144
|
-
});
|
|
135
|
+
await assess([{ role: "user", content: userMessage }], llmOutput);
|
|
145
136
|
}
|
|
146
137
|
|
|
147
138
|
return (
|
|
@@ -159,12 +150,40 @@ function ChatWidget() {
|
|
|
159
150
|
}
|
|
160
151
|
```
|
|
161
152
|
|
|
153
|
+
**Env vars** (override any field by passing options to `useAilp({ ... })` instead):
|
|
154
|
+
|
|
155
|
+
| Variable | Required | Default |
|
|
156
|
+
|----------|----------|---------|
|
|
157
|
+
| `NEXT_PUBLIC_GENBOUNTY_PROGRAM_ID` or `VITE_GENBOUNTY_PROGRAM_ID` | Yes (unless you pass `programId`) | — |
|
|
158
|
+
| `NEXT_PUBLIC_AILP_BASE_URL` or `VITE_AILP_BASE_URL` | No | `http://127.0.0.1:8000` |
|
|
159
|
+
| `NEXT_PUBLIC_AILP_FRAMEWORKS` or `VITE_AILP_FRAMEWORKS` | No | `eu-ai-act` |
|
|
160
|
+
|
|
161
|
+
Frameworks in env: comma-separated (`eu-ai-act,owasp-llm`) or a JSON array string (`["eu-ai-act","owasp-llm"]`).
|
|
162
|
+
|
|
163
|
+
Partial override example:
|
|
164
|
+
|
|
165
|
+
```tsx
|
|
166
|
+
const { assess, result, loading, error } = useAilp({ programId: "hardcoded-for-demo" });
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The hook also returns `ailp` (the underlying `AilpFn`) if you need it outside `assess`.
|
|
170
|
+
|
|
171
|
+
### `useAssess(ailp)` — advanced
|
|
172
|
+
|
|
173
|
+
If you already have an `AilpFn` from `createAilp()`:
|
|
174
|
+
|
|
175
|
+
```tsx
|
|
176
|
+
import { createAilp } from "@genbounty/ailp";
|
|
177
|
+
import { useAssess } from "@genbounty/ailp/react";
|
|
178
|
+
|
|
179
|
+
const ailp = createAilp({ baseUrl, programId, frameworks });
|
|
180
|
+
const { assess, result, loading, error } = useAssess(ailp);
|
|
181
|
+
```
|
|
182
|
+
|
|
162
183
|
---
|
|
163
184
|
|
|
164
185
|
## Framework slugs
|
|
165
186
|
|
|
166
|
-
Pass any of these as `frameworks` (hyphen or underscore):
|
|
167
|
-
|
|
168
187
|
| Slug | Framework |
|
|
169
188
|
|------|-----------|
|
|
170
189
|
| `eu_ai_act` / `eu-ai-act` | EU AI Act |
|
|
@@ -184,10 +203,6 @@ Pass any of these as `frameworks` (hyphen or underscore):
|
|
|
184
203
|
|
|
185
204
|
---
|
|
186
205
|
|
|
187
|
-
##
|
|
206
|
+
## License
|
|
188
207
|
|
|
189
|
-
|
|
190
|
-
npm install
|
|
191
|
-
npm run build # outputs to dist/
|
|
192
|
-
npm run dev # watch mode
|
|
193
|
-
```
|
|
208
|
+
MIT
|
package/dist/ailp.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { AilpAssessResponse, AilpCallOptions, AilpMessage, AilpOptions } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* A pre-configured assess function returned by createAilp().
|
|
4
|
+
* Call it after any LLM interaction — vendor agnostic.
|
|
5
|
+
*
|
|
6
|
+
* @param messages The conversation messages sent to the LLM.
|
|
7
|
+
* @param output The raw text response from the LLM.
|
|
8
|
+
* @param options Optional per-call overrides (model, endpoint).
|
|
9
|
+
*/
|
|
10
|
+
export type AilpFn = (messages: AilpMessage[], output: string, options?: AilpCallOptions) => Promise<AilpAssessResponse>;
|
|
11
|
+
/**
|
|
12
|
+
* Create a pre-configured AILP assess function.
|
|
13
|
+
* Call createAilp() once at startup, then drop the returned function
|
|
14
|
+
* in after any LLM call.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* const ailp = createAilp({
|
|
18
|
+
* baseUrl: "http://localhost:8000",
|
|
19
|
+
* programId: "my-program",
|
|
20
|
+
* frameworks: ["eu-ai-act", "owasp-llm"],
|
|
21
|
+
* });
|
|
22
|
+
*
|
|
23
|
+
* // after any LLM call:
|
|
24
|
+
* const res = await ailp(messages, llmOutput);
|
|
25
|
+
* console.log(res.risk_level);
|
|
26
|
+
*/
|
|
27
|
+
export declare function createAilp(options: AilpOptions): AilpFn;
|
|
28
|
+
//# sourceMappingURL=ailp.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ailp.d.ts","sourceRoot":"","sources":["../src/ailp.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EACf,WAAW,EACX,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB;;;;;;;GAOG;AACH,MAAM,MAAM,MAAM,GAAG,CACnB,QAAQ,EAAE,WAAW,EAAE,EACvB,MAAM,EAAE,MAAM,EACd,OAAO,CAAC,EAAE,eAAe,KACtB,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAEjC;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,WAAW,GAAG,MAAM,CAoBvD"}
|
package/dist/ailp.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { AilpClient } from "./client.js";
|
|
2
|
+
/**
|
|
3
|
+
* Create a pre-configured AILP assess function.
|
|
4
|
+
* Call createAilp() once at startup, then drop the returned function
|
|
5
|
+
* in after any LLM call.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* const ailp = createAilp({
|
|
9
|
+
* baseUrl: "http://localhost:8000",
|
|
10
|
+
* programId: "my-program",
|
|
11
|
+
* frameworks: ["eu-ai-act", "owasp-llm"],
|
|
12
|
+
* });
|
|
13
|
+
*
|
|
14
|
+
* // after any LLM call:
|
|
15
|
+
* const res = await ailp(messages, llmOutput);
|
|
16
|
+
* console.log(res.risk_level);
|
|
17
|
+
*/
|
|
18
|
+
export function createAilp(options) {
|
|
19
|
+
const client = new AilpClient({
|
|
20
|
+
baseUrl: options.baseUrl,
|
|
21
|
+
timeoutMs: options.timeoutMs,
|
|
22
|
+
});
|
|
23
|
+
return function ailp(messages, output, callOptions) {
|
|
24
|
+
return client.assess({
|
|
25
|
+
timestamp: new Date().toISOString(),
|
|
26
|
+
input: { messages, endpoint: callOptions?.endpoint },
|
|
27
|
+
output,
|
|
28
|
+
model: callOptions?.model,
|
|
29
|
+
framework: options.frameworks,
|
|
30
|
+
genbounty: { programId: options.programId },
|
|
31
|
+
});
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=ailp.js.map
|
package/dist/ailp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ailp.js","sourceRoot":"","sources":["../src/ailp.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAsBzC;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,UAAU,CAAC,OAAoB;IAC7C,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC;QAC5B,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,SAAS,EAAE,OAAO,CAAC,SAAS;KAC7B,CAAC,CAAC;IAEH,OAAO,SAAS,IAAI,CAClB,QAAuB,EACvB,MAAc,EACd,WAA6B;QAE7B,OAAO,MAAM,CAAC,MAAM,CAAC;YACnB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,KAAK,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE;YACpD,MAAM;YACN,KAAK,EAAE,WAAW,EAAE,KAAK;YACzB,SAAS,EAAE,OAAO,CAAC,UAAU;YAC7B,SAAS,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE;SAC5C,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
export { createAilp } from "./ailp.js";
|
|
2
|
+
export type { AilpFn } from "./ailp.js";
|
|
1
3
|
export { AilpClient, AilpError } from "./client.js";
|
|
2
4
|
export { wrapLlmCall, wrapOpenAI } from "./wrap.js";
|
|
3
|
-
export type { AilpAssessResponse, AilpClientOptions, AilpExpertResult, AilpFrameworkSlug, AilpGenBounty, AilpLogEntry, AilpMessage, AilpRiskLevel, } from "./types.js";
|
|
4
5
|
export type { LlmWrapOptions, OpenAIWrapOptions, WrapOptions } from "./wrap.js";
|
|
6
|
+
export type { AilpAssessResponse, AilpCallOptions, AilpClientOptions, AilpExpertResult, AilpFrameworkSlug, AilpLogEntry, AilpMessage, AilpOptions, AilpRiskLevel, } from "./types.js";
|
|
5
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACpD,YAAY,EACV,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACvC,YAAY,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAEhF,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,WAAW,EACX,WAAW,EACX,aAAa,GACd,MAAM,YAAY,CAAC"}
|
package/dist/index.js
CHANGED
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC;AAGvC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,WAAW,CAAC"}
|
package/dist/react.d.ts
CHANGED
|
@@ -1,5 +1,25 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type { AilpAssessResponse,
|
|
1
|
+
import type { AilpFn } from "./ailp.js";
|
|
2
|
+
import type { AilpAssessResponse, AilpCallOptions, AilpMessage, AilpOptions } from "./types.js";
|
|
3
|
+
/**
|
|
4
|
+
* Resolve config from optional overrides + environment variables.
|
|
5
|
+
* Throws if programId cannot be determined.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveAilpConfigFromEnv(overrides?: Partial<AilpOptions>): AilpOptions;
|
|
8
|
+
/** Optional overrides; omitted fields are read from env (see README). */
|
|
9
|
+
export type UseAilpOptions = Partial<AilpOptions>;
|
|
10
|
+
export type UseAilpResult = UseAssessState & {
|
|
11
|
+
ailp: AilpFn;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* One-liner for React apps: memoized `createAilp` + assessment state.
|
|
15
|
+
* Reads `NEXT_PUBLIC_*` (Next.js) or `VITE_*` (Vite) when options are omitted.
|
|
16
|
+
*
|
|
17
|
+
* Env vars:
|
|
18
|
+
* - `NEXT_PUBLIC_AILP_BASE_URL` / `VITE_AILP_BASE_URL` — default `http://127.0.0.1:8000`
|
|
19
|
+
* - `NEXT_PUBLIC_GENBOUNTY_PROGRAM_ID` / `VITE_GENBOUNTY_PROGRAM_ID` — **required** unless you pass `programId`
|
|
20
|
+
* - `NEXT_PUBLIC_AILP_FRAMEWORKS` / `VITE_AILP_FRAMEWORKS` — comma-separated or JSON array; default `eu-ai-act`
|
|
21
|
+
*/
|
|
22
|
+
export declare function useAilp(options?: UseAilpOptions): UseAilpResult;
|
|
3
23
|
export interface UseAssessState {
|
|
4
24
|
/** Last successful response, or null if not yet assessed. */
|
|
5
25
|
result: AilpAssessResponse | null;
|
|
@@ -7,10 +27,10 @@ export interface UseAssessState {
|
|
|
7
27
|
loading: boolean;
|
|
8
28
|
/** Last error thrown by assess, or null. */
|
|
9
29
|
error: Error | null;
|
|
10
|
-
/** Submit
|
|
11
|
-
assess: (
|
|
30
|
+
/** Submit messages and LLM output for assessment. Returns the response, or null on error. */
|
|
31
|
+
assess: (messages: AilpMessage[], output: string, options?: AilpCallOptions) => Promise<AilpAssessResponse | null>;
|
|
12
32
|
/** Clear result and error back to initial state. */
|
|
13
33
|
reset: () => void;
|
|
14
34
|
}
|
|
15
|
-
export declare function useAssess(
|
|
35
|
+
export declare function useAssess(ailp: AilpFn): UseAssessState;
|
|
16
36
|
//# sourceMappingURL=react.d.ts.map
|
package/dist/react.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAqBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACxC,OAAO,KAAK,EACV,kBAAkB,EAClB,eAAe,EAEf,WAAW,EACX,WAAW,EACZ,MAAM,YAAY,CAAC;AAwCpB;;;GAGG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAiCtF;AAaD,yEAAyE;AACzE,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG,cAAc,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAE9D;;;;;;;;GAQG;AACH,wBAAgB,OAAO,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,aAAa,CAsB/D;AAMD,MAAM,WAAW,cAAc;IAC7B,6DAA6D;IAC7D,MAAM,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAClC,iDAAiD;IACjD,OAAO,EAAE,OAAO,CAAC;IACjB,4CAA4C;IAC5C,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,6FAA6F;IAC7F,MAAM,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,kBAAkB,GAAG,IAAI,CAAC,CAAC;IACnH,oDAAoD;IACpD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAkCtD"}
|
package/dist/react.js
CHANGED
|
@@ -1,21 +1,131 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* React
|
|
3
|
-
* Import from "ailp/react" to keep React out of the main bundle.
|
|
2
|
+
* React hooks for AILP assess.
|
|
3
|
+
* Import from "@genbounty/ailp/react" to keep React out of the main bundle.
|
|
4
4
|
*
|
|
5
|
-
* @example
|
|
6
|
-
* import {
|
|
7
|
-
*
|
|
5
|
+
* @example Recommended — env-driven Next.js / Vite (no useMemo boilerplate)
|
|
6
|
+
* import { useAilp } from "@genbounty/ailp/react";
|
|
7
|
+
*
|
|
8
|
+
* function ChatWidget() {
|
|
9
|
+
* const { assess, result, loading, error, reset } = useAilp();
|
|
10
|
+
* // ...
|
|
11
|
+
* }
|
|
12
|
+
*
|
|
13
|
+
* @example Advanced — reuse an existing AilpFn
|
|
14
|
+
* import { createAilp } from "@genbounty/ailp";
|
|
15
|
+
* import { useAssess } from "@genbounty/ailp/react";
|
|
16
|
+
*
|
|
17
|
+
* const ailp = createAilp({ baseUrl, programId, frameworks });
|
|
18
|
+
* const { assess, result, loading, error } = useAssess(ailp);
|
|
8
19
|
*/
|
|
9
|
-
import { useCallback, useState } from "react";
|
|
10
|
-
|
|
20
|
+
import { useCallback, useMemo, useState } from "react";
|
|
21
|
+
import { createAilp } from "./ailp.js";
|
|
22
|
+
// -------------------------------------------------------------------------
|
|
23
|
+
// Env helpers (Next.js NEXT_PUBLIC_*, Vite VITE_*)
|
|
24
|
+
// -------------------------------------------------------------------------
|
|
25
|
+
function getNodeEnv() {
|
|
26
|
+
const g = globalThis;
|
|
27
|
+
return g.process?.env;
|
|
28
|
+
}
|
|
29
|
+
function readEnv(key) {
|
|
30
|
+
const v = getNodeEnv()?.[key];
|
|
31
|
+
if (v != null && v !== "")
|
|
32
|
+
return v;
|
|
33
|
+
try {
|
|
34
|
+
const im = import.meta;
|
|
35
|
+
const v = im.env?.[key];
|
|
36
|
+
if (typeof v === "string" && v !== "")
|
|
37
|
+
return v;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
/* import.meta unavailable */
|
|
41
|
+
}
|
|
42
|
+
return undefined;
|
|
43
|
+
}
|
|
44
|
+
function parseFrameworksFromEnv(raw) {
|
|
45
|
+
if (raw == null || raw.trim() === "")
|
|
46
|
+
return undefined;
|
|
47
|
+
const t = raw.trim();
|
|
48
|
+
if (t.startsWith("[")) {
|
|
49
|
+
try {
|
|
50
|
+
const j = JSON.parse(t);
|
|
51
|
+
if (Array.isArray(j) && j.every((x) => typeof x === "string")) {
|
|
52
|
+
return j;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
/* fall through */
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
return t.split(",").map((s) => s.trim()).filter(Boolean);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Resolve config from optional overrides + environment variables.
|
|
63
|
+
* Throws if programId cannot be determined.
|
|
64
|
+
*/
|
|
65
|
+
export function resolveAilpConfigFromEnv(overrides) {
|
|
66
|
+
const baseUrl = overrides?.baseUrl ??
|
|
67
|
+
readEnv("NEXT_PUBLIC_AILP_BASE_URL") ??
|
|
68
|
+
readEnv("VITE_AILP_BASE_URL") ??
|
|
69
|
+
"http://127.0.0.1:8000";
|
|
70
|
+
const programIdRaw = overrides?.programId ??
|
|
71
|
+
readEnv("NEXT_PUBLIC_GENBOUNTY_PROGRAM_ID") ??
|
|
72
|
+
readEnv("VITE_GENBOUNTY_PROGRAM_ID");
|
|
73
|
+
if (programIdRaw == null || String(programIdRaw).trim() === "") {
|
|
74
|
+
throw new Error("AILP: missing programId. Set NEXT_PUBLIC_GENBOUNTY_PROGRAM_ID or VITE_GENBOUNTY_PROGRAM_ID, or pass programId to useAilp().");
|
|
75
|
+
}
|
|
76
|
+
let frameworks;
|
|
77
|
+
if (overrides?.frameworks != null) {
|
|
78
|
+
frameworks = overrides.frameworks;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
const raw = readEnv("NEXT_PUBLIC_AILP_FRAMEWORKS") ?? readEnv("VITE_AILP_FRAMEWORKS");
|
|
82
|
+
frameworks = parseFrameworksFromEnv(raw) ?? ["eu-ai-act"];
|
|
83
|
+
}
|
|
84
|
+
return {
|
|
85
|
+
baseUrl: baseUrl.replace(/\/$/, ""),
|
|
86
|
+
programId: String(programIdRaw),
|
|
87
|
+
frameworks,
|
|
88
|
+
timeoutMs: overrides?.timeoutMs,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function frameworksDepKey(fw) {
|
|
92
|
+
if (fw === undefined)
|
|
93
|
+
return "__env__";
|
|
94
|
+
return Array.isArray(fw) ? JSON.stringify(fw) : String(fw);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* One-liner for React apps: memoized `createAilp` + assessment state.
|
|
98
|
+
* Reads `NEXT_PUBLIC_*` (Next.js) or `VITE_*` (Vite) when options are omitted.
|
|
99
|
+
*
|
|
100
|
+
* Env vars:
|
|
101
|
+
* - `NEXT_PUBLIC_AILP_BASE_URL` / `VITE_AILP_BASE_URL` — default `http://127.0.0.1:8000`
|
|
102
|
+
* - `NEXT_PUBLIC_GENBOUNTY_PROGRAM_ID` / `VITE_GENBOUNTY_PROGRAM_ID` — **required** unless you pass `programId`
|
|
103
|
+
* - `NEXT_PUBLIC_AILP_FRAMEWORKS` / `VITE_AILP_FRAMEWORKS` — comma-separated or JSON array; default `eu-ai-act`
|
|
104
|
+
*/
|
|
105
|
+
export function useAilp(options) {
|
|
106
|
+
const baseUrl = options?.baseUrl;
|
|
107
|
+
const programId = options?.programId;
|
|
108
|
+
const frameworks = options?.frameworks;
|
|
109
|
+
const timeoutMs = options?.timeoutMs;
|
|
110
|
+
const config = useMemo(() => resolveAilpConfigFromEnv({
|
|
111
|
+
baseUrl,
|
|
112
|
+
programId,
|
|
113
|
+
frameworks,
|
|
114
|
+
timeoutMs,
|
|
115
|
+
}), [baseUrl, programId, frameworksDepKey(frameworks), timeoutMs]);
|
|
116
|
+
const ailp = useMemo(() => createAilp(config), [config]);
|
|
117
|
+
const state = useAssess(ailp);
|
|
118
|
+
return { ...state, ailp };
|
|
119
|
+
}
|
|
120
|
+
export function useAssess(ailp) {
|
|
11
121
|
const [result, setResult] = useState(null);
|
|
12
122
|
const [loading, setLoading] = useState(false);
|
|
13
123
|
const [error, setError] = useState(null);
|
|
14
|
-
const assess = useCallback(async (
|
|
124
|
+
const assess = useCallback(async (messages, output, callOptions) => {
|
|
15
125
|
setLoading(true);
|
|
16
126
|
setError(null);
|
|
17
127
|
try {
|
|
18
|
-
const res = await
|
|
128
|
+
const res = await ailp(messages, output, callOptions);
|
|
19
129
|
setResult(res);
|
|
20
130
|
return res;
|
|
21
131
|
}
|
|
@@ -27,7 +137,7 @@ export function useAssess(client) {
|
|
|
27
137
|
finally {
|
|
28
138
|
setLoading(false);
|
|
29
139
|
}
|
|
30
|
-
}, [
|
|
140
|
+
}, [ailp]);
|
|
31
141
|
const reset = useCallback(() => {
|
|
32
142
|
setResult(null);
|
|
33
143
|
setError(null);
|
package/dist/react.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"react.js","sourceRoot":"","sources":["../src/react.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -4,15 +4,7 @@ export interface AilpMessage {
|
|
|
4
4
|
role: string;
|
|
5
5
|
content: string;
|
|
6
6
|
}
|
|
7
|
-
export interface AilpGenBounty {
|
|
8
|
-
/** Genbounty API key (returned as "***" in the echoed log). */
|
|
9
|
-
apiKey?: string;
|
|
10
|
-
programId?: string;
|
|
11
|
-
/** One or more framework slugs. First entry wins over top-level framework. */
|
|
12
|
-
frameworks?: AilpFrameworkSlug | AilpFrameworkSlug[];
|
|
13
|
-
}
|
|
14
7
|
export interface AilpLogEntry {
|
|
15
|
-
/** ISO 8601 timestamp of the LLM interaction. */
|
|
16
8
|
timestamp: string;
|
|
17
9
|
/** Name of the calling function / route handler. */
|
|
18
10
|
function?: string;
|
|
@@ -24,20 +16,16 @@ export interface AilpLogEntry {
|
|
|
24
16
|
};
|
|
25
17
|
/** Raw text output from the LLM. */
|
|
26
18
|
output: string;
|
|
27
|
-
promptTokens?: number;
|
|
28
|
-
completionTokens?: number;
|
|
29
|
-
totalTokens?: number;
|
|
30
|
-
/** Total latency in milliseconds. */
|
|
31
|
-
responseTime?: number;
|
|
32
19
|
endpoint?: string;
|
|
33
|
-
/** HTTP or logical status (e.g. "success", "error"). */
|
|
34
|
-
status?: string;
|
|
35
20
|
/**
|
|
36
21
|
* Framework slug(s) to assess against.
|
|
37
|
-
*
|
|
22
|
+
* Defaults to OECD if omitted everywhere.
|
|
38
23
|
*/
|
|
39
24
|
framework?: AilpFrameworkSlug | AilpFrameworkSlug[];
|
|
40
|
-
genbounty?:
|
|
25
|
+
genbounty?: {
|
|
26
|
+
programId?: string;
|
|
27
|
+
frameworks?: AilpFrameworkSlug | AilpFrameworkSlug[];
|
|
28
|
+
};
|
|
41
29
|
}
|
|
42
30
|
export interface AilpExpertResult {
|
|
43
31
|
framework: string;
|
|
@@ -53,15 +41,29 @@ export interface AilpAssessResponse {
|
|
|
53
41
|
frameworks: string[];
|
|
54
42
|
/** One entry per framework expert, in the same order as frameworks. */
|
|
55
43
|
experts: AilpExpertResult[];
|
|
56
|
-
/** Echo of the submitted log entry
|
|
44
|
+
/** Echo of the submitted log entry. */
|
|
57
45
|
log: AilpLogEntry;
|
|
58
46
|
}
|
|
59
|
-
export interface
|
|
47
|
+
export interface AilpOptions {
|
|
60
48
|
/** Base URL of the AILP server (no trailing slash). */
|
|
61
49
|
baseUrl: string;
|
|
50
|
+
/** Genbounty program ID to assess against. */
|
|
51
|
+
programId: string;
|
|
52
|
+
/** Framework slug(s) to run. */
|
|
53
|
+
frameworks: AilpFrameworkSlug | AilpFrameworkSlug[];
|
|
62
54
|
/** Optional request timeout in milliseconds (default: no timeout). */
|
|
63
55
|
timeoutMs?: number;
|
|
64
|
-
|
|
56
|
+
}
|
|
57
|
+
/** Options accepted per individual ailp() call. */
|
|
58
|
+
export interface AilpCallOptions {
|
|
59
|
+
/** Model identifier (e.g. "gpt-4o-mini"). */
|
|
60
|
+
model?: string;
|
|
61
|
+
/** Endpoint path to record (e.g. "/api/chat"). */
|
|
62
|
+
endpoint?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface AilpClientOptions {
|
|
65
|
+
baseUrl: string;
|
|
66
|
+
timeoutMs?: number;
|
|
65
67
|
headers?: Record<string, string>;
|
|
66
68
|
}
|
|
67
69
|
//# sourceMappingURL=types.d.ts.map
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GACzB,WAAW,GAAM,WAAW,GAC5B,MAAM,GACN,WAAW,GAAM,WAAW,GAC5B,aAAa,GAAI,aAAa,GAC9B,cAAc,GAAG,cAAc,GAC/B,KAAK,GACL,WAAW,GAAM,WAAW,GAC5B,eAAe,GAAE,eAAe,GAChC,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,MAAM,aAAa,GACrB,UAAU,GACV,MAAM,GACN,QAAQ,GACR,KAAK,GACL,eAAe,GACf,WAAW,GACX,eAAe,CAAC;AAMpB,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAMD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,EAAE;QACL,QAAQ,EAAE,WAAW,EAAE,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,oCAAoC;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,SAAS,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAC;IACpD,SAAS,CAAC,EAAE;QACV,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,UAAU,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAC;KACtD,CAAC;CACH;AAMD,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,aAAa,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB;IACjC,yEAAyE;IACzE,UAAU,EAAE,aAAa,CAAC;IAC1B,0CAA0C;IAC1C,eAAe,EAAE,MAAM,CAAC;IACxB,yDAAyD;IACzD,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,uEAAuE;IACvE,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,uCAAuC;IACvC,GAAG,EAAE,YAAY,CAAC;CACnB;AAMD,MAAM,WAAW,WAAW;IAC1B,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,SAAS,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,UAAU,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAC;IACpD,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,mDAAmD;AACnD,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC"}
|
package/dist/wrap.d.ts
CHANGED
|
@@ -1,35 +1,11 @@
|
|
|
1
1
|
import type { AilpClient } from "./client.js";
|
|
2
|
-
import type { AilpAssessResponse, AilpFrameworkSlug,
|
|
3
|
-
interface OpenAIMessage {
|
|
4
|
-
role: string;
|
|
5
|
-
content: string | null;
|
|
6
|
-
}
|
|
7
|
-
interface OpenAIChoice {
|
|
8
|
-
message: OpenAIMessage;
|
|
9
|
-
finish_reason?: string;
|
|
10
|
-
}
|
|
11
|
-
interface OpenAIUsage {
|
|
12
|
-
prompt_tokens?: number;
|
|
13
|
-
completion_tokens?: number;
|
|
14
|
-
total_tokens?: number;
|
|
15
|
-
}
|
|
16
|
-
interface OpenAIChatResponse {
|
|
17
|
-
id?: string;
|
|
18
|
-
model?: string;
|
|
19
|
-
choices: OpenAIChoice[];
|
|
20
|
-
usage?: OpenAIUsage;
|
|
21
|
-
}
|
|
22
|
-
interface OpenAIChatParams {
|
|
23
|
-
model: string;
|
|
24
|
-
messages: OpenAIMessage[];
|
|
25
|
-
[key: string]: unknown;
|
|
26
|
-
}
|
|
2
|
+
import type { AilpAssessResponse, AilpFrameworkSlug, AilpLogEntry, AilpMessage } from "./types.js";
|
|
27
3
|
export interface WrapOptions {
|
|
28
4
|
client: AilpClient;
|
|
29
5
|
/** Framework slug(s) to assess against. */
|
|
30
6
|
frameworks?: AilpFrameworkSlug | AilpFrameworkSlug[];
|
|
31
|
-
/**
|
|
32
|
-
|
|
7
|
+
/** Genbounty program ID. */
|
|
8
|
+
programId?: string;
|
|
33
9
|
/** Name of the calling function/route (logged as "function" in the entry). */
|
|
34
10
|
functionName?: string;
|
|
35
11
|
/** Endpoint path to record (e.g. "/api/chat"). */
|
|
@@ -48,37 +24,51 @@ export interface WrapOptions {
|
|
|
48
24
|
export interface LlmWrapOptions<TResult> extends WrapOptions {
|
|
49
25
|
/**
|
|
50
26
|
* Map the LLM result to the fields AILP needs.
|
|
51
|
-
*
|
|
27
|
+
* Only output text is required; model is optional.
|
|
52
28
|
*/
|
|
53
29
|
extractOutput: (result: TResult) => {
|
|
54
30
|
output: string;
|
|
55
31
|
model?: string;
|
|
56
|
-
promptTokens?: number;
|
|
57
|
-
completionTokens?: number;
|
|
58
|
-
totalTokens?: number;
|
|
59
32
|
};
|
|
60
33
|
/** Input messages to log. */
|
|
61
34
|
messages: AilpMessage[];
|
|
62
35
|
}
|
|
63
36
|
/**
|
|
64
|
-
* Generic wrapper: calls any async LLM function
|
|
65
|
-
*
|
|
66
|
-
*
|
|
37
|
+
* Generic wrapper: calls any async LLM function and fires an AILP assess
|
|
38
|
+
* in the background. Never blocks or throws on assess failures — your LLM
|
|
39
|
+
* call result is always returned.
|
|
67
40
|
*/
|
|
68
41
|
export declare function wrapLlmCall<TParams, TResult>(fn: (params: TParams) => Promise<TResult>, params: TParams, options: LlmWrapOptions<TResult>): Promise<TResult>;
|
|
42
|
+
interface OpenAIMessage {
|
|
43
|
+
role: string;
|
|
44
|
+
content: string | null;
|
|
45
|
+
}
|
|
46
|
+
interface OpenAIChoice {
|
|
47
|
+
message: OpenAIMessage;
|
|
48
|
+
finish_reason?: string;
|
|
49
|
+
}
|
|
50
|
+
interface OpenAIChatResponse {
|
|
51
|
+
id?: string;
|
|
52
|
+
model?: string;
|
|
53
|
+
choices: OpenAIChoice[];
|
|
54
|
+
}
|
|
55
|
+
interface OpenAIChatParams {
|
|
56
|
+
model: string;
|
|
57
|
+
messages: OpenAIMessage[];
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
}
|
|
69
60
|
export interface OpenAIWrapOptions extends WrapOptions {
|
|
70
|
-
/** The endpoint path to log (default: "/v1/chat/completions"). */
|
|
71
61
|
endpoint?: string;
|
|
72
62
|
}
|
|
73
63
|
/**
|
|
74
64
|
* Drop-in wrapper for `openai.chat.completions.create()` (or any compatible API).
|
|
75
|
-
*
|
|
65
|
+
* Assessment runs fire-and-forget — your LLM call is never blocked or delayed.
|
|
76
66
|
*
|
|
77
67
|
* @example
|
|
78
68
|
* const response = await wrapOpenAI(
|
|
79
69
|
* (p) => openai.chat.completions.create(p),
|
|
80
70
|
* { model: "gpt-4o-mini", messages },
|
|
81
|
-
* { client, frameworks: ["eu-ai-act"
|
|
71
|
+
* { client, programId: "my-program", frameworks: ["eu-ai-act"] }
|
|
82
72
|
* );
|
|
83
73
|
*/
|
|
84
74
|
export declare function wrapOpenAI<T extends OpenAIChatParams>(fn: (params: T) => Promise<OpenAIChatResponse>, params: T, options: OpenAIWrapOptions): Promise<OpenAIChatResponse>;
|
package/dist/wrap.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAMnG,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,UAAU,CAAC;IACnB,2CAA2C;IAC3C,UAAU,CAAC,EAAE,iBAAiB,GAAG,iBAAiB,EAAE,CAAC;IACrD,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACrE;;;OAGG;IACH,aAAa,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;CAC7D;AAMD,MAAM,WAAW,cAAc,CAAC,OAAO,CAAE,SAAQ,WAAW;IAC1D;;;OAGG;IACH,aAAa,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK;QAClC,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,6BAA6B;IAC7B,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,OAAO,EAChD,EAAE,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,EACzC,MAAM,EAAE,OAAO,EACf,OAAO,EAAE,cAAc,CAAC,OAAO,CAAC,GAC/B,OAAO,CAAC,OAAO,CAAC,CA2ClB;AAMD,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,UAAU,YAAY;IACpB,OAAO,EAAE,aAAa,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,UAAU,kBAAkB;IAC1B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED,UAAU,gBAAgB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAMD,MAAM,WAAW,iBAAkB,SAAQ,WAAW;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,UAAU,CAAC,CAAC,SAAS,gBAAgB,EACzD,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC,kBAAkB,CAAC,EAC9C,MAAM,EAAE,CAAC,EACT,OAAO,EAAE,iBAAiB,GACzB,OAAO,CAAC,kBAAkB,CAAC,CAkB7B"}
|
package/dist/wrap.js
CHANGED
|
@@ -1,32 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Generic wrapper: calls any async LLM function
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Generic wrapper: calls any async LLM function and fires an AILP assess
|
|
3
|
+
* in the background. Never blocks or throws on assess failures — your LLM
|
|
4
|
+
* call result is always returned.
|
|
5
5
|
*/
|
|
6
6
|
export async function wrapLlmCall(fn, params, options) {
|
|
7
|
-
const start = Date.now();
|
|
8
7
|
let result;
|
|
9
|
-
let status = "success";
|
|
10
8
|
try {
|
|
11
9
|
result = await fn(params);
|
|
12
10
|
}
|
|
13
11
|
catch (err) {
|
|
14
|
-
status = "error";
|
|
15
12
|
_fireAssess({
|
|
16
|
-
timestamp: new Date(
|
|
13
|
+
timestamp: new Date().toISOString(),
|
|
17
14
|
function: options.functionName,
|
|
18
|
-
model: undefined,
|
|
19
15
|
input: { messages: options.messages, endpoint: options.endpoint },
|
|
20
16
|
output: err instanceof Error ? err.message : String(err),
|
|
21
|
-
responseTime: Date.now() - start,
|
|
22
17
|
endpoint: options.endpoint,
|
|
23
|
-
status,
|
|
24
18
|
framework: options.frameworks,
|
|
25
|
-
genbounty: options.
|
|
19
|
+
genbounty: { programId: options.programId },
|
|
26
20
|
}, options);
|
|
27
21
|
throw err;
|
|
28
22
|
}
|
|
29
|
-
const responseTime = Date.now() - start;
|
|
30
23
|
let extracted = { output: "" };
|
|
31
24
|
try {
|
|
32
25
|
extracted = options.extractOutput(result);
|
|
@@ -35,32 +28,27 @@ export async function wrapLlmCall(fn, params, options) {
|
|
|
35
28
|
// extractOutput threw — log what we have
|
|
36
29
|
}
|
|
37
30
|
const entry = {
|
|
38
|
-
timestamp: new Date(
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
39
32
|
function: options.functionName,
|
|
40
33
|
model: extracted.model,
|
|
41
34
|
input: { messages: options.messages, endpoint: options.endpoint },
|
|
42
35
|
output: extracted.output ?? "",
|
|
43
|
-
promptTokens: extracted.promptTokens,
|
|
44
|
-
completionTokens: extracted.completionTokens,
|
|
45
|
-
totalTokens: extracted.totalTokens,
|
|
46
|
-
responseTime,
|
|
47
36
|
endpoint: options.endpoint,
|
|
48
|
-
status,
|
|
49
37
|
framework: options.frameworks,
|
|
50
|
-
genbounty: options.
|
|
38
|
+
genbounty: { programId: options.programId },
|
|
51
39
|
};
|
|
52
40
|
_fireAssess(entry, options);
|
|
53
41
|
return result;
|
|
54
42
|
}
|
|
55
43
|
/**
|
|
56
44
|
* Drop-in wrapper for `openai.chat.completions.create()` (or any compatible API).
|
|
57
|
-
*
|
|
45
|
+
* Assessment runs fire-and-forget — your LLM call is never blocked or delayed.
|
|
58
46
|
*
|
|
59
47
|
* @example
|
|
60
48
|
* const response = await wrapOpenAI(
|
|
61
49
|
* (p) => openai.chat.completions.create(p),
|
|
62
50
|
* { model: "gpt-4o-mini", messages },
|
|
63
|
-
* { client, frameworks: ["eu-ai-act"
|
|
51
|
+
* { client, programId: "my-program", frameworks: ["eu-ai-act"] }
|
|
64
52
|
* );
|
|
65
53
|
*/
|
|
66
54
|
export async function wrapOpenAI(fn, params, options) {
|
|
@@ -72,19 +60,12 @@ export async function wrapOpenAI(fn, params, options) {
|
|
|
72
60
|
...options,
|
|
73
61
|
endpoint: options.endpoint ?? "/v1/chat/completions",
|
|
74
62
|
messages,
|
|
75
|
-
extractOutput: (res) => {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
output,
|
|
82
|
-
model: res.model ?? params.model,
|
|
83
|
-
promptTokens: res.usage?.prompt_tokens,
|
|
84
|
-
completionTokens: res.usage?.completion_tokens,
|
|
85
|
-
totalTokens: res.usage?.total_tokens,
|
|
86
|
-
};
|
|
87
|
-
},
|
|
63
|
+
extractOutput: (res) => ({
|
|
64
|
+
output: (typeof res.choices?.[0]?.message?.content === "string"
|
|
65
|
+
? res.choices[0].message.content
|
|
66
|
+
: null) ?? "",
|
|
67
|
+
model: res.model ?? params.model,
|
|
68
|
+
}),
|
|
88
69
|
});
|
|
89
70
|
}
|
|
90
71
|
// -------------------------------------------------------------------------
|
|
@@ -93,7 +74,7 @@ export async function wrapOpenAI(fn, params, options) {
|
|
|
93
74
|
function _fireAssess(entry, options) {
|
|
94
75
|
const onError = options.onAssessError ??
|
|
95
76
|
((err) => {
|
|
96
|
-
console.warn("[ailp
|
|
77
|
+
console.warn("[ailp] assess error (LLM call unaffected):", err);
|
|
97
78
|
});
|
|
98
79
|
options.client
|
|
99
80
|
.assess(entry)
|
package/dist/wrap.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wrap.js","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"wrap.js","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"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"}
|