ankka 0.10.0 → 0.12.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.
Files changed (94) hide show
  1. package/README.md +1 -0
  2. package/dist/_proto/ankka/protocol/v1/agent_pb.d.ts +35 -0
  3. package/dist/_proto/ankka/protocol/v1/agent_pb.js +8 -1
  4. package/dist/_proto/ankka/protocol/v1/client_pb.d.ts +858 -2
  5. package/dist/_proto/ankka/protocol/v1/client_pb.js +184 -9
  6. package/dist/_proto/ankka/protocol/v1/consumer_pb.d.ts +10 -1
  7. package/dist/_proto/ankka/protocol/v1/consumer_pb.js +1 -1
  8. package/dist/_proto/ankka/protocol/v1/discovery_pb.d.ts +373 -0
  9. package/dist/_proto/ankka/protocol/v1/discovery_pb.js +81 -16
  10. package/dist/_proto/ankka/protocol/v1/endpoint_pb.d.ts +210 -0
  11. package/dist/_proto/ankka/protocol/v1/endpoint_pb.js +35 -5
  12. package/dist/_proto/ankka/protocol/v1/event_sourced_pb.d.ts +86 -0
  13. package/dist/_proto/ankka/protocol/v1/event_sourced_pb.js +11 -1
  14. package/dist/_proto/ankka/protocol/v1/payload_pb.d.ts +61 -0
  15. package/dist/_proto/ankka/protocol/v1/payload_pb.js +18 -1
  16. package/dist/_proto/ankka/protocol/v1/view_pb.d.ts +70 -1
  17. package/dist/_proto/ankka/protocol/v1/view_pb.js +11 -1
  18. package/dist/_proto/ankka/protocol/v1/wasm_pb.d.ts +12 -0
  19. package/dist/_proto/ankka/protocol/v1/wasm_pb.js +1 -1
  20. package/dist/_proto/ankka/protocol/v1/workflow_pb.d.ts +7 -0
  21. package/dist/_proto/ankka/protocol/v1/workflow_pb.js +1 -1
  22. package/dist/agent.d.ts +15 -1
  23. package/dist/agent.js +20 -0
  24. package/dist/approvals.d.ts +47 -0
  25. package/dist/approvals.js +57 -0
  26. package/dist/autonomous.d.ts +23 -1
  27. package/dist/autonomous.js +30 -1
  28. package/dist/client.d.ts +188 -7
  29. package/dist/client.js +490 -21
  30. package/dist/consumer.d.ts +42 -3
  31. package/dist/consumer.js +35 -1
  32. package/dist/context.d.ts +29 -1
  33. package/dist/context.js +5 -2
  34. package/dist/contract.d.ts +40 -0
  35. package/dist/contract.js +60 -0
  36. package/dist/effects/common.d.ts +7 -0
  37. package/dist/effects/common.js +9 -1
  38. package/dist/effects/eventSourced.d.ts +26 -1
  39. package/dist/effects/eventSourced.js +58 -5
  40. package/dist/effects/keyed.d.ts +33 -0
  41. package/dist/effects/keyed.js +41 -0
  42. package/dist/endpoint.d.ts +10 -1
  43. package/dist/endpoint.js +20 -0
  44. package/dist/eventSourcedEntity.d.ts +8 -3
  45. package/dist/graph.d.ts +24 -2
  46. package/dist/graph.js +27 -1
  47. package/dist/handlers.d.ts +10 -2
  48. package/dist/handlers.js +6 -2
  49. package/dist/index.d.ts +15 -6
  50. package/dist/index.js +12 -3
  51. package/dist/keyedView.d.ts +59 -0
  52. package/dist/keyedView.js +73 -0
  53. package/dist/kinds.js +2 -0
  54. package/dist/mcp.d.ts +57 -0
  55. package/dist/mcp.js +64 -0
  56. package/dist/routes.d.ts +44 -4
  57. package/dist/routes.js +43 -4
  58. package/dist/server/agent.js +12 -4
  59. package/dist/server/discovery.d.ts +17 -1
  60. package/dist/server/discovery.js +182 -1
  61. package/dist/server/eventSourced.d.ts +4 -1
  62. package/dist/server/eventSourced.js +24 -6
  63. package/dist/server/http.d.ts +2 -1
  64. package/dist/server/http.js +80 -4
  65. package/dist/server/stateless.js +42 -3
  66. package/dist/server/workflow.js +5 -1
  67. package/dist/service.d.ts +46 -2
  68. package/dist/service.js +235 -15
  69. package/dist/services.d.ts +137 -0
  70. package/dist/services.js +259 -0
  71. package/dist/socket.d.ts +15 -0
  72. package/dist/socket.js +25 -0
  73. package/dist/spec.d.ts +1 -1
  74. package/dist/spec.js +94 -15
  75. package/dist/standing.d.ts +18 -0
  76. package/dist/standing.js +26 -0
  77. package/dist/startFrom.d.ts +36 -0
  78. package/dist/startFrom.js +51 -0
  79. package/dist/testkit/index.d.ts +2 -2
  80. package/dist/testkit/index.js +1 -1
  81. package/dist/testkit/integration.js +5 -0
  82. package/dist/testkit/kinds.d.ts +50 -5
  83. package/dist/testkit/kinds.js +208 -35
  84. package/dist/testkit/unit.d.ts +41 -3
  85. package/dist/testkit/unit.js +87 -10
  86. package/dist/timedAction.d.ts +17 -2
  87. package/dist/timedAction.js +33 -1
  88. package/dist/version.d.ts +1 -1
  89. package/dist/version.js +1 -1
  90. package/dist/view.d.ts +48 -1
  91. package/dist/view.js +18 -1
  92. package/dist/workflow.d.ts +18 -1
  93. package/dist/workflow.js +39 -0
  94. package/package.json +3 -2
@@ -1,5 +1,5 @@
1
1
  import type { GenFile, GenMessage, GenService } from "@bufbuild/protobuf/codegenv2";
2
- import type { Empty, Metadata, Payload } from "./payload_pb.ts";
2
+ import type { Empty, Metadata, Payload, WorkflowStanding } from "./payload_pb.ts";
3
3
  import type { Message } from "@bufbuild/protobuf";
4
4
  /**
5
5
  * Describes the file ankka/protocol/v1/view.proto.
@@ -37,6 +37,18 @@ export type ViewRequest = Message<"ankka.protocol.v1.ViewRequest"> & {
37
37
  * @generated from field: bool deleted = 5;
38
38
  */
39
39
  deleted: boolean;
40
+ /**
41
+ * 1.13: a keyed view: the component this change is from. A keyed view is sent no `row`
42
+ *
43
+ * @generated from field: optional string source_id = 6;
44
+ */
45
+ sourceId?: string | undefined;
46
+ /**
47
+ * 1.16: a change from a workflow source: where it stood once the effect was applied
48
+ *
49
+ * @generated from field: optional ankka.protocol.v1.WorkflowStanding standing = 7;
50
+ */
51
+ standing?: WorkflowStanding | undefined;
40
52
  };
41
53
  /**
42
54
  * Describes the message ankka.protocol.v1.ViewRequest.
@@ -68,6 +80,14 @@ export type ViewEffect = Message<"ankka.protocol.v1.ViewEffect"> & {
68
80
  */
69
81
  value: Empty;
70
82
  case: "ignore";
83
+ } | {
84
+ /**
85
+ * 1.13: a keyed view's answer; empty is nothing
86
+ *
87
+ * @generated from field: ankka.protocol.v1.RowChanges rows = 4;
88
+ */
89
+ value: RowChanges;
90
+ case: "rows";
71
91
  } | {
72
92
  case: undefined;
73
93
  value?: undefined;
@@ -78,6 +98,55 @@ export type ViewEffect = Message<"ankka.protocol.v1.ViewEffect"> & {
78
98
  * Use `create(ViewEffectSchema)` to create a new message.
79
99
  */
80
100
  export declare const ViewEffectSchema: GenMessage<ViewEffect>;
101
+ /**
102
+ * 1.13: the rows one change writes and deletes, in order; a later change to a key wins.
103
+ *
104
+ * @generated from message ankka.protocol.v1.RowChanges
105
+ */
106
+ export type RowChanges = Message<"ankka.protocol.v1.RowChanges"> & {
107
+ /**
108
+ * @generated from field: repeated ankka.protocol.v1.RowChange changes = 1;
109
+ */
110
+ changes: RowChange[];
111
+ };
112
+ /**
113
+ * Describes the message ankka.protocol.v1.RowChanges.
114
+ * Use `create(RowChangesSchema)` to create a new message.
115
+ */
116
+ export declare const RowChangesSchema: GenMessage<RowChanges>;
117
+ /**
118
+ * @generated from message ankka.protocol.v1.RowChange
119
+ */
120
+ export type RowChange = Message<"ankka.protocol.v1.RowChange"> & {
121
+ /**
122
+ * @generated from field: string key = 1;
123
+ */
124
+ key: string;
125
+ /**
126
+ * @generated from oneof ankka.protocol.v1.RowChange.change
127
+ */
128
+ change: {
129
+ /**
130
+ * @generated from field: ankka.protocol.v1.Payload upsert = 2;
131
+ */
132
+ value: Payload;
133
+ case: "upsert";
134
+ } | {
135
+ /**
136
+ * @generated from field: ankka.protocol.v1.Empty delete = 3;
137
+ */
138
+ value: Empty;
139
+ case: "delete";
140
+ } | {
141
+ case: undefined;
142
+ value?: undefined;
143
+ };
144
+ };
145
+ /**
146
+ * Describes the message ankka.protocol.v1.RowChange.
147
+ * Use `create(RowChangeSchema)` to create a new message.
148
+ */
149
+ export declare const RowChangeSchema: GenMessage<RowChange>;
81
150
  /**
82
151
  * @generated from service ankka.protocol.v1.View
83
152
  */
@@ -6,7 +6,7 @@ import { file_ankka_protocol_v1_payload } from "./payload_pb.js";
6
6
  /**
7
7
  * Describes the file ankka/protocol/v1/view.proto.
8
8
  */
9
- export const file_ankka_protocol_v1_view = /*@__PURE__*/ fileDesc("ChxhbmtrYS9wcm90b2NvbC92MS92aWV3LnByb3RvEhFhbmtrYS5wcm90b2NvbC52MSLEAQoLVmlld1JlcXVlc3QSFAoMY29tcG9uZW50X2lkGAEgASgJEikKBWV2ZW50GAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZBItCghtZXRhZGF0YRgDIAEoCzIbLmFua2thLnByb3RvY29sLnYxLk1ldGFkYXRhEiwKA3JvdxgEIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBARIPCgdkZWxldGVkGAUgASgIQgYKBF9yb3cipAEKClZpZXdFZmZlY3QSMAoKdXBkYXRlX3JvdxgBIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIABIuCgpkZWxldGVfcm93GAIgASgLMhguYW5ra2EucHJvdG9jb2wudjEuRW1wdHlIABIqCgZpZ25vcmUYAyABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAQggKBmVmZmVjdDJPCgRWaWV3EkcKBkhhbmRsZRIeLmFua2thLnByb3RvY29sLnYxLlZpZXdSZXF1ZXN0Gh0uYW5ra2EucHJvdG9jb2wudjEuVmlld0VmZmVjdGIGcHJvdG8z", [file_ankka_protocol_v1_payload]);
9
+ export const file_ankka_protocol_v1_view = /*@__PURE__*/ fileDesc("ChxhbmtrYS9wcm90b2NvbC92MS92aWV3LnByb3RvEhFhbmtrYS5wcm90b2NvbC52MSKzAgoLVmlld1JlcXVlc3QSFAoMY29tcG9uZW50X2lkGAEgASgJEikKBWV2ZW50GAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZBItCghtZXRhZGF0YRgDIAEoCzIbLmFua2thLnByb3RvY29sLnYxLk1ldGFkYXRhEiwKA3JvdxgEIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBARIPCgdkZWxldGVkGAUgASgIEhYKCXNvdXJjZV9pZBgGIAEoCUgBiAEBEjoKCHN0YW5kaW5nGAcgASgLMiMuYW5ra2EucHJvdG9jb2wudjEuV29ya2Zsb3dTdGFuZGluZ0gCiAEBQgYKBF9yb3dCDAoKX3NvdXJjZV9pZEILCglfc3RhbmRpbmci0wEKClZpZXdFZmZlY3QSMAoKdXBkYXRlX3JvdxgBIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIABIuCgpkZWxldGVfcm93GAIgASgLMhguYW5ra2EucHJvdG9jb2wudjEuRW1wdHlIABIqCgZpZ25vcmUYAyABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAEi0KBHJvd3MYBCABKAsyHS5hbmtrYS5wcm90b2NvbC52MS5Sb3dDaGFuZ2VzSABCCAoGZWZmZWN0IjsKClJvd0NoYW5nZXMSLQoHY2hhbmdlcxgBIAMoCzIcLmFua2thLnByb3RvY29sLnYxLlJvd0NoYW5nZSJ8CglSb3dDaGFuZ2USCwoDa2V5GAEgASgJEiwKBnVwc2VydBgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIABIqCgZkZWxldGUYAyABKAsyGC5hbmtrYS5wcm90b2NvbC52MS5FbXB0eUgAQggKBmNoYW5nZTJPCgRWaWV3EkcKBkhhbmRsZRIeLmFua2thLnByb3RvY29sLnYxLlZpZXdSZXF1ZXN0Gh0uYW5ra2EucHJvdG9jb2wudjEuVmlld0VmZmVjdGIGcHJvdG8z", [file_ankka_protocol_v1_payload]);
10
10
  /**
11
11
  * Describes the message ankka.protocol.v1.ViewRequest.
12
12
  * Use `create(ViewRequestSchema)` to create a new message.
@@ -17,6 +17,16 @@ export const ViewRequestSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v
17
17
  * Use `create(ViewEffectSchema)` to create a new message.
18
18
  */
19
19
  export const ViewEffectSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_view, 1);
20
+ /**
21
+ * Describes the message ankka.protocol.v1.RowChanges.
22
+ * Use `create(RowChangesSchema)` to create a new message.
23
+ */
24
+ export const RowChangesSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_view, 2);
25
+ /**
26
+ * Describes the message ankka.protocol.v1.RowChange.
27
+ * Use `create(RowChangeSchema)` to create a new message.
28
+ */
29
+ export const RowChangeSchema = /*@__PURE__*/ messageDesc(file_ankka_protocol_v1_view, 3);
20
30
  /**
21
31
  * @generated from service ankka.protocol.v1.View
22
32
  */
@@ -167,6 +167,18 @@ export type FoldRequest = Message<"ankka.protocol.v1.FoldRequest"> & {
167
167
  * @generated from field: int64 sequence = 5;
168
168
  */
169
169
  sequence: bigint;
170
+ /**
171
+ * 1.19: where the event was written; empty when none is named
172
+ *
173
+ * @generated from field: string installation = 6;
174
+ */
175
+ installation: string;
176
+ /**
177
+ * 1.19: written at another installation than this one
178
+ *
179
+ * @generated from field: bool mirrored = 7;
180
+ */
181
+ mirrored: boolean;
170
182
  };
171
183
  /**
172
184
  * Describes the message ankka.protocol.v1.FoldRequest.
@@ -14,7 +14,7 @@ import { file_ankka_protocol_v1_client } from "./client_pb.js";
14
14
  /**
15
15
  * Describes the file ankka/protocol/v1/wasm.proto.
16
16
  */
17
- export const file_ankka_protocol_v1_wasm = /*@__PURE__*/ fileDesc("ChxhbmtrYS9wcm90b2NvbC92MS93YXNtLnByb3RvEhFhbmtrYS5wcm90b2NvbC52MSJYCghXYXNtU3BlYxIlCgRzcGVjGAEgASgLMhcuYW5ra2EucHJvdG9jb2wudjEuU3BlYxIQCghzdGF0ZWZ1bBgCIAMoCRITCgthYmlfdmVyc2lvbhgDIAEoCSLfAgoNSGFuZGxlUmVxdWVzdBIlCgRraW5kGAEgASgOMhcuYW5ra2EucHJvdG9jb2wudjEuS2luZBIUCgxjb21wb25lbnRfaWQYAiABKAkSEQoJZW50aXR5X2lkGAMgASgJEi4KBXN0YXRlGAQgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgBiAEBEkIKDWV2ZW50X3NvdXJjZWQYCiABKAsyKS5hbmtrYS5wcm90b2NvbC52MS5FdmVudFNvdXJjZWRJbi5Db21tYW5kSAASOgoJa2V5X3ZhbHVlGAsgASgLMiUuYW5ra2EucHJvdG9jb2wudjEuS2V5VmFsdWVJbi5Db21tYW5kSAASOQoId29ya2Zsb3cYDCABKAsyJS5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0luLkNvbW1hbmRIAEIJCgdjb21tYW5kQggKBl9zdGF0ZSLGAgoLSGFuZGxlUmVwbHkSQQoNZXZlbnRfc291cmNlZBgKIAEoCzIoLmFua2thLnByb3RvY29sLnYxLkV2ZW50U291cmNlZE91dC5SZXBseUgAEjkKCWtleV92YWx1ZRgLIAEoCzIkLmFua2thLnByb3RvY29sLnYxLktleVZhbHVlT3V0LlJlcGx5SAASOAoId29ya2Zsb3cYDCABKAsyJC5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd091dC5SZXBseUgAEi4KBXN0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgBiAEBEjAKB2ZhaWx1cmUYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5GYWlsdXJlSAKIAQFCBwoFcmVwbHlCCAoGX3N0YXRlQgoKCF9mYWlsdXJlIq0BCgtGb2xkUmVxdWVzdBIUCgxjb21wb25lbnRfaWQYASABKAkSEQoJZW50aXR5X2lkGAIgASgJEi4KBXN0YXRlGAMgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEikKBWV2ZW50GAQgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZBIQCghzZXF1ZW5jZRgFIAEoA0IICgZfc3RhdGUidAoJRm9sZFJlcGx5EikKBXN0YXRlGAEgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZBIwCgdmYWlsdXJlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuRmFpbHVyZUgAiAEBQgoKCF9mYWlsdXJlIqkBCgtTdGVwUmVxdWVzdBIUCgxjb21wb25lbnRfaWQYASABKAkSEQoJZW50aXR5X2lkGAIgASgJEi4KBXN0YXRlGAMgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEjcKCHJ1bl9zdGVwGAQgASgLMiUuYW5ra2EucHJvdG9jb2wudjEuV29ya2Zsb3dJbi5SdW5TdGVwQggKBl9zdGF0ZSK8AQoJU3RlcFJlcGx5EjcKBXJlcGx5GAEgASgLMiguYW5ra2EucHJvdG9jb2wudjEuV29ya2Zsb3dPdXQuU3RlcFJlcGx5Ei4KBXN0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEjAKB2ZhaWx1cmUYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5GYWlsdXJlSAGIAQFCCAoGX3N0YXRlQgoKCF9mYWlsdXJlIjQKCVBhc3NpdmF0ZRIUCgxjb21wb25lbnRfaWQYASABKAkSEQoJZW50aXR5X2lkGAIgASgJIh0KDUNvbmZpZ1JlcXVlc3QSDAoEbmFtZRgBIAEoCSIrCgtDb25maWdSZXBseRISCgV2YWx1ZRgBIAEoCUgAiAEBQggKBl92YWx1ZSI+CgxTdHJlYW1Ub2tlbnMSLgoGdG9rZW5zGAEgAygLMh4uYW5ra2EucHJvdG9jb2wudjEuU3RyZWFtVG9rZW5iBnByb3RvMw", [file_ankka_protocol_v1_payload, file_ankka_protocol_v1_discovery, file_ankka_protocol_v1_event_sourced, file_ankka_protocol_v1_key_value, file_ankka_protocol_v1_workflow, file_ankka_protocol_v1_client]);
17
+ export const file_ankka_protocol_v1_wasm = /*@__PURE__*/ fileDesc("ChxhbmtrYS9wcm90b2NvbC92MS93YXNtLnByb3RvEhFhbmtrYS5wcm90b2NvbC52MSJYCghXYXNtU3BlYxIlCgRzcGVjGAEgASgLMhcuYW5ra2EucHJvdG9jb2wudjEuU3BlYxIQCghzdGF0ZWZ1bBgCIAMoCRITCgthYmlfdmVyc2lvbhgDIAEoCSLfAgoNSGFuZGxlUmVxdWVzdBIlCgRraW5kGAEgASgOMhcuYW5ra2EucHJvdG9jb2wudjEuS2luZBIUCgxjb21wb25lbnRfaWQYAiABKAkSEQoJZW50aXR5X2lkGAMgASgJEi4KBXN0YXRlGAQgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgBiAEBEkIKDWV2ZW50X3NvdXJjZWQYCiABKAsyKS5hbmtrYS5wcm90b2NvbC52MS5FdmVudFNvdXJjZWRJbi5Db21tYW5kSAASOgoJa2V5X3ZhbHVlGAsgASgLMiUuYW5ra2EucHJvdG9jb2wudjEuS2V5VmFsdWVJbi5Db21tYW5kSAASOQoId29ya2Zsb3cYDCABKAsyJS5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0luLkNvbW1hbmRIAEIJCgdjb21tYW5kQggKBl9zdGF0ZSLGAgoLSGFuZGxlUmVwbHkSQQoNZXZlbnRfc291cmNlZBgKIAEoCzIoLmFua2thLnByb3RvY29sLnYxLkV2ZW50U291cmNlZE91dC5SZXBseUgAEjkKCWtleV92YWx1ZRgLIAEoCzIkLmFua2thLnByb3RvY29sLnYxLktleVZhbHVlT3V0LlJlcGx5SAASOAoId29ya2Zsb3cYDCABKAsyJC5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd091dC5SZXBseUgAEi4KBXN0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgBiAEBEjAKB2ZhaWx1cmUYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5GYWlsdXJlSAKIAQFCBwoFcmVwbHlCCAoGX3N0YXRlQgoKCF9mYWlsdXJlItUBCgtGb2xkUmVxdWVzdBIUCgxjb21wb25lbnRfaWQYASABKAkSEQoJZW50aXR5X2lkGAIgASgJEi4KBXN0YXRlGAMgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEikKBWV2ZW50GAQgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZBIQCghzZXF1ZW5jZRgFIAEoAxIUCgxpbnN0YWxsYXRpb24YBiABKAkSEAoIbWlycm9yZWQYByABKAhCCAoGX3N0YXRlInQKCUZvbGRSZXBseRIpCgVzdGF0ZRgBIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWQSMAoHZmFpbHVyZRgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLkZhaWx1cmVIAIgBAUIKCghfZmFpbHVyZSKpAQoLU3RlcFJlcXVlc3QSFAoMY29tcG9uZW50X2lkGAEgASgJEhEKCWVudGl0eV9pZBgCIAEoCRIuCgVzdGF0ZRgDIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBARI3CghydW5fc3RlcBgEIAEoCzIlLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4uUnVuU3RlcEIICgZfc3RhdGUivAEKCVN0ZXBSZXBseRI3CgVyZXBseRgBIAEoCzIoLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93T3V0LlN0ZXBSZXBseRIuCgVzdGF0ZRgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBARIwCgdmYWlsdXJlGAMgASgLMhouYW5ra2EucHJvdG9jb2wudjEuRmFpbHVyZUgBiAEBQggKBl9zdGF0ZUIKCghfZmFpbHVyZSI0CglQYXNzaXZhdGUSFAoMY29tcG9uZW50X2lkGAEgASgJEhEKCWVudGl0eV9pZBgCIAEoCSIdCg1Db25maWdSZXF1ZXN0EgwKBG5hbWUYASABKAkiKwoLQ29uZmlnUmVwbHkSEgoFdmFsdWUYASABKAlIAIgBAUIICgZfdmFsdWUiPgoMU3RyZWFtVG9rZW5zEi4KBnRva2VucxgBIAMoCzIeLmFua2thLnByb3RvY29sLnYxLlN0cmVhbVRva2VuYgZwcm90bzM", [file_ankka_protocol_v1_payload, file_ankka_protocol_v1_discovery, file_ankka_protocol_v1_event_sourced, file_ankka_protocol_v1_key_value, file_ankka_protocol_v1_workflow, file_ankka_protocol_v1_client]);
18
18
  /**
19
19
  * Describes the message ankka.protocol.v1.WasmSpec.
20
20
  * Use `create(WasmSpecSchema)` to create a new message.
@@ -89,6 +89,9 @@ export type WorkflowIn_Command = Message<"ankka.protocol.v1.WorkflowIn.Command">
89
89
  */
90
90
  export declare const WorkflowIn_CommandSchema: GenMessage<WorkflowIn_Command>;
91
91
  /**
92
+ * `metadata` (1.3): the trace this step belongs to and the step's own name as the caller of
93
+ * whatever it calls, for the process to forward on those calls as it does a command's.
94
+ *
92
95
  * @generated from message ankka.protocol.v1.WorkflowIn.RunStep
93
96
  */
94
97
  export type WorkflowIn_RunStep = Message<"ankka.protocol.v1.WorkflowIn.RunStep"> & {
@@ -104,6 +107,10 @@ export type WorkflowIn_RunStep = Message<"ankka.protocol.v1.WorkflowIn.RunStep">
104
107
  * @generated from field: optional ankka.protocol.v1.Payload input = 3;
105
108
  */
106
109
  input?: Payload | undefined;
110
+ /**
111
+ * @generated from field: ankka.protocol.v1.Metadata metadata = 4;
112
+ */
113
+ metadata?: Metadata | undefined;
107
114
  };
108
115
  /**
109
116
  * Describes the message ankka.protocol.v1.WorkflowIn.RunStep.
@@ -5,7 +5,7 @@ import { file_ankka_protocol_v1_payload } from "./payload_pb.js";
5
5
  /**
6
6
  * Describes the file ankka/protocol/v1/workflow.proto.
7
7
  */
8
- export const file_ankka_protocol_v1_workflow = /*@__PURE__*/ fileDesc("CiBhbmtrYS9wcm90b2NvbC92MS93b3JrZmxvdy5wcm90bxIRYW5ra2EucHJvdG9jb2wudjEiiwQKCldvcmtmbG93SW4SMgoEaW5pdBgBIAEoCzIiLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4uSW5pdEgAEjgKB2NvbW1hbmQYAiABKAsyJS5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0luLkNvbW1hbmRIABI5CghydW5fc3RlcBgDIAEoCzIlLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4uUnVuU3RlcEgAGmkKBEluaXQSFAoMY29tcG9uZW50X2lkGAEgASgJEhEKCWVudGl0eV9pZBgCIAEoCRIuCgVzdGF0ZRgDIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBAUIICgZfc3RhdGUafwoHQ29tbWFuZBIKCgJpZBgBIAEoAxIMCgRuYW1lGAIgASgJEisKB3BheWxvYWQYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5QYXlsb2FkEi0KCG1ldGFkYXRhGAQgASgLMhsuYW5ra2EucHJvdG9jb2wudjEuTWV0YWRhdGEaXQoHUnVuU3RlcBIKCgJpZBgBIAEoAxIMCgRzdGVwGAIgASgJEi4KBWlucHV0GAMgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBQggKBl9pbnB1dEIJCgdtZXNzYWdlIqEECgtXb3JrZmxvd091dBI1CgVyZXBseRgBIAEoCzIkLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93T3V0LlJlcGx5SAASPgoKc3RlcF9yZXBseRgCIAEoCzIoLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93T3V0LlN0ZXBSZXBseUgAEi0KB2ZhaWx1cmUYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5GYWlsdXJlSAAazgEKBVJlcGx5EhIKCmNvbW1hbmRfaWQYASABKAMSMgoJbmV3X3N0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEjMKCnRyYW5zaXRpb24YAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5TdGVwUmVmSAGIAQESKwoHb3V0Y29tZRgEIAEoCzIaLmFua2thLnByb3RvY29sLnYxLk91dGNvbWVCDAoKX25ld19zdGF0ZUINCgtfdHJhbnNpdGlvbhqPAQoJU3RlcFJlcGx5EhIKCmNvbW1hbmRfaWQYASABKAMSMgoJbmV3X3N0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEiwKBG5leHQYAyABKAsyHi5hbmtrYS5wcm90b2NvbC52MS5TdGVwT3V0Y29tZUIMCgpfbmV3X3N0YXRlQgkKB21lc3NhZ2UiUQoHU3RlcFJlZhIMCgRzdGVwGAEgASgJEi4KBWlucHV0GAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBQggKBl9pbnB1dCLhAgoLU3RlcE91dGNvbWUSMwoNdHJhbnNpdGlvbl90bxgBIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlN0ZXBSZWZIABI1CgVwYXVzZRgCIAEoCzIkLmFua2thLnByb3RvY29sLnYxLlN0ZXBPdXRjb21lLlBhdXNlSAASMQoDZW5kGAMgASgLMiIuYW5ra2EucHJvdG9jb2wudjEuU3RlcE91dGNvbWUuRW5kSAASKAoEZmFpbBgEIAEoCzIYLmFua2thLnByb3RvY29sLnYxLkVycm9ySAAadwoFUGF1c2USGQoMYWZ0ZXJfbWlsbGlzGAEgASgDSACIAQESMwoKb25fdGltZW91dBgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlN0ZXBSZWZIAYgBAUIPCg1fYWZ0ZXJfbWlsbGlzQg0KC19vbl90aW1lb3V0GgUKA0VuZEIJCgdvdXRjb21lMlcKCFdvcmtmbG93EksKBkhhbmRsZRIdLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4aHi5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd091dCgBMAFiBnByb3RvMw", [file_ankka_protocol_v1_payload]);
8
+ export const file_ankka_protocol_v1_workflow = /*@__PURE__*/ fileDesc("CiBhbmtrYS9wcm90b2NvbC92MS93b3JrZmxvdy5wcm90bxIRYW5ra2EucHJvdG9jb2wudjEiuwQKCldvcmtmbG93SW4SMgoEaW5pdBgBIAEoCzIiLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4uSW5pdEgAEjgKB2NvbW1hbmQYAiABKAsyJS5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd0luLkNvbW1hbmRIABI5CghydW5fc3RlcBgDIAEoCzIlLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4uUnVuU3RlcEgAGmkKBEluaXQSFAoMY29tcG9uZW50X2lkGAEgASgJEhEKCWVudGl0eV9pZBgCIAEoCRIuCgVzdGF0ZRgDIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBAUIICgZfc3RhdGUafwoHQ29tbWFuZBIKCgJpZBgBIAEoAxIMCgRuYW1lGAIgASgJEisKB3BheWxvYWQYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5QYXlsb2FkEi0KCG1ldGFkYXRhGAQgASgLMhsuYW5ra2EucHJvdG9jb2wudjEuTWV0YWRhdGEajAEKB1J1blN0ZXASCgoCaWQYASABKAMSDAoEc3RlcBgCIAEoCRIuCgVpbnB1dBgDIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlBheWxvYWRIAIgBARItCghtZXRhZGF0YRgEIAEoCzIbLmFua2thLnByb3RvY29sLnYxLk1ldGFkYXRhQggKBl9pbnB1dEIJCgdtZXNzYWdlIqEECgtXb3JrZmxvd091dBI1CgVyZXBseRgBIAEoCzIkLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93T3V0LlJlcGx5SAASPgoKc3RlcF9yZXBseRgCIAEoCzIoLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93T3V0LlN0ZXBSZXBseUgAEi0KB2ZhaWx1cmUYAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5GYWlsdXJlSAAazgEKBVJlcGx5EhIKCmNvbW1hbmRfaWQYASABKAMSMgoJbmV3X3N0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEjMKCnRyYW5zaXRpb24YAyABKAsyGi5hbmtrYS5wcm90b2NvbC52MS5TdGVwUmVmSAGIAQESKwoHb3V0Y29tZRgEIAEoCzIaLmFua2thLnByb3RvY29sLnYxLk91dGNvbWVCDAoKX25ld19zdGF0ZUINCgtfdHJhbnNpdGlvbhqPAQoJU3RlcFJlcGx5EhIKCmNvbW1hbmRfaWQYASABKAMSMgoJbmV3X3N0YXRlGAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBEiwKBG5leHQYAyABKAsyHi5hbmtrYS5wcm90b2NvbC52MS5TdGVwT3V0Y29tZUIMCgpfbmV3X3N0YXRlQgkKB21lc3NhZ2UiUQoHU3RlcFJlZhIMCgRzdGVwGAEgASgJEi4KBWlucHV0GAIgASgLMhouYW5ra2EucHJvdG9jb2wudjEuUGF5bG9hZEgAiAEBQggKBl9pbnB1dCLhAgoLU3RlcE91dGNvbWUSMwoNdHJhbnNpdGlvbl90bxgBIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlN0ZXBSZWZIABI1CgVwYXVzZRgCIAEoCzIkLmFua2thLnByb3RvY29sLnYxLlN0ZXBPdXRjb21lLlBhdXNlSAASMQoDZW5kGAMgASgLMiIuYW5ra2EucHJvdG9jb2wudjEuU3RlcE91dGNvbWUuRW5kSAASKAoEZmFpbBgEIAEoCzIYLmFua2thLnByb3RvY29sLnYxLkVycm9ySAAadwoFUGF1c2USGQoMYWZ0ZXJfbWlsbGlzGAEgASgDSACIAQESMwoKb25fdGltZW91dBgCIAEoCzIaLmFua2thLnByb3RvY29sLnYxLlN0ZXBSZWZIAYgBAUIPCg1fYWZ0ZXJfbWlsbGlzQg0KC19vbl90aW1lb3V0GgUKA0VuZEIJCgdvdXRjb21lMlcKCFdvcmtmbG93EksKBkhhbmRsZRIdLmFua2thLnByb3RvY29sLnYxLldvcmtmbG93SW4aHi5hbmtrYS5wcm90b2NvbC52MS5Xb3JrZmxvd091dCgBMAFiBnByb3RvMw", [file_ankka_protocol_v1_payload]);
9
9
  /**
10
10
  * Describes the message ankka.protocol.v1.WorkflowIn.
11
11
  * Use `create(WorkflowInSchema)` to create a new message.
package/dist/agent.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  import type { Metadata } from "./effects/common.ts";
2
- import type { ComponentClient } from "./client.ts";
2
+ import { type ComponentClient, type Secrets } from "./client.ts";
3
3
  import type { GuardrailRef, HandlerTable, ToolRef } from "./handlers.ts";
4
4
  import { AgentEffects } from "./effects/agent.ts";
5
+ import { type Services } from "./services.ts";
6
+ import type { McpServerRef, ResultGuardrailRef } from "./mcp.ts";
5
7
  export declare abstract class Agent {
6
8
  #private;
7
9
  readonly effects: AgentEffects;
@@ -9,6 +11,14 @@ export declare abstract class Agent {
9
11
  get sessionId(): string;
10
12
  get metadata(): Metadata;
11
13
  get client(): ComponentClient;
14
+ /** The service's secret store: values kept encrypted in the service's own database, never in a journal or a view. */
15
+ get secrets(): Secrets;
16
+ /** A unit test's store in place of the runtime's: `component.secrets = new InMemorySecrets()`. */
17
+ set secrets(store: Secrets);
18
+ /** Other services, called as this one, through the runtime: `this.services.service("orders")`. */
19
+ get services(): Services;
20
+ /** A unit test's in place of the runtime's: `component.services = new ScriptedServices()`. */
21
+ set services(services: Services);
12
22
  /** @internal */
13
23
  get _kind(): "agent";
14
24
  /** @internal */
@@ -23,5 +33,9 @@ export interface AgentClass<C extends Agent = Agent> {
23
33
  readonly maxToolCallSteps?: number;
24
34
  readonly tools?: Readonly<Record<string, ToolRef<C, any>>>;
25
35
  readonly guardrails?: Readonly<Record<string, GuardrailRef>>;
36
+ /** MCP servers whose tools are offered beside the agent's own, as `mcp__<server>__<tool>`. */
37
+ readonly mcpServers?: Readonly<Record<string, McpServerRef>>;
38
+ /** Checks on what an MCP server's tool answered, before the model is told it. */
39
+ readonly resultGuardrails?: Readonly<Record<string, ResultGuardrailRef>>;
26
40
  readonly handlers: HandlerTable<C>;
27
41
  }
package/dist/agent.js CHANGED
@@ -5,7 +5,9 @@
5
5
  // static readonly tools = { lookup: tool("lookup", "Looks up a cart by id.", CartLookup, (a: Assistant, input) => a.lookup(input.cartId)) }
6
6
  // static readonly guardrails = { noSecrets: guardrail("no-secrets", (stage, text) => text.includes("sk-") ? "a key leaked" : null) }
7
7
  // static readonly handlers = { ask: command("ask", s.string, s.string, (a: Assistant, q) => a.ask(q)), chat: stream("chat", s.string, (a: Assistant, q) => a.ask(q)) }
8
+ import { secretsFor } from "./client.js";
8
9
  import { AgentEffects } from "./effects/agent.js";
10
+ import { servicesFor } from "./services.js";
9
11
  export class Agent {
10
12
  effects = new AgentEffects();
11
13
  #sessionId = "";
@@ -23,6 +25,24 @@ export class Agent {
23
25
  throw new Error("client is only available inside a handler, a tool or a guardrail");
24
26
  return this.#client;
25
27
  }
28
+ #secrets;
29
+ /** The service's secret store: values kept encrypted in the service's own database, never in a journal or a view. */
30
+ get secrets() {
31
+ return this.#secrets ?? secretsFor(this.client);
32
+ }
33
+ /** A unit test's store in place of the runtime's: `component.secrets = new InMemorySecrets()`. */
34
+ set secrets(store) {
35
+ this.#secrets = store;
36
+ }
37
+ #services;
38
+ /** Other services, called as this one, through the runtime: `this.services.service("orders")`. */
39
+ get services() {
40
+ return this.#services ?? servicesFor(this.client);
41
+ }
42
+ /** A unit test's in place of the runtime's: `component.services = new ScriptedServices()`. */
43
+ set services(services) {
44
+ this.#services = services;
45
+ }
26
46
  /** @internal */
27
47
  get _kind() {
28
48
  return "agent";
@@ -0,0 +1,47 @@
1
+ import type { ApprovalAwaited as ApprovalAwaitedProto, ApprovalRequest as ApprovalRequestProto } from "./_proto/ankka/protocol/v1/client_pb.ts";
2
+ /** The protocol version that carries approvals: a runtime before it cannot record a decision. */
3
+ export declare const APPROVALS_SINCE = "1.11";
4
+ /** That a tool, or every tool of an MCP server, waits for a person; with `withinMs`, the platform refuses it when that much time passes undecided. */
5
+ export type Approval = true | {
6
+ readonly withinMs: number;
7
+ };
8
+ /** A problem with an approval as declared, or undefined. */
9
+ export declare function approvalProblem(approval: Approval | undefined): string | undefined;
10
+ /** The discovery form: absent for none, empty for no time limit. */
11
+ export declare function approvalToProto(approval: Approval | undefined): {
12
+ withinMillis?: bigint;
13
+ } | undefined;
14
+ /** What an agent records when the model calls a tool that requires approval: the id a decision names, the tool and the model's arguments. */
15
+ export interface ApprovalRequest {
16
+ readonly id: string;
17
+ readonly tool: string;
18
+ readonly arguments: unknown;
19
+ readonly requestedAt: number;
20
+ readonly expiresAt?: number;
21
+ }
22
+ export declare function requestFromProto(pb: ApprovalRequestProto): ApprovalRequest;
23
+ /** A request as an autonomous agent's record holds it. */
24
+ export declare function requestFromJson(body: Record<string, any>): ApprovalRequest;
25
+ /** What a turn that may wait came to: the model's answer, or the requests it waits on. */
26
+ export type AgentOutcome<R> = {
27
+ readonly kind: "answered";
28
+ readonly value: R;
29
+ } | {
30
+ readonly kind: "awaiting-approval";
31
+ readonly requests: readonly ApprovalRequest[];
32
+ };
33
+ export declare function awaitingOf(pb: ApprovalAwaitedProto): AgentOutcome<never>;
34
+ /**
35
+ * Thrown by the calls that answer only with a value — `invoke` and `stream` — when the turn waits. Use
36
+ * `ask`, `streamParts` or `decide` to be answered with the requests instead.
37
+ */
38
+ export declare class ApprovalAwaited extends Error {
39
+ readonly requests: readonly ApprovalRequest[];
40
+ constructor(requests: readonly ApprovalRequest[]);
41
+ }
42
+ /** A person's decision: `by` names who decided and is required; a refusal may carry a note the model is told. */
43
+ export interface DecisionInput {
44
+ readonly approved: boolean;
45
+ readonly by: string;
46
+ readonly note?: string;
47
+ }
@@ -0,0 +1,57 @@
1
+ // Approvals: a tool that waits for a person's decision before it runs.
2
+ //
3
+ // A tool declared with `approval` is never run when the model calls it. The sidecar records an approval
4
+ // request and answers the caller with it instead of an answer; the turn goes on when a person decides,
5
+ // through `decide`. Approved, the tool runs once and the model is told its result; refused, the model is
6
+ // told who refused it and why, and the tool never runs. Who decided is required and recorded; who *may*
7
+ // decide is the ACL of whatever route sends the decision.
8
+ /** The protocol version that carries approvals: a runtime before it cannot record a decision. */
9
+ export const APPROVALS_SINCE = "1.11";
10
+ /** A problem with an approval as declared, or undefined. */
11
+ export function approvalProblem(approval) {
12
+ if (approval === undefined || approval === true)
13
+ return undefined;
14
+ if (!Number.isFinite(approval.withinMs) || approval.withinMs <= 0)
15
+ return `a time limit for approval must be positive, not ${approval.withinMs}ms`;
16
+ return undefined;
17
+ }
18
+ /** The discovery form: absent for none, empty for no time limit. */
19
+ export function approvalToProto(approval) {
20
+ if (approval === undefined)
21
+ return undefined;
22
+ return approval === true ? {} : { withinMillis: BigInt(Math.trunc(approval.withinMs)) };
23
+ }
24
+ export function requestFromProto(pb) {
25
+ return Object.freeze({
26
+ id: pb.id,
27
+ tool: pb.tool,
28
+ arguments: pb.argumentsJson ? JSON.parse(pb.argumentsJson) : {},
29
+ requestedAt: Number(pb.requestedAtMillis),
30
+ ...(pb.expiresAtMillis !== undefined ? { expiresAt: Number(pb.expiresAtMillis) } : {}),
31
+ });
32
+ }
33
+ /** A request as an autonomous agent's record holds it. */
34
+ export function requestFromJson(body) {
35
+ return Object.freeze({
36
+ id: String(body.id),
37
+ tool: String(body.tool),
38
+ arguments: body.arguments ?? {},
39
+ requestedAt: Number(body.requestedAt ?? 0),
40
+ ...(body.expiresAt !== undefined ? { expiresAt: Number(body.expiresAt) } : {}),
41
+ });
42
+ }
43
+ export function awaitingOf(pb) {
44
+ return Object.freeze({ kind: "awaiting-approval", requests: pb.requests.map(requestFromProto) });
45
+ }
46
+ /**
47
+ * Thrown by the calls that answer only with a value — `invoke` and `stream` — when the turn waits. Use
48
+ * `ask`, `streamParts` or `decide` to be answered with the requests instead.
49
+ */
50
+ export class ApprovalAwaited extends Error {
51
+ requests;
52
+ constructor(requests) {
53
+ super(`approval awaited for ${requests.map((r) => `'${r.tool}' (${r.id})`).join(", ")}`);
54
+ this.name = "ApprovalAwaited";
55
+ this.requests = requests;
56
+ }
57
+ }
@@ -1,6 +1,9 @@
1
- import type { ComponentClient } from "./client.ts";
1
+ import { type ApprovalRequest, type DecisionInput } from "./approvals.ts";
2
+ import type { McpServerRef, ResultGuardrailRef } from "./mcp.ts";
3
+ import { type ComponentClient, type Secrets } from "./client.ts";
2
4
  import type { GuardrailRef, ToolRef } from "./handlers.ts";
3
5
  import type { Schema } from "./schema.ts";
6
+ import { type Services } from "./services.ts";
4
7
  type MaybePromise<T> = T | Promise<T>;
5
8
  export declare const COMPLETE_TASK = "complete_task";
6
9
  export declare const FAIL_TASK = "fail_task";
@@ -51,6 +54,14 @@ export declare abstract class AutonomousAgent {
51
54
  /** The task a tool, a guardrail or a rule is running for. */
52
55
  get taskId(): string;
53
56
  get client(): ComponentClient;
57
+ /** The service's secret store: values kept encrypted in the service's own database, never in a journal or a view. */
58
+ get secrets(): Secrets;
59
+ /** A unit test's store in place of the runtime's: `component.secrets = new InMemorySecrets()`. */
60
+ set secrets(store: Secrets);
61
+ /** Other services, called as this one, through the runtime: `this.services.service("orders")`. */
62
+ get services(): Services;
63
+ /** A unit test's in place of the runtime's: `component.services = new ScriptedServices()`. */
64
+ set services(services: Services);
54
65
  /** @internal */
55
66
  get _kind(): "autonomous-agent";
56
67
  /** @internal */
@@ -67,6 +78,10 @@ export interface AutonomousAgentClass<C extends AutonomousAgent = AutonomousAgen
67
78
  readonly guardrails?: Readonly<Record<string, GuardrailRef>>;
68
79
  readonly accepts: readonly TaskAcceptance[];
69
80
  readonly settings?: AutonomousSettings;
81
+ /** MCP servers whose tools are offered beside the agent's own, as `mcp__<server>__<tool>`. */
82
+ readonly mcpServers?: Readonly<Record<string, McpServerRef>>;
83
+ /** Checks on what an MCP server's tool answered, before the model is told it. */
84
+ readonly resultGuardrails?: Readonly<Record<string, ResultGuardrailRef>>;
70
85
  }
71
86
  /** The discovery form of a result schema. */
72
87
  export declare function resultSchemaJson(type: TaskType<any>): string | undefined;
@@ -94,6 +109,8 @@ export interface AgentState {
94
109
  readonly currentTask: string | undefined;
95
110
  readonly iteration: number;
96
111
  readonly queued: readonly string[];
112
+ /** The approval requests the current task's tool calls await; while any does, the instance calls no model. */
113
+ readonly awaiting: readonly ApprovalRequest[];
97
114
  }
98
115
  /** One thing an instance did: `type` names it, and the rest of its fields are as sent. */
99
116
  export interface Notification {
@@ -148,6 +165,11 @@ export declare class AutonomousAgentCalls {
148
165
  /** Stops the instance for good; its tasks go back to pending for another to take. */
149
166
  terminate(): Promise<void>;
150
167
  state(): Promise<AgentState>;
168
+ /**
169
+ * Decides one of the instance's approval requests. `by` names who decided and is required. Approved, the
170
+ * tool runs and the task goes on; refused, the model is told so. A request already decided is a conflict.
171
+ */
172
+ decide(approvalId: string, decision: DecisionInput): Promise<void>;
151
173
  /** What the instance does from now on, as it happens. Nothing is replayed. */
152
174
  notifications(): AsyncIterable<Notification>;
153
175
  }
@@ -14,8 +14,11 @@
14
14
  //
15
15
  // A tool may run more than once for one request of the model — after a crash, the last recorded
16
16
  // request's tools run again — so a tool with a side effect should tolerate a repeat.
17
+ import { requestFromJson } from "./approvals.js";
18
+ import { secretsFor } from "./client.js";
17
19
  import { decodeJsonValue, reviver } from "./json.js";
18
20
  import { toJsonSchema } from "./schema.js";
21
+ import { servicesFor } from "./services.js";
19
22
  export const COMPLETE_TASK = "complete_task";
20
23
  export const FAIL_TASK = "fail_task";
21
24
  export const accepted = () => Object.freeze({ verdict: "accepted" });
@@ -56,6 +59,24 @@ export class AutonomousAgent {
56
59
  throw new Error("client is only available inside a tool, a guardrail or a rule");
57
60
  return this.#client;
58
61
  }
62
+ #secrets;
63
+ /** The service's secret store: values kept encrypted in the service's own database, never in a journal or a view. */
64
+ get secrets() {
65
+ return this.#secrets ?? secretsFor(this.client);
66
+ }
67
+ /** A unit test's store in place of the runtime's: `component.secrets = new InMemorySecrets()`. */
68
+ set secrets(store) {
69
+ this.#secrets = store;
70
+ }
71
+ #services;
72
+ /** Other services, called as this one, through the runtime: `this.services.service("orders")`. */
73
+ get services() {
74
+ return this.#services ?? servicesFor(this.client);
75
+ }
76
+ /** A unit test's in place of the runtime's: `component.services = new ScriptedServices()`. */
77
+ set services(services) {
78
+ this.#services = services;
79
+ }
59
80
  /** @internal */
60
81
  get _kind() {
61
82
  return "autonomous-agent";
@@ -188,7 +209,15 @@ export class AutonomousAgentCalls {
188
209
  const r = (await this.#client._raw("event-sourced", INSTANCE, `${this.componentId}/${this.#instance()}`, "get"));
189
210
  const current = r.current;
190
211
  const phase = r.terminated ? "terminated" : r.suspended ? "suspended" : current ? "working" : (r.queue ?? []).length > 0 ? "waiting" : "idle";
191
- return Object.freeze({ phase, currentTask: current?.taskId, iteration: current?.iteration ?? 0, queued: [...(r.queue ?? [])] });
212
+ const awaiting = (current?.approvals ?? []).filter((a) => a.decision === undefined || a.decision === null).map(requestFromJson);
213
+ return Object.freeze({ phase, currentTask: current?.taskId, iteration: current?.iteration ?? 0, queued: [...(r.queue ?? [])], awaiting });
214
+ }
215
+ /**
216
+ * Decides one of the instance's approval requests. `by` names who decided and is required. Approved, the
217
+ * tool runs and the task goes on; refused, the model is told so. A request already decided is a conflict.
218
+ */
219
+ async decide(approvalId, decision) {
220
+ await this.#client._decide("autonomous-agent", this.componentId, this.#instance(), "", approvalId, decision);
192
221
  }
193
222
  /** What the instance does from now on, as it happens. Nothing is replayed. */
194
223
  async *notifications() {