@adonis-agora/agent 0.1.0 → 0.2.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/CHANGELOG.md +21 -0
- package/dist/src/actor-resolver.js +86 -0
- package/dist/src/actor-resolver.js.map +1 -0
- package/dist/src/agent-registry.js +17 -0
- package/dist/src/agent-registry.js.map +1 -0
- package/dist/src/ai-sdk/index.js +2 -0
- package/dist/src/ai-sdk/index.js.map +1 -0
- package/dist/src/authorizer.js +21 -0
- package/dist/src/authorizer.js.map +1 -0
- package/dist/src/durable/agent-run-workflow.d.ts +6 -2
- package/dist/src/durable/agent-run-workflow.d.ts.map +1 -1
- package/dist/src/durable/agent-run-workflow.js +5 -15
- package/dist/src/durable/agent-run-workflow.js.map +1 -1
- package/dist/src/hooks/tools.d.ts +45 -0
- package/dist/src/hooks/tools.d.ts.map +1 -0
- package/dist/src/hooks/tools.js +48 -0
- package/dist/src/hooks/tools.js.map +1 -0
- package/dist/src/in-process-sink.d.ts +16 -0
- package/dist/src/in-process-sink.d.ts.map +1 -0
- package/dist/src/in-process-sink.js +57 -0
- package/dist/src/in-process-sink.js.map +1 -0
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +1 -1
- package/dist/src/personas.js +14 -0
- package/dist/src/personas.js.map +1 -0
- package/dist/src/spi/actor-resolver.js +2 -0
- package/dist/src/spi/actor-resolver.js.map +1 -0
- package/dist/src/spi/agent-runner.js +2 -0
- package/dist/src/spi/agent-runner.js.map +1 -0
- package/dist/src/spi/model-provider.js +2 -0
- package/dist/src/spi/model-provider.js.map +1 -0
- package/dist/src/spi/quota-store.js +2 -0
- package/dist/src/spi/quota-store.js.map +1 -0
- package/dist/src/spi/roles-policy.js +2 -0
- package/dist/src/spi/roles-policy.js.map +1 -0
- package/dist/src/spi/token-stream-sink.d.ts +22 -0
- package/dist/src/spi/token-stream-sink.d.ts.map +1 -0
- package/dist/src/spi/token-stream-sink.js +2 -0
- package/dist/src/spi/token-stream-sink.js.map +1 -0
- package/dist/src/spi/tool.js +2 -0
- package/dist/src/spi/tool.js.map +1 -0
- package/dist/src/testing/fake-model-provider.js +36 -0
- package/dist/src/testing/fake-model-provider.js.map +1 -0
- package/dist/src/testing/in-memory-quota.js +24 -0
- package/dist/src/testing/in-memory-quota.js.map +1 -0
- package/dist/src/testing/in-memory-sink.js +55 -0
- package/dist/src/testing/in-memory-sink.js.map +1 -0
- package/dist/src/tool-discovery.js +126 -0
- package/dist/src/tool-discovery.js.map +1 -0
- package/dist/src/tool-registry.js +90 -0
- package/dist/src/tool-registry.js.map +1 -0
- package/dist/stubs/main.d.ts +3 -0
- package/dist/stubs/main.d.ts.map +1 -0
- package/dist/stubs/main.js +4 -0
- package/dist/stubs/main.js.map +1 -0
- package/package.json +6 -5
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# @adonis-agora/agent
|
|
2
|
+
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`f1fea00`](https://github.com/DavideCarvalho/adonis-agent/commit/f1fea00e165ef6d106fa67ed9ceda6e03ddbca3b) - Suporta `@adonis-agora/durable` 0.8.x (o peer passa de `^0.7.0` para `^0.8.0`).
|
|
8
|
+
|
|
9
|
+
O durable 0.8.0 removeu o decorator `@Workflow`, que o `AgentRunWorkflow` usava, em favor de
|
|
10
|
+
`BaseWorkflow` + `static workflow = { name, version }`. Instalar agent 0.1.0 ao lado de durable
|
|
11
|
+
0.8.0 derrubava o modo durable inteiro — `TypeError: (0 , Workflow) is not a function` ao carregar
|
|
12
|
+
o módulo, com o provider caindo silenciosamente no runner inline. O `^0.7.0` barrava a combinação,
|
|
13
|
+
então ninguém instalou os dois juntos; o preço era ficar preso ao durable 0.7.
|
|
14
|
+
|
|
15
|
+
O `AgentRunWorkflow` agora estende `BaseWorkflow` e declara `static workflow`. O resto da
|
|
16
|
+
integração (`WorkflowEngine.start/signal/cancel`, `registerWorkflowClass`, `WorkflowSuspended`,
|
|
17
|
+
`ContinueAsNew`, `WorkflowCtx`) não mudou.
|
|
18
|
+
|
|
19
|
+
O bug nasceu de um vão de teste: o `durable` não era devDependency, então o lockfile resolvia
|
|
20
|
+
0.7.0 e a suíte exercitava o runner durable contra a versão antiga — verde e cega para o 0.8.0.
|
|
21
|
+
Agora é devDependency em `^0.8.0`, e os testes rodam contra a mesma versão que o peer promete.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default {@link ActorResolver} the provider installs when `config/agent.ts` sets no
|
|
3
|
+
* `actorResolver`. It throws on every request rather than inventing an identity — security by
|
|
4
|
+
* default. Wire a real resolver (e.g. {@link AuthActorResolver}) or the opt-in
|
|
5
|
+
* {@link HeaderActorResolver} via `defineConfig({ actorResolver })`.
|
|
6
|
+
*/
|
|
7
|
+
export class UnconfiguredActorResolver {
|
|
8
|
+
resolve() {
|
|
9
|
+
throw new Error('No actorResolver configured. @adonis-agora/agent refuses to fabricate a caller identity. ' +
|
|
10
|
+
'Set defineConfig({ actorResolver }) in config/agent.ts with a resolver that reads your ' +
|
|
11
|
+
'authenticated principal (e.g. AuthActorResolver over ctx.auth.user), or the built-in ' +
|
|
12
|
+
'HeaderActorResolver behind a trusted gateway.');
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
/** Read a string header off an Adonis-ish `HttpContext` without trusting its concrete shape. */
|
|
16
|
+
function readHeader(ctx, name) {
|
|
17
|
+
const request = ctx.request;
|
|
18
|
+
const value = request?.header?.(name);
|
|
19
|
+
return typeof value === 'string' ? value : undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* A development / gateway {@link ActorResolver} that trusts request headers:
|
|
23
|
+
* `x-actor-id` (required), `x-actor-role` (comma-separated → `roles`), `x-tenant-ref`.
|
|
24
|
+
*
|
|
25
|
+
* **Security:** it throws when `x-actor-id` is absent — it never fabricates an identity and never
|
|
26
|
+
* grants a default role (an actor with no `x-actor-role` gets `roles: []`, i.e. no tools). Trusting
|
|
27
|
+
* client headers is only safe behind a gateway that strips and re-sets them from an authenticated
|
|
28
|
+
* principal. Real deployments should provide their own resolver (or {@link AuthActorResolver}) that
|
|
29
|
+
* reads a verified session/JWT instead.
|
|
30
|
+
*/
|
|
31
|
+
export class HeaderActorResolver {
|
|
32
|
+
resolve(ctx) {
|
|
33
|
+
const id = readHeader(ctx, 'x-actor-id');
|
|
34
|
+
if (id === undefined || id.length === 0) {
|
|
35
|
+
throw new Error('HeaderActorResolver: missing x-actor-id header. No default actor is fabricated. ' +
|
|
36
|
+
'Send x-actor-id from a trusted gateway, or configure defineConfig({ actorResolver }) ' +
|
|
37
|
+
'with a resolver that reads your authenticated principal.');
|
|
38
|
+
}
|
|
39
|
+
const roles = (readHeader(ctx, 'x-actor-role') ?? '')
|
|
40
|
+
.split(',')
|
|
41
|
+
.map((role) => role.trim())
|
|
42
|
+
.filter((role) => role.length > 0);
|
|
43
|
+
const tenantRef = readHeader(ctx, 'x-tenant-ref');
|
|
44
|
+
return {
|
|
45
|
+
id,
|
|
46
|
+
roles,
|
|
47
|
+
...(tenantRef !== undefined ? { tenantRef } : {}),
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Reads Adonis's authenticated principal (`ctx.auth.user`, populated by `@adonisjs/auth`) into an
|
|
53
|
+
* {@link Actor}. Fail-closed: throws when no user is authenticated rather than fabricating one. Pass
|
|
54
|
+
* a `toActor` mapper when your user model doesn't expose `id`/`roles`/`tenantRef` directly (e.g. to
|
|
55
|
+
* pull roles from a relation). This is the resolver most apps wire in `config/agent.ts`.
|
|
56
|
+
*/
|
|
57
|
+
export class AuthActorResolver {
|
|
58
|
+
options;
|
|
59
|
+
constructor(options = {}) {
|
|
60
|
+
this.options = options;
|
|
61
|
+
}
|
|
62
|
+
resolve(ctx) {
|
|
63
|
+
const user = ctx.auth?.user;
|
|
64
|
+
if (user === undefined || user === null) {
|
|
65
|
+
throw new Error('AuthActorResolver: no authenticated user on ctx.auth.user. Authenticate the request ' +
|
|
66
|
+
'(e.g. an auth middleware) before it reaches the agent routes; no identity is fabricated.');
|
|
67
|
+
}
|
|
68
|
+
if (this.options.toActor !== undefined) {
|
|
69
|
+
return this.options.toActor(user);
|
|
70
|
+
}
|
|
71
|
+
const record = user;
|
|
72
|
+
if (record.id === undefined || record.id === null) {
|
|
73
|
+
throw new Error('AuthActorResolver: ctx.auth.user has no id; pass a toActor mapper.');
|
|
74
|
+
}
|
|
75
|
+
const roles = Array.isArray(record.roles)
|
|
76
|
+
? record.roles.filter((role) => typeof role === 'string')
|
|
77
|
+
: [];
|
|
78
|
+
const tenantRef = typeof record.tenantRef === 'string' ? record.tenantRef : undefined;
|
|
79
|
+
return {
|
|
80
|
+
id: String(record.id),
|
|
81
|
+
roles,
|
|
82
|
+
...(tenantRef !== undefined ? { tenantRef } : {}),
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=actor-resolver.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor-resolver.js","sourceRoot":"","sources":["../../src/actor-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Holds the named agent definitions registered via `AgentModule.forFeature([...])`. */
|
|
2
|
+
export class AgentRegistry {
|
|
3
|
+
definitions = new Map();
|
|
4
|
+
register(definition) {
|
|
5
|
+
this.definitions.set(definition.name, definition);
|
|
6
|
+
}
|
|
7
|
+
get(name) {
|
|
8
|
+
return this.definitions.get(name);
|
|
9
|
+
}
|
|
10
|
+
has(name) {
|
|
11
|
+
return this.definitions.has(name);
|
|
12
|
+
}
|
|
13
|
+
list() {
|
|
14
|
+
return [...this.definitions.values()];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=agent-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-registry.js","sourceRoot":"","sources":["../../src/agent-registry.ts"],"names":[],"mappings":"AAEA,wFAAwF;AACxF,MAAM,OAAO,aAAa;IACP,WAAW,GAAG,IAAI,GAAG,EAA2B,CAAC;IAElE,QAAQ,CAAC,UAA2B;QAClC,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACpD,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,GAAG,CAAC,IAAY;QACd,OAAO,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACpC,CAAC;IAED,IAAI;QACF,OAAO,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAA0B,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { DefaultRolesPolicy } from './tool-registry.js';
|
|
2
|
+
/**
|
|
3
|
+
* The default tool authorizer the provider binds when `config/agent.ts` sets no `authorizer` /
|
|
4
|
+
* `rolesPolicy`. Fail-closed and ADMIN-only by default: a tool that declares no `roles` is offered
|
|
5
|
+
* (and invocable) ONLY to an actor holding one of the configured `defaultRoles` (`['ADMIN']` unless
|
|
6
|
+
* overridden). Authorization is a plain set intersection of the actor's roles against the tool's.
|
|
7
|
+
*
|
|
8
|
+
* This is a thin, explicitly-named binding over core's {@link DefaultRolesPolicy} (the `RolesPolicy`
|
|
9
|
+
* seam) so apps that plug an ability-aware gate (`@adonis-agora/authz` Bouncer adapter) swap ONLY the
|
|
10
|
+
* binding, never the seam. The double check — offered-tools filter AND an invoke-time re-check inside
|
|
11
|
+
* `ToolRegistry.invoke` — both run through this same `can(actor, tool)`.
|
|
12
|
+
*/
|
|
13
|
+
export class DefaultToolAuthorizer extends DefaultRolesPolicy {
|
|
14
|
+
constructor(defaultRoles = ['ADMIN']) {
|
|
15
|
+
super(defaultRoles);
|
|
16
|
+
}
|
|
17
|
+
can(actor, tool) {
|
|
18
|
+
return super.can(actor, tool);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=authorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizer.js","sourceRoot":"","sources":["../../src/authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD;;;;;;;;;;GAUG;AACH,MAAM,OAAO,qBAAsB,SAAQ,kBAAkB;IAC3D,YAAY,eAAyB,CAAC,OAAO,CAAC;QAC5C,KAAK,CAAC,YAAY,CAAC,CAAC;IACtB,CAAC;IAEQ,GAAG,CAAC,KAAY,EAAE,IAAc;QACvC,OAAO,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;CACF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type WorkflowCtx } from '@adonis-agora/durable';
|
|
1
|
+
import { BaseWorkflow, type WorkflowCtx } from '@adonis-agora/durable';
|
|
2
2
|
import type { AgentRunInput } from '../types.js';
|
|
3
3
|
/**
|
|
4
4
|
* The workflow input. A superset of {@link AgentRunInput} carrying the two fields only the durable
|
|
@@ -29,7 +29,11 @@ export interface DurableAgentRunInput extends AgentRunInput {
|
|
|
29
29
|
*
|
|
30
30
|
* Instantiated by the engine with no arguments; its deps come from {@link getDurableAgentContext}.
|
|
31
31
|
*/
|
|
32
|
-
export declare class AgentRunWorkflow {
|
|
32
|
+
export declare class AgentRunWorkflow extends BaseWorkflow {
|
|
33
|
+
static workflow: {
|
|
34
|
+
name: string;
|
|
35
|
+
version: string;
|
|
36
|
+
};
|
|
33
37
|
run(ctx: WorkflowCtx, input: DurableAgentRunInput): Promise<{
|
|
34
38
|
text: string;
|
|
35
39
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-workflow.d.ts","sourceRoot":"","sources":["../../../src/durable/agent-run-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"agent-run-workflow.d.ts","sourceRoot":"","sources":["../../../src/durable/agent-run-workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EAEZ,KAAK,WAAW,EAEjB,MAAM,uBAAuB,CAAC;AAI/B,OAAO,KAAK,EAAE,aAAa,EAAY,MAAM,aAAa,CAAC;AAG3D;;;;;;;;GAQG;AACH,MAAM,WAAW,oBAAqB,SAAQ,aAAa;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AA+BD;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,gBAAiB,SAAQ,YAAY;IAChD,OAAgB,QAAQ;;;MAA6C;IAE/D,GAAG,CAAC,GAAG,EAAE,WAAW,EAAE,KAAK,EAAE,oBAAoB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;CAuEpF"}
|
|
@@ -1,11 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
-
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
-
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
-
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
-
};
|
|
7
|
-
var AgentRunWorkflow_1;
|
|
8
|
-
import { ContinueAsNew, Workflow, WorkflowSuspended, } from '@adonis-agora/durable';
|
|
1
|
+
import { BaseWorkflow, ContinueAsNew, WorkflowSuspended, } from '@adonis-agora/durable';
|
|
9
2
|
import { utcDay } from '../agent-deps.js';
|
|
10
3
|
import { runAgentLoop } from '../agent-loop.js';
|
|
11
4
|
import { getDurableAgentContext } from './agent-run-context.js';
|
|
@@ -52,7 +45,8 @@ function childSinkWriter(inner) {
|
|
|
52
45
|
*
|
|
53
46
|
* Instantiated by the engine with no arguments; its deps come from {@link getDurableAgentContext}.
|
|
54
47
|
*/
|
|
55
|
-
|
|
48
|
+
export class AgentRunWorkflow extends BaseWorkflow {
|
|
49
|
+
static workflow = { name: 'agora.agent.run', version: '1' };
|
|
56
50
|
async run(ctx, input) {
|
|
57
51
|
const { factory, store } = getDurableAgentContext();
|
|
58
52
|
const day = input.day ?? utcDay();
|
|
@@ -84,7 +78,7 @@ let AgentRunWorkflow = AgentRunWorkflow_1 = class AgentRunWorkflow {
|
|
|
84
78
|
});
|
|
85
79
|
return thread.id;
|
|
86
80
|
});
|
|
87
|
-
return ctx.child(
|
|
81
|
+
return ctx.child(AgentRunWorkflow, {
|
|
88
82
|
agentName,
|
|
89
83
|
threadId: subThreadId,
|
|
90
84
|
actor: input.actor,
|
|
@@ -120,9 +114,5 @@ let AgentRunWorkflow = AgentRunWorkflow_1 = class AgentRunWorkflow {
|
|
|
120
114
|
throw error;
|
|
121
115
|
}
|
|
122
116
|
}
|
|
123
|
-
}
|
|
124
|
-
AgentRunWorkflow = AgentRunWorkflow_1 = __decorate([
|
|
125
|
-
Workflow({ name: 'agora.agent.run', version: '1' })
|
|
126
|
-
], AgentRunWorkflow);
|
|
127
|
-
export { AgentRunWorkflow };
|
|
117
|
+
}
|
|
128
118
|
//# sourceMappingURL=agent-run-workflow.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-run-workflow.js","sourceRoot":"","sources":["../../../src/durable/agent-run-workflow.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"agent-run-workflow.js","sourceRoot":"","sources":["../../../src/durable/agent-run-workflow.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { IndexGenerator } from '@adonisjs/assembler/index_generator';
|
|
2
|
+
/**
|
|
3
|
+
* Where the generated tools barrel is written, relative to the app root. The agent provider imports
|
|
4
|
+
* THIS path at boot (build-time codegen) instead of scanning `app/agent_tools` with `readdir` at
|
|
5
|
+
* runtime. Kept in sync with the module the provider imports.
|
|
6
|
+
*/
|
|
7
|
+
export declare const GENERATED_TOOLS_OUTPUT = ".adonisjs/agent/tools.ts";
|
|
8
|
+
/** Options for {@link toolsHook} — mirror the relevant `IndexGenerator.add` knobs. */
|
|
9
|
+
export interface ToolsHookOptions {
|
|
10
|
+
/** Directory the generator scans for tool modules, relative to the app root. Default `app/agent_tools`. */
|
|
11
|
+
source?: string;
|
|
12
|
+
/** Import alias the generated barrel uses for each tool module. Default `#agent_tools`. */
|
|
13
|
+
importAlias?: string;
|
|
14
|
+
/** Output path for the generated barrel, relative to the app root. Default `.adonisjs/agent/tools.ts`. */
|
|
15
|
+
output?: string;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* An AdonisJS **Assembler `init` hook** that generates a typed barrel of the app's `app/agent_tools/`
|
|
19
|
+
* directory at build/dev time — exactly how `@adonisjs/core` generates the controllers/events barrels
|
|
20
|
+
* and how `@adonis-agora/durable`'s steps hook does for `app/steps`. The provider imports the generated
|
|
21
|
+
* `.adonisjs/agent/tools.ts` at boot and registers every `@AiTool`/`defineTool` export it finds
|
|
22
|
+
* (falling back to the runtime scan when the barrel is absent).
|
|
23
|
+
*
|
|
24
|
+
* Register it in `adonisrc.ts`:
|
|
25
|
+
*
|
|
26
|
+
* ```ts
|
|
27
|
+
* export default defineConfig({
|
|
28
|
+
* hooks: {
|
|
29
|
+
* init: [() => import('@adonis-agora/agent/hooks/tools')],
|
|
30
|
+
* },
|
|
31
|
+
* })
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function toolsHook(options?: ToolsHookOptions): {
|
|
35
|
+
run(_parent: unknown, _hooks: unknown, indexGenerator: IndexGenerator): void;
|
|
36
|
+
};
|
|
37
|
+
/**
|
|
38
|
+
* The default export is the hook object itself, so `() => import('@adonis-agora/agent/hooks/tools')`
|
|
39
|
+
* in `adonisrc.ts` resolves to a ready hook (the assembler calls its `run`).
|
|
40
|
+
*/
|
|
41
|
+
declare const _default: {
|
|
42
|
+
run(_parent: unknown, _hooks: unknown, indexGenerator: IndexGenerator): void;
|
|
43
|
+
};
|
|
44
|
+
export default _default;
|
|
45
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../../src/hooks/tools.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAE1E;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AAEjE,sFAAsF;AACtF,MAAM,WAAW,gBAAgB;IAC/B,2GAA2G;IAC3G,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0GAA0G;IAC1G,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,CAAC,OAAO,GAAE,gBAAqB;iBAMvC,OAAO,UAAU,OAAO,kBAAkB,cAAc,GAAG,IAAI;EAa/E;AAED;;;GAGG;;iBAlBc,OAAO,UAAU,OAAO,kBAAkB,cAAc,GAAG,IAAI;;AAmBhF,wBAA2B"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the generated tools barrel is written, relative to the app root. The agent provider imports
|
|
3
|
+
* THIS path at boot (build-time codegen) instead of scanning `app/agent_tools` with `readdir` at
|
|
4
|
+
* runtime. Kept in sync with the module the provider imports.
|
|
5
|
+
*/
|
|
6
|
+
export const GENERATED_TOOLS_OUTPUT = '.adonisjs/agent/tools.ts';
|
|
7
|
+
/**
|
|
8
|
+
* An AdonisJS **Assembler `init` hook** that generates a typed barrel of the app's `app/agent_tools/`
|
|
9
|
+
* directory at build/dev time — exactly how `@adonisjs/core` generates the controllers/events barrels
|
|
10
|
+
* and how `@adonis-agora/durable`'s steps hook does for `app/steps`. The provider imports the generated
|
|
11
|
+
* `.adonisjs/agent/tools.ts` at boot and registers every `@AiTool`/`defineTool` export it finds
|
|
12
|
+
* (falling back to the runtime scan when the barrel is absent).
|
|
13
|
+
*
|
|
14
|
+
* Register it in `adonisrc.ts`:
|
|
15
|
+
*
|
|
16
|
+
* ```ts
|
|
17
|
+
* export default defineConfig({
|
|
18
|
+
* hooks: {
|
|
19
|
+
* init: [() => import('@adonis-agora/agent/hooks/tools')],
|
|
20
|
+
* },
|
|
21
|
+
* })
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function toolsHook(options = {}) {
|
|
25
|
+
const source = options.source ?? 'app/agent_tools';
|
|
26
|
+
const importAlias = options.importAlias ?? '#agent_tools';
|
|
27
|
+
const output = options.output ?? GENERATED_TOOLS_OUTPUT;
|
|
28
|
+
return {
|
|
29
|
+
run(_parent, _hooks, indexGenerator) {
|
|
30
|
+
indexGenerator.add('agent_tools', {
|
|
31
|
+
source,
|
|
32
|
+
as: 'barrelFile',
|
|
33
|
+
exportName: 'tools',
|
|
34
|
+
importAlias,
|
|
35
|
+
removeSuffix: 'tool',
|
|
36
|
+
skipSegments: ['agent_tools'],
|
|
37
|
+
output,
|
|
38
|
+
comment: true,
|
|
39
|
+
});
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The default export is the hook object itself, so `() => import('@adonis-agora/agent/hooks/tools')`
|
|
45
|
+
* in `adonisrc.ts` resolves to a ready hook (the assembler calls its `run`).
|
|
46
|
+
*/
|
|
47
|
+
export default toolsHook();
|
|
48
|
+
//# sourceMappingURL=tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/hooks/tools.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,0BAA0B,CAAC;AAYjE;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,SAAS,CAAC,UAA4B,EAAE;IACtD,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,iBAAiB,CAAC;IACnD,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,cAAc,CAAC;IAC1D,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,sBAAsB,CAAC;IAExD,OAAO;QACL,GAAG,CAAC,OAAgB,EAAE,MAAe,EAAE,cAA8B;YACnE,cAAc,CAAC,GAAG,CAAC,aAAa,EAAE;gBAChC,MAAM;gBACN,EAAE,EAAE,YAAY;gBAChB,UAAU,EAAE,OAAO;gBACnB,WAAW;gBACX,YAAY,EAAE,MAAM;gBACpB,YAAY,EAAE,CAAC,aAAa,CAAC;gBAC7B,MAAM;gBACN,OAAO,EAAE,IAAI;aACd,CAAC,CAAC;QACL,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,eAAe,SAAS,EAAE,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { SinkWriter, TokenStreamSink } from './spi/token-stream-sink.js';
|
|
2
|
+
/**
|
|
3
|
+
* The default {@link TokenStreamSink}: buffers chunks per run in-process so a reconnecting
|
|
4
|
+
* subscriber replays everything so far, then follows live until the run ends. Good for a single
|
|
5
|
+
* replica; a multi-replica deployment needs a shared (Redis) sink so any pod can serve any run's
|
|
6
|
+
* stream. Byte-identical to the `InMemoryTokenStreamSink` shipped from `./testing`.
|
|
7
|
+
*/
|
|
8
|
+
export declare class InProcessTokenStreamSink implements TokenStreamSink {
|
|
9
|
+
private readonly runs;
|
|
10
|
+
private buffer;
|
|
11
|
+
private wake;
|
|
12
|
+
open(runId: string): SinkWriter;
|
|
13
|
+
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
14
|
+
close(runId: string): void;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=in-process-sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-process-sink.d.ts","sourceRoot":"","sources":["../../src/in-process-sink.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAQ9E;;;;;GAKG;AACH,qBAAa,wBAAyB,YAAW,eAAe;IAC9D,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IAErD,OAAO,CAAC,MAAM;IASd,OAAO,CAAC,IAAI;IAOZ,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU;IAcxB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC;IAkB1D,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI;CAG3B"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The default {@link TokenStreamSink}: buffers chunks per run in-process so a reconnecting
|
|
3
|
+
* subscriber replays everything so far, then follows live until the run ends. Good for a single
|
|
4
|
+
* replica; a multi-replica deployment needs a shared (Redis) sink so any pod can serve any run's
|
|
5
|
+
* stream. Byte-identical to the `InMemoryTokenStreamSink` shipped from `./testing`.
|
|
6
|
+
*/
|
|
7
|
+
export class InProcessTokenStreamSink {
|
|
8
|
+
runs = new Map();
|
|
9
|
+
buffer(runId) {
|
|
10
|
+
let buf = this.runs.get(runId);
|
|
11
|
+
if (buf === undefined) {
|
|
12
|
+
buf = { chunks: [], ended: false, notify: new Set() };
|
|
13
|
+
this.runs.set(runId, buf);
|
|
14
|
+
}
|
|
15
|
+
return buf;
|
|
16
|
+
}
|
|
17
|
+
wake(buf) {
|
|
18
|
+
for (const resolve of buf.notify) {
|
|
19
|
+
resolve();
|
|
20
|
+
}
|
|
21
|
+
buf.notify.clear();
|
|
22
|
+
}
|
|
23
|
+
open(runId) {
|
|
24
|
+
const buf = this.buffer(runId);
|
|
25
|
+
return {
|
|
26
|
+
write: (chunk) => {
|
|
27
|
+
buf.chunks.push(chunk);
|
|
28
|
+
this.wake(buf);
|
|
29
|
+
},
|
|
30
|
+
end: () => {
|
|
31
|
+
buf.ended = true;
|
|
32
|
+
this.wake(buf);
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
async *subscribe(runId) {
|
|
37
|
+
const buf = this.buffer(runId);
|
|
38
|
+
let index = 0;
|
|
39
|
+
while (true) {
|
|
40
|
+
while (index < buf.chunks.length) {
|
|
41
|
+
const chunk = buf.chunks[index];
|
|
42
|
+
index += 1;
|
|
43
|
+
if (chunk !== undefined) {
|
|
44
|
+
yield chunk;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
if (buf.ended) {
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
await new Promise((resolve) => buf.notify.add(resolve));
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
close(runId) {
|
|
54
|
+
this.runs.delete(runId);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=in-process-sink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-process-sink.js","sourceRoot":"","sources":["../../src/in-process-sink.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,MAAM,OAAO,wBAAwB;IAClB,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE7C,MAAM,CAAC,KAAa;QAC1B,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,GAAG,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,IAAI,CAAC,GAAc;QACzB,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,KAAa;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO;YACL,KAAK,EAAE,CAAC,KAAiB,EAAE,EAAE;gBAC3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;YACD,GAAG,EAAE,GAAG,EAAE;gBACR,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,CAAC,SAAS,CAAC,KAAa;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,EAAE,CAAC;YACZ,OAAO,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChC,KAAK,IAAI,CAAC,CAAC;gBACX,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
package/dist/src/index.d.ts
CHANGED
package/dist/src/index.js
CHANGED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** First filter layer: drop tools the actor's role may not invoke. `can` may be async (authz). */
|
|
2
|
+
export async function filterToolsByRole(tools, actor, policy) {
|
|
3
|
+
const checked = await Promise.all(tools.map(async (tool) => ({ tool, allowed: await policy.can(actor, tool) })));
|
|
4
|
+
return checked.filter((entry) => entry.allowed).map((entry) => entry.tool);
|
|
5
|
+
}
|
|
6
|
+
/** Second filter layer: if the persona pins an allow-list, keep only those tool names. */
|
|
7
|
+
export function personaFilterTools(tools, allowedTools) {
|
|
8
|
+
if (allowedTools === undefined) {
|
|
9
|
+
return tools;
|
|
10
|
+
}
|
|
11
|
+
const allowed = new Set(allowedTools);
|
|
12
|
+
return tools.filter((tool) => allowed.has(tool.name));
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=personas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"personas.js","sourceRoot":"","sources":["../../src/personas.ts"],"names":[],"mappings":"AAGA,kGAAkG;AAClG,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,KAAiB,EACjB,KAAY,EACZ,MAAmB;IAEnB,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,CAC/B,KAAK,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAC9E,CAAC;IACF,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;AAC7E,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,kBAAkB,CAChC,KAAiB,EACjB,YAAkC;IAElC,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,YAAY,CAAC,CAAC;IACtC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACxD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"actor-resolver.js","sourceRoot":"","sources":["../../../src/spi/actor-resolver.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-runner.js","sourceRoot":"","sources":["../../../src/spi/agent-runner.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-provider.js","sourceRoot":"","sources":["../../../src/spi/model-provider.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quota-store.js","sourceRoot":"","sources":["../../../src/spi/quota-store.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"roles-policy.js","sourceRoot":"","sources":["../../../src/spi/roles-policy.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The "data plane": live token transport, decoupled from the durable control plane.
|
|
3
|
+
*
|
|
4
|
+
* The model turn writes deltas to a `SinkWriter` keyed by runId; the HTTP layer
|
|
5
|
+
* `subscribe`s by runId and pipes the chunks to the browser as SSE. A late subscriber
|
|
6
|
+
* (reconnect/resume) replays buffered chunks first, then follows live — which is what
|
|
7
|
+
* makes streaming survive a dropped connection or a pod restart.
|
|
8
|
+
*/
|
|
9
|
+
export interface SinkWriter {
|
|
10
|
+
write(chunk: Uint8Array): void | Promise<void>;
|
|
11
|
+
/** Mark the run's stream finished (no more chunks). */
|
|
12
|
+
end(): void | Promise<void>;
|
|
13
|
+
}
|
|
14
|
+
export interface TokenStreamSink {
|
|
15
|
+
/** Open (or reopen) the writer for a run. */
|
|
16
|
+
open(runId: string): SinkWriter | Promise<SinkWriter>;
|
|
17
|
+
/** Replay buffered chunks for the run, then yield live ones until `end()`. */
|
|
18
|
+
subscribe(runId: string): AsyncIterable<Uint8Array>;
|
|
19
|
+
/** Drop any buffer/resources for the run. */
|
|
20
|
+
close(runId: string): void | Promise<void>;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=token-stream-sink.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-stream-sink.d.ts","sourceRoot":"","sources":["../../../src/spi/token-stream-sink.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/C,uDAAuD;IACvD,GAAG,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;IACtD,8EAA8E;IAC9E,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC,CAAC;IACpD,6CAA6C;IAC7C,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-stream-sink.js","sourceRoot":"","sources":["../../../src/spi/token-stream-sink.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../src/spi/tool.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A deterministic, offline `ModelProvider`. Drives the agent loop without any API key,
|
|
3
|
+
* streaming the scripted text to the sink and optionally requesting one tool call.
|
|
4
|
+
*/
|
|
5
|
+
export class FakeModelProvider {
|
|
6
|
+
script;
|
|
7
|
+
constructor(script) {
|
|
8
|
+
this.script = script;
|
|
9
|
+
}
|
|
10
|
+
async runTurn(args) {
|
|
11
|
+
const turnIndex = args.messages.filter((message) => message.role === 'assistant').length;
|
|
12
|
+
const turn = this.script(args, turnIndex);
|
|
13
|
+
const encoder = new TextEncoder();
|
|
14
|
+
await args.sink.write(encoder.encode(turn.text));
|
|
15
|
+
const toolCalls = turn.toolCall
|
|
16
|
+
? [
|
|
17
|
+
{
|
|
18
|
+
id: `call-${turnIndex}-${turn.toolCall.name}`,
|
|
19
|
+
name: turn.toolCall.name,
|
|
20
|
+
input: turn.toolCall.input,
|
|
21
|
+
},
|
|
22
|
+
]
|
|
23
|
+
: [];
|
|
24
|
+
return {
|
|
25
|
+
text: turn.text,
|
|
26
|
+
toolCalls,
|
|
27
|
+
usage: { inputTokens: args.messages.length, outputTokens: turn.text.length },
|
|
28
|
+
...(turn.costUsd !== undefined ? { costUsd: turn.costUsd } : {}),
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** A trivial script: stream a fixed reply and never call a tool. */
|
|
33
|
+
export function echoScript(reply = 'ok') {
|
|
34
|
+
return () => ({ text: reply });
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=fake-model-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fake-model-provider.js","sourceRoot":"","sources":["../../../src/testing/fake-model-provider.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,MAAM,OAAO,iBAAiB;IACC;IAA7B,YAA6B,MAAkB;QAAlB,WAAM,GAAN,MAAM,CAAY;IAAG,CAAC;IAEnD,KAAK,CAAC,OAAO,CAAC,IAAmB;QAC/B,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,MAAM,CAAC;QACzF,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QAE1C,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;QAClC,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEjD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ;YAC7B,CAAC,CAAC;gBACE;oBACE,EAAE,EAAE,QAAQ,SAAS,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE;oBAC7C,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI;oBACxB,KAAK,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK;iBAC3B;aACF;YACH,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO;YACL,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS;YACT,KAAK,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAC5E,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACjE,CAAC;IACJ,CAAC;CACF;AAED,oEAAoE;AACpE,MAAM,UAAU,UAAU,CAAC,KAAK,GAAG,IAAI;IACrC,OAAO,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** In-memory per-actor/day token budget for tests and the offline demo. */
|
|
2
|
+
export class InMemoryQuotaStore {
|
|
3
|
+
limitTokens;
|
|
4
|
+
used = new Map();
|
|
5
|
+
constructor(limitTokens = 1_000_000) {
|
|
6
|
+
this.limitTokens = limitTokens;
|
|
7
|
+
}
|
|
8
|
+
key(actorRef, day) {
|
|
9
|
+
return `${actorRef}:${day}`;
|
|
10
|
+
}
|
|
11
|
+
async check(actorRef, day) {
|
|
12
|
+
const usedTokens = this.used.get(this.key(actorRef, day)) ?? 0;
|
|
13
|
+
return {
|
|
14
|
+
usedTokens,
|
|
15
|
+
limitTokens: this.limitTokens,
|
|
16
|
+
withinLimit: usedTokens < this.limitTokens,
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
async bump(actorRef, day, tokens) {
|
|
20
|
+
const key = this.key(actorRef, day);
|
|
21
|
+
this.used.set(key, (this.used.get(key) ?? 0) + tokens);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=in-memory-quota.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-quota.js","sourceRoot":"","sources":["../../../src/testing/in-memory-quota.ts"],"names":[],"mappings":"AAEA,2EAA2E;AAC3E,MAAM,OAAO,kBAAkB;IAGA;IAFZ,IAAI,GAAG,IAAI,GAAG,EAAkB,CAAC;IAElD,YAA6B,cAAc,SAAS;QAAvB,gBAAW,GAAX,WAAW,CAAY;IAAG,CAAC;IAEhD,GAAG,CAAC,QAAgB,EAAE,GAAW;QACvC,OAAO,GAAG,QAAQ,IAAI,GAAG,EAAE,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,QAAgB,EAAE,GAAW;QACvC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;QAC/D,OAAO;YACL,UAAU;YACV,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,WAAW,EAAE,UAAU,GAAG,IAAI,CAAC,WAAW;SAC3C,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,QAAgB,EAAE,GAAW,EAAE,MAAc;QACtD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC;IACzD,CAAC;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory `TokenStreamSink`. Buffers chunks per run so a late subscriber (reconnect)
|
|
3
|
+
* replays everything emitted so far, then follows live until the run ends.
|
|
4
|
+
*/
|
|
5
|
+
export class InMemoryTokenStreamSink {
|
|
6
|
+
runs = new Map();
|
|
7
|
+
buffer(runId) {
|
|
8
|
+
let buf = this.runs.get(runId);
|
|
9
|
+
if (buf === undefined) {
|
|
10
|
+
buf = { chunks: [], ended: false, notify: new Set() };
|
|
11
|
+
this.runs.set(runId, buf);
|
|
12
|
+
}
|
|
13
|
+
return buf;
|
|
14
|
+
}
|
|
15
|
+
wake(buf) {
|
|
16
|
+
for (const resolve of buf.notify) {
|
|
17
|
+
resolve();
|
|
18
|
+
}
|
|
19
|
+
buf.notify.clear();
|
|
20
|
+
}
|
|
21
|
+
open(runId) {
|
|
22
|
+
const buf = this.buffer(runId);
|
|
23
|
+
return {
|
|
24
|
+
write: (chunk) => {
|
|
25
|
+
buf.chunks.push(chunk);
|
|
26
|
+
this.wake(buf);
|
|
27
|
+
},
|
|
28
|
+
end: () => {
|
|
29
|
+
buf.ended = true;
|
|
30
|
+
this.wake(buf);
|
|
31
|
+
},
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
async *subscribe(runId) {
|
|
35
|
+
const buf = this.buffer(runId);
|
|
36
|
+
let index = 0;
|
|
37
|
+
while (true) {
|
|
38
|
+
while (index < buf.chunks.length) {
|
|
39
|
+
const chunk = buf.chunks[index];
|
|
40
|
+
index += 1;
|
|
41
|
+
if (chunk !== undefined) {
|
|
42
|
+
yield chunk;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
if (buf.ended) {
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
await new Promise((resolve) => buf.notify.add(resolve));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
close(runId) {
|
|
52
|
+
this.runs.delete(runId);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=in-memory-sink.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"in-memory-sink.js","sourceRoot":"","sources":["../../../src/testing/in-memory-sink.ts"],"names":[],"mappings":"AAQA;;;GAGG;AACH,MAAM,OAAO,uBAAuB;IACjB,IAAI,GAAG,IAAI,GAAG,EAAqB,CAAC;IAE7C,MAAM,CAAC,KAAa;QAC1B,IAAI,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,GAAG,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,CAAC;YACtD,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAC5B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,IAAI,CAAC,GAAc;QACzB,KAAK,MAAM,OAAO,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACjC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,IAAI,CAAC,KAAa;QAChB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,OAAO;YACL,KAAK,EAAE,CAAC,KAAiB,EAAE,EAAE;gBAC3B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;YACD,GAAG,EAAE,GAAG,EAAE;gBACR,GAAG,CAAC,KAAK,GAAG,IAAI,CAAC;gBACjB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,CAAC;SACF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,CAAC,SAAS,CAAC,KAAa;QAC5B,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,OAAO,IAAI,EAAE,CAAC;YACZ,OAAO,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;gBACjC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAChC,KAAK,IAAI,CAAC,CAAC;gBACX,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;oBACxB,MAAM,KAAK,CAAC;gBACd,CAAC;YACH,CAAC;YACD,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;gBACd,OAAO;YACT,CAAC;YACD,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { readdir } from 'node:fs/promises';
|
|
2
|
+
import { extname, join } from 'node:path';
|
|
3
|
+
import { pathToFileURL } from 'node:url';
|
|
4
|
+
import { isBrandedFunctionalTool, readAiToolMeta, } from './ai-tool-ref.js';
|
|
5
|
+
/**
|
|
6
|
+
* Register one module export into the registry if it is an `@AiTool` class or a `defineTool(...)`
|
|
7
|
+
* functional tool; ignore anything else. A name already present is skipped (first wins). Returns the
|
|
8
|
+
* registered descriptor, or `null` when the export was not a tool / duplicated a registered name.
|
|
9
|
+
*/
|
|
10
|
+
export function registerToolExport(registry, exported, defaultRoles) {
|
|
11
|
+
// A functional tool: a branded { spec, handler } from `defineTool`.
|
|
12
|
+
if (isBrandedFunctionalTool(exported)) {
|
|
13
|
+
return registerFunctionalTool(registry, exported, defaultRoles);
|
|
14
|
+
}
|
|
15
|
+
// An `@AiTool` class: read its stamped metadata, instantiate once, bind `execute`.
|
|
16
|
+
const meta = readAiToolMeta(exported);
|
|
17
|
+
if (meta === undefined || typeof exported !== 'function') {
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
const instance = instantiate(exported);
|
|
21
|
+
if (instance === null || typeof instance.execute !== 'function') {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
if (registry.has(meta.name)) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
registry.register(specFromMeta(meta, defaultRoles), {
|
|
28
|
+
execute: (input, ctx) => instance.execute(input, ctx),
|
|
29
|
+
});
|
|
30
|
+
return { name: meta.name, source: 'class' };
|
|
31
|
+
}
|
|
32
|
+
/** Register a `defineTool` functional tool, applying `defaultRoles` when it declares none. */
|
|
33
|
+
export function registerFunctionalTool(registry, tool, defaultRoles) {
|
|
34
|
+
if (registry.has(tool.spec.name)) {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
const spec = tool.spec.roles === undefined ? { ...tool.spec, roles: defaultRoles } : tool.spec;
|
|
38
|
+
registry.register(spec, tool.handler);
|
|
39
|
+
return { name: tool.spec.name, source: 'functional' };
|
|
40
|
+
}
|
|
41
|
+
function specFromMeta(meta, defaultRoles) {
|
|
42
|
+
return {
|
|
43
|
+
name: meta.name,
|
|
44
|
+
kind: meta.kind,
|
|
45
|
+
description: meta.description,
|
|
46
|
+
inputSchema: meta.input,
|
|
47
|
+
roles: meta.roles ?? defaultRoles,
|
|
48
|
+
...(meta.ability !== undefined ? { ability: meta.ability } : {}),
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
function instantiate(cls) {
|
|
52
|
+
try {
|
|
53
|
+
const Ctor = cls;
|
|
54
|
+
return new Ctor();
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Pick the module extension for the running environment so a built app (`.js`) and a dev/ts app
|
|
62
|
+
* (`.ts`, run under a loader) never double-register the same tool — matching the durable scanner.
|
|
63
|
+
*/
|
|
64
|
+
const MODULE_EXT = extname(import.meta.url || '') === '.ts' ? '.ts' : '.js';
|
|
65
|
+
/**
|
|
66
|
+
* Scan `dir` RECURSIVELY for modules and register every exported `@AiTool` class / `defineTool`
|
|
67
|
+
* tool into `registry` — the `app/agent_tools` convention. Only the environment-appropriate extension
|
|
68
|
+
* is imported and each export is visited once (deduped), so a built `.js` and a dev `.ts` of the same
|
|
69
|
+
* module never both register. Missing directory → no-op (the convention is opt-in). `defaultRoles`
|
|
70
|
+
* fills a tool that declares no `roles` (ADMIN-only by default).
|
|
71
|
+
*/
|
|
72
|
+
export async function discoverTools(registry, dir, defaultRoles) {
|
|
73
|
+
let entries;
|
|
74
|
+
try {
|
|
75
|
+
entries = await readdir(dir, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
if (err.code === 'ENOENT') {
|
|
79
|
+
return [];
|
|
80
|
+
}
|
|
81
|
+
throw err;
|
|
82
|
+
}
|
|
83
|
+
const registered = [];
|
|
84
|
+
const seen = new Set();
|
|
85
|
+
for (const entry of entries.sort()) {
|
|
86
|
+
if (extname(entry) !== MODULE_EXT || entry.endsWith(`.d${MODULE_EXT}`)) {
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
const mod = (await import(pathToFileURL(join(dir, entry)).href));
|
|
90
|
+
for (const exported of Object.values(mod)) {
|
|
91
|
+
if (seen.has(exported)) {
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
seen.add(exported);
|
|
95
|
+
const result = registerToolExport(registry, exported, defaultRoles);
|
|
96
|
+
if (result !== null) {
|
|
97
|
+
registered.push(result);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return registered;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Register every `@AiTool` / `defineTool` reachable from a generated {@link ToolsBarrel} — the
|
|
105
|
+
* build-time equivalent of {@link discoverTools} with no runtime `readdir`. Each module is imported
|
|
106
|
+
* once and each export registered once (deduped).
|
|
107
|
+
*/
|
|
108
|
+
export async function registerToolsFromBarrel(registry, barrel, defaultRoles) {
|
|
109
|
+
const registered = [];
|
|
110
|
+
const seen = new Set();
|
|
111
|
+
for (const load of Object.values(barrel)) {
|
|
112
|
+
const mod = await load();
|
|
113
|
+
for (const exported of Object.values(mod)) {
|
|
114
|
+
if (seen.has(exported)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
seen.add(exported);
|
|
118
|
+
const result = registerToolExport(registry, exported, defaultRoles);
|
|
119
|
+
if (result !== null) {
|
|
120
|
+
registered.push(result);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return registered;
|
|
125
|
+
}
|
|
126
|
+
//# sourceMappingURL=tool-discovery.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-discovery.js","sourceRoot":"","sources":["../../src/tool-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAIL,uBAAuB,EACvB,cAAc,GACf,MAAM,kBAAkB,CAAC;AAW1B;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAChC,QAAsB,EACtB,QAAiB,EACjB,YAAsB;IAEtB,oEAAoE;IACpE,IAAI,uBAAuB,CAAC,QAAQ,CAAC,EAAE,CAAC;QACtC,OAAO,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IAClE,CAAC;IACD,mFAAmF;IACnF,MAAM,IAAI,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IACtC,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;QACzD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,QAAQ,GAAG,WAAW,CAAC,QAAqB,CAAC,CAAC;IACpD,IAAI,QAAQ,KAAK,IAAI,IAAI,OAAO,QAAQ,CAAC,OAAO,KAAK,UAAU,EAAE,CAAC;QAChE,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IACD,QAAQ,CAAC,QAAQ,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE;QAClD,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;KACtD,CAAC,CAAC;IACH,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;AAC9C,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,sBAAsB,CACpC,QAAsB,EACtB,IAAoB,EACpB,YAAsB;IAEtB,IAAI,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,IAAI,GACR,IAAI,CAAC,IAAI,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IACpF,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;AACxD,CAAC;AAED,SAAS,YAAY,CAAC,IAAgB,EAAE,YAAsB;IAC5D,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,WAAW,EAAE,IAAI,CAAC,WAAW;QAC7B,WAAW,EAAE,IAAI,CAAC,KAAK;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,YAAY;QACjC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjE,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,GAAc;IACjC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAuC,CAAC;QACrD,OAAO,IAAI,IAAI,EAAE,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;AAE5E;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAsB,EACtB,GAAW,EACX,YAAsB;IAEtB,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAK,GAA6B,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,MAAM,GAAG,CAAC;IACZ,CAAC;IACD,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;IAChC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;QACnC,IAAI,OAAO,CAAC,KAAK,CAAC,KAAK,UAAU,IAAI,KAAK,CAAC,QAAQ,CAAC,KAAK,UAAU,EAAE,CAAC,EAAE,CAAC;YACvE,SAAS;QACX,CAAC;QACD,MAAM,GAAG,GAAG,CAAC,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAA4B,CAAC;QAC5F,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;YACpE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC;AAQD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,QAAsB,EACtB,MAAmB,EACnB,YAAsB;IAEtB,MAAM,UAAU,GAAqB,EAAE,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,GAAG,EAAW,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;QACzC,MAAM,GAAG,GAAG,MAAM,IAAI,EAAE,CAAC;QACzB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;YAC1C,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvB,SAAS;YACX,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACnB,MAAM,MAAM,GAAG,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;YACpE,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;gBACpB,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { filterToolsByRole, personaFilterTools } from './personas.js';
|
|
2
|
+
/** Thrown when an actor invokes a tool their role is not allowed. */
|
|
3
|
+
export class ToolForbiddenError extends Error {
|
|
4
|
+
toolName;
|
|
5
|
+
constructor(toolName) {
|
|
6
|
+
super(`Tool "${toolName}" is not allowed for this role`);
|
|
7
|
+
this.toolName = toolName;
|
|
8
|
+
this.name = 'ToolForbiddenError';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
/** Thrown when a tool is invoked that was never registered. */
|
|
12
|
+
export class ToolNotFoundError extends Error {
|
|
13
|
+
toolName;
|
|
14
|
+
constructor(toolName) {
|
|
15
|
+
super(`Tool "${toolName}" is not registered`);
|
|
16
|
+
this.toolName = toolName;
|
|
17
|
+
this.name = 'ToolNotFoundError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
/** Thrown when a tool's input fails its Standard Schema validation. */
|
|
21
|
+
export class ToolInputInvalidError extends Error {
|
|
22
|
+
toolName;
|
|
23
|
+
issues;
|
|
24
|
+
constructor(toolName, issues) {
|
|
25
|
+
super(`Invalid input for tool "${toolName}": ${issues.map((issue) => issue.message).join('; ')}`);
|
|
26
|
+
this.toolName = toolName;
|
|
27
|
+
this.issues = issues;
|
|
28
|
+
this.name = 'ToolInputInvalidError';
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Holds every registered tool and gates invocation.
|
|
33
|
+
*
|
|
34
|
+
* Note: `definitionsFor` returns NEUTRAL definitions (no `execute`). The agent loop runs
|
|
35
|
+
* each tool itself as a (durable) step — so even read tools are not auto-executed by the
|
|
36
|
+
* model. `action` tools additionally require HITL approval before the loop runs them.
|
|
37
|
+
*/
|
|
38
|
+
export class ToolRegistry {
|
|
39
|
+
entries = new Map();
|
|
40
|
+
register(spec, handler) {
|
|
41
|
+
this.entries.set(spec.name, { spec, handler });
|
|
42
|
+
}
|
|
43
|
+
has(name) {
|
|
44
|
+
return this.entries.has(name);
|
|
45
|
+
}
|
|
46
|
+
spec(name) {
|
|
47
|
+
return this.entries.get(name)?.spec;
|
|
48
|
+
}
|
|
49
|
+
allSpecs() {
|
|
50
|
+
return [...this.entries.values()].map((entry) => entry.spec);
|
|
51
|
+
}
|
|
52
|
+
/** The tools to offer the model for this actor+persona, after the two filter layers. */
|
|
53
|
+
async definitionsFor(actor, policy, allowedTools) {
|
|
54
|
+
const roleScoped = await filterToolsByRole(this.allSpecs(), actor, policy);
|
|
55
|
+
const personaScoped = personaFilterTools(roleScoped, allowedTools);
|
|
56
|
+
return personaScoped.map((spec) => ({
|
|
57
|
+
name: spec.name,
|
|
58
|
+
kind: spec.kind,
|
|
59
|
+
description: spec.description,
|
|
60
|
+
inputSchema: spec.inputSchema,
|
|
61
|
+
}));
|
|
62
|
+
}
|
|
63
|
+
/** Run a tool. Re-checks the role (defense-in-depth) and re-parses the input via Zod. */
|
|
64
|
+
async invoke(name, input, ctx, policy) {
|
|
65
|
+
const entry = this.entries.get(name);
|
|
66
|
+
if (entry === undefined) {
|
|
67
|
+
throw new ToolNotFoundError(name);
|
|
68
|
+
}
|
|
69
|
+
if (!(await policy.can(ctx.actor, entry.spec))) {
|
|
70
|
+
throw new ToolForbiddenError(name);
|
|
71
|
+
}
|
|
72
|
+
const validation = await entry.spec.inputSchema['~standard'].validate(input);
|
|
73
|
+
if (validation.issues !== undefined) {
|
|
74
|
+
throw new ToolInputInvalidError(name, validation.issues);
|
|
75
|
+
}
|
|
76
|
+
return entry.handler.execute(validation.value, ctx);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** Default gate: one of the actor's roles must be in spec.roles (defaulting to ADMIN-only). */
|
|
80
|
+
export class DefaultRolesPolicy {
|
|
81
|
+
defaultRoles;
|
|
82
|
+
constructor(defaultRoles = ['ADMIN']) {
|
|
83
|
+
this.defaultRoles = defaultRoles;
|
|
84
|
+
}
|
|
85
|
+
can(actor, tool) {
|
|
86
|
+
const allowed = tool.roles ?? this.defaultRoles;
|
|
87
|
+
return (actor.roles ?? []).some((role) => allowed.includes(role));
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=tool-registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../../src/tool-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../stubs/main.ts"],"names":[],"mappings":"AAEA,6EAA6E;AAC7E,eAAO,MAAM,SAAS,QAAgD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"main.js","sourceRoot":"","sources":["../../stubs/main.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,6EAA6E;AAC7E,MAAM,CAAC,MAAM,SAAS,GAAG,aAAa,CAAC,IAAI,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@adonis-agora/agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -89,14 +89,14 @@
|
|
|
89
89
|
"@standard-schema/spec": "^1.0.0"
|
|
90
90
|
},
|
|
91
91
|
"peerDependencies": {
|
|
92
|
+
"@adonis-agora/authz": "^0.4.0",
|
|
93
|
+
"@adonis-agora/diagnostics": "^0.1.0",
|
|
94
|
+
"@adonis-agora/durable": "^0.8.0",
|
|
95
|
+
"@adonis-agora/telescope": "^0.4.0",
|
|
92
96
|
"@adonisjs/assembler": "^8.4.0",
|
|
93
97
|
"@adonisjs/core": "^7.3.0",
|
|
94
98
|
"@adonisjs/lucid": "^22.4.0",
|
|
95
99
|
"@adonisjs/redis": "^9.2.0",
|
|
96
|
-
"@adonis-agora/durable": "^0.7.0",
|
|
97
|
-
"@adonis-agora/diagnostics": "^0.1.0",
|
|
98
|
-
"@adonis-agora/authz": "^0.4.0",
|
|
99
|
-
"@adonis-agora/telescope": "^0.4.0",
|
|
100
100
|
"ai": "^7.0.0",
|
|
101
101
|
"node-sql-parser": "^5.3.0",
|
|
102
102
|
"zod": "^3.23.0 || ^4.0.0"
|
|
@@ -137,6 +137,7 @@
|
|
|
137
137
|
}
|
|
138
138
|
},
|
|
139
139
|
"devDependencies": {
|
|
140
|
+
"@adonis-agora/durable": "^0.8.0",
|
|
140
141
|
"@adonisjs/assembler": "^8.4.0",
|
|
141
142
|
"@adonisjs/core": "^7.3.0",
|
|
142
143
|
"@adonisjs/lucid": "^22.4.0",
|