@nhtio/adk 1.20260607.0 → 1.20260607.2
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 +29 -0
- package/common-BUIjZ6LV.mjs +119 -0
- package/common-BUIjZ6LV.mjs.map +1 -0
- package/common-DeNipTQI.js +148 -0
- package/common-DeNipTQI.js.map +1 -0
- package/eslint/index.d.ts +106 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs +57 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.cjs.map +1 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.d.ts +21 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs +52 -0
- package/eslint/rules/artifact_tool_forbids_artifact_constructor.mjs.map +1 -0
- package/eslint/rules/common.d.ts +41 -0
- package/eslint/rules/index.d.ts +12 -0
- package/eslint/rules/no_model_in_tool_handler.cjs +64 -0
- package/eslint/rules/no_model_in_tool_handler.cjs.map +1 -0
- package/eslint/rules/no_model_in_tool_handler.d.ts +26 -0
- package/eslint/rules/no_model_in_tool_handler.mjs +59 -0
- package/eslint/rules/no_model_in_tool_handler.mjs.map +1 -0
- package/eslint/rules/require_validator_any_required.cjs +100 -0
- package/eslint/rules/require_validator_any_required.cjs.map +1 -0
- package/eslint/rules/require_validator_any_required.d.ts +31 -0
- package/eslint/rules/require_validator_any_required.mjs +95 -0
- package/eslint/rules/require_validator_any_required.mjs.map +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.cjs +71 -0
- package/eslint/rules/thought_payload_requires_replay_tag.cjs.map +1 -0
- package/eslint/rules/thought_payload_requires_replay_tag.d.ts +26 -0
- package/eslint/rules/thought_payload_requires_replay_tag.mjs +66 -0
- package/eslint/rules/thought_payload_requires_replay_tag.mjs.map +1 -0
- package/eslint/rules/token_encoding_requires_context_window.cjs +70 -0
- package/eslint/rules/token_encoding_requires_context_window.cjs.map +1 -0
- package/eslint/rules/token_encoding_requires_context_window.d.ts +24 -0
- package/eslint/rules/token_encoding_requires_context_window.mjs +65 -0
- package/eslint/rules/token_encoding_requires_context_window.mjs.map +1 -0
- package/eslint/rules.cjs +12 -0
- package/eslint/rules.mjs +6 -0
- package/eslint.cjs +82 -0
- package/eslint.cjs.map +1 -0
- package/eslint.mjs +74 -0
- package/eslint.mjs.map +1 -0
- package/index.cjs +1 -1
- package/index.mjs +1 -1
- package/mcp/adk-docs-corpus.json +1 -1
- package/package.json +230 -187
- package/skills/adk-assembly/SKILL.md +2 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"thought_payload_requires_replay_tag.mjs","names":[],"sources":["../../../src/eslint/rules/thought_payload_requires_replay_tag.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/eslint/rules/thought_payload_requires_replay_tag\n *\n * Flags `new Thought({ … })` whose options literal sets a `payload` but omits a\n * `replayCompatibility` tag.\n *\n * Why: a `Thought` may carry a vendor-opaque `payload` that the harness cannot interpret, to be\n * replayed back to a matching model wire. The ADK can only route that payload if the thought also\n * declares which adapter wire-shape it is replayable into, via `replayCompatibility`. A `payload`\n * with no `replayCompatibility` is a footgun: the harness has no way to know which adapter can\n * consume it, so it is dropped silently. The `Thought` constructor enforces this cross-field\n * invariant at runtime (`payload` present ⇒ `replayCompatibility` required); this rule surfaces it\n * statically at the construction site so it fails lint, not just at runtime.\n *\n * Detects the common literal form: a `new Thought({ … })` options object that has a `payload`\n * property but no `replayCompatibility` property. Spreads or computed keys are not analyzable here —\n * those fall back to the runtime check.\n *\n * Opt-out:\n * // eslint-disable-next-line adk/thought-payload-requires-replay-tag -- <reason>\n */\n\nimport { createRule } from './common'\n\nimport type { TSESTree } from '@typescript-eslint/utils'\n\nconst literalKey = (prop: TSESTree.Property): string | undefined => {\n if (prop.computed) return undefined\n if (prop.key.type === 'Identifier') return prop.key.name\n if (prop.key.type === 'Literal' && typeof prop.key.value === 'string') return prop.key.value\n return undefined\n}\n\n// True when the property value is statically `undefined` (the absent case) — `payload: undefined`\n// is equivalent to omitting it, so it should not trigger the rule.\nconst isUndefinedValue = (node: TSESTree.Node): boolean =>\n node.type === 'Identifier' && node.name === 'undefined'\n\nconst thoughtPayloadRequiresReplayTagRule = createRule({\n name: 'thought-payload-requires-replay-tag',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'A `Thought` carrying a `payload` must declare `replayCompatibility`; otherwise the harness cannot route the opaque payload to a matching adapter and drops it. Enforced at runtime by the Thought constructor; this surfaces it at the construction site.',\n },\n schema: [],\n messages: {\n requireReplayTag:\n '`new Thought({ payload })` requires a `replayCompatibility` tag — without it the harness cannot route the opaque payload to an adapter and silently drops it. Add `replayCompatibility: \"<wire-shape-id>\"`, or remove the payload. Opt out with an eslint-disable-next-line adk/thought-payload-requires-replay-tag comment + reason.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n NewExpression(node: TSESTree.NewExpression) {\n if (node.callee.type !== 'Identifier' || node.callee.name !== 'Thought') return\n const arg = node.arguments[0]\n if (!arg || arg.type !== 'ObjectExpression') return\n\n let payloadProp: TSESTree.Property | undefined\n let hasReplayTag = false\n let hasSpread = false\n for (const p of arg.properties) {\n if (p.type === 'SpreadElement') {\n hasSpread = true\n continue\n }\n const key = literalKey(p)\n if (key === 'payload' && !isUndefinedValue(p.value)) payloadProp = p\n else if (key === 'replayCompatibility' && !isUndefinedValue(p.value)) hasReplayTag = true\n }\n\n // A spread could supply replayCompatibility we can't see — stay conservative, don't flag.\n if (payloadProp && !hasReplayTag && !hasSpread) {\n context.report({ node: payloadProp, messageId: 'requireReplayTag' })\n }\n },\n }\n },\n})\n\nexport default thoughtPayloadRequiresReplayTagRule\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA0BA,IAAM,cAAc,SAAgD;CAClE,IAAI,KAAK,UAAU,OAAO,KAAA;CAC1B,IAAI,KAAK,IAAI,SAAS,cAAc,OAAO,KAAK,IAAI;CACpD,IAAI,KAAK,IAAI,SAAS,aAAa,OAAO,KAAK,IAAI,UAAU,UAAU,OAAO,KAAK,IAAI;AAEzF;AAIA,IAAM,oBAAoB,SACxB,KAAK,SAAS,gBAAgB,KAAK,SAAS;AAE9C,IAAM,sCAAsC,WAAW;CACrD,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aACE,4PACJ;EACA,QAAQ,CAAC;EACT,UAAU,EACR,kBACE,0UACJ;CACF;CACA,gBAAgB,CAAC;CACjB,OAAO,SAAS;EACd,OAAO,EACL,cAAc,MAA8B;GAC1C,IAAI,KAAK,OAAO,SAAS,gBAAgB,KAAK,OAAO,SAAS,WAAW;GACzE,MAAM,MAAM,KAAK,UAAU;GAC3B,IAAI,CAAC,OAAO,IAAI,SAAS,oBAAoB;GAE7C,IAAI;GACJ,IAAI,eAAe;GACnB,IAAI,YAAY;GAChB,KAAK,MAAM,KAAK,IAAI,YAAY;IAC9B,IAAI,EAAE,SAAS,iBAAiB;KAC9B,YAAY;KACZ;IACF;IACA,MAAM,MAAM,WAAW,CAAC;IACxB,IAAI,QAAQ,aAAa,CAAC,iBAAiB,EAAE,KAAK,GAAG,cAAc;SAC9D,IAAI,QAAQ,yBAAyB,CAAC,iBAAiB,EAAE,KAAK,GAAG,eAAe;GACvF;GAGA,IAAI,eAAe,CAAC,gBAAgB,CAAC,WACnC,QAAQ,OAAO;IAAE,MAAM;IAAa,WAAW;GAAmB,CAAC;EAEvE,EACF;CACF;AACF,CAAC"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
require("../../chunk-Ble4zEEl.js");
|
|
6
|
+
const require_common = require("../../common-DeNipTQI.js");
|
|
7
|
+
//#region src/eslint/rules/token_encoding_requires_context_window.ts
|
|
8
|
+
/**
|
|
9
|
+
* @module @nhtio/adk/eslint/rules/token_encoding_requires_context_window
|
|
10
|
+
*
|
|
11
|
+
* Flags a Chat Completions adapter options literal that sets a non-null `tokenEncoding` but omits
|
|
12
|
+
* `contextWindow`.
|
|
13
|
+
*
|
|
14
|
+
* Why: the OpenAI / WebLLM Chat Completions batteries only perform local token counting + overflow
|
|
15
|
+
* protection when BOTH `tokenEncoding` (how to count) and `contextWindow` (the budget to count
|
|
16
|
+
* against) are provided. Setting `tokenEncoding` alone is a footgun — the encoding is configured but
|
|
17
|
+
* there is no ceiling to enforce, so the overflow guard silently never runs. The adapters throw on
|
|
18
|
+
* this cross-field mismatch at iteration time; this rule surfaces it at the construction site.
|
|
19
|
+
*
|
|
20
|
+
* Detects `new OpenAIChatCompletionsAdapter({ … })` / `new WebLLMChatCompletionsAdapter({ … })`
|
|
21
|
+
* (and any `*ChatCompletionsAdapter`) where `tokenEncoding` is present and not `null`/`undefined`
|
|
22
|
+
* while `contextWindow` is absent.
|
|
23
|
+
*
|
|
24
|
+
* Opt-out:
|
|
25
|
+
* // eslint-disable-next-line adk/token-encoding-requires-context-window -- <reason>
|
|
26
|
+
*/
|
|
27
|
+
var literalKey = (prop) => {
|
|
28
|
+
if (prop.computed) return void 0;
|
|
29
|
+
if (prop.key.type === "Identifier") return prop.key.name;
|
|
30
|
+
if (prop.key.type === "Literal" && typeof prop.key.value === "string") return prop.key.value;
|
|
31
|
+
};
|
|
32
|
+
var isNullOrUndefined = (node) => node.type === "Literal" && node.value === null || node.type === "Identifier" && node.name === "undefined";
|
|
33
|
+
var tokenEncodingRequiresContextWindowRule = require_common.createRule({
|
|
34
|
+
name: "token-encoding-requires-context-window",
|
|
35
|
+
meta: {
|
|
36
|
+
type: "problem",
|
|
37
|
+
docs: { description: "A Chat Completions adapter configured with a non-null `tokenEncoding` must also set `contextWindow`; otherwise token counting is configured but the overflow guard has no budget and never runs. The adapters enforce this at runtime; this surfaces it at the construction site." },
|
|
38
|
+
schema: [],
|
|
39
|
+
messages: { requireContextWindow: "`tokenEncoding` is set but `contextWindow` is missing — the adapter counts tokens with no budget to enforce, so the context-overflow guard never runs. Add `contextWindow`, or drop `tokenEncoding`. Opt out with an eslint-disable-next-line adk/token-encoding-requires-context-window comment + reason." }
|
|
40
|
+
},
|
|
41
|
+
defaultOptions: [],
|
|
42
|
+
create(context) {
|
|
43
|
+
return { NewExpression(node) {
|
|
44
|
+
if (node.callee.type !== "Identifier") return;
|
|
45
|
+
if (!/ChatCompletionsAdapter$/.test(node.callee.name)) return;
|
|
46
|
+
const arg = node.arguments[0];
|
|
47
|
+
if (!arg || arg.type !== "ObjectExpression") return;
|
|
48
|
+
let tokenEncodingProp;
|
|
49
|
+
let hasContextWindow = false;
|
|
50
|
+
let hasSpread = false;
|
|
51
|
+
for (const p of arg.properties) {
|
|
52
|
+
if (p.type === "SpreadElement") {
|
|
53
|
+
hasSpread = true;
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
const key = literalKey(p);
|
|
57
|
+
if (key === "tokenEncoding" && !isNullOrUndefined(p.value)) tokenEncodingProp = p;
|
|
58
|
+
else if (key === "contextWindow" && !isNullOrUndefined(p.value)) hasContextWindow = true;
|
|
59
|
+
}
|
|
60
|
+
if (tokenEncodingProp && !hasContextWindow && !hasSpread) context.report({
|
|
61
|
+
node: tokenEncodingProp,
|
|
62
|
+
messageId: "requireContextWindow"
|
|
63
|
+
});
|
|
64
|
+
} };
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
//#endregion
|
|
68
|
+
exports.default = tokenEncodingRequiresContextWindowRule;
|
|
69
|
+
|
|
70
|
+
//# sourceMappingURL=token_encoding_requires_context_window.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token_encoding_requires_context_window.cjs","names":[],"sources":["../../../src/eslint/rules/token_encoding_requires_context_window.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/eslint/rules/token_encoding_requires_context_window\n *\n * Flags a Chat Completions adapter options literal that sets a non-null `tokenEncoding` but omits\n * `contextWindow`.\n *\n * Why: the OpenAI / WebLLM Chat Completions batteries only perform local token counting + overflow\n * protection when BOTH `tokenEncoding` (how to count) and `contextWindow` (the budget to count\n * against) are provided. Setting `tokenEncoding` alone is a footgun — the encoding is configured but\n * there is no ceiling to enforce, so the overflow guard silently never runs. The adapters throw on\n * this cross-field mismatch at iteration time; this rule surfaces it at the construction site.\n *\n * Detects `new OpenAIChatCompletionsAdapter({ … })` / `new WebLLMChatCompletionsAdapter({ … })`\n * (and any `*ChatCompletionsAdapter`) where `tokenEncoding` is present and not `null`/`undefined`\n * while `contextWindow` is absent.\n *\n * Opt-out:\n * // eslint-disable-next-line adk/token-encoding-requires-context-window -- <reason>\n */\n\nimport { createRule } from './common'\n\nimport type { TSESTree } from '@typescript-eslint/utils'\n\nconst literalKey = (prop: TSESTree.Property): string | undefined => {\n if (prop.computed) return undefined\n if (prop.key.type === 'Identifier') return prop.key.name\n if (prop.key.type === 'Literal' && typeof prop.key.value === 'string') return prop.key.value\n return undefined\n}\n\nconst isNullOrUndefined = (node: TSESTree.Node): boolean =>\n (node.type === 'Literal' && node.value === null) ||\n (node.type === 'Identifier' && node.name === 'undefined')\n\nconst tokenEncodingRequiresContextWindowRule = createRule({\n name: 'token-encoding-requires-context-window',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'A Chat Completions adapter configured with a non-null `tokenEncoding` must also set `contextWindow`; otherwise token counting is configured but the overflow guard has no budget and never runs. The adapters enforce this at runtime; this surfaces it at the construction site.',\n },\n schema: [],\n messages: {\n requireContextWindow:\n '`tokenEncoding` is set but `contextWindow` is missing — the adapter counts tokens with no budget to enforce, so the context-overflow guard never runs. Add `contextWindow`, or drop `tokenEncoding`. Opt out with an eslint-disable-next-line adk/token-encoding-requires-context-window comment + reason.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n NewExpression(node: TSESTree.NewExpression) {\n if (node.callee.type !== 'Identifier') return\n if (!/ChatCompletionsAdapter$/.test(node.callee.name)) return\n const arg = node.arguments[0]\n if (!arg || arg.type !== 'ObjectExpression') return\n\n let tokenEncodingProp: TSESTree.Property | undefined\n let hasContextWindow = false\n let hasSpread = false\n for (const p of arg.properties) {\n if (p.type === 'SpreadElement') {\n hasSpread = true\n continue\n }\n const key = literalKey(p)\n if (key === 'tokenEncoding' && !isNullOrUndefined(p.value)) tokenEncodingProp = p\n else if (key === 'contextWindow' && !isNullOrUndefined(p.value)) hasContextWindow = true\n }\n\n // A spread could supply contextWindow we can't see — stay conservative, don't flag.\n if (tokenEncodingProp && !hasContextWindow && !hasSpread) {\n context.report({ node: tokenEncodingProp, messageId: 'requireContextWindow' })\n }\n },\n }\n },\n})\n\nexport default tokenEncodingRequiresContextWindowRule\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAwBA,IAAM,cAAc,SAAgD;CAClE,IAAI,KAAK,UAAU,OAAO,KAAA;CAC1B,IAAI,KAAK,IAAI,SAAS,cAAc,OAAO,KAAK,IAAI;CACpD,IAAI,KAAK,IAAI,SAAS,aAAa,OAAO,KAAK,IAAI,UAAU,UAAU,OAAO,KAAK,IAAI;AAEzF;AAEA,IAAM,qBAAqB,SACxB,KAAK,SAAS,aAAa,KAAK,UAAU,QAC1C,KAAK,SAAS,gBAAgB,KAAK,SAAS;AAE/C,IAAM,yCAAyC,eAAA,WAAW;CACxD,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aACE,oRACJ;EACA,QAAQ,CAAC;EACT,UAAU,EACR,sBACE,6SACJ;CACF;CACA,gBAAgB,CAAC;CACjB,OAAO,SAAS;EACd,OAAO,EACL,cAAc,MAA8B;GAC1C,IAAI,KAAK,OAAO,SAAS,cAAc;GACvC,IAAI,CAAC,0BAA0B,KAAK,KAAK,OAAO,IAAI,GAAG;GACvD,MAAM,MAAM,KAAK,UAAU;GAC3B,IAAI,CAAC,OAAO,IAAI,SAAS,oBAAoB;GAE7C,IAAI;GACJ,IAAI,mBAAmB;GACvB,IAAI,YAAY;GAChB,KAAK,MAAM,KAAK,IAAI,YAAY;IAC9B,IAAI,EAAE,SAAS,iBAAiB;KAC9B,YAAY;KACZ;IACF;IACA,MAAM,MAAM,WAAW,CAAC;IACxB,IAAI,QAAQ,mBAAmB,CAAC,kBAAkB,EAAE,KAAK,GAAG,oBAAoB;SAC3E,IAAI,QAAQ,mBAAmB,CAAC,kBAAkB,EAAE,KAAK,GAAG,mBAAmB;GACtF;GAGA,IAAI,qBAAqB,CAAC,oBAAoB,CAAC,WAC7C,QAAQ,OAAO;IAAE,MAAM;IAAmB,WAAW;GAAuB,CAAC;EAEjF,EACF;CACF;AACF,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module @nhtio/adk/eslint/rules/token_encoding_requires_context_window
|
|
3
|
+
*
|
|
4
|
+
* Flags a Chat Completions adapter options literal that sets a non-null `tokenEncoding` but omits
|
|
5
|
+
* `contextWindow`.
|
|
6
|
+
*
|
|
7
|
+
* Why: the OpenAI / WebLLM Chat Completions batteries only perform local token counting + overflow
|
|
8
|
+
* protection when BOTH `tokenEncoding` (how to count) and `contextWindow` (the budget to count
|
|
9
|
+
* against) are provided. Setting `tokenEncoding` alone is a footgun — the encoding is configured but
|
|
10
|
+
* there is no ceiling to enforce, so the overflow guard silently never runs. The adapters throw on
|
|
11
|
+
* this cross-field mismatch at iteration time; this rule surfaces it at the construction site.
|
|
12
|
+
*
|
|
13
|
+
* Detects `new OpenAIChatCompletionsAdapter({ … })` / `new WebLLMChatCompletionsAdapter({ … })`
|
|
14
|
+
* (and any `*ChatCompletionsAdapter`) where `tokenEncoding` is present and not `null`/`undefined`
|
|
15
|
+
* while `contextWindow` is absent.
|
|
16
|
+
*
|
|
17
|
+
* Opt-out:
|
|
18
|
+
* // eslint-disable-next-line adk/token-encoding-requires-context-window -- <reason>
|
|
19
|
+
*/
|
|
20
|
+
declare const tokenEncodingRequiresContextWindowRule: import("@typescript-eslint/utils/ts-eslint").RuleModule<"requireContextWindow", [
|
|
21
|
+
], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener> & {
|
|
22
|
+
name: string;
|
|
23
|
+
};
|
|
24
|
+
export default tokenEncodingRequiresContextWindowRule;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { t as createRule } from "../../common-BUIjZ6LV.mjs";
|
|
2
|
+
//#region src/eslint/rules/token_encoding_requires_context_window.ts
|
|
3
|
+
/**
|
|
4
|
+
* @module @nhtio/adk/eslint/rules/token_encoding_requires_context_window
|
|
5
|
+
*
|
|
6
|
+
* Flags a Chat Completions adapter options literal that sets a non-null `tokenEncoding` but omits
|
|
7
|
+
* `contextWindow`.
|
|
8
|
+
*
|
|
9
|
+
* Why: the OpenAI / WebLLM Chat Completions batteries only perform local token counting + overflow
|
|
10
|
+
* protection when BOTH `tokenEncoding` (how to count) and `contextWindow` (the budget to count
|
|
11
|
+
* against) are provided. Setting `tokenEncoding` alone is a footgun — the encoding is configured but
|
|
12
|
+
* there is no ceiling to enforce, so the overflow guard silently never runs. The adapters throw on
|
|
13
|
+
* this cross-field mismatch at iteration time; this rule surfaces it at the construction site.
|
|
14
|
+
*
|
|
15
|
+
* Detects `new OpenAIChatCompletionsAdapter({ … })` / `new WebLLMChatCompletionsAdapter({ … })`
|
|
16
|
+
* (and any `*ChatCompletionsAdapter`) where `tokenEncoding` is present and not `null`/`undefined`
|
|
17
|
+
* while `contextWindow` is absent.
|
|
18
|
+
*
|
|
19
|
+
* Opt-out:
|
|
20
|
+
* // eslint-disable-next-line adk/token-encoding-requires-context-window -- <reason>
|
|
21
|
+
*/
|
|
22
|
+
var literalKey = (prop) => {
|
|
23
|
+
if (prop.computed) return void 0;
|
|
24
|
+
if (prop.key.type === "Identifier") return prop.key.name;
|
|
25
|
+
if (prop.key.type === "Literal" && typeof prop.key.value === "string") return prop.key.value;
|
|
26
|
+
};
|
|
27
|
+
var isNullOrUndefined = (node) => node.type === "Literal" && node.value === null || node.type === "Identifier" && node.name === "undefined";
|
|
28
|
+
var tokenEncodingRequiresContextWindowRule = createRule({
|
|
29
|
+
name: "token-encoding-requires-context-window",
|
|
30
|
+
meta: {
|
|
31
|
+
type: "problem",
|
|
32
|
+
docs: { description: "A Chat Completions adapter configured with a non-null `tokenEncoding` must also set `contextWindow`; otherwise token counting is configured but the overflow guard has no budget and never runs. The adapters enforce this at runtime; this surfaces it at the construction site." },
|
|
33
|
+
schema: [],
|
|
34
|
+
messages: { requireContextWindow: "`tokenEncoding` is set but `contextWindow` is missing — the adapter counts tokens with no budget to enforce, so the context-overflow guard never runs. Add `contextWindow`, or drop `tokenEncoding`. Opt out with an eslint-disable-next-line adk/token-encoding-requires-context-window comment + reason." }
|
|
35
|
+
},
|
|
36
|
+
defaultOptions: [],
|
|
37
|
+
create(context) {
|
|
38
|
+
return { NewExpression(node) {
|
|
39
|
+
if (node.callee.type !== "Identifier") return;
|
|
40
|
+
if (!/ChatCompletionsAdapter$/.test(node.callee.name)) return;
|
|
41
|
+
const arg = node.arguments[0];
|
|
42
|
+
if (!arg || arg.type !== "ObjectExpression") return;
|
|
43
|
+
let tokenEncodingProp;
|
|
44
|
+
let hasContextWindow = false;
|
|
45
|
+
let hasSpread = false;
|
|
46
|
+
for (const p of arg.properties) {
|
|
47
|
+
if (p.type === "SpreadElement") {
|
|
48
|
+
hasSpread = true;
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
const key = literalKey(p);
|
|
52
|
+
if (key === "tokenEncoding" && !isNullOrUndefined(p.value)) tokenEncodingProp = p;
|
|
53
|
+
else if (key === "contextWindow" && !isNullOrUndefined(p.value)) hasContextWindow = true;
|
|
54
|
+
}
|
|
55
|
+
if (tokenEncodingProp && !hasContextWindow && !hasSpread) context.report({
|
|
56
|
+
node: tokenEncodingProp,
|
|
57
|
+
messageId: "requireContextWindow"
|
|
58
|
+
});
|
|
59
|
+
} };
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
//#endregion
|
|
63
|
+
export { tokenEncodingRequiresContextWindowRule as default };
|
|
64
|
+
|
|
65
|
+
//# sourceMappingURL=token_encoding_requires_context_window.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token_encoding_requires_context_window.mjs","names":[],"sources":["../../../src/eslint/rules/token_encoding_requires_context_window.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/eslint/rules/token_encoding_requires_context_window\n *\n * Flags a Chat Completions adapter options literal that sets a non-null `tokenEncoding` but omits\n * `contextWindow`.\n *\n * Why: the OpenAI / WebLLM Chat Completions batteries only perform local token counting + overflow\n * protection when BOTH `tokenEncoding` (how to count) and `contextWindow` (the budget to count\n * against) are provided. Setting `tokenEncoding` alone is a footgun — the encoding is configured but\n * there is no ceiling to enforce, so the overflow guard silently never runs. The adapters throw on\n * this cross-field mismatch at iteration time; this rule surfaces it at the construction site.\n *\n * Detects `new OpenAIChatCompletionsAdapter({ … })` / `new WebLLMChatCompletionsAdapter({ … })`\n * (and any `*ChatCompletionsAdapter`) where `tokenEncoding` is present and not `null`/`undefined`\n * while `contextWindow` is absent.\n *\n * Opt-out:\n * // eslint-disable-next-line adk/token-encoding-requires-context-window -- <reason>\n */\n\nimport { createRule } from './common'\n\nimport type { TSESTree } from '@typescript-eslint/utils'\n\nconst literalKey = (prop: TSESTree.Property): string | undefined => {\n if (prop.computed) return undefined\n if (prop.key.type === 'Identifier') return prop.key.name\n if (prop.key.type === 'Literal' && typeof prop.key.value === 'string') return prop.key.value\n return undefined\n}\n\nconst isNullOrUndefined = (node: TSESTree.Node): boolean =>\n (node.type === 'Literal' && node.value === null) ||\n (node.type === 'Identifier' && node.name === 'undefined')\n\nconst tokenEncodingRequiresContextWindowRule = createRule({\n name: 'token-encoding-requires-context-window',\n meta: {\n type: 'problem',\n docs: {\n description:\n 'A Chat Completions adapter configured with a non-null `tokenEncoding` must also set `contextWindow`; otherwise token counting is configured but the overflow guard has no budget and never runs. The adapters enforce this at runtime; this surfaces it at the construction site.',\n },\n schema: [],\n messages: {\n requireContextWindow:\n '`tokenEncoding` is set but `contextWindow` is missing — the adapter counts tokens with no budget to enforce, so the context-overflow guard never runs. Add `contextWindow`, or drop `tokenEncoding`. Opt out with an eslint-disable-next-line adk/token-encoding-requires-context-window comment + reason.',\n },\n },\n defaultOptions: [],\n create(context) {\n return {\n NewExpression(node: TSESTree.NewExpression) {\n if (node.callee.type !== 'Identifier') return\n if (!/ChatCompletionsAdapter$/.test(node.callee.name)) return\n const arg = node.arguments[0]\n if (!arg || arg.type !== 'ObjectExpression') return\n\n let tokenEncodingProp: TSESTree.Property | undefined\n let hasContextWindow = false\n let hasSpread = false\n for (const p of arg.properties) {\n if (p.type === 'SpreadElement') {\n hasSpread = true\n continue\n }\n const key = literalKey(p)\n if (key === 'tokenEncoding' && !isNullOrUndefined(p.value)) tokenEncodingProp = p\n else if (key === 'contextWindow' && !isNullOrUndefined(p.value)) hasContextWindow = true\n }\n\n // A spread could supply contextWindow we can't see — stay conservative, don't flag.\n if (tokenEncodingProp && !hasContextWindow && !hasSpread) {\n context.report({ node: tokenEncodingProp, messageId: 'requireContextWindow' })\n }\n },\n }\n },\n})\n\nexport default tokenEncodingRequiresContextWindowRule\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAwBA,IAAM,cAAc,SAAgD;CAClE,IAAI,KAAK,UAAU,OAAO,KAAA;CAC1B,IAAI,KAAK,IAAI,SAAS,cAAc,OAAO,KAAK,IAAI;CACpD,IAAI,KAAK,IAAI,SAAS,aAAa,OAAO,KAAK,IAAI,UAAU,UAAU,OAAO,KAAK,IAAI;AAEzF;AAEA,IAAM,qBAAqB,SACxB,KAAK,SAAS,aAAa,KAAK,UAAU,QAC1C,KAAK,SAAS,gBAAgB,KAAK,SAAS;AAE/C,IAAM,yCAAyC,WAAW;CACxD,MAAM;CACN,MAAM;EACJ,MAAM;EACN,MAAM,EACJ,aACE,oRACJ;EACA,QAAQ,CAAC;EACT,UAAU,EACR,sBACE,6SACJ;CACF;CACA,gBAAgB,CAAC;CACjB,OAAO,SAAS;EACd,OAAO,EACL,cAAc,MAA8B;GAC1C,IAAI,KAAK,OAAO,SAAS,cAAc;GACvC,IAAI,CAAC,0BAA0B,KAAK,KAAK,OAAO,IAAI,GAAG;GACvD,MAAM,MAAM,KAAK,UAAU;GAC3B,IAAI,CAAC,OAAO,IAAI,SAAS,oBAAoB;GAE7C,IAAI;GACJ,IAAI,mBAAmB;GACvB,IAAI,YAAY;GAChB,KAAK,MAAM,KAAK,IAAI,YAAY;IAC9B,IAAI,EAAE,SAAS,iBAAiB;KAC9B,YAAY;KACZ;IACF;IACA,MAAM,MAAM,WAAW,CAAC;IACxB,IAAI,QAAQ,mBAAmB,CAAC,kBAAkB,EAAE,KAAK,GAAG,oBAAoB;SAC3E,IAAI,QAAQ,mBAAmB,CAAC,kBAAkB,EAAE,KAAK,GAAG,mBAAmB;GACtF;GAGA,IAAI,qBAAqB,CAAC,oBAAoB,CAAC,WAC7C,QAAQ,OAAO;IAAE,MAAM;IAAmB,WAAW;GAAuB,CAAC;EAEjF,EACF;CACF;AACF,CAAC"}
|
package/eslint/rules.cjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
require("../chunk-Ble4zEEl.js");
|
|
3
|
+
const require_eslint_rules_no_model_in_tool_handler = require("./rules/no_model_in_tool_handler.cjs");
|
|
4
|
+
const require_eslint_rules_require_validator_any_required = require("./rules/require_validator_any_required.cjs");
|
|
5
|
+
const require_eslint_rules_thought_payload_requires_replay_tag = require("./rules/thought_payload_requires_replay_tag.cjs");
|
|
6
|
+
const require_eslint_rules_token_encoding_requires_context_window = require("./rules/token_encoding_requires_context_window.cjs");
|
|
7
|
+
const require_eslint_rules_artifact_tool_forbids_artifact_constructor = require("./rules/artifact_tool_forbids_artifact_constructor.cjs");
|
|
8
|
+
exports.artifactToolForbidsArtifactConstructor = require_eslint_rules_artifact_tool_forbids_artifact_constructor.default;
|
|
9
|
+
exports.noModelInToolHandler = require_eslint_rules_no_model_in_tool_handler.default;
|
|
10
|
+
exports.requireValidatorAnyRequired = require_eslint_rules_require_validator_any_required.default;
|
|
11
|
+
exports.thoughtPayloadRequiresReplayTag = require_eslint_rules_thought_payload_requires_replay_tag.default;
|
|
12
|
+
exports.tokenEncodingRequiresContextWindow = require_eslint_rules_token_encoding_requires_context_window.default;
|
package/eslint/rules.mjs
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import noModelInToolHandlerRule from "./rules/no_model_in_tool_handler.mjs";
|
|
2
|
+
import requireValidatorAnyRequiredRule from "./rules/require_validator_any_required.mjs";
|
|
3
|
+
import thoughtPayloadRequiresReplayTagRule from "./rules/thought_payload_requires_replay_tag.mjs";
|
|
4
|
+
import tokenEncodingRequiresContextWindowRule from "./rules/token_encoding_requires_context_window.mjs";
|
|
5
|
+
import artifactToolForbidsArtifactConstructorRule from "./rules/artifact_tool_forbids_artifact_constructor.mjs";
|
|
6
|
+
export { artifactToolForbidsArtifactConstructorRule as artifactToolForbidsArtifactConstructor, noModelInToolHandlerRule as noModelInToolHandler, requireValidatorAnyRequiredRule as requireValidatorAnyRequired, thoughtPayloadRequiresReplayTagRule as thoughtPayloadRequiresReplayTag, tokenEncodingRequiresContextWindowRule as tokenEncodingRequiresContextWindow };
|
package/eslint.cjs
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
require("./chunk-Ble4zEEl.js");
|
|
6
|
+
const require_eslint_rules_no_model_in_tool_handler = require("./eslint/rules/no_model_in_tool_handler.cjs");
|
|
7
|
+
const require_eslint_rules_require_validator_any_required = require("./eslint/rules/require_validator_any_required.cjs");
|
|
8
|
+
const require_eslint_rules_thought_payload_requires_replay_tag = require("./eslint/rules/thought_payload_requires_replay_tag.cjs");
|
|
9
|
+
const require_eslint_rules_token_encoding_requires_context_window = require("./eslint/rules/token_encoding_requires_context_window.cjs");
|
|
10
|
+
const require_eslint_rules_artifact_tool_forbids_artifact_constructor = require("./eslint/rules/artifact_tool_forbids_artifact_constructor.cjs");
|
|
11
|
+
//#region src/eslint/index.ts
|
|
12
|
+
/**
|
|
13
|
+
* @module @nhtio/adk/eslint
|
|
14
|
+
*
|
|
15
|
+
* The `@nhtio/adk` ESLint plugin: machine-checkable enforcement of the harness contracts that
|
|
16
|
+
* implementors of bring-your-own batteries, tools, and primitives are most likely to get wrong.
|
|
17
|
+
*
|
|
18
|
+
* @remarks
|
|
19
|
+
* These rules turn documented footguns into lint errors. They are report-only (no autofix) — each
|
|
20
|
+
* names the contract it enforces and the fix; carve out a deliberate exception with an inline
|
|
21
|
+
* `// eslint-disable-next-line adk/<rule> -- <reason>` comment.
|
|
22
|
+
*
|
|
23
|
+
* `@typescript-eslint/utils` and `eslint` are OPTIONAL peer dependencies of `@nhtio/adk` — installed
|
|
24
|
+
* only by consumers who lint with this plugin. The main library never imports this module.
|
|
25
|
+
*
|
|
26
|
+
* @example Flat config
|
|
27
|
+
* ```ts
|
|
28
|
+
* import adk from '@nhtio/adk/eslint'
|
|
29
|
+
*
|
|
30
|
+
* export default [
|
|
31
|
+
* { plugins: { adk: adk.plugin }, rules: adk.configs.recommended.rules },
|
|
32
|
+
* ]
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
/**
|
|
36
|
+
* Map of rule id (without the `adk/` plugin prefix) to its rule object. Registered on the plugin as
|
|
37
|
+
* `rules`, so configs reference them as `adk/<id>`.
|
|
38
|
+
*/
|
|
39
|
+
var rules = {
|
|
40
|
+
"require-validator-any-required": require_eslint_rules_require_validator_any_required.default,
|
|
41
|
+
"no-model-in-tool-handler": require_eslint_rules_no_model_in_tool_handler.default,
|
|
42
|
+
"thought-payload-requires-replay-tag": require_eslint_rules_thought_payload_requires_replay_tag.default,
|
|
43
|
+
"token-encoding-requires-context-window": require_eslint_rules_token_encoding_requires_context_window.default,
|
|
44
|
+
"artifact-tool-forbids-artifact-constructor": require_eslint_rules_artifact_tool_forbids_artifact_constructor.default
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The ESLint plugin object. Register under the `adk` namespace: `plugins: { adk: plugin }`.
|
|
48
|
+
*/
|
|
49
|
+
var plugin = {
|
|
50
|
+
meta: {
|
|
51
|
+
name: "@nhtio/adk/eslint",
|
|
52
|
+
version: "1.20260607.2"
|
|
53
|
+
},
|
|
54
|
+
rules
|
|
55
|
+
};
|
|
56
|
+
/** Every rule enabled at `error`, keyed `adk/<id>` (assumes the plugin is registered as `adk`). */
|
|
57
|
+
var recommendedRules = Object.fromEntries(Object.keys(rules).map((id) => [`adk/${id}`, "error"]));
|
|
58
|
+
/**
|
|
59
|
+
* Named config presets. `recommended` enables every rule at `error` and registers the plugin under
|
|
60
|
+
* the `adk` namespace — spread it into a flat config to adopt the full set.
|
|
61
|
+
*/
|
|
62
|
+
var configs = { recommended: {
|
|
63
|
+
name: "@nhtio/adk/eslint/recommended",
|
|
64
|
+
plugins: { adk: plugin },
|
|
65
|
+
rules: recommendedRules
|
|
66
|
+
} };
|
|
67
|
+
/**
|
|
68
|
+
* Default export bundles the plugin and its config presets, mirroring the shape ESLint flat configs
|
|
69
|
+
* expect from a plugin module.
|
|
70
|
+
*/
|
|
71
|
+
var eslint_default = {
|
|
72
|
+
plugin,
|
|
73
|
+
rules,
|
|
74
|
+
configs
|
|
75
|
+
};
|
|
76
|
+
//#endregion
|
|
77
|
+
exports.configs = configs;
|
|
78
|
+
exports.default = eslint_default;
|
|
79
|
+
exports.plugin = plugin;
|
|
80
|
+
exports.rules = rules;
|
|
81
|
+
|
|
82
|
+
//# sourceMappingURL=eslint.cjs.map
|
package/eslint.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.cjs","names":[],"sources":["../src/eslint/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/eslint\n *\n * The `@nhtio/adk` ESLint plugin: machine-checkable enforcement of the harness contracts that\n * implementors of bring-your-own batteries, tools, and primitives are most likely to get wrong.\n *\n * @remarks\n * These rules turn documented footguns into lint errors. They are report-only (no autofix) — each\n * names the contract it enforces and the fix; carve out a deliberate exception with an inline\n * `// eslint-disable-next-line adk/<rule> -- <reason>` comment.\n *\n * `@typescript-eslint/utils` and `eslint` are OPTIONAL peer dependencies of `@nhtio/adk` — installed\n * only by consumers who lint with this plugin. The main library never imports this module.\n *\n * @example Flat config\n * ```ts\n * import adk from '@nhtio/adk/eslint'\n *\n * export default [\n * { plugins: { adk: adk.plugin }, rules: adk.configs.recommended.rules },\n * ]\n * ```\n */\n\nimport { default as noModelInToolHandler } from './rules/no_model_in_tool_handler'\nimport { default as requireValidatorAnyRequired } from './rules/require_validator_any_required'\nimport { default as thoughtPayloadRequiresReplayTag } from './rules/thought_payload_requires_replay_tag'\nimport { default as tokenEncodingRequiresContextWindow } from './rules/token_encoding_requires_context_window'\nimport { default as artifactToolForbidsArtifactConstructor } from './rules/artifact_tool_forbids_artifact_constructor'\nimport type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'\n\n/**\n * Map of rule id (without the `adk/` plugin prefix) to its rule object. Registered on the plugin as\n * `rules`, so configs reference them as `adk/<id>`.\n */\nexport const rules = {\n 'require-validator-any-required': requireValidatorAnyRequired,\n 'no-model-in-tool-handler': noModelInToolHandler,\n 'thought-payload-requires-replay-tag': thoughtPayloadRequiresReplayTag,\n 'token-encoding-requires-context-window': tokenEncodingRequiresContextWindow,\n 'artifact-tool-forbids-artifact-constructor': artifactToolForbidsArtifactConstructor,\n} satisfies FlatConfig.Plugin['rules']\n\n/**\n * The ESLint plugin object. Register under the `adk` namespace: `plugins: { adk: plugin }`.\n */\nexport const plugin: FlatConfig.Plugin = {\n meta: { name: '@nhtio/adk/eslint', version: __VERSION__ },\n rules,\n}\n\n/** Every rule enabled at `error`, keyed `adk/<id>` (assumes the plugin is registered as `adk`). */\nconst recommendedRules: NonNullable<FlatConfig.Config['rules']> = Object.fromEntries(\n Object.keys(rules).map((id) => [`adk/${id}`, 'error'])\n)\n\n/**\n * Named config presets. `recommended` enables every rule at `error` and registers the plugin under\n * the `adk` namespace — spread it into a flat config to adopt the full set.\n */\nexport const configs = {\n recommended: {\n name: '@nhtio/adk/eslint/recommended',\n plugins: { adk: plugin },\n rules: recommendedRules,\n } satisfies FlatConfig.Config,\n}\n\n/**\n * Default export bundles the plugin and its config presets, mirroring the shape ESLint flat configs\n * expect from a plugin module.\n */\nexport default { plugin, rules, configs }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,IAAa,QAAQ;CACnB,kCAAkC,oDAAA;CAClC,4BAA4B,8CAAA;CAC5B,uCAAuC,yDAAA;CACvC,0CAA0C,4DAAA;CAC1C,8CAA8C,gEAAA;AAChD;;;;AAKA,IAAa,SAA4B;CACvC,MAAM;EAAE,MAAM;EAAqB,SAAA;CAAqB;CACxD;AACF;;AAGA,IAAM,mBAA4D,OAAO,YACvE,OAAO,KAAK,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,MAAM,OAAO,CAAC,CACvD;;;;;AAMA,IAAa,UAAU,EACrB,aAAa;CACX,MAAM;CACN,SAAS,EAAE,KAAK,OAAO;CACvB,OAAO;AACT,EACF;;;;;AAMA,IAAA,iBAAe;CAAE;CAAQ;CAAO;AAAQ"}
|
package/eslint.mjs
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import noModelInToolHandlerRule from "./eslint/rules/no_model_in_tool_handler.mjs";
|
|
2
|
+
import requireValidatorAnyRequiredRule from "./eslint/rules/require_validator_any_required.mjs";
|
|
3
|
+
import thoughtPayloadRequiresReplayTagRule from "./eslint/rules/thought_payload_requires_replay_tag.mjs";
|
|
4
|
+
import tokenEncodingRequiresContextWindowRule from "./eslint/rules/token_encoding_requires_context_window.mjs";
|
|
5
|
+
import artifactToolForbidsArtifactConstructorRule from "./eslint/rules/artifact_tool_forbids_artifact_constructor.mjs";
|
|
6
|
+
//#region src/eslint/index.ts
|
|
7
|
+
/**
|
|
8
|
+
* @module @nhtio/adk/eslint
|
|
9
|
+
*
|
|
10
|
+
* The `@nhtio/adk` ESLint plugin: machine-checkable enforcement of the harness contracts that
|
|
11
|
+
* implementors of bring-your-own batteries, tools, and primitives are most likely to get wrong.
|
|
12
|
+
*
|
|
13
|
+
* @remarks
|
|
14
|
+
* These rules turn documented footguns into lint errors. They are report-only (no autofix) — each
|
|
15
|
+
* names the contract it enforces and the fix; carve out a deliberate exception with an inline
|
|
16
|
+
* `// eslint-disable-next-line adk/<rule> -- <reason>` comment.
|
|
17
|
+
*
|
|
18
|
+
* `@typescript-eslint/utils` and `eslint` are OPTIONAL peer dependencies of `@nhtio/adk` — installed
|
|
19
|
+
* only by consumers who lint with this plugin. The main library never imports this module.
|
|
20
|
+
*
|
|
21
|
+
* @example Flat config
|
|
22
|
+
* ```ts
|
|
23
|
+
* import adk from '@nhtio/adk/eslint'
|
|
24
|
+
*
|
|
25
|
+
* export default [
|
|
26
|
+
* { plugins: { adk: adk.plugin }, rules: adk.configs.recommended.rules },
|
|
27
|
+
* ]
|
|
28
|
+
* ```
|
|
29
|
+
*/
|
|
30
|
+
/**
|
|
31
|
+
* Map of rule id (without the `adk/` plugin prefix) to its rule object. Registered on the plugin as
|
|
32
|
+
* `rules`, so configs reference them as `adk/<id>`.
|
|
33
|
+
*/
|
|
34
|
+
var rules = {
|
|
35
|
+
"require-validator-any-required": requireValidatorAnyRequiredRule,
|
|
36
|
+
"no-model-in-tool-handler": noModelInToolHandlerRule,
|
|
37
|
+
"thought-payload-requires-replay-tag": thoughtPayloadRequiresReplayTagRule,
|
|
38
|
+
"token-encoding-requires-context-window": tokenEncodingRequiresContextWindowRule,
|
|
39
|
+
"artifact-tool-forbids-artifact-constructor": artifactToolForbidsArtifactConstructorRule
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* The ESLint plugin object. Register under the `adk` namespace: `plugins: { adk: plugin }`.
|
|
43
|
+
*/
|
|
44
|
+
var plugin = {
|
|
45
|
+
meta: {
|
|
46
|
+
name: "@nhtio/adk/eslint",
|
|
47
|
+
version: "1.20260607.2"
|
|
48
|
+
},
|
|
49
|
+
rules
|
|
50
|
+
};
|
|
51
|
+
/** Every rule enabled at `error`, keyed `adk/<id>` (assumes the plugin is registered as `adk`). */
|
|
52
|
+
var recommendedRules = Object.fromEntries(Object.keys(rules).map((id) => [`adk/${id}`, "error"]));
|
|
53
|
+
/**
|
|
54
|
+
* Named config presets. `recommended` enables every rule at `error` and registers the plugin under
|
|
55
|
+
* the `adk` namespace — spread it into a flat config to adopt the full set.
|
|
56
|
+
*/
|
|
57
|
+
var configs = { recommended: {
|
|
58
|
+
name: "@nhtio/adk/eslint/recommended",
|
|
59
|
+
plugins: { adk: plugin },
|
|
60
|
+
rules: recommendedRules
|
|
61
|
+
} };
|
|
62
|
+
/**
|
|
63
|
+
* Default export bundles the plugin and its config presets, mirroring the shape ESLint flat configs
|
|
64
|
+
* expect from a plugin module.
|
|
65
|
+
*/
|
|
66
|
+
var eslint_default = {
|
|
67
|
+
plugin,
|
|
68
|
+
rules,
|
|
69
|
+
configs
|
|
70
|
+
};
|
|
71
|
+
//#endregion
|
|
72
|
+
export { configs, eslint_default as default, plugin, rules };
|
|
73
|
+
|
|
74
|
+
//# sourceMappingURL=eslint.mjs.map
|
package/eslint.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"eslint.mjs","names":[],"sources":["../src/eslint/index.ts"],"sourcesContent":["/**\n * @module @nhtio/adk/eslint\n *\n * The `@nhtio/adk` ESLint plugin: machine-checkable enforcement of the harness contracts that\n * implementors of bring-your-own batteries, tools, and primitives are most likely to get wrong.\n *\n * @remarks\n * These rules turn documented footguns into lint errors. They are report-only (no autofix) — each\n * names the contract it enforces and the fix; carve out a deliberate exception with an inline\n * `// eslint-disable-next-line adk/<rule> -- <reason>` comment.\n *\n * `@typescript-eslint/utils` and `eslint` are OPTIONAL peer dependencies of `@nhtio/adk` — installed\n * only by consumers who lint with this plugin. The main library never imports this module.\n *\n * @example Flat config\n * ```ts\n * import adk from '@nhtio/adk/eslint'\n *\n * export default [\n * { plugins: { adk: adk.plugin }, rules: adk.configs.recommended.rules },\n * ]\n * ```\n */\n\nimport { default as noModelInToolHandler } from './rules/no_model_in_tool_handler'\nimport { default as requireValidatorAnyRequired } from './rules/require_validator_any_required'\nimport { default as thoughtPayloadRequiresReplayTag } from './rules/thought_payload_requires_replay_tag'\nimport { default as tokenEncodingRequiresContextWindow } from './rules/token_encoding_requires_context_window'\nimport { default as artifactToolForbidsArtifactConstructor } from './rules/artifact_tool_forbids_artifact_constructor'\nimport type { FlatConfig } from '@typescript-eslint/utils/ts-eslint'\n\n/**\n * Map of rule id (without the `adk/` plugin prefix) to its rule object. Registered on the plugin as\n * `rules`, so configs reference them as `adk/<id>`.\n */\nexport const rules = {\n 'require-validator-any-required': requireValidatorAnyRequired,\n 'no-model-in-tool-handler': noModelInToolHandler,\n 'thought-payload-requires-replay-tag': thoughtPayloadRequiresReplayTag,\n 'token-encoding-requires-context-window': tokenEncodingRequiresContextWindow,\n 'artifact-tool-forbids-artifact-constructor': artifactToolForbidsArtifactConstructor,\n} satisfies FlatConfig.Plugin['rules']\n\n/**\n * The ESLint plugin object. Register under the `adk` namespace: `plugins: { adk: plugin }`.\n */\nexport const plugin: FlatConfig.Plugin = {\n meta: { name: '@nhtio/adk/eslint', version: __VERSION__ },\n rules,\n}\n\n/** Every rule enabled at `error`, keyed `adk/<id>` (assumes the plugin is registered as `adk`). */\nconst recommendedRules: NonNullable<FlatConfig.Config['rules']> = Object.fromEntries(\n Object.keys(rules).map((id) => [`adk/${id}`, 'error'])\n)\n\n/**\n * Named config presets. `recommended` enables every rule at `error` and registers the plugin under\n * the `adk` namespace — spread it into a flat config to adopt the full set.\n */\nexport const configs = {\n recommended: {\n name: '@nhtio/adk/eslint/recommended',\n plugins: { adk: plugin },\n rules: recommendedRules,\n } satisfies FlatConfig.Config,\n}\n\n/**\n * Default export bundles the plugin and its config presets, mirroring the shape ESLint flat configs\n * expect from a plugin module.\n */\nexport default { plugin, rules, configs }\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAmCA,IAAa,QAAQ;CACnB,kCAAkC;CAClC,4BAA4B;CAC5B,uCAAuC;CACvC,0CAA0C;CAC1C,8CAA8C;AAChD;;;;AAKA,IAAa,SAA4B;CACvC,MAAM;EAAE,MAAM;EAAqB,SAAA;CAAqB;CACxD;AACF;;AAGA,IAAM,mBAA4D,OAAO,YACvE,OAAO,KAAK,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,MAAM,OAAO,CAAC,CACvD;;;;;AAMA,IAAa,UAAU,EACrB,aAAa;CACX,MAAM;CACN,SAAS,EAAE,KAAK,OAAO;CACvB,OAAO;AACT,EACF;;;;;AAMA,IAAA,iBAAe;CAAE;CAAQ;CAAO;AAAQ"}
|
package/index.cjs
CHANGED
|
@@ -26,7 +26,7 @@ require("./turn_runner.cjs");
|
|
|
26
26
|
*
|
|
27
27
|
* @tip This is a constant that is replaced during the build process with the actual version of the package.
|
|
28
28
|
*/
|
|
29
|
-
var version = "1.20260607.
|
|
29
|
+
var version = "1.20260607.2";
|
|
30
30
|
//#endregion
|
|
31
31
|
exports.ArtifactTool = require_spooled_artifact.ArtifactTool;
|
|
32
32
|
exports.DispatchRunner = require_dispatch_runner.DispatchRunner;
|
package/index.mjs
CHANGED
|
@@ -24,7 +24,7 @@ import "./turn_runner.mjs";
|
|
|
24
24
|
*
|
|
25
25
|
* @tip This is a constant that is replaced during the build process with the actual version of the package.
|
|
26
26
|
*/
|
|
27
|
-
var version = "1.20260607.
|
|
27
|
+
var version = "1.20260607.2";
|
|
28
28
|
//#endregion
|
|
29
29
|
export { ArtifactTool, DispatchRunner, E_DISPATCH_PIPELINE_ERROR, E_INPUT_PIPELINE_ERROR, E_INVALID_INITIAL_IDENTITY_VALUE, E_INVALID_INITIAL_MEMORY_VALUE, E_INVALID_INITIAL_MESSAGE_VALUE, E_INVALID_INITIAL_REGISTRY_VALUE, E_INVALID_INITIAL_THOUGHT_VALUE, E_INVALID_INITIAL_TOOL_CALL_VALUE, E_INVALID_INITIAL_TOOL_VALUE, E_INVALID_INITIAL_TURN_GATE_VALUE, E_INVALID_LLM_DISPATCH_INPUT, E_INVALID_LLM_EXECUTION_CONTEXT, E_INVALID_TOOL_ARGS, E_INVALID_TURN_CONTEXT, E_INVALID_TURN_GATE_RESOLUTION, E_INVALID_TURN_RUNNER_CONFIG, E_LLM_EXECUTION_ALREADY_SIGNALLED, E_LLM_EXECUTION_EXECUTOR_ERROR, E_LLM_EXECUTION_GATE_NOT_SUPPORTED, E_NOT_A_SPOOL_READER, E_OUTPUT_PIPELINE_ERROR, E_PIPELINE_SHORT_CIRCUITED, E_TOOL_ALREADY_REGISTERED, E_TOOL_DOWNSTREAM_ERROR, E_TURN_GATE_ABORTED, E_TURN_GATE_TIMEOUT, Identity, Media, Memory, Message, Registry, Retrievable, SpooledArtifact, SpooledJsonArtifact, SpooledMarkdownArtifact, Thought, TokenEncoding, Tokenizable, Tool, ToolCall, ToolRegistry, TurnRunner, ValidationException, fromFetch, fromWebFile, implementsMediaReader, implementsSpoolReader, inMemoryMediaReader, isArtifactTool, isBaseException, isDispatchContext, isDispatchRunner, isError, isIdentity, isInstanceOf, isMedia, isMemory, isMessage, isObject, isRegistry, isSpooledArtifact, isSpooledArtifactConstructor, isSpooledJsonArtifact, isSpooledMarkdownArtifact, isThought, isTokenizable, isTool, isToolCall, isToolRegistry, isTurnContext, isTurnGate, isTurnRunner, mediaReaderSchema, version };
|
|
30
30
|
|