lemon-model 1.2.0 → 1.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 +79 -0
- package/dist/esm/cores/index.js +11 -0
- package/dist/esm/cores/index.js.map +1 -0
- package/dist/esm/cores/transformer.js +91 -0
- package/dist/esm/cores/transformer.js.map +1 -0
- package/dist/esm/genai/dump-test.js +196 -0
- package/dist/esm/genai/dump-test.js.map +1 -0
- package/dist/esm/genai/index.js +15 -0
- package/dist/esm/genai/index.js.map +1 -0
- package/dist/esm/genai/mocks.js +121 -0
- package/dist/esm/genai/mocks.js.map +1 -0
- package/dist/esm/genai/proxy.js +161 -0
- package/dist/esm/genai/proxy.js.map +1 -0
- package/dist/esm/genai/testing.js +12 -0
- package/dist/esm/genai/testing.js.map +1 -0
- package/dist/esm/genai/transport.js +131 -0
- package/dist/esm/genai/transport.js.map +1 -0
- package/dist/esm/genai/types.js +9 -0
- package/dist/esm/genai/types.js.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/package.json +3 -0
- package/dist/esm/socket/index.js +13 -0
- package/dist/esm/socket/index.js.map +1 -0
- package/dist/esm/socket/socket.js +833 -0
- package/dist/esm/socket/socket.js.map +1 -0
- package/dist/esm/socket/testing.js +12 -0
- package/dist/esm/socket/testing.js.map +1 -0
- package/dist/esm/socket/transport.js +603 -0
- package/dist/esm/socket/transport.js.map +1 -0
- package/dist/esm/socket/types.js +8 -0
- package/dist/esm/socket/types.js.map +1 -0
- package/dist/esm/socket/websocket.js +267 -0
- package/dist/esm/socket/websocket.js.map +1 -0
- package/dist/esm/types/core-storage.js +30 -0
- package/dist/esm/types/core-storage.js.map +1 -0
- package/dist/esm/types/core-types.js +17 -0
- package/dist/esm/types/core-types.js.map +1 -0
- package/dist/esm/types/index.js +13 -0
- package/dist/esm/types/index.js.map +1 -0
- package/dist/genai/index.js +1 -1
- package/dist/genai/index.js.map +1 -1
- package/dist/genai/testing.d.ts +1 -1
- package/dist/genai/testing.js +1 -1
- package/dist/socket/index.js +1 -1
- package/dist/socket/index.js.map +1 -1
- package/dist/socket/testing.d.ts +1 -1
- package/dist/socket/testing.js +1 -1
- package/package.json +26 -2
package/README.md
CHANGED
|
@@ -11,6 +11,85 @@ Common shared model definitions for both `backend` and `frontend`.
|
|
|
11
11
|
npm install --save lemon-model
|
|
12
12
|
```
|
|
13
13
|
|
|
14
|
+
Backend API services that need the full Lemon runtime should use `lemon-core`.
|
|
15
|
+
|
|
16
|
+
## Import
|
|
17
|
+
|
|
18
|
+
```ts
|
|
19
|
+
import type { NextContext } from 'lemon-model';
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```js
|
|
23
|
+
const { HttpAbstractGenAI } = require('lemon-model');
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Frontend bundlers use the ESM build. Existing Node `require()` consumers use the CommonJS build.
|
|
27
|
+
|
|
28
|
+
## Package Map
|
|
29
|
+
|
|
30
|
+
| Area | Responsibility | Detail Doc |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| `types` | Shared request, identity, storage, and service shapes | Source types |
|
|
33
|
+
| `cores` | Small shared transform helpers | Source tests |
|
|
34
|
+
| `socket` | Peer socket, network contract, WebSocket bridge, JSON chunk transport | `src/socket/README.md` |
|
|
35
|
+
| `genai` | Gemini-like `generateContent()` adapter over Lemon agents APIs | `src/genai/README.md` |
|
|
36
|
+
| `samples` | Real usage cases and PR-ready sample notes | `samples/README.md` |
|
|
37
|
+
|
|
38
|
+
## User Sequence
|
|
39
|
+
|
|
40
|
+
```mermaid
|
|
41
|
+
sequenceDiagram
|
|
42
|
+
participant App as App or service
|
|
43
|
+
participant Package as lemon-model
|
|
44
|
+
participant TS as TypeScript
|
|
45
|
+
participant Runtime
|
|
46
|
+
|
|
47
|
+
App->>Package: Install package
|
|
48
|
+
App->>Package: Import selected type or helper
|
|
49
|
+
Package-->>TS: Shared declarations
|
|
50
|
+
TS-->>App: Contract check
|
|
51
|
+
App->>Runtime: Run selected helper
|
|
52
|
+
Runtime-->>App: Typed result
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
1. App installs `lemon-model`
|
|
56
|
+
2. App imports only the needed type or helper
|
|
57
|
+
3. TypeScript checks shared contracts
|
|
58
|
+
4. Runtime loads CJS or ESM build
|
|
59
|
+
5. Selected module handles its own job
|
|
60
|
+
6. Module README owns detailed behavior
|
|
61
|
+
|
|
62
|
+
## Choosing A Module
|
|
63
|
+
|
|
64
|
+
```mermaid
|
|
65
|
+
flowchart TD
|
|
66
|
+
A[Need shared code] --> B{Need runtime behavior}
|
|
67
|
+
B -- No --> C[Use types]
|
|
68
|
+
B -- Yes --> D{Which behavior}
|
|
69
|
+
D -- Data transforms --> E[Use cores]
|
|
70
|
+
D -- Socket or network test --> F[Use socket]
|
|
71
|
+
D -- Agents generateContent --> G[Use genai]
|
|
72
|
+
F --> H[Read src/socket/README.md]
|
|
73
|
+
G --> I[Read src/genai/README.md]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Main branch: type-only, transform helper, socket flow, or GenAI proxy.
|
|
77
|
+
|
|
78
|
+
## Build Formats
|
|
79
|
+
|
|
80
|
+
- CommonJS entry: `dist/index.js`
|
|
81
|
+
- ESM entry: `dist/esm/index.js`
|
|
82
|
+
- Type declarations: `dist/index.d.ts`
|
|
83
|
+
- Package export: `import { ... } from 'lemon-model'`
|
|
84
|
+
- Test helper exports: `lemon-model/genai/testing`, `lemon-model/socket/testing`
|
|
85
|
+
|
|
86
|
+
## Module Docs
|
|
87
|
+
|
|
88
|
+
- `src/socket/README.md`: peer socket and network contract
|
|
89
|
+
- `src/socket/JSON_TRANSPORT_SPEC.md`: JSON chunk transport protocol
|
|
90
|
+
- `src/genai/README.md`: GenAI adapter contract
|
|
91
|
+
- `samples/README.md`: sample case rules
|
|
92
|
+
|
|
14
93
|
## Contribution
|
|
15
94
|
|
|
16
95
|
Plz, request PR.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `index.ts`
|
|
3
|
+
* - main index
|
|
4
|
+
*
|
|
5
|
+
* @author Steve Jung <steve@lemoncloud.io>
|
|
6
|
+
* @date 2023-01-19 initial version
|
|
7
|
+
*
|
|
8
|
+
* @copyright (C) lemoncloud.io 2023 - All Rights Reserved.
|
|
9
|
+
*/
|
|
10
|
+
export * from './transformer.js';
|
|
11
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cores/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,cAAc,eAAe,CAAC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* type: `AbstractTransformer`
|
|
3
|
+
* - common base class of `Transformable`
|
|
4
|
+
*/
|
|
5
|
+
export class AbstractTransformer {
|
|
6
|
+
constructor() {
|
|
7
|
+
/**
|
|
8
|
+
* check in date: YYYY-MM-DD
|
|
9
|
+
*
|
|
10
|
+
* @param val string
|
|
11
|
+
* @param field (optional) target field name to use
|
|
12
|
+
*/
|
|
13
|
+
this.asDate = (val, field = 'date') => {
|
|
14
|
+
if (!val || typeof val !== 'string')
|
|
15
|
+
return '';
|
|
16
|
+
const re = /^[12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$/;
|
|
17
|
+
if (!re.test(val))
|
|
18
|
+
throw new Error(`.${field}[${val}] is invalid format - asDate()`);
|
|
19
|
+
return val;
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* extract only the defined attribute.
|
|
23
|
+
* ex) `{ a:1, b: undefined }` -> `{ a:1 }`
|
|
24
|
+
*/
|
|
25
|
+
this.onlyDefined = (N) => N === undefined || N === null
|
|
26
|
+
? N
|
|
27
|
+
: N && typeof N === 'object'
|
|
28
|
+
? Object.entries(N).reduce((N, [k, v]) => {
|
|
29
|
+
if (v !== undefined)
|
|
30
|
+
N[k] = v;
|
|
31
|
+
return N;
|
|
32
|
+
}, {})
|
|
33
|
+
: null;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* transform the cores data
|
|
37
|
+
* @param cores the cores data to transform
|
|
38
|
+
* @returns transformed cores data or null
|
|
39
|
+
*/
|
|
40
|
+
asCore(cores) {
|
|
41
|
+
if (!cores || typeof cores !== 'object')
|
|
42
|
+
return null;
|
|
43
|
+
const ret = {};
|
|
44
|
+
if (cores.sid !== undefined)
|
|
45
|
+
ret.sid = String(cores.sid);
|
|
46
|
+
if (cores.gid !== undefined)
|
|
47
|
+
ret.gid = String(cores.gid);
|
|
48
|
+
if (cores.uid !== undefined)
|
|
49
|
+
ret.uid = String(cores.uid);
|
|
50
|
+
return this.onlyDefined(ret);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* transform from model to view
|
|
54
|
+
*
|
|
55
|
+
* @see Transformable.modelAsView
|
|
56
|
+
*/
|
|
57
|
+
modelAsView(model, hasCores) {
|
|
58
|
+
var _a;
|
|
59
|
+
if (!model || typeof model !== 'object')
|
|
60
|
+
return null;
|
|
61
|
+
const view = this.onlyDefined({
|
|
62
|
+
$: (_a = model === null || model === void 0 ? void 0 : model.$) !== null && _a !== void 0 ? _a : undefined,
|
|
63
|
+
id: model.id,
|
|
64
|
+
createdAt: model.createdAt,
|
|
65
|
+
updatedAt: model.updatedAt,
|
|
66
|
+
deletedAt: model.deletedAt,
|
|
67
|
+
});
|
|
68
|
+
if (model.error)
|
|
69
|
+
view.error = model.error;
|
|
70
|
+
if (hasCores) {
|
|
71
|
+
const $ = this.asCore(model);
|
|
72
|
+
Object.assign(view, { $ });
|
|
73
|
+
}
|
|
74
|
+
return this.onlyDefined(view);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* transform from body(req-body) to model
|
|
78
|
+
*
|
|
79
|
+
* @see Transformable.bodyToModel
|
|
80
|
+
*/
|
|
81
|
+
bodyToModel(body, isCreate) {
|
|
82
|
+
var _a;
|
|
83
|
+
if (!body || typeof body !== 'object')
|
|
84
|
+
return null;
|
|
85
|
+
const model = {};
|
|
86
|
+
if ((body === null || body === void 0 ? void 0 : body.id) !== undefined)
|
|
87
|
+
model.id = `${(_a = body.id) !== null && _a !== void 0 ? _a : ''}`;
|
|
88
|
+
return model;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=transformer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transformer.js","sourceRoot":"","sources":["../../../src/cores/transformer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* `genai/dump-test.ts`
|
|
12
|
+
* - Browser-facing diagnostic loop for WebSocket transport generate dumps.
|
|
13
|
+
* - upstream exposed this as `BrowserWebSocketNetwork.dumpTest()`; here the bridge lives in the
|
|
14
|
+
* shared socket core, so use the standalone `browserWebSocketDumpTest()` instead.
|
|
15
|
+
*
|
|
16
|
+
* @origin eureka-agents-api / src/lib/proxy/dump-test.ts
|
|
17
|
+
* @copyright (C) 2026 LemonCloud Co Ltd. - All Rights Reserved.
|
|
18
|
+
*/
|
|
19
|
+
import { BrowserWebSocketNetwork, waitWebSocketConnectionId } from '../socket/websocket.js';
|
|
20
|
+
import { createProxyTransportReceiver } from './transport.js';
|
|
21
|
+
/**
|
|
22
|
+
* End-to-end browser diagnostic for generate transport.
|
|
23
|
+
*
|
|
24
|
+
* It discovers the WebSocket connection id, sends an inline-image `/dump`
|
|
25
|
+
* request, waits for the JSONTransport response, and returns checks that a UI
|
|
26
|
+
* can display directly.
|
|
27
|
+
*/
|
|
28
|
+
export const browserWebSocketDumpTest = (options = {}) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z;
|
|
30
|
+
const started = Date.now();
|
|
31
|
+
const startedAt = new Date(started).toISOString();
|
|
32
|
+
const logs = [];
|
|
33
|
+
const log = (level, event, data) => {
|
|
34
|
+
var _a;
|
|
35
|
+
const entry = {
|
|
36
|
+
time: new Date().toISOString(),
|
|
37
|
+
level,
|
|
38
|
+
event,
|
|
39
|
+
data,
|
|
40
|
+
};
|
|
41
|
+
logs.push(entry);
|
|
42
|
+
(_a = options.log) === null || _a === void 0 ? void 0 : _a.call(options, entry);
|
|
43
|
+
};
|
|
44
|
+
const endpoint = (_a = options.endpoint) !== null && _a !== void 0 ? _a : 'http://localhost:8830/agents/!/generate';
|
|
45
|
+
const timeoutMs = (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 30000;
|
|
46
|
+
const model = (_c = options.model) !== null && _c !== void 0 ? _c : 'gemini-3.1-flash-image-preview';
|
|
47
|
+
const prompt = (_d = options.prompt) !== null && _d !== void 0 ? _d : 'make a banner from this inline image';
|
|
48
|
+
const imageBase64 = (_e = options.imageBase64) !== null && _e !== void 0 ? _e : 'abcdefghijklmnopqrstuvwxyz0123456789-browser-websocket-dump-test';
|
|
49
|
+
const imageMimeType = (_f = options.imageMimeType) !== null && _f !== void 0 ? _f : 'image/jpeg';
|
|
50
|
+
const ws = (_g = options.ws) !== null && _g !== void 0 ? _g : createDefaultWebSocket((_h = options.wsUrl) !== null && _h !== void 0 ? _h : 'wss://wss.eureka.codes/cht-d1?v2');
|
|
51
|
+
const shouldClose = (_j = options.close) !== null && _j !== void 0 ? _j : !options.ws;
|
|
52
|
+
let network;
|
|
53
|
+
let receiver;
|
|
54
|
+
try {
|
|
55
|
+
log('info', 'dumpTest.connectionId.start', { endpoint });
|
|
56
|
+
const transportId = yield waitWebSocketConnectionId(ws, {
|
|
57
|
+
connectMessage: (_k = options.connectMessage) !== null && _k !== void 0 ? _k : 'device.save',
|
|
58
|
+
timeoutMs,
|
|
59
|
+
});
|
|
60
|
+
log('info', 'dumpTest.connectionId.ready', { transportId });
|
|
61
|
+
network = new BrowserWebSocketNetwork(ws);
|
|
62
|
+
yield network.ready();
|
|
63
|
+
receiver = createProxyTransportReceiver(network, { timeoutMs });
|
|
64
|
+
const url = withQuery(endpoint, { transportId });
|
|
65
|
+
const body = {
|
|
66
|
+
model,
|
|
67
|
+
prompt: {
|
|
68
|
+
type: 'user',
|
|
69
|
+
content: {
|
|
70
|
+
parts: [
|
|
71
|
+
{
|
|
72
|
+
inlineData: {
|
|
73
|
+
data: imageBase64,
|
|
74
|
+
mimeType: imageMimeType,
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
text: prompt,
|
|
79
|
+
},
|
|
80
|
+
],
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
system: '/dump',
|
|
84
|
+
image: true,
|
|
85
|
+
config: {
|
|
86
|
+
responseModalities: ['IMAGE', 'TEXT'],
|
|
87
|
+
},
|
|
88
|
+
};
|
|
89
|
+
let ack;
|
|
90
|
+
log('info', 'dumpTest.fetch.start', { url, model, imageMimeType, imageBase64Length: imageBase64.length });
|
|
91
|
+
const response = yield receiver.wait(transportId, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
92
|
+
var _0, _1, _2;
|
|
93
|
+
const fetcher = (_0 = options.fetch) !== null && _0 !== void 0 ? _0 : globalThis.fetch;
|
|
94
|
+
const http = yield callFetch(fetcher, url, {
|
|
95
|
+
method: 'POST',
|
|
96
|
+
headers: Object.assign({ 'content-type': 'application/json' }, ((_1 = options.headers) !== null && _1 !== void 0 ? _1 : {})),
|
|
97
|
+
body: JSON.stringify(body),
|
|
98
|
+
});
|
|
99
|
+
const text = yield http.text();
|
|
100
|
+
ack = (_2 = tryParseJSON(text)) !== null && _2 !== void 0 ? _2 : text;
|
|
101
|
+
if (!http.ok)
|
|
102
|
+
throw new Error(`HTTP ${http.status} ${http.statusText}`.trim() + (text ? ` - ${text}` : ''));
|
|
103
|
+
log('info', 'dumpTest.fetch.ack', {
|
|
104
|
+
status: http.status,
|
|
105
|
+
transport: !!(ack === null || ack === void 0 ? void 0 : ack.transport),
|
|
106
|
+
transportId: ack === null || ack === void 0 ? void 0 : ack.transportId,
|
|
107
|
+
});
|
|
108
|
+
return ack;
|
|
109
|
+
}));
|
|
110
|
+
const outputText = asGenAIOutputText(response);
|
|
111
|
+
const dumped = outputText ? tryParseJSON(outputText) : undefined;
|
|
112
|
+
const checks = {
|
|
113
|
+
ackTransport: !!(ack === null || ack === void 0 ? void 0 : ack.transport),
|
|
114
|
+
hasOutputText: typeof outputText === 'string' && outputText.length > 0,
|
|
115
|
+
dumpParsed: !!dumped,
|
|
116
|
+
modelMatches: (dumped === null || dumped === void 0 ? void 0 : dumped.model) === model,
|
|
117
|
+
inlineMimeTypeMatches: ((_p = (_o = (_m = (_l = dumped === null || dumped === void 0 ? void 0 : dumped.contents) === null || _l === void 0 ? void 0 : _l.parts) === null || _m === void 0 ? void 0 : _m[0]) === null || _o === void 0 ? void 0 : _o.inlineData) === null || _p === void 0 ? void 0 : _p.mimeType) === imageMimeType,
|
|
118
|
+
inlineDataTruncated: ((_t = (_s = (_r = (_q = dumped === null || dumped === void 0 ? void 0 : dumped.contents) === null || _q === void 0 ? void 0 : _q.parts) === null || _r === void 0 ? void 0 : _r[0]) === null || _s === void 0 ? void 0 : _s.inlineData) === null || _t === void 0 ? void 0 : _t.data) === imageBase64.substring(0, 36),
|
|
119
|
+
promptTextMatches: ((_w = (_v = (_u = dumped === null || dumped === void 0 ? void 0 : dumped.contents) === null || _u === void 0 ? void 0 : _u.parts) === null || _v === void 0 ? void 0 : _v[1]) === null || _w === void 0 ? void 0 : _w.text) === prompt,
|
|
120
|
+
imageRequestMarked: ((_x = dumped === null || dumped === void 0 ? void 0 : dumped.$param) === null || _x === void 0 ? void 0 : _x.isImage) === true,
|
|
121
|
+
responseModalitiesKept: JSON.stringify((_z = (_y = dumped === null || dumped === void 0 ? void 0 : dumped.$param) === null || _y === void 0 ? void 0 : _y.config) === null || _z === void 0 ? void 0 : _z.responseModalities) === JSON.stringify(['IMAGE', 'TEXT']),
|
|
122
|
+
};
|
|
123
|
+
const ok = Object.values(checks).every(Boolean);
|
|
124
|
+
const finished = Date.now();
|
|
125
|
+
const result = {
|
|
126
|
+
ok,
|
|
127
|
+
startedAt,
|
|
128
|
+
finishedAt: new Date(finished).toISOString(),
|
|
129
|
+
durationMs: finished - started,
|
|
130
|
+
endpoint,
|
|
131
|
+
transportId,
|
|
132
|
+
request: { url, body },
|
|
133
|
+
ack,
|
|
134
|
+
response,
|
|
135
|
+
dumped,
|
|
136
|
+
checks,
|
|
137
|
+
logs,
|
|
138
|
+
};
|
|
139
|
+
log(ok ? 'info' : 'error', 'dumpTest.done', { ok, checks });
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
log('error', 'dumpTest.failed', { error: normalizeError(error) });
|
|
144
|
+
throw error;
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
receiver === null || receiver === void 0 ? void 0 : receiver.detach();
|
|
148
|
+
network === null || network === void 0 ? void 0 : network.detach();
|
|
149
|
+
if (shouldClose && typeof ws.close === 'function')
|
|
150
|
+
ws.close();
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const createDefaultWebSocket = (url) => {
|
|
154
|
+
const WebSocketCtor = globalThis.WebSocket;
|
|
155
|
+
if (!WebSocketCtor)
|
|
156
|
+
throw new Error(`global WebSocket is not available - browserWebSocketDumpTest`);
|
|
157
|
+
return new WebSocketCtor(url);
|
|
158
|
+
};
|
|
159
|
+
const withQuery = (endpoint, params) => {
|
|
160
|
+
const url = new URL(endpoint, 'http://localhost');
|
|
161
|
+
for (const [key, value] of Object.entries(params))
|
|
162
|
+
url.searchParams.set(key, value);
|
|
163
|
+
if (/^https?:\/\//.test(endpoint))
|
|
164
|
+
return url.toString();
|
|
165
|
+
return `${url.pathname}${url.search}${url.hash}`;
|
|
166
|
+
};
|
|
167
|
+
const callFetch = (fetcher, input, init) => fetcher.call(globalThis, input, init);
|
|
168
|
+
const asGenAIOutputText = (response) => {
|
|
169
|
+
var _a;
|
|
170
|
+
const content = (_a = response === null || response === void 0 ? void 0 : response.output) === null || _a === void 0 ? void 0 : _a.content;
|
|
171
|
+
if (typeof content === 'string')
|
|
172
|
+
return content;
|
|
173
|
+
const data = content && typeof content === 'object' ? content.data : undefined;
|
|
174
|
+
return typeof data === 'string' ? data : undefined;
|
|
175
|
+
};
|
|
176
|
+
const tryParseJSON = (text) => {
|
|
177
|
+
try {
|
|
178
|
+
return JSON.parse(text);
|
|
179
|
+
}
|
|
180
|
+
catch (_a) {
|
|
181
|
+
return undefined;
|
|
182
|
+
}
|
|
183
|
+
};
|
|
184
|
+
const normalizeError = (error) => {
|
|
185
|
+
if (error instanceof Error)
|
|
186
|
+
return error.message;
|
|
187
|
+
if (typeof error === 'string')
|
|
188
|
+
return error;
|
|
189
|
+
try {
|
|
190
|
+
return JSON.stringify(error);
|
|
191
|
+
}
|
|
192
|
+
catch (_a) {
|
|
193
|
+
return String(error);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
//# sourceMappingURL=dump-test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dump-test.js","sourceRoot":"","sources":["../../../src/genai/dump-test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `genai/index.ts`
|
|
3
|
+
* - shared GenAI proxy adapter (Gemini-compatible surface over HTTP + JSONTransport) for F/B usage.
|
|
4
|
+
*
|
|
5
|
+
* @origin eureka-agents-api / src/lib/proxy/index.ts
|
|
6
|
+
* @copyright (C) 2026 LemonCloud Co Ltd. - All Rights Reserved.
|
|
7
|
+
*/
|
|
8
|
+
export * from './types.js';
|
|
9
|
+
export * from './proxy.js';
|
|
10
|
+
export * from './transport.js';
|
|
11
|
+
export * from './dump-test.js';
|
|
12
|
+
//! NOTE: test helpers (`./mocks`) are intentionally NOT re-exported here.
|
|
13
|
+
//! Import them via the isolated `lemon-model/genai/testing` entry so
|
|
14
|
+
//! production (esp. frontend) bundles do not pull in test-only helpers.
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/genai/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,cAAc,SAAS,CAAC;AACxB,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAE5B,0EAA0E;AAC1E,qEAAqE;AACrE,wEAAwE"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `genai/mocks.ts`
|
|
3
|
+
* - Test helpers for exercising `HttpAbstractGenAI` without a live agents API.
|
|
4
|
+
* - `createAgentGenerateFetcher()` routes fetch calls into a controller-like object, and
|
|
5
|
+
* `MockAgentGenerateController` emulates the `/agents/!/generate` `/dump` + transport contract
|
|
6
|
+
* that `eureka-agents-api`'s `AgentAPIController.doPostGenerate()` provides.
|
|
7
|
+
*
|
|
8
|
+
* @origin eureka-agents-api / src/lib/proxy/mocks.ts (+ `/dump` contract distilled from `AgentAPIController` for F/B-neutral tests)
|
|
9
|
+
* @copyright (C) 2026 LemonCloud Co Ltd. - All Rights Reserved.
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Create a `fetch` implementation that routes `/agents/:id/generate` calls
|
|
22
|
+
* directly into a controller instance.
|
|
23
|
+
*/
|
|
24
|
+
export const createAgentGenerateFetcher = (api, ctx) => ((url, init) => __awaiter(void 0, void 0, void 0, function* () {
|
|
25
|
+
const href = typeof url === 'string' || url instanceof URL ? `${url}` : url.url;
|
|
26
|
+
const parsed = new URL(href, 'http://localhost');
|
|
27
|
+
const matched = parsed.pathname.match(/^\/agents\/(.+)\/generate$/);
|
|
28
|
+
if (!matched) {
|
|
29
|
+
return {
|
|
30
|
+
ok: false,
|
|
31
|
+
status: 404,
|
|
32
|
+
statusText: 'Not Found',
|
|
33
|
+
text: () => __awaiter(void 0, void 0, void 0, function* () { return `unsupported endpoint: ${parsed.pathname}`; }),
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const body = (init === null || init === void 0 ? void 0 : init.body) ? JSON.parse(`${init.body}`) : {};
|
|
37
|
+
try {
|
|
38
|
+
const data = yield api.doPostGenerate(decodeURIComponent(matched[1]), Object.fromEntries(parsed.searchParams.entries()), body, ctx);
|
|
39
|
+
return {
|
|
40
|
+
ok: true,
|
|
41
|
+
status: 200,
|
|
42
|
+
statusText: 'OK',
|
|
43
|
+
json: () => __awaiter(void 0, void 0, void 0, function* () { return data; }),
|
|
44
|
+
text: () => __awaiter(void 0, void 0, void 0, function* () { return JSON.stringify(data); }),
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
catch (e) {
|
|
48
|
+
const text = e instanceof Error ? e.message : `${e}`;
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
status: 500,
|
|
52
|
+
statusText: 'Internal Server Error',
|
|
53
|
+
text: () => __awaiter(void 0, void 0, void 0, function* () { return text; }),
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}));
|
|
57
|
+
const onlyDefined = (data) => Object.fromEntries(Object.entries(data).filter(([, value]) => value !== undefined));
|
|
58
|
+
/** truncate inlineData payloads to 36 chars like the upstream `/dump` echo */
|
|
59
|
+
const truncateInlineData = (contents) => {
|
|
60
|
+
if (!contents || typeof contents !== 'object')
|
|
61
|
+
return contents;
|
|
62
|
+
if (Array.isArray(contents))
|
|
63
|
+
return contents.map(truncateInlineData);
|
|
64
|
+
const parts = Array.isArray(contents.parts)
|
|
65
|
+
? contents.parts.map((part) => {
|
|
66
|
+
var _a;
|
|
67
|
+
return ((_a = part === null || part === void 0 ? void 0 : part.inlineData) === null || _a === void 0 ? void 0 : _a.data)
|
|
68
|
+
? Object.assign(Object.assign({}, part), { inlineData: Object.assign(Object.assign({}, part.inlineData), { data: `${part.inlineData.data}`.substring(0, 36) }) }) : part;
|
|
69
|
+
})
|
|
70
|
+
: undefined;
|
|
71
|
+
return parts ? Object.assign(Object.assign({}, contents), { parts }) : contents;
|
|
72
|
+
};
|
|
73
|
+
/** build the `/dump` echo payload from an agents generate request body */
|
|
74
|
+
export const asDumpedGenerateRequest = (body) => {
|
|
75
|
+
var _a;
|
|
76
|
+
const prompt = body === null || body === void 0 ? void 0 : body.prompt;
|
|
77
|
+
const contents = typeof prompt === 'string' ? prompt : truncateInlineData(prompt === null || prompt === void 0 ? void 0 : prompt.content);
|
|
78
|
+
const config0 = onlyDefined(Object.assign(Object.assign({}, ((_a = body === null || body === void 0 ? void 0 : body.config) !== null && _a !== void 0 ? _a : {})), { systemInstruction: body === null || body === void 0 ? void 0 : body.system }));
|
|
79
|
+
const config = Object.keys(config0).length > 0 ? config0 : undefined;
|
|
80
|
+
const $param = onlyDefined({
|
|
81
|
+
model: body === null || body === void 0 ? void 0 : body.model,
|
|
82
|
+
isImage: (body === null || body === void 0 ? void 0 : body.image) === true ? true : undefined,
|
|
83
|
+
config: body === null || body === void 0 ? void 0 : body.config,
|
|
84
|
+
});
|
|
85
|
+
return onlyDefined({ model: body === null || body === void 0 ? void 0 : body.model, contents, config, $param });
|
|
86
|
+
};
|
|
87
|
+
/**
|
|
88
|
+
* In-memory stand-in for `AgentAPIController.doPostGenerate()` covering the `/dump` contract:
|
|
89
|
+
* - without `transportId`, it answers the dumped request as `output.content` JSON.
|
|
90
|
+
* - with `transportId`, it delivers the payload via `sendTransport()` and answers a transport ack.
|
|
91
|
+
*/
|
|
92
|
+
export class MockAgentGenerateController {
|
|
93
|
+
constructor(options = {}) {
|
|
94
|
+
this.options = options;
|
|
95
|
+
}
|
|
96
|
+
doPostGenerate(id, param, body, _ctx) {
|
|
97
|
+
var _a, _b;
|
|
98
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
99
|
+
if (!id)
|
|
100
|
+
throw new Error(`@id (string) is required - mocks.doPostGenerate`);
|
|
101
|
+
const model = body === null || body === void 0 ? void 0 : body.model;
|
|
102
|
+
const dumped = asDumpedGenerateRequest(body);
|
|
103
|
+
const $final = { output: { content: JSON.stringify(dumped) }, model };
|
|
104
|
+
const transportId = typeof (param === null || param === void 0 ? void 0 : param.transportId) === 'string' ? param.transportId : '';
|
|
105
|
+
if (!transportId)
|
|
106
|
+
return $final;
|
|
107
|
+
const sender = this.options.sendTransport;
|
|
108
|
+
if (!sender)
|
|
109
|
+
throw new Error(`.sendTransport is required when transportId is set - MockAgentGenerateController`);
|
|
110
|
+
const transport = yield sender(transportId, $final);
|
|
111
|
+
return onlyDefined({
|
|
112
|
+
transport: true,
|
|
113
|
+
transportId,
|
|
114
|
+
sent: (_a = transport.result) !== null && _a !== void 0 ? _a : true,
|
|
115
|
+
packets: (_b = transport.packets) !== null && _b !== void 0 ? _b : 1,
|
|
116
|
+
model,
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=mocks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mocks.js","sourceRoot":"","sources":["../../../src/genai/mocks.ts"],"names":[],"mappings":"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"}
|