@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 +32 -0
- package/dist/index.d.mts +12 -0
- package/dist/index.mjs +64 -0
- package/package.json +32 -0
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.
|
package/dist/index.d.mts
ADDED
|
@@ -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
|
+
}
|