@xemahq/llm-client-nest 0.1.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/LICENSE +176 -0
- package/README.md +105 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +70 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/dialect.d.ts +15 -0
- package/dist/lib/dialect.d.ts.map +1 -0
- package/dist/lib/dialect.js +63 -0
- package/dist/lib/dialect.js.map +1 -0
- package/dist/lib/errors.d.ts +23 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +47 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/gateway-session-minter.d.ts +20 -0
- package/dist/lib/gateway-session-minter.d.ts.map +1 -0
- package/dist/lib/gateway-session-minter.js +112 -0
- package/dist/lib/gateway-session-minter.js.map +1 -0
- package/dist/lib/gen-ai.d.ts +45 -0
- package/dist/lib/gen-ai.d.ts.map +1 -0
- package/dist/lib/gen-ai.js +126 -0
- package/dist/lib/gen-ai.js.map +1 -0
- package/dist/lib/json-readers.d.ts +6 -0
- package/dist/lib/json-readers.d.ts.map +1 -0
- package/dist/lib/json-readers.js +32 -0
- package/dist/lib/json-readers.js.map +1 -0
- package/dist/lib/llm-client.d.ts +46 -0
- package/dist/lib/llm-client.d.ts.map +1 -0
- package/dist/lib/llm-client.js +341 -0
- package/dist/lib/llm-client.js.map +1 -0
- package/dist/lib/provider-address.d.ts +3 -0
- package/dist/lib/provider-address.d.ts.map +1 -0
- package/dist/lib/provider-address.js +18 -0
- package/dist/lib/provider-address.js.map +1 -0
- package/dist/lib/session-cache.d.ts +21 -0
- package/dist/lib/session-cache.d.ts.map +1 -0
- package/dist/lib/session-cache.js +65 -0
- package/dist/lib/session-cache.js.map +1 -0
- package/dist/lib/stream.d.ts +18 -0
- package/dist/lib/stream.d.ts.map +1 -0
- package/dist/lib/stream.js +185 -0
- package/dist/lib/stream.js.map +1 -0
- package/dist/lib/structured.d.ts +22 -0
- package/dist/lib/structured.d.ts.map +1 -0
- package/dist/lib/structured.js +62 -0
- package/dist/lib/structured.js.map +1 -0
- package/dist/lib/wire.d.ts +45 -0
- package/dist/lib/wire.d.ts.map +1 -0
- package/dist/lib/wire.js +7 -0
- package/dist/lib/wire.js.map +1 -0
- package/dist/nest/llm-client.module.d.ts +15 -0
- package/dist/nest/llm-client.module.d.ts.map +1 -0
- package/dist/nest/llm-client.module.js +61 -0
- package/dist/nest/llm-client.module.js.map +1 -0
- package/dist/nest/typed-client-mint-transport.d.ts +15 -0
- package/dist/nest/typed-client-mint-transport.d.ts.map +1 -0
- package/dist/nest/typed-client-mint-transport.js +32 -0
- package/dist/nest/typed-client-mint-transport.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sseDataLines = sseDataLines;
|
|
4
|
+
exports.accumulatorFor = accumulatorFor;
|
|
5
|
+
exports.chatStreamEvents = chatStreamEvents;
|
|
6
|
+
const dialect_1 = require("./dialect");
|
|
7
|
+
const errors_1 = require("./errors");
|
|
8
|
+
const json_readers_1 = require("./json-readers");
|
|
9
|
+
const OPENAI_DONE = '[DONE]';
|
|
10
|
+
async function* sseDataLines(body) {
|
|
11
|
+
const reader = body.getReader();
|
|
12
|
+
const decoder = new TextDecoder();
|
|
13
|
+
let buffer = '';
|
|
14
|
+
try {
|
|
15
|
+
for (;;) {
|
|
16
|
+
const chunk = await reader.read();
|
|
17
|
+
if (chunk.done === true) {
|
|
18
|
+
break;
|
|
19
|
+
}
|
|
20
|
+
buffer += decoder.decode(chunk.value, { stream: true });
|
|
21
|
+
for (;;) {
|
|
22
|
+
const newline = buffer.indexOf('\n');
|
|
23
|
+
if (newline === -1) {
|
|
24
|
+
break;
|
|
25
|
+
}
|
|
26
|
+
const line = buffer.slice(0, newline).replace(/\r$/, '');
|
|
27
|
+
buffer = buffer.slice(newline + 1);
|
|
28
|
+
if (line.startsWith('data:')) {
|
|
29
|
+
yield line.slice('data:'.length).trim();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const trailing = buffer.replace(/\r$/, '');
|
|
34
|
+
if (trailing.startsWith('data:')) {
|
|
35
|
+
yield trailing.slice('data:'.length).trim();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
finally {
|
|
39
|
+
await reader.cancel().catch(() => undefined);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function parsePayload(payload) {
|
|
43
|
+
let parsed;
|
|
44
|
+
try {
|
|
45
|
+
parsed = JSON.parse(payload);
|
|
46
|
+
}
|
|
47
|
+
catch (cause) {
|
|
48
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.GatewayResponseMalformed, 'The LLM gateway sent an SSE `data:` line that is not JSON.', { cause });
|
|
49
|
+
}
|
|
50
|
+
const record = (0, json_readers_1.asRecordOrUndefined)(parsed);
|
|
51
|
+
if (record === undefined) {
|
|
52
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.GatewayResponseMalformed, 'The LLM gateway sent an SSE event that is not a JSON object.');
|
|
53
|
+
}
|
|
54
|
+
return record;
|
|
55
|
+
}
|
|
56
|
+
function openAiAccumulator() {
|
|
57
|
+
let content = '';
|
|
58
|
+
let model;
|
|
59
|
+
let responseId;
|
|
60
|
+
let finishReason;
|
|
61
|
+
let usage = {};
|
|
62
|
+
return {
|
|
63
|
+
push(payload) {
|
|
64
|
+
if (payload === OPENAI_DONE) {
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
const chunk = parsePayload(payload);
|
|
68
|
+
model ??= (0, json_readers_1.stringOrUndefined)(chunk['model']);
|
|
69
|
+
responseId ??= (0, json_readers_1.stringOrUndefined)(chunk['id']);
|
|
70
|
+
const usageBlock = (0, json_readers_1.asRecordOrUndefined)(chunk['usage']);
|
|
71
|
+
if (usageBlock !== undefined) {
|
|
72
|
+
usage = {
|
|
73
|
+
inputTokens: (0, json_readers_1.numberOrUndefined)(usageBlock['prompt_tokens']),
|
|
74
|
+
outputTokens: (0, json_readers_1.numberOrUndefined)(usageBlock['completion_tokens']),
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
const choices = chunk['choices'];
|
|
78
|
+
const choice = Array.isArray(choices)
|
|
79
|
+
? (0, json_readers_1.asRecordOrUndefined)(choices[0])
|
|
80
|
+
: undefined;
|
|
81
|
+
if (choice === undefined) {
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
finishReason ??= (0, json_readers_1.stringOrUndefined)(choice['finish_reason']);
|
|
85
|
+
const text = (0, json_readers_1.stringOrUndefined)((0, json_readers_1.asRecordOrUndefined)(choice['delta'])?.['content']);
|
|
86
|
+
if (text === undefined || text === '') {
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
content += text;
|
|
90
|
+
return text;
|
|
91
|
+
},
|
|
92
|
+
finish() {
|
|
93
|
+
return { content, model, responseId, finishReason, usage };
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
function anthropicAccumulator() {
|
|
98
|
+
let content = '';
|
|
99
|
+
let model;
|
|
100
|
+
let responseId;
|
|
101
|
+
let finishReason;
|
|
102
|
+
let inputTokens;
|
|
103
|
+
let outputTokens;
|
|
104
|
+
return {
|
|
105
|
+
push(payload) {
|
|
106
|
+
const event = parsePayload(payload);
|
|
107
|
+
switch ((0, json_readers_1.stringOrUndefined)(event['type'])) {
|
|
108
|
+
case 'message_start': {
|
|
109
|
+
const message = (0, json_readers_1.asRecordOrUndefined)(event['message']);
|
|
110
|
+
model = (0, json_readers_1.stringOrUndefined)(message?.['model']);
|
|
111
|
+
responseId = (0, json_readers_1.stringOrUndefined)(message?.['id']);
|
|
112
|
+
inputTokens = (0, json_readers_1.numberOrUndefined)((0, json_readers_1.asRecordOrUndefined)(message?.['usage'])?.['input_tokens']);
|
|
113
|
+
return undefined;
|
|
114
|
+
}
|
|
115
|
+
case 'content_block_delta': {
|
|
116
|
+
const delta = (0, json_readers_1.asRecordOrUndefined)(event['delta']);
|
|
117
|
+
if ((0, json_readers_1.stringOrUndefined)(delta?.['type']) !== 'text_delta') {
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
const text = (0, json_readers_1.stringOrUndefined)(delta?.['text']);
|
|
121
|
+
if (text === undefined || text === '') {
|
|
122
|
+
return undefined;
|
|
123
|
+
}
|
|
124
|
+
content += text;
|
|
125
|
+
return text;
|
|
126
|
+
}
|
|
127
|
+
case 'message_delta': {
|
|
128
|
+
finishReason ??= (0, json_readers_1.stringOrUndefined)((0, json_readers_1.asRecordOrUndefined)(event['delta'])?.['stop_reason']);
|
|
129
|
+
outputTokens =
|
|
130
|
+
(0, json_readers_1.numberOrUndefined)((0, json_readers_1.asRecordOrUndefined)(event['usage'])?.['output_tokens']) ?? outputTokens;
|
|
131
|
+
return undefined;
|
|
132
|
+
}
|
|
133
|
+
case 'message_stop':
|
|
134
|
+
return null;
|
|
135
|
+
case 'error': {
|
|
136
|
+
const error = (0, json_readers_1.asRecordOrUndefined)(event['error']);
|
|
137
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.GatewayCallFailed, 'The provider reported an error mid-stream: ' +
|
|
138
|
+
((0, json_readers_1.stringOrUndefined)(error?.['message']) ?? 'no message given'));
|
|
139
|
+
}
|
|
140
|
+
default:
|
|
141
|
+
return undefined;
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
finish() {
|
|
145
|
+
return {
|
|
146
|
+
content,
|
|
147
|
+
model,
|
|
148
|
+
responseId,
|
|
149
|
+
finishReason,
|
|
150
|
+
usage: { inputTokens, outputTokens },
|
|
151
|
+
};
|
|
152
|
+
},
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
function accumulatorFor(dialect) {
|
|
156
|
+
switch (dialect) {
|
|
157
|
+
case dialect_1.GatewayDialect.AnthropicNative:
|
|
158
|
+
return anthropicAccumulator();
|
|
159
|
+
case dialect_1.GatewayDialect.OpenAiCompatible:
|
|
160
|
+
return openAiAccumulator();
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
async function* chatStreamEvents(dialect, body) {
|
|
164
|
+
const accumulator = accumulatorFor(dialect);
|
|
165
|
+
let sawSentinel = false;
|
|
166
|
+
for await (const payload of sseDataLines(body)) {
|
|
167
|
+
if (payload === '') {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
const text = accumulator.push(payload);
|
|
171
|
+
if (text === null) {
|
|
172
|
+
sawSentinel = true;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
if (text !== undefined) {
|
|
176
|
+
yield { kind: 'delta', text };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (!sawSentinel) {
|
|
180
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.GatewayResponseMalformed, 'The LLM gateway stream ended without its end-of-stream event; the ' +
|
|
181
|
+
'completion is truncated. Refusing to report a partial answer as whole.');
|
|
182
|
+
}
|
|
183
|
+
yield { kind: 'done', result: accumulator.finish() };
|
|
184
|
+
}
|
|
185
|
+
//# sourceMappingURL=stream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stream.js","sourceRoot":"","sources":["../../src/lib/stream.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { GatewayDialect } from './dialect';
|
|
2
|
+
export interface StructuredOutputSchema<T> {
|
|
3
|
+
toJSONSchema(options?: {
|
|
4
|
+
readonly io?: 'input' | 'output';
|
|
5
|
+
readonly unrepresentable?: 'throw' | 'any';
|
|
6
|
+
}): object;
|
|
7
|
+
safeParse(value: unknown): {
|
|
8
|
+
readonly success: true;
|
|
9
|
+
readonly data: T;
|
|
10
|
+
} | {
|
|
11
|
+
readonly success: false;
|
|
12
|
+
readonly error: unknown;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface StructuredOutputSpec<T> {
|
|
16
|
+
readonly name: string;
|
|
17
|
+
readonly schema: StructuredOutputSchema<T>;
|
|
18
|
+
}
|
|
19
|
+
export declare function structuredOutputJsonSchema<T>(spec: StructuredOutputSpec<T>): object;
|
|
20
|
+
export declare function structuredOutputBodyFields(dialect: GatewayDialect, spec: StructuredOutputSpec<unknown>, jsonSchema: object): Record<string, unknown>;
|
|
21
|
+
export declare function parseStructuredOutput<T>(spec: StructuredOutputSpec<T>, content: string): T;
|
|
22
|
+
//# sourceMappingURL=structured.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured.d.ts","sourceRoot":"","sources":["../../src/lib/structured.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AA0B3C,MAAM,WAAW,sBAAsB,CAAC,CAAC;IACvC,YAAY,CAAC,OAAO,CAAC,EAAE;QACrB,QAAQ,CAAC,EAAE,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;QACjC,QAAQ,CAAC,eAAe,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;KAC5C,GAAG,MAAM,CAAC;IACX,SAAS,CACP,KAAK,EAAE,OAAO,GAEZ;QAAE,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;KAAE,GAC5C;QAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;KAAE,CAAC;CAC1D;AAGD,MAAM,WAAW,oBAAoB,CAAC,CAAC;IAErC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC,CAAC,CAAC;CAC5C;AAeD,wBAAgB,0BAA0B,CAAC,CAAC,EAC1C,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAAC,GAC5B,MAAM,CAwCR;AAYD,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,cAAc,EACvB,IAAI,EAAE,oBAAoB,CAAC,OAAO,CAAC,EACnC,UAAU,EAAE,MAAM,GACjB,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAczB;AAUD,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,IAAI,EAAE,oBAAoB,CAAC,CAAC,CAAC,EAC7B,OAAO,EAAE,MAAM,GACd,CAAC,CAsBH"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.structuredOutputJsonSchema = structuredOutputJsonSchema;
|
|
4
|
+
exports.structuredOutputBodyFields = structuredOutputBodyFields;
|
|
5
|
+
exports.parseStructuredOutput = parseStructuredOutput;
|
|
6
|
+
const dialect_1 = require("./dialect");
|
|
7
|
+
const errors_1 = require("./errors");
|
|
8
|
+
function structuredOutputJsonSchema(spec) {
|
|
9
|
+
if (typeof spec.schema.toJSONSchema !== 'function') {
|
|
10
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.StructuredOutputUnrepresentable, `Structured output "${spec.name}" was given a schema with no ` +
|
|
11
|
+
'`toJSONSchema()`. A zod 4 schema has one; a validator that cannot ' +
|
|
12
|
+
'describe itself cannot constrain the model.');
|
|
13
|
+
}
|
|
14
|
+
let jsonSchema;
|
|
15
|
+
try {
|
|
16
|
+
jsonSchema = spec.schema.toJSONSchema({
|
|
17
|
+
io: 'input',
|
|
18
|
+
unrepresentable: 'throw',
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
catch (cause) {
|
|
22
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.StructuredOutputUnrepresentable, `Structured output "${spec.name}" has a schema that cannot be expressed ` +
|
|
23
|
+
'as JSON Schema, so the model cannot be constrained to it: ' +
|
|
24
|
+
(cause instanceof Error ? cause.message : String(cause)), { cause });
|
|
25
|
+
}
|
|
26
|
+
if (typeof jsonSchema !== 'object' || jsonSchema === null) {
|
|
27
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.StructuredOutputUnrepresentable, `Structured output "${spec.name}" produced a JSON Schema that is not an object.`);
|
|
28
|
+
}
|
|
29
|
+
return jsonSchema;
|
|
30
|
+
}
|
|
31
|
+
function structuredOutputBodyFields(dialect, spec, jsonSchema) {
|
|
32
|
+
switch (dialect) {
|
|
33
|
+
case dialect_1.GatewayDialect.AnthropicNative:
|
|
34
|
+
return {
|
|
35
|
+
output_config: { format: { type: 'json_schema', schema: jsonSchema } },
|
|
36
|
+
};
|
|
37
|
+
case dialect_1.GatewayDialect.OpenAiCompatible:
|
|
38
|
+
return {
|
|
39
|
+
response_format: {
|
|
40
|
+
type: 'json_schema',
|
|
41
|
+
json_schema: { name: spec.name, schema: jsonSchema, strict: true },
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
function parseStructuredOutput(spec, content) {
|
|
47
|
+
let parsed;
|
|
48
|
+
try {
|
|
49
|
+
parsed = JSON.parse(content);
|
|
50
|
+
}
|
|
51
|
+
catch (cause) {
|
|
52
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.StructuredOutputInvalid, `The model's answer for structured output "${spec.name}" is not JSON.`, { cause });
|
|
53
|
+
}
|
|
54
|
+
const verdict = spec.schema.safeParse(parsed);
|
|
55
|
+
if (!verdict.success) {
|
|
56
|
+
throw new errors_1.LlmClientError(errors_1.LlmClientFailure.StructuredOutputInvalid, `The model's answer for structured output "${spec.name}" did not satisfy ` +
|
|
57
|
+
'its schema. The provider was asked to enforce it, so this is a ' +
|
|
58
|
+
'provider or schema fault rather than a prompt to retry.', { cause: verdict.error });
|
|
59
|
+
}
|
|
60
|
+
return verdict.data;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=structured.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured.js","sourceRoot":"","sources":["../../src/lib/structured.ts"],"names":[],"mappings":";;AA0DA,gEA0CC;AAYD,gEAkBC;AAUD,sDAyBC;AArKD,uCAA2C;AAC3C,qCAA4D;AAyD5D,SAAgB,0BAA0B,CACxC,IAA6B;IAE7B,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,YAAY,KAAK,UAAU,EAAE,CAAC;QAKnD,MAAM,IAAI,uBAAc,CACtB,yBAAgB,CAAC,+BAA+B,EAChD,sBAAsB,IAAI,CAAC,IAAI,+BAA+B;YAC5D,oEAAoE;YACpE,6CAA6C,CAChD,CAAC;IACJ,CAAC;IAMD,IAAI,UAAmB,CAAC;IACxB,IAAI,CAAC;QACH,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;YACpC,EAAE,EAAE,OAAO;YACX,eAAe,EAAE,OAAO;SACzB,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,uBAAc,CACtB,yBAAgB,CAAC,+BAA+B,EAChD,sBAAsB,IAAI,CAAC,IAAI,0CAA0C;YACvE,4DAA4D;YAC5D,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAC1D,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,uBAAc,CACtB,yBAAgB,CAAC,+BAA+B,EAChD,sBAAsB,IAAI,CAAC,IAAI,iDAAiD,CACjF,CAAC;IACJ,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAYD,SAAgB,0BAA0B,CACxC,OAAuB,EACvB,IAAmC,EACnC,UAAkB;IAElB,QAAQ,OAAO,EAAE,CAAC;QAChB,KAAK,wBAAc,CAAC,eAAe;YACjC,OAAO;gBACL,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE;aACvE,CAAC;QACJ,KAAK,wBAAc,CAAC,gBAAgB;YAClC,OAAO;gBACL,eAAe,EAAE;oBACf,IAAI,EAAE,aAAa;oBACnB,WAAW,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,IAAI,EAAE;iBACnE;aACF,CAAC;IACN,CAAC;AACH,CAAC;AAUD,SAAgB,qBAAqB,CACnC,IAA6B,EAC7B,OAAe;IAEf,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,uBAAc,CACtB,yBAAgB,CAAC,uBAAuB,EACxC,6CAA6C,IAAI,CAAC,IAAI,gBAAgB,EACtE,EAAE,KAAK,EAAE,CACV,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC9C,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;QACrB,MAAM,IAAI,uBAAc,CACtB,yBAAgB,CAAC,uBAAuB,EACxC,6CAA6C,IAAI,CAAC,IAAI,oBAAoB;YACxE,iEAAiE;YACjE,yDAAyD,EAC3D,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CACzB,CAAC;IACJ,CAAC;IACD,OAAO,OAAO,CAAC,IAAI,CAAC;AACtB,CAAC"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { LlmCaller } from '@xemahq/contracts/llm-gateway';
|
|
2
|
+
import type { GroupCategory, ProviderTier } from '@xemahq/platform-common';
|
|
3
|
+
export interface GatewaySession {
|
|
4
|
+
readonly token: string;
|
|
5
|
+
readonly expiresIn: number;
|
|
6
|
+
readonly gatewayUrl: string;
|
|
7
|
+
readonly nativeProxyUrl: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ResolvedModel {
|
|
10
|
+
readonly modelId: string;
|
|
11
|
+
readonly providerSlug?: string | undefined;
|
|
12
|
+
readonly providerId?: string | undefined;
|
|
13
|
+
readonly providerName?: string | undefined;
|
|
14
|
+
readonly providerIsSystem?: boolean | undefined;
|
|
15
|
+
readonly apiType?: string | undefined;
|
|
16
|
+
readonly temperature?: number | undefined;
|
|
17
|
+
readonly reasoningEffort?: string | undefined;
|
|
18
|
+
}
|
|
19
|
+
export interface MintGatewaySessionInput {
|
|
20
|
+
readonly orgId: string;
|
|
21
|
+
readonly projectId?: string | undefined;
|
|
22
|
+
readonly userId: string;
|
|
23
|
+
readonly groupLabel: string;
|
|
24
|
+
readonly groupCategory: GroupCategory;
|
|
25
|
+
readonly caller: LlmCaller;
|
|
26
|
+
readonly metadata?: Readonly<Record<string, string>> | undefined;
|
|
27
|
+
readonly plugins?: readonly string[] | undefined;
|
|
28
|
+
readonly skipAudit?: boolean | undefined;
|
|
29
|
+
}
|
|
30
|
+
export interface CreateGatewayTokenBody {
|
|
31
|
+
readonly userId: string;
|
|
32
|
+
readonly providerId: string;
|
|
33
|
+
readonly modelId: string;
|
|
34
|
+
readonly providerTier: ProviderTier;
|
|
35
|
+
readonly groupLabel: string;
|
|
36
|
+
readonly groupCategory: GroupCategory;
|
|
37
|
+
readonly caller: LlmCaller;
|
|
38
|
+
readonly metadata?: Record<string, string> | undefined;
|
|
39
|
+
readonly plugins?: string[] | undefined;
|
|
40
|
+
readonly skipAudit?: boolean | undefined;
|
|
41
|
+
}
|
|
42
|
+
export declare const GATEWAY_TOKEN_MINT_PATH = "/internal/gateway-tokens";
|
|
43
|
+
export declare const ORG_HEADER = "X-Xema-Org-Id";
|
|
44
|
+
export declare const PROJECT_HEADER = "X-Project-Id";
|
|
45
|
+
//# sourceMappingURL=wire.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire.d.ts","sourceRoot":"","sources":["../../src/lib/wire.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,+BAA+B,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AAc3E,MAAM,WAAW,cAAc;IAO7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IAEvB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAE3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAYD,MAAM,WAAW,aAAa;IAE5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAKzB,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAE3C,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEzC,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAK3C,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAEhD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEtC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAe1C,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC/C;AAWD,MAAM,WAAW,uBAAuB;IACtC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAExC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAExB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAE5B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAE3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,SAAS,CAAC;IAEjE,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC;IAEjD,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1C;AAUD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IACpC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;IACvD,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC1C;AAGD,eAAO,MAAM,uBAAuB,6BAA6B,CAAC;AAGlE,eAAO,MAAM,UAAU,kBAAkB,CAAC;AAG1C,eAAO,MAAM,cAAc,iBAAiB,CAAC"}
|
package/dist/lib/wire.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PROJECT_HEADER = exports.ORG_HEADER = exports.GATEWAY_TOKEN_MINT_PATH = void 0;
|
|
4
|
+
exports.GATEWAY_TOKEN_MINT_PATH = '/internal/gateway-tokens';
|
|
5
|
+
exports.ORG_HEADER = 'X-Xema-Org-Id';
|
|
6
|
+
exports.PROJECT_HEADER = 'X-Project-Id';
|
|
7
|
+
//# sourceMappingURL=wire.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wire.js","sourceRoot":"","sources":["../../src/lib/wire.ts"],"names":[],"mappings":";;;AAiIa,QAAA,uBAAuB,GAAG,0BAA0B,CAAC;AAGrD,QAAA,UAAU,GAAG,eAAe,CAAC;AAG7B,QAAA,cAAc,GAAG,cAAc,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type DynamicModule, type FactoryProvider } from '@nestjs/common';
|
|
2
|
+
export interface LlmClientModuleOptions {
|
|
3
|
+
readonly realm: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LlmClientModuleAsyncOptions {
|
|
6
|
+
readonly imports?: DynamicModule['imports'];
|
|
7
|
+
readonly inject?: NonNullable<FactoryProvider['inject']>;
|
|
8
|
+
readonly useFactory: (...args: never[]) => LlmClientModuleOptions | Promise<LlmClientModuleOptions>;
|
|
9
|
+
}
|
|
10
|
+
export declare class LlmClientModule {
|
|
11
|
+
static forRoot(options: LlmClientModuleOptions): DynamicModule;
|
|
12
|
+
static forRootAsync(options: LlmClientModuleAsyncOptions): DynamicModule;
|
|
13
|
+
private static build;
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=llm-client.module.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-client.module.d.ts","sourceRoot":"","sources":["../../src/nest/llm-client.module.ts"],"names":[],"mappings":"AAAA,OAAO,EAAU,KAAK,aAAa,EAAE,KAAK,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAWlF,MAAM,WAAW,sBAAsB;IASrC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAGD,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;IACzD,QAAQ,CAAC,UAAU,EAAE,CACnB,GAAG,IAAI,EAAE,KAAK,EAAE,KACb,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAAC;CAC/D;AAkBD,qBACa,eAAe;WACZ,OAAO,CAAC,OAAO,EAAE,sBAAsB,GAAG,aAAa;WAMvD,YAAY,CACxB,OAAO,EAAE,2BAA2B,GACnC,aAAa;IAahB,OAAO,CAAC,MAAM,CAAC,KAAK;CAiCrB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var LlmClientModule_1;
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.LlmClientModule = void 0;
|
|
11
|
+
const common_1 = require("@nestjs/common");
|
|
12
|
+
const service_registry_1 = require("@xemahq/contracts/service-registry");
|
|
13
|
+
const service_registry_nest_1 = require("@xemahq/service-registry-nest");
|
|
14
|
+
const typed_client_mint_transport_1 = require("./typed-client-mint-transport");
|
|
15
|
+
const gateway_session_minter_1 = require("../lib/gateway-session-minter");
|
|
16
|
+
const llm_client_1 = require("../lib/llm-client");
|
|
17
|
+
const LLM_CLIENT_OPTIONS = Symbol.for('@xemahq/llm-client-nest/options');
|
|
18
|
+
let LlmClientModule = LlmClientModule_1 = class LlmClientModule {
|
|
19
|
+
static forRoot(options) {
|
|
20
|
+
return LlmClientModule_1.build([
|
|
21
|
+
{ provide: LLM_CLIENT_OPTIONS, useValue: options },
|
|
22
|
+
]);
|
|
23
|
+
}
|
|
24
|
+
static forRootAsync(options) {
|
|
25
|
+
return LlmClientModule_1.build([
|
|
26
|
+
{
|
|
27
|
+
provide: LLM_CLIENT_OPTIONS,
|
|
28
|
+
useFactory: options.useFactory,
|
|
29
|
+
inject: [...(options.inject ?? [])],
|
|
30
|
+
},
|
|
31
|
+
], options.imports);
|
|
32
|
+
}
|
|
33
|
+
static build(optionProviders, imports) {
|
|
34
|
+
return {
|
|
35
|
+
module: LlmClientModule_1,
|
|
36
|
+
...(imports === undefined ? {} : { imports }),
|
|
37
|
+
providers: [
|
|
38
|
+
...optionProviders,
|
|
39
|
+
{
|
|
40
|
+
provide: gateway_session_minter_1.GatewaySessionMinter,
|
|
41
|
+
useFactory: (client, options) => new gateway_session_minter_1.GatewaySessionMinter(new typed_client_mint_transport_1.TypedServiceClientMintTransport(client, options.realm)),
|
|
42
|
+
inject: [
|
|
43
|
+
(0, service_registry_nest_1.typedServiceClientToken)(service_registry_1.ServiceName.LLM_REGISTRY_API),
|
|
44
|
+
LLM_CLIENT_OPTIONS,
|
|
45
|
+
],
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
provide: llm_client_1.LlmClient,
|
|
49
|
+
useFactory: (minter) => new llm_client_1.LlmClient(minter),
|
|
50
|
+
inject: [gateway_session_minter_1.GatewaySessionMinter],
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
exports: [llm_client_1.LlmClient, gateway_session_minter_1.GatewaySessionMinter],
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
exports.LlmClientModule = LlmClientModule;
|
|
58
|
+
exports.LlmClientModule = LlmClientModule = LlmClientModule_1 = __decorate([
|
|
59
|
+
(0, common_1.Module)({})
|
|
60
|
+
], LlmClientModule);
|
|
61
|
+
//# sourceMappingURL=llm-client.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-client.module.js","sourceRoot":"","sources":["../../src/nest/llm-client.module.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,2CAAkF;AAClF,yEAAiE;AACjE,yEAAwE;AAExE,+EAAgF;AAChF,0EAAqE;AACrE,kDAA8C;AA0B9C,MAAM,kBAAkB,GAAG,MAAM,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;AAiBlE,IAAM,eAAe,uBAArB,MAAM,eAAe;IACnB,MAAM,CAAC,OAAO,CAAC,OAA+B;QACnD,OAAO,iBAAe,CAAC,KAAK,CAAC;YAC3B,EAAE,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,OAAO,EAAE;SACnD,CAAC,CAAC;IACL,CAAC;IAEM,MAAM,CAAC,YAAY,CACxB,OAAoC;QAEpC,OAAO,iBAAe,CAAC,KAAK,CAC1B;YACE;gBACE,OAAO,EAAE,kBAAkB;gBAC3B,UAAU,EAAE,OAAO,CAAC,UAAU;gBAC9B,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;aACpC;SACF,EACD,OAAO,CAAC,OAAO,CAChB,CAAC;IACJ,CAAC;IAEO,MAAM,CAAC,KAAK,CAClB,eAAwD,EACxD,OAAkC;QAElC,OAAO;YACL,MAAM,EAAE,iBAAe;YACvB,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC;YAC7C,SAAS,EAAE;gBACT,GAAG,eAAe;gBAClB;oBACE,OAAO,EAAE,6CAAoB;oBAC7B,UAAU,EAAE,CACV,MAA0B,EAC1B,OAA+B,EACT,EAAE,CACxB,IAAI,6CAAoB,CACtB,IAAI,6DAA+B,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,CAAC,CAC3D;oBACH,MAAM,EAAE;wBACN,IAAA,+CAAuB,EAAC,8BAAW,CAAC,gBAAgB,CAAC;wBACrD,kBAAkB;qBACnB;iBACF;gBACD;oBACE,OAAO,EAAE,sBAAS;oBAClB,UAAU,EAAE,CAAC,MAA4B,EAAa,EAAE,CACtD,IAAI,sBAAS,CAAC,MAAM,CAAC;oBACvB,MAAM,EAAE,CAAC,6CAAoB,CAAC;iBAC/B;aACF;YACD,OAAO,EAAE,CAAC,sBAAS,EAAE,6CAAoB,CAAC;SAC3C,CAAC;IACJ,CAAC;CACF,CAAA;AAvDY,0CAAe;0BAAf,eAAe;IAD3B,IAAA,eAAM,EAAC,EAAE,CAAC;GACE,eAAe,CAuD3B"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { GatewayMintTransport } from '../lib/gateway-session-minter';
|
|
2
|
+
import type { CreateGatewayTokenBody } from '../lib/wire';
|
|
3
|
+
import type { ExactScopedClaim, TypedServiceClient } from '@xemahq/service-registry-nest';
|
|
4
|
+
export declare class TypedServiceClientMintTransport implements GatewayMintTransport {
|
|
5
|
+
private readonly client;
|
|
6
|
+
private readonly realm;
|
|
7
|
+
constructor(client: TypedServiceClient, realm: string);
|
|
8
|
+
post(path: string, body: CreateGatewayTokenBody, context: {
|
|
9
|
+
readonly orgId: string;
|
|
10
|
+
readonly projectId?: string | undefined;
|
|
11
|
+
readonly headers: Readonly<Record<string, string>>;
|
|
12
|
+
}): Promise<unknown>;
|
|
13
|
+
}
|
|
14
|
+
export declare function orgScopedClaim(realm: string, orgId: string): ExactScopedClaim;
|
|
15
|
+
//# sourceMappingURL=typed-client-mint-transport.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-client-mint-transport.d.ts","sourceRoot":"","sources":["../../src/nest/typed-client-mint-transport.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAC;AAC1E,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EACnB,MAAM,+BAA+B,CAAC;AAqBvC,qBAAa,+BAAgC,YAAW,oBAAoB;IAExE,OAAO,CAAC,QAAQ,CAAC,MAAM;IAQvB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBARL,MAAM,EAAE,kBAAkB,EAQ1B,KAAK,EAAE,MAAM;IAGzB,IAAI,CACT,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,sBAAsB,EAC5B,OAAO,EAAE;QACP,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QACvB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QACxC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;KACpD,GACA,OAAO,CAAC,OAAO,CAAC;CAMpB;AAwBD,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,gBAAgB,CAI7E"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.TypedServiceClientMintTransport = void 0;
|
|
4
|
+
exports.orgScopedClaim = orgScopedClaim;
|
|
5
|
+
const platform_common_1 = require("@xemahq/platform-common");
|
|
6
|
+
class TypedServiceClientMintTransport {
|
|
7
|
+
client;
|
|
8
|
+
realm;
|
|
9
|
+
constructor(client, realm) {
|
|
10
|
+
this.client = client;
|
|
11
|
+
this.realm = realm;
|
|
12
|
+
}
|
|
13
|
+
post(path, body, context) {
|
|
14
|
+
return this.client.post(path, body, {
|
|
15
|
+
headers: { ...context.headers },
|
|
16
|
+
scopedClaim: orgScopedClaim(this.realm, context.orgId),
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.TypedServiceClientMintTransport = TypedServiceClientMintTransport;
|
|
21
|
+
function orgScopedClaim(realm, orgId) {
|
|
22
|
+
assertExact('realm', realm);
|
|
23
|
+
assertExact('orgId', orgId);
|
|
24
|
+
return { realm, claimName: platform_common_1.OrgClaimKey.Canonical, claimValue: orgId };
|
|
25
|
+
}
|
|
26
|
+
function assertExact(field, value) {
|
|
27
|
+
if (value.trim() === '' || value !== value.trim()) {
|
|
28
|
+
throw new Error(`[llm-client-nest] ${field} must be non-empty and must not have leading ` +
|
|
29
|
+
'or trailing whitespace.');
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=typed-client-mint-transport.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"typed-client-mint-transport.js","sourceRoot":"","sources":["../../src/nest/typed-client-mint-transport.ts"],"names":[],"mappings":";;;AA+EA,wCAIC;AAnFD,6DAAsD;AA4BtD,MAAa,+BAA+B;IAEvB;IAQA;IATnB,YACmB,MAA0B,EAQ1B,KAAa;QARb,WAAM,GAAN,MAAM,CAAoB;QAQ1B,UAAK,GAAL,KAAK,CAAQ;IAC7B,CAAC;IAEG,IAAI,CACT,IAAY,EACZ,IAA4B,EAC5B,OAIC;QAED,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAkC,IAAI,EAAE,IAAI,EAAE;YACnE,OAAO,EAAE,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE;YAC/B,WAAW,EAAE,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC;SACvD,CAAC,CAAC;IACL,CAAC;CACF;AA3BD,0EA2BC;AAwBD,SAAgB,cAAc,CAAC,KAAa,EAAE,KAAa;IACzD,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5B,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;IAC5B,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,6BAAW,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;AACxE,CAAC;AAED,SAAS,WAAW,CAAC,KAAa,EAAE,KAAa;IAC/C,IAAI,KAAK,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,KAAK,KAAK,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;QAClD,MAAM,IAAI,KAAK,CACb,qBAAqB,KAAK,+CAA+C;YACvE,yBAAyB,CAC5B,CAAC;IACJ,CAAC;AACH,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@xemahq/llm-client-nest",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The one way a Xema service calls a model: resolve the LLM gateway from the service registry, mint a short-lived sealed grant through llm-registry-api, call it, and emit the OpenTelemetry GenAI semantic conventions — once, instead of eleven times.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"xema",
|
|
7
|
+
"xema-platform",
|
|
8
|
+
"nestjs",
|
|
9
|
+
"llm",
|
|
10
|
+
"opentelemetry",
|
|
11
|
+
"gen-ai"
|
|
12
|
+
],
|
|
13
|
+
"license": "Apache-2.0",
|
|
14
|
+
"author": "Neuralchowder Inc. <developer@xema.dev> (https://xema.dev)",
|
|
15
|
+
"homepage": "https://docs.xema.dev/llm-client-nest",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/xema-dev/xema-kernel-sdk.git",
|
|
19
|
+
"directory": "packages/sdks/llm-client-nest"
|
|
20
|
+
},
|
|
21
|
+
"bugs": "https://github.com/xema-dev/xema-kernel-sdk/issues",
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public",
|
|
24
|
+
"registry": "https://registry.npmjs.org/"
|
|
25
|
+
},
|
|
26
|
+
"main": "dist/index.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"README.md"
|
|
31
|
+
],
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"@nestjs/common": "^10 || ^11",
|
|
34
|
+
"@xemahq/contracts": "^0.1.0",
|
|
35
|
+
"@xemahq/observability-nest": "^0.3.0",
|
|
36
|
+
"@xemahq/platform-common": ">=0.28.0",
|
|
37
|
+
"@xemahq/service-registry-nest": ">=0.8.0",
|
|
38
|
+
"reflect-metadata": "^0.2"
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@nestjs/common": "11.1.18",
|
|
42
|
+
"@nestjs/core": "11.1.18",
|
|
43
|
+
"@nestjs/testing": "11.1.18",
|
|
44
|
+
"@types/jest": "^30.0.0",
|
|
45
|
+
"@types/node": "25.2.3",
|
|
46
|
+
"@xemahq/contracts": "^0.1.0",
|
|
47
|
+
"@xemahq/platform-common": "^0.31.0",
|
|
48
|
+
"eslint": "^9.39.4",
|
|
49
|
+
"jest": "^30.3.0",
|
|
50
|
+
"prettier": "3.6.2",
|
|
51
|
+
"reflect-metadata": "0.2.2",
|
|
52
|
+
"rxjs": "7.8.2",
|
|
53
|
+
"ts-jest": "^29.4.9",
|
|
54
|
+
"typescript": "5.9.3",
|
|
55
|
+
"@xemahq/eslint-config": "0.6.0",
|
|
56
|
+
"@xemahq/observability-nest": "0.3.1",
|
|
57
|
+
"@xemahq/service-registry-nest": "0.9.0"
|
|
58
|
+
},
|
|
59
|
+
"scripts": {
|
|
60
|
+
"clean": "rm -rf dist",
|
|
61
|
+
"build": "tsc -p tsconfig.build.json",
|
|
62
|
+
"format": "prettier --write \"src/**/*.ts\"",
|
|
63
|
+
"lint": "eslint .",
|
|
64
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
65
|
+
"test": "jest"
|
|
66
|
+
}
|
|
67
|
+
}
|