@everworker/oneringai 0.1.1 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -6,6 +6,54 @@
6
6
  [![TypeScript](https://img.shields.io/badge/TypeScript-5.3-blue.svg)](https://www.typescriptlang.org/)
7
7
  [![Node.js](https://img.shields.io/badge/Node.js-18+-green.svg)](https://nodejs.org/)
8
8
 
9
+ ## Table of Contents
10
+
11
+ - [Features](#features)
12
+ - [Quick Start](#quick-start) — Installation, basic usage, tools, vision, audio, images, video, search, scraping
13
+ - [Supported Providers](#supported-providers)
14
+ - [Key Features](#key-features)
15
+ - [1. Agent with Plugins](#1-agent-with-plugins)
16
+ - [2. Dynamic Tool Management](#2-dynamic-tool-management-new)
17
+ - [3. Tool Execution Plugins](#3-tool-execution-plugins-new)
18
+ - [4. Session Persistence](#4-session-persistence)
19
+ - [5. Working Memory](#5-working-memory)
20
+ - [6. Research with Search Tools](#6-research-with-search-tools)
21
+ - [6. Context Management](#6-context-management)
22
+ - [7. InContextMemory](#7-incontextmemory)
23
+ - [8. Persistent Instructions](#8-persistent-instructions)
24
+ - [9. Direct LLM Access](#9-direct-llm-access)
25
+ - [11. Audio Capabilities](#11-audio-capabilities)
26
+ - [12. Model Registry](#12-model-registry)
27
+ - [13. Streaming](#13-streaming)
28
+ - [14. OAuth for External APIs](#14-oauth-for-external-apis)
29
+ - [15. Developer Tools](#15-developer-tools)
30
+ - [16. External API Integration](#16-external-api-integration) — Scoped Registry, Vendor Templates, Tool Discovery
31
+ - [MCP Integration](#mcp-model-context-protocol-integration)
32
+ - [Documentation](#documentation)
33
+ - [Examples](#examples)
34
+ - [Development](#development)
35
+ - [Architecture](#architecture)
36
+ - [Troubleshooting](#troubleshooting)
37
+ - [Contributing](#contributing)
38
+ - [License](#license)
39
+
40
+ <!-- For in-depth guides and full API reference, see the docs section below -->
41
+
42
+ ## Documentation
43
+
44
+ > **Start here if you're looking for detailed docs or the full API reference.**
45
+
46
+ | Document | Description |
47
+ |----------|-------------|
48
+ | **[User Guide](./USER_GUIDE.md)** | Comprehensive guide covering every feature with examples — connectors, agents, context, plugins, audio, video, search, MCP, OAuth, and more |
49
+ | **[API Reference](./API_REFERENCE.md)** | Auto-generated reference for all 600+ public exports — classes, interfaces, types, and functions with signatures |
50
+ | [CHANGELOG](./CHANGELOG.md) | Version history and migration notes |
51
+ | [MCP Integration](./MCP_INTEGRATION.md) | Model Context Protocol setup and usage |
52
+ | [Architecture (CLAUDE.md)](./CLAUDE.md) | Internal architecture guide |
53
+ | [Testing Guide](./TESTING.md) | How to run and write tests |
54
+
55
+ ---
56
+
9
57
  ## Features
10
58
 
11
59
  - ✨ **Unified API** - One interface for 10+ AI providers (OpenAI, Anthropic, Google, Groq, DeepSeek, and more)
@@ -22,7 +70,7 @@
22
70
  - 🤖 **Universal Agent** - ⚠️ *Deprecated* - Use `Agent` with plugins instead
23
71
  - 🤖 **Task Agents** - ⚠️ *Deprecated* - Use `Agent` with `WorkingMemoryPluginNextGen`
24
72
  - 🔬 **Research Agent** - ⚠️ *Deprecated* - Use `Agent` with search tools
25
- - 🎯 **Context Management** - Smart strategies (proactive, aggressive, lazy, rolling-window, adaptive)
73
+ - 🎯 **Context Management** - Algorithmic compaction with tool-result-to-memory offloading
26
74
  - 📌 **InContextMemory** - NEW: Live key-value storage directly in LLM context for instant access
27
75
  - 📝 **Persistent Instructions** - NEW: Agent-level custom instructions that persist across sessions on disk
28
76
  - 🛠️ **Agentic Workflows** - Built-in tool calling and multi-turn conversations
@@ -30,6 +78,7 @@
30
78
  - 🔌 **MCP Integration** - NEW: Model Context Protocol client for seamless tool discovery from local and remote servers
31
79
  - 👁️ **Vision Support** - Analyze images with AI across all providers
32
80
  - 📋 **Clipboard Integration** - Paste screenshots directly (like Claude Code!)
81
+ - 🔐 **Scoped Connector Registry** - NEW: Pluggable access control for multi-tenant connector isolation
33
82
  - 🔐 **OAuth 2.0** - Full OAuth support for external APIs with encrypted token storage
34
83
  - 📦 **Vendor Templates** - NEW: Pre-configured auth templates for 43+ services (GitHub, Slack, Stripe, etc.)
35
84
  - 🔄 **Streaming** - Real-time responses with event streams
@@ -578,7 +627,6 @@ const agent = Agent.create({
578
627
  connector: 'openai',
579
628
  model: 'gpt-4',
580
629
  context: {
581
- strategy: 'balanced', // proactive, balanced, lazy
582
630
  features: { workingMemory: true },
583
631
  },
584
632
  });
@@ -621,7 +669,7 @@ const agent = Agent.create({
621
669
  |---------|---------|--------|------------------|
622
670
  | `workingMemory` | `true` | WorkingMemoryPluginNextGen | `memory_store/retrieve/delete/list` |
623
671
  | `inContextMemory` | `false` | InContextMemoryPluginNextGen | `context_set/delete/list` |
624
- | `persistentInstructions` | `false` | PersistentInstructionsPluginNextGen | `instructions_set/get/append/clear` |
672
+ | `persistentInstructions` | `false` | PersistentInstructionsPluginNextGen | `instructions_set/remove/list/clear` |
625
673
 
626
674
  **AgentContextNextGen architecture:**
627
675
  - **Plugin-first design** - All features are composable plugins
@@ -629,10 +677,8 @@ const agent = Agent.create({
629
677
  - **Single system message** - All context components combined
630
678
  - **Smart compaction** - Happens once, right before LLM call
631
679
 
632
- **Three compaction strategies:**
633
- - **proactive** - Compact at 70% usage
634
- - **balanced** (default) - Compact at 80% usage
635
- - **lazy** - Compact at 90% usage
680
+ **Compaction strategy:**
681
+ - **algorithmic** (default) - Moves large tool results to Working Memory, limits tool pairs, applies rolling window. Triggers at 75% context usage.
636
682
 
637
683
  **Context preparation:**
638
684
  ```typescript
@@ -694,8 +740,8 @@ const agent = Agent.create({
694
740
  },
695
741
  });
696
742
 
697
- // LLM can now use instructions_set/append/get/clear tools
698
- // Instructions persist to ~/.oneringai/agents/my-assistant/custom_instructions.md
743
+ // LLM can now use instructions_set/remove/list/clear tools
744
+ // Instructions persist to ~/.oneringai/agents/my-assistant/custom_instructions.json
699
745
  ```
700
746
 
701
747
  **Key Features:**
@@ -705,9 +751,9 @@ const agent = Agent.create({
705
751
  - 🛡️ **Never Compacted** - Critical instructions always preserved in context
706
752
 
707
753
  **Available Tools:**
708
- - `instructions_set` - Replace all custom instructions
709
- - `instructions_append` - Add a new section to existing instructions
710
- - `instructions_get` - Read current instructions
754
+ - `instructions_set` - Add or update a single instruction by key
755
+ - `instructions_remove` - Remove a single instruction by key
756
+ - `instructions_list` - List all instructions with keys and content
711
757
  - `instructions_clear` - Remove all instructions (requires confirmation)
712
758
 
713
759
  **Use cases:** Agent personality/behavior, user preferences, learned rules, tool usage patterns.
@@ -966,6 +1012,51 @@ const metrics = connector.getMetrics();
966
1012
  console.log(`Success rate: ${metrics.successCount / metrics.requestCount * 100}%`);
967
1013
  ```
968
1014
 
1015
+ #### Scoped Connector Registry (NEW)
1016
+
1017
+ Limit connector visibility by user, group, or tenant in multi-user systems:
1018
+
1019
+ ```typescript
1020
+ import { Connector, ScopedConnectorRegistry } from '@everworker/oneringai';
1021
+ import type { IConnectorAccessPolicy } from '@everworker/oneringai';
1022
+
1023
+ // Define an access policy
1024
+ const policy: IConnectorAccessPolicy = {
1025
+ canAccess: (connector, context) => {
1026
+ const tags = connector.config.tags as string[] | undefined;
1027
+ return !!tags && tags.includes(context.tenantId as string);
1028
+ },
1029
+ };
1030
+
1031
+ // Set the global policy
1032
+ Connector.setAccessPolicy(policy);
1033
+
1034
+ // Create a scoped view for a specific tenant
1035
+ const registry = Connector.scoped({ tenantId: 'acme-corp' });
1036
+
1037
+ // Only connectors tagged with 'acme-corp' are visible
1038
+ registry.list(); // ['acme-openai', 'acme-slack']
1039
+ registry.get('other-co'); // throws "not found" (no info leakage)
1040
+
1041
+ // Use with Agent
1042
+ const agent = Agent.create({
1043
+ connector: 'acme-openai',
1044
+ model: 'gpt-4',
1045
+ registry, // Agent resolves connectors through the scoped view
1046
+ });
1047
+
1048
+ // Use with ConnectorTools
1049
+ const tools = ConnectorTools.for('acme-slack', undefined, { registry });
1050
+ const allTools = ConnectorTools.discoverAll(undefined, { registry });
1051
+ ```
1052
+
1053
+ **Features:**
1054
+ - Pluggable `IConnectorAccessPolicy` interface — bring your own access logic
1055
+ - Opaque context object (`{ userId, tenantId, roles, ... }`) — library imposes no structure
1056
+ - Denied connectors get the same "not found" error — no information leakage
1057
+ - Zero changes to existing API — scoping is entirely opt-in
1058
+ - Works with `Agent.create()`, `ConnectorTools.for()`, and `ConnectorTools.discoverAll()`
1059
+
969
1060
  #### Vendor Templates (NEW)
970
1061
 
971
1062
  Quickly set up connectors for 43+ services with pre-configured authentication templates:
@@ -1130,18 +1221,6 @@ await agent.run('List files and analyze them');
1130
1221
 
1131
1222
  See [MCP_INTEGRATION.md](./MCP_INTEGRATION.md) for complete documentation.
1132
1223
 
1133
- ## Documentation
1134
-
1135
- 📖 **[Complete User Guide](./USER_GUIDE.md)** - Comprehensive guide covering all features
1136
-
1137
- ### Additional Resources
1138
-
1139
- - **[MCP_INTEGRATION.md](./MCP_INTEGRATION.md)** - Model Context Protocol integration guide
1140
- - **[CLAUDE.md](./CLAUDE.md)** - Architecture guide for AI assistants
1141
- - **[MULTIMODAL_ARCHITECTURE.md](./MULTIMODAL_ARCHITECTURE.md)** - Multimodal implementation details
1142
- - **[MICROSOFT_GRAPH_SETUP.md](./MICROSOFT_GRAPH_SETUP.md)** - Microsoft Graph OAuth setup
1143
- - **[TESTING.md](./TESTING.md)** - Testing guide for contributors
1144
-
1145
1224
  ## Examples
1146
1225
 
1147
1226
  ```bash
@@ -1196,6 +1275,7 @@ User Code → Connector Registry → Agent → Provider → LLM
1196
1275
  - ✅ Named connectors for easy reference
1197
1276
  - ✅ No API key management in agent code
1198
1277
  - ✅ Same pattern for AI providers AND external APIs
1278
+ - ✅ Scoped registry for multi-tenant access control
1199
1279
 
1200
1280
  ## Troubleshooting
1201
1281
 
@@ -1221,9 +1301,4 @@ MIT License - See [LICENSE](./LICENSE) file.
1221
1301
 
1222
1302
  ---
1223
1303
 
1224
- **Version:** 0.1.0
1225
- **Last Updated:** 2026-02-05
1226
-
1227
- For detailed documentation on all features, see the **[Complete User Guide](./USER_GUIDE.md)**.
1228
-
1229
- For internal development and architecture improvement plans, see **[IMPROVEMENT_PLAN.md](./IMPROVEMENT_PLAN.md)**.
1304
+ **Version:** 0.1.3 | **Last Updated:** 2026-02-07 | **[User Guide](./USER_GUIDE.md)** | **[API Reference](./API_REFERENCE.md)** | **[Changelog](./CHANGELOG.md)**
@@ -227,6 +227,57 @@ interface ITokenStorage {
227
227
  hasToken(key: string): Promise<boolean>;
228
228
  }
229
229
 
230
+ /**
231
+ * IConnectorRegistry - Read-only interface for connector lookup
232
+ *
233
+ * Covers the read-only subset of Connector static methods.
234
+ * Used by ScopedConnectorRegistry to provide filtered views
235
+ * and by consumers that only need to read from the registry.
236
+ */
237
+
238
+ interface IConnectorRegistry {
239
+ /** Get a connector by name. Throws if not found (or not accessible). */
240
+ get(name: string): Connector;
241
+ /** Check if a connector exists (and is accessible) */
242
+ has(name: string): boolean;
243
+ /** List all accessible connector names */
244
+ list(): string[];
245
+ /** List all accessible connector instances */
246
+ listAll(): Connector[];
247
+ /** Get number of accessible connectors */
248
+ size(): number;
249
+ /** Get connector descriptions formatted for tool parameters */
250
+ getDescriptionsForTools(): string;
251
+ /** Get connector info map */
252
+ getInfo(): Record<string, {
253
+ displayName: string;
254
+ description: string;
255
+ baseURL: string;
256
+ }>;
257
+ }
258
+
259
+ /**
260
+ * IConnectorAccessPolicy - Pluggable access control for connector registry
261
+ *
262
+ * Policies are sync-only for performance — access checks must be fast
263
+ * and policy data should be in-memory.
264
+ */
265
+
266
+ /**
267
+ * Opaque context passed to access policy checks.
268
+ * Library imposes no structure — consumers define their own shape
269
+ * (e.g., { userId, tenantId, roles }).
270
+ */
271
+ type ConnectorAccessContext = Record<string, unknown>;
272
+ interface IConnectorAccessPolicy {
273
+ /**
274
+ * Check if a connector is accessible in the given context.
275
+ * Receives the full Connector instance so it can inspect
276
+ * config.tags, vendor, serviceType, etc.
277
+ */
278
+ canAccess(connector: Connector, context: ConnectorAccessContext): boolean;
279
+ }
280
+
230
281
  /**
231
282
  * Connector - The single source of truth for authentication
232
283
  *
@@ -305,6 +356,30 @@ declare class Connector {
305
356
  * Get number of registered connectors
306
357
  */
307
358
  static size(): number;
359
+ private static _accessPolicy;
360
+ /**
361
+ * Set a global access policy for connector scoping.
362
+ * Pass null to clear the policy.
363
+ */
364
+ static setAccessPolicy(policy: IConnectorAccessPolicy | null): void;
365
+ /**
366
+ * Get the current global access policy (or null if none set).
367
+ */
368
+ static getAccessPolicy(): IConnectorAccessPolicy | null;
369
+ /**
370
+ * Create a scoped (filtered) view of the connector registry.
371
+ * Requires a global access policy to be set via setAccessPolicy().
372
+ *
373
+ * @param context - Opaque context passed to the policy (e.g., { userId, tenantId })
374
+ * @returns IConnectorRegistry that only exposes accessible connectors
375
+ * @throws Error if no access policy is set
376
+ */
377
+ static scoped(context: ConnectorAccessContext): IConnectorRegistry;
378
+ /**
379
+ * Return the static Connector methods as an IConnectorRegistry object (unfiltered).
380
+ * Useful when code accepts the interface but you want the full admin view.
381
+ */
382
+ static asRegistry(): IConnectorRegistry;
308
383
  /**
309
384
  * Get connector descriptions formatted for tool parameters
310
385
  * Useful for generating dynamic tool descriptions
@@ -760,4 +835,4 @@ declare function getImageModelsWithFeature(feature: keyof IImageModelDescription
760
835
  */
761
836
  declare function calculateImageCost(modelName: string, imageCount: number, quality?: 'standard' | 'hd'): number | null;
762
837
 
763
- export { type AudioFormat as A, type ImageResponse as B, Connector as C, type AspectRatio$1 as D, type OutputFormat as E, type ISourceLinks as F, DEFAULT_CONNECTOR_TIMEOUT as G, DEFAULT_MAX_RETRIES as H, type IBaseModelDescription as I, type JWTConnectorAuth as J, DEFAULT_RETRYABLE_STATUSES as K, DEFAULT_BASE_DELAY_MS as L, DEFAULT_MAX_DELAY_MS as M, type OAuthConnectorAuth as O, type QualityLevel as Q, type StoredToken as S, type VendorOptionSchema as V, Vendor as a, type IImageProvider as b, type ConnectorFetchOptions as c, type ITokenStorage as d, type ConnectorConfig as e, type ConnectorAuth as f, type ConnectorConfigResult as g, VENDORS as h, isVendor as i, ImageGeneration as j, type ImageGenerationCreateOptions as k, type SimpleGenerateOptions as l, type APIKeyConnectorAuth as m, type IImageModelDescription as n, type ImageModelCapabilities as o, type ImageModelPricing as p, IMAGE_MODELS as q, IMAGE_MODEL_REGISTRY as r, getImageModelInfo as s, getImageModelsByVendor as t, getActiveImageModels as u, getImageModelsWithFeature as v, calculateImageCost as w, type ImageGenerateOptions as x, type ImageEditOptions as y, type ImageVariationOptions as z };
838
+ export { type AudioFormat as A, type ImageGenerateOptions as B, type ConnectorAccessContext as C, type ImageEditOptions as D, type ImageVariationOptions as E, type ImageResponse as F, type AspectRatio$1 as G, type OutputFormat as H, type IConnectorRegistry as I, type JWTConnectorAuth as J, type ISourceLinks as K, DEFAULT_CONNECTOR_TIMEOUT as L, DEFAULT_MAX_RETRIES as M, DEFAULT_RETRYABLE_STATUSES as N, type OAuthConnectorAuth as O, DEFAULT_BASE_DELAY_MS as P, type QualityLevel as Q, DEFAULT_MAX_DELAY_MS as R, type StoredToken as S, type VendorOptionSchema as V, type IConnectorAccessPolicy as a, Connector as b, type IBaseModelDescription as c, Vendor as d, type IImageProvider as e, type ConnectorFetchOptions as f, type ITokenStorage as g, type ConnectorConfig as h, type ConnectorAuth as i, type ConnectorConfigResult as j, VENDORS as k, isVendor as l, ImageGeneration as m, type ImageGenerationCreateOptions as n, type SimpleGenerateOptions as o, type APIKeyConnectorAuth as p, type IImageModelDescription as q, type ImageModelCapabilities as r, type ImageModelPricing as s, IMAGE_MODELS as t, IMAGE_MODEL_REGISTRY as u, getImageModelInfo as v, getImageModelsByVendor as w, getActiveImageModels as x, getImageModelsWithFeature as y, calculateImageCost as z };
@@ -227,6 +227,57 @@ interface ITokenStorage {
227
227
  hasToken(key: string): Promise<boolean>;
228
228
  }
229
229
 
230
+ /**
231
+ * IConnectorRegistry - Read-only interface for connector lookup
232
+ *
233
+ * Covers the read-only subset of Connector static methods.
234
+ * Used by ScopedConnectorRegistry to provide filtered views
235
+ * and by consumers that only need to read from the registry.
236
+ */
237
+
238
+ interface IConnectorRegistry {
239
+ /** Get a connector by name. Throws if not found (or not accessible). */
240
+ get(name: string): Connector;
241
+ /** Check if a connector exists (and is accessible) */
242
+ has(name: string): boolean;
243
+ /** List all accessible connector names */
244
+ list(): string[];
245
+ /** List all accessible connector instances */
246
+ listAll(): Connector[];
247
+ /** Get number of accessible connectors */
248
+ size(): number;
249
+ /** Get connector descriptions formatted for tool parameters */
250
+ getDescriptionsForTools(): string;
251
+ /** Get connector info map */
252
+ getInfo(): Record<string, {
253
+ displayName: string;
254
+ description: string;
255
+ baseURL: string;
256
+ }>;
257
+ }
258
+
259
+ /**
260
+ * IConnectorAccessPolicy - Pluggable access control for connector registry
261
+ *
262
+ * Policies are sync-only for performance — access checks must be fast
263
+ * and policy data should be in-memory.
264
+ */
265
+
266
+ /**
267
+ * Opaque context passed to access policy checks.
268
+ * Library imposes no structure — consumers define their own shape
269
+ * (e.g., { userId, tenantId, roles }).
270
+ */
271
+ type ConnectorAccessContext = Record<string, unknown>;
272
+ interface IConnectorAccessPolicy {
273
+ /**
274
+ * Check if a connector is accessible in the given context.
275
+ * Receives the full Connector instance so it can inspect
276
+ * config.tags, vendor, serviceType, etc.
277
+ */
278
+ canAccess(connector: Connector, context: ConnectorAccessContext): boolean;
279
+ }
280
+
230
281
  /**
231
282
  * Connector - The single source of truth for authentication
232
283
  *
@@ -305,6 +356,30 @@ declare class Connector {
305
356
  * Get number of registered connectors
306
357
  */
307
358
  static size(): number;
359
+ private static _accessPolicy;
360
+ /**
361
+ * Set a global access policy for connector scoping.
362
+ * Pass null to clear the policy.
363
+ */
364
+ static setAccessPolicy(policy: IConnectorAccessPolicy | null): void;
365
+ /**
366
+ * Get the current global access policy (or null if none set).
367
+ */
368
+ static getAccessPolicy(): IConnectorAccessPolicy | null;
369
+ /**
370
+ * Create a scoped (filtered) view of the connector registry.
371
+ * Requires a global access policy to be set via setAccessPolicy().
372
+ *
373
+ * @param context - Opaque context passed to the policy (e.g., { userId, tenantId })
374
+ * @returns IConnectorRegistry that only exposes accessible connectors
375
+ * @throws Error if no access policy is set
376
+ */
377
+ static scoped(context: ConnectorAccessContext): IConnectorRegistry;
378
+ /**
379
+ * Return the static Connector methods as an IConnectorRegistry object (unfiltered).
380
+ * Useful when code accepts the interface but you want the full admin view.
381
+ */
382
+ static asRegistry(): IConnectorRegistry;
308
383
  /**
309
384
  * Get connector descriptions formatted for tool parameters
310
385
  * Useful for generating dynamic tool descriptions
@@ -760,4 +835,4 @@ declare function getImageModelsWithFeature(feature: keyof IImageModelDescription
760
835
  */
761
836
  declare function calculateImageCost(modelName: string, imageCount: number, quality?: 'standard' | 'hd'): number | null;
762
837
 
763
- export { type AudioFormat as A, type ImageResponse as B, Connector as C, type AspectRatio$1 as D, type OutputFormat as E, type ISourceLinks as F, DEFAULT_CONNECTOR_TIMEOUT as G, DEFAULT_MAX_RETRIES as H, type IBaseModelDescription as I, type JWTConnectorAuth as J, DEFAULT_RETRYABLE_STATUSES as K, DEFAULT_BASE_DELAY_MS as L, DEFAULT_MAX_DELAY_MS as M, type OAuthConnectorAuth as O, type QualityLevel as Q, type StoredToken as S, type VendorOptionSchema as V, Vendor as a, type IImageProvider as b, type ConnectorFetchOptions as c, type ITokenStorage as d, type ConnectorConfig as e, type ConnectorAuth as f, type ConnectorConfigResult as g, VENDORS as h, isVendor as i, ImageGeneration as j, type ImageGenerationCreateOptions as k, type SimpleGenerateOptions as l, type APIKeyConnectorAuth as m, type IImageModelDescription as n, type ImageModelCapabilities as o, type ImageModelPricing as p, IMAGE_MODELS as q, IMAGE_MODEL_REGISTRY as r, getImageModelInfo as s, getImageModelsByVendor as t, getActiveImageModels as u, getImageModelsWithFeature as v, calculateImageCost as w, type ImageGenerateOptions as x, type ImageEditOptions as y, type ImageVariationOptions as z };
838
+ export { type AudioFormat as A, type ImageGenerateOptions as B, type ConnectorAccessContext as C, type ImageEditOptions as D, type ImageVariationOptions as E, type ImageResponse as F, type AspectRatio$1 as G, type OutputFormat as H, type IConnectorRegistry as I, type JWTConnectorAuth as J, type ISourceLinks as K, DEFAULT_CONNECTOR_TIMEOUT as L, DEFAULT_MAX_RETRIES as M, DEFAULT_RETRYABLE_STATUSES as N, type OAuthConnectorAuth as O, DEFAULT_BASE_DELAY_MS as P, type QualityLevel as Q, DEFAULT_MAX_DELAY_MS as R, type StoredToken as S, type VendorOptionSchema as V, type IConnectorAccessPolicy as a, Connector as b, type IBaseModelDescription as c, Vendor as d, type IImageProvider as e, type ConnectorFetchOptions as f, type ITokenStorage as g, type ConnectorConfig as h, type ConnectorAuth as i, type ConnectorConfigResult as j, VENDORS as k, isVendor as l, ImageGeneration as m, type ImageGenerationCreateOptions as n, type SimpleGenerateOptions as o, type APIKeyConnectorAuth as p, type IImageModelDescription as q, type ImageModelCapabilities as r, type ImageModelPricing as s, IMAGE_MODELS as t, IMAGE_MODEL_REGISTRY as u, getImageModelInfo as v, getImageModelsByVendor as w, getActiveImageModels as x, getImageModelsWithFeature as y, calculateImageCost as z };
@@ -1452,6 +1452,58 @@ var metrics = createMetricsCollector(
1452
1452
  process.env.METRICS_PREFIX || "oneringai"
1453
1453
  );
1454
1454
 
1455
+ // src/core/ScopedConnectorRegistry.ts
1456
+ var ScopedConnectorRegistry = class {
1457
+ constructor(policy, context) {
1458
+ this.policy = policy;
1459
+ this.context = context;
1460
+ }
1461
+ get(name) {
1462
+ if (!Connector.has(name)) {
1463
+ const available = this.list().join(", ") || "none";
1464
+ throw new Error(`Connector '${name}' not found. Available: ${available}`);
1465
+ }
1466
+ const connector = Connector.get(name);
1467
+ if (!this.policy.canAccess(connector, this.context)) {
1468
+ const available = this.list().join(", ") || "none";
1469
+ throw new Error(`Connector '${name}' not found. Available: ${available}`);
1470
+ }
1471
+ return connector;
1472
+ }
1473
+ has(name) {
1474
+ if (!Connector.has(name)) return false;
1475
+ const connector = Connector.get(name);
1476
+ return this.policy.canAccess(connector, this.context);
1477
+ }
1478
+ list() {
1479
+ return this.listAll().map((c) => c.name);
1480
+ }
1481
+ listAll() {
1482
+ return Connector.listAll().filter((c) => this.policy.canAccess(c, this.context));
1483
+ }
1484
+ size() {
1485
+ return this.listAll().length;
1486
+ }
1487
+ getDescriptionsForTools() {
1488
+ const connectors = this.listAll();
1489
+ if (connectors.length === 0) {
1490
+ return "No connectors registered yet.";
1491
+ }
1492
+ return connectors.map((c) => ` - "${c.name}": ${c.displayName} - ${c.config.description || "No description"}`).join("\n");
1493
+ }
1494
+ getInfo() {
1495
+ const info = {};
1496
+ for (const connector of this.listAll()) {
1497
+ info[connector.name] = {
1498
+ displayName: connector.displayName,
1499
+ description: connector.config.description || "",
1500
+ baseURL: connector.baseURL
1501
+ };
1502
+ }
1503
+ return info;
1504
+ }
1505
+ };
1506
+
1455
1507
  // src/core/Connector.ts
1456
1508
  var DEFAULT_CONNECTOR_TIMEOUT = 3e4;
1457
1509
  var DEFAULT_MAX_RETRIES = 3;
@@ -1537,6 +1589,50 @@ var Connector = class _Connector {
1537
1589
  static size() {
1538
1590
  return _Connector.registry.size;
1539
1591
  }
1592
+ // ============ Access Control ============
1593
+ static _accessPolicy = null;
1594
+ /**
1595
+ * Set a global access policy for connector scoping.
1596
+ * Pass null to clear the policy.
1597
+ */
1598
+ static setAccessPolicy(policy) {
1599
+ _Connector._accessPolicy = policy;
1600
+ }
1601
+ /**
1602
+ * Get the current global access policy (or null if none set).
1603
+ */
1604
+ static getAccessPolicy() {
1605
+ return _Connector._accessPolicy;
1606
+ }
1607
+ /**
1608
+ * Create a scoped (filtered) view of the connector registry.
1609
+ * Requires a global access policy to be set via setAccessPolicy().
1610
+ *
1611
+ * @param context - Opaque context passed to the policy (e.g., { userId, tenantId })
1612
+ * @returns IConnectorRegistry that only exposes accessible connectors
1613
+ * @throws Error if no access policy is set
1614
+ */
1615
+ static scoped(context) {
1616
+ if (!_Connector._accessPolicy) {
1617
+ throw new Error("No access policy set. Call Connector.setAccessPolicy() first.");
1618
+ }
1619
+ return new ScopedConnectorRegistry(_Connector._accessPolicy, context);
1620
+ }
1621
+ /**
1622
+ * Return the static Connector methods as an IConnectorRegistry object (unfiltered).
1623
+ * Useful when code accepts the interface but you want the full admin view.
1624
+ */
1625
+ static asRegistry() {
1626
+ return {
1627
+ get: (name) => _Connector.get(name),
1628
+ has: (name) => _Connector.has(name),
1629
+ list: () => _Connector.list(),
1630
+ listAll: () => _Connector.listAll(),
1631
+ size: () => _Connector.size(),
1632
+ getDescriptionsForTools: () => _Connector.getDescriptionsForTools(),
1633
+ getInfo: () => _Connector.getInfo()
1634
+ };
1635
+ }
1540
1636
  /**
1541
1637
  * Get connector descriptions formatted for tool parameters
1542
1638
  * Useful for generating dynamic tool descriptions