@halo-sdk/strategies 1.0.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/README.md +6 -0
- package/dist/basic-repair.d.ts +5 -0
- package/dist/basic-repair.d.ts.map +1 -0
- package/dist/basic-repair.js +101 -0
- package/dist/basic-repair.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/truncate.d.ts +14 -0
- package/dist/truncate.d.ts.map +1 -0
- package/dist/truncate.js +34 -0
- package/dist/truncate.js.map +1 -0
- package/package.json +47 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-repair.d.ts","sourceRoot":"","sources":["../src/basic-repair.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE7E,qBAAa,WAAY,YAAW,cAAc;IAChD,MAAM,CAAC,SAAS,EAAE,QAAQ,EAAE,EAAE,WAAW,EAAE,MAAM,GAAG,YAAY;CAyBjE"}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
export class BasicRepair {
|
|
2
|
+
repair(toolCalls, _rawContent) {
|
|
3
|
+
const repaired = [];
|
|
4
|
+
let fixed = 0;
|
|
5
|
+
for (const call of toolCalls) {
|
|
6
|
+
const args = call.function?.arguments ?? "";
|
|
7
|
+
const fix = tryFixTruncatedJson(args);
|
|
8
|
+
if (fix !== args) {
|
|
9
|
+
fixed++;
|
|
10
|
+
repaired.push({
|
|
11
|
+
...call,
|
|
12
|
+
function: { ...call.function, arguments: fix },
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
repaired.push(call);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return {
|
|
20
|
+
toolCalls: repaired,
|
|
21
|
+
fixed,
|
|
22
|
+
suppressed: 0,
|
|
23
|
+
notes: fixed > 0 ? [`fixed ${fixed} truncated JSON argument(s)`] : [],
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function tryFixTruncatedJson(raw) {
|
|
28
|
+
if (!raw || !raw.trim())
|
|
29
|
+
return raw;
|
|
30
|
+
// Try direct parse first.
|
|
31
|
+
try {
|
|
32
|
+
JSON.parse(raw);
|
|
33
|
+
return raw;
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
/* needs fixing */
|
|
37
|
+
}
|
|
38
|
+
// Count unbalanced brackets and braces.
|
|
39
|
+
let braces = 0;
|
|
40
|
+
let brackets = 0;
|
|
41
|
+
let inString = false;
|
|
42
|
+
let escaped = false;
|
|
43
|
+
for (const ch of raw) {
|
|
44
|
+
if (escaped) {
|
|
45
|
+
escaped = false;
|
|
46
|
+
continue;
|
|
47
|
+
}
|
|
48
|
+
if (ch === "\\") {
|
|
49
|
+
escaped = true;
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
if (ch === '"') {
|
|
53
|
+
inString = !inString;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
if (inString)
|
|
57
|
+
continue;
|
|
58
|
+
if (ch === "{")
|
|
59
|
+
braces++;
|
|
60
|
+
if (ch === "}")
|
|
61
|
+
braces--;
|
|
62
|
+
if (ch === "[")
|
|
63
|
+
brackets++;
|
|
64
|
+
if (ch === "]")
|
|
65
|
+
brackets--;
|
|
66
|
+
}
|
|
67
|
+
// Also fix unterminated string.
|
|
68
|
+
if (inString) {
|
|
69
|
+
let fixed = raw;
|
|
70
|
+
// Close the string before closing brackets.
|
|
71
|
+
if (braces > 0 || brackets > 0)
|
|
72
|
+
fixed += '"';
|
|
73
|
+
while (braces > 0) {
|
|
74
|
+
fixed += "}";
|
|
75
|
+
braces--;
|
|
76
|
+
}
|
|
77
|
+
while (brackets > 0) {
|
|
78
|
+
fixed += "]";
|
|
79
|
+
brackets--;
|
|
80
|
+
}
|
|
81
|
+
return fixed;
|
|
82
|
+
}
|
|
83
|
+
let fixed = raw;
|
|
84
|
+
while (braces > 0) {
|
|
85
|
+
fixed += "}";
|
|
86
|
+
braces--;
|
|
87
|
+
}
|
|
88
|
+
while (brackets > 0) {
|
|
89
|
+
fixed += "]";
|
|
90
|
+
brackets--;
|
|
91
|
+
}
|
|
92
|
+
// Verify the fix is valid JSON.
|
|
93
|
+
try {
|
|
94
|
+
JSON.parse(fixed);
|
|
95
|
+
return fixed;
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return raw;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
//# sourceMappingURL=basic-repair.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basic-repair.js","sourceRoot":"","sources":["../src/basic-repair.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,WAAW;IACtB,MAAM,CAAC,SAAqB,EAAE,WAAmB;QAC/C,MAAM,QAAQ,GAAe,EAAE,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC,CAAC;QAEd,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,IAAI,EAAE,CAAC;YAC5C,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;YACtC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACjB,KAAK,EAAE,CAAC;gBACR,QAAQ,CAAC,IAAI,CAAC;oBACZ,GAAG,IAAI;oBACP,QAAQ,EAAE,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,EAAE,GAAG,EAAE;iBAC/C,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;QAED,OAAO;YACL,SAAS,EAAE,QAAQ;YACnB,KAAK;YACL,UAAU,EAAE,CAAC;YACb,KAAK,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,KAAK,6BAA6B,CAAC,CAAC,CAAC,CAAC,EAAE;SACtE,CAAC;IACJ,CAAC;CACF;AAED,SAAS,mBAAmB,CAAC,GAAW;IACtC,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE;QAAE,OAAO,GAAG,CAAC;IAEpC,0BAA0B;IAC1B,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAChB,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACP,kBAAkB;IACpB,CAAC;IAED,wCAAwC;IACxC,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;QACrB,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,GAAG,KAAK,CAAC;YAChB,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAChB,OAAO,GAAG,IAAI,CAAC;YACf,SAAS;QACX,CAAC;QACD,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,QAAQ,GAAG,CAAC,QAAQ,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,QAAQ;YAAE,SAAS;QACvB,IAAI,EAAE,KAAK,GAAG;YAAE,MAAM,EAAE,CAAC;QACzB,IAAI,EAAE,KAAK,GAAG;YAAE,MAAM,EAAE,CAAC;QACzB,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,EAAE,CAAC;QAC3B,IAAI,EAAE,KAAK,GAAG;YAAE,QAAQ,EAAE,CAAC;IAC7B,CAAC;IAED,gCAAgC;IAChC,IAAI,QAAQ,EAAE,CAAC;QACb,IAAI,KAAK,GAAG,GAAG,CAAC;QAChB,4CAA4C;QAC5C,IAAI,MAAM,GAAG,CAAC,IAAI,QAAQ,GAAG,CAAC;YAAE,KAAK,IAAI,GAAG,CAAC;QAC7C,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;YAClB,KAAK,IAAI,GAAG,CAAC;YACb,MAAM,EAAE,CAAC;QACX,CAAC;QACD,OAAO,QAAQ,GAAG,CAAC,EAAE,CAAC;YACpB,KAAK,IAAI,GAAG,CAAC;YACb,QAAQ,EAAE,CAAC;QACb,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,IAAI,KAAK,GAAG,GAAG,CAAC;IAChB,OAAO,MAAM,GAAG,CAAC,EAAE,CAAC;QAClB,KAAK,IAAI,GAAG,CAAC;QACb,MAAM,EAAE,CAAC;IACX,CAAC;IACD,OAAO,QAAQ,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,IAAI,GAAG,CAAC;QACb,QAAQ,EAAE,CAAC;IACb,CAAC;IAED,gCAAgC;IAChC,IAAI,CAAC;QACH,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QAClB,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,GAAG,CAAC;IACb,CAAC;AACH,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ChatMessage, ContextStrategy } from "@halo-sdk/core";
|
|
2
|
+
export declare class TruncateStrategy implements ContextStrategy {
|
|
3
|
+
private _maxTokens;
|
|
4
|
+
constructor(opts?: {
|
|
5
|
+
maxTokens?: number;
|
|
6
|
+
});
|
|
7
|
+
prepare(prefix: ChatMessage[], history: ChatMessage[], _ctxMax: number): {
|
|
8
|
+
history: ChatMessage[];
|
|
9
|
+
modified: boolean;
|
|
10
|
+
summary?: string;
|
|
11
|
+
droppedCount: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=truncate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truncate.d.ts","sourceRoot":"","sources":["../src/truncate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEnE,qBAAa,gBAAiB,YAAW,eAAe;IACtD,OAAO,CAAC,UAAU,CAAS;gBAEf,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE;IAKzC,OAAO,CACL,MAAM,EAAE,WAAW,EAAE,EACrB,OAAO,EAAE,WAAW,EAAE,EACtB,OAAO,EAAE,MAAM,GACd;QACD,OAAO,EAAE,WAAW,EAAE,CAAC;QACvB,QAAQ,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,YAAY,EAAE,MAAM,CAAC;KACtB;CA6BF"}
|
package/dist/truncate.js
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export class TruncateStrategy {
|
|
2
|
+
_maxTokens;
|
|
3
|
+
constructor(opts) {
|
|
4
|
+
// Default: 80% of a 128K context window.
|
|
5
|
+
this._maxTokens = opts?.maxTokens ?? 102_400;
|
|
6
|
+
}
|
|
7
|
+
prepare(prefix, history, _ctxMax) {
|
|
8
|
+
// Prefix is read-only — only history may be truncated.
|
|
9
|
+
const histEstimate = history.reduce((sum, m) => sum + m.content.length, 0);
|
|
10
|
+
const prefixEstimate = prefix.reduce((sum, m) => sum + m.content.length, 0);
|
|
11
|
+
const budgetChars = (this._maxTokens - prefixEstimate / 4) * 4;
|
|
12
|
+
if (histEstimate <= budgetChars * 0.9) {
|
|
13
|
+
return { history, modified: false, droppedCount: 0 };
|
|
14
|
+
}
|
|
15
|
+
// Keep the most recent messages that fit the remaining budget.
|
|
16
|
+
let tailTokens = 0;
|
|
17
|
+
const tail = [];
|
|
18
|
+
for (let i = history.length - 1; i >= 0; i--) {
|
|
19
|
+
const msg = history[i];
|
|
20
|
+
const size = msg.content.length;
|
|
21
|
+
if (tailTokens + size > budgetChars * 0.9)
|
|
22
|
+
break;
|
|
23
|
+
tailTokens += size;
|
|
24
|
+
tail.unshift(msg);
|
|
25
|
+
}
|
|
26
|
+
const droppedCount = history.length - tail.length;
|
|
27
|
+
return {
|
|
28
|
+
history: tail,
|
|
29
|
+
modified: droppedCount > 0,
|
|
30
|
+
droppedCount,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=truncate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"truncate.js","sourceRoot":"","sources":["../src/truncate.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,gBAAgB;IACnB,UAAU,CAAS;IAE3B,YAAY,IAA6B;QACvC,yCAAyC;QACzC,IAAI,CAAC,UAAU,GAAG,IAAI,EAAE,SAAS,IAAI,OAAO,CAAC;IAC/C,CAAC;IAED,OAAO,CACL,MAAqB,EACrB,OAAsB,EACtB,OAAe;QAOf,uDAAuD;QACvD,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC3E,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QAC5E,MAAM,WAAW,GAAG,CAAC,IAAI,CAAC,UAAU,GAAG,cAAc,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;QAE/D,IAAI,YAAY,IAAI,WAAW,GAAG,GAAG,EAAE,CAAC;YACtC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,EAAE,CAAC;QACvD,CAAC;QAED,+DAA+D;QAC/D,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,MAAM,IAAI,GAAkB,EAAE,CAAC;QAC/B,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC7C,MAAM,GAAG,GAAG,OAAO,CAAC,CAAC,CAAE,CAAC;YACxB,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC;YAChC,IAAI,UAAU,GAAG,IAAI,GAAG,WAAW,GAAG,GAAG;gBAAE,MAAM;YACjD,UAAU,IAAI,IAAI,CAAC;YACnB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACpB,CAAC;QAED,MAAM,YAAY,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAElD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,QAAQ,EAAE,YAAY,GAAG,CAAC;YAC1B,YAAY;SACb,CAAC;IACJ,CAAC;CACF"}
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@halo-sdk/strategies",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Pluggable strategies for Halo AI SDK — context window truncation and JSON repair",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"keywords": [
|
|
7
|
+
"ai",
|
|
8
|
+
"llm",
|
|
9
|
+
"context-window",
|
|
10
|
+
"truncation",
|
|
11
|
+
"json-repair"
|
|
12
|
+
],
|
|
13
|
+
"repository": {
|
|
14
|
+
"type": "git",
|
|
15
|
+
"url": "https://github.com/halo-sdk/halo-ai",
|
|
16
|
+
"directory": "packages/strategies"
|
|
17
|
+
},
|
|
18
|
+
"files": [
|
|
19
|
+
"dist"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/index.d.ts",
|
|
27
|
+
"import": "./dist/index.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"@halo-sdk/core": ">=1.0.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"typescript": "^5.8.0",
|
|
38
|
+
"vitest": "^3.0.0",
|
|
39
|
+
"@halo-sdk/core": "1.0.0"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"build": "tsc",
|
|
43
|
+
"dev": "tsc --watch",
|
|
44
|
+
"test": "vitest run",
|
|
45
|
+
"test:watch": "vitest"
|
|
46
|
+
}
|
|
47
|
+
}
|