@juspay/neurolink 12.35.2 → 12.35.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +3 -3
- package/dist/browser/neurolink.min.js +400 -400
- package/dist/neurolink.js +67 -7
- package/dist/server/abstract/baseServerAdapter.d.ts +5 -1
- package/dist/server/abstract/baseServerAdapter.js +1 -1
- package/dist/server/adapters/honoAdapter.d.ts +5 -1
- package/dist/server/adapters/honoAdapter.js +21 -10
- package/docs-site/static/search-index.json +176 -66
- package/package.json +1 -1
package/dist/neurolink.js
CHANGED
|
@@ -8146,8 +8146,30 @@ Current user's request: ${currentInput}`;
|
|
|
8146
8146
|
const streamResult = await this.processStreamResult(processedStream, enhancedOptions, factoryResult);
|
|
8147
8147
|
streamResult.finishReason =
|
|
8148
8148
|
streamState.finishReason || streamResult.finishReason;
|
|
8149
|
-
|
|
8150
|
-
|
|
8149
|
+
// Unresolved #1819 review comment: a top-level cross-provider fallback
|
|
8150
|
+
// (handleStreamFallback, inside `processedStream` above) only
|
|
8151
|
+
// reassigns `streamState.toolCalls`/`toolResults` once the caller
|
|
8152
|
+
// starts draining the stream — strictly AFTER this point, since
|
|
8153
|
+
// `processedStream` is a lazy async generator and the
|
|
8154
|
+
// `processStreamResult` call above resolves without pulling a single
|
|
8155
|
+
// chunk. A plain value copy here (`streamResult.toolCalls =
|
|
8156
|
+
// streamState.toolCalls`) would freeze whatever streamState held at
|
|
8157
|
+
// THIS instant — the primary attempt's (usually empty) arrays —
|
|
8158
|
+
// because a property assignment is not a live binding. Define live
|
|
8159
|
+
// getters instead so every later read reflects streamState's current
|
|
8160
|
+
// value, mirroring the pattern #1819 already used to keep
|
|
8161
|
+
// finishReason/usage/model live via getters over streamState/
|
|
8162
|
+
// mcpStreamOutcome.
|
|
8163
|
+
Object.defineProperty(streamResult, "toolCalls", {
|
|
8164
|
+
enumerable: true,
|
|
8165
|
+
configurable: true,
|
|
8166
|
+
get: () => streamState.toolCalls,
|
|
8167
|
+
});
|
|
8168
|
+
Object.defineProperty(streamResult, "toolResults", {
|
|
8169
|
+
enumerable: true,
|
|
8170
|
+
configurable: true,
|
|
8171
|
+
get: () => streamState.toolResults,
|
|
8172
|
+
});
|
|
8151
8173
|
if (!streamResult.usage) {
|
|
8152
8174
|
streamResult.usage = mcpStreamOutcome.usage;
|
|
8153
8175
|
}
|
|
@@ -9103,13 +9125,27 @@ Current user's request: ${currentInput}`;
|
|
|
9103
9125
|
model: source?.model ?? config.options.model,
|
|
9104
9126
|
usage: streamResult.usage,
|
|
9105
9127
|
finishReason: streamResult.finishReason,
|
|
9106
|
-
toolCalls: streamResult.toolCalls,
|
|
9107
|
-
toolResults: streamResult.toolResults,
|
|
9108
9128
|
analytics: streamResult.analytics,
|
|
9109
9129
|
evaluation: streamResult.evaluation,
|
|
9110
9130
|
events: config.events && config.events.length > 0 ? config.events : undefined,
|
|
9111
9131
|
metadata: source ? undefined : Object.assign({}, responseMetadata),
|
|
9112
9132
|
};
|
|
9133
|
+
// Unresolved #1819 review comment: toolCalls/toolResults must stay bound
|
|
9134
|
+
// to `streamResult`'s own live getters (defined in stream(), right after
|
|
9135
|
+
// processStreamResult) rather than the plain values a
|
|
9136
|
+
// `toolCalls: streamResult.toolCalls` literal above would have captured
|
|
9137
|
+
// — that reads the getter once and freezes whatever streamState held
|
|
9138
|
+
// before a top-level cross-provider fallback (handleStreamFallback) had
|
|
9139
|
+
// a chance to reassign it. Copying the property DESCRIPTOR, not its
|
|
9140
|
+
// current value, keeps every later read on `response` live too.
|
|
9141
|
+
const toolCallsDescriptor = Object.getOwnPropertyDescriptor(streamResult, "toolCalls");
|
|
9142
|
+
if (toolCallsDescriptor) {
|
|
9143
|
+
Object.defineProperty(response, "toolCalls", toolCallsDescriptor);
|
|
9144
|
+
}
|
|
9145
|
+
const toolResultsDescriptor = Object.getOwnPropertyDescriptor(streamResult, "toolResults");
|
|
9146
|
+
if (toolResultsDescriptor) {
|
|
9147
|
+
Object.defineProperty(response, "toolResults", toolResultsDescriptor);
|
|
9148
|
+
}
|
|
9113
9149
|
if (!source) {
|
|
9114
9150
|
return response;
|
|
9115
9151
|
}
|
|
@@ -9117,14 +9153,26 @@ Current user's request: ${currentInput}`;
|
|
|
9117
9153
|
// finishReason, stopReason for aborts and time limits), so those fields
|
|
9118
9154
|
// stay plain values here. Copying the provider's getter for them would
|
|
9119
9155
|
// report the raw vendor reason, e.g. Anthropic's end_turn, instead.
|
|
9120
|
-
|
|
9156
|
+
//
|
|
9157
|
+
// toolCalls/toolResults are excluded for a different reason: `source`
|
|
9158
|
+
// (the PRIMARY provider's own result) may itself define them as live
|
|
9159
|
+
// getters over BaseProvider.withStreamModelFallback's `activeResult`
|
|
9160
|
+
// (#1819) — which only ever tracks a SAME-PROVIDER model retry. Copying
|
|
9161
|
+
// that descriptor here would silently re-point `response.toolCalls`/
|
|
9162
|
+
// `toolResults` back at the primary attempt, undoing the descriptor
|
|
9163
|
+
// copy above that binds them to `streamResult`'s `streamState`-backed
|
|
9164
|
+
// getters — the ones that actually track a top-level cross-provider
|
|
9165
|
+
// fallback.
|
|
9166
|
+
const liveAccessorExclusions = new Set([
|
|
9121
9167
|
"finishReason",
|
|
9122
9168
|
"stopReason",
|
|
9123
9169
|
"rawFinishReason",
|
|
9170
|
+
"toolCalls",
|
|
9171
|
+
"toolResults",
|
|
9124
9172
|
]);
|
|
9125
9173
|
for (const key of Object.getOwnPropertyNames(source)) {
|
|
9126
9174
|
const descriptor = Object.getOwnPropertyDescriptor(source, key);
|
|
9127
|
-
if (!
|
|
9175
|
+
if (!liveAccessorExclusions.has(key) &&
|
|
9128
9176
|
descriptor &&
|
|
9129
9177
|
typeof descriptor.get === "function") {
|
|
9130
9178
|
Object.defineProperty(response, key, descriptor);
|
|
@@ -9133,7 +9181,19 @@ Current user's request: ${currentInput}`;
|
|
|
9133
9181
|
Object.defineProperty(response, "metadata", {
|
|
9134
9182
|
enumerable: true,
|
|
9135
9183
|
configurable: true,
|
|
9136
|
-
get: () =>
|
|
9184
|
+
get: () => {
|
|
9185
|
+
// A caller mutation (`result.metadata.x = 1`) must persist across
|
|
9186
|
+
// reads. The previous `Object.assign(source.metadata ?? {},
|
|
9187
|
+
// responseMetadata)` allocated a brand-new object every time
|
|
9188
|
+
// `source.metadata` was undefined, so the mutation landed on a
|
|
9189
|
+
// value discarded immediately after. Installing a persistent object
|
|
9190
|
+
// into `source.metadata` the first time makes every later read
|
|
9191
|
+
// return the SAME object, so mutations on it stick.
|
|
9192
|
+
if (source.metadata === undefined) {
|
|
9193
|
+
source.metadata = {};
|
|
9194
|
+
}
|
|
9195
|
+
return Object.assign(source.metadata, responseMetadata);
|
|
9196
|
+
},
|
|
9137
9197
|
set: (value) => {
|
|
9138
9198
|
source.metadata = value;
|
|
9139
9199
|
},
|
|
@@ -28,8 +28,12 @@ export declare abstract class BaseServerAdapter extends EventEmitter {
|
|
|
28
28
|
constructor(neurolink: NeuroLink, config?: ServerAdapterConfig);
|
|
29
29
|
/**
|
|
30
30
|
* Initialize the underlying server framework
|
|
31
|
+
* May be async: adapters that dynamically import their framework package
|
|
32
|
+
* (e.g. Hono) return a Promise; adapters with a synchronous no-op stub that
|
|
33
|
+
* defer real setup to their own overridden `initialize()` (Express/Fastify/
|
|
34
|
+
* Koa) still return void.
|
|
31
35
|
*/
|
|
32
|
-
protected abstract initializeFramework(): void
|
|
36
|
+
protected abstract initializeFramework(): void | Promise<void>;
|
|
33
37
|
/**
|
|
34
38
|
* Register a route with the framework
|
|
35
39
|
*/
|
|
@@ -145,7 +145,7 @@ export class BaseServerAdapter extends EventEmitter {
|
|
|
145
145
|
const startTime = Date.now();
|
|
146
146
|
try {
|
|
147
147
|
// Initialize framework-specific setup
|
|
148
|
-
this.initializeFramework();
|
|
148
|
+
await this.initializeFramework();
|
|
149
149
|
// Register built-in middleware
|
|
150
150
|
this.registerBuiltInMiddleware();
|
|
151
151
|
// Register built-in routes
|
|
@@ -16,6 +16,8 @@ export declare class HonoServerAdapter extends BaseServerAdapter {
|
|
|
16
16
|
private rateLimitStore;
|
|
17
17
|
private rateLimitCleanupInterval?;
|
|
18
18
|
private requestContextStore;
|
|
19
|
+
private HTTPExceptionCtor;
|
|
20
|
+
private streamSSEFn;
|
|
19
21
|
constructor(neurolink: NeuroLink, config?: ServerAdapterConfig);
|
|
20
22
|
/**
|
|
21
23
|
* Create rate limiter middleware for Hono
|
|
@@ -27,8 +29,10 @@ export declare class HonoServerAdapter extends BaseServerAdapter {
|
|
|
27
29
|
private cleanupRateLimitStore;
|
|
28
30
|
/**
|
|
29
31
|
* Initialize Hono framework
|
|
32
|
+
* Dynamically imports Hono and its middleware so requiring only another
|
|
33
|
+
* adapter (Express/Fastify/Koa) never pulls Hono's import graph in.
|
|
30
34
|
*/
|
|
31
|
-
protected initializeFramework(): void
|
|
35
|
+
protected initializeFramework(): Promise<void>;
|
|
32
36
|
/**
|
|
33
37
|
* Register route with Hono
|
|
34
38
|
*/
|
|
@@ -3,13 +3,6 @@
|
|
|
3
3
|
* Primary server adapter implementation using Hono framework
|
|
4
4
|
* Hono is chosen for its performance, TypeScript-first design, and edge compatibility
|
|
5
5
|
*/
|
|
6
|
-
import { Hono } from "hono";
|
|
7
|
-
import { cors } from "hono/cors";
|
|
8
|
-
import { HTTPException } from "hono/http-exception";
|
|
9
|
-
import { logger as honoLogger } from "hono/logger";
|
|
10
|
-
import { secureHeaders } from "hono/secure-headers";
|
|
11
|
-
import { streamSSE } from "hono/streaming";
|
|
12
|
-
import { timeout } from "hono/timeout";
|
|
13
6
|
import { logger } from "../../utils/logger.js";
|
|
14
7
|
import { AlreadyRunningError, ServerStopError, wrapError } from "../errors.js";
|
|
15
8
|
import { BaseServerAdapter } from "../abstract/baseServerAdapter.js";
|
|
@@ -25,6 +18,11 @@ export class HonoServerAdapter extends BaseServerAdapter {
|
|
|
25
18
|
rateLimitCleanupInterval;
|
|
26
19
|
// Store context by request ID for sharing between middleware and route handlers
|
|
27
20
|
requestContextStore = new Map();
|
|
21
|
+
// Populated by initializeFramework's dynamic imports; used by methods that
|
|
22
|
+
// run after initialization (route registration, streaming) and so cannot
|
|
23
|
+
// rely on initializeFramework's own local closure variables.
|
|
24
|
+
HTTPExceptionCtor;
|
|
25
|
+
streamSSEFn;
|
|
28
26
|
constructor(neurolink, config = {}) {
|
|
29
27
|
super(neurolink, config);
|
|
30
28
|
}
|
|
@@ -113,8 +111,21 @@ export class HonoServerAdapter extends BaseServerAdapter {
|
|
|
113
111
|
}
|
|
114
112
|
/**
|
|
115
113
|
* Initialize Hono framework
|
|
114
|
+
* Dynamically imports Hono and its middleware so requiring only another
|
|
115
|
+
* adapter (Express/Fastify/Koa) never pulls Hono's import graph in.
|
|
116
116
|
*/
|
|
117
|
-
initializeFramework() {
|
|
117
|
+
async initializeFramework() {
|
|
118
|
+
const [{ Hono }, { cors }, { HTTPException }, { logger: honoLogger }, { secureHeaders }, { streamSSE }, { timeout },] = await Promise.all([
|
|
119
|
+
this.importFrameworkDependency("hono", "hono"),
|
|
120
|
+
this.importFrameworkDependency("hono/cors", "hono"),
|
|
121
|
+
this.importFrameworkDependency("hono/http-exception", "hono"),
|
|
122
|
+
this.importFrameworkDependency("hono/logger", "hono"),
|
|
123
|
+
this.importFrameworkDependency("hono/secure-headers", "hono"),
|
|
124
|
+
this.importFrameworkDependency("hono/streaming", "hono"),
|
|
125
|
+
this.importFrameworkDependency("hono/timeout", "hono"),
|
|
126
|
+
]);
|
|
127
|
+
this.HTTPExceptionCtor = HTTPException;
|
|
128
|
+
this.streamSSEFn = streamSSE;
|
|
118
129
|
this.app = new Hono();
|
|
119
130
|
// Add secure headers
|
|
120
131
|
this.app.use("*", secureHeaders());
|
|
@@ -284,7 +295,7 @@ export class HonoServerAdapter extends BaseServerAdapter {
|
|
|
284
295
|
route: route.path,
|
|
285
296
|
error: errorMessage,
|
|
286
297
|
});
|
|
287
|
-
throw new
|
|
298
|
+
throw new this.HTTPExceptionCtor(500, { message: errorMessage });
|
|
288
299
|
}
|
|
289
300
|
finally {
|
|
290
301
|
// Untrack connection when request completes
|
|
@@ -304,7 +315,7 @@ export class HonoServerAdapter extends BaseServerAdapter {
|
|
|
304
315
|
c.header(key, value);
|
|
305
316
|
}
|
|
306
317
|
}
|
|
307
|
-
return
|
|
318
|
+
return this.streamSSEFn(c, async (stream) => {
|
|
308
319
|
try {
|
|
309
320
|
// Get streaming result from handler
|
|
310
321
|
const result = await route.handler(ctx);
|