@carlonicora/nestjs-neo4jsonapi 1.110.3 → 1.112.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/dist/agents/graph/tools/describe-entity.tool.d.ts +1 -1
- package/dist/agents/graph/tools/describe-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/describe-entity.tool.js +2 -1
- package/dist/agents/graph/tools/describe-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/read-entity.tool.d.ts +1 -1
- package/dist/agents/graph/tools/read-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/read-entity.tool.js +2 -1
- package/dist/agents/graph/tools/read-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/resolve-entity.tool.d.ts +1 -1
- package/dist/agents/graph/tools/resolve-entity.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/resolve-entity.tool.js +2 -1
- package/dist/agents/graph/tools/resolve-entity.tool.js.map +1 -1
- package/dist/agents/graph/tools/search-entities.tool.d.ts +1 -1
- package/dist/agents/graph/tools/search-entities.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/search-entities.tool.js +2 -1
- package/dist/agents/graph/tools/search-entities.tool.js.map +1 -1
- package/dist/agents/graph/tools/traverse.tool.d.ts +1 -1
- package/dist/agents/graph/tools/traverse.tool.d.ts.map +1 -1
- package/dist/agents/graph/tools/traverse.tool.js +2 -1
- package/dist/agents/graph/tools/traverse.tool.js.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.d.ts +1 -1
- package/dist/agents/operator/tools/search-documents.tool.d.ts.map +1 -1
- package/dist/agents/operator/tools/search-documents.tool.js +2 -1
- package/dist/agents/operator/tools/search-documents.tool.js.map +1 -1
- package/dist/bootstrap/app.module.factory.d.ts.map +1 -1
- package/dist/bootstrap/app.module.factory.js +3 -0
- package/dist/bootstrap/app.module.factory.js.map +1 -1
- package/dist/bootstrap/bootstrap.options.d.ts +2 -0
- package/dist/bootstrap/bootstrap.options.d.ts.map +1 -1
- package/dist/config/base.config.d.ts.map +1 -1
- package/dist/config/base.config.js +15 -0
- package/dist/config/base.config.js.map +1 -1
- package/dist/config/interfaces/base.config.interface.d.ts +2 -0
- package/dist/config/interfaces/base.config.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.ai.interface.d.ts +29 -0
- package/dist/config/interfaces/config.ai.interface.d.ts.map +1 -1
- package/dist/config/interfaces/config.mcp.interface.d.ts +34 -0
- package/dist/config/interfaces/config.mcp.interface.d.ts.map +1 -0
- package/dist/config/interfaces/config.mcp.interface.js +3 -0
- package/dist/config/interfaces/config.mcp.interface.js.map +1 -0
- package/dist/config/interfaces/index.d.ts +1 -0
- package/dist/config/interfaces/index.d.ts.map +1 -1
- package/dist/config/interfaces/index.js +1 -0
- package/dist/config/interfaces/index.js.map +1 -1
- package/dist/core/llm/services/llm.service.d.ts +52 -0
- package/dist/core/llm/services/llm.service.d.ts.map +1 -1
- package/dist/core/llm/services/llm.service.js +163 -10
- package/dist/core/llm/services/llm.service.js.map +1 -1
- package/dist/core/llm/services/model.service.d.ts +2 -0
- package/dist/core/llm/services/model.service.d.ts.map +1 -1
- package/dist/core/llm/services/model.service.js +7 -0
- package/dist/core/llm/services/model.service.js.map +1 -1
- package/dist/foundations/oauth/constants/oauth.scopes.d.ts +2 -0
- package/dist/foundations/oauth/constants/oauth.scopes.d.ts.map +1 -1
- package/dist/foundations/oauth/constants/oauth.scopes.js +4 -0
- package/dist/foundations/oauth/constants/oauth.scopes.js.map +1 -1
- package/dist/foundations/oauth/controllers/index.d.ts +2 -0
- package/dist/foundations/oauth/controllers/index.d.ts.map +1 -1
- package/dist/foundations/oauth/controllers/index.js +2 -0
- package/dist/foundations/oauth/controllers/index.js.map +1 -1
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.d.ts +46 -0
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.d.ts.map +1 -0
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.js +102 -0
- package/dist/foundations/oauth/controllers/oauth.discovery.controller.js.map +1 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.d.ts +36 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.d.ts.map +1 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.js +81 -0
- package/dist/foundations/oauth/controllers/oauth.registration.controller.js.map +1 -0
- package/dist/foundations/oauth/dtos/index.d.ts +1 -0
- package/dist/foundations/oauth/dtos/index.d.ts.map +1 -1
- package/dist/foundations/oauth/dtos/index.js +1 -0
- package/dist/foundations/oauth/dtos/index.js.map +1 -1
- package/dist/foundations/oauth/dtos/oauth.register.dto.d.ts +14 -0
- package/dist/foundations/oauth/dtos/oauth.register.dto.d.ts.map +1 -0
- package/dist/foundations/oauth/dtos/oauth.register.dto.js +49 -0
- package/dist/foundations/oauth/dtos/oauth.register.dto.js.map +1 -0
- package/dist/foundations/oauth/index.d.ts +1 -0
- package/dist/foundations/oauth/index.d.ts.map +1 -1
- package/dist/foundations/oauth/index.js +3 -1
- package/dist/foundations/oauth/index.js.map +1 -1
- package/dist/foundations/oauth/oauth.module.d.ts +3 -1
- package/dist/foundations/oauth/oauth.module.d.ts.map +1 -1
- package/dist/foundations/oauth/oauth.module.js +12 -2
- package/dist/foundations/oauth/oauth.module.js.map +1 -1
- package/dist/foundations/oauth/repositories/oauth.repository.d.ts +2 -1
- package/dist/foundations/oauth/repositories/oauth.repository.d.ts.map +1 -1
- package/dist/foundations/oauth/repositories/oauth.repository.js +16 -34
- package/dist/foundations/oauth/repositories/oauth.repository.js.map +1 -1
- package/dist/foundations/oauth/services/oauth.client.service.d.ts +2 -1
- package/dist/foundations/oauth/services/oauth.client.service.d.ts.map +1 -1
- package/dist/foundations/oauth/services/oauth.client.service.js.map +1 -1
- package/dist/foundations/rbac/index.d.ts +4 -0
- package/dist/foundations/rbac/index.d.ts.map +1 -1
- package/dist/foundations/rbac/index.js +7 -1
- package/dist/foundations/rbac/index.js.map +1 -1
- package/dist/foundations/rbac/rbac-permission.module.d.ts +14 -0
- package/dist/foundations/rbac/rbac-permission.module.d.ts.map +1 -0
- package/dist/foundations/rbac/rbac-permission.module.js +33 -0
- package/dist/foundations/rbac/rbac-permission.module.js.map +1 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.d.ts +31 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.d.ts.map +1 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.js +80 -0
- package/dist/foundations/rbac/repositories/rbac-permission.repository.js.map +1 -0
- package/dist/foundations/rbac/services/rbac-permission.service.d.ts +31 -0
- package/dist/foundations/rbac/services/rbac-permission.service.d.ts.map +1 -0
- package/dist/foundations/rbac/services/rbac-permission.service.js +41 -0
- package/dist/foundations/rbac/services/rbac-permission.service.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/mcp/controllers/mcp.controller.d.ts +34 -0
- package/dist/mcp/controllers/mcp.controller.d.ts.map +1 -0
- package/dist/mcp/controllers/mcp.controller.js +108 -0
- package/dist/mcp/controllers/mcp.controller.js.map +1 -0
- package/dist/mcp/filters/mcp.auth.filter.d.ts +21 -0
- package/dist/mcp/filters/mcp.auth.filter.d.ts.map +1 -0
- package/dist/mcp/filters/mcp.auth.filter.js +52 -0
- package/dist/mcp/filters/mcp.auth.filter.js.map +1 -0
- package/dist/mcp/index.d.ts +4 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +11 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/interfaces/mcp.tool.interface.d.ts +37 -0
- package/dist/mcp/interfaces/mcp.tool.interface.d.ts.map +1 -0
- package/dist/mcp/interfaces/mcp.tool.interface.js +6 -0
- package/dist/mcp/interfaces/mcp.tool.interface.js.map +1 -0
- package/dist/mcp/mcp.module.d.ts +23 -0
- package/dist/mcp/mcp.module.d.ts.map +1 -0
- package/dist/mcp/mcp.module.js +59 -0
- package/dist/mcp/mcp.module.js.map +1 -0
- package/dist/mcp/services/mcp.entity.write.service.d.ts +79 -0
- package/dist/mcp/services/mcp.entity.write.service.d.ts.map +1 -0
- package/dist/mcp/services/mcp.entity.write.service.js +270 -0
- package/dist/mcp/services/mcp.entity.write.service.js.map +1 -0
- package/dist/mcp/services/mcp.errors.d.ts +24 -0
- package/dist/mcp/services/mcp.errors.d.ts.map +1 -0
- package/dist/mcp/services/mcp.errors.js +50 -0
- package/dist/mcp/services/mcp.errors.js.map +1 -0
- package/dist/mcp/services/mcp.generic.tools.service.d.ts +26 -0
- package/dist/mcp/services/mcp.generic.tools.service.d.ts.map +1 -0
- package/dist/mcp/services/mcp.generic.tools.service.js +108 -0
- package/dist/mcp/services/mcp.generic.tools.service.js.map +1 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.d.ts +58 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.d.ts.map +1 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.js +260 -0
- package/dist/mcp/services/mcp.promoted.tools.factory.js.map +1 -0
- package/dist/mcp/services/mcp.server.factory.d.ts +24 -0
- package/dist/mcp/services/mcp.server.factory.d.ts.map +1 -0
- package/dist/mcp/services/mcp.server.factory.js +60 -0
- package/dist/mcp/services/mcp.server.factory.js.map +1 -0
- package/dist/mcp/services/mcp.tool.registry.d.ts +21 -0
- package/dist/mcp/services/mcp.tool.registry.d.ts.map +1 -0
- package/dist/mcp/services/mcp.tool.registry.js +72 -0
- package/dist/mcp/services/mcp.tool.registry.js.map +1 -0
- package/package.json +17 -12
|
@@ -81,6 +81,35 @@ export interface ConfigAiInterface {
|
|
|
81
81
|
* `ENV === "production"` to enforce this. Driven by MOCK_AI=true.
|
|
82
82
|
*/
|
|
83
83
|
mock: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* Per-ATTEMPT wall-clock budget for one provider request, in milliseconds.
|
|
86
|
+
* Driven by AI_REQUEST_TIMEOUT_MS (default 120000).
|
|
87
|
+
*
|
|
88
|
+
* Without it the only bound is the OpenAI SDK's own 600s default, so a
|
|
89
|
+
* provider that accepts a request and never answers freezes the caller for
|
|
90
|
+
* ten minutes with no error, no log and no dump (the dump file is written on
|
|
91
|
+
* close). Callers that need a different bound pass `timeout` per call.
|
|
92
|
+
*
|
|
93
|
+
* This is the budget for ONE attempt: the LangChain retry layer may re-issue
|
|
94
|
+
* (on OpenRouter each retry escalates `allow_fallbacks`, so a stalled provider
|
|
95
|
+
* is rerouted rather than waited on again). {@link requestDeadlineAttempts}
|
|
96
|
+
* bounds the total.
|
|
97
|
+
*/
|
|
98
|
+
requestTimeoutMs: number;
|
|
99
|
+
/**
|
|
100
|
+
* How many attempts the absolute deadline budgets for before it force-fails a
|
|
101
|
+
* call, so an adapter that ignores its own timeout still settles. Driven by
|
|
102
|
+
* AI_REQUEST_DEADLINE_ATTEMPTS (default 3 — matches LangChain's maxRetries: 2
|
|
103
|
+
* plus the first attempt).
|
|
104
|
+
*/
|
|
105
|
+
requestDeadlineAttempts: number;
|
|
106
|
+
/**
|
|
107
|
+
* How often, in milliseconds, a still-pending provider request logs a warning.
|
|
108
|
+
* Driven by AI_REQUEST_WATCHDOG_MS (default 30000). A stall used to be
|
|
109
|
+
* completely silent until it resolved; this makes it visible while it happens.
|
|
110
|
+
* Set to 0 to disable.
|
|
111
|
+
*/
|
|
112
|
+
requestWatchdogMs: number;
|
|
84
113
|
/**
|
|
85
114
|
* Mistral Document AI (OCR) on Azure AI Foundry — see DocumentAiService.
|
|
86
115
|
* Driven by DOCUMENT_AI_{ENABLED,PROVIDER,API_KEY,MODEL,URL,API_VERSION}.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.ai.interface.d.ts","sourceRoot":"","sources":["../../../src/config/interfaces/config.ai.interface.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"config.ai.interface.d.ts","sourceRoot":"","sources":["../../../src/config/interfaces/config.ai.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP (Model Context Protocol) Server Configuration Interface
|
|
3
|
+
*
|
|
4
|
+
* Controls the MCP server exposed at POST /mcp, which lets external AI agents
|
|
5
|
+
* (claude.ai connectors, Claude Desktop, ChatGPT) interact with the application
|
|
6
|
+
* through OAuth-authenticated, RBAC-gated tools.
|
|
7
|
+
*
|
|
8
|
+
* @see https://modelcontextprotocol.io - Model Context Protocol specification
|
|
9
|
+
*/
|
|
10
|
+
export interface ConfigMcpInterface {
|
|
11
|
+
/**
|
|
12
|
+
* Master switch to enable/disable the MCP server.
|
|
13
|
+
* When false, the MCP endpoint is not served.
|
|
14
|
+
* @default false
|
|
15
|
+
*/
|
|
16
|
+
enabled: boolean;
|
|
17
|
+
/**
|
|
18
|
+
* Server name advertised to MCP clients during initialization.
|
|
19
|
+
* @default "neural-erp"
|
|
20
|
+
*/
|
|
21
|
+
serverName: string;
|
|
22
|
+
/**
|
|
23
|
+
* Optional instructions string advertised to MCP clients,
|
|
24
|
+
* describing how to best use this server's tools.
|
|
25
|
+
*/
|
|
26
|
+
instructions?: string;
|
|
27
|
+
/**
|
|
28
|
+
* JSON:API types promoted to dedicated per-entity MCP tools,
|
|
29
|
+
* parsed from a comma-separated environment variable.
|
|
30
|
+
* @default []
|
|
31
|
+
*/
|
|
32
|
+
promotedEntities: string[];
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=config.mcp.interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.mcp.interface.d.ts","sourceRoot":"","sources":["../../../src/config/interfaces/config.mcp.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,UAAU,EAAE,MAAM,CAAC;IAEnB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,gBAAgB,EAAE,MAAM,EAAE,CAAC;CAC5B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.mcp.interface.js","sourceRoot":"","sources":["../../../src/config/interfaces/config.mcp.interface.ts"],"names":[],"mappings":""}
|
|
@@ -21,6 +21,7 @@ export * from "./config.interface";
|
|
|
21
21
|
export * from "./config.job.names.interface";
|
|
22
22
|
export * from "./config.jwt.interface";
|
|
23
23
|
export * from "./config.logging.interface";
|
|
24
|
+
export * from "./config.mcp.interface";
|
|
24
25
|
export * from "./config.neo4j.interface";
|
|
25
26
|
export * from "./config.oauth.interface";
|
|
26
27
|
export * from "./config.operator.interface";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/interfaces/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/config/interfaces/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC;AACtC,cAAc,wBAAwB,CAAC;AACvC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC;AAChD,cAAc,kCAAkC,CAAC;AACjD,cAAc,yBAAyB,CAAC;AACxC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,sCAAsC,CAAC;AACrD,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,wBAAwB,CAAC;AACvC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,wBAAwB,CAAC;AACvC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,8BAA8B,CAAC;AAC7C,cAAc,0BAA0B,CAAC;AACzC,cAAc,uBAAuB,CAAC;AACtC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,0BAA0B,CAAC"}
|
|
@@ -37,6 +37,7 @@ __exportStar(require("./config.interface"), exports);
|
|
|
37
37
|
__exportStar(require("./config.job.names.interface"), exports);
|
|
38
38
|
__exportStar(require("./config.jwt.interface"), exports);
|
|
39
39
|
__exportStar(require("./config.logging.interface"), exports);
|
|
40
|
+
__exportStar(require("./config.mcp.interface"), exports);
|
|
40
41
|
__exportStar(require("./config.neo4j.interface"), exports);
|
|
41
42
|
__exportStar(require("./config.oauth.interface"), exports);
|
|
42
43
|
__exportStar(require("./config.operator.interface"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/interfaces/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,0DAAwC;AACxC,wDAAsC;AACtC,yDAAuC;AACvC,yDAAuC;AACvC,0DAAwC;AACxC,2DAAyC;AACzC,6DAA2C;AAC3C,kEAAgD;AAChD,mEAAiD;AACjD,0DAAwC;AACxC,6DAA2C;AAC3C,uEAAqD;AACrD,4DAA0C;AAC1C,2DAAyC;AACzC,gEAA8C;AAC9C,iEAA+C;AAC/C,qDAAmC;AACnC,+DAA6C;AAC7C,yDAAuC;AACvC,6DAA2C;AAC3C,2DAAyC;AACzC,2DAAyC;AACzC,8DAA4C;AAC5C,6DAA2C;AAC3C,+DAA6C;AAC7C,2DAAyC;AACzC,wDAAsC;AACtC,4DAA0C;AAC1C,2DAAyC;AACzC,gEAA8C;AAC9C,2DAAyC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/interfaces/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,0DAAwC;AACxC,wDAAsC;AACtC,yDAAuC;AACvC,yDAAuC;AACvC,0DAAwC;AACxC,2DAAyC;AACzC,6DAA2C;AAC3C,kEAAgD;AAChD,mEAAiD;AACjD,0DAAwC;AACxC,6DAA2C;AAC3C,uEAAqD;AACrD,4DAA0C;AAC1C,2DAAyC;AACzC,gEAA8C;AAC9C,iEAA+C;AAC/C,qDAAmC;AACnC,+DAA6C;AAC7C,yDAAuC;AACvC,6DAA2C;AAC3C,yDAAuC;AACvC,2DAAyC;AACzC,2DAAyC;AACzC,8DAA4C;AAC5C,6DAA2C;AAC3C,+DAA6C;AAC7C,2DAAyC;AACzC,wDAAsC;AACtC,4DAA0C;AAC1C,2DAAyC;AACzC,gEAA8C;AAC9C,2DAAyC"}
|
|
@@ -10,6 +10,23 @@ import { LLMCacheService } from "./llm-cache.service";
|
|
|
10
10
|
import { ModelService } from "../../llm/services/model.service";
|
|
11
11
|
import { LLMCallDumper } from "./llm-call-dumper.service";
|
|
12
12
|
export { injectOpenRouterProvider } from "./openrouter-fetch";
|
|
13
|
+
/**
|
|
14
|
+
* True for the abort a request timeout raises, whichever layer raised it — the
|
|
15
|
+
* OpenAI SDK's `APIConnectionTimeoutError`, undici's `TimeoutError`/
|
|
16
|
+
* `AbortError` DOMException, or a LangChain wrapper around either. Matched on
|
|
17
|
+
* name and message because the concrete class differs per transport.
|
|
18
|
+
*/
|
|
19
|
+
export declare function isTimeoutError(error: unknown): boolean;
|
|
20
|
+
/**
|
|
21
|
+
* Thrown when a provider call burns its whole deadline without settling.
|
|
22
|
+
* Distinguishable from a provider error so callers can treat a stall
|
|
23
|
+
* differently from a refusal if they choose — both are retryable.
|
|
24
|
+
*/
|
|
25
|
+
export declare class LLMTimeoutError extends Error {
|
|
26
|
+
readonly label: string;
|
|
27
|
+
readonly deadlineMs: number;
|
|
28
|
+
constructor(label: string, deadlineMs: number);
|
|
29
|
+
}
|
|
13
30
|
/**
|
|
14
31
|
* Parameters for LLM service calls
|
|
15
32
|
*/
|
|
@@ -47,6 +64,39 @@ export declare class LLMService {
|
|
|
47
64
|
private readonly cache?;
|
|
48
65
|
private readonly logger;
|
|
49
66
|
constructor(modelService: ModelService, config: ConfigService<BaseConfigInterface>, dumper: LLMCallDumper, tokenUsageService: TokenUsageService, cache?: LLMCacheService);
|
|
67
|
+
/**
|
|
68
|
+
* The per-ATTEMPT budget for one provider request. `params.timeout` wins;
|
|
69
|
+
* otherwise the configured default (`AI_REQUEST_TIMEOUT_MS`).
|
|
70
|
+
*/
|
|
71
|
+
private attemptTimeoutMs;
|
|
72
|
+
/**
|
|
73
|
+
* Runs one provider call under a WATCHDOG and an ABSOLUTE DEADLINE.
|
|
74
|
+
*
|
|
75
|
+
* Why this exists (game e51493e4 r002, 2026-07-26): a plotter request was
|
|
76
|
+
* accepted by the provider and never answered. Nothing in the stack could
|
|
77
|
+
* interrupt it — no timeout was configured anywhere, the dump file is only
|
|
78
|
+
* written when the call closes, and the callers' retry/fallback wrappers catch
|
|
79
|
+
* ERRORS, not promises that never settle. The round froze for 639 seconds with
|
|
80
|
+
* no log, no dump and no error, and only unfroze because the OpenAI SDK's own
|
|
81
|
+
* 600s default finally fired. Three such stalls are on record (547s, 514s,
|
|
82
|
+
* 639s) across two tiers and two models, so this is a property of talking to a
|
|
83
|
+
* provider, not of one model.
|
|
84
|
+
*
|
|
85
|
+
* Two independent guarantees, because the first one can be ignored by an
|
|
86
|
+
* adapter that owns its own transport:
|
|
87
|
+
* - the WATCHDOG logs every `requestWatchdogMs` while the call is pending, so
|
|
88
|
+
* a stall is visible AS IT HAPPENS instead of after it resolves;
|
|
89
|
+
* - the DEADLINE aborts the signal and rejects with {@link LLMTimeoutError}
|
|
90
|
+
* once the call has burned its whole attempt budget, so the promise ALWAYS
|
|
91
|
+
* settles and the caller's existing retry/fallback path gets to run.
|
|
92
|
+
*
|
|
93
|
+
* The deadline is deliberately the LAST line of defence: it budgets
|
|
94
|
+
* `requestDeadlineAttempts` attempts, so in normal operation the per-attempt
|
|
95
|
+
* timeout fires first and the retry escalates the OpenRouter pin onto a
|
|
96
|
+
* healthy provider — which is the outcome we actually want. Reaching the
|
|
97
|
+
* deadline means the adapter never honoured its own timeout.
|
|
98
|
+
*/
|
|
99
|
+
private runBounded;
|
|
50
100
|
/**
|
|
51
101
|
* Records token usage for cost/observability attribution. Never throws —
|
|
52
102
|
* a persistence failure logs a warning and the LLM call continues, so
|
|
@@ -331,6 +381,8 @@ export declare class LLMService {
|
|
|
331
381
|
* systemPrompts/prompt). A hit returns early WITHOUT invoking the provider,
|
|
332
382
|
* so it costs no tokens. Default: false. */
|
|
333
383
|
cacheable?: boolean;
|
|
384
|
+
/** Per-attempt request budget in ms. Defaults to `ai.requestTimeoutMs`. */
|
|
385
|
+
timeout?: number;
|
|
334
386
|
}): Promise<T>;
|
|
335
387
|
/**
|
|
336
388
|
* Single-step model invocation with tools bound — the durable-checkpointing
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.service.d.ts","sourceRoot":"","sources":["../../../../src/core/llm/services/llm.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,WAAW,EAA4C,MAAM,0BAA0B,CAAC;AAE5G,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAE9D,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAG/C,OAAO,EAAE,OAAO,EAAE,MAAM,KAAK,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,mBAAmB,EAAqB,MAAM,4BAA4B,CAAC;AAEpF,OAAO,EAAE,iBAAiB,EAAE,MAAM,6DAA6D,CAAC;AAChG,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,eAAe,EAAiB,MAAM,qBAAqB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAShE,OAAO,EAAuC,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAa/F,OAAO,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"llm.service.d.ts","sourceRoot":"","sources":["../../../../src/core/llm/services/llm.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -46,7 +46,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
46
46
|
};
|
|
47
47
|
var LLMService_1;
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
-
exports.LLMService = exports.injectOpenRouterProvider = void 0;
|
|
49
|
+
exports.LLMService = exports.LLMTimeoutError = exports.injectOpenRouterProvider = void 0;
|
|
50
|
+
exports.isTimeoutError = isTimeoutError;
|
|
50
51
|
const openai_compatible_1 = require("@ai-sdk/openai-compatible");
|
|
51
52
|
const messages_1 = require("@langchain/core/messages");
|
|
52
53
|
const prompts_1 = require("@langchain/core/prompts");
|
|
@@ -77,6 +78,40 @@ const { streamText, streamObject } = (0, vercel_1.wrapAISDK)(ai);
|
|
|
77
78
|
// Re-export for the existing test import path.
|
|
78
79
|
var openrouter_fetch_2 = require("./openrouter-fetch");
|
|
79
80
|
Object.defineProperty(exports, "injectOpenRouterProvider", { enumerable: true, get: function () { return openrouter_fetch_2.injectOpenRouterProvider; } });
|
|
81
|
+
/** Fallbacks used only when no `ai` config block is registered (test harnesses). */
|
|
82
|
+
const DEFAULT_REQUEST_TIMEOUT_MS = 120_000;
|
|
83
|
+
const DEFAULT_REQUEST_WATCHDOG_MS = 30_000;
|
|
84
|
+
const DEFAULT_REQUEST_DEADLINE_ATTEMPTS = 3;
|
|
85
|
+
/** Grace on top of the budgeted attempts, covering backoff between retries. */
|
|
86
|
+
const DEADLINE_SLACK_MS = 15_000;
|
|
87
|
+
/**
|
|
88
|
+
* True for the abort a request timeout raises, whichever layer raised it — the
|
|
89
|
+
* OpenAI SDK's `APIConnectionTimeoutError`, undici's `TimeoutError`/
|
|
90
|
+
* `AbortError` DOMException, or a LangChain wrapper around either. Matched on
|
|
91
|
+
* name and message because the concrete class differs per transport.
|
|
92
|
+
*/
|
|
93
|
+
function isTimeoutError(error) {
|
|
94
|
+
const name = error?.name ?? "";
|
|
95
|
+
const message = error instanceof Error ? error.message : String(error ?? "");
|
|
96
|
+
return (name === "TimeoutError" ||
|
|
97
|
+
name === "AbortError" ||
|
|
98
|
+
name === "APIConnectionTimeoutError" ||
|
|
99
|
+
/aborted due to timeout|timed? ?out|Request was aborted/i.test(message));
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Thrown when a provider call burns its whole deadline without settling.
|
|
103
|
+
* Distinguishable from a provider error so callers can treat a stall
|
|
104
|
+
* differently from a refusal if they choose — both are retryable.
|
|
105
|
+
*/
|
|
106
|
+
class LLMTimeoutError extends Error {
|
|
107
|
+
constructor(label, deadlineMs) {
|
|
108
|
+
super(`LLM call "${label}" exceeded its ${Math.round(deadlineMs / 1000)}s deadline`);
|
|
109
|
+
this.label = label;
|
|
110
|
+
this.deadlineMs = deadlineMs;
|
|
111
|
+
this.name = "LLMTimeoutError";
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.LLMTimeoutError = LLMTimeoutError;
|
|
80
115
|
/**
|
|
81
116
|
* Best-effort extraction of a JSON object from free-form model text. Local
|
|
82
117
|
* models (notably Gemma over Ollama) routinely ignore a forced `tool_choice`
|
|
@@ -187,6 +222,73 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
187
222
|
this.cache = cache;
|
|
188
223
|
this.logger = new common_1.Logger(LLMService_1.name);
|
|
189
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* The per-ATTEMPT budget for one provider request. `params.timeout` wins;
|
|
227
|
+
* otherwise the configured default (`AI_REQUEST_TIMEOUT_MS`).
|
|
228
|
+
*/
|
|
229
|
+
attemptTimeoutMs(explicit) {
|
|
230
|
+
return explicit ?? this.config.get("ai")?.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Runs one provider call under a WATCHDOG and an ABSOLUTE DEADLINE.
|
|
234
|
+
*
|
|
235
|
+
* Why this exists (game e51493e4 r002, 2026-07-26): a plotter request was
|
|
236
|
+
* accepted by the provider and never answered. Nothing in the stack could
|
|
237
|
+
* interrupt it — no timeout was configured anywhere, the dump file is only
|
|
238
|
+
* written when the call closes, and the callers' retry/fallback wrappers catch
|
|
239
|
+
* ERRORS, not promises that never settle. The round froze for 639 seconds with
|
|
240
|
+
* no log, no dump and no error, and only unfroze because the OpenAI SDK's own
|
|
241
|
+
* 600s default finally fired. Three such stalls are on record (547s, 514s,
|
|
242
|
+
* 639s) across two tiers and two models, so this is a property of talking to a
|
|
243
|
+
* provider, not of one model.
|
|
244
|
+
*
|
|
245
|
+
* Two independent guarantees, because the first one can be ignored by an
|
|
246
|
+
* adapter that owns its own transport:
|
|
247
|
+
* - the WATCHDOG logs every `requestWatchdogMs` while the call is pending, so
|
|
248
|
+
* a stall is visible AS IT HAPPENS instead of after it resolves;
|
|
249
|
+
* - the DEADLINE aborts the signal and rejects with {@link LLMTimeoutError}
|
|
250
|
+
* once the call has burned its whole attempt budget, so the promise ALWAYS
|
|
251
|
+
* settles and the caller's existing retry/fallback path gets to run.
|
|
252
|
+
*
|
|
253
|
+
* The deadline is deliberately the LAST line of defence: it budgets
|
|
254
|
+
* `requestDeadlineAttempts` attempts, so in normal operation the per-attempt
|
|
255
|
+
* timeout fires first and the retry escalates the OpenRouter pin onto a
|
|
256
|
+
* healthy provider — which is the outcome we actually want. Reaching the
|
|
257
|
+
* deadline means the adapter never honoured its own timeout.
|
|
258
|
+
*/
|
|
259
|
+
async runBounded(label, attemptTimeoutMs, controller, work) {
|
|
260
|
+
const aiConfig = this.config.get("ai");
|
|
261
|
+
const watchdogMs = aiConfig?.requestWatchdogMs ?? DEFAULT_REQUEST_WATCHDOG_MS;
|
|
262
|
+
const attempts = aiConfig?.requestDeadlineAttempts ?? DEFAULT_REQUEST_DEADLINE_ATTEMPTS;
|
|
263
|
+
const deadlineMs = attemptTimeoutMs * Math.max(1, attempts) + DEADLINE_SLACK_MS;
|
|
264
|
+
const startedAt = Date.now();
|
|
265
|
+
const watchdog = watchdogMs > 0
|
|
266
|
+
? setInterval(() => {
|
|
267
|
+
this.logger.warn(`[${label}] still pending after ${Math.round((Date.now() - startedAt) / 1000)}s ` +
|
|
268
|
+
`(attempt budget ${Math.round(attemptTimeoutMs / 1000)}s, hard deadline ${Math.round(deadlineMs / 1000)}s)`);
|
|
269
|
+
}, watchdogMs)
|
|
270
|
+
: undefined;
|
|
271
|
+
watchdog?.unref?.();
|
|
272
|
+
let deadline;
|
|
273
|
+
try {
|
|
274
|
+
return await new Promise((resolve, reject) => {
|
|
275
|
+
deadline = setTimeout(() => {
|
|
276
|
+
// Abort first so the in-flight socket is released, then reject — the
|
|
277
|
+
// caller must not be left waiting on a request nobody is reading.
|
|
278
|
+
controller.abort();
|
|
279
|
+
reject(new LLMTimeoutError(label, deadlineMs));
|
|
280
|
+
}, deadlineMs);
|
|
281
|
+
deadline.unref?.();
|
|
282
|
+
work().then(resolve, reject);
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
finally {
|
|
286
|
+
if (watchdog)
|
|
287
|
+
clearInterval(watchdog);
|
|
288
|
+
if (deadline)
|
|
289
|
+
clearTimeout(deadline);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
190
292
|
/**
|
|
191
293
|
* Records token usage for cost/observability attribution. Never throws —
|
|
192
294
|
* a persistence failure logs a warning and the LLM call continues, so
|
|
@@ -478,12 +580,18 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
478
580
|
let totalCached = 0;
|
|
479
581
|
const parseFallbacks = [];
|
|
480
582
|
const warnings = [];
|
|
583
|
+
// Bounded from here on: the request carries an abort signal, a watchdog
|
|
584
|
+
// reports it while it is still open, and the deadline guarantees this
|
|
585
|
+
// promise settles even if the provider never answers.
|
|
586
|
+
const attemptTimeoutMs = this.attemptTimeoutMs(params.timeout);
|
|
587
|
+
const controller = new AbortController();
|
|
588
|
+
const label = `${params.metadata?.nodeName ?? "llm.call"}:${aiConfig.model}`;
|
|
481
589
|
try {
|
|
482
|
-
const result = await this._invokeOriginal(params, session, (i, o, c) => {
|
|
590
|
+
const result = await this.runBounded(label, attemptTimeoutMs, controller, () => this._invokeOriginal(params, session, (i, o, c) => {
|
|
483
591
|
totalInput += i;
|
|
484
592
|
totalOutput += o;
|
|
485
593
|
totalCached += c;
|
|
486
|
-
}, (kind) => parseFallbacks.push(kind), (w) => warnings.push(w));
|
|
594
|
+
}, (kind) => parseFallbacks.push(kind), (w) => warnings.push(w), { attemptTimeoutMs, signal: controller.signal }));
|
|
487
595
|
session.close({
|
|
488
596
|
finalStatus: "success",
|
|
489
597
|
totalTokens: { input: totalInput, output: totalOutput, cached: totalCached },
|
|
@@ -517,7 +625,10 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
517
625
|
throw new Error(`LLM service error: ${message}`);
|
|
518
626
|
}
|
|
519
627
|
}
|
|
520
|
-
async _invokeOriginal(params, session, addTokens, addParseFallback, addWarning
|
|
628
|
+
async _invokeOriginal(params, session, addTokens, addParseFallback, addWarning,
|
|
629
|
+
// The per-attempt budget and the deadline's abort signal, supplied by
|
|
630
|
+
// `call()`. Optional so direct callers (tests) keep working unbounded.
|
|
631
|
+
bounds) {
|
|
521
632
|
// Optional: Validate input parameters against schema
|
|
522
633
|
if (params.inputSchema && params.validateInput) {
|
|
523
634
|
try {
|
|
@@ -538,11 +649,15 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
538
649
|
maxHistoryMessages: params.maxHistoryMessages,
|
|
539
650
|
});
|
|
540
651
|
const prompt = prompts_1.ChatPromptTemplate.fromMessages(template);
|
|
541
|
-
// Get base model
|
|
652
|
+
// Get base model. The per-attempt budget rides on the model itself: the
|
|
653
|
+
// OpenAI client is built with it, so each attempt aborts on schedule and the
|
|
654
|
+
// LangChain retry re-issues (escalating the OpenRouter pin) instead of the
|
|
655
|
+
// whole call sitting on one dead socket.
|
|
542
656
|
const baseModel = this.modelService.getLLM({
|
|
543
657
|
temperature: params.temperature,
|
|
544
658
|
modelWeight: params.modelWeight,
|
|
545
659
|
disableThinking: params.disableThinking,
|
|
660
|
+
timeoutMs: bounds?.attemptTimeoutMs ?? params.timeout,
|
|
546
661
|
});
|
|
547
662
|
// Build config options for the invocation
|
|
548
663
|
const configOptions = {};
|
|
@@ -554,6 +669,10 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
554
669
|
configOptions.metadata = params.metadata;
|
|
555
670
|
if (params.timeout)
|
|
556
671
|
configOptions.timeout = params.timeout;
|
|
672
|
+
// The deadline's signal — aborting it releases the in-flight request rather
|
|
673
|
+
// than leaving an orphaned socket behind a rejected promise.
|
|
674
|
+
if (bounds?.signal)
|
|
675
|
+
configOptions.signal = bounds.signal;
|
|
557
676
|
// Track token usage across tool iterations
|
|
558
677
|
let totalInputTokens = 0;
|
|
559
678
|
let totalOutputTokens = 0;
|
|
@@ -684,7 +803,33 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
684
803
|
});
|
|
685
804
|
}
|
|
686
805
|
session.startIteration("final-structured", conversationMessages);
|
|
687
|
-
|
|
806
|
+
// A timed-out attempt is RE-ISSUED ONCE on the same model instance, because
|
|
807
|
+
// that is what actually recovers a stall: the instance's
|
|
808
|
+
// `openRouterEscalatingFetch` closure escalates on its second request, so
|
|
809
|
+
// the retry allows fallbacks and OpenRouter reroutes off the provider that
|
|
810
|
+
// went quiet. (This is precisely how the 639s stall eventually resolved —
|
|
811
|
+
// the SDK's 600s abort, then a rerouted retry that answered in 39s. Here it
|
|
812
|
+
// happens after the attempt budget instead of after ten minutes.)
|
|
813
|
+
//
|
|
814
|
+
// A fresh call would NOT get this: `getLLM` builds a new instance per call,
|
|
815
|
+
// resetting the escalation, so a hard-pinned tier would retry straight back
|
|
816
|
+
// onto the stalled provider. An abort is the ONLY thing retried here —
|
|
817
|
+
// provider errors and parse failures stay the caller's business.
|
|
818
|
+
const invokeStructured = async () => (await structuredLlm.invoke(conversationMessages, Object.keys(configOptions).length > 0 ? configOptions : undefined));
|
|
819
|
+
let response;
|
|
820
|
+
try {
|
|
821
|
+
response = await invokeStructured();
|
|
822
|
+
}
|
|
823
|
+
catch (error) {
|
|
824
|
+
// The deadline's own abort is NOT a stall to reroute around — it means the
|
|
825
|
+
// whole call is over, so let it through.
|
|
826
|
+
if (!isTimeoutError(error) || bounds?.signal?.aborted)
|
|
827
|
+
throw error;
|
|
828
|
+
const msg = `[LLMService] attempt timed out after ${Math.round((bounds?.attemptTimeoutMs ?? 0) / 1000)}s — re-issuing with provider fallbacks escalated`;
|
|
829
|
+
console.warn(msg);
|
|
830
|
+
addWarning(msg);
|
|
831
|
+
response = await invokeStructured();
|
|
832
|
+
}
|
|
688
833
|
// Extract token usage with type guard (includes tool iteration tokens)
|
|
689
834
|
const raw = (0, llm_raw_response_1.isValidRaw)(response.raw) ? response.raw : undefined;
|
|
690
835
|
session.recordResponse({
|
|
@@ -910,7 +1055,7 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
910
1055
|
// the session open indefinitely. The AbortError surfaces as a rejection on
|
|
911
1056
|
// the awaited promises below (caught + logged).
|
|
912
1057
|
const controller = new AbortController();
|
|
913
|
-
const timeoutId = setTimeout(() => controller.abort(), params.timeout
|
|
1058
|
+
const timeoutId = setTimeout(() => controller.abort(), this.attemptTimeoutMs(params.timeout));
|
|
914
1059
|
// Schema cast: `streamObject`'s typing is a conditional union over the
|
|
915
1060
|
// output mode (`object` / `enum` / `array` / `no-schema`). Our T is always
|
|
916
1061
|
// a Zod object schema; the runtime call is correct.
|
|
@@ -1055,7 +1200,7 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
1055
1200
|
// Abort the stream if the provider stalls (see streamCall). The AbortError
|
|
1056
1201
|
// surfaces as a rejection on the awaited promises below (caught + logged).
|
|
1057
1202
|
const controller = new AbortController();
|
|
1058
|
-
const timeoutId = setTimeout(() => controller.abort(), params.timeout
|
|
1203
|
+
const timeoutId = setTimeout(() => controller.abort(), this.attemptTimeoutMs(params.timeout));
|
|
1059
1204
|
const streamResult = streamText({
|
|
1060
1205
|
model,
|
|
1061
1206
|
system,
|
|
@@ -1175,6 +1320,7 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
1175
1320
|
tools: [{ name: params.tool.name, description: params.tool.description, schema: params.tool.schema }],
|
|
1176
1321
|
outputSchemaName: params.tool.name,
|
|
1177
1322
|
});
|
|
1323
|
+
const attemptTimeoutMs = this.attemptTimeoutMs(params.timeout);
|
|
1178
1324
|
try {
|
|
1179
1325
|
const model = this.modelService.getLLM({
|
|
1180
1326
|
modelWeight,
|
|
@@ -1182,6 +1328,7 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
1182
1328
|
maxOutputTokens: params.maxOutputTokens,
|
|
1183
1329
|
frequencyPenalty: params.frequencyPenalty,
|
|
1184
1330
|
temperature: params.temperature,
|
|
1331
|
+
timeoutMs: attemptTimeoutMs,
|
|
1185
1332
|
});
|
|
1186
1333
|
const tool = new tools_1.DynamicStructuredTool({
|
|
1187
1334
|
name: params.tool.name,
|
|
@@ -1251,14 +1398,20 @@ let LLMService = LLMService_1 = class LLMService {
|
|
|
1251
1398
|
}
|
|
1252
1399
|
return null;
|
|
1253
1400
|
};
|
|
1254
|
-
|
|
1401
|
+
// Each provider invocation is bounded independently — the nudge retry is a
|
|
1402
|
+
// second request and gets its own budget, not the leftovers of the first.
|
|
1403
|
+
const invokeBounded = async (messages, attempt) => {
|
|
1404
|
+
const controller = new AbortController();
|
|
1405
|
+
return (await this.runBounded(`extractViaTool:${params.tool.name}:${attempt}`, attemptTimeoutMs, controller, () => bound.invoke(messages, { signal: controller.signal })));
|
|
1406
|
+
};
|
|
1407
|
+
let response = await invokeBounded(baseMessages, "attempt-1");
|
|
1255
1408
|
let parsed = tryExtract(response);
|
|
1256
1409
|
// One retry with an explicit nudge — local models frequently comply on a
|
|
1257
1410
|
// second pass once told plainly that prose is not acceptable.
|
|
1258
1411
|
if (parsed === null) {
|
|
1259
1412
|
describe(response, "attempt-1");
|
|
1260
1413
|
const nudge = new messages_1.HumanMessage(`You did NOT call the \`${params.tool.name}\` tool. Do not write prose, refusals, or explanations. Respond ONLY by calling \`${params.tool.name}\` with valid arguments now.`);
|
|
1261
|
-
response =
|
|
1414
|
+
response = await invokeBounded([...baseMessages, nudge], "attempt-2");
|
|
1262
1415
|
parsed = tryExtract(response);
|
|
1263
1416
|
if (parsed === null)
|
|
1264
1417
|
describe(response, "attempt-2");
|