@adonis-agora/agent 0.1.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/LICENSE +21 -0
- package/dist/configure.d.ts +18 -0
- package/dist/configure.d.ts.map +1 -0
- package/dist/configure.js +29 -0
- package/dist/configure.js.map +1 -0
- package/dist/providers/agent_provider.d.ts +25 -0
- package/dist/providers/agent_provider.d.ts.map +1 -0
- package/dist/providers/agent_provider.js +511 -0
- package/dist/providers/agent_provider.js.map +1 -0
- package/dist/src/actor-resolver.d.ts +41 -0
- package/dist/src/actor-resolver.d.ts.map +1 -0
- package/dist/src/agent-deps-factory.d.ts +59 -0
- package/dist/src/agent-deps-factory.d.ts.map +1 -0
- package/dist/src/agent-deps-factory.js +111 -0
- package/dist/src/agent-deps-factory.js.map +1 -0
- package/dist/src/agent-deps.d.ts +42 -0
- package/dist/src/agent-deps.d.ts.map +1 -0
- package/dist/src/agent-deps.js +5 -0
- package/dist/src/agent-deps.js.map +1 -0
- package/dist/src/agent-loop.d.ts +101 -0
- package/dist/src/agent-loop.d.ts.map +1 -0
- package/dist/src/agent-loop.js +396 -0
- package/dist/src/agent-loop.js.map +1 -0
- package/dist/src/agent-registry.d.ts +10 -0
- package/dist/src/agent-registry.d.ts.map +1 -0
- package/dist/src/agent-service.d.ts +50 -0
- package/dist/src/agent-service.d.ts.map +1 -0
- package/dist/src/agent-service.js +82 -0
- package/dist/src/agent-service.js.map +1 -0
- package/dist/src/ai-sdk/ai-sdk-model.d.ts +17 -0
- package/dist/src/ai-sdk/ai-sdk-model.d.ts.map +1 -0
- package/dist/src/ai-sdk/ai-sdk-model.js +263 -0
- package/dist/src/ai-sdk/ai-sdk-model.js.map +1 -0
- package/dist/src/ai-sdk/index.d.ts +2 -0
- package/dist/src/ai-sdk/index.d.ts.map +1 -0
- package/dist/src/ai-tool-ref.d.ts +79 -0
- package/dist/src/ai-tool-ref.d.ts.map +1 -0
- package/dist/src/ai-tool-ref.js +81 -0
- package/dist/src/ai-tool-ref.js.map +1 -0
- package/dist/src/authorizer.d.ts +18 -0
- package/dist/src/authorizer.d.ts.map +1 -0
- package/dist/src/authz/authz-tool-authorizer.d.ts +85 -0
- package/dist/src/authz/authz-tool-authorizer.d.ts.map +1 -0
- package/dist/src/authz/authz-tool-authorizer.js +63 -0
- package/dist/src/authz/authz-tool-authorizer.js.map +1 -0
- package/dist/src/authz/index.d.ts +3 -0
- package/dist/src/authz/index.d.ts.map +1 -0
- package/dist/src/authz/index.js +2 -0
- package/dist/src/authz/index.js.map +1 -0
- package/dist/src/data/data-tool.d.ts +64 -0
- package/dist/src/data/data-tool.d.ts.map +1 -0
- package/dist/src/data/data-tool.js +146 -0
- package/dist/src/data/data-tool.js.map +1 -0
- package/dist/src/data/index.d.ts +7 -0
- package/dist/src/data/index.d.ts.map +1 -0
- package/dist/src/data/index.js +7 -0
- package/dist/src/data/index.js.map +1 -0
- package/dist/src/data/limit.d.ts +12 -0
- package/dist/src/data/limit.d.ts.map +1 -0
- package/dist/src/data/limit.js +29 -0
- package/dist/src/data/limit.js.map +1 -0
- package/dist/src/data/parser.d.ts +27 -0
- package/dist/src/data/parser.d.ts.map +1 -0
- package/dist/src/data/parser.js +18 -0
- package/dist/src/data/parser.js.map +1 -0
- package/dist/src/data/sql-validator.d.ts +37 -0
- package/dist/src/data/sql-validator.d.ts.map +1 -0
- package/dist/src/data/sql-validator.js +92 -0
- package/dist/src/data/sql-validator.js.map +1 -0
- package/dist/src/data/table-access.d.ts +40 -0
- package/dist/src/data/table-access.d.ts.map +1 -0
- package/dist/src/data/table-access.js +41 -0
- package/dist/src/data/table-access.js.map +1 -0
- package/dist/src/data/tenant-scope.d.ts +39 -0
- package/dist/src/data/tenant-scope.d.ts.map +1 -0
- package/dist/src/data/tenant-scope.js +126 -0
- package/dist/src/data/tenant-scope.js.map +1 -0
- package/dist/src/define_config.d.ts +153 -0
- package/dist/src/define_config.d.ts.map +1 -0
- package/dist/src/define_config.js +7 -0
- package/dist/src/define_config.js.map +1 -0
- package/dist/src/diagnostics.d.ts +82 -0
- package/dist/src/diagnostics.d.ts.map +1 -0
- package/dist/src/diagnostics.js +50 -0
- package/dist/src/diagnostics.js.map +1 -0
- package/dist/src/durable/agent-run-context.d.ts +24 -0
- package/dist/src/durable/agent-run-context.d.ts.map +1 -0
- package/dist/src/durable/agent-run-context.js +17 -0
- package/dist/src/durable/agent-run-context.js.map +1 -0
- package/dist/src/durable/agent-run-workflow.d.ts +37 -0
- package/dist/src/durable/agent-run-workflow.d.ts.map +1 -0
- package/dist/src/durable/agent-run-workflow.js +128 -0
- package/dist/src/durable/agent-run-workflow.js.map +1 -0
- package/dist/src/durable/durable-agent-runner.d.ts +25 -0
- package/dist/src/durable/durable-agent-runner.d.ts.map +1 -0
- package/dist/src/durable/durable-agent-runner.js +59 -0
- package/dist/src/durable/durable-agent-runner.js.map +1 -0
- package/dist/src/durable/index.d.ts +17 -0
- package/dist/src/durable/index.d.ts.map +1 -0
- package/dist/src/durable/index.js +20 -0
- package/dist/src/durable/index.js.map +1 -0
- package/dist/src/index.d.ts +55 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +45 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/personas.d.ts +7 -0
- package/dist/src/personas.d.ts.map +1 -0
- package/dist/src/rag/chunk.d.ts +14 -0
- package/dist/src/rag/chunk.d.ts.map +1 -0
- package/dist/src/rag/chunk.js +42 -0
- package/dist/src/rag/chunk.js.map +1 -0
- package/dist/src/rag/embedding-retriever.d.ts +15 -0
- package/dist/src/rag/embedding-retriever.d.ts.map +1 -0
- package/dist/src/rag/embedding-retriever.js +24 -0
- package/dist/src/rag/embedding-retriever.js.map +1 -0
- package/dist/src/rag/filter.d.ts +6 -0
- package/dist/src/rag/filter.d.ts.map +1 -0
- package/dist/src/rag/filter.js +11 -0
- package/dist/src/rag/filter.js.map +1 -0
- package/dist/src/rag/index.d.ts +8 -0
- package/dist/src/rag/index.d.ts.map +1 -0
- package/dist/src/rag/index.js +8 -0
- package/dist/src/rag/index.js.map +1 -0
- package/dist/src/rag/ingest.d.ts +33 -0
- package/dist/src/rag/ingest.d.ts.map +1 -0
- package/dist/src/rag/ingest.js +37 -0
- package/dist/src/rag/ingest.js.map +1 -0
- package/dist/src/rag/memory-vector-store.d.ts +16 -0
- package/dist/src/rag/memory-vector-store.d.ts.map +1 -0
- package/dist/src/rag/memory-vector-store.js +70 -0
- package/dist/src/rag/memory-vector-store.js.map +1 -0
- package/dist/src/rag/pg-vector-store.d.ts +84 -0
- package/dist/src/rag/pg-vector-store.d.ts.map +1 -0
- package/dist/src/rag/pg-vector-store.js +220 -0
- package/dist/src/rag/pg-vector-store.js.map +1 -0
- package/dist/src/rag/vector-store.d.ts +47 -0
- package/dist/src/rag/vector-store.d.ts.map +1 -0
- package/dist/src/rag/vector-store.js +5 -0
- package/dist/src/rag/vector-store.js.map +1 -0
- package/dist/src/rag-media/diagnostics.d.ts +43 -0
- package/dist/src/rag-media/diagnostics.d.ts.map +1 -0
- package/dist/src/rag-media/diagnostics.js +36 -0
- package/dist/src/rag-media/diagnostics.js.map +1 -0
- package/dist/src/rag-media/index.d.ts +5 -0
- package/dist/src/rag-media/index.d.ts.map +1 -0
- package/dist/src/rag-media/index.js +5 -0
- package/dist/src/rag-media/index.js.map +1 -0
- package/dist/src/rag-media/media-events.d.ts +23 -0
- package/dist/src/rag-media/media-events.d.ts.map +1 -0
- package/dist/src/rag-media/media-events.js +28 -0
- package/dist/src/rag-media/media-events.js.map +1 -0
- package/dist/src/rag-media/media-rag-ingestion.d.ts +155 -0
- package/dist/src/rag-media/media-rag-ingestion.d.ts.map +1 -0
- package/dist/src/rag-media/media-rag-ingestion.js +204 -0
- package/dist/src/rag-media/media-rag-ingestion.js.map +1 -0
- package/dist/src/rag-media/text-extractor.d.ts +46 -0
- package/dist/src/rag-media/text-extractor.d.ts.map +1 -0
- package/dist/src/rag-media/text-extractor.js +92 -0
- package/dist/src/rag-media/text-extractor.js.map +1 -0
- package/dist/src/redis-stream-client.d.ts +29 -0
- package/dist/src/redis-stream-client.d.ts.map +1 -0
- package/dist/src/redis-stream-client.js +2 -0
- package/dist/src/redis-stream-client.js.map +1 -0
- package/dist/src/redis-token-stream-sink.d.ts +36 -0
- package/dist/src/redis-token-stream-sink.d.ts.map +1 -0
- package/dist/src/redis-token-stream-sink.js +94 -0
- package/dist/src/redis-token-stream-sink.js.map +1 -0
- package/dist/src/runners/inline-agent-runner.d.ts +26 -0
- package/dist/src/runners/inline-agent-runner.d.ts.map +1 -0
- package/dist/src/runners/inline-agent-runner.js +85 -0
- package/dist/src/runners/inline-agent-runner.js.map +1 -0
- package/dist/src/spi/actor-directory.d.ts +23 -0
- package/dist/src/spi/actor-directory.d.ts.map +1 -0
- package/dist/src/spi/actor-directory.js +2 -0
- package/dist/src/spi/actor-directory.js.map +1 -0
- package/dist/src/spi/actor-resolver.d.ts +18 -0
- package/dist/src/spi/actor-resolver.d.ts.map +1 -0
- package/dist/src/spi/agent-runner.d.ts +20 -0
- package/dist/src/spi/agent-runner.d.ts.map +1 -0
- package/dist/src/spi/agent-store.d.ts +104 -0
- package/dist/src/spi/agent-store.d.ts.map +1 -0
- package/dist/src/spi/agent-store.js +2 -0
- package/dist/src/spi/agent-store.js.map +1 -0
- package/dist/src/spi/attachment-staging.d.ts +27 -0
- package/dist/src/spi/attachment-staging.d.ts.map +1 -0
- package/dist/src/spi/attachment-staging.js +2 -0
- package/dist/src/spi/attachment-staging.js.map +1 -0
- package/dist/src/spi/embedding-provider.d.ts +12 -0
- package/dist/src/spi/embedding-provider.d.ts.map +1 -0
- package/dist/src/spi/embedding-provider.js +2 -0
- package/dist/src/spi/embedding-provider.js.map +1 -0
- package/dist/src/spi/governance-queries.d.ts +215 -0
- package/dist/src/spi/governance-queries.d.ts.map +1 -0
- package/dist/src/spi/governance-queries.js +15 -0
- package/dist/src/spi/governance-queries.js.map +1 -0
- package/dist/src/spi/model-provider.d.ts +41 -0
- package/dist/src/spi/model-provider.d.ts.map +1 -0
- package/dist/src/spi/pricing-store.d.ts +45 -0
- package/dist/src/spi/pricing-store.d.ts.map +1 -0
- package/dist/src/spi/pricing-store.js +24 -0
- package/dist/src/spi/pricing-store.js.map +1 -0
- package/dist/src/spi/quota-store.d.ts +7 -0
- package/dist/src/spi/quota-store.d.ts.map +1 -0
- package/dist/src/spi/reranker.d.ts +17 -0
- package/dist/src/spi/reranker.d.ts.map +1 -0
- package/dist/src/spi/reranker.js +2 -0
- package/dist/src/spi/reranker.js.map +1 -0
- package/dist/src/spi/retriever.d.ts +28 -0
- package/dist/src/spi/retriever.d.ts.map +1 -0
- package/dist/src/spi/retriever.js +11 -0
- package/dist/src/spi/retriever.js.map +1 -0
- package/dist/src/spi/roles-policy.d.ts +11 -0
- package/dist/src/spi/roles-policy.d.ts.map +1 -0
- package/dist/src/spi/tool.d.ts +21 -0
- package/dist/src/spi/tool.d.ts.map +1 -0
- package/dist/src/stores/factory.d.ts +363 -0
- package/dist/src/stores/factory.d.ts.map +1 -0
- package/dist/src/stores/factory.js +341 -0
- package/dist/src/stores/factory.js.map +1 -0
- package/dist/src/stores/ledger-quota.d.ts +23 -0
- package/dist/src/stores/ledger-quota.d.ts.map +1 -0
- package/dist/src/stores/ledger-quota.js +32 -0
- package/dist/src/stores/ledger-quota.js.map +1 -0
- package/dist/src/stores/lucid-governance-queries.d.ts +73 -0
- package/dist/src/stores/lucid-governance-queries.d.ts.map +1 -0
- package/dist/src/stores/lucid-governance-queries.js +510 -0
- package/dist/src/stores/lucid-governance-queries.js.map +1 -0
- package/dist/src/stores/lucid-pricing.d.ts +20 -0
- package/dist/src/stores/lucid-pricing.d.ts.map +1 -0
- package/dist/src/stores/lucid-pricing.js +67 -0
- package/dist/src/stores/lucid-pricing.js.map +1 -0
- package/dist/src/stores/lucid-schema.d.ts +37 -0
- package/dist/src/stores/lucid-schema.d.ts.map +1 -0
- package/dist/src/stores/lucid-schema.js +139 -0
- package/dist/src/stores/lucid-schema.js.map +1 -0
- package/dist/src/stores/lucid.d.ts +73 -0
- package/dist/src/stores/lucid.d.ts.map +1 -0
- package/dist/src/stores/lucid.js +400 -0
- package/dist/src/stores/lucid.js.map +1 -0
- package/dist/src/telescope/dashboard.d.ts +21 -0
- package/dist/src/telescope/dashboard.d.ts.map +1 -0
- package/dist/src/telescope/dashboard.js +140 -0
- package/dist/src/telescope/dashboard.js.map +1 -0
- package/dist/src/telescope/data-providers.d.ts +39 -0
- package/dist/src/telescope/data-providers.d.ts.map +1 -0
- package/dist/src/telescope/data-providers.js +345 -0
- package/dist/src/telescope/data-providers.js.map +1 -0
- package/dist/src/telescope/extension.d.ts +27 -0
- package/dist/src/telescope/extension.d.ts.map +1 -0
- package/dist/src/telescope/extension.js +45 -0
- package/dist/src/telescope/extension.js.map +1 -0
- package/dist/src/telescope/index.d.ts +5 -0
- package/dist/src/telescope/index.d.ts.map +1 -0
- package/dist/src/telescope/index.js +4 -0
- package/dist/src/telescope/index.js.map +1 -0
- package/dist/src/telescope/telescope-sdk.d.ts +126 -0
- package/dist/src/telescope/telescope-sdk.d.ts.map +1 -0
- package/dist/src/telescope/telescope-sdk.js +15 -0
- package/dist/src/telescope/telescope-sdk.js.map +1 -0
- package/dist/src/testing/fake-embedding-provider.d.ts +37 -0
- package/dist/src/testing/fake-embedding-provider.d.ts.map +1 -0
- package/dist/src/testing/fake-embedding-provider.js +67 -0
- package/dist/src/testing/fake-embedding-provider.js.map +1 -0
- package/dist/src/testing/fake-media.d.ts +44 -0
- package/dist/src/testing/fake-media.d.ts.map +1 -0
- package/dist/src/testing/fake-media.js +69 -0
- package/dist/src/testing/fake-media.js.map +1 -0
- package/dist/src/testing/fake-model-provider.d.ts +29 -0
- package/dist/src/testing/fake-model-provider.d.ts.map +1 -0
- package/dist/src/testing/in-memory-actor-directory.d.ts +14 -0
- package/dist/src/testing/in-memory-actor-directory.d.ts.map +1 -0
- package/dist/src/testing/in-memory-actor-directory.js +27 -0
- package/dist/src/testing/in-memory-actor-directory.js.map +1 -0
- package/dist/src/testing/in-memory-attachment-staging.d.ts +22 -0
- package/dist/src/testing/in-memory-attachment-staging.d.ts.map +1 -0
- package/dist/src/testing/in-memory-attachment-staging.js +28 -0
- package/dist/src/testing/in-memory-attachment-staging.js.map +1 -0
- package/dist/src/testing/in-memory-governance-queries.d.ts +34 -0
- package/dist/src/testing/in-memory-governance-queries.d.ts.map +1 -0
- package/dist/src/testing/in-memory-governance-queries.js +373 -0
- package/dist/src/testing/in-memory-governance-queries.js.map +1 -0
- package/dist/src/testing/in-memory-pricing.d.ts +13 -0
- package/dist/src/testing/in-memory-pricing.d.ts.map +1 -0
- package/dist/src/testing/in-memory-pricing.js +27 -0
- package/dist/src/testing/in-memory-pricing.js.map +1 -0
- package/dist/src/testing/in-memory-quota.d.ts +11 -0
- package/dist/src/testing/in-memory-quota.d.ts.map +1 -0
- package/dist/src/testing/in-memory-sink.d.ts +14 -0
- package/dist/src/testing/in-memory-sink.d.ts.map +1 -0
- package/dist/src/testing/in-memory-store.d.ts +119 -0
- package/dist/src/testing/in-memory-store.d.ts.map +1 -0
- package/dist/src/testing/in-memory-store.js +317 -0
- package/dist/src/testing/in-memory-store.js.map +1 -0
- package/dist/src/testing/index.d.ts +11 -0
- package/dist/src/testing/index.d.ts.map +1 -0
- package/dist/src/testing/index.js +11 -0
- package/dist/src/testing/index.js.map +1 -0
- package/dist/src/tool-discovery.d.ts +35 -0
- package/dist/src/tool-discovery.d.ts.map +1 -0
- package/dist/src/tool-registry.d.ts +45 -0
- package/dist/src/tool-registry.d.ts.map +1 -0
- package/dist/src/tool-retry.d.ts +56 -0
- package/dist/src/tool-retry.d.ts.map +1 -0
- package/dist/src/tool-retry.js +95 -0
- package/dist/src/tool-retry.js.map +1 -0
- package/dist/src/types.d.ts +222 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/stubs/config/agent.stub +55 -0
- package/dist/stubs/database/migrations/create_agent_rag_chunks.stub +41 -0
- package/dist/stubs/database/migrations/create_agent_run_tracking.stub +80 -0
- package/dist/stubs/database/migrations/create_agent_tables.stub +113 -0
- package/package.json +174 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Davi Carvalho
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type Configure from '@adonisjs/core/commands/configure';
|
|
2
|
+
/**
|
|
3
|
+
* `node ace configure @adonis-agora/agent` — auto-wires the package:
|
|
4
|
+
*
|
|
5
|
+
* 1. registers the agent service provider in `adonisrc.ts`;
|
|
6
|
+
* 2. registers the Assembler `init` hook that generates the typed `app/agent_tools` barrel at
|
|
7
|
+
* build/dev time (the provider imports it instead of scanning at runtime; it falls back to the
|
|
8
|
+
* runtime scan when the barrel is absent);
|
|
9
|
+
* 3. publishes `config/agent.ts`;
|
|
10
|
+
* 4. publishes the Lucid migration for the five agent tables (run `node ace migration:run`; delete it
|
|
11
|
+
* if you only use the in-memory store);
|
|
12
|
+
* 5. publishes the additive run-tracking migration (`agent_run` table + `run_id` columns) — run it
|
|
13
|
+
* after the base migration; delete it with the base one if you only use the in-memory store;
|
|
14
|
+
* 6. publishes the pgvector migration for the RAG chunk table (Postgres + pgvector only; delete it
|
|
15
|
+
* unless you use `retrievers.pgvector({...})`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function configure(command: Configure): Promise<void>;
|
|
18
|
+
//# sourceMappingURL=configure.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.d.ts","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,SAAS,MAAM,mCAAmC,CAAC;AAG/D;;;;;;;;;;;;;;GAcG;AACH,wBAAsB,SAAS,CAAC,OAAO,EAAE,SAAS,iBAajD"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { stubsRoot } from './stubs/main.js';
|
|
2
|
+
/**
|
|
3
|
+
* `node ace configure @adonis-agora/agent` — auto-wires the package:
|
|
4
|
+
*
|
|
5
|
+
* 1. registers the agent service provider in `adonisrc.ts`;
|
|
6
|
+
* 2. registers the Assembler `init` hook that generates the typed `app/agent_tools` barrel at
|
|
7
|
+
* build/dev time (the provider imports it instead of scanning at runtime; it falls back to the
|
|
8
|
+
* runtime scan when the barrel is absent);
|
|
9
|
+
* 3. publishes `config/agent.ts`;
|
|
10
|
+
* 4. publishes the Lucid migration for the five agent tables (run `node ace migration:run`; delete it
|
|
11
|
+
* if you only use the in-memory store);
|
|
12
|
+
* 5. publishes the additive run-tracking migration (`agent_run` table + `run_id` columns) — run it
|
|
13
|
+
* after the base migration; delete it with the base one if you only use the in-memory store;
|
|
14
|
+
* 6. publishes the pgvector migration for the RAG chunk table (Postgres + pgvector only; delete it
|
|
15
|
+
* unless you use `retrievers.pgvector({...})`).
|
|
16
|
+
*/
|
|
17
|
+
export async function configure(command) {
|
|
18
|
+
const codemods = await command.createCodemods();
|
|
19
|
+
await codemods.updateRcFile((rcFile) => {
|
|
20
|
+
rcFile.addProvider('@adonis-agora/agent/agent_provider');
|
|
21
|
+
// Generate the typed app/agent_tools barrel at build/dev time (replaces the runtime readdir scan).
|
|
22
|
+
rcFile.addAssemblerHook('init', '@adonis-agora/agent/hooks/tools');
|
|
23
|
+
});
|
|
24
|
+
await codemods.makeUsingStub(stubsRoot, 'config/agent.stub', {});
|
|
25
|
+
await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_agent_tables.stub', {});
|
|
26
|
+
await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_agent_run_tracking.stub', {});
|
|
27
|
+
await codemods.makeUsingStub(stubsRoot, 'database/migrations/create_agent_rag_chunks.stub', {});
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=configure.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"configure.js","sourceRoot":"","sources":["../configure.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAkB;IAChD,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,cAAc,EAAE,CAAC;IAEhD,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC,MAAM,EAAE,EAAE;QACrC,MAAM,CAAC,WAAW,CAAC,oCAAoC,CAAC,CAAC;QACzD,mGAAmG;QACnG,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,iCAAiC,CAAC,CAAC;IACrE,CAAC,CAAC,CAAC;IAEH,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACjE,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,8CAA8C,EAAE,EAAE,CAAC,CAAC;IAC5F,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,oDAAoD,EAAE,EAAE,CAAC,CAAC;IAClG,MAAM,QAAQ,CAAC,aAAa,CAAC,SAAS,EAAE,kDAAkD,EAAE,EAAE,CAAC,CAAC;AAClG,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { ApplicationService } from '@adonisjs/core/types';
|
|
2
|
+
/**
|
|
3
|
+
* Wires `@adonis-agora/agent` into the AdonisJS application from `config/agent.ts`:
|
|
4
|
+
*
|
|
5
|
+
* - `register()` binds the shared `ToolRegistry` + `AgentRegistry` singletons.
|
|
6
|
+
* - `boot()` discovers tools (the generated `hooks/tools` barrel first, then an `app/agent_tools`
|
|
7
|
+
* readdir fallback), registers config-level functional tools and synthesizes `agent`-kind delegate
|
|
8
|
+
* tools for `delegatesTo` edges, builds the runtime graph (store/sink/quota/authorizer/actor-resolver
|
|
9
|
+
* → deps factory → the inline runner → the `AgentService` facade), and mounts the eleven `/agent`
|
|
10
|
+
* routes under `config.path` — plus an optional twelfth `POST /agent/attachments` upload route when
|
|
11
|
+
* `attachmentStaging` is configured.
|
|
12
|
+
*
|
|
13
|
+
* The selected store (`lucid`/`memory`) is built lazily from the config so its peer (`@adonisjs/lucid`)
|
|
14
|
+
* loads only when chosen. Agent lifecycle events are emitted structurally by core onto the
|
|
15
|
+
* `agora:agent:*` diagnostics channel when `@adonis-agora/diagnostics` is installed — no bridge needed.
|
|
16
|
+
*/
|
|
17
|
+
export default class AgentProvider {
|
|
18
|
+
#private;
|
|
19
|
+
protected app: ApplicationService;
|
|
20
|
+
constructor(app: ApplicationService);
|
|
21
|
+
register(): void;
|
|
22
|
+
boot(): Promise<void>;
|
|
23
|
+
shutdown(): Promise<void>;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=agent_provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent_provider.d.ts","sourceRoot":"","sources":["../../providers/agent_provider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAwD/D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,OAAO,OAAO,aAAa;;IAKpB,SAAS,CAAC,GAAG,EAAE,kBAAkB;gBAAvB,GAAG,EAAE,kBAAkB;IAE7C,QAAQ;IAgBF,IAAI;IAoEJ,QAAQ;CA6bf"}
|
|
@@ -0,0 +1,511 @@
|
|
|
1
|
+
import { pathToFileURL } from 'node:url';
|
|
2
|
+
import { AgentDepsFactory, AgentRegistry, AgentService, DefaultToolAuthorizer, InProcessTokenStreamSink, InlineAgentRunner, ToolRegistry, UnconfiguredActorResolver, discoverTools, registerDelegateTools, registerFunctionalTool, registerToolsFromBarrel, } from '../src/index.js';
|
|
3
|
+
/** Default per-file size cap when `attachmentMaxBytes` is omitted (20 MiB). */
|
|
4
|
+
const DEFAULT_MAX_ATTACHMENT_BYTES = 20 * 1024 * 1024;
|
|
5
|
+
/** Default allowlist: what multimodal model providers commonly accept as native image/file parts. */
|
|
6
|
+
const DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES = [
|
|
7
|
+
'image/png',
|
|
8
|
+
'image/jpeg',
|
|
9
|
+
'image/gif',
|
|
10
|
+
'image/webp',
|
|
11
|
+
'application/pdf',
|
|
12
|
+
'text/plain',
|
|
13
|
+
'text/csv',
|
|
14
|
+
];
|
|
15
|
+
/**
|
|
16
|
+
* Wires `@adonis-agora/agent` into the AdonisJS application from `config/agent.ts`:
|
|
17
|
+
*
|
|
18
|
+
* - `register()` binds the shared `ToolRegistry` + `AgentRegistry` singletons.
|
|
19
|
+
* - `boot()` discovers tools (the generated `hooks/tools` barrel first, then an `app/agent_tools`
|
|
20
|
+
* readdir fallback), registers config-level functional tools and synthesizes `agent`-kind delegate
|
|
21
|
+
* tools for `delegatesTo` edges, builds the runtime graph (store/sink/quota/authorizer/actor-resolver
|
|
22
|
+
* → deps factory → the inline runner → the `AgentService` facade), and mounts the eleven `/agent`
|
|
23
|
+
* routes under `config.path` — plus an optional twelfth `POST /agent/attachments` upload route when
|
|
24
|
+
* `attachmentStaging` is configured.
|
|
25
|
+
*
|
|
26
|
+
* The selected store (`lucid`/`memory`) is built lazily from the config so its peer (`@adonisjs/lucid`)
|
|
27
|
+
* loads only when chosen. Agent lifecycle events are emitted structurally by core onto the
|
|
28
|
+
* `agora:agent:*` diagnostics channel when `@adonis-agora/diagnostics` is installed — no bridge needed.
|
|
29
|
+
*/
|
|
30
|
+
export default class AgentProvider {
|
|
31
|
+
app;
|
|
32
|
+
#store = null;
|
|
33
|
+
#sink = null;
|
|
34
|
+
#actorDirectory = null;
|
|
35
|
+
constructor(app) {
|
|
36
|
+
this.app = app;
|
|
37
|
+
}
|
|
38
|
+
register() {
|
|
39
|
+
this.app.container.singleton(ToolRegistry, () => new ToolRegistry());
|
|
40
|
+
this.app.container.singleton(AgentRegistry, () => {
|
|
41
|
+
const config = this.app.config.get('agent', {});
|
|
42
|
+
const registry = new AgentRegistry();
|
|
43
|
+
registry.register({
|
|
44
|
+
name: config.defaultAgent?.name ?? 'default',
|
|
45
|
+
...config.defaultAgent,
|
|
46
|
+
});
|
|
47
|
+
for (const definition of config.agents ?? []) {
|
|
48
|
+
registry.register(definition);
|
|
49
|
+
}
|
|
50
|
+
return registry;
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async boot() {
|
|
54
|
+
const config = this.app.config.get('agent', {});
|
|
55
|
+
const registry = await this.app.container.make(ToolRegistry);
|
|
56
|
+
const agents = await this.app.container.make(AgentRegistry);
|
|
57
|
+
const defaultRoles = config.defaultRoles ?? ['ADMIN'];
|
|
58
|
+
// ── Tool discovery: generated barrel first, else the app/agent_tools readdir fallback ──
|
|
59
|
+
const barrel = await this.#loadGeneratedToolsBarrel();
|
|
60
|
+
if (barrel) {
|
|
61
|
+
await registerToolsFromBarrel(registry, barrel, defaultRoles);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
await discoverTools(registry, this.app.makePath('app/agent_tools'), defaultRoles);
|
|
65
|
+
}
|
|
66
|
+
// Config-level functional tools (defineTool), then synthesized delegate tools.
|
|
67
|
+
for (const tool of config.tools ?? []) {
|
|
68
|
+
registerFunctionalTool(registry, tool, defaultRoles);
|
|
69
|
+
}
|
|
70
|
+
registerDelegateTools(registry, agents);
|
|
71
|
+
// ── Runtime graph ──
|
|
72
|
+
const model = await this.#resolveModel(config);
|
|
73
|
+
const store = await this.#resolveStore(config);
|
|
74
|
+
const sink = await this.#resolveSink(config);
|
|
75
|
+
// Quota is resolved after the store so a ledger-backed quota can read the store's usage ledger.
|
|
76
|
+
const quota = await this.#resolveQuota(config, store);
|
|
77
|
+
const pricingStore = await this.#resolvePricing(config);
|
|
78
|
+
// Governance read-model is resolved after pricing so the Lucid read-model prices its rollups
|
|
79
|
+
// against the same live prices the loop's cost fold uses.
|
|
80
|
+
const governance = await this.#resolveGovernance(config, pricingStore);
|
|
81
|
+
const retriever = await this.#resolveRetriever(config);
|
|
82
|
+
const attachmentStaging = await this.#resolveAttachmentStaging(config);
|
|
83
|
+
const authorizer = this.#resolveAuthorizer(config, defaultRoles);
|
|
84
|
+
const actorResolver = config.actorResolver ?? new UnconfiguredActorResolver();
|
|
85
|
+
// Read-side identity lookup for governance/dashboard surfaces (optional; renders raw refs if unset).
|
|
86
|
+
const actorDirectory = await this.#resolveActorDirectory(config);
|
|
87
|
+
this.#store = store;
|
|
88
|
+
this.#sink = sink;
|
|
89
|
+
this.#actorDirectory = actorDirectory;
|
|
90
|
+
const factory = new AgentDepsFactory({
|
|
91
|
+
model,
|
|
92
|
+
store,
|
|
93
|
+
sink,
|
|
94
|
+
rolesPolicy: authorizer,
|
|
95
|
+
registry,
|
|
96
|
+
agents,
|
|
97
|
+
defaultAgentName: config.defaultAgent?.name ?? 'default',
|
|
98
|
+
...(quota !== undefined ? { quota } : {}),
|
|
99
|
+
...(pricingStore !== undefined ? { pricingStore } : {}),
|
|
100
|
+
...(retriever !== undefined ? { retriever } : {}),
|
|
101
|
+
...(config.retrievalTopK !== undefined ? { retrievalTopK: config.retrievalTopK } : {}),
|
|
102
|
+
...(config.toolTransientRetry !== undefined
|
|
103
|
+
? { toolTransientRetry: config.toolTransientRetry }
|
|
104
|
+
: {}),
|
|
105
|
+
});
|
|
106
|
+
// `durable: true` runs each turn as a replay-safe `@adonis-agora/durable` workflow; it degrades
|
|
107
|
+
// gracefully to the in-process runner when the durable peer isn't installed/configured.
|
|
108
|
+
const runner = config.durable === true
|
|
109
|
+
? ((await this.#resolveDurableRunner(factory, store)) ??
|
|
110
|
+
new InlineAgentRunner(factory, store))
|
|
111
|
+
: new InlineAgentRunner(factory, store);
|
|
112
|
+
const service = new AgentService(runner, store, factory);
|
|
113
|
+
this.app.container.bindValue(AgentService, service);
|
|
114
|
+
await this.#registerRoutes(config, service, actorResolver, attachmentStaging, governance);
|
|
115
|
+
}
|
|
116
|
+
async shutdown() {
|
|
117
|
+
// The Lucid store shares the app's `db` (it owns no connection to close); the in-process sink
|
|
118
|
+
// holds only per-run buffers that GC with the provider. Drop refs so a hot reload starts clean.
|
|
119
|
+
this.#store = null;
|
|
120
|
+
this.#sink = null;
|
|
121
|
+
this.#actorDirectory = null;
|
|
122
|
+
}
|
|
123
|
+
// ── resolution helpers ────────────────────────────────────────────────────
|
|
124
|
+
async #resolveModel(config) {
|
|
125
|
+
const model = config.model;
|
|
126
|
+
if (typeof model === 'function') {
|
|
127
|
+
return model();
|
|
128
|
+
}
|
|
129
|
+
return model;
|
|
130
|
+
}
|
|
131
|
+
async #resolveStore(config) {
|
|
132
|
+
const name = config.store;
|
|
133
|
+
if (name && config.stores?.[name]) {
|
|
134
|
+
return config.stores[name]({ app: this.app });
|
|
135
|
+
}
|
|
136
|
+
const { InMemoryAgentStore } = await import('../src/testing/in-memory-store.js');
|
|
137
|
+
return new InMemoryAgentStore();
|
|
138
|
+
}
|
|
139
|
+
async #resolveSink(config) {
|
|
140
|
+
const sink = config.sink;
|
|
141
|
+
if (sink === undefined)
|
|
142
|
+
return new InProcessTokenStreamSink();
|
|
143
|
+
return typeof sink === 'function' ? sink() : sink;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Build the read-side actor directory from config (an `ActorDirectoryFactory` thunk or a ready
|
|
147
|
+
* instance). `undefined` → governance/dashboard surfaces render raw opaque `actorRef`s.
|
|
148
|
+
*/
|
|
149
|
+
async #resolveActorDirectory(config) {
|
|
150
|
+
const directory = config.actorDirectory;
|
|
151
|
+
if (directory === undefined)
|
|
152
|
+
return null;
|
|
153
|
+
return typeof directory === 'function' ? directory({ app: this.app }) : directory;
|
|
154
|
+
}
|
|
155
|
+
async #resolveQuota(config, store) {
|
|
156
|
+
const quota = config.quota;
|
|
157
|
+
if (quota === undefined)
|
|
158
|
+
return undefined;
|
|
159
|
+
return typeof quota === 'function' ? quota({ app: this.app, store }) : quota;
|
|
160
|
+
}
|
|
161
|
+
async #resolvePricing(config) {
|
|
162
|
+
const pricingStore = config.pricingStore;
|
|
163
|
+
if (pricingStore === undefined)
|
|
164
|
+
return undefined;
|
|
165
|
+
return typeof pricingStore === 'function' ? pricingStore({ app: this.app }) : pricingStore;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Build the governance read-model from config (a `GovernanceQueriesFactory` thunk or a ready
|
|
169
|
+
* instance). The factory receives the already-resolved `pricingStore` so the Lucid read-model prices
|
|
170
|
+
* its rollups against the loop's live prices. `undefined` → the `/agent/governance/*` routes aren't
|
|
171
|
+
* mounted.
|
|
172
|
+
*/
|
|
173
|
+
async #resolveGovernance(config, pricingStore) {
|
|
174
|
+
const governance = config.governanceQueries;
|
|
175
|
+
if (governance === undefined)
|
|
176
|
+
return undefined;
|
|
177
|
+
return typeof governance === 'function'
|
|
178
|
+
? governance({ app: this.app, ...(pricingStore !== undefined ? { pricingStore } : {}) })
|
|
179
|
+
: governance;
|
|
180
|
+
}
|
|
181
|
+
/** Build the inject-mode retriever from config (a `RetrieverFactory` thunk or a ready instance). */
|
|
182
|
+
async #resolveRetriever(config) {
|
|
183
|
+
const retriever = config.retriever;
|
|
184
|
+
if (retriever === undefined)
|
|
185
|
+
return undefined;
|
|
186
|
+
return typeof retriever === 'function' ? retriever({ app: this.app }) : retriever;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Build the attachment-staging store from config (an `AttachmentStagingFactory` thunk or a ready
|
|
190
|
+
* instance). `undefined` → no upload route is mounted (a client sends already-staged references).
|
|
191
|
+
*/
|
|
192
|
+
async #resolveAttachmentStaging(config) {
|
|
193
|
+
const staging = config.attachmentStaging;
|
|
194
|
+
if (staging === undefined)
|
|
195
|
+
return undefined;
|
|
196
|
+
return typeof staging === 'function' ? staging({ app: this.app }) : staging;
|
|
197
|
+
}
|
|
198
|
+
#resolveAuthorizer(config, defaultRoles) {
|
|
199
|
+
return config.authorizer ?? config.rolesPolicy ?? new DefaultToolAuthorizer(defaultRoles);
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Build the durable runner when `durable: true`, or `null` to fall back to inline. The optional
|
|
203
|
+
* `@adonis-agora/durable` peer is imported lazily (so the agent package never hard-depends on it),
|
|
204
|
+
* its {@link WorkflowEngine} resolved from the container (bound by the durable provider), the agent
|
|
205
|
+
* workflow registered on it, and the module-level durable context wired. A missing peer, an
|
|
206
|
+
* unresolvable engine, or any wiring error logs a warning and degrades to the in-process runner
|
|
207
|
+
* rather than breaking boot.
|
|
208
|
+
*/
|
|
209
|
+
async #resolveDurableRunner(factory, store) {
|
|
210
|
+
try {
|
|
211
|
+
const durable = await import('@adonis-agora/durable');
|
|
212
|
+
const engine = await this.app.container.make(durable.WorkflowEngine);
|
|
213
|
+
const { DurableAgentRunner, registerAgentWorkflow, setDurableAgentContext } = await import('../src/durable/index.js');
|
|
214
|
+
setDurableAgentContext({ factory, store });
|
|
215
|
+
registerAgentWorkflow(engine);
|
|
216
|
+
return new DurableAgentRunner(engine, store);
|
|
217
|
+
}
|
|
218
|
+
catch (error) {
|
|
219
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
220
|
+
console.warn(`[@adonis-agora/agent] \`durable: true\` was requested but the durable runner could not be wired (${message}) — is \`@adonis-agora/durable\` installed and configured? Falling back to the in-process (inline) runner.`);
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/** Best-effort import of the build-time tools barrel; `null` when absent (fall back to the scan). */
|
|
225
|
+
async #loadGeneratedToolsBarrel() {
|
|
226
|
+
const path = this.app.makePath('.adonisjs/agent/tools.js');
|
|
227
|
+
try {
|
|
228
|
+
const mod = (await import(pathToFileURL(path).href));
|
|
229
|
+
return mod.tools ?? null;
|
|
230
|
+
}
|
|
231
|
+
catch (err) {
|
|
232
|
+
const code = err.code;
|
|
233
|
+
if (code === 'ERR_MODULE_NOT_FOUND' || code === 'ENOENT')
|
|
234
|
+
return null;
|
|
235
|
+
throw err;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// ── routes ────────────────────────────────────────────────────────────────
|
|
239
|
+
async #registerRoutes(config, service, actorResolver, attachmentStaging, governance) {
|
|
240
|
+
const router = await this.app.container.make('router');
|
|
241
|
+
const path = (config.path ?? 'agent').replace(/^\/+|\/+$/g, '');
|
|
242
|
+
const p = (suffix) => `${path}/${suffix}`;
|
|
243
|
+
// 1. POST /agent/chat — resolve actor, start the run, SSE-pipe the token stream.
|
|
244
|
+
router.post(p('chat'), async (ctx) => {
|
|
245
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
246
|
+
if (actor === null)
|
|
247
|
+
return;
|
|
248
|
+
const body = (ctx.request.body() ?? {});
|
|
249
|
+
const { runId, threadId } = await service.chat({
|
|
250
|
+
actor,
|
|
251
|
+
message: body.message,
|
|
252
|
+
...(body.threadId !== undefined ? { threadId: body.threadId } : {}),
|
|
253
|
+
...(body.agent !== undefined ? { agentName: body.agent } : {}),
|
|
254
|
+
...(body.persona !== undefined ? { personaId: body.persona } : {}),
|
|
255
|
+
...(body.pageContext !== undefined ? { pageContext: body.pageContext } : {}),
|
|
256
|
+
...(body.attachments !== undefined ? { attachments: body.attachments } : {}),
|
|
257
|
+
});
|
|
258
|
+
await this.#pipe(ctx, service, runId, threadId);
|
|
259
|
+
});
|
|
260
|
+
// 2. GET /agent/chat/:runId/stream — re-attach SSE.
|
|
261
|
+
router.get(p('chat/:runId/stream'), async (ctx) => {
|
|
262
|
+
await this.#pipe(ctx, service, String(ctx.params.runId));
|
|
263
|
+
});
|
|
264
|
+
// 3. POST /agent/chat/:runId/cancel.
|
|
265
|
+
router.post(p('chat/:runId/cancel'), async (ctx) => {
|
|
266
|
+
await service.cancel(String(ctx.params.runId));
|
|
267
|
+
return ctx.response.json({ aborted: true });
|
|
268
|
+
});
|
|
269
|
+
// 4. POST /agent/tool-call/approve.
|
|
270
|
+
router.post(p('tool-call/approve'), async (ctx) => {
|
|
271
|
+
const body = (ctx.request.body() ?? {});
|
|
272
|
+
await service.approve(body.runId, body.toolCallId);
|
|
273
|
+
return ctx.response.json({ ok: true });
|
|
274
|
+
});
|
|
275
|
+
// 5. POST /agent/tool-call/reject.
|
|
276
|
+
router.post(p('tool-call/reject'), async (ctx) => {
|
|
277
|
+
const body = (ctx.request.body() ?? {});
|
|
278
|
+
await service.reject(body.runId, body.toolCallId, body.reason);
|
|
279
|
+
return ctx.response.json({ ok: true });
|
|
280
|
+
});
|
|
281
|
+
// 6. GET /agent/threads — the actor's threads.
|
|
282
|
+
router.get(p('threads'), async (ctx) => {
|
|
283
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
284
|
+
if (actor === null)
|
|
285
|
+
return;
|
|
286
|
+
return ctx.response.json(await service.listThreads(actor.id));
|
|
287
|
+
});
|
|
288
|
+
// 7. GET /agent/threads/personas/catalog (before :id so it isn't captured by the param).
|
|
289
|
+
router.get(p('threads/personas/catalog'), async (ctx) => {
|
|
290
|
+
return ctx.response.json(service.personaCatalog());
|
|
291
|
+
});
|
|
292
|
+
// 8. GET /agent/threads/:id — detail or null.
|
|
293
|
+
router.get(p('threads/:id'), async (ctx) => {
|
|
294
|
+
return ctx.response.json(await service.getThread(String(ctx.params.id)));
|
|
295
|
+
});
|
|
296
|
+
// 9. DELETE /agent/threads/:id.
|
|
297
|
+
router.delete(p('threads/:id'), async (ctx) => {
|
|
298
|
+
await service.deleteThread(String(ctx.params.id));
|
|
299
|
+
return ctx.response.json({ ok: true });
|
|
300
|
+
});
|
|
301
|
+
// 10. POST /agent/threads/:id/fork-from/:messageId.
|
|
302
|
+
router.post(p('threads/:id/fork-from/:messageId'), async (ctx) => {
|
|
303
|
+
return ctx.response.json(await service.forkThread(String(ctx.params.id), String(ctx.params.messageId)));
|
|
304
|
+
});
|
|
305
|
+
// 11. GET /agent/quota/today.
|
|
306
|
+
router.get(p('quota/today'), async (ctx) => {
|
|
307
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
308
|
+
if (actor === null)
|
|
309
|
+
return;
|
|
310
|
+
return ctx.response.json(await service.quotaToday(actor.id));
|
|
311
|
+
});
|
|
312
|
+
// 12. POST /agent/attachments — OPTIONAL. Mounted only when `attachmentStaging` is configured, so
|
|
313
|
+
// an app without it never exposes an upload surface. Buffers the multipart `file` field, validates
|
|
314
|
+
// it against the size cap + content-type allowlist, then stages it into a model-fetchable
|
|
315
|
+
// MessageAttachment the client sends back on its next `chat` call. Mirrors the SSE routes' envelope
|
|
316
|
+
// (JSON body, actor resolved via the shared resolver, precise HTTP status on rejection).
|
|
317
|
+
if (attachmentStaging !== undefined) {
|
|
318
|
+
const staging = attachmentStaging;
|
|
319
|
+
const maxBytes = config.attachmentMaxBytes ?? DEFAULT_MAX_ATTACHMENT_BYTES;
|
|
320
|
+
const allowedContentTypes = config.attachmentAllowedContentTypes ?? DEFAULT_ALLOWED_ATTACHMENT_CONTENT_TYPES;
|
|
321
|
+
router.post(p('attachments'), async (ctx) => {
|
|
322
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
323
|
+
if (actor === null)
|
|
324
|
+
return;
|
|
325
|
+
const file = ctx.request.file('file');
|
|
326
|
+
if (file === null || file.tmpPath === undefined) {
|
|
327
|
+
return ctx.response.status(400).json({ error: 'multipart field "file" is required' });
|
|
328
|
+
}
|
|
329
|
+
const contentType = file.headers?.['content-type']?.split(';')[0]?.trim() ?? `${file.type}/${file.subtype}`;
|
|
330
|
+
if (!allowedContentTypes.includes(contentType)) {
|
|
331
|
+
return ctx.response.status(415).json({
|
|
332
|
+
error: `content type "${contentType}" is not allowed (allowed: ${allowedContentTypes.join(', ')})`,
|
|
333
|
+
});
|
|
334
|
+
}
|
|
335
|
+
const sizeBytes = file.size;
|
|
336
|
+
if (sizeBytes > maxBytes) {
|
|
337
|
+
return ctx.response
|
|
338
|
+
.status(413)
|
|
339
|
+
.json({ error: `file exceeds the ${maxBytes}-byte limit` });
|
|
340
|
+
}
|
|
341
|
+
const { readFile } = await import('node:fs/promises');
|
|
342
|
+
const data = await readFile(file.tmpPath);
|
|
343
|
+
const attachment = await staging.stage({
|
|
344
|
+
data,
|
|
345
|
+
filename: file.clientName,
|
|
346
|
+
contentType,
|
|
347
|
+
sizeBytes,
|
|
348
|
+
actor,
|
|
349
|
+
});
|
|
350
|
+
return ctx.response.json(attachment);
|
|
351
|
+
});
|
|
352
|
+
}
|
|
353
|
+
// ── OPTIONAL governance read routes. Mounted only when `governanceQueries` is configured, so an
|
|
354
|
+
// app without it never exposes the cost/usage read-model. All read-only (GET) and authenticated
|
|
355
|
+
// (actor resolved via the shared resolver — governance is cross-actor data). `from`/`to` are
|
|
356
|
+
// inclusive UTC days (`YYYY-MM-DD`), defaulting to today; `limit` defaults to 50, clamped to 200
|
|
357
|
+
// (mirroring the dashboard's own clamp).
|
|
358
|
+
if (governance !== undefined) {
|
|
359
|
+
const gov = governance;
|
|
360
|
+
const g = (suffix) => p(`governance/${suffix}`);
|
|
361
|
+
const range = (ctx) => {
|
|
362
|
+
const today = new Date().toISOString().slice(0, 10);
|
|
363
|
+
const from = ctx.request.input('from', today);
|
|
364
|
+
const to = ctx.request.input('to', today);
|
|
365
|
+
return { fromDay: String(from), toDay: String(to) };
|
|
366
|
+
};
|
|
367
|
+
const limitOf = (ctx) => {
|
|
368
|
+
const raw = Number.parseInt(String(ctx.request.input('limit', '50')), 10);
|
|
369
|
+
const value = Number.isFinite(raw) && raw > 0 ? raw : 50;
|
|
370
|
+
return Math.min(value, 200);
|
|
371
|
+
};
|
|
372
|
+
// GET /agent/governance/spend/model — per-model token + cost rollup over the range.
|
|
373
|
+
router.get(g('spend/model'), async (ctx) => {
|
|
374
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
375
|
+
if (actor === null)
|
|
376
|
+
return;
|
|
377
|
+
return ctx.response.json(await gov.spendByModel(range(ctx)));
|
|
378
|
+
});
|
|
379
|
+
// GET /agent/governance/spend/actor — per-actor token + cost rollup over the range.
|
|
380
|
+
router.get(g('spend/actor'), async (ctx) => {
|
|
381
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
382
|
+
if (actor === null)
|
|
383
|
+
return;
|
|
384
|
+
return ctx.response.json(await gov.spendByActor(range(ctx)));
|
|
385
|
+
});
|
|
386
|
+
// GET /agent/governance/usage/trend — the daily token + cost trend over the range.
|
|
387
|
+
router.get(g('usage/trend'), async (ctx) => {
|
|
388
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
389
|
+
if (actor === null)
|
|
390
|
+
return;
|
|
391
|
+
return ctx.response.json(await gov.usageTrend(range(ctx)));
|
|
392
|
+
});
|
|
393
|
+
// GET /agent/governance/tool-calls/recent — newest-first recent tool-call activity feed.
|
|
394
|
+
router.get(g('tool-calls/recent'), async (ctx) => {
|
|
395
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
396
|
+
if (actor === null)
|
|
397
|
+
return;
|
|
398
|
+
return ctx.response.json(await gov.recentToolCalls(limitOf(ctx)));
|
|
399
|
+
});
|
|
400
|
+
// GET /agent/governance/threads/recent — newest-first recent thread activity feed.
|
|
401
|
+
router.get(g('threads/recent'), async (ctx) => {
|
|
402
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
403
|
+
if (actor === null)
|
|
404
|
+
return;
|
|
405
|
+
return ctx.response.json(await gov.recentThreads(limitOf(ctx)));
|
|
406
|
+
});
|
|
407
|
+
// ── Run lifecycle governance (the run tracking read-model). Same read-only + authenticated
|
|
408
|
+
// envelope; the runs are cross-actor governance data.
|
|
409
|
+
const optionalRange = (ctx) => {
|
|
410
|
+
const from = ctx.request.input('from');
|
|
411
|
+
const to = ctx.request.input('to');
|
|
412
|
+
return {
|
|
413
|
+
...(from !== undefined ? { from: String(from) } : {}),
|
|
414
|
+
...(to !== undefined ? { to: String(to) } : {}),
|
|
415
|
+
};
|
|
416
|
+
};
|
|
417
|
+
// GET /agent/governance/runs — filterable, cursor-paginated run list, newest-first.
|
|
418
|
+
// Query: actor?, agent?, status?, from?, to?, cursor?, limit?
|
|
419
|
+
router.get(g('runs'), async (ctx) => {
|
|
420
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
421
|
+
if (actor === null)
|
|
422
|
+
return;
|
|
423
|
+
const filterActor = ctx.request.input('actor');
|
|
424
|
+
const agent = ctx.request.input('agent');
|
|
425
|
+
const status = ctx.request.input('status');
|
|
426
|
+
const cursor = ctx.request.input('cursor');
|
|
427
|
+
const { from, to } = optionalRange(ctx);
|
|
428
|
+
return ctx.response.json(await gov.listRuns({
|
|
429
|
+
limit: limitOf(ctx),
|
|
430
|
+
...(filterActor !== undefined ? { actor: String(filterActor) } : {}),
|
|
431
|
+
...(agent !== undefined ? { agent: String(agent) } : {}),
|
|
432
|
+
...(status !== undefined ? { status: String(status) } : {}),
|
|
433
|
+
...(cursor !== undefined ? { cursor: String(cursor) } : {}),
|
|
434
|
+
...(from !== undefined ? { from } : {}),
|
|
435
|
+
...(to !== undefined ? { to } : {}),
|
|
436
|
+
}));
|
|
437
|
+
});
|
|
438
|
+
// GET /agent/governance/runs/:id — one run's full trace (run + messages + tool calls +
|
|
439
|
+
// approvals + usage), or null.
|
|
440
|
+
router.get(g('runs/:id'), async (ctx) => {
|
|
441
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
442
|
+
if (actor === null)
|
|
443
|
+
return;
|
|
444
|
+
return ctx.response.json(await gov.runDetail(String(ctx.params.id)));
|
|
445
|
+
});
|
|
446
|
+
// GET /agent/governance/approvals/pending — cross-thread HITL approvals inbox, oldest first.
|
|
447
|
+
router.get(g('approvals/pending'), async (ctx) => {
|
|
448
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
449
|
+
if (actor === null)
|
|
450
|
+
return;
|
|
451
|
+
const filterActor = ctx.request.input('actor');
|
|
452
|
+
return ctx.response.json(await gov.pendingApprovals({
|
|
453
|
+
limit: limitOf(ctx),
|
|
454
|
+
...(filterActor !== undefined ? { actor: String(filterActor) } : {}),
|
|
455
|
+
}));
|
|
456
|
+
});
|
|
457
|
+
// GET /agent/governance/tools/stats — per-tool call/failure/rejection/latency rollup.
|
|
458
|
+
router.get(g('tools/stats'), async (ctx) => {
|
|
459
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
460
|
+
if (actor === null)
|
|
461
|
+
return;
|
|
462
|
+
return ctx.response.json(await gov.perToolStats(optionalRange(ctx)));
|
|
463
|
+
});
|
|
464
|
+
// GET /agent/governance/reliability — success/failure/cancel rates + mean settled duration.
|
|
465
|
+
router.get(g('reliability'), async (ctx) => {
|
|
466
|
+
const actor = await this.#resolveActor(ctx, actorResolver);
|
|
467
|
+
if (actor === null)
|
|
468
|
+
return;
|
|
469
|
+
return ctx.response.json(await gov.runReliability(optionalRange(ctx)));
|
|
470
|
+
});
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
/** Resolve the actor; on failure reply 401 and return `null` so the handler short-circuits. */
|
|
474
|
+
async #resolveActor(ctx, actorResolver) {
|
|
475
|
+
try {
|
|
476
|
+
return await actorResolver.resolve(ctx);
|
|
477
|
+
}
|
|
478
|
+
catch (error) {
|
|
479
|
+
ctx.response
|
|
480
|
+
.status(401)
|
|
481
|
+
.json({ error: error instanceof Error ? error.message : 'unauthorized' });
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Pipe the run's live token stream to the client as SSE, reproducing the envelope byte-for-byte:
|
|
487
|
+
* `event: meta` (runId/threadId) → `data: {"delta":...}` per chunk → `event: done`. Sets the
|
|
488
|
+
* `X-Agent-Run-Id` / `X-Agent-Thread-Id` headers. Writes the raw Node response directly (Adonis has
|
|
489
|
+
* no SSE helper) and ends only on stream completion — the sink closes on run finish, not on suspend.
|
|
490
|
+
*/
|
|
491
|
+
async #pipe(ctx, service, runId, threadId) {
|
|
492
|
+
const raw = ctx.response.response;
|
|
493
|
+
const headers = {
|
|
494
|
+
'Content-Type': 'text/event-stream',
|
|
495
|
+
'Cache-Control': 'no-cache, no-transform',
|
|
496
|
+
Connection: 'keep-alive',
|
|
497
|
+
'X-Accel-Buffering': 'no',
|
|
498
|
+
'X-Agent-Run-Id': runId,
|
|
499
|
+
...(threadId !== undefined ? { 'X-Agent-Thread-Id': threadId } : {}),
|
|
500
|
+
};
|
|
501
|
+
raw.writeHead(200, headers);
|
|
502
|
+
raw.write(`event: meta\ndata: ${JSON.stringify({ runId, threadId })}\n\n`);
|
|
503
|
+
const decoder = new TextDecoder();
|
|
504
|
+
for await (const chunk of service.subscribe(runId)) {
|
|
505
|
+
raw.write(`data: ${JSON.stringify({ delta: decoder.decode(chunk) })}\n\n`);
|
|
506
|
+
}
|
|
507
|
+
raw.write('event: done\ndata: {}\n\n');
|
|
508
|
+
raw.end();
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
//# sourceMappingURL=agent_provider.js.map
|