@ngockhoale/ukit 3.1.5 → 3.1.6
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
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to UKit are documented here.
|
|
4
4
|
|
|
5
|
+
## 3.1.6 - 2026-09-26
|
|
6
|
+
|
|
7
|
+
- **Decision endpoint URL normalization**: a `UKIT_DECISION_BASE_URL` that already ends in `/v1` (OpenAI convention) no longer produces `…/v1/v1/chat/completions`; the client strips a trailing `/v1` before joining. Applied to `src/decision/client.js` and mirrored in `unic-decision.mjs`.
|
|
8
|
+
|
|
5
9
|
## 3.1.5 - 2026-09-26
|
|
6
10
|
|
|
7
11
|
- **Install/update warns when the decision lane has no API key.** After a project refresh, `ukit install` (and `ukit update`'s refresh) prints a bold-red warning with setup instructions — `ukit decision --base-url <url> --key <key>`, `~/.ukit/storage/gatewayDecision.json`, or `UKIT_DECISION_API_KEY` — whenever no dedicated decision key and no shared UNIC token are resolvable. When a key (or the shared UNIC token fallback) is found, a one-line confirmation is printed instead.
|
package/package.json
CHANGED
package/src/decision/client.js
CHANGED
|
@@ -56,6 +56,15 @@ const DEFAULT_CHECKPOINTS = {
|
|
|
56
56
|
const FALLBACK_CHECKPOINT = 'unic-decision';
|
|
57
57
|
|
|
58
58
|
const DEFAULT_TIMEOUT_MS = 5000;
|
|
59
|
+
|
|
60
|
+
// Join `<baseUrl>/v1/chat/completions` tolerantly: users reasonably paste a
|
|
61
|
+
// base that already ends in /v1 (OpenAI convention). Strip a trailing /v1
|
|
62
|
+
// before appending so `.../v1` and `.../` yield the same endpoint.
|
|
63
|
+
function decisionCompletionsUrl(baseUrl) {
|
|
64
|
+
const trimmed = String(baseUrl).replace(/\/+$/, '').replace(/\/v1$/i, '');
|
|
65
|
+
return `${trimmed}/v1/chat/completions`;
|
|
66
|
+
}
|
|
67
|
+
|
|
59
68
|
const DEFAULT_MAX_RETRIES = 1;
|
|
60
69
|
const DEFAULT_BREAKER = { failureThreshold: 3, cooldownMs: 30_000 };
|
|
61
70
|
|
|
@@ -218,7 +227,7 @@ export function createDecisionClient({
|
|
|
218
227
|
if (!base?.baseUrl) return null;
|
|
219
228
|
const key = await resolveDecisionApiKey({ projectRoot, homeDir, env });
|
|
220
229
|
return {
|
|
221
|
-
url: `${
|
|
230
|
+
url: `${decisionCompletionsUrl(base.baseUrl)}`,
|
|
222
231
|
headers: buildAuthHeaders(key),
|
|
223
232
|
};
|
|
224
233
|
}
|
|
@@ -486,6 +486,15 @@ const DEFAULT_CHECKPOINTS = {
|
|
|
486
486
|
|
|
487
487
|
const DEFAULT_TIMEOUT_MS = 5000;
|
|
488
488
|
const DEFAULT_MAX_RETRIES = 1;
|
|
489
|
+
|
|
490
|
+
// Join `<baseUrl>/v1/chat/completions` tolerantly: users reasonably paste a
|
|
491
|
+
// base that already ends in /v1 (OpenAI convention). Strip a trailing /v1
|
|
492
|
+
// before appending so `.../v1` and `.../` yield the same endpoint.
|
|
493
|
+
function decisionCompletionsUrl(baseUrl) {
|
|
494
|
+
const trimmed = String(baseUrl).replace(/\/+$/, '').replace(/\/v1$/i, '');
|
|
495
|
+
return `${trimmed}/v1/chat/completions`;
|
|
496
|
+
}
|
|
497
|
+
|
|
489
498
|
const DEFAULT_STATE_LIMITS = { multilingual: 1024, english: 512 };
|
|
490
499
|
|
|
491
500
|
function decisionPlaneConfig(config) {
|
|
@@ -671,7 +680,7 @@ export async function requestBatch(batch, {
|
|
|
671
680
|
}
|
|
672
681
|
const key = resolveDecisionApiKey({ projectRoot, homeDir, env });
|
|
673
682
|
const endpoint = {
|
|
674
|
-
url:
|
|
683
|
+
url: decisionCompletionsUrl(base.baseUrl),
|
|
675
684
|
headers: buildAuthHeaders(key),
|
|
676
685
|
};
|
|
677
686
|
|
|
@@ -801,7 +810,7 @@ export async function runHealthProbe({
|
|
|
801
810
|
try {
|
|
802
811
|
const res = await postWithDeadline(
|
|
803
812
|
transport,
|
|
804
|
-
|
|
813
|
+
decisionCompletionsUrl(base.baseUrl),
|
|
805
814
|
buildAuthHeaders(key),
|
|
806
815
|
body,
|
|
807
816
|
timeoutMs,
|