ankka 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_proto/ankka/protocol/v1/agent_pb.d.ts +35 -0
- package/dist/_proto/ankka/protocol/v1/agent_pb.js +8 -1
- package/dist/_proto/ankka/protocol/v1/client_pb.d.ts +542 -2
- package/dist/_proto/ankka/protocol/v1/client_pb.js +107 -6
- package/dist/_proto/ankka/protocol/v1/discovery_pb.d.ts +330 -0
- package/dist/_proto/ankka/protocol/v1/discovery_pb.js +81 -16
- package/dist/_proto/ankka/protocol/v1/endpoint_pb.d.ts +184 -0
- package/dist/_proto/ankka/protocol/v1/endpoint_pb.js +26 -1
- package/dist/_proto/ankka/protocol/v1/view_pb.d.ts +63 -0
- package/dist/_proto/ankka/protocol/v1/view_pb.js +11 -1
- package/dist/_proto/ankka/protocol/v1/workflow_pb.d.ts +7 -0
- package/dist/_proto/ankka/protocol/v1/workflow_pb.js +1 -1
- package/dist/agent.d.ts +15 -1
- package/dist/agent.js +20 -0
- package/dist/approvals.d.ts +47 -0
- package/dist/approvals.js +57 -0
- package/dist/autonomous.d.ts +23 -1
- package/dist/autonomous.js +30 -1
- package/dist/client.d.ts +92 -4
- package/dist/client.js +262 -15
- package/dist/consumer.d.ts +24 -2
- package/dist/consumer.js +20 -0
- package/dist/context.d.ts +4 -0
- package/dist/contract.d.ts +36 -0
- package/dist/contract.js +58 -0
- package/dist/effects/keyed.d.ts +33 -0
- package/dist/effects/keyed.js +41 -0
- package/dist/endpoint.d.ts +10 -1
- package/dist/endpoint.js +20 -0
- package/dist/graph.d.ts +15 -1
- package/dist/graph.js +20 -0
- package/dist/handlers.d.ts +10 -2
- package/dist/handlers.js +6 -2
- package/dist/index.d.ts +12 -4
- package/dist/index.js +11 -3
- package/dist/keyedView.d.ts +56 -0
- package/dist/keyedView.js +67 -0
- package/dist/mcp.d.ts +57 -0
- package/dist/mcp.js +64 -0
- package/dist/routes.d.ts +23 -3
- package/dist/routes.js +16 -3
- package/dist/server/agent.js +12 -4
- package/dist/server/discovery.d.ts +12 -1
- package/dist/server/discovery.js +95 -1
- package/dist/server/http.d.ts +2 -1
- package/dist/server/http.js +78 -4
- package/dist/server/stateless.js +38 -0
- package/dist/server/workflow.js +5 -1
- package/dist/service.d.ts +40 -2
- package/dist/service.js +209 -14
- package/dist/services.d.ts +137 -0
- package/dist/services.js +259 -0
- package/dist/socket.d.ts +15 -0
- package/dist/socket.js +25 -0
- package/dist/spec.d.ts +1 -1
- package/dist/spec.js +87 -14
- package/dist/startFrom.d.ts +32 -0
- package/dist/startFrom.js +44 -0
- package/dist/testkit/index.d.ts +2 -2
- package/dist/testkit/index.js +1 -1
- package/dist/testkit/integration.js +5 -0
- package/dist/testkit/kinds.d.ts +43 -2
- package/dist/testkit/kinds.js +196 -26
- package/dist/testkit/unit.d.ts +14 -1
- package/dist/testkit/unit.js +40 -3
- package/dist/timedAction.d.ts +17 -2
- package/dist/timedAction.js +33 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/view.d.ts +32 -0
- package/dist/view.js +8 -0
- package/dist/workflow.d.ts +18 -1
- package/dist/workflow.js +39 -0
- package/package.json +3 -2
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
|
+
}
|
package/dist/autonomous.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import type
|
|
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
|
}
|
package/dist/autonomous.js
CHANGED
|
@@ -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
|
-
|
|
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() {
|
package/dist/client.d.ts
CHANGED
|
@@ -4,8 +4,9 @@ import { jsonCodec, type Shape } from "./codec.ts";
|
|
|
4
4
|
import { type Metadata } from "./effects/common.ts";
|
|
5
5
|
import type { HandlerRef } from "./handlers.ts";
|
|
6
6
|
import { type ComponentKind } from "./kinds.ts";
|
|
7
|
-
import
|
|
7
|
+
import { Duration } from "./time.ts";
|
|
8
8
|
import { AutonomousAgentCalls, TaskCalls, Tasks } from "./autonomous.ts";
|
|
9
|
+
import { type AgentOutcome, type DecisionInput } from "./approvals.ts";
|
|
9
10
|
/** A component class as the typed client sees it: an id and, on its prototype, its kind. */
|
|
10
11
|
export interface ComponentRef {
|
|
11
12
|
readonly componentId: string;
|
|
@@ -22,10 +23,25 @@ interface Connection {
|
|
|
22
23
|
export declare class Invocation<I, R> {
|
|
23
24
|
#private;
|
|
24
25
|
constructor(connection: Connection, metadata: Metadata, kind: ComponentKind, componentId: string, entityId: string, name: string, input: Shape<I> | undefined, reply: Shape<R> | undefined);
|
|
25
|
-
/**
|
|
26
|
+
/**
|
|
27
|
+
* Invokes and decodes the reply; a refusal rejects with `CommandError`. An agent's turn that waits for a
|
|
28
|
+
* person rejects with `ApprovalAwaited`; `ask` answers it instead.
|
|
29
|
+
*/
|
|
26
30
|
invoke(input?: I): Promise<R>;
|
|
27
|
-
/**
|
|
31
|
+
/** Calls an agent's handler for its outcome: the model's answer, or the approval requests the turn waits on. */
|
|
32
|
+
ask(input?: I): Promise<AgentOutcome<R>>;
|
|
33
|
+
/**
|
|
34
|
+
* Decides one of the session's approval requests; this invocation names the handler whose turn waits.
|
|
35
|
+
* `by` names who decided and is required. When it was the turn's last awaited decision the turn goes on,
|
|
36
|
+
* and this answers as `ask` would have. A request already decided is a conflict.
|
|
37
|
+
*/
|
|
38
|
+
decide(approvalId: string, decision: DecisionInput): Promise<AgentOutcome<R>>;
|
|
39
|
+
/** Invokes a streaming handler; yields tokens in order; a failure rejects with `CommandError`, a turn that waits with `ApprovalAwaited`. */
|
|
28
40
|
stream(input?: I): AsyncIterable<string>;
|
|
41
|
+
/** As `stream`, ending with one awaiting part when the turn waits for a person. */
|
|
42
|
+
streamParts(input?: I): AsyncIterable<string | Extract<AgentOutcome<never>, {
|
|
43
|
+
kind: "awaiting-approval";
|
|
44
|
+
}>>;
|
|
29
45
|
}
|
|
30
46
|
/** Calls on one component instance, by wire name. */
|
|
31
47
|
export declare class Calls {
|
|
@@ -44,10 +60,15 @@ export declare class TypedCalls<C> {
|
|
|
44
60
|
/** View queries: rows come back as a JSON array decoded with the row shape. */
|
|
45
61
|
export declare class Views {
|
|
46
62
|
#private;
|
|
47
|
-
constructor(connection: Connection);
|
|
63
|
+
constructor(connection: Connection, metadata?: Metadata);
|
|
48
64
|
get<Row>(viewId: string, key: string, row: Shape<Row>): Promise<Row | null>;
|
|
49
65
|
all<Row>(viewId: string, row: Shape<Row>): Promise<Row[]>;
|
|
50
66
|
query<Row>(viewId: string, name: string, key: string | null, row: Shape<Row>): Promise<Row[]>;
|
|
67
|
+
/**
|
|
68
|
+
* The rows of one of a view's declared queries, asked by name with the values it takes. At most
|
|
69
|
+
* `limit` rows, 1000 when it is not given, in the statement's own order.
|
|
70
|
+
*/
|
|
71
|
+
ask<Row>(viewId: string, name: string, values: Readonly<Record<string, string>>, row: Shape<Row>, limit?: number): Promise<Row[]>;
|
|
51
72
|
}
|
|
52
73
|
/** What a timer fires: a component class and one of its handlers, or the same by name. */
|
|
53
74
|
export type TimerTarget = {
|
|
@@ -61,13 +82,78 @@ export type TimerTarget = {
|
|
|
61
82
|
readonly input?: Shape<any>;
|
|
62
83
|
readonly entityId?: string;
|
|
63
84
|
};
|
|
85
|
+
/** What a recurring timer fires: a timed action's class and one of its handlers, or the same by name. */
|
|
86
|
+
export type TimedActionTarget = {
|
|
87
|
+
readonly component: ComponentRef;
|
|
88
|
+
readonly handler: HandlerRef<any, any, any, any>;
|
|
89
|
+
} | {
|
|
90
|
+
readonly componentId: string;
|
|
91
|
+
readonly name: string;
|
|
92
|
+
readonly input?: Shape<any>;
|
|
93
|
+
};
|
|
64
94
|
export declare class Timers {
|
|
65
95
|
#private;
|
|
66
96
|
constructor(connection: Connection);
|
|
67
97
|
/** Schedules `target` after `delay`. Scheduling twice under one id replaces the earlier schedule. */
|
|
68
98
|
schedule(timerId: string, delay: Duration, target: TimerTarget, input?: unknown): Promise<void>;
|
|
99
|
+
/**
|
|
100
|
+
* Schedules `target`, a timed action's handler, first after `delay` (zero or less is due at once) and
|
|
101
|
+
* then every `period` until it is cancelled or replaced. Setting it again with the same handler and
|
|
102
|
+
* period keeps its next due time, so a service may set its recurring timers every time it starts.
|
|
103
|
+
* A period outside 1 millisecond to 36,500 days is refused with `BAD_REQUEST` before anything is sent.
|
|
104
|
+
*/
|
|
105
|
+
scheduleRecurring(timerId: string, delay: Duration, period: Duration, target: TimedActionTarget, input?: unknown): Promise<void>;
|
|
106
|
+
/** Cancels the timer under `timerId`, whether it fires once or recurs. */
|
|
69
107
|
cancel(timerId: string): Promise<void>;
|
|
70
108
|
}
|
|
109
|
+
export declare const MAX_SECRET_NAME_LENGTH = 253;
|
|
110
|
+
export declare const MAX_SECRET_VALUE_BYTES = 65536;
|
|
111
|
+
/** What is wrong with a secret's name, if anything: the runtime's own rule. */
|
|
112
|
+
export declare function secretNameProblem(name: string): string | undefined;
|
|
113
|
+
/** What is wrong with a secret's value, if anything. Never quotes the value. */
|
|
114
|
+
export declare function secretValueProblem(value: string): string | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* The service's secret store: named text values the runtime keeps in the service's own database,
|
|
117
|
+
* encrypted with a key this process never sees. Offered to endpoints, workflow steps, consumers,
|
|
118
|
+
* timed actions and agents; an entity and a view have no `secrets` at all.
|
|
119
|
+
*
|
|
120
|
+
* Every refusal is a `CommandError` with the runtime's code: `BAD_REQUEST` for a name or a value that
|
|
121
|
+
* breaks its rule, `INTERNAL` when the service has no secret key or a value was kept with another
|
|
122
|
+
* one, `UNAVAILABLE` when the database cannot be reached.
|
|
123
|
+
*/
|
|
124
|
+
export declare class Secrets {
|
|
125
|
+
#private;
|
|
126
|
+
/** The store reached through `client`'s sidecar; with none, every call throws. */
|
|
127
|
+
constructor(client?: ComponentClient);
|
|
128
|
+
/** Keeps `value` under `name`, replacing what was there. */
|
|
129
|
+
put(name: string, value: string): Promise<void>;
|
|
130
|
+
/** The value kept under `name`, or `undefined` when there is none. Never an empty string. */
|
|
131
|
+
get(name: string): Promise<string | undefined>;
|
|
132
|
+
/** Removes what is kept under `name`. Removing nothing is not an error. */
|
|
133
|
+
delete(name: string): Promise<void>;
|
|
134
|
+
}
|
|
135
|
+
/** A secret store for unit tests: a map, applying the runtime's rules with its words. */
|
|
136
|
+
export declare class InMemorySecrets extends Secrets {
|
|
137
|
+
readonly values: Map<string, string>;
|
|
138
|
+
put(name: string, value: string): Promise<void>;
|
|
139
|
+
get(name: string): Promise<string | undefined>;
|
|
140
|
+
delete(name: string): Promise<void>;
|
|
141
|
+
}
|
|
142
|
+
/** A store for unit tests whose every call throws: the unit kit's default, beside `noClient()`. */
|
|
143
|
+
export declare function noSecrets(): Secrets;
|
|
144
|
+
/**
|
|
145
|
+
* @internal What a call to another service is sent through: `client`'s sidecar, and the metadata of
|
|
146
|
+
* the handler `client` was scoped to. Not a member of the client, which an entity holds too.
|
|
147
|
+
*/
|
|
148
|
+
export declare function channelOf(client: ComponentClient): {
|
|
149
|
+
stub(): ConnectClient<typeof Client>;
|
|
150
|
+
metadata: Metadata;
|
|
151
|
+
} | undefined;
|
|
152
|
+
/**
|
|
153
|
+
* @internal The secret store reached through `client`'s sidecar. Not a member of the client, which
|
|
154
|
+
* an entity holds too: only the component kinds that may have a store call this.
|
|
155
|
+
*/
|
|
156
|
+
export declare function secretsFor(client: ComponentClient): Secrets;
|
|
71
157
|
export declare class ComponentClient {
|
|
72
158
|
#private;
|
|
73
159
|
readonly views: Views;
|
|
@@ -93,6 +179,8 @@ export declare class ComponentClient {
|
|
|
93
179
|
} | string, instanceId?: string): AutonomousAgentCalls;
|
|
94
180
|
/** @internal A call with a JSON body and a JSON reply, as the platform's own components take them. */
|
|
95
181
|
_raw(kind: ComponentKind, componentId: string, entityId: string, name: string, body?: unknown): Promise<unknown>;
|
|
182
|
+
/** @internal A decision on an approval request; a refusal rejects with `CommandError`. */
|
|
183
|
+
_decide(kind: ComponentKind, componentId: string, entityId: string, name: string, approvalId: string, decision: DecisionInput): Promise<void>;
|
|
96
184
|
/** @internal A streaming call whose tokens are text. */
|
|
97
185
|
_rawStream(kind: ComponentKind, componentId: string, entityId: string, name: string): AsyncIterable<string>;
|
|
98
186
|
/** Typed calls through a component class's handler table: `client.of(ShoppingCartEntity, cartId).call(ShoppingCartEntity.handlers.addItem).invoke(item)`. */
|