@microsoft/agents-hosting 1.9.0-beta.18.g6b8111bba5 → 1.9.0-beta.20.g0c48a31a21

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.
Files changed (71) hide show
  1. package/README.md +18 -10
  2. package/dist/package.json +3 -3
  3. package/dist/src/app/agentApplication.d.ts +1 -0
  4. package/dist/src/app/agentApplication.js +18 -5
  5. package/dist/src/app/agentApplication.js.map +1 -1
  6. package/dist/src/app/agentApplicationBuilder.d.ts +9 -2
  7. package/dist/src/app/agentApplicationBuilder.js +9 -0
  8. package/dist/src/app/agentApplicationBuilder.js.map +1 -1
  9. package/dist/src/app/agentApplicationOptions.d.ts +10 -4
  10. package/dist/src/app/auth/handlerStorage.d.ts +5 -3
  11. package/dist/src/app/auth/handlerStorage.js +36 -10
  12. package/dist/src/app/auth/handlerStorage.js.map +1 -1
  13. package/dist/src/app/auth/types.d.ts +2 -2
  14. package/dist/src/app/index.d.ts +1 -0
  15. package/dist/src/app/proactive/proactive.js +10 -6
  16. package/dist/src/app/proactive/proactive.js.map +1 -1
  17. package/dist/src/app/proactive/proactiveOptions.d.ts +2 -2
  18. package/dist/src/app/rateLimit.d.ts +315 -0
  19. package/dist/src/app/rateLimit.js +333 -0
  20. package/dist/src/app/rateLimit.js.map +1 -0
  21. package/dist/src/app/turnState.d.ts +6 -3
  22. package/dist/src/app/turnState.js +43 -4
  23. package/dist/src/app/turnState.js.map +1 -1
  24. package/dist/src/errorHelper.js +40 -9
  25. package/dist/src/errorHelper.js.map +1 -1
  26. package/dist/src/observability/traces.d.ts +6 -4
  27. package/dist/src/observability/traces.js +10 -9
  28. package/dist/src/observability/traces.js.map +1 -1
  29. package/dist/src/state/agentState.d.ts +8 -3
  30. package/dist/src/state/agentState.js +26 -8
  31. package/dist/src/state/agentState.js.map +1 -1
  32. package/dist/src/state/conversationState.d.ts +2 -2
  33. package/dist/src/state/conversationState.js.map +1 -1
  34. package/dist/src/state/userState.d.ts +2 -2
  35. package/dist/src/state/userState.js.map +1 -1
  36. package/dist/src/statusCodes.d.ts +5 -0
  37. package/dist/src/statusCodes.js +5 -0
  38. package/dist/src/statusCodes.js.map +1 -1
  39. package/dist/src/storage/fileStorage.d.ts +83 -71
  40. package/dist/src/storage/fileStorage.js +272 -136
  41. package/dist/src/storage/fileStorage.js.map +1 -1
  42. package/dist/src/storage/memoryStorage.d.ts +85 -62
  43. package/dist/src/storage/memoryStorage.js +240 -109
  44. package/dist/src/storage/memoryStorage.js.map +1 -1
  45. package/dist/src/storage/storage.d.ts +101 -16
  46. package/dist/src/storage/storage.js +25 -0
  47. package/dist/src/storage/storage.js.map +1 -1
  48. package/dist/src/storage/storageCompatibility.d.ts +17 -0
  49. package/dist/src/storage/storageCompatibility.js +157 -0
  50. package/dist/src/storage/storageCompatibility.js.map +1 -0
  51. package/package.json +3 -3
  52. package/src/app/agentApplication.ts +16 -0
  53. package/src/app/agentApplicationBuilder.ts +13 -2
  54. package/src/app/agentApplicationOptions.ts +11 -4
  55. package/src/app/auth/handlerStorage.ts +51 -7
  56. package/src/app/auth/types.ts +2 -2
  57. package/src/app/index.ts +7 -0
  58. package/src/app/proactive/proactive.ts +19 -9
  59. package/src/app/proactive/proactiveOptions.ts +2 -2
  60. package/src/app/rateLimit.ts +659 -0
  61. package/src/app/turnState.ts +50 -7
  62. package/src/errorHelper.ts +46 -8
  63. package/src/observability/traces.ts +8 -7
  64. package/src/state/agentState.ts +39 -13
  65. package/src/state/conversationState.ts +2 -2
  66. package/src/state/userState.ts +2 -2
  67. package/src/statusCodes.ts +6 -0
  68. package/src/storage/fileStorage.ts +289 -134
  69. package/src/storage/memoryStorage.ts +266 -109
  70. package/src/storage/storage.ts +115 -17
  71. package/src/storage/storageCompatibility.ts +185 -0
@@ -45,19 +45,6 @@ export interface StoreItems {
45
45
  */
46
46
  [key: string]: any;
47
47
  }
48
- /**
49
- * Options for writing items to storage.
50
- */
51
- export interface StorageWriteOptions {
52
- /**
53
- * Optional time to live, in seconds, for written items.
54
- *
55
- * @remarks
56
- * When set, storage providers should stop returning the written items after
57
- * this duration has elapsed. Values must be finite numbers greater than zero.
58
- */
59
- ttl?: number;
60
- }
61
48
  /**
62
49
  * A factory function to generate storage keys based on the conversation context.
63
50
  *
@@ -70,7 +57,7 @@ export interface StorageWriteOptions {
70
57
  */
71
58
  export type StorageKeyFactory = (context: TurnContext) => string | Promise<string>;
72
59
  /**
73
- * Defines the interface for storage operations in the Agents platform.
60
+ * Defines the version 1 interface for storage operations in the Agents platform.
74
61
  *
75
62
  * @remarks
76
63
  * Storage providers persist state data across conversation turns, enabling
@@ -79,7 +66,9 @@ export type StorageKeyFactory = (context: TurnContext) => string | Promise<strin
79
66
  *
80
67
  * The interface is designed to be simple with just three core operations:
81
68
  * read, write, and delete. All operations are asynchronous to support both
82
- * in-memory and remote storage providers.
69
+ * in-memory and remote storage providers. New implementations should use
70
+ * {@link StorageV2}; this V1 interface remains supported by
71
+ * {@link StorageProvider} through a compatibility adapter.
83
72
  */
84
73
  export interface Storage {
85
74
  /**
@@ -97,7 +86,7 @@ export interface Storage {
97
86
  * @returns A promise that resolves when the write operation is complete
98
87
  * @throws If the changes object is empty or undefined, or if an eTag conflict occurs and optimistic concurrency is enabled
99
88
  */
100
- write: (changes: StoreItem, options?: StorageWriteOptions) => Promise<void>;
89
+ write: (changes: StoreItem) => Promise<void>;
101
90
  /**
102
91
  * Deletes store items from storage.
103
92
  *
@@ -106,3 +95,99 @@ export interface Storage {
106
95
  */
107
96
  delete: (keys: string[]) => Promise<void>;
108
97
  }
98
+ /**
99
+ * The result of a version 2 storage read operation.
100
+ *
101
+ * A result is returned for every requested key. `value` and `version` are
102
+ * available when `status` is {@link StorageOperationStatus.Succeeded}.
103
+ */
104
+ export interface StorageReadResult<T extends object = Record<string, unknown>> {
105
+ key: string;
106
+ status: StorageOperationStatus;
107
+ value?: T;
108
+ version?: string;
109
+ }
110
+ /**
111
+ * The result of a version 2 storage write operation.
112
+ */
113
+ export interface StorageWriteResult {
114
+ key: string;
115
+ status: StorageOperationStatus;
116
+ version?: string;
117
+ }
118
+ /**
119
+ * The result of a version 2 storage delete operation.
120
+ */
121
+ export interface StorageDeleteResult {
122
+ key: string;
123
+ status: StorageOperationStatus;
124
+ version?: string;
125
+ }
126
+ /** A keyed set of storage read results. */
127
+ export type StorageReadResults<T extends object = Record<string, unknown>> = Record<string, StorageReadResult<T>>;
128
+ /** A keyed set of storage write results. */
129
+ export type StorageWriteResults = Record<string, StorageWriteResult>;
130
+ /** A keyed set of storage delete results. */
131
+ export type StorageDeleteResults = Record<string, StorageDeleteResult>;
132
+ /** The outcome of one version 2 storage operation. */
133
+ export declare enum StorageOperationStatus {
134
+ Succeeded = "succeeded",
135
+ NotFound = "notFound",
136
+ Conflict = "conflict",
137
+ ConditionNotMet = "conditionNotMet"
138
+ }
139
+ /** The write mode for a version 2 storage operation. */
140
+ export declare enum StorageWriteMode {
141
+ Upsert = "upsert",
142
+ CreateOnly = "createOnly",
143
+ Replace = "replace"
144
+ }
145
+ /** Options applied to every item in a version 2 write operation. */
146
+ export interface StorageWriteOptions {
147
+ /**
148
+ * Optional time to live, in seconds, for written items.
149
+ *
150
+ * When set, storage providers stop returning the written items after this
151
+ * duration has elapsed. Values must be finite numbers greater than zero.
152
+ */
153
+ ttl?: number;
154
+ mode?: StorageWriteMode;
155
+ expectedVersion?: string;
156
+ }
157
+ /** Options applied to every item in a version 2 delete operation. */
158
+ export interface StorageDeleteOptions {
159
+ expectedVersion?: string;
160
+ }
161
+ /**
162
+ * The version 2 storage contract.
163
+ *
164
+ * This does not extend {@link Storage}: JavaScript cannot overload methods by
165
+ * return type at runtime. V2 providers are exposed as separately named classes.
166
+ */
167
+ export declare abstract class StorageV2 {
168
+ /**
169
+ * Reads stored values and returns one result for every requested key.
170
+ *
171
+ * @param keys The keys to read. An empty array is valid.
172
+ * @returns Keyed results containing a value and storage version when found.
173
+ */
174
+ abstract read<T extends object = Record<string, unknown>>(keys: string[]): Promise<StorageReadResults<T>>;
175
+ /**
176
+ * Writes values with optional create, replace, or version conditions.
177
+ *
178
+ * @param changes Values indexed by their storage keys.
179
+ * @param options Conditions applied to every value in the batch.
180
+ * @returns One result for every supplied key.
181
+ */
182
+ abstract write<T extends object = Record<string, unknown>>(changes: Record<string, T>, options?: StorageWriteOptions): Promise<StorageWriteResults>;
183
+ /**
184
+ * Deletes values with an optional version condition.
185
+ *
186
+ * @param keys The keys to delete. An empty array is valid.
187
+ * @param options Conditions applied to every key in the batch.
188
+ * @returns One result for every supplied key.
189
+ */
190
+ abstract delete(keys: string[], options?: StorageDeleteOptions): Promise<StorageDeleteResults>;
191
+ }
192
+ /** A storage implementation supported by public hosting interfaces. */
193
+ export type StorageProvider = Storage | StorageV2;
@@ -4,4 +4,29 @@
4
4
  * Licensed under the MIT License.
5
5
  */
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.StorageV2 = exports.StorageWriteMode = exports.StorageOperationStatus = void 0;
8
+ /** The outcome of one version 2 storage operation. */
9
+ var StorageOperationStatus;
10
+ (function (StorageOperationStatus) {
11
+ StorageOperationStatus["Succeeded"] = "succeeded";
12
+ StorageOperationStatus["NotFound"] = "notFound";
13
+ StorageOperationStatus["Conflict"] = "conflict";
14
+ StorageOperationStatus["ConditionNotMet"] = "conditionNotMet";
15
+ })(StorageOperationStatus || (exports.StorageOperationStatus = StorageOperationStatus = {}));
16
+ /** The write mode for a version 2 storage operation. */
17
+ var StorageWriteMode;
18
+ (function (StorageWriteMode) {
19
+ StorageWriteMode["Upsert"] = "upsert";
20
+ StorageWriteMode["CreateOnly"] = "createOnly";
21
+ StorageWriteMode["Replace"] = "replace";
22
+ })(StorageWriteMode || (exports.StorageWriteMode = StorageWriteMode = {}));
23
+ /**
24
+ * The version 2 storage contract.
25
+ *
26
+ * This does not extend {@link Storage}: JavaScript cannot overload methods by
27
+ * return type at runtime. V2 providers are exposed as separately named classes.
28
+ */
29
+ class StorageV2 {
30
+ }
31
+ exports.StorageV2 = StorageV2;
7
32
  //# sourceMappingURL=storage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/storage.ts"],"names":[],"mappings":";AAAA;;;GAGG"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../../src/storage/storage.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AA+IH,sDAAsD;AACtD,IAAY,sBAKX;AALD,WAAY,sBAAsB;IAChC,iDAAuB,CAAA;IACvB,+CAAqB,CAAA;IACrB,+CAAqB,CAAA;IACrB,6DAAmC,CAAA;AACrC,CAAC,EALW,sBAAsB,aAAtB,sBAAsB,GAAtB,sBAAsB,QAKjC;AAED,wDAAwD;AACxD,IAAY,gBAIX;AAJD,WAAY,gBAAgB;IAC1B,qCAAiB,CAAA;IACjB,6CAAyB,CAAA;IACzB,uCAAmB,CAAA;AACrB,CAAC,EAJW,gBAAgB,aAAhB,gBAAgB,GAAhB,gBAAgB,QAI3B;AAoBD;;;;;GAKG;AACH;CA0BC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Copyright (c) Microsoft Corporation. All rights reserved.
3
+ * Licensed under the MIT License.
4
+ */
5
+ import { StorageDeleteResults, StorageProvider, StorageReadResults, StorageV2, StorageWriteResults } from './storage';
6
+ /** Returns true when a storage implementation declares the V2 contract. */
7
+ export declare function isStorageV2(storage: StorageProvider): storage is StorageV2;
8
+ /** Converts a supported storage implementation to the V2 contract. */
9
+ export declare function asStorageV2(storage: StorageProvider): StorageV2;
10
+ /** Returns a successful V2 read value, maps not-found to undefined, and rejects invalid results. */
11
+ export declare function getStorageReadValue<T extends object>(results: StorageReadResults<T> | null | undefined, key: string): T | undefined;
12
+ /** Throws when a V2 write did not succeed for every requested key. */
13
+ export declare function assertStorageWriteSucceeded(results: StorageWriteResults | null | undefined, keys: string[]): void;
14
+ /** Throws the state-specific concurrency error when a state write does not succeed. */
15
+ export declare function assertAgentStateWriteSucceeded(results: StorageWriteResults | null | undefined, key: string, name: string): void;
16
+ /** Throws when a V2 delete did not complete with idempotent V1 semantics. */
17
+ export declare function assertStorageDeleteSucceeded(results: StorageDeleteResults | null | undefined, keys: string[]): void;
@@ -0,0 +1,157 @@
1
+ "use strict";
2
+ /**
3
+ * Copyright (c) Microsoft Corporation. All rights reserved.
4
+ * Licensed under the MIT License.
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.isStorageV2 = isStorageV2;
8
+ exports.asStorageV2 = asStorageV2;
9
+ exports.getStorageReadValue = getStorageReadValue;
10
+ exports.assertStorageWriteSucceeded = assertStorageWriteSucceeded;
11
+ exports.assertAgentStateWriteSucceeded = assertAgentStateWriteSucceeded;
12
+ exports.assertStorageDeleteSucceeded = assertStorageDeleteSucceeded;
13
+ const agents_activity_1 = require("@microsoft/agents-activity");
14
+ const errorHelper_1 = require("../errorHelper");
15
+ const storage_1 = require("./storage");
16
+ /** Returns true when a storage implementation declares the V2 contract. */
17
+ function isStorageV2(storage) {
18
+ return storage instanceof storage_1.StorageV2;
19
+ }
20
+ /** Converts a supported storage implementation to the V2 contract. */
21
+ function asStorageV2(storage) {
22
+ return isStorageV2(storage) ? storage : new StorageToStorageV2Adapter(storage);
23
+ }
24
+ /** Returns a successful V2 read value, maps not-found to undefined, and rejects invalid results. */
25
+ function getStorageReadValue(results, key) {
26
+ const result = results === null || results === void 0 ? void 0 : results[key];
27
+ if ((result === null || result === void 0 ? void 0 : result.status) === storage_1.StorageOperationStatus.NotFound)
28
+ return undefined;
29
+ if ((result === null || result === void 0 ? void 0 : result.status) === storage_1.StorageOperationStatus.Succeeded)
30
+ return result.value;
31
+ throwStorageResultError('read', key, result === null || result === void 0 ? void 0 : result.status);
32
+ }
33
+ /** Adapts the legacy storage contract to version 2 where its semantics allow it. */
34
+ class StorageToStorageV2Adapter extends storage_1.StorageV2 {
35
+ constructor(storage) {
36
+ super();
37
+ this.storage = storage;
38
+ }
39
+ async read(keys) {
40
+ validateKeys(keys);
41
+ if (keys.length === 0)
42
+ return {};
43
+ const items = await this.storage.read(keys);
44
+ return Object.fromEntries(keys.map(key => {
45
+ const value = items[key];
46
+ return [key, Object.prototype.hasOwnProperty.call(items, key)
47
+ ? { key, status: storage_1.StorageOperationStatus.Succeeded, value: value, version: value === null || value === void 0 ? void 0 : value.eTag }
48
+ : { key, status: storage_1.StorageOperationStatus.NotFound }];
49
+ }));
50
+ }
51
+ async write(changes, options) {
52
+ validateChanges(changes);
53
+ if ((options === null || options === void 0 ? void 0 : options.mode) !== undefined && options.mode !== storage_1.StorageWriteMode.Upsert) {
54
+ throwUnsupportedOption('mode');
55
+ }
56
+ if ((options === null || options === void 0 ? void 0 : options.ttl) !== undefined) {
57
+ throwUnsupportedOption('ttl');
58
+ }
59
+ validateExpectedVersion(options === null || options === void 0 ? void 0 : options.expectedVersion);
60
+ if (Object.keys(changes).length === 0)
61
+ return {};
62
+ const legacyChanges = Object.fromEntries(Object.entries(changes).map(([key, value]) => [
63
+ key,
64
+ (options === null || options === void 0 ? void 0 : options.expectedVersion) === undefined
65
+ ? removeLegacyETag(value)
66
+ : { ...removeLegacyETag(value), eTag: options.expectedVersion },
67
+ ]));
68
+ await this.storage.write(legacyChanges);
69
+ return Object.fromEntries(Object.keys(changes).map(key => [key, { key, status: storage_1.StorageOperationStatus.Succeeded }]));
70
+ }
71
+ async delete(keys, options) {
72
+ validateDeleteKeys(keys);
73
+ validateExpectedVersion(options === null || options === void 0 ? void 0 : options.expectedVersion);
74
+ if ((options === null || options === void 0 ? void 0 : options.expectedVersion) !== undefined) {
75
+ throwUnsupportedOption('expectedVersion');
76
+ }
77
+ if (keys.length === 0)
78
+ return {};
79
+ await this.storage.delete(keys);
80
+ return Object.fromEntries(keys.map(key => [key, { key, status: storage_1.StorageOperationStatus.Succeeded }]));
81
+ }
82
+ }
83
+ function validateKeys(keys) {
84
+ if (!Array.isArray(keys)) {
85
+ throw agents_activity_1.ExceptionHelper.generateException(ReferenceError, errorHelper_1.Errors.StorageReadKeysRequired);
86
+ }
87
+ if (keys.some(key => typeof key !== 'string' || key.trim() === '')) {
88
+ throw agents_activity_1.ExceptionHelper.generateException(ReferenceError, errorHelper_1.Errors.StorageV2KeyRequired);
89
+ }
90
+ }
91
+ function validateDeleteKeys(keys) {
92
+ if (!Array.isArray(keys)) {
93
+ throw agents_activity_1.ExceptionHelper.generateException(ReferenceError, errorHelper_1.Errors.StorageDeleteKeysRequired);
94
+ }
95
+ if (keys.some(key => typeof key !== 'string' || key.trim() === '')) {
96
+ throw agents_activity_1.ExceptionHelper.generateException(ReferenceError, errorHelper_1.Errors.StorageV2KeyRequired);
97
+ }
98
+ }
99
+ function validateChanges(changes) {
100
+ if (changes === null || typeof changes !== 'object' || Array.isArray(changes)) {
101
+ throw agents_activity_1.ExceptionHelper.generateException(ReferenceError, errorHelper_1.Errors.StorageWriteChangesRequired);
102
+ }
103
+ if (Object.keys(changes).some(key => key.trim() === '')) {
104
+ throw agents_activity_1.ExceptionHelper.generateException(ReferenceError, errorHelper_1.Errors.StorageV2KeyRequired);
105
+ }
106
+ }
107
+ function removeLegacyETag(value) {
108
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
109
+ return value;
110
+ const { eTag: _eTag, ...withoutETag } = value;
111
+ return withoutETag;
112
+ }
113
+ function validateExpectedVersion(expectedVersion) {
114
+ if (expectedVersion === '') {
115
+ throw agents_activity_1.ExceptionHelper.generateException(RangeError, errorHelper_1.Errors.StorageV2ExpectedVersionEmpty);
116
+ }
117
+ }
118
+ function throwUnsupportedOption(option) {
119
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.StorageV2UnsupportedOption, undefined, { option });
120
+ }
121
+ /** Throws when a V2 write did not succeed for every requested key. */
122
+ function assertStorageWriteSucceeded(results, keys) {
123
+ assertStorageResults('write', results, keys, new Set([storage_1.StorageOperationStatus.Succeeded]));
124
+ }
125
+ /** Throws the state-specific concurrency error when a state write does not succeed. */
126
+ function assertAgentStateWriteSucceeded(results, key, name) {
127
+ var _a;
128
+ const status = (_a = results === null || results === void 0 ? void 0 : results[key]) === null || _a === void 0 ? void 0 : _a.status;
129
+ if (status !== storage_1.StorageOperationStatus.Succeeded) {
130
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.AgentStateWriteConflict, undefined, {
131
+ name,
132
+ key,
133
+ status: status !== null && status !== void 0 ? status : 'missing',
134
+ });
135
+ }
136
+ }
137
+ /** Throws when a V2 delete did not complete with idempotent V1 semantics. */
138
+ function assertStorageDeleteSucceeded(results, keys) {
139
+ assertStorageResults('delete', results, keys, new Set([storage_1.StorageOperationStatus.Succeeded, storage_1.StorageOperationStatus.NotFound]));
140
+ }
141
+ function assertStorageResults(operation, results, keys, acceptedStatuses) {
142
+ var _a;
143
+ for (const key of keys) {
144
+ const status = (_a = results === null || results === void 0 ? void 0 : results[key]) === null || _a === void 0 ? void 0 : _a.status;
145
+ if (status === undefined || !acceptedStatuses.has(status)) {
146
+ throwStorageResultError(operation, key, status);
147
+ }
148
+ }
149
+ }
150
+ function throwStorageResultError(operation, key, status) {
151
+ throw agents_activity_1.ExceptionHelper.generateException(Error, errorHelper_1.Errors.StorageV2OperationFailed, undefined, {
152
+ operation,
153
+ key,
154
+ status: status !== null && status !== void 0 ? status : 'missing',
155
+ });
156
+ }
157
+ //# sourceMappingURL=storageCompatibility.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storageCompatibility.js","sourceRoot":"","sources":["../../../src/storage/storageCompatibility.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package.json",
3
3
  "name": "@microsoft/agents-hosting",
4
- "version": "1.9.0-beta.18.g6b8111bba5",
4
+ "version": "1.9.0-beta.20.g0c48a31a21",
5
5
  "homepage": "https://github.com/microsoft/Agents-for-js",
6
6
  "repository": {
7
7
  "type": "git",
@@ -21,8 +21,8 @@
21
21
  "dependencies": {
22
22
  "@azure/core-auth": "1.10.1",
23
23
  "@azure/msal-node": "5.6.0",
24
- "@microsoft/agents-activity": "1.9.0-beta.18.g6b8111bba5",
25
- "@microsoft/agents-telemetry": "1.9.0-beta.18.g6b8111bba5",
24
+ "@microsoft/agents-activity": "1.9.0-beta.20.g0c48a31a21",
25
+ "@microsoft/agents-telemetry": "1.9.0-beta.20.g0c48a31a21",
26
26
  "jsonwebtoken": "9.0.3",
27
27
  "jwks-rsa": "4.0.1",
28
28
  "zod": "3.25.75"
@@ -20,6 +20,7 @@ import { TranscriptLoggerMiddleware } from '../transcript'
20
20
  import { CloudAdapter } from '../cloudAdapter'
21
21
  import { Authorization, UserAuthorization, AuthorizationManager } from './auth'
22
22
  import { Proactive } from './proactive'
23
+ import { AgentApplicationRateLimiter } from './rateLimit'
23
24
  import { JwtPayload } from 'jsonwebtoken'
24
25
  import { trace, debug, redactString } from '@microsoft/agents-telemetry'
25
26
  import { AgentApplicationTraceDefinitions } from '../observability'
@@ -104,6 +105,7 @@ export class AgentApplication<TState extends TurnState> {
104
105
  private readonly _proactive?: Proactive<TState>
105
106
  protected readonly _extensions: AgentExtension<TState>[] = []
106
107
  private readonly _adaptiveCards: AdaptiveCardsActions<TState>
108
+ private readonly _rateLimiter?: AgentApplicationRateLimiter
107
109
 
108
110
  /**
109
111
  * Creates a new instance of AgentApplication.
@@ -141,6 +143,7 @@ export class AgentApplication<TState extends TurnState> {
141
143
  longRunningMessages: options?.longRunningMessages !== undefined ? options.longRunningMessages : false,
142
144
  removeRecipientMention: options?.removeRecipientMention !== undefined ? options.removeRecipientMention : true,
143
145
  transcriptLogger: options?.transcriptLogger || undefined,
146
+ rateLimit: options?.rateLimit || undefined,
144
147
  }
145
148
 
146
149
  this._adaptiveCards = new AdaptiveCardsActions<TState>(this)
@@ -158,6 +161,10 @@ export class AgentApplication<TState extends TurnState> {
158
161
 
159
162
  this._adapter.setAgentName(this._options.agentName)
160
163
 
164
+ if (this._options.rateLimit && this._options.rateLimit.length > 0) {
165
+ this._rateLimiter = new AgentApplicationRateLimiter(this._options.rateLimit, this._options.storage)
166
+ }
167
+
161
168
  // Create Proactive whenever proactive options are explicitly configured or a storage
162
169
  // backend is available — no explicit `proactive` option is required.
163
170
  if (this._options.proactive !== undefined || this._options.storage !== undefined) {
@@ -206,6 +213,7 @@ export class AgentApplication<TState extends TurnState> {
206
213
  fileDownloaders: this._options.fileDownloaders ? 'configured' : undefined,
207
214
  turnStateFactory: options?.turnStateFactory ? 'custom' : 'default',
208
215
  adaptiveCardsOptions: this._options.adaptiveCardsOptions,
216
+ rateLimitRules: this._options.rateLimit?.length,
209
217
  })
210
218
  }
211
219
 
@@ -672,6 +680,14 @@ export class AgentApplication<TState extends TurnState> {
672
680
  * ```
673
681
  */
674
682
  public async runInternal (turnContext: TurnContext): Promise<boolean> {
683
+ if (this._rateLimiter) {
684
+ const rateLimitDecision = await this._rateLimiter.shouldAllowTurn(turnContext)
685
+ if (!rateLimitDecision.allowed) {
686
+ await this._rateLimiter.handleThrottledTurn(turnContext, rateLimitDecision.rule!, rateLimitDecision.result!)
687
+ return false
688
+ }
689
+ }
690
+
675
691
  const { authorized, context } = await this.handleAuthorization(turnContext)
676
692
 
677
693
  if (!authorized) {
@@ -3,11 +3,12 @@
3
3
  * Licensed under the MIT License.
4
4
  */
5
5
 
6
- import { Storage } from '../storage'
6
+ import { StorageProvider } from '../storage'
7
7
  import { AgentApplication } from './agentApplication'
8
8
  import { AgentApplicationOptions } from './agentApplicationOptions'
9
9
  import { AuthorizationOptions } from './auth/types'
10
10
  import { ProactiveOptions } from './proactive'
11
+ import { RateLimitRule } from './rateLimit'
11
12
  import { TurnState } from './turnState'
12
13
  import { TypingOptions } from './agentApplicationOptions'
13
14
 
@@ -31,7 +32,7 @@ export class AgentApplicationBuilder<TState extends TurnState = TurnState> {
31
32
  * @param storage The storage implementation to use
32
33
  * @returns This builder instance for chaining
33
34
  */
34
- public withStorage (storage: Storage): this {
35
+ public withStorage (storage: StorageProvider): this {
35
36
  this._options.storage = storage
36
37
  return this
37
38
  }
@@ -86,6 +87,16 @@ export class AgentApplicationBuilder<TState extends TurnState = TurnState> {
86
87
  return this
87
88
  }
88
89
 
90
+ /**
91
+ * Configures rate limit rules for incoming turns.
92
+ * @param rules The rate limit rules to apply
93
+ * @returns This builder instance for chaining
94
+ */
95
+ public withRateLimit (rules: RateLimitRule[]): this {
96
+ this._options.rateLimit = rules
97
+ return this
98
+ }
99
+
89
100
  /**
90
101
  * Builds and returns a new AgentApplication instance configured with the provided options.
91
102
  * @returns A new AgentApplication instance
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { CloudAdapter } from '../cloudAdapter'
7
- import { Storage } from '../storage'
7
+ import { StorageProvider } from '../storage'
8
8
  import { TranscriptLogger } from '../transcript'
9
9
  import { AdaptiveCardsOptions } from './adaptiveCards'
10
10
  import { InputFileDownloader } from './inputFileDownloader'
@@ -13,6 +13,7 @@ import { HeaderPropagationDefinition } from '../headerPropagation'
13
13
  import { AuthorizationOptions } from './auth/types'
14
14
  import { Connections } from '../auth/connections'
15
15
  import { ProactiveOptions } from './proactive'
16
+ import { RateLimitRule } from './rateLimit'
16
17
  import { ConfigurationContext } from '../configuration/configuration'
17
18
 
18
19
  /**
@@ -79,12 +80,12 @@ export interface AgentApplicationOptions<TState extends TurnState> {
79
80
 
80
81
  /**
81
82
  * The storage mechanism for persisting conversation and user state across turns.
82
- * This can be any implementation of the Storage interface, such as memory storage
83
- * for development or blob storage for production scenarios.
83
+ * This can be a legacy Storage implementation, a StorageV2 implementation,
84
+ * or a built-in storage provider.
84
85
  *
85
86
  * @default undefined (no persistence)
86
87
  */
87
- storage?: Storage;
88
+ storage?: StorageProvider;
88
89
 
89
90
  /**
90
91
  * Whether to start a typing indicator timer when the bot begins processing a message.
@@ -208,4 +209,10 @@ export interface AgentApplicationOptions<TState extends TurnState> {
208
209
  * When provided, `app.proactive` will be available.
209
210
  */
210
211
  proactive?: ProactiveOptions
212
+
213
+ /**
214
+ * Optional. Rate limit rules for incoming turns.
215
+ * When omitted or empty, no rate limiting is applied.
216
+ */
217
+ rateLimit?: RateLimitRule[]
211
218
  }
@@ -5,10 +5,19 @@
5
5
 
6
6
  import { ActiveAuthorizationHandler } from './types'
7
7
  import { TurnContext } from '../../turnContext'
8
- import { Storage } from '../../storage'
8
+ import { StorageProvider, StorageV2 } from '../../storage'
9
+ import {
10
+ asStorageV2,
11
+ assertStorageDeleteSucceeded,
12
+ assertStorageWriteSucceeded,
13
+ getStorageReadValue,
14
+ } from '../../storage/storageCompatibility'
9
15
  import { ExceptionHelper } from '@microsoft/agents-activity'
10
16
  import { Errors } from '../../errorHelper'
11
17
 
18
+ // Version metadata only bridges reads and writes in one turn. Cloned contexts share turnState.
19
+ const HANDLER_STORAGE_VERSIONS = Symbol('handlerStorageVersions')
20
+
12
21
  /**
13
22
  * Storage manager for handler state.
14
23
  */
@@ -18,7 +27,11 @@ export class HandlerStorage<TActiveHandler extends ActiveAuthorizationHandler =
18
27
  * @param storage The storage provider.
19
28
  * @param context The turn context.
20
29
  */
21
- constructor (private storage: Storage, private context: TurnContext) { }
30
+ private readonly storage: StorageV2
31
+
32
+ constructor (storage: StorageProvider, private context: TurnContext) {
33
+ this.storage = asStorageV2(storage)
34
+ }
22
35
 
23
36
  /**
24
37
  * Gets the unique key for a handler session.
@@ -36,15 +49,23 @@ export class HandlerStorage<TActiveHandler extends ActiveAuthorizationHandler =
36
49
  * Reads the active handler state from storage.
37
50
  */
38
51
  public async read (): Promise<TActiveHandler | undefined> {
39
- const ongoing = await this.storage.read([this.key])
40
- return ongoing?.[this.key]
52
+ const ongoing = await this.storage.read<TActiveHandler>([this.key])
53
+ const value = getStorageReadValue(ongoing, this.key)
54
+ this.version = ongoing[this.key]?.version
55
+ return value
41
56
  }
42
57
 
43
58
  /**
44
59
  * Writes handler state to storage.
45
60
  */
46
- public write (data: TActiveHandler) : Promise<void> {
47
- return this.storage.write({ [this.key]: data })
61
+ public async write (data: TActiveHandler) : Promise<void> {
62
+ const { eTag: _eTag, ...value } = data
63
+ const results = await this.storage.write(
64
+ { [this.key]: value },
65
+ this.version === undefined ? undefined : { expectedVersion: this.version }
66
+ )
67
+ assertStorageWriteSucceeded(results, [this.key])
68
+ this.version = results[this.key]?.version
48
69
  }
49
70
 
50
71
  /**
@@ -52,7 +73,9 @@ export class HandlerStorage<TActiveHandler extends ActiveAuthorizationHandler =
52
73
  */
53
74
  public async delete (): Promise<void> {
54
75
  try {
55
- await this.storage.delete([this.key])
76
+ const results = await this.storage.delete([this.key])
77
+ assertStorageDeleteSucceeded(results, [this.key])
78
+ this.version = undefined
56
79
  } catch (error) {
57
80
  if (error instanceof Error && 'code' in error && error.code === 404) {
58
81
  return
@@ -60,4 +83,25 @@ export class HandlerStorage<TActiveHandler extends ActiveAuthorizationHandler =
60
83
  throw error
61
84
  }
62
85
  }
86
+
87
+ private get version (): string | undefined {
88
+ return this.context.turnState.get<Map<string, string>>(HANDLER_STORAGE_VERSIONS)?.get(this.key)
89
+ }
90
+
91
+ private set version (value: string | undefined) {
92
+ let versions = this.context.turnState.get<Map<string, string>>(HANDLER_STORAGE_VERSIONS)
93
+ if (value === undefined) {
94
+ versions?.delete(this.key)
95
+ if (versions?.size === 0) {
96
+ this.context.turnState.delete(HANDLER_STORAGE_VERSIONS)
97
+ }
98
+ return
99
+ }
100
+
101
+ if (!versions) {
102
+ versions = new Map<string, string>()
103
+ this.context.turnState.set(HANDLER_STORAGE_VERSIONS, versions)
104
+ }
105
+ versions.set(this.key, value)
106
+ }
63
107
  }
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { Activity } from '@microsoft/agents-activity'
7
- import { Storage, StoreItem } from '../../storage'
7
+ import { StorageProvider, StoreItem } from '../../storage'
8
8
  import { TurnContext } from '../../turnContext'
9
9
  import { AgenticAuthorizationOptions, AzureBotAuthorizationOptions } from './handlers'
10
10
  import { TokenResponse } from '../../oauth'
@@ -97,7 +97,7 @@ export interface AuthorizationHandlerSettings {
97
97
  /**
98
98
  * Storage instance for persisting handler state.
99
99
  */
100
- storage: Storage
100
+ storage: StorageProvider
101
101
  /**
102
102
  * Connections instance for managing authentication connections.
103
103
  */
package/src/app/index.ts CHANGED
@@ -28,3 +28,10 @@ export * from './streaming/streamingResponse'
28
28
  export * from './streaming/citation'
29
29
  export * from './teamsAttachmentDownloader'
30
30
  export * from './proactive'
31
+ export type {
32
+ RateLimitMessageFactory,
33
+ RateLimitResult,
34
+ RateLimitRule,
35
+ RateLimitScope,
36
+ RateLimitStorageErrorBehavior
37
+ } from './rateLimit'