@alint-js/agent-apeira 0.0.4

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 ADDED
@@ -0,0 +1,32 @@
1
+ # `@alint-js/agent-apeira`
2
+
3
+ > [!IMPORTANT]
4
+ > This package is a WIP. APIs may be subject to major changes.
5
+
6
+ An [Apeira](https://github.com/moeru-ai/apeira)-backed `AgentAdapter` for alint. One of the swappable vendor adapters behind `@alint-js/agent`.
7
+
8
+ ## What it does
9
+
10
+ `createApeiraAdapter()` returns an `AgentAdapter` that runs a rule's request through
11
+ Apeira's `chat` runner: it translates the framework-agnostic `AgentTool`s to xsai tools,
12
+ runs the tool loop (capped at 8 steps), and reads back the final answer and usage.
13
+
14
+ ## How to use
15
+
16
+ ```ts
17
+ import { createApeiraAdapter } from '@alint-js/agent-apeira'
18
+
19
+ const adapter = createApeiraAdapter()
20
+ ```
21
+
22
+ Pass `{ createRunner }` to inject a custom Apeira runner.
23
+
24
+ ## When to use
25
+
26
+ - You want tool-using rules powered by Apeira on the xsai stack.
27
+
28
+ ## When not to use
29
+
30
+ - You use a different agent framework. Pick that vendor's adapter (e.g.
31
+ `@alint-js/agent-pi`) or write your own `AgentAdapter`.
32
+ - Your rule needs no tools. Keep it on the plain `@alint-js/core` rule DSL.
@@ -0,0 +1,12 @@
1
+ import { Runner } from "apeira";
2
+ import { AgentAdapter } from "@alint-js/agent";
3
+ import { ResolvedModel } from "@alint-js/core";
4
+
5
+ //#region src/index.d.ts
6
+ interface ApeiraAdapterOptions {
7
+ createRunner: (model: ResolvedModel) => Runner;
8
+ }
9
+ declare function createApeiraAdapter(options?: Partial<ApeiraAdapterOptions>): AgentAdapter;
10
+ declare function createApeiraRunner(model: ResolvedModel): Runner;
11
+ //#endregion
12
+ export { ApeiraAdapterOptions, createApeiraAdapter, createApeiraRunner };
package/dist/index.mjs ADDED
@@ -0,0 +1,64 @@
1
+ import { chat, stepCountAtLeast, user } from "apeira";
2
+ import { rawTool } from "xsai";
3
+ //#region src/index.ts
4
+ const maxSteps = 8;
5
+ function createApeiraAdapter(options = {}) {
6
+ const createRunner = options.createRunner ?? createApeiraRunner;
7
+ return async (request) => {
8
+ const result = await createRunner(request.model)(buildRunnerContext(request));
9
+ return {
10
+ answer: extractAnswer(result.output),
11
+ usage: mapUsage(result.usage)
12
+ };
13
+ };
14
+ }
15
+ function createApeiraRunner(model) {
16
+ return chat({
17
+ baseURL: model.provider.endpoint,
18
+ headers: model.provider.headers,
19
+ model: model.id,
20
+ stopWhen: stepCountAtLeast(maxSteps)
21
+ });
22
+ }
23
+ function buildRunnerContext(request) {
24
+ return {
25
+ channel: noopChannel(),
26
+ input: [user(request.prompt)],
27
+ instructions: request.instructions,
28
+ tools: toRunnerTools(request.tools),
29
+ turnId: "alint"
30
+ };
31
+ }
32
+ function extractAnswer(output) {
33
+ for (let index = output.length - 1; index >= 0; index -= 1) {
34
+ const item = output[index];
35
+ if (item.role === "assistant" && typeof item.content === "string") return item.content;
36
+ }
37
+ return "";
38
+ }
39
+ function mapUsage(usage) {
40
+ if (!usage) return;
41
+ return {
42
+ inputTokens: usage.inputTokens,
43
+ outputTokens: usage.outputTokens,
44
+ totalTokens: usage.totalTokens
45
+ };
46
+ }
47
+ function noopChannel() {
48
+ return {
49
+ emit: () => {},
50
+ subscribe: () => () => {}
51
+ };
52
+ }
53
+ function toRunnerTools(tools) {
54
+ return tools.map((agentTool) => rawTool({
55
+ description: agentTool.description,
56
+ execute: async (input) => {
57
+ return await agentTool.execute(input) ?? "";
58
+ },
59
+ name: agentTool.name,
60
+ parameters: agentTool.parameters
61
+ }));
62
+ }
63
+ //#endregion
64
+ export { createApeiraAdapter, createApeiraRunner };
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@alint-js/agent-apeira",
3
+ "type": "module",
4
+ "version": "0.0.4",
5
+ "exports": {
6
+ ".": {
7
+ "types": "./dist/index.d.mts",
8
+ "default": "./dist/index.mjs"
9
+ },
10
+ "./package.json": "./package.json"
11
+ },
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "dependencies": {
16
+ "apeira": "^0.0.6",
17
+ "xsai": "^0.5.0-beta.6",
18
+ "@alint-js/core": "0.0.4",
19
+ "@alint-js/agent": "0.0.4"
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "^26.0.1",
23
+ "tsdown": "^0.22.3",
24
+ "typescript": "^6.0.3",
25
+ "vitest": "^4.1.9"
26
+ },
27
+ "scripts": {
28
+ "build": "tsdown",
29
+ "typecheck": "tsc -p tsconfig.json --noEmit",
30
+ "test": "vitest run --config vitest.config.ts"
31
+ }
32
+ }