@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
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { jsonSchema, streamText, tool, } from 'ai';
|
|
2
|
+
/**
|
|
3
|
+
* Adapt a Vercel AI SDK v7 `LanguageModel` to the core `ModelProvider` SPI so a host app writes
|
|
4
|
+
* zero provider code. Streams text deltas to `args.sink`, returns the assembled text, requested
|
|
5
|
+
* tool calls, usage, and (when a gateway reports it) the real USD cost. It never executes tools —
|
|
6
|
+
* tools are handed to the SDK WITHOUT an `execute` fn, so the SDK returns tool-calls for the agent
|
|
7
|
+
* loop to run as its own (replay-safe) steps.
|
|
8
|
+
*/
|
|
9
|
+
export function aiSdkModel(model, opts) {
|
|
10
|
+
return {
|
|
11
|
+
async runTurn(args) {
|
|
12
|
+
const result = streamText({
|
|
13
|
+
...opts,
|
|
14
|
+
model,
|
|
15
|
+
instructions: args.system,
|
|
16
|
+
messages: mapMessages(args.messages),
|
|
17
|
+
tools: mapTools(args.tools),
|
|
18
|
+
...(args.abortSignal ? { abortSignal: args.abortSignal } : {}),
|
|
19
|
+
});
|
|
20
|
+
// Encode deltas to bytes for the live token sink, exactly as the reference fake provider does.
|
|
21
|
+
const encoder = new TextEncoder();
|
|
22
|
+
let text = '';
|
|
23
|
+
for await (const part of result.stream) {
|
|
24
|
+
if (part.type === 'text-delta') {
|
|
25
|
+
text += part.text;
|
|
26
|
+
await args.sink.write(encoder.encode(part.text));
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// The promise accessors resolve once the stream is fully consumed above. `modelId` and the
|
|
30
|
+
// reported cost live on the final step (the top-level aliases are deprecated in AI SDK v7).
|
|
31
|
+
const [toolCalls, usage, finalStep] = await Promise.all([
|
|
32
|
+
result.toolCalls,
|
|
33
|
+
result.usage,
|
|
34
|
+
result.finalStep,
|
|
35
|
+
]);
|
|
36
|
+
const modelId = finalStep.response.modelId;
|
|
37
|
+
const costUsd = extractCostUsd(finalStep.providerMetadata);
|
|
38
|
+
return {
|
|
39
|
+
text,
|
|
40
|
+
toolCalls: toolCalls.map(mapToolCall),
|
|
41
|
+
usage: mapUsage(usage),
|
|
42
|
+
...(typeof modelId === 'string' && modelId.length > 0 ? { modelId } : {}),
|
|
43
|
+
...(costUsd !== undefined ? { costUsd } : {}),
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Map core `ModelMessage[]` → SDK messages. Tool calls ride on the assistant message as
|
|
50
|
+
* `tool-call` content parts; tool results become a following `tool` message. A message can
|
|
51
|
+
* therefore expand into two SDK messages, so we build the list imperatively.
|
|
52
|
+
*/
|
|
53
|
+
function mapMessages(messages) {
|
|
54
|
+
const out = [];
|
|
55
|
+
for (const message of messages) {
|
|
56
|
+
if (message.role === 'system') {
|
|
57
|
+
out.push({ role: 'system', content: message.content });
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (message.role === 'user') {
|
|
61
|
+
const attachments = message.attachments ?? [];
|
|
62
|
+
out.push(attachments.length === 0
|
|
63
|
+
? { role: 'user', content: message.content }
|
|
64
|
+
: { role: 'user', content: userContentWithAttachments(message.content, attachments) });
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const toolCalls = message.toolCalls ?? [];
|
|
68
|
+
if (toolCalls.length > 0) {
|
|
69
|
+
const content = [];
|
|
70
|
+
if (message.content.length > 0) {
|
|
71
|
+
content.push({ type: 'text', text: message.content });
|
|
72
|
+
}
|
|
73
|
+
for (const call of toolCalls) {
|
|
74
|
+
content.push({
|
|
75
|
+
type: 'tool-call',
|
|
76
|
+
toolCallId: call.id,
|
|
77
|
+
toolName: call.name,
|
|
78
|
+
input: call.input,
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
out.push({ role: 'assistant', content: assistantContent(content) });
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
out.push({ role: 'assistant', content: message.content });
|
|
85
|
+
}
|
|
86
|
+
const toolResults = message.toolResults ?? [];
|
|
87
|
+
if (toolResults.length > 0) {
|
|
88
|
+
out.push({
|
|
89
|
+
role: 'tool',
|
|
90
|
+
content: toolResults.map((result) => ({
|
|
91
|
+
type: 'tool-result',
|
|
92
|
+
toolCallId: result.id,
|
|
93
|
+
toolName: result.name,
|
|
94
|
+
output: toModelOutput(result),
|
|
95
|
+
})),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return out;
|
|
100
|
+
}
|
|
101
|
+
/** `Array<TextPart | ToolCallPart>` is a valid `AssistantContent`; name the widening explicitly. */
|
|
102
|
+
function assistantContent(parts) {
|
|
103
|
+
return parts;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Build a multimodal user content array: the text (when non-empty) followed by one part per
|
|
107
|
+
* attachment — `image/*` → an image part, everything else → a file part (Bedrock Claude reads a PDF
|
|
108
|
+
* this way). The attachment's `url` is passed straight through as the part's source; making it
|
|
109
|
+
* reachable by the provider is the consumer's concern (the staging SPI's job), not the adapter's.
|
|
110
|
+
*/
|
|
111
|
+
function userContentWithAttachments(text, attachments) {
|
|
112
|
+
const parts = [];
|
|
113
|
+
if (text.length > 0) {
|
|
114
|
+
parts.push({ type: 'text', text });
|
|
115
|
+
}
|
|
116
|
+
for (const attachment of attachments) {
|
|
117
|
+
parts.push(attachment.contentType.startsWith('image/')
|
|
118
|
+
? { type: 'image', image: new URL(attachment.url), mediaType: attachment.contentType }
|
|
119
|
+
: {
|
|
120
|
+
type: 'file',
|
|
121
|
+
data: new URL(attachment.url),
|
|
122
|
+
mediaType: attachment.contentType,
|
|
123
|
+
filename: attachment.name,
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
return parts;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* NOTE: core tool `output` is `unknown`, but the SDK's structured `json` output demands a
|
|
130
|
+
* `JSONValue`. Rather than an unsafe cast we serialise every result to text — the model reads
|
|
131
|
+
* tool output as text regardless, and the loop already validated the tool INPUT via the schema.
|
|
132
|
+
*/
|
|
133
|
+
function toModelOutput(result) {
|
|
134
|
+
if (result.error !== undefined) {
|
|
135
|
+
return { type: 'text', value: result.error };
|
|
136
|
+
}
|
|
137
|
+
const { output } = result;
|
|
138
|
+
if (typeof output === 'string') {
|
|
139
|
+
return { type: 'text', value: output };
|
|
140
|
+
}
|
|
141
|
+
return { type: 'text', value: JSON.stringify(output ?? null) };
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Map core `ToolDefinition[]` → an SDK `ToolSet`. Each tool is built WITHOUT an `execute` fn so the
|
|
145
|
+
* SDK surfaces the tool-call for the agent loop to run, instead of executing it inline.
|
|
146
|
+
*/
|
|
147
|
+
function mapTools(tools) {
|
|
148
|
+
const set = {};
|
|
149
|
+
for (const definition of tools) {
|
|
150
|
+
set[definition.name] = tool({
|
|
151
|
+
description: definition.description,
|
|
152
|
+
inputSchema: toSdkInputSchema(definition.inputSchema),
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
return set;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Convert a core `StandardSchemaV1` into the schema the SDK feeds the model as tool parameters.
|
|
159
|
+
* The SDK's own `asSchema` derives a precise JSON schema from exactly two kinds of Standard Schema,
|
|
160
|
+
* so we hand those straight through and let it do the conversion:
|
|
161
|
+
*
|
|
162
|
+
* - **Zod** (`~standard.vendor === 'zod'`) — the SDK runs zod-to-json-schema natively. Zod 3 does
|
|
163
|
+
* NOT expose the Standard JSON Schema extension, so this vendor tag is the only way to recognise
|
|
164
|
+
* it, and it's the common case (`@AiTool({ input: z.object(...) })`).
|
|
165
|
+
* - **Standard JSON Schema** (`~standard.jsonSchema`) — Valibot, ArkType, and Zod 4 implement the
|
|
166
|
+
* extension; the SDK calls its `input()` converter to derive the schema.
|
|
167
|
+
*
|
|
168
|
+
* Anything else is a bare Standard Schema the SDK can't introspect (its `asSchema` throws on one), so
|
|
169
|
+
* we degrade to a permissive object schema — the model loses the parameter shapes, but the agent loop
|
|
170
|
+
* still validates the tool input against the real schema via `~standard.validate` before running it.
|
|
171
|
+
*/
|
|
172
|
+
function toSdkInputSchema(schema) {
|
|
173
|
+
if (isZodSchema(schema) || hasStandardJsonSchema(schema)) {
|
|
174
|
+
return schema;
|
|
175
|
+
}
|
|
176
|
+
return jsonSchema({ type: 'object', properties: {}, additionalProperties: true });
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* True for a Zod schema. Zod tags its Standard Schema props with `vendor: 'zod'`, and its own type
|
|
180
|
+
* declares `~standard`, so this narrows to `ZodTypeAny` — a member of the SDK's `FlexibleSchema` —
|
|
181
|
+
* without a cast, letting the SDK convert it natively.
|
|
182
|
+
*/
|
|
183
|
+
function isZodSchema(schema) {
|
|
184
|
+
return schema['~standard'].vendor === 'zod';
|
|
185
|
+
}
|
|
186
|
+
/** True when the schema carries the Standard JSON Schema converter (`~standard.jsonSchema.input`). */
|
|
187
|
+
function hasStandardJsonSchema(schema) {
|
|
188
|
+
const standard = schema['~standard'];
|
|
189
|
+
if (!('jsonSchema' in standard)) {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
const converter = standard.jsonSchema;
|
|
193
|
+
return (typeof converter === 'object' &&
|
|
194
|
+
converter !== null &&
|
|
195
|
+
'input' in converter &&
|
|
196
|
+
typeof converter.input === 'function');
|
|
197
|
+
}
|
|
198
|
+
function mapToolCall(call) {
|
|
199
|
+
return { id: call.toolCallId, name: call.toolName, input: call.input };
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Map SDK usage → core `MessageUsage`. Cache/reasoning breakdowns are optional and only added when
|
|
203
|
+
* the provider reports them (conditional spread, never an `undefined` assignment). AI SDK v7 carries
|
|
204
|
+
* them on the `*Details` objects; the deprecated flat aliases (`cachedInputTokens`, `reasoningTokens`)
|
|
205
|
+
* were removed.
|
|
206
|
+
*/
|
|
207
|
+
function mapUsage(usage) {
|
|
208
|
+
const cacheReadTokens = usage.inputTokenDetails?.cacheReadTokens;
|
|
209
|
+
const cacheWriteTokens = usage.inputTokenDetails?.cacheWriteTokens;
|
|
210
|
+
const reasoningTokens = usage.outputTokenDetails?.reasoningTokens;
|
|
211
|
+
return {
|
|
212
|
+
inputTokens: usage.inputTokens ?? 0,
|
|
213
|
+
outputTokens: usage.outputTokens ?? 0,
|
|
214
|
+
...(cacheWriteTokens !== undefined ? { cacheWriteTokens } : {}),
|
|
215
|
+
...(cacheReadTokens !== undefined ? { cacheReadTokens } : {}),
|
|
216
|
+
...(reasoningTokens !== undefined ? { reasoningTokens } : {}),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
/**
|
|
220
|
+
* A gateway reports the ACTUAL spend for the turn; a direct provider (Anthropic/OpenAI/Bedrock)
|
|
221
|
+
* doesn't, leaving this undefined so the governance read-model estimates from tokens. We read the
|
|
222
|
+
* Vercel AI Gateway shape (`gateway.cost`) first, then OpenRouter (`openrouter.total_cost`, also
|
|
223
|
+
* nested under `openrouter.usage.total_cost`).
|
|
224
|
+
*/
|
|
225
|
+
function extractCostUsd(metadata) {
|
|
226
|
+
if (!metadata) {
|
|
227
|
+
return undefined;
|
|
228
|
+
}
|
|
229
|
+
const gateway = metadata.gateway;
|
|
230
|
+
const gatewayCost = gateway ? toFiniteNumber(gateway.cost) : undefined;
|
|
231
|
+
if (gatewayCost !== undefined) {
|
|
232
|
+
return gatewayCost;
|
|
233
|
+
}
|
|
234
|
+
const openrouter = metadata.openrouter;
|
|
235
|
+
if (openrouter) {
|
|
236
|
+
const direct = toFiniteNumber(openrouter.total_cost);
|
|
237
|
+
if (direct !== undefined) {
|
|
238
|
+
return direct;
|
|
239
|
+
}
|
|
240
|
+
const usage = asJsonObject(openrouter.usage);
|
|
241
|
+
if (usage) {
|
|
242
|
+
const nested = toFiniteNumber(usage.total_cost);
|
|
243
|
+
if (nested !== undefined) {
|
|
244
|
+
return nested;
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return undefined;
|
|
249
|
+
}
|
|
250
|
+
function toFiniteNumber(value) {
|
|
251
|
+
if (typeof value === 'number') {
|
|
252
|
+
return Number.isFinite(value) ? value : undefined;
|
|
253
|
+
}
|
|
254
|
+
if (typeof value === 'string') {
|
|
255
|
+
const parsed = Number.parseFloat(value);
|
|
256
|
+
return Number.isFinite(parsed) ? parsed : undefined;
|
|
257
|
+
}
|
|
258
|
+
return undefined;
|
|
259
|
+
}
|
|
260
|
+
function asJsonObject(value) {
|
|
261
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value) ? value : undefined;
|
|
262
|
+
}
|
|
263
|
+
//# sourceMappingURL=ai-sdk-model.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk-model.js","sourceRoot":"","sources":["../../../src/ai-sdk/ai-sdk-model.ts"],"names":[],"mappings":"AACA,OAAO,EAgBL,UAAU,EACV,UAAU,EACV,IAAI,GACL,MAAM,IAAI,CAAC;AAqBZ;;;;;;GAMG;AACH,MAAM,UAAU,UAAU,CAAC,KAAoB,EAAE,IAAwB;IACvE,OAAO;QACL,KAAK,CAAC,OAAO,CAAC,IAAmB;YAC/B,MAAM,MAAM,GAAG,UAAU,CAAC;gBACxB,GAAG,IAAI;gBACP,KAAK;gBACL,YAAY,EAAE,IAAI,CAAC,MAAM;gBACzB,QAAQ,EAAE,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC;gBACpC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;gBAC3B,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC/D,CAAC,CAAC;YAEH,+FAA+F;YAC/F,MAAM,OAAO,GAAG,IAAI,WAAW,EAAE,CAAC;YAClC,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,IAAI,KAAK,EAAE,MAAM,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;gBACvC,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;oBAC/B,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC;oBAClB,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YAED,2FAA2F;YAC3F,4FAA4F;YAC5F,MAAM,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBACtD,MAAM,CAAC,SAAS;gBAChB,MAAM,CAAC,KAAK;gBACZ,MAAM,CAAC,SAAS;aACjB,CAAC,CAAC;YAEH,MAAM,OAAO,GAAG,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC3C,MAAM,OAAO,GAAG,cAAc,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;YAE3D,OAAO;gBACL,IAAI;gBACJ,SAAS,EAAE,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC;gBACrC,KAAK,EAAE,QAAQ,CAAC,KAAK,CAAC;gBACtB,GAAG,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACzE,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aAC9C,CAAC;QACJ,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,QAAwB;IAC3C,MAAM,GAAG,GAAsB,EAAE,CAAC;IAClC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9B,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QACD,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC5B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;YAC9C,GAAG,CAAC,IAAI,CACN,WAAW,CAAC,MAAM,KAAK,CAAC;gBACtB,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE;gBAC5C,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,0BAA0B,CAAC,OAAO,CAAC,OAAO,EAAE,WAAW,CAAC,EAAE,CACxF,CAAC;YACF,SAAS;QACX,CAAC;QAED,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;QAC1C,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,OAAO,GAAmC,EAAE,CAAC;YACnD,IAAI,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC/B,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;YACxD,CAAC;YACD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,CAAC;oBACX,IAAI,EAAE,WAAW;oBACjB,UAAU,EAAE,IAAI,CAAC,EAAE;oBACnB,QAAQ,EAAE,IAAI,CAAC,IAAI;oBACnB,KAAK,EAAE,IAAI,CAAC,KAAK;iBAClB,CAAC,CAAC;YACL,CAAC;YACD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACtE,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;QAC9C,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,WAAW,CAAC,GAAG,CACtB,CAAC,MAAM,EAAkB,EAAE,CAAC,CAAC;oBAC3B,IAAI,EAAE,aAAa;oBACnB,UAAU,EAAE,MAAM,CAAC,EAAE;oBACrB,QAAQ,EAAE,MAAM,CAAC,IAAI;oBACrB,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC;iBAC9B,CAAC,CACH;aACF,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,oGAAoG;AACpG,SAAS,gBAAgB,CAAC,KAAqC;IAC7D,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;;GAKG;AACH,SAAS,0BAA0B,CACjC,IAAY,EACZ,WAAgC;IAEhC,MAAM,KAAK,GAA2C,EAAE,CAAC;IACzD,IAAI,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,KAAK,MAAM,UAAU,IAAI,WAAW,EAAE,CAAC;QACrC,KAAK,CAAC,IAAI,CACR,UAAU,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC;YACzC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,UAAU,CAAC,WAAW,EAAE;YACtF,CAAC,CAAC;gBACE,IAAI,EAAE,MAAM;gBACZ,IAAI,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC;gBAC7B,SAAS,EAAE,UAAU,CAAC,WAAW;gBACjC,QAAQ,EAAE,UAAU,CAAC,IAAI;aAC1B,CACN,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;;GAIG;AACH,SAAS,aAAa,CAAC,MAAkB;IACvC,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;IAC/C,CAAC;IACD,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;QAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IACzC,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,IAAI,IAAI,CAAC,EAAE,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,SAAS,QAAQ,CAAC,KAAuB;IACvC,MAAM,GAAG,GAAY,EAAE,CAAC;IACxB,KAAK,MAAM,UAAU,IAAI,KAAK,EAAE,CAAC;QAC/B,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;YAC1B,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,WAAW,EAAE,gBAAgB,CAAC,UAAU,CAAC,WAAW,CAAC;SACtD,CAAC,CAAC;IACL,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,SAAS,gBAAgB,CAAC,MAAwB;IAChD,IAAI,WAAW,CAAC,MAAM,CAAC,IAAI,qBAAqB,CAAC,MAAM,CAAC,EAAE,CAAC;QACzD,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,oBAAoB,EAAE,IAAI,EAAE,CAAC,CAAC;AACpF,CAAC;AAED;;;;GAIG;AACH,SAAS,WAAW,CAAC,MAAwB;IAC3C,OAAO,MAAM,CAAC,WAAW,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC;AAC9C,CAAC;AAED,sGAAsG;AACtG,SAAS,qBAAqB,CAC5B,MAAwB;IAExB,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;IACrC,IAAI,CAAC,CAAC,YAAY,IAAI,QAAQ,CAAC,EAAE,CAAC;QAChC,OAAO,KAAK,CAAC;IACf,CAAC;IACD,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAU,CAAC;IACtC,OAAO,CACL,OAAO,SAAS,KAAK,QAAQ;QAC7B,SAAS,KAAK,IAAI;QAClB,OAAO,IAAI,SAAS;QACpB,OAAO,SAAS,CAAC,KAAK,KAAK,UAAU,CACtC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,IAA4B;IAC/C,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;AACzE,CAAC;AAED;;;;;GAKG;AACH,SAAS,QAAQ,CAAC,KAAyB;IACzC,MAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,EAAE,eAAe,CAAC;IACjE,MAAM,gBAAgB,GAAG,KAAK,CAAC,iBAAiB,EAAE,gBAAgB,CAAC;IACnE,MAAM,eAAe,GAAG,KAAK,CAAC,kBAAkB,EAAE,eAAe,CAAC;IAClE,OAAO;QACL,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,CAAC;QACnC,YAAY,EAAE,KAAK,CAAC,YAAY,IAAI,CAAC;QACrC,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC7D,GAAG,CAAC,eAAe,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC9D,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,SAAS,cAAc,CAAC,QAAsC;IAC5D,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACvE,IAAI,WAAW,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,WAAW,CAAC;IACrB,CAAC;IACD,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC;IACvC,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,MAAM,KAAK,GAAG,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,cAAc,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YAChD,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACzB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,KAA4B;IAClD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;IACpD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACxC,OAAO,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IACtD,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,YAAY,CACnB,KAA4B;IAE5B,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;AAClG,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ai-sdk/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,iBAAiB,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
2
|
+
import type { AiToolCtx, ToolHandler } from './spi/tool.js';
|
|
3
|
+
import type { ToolSpec } from './types.js';
|
|
4
|
+
/**
|
|
5
|
+
* The symbol the `@AiTool` decorator stamps its options onto (the tool class), read back by
|
|
6
|
+
* discovery to register the class into the {@link import('./tool-registry.js').ToolRegistry}. A
|
|
7
|
+
* global-registry symbol (`Symbol.for`) so it survives duplicate copies of this package in a tree.
|
|
8
|
+
*/
|
|
9
|
+
export declare const AI_TOOL_META_KEY: unique symbol;
|
|
10
|
+
/**
|
|
11
|
+
* Brand stamped on the object {@link defineTool} returns so discovery picks it up when it walks a
|
|
12
|
+
* module's exports — the functional alternative to an `@AiTool` class.
|
|
13
|
+
*/
|
|
14
|
+
export declare const AGENT_TOOL_BRAND: unique symbol;
|
|
15
|
+
export interface AiToolOptions {
|
|
16
|
+
name: string;
|
|
17
|
+
/**
|
|
18
|
+
* `read` auto-executes; `action` requires HITL approval. (Core's `ToolKind` also has `agent` for
|
|
19
|
+
* delegation, but that kind is synthesized from an agent's `delegatesTo` — never authored here.)
|
|
20
|
+
*/
|
|
21
|
+
kind: 'read' | 'action';
|
|
22
|
+
description: string;
|
|
23
|
+
/**
|
|
24
|
+
* Input schema as a [Standard Schema](https://standardschema.dev) — Zod, Valibot, or ArkType.
|
|
25
|
+
* Validated (again) before the handler runs.
|
|
26
|
+
*/
|
|
27
|
+
input: StandardSchemaV1;
|
|
28
|
+
/** Roles allowed to invoke. Omit to inherit the config's `defaultRoles` (ADMIN-only by default). */
|
|
29
|
+
roles?: string[];
|
|
30
|
+
/**
|
|
31
|
+
* Authz ability checked by an ability-aware `RolesPolicy` (e.g. an `@adonis-agora/authz` Bouncer
|
|
32
|
+
* adapter → `bouncer.forUser(actor).allows(ability)`). Ignored by the default role-based policy.
|
|
33
|
+
*/
|
|
34
|
+
ability?: string;
|
|
35
|
+
}
|
|
36
|
+
/** The metadata the `@AiTool` decorator stamps onto a class for discovery + registration. */
|
|
37
|
+
export type AiToolMeta = AiToolOptions;
|
|
38
|
+
/** Structural shape of an `@AiTool` class: a constructor whose instance implements `execute`. */
|
|
39
|
+
export type ToolClass = abstract new (...args: never[]) => ToolHandler;
|
|
40
|
+
/**
|
|
41
|
+
* Marks a class as an AI tool. The class must implement `execute(input, ctx)`. The provider's
|
|
42
|
+
* `app/agent_tools` discovery (or the generated `hooks/tools` barrel) registers every `@AiTool`
|
|
43
|
+
* class into the shared `ToolRegistry` at boot.
|
|
44
|
+
*
|
|
45
|
+
* ```ts
|
|
46
|
+
* @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })
|
|
47
|
+
* export default class GetWeatherTool implements ToolHandler<{ city: string }> {
|
|
48
|
+
* async execute(input: { city: string }, ctx: AiToolCtx) { return { tempC: 21 } }
|
|
49
|
+
* }
|
|
50
|
+
* ```
|
|
51
|
+
*/
|
|
52
|
+
export declare function AiTool(options: AiToolOptions): <T extends ToolClass>(target: T) => T;
|
|
53
|
+
/** Read the {@link AiToolMeta} an `@AiTool` decorator stamped on a class (or an instance's ctor). */
|
|
54
|
+
export declare function readAiToolMeta(target: unknown): AiToolMeta | undefined;
|
|
55
|
+
/** A tool expressed as data + handler (from {@link defineTool}), not an `@AiTool` class. */
|
|
56
|
+
export interface FunctionalTool {
|
|
57
|
+
spec: ToolSpec;
|
|
58
|
+
handler: ToolHandler;
|
|
59
|
+
}
|
|
60
|
+
/** A {@link FunctionalTool} carrying {@link AGENT_TOOL_BRAND} — what {@link defineTool} returns. */
|
|
61
|
+
export interface BrandedFunctionalTool extends FunctionalTool {
|
|
62
|
+
readonly [AGENT_TOOL_BRAND]: true;
|
|
63
|
+
}
|
|
64
|
+
/** Narrows an arbitrary module export to a branded functional tool for boot-time registration. */
|
|
65
|
+
export declare function isBrandedFunctionalTool(value: unknown): value is BrandedFunctionalTool;
|
|
66
|
+
/**
|
|
67
|
+
* The functional form of a tool: pass the same options as `@AiTool` plus an `execute` function, get
|
|
68
|
+
* back a branded `{ spec, handler }` that discovery auto-registers. Export it from an `app/agent_tools`
|
|
69
|
+
* module (or pass it to `defineConfig({ tools })`).
|
|
70
|
+
*
|
|
71
|
+
* ```ts
|
|
72
|
+
* export const purgeCache = defineTool(
|
|
73
|
+
* { name: 'purgeCache', kind: 'action', description: '...', input: z.object({ key: z.string() }) },
|
|
74
|
+
* async ({ key }, ctx) => { ... },
|
|
75
|
+
* )
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
export declare function defineTool<I = unknown>(options: AiToolOptions, execute: (input: I, ctx: AiToolCtx) => Promise<unknown> | unknown): BrandedFunctionalTool;
|
|
79
|
+
//# sourceMappingURL=ai-tool-ref.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tool-ref.d.ts","sourceRoot":"","sources":["../../src/ai-tool-ref.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,EAAE,OAAO,MAAgD,CAAC;AAEvF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,OAAO,MAAmD,CAAC;AAE1F,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,KAAK,EAAE,gBAAgB,CAAC;IACxB,oGAAoG;IACpG,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6FAA6F;AAC7F,MAAM,MAAM,UAAU,GAAG,aAAa,CAAC;AAEvC,iGAAiG;AACjG,MAAM,MAAM,SAAS,GAAG,QAAQ,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,WAAW,CAAC;AAEvE;;;;;;;;;;;GAWG;AACH,wBAAgB,MAAM,CAAC,OAAO,EAAE,aAAa,IACnC,CAAC,SAAS,SAAS,EAAE,QAAQ,CAAC,KAAG,CAAC,CAQ3C;AAED,qGAAqG;AACrG,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAUtE;AAED,4FAA4F;AAC5F,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE,WAAW,CAAC;CACtB;AAED,oGAAoG;AACpG,MAAM,WAAW,qBAAsB,SAAQ,cAAc;IAC3D,QAAQ,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,CAAC;CACnC;AAED,kGAAkG;AAClG,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,qBAAqB,CAQtF;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,UAAU,CAAC,CAAC,GAAG,OAAO,EACpC,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,SAAS,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,GAChE,qBAAqB,CAcvB"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The symbol the `@AiTool` decorator stamps its options onto (the tool class), read back by
|
|
3
|
+
* discovery to register the class into the {@link import('./tool-registry.js').ToolRegistry}. A
|
|
4
|
+
* global-registry symbol (`Symbol.for`) so it survives duplicate copies of this package in a tree.
|
|
5
|
+
*/
|
|
6
|
+
export const AI_TOOL_META_KEY = Symbol.for('@agora/agent:ai-tool-meta');
|
|
7
|
+
/**
|
|
8
|
+
* Brand stamped on the object {@link defineTool} returns so discovery picks it up when it walks a
|
|
9
|
+
* module's exports — the functional alternative to an `@AiTool` class.
|
|
10
|
+
*/
|
|
11
|
+
export const AGENT_TOOL_BRAND = Symbol.for('@agora/agent:functional-tool');
|
|
12
|
+
/**
|
|
13
|
+
* Marks a class as an AI tool. The class must implement `execute(input, ctx)`. The provider's
|
|
14
|
+
* `app/agent_tools` discovery (or the generated `hooks/tools` barrel) registers every `@AiTool`
|
|
15
|
+
* class into the shared `ToolRegistry` at boot.
|
|
16
|
+
*
|
|
17
|
+
* ```ts
|
|
18
|
+
* @AiTool({ name: 'getWeather', kind: 'read', description: '...', input: z.object({ city: z.string() }) })
|
|
19
|
+
* export default class GetWeatherTool implements ToolHandler<{ city: string }> {
|
|
20
|
+
* async execute(input: { city: string }, ctx: AiToolCtx) { return { tempC: 21 } }
|
|
21
|
+
* }
|
|
22
|
+
* ```
|
|
23
|
+
*/
|
|
24
|
+
export function AiTool(options) {
|
|
25
|
+
return (target) => {
|
|
26
|
+
Object.defineProperty(target, AI_TOOL_META_KEY, {
|
|
27
|
+
value: options,
|
|
28
|
+
enumerable: false,
|
|
29
|
+
configurable: true,
|
|
30
|
+
});
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/** Read the {@link AiToolMeta} an `@AiTool` decorator stamped on a class (or an instance's ctor). */
|
|
35
|
+
export function readAiToolMeta(target) {
|
|
36
|
+
if (target === null || (typeof target !== 'function' && typeof target !== 'object')) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const direct = target[AI_TOOL_META_KEY];
|
|
40
|
+
if (direct !== undefined) {
|
|
41
|
+
return direct;
|
|
42
|
+
}
|
|
43
|
+
const ctor = target.constructor;
|
|
44
|
+
return ctor?.[AI_TOOL_META_KEY];
|
|
45
|
+
}
|
|
46
|
+
/** Narrows an arbitrary module export to a branded functional tool for boot-time registration. */
|
|
47
|
+
export function isBrandedFunctionalTool(value) {
|
|
48
|
+
return (typeof value === 'object' &&
|
|
49
|
+
value !== null &&
|
|
50
|
+
AGENT_TOOL_BRAND in value &&
|
|
51
|
+
'spec' in value &&
|
|
52
|
+
'handler' in value);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* The functional form of a tool: pass the same options as `@AiTool` plus an `execute` function, get
|
|
56
|
+
* back a branded `{ spec, handler }` that discovery auto-registers. Export it from an `app/agent_tools`
|
|
57
|
+
* module (or pass it to `defineConfig({ tools })`).
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* export const purgeCache = defineTool(
|
|
61
|
+
* { name: 'purgeCache', kind: 'action', description: '...', input: z.object({ key: z.string() }) },
|
|
62
|
+
* async ({ key }, ctx) => { ... },
|
|
63
|
+
* )
|
|
64
|
+
* ```
|
|
65
|
+
*/
|
|
66
|
+
export function defineTool(options, execute) {
|
|
67
|
+
const spec = {
|
|
68
|
+
name: options.name,
|
|
69
|
+
kind: options.kind,
|
|
70
|
+
description: options.description,
|
|
71
|
+
inputSchema: options.input,
|
|
72
|
+
...(options.roles !== undefined ? { roles: options.roles } : {}),
|
|
73
|
+
...(options.ability !== undefined ? { ability: options.ability } : {}),
|
|
74
|
+
};
|
|
75
|
+
return {
|
|
76
|
+
[AGENT_TOOL_BRAND]: true,
|
|
77
|
+
spec,
|
|
78
|
+
handler: { execute: (input, ctx) => Promise.resolve(execute(input, ctx)) },
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=ai-tool-ref.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-tool-ref.js","sourceRoot":"","sources":["../../src/ai-tool-ref.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAkB,MAAM,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;AAEvF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAkB,MAAM,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AA8B1F;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,MAAM,CAAC,OAAsB;IAC3C,OAAO,CAAsB,MAAS,EAAK,EAAE;QAC3C,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,gBAAgB,EAAE;YAC9C,KAAK,EAAE,OAAO;YACd,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,OAAO,MAAM,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC;AAED,qGAAqG;AACrG,MAAM,UAAU,cAAc,CAAC,MAAe;IAC5C,IAAI,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,MAAM,KAAK,UAAU,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAE,CAAC;QACpF,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,MAAM,GAAI,MAA8C,CAAC,gBAAgB,CAAC,CAAC;IACjF,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,MAAM,IAAI,GAAI,MAAgE,CAAC,WAAW,CAAC;IAC3F,OAAO,IAAI,EAAE,CAAC,gBAAgB,CAAC,CAAC;AAClC,CAAC;AAaD,kGAAkG;AAClG,MAAM,UAAU,uBAAuB,CAAC,KAAc;IACpD,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACzB,KAAK,KAAK,IAAI;QACd,gBAAgB,IAAI,KAAK;QACzB,MAAM,IAAI,KAAK;QACf,SAAS,IAAI,KAAK,CACnB,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,UAAU,CACxB,OAAsB,EACtB,OAAiE;IAEjE,MAAM,IAAI,GAAa;QACrB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,IAAI,EAAE,OAAO,CAAC,IAAI;QAClB,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,WAAW,EAAE,OAAO,CAAC,KAAK;QAC1B,GAAG,CAAC,OAAO,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAChE,GAAG,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACvE,CAAC;IACF,OAAO;QACL,CAAC,gBAAgB,CAAC,EAAE,IAAI;QACxB,IAAI;QACJ,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,KAAU,EAAE,GAAG,CAAC,CAAC,EAAE;KAChF,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { DefaultRolesPolicy } from './tool-registry.js';
|
|
2
|
+
import type { Actor, ToolSpec } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* The default tool authorizer the provider binds when `config/agent.ts` sets no `authorizer` /
|
|
5
|
+
* `rolesPolicy`. Fail-closed and ADMIN-only by default: a tool that declares no `roles` is offered
|
|
6
|
+
* (and invocable) ONLY to an actor holding one of the configured `defaultRoles` (`['ADMIN']` unless
|
|
7
|
+
* overridden). Authorization is a plain set intersection of the actor's roles against the tool's.
|
|
8
|
+
*
|
|
9
|
+
* This is a thin, explicitly-named binding over core's {@link DefaultRolesPolicy} (the `RolesPolicy`
|
|
10
|
+
* seam) so apps that plug an ability-aware gate (`@adonis-agora/authz` Bouncer adapter) swap ONLY the
|
|
11
|
+
* binding, never the seam. The double check — offered-tools filter AND an invoke-time re-check inside
|
|
12
|
+
* `ToolRegistry.invoke` — both run through this same `can(actor, tool)`.
|
|
13
|
+
*/
|
|
14
|
+
export declare class DefaultToolAuthorizer extends DefaultRolesPolicy {
|
|
15
|
+
constructor(defaultRoles?: string[]);
|
|
16
|
+
can(actor: Actor, tool: ToolSpec): boolean;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=authorizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authorizer.d.ts","sourceRoot":"","sources":["../../src/authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAElD;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,SAAQ,kBAAkB;gBAC/C,YAAY,GAAE,MAAM,EAAc;IAIrC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO;CAGpD"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { RolesPolicy } from '../spi/roles-policy.js';
|
|
2
|
+
import type { Actor, ToolSpec } from '../types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tenant scope shape — a structural mirror of `@adonis-agora/authz`'s `TenantScope`
|
|
5
|
+
* (`{ tenantId?: string }`). Kept local so the adapter references the authz package
|
|
6
|
+
* only by structure, never by import (see {@link AuthzServiceLike}).
|
|
7
|
+
*/
|
|
8
|
+
export interface AuthzTenantScope {
|
|
9
|
+
tenantId?: string;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* The structural slice of `@adonis-agora/authz`'s `AuthzService` this adapter needs: a
|
|
13
|
+
* tenant-scoped, wildcard permission check.
|
|
14
|
+
*
|
|
15
|
+
* Typing it structurally (rather than `import type { AuthzService } from '@adonis-agora/authz'`)
|
|
16
|
+
* is what keeps `@adonis-agora/authz` an OPTIONAL lazy peer — the adapter carries zero import of
|
|
17
|
+
* the package, so it is pulled in only by an app that has already wired authz and hands its
|
|
18
|
+
* `AuthzService` to the factory. The `./authz` subpath is the load boundary: the main entry never
|
|
19
|
+
* references this file, so apps that don't use authz never load it.
|
|
20
|
+
*/
|
|
21
|
+
export interface AuthzServiceLike {
|
|
22
|
+
/**
|
|
23
|
+
* Does `user` hold `permission` (with wildcard matching, e.g. `posts.*` ⊇ `posts.edit`),
|
|
24
|
+
* scoped to `options.scope`? Mirrors `AuthzService.can`.
|
|
25
|
+
*/
|
|
26
|
+
can(user: unknown, permission: string, options?: {
|
|
27
|
+
scope?: AuthzTenantScope;
|
|
28
|
+
}): Promise<boolean>;
|
|
29
|
+
}
|
|
30
|
+
/** Options for {@link AuthzToolAuthorizer} / {@link authzToolAuthorizer}. */
|
|
31
|
+
export interface AuthzToolAuthorizerConfig {
|
|
32
|
+
/**
|
|
33
|
+
* The `@adonis-agora/authz` `AuthzService` (or any structural match) the adapter consults for
|
|
34
|
+
* each tool's declared `ability`. The app builds it from its own `config/authz.ts` and passes
|
|
35
|
+
* the instance here — no host user entity is required.
|
|
36
|
+
*/
|
|
37
|
+
authz: AuthzServiceLike;
|
|
38
|
+
/**
|
|
39
|
+
* Maps an {@link Actor} onto the user object authz resolves a `UserRef` from. Defaults to
|
|
40
|
+
* `{ id: actor.id }` — enough for authz's `defaultResolveUserRef` (which reads `.id`, defaulting
|
|
41
|
+
* the type to `user`). Override to attach a polymorphic `type` or a host user entity.
|
|
42
|
+
*/
|
|
43
|
+
userFromActor?: (actor: Actor) => unknown;
|
|
44
|
+
}
|
|
45
|
+
/** Default {@link Actor} → authz user mapping: the minimal `{ id }` authz needs to resolve a `UserRef`. */
|
|
46
|
+
export declare function defaultUserFromActor(actor: Actor): unknown;
|
|
47
|
+
/**
|
|
48
|
+
* A {@link RolesPolicy} (the agent's `ToolAuthorizer` seam) backed by `@adonis-agora/authz`
|
|
49
|
+
* (AdonisJS Bouncer). For each tool it checks the actor against the tool's declared `ability`
|
|
50
|
+
* via {@link AuthzServiceLike.can}, scoped to the actor's tenant.
|
|
51
|
+
*
|
|
52
|
+
* Security posture — FAIL-CLOSED:
|
|
53
|
+
* - A tool that declares no `ability` is NEVER authorized (deny). Unlike the role-based default,
|
|
54
|
+
* there is no ADMIN fallback: with authz selected, an un-annotated tool is simply not reachable.
|
|
55
|
+
* - Any error thrown while resolving the decision denies.
|
|
56
|
+
*
|
|
57
|
+
* Tenant isolation: `actor.tenantRef` is passed as the authz **scope** (`{ tenantId }`), so a
|
|
58
|
+
* permission granted in one tenant never authorizes a tool call made in another. When the actor has
|
|
59
|
+
* no `tenantRef`, the check runs against the global scope (authz's default).
|
|
60
|
+
*
|
|
61
|
+
* The agent's double check — the offered-tools filter AND the invoke-time re-check inside
|
|
62
|
+
* `ToolRegistry` — both run through this same `can(actor, tool)`, so offer and invoke stay
|
|
63
|
+
* consistent.
|
|
64
|
+
*/
|
|
65
|
+
export declare class AuthzToolAuthorizer implements RolesPolicy {
|
|
66
|
+
#private;
|
|
67
|
+
constructor(config: AuthzToolAuthorizerConfig);
|
|
68
|
+
can(actor: Actor, tool: ToolSpec): Promise<boolean>;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Factory for an {@link AuthzToolAuthorizer}. Wire it in `config/agent.ts` as the tool authorizer,
|
|
72
|
+
* replacing the ADMIN-only `DefaultToolAuthorizer`:
|
|
73
|
+
*
|
|
74
|
+
* ```ts
|
|
75
|
+
* import { defineConfig } from '@adonis-agora/agent'
|
|
76
|
+
* import { authzToolAuthorizer } from '@adonis-agora/agent/authz'
|
|
77
|
+
*
|
|
78
|
+
* export default defineConfig({
|
|
79
|
+
* model: () => aiSdkModel({ model: '...' }),
|
|
80
|
+
* authorizer: authzToolAuthorizer({ authz: await app.container.make('authz.service') }),
|
|
81
|
+
* })
|
|
82
|
+
* ```
|
|
83
|
+
*/
|
|
84
|
+
export declare function authzToolAuthorizer(config: AuthzToolAuthorizerConfig): AuthzToolAuthorizer;
|
|
85
|
+
//# sourceMappingURL=authz-tool-authorizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authz-tool-authorizer.d.ts","sourceRoot":"","sources":["../../../src/authz/authz-tool-authorizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEnD;;;;GAIG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;;OAGG;IACH,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,gBAAgB,CAAA;KAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClG;AAED,6EAA6E;AAC7E,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,KAAK,EAAE,gBAAgB,CAAC;IACxB;;;;OAIG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;CAC3C;AAED,2GAA2G;AAC3G,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAE1D;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,qBAAa,mBAAoB,YAAW,WAAW;;gBAIzC,MAAM,EAAE,yBAAyB;IAKvC,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;CAa1D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,yBAAyB,GAAG,mBAAmB,CAE1F"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Default {@link Actor} → authz user mapping: the minimal `{ id }` authz needs to resolve a `UserRef`. */
|
|
2
|
+
export function defaultUserFromActor(actor) {
|
|
3
|
+
return { id: actor.id };
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* A {@link RolesPolicy} (the agent's `ToolAuthorizer` seam) backed by `@adonis-agora/authz`
|
|
7
|
+
* (AdonisJS Bouncer). For each tool it checks the actor against the tool's declared `ability`
|
|
8
|
+
* via {@link AuthzServiceLike.can}, scoped to the actor's tenant.
|
|
9
|
+
*
|
|
10
|
+
* Security posture — FAIL-CLOSED:
|
|
11
|
+
* - A tool that declares no `ability` is NEVER authorized (deny). Unlike the role-based default,
|
|
12
|
+
* there is no ADMIN fallback: with authz selected, an un-annotated tool is simply not reachable.
|
|
13
|
+
* - Any error thrown while resolving the decision denies.
|
|
14
|
+
*
|
|
15
|
+
* Tenant isolation: `actor.tenantRef` is passed as the authz **scope** (`{ tenantId }`), so a
|
|
16
|
+
* permission granted in one tenant never authorizes a tool call made in another. When the actor has
|
|
17
|
+
* no `tenantRef`, the check runs against the global scope (authz's default).
|
|
18
|
+
*
|
|
19
|
+
* The agent's double check — the offered-tools filter AND the invoke-time re-check inside
|
|
20
|
+
* `ToolRegistry` — both run through this same `can(actor, tool)`, so offer and invoke stay
|
|
21
|
+
* consistent.
|
|
22
|
+
*/
|
|
23
|
+
export class AuthzToolAuthorizer {
|
|
24
|
+
#authz;
|
|
25
|
+
#userFromActor;
|
|
26
|
+
constructor(config) {
|
|
27
|
+
this.#authz = config.authz;
|
|
28
|
+
this.#userFromActor = config.userFromActor ?? defaultUserFromActor;
|
|
29
|
+
}
|
|
30
|
+
async can(actor, tool) {
|
|
31
|
+
// Fail-closed: no declared ability → deny. There is no role fallback under authz.
|
|
32
|
+
if (tool.ability === undefined)
|
|
33
|
+
return false;
|
|
34
|
+
try {
|
|
35
|
+
// Pass the actor's tenant as the authz scope so the grant is tenant-isolated. Omit the option
|
|
36
|
+
// entirely when there is no tenantRef (global scope) — honors `exactOptionalPropertyTypes`.
|
|
37
|
+
const options = actor.tenantRef !== undefined ? { scope: { tenantId: actor.tenantRef } } : {};
|
|
38
|
+
return await this.#authz.can(this.#userFromActor(actor), tool.ability, options);
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// Fail-closed: any failure resolving the decision denies.
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Factory for an {@link AuthzToolAuthorizer}. Wire it in `config/agent.ts` as the tool authorizer,
|
|
48
|
+
* replacing the ADMIN-only `DefaultToolAuthorizer`:
|
|
49
|
+
*
|
|
50
|
+
* ```ts
|
|
51
|
+
* import { defineConfig } from '@adonis-agora/agent'
|
|
52
|
+
* import { authzToolAuthorizer } from '@adonis-agora/agent/authz'
|
|
53
|
+
*
|
|
54
|
+
* export default defineConfig({
|
|
55
|
+
* model: () => aiSdkModel({ model: '...' }),
|
|
56
|
+
* authorizer: authzToolAuthorizer({ authz: await app.container.make('authz.service') }),
|
|
57
|
+
* })
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export function authzToolAuthorizer(config) {
|
|
61
|
+
return new AuthzToolAuthorizer(config);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=authz-tool-authorizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authz-tool-authorizer.js","sourceRoot":"","sources":["../../../src/authz/authz-tool-authorizer.ts"],"names":[],"mappings":"AA8CA,2GAA2G;AAC3G,MAAM,UAAU,oBAAoB,CAAC,KAAY;IAC/C,OAAO,EAAE,EAAE,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,OAAO,mBAAmB;IACrB,MAAM,CAAmB;IACzB,cAAc,CAA4B;IAEnD,YAAY,MAAiC;QAC3C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC;QAC3B,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,aAAa,IAAI,oBAAoB,CAAC;IACrE,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,KAAY,EAAE,IAAc;QACpC,kFAAkF;QAClF,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QAC7C,IAAI,CAAC;YACH,8FAA8F;YAC9F,4FAA4F;YAC5F,MAAM,OAAO,GAAG,KAAK,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9F,OAAO,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAClF,CAAC;QAAC,MAAM,CAAC;YACP,0DAA0D;YAC1D,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAiC;IACnE,OAAO,IAAI,mBAAmB,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/authz/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC;AACpC,YAAY,EACV,yBAAyB,EACzB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/authz/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,4BAA4B,CAAC"}
|