@jxburros/ai-nugget 0.4.1 → 0.7.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.
Files changed (187) hide show
  1. package/README.md +158 -382
  2. package/UPGRADING.md +182 -0
  3. package/dist/adapters/engines/anthropic.d.ts +7 -1
  4. package/dist/adapters/engines/anthropic.js +82 -37
  5. package/dist/adapters/engines/base.d.ts +29 -2
  6. package/dist/adapters/engines/base.js +52 -8
  7. package/dist/adapters/engines/google.d.ts +7 -1
  8. package/dist/adapters/engines/google.js +80 -29
  9. package/dist/adapters/engines/ollama.d.ts +2 -1
  10. package/dist/adapters/engines/ollama.js +57 -15
  11. package/dist/adapters/engines/openaiChat.d.ts +8 -1
  12. package/dist/adapters/engines/openaiChat.js +109 -29
  13. package/dist/adapters/profiles.d.ts +21 -1
  14. package/dist/adapters/profiles.js +12 -2
  15. package/dist/agent/loop.d.ts +45 -1
  16. package/dist/agent/loop.js +117 -12
  17. package/dist/cjs/adapters/engines/anthropic.js +326 -0
  18. package/dist/cjs/adapters/engines/base.js +147 -0
  19. package/dist/cjs/adapters/engines/google.js +291 -0
  20. package/dist/cjs/adapters/engines/ollama.js +205 -0
  21. package/dist/cjs/adapters/engines/openaiChat.js +312 -0
  22. package/dist/cjs/adapters/index.js +22 -0
  23. package/dist/cjs/adapters/profiles.js +125 -0
  24. package/dist/cjs/agent/index.js +18 -0
  25. package/dist/cjs/agent/loop.js +373 -0
  26. package/dist/cjs/agent/tools.js +51 -0
  27. package/dist/cjs/connect.js +27 -0
  28. package/dist/cjs/errors.js +110 -0
  29. package/dist/cjs/handler.js +586 -0
  30. package/dist/cjs/index.js +28 -0
  31. package/dist/cjs/json.js +121 -0
  32. package/dist/cjs/keys.js +81 -0
  33. package/dist/cjs/package.json +3 -0
  34. package/dist/cjs/policy.js +42 -0
  35. package/dist/cjs/reasoning.js +159 -0
  36. package/dist/cjs/redact.js +78 -0
  37. package/dist/cjs/tokens.js +22 -0
  38. package/dist/cjs/transport.js +172 -0
  39. package/dist/cjs/types.js +6 -0
  40. package/dist/cjs/util.js +126 -0
  41. package/dist/errors.js +25 -1
  42. package/dist/handler.d.ts +67 -1
  43. package/dist/handler.js +266 -61
  44. package/dist/index.d.ts +1 -0
  45. package/dist/index.js +1 -0
  46. package/dist/reasoning.d.ts +45 -0
  47. package/dist/reasoning.js +154 -0
  48. package/dist/redact.d.ts +18 -0
  49. package/dist/redact.js +29 -1
  50. package/dist/transport.d.ts +3 -1
  51. package/dist/transport.js +21 -1
  52. package/dist/types.d.ts +112 -2
  53. package/dist/util.d.ts +22 -0
  54. package/dist/util.js +59 -0
  55. package/nugget/VERSION.txt +2 -2
  56. package/nugget/dist/adapters/engines/anthropic.d.ts +14 -0
  57. package/nugget/dist/adapters/engines/anthropic.d.ts.map +1 -0
  58. package/nugget/dist/adapters/engines/anthropic.js +323 -0
  59. package/nugget/dist/adapters/engines/anthropic.js.map +1 -0
  60. package/nugget/dist/adapters/engines/base.d.ts +50 -0
  61. package/nugget/dist/adapters/engines/base.d.ts.map +1 -0
  62. package/nugget/dist/adapters/engines/base.js +137 -0
  63. package/nugget/dist/adapters/engines/base.js.map +1 -0
  64. package/nugget/dist/adapters/engines/google.d.ts +24 -0
  65. package/nugget/dist/adapters/engines/google.d.ts.map +1 -0
  66. package/nugget/dist/adapters/engines/google.js +288 -0
  67. package/nugget/dist/adapters/engines/google.js.map +1 -0
  68. package/nugget/dist/adapters/engines/ollama.d.ts +11 -0
  69. package/nugget/dist/adapters/engines/ollama.d.ts.map +1 -0
  70. package/nugget/dist/adapters/engines/ollama.js +202 -0
  71. package/nugget/dist/adapters/engines/ollama.js.map +1 -0
  72. package/nugget/dist/adapters/engines/openaiChat.d.ts +22 -0
  73. package/nugget/dist/adapters/engines/openaiChat.d.ts.map +1 -0
  74. package/nugget/dist/adapters/engines/openaiChat.js +308 -0
  75. package/nugget/dist/adapters/engines/openaiChat.js.map +1 -0
  76. package/nugget/dist/adapters/index.d.ts +5 -0
  77. package/nugget/dist/adapters/index.d.ts.map +1 -0
  78. package/nugget/dist/adapters/index.js +17 -0
  79. package/nugget/dist/adapters/index.js.map +1 -0
  80. package/nugget/dist/adapters/profiles.d.ts +62 -0
  81. package/nugget/dist/adapters/profiles.d.ts.map +1 -0
  82. package/nugget/dist/adapters/profiles.js +121 -0
  83. package/nugget/dist/adapters/profiles.js.map +1 -0
  84. package/nugget/dist/agent/index.d.ts +3 -0
  85. package/nugget/dist/agent/index.d.ts.map +1 -0
  86. package/nugget/dist/agent/index.js +3 -0
  87. package/nugget/dist/agent/index.js.map +1 -0
  88. package/nugget/dist/agent/loop.d.ts +114 -0
  89. package/nugget/dist/agent/loop.d.ts.map +1 -0
  90. package/nugget/dist/agent/loop.js +371 -0
  91. package/nugget/dist/agent/loop.js.map +1 -0
  92. package/nugget/dist/agent/tools.d.ts +29 -0
  93. package/nugget/dist/agent/tools.d.ts.map +1 -0
  94. package/nugget/dist/agent/tools.js +48 -0
  95. package/nugget/dist/agent/tools.js.map +1 -0
  96. package/nugget/dist/cjs/adapters/engines/anthropic.js +326 -0
  97. package/nugget/dist/cjs/adapters/engines/base.js +147 -0
  98. package/nugget/dist/cjs/adapters/engines/google.js +291 -0
  99. package/nugget/dist/cjs/adapters/engines/ollama.js +205 -0
  100. package/nugget/dist/cjs/adapters/engines/openaiChat.js +312 -0
  101. package/nugget/dist/cjs/adapters/index.js +22 -0
  102. package/nugget/dist/cjs/adapters/profiles.js +125 -0
  103. package/nugget/dist/cjs/agent/index.js +18 -0
  104. package/nugget/dist/cjs/agent/loop.js +373 -0
  105. package/nugget/dist/cjs/agent/tools.js +51 -0
  106. package/nugget/dist/cjs/connect.js +27 -0
  107. package/nugget/dist/cjs/errors.js +110 -0
  108. package/nugget/dist/cjs/handler.js +586 -0
  109. package/nugget/dist/cjs/index.js +28 -0
  110. package/nugget/dist/cjs/json.js +121 -0
  111. package/nugget/dist/cjs/keys.js +81 -0
  112. package/nugget/dist/cjs/package.json +3 -0
  113. package/nugget/dist/cjs/policy.js +42 -0
  114. package/nugget/dist/cjs/reasoning.js +159 -0
  115. package/nugget/dist/cjs/redact.js +78 -0
  116. package/nugget/dist/cjs/tokens.js +22 -0
  117. package/nugget/dist/cjs/transport.js +172 -0
  118. package/nugget/dist/cjs/types.js +6 -0
  119. package/nugget/dist/cjs/util.js +126 -0
  120. package/nugget/dist/connect.d.ts +31 -0
  121. package/nugget/dist/connect.d.ts.map +1 -0
  122. package/nugget/dist/connect.js +25 -0
  123. package/nugget/dist/connect.js.map +1 -0
  124. package/nugget/dist/errors.d.ts +22 -0
  125. package/nugget/dist/errors.d.ts.map +1 -0
  126. package/nugget/dist/errors.js +104 -0
  127. package/nugget/dist/errors.js.map +1 -0
  128. package/nugget/dist/handler.d.ts +114 -0
  129. package/nugget/dist/handler.d.ts.map +1 -0
  130. package/nugget/dist/handler.js +582 -0
  131. package/nugget/dist/handler.js.map +1 -0
  132. package/nugget/dist/index.d.ts +13 -0
  133. package/nugget/dist/index.d.ts.map +1 -0
  134. package/nugget/dist/index.js +13 -0
  135. package/nugget/dist/index.js.map +1 -0
  136. package/nugget/dist/json.d.ts +7 -0
  137. package/nugget/dist/json.d.ts.map +1 -0
  138. package/nugget/dist/json.js +114 -0
  139. package/nugget/dist/json.js.map +1 -0
  140. package/nugget/dist/keys.d.ts +7 -0
  141. package/nugget/dist/keys.d.ts.map +1 -0
  142. package/nugget/dist/keys.js +75 -0
  143. package/nugget/dist/keys.js.map +1 -0
  144. package/nugget/dist/policy.d.ts +6 -0
  145. package/nugget/dist/policy.d.ts.map +1 -0
  146. package/nugget/dist/policy.js +37 -0
  147. package/nugget/dist/policy.js.map +1 -0
  148. package/nugget/dist/reasoning.d.ts +45 -0
  149. package/nugget/dist/reasoning.d.ts.map +1 -0
  150. package/nugget/dist/reasoning.js +154 -0
  151. package/nugget/dist/reasoning.js.map +1 -0
  152. package/nugget/dist/redact.d.ts +26 -0
  153. package/nugget/dist/redact.d.ts.map +1 -0
  154. package/nugget/dist/redact.js +74 -0
  155. package/nugget/dist/redact.js.map +1 -0
  156. package/nugget/dist/tokens.d.ts +5 -0
  157. package/nugget/dist/tokens.d.ts.map +1 -0
  158. package/nugget/dist/tokens.js +18 -0
  159. package/nugget/dist/tokens.js.map +1 -0
  160. package/nugget/dist/transport.d.ts +30 -0
  161. package/nugget/dist/transport.d.ts.map +1 -0
  162. package/nugget/dist/transport.js +165 -0
  163. package/nugget/dist/transport.js.map +1 -0
  164. package/nugget/dist/types.d.ts +301 -0
  165. package/nugget/dist/types.d.ts.map +1 -0
  166. package/nugget/dist/types.js +4 -0
  167. package/nugget/dist/types.js.map +1 -0
  168. package/nugget/dist/util.d.ts +31 -0
  169. package/nugget/dist/util.d.ts.map +1 -0
  170. package/nugget/dist/util.js +114 -0
  171. package/nugget/dist/util.js.map +1 -0
  172. package/nugget/src/adapters/engines/anthropic.ts +78 -37
  173. package/nugget/src/adapters/engines/base.ts +50 -7
  174. package/nugget/src/adapters/engines/google.ts +79 -29
  175. package/nugget/src/adapters/engines/ollama.ts +56 -17
  176. package/nugget/src/adapters/engines/openaiChat.ts +104 -30
  177. package/nugget/src/adapters/profiles.ts +53 -3
  178. package/nugget/src/agent/loop.ts +156 -13
  179. package/nugget/src/errors.ts +25 -1
  180. package/nugget/src/handler.ts +308 -59
  181. package/nugget/src/index.ts +1 -0
  182. package/nugget/src/reasoning.ts +174 -0
  183. package/nugget/src/redact.ts +32 -1
  184. package/nugget/src/transport.ts +20 -1
  185. package/nugget/src/types.ts +113 -1
  186. package/nugget/src/util.ts +64 -0
  187. package/package.json +18 -5
@@ -0,0 +1,126 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REASONING_BUDGET_TOKENS = void 0;
4
+ exports.asRecord = asRecord;
5
+ exports.asString = asString;
6
+ exports.asNumber = asNumber;
7
+ exports.promptChars = promptChars;
8
+ exports.textFromMessages = textFromMessages;
9
+ exports.globalEnv = globalEnv;
10
+ exports.applyProviderOptions = applyProviderOptions;
11
+ exports.joinUrl = joinUrl;
12
+ exports.mapWithConcurrency = mapWithConcurrency;
13
+ exports.sleep = sleep;
14
+ function asRecord(value) {
15
+ return value && typeof value === 'object' && !Array.isArray(value) ? value : undefined;
16
+ }
17
+ function asString(value) {
18
+ return typeof value === 'string' ? value : undefined;
19
+ }
20
+ function asNumber(value) {
21
+ return typeof value === 'number' && Number.isFinite(value) ? value : undefined;
22
+ }
23
+ function promptChars(messages) {
24
+ return messages.reduce((sum, message) => {
25
+ if (typeof message.content === 'string')
26
+ return sum + message.content.length;
27
+ return sum + message.content.reduce((partSum, part) => partSum + (part.text?.length ?? 0) + (part.imageBase64?.length ?? 0), 0);
28
+ }, 0);
29
+ }
30
+ function textFromMessages(messages) {
31
+ return messages.map((message) => {
32
+ if (typeof message.content === 'string')
33
+ return message.content;
34
+ return message.content.map((part) => part.text ?? '').join('');
35
+ }).join('\n');
36
+ }
37
+ function globalEnv() {
38
+ const maybeProcess = globalThis;
39
+ return maybeProcess.process?.env ?? {};
40
+ }
41
+ /**
42
+ * Merges app-supplied {@link ChatRequest.providerOptions} into a provider
43
+ * request body: shallow at the top level, and one level deep for each key in
44
+ * `nestedKeys` where both sides are plain objects (Ollama `options`, Google
45
+ * `generationConfig`). Values in `providerOptions` win on collision.
46
+ */
47
+ function applyProviderOptions(body, providerOptions, nestedKeys = []) {
48
+ if (!providerOptions)
49
+ return body;
50
+ const merged = { ...body };
51
+ for (const [key, value] of Object.entries(providerOptions)) {
52
+ const base = asRecord(merged[key]);
53
+ if (nestedKeys.includes(key) && base && asRecord(value)) {
54
+ merged[key] = { ...base, ...value };
55
+ }
56
+ else {
57
+ merged[key] = value;
58
+ }
59
+ }
60
+ return merged;
61
+ }
62
+ /** Joins a base URL and path without producing a double slash, even if `base` ends with `/`. */
63
+ function joinUrl(base, path) {
64
+ return `${base.replace(/\/+$/, '')}/${path.replace(/^\/+/, '')}`;
65
+ }
66
+ /**
67
+ * Runs `fn` over `items` with at most `limit` in flight at once, preserving
68
+ * input order in the returned array. Used to probe many local models
69
+ * concurrently without opening an unbounded number of sockets.
70
+ */
71
+ async function mapWithConcurrency(items, limit, fn) {
72
+ const results = new Array(items.length);
73
+ let next = 0;
74
+ const workerCount = Math.max(1, Math.min(limit, items.length));
75
+ const worker = async () => {
76
+ for (;;) {
77
+ const index = next;
78
+ next += 1;
79
+ if (index >= items.length)
80
+ return;
81
+ results[index] = await fn(items[index], index);
82
+ }
83
+ };
84
+ await Promise.all(Array.from({ length: workerCount }, worker));
85
+ return results;
86
+ }
87
+ function sleep(ms, signal) {
88
+ if (ms <= 0)
89
+ return Promise.resolve();
90
+ return new Promise((resolve, reject) => {
91
+ let settled = false;
92
+ const cleanup = () => signal?.removeEventListener('abort', onAbort);
93
+ const timer = setTimeout(() => {
94
+ settled = true;
95
+ cleanup();
96
+ resolve();
97
+ }, ms);
98
+ const onAbort = () => {
99
+ if (settled)
100
+ return;
101
+ settled = true;
102
+ clearTimeout(timer);
103
+ cleanup();
104
+ reject(new DOMException('Sleep aborted', 'AbortError'));
105
+ };
106
+ if (signal) {
107
+ if (signal.aborted)
108
+ onAbort();
109
+ else
110
+ signal.addEventListener('abort', onAbort, { once: true });
111
+ }
112
+ });
113
+ }
114
+ /**
115
+ * Token budgets behind the {@link ReasoningEffort} tiers for providers that
116
+ * express effort as a thinking-token budget (Anthropic `budget_tokens`, Google
117
+ * `thinkingBudget`). `'none'` is 0. Deliberately conservative: they are floors
118
+ * a model may stop under, not ceilings it fills.
119
+ */
120
+ exports.REASONING_BUDGET_TOKENS = {
121
+ none: 0,
122
+ minimal: 1024,
123
+ low: 2048,
124
+ medium: 8192,
125
+ high: 16384,
126
+ };
package/dist/errors.js CHANGED
@@ -1,3 +1,12 @@
1
+ import { createDefaultRedactor } from './redact.js';
2
+ /**
3
+ * Pattern-based redaction applied at the wire boundary, before an error object
4
+ * exists. `AIHandler` redacts again on the way out (adding session-registered
5
+ * exact secrets), but doing it here means a provider body that echoes a
6
+ * recognizable secret can never be carried by an `AIError` in the first place —
7
+ * including on code paths that never reach the handler's own catch blocks.
8
+ */
9
+ const wireRedactor = createDefaultRedactor();
1
10
  export class AIError extends Error {
2
11
  kind;
3
12
  status;
@@ -26,9 +35,13 @@ export function defaultRetryable(kind) {
26
35
  return kind === 'rate_limit' || kind === 'timeout' || kind === 'network' || kind === 'server' || kind === 'invalid_response';
27
36
  }
28
37
  export function classify(status, body = '', provider, headers) {
29
- const excerpt = body.slice(0, 200);
38
+ const excerpt = wireRedactor.redact(body.slice(0, 200));
30
39
  const lower = body.toLowerCase();
31
40
  let kind = 'server';
41
+ // 403 is classified as `auth` (non-retryable) deliberately: a forbidden
42
+ // response almost always means a bad/insufficient credential or a blocked
43
+ // region/model, none of which a retry fixes. Callers that know a specific
44
+ // provider returns a retryable 403 can reclassify in a `beforeCall`/adapter.
32
45
  if (status === 401 || status === 403)
33
46
  kind = 'auth';
34
47
  else if (status === 408)
@@ -40,8 +53,19 @@ export function classify(status, body = '', provider, headers) {
40
53
  ? 'context_length'
41
54
  : 'invalid_request';
42
55
  }
56
+ else if (status === 404 || status === 410) {
57
+ // A missing route/deployment is not a malformed request: it is usually a
58
+ // wrong baseUrl or model name, and sometimes a temporarily misrouted load
59
+ // balancer. `not_found` keeps it distinguishable from `invalid_request` so
60
+ // apps don't tell a user "your request was invalid" for an infra problem.
61
+ // Non-retryable by default — a caller that knows its 404s are transient can
62
+ // retry on `kind === 'not_found'` itself.
63
+ kind = 'not_found';
64
+ }
43
65
  else if (status >= 500)
44
66
  kind = 'server';
67
+ // Everything else in 4xx (409 conflict, 405, 415, 451, …) is a genuine
68
+ // client-side request problem, so `invalid_request` is honest for it.
45
69
  else
46
70
  kind = 'invalid_request';
47
71
  return new AIError(`HTTP ${status}: ${excerpt}`, {
package/dist/handler.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { CallInfo, CallRecord, ChatRequest, ChatResult, Connection, GovernancePolicy, KeySource, ModelInfo, Redactor, StreamEvent, TelemetrySink } from './types.js';
1
+ import type { CallInfo, CallRecord, ChatRequest, ChatResult, Connection, EmbedRequest, EmbedResult, GovernancePolicy, KeySource, ModelInfo, ParsedResult, Redactor, StandardSchemaV1, StreamEvent, TelemetrySink, Usage } from './types.js';
2
2
  export interface HandlerOptions {
3
3
  keySource: KeySource;
4
4
  policy?: GovernancePolicy;
@@ -13,11 +13,43 @@ export interface HandlerOptions {
13
13
  baseDelayMs?: number;
14
14
  maxDelayMs?: number;
15
15
  };
16
+ /**
17
+ * Concurrency and pacing limits, enforced by an **in-memory queue on this
18
+ * handler instance only**. There is no shared/external coordination, so N
19
+ * instances behind a load balancer allow N × `maxConcurrent` in flight against
20
+ * the provider. Size these per instance, or put a shared limiter in front if a
21
+ * global ceiling matters.
22
+ */
16
23
  limits?: {
17
24
  maxConcurrent?: number;
18
25
  minIntervalMs?: number;
19
26
  };
27
+ /**
28
+ * Silence the one-time startup notice logged when no `policy` is supplied.
29
+ * Set this only when running unrestricted is a deliberate choice — passing an
30
+ * explicit `policy: allowAllPolicy()` says the same thing and is clearer.
31
+ */
32
+ silencePolicyWarning?: boolean;
33
+ /**
34
+ * Strip inline `<think>…</think>`-style reasoning out of `delta` events and `ChatResult.text`,
35
+ * emitting it as `{ type: 'reasoning' }` events instead (default `true`; see `src/reasoning.ts`).
36
+ * Set `false` to receive the raw answer text exactly as the provider sent it.
37
+ */
38
+ stripInlineReasoning?: boolean;
39
+ /**
40
+ * Optional cost estimator. Called once per successful call/embedding with the
41
+ * final usage; its return value (USD) is stored on the telemetry record's
42
+ * `costUsd`. Return undefined to leave a call uncosted. Pricing tables live in
43
+ * the app, not the library — this is only the seam to attach one.
44
+ */
45
+ pricing?(info: {
46
+ provider: string;
47
+ model: string;
48
+ usage: Usage;
49
+ }): number | undefined;
20
50
  }
51
+ /** Test seam: reset the once-per-process startup notice. */
52
+ export declare function resetPolicyWarningForTests(): void;
21
53
  export declare class AIHandler {
22
54
  private opts;
23
55
  private active;
@@ -28,11 +60,45 @@ export declare class AIHandler {
28
60
  constructor(opts: HandlerOptions);
29
61
  chat(conn: Connection, req: ChatRequest): Promise<ChatResult>;
30
62
  stream(conn: Connection, req: ChatRequest): AsyncIterable<StreamEvent>;
63
+ /**
64
+ * The shared pre-call preamble: policy check → key resolution → `beforeCall`
65
+ * hook. Every entry point (`stream`, `embed`, `listModels`/`testConnection`)
66
+ * runs exactly this sequence, so it lives once. Failures are *returned*, not
67
+ * recorded — each caller owns its own telemetry shape (`recordFailure` for
68
+ * chat/probe, `recordEmbed` for embeddings) and records the returned error.
69
+ */
70
+ private preflight;
71
+ /** Record a failed call and emit the single redacted `error` event for it. */
72
+ private failStream;
31
73
  listModels(conn: Connection): Promise<ModelInfo[]>;
32
74
  testConnection(conn: Connection): Promise<{
33
75
  ok: boolean;
34
76
  message: string;
35
77
  }>;
78
+ /**
79
+ * Warm a connection so the first real call doesn't pay cold DNS/TLS and
80
+ * (for a local daemon) process spin-up on the hot path. Runs a lightweight
81
+ * health probe and never throws — call it once at boot. Combined with a CJS
82
+ * `require` path it removes the cold-start "offline" false negative.
83
+ */
84
+ prewarm(conn: Connection): Promise<void>;
85
+ /**
86
+ * Chat that returns typed, validated output. Requests JSON mode, extracts the
87
+ * JSON from the reply, and validates it against any Standard Schema validator
88
+ * (Zod / Valibot / ArkType). On a validation miss it performs exactly one
89
+ * corrective retry that shows the model its error, then throws
90
+ * `invalid_response` if still invalid. No schema library is bundled — the
91
+ * caller supplies the schema.
92
+ */
93
+ chatParsed<T>(conn: Connection, req: ChatRequest, schema: StandardSchemaV1<T>): Promise<ParsedResult<T>>;
94
+ /**
95
+ * Produce embeddings through the same governed pipeline as chat: policy check,
96
+ * key resolution, `beforeCall` hook, concurrency, and exactly one redacted
97
+ * telemetry record. Throws a typed `invalid_request` error for providers whose
98
+ * adapter has no `embed` (Anthropic, Google) rather than failing silently.
99
+ */
100
+ embed(conn: Connection, req: EmbedRequest): Promise<EmbedResult>;
101
+ private recordEmbed;
36
102
  private runProbe;
37
103
  private resolveConnection;
38
104
  private acquire;